texlive[55197] Build/source/libs: harfbuzz 2.6.6

commits+kakuto at tug.org commits+kakuto at tug.org
Mon May 18 12:44:36 CEST 2020


Revision: 55197
          http://tug.org/svn/texlive?view=revision&revision=55197
Author:   kakuto
Date:     2020-05-18 12:44:36 +0200 (Mon, 18 May 2020)
Log Message:
-----------
harfbuzz 2.6.6

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/BUILD.md
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/CONFIG.md
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/Makefile.am
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/README
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/README.md
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/RELEASING.md
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/TESTING.md
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/mingw-ldd.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-libstdc++.sh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-static-inits.sh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.sh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-arabic-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-emoji-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-indic-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-os2-unicode-ranges.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-ucd-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-vowel-constraints.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-fdsc-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-ankr-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-opbd-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-cs-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-dict-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-glib.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-enums.cc.tmpl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-enums.h.tmpl
    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-gobject.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-kern.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number-parser.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number-parser.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-gasp-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-hdmx-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hhea-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-jstf-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-meta-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-language-static.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-unicode-ranges.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-default.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-vowel-constraints.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-vorg-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-string-array.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-emoji-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-buffer-serialize.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-iter.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-meta.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-number.cc
    trunk/Build/source/libs/harfbuzz/include/Makefile.am
    trunk/Build/source/libs/harfbuzz/include/Makefile.in
    trunk/Build/source/libs/harfbuzz/version.ac

Added Paths:
-----------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson_options.txt
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/fix_get_types.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-std-str.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-array.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-ot-glyphname.cc

Removed Paths:
-------------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-ot-color.cc

Modified: trunk/Build/source/libs/README
===================================================================
--- trunk/Build/source/libs/README	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/README	2020-05-18 10:44:36 UTC (rev 55197)
@@ -25,8 +25,8 @@
   http://sourceforge.net/projects/silgraphite/files/graphite2/
   (requires C++11)
 
-harfbuzz 2.6.4 - checked 30oct19
-  http://www.freedesktop.org/software/harfbuzz/release/
+harfbuzz 2.6.6 - checked 18may20
+  https://github.com/harfbuzz/harfbuzz/releases/download/2.6.6/
 
 icu 63.1 - checked 8jan19
   http://download.icu-project.org/files/icu4c/

Modified: trunk/Build/source/libs/harfbuzz/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/ChangeLog	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/ChangeLog	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,3 +1,8 @@
+2020-05-18  Akira Kakuto  <kakuto at w32tex.org>
+
+	Import harfbuzz-2.6.6.
+	* Makefile.am, include/Makefile.am, version.ac: Adjusted.
+
 2019-10-30  Akira Kakuto  <kakuto at w32tex.org>
 
 	Import harfbuzz-2.6.4.

Modified: trunk/Build/source/libs/harfbuzz/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.am	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/Makefile.am	2020-05-18 10:44:36 UTC (rev 55197)
@@ -52,6 +52,8 @@
 	@HARFBUZZ_TREE@/src/hb-config.hh \
 	@HARFBUZZ_TREE@/src/hb-debug.hh \
 	@HARFBUZZ_TREE@/src/hb-dispatch.hh \
+	@HARFBUZZ_TREE@/src/hb-draw.cc \
+	@HARFBUZZ_TREE@/src/hb-draw.hh \
 	@HARFBUZZ_TREE@/src/hb-face.hh \
 	@HARFBUZZ_TREE@/src/hb-face.cc \
 	@HARFBUZZ_TREE@/src/hb-font.hh \
@@ -71,6 +73,7 @@
 	@HARFBUZZ_TREE@/src/hb-open-file.hh \
 	@HARFBUZZ_TREE@/src/hb-open-type.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-cff-common.hh \
+	@HARFBUZZ_TREE@/src/hb-ot-cff1-std-str.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-cff1-table.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-cff1-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-cff2-table.cc \

Modified: trunk/Build/source/libs/harfbuzz/Makefile.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.in	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/Makefile.in	2020-05-18 10:44:36 UTC (rev 55197)
@@ -123,6 +123,7 @@
 	@HARFBUZZ_TREE@/src/hb-buffer-serialize.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-buffer.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-common.$(OBJEXT) \
+	@HARFBUZZ_TREE@/src/hb-draw.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-face.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-font.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-map.$(OBJEXT) \
@@ -199,6 +200,7 @@
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer-serialize.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-common.Po \
+	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-draw.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-face.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-fallback-shape.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-font.Po \
@@ -726,6 +728,7 @@
 	@HARFBUZZ_TREE@/src/hb-config.hh \
 	@HARFBUZZ_TREE@/src/hb-debug.hh \
 	@HARFBUZZ_TREE@/src/hb-dispatch.hh \
+	@HARFBUZZ_TREE@/src/hb-draw.cc @HARFBUZZ_TREE@/src/hb-draw.hh \
 	@HARFBUZZ_TREE@/src/hb-face.hh @HARFBUZZ_TREE@/src/hb-face.cc \
 	@HARFBUZZ_TREE@/src/hb-font.hh @HARFBUZZ_TREE@/src/hb-font.cc \
 	@HARFBUZZ_TREE@/src/hb-iter.hh @HARFBUZZ_TREE@/src/hb-kern.hh \
@@ -740,6 +743,7 @@
 	@HARFBUZZ_TREE@/src/hb-open-file.hh \
 	@HARFBUZZ_TREE@/src/hb-open-type.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-cff-common.hh \
+	@HARFBUZZ_TREE@/src/hb-ot-cff1-std-str.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-cff1-table.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-cff1-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-cff2-table.cc \
@@ -977,6 +981,9 @@
 @HARFBUZZ_TREE@/src/hb-common.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+ at HARFBUZZ_TREE@/src/hb-draw.$(OBJEXT):  \
+	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
+	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
 @HARFBUZZ_TREE@/src/hb-face.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
@@ -1140,6 +1147,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer-serialize.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-common.Po at am__quote@ # am--include-marker
+ at AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-draw.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-face.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-fallback-shape.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-font.Po at am__quote@ # am--include-marker
@@ -1789,6 +1797,7 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer-serialize.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-common.Po
+	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-draw.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-face.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-fallback-shape.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-font.Po
@@ -1888,6 +1897,7 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer-serialize.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-common.Po
+	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-draw.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-face.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-fallback-shape.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-font.Po

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,3 +1,8 @@
+2020-05-18  Akira Kakuto  <kakuto at w32tex.org>
+
+	Imported harfbuzz-2.6.6 source tree from:
+	https://github.com/harfbuzz/harfbuzz/releases/download/2.6.6/
+
 2019-10-30  Akira Kakuto  <kakuto at w32tex.org>
 
 	Imported harfbuzz-2.6.4 source tree from:

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,5 +1,5 @@
-Changes applied to the harfbuzz-2.6.4/ tree as obtained from:
-	http://www.freedesktop.org/software/harfbuzz/release/
+Changes applied to the harfbuzz-2.6.6/ tree as obtained from:
+	https://github.com/harfbuzz/harfbuzz/releases/download/2.6.6/
 
 Removed:
 	COPYING
@@ -22,5 +22,7 @@
 Removed unused dirs:
 	docs
 	m4
+	meson-cc-tests
+	subprojects
 	test
 	util

Modified: trunk/Build/source/libs/harfbuzz/configure
===================================================================
--- trunk/Build/source/libs/harfbuzz/configure	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/configure	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for harfbuzz (TeX Live) 2.6.4.
+# Generated by GNU Autoconf 2.69 for harfbuzz (TeX Live) 2.6.6.
 #
 # Report bugs to <tex-k at tug.org>.
 #
@@ -580,8 +580,8 @@
 # Identity of this package.
 PACKAGE_NAME='harfbuzz (TeX Live)'
 PACKAGE_TARNAME='harfbuzz--tex-live-'
-PACKAGE_VERSION='2.6.4'
-PACKAGE_STRING='harfbuzz (TeX Live) 2.6.4'
+PACKAGE_VERSION='2.6.6'
+PACKAGE_STRING='harfbuzz (TeX Live) 2.6.6'
 PACKAGE_BUGREPORT='tex-k at tug.org'
 PACKAGE_URL=''
 
@@ -1311,7 +1311,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures harfbuzz (TeX Live) 2.6.4 to adapt to many kinds of systems.
+\`configure' configures harfbuzz (TeX Live) 2.6.6 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1382,7 +1382,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 2.6.4:";;
+     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 2.6.6:";;
    esac
   cat <<\_ACEOF
 
@@ -1487,7 +1487,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-harfbuzz (TeX Live) configure 2.6.4
+harfbuzz (TeX Live) configure 2.6.6
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2123,7 +2123,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by harfbuzz (TeX Live) $as_me 2.6.4, which was
+It was created by harfbuzz (TeX Live) $as_me 2.6.6, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -4047,7 +4047,7 @@
 
 # Define the identity of the package.
  PACKAGE='harfbuzz--tex-live-'
- VERSION='2.6.4'
+ VERSION='2.6.6'
 
 
 # Some tools Automake needs.
@@ -4241,8 +4241,8 @@
 
 HB_VERSION_MAJOR=2
 HB_VERSION_MINOR=6
-HB_VERSION_MICRO=4
-HB_VERSION=2.6.4
+HB_VERSION_MICRO=6
+HB_VERSION=2.6.6
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -7919,7 +7919,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by harfbuzz (TeX Live) $as_me 2.6.4, which was
+This file was extended by harfbuzz (TeX Live) $as_me 2.6.6, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -7985,7 +7985,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-harfbuzz (TeX Live) config.status 2.6.4
+harfbuzz (TeX Live) config.status 2.6.6
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/BUILD.md
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/BUILD.md	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/BUILD.md	2020-05-18 10:44:36 UTC (rev 55197)
@@ -7,11 +7,8 @@
 
     sudo yum install gcc gcc-c++ freetype-devel glib2-devel cairo-devel
 
-on Windows, consider using [vcpkg](https://github.com/Microsoft/vcpkg),
-provided by Microsoft, for building HarfBuzz and other open-source libraries
-but if you need to build harfbuzz from source, put ragel binary on your
-PATH and follow appveyor CI's cmake
-[build steps](https://github.com/harfbuzz/harfbuzz/blob/master/appveyor.yml).
+on Windows, consider using [vcpkg](https://github.com/Microsoft/vcpkg)
+or `meson build && ninja -Cbuild`.
 
 on macOS, using MacPorts:
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,7 +1,7 @@
 cmake_minimum_required(VERSION 2.8.0)
 project(harfbuzz)
 
-enable_testing()
+message("HarfBuzz has a Meson port also and tries to migrate all the other build systems to it, please consider using it.")
 
 ## Limit framework build to Xcode generator
 if (BUILD_FRAMEWORK)
@@ -53,7 +53,6 @@
 endif ()
 
 option(HB_BUILD_SUBSET "Build harfbuzz-subset" ON)
-option(HB_BUILD_TESTS "Build harfbuzz tests" ON)
 
 option(HB_HAVE_GOBJECT "Enable GObject Bindings" OFF)
 if (HB_HAVE_GOBJECT)
@@ -66,25 +65,6 @@
   set (HB_HAVE_GLIB ON)
 endif ()
 
-option(HB_CHECK OFF "Do a configuration suitable for testing (shared library and enable all options)")
-if (HB_CHECK)
-  set (BUILD_SHARED_LIBS ON)
-  set (HB_BUILD_UTILS ON)
-  set (HB_HAVE_ICU)
-  set (HB_HAVE_GLIB ON)
-  #set (HB_HAVE_GOBJECT ON)
-  #set (HB_HAVE_INTROSPECTION ON)
-  set (HB_HAVE_FREETYPE ON)
-  set (HB_HAVE_GRAPHITE2 ON)
-  if (WIN32)
-    set (HB_HAVE_UNISCRIBE ON)
-    set (HB_HAVE_GDI ON)
-    set (HB_HAVE_DIRECTWRITE ON)
-  elseif (APPLE)
-    set (HB_HAVE_CORETEXT ON)
-  endif ()
-endif ()
-
 include_directories(AFTER
   ${PROJECT_SOURCE_DIR}/src
   ${PROJECT_BINARY_DIR}/src
@@ -108,7 +88,7 @@
 if (UNIX)
   list(APPEND CMAKE_REQUIRED_LIBRARIES m)
 endif ()
-check_funcs(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l roundf)
+check_funcs(atexit mprotect sysconf getpagesize mmap isatty roundf)
 check_include_file(unistd.h HAVE_UNISTD_H)
 if (${HAVE_UNISTD_H})
   add_definitions(-DHAVE_UNISTD_H)
@@ -117,10 +97,6 @@
 if (${HAVE_SYS_MMAN_H})
   add_definitions(-DHAVE_SYS_MMAN_H)
 endif ()
-check_include_file(xlocale.h HAVE_XLOCALE_H)
-if (${HAVE_XLOCALE_H})
-  add_definitions(-DHAVE_XLOCALE_H)
-endif ()
 check_include_file(stdbool.h HAVE_STDBOOL_H)
 if (${HAVE_STDBOOL_H})
   add_definitions(-DHAVE_STDBOOL_H)
@@ -147,7 +123,7 @@
   set (${variable} ${listVar} PARENT_SCOPE)
 endfunction ()
 
-# http://stackoverflow.com/a/27630120
+# https://stackoverflow.com/a/27630120
 function (add_prefix_to_list var prefix)
   set (listVar "")
   foreach (f ${${var}})
@@ -465,6 +441,19 @@
 add_library(harfbuzz ${project_sources} ${project_extra_sources} ${project_headers})
 target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS})
 
+
+## Define harfbuzz-icu library
+if (HB_HAVE_ICU)
+  add_library(harfbuzz-icu ${PROJECT_SOURCE_DIR}/src/hb-icu.cc ${PROJECT_SOURCE_DIR}/src/hb-icu.h)
+  add_dependencies(harfbuzz-icu harfbuzz)
+  target_link_libraries(harfbuzz-icu harfbuzz ${THIRD_PARTY_LIBS})
+
+  if (BUILD_SHARED_LIBS)
+    set_target_properties(harfbuzz harfbuzz-icu PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
+  endif ()
+endif ()
+
+
 ## Define harfbuzz-subset library
 if (HB_BUILD_SUBSET)
   add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers})
@@ -615,12 +604,14 @@
     POST_BUILD
     COMMAND ${G_IR_SCANNER_CMD}
       --warn-all --no-libtool --verbose
-      -n hb
       --namespace=HarfBuzz
       --nsversion=0.0
+      --symbol-prefix=hb
+      --symbol-prefix=hb_gobject
       --identifier-prefix=hb_
       --include GObject-2.0
-      --pkg-export=harfbuzz
+      --pkg-export=harfbuzz-gobject
+      --c-include=hb-gobject.h
       --cflags-begin
       -I${PROJECT_SOURCE_DIR}/src
       -I${PROJECT_BINARY_DIR}/src
@@ -723,6 +714,14 @@
       NAMESPACE harfbuzz::
       DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/harfbuzz
   )
+  if (HB_HAVE_ICU)
+    install(TARGETS harfbuzz-icu
+      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+      FRAMEWORK DESTINATION Library/Frameworks
+    )
+  endif ()
   if (HB_BUILD_UTILS)
     if (WIN32 AND BUILD_SHARED_LIBS)
       install(TARGETS harfbuzz-subset
@@ -767,54 +766,3 @@
     endif ()
   endif ()
 endif ()
-
-if (HB_BUILD_TESTS)
-  ## src/ executables
-  foreach (prog main test test-gsub-would-substitute test-gpos-size-params test-buffer-serialize test-unicode-ranges) # hb-ot-tag
-    set (prog_name ${prog})
-    if (${prog_name} STREQUAL "test")
-      # test can not be used as a valid executable name on cmake, lets special case it
-      set (prog_name test-test)
-    endif ()
-    add_executable(${prog_name} ${PROJECT_SOURCE_DIR}/src/${prog}.cc)
-    target_link_libraries(${prog_name} harfbuzz ${THIRD_PARTY_LIBS})
-  endforeach ()
-  # set_target_properties(hb-ot-tag PROPERTIES COMPILE_FLAGS "-DMAIN")
-
-  ## Tests
-  if (UNIX OR MINGW)
-    if (BUILD_SHARED_LIBS)
-      # generate harfbuzz.def after build completion
-      add_custom_command(TARGET harfbuzz POST_BUILD
-        COMMAND "${PYTHON_EXECUTABLE}" ${PROJECT_SOURCE_DIR}/src/gen-def.py ${PROJECT_BINARY_DIR}/harfbuzz.def ${project_headers}
-        WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src)
-
-      add_test(NAME check-static-inits.sh
-        COMMAND ${PROJECT_SOURCE_DIR}/src/check-static-inits.sh
-        WORKING_DIRECTORY ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/harfbuzz.dir/src # ugly hack
-      )
-      add_test(NAME check-libstdc++.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-libstdc++.sh)
-      add_test(NAME check-symbols.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-symbols.sh)
-
-      set_tests_properties(
-        check-static-inits.sh check-libstdc++.sh check-symbols.sh
-        PROPERTIES
-          ENVIRONMENT "libs=.;srcdir=${PROJECT_SOURCE_DIR}/src"
-          SKIP_RETURN_CODE 77)
-    endif ()
-
-    add_test(NAME check-c-linkage-decls.sh COMMAND ./check-c-linkage-decls.sh)
-    add_test(NAME check-header-guards.sh COMMAND ./check-header-guards.sh)
-    add_test(NAME check-externs.sh COMMAND ./check-externs.sh)
-    add_test(NAME check-includes.sh COMMAND ./check-includes.sh)
-    set_tests_properties(
-      check-c-linkage-decls.sh check-header-guards.sh check-externs.sh check-includes.sh
-      PROPERTIES
-        WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src
-        SKIP_RETURN_CODE 77)
-  endif ()
-
-  # Needs to come last so that variables defined above are passed to
-  # subdirectories.
-  add_subdirectory(test)
-endif ()

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/CONFIG.md
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/CONFIG.md	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/CONFIG.md	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,7 +1,7 @@
 # Configuring HarfBuzz
 
 Most of the time you will not need any custom configuration.  The configuration
-options provided by `configure` or `cmake` should be enough.  In particular,
+options provided by `configure` or `meson` should be enough.  In particular,
 if you just want HarfBuzz library plus hb-shape / hb-view utilities, make sure
 FreeType and Cairo are available and found during configuration.
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,3 +1,7962 @@
+commit 42025680cb0a30eba4ed48d125586a4dda3c973e
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue May 12 00:14:33 2020 +0430
+
+    2.6.6
+
+ NEWS             | 7 +++++++
+ configure.ac     | 2 +-
+ meson.build      | 2 +-
+ src/hb-version.h | 4 ++--
+ 4 files changed, 11 insertions(+), 4 deletions(-)
+
+commit 57d67f177508c11a2a9b9e8aa5f2d3540b5319f5
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue May 12 00:03:17 2020 +0430
+
+    [RELEASE] minor update
+
+ RELEASING.md | 20 +++++---------------
+ 1 file changed, 5 insertions(+), 15 deletions(-)
+
+commit b169a52c1e3c5d16adcf3e80cba37bb86adcbe77
+Author: Khaled Hosny <khaledhosny at eglug.org>
+Date:   Mon May 11 14:35:11 2020 +0200
+
+    [blob] Fix build when HAVE_MMAP is not defined
+
+ src/hb-blob.cc | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+commit a2ce96881b40c1689319c1f699f1469afc3ffe40
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon May 11 17:15:37 2020 +0430
+
+    [cff] remove the not used member
+
+ src/hb-subset-cff1.cc | 4 ----
+ 1 file changed, 4 deletions(-)
+
+commit 2cc78a58c3fecf7a3cb26c01949e9cd4d0cd9ee5
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon May 11 15:56:54 2020 +0430
+
+    [number] minor
+
+ src/hb-number-parser.hh | 16 +++++++---------
+ src/hb-number-parser.rl |  8 +++-----
+ 2 files changed, 10 insertions(+), 14 deletions(-)
+
+commit bb095e1bdd0f7f1de88651d6f7223bc04bf70d70
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun May 10 22:00:05 2020 +0430
+
+    [meson] make -subset target dependent to deps to get libm dependency
+
+ src/meson.build | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit dca8ba6b6d637ebfc51d658a893e8dbda28b7709
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun May 10 16:57:45 2020 +0430
+
+    [number] Make hb_parse_double simpler now that we don't have to mimic strtod
+
+ src/hb-number-parser.hh | 23 ++++++++++++-----------
+ src/hb-number-parser.rl | 15 ++++++++-------
+ src/hb-number.cc        | 25 +++++++++++++------------
+ src/test-number.cc      | 20 --------------------
+ 4 files changed, 33 insertions(+), 50 deletions(-)
+
+commit 44fe1c8ff19048d11785ff154993d6637b447fdd
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Mar 25 16:36:48 2020 +0430
+
+    Remove xlocale use now that isn't available in most distros
+    
+    Our CI bots don't detect it in Alpine, ArchLinux, Ubuntu and Fedora
+    so let's get rid of it use the fallback we are using anyway for a
+    long time.
+
+ CMakeLists.txt     |  6 +----
+ configure.ac       |  4 +--
+ meson.build        |  3 ---
+ src/hb-number.cc   | 71 +-----------------------------------------------------
+ src/test-number.cc |  9 -------
+ 5 files changed, 4 insertions(+), 89 deletions(-)
+
+commit eea99d7b7253027570f7afe64ca63962618553b7
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun May 10 14:46:16 2020 +0430
+
+    [meson] Let name_prefix of exported libraries the default
+    
+    meson complains about this and it is the default per #2256
+    
+    Fixes #2256
+
+ src/meson.build | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+commit 2ac4222022ee261269994ce4eaf4d7c070152492
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun May 10 14:20:27 2020 +0430
+
+    [meson] specify preferred linker to avoid stdc++ linking
+
+ meson_options.txt |  2 ++
+ src/meson.build   | 19 ++++++++++++++++++-
+ 2 files changed, 20 insertions(+), 1 deletion(-)
+
+commit 15083c24ee7c69e17eee4d99ee9db121a150338b
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun May 10 14:12:20 2020 +0430
+
+    [meson] Reenable make check-symbols compatible with gcov
+
+ src/check-symbols.sh |  2 +-
+ src/meson.build      | 29 ++++++++++++++++++++---------
+ 2 files changed, 21 insertions(+), 10 deletions(-)
+
+commit 68855e4a6dedf40d643a1ec9ac89c9ae32ce763c
+Author: Khaled Hosny <khaledhosny at eglug.org>
+Date:   Fri May 8 00:51:15 2020 +0200
+
+    [docs] Don’t recommend outdated FDO releases pages
+
+ docs/usermanual-install-harfbuzz.xml | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+commit 1ec77522d838dd751733d3927e3d9589bf298853
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu May 7 14:08:05 2020 +0430
+
+    [docs] Simplify logo's SVG source, down scale png version
+    
+    * SVG version is simplified using SVGO and some hand tweak
+    * PNG result of SVG logo is optimized using pngwolf-zopfli
+    * Down scaled to fit visually a little better on docs page
+
+ docs/HarfBuzz.png | Bin 8814 -> 4740 bytes
+ docs/HarfBuzz.svg | 283 ++----------------------------------------------------
+ 2 files changed, 7 insertions(+), 276 deletions(-)
+
+commit 0b261c5d0b38f1b9a564798ea26edb698e872841
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu May 7 10:28:24 2020 +0430
+
+    [ci] disable clang-{everthing,*san} bots
+    
+    are flaky, will enable them somewhere else
+
+ .circleci/config.yml | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 385d64eef1d5dd37187310a08ca6f0408a2e4625
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu May 7 09:59:01 2020 +0430
+
+    Add a not discardable bool type, hb_success_t
+
+ src/hb-open-type.hh |  4 ++--
+ src/hb.hh           | 12 ++++++++++++
+ 2 files changed, 14 insertions(+), 2 deletions(-)
+
+commit 1026b3d0b65fd101939ce8d2b74aaf074c44c3e6
+Author: jfkthame <jfkthame at gmail.com>
+Date:   Wed May 6 21:32:24 2020 +0100
+
+    [subset] Check vector resize() call for failure (#2389)
+    
+    Other .resize() calls are checked, presumably this one should be as well.
+
+ src/hb-subset-cff2.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 100d40c827eb8336b2b671856f151275d47e71ad
+Author: jfkthame <jfkthame at gmail.com>
+Date:   Wed May 6 01:48:24 2020 +0100
+
+    [aat] Fix implementation of AAT kerning for Geeza Pro. (#2388)
+    
+    * [aat] Fix implementation of AAT kerning for Geeza Pro.
+    
+    Despite what the comment in the code used to say, it appears that Geeza Pro
+    does rely on accumulating kerning values from successive subtables. With
+    this change, the results now match Core Text rendering (and avoid the clear
+    visual breakage reported in #2358).
+    
+    Testcase: U+0644,U+064E,U+0645,U+064E,U+0651,U+0627
+    
+    Fixes #2358.
+    
+    * [aat] Update test expectations, add new testcase.
+
+ src/hb-aat-layout-kerx-table.hh              | 50 +++++++++++++---------------
+ test/shaping/data/in-house/tests/macos.tests | 12 ++++---
+ 2 files changed, 31 insertions(+), 31 deletions(-)
+
+commit 9fc774ab00be92dbfd1cc1c03b4e6cadcd9b7674
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Apr 30 23:14:54 2020 +0430
+
+    minor spacing
+
+ src/hb-blob.cc                |  4 ++--
+ src/hb-ot-color-cbdt-table.hh | 12 ++++++------
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+commit 09b9d63e56eb8dac50db9684cf5a77a84eb31a60
+Author: Khaled Hosny <khaledhosny at eglug.org>
+Date:   Thu Apr 30 18:51:46 2020 +0200
+
+    [blob] Try to support resource fork fonts on macOS
+    
+    If the size of opened file is zero, try opening resource fork by
+    appending "/..namedfork/rsrc" to the file name. This is guarded with
+    __APPLE__ ifdef and uses _PATH_RSRCFORKSPEC macro from sys/paths.h.
+    
+    Defining HB_NO_RESOURCE_FORK will disable this fallback.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/2383
+
+ src/hb-blob.cc | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 50 insertions(+)
+
+commit d6ddb232fc9b8c3a04398360a1d3a0b7931033e3
+Author: René Meusel <rene.meusel at nexenio.com>
+Date:   Tue Apr 28 19:30:00 2020 +0200
+
+    FIX: -Wextra-semi-stmt in Clang9
+
+ src/hb-coretext.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 8ba8980222731a51f23ebc12b0145d29caee1a91
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 28 20:14:17 2020 +0430
+
+    [ci] enable experimental apis in coverity scan
+
+ .github/workflows/coverity-scan.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit d63ee13a2a3d4e480bd563dcbac74817b675e812
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 28 20:01:11 2020 +0430
+
+    [ci] enable more on coverity
+
+ .github/workflows/coverity-scan.yml | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit ace202e17e7f41aa3347618426b334be3d9f0e17
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 28 19:38:04 2020 +0430
+
+    [ci] remove trigger-coverity.sh
+    
+    hopefully not needed, we are submitting it in a bot
+
+ .ci/trigger-coverity.sh | 11 -----------
+ 1 file changed, 11 deletions(-)
+
+commit a22e6de0e96b68b28cd750e3041fdc864bf3331a
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 28 19:25:37 2020 +0430
+
+    [blob] close file reader handle
+    
+    fortunately it isn't in that use as having mmap reader as the default
+
+ src/hb-blob.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 39976ee660ba82c75e4fa757134f7925740b1c4d
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 28 18:50:33 2020 +0430
+
+    [ci] install fonttools in linux-ci bot
+
+ .github/workflows/linux-ci.yml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 1801489b49f4c2c6ef82fba89440d4e766de3555
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 28 18:47:39 2020 +0430
+
+    [ci] Add coverity scan bot
+
+ .github/workflows/coverity-scan.yml | 38 +++++++++++++++++++++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+
+commit 156714f797fcb5bc07ff5e22ae8ee8d78a7cf79b
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 28 16:32:15 2020 +0430
+
+    [ci] fix linux-ci bot
+    
+    It shows some percentage of coverage regression
+    as the switch from lcov to gcovr and autotools to meson while this travis to github actions switch.
+
+ .github/workflows/linux-ci.yml | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 4b298cc6c4e3ecdde2d27dfa28e8cbb377a5e05d
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 28 15:50:03 2020 +0430
+
+    [ci] remove travis's clang bot
+    
+    we are testing it on other bots, let's remove it from travis
+
+ .travis.yml | 24 ++----------------------
+ 1 file changed, 2 insertions(+), 22 deletions(-)
+
+commit 34a4ce98f4ccf7c6aa6cb7d4e4497da4cf2aeb0f
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 28 15:34:29 2020 +0430
+
+    [ci] run apt-get with sudo
+
+ .github/workflows/linux-ci.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f27c0065d42f22c3f1484d97cac34f727832ff78
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 28 15:30:25 2020 +0430
+
+    [ci] Add a GitHub CI bot
+    
+    Run coverage also
+
+ .github/workflows/linux-ci.yml | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+commit 482f4aafd53982d96f08eaebe9af6e7dd4419dc9
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 28 15:29:19 2020 +0430
+
+    [ci] Remove coverity and codecov
+    
+    * This coverity runner doesn't work from here but will try again in GitHub Actions bot
+    * Trying to move codecov to GitHub Actions
+
+ .travis.yml | 13 -------------
+ 1 file changed, 13 deletions(-)
+
+commit 6890554256f96d2dee43261ad5012e788695754c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 28 14:56:47 2020 +0430
+
+    [ci/meson] temporarily disable check-symbols
+    
+    will enable again
+
+ src/meson.build | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit e53c44e3260d6136e27635b5bbcb2da43bc4f1b1
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Fri Apr 24 14:06:13 2020 -0700
+
+    [subset] temporarily revert previous cmap commit
+    Required in https://github.com/harfbuzz/harfbuzz/issues/2356
+
+ src/hb-ot-cmap-table.hh                                  |   3 ++-
+ test/api/test-subset-cmap.c                              |   4 +++-
+ test/subset/data/Makefile.sources                        |   2 +-
+ .../expected/japanese/Mplus1p-Regular.default.25771.ttf  | Bin 1824 -> 0 bytes
+ .../japanese/Mplus1p-Regular.drop-hints.25771.ttf        | Bin 1096 -> 0 bytes
+ .../japanese/Mplus1p-Regular.keep-gdef.25771.ttf         | Bin 1860 -> 0 bytes
+ test/subset/data/tests/japanese.tests                    |   1 -
+ test/subset/meson.build                                  |   1 -
+ 8 files changed, 6 insertions(+), 5 deletions(-)
+
+commit 08428a15c392e2fff267aa3bc92b343f566c983a
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Apr 24 23:45:17 2020 +0430
+
+    minor, spacing
+
+ src/hb-aat-fdsc-table.hh        |   4 +-
+ src/hb-aat-layout-just-table.hh |   8 +--
+ src/hb-aat-layout-opbd-table.hh |   4 +-
+ src/hb-aat-layout-trak-table.hh |   2 +-
+ src/hb-ot-cff-common.hh         |   3 +-
+ src/hb-ot-cmap-table.hh         |   4 +-
+ src/hb-ot-hdmx-table.hh         |  10 ++--
+ src/hb-ot-hhea-table.hh         |  61 ++++++++++---------
+ src/hb-ot-hmtx-table.hh         |  44 +++++++-------
+ src/hb-ot-kern-table.hh         |  37 +++++++-----
+ src/hb-ot-layout-gsubgpos.hh    |   2 +-
+ src/hb-ot-math-table.hh         | 130 ++++++++++++++++++++++------------------
+ src/hb-ot-maxp-table.hh         |   7 ++-
+ src/hb-ot-meta-table.hh         |   5 +-
+ src/hb-ot-name-table.hh         |   8 +--
+ src/hb-ot-post-table.hh         |   2 +-
+ src/hb-ot-stat-table.hh         |  14 ++---
+ src/hb-ot-var-fvar-table.hh     |   6 +-
+ src/hb-ot-vorg-table.hh         |   7 ++-
+ 19 files changed, 194 insertions(+), 164 deletions(-)
+
+commit 89ad3c6cc520517af15174391a9725e634929107
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Apr 23 10:57:30 2020 -0700
+
+    Rename add_class to collect_class
+
+ src/hb-ot-layout-common.hh     | 10 +++++-----
+ src/hb-ot-layout-gdef-table.hh |  2 +-
+ src/hb-ot-layout-gsubgpos.hh   |  2 +-
+ 3 files changed, 7 insertions(+), 7 deletions(-)
+
+commit 5cf53c06e66d3307d7b30ea32059437887abcab1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Apr 23 10:55:41 2020 -0700
+
+    Rename add_coverage to collect_coverage
+
+ src/hb-ot-layout-common.hh     | 28 ++++++++++++++--------------
+ src/hb-ot-layout-gpos-table.hh | 28 ++++++++++++++--------------
+ src/hb-ot-layout-gsub-table.hh | 20 ++++++++++----------
+ src/hb-ot-layout-gsubgpos.hh   | 30 +++++++++++++++---------------
+ 4 files changed, 53 insertions(+), 53 deletions(-)
+
+commit 689f3f57fa26922af4f2ab451eb834ae6c3119b2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Apr 23 10:51:12 2020 -0700
+
+    [set] Add << overload for range-sink
+
+ src/hb-set.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit a7df5a7bdaef870617b6bdb7350a26ebbec5824a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Apr 23 10:50:02 2020 -0700
+
+    [hashmap] Minor
+
+ src/hb-map.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit cc1ed76f381531c800833cb0f5b41fc524ed20a3
+Merge: 5a0936f5 a11db0b9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 24 08:15:32 2020 -0700
+
+    Merge pull request #1729 from n8willis/usermanual-integration
+    
+    [Docs] Usermanual: Add OS/platform-integration chapter
+
+commit 5a0936f53ef533787a91063c0884275cc121585f
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Thu Apr 23 19:09:00 2020 -0400
+
+    Increase the size of the serialization buffer
+
+ util/options.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a11db0b9d4d3e7cc22a4a53374d4f8a049ce067e
+Merge: 1ed30515 19346524
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Apr 23 15:32:43 2020 -0700
+
+    Merge branch 'master' into usermanual-integration
+
+commit 19346524c698586c24b0461648b33373092c60df
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Apr 23 14:22:33 2020 +0430
+
+    minor, add an option to skip private APIs use in main.cc
+
+ src/main.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 2e3dfdcd5fe6ebf38872d8fd817a562bfade8c46
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Apr 23 14:04:24 2020 +0430
+
+    [meson] make 'tests' option enabled by default
+    
+    Not sure what 'auto' can mean here but it makes my local test to not run properly
+
+ meson_options.txt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6881939f77e2d89ceba4cb6ed08075b93de6e500
+Author: Hugo Beauzée-Luyssen <hugo at beauzee.fr>
+Date:   Thu Apr 23 10:08:45 2020 +0200
+
+    src: meson: Reindent after last changes
+
+ src/meson.build | 162 ++++++++++++++++++++++++++++----------------------------
+ 1 file changed, 81 insertions(+), 81 deletions(-)
+
+commit e18858c68509e1d4576bb14c7a07a5e9818c50ae
+Author: Hugo Beauzée-Luyssen <hugo at beauzee.fr>
+Date:   Thu Apr 23 10:06:20 2020 +0200
+
+    src: Don't build tests when they are disabled
+
+ src/meson.build | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 0c65a232fa00a1eb09ca0e9d1d8d26747b27416e
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Apr 23 11:23:54 2020 +0430
+
+    minor, add unlikely around lookup_limit_exceeded checks
+    
+    addresses https://github.com/harfbuzz/harfbuzz/pull/2294#issuecomment-618022488
+
+ src/hb-ot-layout-gsubgpos.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit 3e686d24590fc0b30a4bbbf4dc762d6858de8e8f
+Author: Evgeniy Reizner <razrfalcon at gmail.com>
+Date:   Wed Apr 22 13:44:53 2020 +0300
+
+    [kern] Refactoring.
+
+ src/hb-kern.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 186976ebd6cefdfe993b5ae400a559ca33c66688
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 21 22:37:56 2020 -0700
+
+    [autotools] C++11 requirement is mandatory
+    
+    How was this not updated?
+
+ configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f4cd99f28eefe695b86876736166fd119e22e04e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Apr 22 14:45:57 2020 -0700
+
+    Reordering fails when GDEF table is absent #2140
+    
+    Preserve glyph class if there's no GDEF and no guess.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/2140
+
+ src/hb-ot-layout-gsubgpos.hh | 41 ++++++++++++++++++++++-------------------
+ src/hb-ot-layout.hh          |  8 ++++----
+ 2 files changed, 26 insertions(+), 23 deletions(-)
+
+commit 05be05eb65ed2a5d5d88df55f9e36d005408d66c
+Author: Evgeniy Reizner <razrfalcon at gmail.com>
+Date:   Wed Apr 22 13:34:51 2020 +0300
+
+    [kern] Test format 3.
+
+ test/shaping/data/in-house/tests/macos.tests | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit c7afb6d7b83da9f7503a033d289d4bba6af2ae39
+Author: Khaled Hosny <khaledhosny at eglug.org>
+Date:   Wed Apr 22 15:18:40 2020 +0200
+
+    [docs] Fix broken link
+
+ src/hb-ot-layout.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit bd8aa1b043a6fb9e1d5dce735715ae9530d9ff20
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Apr 21 22:19:46 2020 -0700
+
+    Minor
+
+ src/hb-null.hh   | 4 ++--
+ src/hb-shaper.hh | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit b22f61d86a27e1dcbcab5ecdbbff579175dc5aaf
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Tue Apr 21 11:49:05 2020 -0400
+
+    Fix bug
+
+ src/hb-ot-color-cbdt-table.hh                            |   7 ++++++-
+ ...-testcase-minimized-hb-subset-fuzzer-5684014636859392 | Bin 0 -> 7148 bytes
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+commit 1cd14b40e794721d594553614cf4ece11410a934
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 21 14:42:17 2020 +0430
+
+    minor, update ragel generated hb-number-parser.hh
+
+ src/hb-number-parser.hh | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+commit 6d5e8e5ee49aac1f51a35f67335ee2f633470d76
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 21 14:38:09 2020 +0430
+
+    minor
+    
+    following to c37100e7d
+
+ src/hb-number-parser.rl | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit 5b91c52083aee1653c0cf1e778923de00c08fa5d
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Apr 20 21:44:01 2020 +0000
+
+    [ci] run experimental APIs tests
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 750bb73e32f967ce40e29751338e6a64042b5674
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 21 01:13:13 2020 +0430
+
+    [meson] Add an experimental-api option
+
+ .circleci/config.yml    |  4 ++--
+ meson.build             |  4 ++++
+ meson_options.txt       |  2 ++
+ src/gen-def.py          |  2 +-
+ src/main.cc             | 12 ++++++------
+ src/meson.build         |  8 +++++++-
+ test/subset/meson.build | 23 ++++++++++++++---------
+ 7 files changed, 36 insertions(+), 19 deletions(-)
+
+commit 262eced2adae740de7dd7bcbb4359e892471536b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Apr 20 12:17:28 2020 -0700
+
+    [subset] FeatureVariations subsetting is wrong
+    
+    Never drop FeatureVariationRecord for now.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/2334
+
+ src/hb-ot-layout-common.hh | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+commit 2a549aadd334b43d37444fed37fdbf8ec673ec14
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Apr 21 00:32:34 2020 +0430
+
+    minor
+
+ util/options.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 2be859d289a9e04199a29bd4b8d393a502ed4791
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Apr 20 23:48:23 2020 +0430
+
+    minor, replace nullptr checks with implicit ones
+
+ src/hb-blob.cc                  | 12 ++++++------
+ src/hb-cff-interp-common.hh     |  6 +++---
+ src/hb-cff-interp-cs-common.hh  |  4 ++--
+ src/hb-cff2-interp-cs.hh        |  2 +-
+ src/hb-directwrite.cc           |  2 +-
+ src/hb-ot-cff-common.hh         | 18 ++++++++----------
+ src/hb-ot-cff1-table.hh         | 26 +++++++++++++-------------
+ src/hb-ot-cff2-table.hh         |  6 +++---
+ src/hb-ot-layout.cc             |  2 +-
+ src/hb-ot-os2-unicode-ranges.hh |  3 +--
+ src/hb-subset-cff-common.cc     |  6 +++---
+ src/hb-subset-cff-common.hh     | 22 +++++++++++-----------
+ src/hb-subset-cff1.cc           | 28 ++++++++++++++--------------
+ src/hb-subset-cff2.cc           | 17 ++++++++---------
+ src/main.cc                     |  4 ++--
+ src/test-buffer-serialize.cc    |  2 +-
+ util/hb-subset.cc               |  4 ++--
+ util/options.cc                 | 10 ++++++----
+ 18 files changed, 86 insertions(+), 88 deletions(-)
+
+commit 0181f03019ec13031c179727eb2a38c478c05f5c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Apr 20 17:07:09 2020 +0430
+
+    [test] Workaround Windows pipe issue by storing ttx in a file
+
+ test/subset/run-tests.py | 40 +++++++++++++++++++++++++++++-----------
+ 1 file changed, 29 insertions(+), 11 deletions(-)
+
+commit 4cfb6cb9649fa58b606154e52bf7bb05d23f3f5b
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Apr 20 16:40:25 2020 +0430
+
+    [ci] Switch msys2 bot to meson
+
+ appveyor.yml | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+commit 2dda6dd744b192616c65ca4aa5fce8e90fd0ff30
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Apr 20 14:12:45 2020 +0430
+
+    minor, tweak spacing
+    
+    turn 8 spaces to tab, add space before Null/Crap
+
+ src/hb-aat-layout-ankr-table.hh            |   2 +-
+ src/hb-aat-layout-common.hh                |   6 +-
+ src/hb-aat-layout-morx-table.hh            |   6 +-
+ src/hb-aat-layout.cc                       |   2 +-
+ src/hb-aat-map.cc                          |  10 +--
+ src/hb-aat-map.hh                          |   4 +-
+ src/hb-blob.cc                             |   2 +-
+ src/hb-buffer.cc                           |   2 +-
+ src/hb-buffer.h                            |   2 +-
+ src/hb-buffer.hh                           |   4 +-
+ src/hb-cff-interp-common.hh                |   6 +-
+ src/hb-cff-interp-cs-common.hh             |   2 +-
+ src/hb-cff2-interp-cs.hh                   |   2 +-
+ src/hb-draw.hh                             |   2 +-
+ src/hb-face.cc                             |   2 +-
+ src/hb-font.cc                             |   2 +-
+ src/hb-font.hh                             |   2 +-
+ src/hb-machinery.hh                        |   2 +-
+ src/hb-map.cc                              |   2 +-
+ src/hb-map.hh                              |   4 +-
+ src/hb-null.hh                             |   8 +-
+ src/hb-open-file.hh                        |   4 +-
+ src/hb-ot-cff-common.hh                    |   4 +-
+ src/hb-ot-cff1-table.hh                    | 107 ++++++++++++------------
+ src/hb-ot-cff2-table.hh                    |  18 ++---
+ src/hb-ot-cmap-table.hh                    |  34 ++++----
+ src/hb-ot-color-cpal-table.hh              |   2 +-
+ src/hb-ot-glyf-table.hh                    |   4 +-
+ src/hb-ot-hmtx-table.hh                    |   2 +-
+ src/hb-ot-layout-common.hh                 | 126 ++++++++++++++---------------
+ src/hb-ot-layout-gdef-table.hh             |  10 +--
+ src/hb-ot-layout-gpos-table.hh             |  26 +++---
+ src/hb-ot-layout-gsubgpos.hh               |  70 ++++++++--------
+ src/hb-ot-layout.cc                        |  18 ++---
+ src/hb-ot-name-table.hh                    |   2 +-
+ src/hb-ot-shape-complex-arabic-fallback.hh |   4 +-
+ src/hb-ot-shape-complex-arabic.cc          |   2 +-
+ src/hb-ot-var-hvar-table.hh                |   4 +-
+ src/hb-set.cc                              |  62 +++++++-------
+ src/hb-set.hh                              |  24 +++---
+ src/hb-shape-plan.cc                       |   2 +-
+ src/hb-subset-cff-common.hh                |   2 +-
+ src/hb-subset-cff1.cc                      |  12 +--
+ src/hb-subset-cff2.cc                      |   6 +-
+ src/hb-subset.hh                           |   2 +-
+ src/hb-unicode.cc                          |   2 +-
+ src/hb-vector.hh                           |   6 +-
+ src/test-iter.cc                           |   2 +-
+ 48 files changed, 316 insertions(+), 315 deletions(-)
+
+commit ac26f19c9ea1ff170cd5226470115f7d08860e02
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Apr 19 22:25:14 2020 +0430
+
+    Refactor test/api/meson.build and always run test-unicode test
+
+ test/api/meson.build | 39 ++++++++++-----------------------------
+ 1 file changed, 10 insertions(+), 29 deletions(-)
+
+commit 0133cb55e2d76c81ccfeef3baf4c46e31297665c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Apr 19 22:42:57 2020 +0430
+
+    Minor, use hb_sorted_array::bsearch where possible
+
+ src/hb-aat-layout.cc            | 2 +-
+ src/hb-ot-cff1-table.cc         | 4 ++--
+ src/hb-ot-os2-unicode-ranges.hh | 7 +++----
+ 3 files changed, 6 insertions(+), 7 deletions(-)
+
+commit 1ed30515cb6308f1cf651cd502012ee5c8bd24ef
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Sun Apr 19 15:38:52 2020 +0100
+
+    [Docs, usernmanual] Fix with-icu=builtin explanation
+
+ docs/usermanual-integration.xml | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+commit d6edd9a4083f523b6290ba29c1fcbb5a6b7f96bb
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Sun Apr 19 15:26:28 2020 +0100
+
+    [Docs, usermanual] Reword hb_ft_font_create_referenced explanation
+
+ docs/usermanual-integration.xml | 29 +++++++++++++++++++----------
+ 1 file changed, 19 insertions(+), 10 deletions(-)
+
+commit fb3acdbcb645f30671db0776577652d7545d21ed
+Author: Christoph Reiter <reiter.christoph at gmail.com>
+Date:   Sun Apr 19 14:57:04 2020 +0200
+
+    meson: only install gobject/icu headers if the features are enabled
+
+ src/meson.build | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit ad5dcda0b5a7fe3acb09615c0ba020927cca5cee
+Author: Christoph Reiter <reiter.christoph at gmail.com>
+Date:   Sun Apr 19 14:53:05 2020 +0200
+
+    meson: install hb-icu.h header
+
+ src/meson.build | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 2cc85281c2cc4169b972e9c5d951ddfcded6ddde
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Apr 18 16:29:32 2020 -0700
+
+    [serializer] Make snapshot()/revert() revert current object links
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/2325
+
+ src/hb-serialize.hh | 38 +++++++++++++++++++++++++-------------
+ 1 file changed, 25 insertions(+), 13 deletions(-)
+
+commit 6f6e78a26ecdd874403b7fe397e335f386ac02e7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Apr 18 16:12:18 2020 -0700
+
+    Fix float-to-double warnings
+    
+    ./hb-ot-glyf-table.hh:978:37: warning: implicit conversion increases floating-point precision: 'float' to 'double' [-Wdouble-promotion]
+
+ src/hb-ot-glyf-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit c37100e7d9a1bcce35c9db651f404a1a87c8a1a1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Apr 18 16:02:55 2020 -0700
+
+    Clean up math.h and float.h includes
+
+ src/hb-cff-interp-dict-common.hh | 2 --
+ src/hb-number-parser.hh          | 2 --
+ src/hb-ot-glyf-table.hh          | 2 --
+ src/hb.hh                        | 1 +
+ 4 files changed, 1 insertion(+), 6 deletions(-)
+
+commit c6b3f73b098225728d36448e15499473ff9419b8
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Apr 19 00:54:24 2020 +0430
+
+    [meson] Make harfbuzz-icu separate module optout-able
+
+ meson.build          |  3 +++
+ meson_options.txt    |  2 ++
+ src/meson.build      | 13 ++++++++++---
+ test/api/meson.build |  2 +-
+ 4 files changed, 16 insertions(+), 4 deletions(-)
+
+commit 8ae06c9489f132844cbede80b5fe8241ce47fc0e
+Author: Christoph Reiter <reiter.christoph at gmail.com>
+Date:   Sat Apr 18 20:22:45 2020 +0200
+
+    meson: build a separate library for harfbuzz-icu
+    
+    This adds a seperate library like with autotools.
+    
+    This also fixes the ico feature option which was just set to required:false
+    when disabled instead of really disabling it.
+    Disabling is still broken with msvc because it then tries to find the library
+    another way, but that's broken for all other deps as well so I left it as is.
+    
+    For tests only test-unicode.c is using icu specific functions so split it out
+    into its own category which depends on harfbuzz-icu.
+    
+    Fixes #2338
+
+ meson.build          |  7 +++++--
+ src/meson.build      | 33 +++++++++++++++++++++++++++------
+ test/api/meson.build | 16 +++++++++++++++-
+ 3 files changed, 47 insertions(+), 9 deletions(-)
+
+commit 2354a90008043b0679e46c09165a9e53e47d39ab
+Author: Christoph Reiter <reiter.christoph at gmail.com>
+Date:   Sat Apr 18 20:28:25 2020 +0200
+
+    tests: fix subset/run-tests.py under Windows
+    
+    It assumed that stdout of a subprocess in binary mode was using
+    utf-8 which isn't the case. Instead open stdout of the subprocess
+    in text mode and let Python handle the decoding.
+
+ test/subset/run-tests.py | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit c1228990b9693226d8d14740414e4e93597f4a0f
+Author: Christoph Reiter <reiter.christoph at gmail.com>
+Date:   Sat Apr 18 15:29:56 2020 +0200
+
+    autotools: Add fix_get_types.py to EXTRA_DIST
+    
+    So it ends up in the release tarball and can be used in the meson build.
+    
+    Fixes #2337
+
+ src/Makefile.am | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit dced2fbee97a4f8af9572076306d3b2e6476640e
+Author: Christoph Reiter <reiter.christoph at gmail.com>
+Date:   Sat Apr 18 14:37:03 2020 +0200
+
+    meson: complete introspection build config
+    
+    Pass the same config to gobject-introspection as with cmake/autotools.
+    
+    This makes sure the c-include and package name is included in the gir
+    and also fixes the build because of the missing HB_AAT_H* defines.
+    
+    Fixes #2336
+
+ src/meson.build | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit 22f7c61acf8073cb8db8db47e92aef18864a85c6
+Author: ariza <ariza at adobe.com>
+Date:   Fri Apr 17 23:49:51 2020 -0700
+
+    implement SID to glyph ID mapping with predefined Charset
+    Also fixes oss-fuzz 21769
+
+ src/hb-ot-cff1-table.cc                            |  99 +++++++++++++++++++++
+ src/hb-ot-cff1-table.hh                            |  29 +++++-
+ test/api/test-ot-glyphname.c                       |  15 ++++
+ ...case-minimized-hb-shape-fuzzer-5769590820044800 | Bin 0 -> 87807 bytes
+ 4 files changed, 142 insertions(+), 1 deletion(-)
+
+commit f9bc373381ddf8553f943b774596ae5a53bf2641
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Apr 17 22:37:48 2020 +0430
+
+    2.6.5
+
+ NEWS             | 13 +++++++++++++
+ configure.ac     |  2 +-
+ meson.build      |  2 +-
+ src/hb-ft.cc     |  4 ++--
+ src/hb-version.h |  4 ++--
+ 5 files changed, 19 insertions(+), 6 deletions(-)
+
+commit a8455292f4fc44ffee5a4efae04cd94195696908
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Apr 17 22:50:48 2020 +0430
+
+    [layout] minor on doc
+
+ src/hb-ot-layout.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit fefaa8c835cf42f3ee5327a927aac62a10165019
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Apr 17 22:28:09 2020 +0430
+
+    [test] define G_APPROX_VALUE and EPSILON only when used
+    
+    resolves -Weverything bot complain
+
+ test/api/test-var-coords.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 29c903223b31c30ad609a23c75a98231674c3a73
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Apr 17 22:11:40 2020 +0430
+
+    Move hb_ot_layout_closure_{features,lookups} behind EXPERIMENTAL flag
+
+ src/gen-def.py                    |  4 +++-
+ src/hb-ot-layout.cc               |  2 ++
+ src/hb-ot-layout.h                |  2 ++
+ src/hb-subset-plan.cc             |  6 ++++++
+ test/api/test-ot-face.c           |  4 ++++
+ test/api/test-subset-gpos.c       |  4 ++++
+ test/subset/data/Makefile.sources | 13 ++++++++-----
+ test/subset/meson.build           | 18 +++++++++---------
+ 8 files changed, 38 insertions(+), 15 deletions(-)
+
+commit 9b7fb5c23fb7b333e0e81b8c82160aac4a21b27e
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Apr 17 20:12:24 2020 +0430
+
+    Move hb_font_get_var_coords_design behind HB_EXPERIMENTAL_API
+
+ src/gen-def.py             | 3 ++-
+ src/hb-font.cc             | 4 +++-
+ src/hb-font.h              | 2 ++
+ test/api/test-var-coords.c | 2 ++
+ 4 files changed, 9 insertions(+), 2 deletions(-)
+
+commit 41c671e701e13bdd4a196030b74172fe1c6b7ccf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Apr 17 08:37:25 2020 -0700
+
+    [build] Adjust check-symbols for -flto
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/2328
+
+ src/check-symbols.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e7d5fa4a5891a4fb4c4a5d8ba0a05540c4358a33
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Fri Apr 17 15:54:40 2020 +0100
+
+    [Usermanual, utilities] - correct DocBook tags
+    
+    Changes stray <program> DocBook tags on this page to <command>. No instances found in the other docs.
+
+ docs/usermanual-utilities.xml | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+commit 8f6d0f8401ffd011332981fd9ba6d38d18b6cf3b
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Apr 17 11:30:27 2020 +0430
+
+    [os2] minor, fix font_page_t enum naming
+    
+    As https://github.com/harfbuzz/harfbuzz/pull/986#pullrequestreview-395052800
+
+ src/hb-ot-os2-table.hh | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+commit 818f109bdec9659c05f9fd9a1de1db85ece65cbe
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Apr 16 21:25:32 2020 +0430
+
+    Use float in avar calculation instead ints and checking their overflows
+
+ src/hb-algs.hh              | 12 ------------
+ src/hb-ot-var-avar-table.hh |  9 ++-------
+ src/hb.hh                   |  4 ----
+ 3 files changed, 2 insertions(+), 23 deletions(-)
+
+commit 9ffa50fe5dfeb7e999a178e031d7092121e0c146
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Apr 16 21:25:32 2020 +0430
+
+    Add an appropriate fallback to hb_int_mul_overflows
+
+ src/hb-algs.hh              | 15 ++++++++-------
+ src/hb-ot-var-avar-table.hh |  6 +++---
+ src/hb.hh                   |  4 ++++
+ 3 files changed, 15 insertions(+), 10 deletions(-)
+
+commit 32f431406e602e977bde17e335a4ad086064494e
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Apr 16 22:07:07 2020 +0430
+
+    [docs] minor
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/2321
+
+ docs/usermanual-buffers-language-script-and-direction.xml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a5e5a79004c5ebdef52ab282c7772ab0d9cf354b
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Apr 16 01:38:43 2020 +0430
+
+    [tests] Enable the just added macOS test for older version
+    
+    The test is added in 7035c9cd but the same font is available in older versions of macOS
+    so let's run it in older versions also.
+    
+    It doesn't matter much, more for consistency reasons.
+
+ test/shaping/data/in-house/tests/macos.tests | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 7035c9cdfe38dd6654bd9b71e3bb5cbf49e4014d
+Author: Jonathan Kew <jfkthame at gmail.com>
+Date:   Fri Apr 3 19:00:42 2020 +0100
+
+    Add test for #2290.
+    
+    This tests that we can set two separate Type=Ligature selectors at the same time,
+    common=off + discretionary=on.
+
+ test/shaping/data/in-house/tests/macos.tests | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 573b6bf82692c5fdd54d55a512405f7f75556362
+Author: Jonathan Kew <jfkthame at gmail.com>
+Date:   Mon Mar 30 23:20:30 2020 +0100
+
+    Handle non-exclusive features when mapping OpenType tags to AAT feature type/selector pairs.
+    
+    Fixes #2290.
+
+ src/hb-aat-layout-feat-table.hh |  2 ++
+ src/hb-aat-layout-morx-table.hh |  6 ++++--
+ src/hb-aat-map.cc               | 15 ++++++++++++---
+ src/hb-aat-map.hh               | 13 +++++++++----
+ 4 files changed, 27 insertions(+), 9 deletions(-)
+
+commit b57b9042420538f998cc0941407be8059b6e7562
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Wed Apr 15 18:46:31 2020 +0100
+
+    Add detail to hb_ft_font_create inline comments
+    
+    Providing lengthier explanation for how the destroy function works on the hb_font_t but that destroying the FT_Face (and not destroying it too early) remains the client's responsibility.
+
+ src/hb-ft.cc | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 1bca2be256ce1c2c4d74efac2286db80dbfa5c48
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Wed Apr 15 18:30:47 2020 +0100
+
+    Rewrite hb_ft_font_set_funcs inline explanation
+
+ src/hb-ft.cc | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+commit 80c01d768734faafe5701414bd63c63cd243a404
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Wed Apr 15 18:08:55 2020 +0100
+
+    Update hb-ft.cc
+
+ src/hb-ft.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 9457b60edc6f3c7b3b4ccf7460d4569c072bc98e
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Mon Apr 13 17:01:15 2020 +0100
+
+    Update usermanual-integration.xml
+
+ docs/usermanual-integration.xml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 05b7bdb4dd57d1bf233379e0f4ae5ec6451113d7
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Mon Apr 13 16:59:41 2020 +0100
+
+    Update usermanual-integration.xml
+
+ docs/usermanual-integration.xml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f782d736cefa7808ef31712bcc6a51cfa2d02826
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Mon Apr 13 16:57:36 2020 +0100
+
+    Update usermanual-integration.xml
+
+ docs/usermanual-integration.xml | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 17b60efc38fbc32953424fa9a21daf3738ff8935
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Mon Apr 13 16:51:58 2020 +0100
+
+    Update docs/usermanual-integration.xml
+    
+    Co-Authored-By: Khaled Hosny <dr.khaled.hosny at gmail.com>
+
+ docs/usermanual-integration.xml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9b91669cb4e92281f155e4b1b1cef26ba562e786
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Mon Apr 13 16:40:15 2020 +0100
+
+    Update hb-ft.cc
+
+ src/hb-ft.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3a47921e88ad20873e08e19dff22205ecdf48f98
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Mon Apr 13 15:42:00 2020 +0100
+
+    Update usermanual-integration.xml
+
+ docs/usermanual-integration.xml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a29578c17a10f409db651ed55f20ca3eb20953ae
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Mon Apr 13 15:30:18 2020 +0100
+
+    Update usermanual-integration.xml
+
+ docs/usermanual-integration.xml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c241e82f00dad423bf1d15cc8e365224fb7a8575
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Mon Apr 13 15:28:42 2020 +0100
+
+    Update docs/usermanual-integration.xml
+    
+    Co-Authored-By: Khaled Hosny <dr.khaled.hosny at gmail.com>
+
+ docs/usermanual-integration.xml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit fd59cc700ade05fa86b89d10cf07eef7f57c9973
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Mon Apr 13 15:15:00 2020 +0100
+
+    Update src/hb-glib.cc
+    
+    Co-Authored-By: Khaled Hosny <dr.khaled.hosny at gmail.com>
+
+ src/hb-glib.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit fb9d106797f4ae458717dd9e9d0b2c9eca4b89c2
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Mon Apr 13 15:14:42 2020 +0100
+
+    Update src/hb-graphite2.cc
+    
+    Co-Authored-By: Khaled Hosny <dr.khaled.hosny at gmail.com>
+
+ src/hb-graphite2.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a199eab20eca8710e58fab845b8c330aada797a3
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Mon Apr 13 15:14:28 2020 +0100
+
+    Update src/hb-graphite2.cc
+    
+    Co-Authored-By: Khaled Hosny <dr.khaled.hosny at gmail.com>
+
+ src/hb-graphite2.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit aff21795b2da558e8f595706e7a46f11b891f8be
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Mon Apr 13 15:14:06 2020 +0100
+
+    Update src/hb-icu.cc
+    
+    Co-Authored-By: Khaled Hosny <dr.khaled.hosny at gmail.com>
+
+ src/hb-icu.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ccc235698394aab2cea69bd2e00a0caa766d577b
+Author: n8willis <n8willis at users.noreply.github.com>
+Date:   Mon Apr 13 15:13:56 2020 +0100
+
+    Update src/hb-graphite2.h
+    
+    Co-Authored-By: Khaled Hosny <dr.khaled.hosny at gmail.com>
+
+ src/hb-graphite2.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0d5695983e8bf3184ecd4cb92f737b9dfe5d6d25
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Sun Apr 5 18:44:26 2020 -0700
+
+    [subset] fixes dangling object_t issue in FeatureVariationRecord
+    Fixes https://crbug.com/oss-fuzz/21560
+    revert () does not clean up useless object_t. Adjust the order of
+    subsetting substitutions and conditions to avoid dangling object_t.
+
+ src/hb-ot-layout-common.hh                                |   9 +++++----
+ ...z-testcase-minimized-hb-subset-fuzzer-5759725666041856 | Bin 0 -> 114 bytes
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+commit 57b7de032f60d0499ae2debb293d0f8456acfdfb
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Apr 5 17:07:48 2020 +0430
+
+    [subset] Fail ClassDefFormat1 serialization if no space available
+    
+    Fixes https://crbug.com/oss-fuzz/21580
+
+ src/hb-ot-layout-common.hh                               |   2 +-
+ ...-testcase-minimized-hb-subset-fuzzer-5704307501694976 | Bin 0 -> 1062 bytes
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+
+commit c8cc1e378df500122d8082a2038d68179eec63d0
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Apr 2 16:57:01 2020 -0700
+
+    fix issues in ClassDefFormat1 serialize:
+    glyph ids in Iterator may be non-consecutive,
+    so the number in classValue might be larger than length of the Iterator
+
+ src/hb-ot-layout-common.hh                          |  20 +++++++++++++++-----
+ src/hb-ot-layout-gpos-table.hh                      |   2 +-
+ ...f => Roboto-Regular.keep-gdef-gpos.1E00,303.ttf} | Bin 2520 -> 2648 bytes
+ ...03.ttf => Roboto-Regular.keep-gdef-gpos.303.ttf} | Bin 2192 -> 2240 bytes
+ ...=> Roboto-Regular.keep-gdef-gpos.309,20,30F.ttf} | Bin 2288 -> 2336 bytes
+ ...23.ttf => Roboto-Regular.keep-gdef-gpos.323.ttf} | Bin 2084 -> 2132 bytes
+ ...f => Roboto-Regular.keep-gdef-gpos.41,42,43.ttf} | Bin 2536 -> 2736 bytes
+ test/subset/data/profiles/keep-gdef-gpos.txt        |   1 +
+ test/subset/data/tests/layout.gdef.tests            |   2 +-
+ 9 files changed, 18 insertions(+), 7 deletions(-)
+
+commit 4a49b36a9e244e176a8e6d9ae9d6caadabfbcc6c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Apr 3 19:36:48 2020 +0430
+
+    [tests/macos] Adopt added Apple Chancery tests with older macos versions
+
+ test/shaping/data/in-house/tests/macos.tests | 30 ++++++++++++++++++++++------
+ 1 file changed, 24 insertions(+), 6 deletions(-)
+
+commit 75cae46dc2702e4edd32a92fe59300172931ed9f
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Apr 3 20:04:16 2020 +0430
+
+    [aat] minor spacing
+
+ src/hb-aat-map.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 37377763842c80bf261d7bc0b3502cd5213244a4
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Apr 3 20:03:20 2020 +0430
+
+    [aat] add the bug link, minor
+
+ src/hb-aat-map.cc | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 548a25259e183f95713c0fdf0ad8c9450af73252
+Author: Jonathan Kew <jfkthame at gmail.com>
+Date:   Fri Apr 3 16:18:20 2020 +0100
+
+    Add a test for #2307.
+
+ test/shaping/data/in-house/tests/macos.tests | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 1faf0caae165f680689610b20c467b9308275308
+Author: Jonathan Kew <jfkthame at gmail.com>
+Date:   Fri Apr 3 16:10:34 2020 +0100
+
+    Special-case 'smcp' when checking for exposed AAT features.
+    
+    This may be implemented by selectors under either LETTER_CASE or LOWER_CASE feature types
+    in AAT, so we need to check for the presence of either one.
+    
+    Fixes #2307.
+
+ src/hb-aat-map.cc | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+commit 120d86fa189ca4f3dbb8502e92f7ac63f66d0037
+Author: Jonathan Kew <jfkthame at gmail.com>
+Date:   Fri Apr 3 15:10:14 2020 +0100
+
+    Add tests for #2305.
+
+ test/shaping/data/in-house/tests/macos.tests | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit b87cf6e8d44aa60e162a68225394386cecb0e690
+Author: Jonathan Kew <jfkthame at gmail.com>
+Date:   Fri Apr 3 15:02:07 2020 +0100
+
+    Fix sense of comparsion in hb_aat_map_builder_t::feature_info_t.
+    
+    This makes bsearch actually work for the features array.
+    
+    Fixes #2305.
+
+ src/hb-aat-map.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b027cb518dc7e6ac7e41e617364476e3c7839792
+Author: Jonathan Kew <jfkthame at gmail.com>
+Date:   Mon Mar 30 18:47:22 2020 +0100
+
+    Set sequence number when adding feature to aat map builder, to support stable sort.
+    
+    Fixes #2288.
+
+ src/hb-aat-map.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit e0e77270641fb932552b36bbb35813fbc5cfac1e
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Apr 3 01:12:16 2020 +0430
+
+    [ci] Update macOS 10.15's version
+
+ .circleci/config.yml | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 89fa70f511a62fedc46e68f692b6f19e119d647e
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Apr 3 00:05:40 2020 +0430
+
+    [aat] minor over previous feat related changes
+
+ src/hb-aat-layout-feat-table.hh              |  2 +-
+ src/hb-aat-map.cc                            | 12 +++++-------
+ test/shaping/data/in-house/tests/macos.tests | 14 ++++++++++++--
+ 3 files changed, 18 insertions(+), 10 deletions(-)
+
+commit 58b4d18b53a530b1bbc2fea2c3123754b9be4868
+Author: Jonathan Kew <jfkthame at gmail.com>
+Date:   Thu Apr 2 17:54:09 2020 +0100
+
+    Add a couple testcases for issue 2285.
+    
+    A few simple testcases to confirm that setting liga=0 does not break shaping with
+    the Tibetan AAT font Kokonor, but does still disable common ligatures in Times.
+
+ test/shaping/data/in-house/tests/macos.tests | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit b1c0b9da2ff105d3476fed411e1d7010decb394e
+Author: Jonathan Kew <jfkthame at gmail.com>
+Date:   Thu Apr 2 14:39:13 2020 +0100
+
+    [AAT] Don't map OT tags to AAT feature types that are not exposed.
+    
+    If an AAT feature type is not exposed in the 'feat' table, we assume it is not intended
+    to be user-controllable and so we should not map any OT feature tag requests to it.
+    
+    Fixes #2285.
+
+ src/hb-aat-layout-feat-table.hh | 6 ++++++
+ src/hb-aat-map.cc               | 7 +++++++
+ 2 files changed, 13 insertions(+)
+
+commit e0c3979af1c84f82b8879c710a07f027fe32f564
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Apr 1 16:49:53 2020 -0700
+
+    typo fix
+
+ src/hb-ot-layout-common.hh   | 2 +-
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 65f413630366ded4867522ca9ffa0d7e936380ac
+Author: ariza <ariza at adobe.com>
+Date:   Wed Apr 1 19:49:18 2020 -0700
+
+    minor; fixes #2292
+
+ src/hb-serialize.hh | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+commit 014e038b2c2fd55e0bffbe5c5adc893c07df187a
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Mar 31 16:29:29 2020 -0700
+
+    [subset] Bail out of context lookup expansion once the lookup limit is encountered.
+
+ src/hb-ot-layout-gsubgpos.hh                           |   8 ++++++++
+ ...testcase-minimized-hb-shape-fuzzer-5158673602314240 | Bin 0 -> 881650 bytes
+ 2 files changed, 8 insertions(+)
+
+commit 5d345d0cd169dcc8c0205918a6e064f03e4bc07a
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Mar 31 17:46:19 2020 -0700
+
+    [subset] Limit the number of lookup indices processed subsetting Feature.
+    > Also, remove two unnessecary full iterations of the lookup index iterator during serialization of the index array. Fixes fuzzer found timeout.
+
+ src/hb-ot-layout-common.hh                         |  25 +++++++++++++++------
+ ...ase-minimized-hb-subset-fuzzer-5719588814979072 | Bin 0 -> 1048576 bytes
+ 2 files changed, 18 insertions(+), 7 deletions(-)
+
+commit 1b64b73080994ac577a6d936a0109b3c6f5d21de
+Author: Khaled Hosny <khaledhosny at eglug.org>
+Date:   Mon Mar 30 16:49:23 2020 +0200
+
+    Revert "Add messages for GPOS/GSUB phases"
+    
+    This reverts commit b07714d6b53bb20a2796f5efa607dc32aac587f1.
+
+ src/hb-ot-layout.cc | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit 2e1bf61dd5afcef71957b349254b80e7cfd14e45
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Mar 26 22:59:26 2020 +0430
+
+    [gsubgpos] Use FeatureVariations::NOT_FOUND_INDEX instead Index::
+    
+    As noted by https://github.com/harfbuzz/harfbuzz/issues/2280#issuecomment-604386389
+    
+    Added on b143e34, fixed on 2571891
+    
+    Closes #2280
+
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 96d792ae80c448715ef317c9f69eb30dc3d34a10
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 24 14:05:47 2020 +0430
+
+    [avar] Prevent mul overflow
+    
+    Fixes https://crbug.com/oss-fuzz/21350
+
+ src/hb-algs.hh                                     |  29 ++++++++++++++++-----
+ src/hb-ot-var-avar-table.hh                        |  10 ++++---
+ ...tcase-minimized-hb-draw-fuzzer-5712313459146752 | Bin 0 -> 146696 bytes
+ 3 files changed, 30 insertions(+), 9 deletions(-)
+
+commit 18fc9197e23460f2599670b65548d07a522d5a73
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Mar 26 13:34:28 2020 +0430
+
+    [meson] Run check-symbols.sh and check-static-inits.sh correctly
+    
+    * Search src/ build directory for objects in check-static-inits.sh
+    * Find .def files in src/ build directory in src/check-symbols.sh
+    * Pass builddir also in autotools also, we may just remove libs passing after autotools removal
+    * Move harfbuzz_subset_def target so can be referenced as a check-static-inits.sh dependency
+
+ src/Makefile.am           |  1 +
+ src/check-static-inits.sh | 13 ++++++++--
+ src/check-symbols.sh      |  7 +++---
+ src/meson.build           | 63 +++++++++++++++++++++++++----------------------
+ 4 files changed, 50 insertions(+), 34 deletions(-)
+
+commit 9c2c9553eb85b272c2838f5fc60301aafe361549
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Mar 26 13:24:38 2020 +0430
+
+    [test] Check -subset also doesn't link to lib[std]c++
+
+ src/check-libstdc++.sh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 25718913d4263ed709bd7142a107e128c9f91d4c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Mar 26 14:04:37 2020 +0430
+
+    [gsubgpos] minor build fix
+
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b143e34ee1bb56d104e33b78abff70302a93d3d0
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Mar 26 11:58:45 2020 +0430
+
+    [gsubgpos] Initialize variation index on HB_NO_VAR
+    
+    hb_shape_plan_key_t::equal expects hb_ot_shape_plan_key_t be initialized by
+    hb_ot_layout_table_find_feature_variations calls but it won't get initialized
+    when HB_NO_VAR build config is used.
+    
+    Related to https://github.com/harfbuzz/harfbuzz/issues/2280
+
+ src/hb-ot-layout-gsubgpos.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 071e2e345fb0a78d13462744dca9b1a8b15e78cb
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Mar 26 12:01:53 2020 +0430
+
+    minor
+
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ src/hb-ot-shape.hh           | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit cc977b6e5c263803abc47f52538b530458f08f16
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Mar 26 11:18:02 2020 +0430
+
+    [gsubgpos] Minor simplification
+    
+    Just changed the order, no functional change
+
+ src/hb-ot-layout-gsubgpos.hh | 23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+commit 1a48278511c396799693f23dde98c82b44a5f7d3
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Mar 26 11:15:09 2020 +0430
+
+    [gsubgpos] Minor style improve
+
+ src/hb-ot-layout-gsubgpos.hh | 24 ++++++------------------
+ 1 file changed, 6 insertions(+), 18 deletions(-)
+
+commit 4ad686b9c0460bdc88663b882e5039b808bf8cce
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Mar 25 23:32:28 2020 -0700
+
+    [subset] fix fuzzer timeout in layout closure
+    
+    Bail out of chain context lookup expansion once the lookup limit is encountered.
+
+ src/hb-ot-layout-gsubgpos.hh                       |  26 +++++++++++++++++++++
+ ...ase-minimized-hb-subset-fuzzer-5713850117914624 | Bin 0 -> 1048576 bytes
+ 2 files changed, 26 insertions(+)
+
+commit f0ce56bbd031a8b922e9695670c09c8a385c657f
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 24 22:53:38 2020 +0430
+
+    [meson] Don't compile test-bimap on msvc either
+    
+    MSVC doens't like its NullPool,
+    
+    test-bimap.cc.obj : error LNK2019: unresolved external symbol "unsigned __int64 const * const _hb_NullPool" (?_hb_NullPool@@3QB_KB) referenced in function
+
+ src/meson.build | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 22f311e100bf18728f3d697b724e643a4a5c917e
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 24 22:43:02 2020 +0430
+
+    [meson] Don't compile noinst_programs in msvc for now
+
+ src/meson.build | 40 ++++++++++++++++++++++------------------
+ 1 file changed, 22 insertions(+), 18 deletions(-)
+
+commit 7054b122068f14fda3442c1a3d2c05562ef8453d
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 24 22:35:41 2020 +0430
+
+    [meson] Mark rest of non-install executables explicitly
+
+ src/meson.build          | 12 ++++++------
+ test/api/meson.build     |  2 ++
+ test/fuzzing/meson.build |  1 +
+ 3 files changed, 9 insertions(+), 6 deletions(-)
+
+commit 68df3f7dacfa85d61fa7c059a13a09925b613484
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 24 20:58:38 2020 +0430
+
+    [meson] test/api, separate subset tests
+
+ test/api/meson.build | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+commit 600bf21fbc9076e1a7c276b41a7fcd610dae8adc
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 24 20:08:40 2020 +0430
+
+    [meson] Add draw-fuzzer runner
+
+ test/fuzzing/meson.build | 22 ++++++++++++++--------
+ 1 file changed, 14 insertions(+), 8 deletions(-)
+
+commit 466dbaa2583c9570016208655951b0b2466ac6c7
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 24 19:52:43 2020 +0430
+
+    [meson] Add a note on meson stability status
+
+ meson.build | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 28deb6b718997976a519e66e9aa8c15d8f117217
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 24 19:41:53 2020 +0430
+
+    [meson] test/fuzzing simplify
+
+ test/fuzzing/meson.build | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+commit 78622231ac6da55bf86e598a7bca9e50471c03ab
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 24 19:39:42 2020 +0430
+
+    [meson] More comment on tests are causing timeout failure
+
+ test/fuzzing/meson.build | 3 ++-
+ test/subset/meson.build  | 5 +++--
+ 2 files changed, 5 insertions(+), 3 deletions(-)
+
+commit 9bc792f416dddd4aabb99780c632010d97054f5d
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 24 19:37:56 2020 +0430
+
+    [meson] Don't set MALLOC_PERTURB_ as it is already set by meson
+
+ test/api/meson.build | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+commit e8808c1c203c306f7b7667f9a0f32422c9f7abbb
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 24 19:15:09 2020 +0430
+
+    [meson] Minor, replace tabs with spaces
+
+ .editorconfig            |  1 +
+ meson.build              |  4 ++--
+ src/meson.build          | 32 ++++++++++++++++----------------
+ test/shaping/meson.build | 16 ++++++++--------
+ 4 files changed, 27 insertions(+), 26 deletions(-)
+
+commit 4dfda9feaa431c2ab19d87cb177cc2502f5f0c21
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 24 19:33:31 2020 +0430
+
+    [meson] Update and simplify test/shaping
+
+ test/shaping/meson.build | 538 +++++++++++++++++++++++------------------------
+ 1 file changed, 268 insertions(+), 270 deletions(-)
+
+commit f22e92bb300775c1d494c841c6fb26b0bbc96668
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 24 19:32:55 2020 +0430
+
+    [meson] Update test/api from autotools
+
+ test/api/meson.build | 118 ++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 70 insertions(+), 48 deletions(-)
+
+commit e248a4e46c5c94b6de349d0fd0e1765b29acad99
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 24 18:56:49 2020 +0430
+
+    [make] Minor reordering on test/api/Makefile.am
+
+ test/api/Makefile.am | 30 +++++++++++-------------------
+ 1 file changed, 11 insertions(+), 19 deletions(-)
+
+commit 2db8279162be7ac184ccf99982fad2aeeb0d7540
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 24 18:55:56 2020 +0430
+
+    [meson] Don't compile test-{algs,iter,meta} on msvc
+
+ src/meson.build | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+commit 3385afacd3daabc98e69d1880dad558faa932842
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 24 18:55:01 2020 +0430
+
+    [meson] Don't run check-includes if is amalgam build
+
+ src/meson.build | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 6a8a1dc5bb67e2acd3fb3e8aae4cb558e3b093f7
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 24 16:04:33 2020 +0430
+
+    [meson] Port src/ binary artifacts to meson
+
+ src/meson.build | 416 +++++++++++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 306 insertions(+), 110 deletions(-)
+
+commit d57fc627e9923579aed3d451c8f3b15520805fc1
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 24 16:03:04 2020 +0430
+
+    [meson] raise timeout value of subset fuzzer
+
+ test/fuzzing/meson.build | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 4738dff18e7644306c3526b8cc9429fda6d6db0d
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Mar 23 23:37:49 2020 +0430
+
+    [make] minor move on Makefile.am
+
+ src/Makefile.am | 40 ++++++++++++++++++++--------------------
+ 1 file changed, 20 insertions(+), 20 deletions(-)
+
+commit b07714d6b53bb20a2796f5efa607dc32aac587f1
+Author: Simon Cozens <simon at simon-cozens.org>
+Date:   Sat Mar 14 17:55:27 2020 +0000
+
+    Add messages for GPOS/GSUB phases
+
+ src/hb-ot-layout.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 748e1cf8980e8c54b61ec86599f94450e98ad47a
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Mar 21 23:31:52 2020 +0430
+
+    [subset] Avoid linking to libstdc++ in libharfbuzz-subset.so
+    
+    Just like other targets (except harfbuzz-icu) avoid linking to libstdc++
+
+ src/Makefile.am | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 761695264b309693346dd027d38e6bc53056c3ab
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Mar 19 11:43:37 2020 +0330
+
+    [tests] Remove py2 workaround for lack of timeout in subprocess
+
+ test/fuzzing/run-draw-fuzzer-tests.py   | 28 ++++++----------------------
+ test/fuzzing/run-shape-fuzzer-tests.py  | 28 ++++++----------------------
+ test/fuzzing/run-subset-fuzzer-tests.py | 32 ++++++++------------------------
+ 3 files changed, 20 insertions(+), 68 deletions(-)
+
+commit b5526a09ff89780de4584ff422127cb962b138f3
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Mar 18 23:58:20 2020 +0330
+
+    [tools] Remove in-house 'which' now that we have py3
+
+ test/fuzzing/run-draw-fuzzer-tests.py   | 22 ++--------------------
+ test/fuzzing/run-shape-fuzzer-tests.py  | 22 ++--------------------
+ test/fuzzing/run-subset-fuzzer-tests.py | 22 ++--------------------
+ test/subset/run-tests.py                | 22 +++-------------------
+ 4 files changed, 9 insertions(+), 79 deletions(-)
+
+commit a0c58be371f67aa03335f40b98aa7073f1968cab
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Mar 18 23:40:59 2020 +0330
+
+    [tools] Remove py2 remains
+
+ src/gen-os2-unicode-ranges.py | 5 -----
+ src/gen-use-table.py          | 7 +------
+ test/shaping/hb_test_tools.py | 4 ----
+ 3 files changed, 1 insertion(+), 15 deletions(-)
+
+commit 2e29a4077b48e11d5c33a0d054dafcd17749ff07
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Mar 14 16:34:36 2020 +0330
+
+    [ci/appveyor] Adopt with Meson
+
+ appveyor.yml | 59 +++++++++++++----------------------------------------------
+ 1 file changed, 13 insertions(+), 46 deletions(-)
+
+commit 03564fd2cfa752c28a3f306994cfc8865d208cfd
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Mar 14 20:09:00 2020 +0330
+
+    [test] fix misspell
+
+ test/shaping/run-tests.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1b8a37f75f44bf6cd20250c0dcfc1c0a70879aa5
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Mar 14 20:06:41 2020 +0330
+
+    [test] minor fix
+    
+    oops...
+
+ test/shaping/run-tests.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0423da33732cda737354f52b37053809a80571b1
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Mar 14 20:05:23 2020 +0330
+
+    [test] minor fix
+    
+    macos tests are using absolute path which aren't relevant in Windows
+
+ test/shaping/run-tests.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 74fdd34f4d1912b506b2e640f52b3606dad4a3aa
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Mar 14 20:03:14 2020 +0330
+
+    [test] make run-tests.py work on Windows
+
+ test/shaping/run-tests.py | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 93b3e30215599fad6ec40351e5eef0a91e2ae031
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Sat Mar 14 11:27:50 2020 +0000
+
+    [meson] fix icu-related linking errors in test with amalgam build
+    
+    test-unicode.c:960: undefined reference to `hb_icu_get_unicode_funcs'
+    test-unicode.c:961: undefined reference to `hb_icu_get_unicode_funcs'
+    
+    For now add the icu sources to libharfbuzz also for the amalgam
+    build, later we need to have a separate harfbuzz-icu module and
+    link against that, and/or generate harfbuzz.cc.
+
+ src/meson.build | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+commit a3892be70108adb0cbafcff9bf4c2ebc0f65acb0
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Sat Mar 14 01:08:15 2020 +0000
+
+    [meson] fix spurious warning when building test/api C sources
+    
+    Fixes compiler warning
+    
+      test-unicode.c:589:1: warning: ‘test_unicode_properties_lenient’ defined but not used
+    
+    which didn't happen with autotools.
+    
+    Reason it does with meson is that the setup for C was slightly wrong.
+    We would only add -DHAVE_CONFIG_H to cpp_args which is only valid when
+    compiling C++ code, but not plain C code, and many of these tests were
+    plain C.
+    
+    Instead pass -DHAVE_CONFIG_H via add_project_arguments() and make sure
+    to set both c_args and cpp_args when building test executables.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/2257
+
+ meson.build          | 5 +++--
+ test/api/meson.build | 3 +--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit bb8aaa310887aa6b4a5ec2bfa9ee0330f1619c75
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Sat Mar 14 01:05:38 2020 +0000
+
+    [meson] use add_project_arguments() instead of add_global_arguments()
+    
+    .. and simplify, can pass two languages in one go.
+    
+    add_global_arguments() won't work if harfbuzz is used as a
+    meson subproject.
+
+ meson.build | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+commit 2f556c38c08d6d19bed115cc5ab5e0e369d9b4d0
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Mar 13 12:21:10 2020 -0700
+
+    [subset] Fix crash when serializer runs out of room during gpos subsetting.
+
+ src/hb-ot-layout-gpos-table.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 430bf696537a4cf19e3ad371c4485f9580b4433b
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Mar 13 11:20:34 2020 -0700
+
+    Add potentially crashing font as a fuzzer seed.
+
+ test/fuzzing/fonts/kanit.ttf | Bin 0 -> 160304 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit c54ab9ba791efe5492dac89c64ac449de308eb6f
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Mar 13 14:41:28 2020 +0330
+
+    Provide meson wrap files on release tarball
+
+ Makefile.am | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit f1dd605cd9023b697c319b6640fdc25f78ef7e8c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Mar 13 14:40:07 2020 +0330
+
+    [docs] Update to mention meson
+
+ BUILD.md   | 7 ++-----
+ CONFIG.md  | 2 +-
+ TESTING.md | 5 ++---
+ 3 files changed, 5 insertions(+), 9 deletions(-)
+
+commit 838346c54a332cc7acafea676b4272ab8419c9e8
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Fri Mar 13 18:01:17 2020 +0800
+
+    meson: Support GDI integration
+    
+    ...and supersede the configuration option uniscribe with gdi, as Uniscribe is
+    tightly tied to GDI.  This means that enabling GDI would also mean enabling
+    Uniscribe.
+
+ meson.build       | 9 +++++----
+ meson_options.txt | 4 ++--
+ src/meson.build   | 5 +++++
+ 3 files changed, 12 insertions(+), 6 deletions(-)
+
+commit 9d0e6aef8abe12270df161d7535d6bc741cf4c31
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Fri Mar 13 16:56:55 2020 +0800
+
+    Meson: Look harder for Cairo on Visual Studio
+    
+    Since Cairo's build system for Visual Studio does not generate pkg-config files
+    for us, look for cairo.h and cairo.lib manually if the pkg-config files cannot
+    be found.
+    
+    Also look for cairo-ft more carefully: ensure that we have cairo-ft.h, and one
+    of its symbols can be found in the same cairo.lib that we previously found.
+
+ meson.build | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+commit 5efce600ab3a8e4e7f429f5d683595c33d6cbe45
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Fri Mar 13 16:40:20 2020 +0800
+
+    Meson: Try harder to look for ICU on Visual Studio
+    
+    ICU's Visual Studio build files do not generate pkg-config files for us, unless
+    it is built with Cygwin instead of the project files.  If pkg-config files for
+    ICU cannot be found, look for its headers and .lib manually.
+
+ meson.build | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+commit 7baa8e0dbe816769f1ceeffdc2e72af7797e5df9
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Fri Mar 13 16:21:25 2020 +0800
+
+    meson: Updates to Uniscribe and DirectWrite build support
+    
+    Update the DirectWrite support to look for dwrite_1.h, and give the green light
+    for both the DirectWrite and Uniscribe build options.
+
+ meson.build | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 733414b286b544b54c48e72ba8ae78d5584c157d
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Fri Mar 13 16:15:21 2020 +0800
+
+    meson: Try harder to find FreeType on Visual Studio
+    
+    If we can't find FreeType via pkg-config or CMake, try looking for it manually,
+    before we attempt to build it as a fallback.
+
+ meson.build | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+commit 4b4d5c295d584809e0281b27687757e895e7edfc
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Fri Mar 13 16:00:09 2020 +0800
+
+    src/meson.build: Some cleanups for Visual Studio builds
+    
+    We don't actually need the .def files (vs_module_defs) entry when we are
+    building DLLs with Visual Studio as long as we have HB_DLL_EXPORT defined.
+    
+    Plus, to maintain compatibility with the CMake builds, for Visual Studio builds
+    we do not prefix the libraries with 'lib', nor have a '-0' suffix for the DLL
+    file name.
+
+ src/meson.build | 26 +++++++++++++++-----------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+commit da95a8c239bda7020716cc8c7ba34c380f68ffc3
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Fri Mar 13 15:49:08 2020 +0800
+
+    Shaping tests: Skip FreeType tests if support not present
+    
+    HarfBuzz could have been built without FreeType, so we skip the test
+    when hb-shape reports that the font function `ft' is unknown
+
+ test/shaping/run-tests.py | 40 +++++++++++++++++++++++++++-------------
+ 1 file changed, 27 insertions(+), 13 deletions(-)
+
+commit 91ca17e1fd8145e863a5df27092ddd20aa2599f5
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Fri Mar 13 12:19:32 2020 +0800
+
+    src/hb-gobject-enums.cc.tmpl: Replace © with (C)
+    
+    This was, we also avoid Visual Studio compiler warnings C4828 as that sign is
+    not favored when /utf-8 is enabled, which is the norm nowadays as Visual Studio
+    2015 or later is required to build harfbuzz nowadays.
+
+ src/hb-gobject-enums.cc.tmpl | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 62fb6738d5115298ee7c72a4da3d9858b08a7269
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Fri Mar 13 12:18:09 2020 +0800
+
+    Fix gen-def for harefbuzz-gobject
+    
+    The © sign is causing issues for the script, so replace those with (C)
+
+ src/hb-gobject-enums.h.tmpl | 2 +-
+ src/hb-gobject-structs.h    | 2 +-
+ src/hb-gobject.h            | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+commit 8d425ed446e6b6cce30c5da16d9ad7d492f0c368
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Fri Mar 13 12:15:28 2020 +0800
+
+    meson: Fix harfbuzz-gobject builds without introspection
+    
+    Make the `sources:` field reflect the items depending on whether introspection
+    is being built
+
+ src/meson.build | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3341d5346e530cd67d23f93cbc85e21bba7e8d0e
+Author: Chun-wei Fan <fanchunwei at src.gnome.org>
+Date:   Fri Mar 13 12:07:06 2020 +0800
+
+    meson: Don't apply -DHB_DLL_EXPORT to all targets
+    
+    Only have it apply to the libraries when they are not built statically on
+    Visual Studio
+
+ meson.build     |  1 -
+ src/meson.build | 11 ++++++++---
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+commit a224f4179fea20b782cc131e4840c258cc3600ad
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Mar 13 08:33:34 2020 +0330
+
+    Turn more of simple dagger chains to foreach
+    
+    Less noise, as was agreed before and applied 385741d also
+
+ src/hb-ot-cff-common.hh |  21 ++++---
+ src/hb-ot-cmap-table.hh | 142 ++++++++++++++++++++++--------------------------
+ src/hb-ot-hdmx-table.hh |   7 +--
+ src/hb-pool.hh          |   4 +-
+ 4 files changed, 79 insertions(+), 95 deletions(-)
+
+commit 755a77d6608c5b6d4e9ee3374a4721c77ff693ac
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Jan 29 22:26:04 2020 +0330
+
+    Move outline draw API behind HB_EXPERIMENTAL_API directive
+
+ .circleci/config.yml           |  2 ++
+ docs/harfbuzz-sections.txt     | 21 ---------------------
+ src/gen-def.py                 | 24 +++++++++++++++++++++++-
+ src/hb-draw.cc                 | 24 +++++++++++++-----------
+ src/hb-draw.h                  |  4 +++-
+ src/hb-draw.hh                 |  2 ++
+ src/hb-font.h                  |  2 ++
+ src/hb-ot-cff1-table.cc        |  2 ++
+ src/hb-ot-cff1-table.hh        |  2 ++
+ src/hb-ot-cff2-table.cc        |  2 ++
+ src/hb-ot-cff2-table.hh        |  2 ++
+ src/hb-ot-glyf-table.hh        |  2 ++
+ src/main.cc                    |  4 ++++
+ test/api/test-draw.c           |  7 +++++++
+ test/api/test-ot-face.c        |  2 ++
+ test/fuzzing/hb-draw-fuzzer.cc |  8 ++++++++
+ 16 files changed, 76 insertions(+), 34 deletions(-)
+
+commit dfab7a254655f5ef5d68a2b92f0d5c197517c853
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Mar 12 21:05:01 2020 +0330
+
+    [cmake] Bring it back to release tarball
+
+ .circleci/config.yml | 6 ++++--
+ Makefile.am          | 3 ++-
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+commit e860000db5c393139c546a1273ba37983c729b41
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Mar 12 21:04:06 2020 +0330
+
+    [cmake] Suggest Meson port in CMake
+
+ CMakeLists.txt | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit b1c3d0b8b0f3d8f644e7bc2f0e4aae2d383f4d79
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Mar 12 20:59:18 2020 +0330
+
+    [cmake] cleanup
+
+ CMakeLists.txt | 21 ---------------------
+ 1 file changed, 21 deletions(-)
+
+commit cc63eb66ce7e8579c92303f8b9d8a8183ec76513
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Mar 12 14:53:26 2020 +0330
+
+    [editorconfig] Add meson config
+
+ .editorconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 1dd389668847bcbc5e94573c80bb71bb87ee0d9c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Mar 12 13:41:10 2020 +0330
+
+    [meson] Make it work on autotools dist
+
+ .circleci/config.yml | 3 ++-
+ Makefile.am          | 3 +++
+ src/Makefile.am      | 1 +
+ util/Makefile.am     | 2 ++
+ 4 files changed, 8 insertions(+), 1 deletion(-)
+
+commit 47a047bd16c072d883a86a8dfc6ab22de9a4be5b
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Mar 12 14:47:40 2020 +0330
+
+    [ci] Remove the not used azure-pipelines.yml
+    
+    We will use GitHub Actions instead, same infrastructure anyway, or even better, CircleCI's Windows support
+
+ azure-pipelines.yml | 21 ---------------------
+ 1 file changed, 21 deletions(-)
+
+commit 834a224a507bc8b971b280483de3f067a709611f
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Mar 12 03:02:36 2020 -0700
+
+    [subset] Put a limit on the number of lookup indices that can be visited during closures
+    
+    Fixes https://crbug.com/oss-fuzz/21025
+
+ src/hb-ot-layout-common.hh                          |   3 +++
+ src/hb-ot-layout-gsubgpos.hh                        |  20 +++++++++++++++++---
+ ...case-minimized-hb-subset-fuzzer-5662792105590784 | Bin 0 -> 1047599 bytes
+ 3 files changed, 20 insertions(+), 3 deletions(-)
+
+commit 31218b41c6bf8e8d43220f7bc87af03a7c70783b
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Mar 11 22:27:32 2020 +0330
+
+    [meson] Explicit state C++11 for older compilers
+    
+    Needed as https://circleci.com/gh/harfbuzz/harfbuzz/132417
+
+ meson.build | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 749cf378e81be77eb7d23ba1a4f26e5dbbc67037
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Mar 11 22:25:27 2020 +0330
+
+    [meson] test meson's own unity feature also
+
+ .circleci/config.yml | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit f8c8be05640618cadbbcb5e4717261e6360828d5
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Mar 11 20:51:40 2020 +0330
+
+    [meson] Add amalgam build option
+
+ .circleci/config.yml | 7 +++++--
+ meson_options.txt    | 3 +++
+ src/meson.build      | 5 +++++
+ 3 files changed, 13 insertions(+), 2 deletions(-)
+
+commit 365d2d3cc32fc0117d88e4a161a34c952151ba58
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Mar 11 20:16:36 2020 +0330
+
+    [meson] Add needed compiler flags
+
+ meson.build | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+commit 12df69e59c1e54137c36113a5ceb1e3000e0dc0f
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Mar 11 21:52:43 2020 +0330
+
+    Minor, delete not needed cmake testing file
+
+ test/subset/CMakeLists.txt | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+commit 943bfeda53f6a8e0aa9b32c7cb0fcc9d01b7dcff
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Mar 11 20:30:41 2020 +0330
+
+    [meson] Enable more of the subset tests
+
+ test/subset/meson.build | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit c494d7abcd626c274477319859b9bcb873aca388
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Mar 11 19:44:13 2020 +0330
+
+    Remove cmake testing and add meson build bot
+    
+    CMake tests are broken anyway as py3 changes so let's get rid of them
+
+ .circleci/config.yml        | 90 ++++-----------------------------------------
+ CMakeLists.txt              | 52 --------------------------
+ Makefile.am                 |  2 +-
+ test/CMakeLists.txt         |  4 --
+ test/Makefile.am            |  2 +-
+ test/api/CMakeLists.txt     | 36 ------------------
+ test/api/Makefile.am        |  2 +-
+ test/fuzzing/CMakeLists.txt | 27 --------------
+ test/fuzzing/Makefile.am    |  2 +-
+ test/shaping/CMakeLists.txt | 28 --------------
+ test/shaping/Makefile.am    |  2 +-
+ test/subset/Makefile.am     |  2 +-
+ 12 files changed, 13 insertions(+), 236 deletions(-)
+
+commit 1c3f80ba136bffec00343bae87269bbc9c33ecde
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Mar 11 19:29:47 2020 +0330
+
+    [meson] Minor updates
+
+ meson.build              |  4 ++--
+ test/fuzzing/meson.build |  2 ++
+ test/subset/meson.build  | 22 +++++++++++++++++++++-
+ 3 files changed, 25 insertions(+), 3 deletions(-)
+
+commit 68f982415be747b8fd675d3eb55332a8277805e5
+Author: Aaron Boxer <aaron.boxer at collabora.com>
+Date:   Mon Jul 22 12:12:02 2019 -0600
+
+    meson: update to latest master
+
+ meson_options.txt |  2 --
+ src/meson.build   | 21 ++++++++++++---------
+ util/meson.build  |  1 +
+ 3 files changed, 13 insertions(+), 11 deletions(-)
+
+commit 535186fd84d0fba3710cb33a4983efbbc074fcca
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Mon Dec 3 20:51:06 2018 +0100
+
+    meson: provide a harfbuzz-config for use from CMake
+    
+    See #822 and #1437.
+
+ meson.build     | 16 ++++++++++++++++
+ src/meson.build | 14 +++++++++++++-
+ 2 files changed, 29 insertions(+), 1 deletion(-)
+
+commit 6afa7e1c3682b70ea49e3ec0f75a4e0b1deae3cc
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Sun Dec 2 01:28:23 2018 +0000
+
+    meson: update harfbuzz version
+
+ meson.build | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f1e5f4a78440b2f43a8a3fb753fe88971eddad8b
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Sun Dec 2 00:33:43 2018 +0000
+
+    meson: tests: shaping: add aots tests
+
+ test/shaping/meson.build | 139 +++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 139 insertions(+)
+
+commit 84725fb005777990890a85ba9e67566c7f2e0a74
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Sun Dec 2 00:32:57 2018 +0000
+
+    meson: tests: shaping: add missing in-house tests
+
+ test/shaping/meson.build | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 8fc66dbf9f95c707f57c7714b0ee1c88338d4bd3
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Sat Dec 1 21:15:33 2018 +0000
+
+    meson: tests: subset: no need to check for 'which' command any more
+    
+    Test runner script now handles that.
+
+ test/subset/meson.build | 33 +++++++++++++--------------------
+ 1 file changed, 13 insertions(+), 20 deletions(-)
+
+commit 0976300be4f4f3c049f48fdc29bcabb385b6e182
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Sat Dec 1 21:10:57 2018 +0000
+
+    meson: pin glib wrap to 2.58.1 release
+
+ subprojects/glib.wrap | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0fcf098206e669ab4ca17e2e04c4aa52e6ef0e90
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Sat Dec 1 18:22:46 2018 +0000
+
+    meson: fix linking on MSVC
+
+ meson.build | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 4a47f1aabc300317a87c581b71e21048416d2c20
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Sat Dec 1 11:05:27 2018 +0000
+
+    meson: suppress some spurious compiler warnings with MSVC
+
+ meson.build | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+commit 7eaf3754dc39f91295ba769714e01e37ddf23189
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Fri Nov 16 16:26:06 2018 +0000
+
+    meson: update for changes in master
+    
+    And remove header files from sources list, Meson figures
+    out header dependencies by itself (via the compiler).
+
+ src/meson.build | 104 +++++---------------------------------------------------
+ 1 file changed, 9 insertions(+), 95 deletions(-)
+
+commit 04438554c838abcfc860a646df866cb3baed5621
+Author: Khaled Hosny <khaledhosny at eglug.org>
+Date:   Thu Nov 15 00:25:41 2018 +0200
+
+    meson: Update build files after rebase
+
+ src/meson.build          | 111 ++++++++++++++++++++++++++++++++++++++++++++---
+ test/api/meson.build     |  16 +++++--
+ test/fuzzing/meson.build |   2 -
+ test/shaping/meson.build |  64 ++++++++++++++++++++++++++-
+ 4 files changed, 181 insertions(+), 12 deletions(-)
+
+commit 618584e9234c13369505b5064949214d0871e2d0
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Wed Nov 14 20:19:36 2018 +0000
+
+    meson: rename incbase to incconfig
+    
+    Makes it clearer what it's for: config.h. See #4.
+
+ meson.build              | 2 +-
+ src/meson.build          | 6 +++---
+ test/api/meson.build     | 2 +-
+ test/fuzzing/meson.build | 2 +-
+ util/meson.build         | 8 ++++----
+ 5 files changed, 10 insertions(+), 10 deletions(-)
+
+commit 14b5c774c205a1f8db72fa68a3e626391e917e09
+Author: Khaled Hosny <khaledhosny at eglug.org>
+Date:   Wed Nov 14 21:05:47 2018 +0200
+
+    meson: Fix include directory when used as subproject
+    
+    HarfBuzz headers are under src/ not the root directory, without using
+    incsrc no headers will be found by the dependent project. I think
+    incbase is superfluous, it should be replaced by incsrc or dropped.
+
+ src/meson.build | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 6abe7983edcf820d7b8b35e1a7dddaaf3d0f1346
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Wed Nov 14 13:49:03 2018 +0000
+
+    meson: add g-i introspection
+
+ meson_options.txt |  4 ++--
+ src/meson.build   | 24 ++++++++++++++++++++++++
+ 2 files changed, 26 insertions(+), 2 deletions(-)
+
+commit 6147df337ee5a0b8135453443c696f85624dbfa3
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Wed Nov 14 10:12:40 2018 +0000
+
+    meson: add option to disable tests
+
+ meson.build       | 5 ++++-
+ meson_options.txt | 4 ++--
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+commit d230a02048efb860190a6d694ecc2729d4c4fb12
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Mon Nov 12 19:41:39 2018 +0000
+
+    meson: generate .def file for MSVC symbol export on the fly
+    
+    Fix symbol export with MSVC when features are disabled,
+    such as GLib. We need to generate the list of exported
+    symbols on the fly to make sure we only export symbols
+    that are actually available.
+    
+    Needs some minor modifications to the gen-def.py script:
+     - accept header list also via command line args; we can't
+       pass things to a configure_file() command via the environment
+       in Meson.
+     - strip any leading 'src/' from library filename. This might
+       be there because in Meson the script might be called from
+       the top-level directory and not the current source directory.
+    
+    Remove .def files again which had been checked in for earlier
+    versions of the Meson port.
+
+ src/gen-def.py           |   2 +-
+ src/harfbuzz-gobject.def |  33 -----
+ src/harfbuzz-icu.def     |   5 -
+ src/harfbuzz-subset.def  |  12 --
+ src/harfbuzz.def         | 310 -----------------------------------------------
+ src/meson.build          |  56 ++++++---
+ 6 files changed, 38 insertions(+), 380 deletions(-)
+
+commit 4840c8237e484177b676e774ffebbdf40c654133
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Mon Nov 12 16:56:56 2018 +0000
+
+    meson: add option and build system plumbing for CoreText on macOS/iOS
+    
+    Untested though.
+
+ meson.build       | 21 +++++++++++++++++++++
+ meson_options.txt |  2 ++
+ src/meson.build   |  9 +++++----
+ 3 files changed, 28 insertions(+), 4 deletions(-)
+
+commit 83ebbe4ade0c74ec83d62fcfc6ba04de87384ff5
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Mon Nov 12 16:56:56 2018 +0000
+
+    meson: add option and build system plumbing for DirectWrite on Windows
+    
+    Untested though.
+
+ meson.build       | 10 ++++++++++
+ meson_options.txt |  2 ++
+ src/meson.build   |  9 +++++----
+ 3 files changed, 17 insertions(+), 4 deletions(-)
+
+commit b7796a5d6984d40a44fbd828a6d3006c71f1cb3d
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Mon Nov 12 16:56:56 2018 +0000
+
+    meson: add option and build system plumbing for uniscribe on Windows
+    
+    Untested though.
+
+ meson.build       | 14 ++++++++++++++
+ meson_options.txt |  2 ++
+ src/meson.build   |  9 +++++----
+ 3 files changed, 21 insertions(+), 4 deletions(-)
+
+commit c81290b0c11a6bcc960ab5d043502ac3a5998abd
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Mon Nov 12 15:58:09 2018 +0000
+
+    meson: add feature option for internal ucdn lib
+
+ meson_options.txt |  2 ++
+ src/meson.build   | 17 ++++++++---------
+ 2 files changed, 10 insertions(+), 9 deletions(-)
+
+commit 49ba211a9d4518ebba0c44e2d22946e23a2cead8
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Mon Nov 12 15:36:27 2018 +0000
+
+    meson: add options to enable/disable various features
+    
+    And fix build without GLib. Fixes #2.
+
+ meson.build       | 16 ++++++++--------
+ meson_options.txt | 21 +++++++++++++++++++++
+ util/meson.build  |  4 ++++
+ 3 files changed, 33 insertions(+), 8 deletions(-)
+
+commit c5f2e5e5abb9754460e9db37b54cd314b665a8d2
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Mon Nov 12 10:05:04 2018 +0000
+
+    meson: use proxy-libintl from frida
+
+ subprojects/proxy-libintl.wrap | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 54417b127b3cfb4952788f8535ad5bfa788fb2b8
+Author: Tim-Philipp Müller <tim at centricular.com>
+Date:   Mon Nov 12 10:04:15 2018 +0000
+
+    meson: fix glib git url
+    
+    It's on gitlab now.
+    
+    Fixes #1
+
+ subprojects/glib.wrap | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit f65def4dc7bad244742be1f6aed2552c23d12b8f
+Author: Nirbheek Chauhan <nirbheek at centricular.com>
+Date:   Fri Oct 12 19:41:49 2018 +0530
+
+    meson: Declare dependencies for use as a subproject
+    
+    Also use fallbacks for dependencies that have meson build files
+
+ meson.build     | 28 ++++++++++++++++++++++------
+ src/meson.build | 17 +++++++++++++++++
+ 2 files changed, 39 insertions(+), 6 deletions(-)
+
+commit 14432b3ded153972b02fe2aed4f5c3d095ef5b4a
+Author: Mathieu Duponchelle <mathieu at centricular.com>
+Date:   Wed Jul 4 17:54:28 2018 +0200
+
+    meson: remove debug message
+
+ meson.build | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit 07cadc9c870c9ed49973ecf8828cbbe9e3e9daf2
+Author: Mathieu Duponchelle <mathieu at centricular.com>
+Date:   Mon Jun 18 17:18:05 2018 +0200
+
+    meson: update minimum meson version
+
+ meson.build | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 04bcdb9c73ff47a4b624608b69bde86b88505588
+Author: Mathieu Duponchelle <mathieu at centricular.com>
+Date:   Tue Jun 5 20:59:29 2018 +0200
+
+    meson: misc fixes
+
+ meson.build | 24 +++++++++++++-----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+commit 29c47d8eb5adf4967fe0b05013d0f53856066288
+Author: Mathieu Duponchelle <mathieu at centricular.com>
+Date:   Tue Jun 5 18:19:29 2018 +0200
+
+    meson: pass subdirs to pkgconfig.generate()
+
+ src/meson.build | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 484313ff3667f279f0a1d98021b2e5719508ad31
+Author: Mathieu Duponchelle <mathieu at centricular.com>
+Date:   Tue Jun 5 02:15:43 2018 +0200
+
+    meson: install
+
+ meson.build      |  1 +
+ src/meson.build  | 32 +++++++++++++++++++++++++++++---
+ util/meson.build | 14 +++++++++-----
+ 3 files changed, 39 insertions(+), 8 deletions(-)
+
+commit d4a723732791a4806d92828d55fd6138d857722d
+Author: Mathieu Duponchelle <mathieu at centricular.com>
+Date:   Thu May 17 16:25:22 2018 -0700
+
+    meson: all tests passing on Windows / MSVC
+
+ src/harfbuzz-gobject.def       |  33 +++++
+ src/harfbuzz-icu.def           |   5 +
+ src/harfbuzz-subset.def        |  12 ++
+ src/harfbuzz.def               | 310 +++++++++++++++++++++++++++++++++++++++++
+ subprojects/.gitignore         |   2 +
+ subprojects/proxy-libintl.wrap |   4 +
+ subprojects/zlib.wrap          |   4 +
+ test/fuzzing/meson.build       |   6 +-
+ test/shaping/meson.build       |   8 +-
+ test/subset/meson.build        |  27 ++--
+ 10 files changed, 393 insertions(+), 18 deletions(-)
+
+commit 99b26789d2ff2874ec8adf760416f2434e3093ad
+Author: Mathieu Duponchelle <mathieu at centricular.com>
+Date:   Thu May 17 14:53:20 2018 -0700
+
+    meson: more windows fixes
+
+ src/meson.build  | 14 +++++++++++---
+ util/meson.build | 59 ++++++++++++++++++++++++++++++--------------------------
+ 2 files changed, 43 insertions(+), 30 deletions(-)
+
+commit 7ee650b173dc39fa998fb16aa10206dc8501a004
+Author: Mathieu Duponchelle <mathieu at centricular.com>
+Date:   Thu May 17 23:52:36 2018 +0200
+
+    meson: refactor fuzzing test
+
+ test/fuzzing/meson.build | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+commit fce88f9905f336aa83c934f346c44eb0829abeae
+Author: Mathieu Duponchelle <mathieu at centricular.com>
+Date:   Thu May 17 16:20:10 2018 +0200
+
+    meson: add subproject wraps for dependencies
+
+ meson.build                 | 29 ++++++++++-------------------
+ subprojects/.gitignore      |  6 ++++++
+ subprojects/expat.wrap      | 10 ++++++++++
+ subprojects/fontconfig.wrap |  5 +++++
+ subprojects/freetype2.wrap  |  5 +++++
+ subprojects/glib.wrap       |  5 +++++
+ subprojects/libffi.wrap     |  4 ++++
+ 7 files changed, 45 insertions(+), 19 deletions(-)
+
+commit 920efc0ef72eb4bb5dce02ee9f9adcdd5fdf8f7a
+Author: Mathieu Duponchelle <mathieu at centricular.com>
+Date:   Thu May 17 01:28:53 2018 +0200
+
+    Add Meson build definitions
+    
+    Fixes #490
+    
+    http://mesonbuild.com
+
+ meson-cc-tests/intel-atomic-primitives-test.c |   6 +
+ meson-cc-tests/solaris-atomic-operations.c    |   8 +
+ meson.build                                   | 189 ++++++++++++++++++++
+ src/fix_get_types.py                          |  15 ++
+ src/meson.build                               | 237 ++++++++++++++++++++++++++
+ test/api/meson.build                          |  51 ++++++
+ test/fuzzing/meson.build                      |  32 ++++
+ test/meson.build                              |   4 +
+ test/shaping/meson.build                      | 110 ++++++++++++
+ test/subset/meson.build                       |  20 +++
+ util/meson.build                              |  51 ++++++
+ 11 files changed, 723 insertions(+)
+
+commit 0615c7b64b63400b2a70a1a6dd8a57d0b0fff10c
+Author: Khaled Hosny <khaledhosny at eglug.org>
+Date:   Tue Mar 10 21:57:31 2020 +0200
+
+    Remove workaround for old pkg-config
+    
+    Add FreeType dependency to .pc, Ubuntu 14.4 is long dead.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1565
+
+ src/Makefile.am | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+commit 78eabf247e3127413a80ad92f7d576b00a438687
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 10 13:34:42 2020 +0330
+
+    [test] Enable OT funcs on tests that are working
+
+ .../data/in-house/tests/indic-joiners.tests        |  8 +--
+ test/shaping/data/in-house/tests/use.tests         |  2 +-
+ .../data/text-rendering-tests/tests/AVAR-1.tests   | 34 ++++++------
+ .../data/text-rendering-tests/tests/CFF-1.tests    | 26 ++++-----
+ .../data/text-rendering-tests/tests/CFF-2.tests    | 26 ++++-----
+ .../data/text-rendering-tests/tests/CFF2-1.tests   | 18 +++----
+ .../data/text-rendering-tests/tests/CMAP-1.tests   |  8 +--
+ .../data/text-rendering-tests/tests/CMAP-2.tests   |  4 +-
+ .../data/text-rendering-tests/tests/CMAP-3.tests   | 40 +++++++-------
+ .../data/text-rendering-tests/tests/CVAR-1.tests   |  6 +--
+ .../data/text-rendering-tests/tests/CVAR-2.tests   |  6 +--
+ .../data/text-rendering-tests/tests/GLYF-1.tests   |  2 +-
+ .../data/text-rendering-tests/tests/GPOS-1.tests   | 38 ++++++-------
+ .../data/text-rendering-tests/tests/SHARAN-1.tests | 12 ++---
+ .../data/text-rendering-tests/tests/SHBALI-1.tests | 44 +++++++--------
+ .../data/text-rendering-tests/tests/SHBALI-2.tests | 24 ++++-----
+ .../data/text-rendering-tests/tests/SHKNDA-2.tests | 32 +++++------
+ .../data/text-rendering-tests/tests/SHKNDA-3.tests | 62 +++++++++++-----------
+ 18 files changed, 196 insertions(+), 196 deletions(-)
+
+commit 47f5a860362180f6655d49956d7d12e0d296463d
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 10 13:57:46 2020 +0330
+
+    minor, use NN on every OffsetTo<UnsizedArrayOf<>>
+
+ src/hb-aat-layout-feat-table.hh | 2 +-
+ src/hb-aat-layout-trak-table.hh | 2 +-
+ src/hb-ot-meta-table.hh         | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+commit 648338c7d495f69a896348faabd2175c1e21981f
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 10 13:12:00 2020 +0330
+
+    [gvar] Add fields docs from ot-spec as other tables
+
+ src/hb-ot-var-gvar-table.hh | 151 ++++++++++++++++++++++++++------------------
+ 1 file changed, 88 insertions(+), 63 deletions(-)
+
+commit 1b3b96973bc00294f00adc18104ab12997b75661
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 10 12:46:09 2020 +0330
+
+    [gvar] Don't copy shared tuples into gvar's accelerator
+
+ src/hb-ot-var-gvar-table.hh | 26 +++++++-------------------
+ 1 file changed, 7 insertions(+), 19 deletions(-)
+
+commit 29dd1fe506d254abdf8b4cccd7dfdf48d6f5e7e6
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 10 11:41:51 2020 +0330
+
+    [gvar] Don't check again against face num glyph
+    
+    Done once by sanitize_shallow
+
+ src/hb-ot-var-gvar-table.hh | 4 ----
+ 1 file changed, 4 deletions(-)
+
+commit d4b11817600e3ac444895336dd78a72dbeaf2a56
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 10 11:29:56 2020 +0330
+
+    [gvar] minor, rename gvar_table to table
+
+ src/hb-ot-var-gvar-table.hh | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+commit 5c376938644f820c7fd69991c8d2e9c4952145c4
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 10 10:51:38 2020 +0330
+
+    [gvar] Remove axisCount comparison with fvar as we runtime check that
+
+ src/hb-ot-var-gvar-table.hh | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+commit ba22df36adf2d60df442330ac13618fe640f8d4c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 10 10:42:20 2020 +0330
+
+    minor
+    
+    makes search for sanitize calls easier for me
+
+ src/hb-ot-color-svg-table.hh   | 2 +-
+ src/hb-ot-hmtx-table.hh        | 4 ++--
+ src/hb-ot-layout-gdef-table.hh | 4 ++--
+ src/hb-ot-layout-gsubgpos.hh   | 2 +-
+ src/hb-ot-name-table.hh        | 2 +-
+ 5 files changed, 7 insertions(+), 7 deletions(-)
+
+commit 8ca9df7acb6283eb68fcf3d66aacac6faafcc94c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 10 10:40:05 2020 +0330
+
+    [subset] Remove not needed blob sanitize call
+
+ src/hb-subset-cff1.cc | 10 +++-------
+ src/hb-subset-cff2.cc | 11 +++--------
+ 2 files changed, 6 insertions(+), 15 deletions(-)
+
+commit 07acd1a0426a5ba3f4924e3bb79a6715c164782c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Mar 8 23:39:24 2020 +0330
+
+    [subset] Rename src_base args to base to match sanitize methods
+    
+    So it will become easier to follow that serialize methods signatures should
+    match with their sanitize methods counterparts.
+
+ src/hb-open-type.hh            |  18 ++----
+ src/hb-ot-cmap-table.hh        |  37 ++++++-----
+ src/hb-ot-color-cbdt-table.hh  |   4 +-
+ src/hb-ot-layout-common.hh     | 135 +++++++++++++++++------------------------
+ src/hb-ot-layout-gpos-table.hh |  51 +++++++---------
+ src/hb-ot-layout-gsubgpos.hh   |   6 +-
+ src/hb-ot-name-table.hh        |   5 +-
+ 7 files changed, 108 insertions(+), 148 deletions(-)
+
+commit 188a0a47c225a0bf1869b2d4c14db96055c2099c
+Author: ariza <ariza at adobe.com>
+Date:   Sat Mar 7 11:02:36 2020 -0800
+
+    removed default base; replaced w/ bias if required
+
+ src/hb-open-type.hh            | 11 +++----
+ src/hb-ot-cmap-table.hh        | 18 +++++------
+ src/hb-ot-color-cbdt-table.hh  |  7 ++---
+ src/hb-ot-color-sbix-table.hh  | 10 +++---
+ src/hb-ot-layout-common.hh     | 70 +++++++++++++++++-------------------------
+ src/hb-ot-layout-gdef-table.hh | 20 ++++++------
+ src/hb-ot-layout-gpos-table.hh | 55 ++++++++++++++++-----------------
+ src/hb-ot-layout-gsub-table.hh |  8 ++---
+ src/hb-ot-layout-gsubgpos.hh   | 30 ++++++++----------
+ src/hb-ot-name-table.hh        |  2 +-
+ src/hb-serialize.hh            | 22 +++++--------
+ 11 files changed, 112 insertions(+), 141 deletions(-)
+
+commit 4c3af7d406359d2addd51b2fc91d49b3a8d45c29
+Author: blueshade7 <ariza at typekit.com>
+Date:   Thu Mar 5 15:40:44 2020 -0800
+
+    add "add_link()" with bias arg
+    
+    issue #2227
+
+ src/hb-ot-cff-common.hh |  2 +-
+ src/hb-serialize.hh     | 37 +++++++++++++++++++++----------------
+ 2 files changed, 22 insertions(+), 17 deletions(-)
+
+commit bdf372b24c19516c7e608b3eb254fb3720b36b6c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Mar 8 00:47:25 2020 +0330
+
+    [subset/cbdt] Release the referenced cbdt table on error
+    
+    Just accidentally spotted it, when the table has less than 4 bytes
+
+ src/hb-ot-color-cbdt-table.hh | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit 0d729b4b7237934abfca0b5738ad4383f3f22476
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Mar 7 11:53:12 2020 +0330
+
+    [avar] Fix out-of-bound read when input is bigger than all the coords
+    
+    'i' shouldn't become equal to array's length which as the increament
+    is happened at end of the loop, if the input is bigger than all the
+    table coords, it will be equal to array's length.
+    
+    Fixes https://crbug.com/oss-fuzz/21092
+
+ src/hb-ot-var-avar-table.hh                              |   2 +-
+ ...zz-testcase-minimized-hb-draw-fuzzer-5681465586352128 | Bin 0 -> 4448 bytes
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+
+commit 6924e29f62a320c91d987a91d4efa752d13c7660
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 3 13:11:11 2020 +0330
+
+    [var] Fix hb_ot_var_get_axis_infos's offset semantic
+    
+    The API was adding offset to input's infos buffer index also which is
+    unusual between our APIs and wrong.
+
+ src/hb-ot-var-fvar-table.hh | 26 ++++----------------------
+ test/api/test-var-coords.c  | 25 +++++++++++++++++++++++++
+ 2 files changed, 29 insertions(+), 22 deletions(-)
+
+commit b7617f6b3cfa0abf10292ea79bcd53ef61a08e90
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Mar 5 12:07:33 2020 +0330
+
+    [glyf] Update to latests of ttf-parser
+
+ src/hb-ot-glyf-table.hh | 45 +++++++++++++++++++++------------------------
+ 1 file changed, 21 insertions(+), 24 deletions(-)
+
+commit 0b290538646b08d391321fcbb9a1cb5f648d83ff
+Author: ariza <ariza at adobe.com>
+Date:   Wed Mar 4 22:31:21 2020 -0800
+
+    removed unused code
+
+ src/hb-ot-cff1-table.hh     | 24 ++++++++++++------------
+ src/hb-ot-cff2-table.hh     | 10 +++++-----
+ src/hb-subset-cff-common.hh |  6 +++---
+ src/hb-subset-cff1.cc       | 16 ++++++++--------
+ 4 files changed, 28 insertions(+), 28 deletions(-)
+
+commit e8f010d7938b9f8c6065ca455c6b24968fcfd898
+Author: ariza <ariza at adobe.com>
+Date:   Wed Mar 4 16:54:27 2020 -0800
+
+    removed unused code & data; rename
+
+ src/hb-cff-interp-dict-common.hh | 13 --------
+ src/hb-ot-cff-common.hh          | 62 +-------------------------------------
+ src/hb-ot-cff1-table.hh          | 65 ++++++++--------------------------------
+ src/hb-ot-cff2-table.hh          | 44 ++++-----------------------
+ src/hb-subset-cff-common.hh      | 52 +++-----------------------------
+ src/hb-subset-cff1.cc            | 18 +++++------
+ 6 files changed, 31 insertions(+), 223 deletions(-)
+
+commit 14a7b6f1ab1926680369bf43efc9ee8d5f89402d
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Feb 26 15:09:04 2020 -0800
+
+    Set hb_buffer_t to use array_t.reverse().
+
+ src/Makefile.am   |  6 ++++-
+ src/hb-array.hh   | 25 ++++++++++--------
+ src/hb-buffer.cc  | 18 ++-----------
+ src/test-array.cc | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 97 insertions(+), 28 deletions(-)
+
+commit 5935a1dc0b45d1256c81b214222125b47e3db345
+Author: ariza <ariza at adobe.com>
+Date:   Tue Mar 3 12:12:51 2020 -0800
+
+    add pop_discard() calls to errror returns
+
+ src/hb-subset-cff1.cc | 135 ++++++++++++++++++++++++++++++++++----------------
+ src/hb-subset-cff2.cc |  54 +++++++++++++-------
+ 2 files changed, 130 insertions(+), 59 deletions(-)
+
+commit c05458ec7f11753be95d1c3cdd7c377d07d7b981
+Author: ariza <ariza at adobe.com>
+Date:   Mon Mar 2 16:51:19 2020 -0800
+
+    update cff & cff2 subsetters
+
+ src/hb-ot-cff-common.hh                            | 201 ++++----
+ src/hb-ot-cff1-table.hh                            |  58 ++-
+ src/hb-ot-cff2-table.hh                            |   9 +-
+ src/hb-subset-cff-common.hh                        |  63 +--
+ src/hb-subset-cff1.cc                              | 526 ++++++---------------
+ src/hb-subset-cff2.cc                              | 320 ++++---------
+ test/api/fonts/AdobeVFPrototype.ac.nohints.otf     | Bin 6220 -> 4212 bytes
+ .../fonts/AdobeVFPrototype.ac.nosubrs.nohints.otf  | Bin 6100 -> 4092 bytes
+ test/api/fonts/cff1_expert.2D,F6E9,FB00.otf        | Bin 3096 -> 1412 bytes
+ 9 files changed, 430 insertions(+), 747 deletions(-)
+
+commit 446d1e3bbce4627f2edf24bb991fe606465f2d7e
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Mar 4 23:32:50 2020 +0330
+
+    [fuzz] Add more of fixed cases
+
+ ...fuzz-testcase-hb-subset-fuzzer-5686749313892352 | Bin 0 -> 2808 bytes
+ ...case-minimized-harfbuzz_fuzzer-5017946948370432 | Bin 0 -> 1321 bytes
+ ...case-minimized-harfbuzz_fuzzer-5170405903695872 | Bin 0 -> 1271 bytes
+ ...case-minimized-harfbuzz_fuzzer-6223034666713088 | Bin 0 -> 1260 bytes
+ ...case-minimized-hb-shape-fuzzer-5154718402215936 | Bin 0 -> 226 bytes
+ ...case-minimized-hb-shape-fuzzer-5196560812474368 | Bin 0 -> 1816 bytes
+ ...case-minimized-hb-shape-fuzzer-5632586529898496 | Bin 0 -> 695 bytes
+ ...case-minimized-hb-shape-fuzzer-5642666339991552 | Bin 0 -> 32 bytes
+ ...case-minimized-hb-shape-fuzzer-5642899625082880 | Bin 0 -> 759578 bytes
+ ...case-minimized-hb-shape-fuzzer-5648999235715072 | Bin 0 -> 297 bytes
+ ...case-minimized-hb-shape-fuzzer-5652700541222912 | Bin 0 -> 232 bytes
+ ...case-minimized-hb-shape-fuzzer-5711096049041408 | Bin 0 -> 93 bytes
+ ...case-minimized-hb-shape-fuzzer-5711472756260864 | Bin 0 -> 154432 bytes
+ ...case-minimized-hb-shape-fuzzer-5742079188140032 | Bin 0 -> 16731 bytes
+ ...case-minimized-hb-shape-fuzzer-5749627240841216 | Bin 0 -> 99 bytes
+ ...case-minimized-hb-shape-fuzzer-6306977171374080 | Bin 0 -> 713443 bytes
+ ...ase-minimized-hb-subset-fuzzer-5160311461511168 | Bin 0 -> 68 bytes
+ ...ase-minimized-hb-subset-fuzzer-5640452927127552 | Bin 0 -> 32376 bytes
+ ...ase-minimized-hb-subset-fuzzer-5640889218629632 | Bin 0 -> 1490 bytes
+ ...ase-minimized-hb-subset-fuzzer-5641053680173056 | Bin 0 -> 2863 bytes
+ ...ase-minimized-hb-subset-fuzzer-5674228796358656 | Bin 0 -> 913 bytes
+ ...ase-minimized-hb-subset-fuzzer-5675720390475776 | Bin 299037 -> 131084 bytes
+ ...ase-minimized-hb-subset-fuzzer-5678476148867072 | Bin 0 -> 113915 bytes
+ ...ase-minimized-hb-subset-fuzzer-5685097303375872 | Bin 0 -> 134 bytes
+ ...ase-minimized-hb-subset-fuzzer-5695865298092032 | Bin 0 -> 139054 bytes
+ ...ase-minimized-hb-subset-fuzzer-5697351339999232 | Bin 0 -> 391689 bytes
+ ...ase-minimized-hb-subset-fuzzer-5708063625969664 | Bin 0 -> 155466 bytes
+ ...ase-minimized-hb-subset-fuzzer-5711849555755008 | Bin 0 -> 1896 bytes
+ ...ase-minimized-hb-subset-fuzzer-5733203291144192 | Bin 0 -> 34 bytes
+ ...ase-minimized-hb-subset-fuzzer-5735719311507456 | Bin 0 -> 879 bytes
+ ...ase-minimized-hb-subset-fuzzer-5745268385906688 | Bin 0 -> 291536 bytes
+ ...ase-minimized-hb-subset-fuzzer-5756658848890880 | Bin 0 -> 2734 bytes
+ ...ase-minimized-hb-subset-fuzzer-5758358618898432 | Bin 0 -> 20112 bytes
+ ...ase-minimized-hb-subset-fuzzer-5764020596899840 | Bin 0 -> 1766 bytes
+ test/fuzzing/fonts/fuzz-0-harfbuzz_hb-fuzzer       | Bin 0 -> 3266 bytes
+ 35 files changed, 0 insertions(+), 0 deletions(-)
+
+commit 9004848560141d98dff61eda2dea01412ddc24ea
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Mar 4 12:12:35 2020 +0330
+
+    [gvar] Make sure font's num_coords matches with gvar.axisCount
+
+ src/hb-ot-glyf-table.hh     |  2 +-
+ src/hb-ot-var-gvar-table.hh | 11 ++++++-----
+ 2 files changed, 7 insertions(+), 6 deletions(-)
+
+commit 1af3363f9e4b52d68e6dd5600cef4479614292d5
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Mar 4 11:32:01 2020 +0330
+
+    [gvar] Use hb_array_t instead indexing raw pointers
+
+ src/hb-ot-var-gvar-table.hh | 39 ++++++++++++++++++---------------------
+ 1 file changed, 18 insertions(+), 21 deletions(-)
+
+commit 99b5b3f1b125010aea0cbb9183950fa18fe089b5
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Mar 4 11:15:46 2020 +0330
+
+    [gvar] Make sure TupleVarHeader has the needed size
+    
+    Fixes https://crbug.com/oss-fuzz/21026
+
+ src/hb-ot-var-gvar-table.hh                              |   2 +-
+ ...zz-testcase-minimized-hb-draw-fuzzer-5703524300357632 | Bin 0 -> 1515 bytes
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+
+commit b398748d8bd61dbf61a3f8ec7e6aaf715bf57f65
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Mar 4 11:18:19 2020 +0330
+
+    [algs] Add hb_clamp
+    
+    Similar to stl and glsl's clamp
+
+ src/hb-algs.hh              | 7 +++++++
+ src/hb-ot-var-fvar-table.hh | 2 +-
+ src/hb-sanitize.hh          | 6 +++---
+ 3 files changed, 11 insertions(+), 4 deletions(-)
+
+commit 558f922788ccceaa80c31bf0e379be4c96598d13
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 3 20:27:19 2020 +0330
+
+    [fuzz] Avoid empty memcpy and ubsan complain by length checking before memcpy
+
+ test/fuzzing/hb-shape-fuzzer.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 6543d166fded5aefb223bcaf614985654a2dafc0
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 3 20:26:46 2020 +0330
+
+    [fuzz] Remove the not yet fixed timeout, going to investigate
+
+ ...zz-testcase-minimized-harfbuzz_fuzzer-5754958982021120 | Bin 319 -> 0 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 2bbf1c8673a549be22b316a8055c080787129f55
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 3 19:42:38 2020 +0330
+
+    [fuzz] Add more of supposed to already be fixed cases from Chromium bug tracker
+
+ ...usterfuzz-testcase-harfbuzz_fuzzer-4822416500195328 | Bin 0 -> 16800 bytes
+ ...usterfuzz-testcase-harfbuzz_fuzzer-5598263003840512 | Bin 0 -> 16800 bytes
+ ...usterfuzz-testcase-harfbuzz_fuzzer-6327734241591296 | Bin 0 -> 30 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-4601449528688640 | Bin 0 -> 99 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-4684060812378112 | Bin 0 -> 604 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-4710179695493120 | Bin 0 -> 982 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-4850271066914816 | Bin 0 -> 386 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-4977194146988032 | Bin 0 -> 520 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-5012913062150144 | Bin 0 -> 283 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-5103148350963712 | Bin 0 -> 112 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-5151890782027776 | Bin 0 -> 318 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-5157039562162176 | Bin 0 -> 363 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-5163560220753920 | Bin 0 -> 520 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-5180622648770560 | Bin 0 -> 110 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-5221177988743168 | Bin 0 -> 936 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-5334300410773504 | Bin 0 -> 99 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-5644474732249088 | Bin 0 -> 568 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-5677289226108928 | Bin 0 -> 47 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-5719356528656384 | Bin 0 -> 330 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-5754958982021120 | Bin 0 -> 319 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-5952939792531456 |   0
+ ...testcase-minimized-harfbuzz_fuzzer-6107935408390144 | Bin 0 -> 16800 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-6120104833843200 | Bin 0 -> 81 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-6128803416637440 | Bin 0 -> 4041 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-6142466903506944 | Bin 0 -> 926 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-6198448785981440 | Bin 0 -> 2357 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-6462232674959360 | Bin 0 -> 2738 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-6600932143136768 | Bin 0 -> 988 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-6603291950841856 | Bin 0 -> 1384 bytes
+ ...testcase-minimized-harfbuzz_fuzzer-6712347260092416 | Bin 0 -> 196336 bytes
+ ...case-minimized-harfbuzz_fuzzer.exe-5470269447340032 | Bin 0 -> 341 bytes
+ ...z-testcase-minimized-hb-set-fuzzer-6255224052514816 |   1 +
+ test/fuzzing/fonts/fuzz-0-harfbuzz_fuzzer              | Bin 0 -> 982 bytes
+ test/fuzzing/fonts/fuzz-1-harfbuzz_fuzzer              | Bin 0 -> 10424 bytes
+ test/fuzzing/fonts/fuzz-1-harfbuzz_fuzzer(1)           | Bin 0 -> 16144 bytes
+ test/fuzzing/fonts/fuzz-2-harfbuzz_fuzzer              | Bin 0 -> 1010 bytes
+ test/fuzzing/fonts/fuzz-2-harfbuzz_fuzzer(1)           | Bin 0 -> 1010 bytes
+ test/fuzzing/fonts/fuzz-3-harfbuzz_fuzzer              | Bin 0 -> 6791 bytes
+ test/fuzzing/fonts/fuzz-3-harfbuzz_fuzzer(1)           | Bin 0 -> 2625 bytes
+ test/fuzzing/fonts/fuzz-3-harfbuzz_fuzzer(2)           | Bin 0 -> 2813 bytes
+ test/fuzzing/fonts/fuzz-3-harfbuzz_fuzzer(3)           | Bin 0 -> 2813 bytes
+ test/fuzzing/fonts/fuzz-3-harfbuzz_fuzzer(4)           | Bin 0 -> 646 bytes
+ test/fuzzing/fonts/fuzz-3-harfbuzz_fuzzer(5)           | Bin 0 -> 6791 bytes
+ 43 files changed, 1 insertion(+)
+
+commit f745777c60455e31d4f30ca0b06f06b8d062b013
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 3 19:14:41 2020 +0330
+
+    minor, debug bit, ops
+
+ src/hb-ot-layout-gsubgpos.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit f253f06cf368d74f1ec5d84c6439ae2a571e99f1
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Mar 3 18:57:13 2020 +0330
+
+    [fuzz] Add another fixed case
+    
+    https://crbug.com/oss-fuzz/14626
+    
+    another numerous subtables count which is fixed by d38360397
+
+ src/hb-ot-layout-gsubgpos.hh                           |   1 +
+ ...testcase-minimized-hb-shape-fuzzer-5712050577211392 | Bin 0 -> 647751 bytes
+ 2 files changed, 1 insertion(+)
+
+commit d38360397609d2f3d2dd115bcb0f58d10a1bb4a3
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Mar 2 22:41:08 2020 +0330
+
+    Limit OT::Lookup subtables (#2219)
+    
+    Fixes https://crbug.com/oss-fuzz/13943
+
+ src/hb-ot-layout-common.hh                             |   7 +++++--
+ src/hb-sanitize.hh                                     |  13 +++++++++++--
+ ...testcase-minimized-hb-shape-fuzzer-5666162551029760 | Bin 0 -> 202319 bytes
+ 3 files changed, 16 insertions(+), 4 deletions(-)
+
+commit 29efd964f20625e12e697d74ae226b0d3b158aa5
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Mar 2 14:22:29 2020 +0330
+
+    [fuzz] Add cases that marked as wontfix
+    
+    Let's see if they were really false alarms, if so, let's just have them.
+
+ ...usterfuzz-testcase-hb-shape-fuzzer-5072750494875648 | Bin 0 -> 35 bytes
+ ...usterfuzz-testcase-hb-shape-fuzzer-5638729035677696 | Bin 0 -> 946 bytes
+ ...usterfuzz-testcase-hb-shape-fuzzer-5643643755429888 | Bin 0 -> 1776 bytes
+ ...usterfuzz-testcase-hb-shape-fuzzer-5644258942386176 | Bin 0 -> 61 bytes
+ ...usterfuzz-testcase-hb-shape-fuzzer-5657878543728640 | Bin 0 -> 1828 bytes
+ ...usterfuzz-testcase-hb-shape-fuzzer-5680362806575104 | Bin 0 -> 564 bytes
+ ...usterfuzz-testcase-hb-shape-fuzzer-5689920685867008 | Bin 0 -> 42 bytes
+ ...sterfuzz-testcase-hb-subset-fuzzer-5756332481708032 | Bin 0 -> 6065 bytes
+ ...estcase-minimized-hb-subset-fuzzer-5121706490593280 | Bin 0 -> 161328 bytes
+ ...estcase-minimized-hb-subset-fuzzer-5759783999635456 | Bin 0 -> 165952 bytes
+ 10 files changed, 0 insertions(+), 0 deletions(-)
+
+commit 60262e4ca9dc8acd740e47b14d6e7b586c16ceac
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Feb 29 22:57:59 2020 +0330
+
+    [var] Build end-points array on gvar itself
+
+ src/hb-ot-glyf-table.hh     | 13 +++----------
+ src/hb-ot-var-gvar-table.hh |  8 ++++++--
+ 2 files changed, 9 insertions(+), 12 deletions(-)
+
+commit cb65150fecee43b47cb706ed51be4f428b8f33df
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Feb 29 16:12:54 2020 +0330
+
+    [draw] minor
+
+ test/fuzzing/hb-draw-fuzzer.cc | 6 ------
+ 1 file changed, 6 deletions(-)
+
+commit 44169f3396af0c60ebc74fd4c624988d871dcf0f
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Feb 29 16:04:03 2020 +0330
+
+    [draw] Fix invalid rendering of some glyph on Estedad-VF
+    
+    Basically reverts 11f3fca so I can do the same tested and better later
+    
+    Fixes #2215
+
+ src/hb-ot-glyf-table.hh       |  15 ++++++++---
+ src/hb-ot-var-gvar-table.hh   |  26 ++++++------------
+ test/api/fonts/Estedad-VF.ttf | Bin 0 -> 94364 bytes
+ test/api/fonts/README         |   2 ++
+ test/api/test-draw.c          |  61 ++++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 83 insertions(+), 21 deletions(-)
+
+commit 86c40b3a1d8c7d970ce1b450f4dfadef8d9d0126
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Feb 29 14:11:46 2020 +0330
+
+    [fuzz/draw] Call _get_glyph_extents
+    
+    Other render related APIs also may be added also later such
+    as ot-color and future rendering things.
+
+ test/fuzzing/hb-draw-fuzzer.cc | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+commit 5ab50eebd7846b79528058a1e4e83bb181416c30
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sat Feb 29 01:32:29 2020 -0800
+
+    collect_unicodes() with clamp, calling add_range()
+    
+    Use add_range instead an inner loop, clamp its input number by
+    number of glyphs a face has.
+    
+    Even the face cmap12 and 13 have 32-bit hb_codepoint_t, which is here
+    used to make timeout, face's maxp has 16-bit gid limitation at least for now,
+    using that makes sure we both fix and the timeout and don't need to change
+    much things here also in order to support 32-bit gids also someday.
+    
+    Fixes #2204
+
+ src/hb-face.cc                                     |   2 +-
+ src/hb-ot-cmap-table.hh                            |  30 ++++++++++++---------
+ .../fonts/1746cad6bc3fb2b355db50a5af37c9b58d9ad376 | Bin 0 -> 23293 bytes
+ 3 files changed, 19 insertions(+), 13 deletions(-)
+
+commit 414529e45a4cb3ee444c2dd5a2a9cbd6be0598af
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Feb 28 15:15:55 2020 -0800
+
+    [subset] Limit the number of feature indices processed during script subsetting.
+
+ src/hb-ot-layout-common.hh   | 20 ++++++++++++++++++--
+ src/hb-ot-layout-gsubgpos.hh |  2 +-
+ 2 files changed, 19 insertions(+), 3 deletions(-)
+
+commit 75622b0d246eefe5d912a6918d14c7250ebaea78
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Feb 28 14:11:48 2020 -0800
+
+    [subset] Limit the number of features processed in the feature closure.
+
+ src/hb-ot-layout-gsubgpos.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 410b4881d088e924781385d1958878f2923645d0
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Feb 28 10:38:27 2020 -0800
+
+    [subset] Add fuzzer timeout testcase.
+
+ ...estcase-minimized-hb-subset-fuzzer-6276691949518848 | Bin 0 -> 184722 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit c66ee213b70eb204b750675d60f25549d942d3d7
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Feb 27 12:25:01 2020 -0800
+
+    Limit the number of feature indices processed during feature collection.
+
+ src/hb-ot-layout-common.hh |  5 +++++
+ src/hb-ot-layout.cc        | 14 +++++++++++---
+ 2 files changed, 16 insertions(+), 3 deletions(-)
+
+commit e57ced5fc06bd14a579a983db73e94416f6fedf4
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Feb 28 23:29:05 2020 +0330
+
+    [gvar] Add other possibly fixed fuzzer case
+    
+    Speculatively should've been fixed by 61208401
+    
+    https://crbug.com/oss-fuzz/20924 related
+
+ ...zz-testcase-minimized-hb-draw-fuzzer-5750654771658752 | Bin 0 -> 4004 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 758fda728ba5c9d4542ea2385482f7d090ffda0d
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Feb 28 23:19:06 2020 +0330
+
+    [glyf] Don't accept gids higher than maxp's glyphs number
+    
+    This specially becomes concerning on sub-components where a gvar table
+    that is sanitized using maxp's glyphs number overflows when a high gid
+    accepted here goes to it, maybe an additional check can be put there
+    also, this however feels to be enough.
+    
+    Fixes https://crbug.com/oss-fuzz/20944
+
+ src/hb-ot-glyf-table.hh                                  |   1 +
+ ...zz-testcase-minimized-hb-draw-fuzzer-5668491560747008 | Bin 0 -> 8771 bytes
+ 2 files changed, 1 insertion(+)
+
+commit e642aab1166cf7782fb55f1721eba057c2bfd609
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Feb 28 22:24:25 2020 +0330
+
+    [subset] Add source_blob as a hb_subset_context_t field (#2203)
+    
+    So no more double sanitizing source table.
+
+ src/hb-ot-color-sbix-table.hh | 23 ++++++++---------------
+ src/hb-ot-var-gvar-table.hh   | 27 ++++++---------------------
+ src/hb-subset.cc              |  2 +-
+ src/hb-subset.hh              |  5 ++++-
+ 4 files changed, 19 insertions(+), 38 deletions(-)
+
+commit e90213868b121af72d19b6022a671ebe72ff55aa
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Feb 28 21:24:27 2020 +0330
+
+    Revert "collect_unicodes() to check gid < num_glyphs with cmap 12"
+    
+    Didn't fix the case actually, making bots to fail.
+    
+    This reverts commit 15b43a410400c74a32d40f4b89dbea02fa7cd6e1.
+
+ src/hb-face.cc                                     |   2 +-
+ src/hb-ot-cmap-table.hh                            |  30 +++++++++------------
+ .../fonts/1746cad6bc3fb2b355db50a5af37c9b58d9ad376 | Bin 23293 -> 0 bytes
+ 3 files changed, 13 insertions(+), 19 deletions(-)
+
+commit 61208401f41f5d41f32d436cee500c630706f6be
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Feb 28 21:09:07 2020 +0330
+
+    [gvar] Use hb_bytes_t.check_range instead having in house one
+    
+    And use TupleVarHeader calculated size for validity check.
+    
+    Fixes https://crbug.com/oss-fuzz/20919 and possibly other gvar related issues
+
+ src/hb-ot-var-gvar-table.hh                        |  36 ++++++++-------------
+ ...tcase-minimized-hb-draw-fuzzer-5686960406659072 | Bin 0 -> 4004 bytes
+ 2 files changed, 13 insertions(+), 23 deletions(-)
+
+commit 15b43a410400c74a32d40f4b89dbea02fa7cd6e1
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Feb 28 08:45:39 2020 -0800
+
+    collect_unicodes() to check gid < num_glyphs with cmap 12
+    
+    fixes #2204
+
+ src/hb-face.cc                                     |   2 +-
+ src/hb-ot-cmap-table.hh                            |  30 ++++++++++++---------
+ .../fonts/1746cad6bc3fb2b355db50a5af37c9b58d9ad376 | Bin 0 -> 23293 bytes
+ 3 files changed, 19 insertions(+), 13 deletions(-)
+
+commit 868ecf7b2660747f7628df2b3a17a8d68b0325eb
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Feb 28 19:50:30 2020 +0330
+
+    [draw] Add fuzzer runner
+
+ test/fuzzing/Makefile.am              |   3 +
+ test/fuzzing/run-draw-fuzzer-tests.py | 107 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 110 insertions(+)
+
+commit b0749bfaa53cdf34180b2d15c6e3840f03d5ece2
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Fri Feb 14 13:49:44 2020 -0800
+
+    [subset] GDEF LigCaretList subsetting support
+
+ src/hb-ot-layout-gdef-table.hh | 73 +++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 72 insertions(+), 1 deletion(-)
+
+commit 002f0e20c4c6e35e0ff379ff58cfe1e19067133a
+Author: ariza <ariza at adobe.com>
+Date:   Thu Feb 27 17:34:26 2020 -0800
+
+    reimplment serialize_int using check_assign()
+
+ src/hb-cff-interp-common.hh | 23 ++++++++++-------------
+ src/hb-ot-cff-common.hh     | 24 +++++++++++++-----------
+ src/hb-subset-cff1.cc       |  2 +-
+ 3 files changed, 24 insertions(+), 25 deletions(-)
+
+commit 14b134379d7a34af1a78b0ea930a6fab79779723
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Feb 27 15:58:58 2020 +0330
+
+    [gvar] Minor, check whether sub_array result also have enough room
+
+ src/hb-ot-var-gvar-table.hh | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+commit 8eba66c1c6d19bcc779a3b4e7b68251511986ee8
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Feb 27 15:58:58 2020 +0330
+
+    [gvar] Fix invalid memory access by refactoring GlyphVarData fetch logic
+    
+    Fixes https://crbug.com/oss-fuzz/20906
+
+ src/hb-ot-var-gvar-table.hh                        |  70 +++++++++++----------
+ ...tcase-minimized-hb-draw-fuzzer-5088336521986048 | Bin 0 -> 1413 bytes
+ 2 files changed, 36 insertions(+), 34 deletions(-)
+
+commit f44e1dc07d24abb4c9311d4a55725219665ca84c
+Author: Evgeniy Reizner <razrfalcon at gmail.com>
+Date:   Thu Feb 27 02:02:22 2020 +0200
+
+    Fix spelling.
+
+ src/hb-ot-glyf-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5ad761b943721c3541d0ca0472f34f7d54b89b5b
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Feb 11 13:05:40 2020 -0800
+
+    [subset] GDEF MarkGlyphSets subsetting support
+
+ src/hb-ot-layout-gdef-table.hh                     |  43 ++++++++++++++++++++-
+ test/subset/data/Makefile.am                       |   1 +
+ test/subset/data/Makefile.sources                  |   1 +
+ .../Roboto-Regular.default.1E00,303.ttf            | Bin 0 -> 2456 bytes
+ .../layout.gdef/Roboto-Regular.default.303.ttf     | Bin 0 -> 2128 bytes
+ .../Roboto-Regular.default.309,20,30F.ttf          | Bin 0 -> 2220 bytes
+ .../layout.gdef/Roboto-Regular.default.323.ttf     | Bin 0 -> 2020 bytes
+ .../Roboto-Regular.default.41,42,43.ttf            | Bin 0 -> 2480 bytes
+ .../Roboto-Regular.drop-hints.1E00,303.ttf         | Bin 0 -> 1204 bytes
+ .../layout.gdef/Roboto-Regular.drop-hints.303.ttf  | Bin 0 -> 1012 bytes
+ .../Roboto-Regular.drop-hints.309,20,30F.ttf       | Bin 0 -> 1068 bytes
+ .../layout.gdef/Roboto-Regular.drop-hints.323.ttf  | Bin 0 -> 952 bytes
+ .../Roboto-Regular.drop-hints.41,42,43.ttf         | Bin 0 -> 1188 bytes
+ .../Roboto-Regular.keep-gdef.1E00,303.ttf          | Bin 0 -> 2520 bytes
+ .../layout.gdef/Roboto-Regular.keep-gdef.303.ttf   | Bin 0 -> 2192 bytes
+ .../Roboto-Regular.keep-gdef.309,20,30F.ttf        | Bin 0 -> 2288 bytes
+ .../layout.gdef/Roboto-Regular.keep-gdef.323.ttf   | Bin 0 -> 2084 bytes
+ .../Roboto-Regular.keep-gdef.41,42,43.ttf          | Bin 0 -> 2536 bytes
+ test/subset/data/tests/layout.gdef.tests           |  14 +++++++
+ 19 files changed, 58 insertions(+), 1 deletion(-)
+
+commit fcd7f33bbb12d66b3a50caa448cb91ef7c0daa9e
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Mon Feb 10 10:36:50 2020 -0800
+
+    [subset] GDEF glyphClassDef subsetting support
+    glyphClassDef uses the same ClassDef format. However, glyphClassDef table
+    uses predefined class values so we do not remap class values.
+
+ src/hb-ot-layout-common.hh                         |  42 ++++++++++++---------
+ ...Mplus1p-Regular.keep-gdef.1D715,1D7D8,41,42.ttf | Bin 0 -> 2148 bytes
+ .../japanese/Mplus1p-Regular.keep-gdef.25771.ttf   | Bin 0 -> 1860 bytes
+ ...lar.keep-gdef.3042,3044,3046,3048,304A,304B.ttf | Bin 0 -> 2572 bytes
+ ...lar.keep-gdef.3042,3044,3046,73E0,5EA6,8F38.ttf | Bin 0 -> 2816 bytes
+ .../Mplus1p-Regular.keep-gdef.61,63,65,6B.ttf      | Bin 0 -> 2116 bytes
+ ...lar.keep-gdef.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 0 -> 3112 bytes
+ .../japanese/Mplus1p-Regular.keep-gdef.660E.ttf    | Bin 0 -> 1852 bytes
+ test/subset/data/profiles/keep-gdef.txt            |   1 +
+ test/subset/data/tests/japanese.tests              |   1 +
+ 10 files changed, 26 insertions(+), 18 deletions(-)
+
+commit 50129b03a1cc0bb08231d46571a34aca85b7b14f
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Feb 25 17:39:59 2020 -0800
+
+    Add a reverse () call to hb_array_t.
+
+ src/hb-array.hh         | 15 +++++++++++++++
+ src/hb-ot-cmap-table.hh | 26 +++++++++++++++-----------
+ 2 files changed, 30 insertions(+), 11 deletions(-)
+
+commit 38c6598c1c7d645b46970ec2e7f345d45dd38380
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Feb 25 17:20:05 2020 -0800
+
+    Switch to C style comments.
+
+ src/hb-ot-cmap-table.hh | 38 +++++++++++++++++++++-----------------
+ 1 file changed, 21 insertions(+), 17 deletions(-)
+
+commit 52b6e0baa0c479511d3e06d3a71a65f73e88cfdc
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Feb 10 12:26:40 2020 -0800
+
+    When serializing cmap14 order the offsets from smallest to largest.
+    Current versions of OTS fail fonts with cmap 14's who's last offset does not point to the a block at the end of the table.
+
+ src/hb-ot-cmap-table.hh | 115 ++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 83 insertions(+), 32 deletions(-)
+
+commit a99134c5bee945e144b9429ba4a4d58ff18313b4
+Author: ariza <ariza at adobe.com>
+Date:   Wed Feb 26 09:58:03 2020 -0800
+
+    add oss-fuzz 20886 test file
+
+ ...-testcase-minimized-hb-subset-fuzzer-5641370503217152 | Bin 0 -> 3099 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit d0aaba5c5087781c7231e26fdd190c65baebde95
+Author: ariza <ariza at adobe.com>
+Date:   Wed Feb 26 09:35:32 2020 -0800
+
+    fixes oss-fuzz 20886
+    
+    hb_set_t::resize () is needed after compact()
+
+ src/hb-set.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 05a25c1a5bfbc70ed9151ab9c368ddc6aa4e8fd4
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 26 19:35:27 2020 +0330
+
+    [cff] minor, remove unused fields
+
+ src/hb-ot-cff1-table.cc | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+commit 9fe0dc3464391e1cd51c01c499b6110d99895d25
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 26 17:40:44 2020 +0330
+
+    [draw] Pass draw_helper_t itself around instead recreating it
+    
+    Specially helpful if we want to change the design
+
+ src/hb-draw.cc          |  7 ++++---
+ src/hb-draw.hh          |  4 ++--
+ src/hb-ot-cff1-table.cc | 43 ++++++++++++++++++++-----------------------
+ src/hb-ot-cff1-table.hh |  4 ++--
+ src/hb-ot-cff2-table.cc | 23 ++++++++++-------------
+ src/hb-ot-cff2-table.hh |  4 ++--
+ src/hb-ot-glyf-table.hh | 42 ++++++++++++++++++++----------------------
+ 7 files changed, 60 insertions(+), 67 deletions(-)
+
+commit 1b8b8638980d4276f424e8c4f59731f50832d119
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 26 16:36:48 2020 +0330
+
+    minor
+
+ test/fuzzing/hb-draw-fuzzer.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 4cdaa9d1f4ca4e9225fab6383f16d24f9a323995
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 26 16:27:04 2020 +0330
+
+    [glyf] Simplify contour end logic
+    
+    So no need for infinite loop here
+
+ src/hb-ot-glyf-table.hh | 53 +++++++++++++++++++++----------------------------
+ 1 file changed, 23 insertions(+), 30 deletions(-)
+
+commit 132fcfbc4733c521733e9fea84e19c58746980f2
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 26 16:15:17 2020 +0330
+
+    [fuzz] minor don't abort main.cc when the file was empty or not found
+
+ test/fuzzing/main.cc | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+commit 84163c83d398665c694b1c90d1a94344e95464b7
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 26 15:58:11 2020 +0330
+
+    [draw] Skip commands and paths not contributing anything
+    
+    They aren't contributing to rendering and making issue for stroking, let's skip them
+    ourselves as Skia does also https://skia-review.googlesource.com/c/skia/+/268166
+    
+    They are useful for extracting extents and so which that functionality won't be effected by this change.
+
+ src/hb-draw.hh                 | 22 ++++++++++++++++------
+ test/api/test-draw.c           |  8 ++++----
+ test/fuzzing/hb-draw-fuzzer.cc |  8 +++++++-
+ 3 files changed, 27 insertions(+), 11 deletions(-)
+
+commit 073d4954e01c45e8dd1cf63a53ad35563f46ef17
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 26 15:40:40 2020 +0330
+
+    [draw] Port glyf path extract to draw_helper_t
+
+ src/hb-draw.hh          |  44 +++++++++++++-------
+ src/hb-ot-glyf-table.hh | 104 +++++++++++-------------------------------------
+ 2 files changed, 52 insertions(+), 96 deletions(-)
+
+commit 0ebf3a4e62f5f54f3557e954f4493b4de43990dd
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 26 15:14:41 2020 +0330
+
+    [draw] Move common CFF path building logic to draw_helper_t
+
+ src/hb-draw.hh          | 70 +++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-cff1-table.cc | 60 +++++++++---------------------------------
+ src/hb-ot-cff2-table.cc | 67 ++++++++--------------------------------------
+ 3 files changed, 93 insertions(+), 104 deletions(-)
+
+commit c400cb8863abb5f894e021da5d524c1e28b1e980
+Merge: c21eb86b 4081439d
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Feb 25 16:06:03 2020 -0800
+
+    Re-implement hb_set_t::del_range (#2194)
+    
+    * optimize hb_set_del_range()
+    
+    fix issue #2193
+    
+    * fixed bug & added tests
+    
+    * coding & comment tweaks
+
+commit c21eb86bfd671b04aca54395988cbfe6c9fd2e27
+Merge: 152000d9 4aa354be
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 26 02:54:38 2020 +0330
+
+    Merge pull request #2163 from harfbuzz/absolute-link
+    
+    added add_link_abs()
+
+commit 4081439d2a49f5dfde2f9043b0e53f2008ff211f
+Author: ariza <ariza at adobe.com>
+Date:   Tue Feb 25 15:03:12 2020 -0800
+
+    tweak reflecting review & add test cases
+
+ src/hb-set.hh       | 37 ++++++++++++++++++++++---------------
+ test/api/test-set.c | 53 +++++++++++++++++++++++++++++++++++------------------
+ 2 files changed, 57 insertions(+), 33 deletions(-)
+
+commit 152000d9c761233261cfbfb22e771eb97576aab3
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Feb 25 20:07:25 2020 +0330
+
+    [fuzz] Practice variations on font object
+
+ test/api/test-ot-face.c         |  8 +++-----
+ test/fuzzing/hb-shape-fuzzer.cc | 16 ++++++++++++++--
+ 2 files changed, 17 insertions(+), 7 deletions(-)
+
+commit 036d868913b2d4564880d588eb67c48924bd861b
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Feb 24 10:34:51 2020 +0330
+
+    [draw] Add a fuzzer
+    
+    Specially checks correctness of the API semantics:
+    * no move happens when a path is already opened with move-to.
+    * no path will be left open and close-path will happen at the end of opened paths.
+    * no path opens with a move-to and will be closed with no length.
+    * paths start and ending points matches.
+    * no line/quadratic/cubic command will be issued when no path is started.
+
+ test/fuzzing/Makefile.am       |   9 ++++
+ test/fuzzing/hb-draw-fuzzer.cc | 117 +++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 126 insertions(+)
+
+commit de896278f7534c876d28d9b5cf344c5d707d3490
+Author: ariza <ariza at adobe.com>
+Date:   Tue Feb 25 07:12:20 2020 -0800
+
+    coding & comment tweaks
+
+ src/hb-set.hh | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit 2f97aa65e556b6ce0ce220c088a3da5504738189
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Feb 25 18:07:44 2020 +0330
+
+    [cff] Make sure previous is ended on processing a seac
+
+ src/hb-ot-cff1-table.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit acc2d4738eec3444b6f789ccbd30a7790383f2c8
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Feb 25 18:05:48 2020 +0330
+
+    [cff] Make path extract easier to read and more defensive
+
+ src/hb-ot-cff1-table.cc | 8 ++++----
+ src/hb-ot-cff2-table.cc | 8 ++++----
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+commit b59eb54f70c20d0260026067177a958e11c3a044
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Feb 25 10:30:59 2020 +0330
+
+    [glyf] Refactor, move get_points inside Glyph
+
+ src/hb-ot-glyf-table.hh | 267 +++++++++++++++++++++++-------------------------
+ 1 file changed, 125 insertions(+), 142 deletions(-)
+
+commit 173b745da8bfd8bda710c90ab48427364068eeb5
+Author: ariza <ariza at adobe.com>
+Date:   Mon Feb 24 22:56:57 2020 -0800
+
+    fixed bug & added tests
+
+ src/hb-set.hh       |  3 ++-
+ test/api/test-set.c | 10 ++++++----
+ 2 files changed, 8 insertions(+), 5 deletions(-)
+
+commit a5012e97c4a392d2788777580e0d08b44e036750
+Author: ariza <ariza at adobe.com>
+Date:   Mon Feb 24 17:09:48 2020 -0800
+
+    optimize hb_set_del_range()
+    
+    fix issue #2193
+
+ src/hb-set.hh       | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++---
+ test/api/test-set.c | 29 +++++++++++++++++++++++++++
+ 2 files changed, 82 insertions(+), 3 deletions(-)
+
+commit 96b71e802fe8d1fa9a14d1dece7935f4eb9789af
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Feb 24 23:00:58 2020 +0330
+
+    [fuzz] make the custom loader to handle multiple files
+    
+    Actually this was the way it used to work :)
+
+ test/fuzzing/main.cc | 27 ++++++++++++---------------
+ 1 file changed, 12 insertions(+), 15 deletions(-)
+
+commit 1f5a54c768159e1bcf1c772ab236737994f638aa
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Feb 24 13:18:24 2020 +0330
+
+    [gvar] fix infinite loop introduced by 11f3fca
+    
+    The attempt on removing end_points had made the code unreadable
+    and has intrdouced infinite, fixed by making the code clear what
+    it tries to achieve.
+
+ src/hb-ot-var-gvar-table.hh       |  22 ++++++++++++++++------
+ test/api/fonts/TestGVAREight.ttf  | Bin 0 -> 4692 bytes
+ test/api/test-ot-metrics-tt-var.c |  18 ++++++++++++++++++
+ 3 files changed, 34 insertions(+), 6 deletions(-)
+
+commit f00eb4ebfa02dea593c4842a7672aa2640a6bbf2
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Feb 24 09:21:25 2020 +0330
+
+    [gvar] Don't compare against Null address
+
+ src/hb-ot-var-gvar-table.hh | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+commit 19b78d56cdec354d4f35bf6ae529f670cba88fb3
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Feb 24 09:08:01 2020 +0330
+
+    [gvar] Accept coord_count even if is higher than gvar's axisCount
+
+ src/hb-ot-var-gvar-table.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 197e2e929b7184b8c1365b08a1b275871fc08012
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Feb 24 08:53:53 2020 +0330
+
+    [gvar] Return gracefully even if gvar wasn't used at all
+
+ src/hb-ot-var-gvar-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 346ab9884b019ce919c2ab2ee3a3c373bec6fc33
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Feb 24 08:46:08 2020 +0330
+
+    [gvar] Return gracefully even if coords_count != gvar's axis count
+    
+    It shouldn't be that common to have the situation, even so, no need to
+    reject entire a glyph even if gvar isn't used.
+
+ src/hb-ot-var-gvar-table.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 5f23a76e99f627f06ff7e56dddd9b53b4cbaae84
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Feb 24 08:23:23 2020 +0330
+
+    [cff] Don't remove coords const qualification
+    
+    We should find some way to audit all the const removals, perhaps by
+    enabling -Wold-style-cast warning on the project and turning all the
+    implicit const removals to const_cast.
+
+ src/hb-cff2-interp-cs.hh   | 5 ++---
+ src/hb-ot-layout-common.hh | 4 ++--
+ 2 files changed, 4 insertions(+), 5 deletions(-)
+
+commit ff5223ba6075ea4d9c9844e3733ad7a0dc5875bd
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sun Feb 23 15:53:21 2020 -0800
+
+    remove invalid glyphs from closure (#2188)
+    
+    fix issue #2186
+
+ src/hb-ot-layout-gsubgpos.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit e17fd0d91cbd69fa9c01b20bd5c448d0a4fe0e67
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Feb 23 23:58:39 2020 +0330
+
+    [tools] More on py3 compatibility
+
+ src/gen-tag-table.py          | 23 +++++++----------------
+ src/gen-vowel-constraints.py  | 13 ++++---------
+ test/shaping/hb-diff          |  2 +-
+ test/shaping/hb_test_tools.py |  6 +++---
+ 4 files changed, 15 insertions(+), 29 deletions(-)
+
+commit 0cf050a7b13703e0d665f8dd263cc0d22a95c4f1
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Feb 23 23:00:48 2020 +0330
+
+    [draw] Merge consequent move-to commands of CFF/CFF2
+
+ src/hb-ot-cff1-table.cc     |   4 ++--
+ src/hb-ot-cff2-table.cc     |   7 ++-----
+ test/api/fonts/Stroking.otf | Bin 0 -> 1060 bytes
+ test/api/test-draw.c        |  26 +++++++++++++++++++++++++-
+ 4 files changed, 29 insertions(+), 8 deletions(-)
+
+commit 86bd5a0ba12e389eb0742bf63eb9c88ca3fd8786
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Feb 23 22:46:26 2020 +0330
+
+    [draw] End CFF paths with a line-to
+    
+    Issue a line-to command when start and end point of a path isn't same, matches freetype also.
+
+ src/hb-ot-cff1-table.cc | 35 ++++++++++++++++++++++++++++++++---
+ src/hb-ot-cff2-table.cc | 40 ++++++++++++++++++++++++++++++++++++----
+ test/api/test-draw.c    | 16 +++++++++-------
+ 3 files changed, 77 insertions(+), 14 deletions(-)
+
+commit a46ba770ab6ce2f3fd2c420f550600d2589642d3
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Feb 22 17:15:00 2020 +0330
+
+    [number] minor
+
+ src/hb-number-parser.hh | 4 ++--
+ src/hb-number-parser.rl | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 4aa354beba8b01f32257225de052b5e6a6feab3a
+Author: ariza <ariza at adobe.com>
+Date:   Thu Feb 20 05:03:15 2020 -0800
+
+    chain second OffsetTo::serialize_copy() to first
+
+ src/hb-open-type.hh | 18 ++----------------
+ 1 file changed, 2 insertions(+), 16 deletions(-)
+
+commit 6120f50c8f52ff2e8e3c7d4f86f17fc259dcec50
+Author: ariza <ariza at adobe.com>
+Date:   Wed Feb 19 13:55:39 2020 -0800
+
+    fix Head with link.bias
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e65bff09433b66c207f1c40cd6e5b73c7f19d7cd
+Author: ariza <ariza at adobe.com>
+Date:   Wed Feb 19 13:38:04 2020 -0800
+
+    workaround whence_t as bit-field
+
+ src/hb-serialize.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 1aed6d223ccf7e3cce5ed277200c57d4ecf9e2a7
+Author: ariza <ariza at adobe.com>
+Date:   Wed Feb 19 13:20:29 2020 -0800
+
+    fix whence=Head; position as 28 bits
+
+ src/hb-serialize.hh | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+commit 4ca8e0d9891591c56ecca7e4cea3e06c6a5a8e38
+Author: ariza <ariza at adobe.com>
+Date:   Wed Feb 19 12:52:18 2020 -0800
+
+    re-implement Tail; rewrote name table with it
+
+ src/hb-open-type.hh     | 24 ++++++++++++++++++++
+ src/hb-ot-name-table.hh | 16 ++++----------
+ src/hb-serialize.hh     | 58 ++++++++++++++++++-------------------------------
+ 3 files changed, 49 insertions(+), 49 deletions(-)
+
+commit c1313e4be24017478deacfec1d9ee0284c411bbd
+Author: ariza <ariza at adobe.com>
+Date:   Mon Feb 17 17:33:18 2020 -0800
+
+    minor: undid unintended change
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9c65680b48fc993b31526c8aa9b9b71d772fdb52
+Author: ariza <ariza at adobe.com>
+Date:   Mon Feb 17 16:59:45 2020 -0800
+
+    rename enums to avoid conflict on win
+
+ src/hb-serialize.hh | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit 555f6f1daa5cc1365930e2b6ed7283c704b3b438
+Author: ariza <ariza at adobe.com>
+Date:   Mon Feb 17 16:29:40 2020 -0800
+
+    merge add_link_abs() into add_link()
+
+ src/hb-serialize.hh | 92 ++++++++++++++++++++++++++---------------------------
+ 1 file changed, 46 insertions(+), 46 deletions(-)
+
+commit 017cd945bf6351a89c661ba00b0f7e1dad69b52a
+Author: ariza <ariza at adobe.com>
+Date:   Thu Feb 6 16:11:58 2020 -0800
+
+    added add_link_abs()
+
+ src/hb-serialize.hh | 69 ++++++++++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 58 insertions(+), 11 deletions(-)
+
+commit 07504569d5e7ca2f7da987fc016fc4141eeca263
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Feb 21 13:05:44 2020 +0330
+
+    [gsub] minor format
+
+ src/hb-ot-layout-gsub-table.hh | 19 +++++++++----------
+ 1 file changed, 9 insertions(+), 10 deletions(-)
+
+commit 411225426ffca0b93f4e83f7a488a62a54b17880
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Feb 20 13:43:06 2020 -0800
+
+    Fix glyph closure for alternate substitution.
+    It was not filtering on the glyphs to be retained.
+
+ src/hb-ot-layout-gsub-table.hh                           |   1 +
+ test/subset/data/Makefile.am                             |   1 +
+ test/subset/data/Makefile.sources                        |   1 +
+ ...te_substitution.keep-layout-retain-gids.53A9,53F1.otf | Bin 0 -> 5108 bytes
+ ...ternate_substitution.keep-layout-retain-gids.53A9.otf | Bin 0 -> 4676 bytes
+ ...ternate_substitution.keep-layout-retain-gids.53F1.otf | Bin 0 -> 3012 bytes
+ ...tion.keep-layout-retain-gids.retain-all-codepoint.otf | Bin 0 -> 6820 bytes
+ ...gsub_alternate_substitution.keep-layout.53A9,53F1.otf | Bin 0 -> 4984 bytes
+ .../gsub_alternate_substitution.keep-layout.53A9.otf     | Bin 0 -> 4524 bytes
+ .../gsub_alternate_substitution.keep-layout.53F1.otf     | Bin 0 -> 2816 bytes
+ ...ate_substitution.keep-layout.retain-all-codepoint.otf | Bin 0 -> 6728 bytes
+ test/subset/data/fonts/gsub_alternate_substitution.otf   | Bin 0 -> 8448 bytes
+ test/subset/data/tests/layout.gsub3.tests                |  12 ++++++++++++
+ 13 files changed, 15 insertions(+)
+
+commit da37880e172c207001ceff65c51276538a2d90db
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Feb 20 19:01:43 2020 +0330
+
+    [draw] Add a private bit field instead null-checking quad-to callback
+    
+    This doesn't imply the the design is good or stable just is better
+    to not fail due to null quad-to callback so as our quad-cubic curves
+    translation is currently table limited which can be revisited anytime.
+
+ src/hb-draw.cc          | 9 ++++++++-
+ src/hb-draw.hh          | 1 +
+ src/hb-ot-glyf-table.hh | 4 ++--
+ 3 files changed, 11 insertions(+), 3 deletions(-)
+
+commit 79b2b8a91fe5c011bda03a5350a3f482e053d0ba
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 19 16:41:13 2020 +0330
+
+    minor
+
+ CMakeLists.txt              | 2 +-
+ m4/ax_cxx_compile_stdcxx.m4 | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 8c652f72fc1323b811b5cde53604f0a71334efa2
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 19 16:32:44 2020 +0330
+
+    Minor, switch to https links where possible
+
+ src/gen-tag-table.py              | 2 +-
+ src/hb-ot-cff1-table.hh           | 2 +-
+ src/hb-ot-shape-complex-arabic.cc | 2 +-
+ src/hb-unicode-emoji-table.hh     | 4 ++--
+ test/api/hb-test.h                | 8 ++++----
+ test/shaping/hb_test_tools.py     | 2 +-
+ 6 files changed, 10 insertions(+), 10 deletions(-)
+
+commit bbcbcafc2579a3d4b1dbe743fa77a0167e3f949c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 19 16:21:47 2020 +0330
+
+    [tool] Minor, move input files link
+
+ src/gen-tag-table.py | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 83db1e117e4d6f5624eafa6fe51b1622a8642b65
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 19 15:15:18 2020 +0330
+
+    [ci] Compatibility with Python 3
+    
+    Disabled CMake test runners as it goes for Python 2 and updated the bots
+    
+    Install Python 3 on macOS 10.12 bot
+
+ .circleci/config.yml | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+commit 8d199077045bd28cc74d4dc66fc6e1a734ea3bda
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 19 14:56:55 2020 +0330
+
+    Remove python2 support from tests/utils scripts
+
+ mingw-ldd.py                                       |  3 +-
+ src/gen-arabic-table.py                            |  4 +-
+ src/gen-def.py                                     |  4 +-
+ src/gen-emoji-table.py                             |  3 +-
+ src/gen-indic-table.py                             |  4 +-
+ src/gen-os2-unicode-ranges.py                      |  6 +-
+ src/gen-tag-table.py                               | 10 +--
+ src/gen-ucd-table.py                               |  4 +-
+ src/gen-use-table.py                               |  4 +-
+ src/gen-vowel-constraints.py                       |  4 +-
+ src/sample.py                                      | 19 +----
+ test/fuzzing/run-shape-fuzzer-tests.py             |  4 +-
+ test/fuzzing/run-subset-fuzzer-tests.py            |  4 +-
+ .../data/text-rendering-tests/extract-tests.py     |  4 +-
+ test/shaping/hb-diff                               |  2 +-
+ test/shaping/hb-diff-colorize                      |  2 +-
+ test/shaping/hb-diff-filter-failures               |  2 +-
+ test/shaping/hb-diff-stat                          |  2 +-
+ test/shaping/hb-unicode-decode                     |  2 +-
+ test/shaping/hb-unicode-encode                     |  2 +-
+ test/shaping/hb-unicode-prettyname                 |  2 +-
+ test/shaping/hb_test_tools.py                      | 86 ++--------------------
+ test/shaping/record-test.sh                        |  2 +-
+ test/shaping/run-tests.py                          |  4 +-
+ test/subset/generate-expected-outputs.py           |  4 +-
+ test/subset/run-tests.py                           |  4 +-
+ test/subset/subset_test_suite.py                   |  2 +-
+ 27 files changed, 35 insertions(+), 158 deletions(-)
+
+commit 2c9fbf5561e4ca5abe93ce3990c0cca3982f3517
+Author: Rico Tzschichholz <ricotz at ubuntu.com>
+Date:   Wed Feb 12 14:59:52 2020 +0100
+
+    Improve GIR build
+
+ CMakeLists.txt  |  6 ++++--
+ src/Makefile.am | 11 ++++++++++-
+ 2 files changed, 14 insertions(+), 3 deletions(-)
+
+commit bd13470f23744a5bbe44b7b20846e112579abe0d
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 19 13:19:38 2020 +0330
+
+    [ci] Update Ubuntu bots versions
+
+ .circleci/config.yml | 40 ++++++++++++++++++++--------------------
+ 1 file changed, 20 insertions(+), 20 deletions(-)
+
+commit 493e40ff787222af598b4227f40af7718548f335
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Feb 18 13:09:08 2020 -0800
+
+    [subset] add one empty byte to glyf table
+    if it's going to end up empty after subsetting
+    This will make OTS happy and match what fontTools is doing now.
+
+ src/hb-ot-glyf-table.hh                               |  12 ++++++++++++
+ .../colr/TwemojiMozilla.subset.default.32.ttf         | Bin 4660 -> 4664 bytes
+ ...wemojiMozilla.subset.drop-hints-retain-gids.32.ttf | Bin 4640 -> 4644 bytes
+ .../colr/TwemojiMozilla.subset.drop-hints.32.ttf      | Bin 4640 -> 4644 bytes
+ .../colr/TwemojiMozilla.subset.retain-gids.32.ttf     | Bin 4660 -> 4664 bytes
+ 5 files changed, 12 insertions(+)
+
+commit a7dec0cb515d5f9ffc6cf39e712ed0b0b93bd1f0
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Feb 18 16:22:12 2020 +0330
+
+    [glyf] Tweak path_builder_t
+
+ src/hb-ot-glyf-table.hh | 66 ++++++++++++++++++++++++++++---------------------
+ 1 file changed, 38 insertions(+), 28 deletions(-)
+
+commit d52ea2a42ce9332564cc2f049734545796e0c79b
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Feb 18 15:46:02 2020 +0330
+
+    [glyf] minor
+
+ src/hb-ot-glyf-table.hh | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+commit 3b0c58f811203ac59d96d94ab3675a1b85adb411
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Feb 18 15:42:48 2020 +0330
+
+    [glyf] minor, use private font coords to simplify
+
+ src/hb-ot-glyf-table.hh | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+commit dcd2729e717f48013e07d0b93b64826507c049cc
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Feb 18 15:38:57 2020 +0330
+
+    [glyf] Move contour_bounds_t into scope it is actually used
+
+ src/hb-ot-glyf-table.hh | 81 ++++++++++++++++++++++++-------------------------
+ 1 file changed, 40 insertions(+), 41 deletions(-)
+
+commit 8bb47fa17d53d8e4c729d427b7a5d49d8e14953c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Feb 18 15:06:43 2020 +0330
+
+    [glyf] minor, spacing
+
+ src/hb-ot-glyf-table.hh | 46 +++++++++++++++++++++++-----------------------
+ 1 file changed, 23 insertions(+), 23 deletions(-)
+
+commit 21a5fe4f0981bbae8eaa9caec9c288e44c716470
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Feb 18 14:38:55 2020 +0330
+
+    [glyf] Make returning phantoms to not require another vector
+
+ src/hb-ot-glyf-table.hh | 27 +++++++++++++--------------
+ 1 file changed, 13 insertions(+), 14 deletions(-)
+
+commit 5c03fbe7e0b563ac0f1ce8f867bd747c5e72da86
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Feb 18 13:55:28 2020 +0330
+
+    [glyf] do a phantom only iteration when possible
+
+ src/hb-ot-glyf-table.hh | 50 +++++++++++++++++++++++++++++++------------------
+ 1 file changed, 32 insertions(+), 18 deletions(-)
+
+commit 11f3fca01d6840f3a690b59040ad7452e5343abf
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Feb 18 12:53:20 2020 +0330
+
+    [glyf/gvar] Remove need of passing end points vector around
+
+ src/hb-ot-glyf-table.hh     | 30 +++++++++---------------------
+ src/hb-ot-var-gvar-table.hh | 24 ++++++++++++------------
+ 2 files changed, 21 insertions(+), 33 deletions(-)
+
+commit 0f2c2d989b6ad4ddd5bb7d64d90aa3e57dc85a68
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Feb 18 11:52:16 2020 +0330
+
+    [glyf] Push consumer machine one more level further
+
+ src/hb-ot-glyf-table.hh | 69 +++++++++++++++++++++++++------------------------
+ 1 file changed, 35 insertions(+), 34 deletions(-)
+
+commit 11f5f7c59cbf5a430a99831c1d6f0a8ac93090b0
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Feb 17 23:44:31 2020 +0330
+
+    [glyf] Adopt a state machine like style for the path builder
+    
+    Toward making glyf path reader alloc free at least on gvar absence.
+
+ src/hb-ot-glyf-table.hh | 279 +++++++++++++++++++++++++-----------------------
+ 1 file changed, 145 insertions(+), 134 deletions(-)
+
+commit 60f8f384f9d272a8ae2795e3e7a533bdec452da9
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Feb 17 10:11:49 2020 +0330
+
+    [glyf] Switch to ttf-parser's glyf to path algorithm
+    
+    It consumes each point at a time and doesn't need to know contour size before hand
+
+ src/hb-ot-glyf-table.hh | 151 ++++++++++++++++-------
+ test/api/test-draw.c    | 309 +++++++++++++++++++++++-------------------------
+ 2 files changed, 254 insertions(+), 206 deletions(-)
+
+commit 3c792c2aa5ccbe5760a7415df24e8bf04edf7914
+Author: ariza <ariza at adobe.com>
+Date:   Mon Feb 17 07:18:08 2020 -0800
+
+    add test cases for hb_unwrap_type
+
+ src/test-meta.cc | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 168ceeac496f15b4c81b106cfb790dd5739a0143
+Author: ariza <ariza at adobe.com>
+Date:   Fri Feb 14 11:56:56 2020 -0800
+
+    renamed to hb_unrwap_type(); now recursive
+
+ src/hb-meta.hh | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+commit 71552ecc269c84aab46aa8f078526a546a288925
+Author: ariza <ariza at adobe.com>
+Date:   Thu Feb 13 12:58:22 2020 -0800
+
+    add hb_get_type
+
+ src/hb-meta.hh | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+commit 65858463523aa5abb776d0181bf14da7bfb2931e
+Author: ariza <ariza at adobe.com>
+Date:   Sun Feb 16 17:16:29 2020 -0800
+
+    pop_pack(share=false) in end_serialize()
+    
+    issue #2177
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 39fb57c0e456ec352b2d0a6e6dc61b9bdee85665
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sun Feb 16 08:38:41 2020 -0800
+
+    add share option to pop_pack() (#2176)
+    
+    as a solution for #2164
+
+ src/hb-serialize.hh | 21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+commit 9c6499d9f4556b9755487c1755e4d2386979d82b
+Author: ariza <ariza at adobe.com>
+Date:   Sun Feb 16 00:56:31 2020 -0800
+
+    rewrite read_points() to take lambda & consts args
+    
+    replacing awkward x/y_setter_t structs
+
+ src/hb-ot-glyf-table.hh | 35 ++++++++++++-----------------------
+ 1 file changed, 12 insertions(+), 23 deletions(-)
+
+commit a94d1af193ac1601a1725266dbb0dd51195af98b
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 12 19:25:10 2020 +0330
+
+    [fuzz] minor style fixes
+
+ test/fuzzing/hb-set-fuzzer.cc | 51 +++++++++++++++++++++----------------------
+ 1 file changed, 25 insertions(+), 26 deletions(-)
+
+commit 1c015d3e9f5d514da9647dab258af0a09b3ba550
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 12 19:19:37 2020 +0330
+
+    [fuzz] minor fuzzer case move, oops
+
+ ...fuzz-testcase-minimized-hb-shape-fuzzer-5658272078495744 | Bin
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 49341faee27df689e1c155b1990874c2679b563f
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 12 19:15:16 2020 +0330
+
+    [fuzz] minor, move two fuzzer cases to their correct place
+
+ ...fuzz-testcase-minimized-hb-shape-fuzzer-5658272078495744 | Bin
+ ...erfuzz-testcase-minimized-hb-set-fuzzer-6255224052514816 |   0
+ 2 files changed, 0 insertions(+), 0 deletions(-)
+
+commit d663e28af1b84f27bea9730a9a8f18212387bb7f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 12 15:41:21 2020 +0000
+
+    [serialize] Catch signedness overflows in check_assign()
+    
+    Should address https://github.com/harfbuzz/harfbuzz/pull/2163#pullrequestreview-355137936
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 97229244ebd2e50ec0021ecd442e3c1c27156a5c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 12 15:41:22 2020 +0330
+
+    [fuzzer] Fix hb-set-fuzzer minor overflow issue
+    
+    Size shouldn't be smaller than the struct not its pointer size.
+    
+    Fixes https://crbug.com/oss-fuzz/20655
+
+ .../clusterfuzz-testcase-minimized-hb-set-fuzzer-6255224052514816 | 1 +
+ test/fuzzing/hb-set-fuzzer.cc                                     | 8 ++++----
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+commit 7b42403c1c03e6f2f32fcc792b588ca5a42b1e19
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Feb 11 12:25:57 2020 -0800
+
+    Add explicit values to the set fuzzer enums.
+
+ test/fuzzing/hb-set-fuzzer.cc | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit e805923310af6b502e94903b504477266b55b028
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Feb 11 12:20:54 2020 -0800
+
+    Add a few basic seeds for the set fuzzer.
+
+ test/fuzzing/sets/intersect_01      | Bin 0 -> 21 bytes
+ test/fuzzing/sets/subtract_01       | Bin 0 -> 21 bytes
+ test/fuzzing/sets/symmetric_diff_01 | Bin 0 -> 21 bytes
+ test/fuzzing/sets/union_01          | Bin 0 -> 21 bytes
+ 4 files changed, 0 insertions(+), 0 deletions(-)
+
+commit ff984ed3cdd18290ed3a37c76961176d9f86c9cd
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Feb 11 19:50:51 2020 +0330
+
+    Use multiplication to avoid undefined behaviour per clang
+    
+    Newer versions of MSVC with /we4146 don't like putting negative sign behind a
+    unsigned number as https://github.com/harfbuzz/harfbuzz/pull/2069
+    That however have made https://crbug.com/1050424 this complain:
+      src/hb-ot-color-sbix-table.hh:304:28: runtime error: negation of -2147483648 cannot be represented in type 'int';
+                                            cast to an unsigned type to negate this value to itself
+    which apparently can be fixed using this change.
+    
+    Let's see if this won't make another ubsan complain!
+
+ src/hb-ot-color-sbix-table.hh                             |   2 +-
+ ...zz-testcase-minimized-hb_shape_fuzzer-5633785895911424 | Bin 0 -> 582 bytes
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+
+commit 21e1b1310ab20628d0a81c02b17cc5e49a56a4a7
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Feb 11 17:08:55 2020 +0330
+
+    [colr] minor style fix
+
+ src/hb-ot-color-colr-table.hh | 87 ++++++++++++++++++++++---------------------
+ 1 file changed, 44 insertions(+), 43 deletions(-)
+
+commit cbb45c3ee7be42091a04fc1edfd98a07cfcd864c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Feb 11 16:46:14 2020 +0330
+
+    [subset/colr] minor improve to resolve msvc complain
+    
+    MSVC says,
+      hb-ot-color-colr-table.hh(215): warning C4700: uninitialized local variable 'new_record' used [build\harfbuzz-subset.vcxproj]
+        harfbuzz-subset.vcxproj -> build\Debug\harfbuzz-subset.lib
+
+ src/hb-ot-color-colr-table.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit bca9bc6b92cfdba1118f74c1d1d6fdb1301f5c81
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Feb 6 13:02:58 2020 -0800
+
+    Add hb-set-fuzzer.
+    It fuzzes all of the hb_set process methods (intersection, subtraction, union, and symmetric difference).
+
+ test/fuzzing/Makefile.am      | 11 +++++++
+ test/fuzzing/hb-set-fuzzer.cc | 77 +++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 88 insertions(+)
+
+commit 352ac63ef937629385da7517408cd3d6df7db08a
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Feb 11 03:03:03 2020 +0330
+
+    Fix an unlikely UAF on the deprecated _set_glyph_func API
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/2168
+
+ src/hb-font.cc | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+commit 6a390df8af534cc95c19a07ec2bbdd818ade6cac
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Feb 10 17:19:23 2020 +0330
+
+    [tools] Print unicode links on gen-* tools output
+    
+    As Behdad's review
+
+ src/gen-arabic-table.py      | 13 +++++++------
+ src/gen-emoji-table.py       |  7 ++++---
+ src/gen-indic-table.py       | 12 ++++++------
+ src/gen-ucd-table.py         |  7 ++++---
+ src/gen-use-table.py         | 14 +++++++-------
+ src/gen-vowel-constraints.py |  6 ++++--
+ 6 files changed, 32 insertions(+), 27 deletions(-)
+
+commit 4dc87365d79d9cb0ad85b351b6afe978c3abee3c
+Author: Evgeniy Reizner <razrfalcon at gmail.com>
+Date:   Sun Feb 9 18:39:33 2020 +0200
+
+    Add links to files used by python scripts.
+    
+    Closes #2150
+
+ src/gen-arabic-table.py      | 5 +++++
+ src/gen-emoji-table.py       | 2 ++
+ src/gen-indic-table.py       | 5 +++++
+ src/gen-tag-table.py         | 4 ++++
+ src/gen-ucd-table.py         | 2 ++
+ src/gen-use-table.py         | 6 ++++++
+ src/gen-vowel-constraints.py | 2 ++
+ 7 files changed, 26 insertions(+)
+
+commit 40166eb0e5d4095772059d509aa647ef4118f794
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Feb 8 13:17:06 2020 +0330
+
+    [var] Fix the just introduced hb_font_set_var_coords_design storing bug
+    
+    The memcpy call was using the current coords count which is zero initially so no copy at all.
+    
+    Sad that no test has caught it, should see why, will however with the upcoming style API tests.
+
+ src/hb-font.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5c1a023f67806ee5316518d11f3c236c66fa5c87
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Feb 8 10:57:07 2020 +0330
+
+    [tool] Optimize COLR glyph dump
+    
+    Move palette colors fetching out of gid iteration so not
+    fetching all the colors of a palette each time.
+
+ src/main.cc | 91 +++++++++++++++++++++++++++++++------------------------------
+ 1 file changed, 46 insertions(+), 45 deletions(-)
+
+commit 0b76e8130e1711754184118fdef8523e943d51c9
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Aug 20 15:15:22 2019 +0430
+
+    Don't use _normalize_variations to avoid twice axis fetch
+
+ src/hb-font.cc | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+commit ab2d3ec542799baa0ac056cfcd264e5b3c301d82
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Aug 14 18:42:51 2019 +0430
+
+    [var] Implement hb_font_get_var_coords_design
+    
+    Hold design coords and simulate when normalized coords are set directly.
+
+ docs/harfbuzz-sections.txt |   1 +
+ src/hb-font.cc             | 121 ++++++++++++++++++++++++++++++++++++---------
+ src/hb-font.h              |   4 ++
+ src/hb-font.hh             |   1 +
+ test/api/Makefile.am       |   1 +
+ test/api/test-var-coords.c |  76 ++++++++++++++++++++++++++++
+ 6 files changed, 180 insertions(+), 24 deletions(-)
+
+commit 5a10f3a0551c2e62bc0969fd857033ed53f10943
+Author: Garret Rieger <grieger at google.com>
+Date:   Fri Feb 7 10:38:27 2020 -0800
+
+    Use vector instead of map during page compaction in hb-set.
+
+ src/hb-set.hh | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+commit 2742c8162479a33d9276fa7a1e6deecc65fef5aa
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Jan 28 13:55:31 2020 -0800
+
+    Fix page_map corruption in hb_set_t during process().
+    
+    If a process operation results in less pages then the current set has, it will likely corrupt the page_map since it overwrites page_map entries ahead of where it's processing. This fixes that problem by removing page_map entries that will be dropped. Then dropping orphaned pages and re-indexing retained pages.
+
+ src/hb-set.hh       | 51 ++++++++++++++++++++++++++++++++--
+ test/api/test-set.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 127 insertions(+), 3 deletions(-)
+
+commit eb7849a806699c1c5efc435cf39ee3a0eb9b9e1c
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Feb 5 15:29:03 2020 -0800
+
+    [subset] GPOS6 MarkToMark subsetting support
+
+ src/hb-ot-layout-gpos-table.hh                     |  66 ++++++++++++++++++++-
+ test/subset/data/Makefile.am                       |   1 +
+ test/subset/data/Makefile.sources                  |   1 +
+ ...6_font1.keep-layout-retain-gids.41,42,43,44.otf | Bin 0 -> 2320 bytes
+ ...6_font1.keep-layout-retain-gids.41,42,43,45.otf | Bin 0 -> 2328 bytes
+ ...pos6_font1.keep-layout-retain-gids.41,42,43.otf | Bin 0 -> 2080 bytes
+ .../gpos6_font1.keep-layout-retain-gids.41,42.otf  | Bin 0 -> 1888 bytes
+ ...ont1.keep-layout-retain-gids.41,43,44,45,46.otf | Bin 0 -> 2688 bytes
+ ...pos6_font1.keep-layout-retain-gids.41,43,44.otf | Bin 0 -> 2324 bytes
+ ...pos6_font1.keep-layout-retain-gids.41,43,45.otf | Bin 0 -> 2336 bytes
+ .../gpos6_font1.keep-layout-retain-gids.41,43.otf  | Bin 0 -> 2092 bytes
+ .../gpos6_font1.keep-layout-retain-gids.41.otf     | Bin 0 -> 1872 bytes
+ ...eep-layout-retain-gids.retain-all-codepoint.otf | Bin 0 -> 3748 bytes
+ .../gpos6_font1.keep-layout.41,42,43,44.otf        | Bin 0 -> 1616 bytes
+ .../gpos6_font1.keep-layout.41,42,43,45.otf        | Bin 0 -> 1608 bytes
+ .../gpos6_font1.keep-layout.41,42,43.otf           | Bin 0 -> 1380 bytes
+ .../layout.gpos6/gpos6_font1.keep-layout.41,42.otf | Bin 0 -> 1184 bytes
+ .../gpos6_font1.keep-layout.41,43,44,45,46.otf     | Bin 0 -> 1968 bytes
+ .../gpos6_font1.keep-layout.41,43,44.otf           | Bin 0 -> 1608 bytes
+ .../gpos6_font1.keep-layout.41,43,45.otf           | Bin 0 -> 1608 bytes
+ .../layout.gpos6/gpos6_font1.keep-layout.41,43.otf | Bin 0 -> 1376 bytes
+ .../layout.gpos6/gpos6_font1.keep-layout.41.otf    | Bin 0 -> 1172 bytes
+ ...pos6_font1.keep-layout.retain-all-codepoint.otf | Bin 0 -> 3748 bytes
+ test/subset/data/fonts/gpos6_font1.otf             | Bin 0 -> 4688 bytes
+ test/subset/data/tests/layout.gpos6.tests          |  18 ++++++
+ 25 files changed, 84 insertions(+), 2 deletions(-)
+
+commit 82afc75835364338b8db4e978ad8a0c466e41225
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Feb 4 13:24:37 2020 -0800
+
+    [subset] GPOS4 MarkBase subsetting support
+
+ src/hb-open-type.hh                                |   7 +
+ src/hb-ot-layout-gpos-table.hh                     | 145 ++++++++++++++++++++-
+ test/subset/data/Makefile.am                       |   1 +
+ test/subset/data/Makefile.sources                  |   1 +
+ ...chors_1.keep-layout-retain-gids.41,42,43,44.otf | Bin 0 -> 2344 bytes
+ ...chors_1.keep-layout-retain-gids.41,42,43,45.otf | Bin 0 -> 2352 bytes
+ ..._anchors_1.keep-layout-retain-gids.41,42,43.otf | Bin 0 -> 2104 bytes
+ ...ple_anchors_1.keep-layout-retain-gids.41,42.otf | Bin 0 -> 1912 bytes
+ ...rs_1.keep-layout-retain-gids.41,43,44,45,46.otf | Bin 0 -> 2712 bytes
+ ..._anchors_1.keep-layout-retain-gids.41,43,44.otf | Bin 0 -> 2348 bytes
+ ..._anchors_1.keep-layout-retain-gids.41,43,45.otf | Bin 0 -> 2360 bytes
+ ...ple_anchors_1.keep-layout-retain-gids.41,43.otf | Bin 0 -> 2116 bytes
+ ...ltiple_anchors_1.keep-layout-retain-gids.41.otf | Bin 0 -> 1896 bytes
+ ...eep-layout-retain-gids.retain-all-codepoint.otf | Bin 0 -> 3772 bytes
+ ..._multiple_anchors_1.keep-layout.41,42,43,44.otf | Bin 0 -> 1640 bytes
+ ..._multiple_anchors_1.keep-layout.41,42,43,45.otf | Bin 0 -> 1632 bytes
+ ...os4_multiple_anchors_1.keep-layout.41,42,43.otf | Bin 0 -> 1404 bytes
+ .../gpos4_multiple_anchors_1.keep-layout.41,42.otf | Bin 0 -> 1208 bytes
+ ...ltiple_anchors_1.keep-layout.41,43,44,45,46.otf | Bin 0 -> 1992 bytes
+ ...os4_multiple_anchors_1.keep-layout.41,43,44.otf | Bin 0 -> 1632 bytes
+ ...os4_multiple_anchors_1.keep-layout.41,43,45.otf | Bin 0 -> 1632 bytes
+ .../gpos4_multiple_anchors_1.keep-layout.41,43.otf | Bin 0 -> 1400 bytes
+ .../gpos4_multiple_anchors_1.keep-layout.41.otf    | Bin 0 -> 1196 bytes
+ ..._anchors_1.keep-layout.retain-all-codepoint.otf | Bin 0 -> 3772 bytes
+ .../subset/data/fonts/gpos4_multiple_anchors_1.otf | Bin 0 -> 4712 bytes
+ test/subset/data/tests/layout.gpos4.tests          |  18 +++
+ 26 files changed, 169 insertions(+), 3 deletions(-)
+
+commit 4dc3db7344b464695d3c8cfdb7f3e5d518b4a6ac
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Feb 6 12:12:41 2020 +0330
+
+    Minor, fix warnings raised when built with -std=c++2a
+    
+    Follow up to c184180,
+    
+    It was raising,
+    
+      src/hb-ot-layout-common.hh:1067:63: warning: implicit capture of 'this' with a capture default of '=' is deprecated [-Wdeprecated-this-capture]
+          | hb_filter ([=] (const OffsetTo<TSubTable> &_) { return (this+_).intersects (glyphset, lookup_type); })
+                                                                    ^
+      src/hb-ot-layout-common.hh:1067:19: note: add an explicit capture of 'this' to capture '*this' by reference
+          | hb_filter ([=] (const OffsetTo<TSubTable> &_) { return (this+_).intersects (glyphset, lookup_type); })
+                        ^
+                         , this
+    
+    and
+    
+      src/hb-ot-layout-common.hh:2626:38: warning: implicit capture of 'this' with a capture default of '=' is deprecated [-Wdeprecated-this-capture]
+                      { r.collect_lookups (this, lookup_indexes); })
+                                           ^
+      src/hb-ot-layout-common.hh:2625:18: note: add an explicit capture of 'this' to capture '*this' by reference
+          | hb_apply ([=] (const FeatureTableSubstitutionRecord& r)
+                       ^
+                        , this
+    
+    and
+    
+      src/hb-ot-hdmx-table.hh:141:44: error: implicit capture of 'this' with a capture default of '=' is deprecated [-Werror,-Wdeprecated-this-capture]
+                              return device_record->widthsZ.as_array (get_num_glyphs ()) [_];
+                                                                      ^
+      src/hb-ot-hdmx-table.hh:137:17: note: add an explicit capture of 'this' to capture '*this' by reference
+                  | hb_map ([=] (hb_codepoint_t _)
+                             ^
+                              , this
+
+ .circleci/config.yml       |  4 +++-
+ src/hb-ot-hdmx-table.hh    |  4 ++--
+ src/hb-ot-layout-common.hh | 18 ++++++++----------
+ 3 files changed, 13 insertions(+), 13 deletions(-)
+
+commit b4d3bf1d8a97b77cbea6dd770a16aea618af7aee
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Feb 2 14:32:38 2020 +0330
+
+    [draw] Add hb_draw_funcs_is_immutable and hb_draw_funcs_make_immutable
+
+ docs/harfbuzz-sections.txt |  2 ++
+ src/hb-draw.cc             | 32 ++++++++++++++++++++++++++++++++
+ src/hb-draw.h              |  6 ++++++
+ test/api/test-draw.c       | 13 +++++++++++++
+ 4 files changed, 53 insertions(+)
+
+commit 63b8190db884d9ae88a80336067eab539a44b882
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Feb 6 11:38:11 2020 +0330
+
+    [test] minor
+    
+    Remained from previous naming.
+
+ test/api/test-draw.c | 32 ++++++++++++++++----------------
+ 1 file changed, 16 insertions(+), 16 deletions(-)
+
+commit 3a98c7fae196fd149078af4553b966dc1c8d763b
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Feb 6 01:11:00 2020 +0330
+
+    [glyf] Skip empty contours
+    
+    As https://savannah.nongnu.org/bugs/index.php?57701
+
+ src/hb-ot-glyf-table.hh     |   8 ++++++
+ test/api/fonts/Stroking.ttf | Bin 0 -> 3380 bytes
+ test/api/test-draw.c        |  60 +++++++++++++++++++++++++++++++++++++++++---
+ 3 files changed, 65 insertions(+), 3 deletions(-)
+
+commit c31762e9e89bc440d21a94d8da34608d1649dc85
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 5 23:12:37 2020 +0330
+
+    [test] minor
+    
+    don't test first ten glyph, just testing cp just like other API calls is enough
+
+ test/api/test-ot-face.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 03f778cf3c1170051c3cfb21d9a835252a0123c9
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Wed Feb 5 09:26:45 2020 -0500
+
+    [cmap] remove dead code
+
+ src/hb-ot-cmap-table.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 43253e404d25da31d8b8a57f1fc3ef5c2bb1d1fd
+Merge: 71a20186 774725b4
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 5 17:45:19 2020 +0330
+
+    Merge remote-tracking branch 'upstream/master'
+
+commit 71a201860023e61ef413b5bf05449c624d3ff575
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 5 17:15:50 2020 +0330
+
+    [cbdt] minor, tweak spaces
+
+ src/hb-ot-color-cbdt-table.hh | 437 +++++++++++++++++++++---------------------
+ 1 file changed, 214 insertions(+), 223 deletions(-)
+
+commit eaa2402a793501bc03e7aa7e662333da2b1aadb1
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 5 17:02:03 2020 +0330
+
+    [cbdt] Merge hb-ot-color-cbdt-table.cc into its header file
+    
+    Not needed as far as can be said.
+
+ src/Makefile.sources          |  2 --
+ src/harfbuzz.cc               |  1 -
+ src/hb-ot-color-cbdt-table.cc | 75 -------------------------------------------
+ src/hb-ot-color-cbdt-table.hh | 55 ++++++++++++++++++++++++-------
+ 4 files changed, 43 insertions(+), 90 deletions(-)
+
+commit a7f694d4b0d5e95a6202da926ba3c29df6fbb6f0
+Merge: 43016715 b114b26a
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 5 16:31:21 2020 +0330
+
+    Merge branch 'subset_cblc' into master
+
+commit 774725b43a05d7e44286a809bb3767f18189c1a4
+Author: ckitagawa-work <59700018+ckitagawa-work at users.noreply.github.com>
+Date:   Wed Feb 5 07:43:10 2020 -0500
+
+    [subset] Avoid incorrectly dropping cmap for NotoColorEmoji.ttf
+    
+    NotoColorEmoji.ttf uses two cmap subtables
+    
+     Format 14 | Platform ID 0 | Platform Encoding ID  5
+     Format 12 | Platform ID 3 | Platform Encoding ID 10
+    
+    This combination results in the cmap table being dropped during subsetting despite being valid/required.
+
+ src/hb-ot-cmap-table.hh                            |   2 +-
+ test/api/fonts/NotoColorEmoji.cmap.38,AE,2049.ttf  | Bin 0 -> 10032 bytes
+ test/api/fonts/NotoColorEmoji.cmap.ttf             | Bin 0 -> 10052 bytes
+ test/api/test-subset-cmap.c                        |  44 +++++++++++++++++++++
+ .../cmap14/cmap14_font2.default.4E00,4E02,4E03.otf | Bin 0 -> 1360 bytes
+ .../cmap14/cmap14_font2.default.4E00,4E03.otf      | Bin 0 -> 1236 bytes
+ .../cmap14/cmap14_font2.default.4E00,4E05,4E07.otf | Bin 0 -> 1332 bytes
+ .../cmap14/cmap14_font2.default.4E02,4E03,4E08.otf | Bin 0 -> 1576 bytes
+ .../expected/cmap14/cmap14_font2.default.4E02.otf  | Bin 0 -> 992 bytes
+ .../expected/cmap14/cmap14_font2.default.4E03.otf  | Bin 0 -> 1076 bytes
+ .../cmap14_font2.default.4E05,4E07,4E08,4E09.otf   | Bin 0 -> 1848 bytes
+ .../cmap14/cmap14_font2.default.4E08,4E09.otf      | Bin 0 -> 1716 bytes
+ .../expected/cmap14/cmap14_font2.default.4E08.otf  | Bin 0 -> 1380 bytes
+ .../cmap14_font2.default.retain-all-codepoint.otf  | Bin 0 -> 2344 bytes
+ ...font2.drop-hints-retain-gids.4E00,4E02,4E03.otf | Bin 0 -> 1388 bytes
+ ...ap14_font2.drop-hints-retain-gids.4E00,4E03.otf | Bin 0 -> 1272 bytes
+ ...font2.drop-hints-retain-gids.4E00,4E05,4E07.otf | Bin 0 -> 1400 bytes
+ ...font2.drop-hints-retain-gids.4E02,4E03,4E08.otf | Bin 0 -> 1720 bytes
+ .../cmap14_font2.drop-hints-retain-gids.4E02.otf   | Bin 0 -> 1024 bytes
+ .../cmap14_font2.drop-hints-retain-gids.4E03.otf   | Bin 0 -> 1120 bytes
+ ....drop-hints-retain-gids.4E05,4E07,4E08,4E09.otf | Bin 0 -> 1984 bytes
+ ...ap14_font2.drop-hints-retain-gids.4E08,4E09.otf | Bin 0 -> 1868 bytes
+ .../cmap14_font2.drop-hints-retain-gids.4E08.otf   | Bin 0 -> 1540 bytes
+ ...drop-hints-retain-gids.retain-all-codepoint.otf | Bin 0 -> 2432 bytes
+ .../cmap14_font2.drop-hints.4E00,4E02,4E03.otf     | Bin 0 -> 1292 bytes
+ .../cmap14/cmap14_font2.drop-hints.4E00,4E03.otf   | Bin 0 -> 1168 bytes
+ .../cmap14_font2.drop-hints.4E00,4E05,4E07.otf     | Bin 0 -> 1264 bytes
+ .../cmap14_font2.drop-hints.4E02,4E03,4E08.otf     | Bin 0 -> 1512 bytes
+ .../cmap14/cmap14_font2.drop-hints.4E02.otf        | Bin 0 -> 924 bytes
+ .../cmap14/cmap14_font2.drop-hints.4E03.otf        | Bin 0 -> 1008 bytes
+ ...cmap14_font2.drop-hints.4E05,4E07,4E08,4E09.otf | Bin 0 -> 1780 bytes
+ .../cmap14/cmap14_font2.drop-hints.4E08,4E09.otf   | Bin 0 -> 1648 bytes
+ .../cmap14/cmap14_font2.drop-hints.4E08.otf        | Bin 0 -> 1312 bytes
+ ...map14_font2.drop-hints.retain-all-codepoint.otf | Bin 0 -> 2276 bytes
+ .../cmap14_font2.name-ids.4E00,4E02,4E03.otf       | Bin 0 -> 1292 bytes
+ .../cmap14/cmap14_font2.name-ids.4E00,4E03.otf     | Bin 0 -> 1168 bytes
+ .../cmap14_font2.name-ids.4E00,4E05,4E07.otf       | Bin 0 -> 1264 bytes
+ .../cmap14_font2.name-ids.4E02,4E03,4E08.otf       | Bin 0 -> 1508 bytes
+ .../expected/cmap14/cmap14_font2.name-ids.4E02.otf | Bin 0 -> 924 bytes
+ .../expected/cmap14/cmap14_font2.name-ids.4E03.otf | Bin 0 -> 1008 bytes
+ .../cmap14_font2.name-ids.4E05,4E07,4E08,4E09.otf  | Bin 0 -> 1780 bytes
+ .../cmap14/cmap14_font2.name-ids.4E08,4E09.otf     | Bin 0 -> 1648 bytes
+ .../expected/cmap14/cmap14_font2.name-ids.4E08.otf | Bin 0 -> 1312 bytes
+ .../cmap14_font2.name-ids.retain-all-codepoint.otf | Bin 0 -> 2276 bytes
+ .../cmap14_font2.retain-gids.4E00,4E02,4E03.otf    | Bin 0 -> 1452 bytes
+ .../cmap14/cmap14_font2.retain-gids.4E00,4E03.otf  | Bin 0 -> 1340 bytes
+ .../cmap14_font2.retain-gids.4E00,4E05,4E07.otf    | Bin 0 -> 1468 bytes
+ .../cmap14_font2.retain-gids.4E02,4E03,4E08.otf    | Bin 0 -> 1788 bytes
+ .../cmap14/cmap14_font2.retain-gids.4E02.otf       | Bin 0 -> 1092 bytes
+ .../cmap14/cmap14_font2.retain-gids.4E03.otf       | Bin 0 -> 1188 bytes
+ ...map14_font2.retain-gids.4E05,4E07,4E08,4E09.otf | Bin 0 -> 2048 bytes
+ .../cmap14/cmap14_font2.retain-gids.4E08,4E09.otf  | Bin 0 -> 1936 bytes
+ .../cmap14/cmap14_font2.retain-gids.4E08.otf       | Bin 0 -> 1604 bytes
+ ...ap14_font2.retain-gids.retain-all-codepoint.otf | Bin 0 -> 2496 bytes
+ test/subset/data/fonts/cmap14_font2.otf            | Bin 0 -> 4480 bytes
+ test/subset/data/tests/cmap14.tests                |   1 +
+ 56 files changed, 46 insertions(+), 1 deletion(-)
+
+commit 43016715e1b4d48bc0cf598f374ffa9213b5fe2e
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 5 15:02:20 2020 +0330
+
+    [subset] minor on _subset
+
+ src/hb-subset.cc | 32 ++++++++++++++------------------
+ 1 file changed, 14 insertions(+), 18 deletions(-)
+
+commit dcb5dfc970f2720b9c76efd672c83cf2bdbd4bf0
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 5 15:01:25 2020 +0330
+
+    [subset] minor on tables iteration
+
+ src/hb-subset.cc | 38 +++++++++++++++++---------------------
+ 1 file changed, 17 insertions(+), 21 deletions(-)
+
+commit a8593339e2bd76eef30d0b87a9f509c5f2e8366c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 5 15:00:25 2020 +0330
+
+    [subset] minor on switch statements
+
+ src/hb-subset.cc | 166 ++++++++++++++++++-------------------------------------
+ 1 file changed, 55 insertions(+), 111 deletions(-)
+
+commit b1f63109c6f084ee1b963ebcb85b440f8639e322
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 5 00:28:21 2020 +0330
+
+    [subset] Optimize _is_table_present
+    
+    One call for most of the fonts and no malloc
+
+ src/hb-subset.cc | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit 25707e37e32777aee76317c55a234921c4a3b51e
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Feb 5 00:27:28 2020 +0330
+
+    [cff] minor
+
+ src/hb-ot-cff1-table.hh | 5 +----
+ src/hb-ot-cff2-table.hh | 5 +----
+ 2 files changed, 2 insertions(+), 8 deletions(-)
+
+commit 0d61926ca7c2f3e1d06231dd659ff3c43aa41746
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Tue Feb 4 13:36:51 2020 -0500
+
+    [subset] Keep head when no glyf table
+
+ src/hb-ot-cff1-table.hh | 12 +------
+ src/hb-ot-cff2-table.hh | 12 +------
+ src/hb-ot-head-table.hh | 12 +++++++
+ src/hb-subset.cc        | 91 ++++++++++++++++++++++++++++++-------------------
+ 4 files changed, 69 insertions(+), 58 deletions(-)
+
+commit 7f9b2228a610ad614b77b24503bf02f95e0bf4b8
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Feb 4 23:05:46 2020 +0330
+
+    [glyf] minor
+    
+    Improve using https://developer.blender.org/diffusion/B/browse/master/source/blender/blenlib/intern/freetypefont.c$572
+
+ src/hb-ot-glyf-table.hh | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+commit 5b436033851960ea3638fbf882100b8c04d6d5a3
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Feb 4 21:29:19 2020 +0330
+
+    [subset] Rename _subset2 to _subset
+
+ src/hb-subset.cc | 62 +++++++++++++++++++-------------------------------------
+ 1 file changed, 21 insertions(+), 41 deletions(-)
+
+commit 2792fb8ba1b542b4f974c272a51014aadbecc670
+Author: ariza <ariza at adobe.com>
+Date:   Sun Feb 2 22:00:53 2020 -0800
+
+    first rewrite of cff/cff2 _subset with _subset2
+
+ src/hb-ot-cff1-table.hh |  12 ++----
+ src/hb-ot-cff2-table.hh |  12 ++----
+ src/hb-subset-cff1.cc   | 106 ++++++++++++++++++++----------------------------
+ src/hb-subset-cff1.hh   |   3 +-
+ src/hb-subset-cff2.cc   |  90 ++++++++++++++++------------------------
+ src/hb-subset-cff2.hh   |   3 +-
+ src/hb-subset.cc        |   4 +-
+ 7 files changed, 89 insertions(+), 141 deletions(-)
+
+commit b114b26a56234c17c620f69d30b1f388fc5fb6df
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Tue Feb 4 09:49:24 2020 -0500
+
+    Add guard to copy_glyph_at_idx
+
+ src/hb-ot-color-cbdt-table.cc | 2 +-
+ src/hb-ot-color-cbdt-table.hh | 9 ++++++++-
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+commit b2a68ed587b9931168bba5cae684e40840afc699
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Feb 1 23:16:26 2020 +0330
+
+    [name] Minor, use subtraction instead ternary operator
+    
+    Guess ternary was a bit more legible, apparently however we agreed to use subtraction,
+    https://github.com/harfbuzz/harfbuzz/pull/2139#discussion_r372582005
+
+ src/hb-ot-name-table.hh | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+commit 490ef1cc236ae77b8168218d77cbc3b85ecb81bc
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Jan 28 15:57:33 2020 -0800
+
+    [subset] Fix namerecord ordering
+    This will fix inconsistency with fontTools.
+    Also according to the spec, namerecords must be sorted
+    first by platform ID, then by platform-specific ID,
+    then by language ID, and then by name ID.
+
+ src/hb-ot-name-table.hh                            |  37 ++++++++++++++++++++-
+ ...numMyeongjo-Regular-subset.default.61,62,63.ttf | Bin 0 -> 4128 bytes
+ .../NanumMyeongjo-Regular-subset.default.61,63.ttf | Bin 0 -> 3580 bytes
+ .../NanumMyeongjo-Regular-subset.default.61.ttf    | Bin 0 -> 3156 bytes
+ .../NanumMyeongjo-Regular-subset.default.62.ttf    | Bin 0 -> 3180 bytes
+ .../NanumMyeongjo-Regular-subset.default.63.ttf    | Bin 0 -> 3048 bytes
+ ...Regular-subset.default.retain-all-codepoint.ttf | Bin 0 -> 9524 bytes
+ ...ular-subset.drop-hints-retain-gids.61,62,63.ttf | Bin 0 -> 1452 bytes
+ ...Regular-subset.drop-hints-retain-gids.61,63.ttf | Bin 0 -> 1284 bytes
+ ...jo-Regular-subset.drop-hints-retain-gids.61.ttf | Bin 0 -> 1128 bytes
+ ...jo-Regular-subset.drop-hints-retain-gids.62.ttf | Bin 0 -> 1144 bytes
+ ...jo-Regular-subset.drop-hints-retain-gids.63.ttf | Bin 0 -> 1116 bytes
+ ...drop-hints-retain-gids.retain-all-codepoint.ttf | Bin 0 -> 3536 bytes
+ ...Myeongjo-Regular-subset.drop-hints.61,62,63.ttf | Bin 0 -> 1452 bytes
+ ...numMyeongjo-Regular-subset.drop-hints.61,63.ttf | Bin 0 -> 1276 bytes
+ .../NanumMyeongjo-Regular-subset.drop-hints.61.ttf | Bin 0 -> 1128 bytes
+ .../NanumMyeongjo-Regular-subset.drop-hints.62.ttf | Bin 0 -> 1140 bytes
+ .../NanumMyeongjo-Regular-subset.drop-hints.63.ttf | Bin 0 -> 1104 bytes
+ ...ular-subset.drop-hints.retain-all-codepoint.ttf | Bin 0 -> 3536 bytes
+ ...umMyeongjo-Regular-subset.name-ids.61,62,63.ttf | Bin 0 -> 3924 bytes
+ ...NanumMyeongjo-Regular-subset.name-ids.61,63.ttf | Bin 0 -> 3376 bytes
+ .../NanumMyeongjo-Regular-subset.name-ids.61.ttf   | Bin 0 -> 2952 bytes
+ .../NanumMyeongjo-Regular-subset.name-ids.62.ttf   | Bin 0 -> 2976 bytes
+ .../NanumMyeongjo-Regular-subset.name-ids.63.ttf   | Bin 0 -> 2844 bytes
+ ...egular-subset.name-ids.retain-all-codepoint.ttf | Bin 0 -> 9320 bytes
+ ...ngjo-Regular-subset.name-languages.61,62,63.ttf | Bin 0 -> 4172 bytes
+ ...yeongjo-Regular-subset.name-languages.61,63.ttf | Bin 0 -> 3624 bytes
+ ...umMyeongjo-Regular-subset.name-languages.61.ttf | Bin 0 -> 3200 bytes
+ ...umMyeongjo-Regular-subset.name-languages.62.ttf | Bin 0 -> 3224 bytes
+ ...umMyeongjo-Regular-subset.name-languages.63.ttf | Bin 0 -> 3092 bytes
+ ...-subset.name-languages.retain-all-codepoint.ttf | Bin 0 -> 9568 bytes
+ ...yeongjo-Regular-subset.name-legacy.61,62,63.ttf | Bin 0 -> 4128 bytes
+ ...umMyeongjo-Regular-subset.name-legacy.61,63.ttf | Bin 0 -> 3580 bytes
+ ...NanumMyeongjo-Regular-subset.name-legacy.61.ttf | Bin 0 -> 3156 bytes
+ ...NanumMyeongjo-Regular-subset.name-legacy.62.ttf | Bin 0 -> 3180 bytes
+ ...NanumMyeongjo-Regular-subset.name-legacy.63.ttf | Bin 0 -> 3048 bytes
+ ...lar-subset.name-legacy.retain-all-codepoint.ttf | Bin 0 -> 9524 bytes
+ ...yeongjo-Regular-subset.retain-gids.61,62,63.ttf | Bin 0 -> 4128 bytes
+ ...umMyeongjo-Regular-subset.retain-gids.61,63.ttf | Bin 0 -> 3588 bytes
+ ...NanumMyeongjo-Regular-subset.retain-gids.61.ttf | Bin 0 -> 3156 bytes
+ ...NanumMyeongjo-Regular-subset.retain-gids.62.ttf | Bin 0 -> 3184 bytes
+ ...NanumMyeongjo-Regular-subset.retain-gids.63.ttf | Bin 0 -> 3060 bytes
+ ...lar-subset.retain-gids.retain-all-codepoint.ttf | Bin 0 -> 9524 bytes
+ .../japanese/Mplus1p-Regular.default.25771.ttf     | Bin 1824 -> 1824 bytes
+ .../japanese/Mplus1p-Regular.drop-hints.25771.ttf  | Bin 1096 -> 1096 bytes
+ .../data/fonts/NanumMyeongjo-Regular-subset.ttf    | Bin 0 -> 9964 bytes
+ test/subset/data/tests/basics.tests                |   1 +
+ 47 files changed, 37 insertions(+), 1 deletion(-)
+
+commit e128f8027888536cb8f84f950bd2dbd6ecaf67a9
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Tue Jan 21 13:35:43 2020 -0500
+
+    parent 777ba47b50f6379b9f9abf1d72559316b7116b9e
+    author ckitagawa <ckitagawa at chromium.org> 1579631743 -0500
+    committer ckitagawa <ckitagawa at chromium.org> 1580506176 -0500
+    
+    [subset] Add CBLC support
+
+ src/Makefile.sources                               |   2 +
+ src/harfbuzz.cc                                    |   1 +
+ src/hb-ot-cmap-table.hh                            |   6 +-
+ src/hb-ot-color-cbdt-table.cc                      |  75 ++++
+ src/hb-ot-color-cbdt-table.hh                      | 411 ++++++++++++++++++++-
+ src/hb-ot-head-table.hh                            |  12 +
+ src/hb-subset.cc                                   |  98 +++--
+ test/api/Makefile.am                               |   2 +
+ .../fonts/NotoColorEmoji.subset.default.2049.ttf   | Bin 0 -> 3112 bytes
+ .../api/fonts/NotoColorEmoji.subset.default.39.ttf | Bin 0 -> 1920 bytes
+ ...oji.subset.index_format3.default.38,AE,2049.ttf | Bin 0 -> 7536 bytes
+ .../fonts/NotoColorEmoji.subset.index_format3.ttf  | Bin 0 -> 10112 bytes
+ ...set.multiple_size_tables.default.38,AE,2049.ttf | Bin 0 -> 14140 bytes
+ .../NotoColorEmoji.subset.multiple_size_tables.ttf | Bin 0 -> 19280 bytes
+ test/api/fonts/NotoColorEmoji.subset.ttf           | Bin 0 -> 10124 bytes
+ test/api/test-subset-cbdt.c                        | 158 ++++++++
+ .../fonts/NotoColorEmoji.subset.index_format3.ttf  | Bin 0 -> 10112 bytes
+ .../NotoColorEmoji.subset.multiple_size_tables.ttf | Bin 0 -> 19280 bytes
+ test/fuzzing/fonts/NotoColorEmoji.subset.ttf       | Bin 0 -> 10124 bytes
+ test/subset/data/Makefile.am                       |   1 +
+ test/subset/data/Makefile.sources                  |   1 +
+ .../cbdt/NotoColorEmoji.subset.default.2049.ttf    | Bin 0 -> 3112 bytes
+ .../cbdt/NotoColorEmoji.subset.default.38,2049.ttf | Bin 0 -> 4084 bytes
+ .../cbdt/NotoColorEmoji.subset.default.38,20E3.ttf | Bin 0 -> 3568 bytes
+ ...rEmoji.subset.default.38,39,AE,2049,38,20E3.ttf | Bin 0 -> 10124 bytes
+ .../NotoColorEmoji.subset.default.38,AE,2049.ttf   | Bin 0 -> 7544 bytes
+ .../cbdt/NotoColorEmoji.subset.default.39.ttf      | Bin 0 -> 1920 bytes
+ .../cbdt/NotoColorEmoji.subset.default.AE.ttf      | Bin 0 -> 4412 bytes
+ ...lorEmoji.subset.drop-hints-retain-gids.2049.ttf | Bin 0 -> 3136 bytes
+ ...Emoji.subset.drop-hints-retain-gids.38,2049.ttf | Bin 0 -> 4108 bytes
+ ...Emoji.subset.drop-hints-retain-gids.38,20E3.ttf | Bin 0 -> 3600 bytes
+ ...rop-hints-retain-gids.38,39,AE,2049,38,20E3.ttf | Bin 0 -> 10124 bytes
+ ...ji.subset.drop-hints-retain-gids.38,AE,2049.ttf | Bin 0 -> 7564 bytes
+ ...ColorEmoji.subset.drop-hints-retain-gids.39.ttf | Bin 0 -> 1928 bytes
+ ...ColorEmoji.subset.drop-hints-retain-gids.AE.ttf | Bin 0 -> 4428 bytes
+ .../cbdt/NotoColorEmoji.subset.drop-hints.2049.ttf | Bin 0 -> 3112 bytes
+ .../NotoColorEmoji.subset.drop-hints.38,2049.ttf   | Bin 0 -> 4084 bytes
+ .../NotoColorEmoji.subset.drop-hints.38,20E3.ttf   | Bin 0 -> 3568 bytes
+ ...oji.subset.drop-hints.38,39,AE,2049,38,20E3.ttf | Bin 0 -> 10124 bytes
+ ...NotoColorEmoji.subset.drop-hints.38,AE,2049.ttf | Bin 0 -> 7544 bytes
+ .../cbdt/NotoColorEmoji.subset.drop-hints.39.ttf   | Bin 0 -> 1920 bytes
+ .../cbdt/NotoColorEmoji.subset.drop-hints.AE.ttf   | Bin 0 -> 4412 bytes
+ .../NotoColorEmoji.subset.gap.default.2049.ttf     | Bin 0 -> 3112 bytes
+ .../NotoColorEmoji.subset.gap.default.38,2049.ttf  | Bin 0 -> 4084 bytes
+ .../NotoColorEmoji.subset.gap.default.38,20E3.ttf  | Bin 0 -> 3568 bytes
+ ...ji.subset.gap.default.38,39,AE,2049,38,20E3.ttf | Bin 0 -> 9188 bytes
+ ...otoColorEmoji.subset.gap.default.38,AE,2049.ttf | Bin 0 -> 7544 bytes
+ .../cbdt/NotoColorEmoji.subset.gap.default.39.ttf  | Bin 0 -> 908 bytes
+ .../cbdt/NotoColorEmoji.subset.gap.default.AE.ttf  | Bin 0 -> 4412 bytes
+ ...moji.subset.gap.drop-hints-retain-gids.2049.ttf | Bin 0 -> 3136 bytes
+ ...i.subset.gap.drop-hints-retain-gids.38,2049.ttf | Bin 0 -> 4108 bytes
+ ...i.subset.gap.drop-hints-retain-gids.38,20E3.ttf | Bin 0 -> 3600 bytes
+ ...rop-hints-retain-gids.38,39,AE,2049,38,20E3.ttf | Bin 0 -> 9188 bytes
+ ...ubset.gap.drop-hints-retain-gids.38,AE,2049.ttf | Bin 0 -> 7564 bytes
+ ...rEmoji.subset.gap.drop-hints-retain-gids.39.ttf | Bin 0 -> 916 bytes
+ ...rEmoji.subset.gap.drop-hints-retain-gids.AE.ttf | Bin 0 -> 4428 bytes
+ .../NotoColorEmoji.subset.gap.drop-hints.2049.ttf  | Bin 0 -> 3112 bytes
+ ...otoColorEmoji.subset.gap.drop-hints.38,2049.ttf | Bin 0 -> 4084 bytes
+ ...otoColorEmoji.subset.gap.drop-hints.38,20E3.ttf | Bin 0 -> 3568 bytes
+ ...subset.gap.drop-hints.38,39,AE,2049,38,20E3.ttf | Bin 0 -> 9188 bytes
+ ...ColorEmoji.subset.gap.drop-hints.38,AE,2049.ttf | Bin 0 -> 7544 bytes
+ .../NotoColorEmoji.subset.gap.drop-hints.39.ttf    | Bin 0 -> 908 bytes
+ .../NotoColorEmoji.subset.gap.drop-hints.AE.ttf    | Bin 0 -> 4412 bytes
+ .../NotoColorEmoji.subset.gap.retain-gids.2049.ttf | Bin 0 -> 3136 bytes
+ ...toColorEmoji.subset.gap.retain-gids.38,2049.ttf | Bin 0 -> 4108 bytes
+ ...toColorEmoji.subset.gap.retain-gids.38,20E3.ttf | Bin 0 -> 3600 bytes
+ ...ubset.gap.retain-gids.38,39,AE,2049,38,20E3.ttf | Bin 0 -> 9188 bytes
+ ...olorEmoji.subset.gap.retain-gids.38,AE,2049.ttf | Bin 0 -> 7564 bytes
+ .../NotoColorEmoji.subset.gap.retain-gids.39.ttf   | Bin 0 -> 916 bytes
+ .../NotoColorEmoji.subset.gap.retain-gids.AE.ttf   | Bin 0 -> 4428 bytes
+ ...olorEmoji.subset.index_format3.default.2049.ttf | Bin 0 -> 3112 bytes
+ ...rEmoji.subset.index_format3.default.38,2049.ttf | Bin 0 -> 4080 bytes
+ ...rEmoji.subset.index_format3.default.38,20E3.ttf | Bin 0 -> 3564 bytes
+ ...index_format3.default.38,39,AE,2049,38,20E3.ttf | Bin 0 -> 10112 bytes
+ ...oji.subset.index_format3.default.38,AE,2049.ttf | Bin 0 -> 7536 bytes
+ ...oColorEmoji.subset.index_format3.default.39.ttf | Bin 0 -> 1920 bytes
+ ...oColorEmoji.subset.index_format3.default.AE.ttf | Bin 0 -> 4412 bytes
+ ...t.index_format3.drop-hints-retain-gids.2049.ttf | Bin 0 -> 3136 bytes
+ ...ndex_format3.drop-hints-retain-gids.38,2049.ttf | Bin 0 -> 4104 bytes
+ ...ndex_format3.drop-hints-retain-gids.38,20E3.ttf | Bin 0 -> 3596 bytes
+ ...rop-hints-retain-gids.38,39,AE,2049,38,20E3.ttf | Bin 0 -> 10112 bytes
+ ...x_format3.drop-hints-retain-gids.38,AE,2049.ttf | Bin 0 -> 7556 bytes
+ ...set.index_format3.drop-hints-retain-gids.39.ttf | Bin 0 -> 1928 bytes
+ ...set.index_format3.drop-hints-retain-gids.AE.ttf | Bin 0 -> 4428 bytes
+ ...rEmoji.subset.index_format3.drop-hints.2049.ttf | Bin 0 -> 3112 bytes
+ ...oji.subset.index_format3.drop-hints.38,2049.ttf | Bin 0 -> 4080 bytes
+ ...oji.subset.index_format3.drop-hints.38,20E3.ttf | Bin 0 -> 3564 bytes
+ ...ex_format3.drop-hints.38,39,AE,2049,38,20E3.ttf | Bin 0 -> 10112 bytes
+ ....subset.index_format3.drop-hints.38,AE,2049.ttf | Bin 0 -> 7536 bytes
+ ...lorEmoji.subset.index_format3.drop-hints.39.ttf | Bin 0 -> 1920 bytes
+ ...lorEmoji.subset.index_format3.drop-hints.AE.ttf | Bin 0 -> 4412 bytes
+ ...Emoji.subset.index_format3.retain-gids.2049.ttf | Bin 0 -> 3136 bytes
+ ...ji.subset.index_format3.retain-gids.38,2049.ttf | Bin 0 -> 4104 bytes
+ ...ji.subset.index_format3.retain-gids.38,20E3.ttf | Bin 0 -> 3596 bytes
+ ...x_format3.retain-gids.38,39,AE,2049,38,20E3.ttf | Bin 0 -> 10112 bytes
+ ...subset.index_format3.retain-gids.38,AE,2049.ttf | Bin 0 -> 7556 bytes
+ ...orEmoji.subset.index_format3.retain-gids.39.ttf | Bin 0 -> 1928 bytes
+ ...orEmoji.subset.index_format3.retain-gids.AE.ttf | Bin 0 -> 4428 bytes
+ ...ji.subset.multiple_size_tables.default.2049.ttf | Bin 0 -> 5312 bytes
+ ...subset.multiple_size_tables.default.38,2049.ttf | Bin 0 -> 7244 bytes
+ ...subset.multiple_size_tables.default.38,20E3.ttf | Bin 0 -> 6212 bytes
+ ...e_size_tables.default.38,39,AE,2049,38,20E3.ttf | Bin 0 -> 19280 bytes
+ ...set.multiple_size_tables.default.38,AE,2049.ttf | Bin 0 -> 14140 bytes
+ ...moji.subset.multiple_size_tables.default.39.ttf | Bin 0 -> 2928 bytes
+ ...moji.subset.multiple_size_tables.default.AE.ttf | Bin 0 -> 7916 bytes
+ ...ple_size_tables.drop-hints-retain-gids.2049.ttf | Bin 0 -> 5336 bytes
+ ..._size_tables.drop-hints-retain-gids.38,2049.ttf | Bin 0 -> 7268 bytes
+ ..._size_tables.drop-hints-retain-gids.38,20E3.ttf | Bin 0 -> 6244 bytes
+ ...rop-hints-retain-gids.38,39,AE,2049,38,20E3.ttf | Bin 0 -> 19280 bytes
+ ...ze_tables.drop-hints-retain-gids.38,AE,2049.ttf | Bin 0 -> 14164 bytes
+ ...tiple_size_tables.drop-hints-retain-gids.39.ttf | Bin 0 -> 2936 bytes
+ ...tiple_size_tables.drop-hints-retain-gids.AE.ttf | Bin 0 -> 7932 bytes
+ ...subset.multiple_size_tables.drop-hints.2049.ttf | Bin 0 -> 5312 bytes
+ ...set.multiple_size_tables.drop-hints.38,2049.ttf | Bin 0 -> 7244 bytes
+ ...set.multiple_size_tables.drop-hints.38,20E3.ttf | Bin 0 -> 6212 bytes
+ ...ize_tables.drop-hints.38,39,AE,2049,38,20E3.ttf | Bin 0 -> 19280 bytes
+ ....multiple_size_tables.drop-hints.38,AE,2049.ttf | Bin 0 -> 14140 bytes
+ ...i.subset.multiple_size_tables.drop-hints.39.ttf | Bin 0 -> 2928 bytes
+ ...i.subset.multiple_size_tables.drop-hints.AE.ttf | Bin 0 -> 7916 bytes
+ ...ubset.multiple_size_tables.retain-gids.2049.ttf | Bin 0 -> 5336 bytes
+ ...et.multiple_size_tables.retain-gids.38,2049.ttf | Bin 0 -> 7268 bytes
+ ...et.multiple_size_tables.retain-gids.38,20E3.ttf | Bin 0 -> 6244 bytes
+ ...ze_tables.retain-gids.38,39,AE,2049,38,20E3.ttf | Bin 0 -> 19280 bytes
+ ...multiple_size_tables.retain-gids.38,AE,2049.ttf | Bin 0 -> 14164 bytes
+ ....subset.multiple_size_tables.retain-gids.39.ttf | Bin 0 -> 2936 bytes
+ ....subset.multiple_size_tables.retain-gids.AE.ttf | Bin 0 -> 7932 bytes
+ .../NotoColorEmoji.subset.retain-gids.2049.ttf     | Bin 0 -> 3136 bytes
+ .../NotoColorEmoji.subset.retain-gids.38,2049.ttf  | Bin 0 -> 4108 bytes
+ .../NotoColorEmoji.subset.retain-gids.38,20E3.ttf  | Bin 0 -> 3600 bytes
+ ...ji.subset.retain-gids.38,39,AE,2049,38,20E3.ttf | Bin 0 -> 10124 bytes
+ ...otoColorEmoji.subset.retain-gids.38,AE,2049.ttf | Bin 0 -> 7564 bytes
+ .../cbdt/NotoColorEmoji.subset.retain-gids.39.ttf  | Bin 0 -> 1928 bytes
+ .../cbdt/NotoColorEmoji.subset.retain-gids.AE.ttf  | Bin 0 -> 4428 bytes
+ .../data/fonts/NotoColorEmoji.subset.gap.ttf       | Bin 0 -> 9188 bytes
+ .../fonts/NotoColorEmoji.subset.index_format3.ttf  | Bin 0 -> 10112 bytes
+ .../NotoColorEmoji.subset.multiple_size_tables.ttf | Bin 0 -> 19280 bytes
+ test/subset/data/fonts/NotoColorEmoji.subset.ttf   | Bin 0 -> 10124 bytes
+ test/subset/data/tests/cbdt.tests                  |  20 +
+ 138 files changed, 747 insertions(+), 40 deletions(-)
+
+commit b4377afd28c8158ff0c8234aa9b2bfec3a54abd1
+Author: Evgeniy Reizner <razrfalcon at gmail.com>
+Date:   Fri Jan 31 15:11:45 2020 +0200
+
+    Minor hb_ot_layout documentation fixes.
+
+ src/hb-ot-layout.cc |  8 ++++----
+ src/hb-ot-layout.h  | 10 +++++-----
+ 2 files changed, 9 insertions(+), 9 deletions(-)
+
+commit 0216a96b0fd6bd1ab4030cd7097873a1063cd846
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Jan 30 12:36:58 2020 -0800
+
+    [subset] Fix simple glyph trim_padding in glyf table
+    Detail: when numOfContours = 1 and flag = 0x31
+    xCoordinates and yCoordinates would be empty
+
+ src/hb-ot-glyf-table.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit b6a8f5e63c144868edb0259e45b33e14275d1e3e
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Jan 28 09:30:51 2020 -0800
+
+    [subset] CMAP table subsetting fix
+    Not all codepoints smaller than 0xFFFF go to cmap4 table.
+    Only subset codepoints existing in each table.
+    This will also make harfbuzz consistent with fontTools' behavior
+
+ src/hb-ot-cmap-table.hh                                 |  15 ++++++++++++---
+ test/subset/data/Makefile.am                            |   1 +
+ test/subset/data/Makefile.sources                       |   1 +
+ .../expected/cmap/AdobeBlank-Regular.default.61,62.ttf  | Bin 0 -> 1336 bytes
+ .../cmap/AdobeBlank-Regular.default.61,FEFA.ttf         | Bin 0 -> 1348 bytes
+ .../cmap/AdobeBlank-Regular.default.FEE6,FECF.ttf       | Bin 0 -> 1300 bytes
+ .../cmap/AdobeBlank-Regular.default.FEF9,FEFA.ttf       | Bin 0 -> 1288 bytes
+ .../expected/cmap/AdobeBlank-Regular.default.FEFA.ttf   | Bin 0 -> 1268 bytes
+ .../AdobeBlank-Regular.drop-hints-retain-gids.61,62.ttf | Bin 0 -> 1552 bytes
+ ...dobeBlank-Regular.drop-hints-retain-gids.61,FEFA.ttf | Bin 0 -> 8316 bytes
+ ...beBlank-Regular.drop-hints-retain-gids.FEE6,FECF.ttf | Bin 0 -> 8188 bytes
+ ...beBlank-Regular.drop-hints-retain-gids.FEF9,FEFA.ttf | Bin 0 -> 8256 bytes
+ .../AdobeBlank-Regular.drop-hints-retain-gids.FEFA.ttf  | Bin 0 -> 8240 bytes
+ .../cmap/AdobeBlank-Regular.drop-hints.61,62.ttf        | Bin 0 -> 1164 bytes
+ .../cmap/AdobeBlank-Regular.drop-hints.61,FEFA.ttf      | Bin 0 -> 1176 bytes
+ .../cmap/AdobeBlank-Regular.drop-hints.FEE6,FECF.ttf    | Bin 0 -> 1128 bytes
+ .../cmap/AdobeBlank-Regular.drop-hints.FEF9,FEFA.ttf    | Bin 0 -> 1116 bytes
+ .../cmap/AdobeBlank-Regular.drop-hints.FEFA.ttf         | Bin 0 -> 1096 bytes
+ .../expected/cmap/AdobeBlank-Regular.name-ids.61,62.ttf | Bin 0 -> 1084 bytes
+ .../cmap/AdobeBlank-Regular.name-ids.61,FEFA.ttf        | Bin 0 -> 1096 bytes
+ .../cmap/AdobeBlank-Regular.name-ids.FEE6,FECF.ttf      | Bin 0 -> 1048 bytes
+ .../cmap/AdobeBlank-Regular.name-ids.FEF9,FEFA.ttf      | Bin 0 -> 1036 bytes
+ .../expected/cmap/AdobeBlank-Regular.name-ids.FEFA.ttf  | Bin 0 -> 1016 bytes
+ .../cmap/AdobeBlank-Regular.retain-gids.61,62.ttf       | Bin 0 -> 1724 bytes
+ .../cmap/AdobeBlank-Regular.retain-gids.61,FEFA.ttf     | Bin 0 -> 8488 bytes
+ .../cmap/AdobeBlank-Regular.retain-gids.FEE6,FECF.ttf   | Bin 0 -> 8360 bytes
+ .../cmap/AdobeBlank-Regular.retain-gids.FEF9,FEFA.ttf   | Bin 0 -> 8428 bytes
+ .../cmap/AdobeBlank-Regular.retain-gids.FEFA.ttf        | Bin 0 -> 8412 bytes
+ test/subset/data/fonts/AdobeBlank-Regular.ttf           | Bin 0 -> 72408 bytes
+ test/subset/data/tests/cmap.tests                       |  16 ++++++++++++++++
+ 30 files changed, 30 insertions(+), 3 deletions(-)
+
+commit 777ba47b50f6379b9f9abf1d72559316b7116b9e
+Merge: 5b069c36 92f43a99
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Jan 30 22:38:43 2020 +0330
+
+    Merge pull request #2132 from ckitagawa-work/subset_colr
+    
+    [subset] Add COLR support
+
+commit 5b069c3612e0347db4b7932135f6a3b9e1f84f58
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Jan 30 18:05:01 2020 +0330
+
+    [draw][docs] update to new terminology
+
+ src/hb-draw.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 920dca4550f73f05d79e95ddf537054e2775f7e5
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Jan 30 18:03:06 2020 +0330
+
+    [draw][docs] update to new terminlogy
+
+ src/hb-draw.cc | 32 ++++++++++++++++----------------
+ 1 file changed, 16 insertions(+), 16 deletions(-)
+
+commit 1632726c1fbcd49d8c27c03948859e80476b41bd
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Jan 30 16:48:34 2020 +0330
+
+    [draw] minor
+
+ src/hb-draw.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 92f43a99c685752416f216c22b6edb9d87ce5d35
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Wed Jan 29 16:06:55 2020 -0500
+
+    [subset] COLR, simplify logic and use add_array
+
+ src/hb-ot-color-colr-table.hh | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+commit fba5128a9e9459de5b08367c96d05674aa1363a9
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Wed Jan 29 10:24:55 2020 -0500
+
+    Fix build
+
+ src/hb-ot-color-colr-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7d542a5274d56229a72c30e53aecbae8ea938f4e
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Wed Jan 29 10:20:00 2020 -0500
+
+    Refactor to two iterators
+
+ src/hb-ot-color-colr-table.hh                      | 142 ++++++++++++---------
+ src/hb-subset-plan.cc                              |   2 +-
+ .../TwemojiMozilla.subset.default.32,3299.ttf      | Bin 0 -> 5264 bytes
+ test/api/test-subset-colr.c                        |  21 +++
+ 4 files changed, 105 insertions(+), 60 deletions(-)
+
+commit 0aed54dca6fefbc26f466ace6c105881c536baa2
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Fri Jan 24 15:51:06 2020 -0500
+
+    Use one-liner methods
+
+ src/hb-ot-color-colr-table.hh | 18 ++++--------------
+ 1 file changed, 4 insertions(+), 14 deletions(-)
+
+commit 81c469eb62294666c27bcd82e4e6fcad742dcbf3
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Fri Jan 24 15:49:25 2020 -0500
+
+    Try to fix Wrange-loop-analysis
+
+ src/hb-ot-color-colr-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0d1ba94ac7910f0fc8232c539d4f6709cd2493fd
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Fri Jan 24 15:44:40 2020 -0500
+
+    Minor style fixes
+
+ src/hb-ot-color-colr-table.hh | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+commit 49b98e865007bbbfd5780b301a68daa7b3800ec3
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Fri Jan 24 15:39:02 2020 -0500
+
+    Fix nullptr de-reference failure if both blobs in a subset test are 0 in size
+
+ test/api/hb-subset-test.h | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit ed857c4680721d767ce9c60cf081ad0a1bcee8e6
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Fri Jan 24 08:52:23 2020 -0500
+
+    [subset] Add COLR support
+
+ src/hb-ot-color-colr-table.hh                      | 127 ++++++++++++++++++++-
+ src/hb-subset-plan.cc                              |   5 +
+ src/hb-subset.cc                                   |   4 +
+ test/api/Makefile.am                               |   2 +
+ .../api/fonts/TwemojiMozilla.subset.default.32.ttf | Bin 0 -> 4660 bytes
+ .../fonts/TwemojiMozilla.subset.default.3297.ttf   | Bin 0 -> 5068 bytes
+ test/api/fonts/TwemojiMozilla.subset.ttf           | Bin 0 -> 5712 bytes
+ test/api/test-subset-colr.c                        |  99 ++++++++++++++++
+ test/fuzzing/fonts/TwemojiMozilla.subset.ttf       | Bin 0 -> 5712 bytes
+ test/subset/data/Makefile.am                       |   1 +
+ test/subset/data/Makefile.sources                  |   1 +
+ .../TwemojiMozilla.subset.default.32,3297,3299.ttf | Bin 0 -> 5624 bytes
+ .../colr/TwemojiMozilla.subset.default.32,3297.ttf | Bin 0 -> 5088 bytes
+ .../colr/TwemojiMozilla.subset.default.32,3299.ttf | Bin 0 -> 5264 bytes
+ .../colr/TwemojiMozilla.subset.default.32.ttf      | Bin 0 -> 4660 bytes
+ .../TwemojiMozilla.subset.default.3297,3299.ttf    | Bin 0 -> 5604 bytes
+ .../colr/TwemojiMozilla.subset.default.3297.ttf    | Bin 0 -> 5068 bytes
+ .../colr/TwemojiMozilla.subset.default.3299.ttf    | Bin 0 -> 5244 bytes
+ ....subset.drop-hints-retain-gids.32,3297,3299.ttf | Bin 0 -> 5604 bytes
+ ...zilla.subset.drop-hints-retain-gids.32,3297.ttf | Bin 0 -> 5084 bytes
+ ...zilla.subset.drop-hints-retain-gids.32,3299.ttf | Bin 0 -> 5264 bytes
+ ...ojiMozilla.subset.drop-hints-retain-gids.32.ttf | Bin 0 -> 4640 bytes
+ ...lla.subset.drop-hints-retain-gids.3297,3299.ttf | Bin 0 -> 5588 bytes
+ ...iMozilla.subset.drop-hints-retain-gids.3297.ttf | Bin 0 -> 5064 bytes
+ ...iMozilla.subset.drop-hints-retain-gids.3299.ttf | Bin 0 -> 5244 bytes
+ ...emojiMozilla.subset.drop-hints.32,3297,3299.ttf | Bin 0 -> 5604 bytes
+ .../TwemojiMozilla.subset.drop-hints.32,3297.ttf   | Bin 0 -> 5068 bytes
+ .../TwemojiMozilla.subset.drop-hints.32,3299.ttf   | Bin 0 -> 5244 bytes
+ .../colr/TwemojiMozilla.subset.drop-hints.32.ttf   | Bin 0 -> 4640 bytes
+ .../TwemojiMozilla.subset.drop-hints.3297,3299.ttf | Bin 0 -> 5584 bytes
+ .../colr/TwemojiMozilla.subset.drop-hints.3297.ttf | Bin 0 -> 5048 bytes
+ .../colr/TwemojiMozilla.subset.drop-hints.3299.ttf | Bin 0 -> 5224 bytes
+ ...mojiMozilla.subset.retain-gids.32,3297,3299.ttf | Bin 0 -> 5624 bytes
+ .../TwemojiMozilla.subset.retain-gids.32,3297.ttf  | Bin 0 -> 5104 bytes
+ .../TwemojiMozilla.subset.retain-gids.32,3299.ttf  | Bin 0 -> 5284 bytes
+ .../colr/TwemojiMozilla.subset.retain-gids.32.ttf  | Bin 0 -> 4660 bytes
+ ...TwemojiMozilla.subset.retain-gids.3297,3299.ttf | Bin 0 -> 5608 bytes
+ .../TwemojiMozilla.subset.retain-gids.3297.ttf     | Bin 0 -> 5084 bytes
+ .../TwemojiMozilla.subset.retain-gids.3299.ttf     | Bin 0 -> 5264 bytes
+ test/subset/data/fonts/TwemojiMozilla.subset.ttf   | Bin 0 -> 5712 bytes
+ test/subset/data/tests/colr.tests                  |  17 +++
+ 41 files changed, 255 insertions(+), 1 deletion(-)
+
+commit d106900bfd61ed45fbd4ffd93875d167d86e01e4
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Jan 28 15:26:13 2020 +0330
+
+    [draw][glyf] Implement quadratic to cubic call translation
+
+ src/hb-draw.cc          |  7 +-----
+ src/hb-draw.h           |  3 +++
+ src/hb-ot-glyf-table.hh | 58 ++++++++++++++++++++++++++++++++++++++++++++-----
+ test/api/test-draw.c    | 27 +++++++++++++++++++++--
+ 4 files changed, 81 insertions(+), 14 deletions(-)
+
+commit 74fdcdcac8bf0467c50ddf6793b147e93b790a52
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Jan 28 13:45:22 2020 +0330
+
+    [draw] Rename conic_to to quadratic_to
+
+ docs/harfbuzz-sections.txt |  4 ++--
+ src/hb-draw.cc             | 16 ++++++++--------
+ src/hb-draw.h              | 10 +++++-----
+ src/hb-draw.hh             |  2 +-
+ src/hb-ot-glyf-table.hh    |  4 ++--
+ src/main.cc                |  8 ++++----
+ test/api/test-draw.c       |  8 ++++----
+ 7 files changed, 26 insertions(+), 26 deletions(-)
+
+commit ac81e94016be3fb638c16bae38bd61cc131104ac
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Jan 28 12:34:47 2020 +0330
+
+    Rename hb_outline_decompose to hb_font_draw_glyph and hb_outline_decompose_funcs_t to hb_draw_funcs_t
+
+ docs/harfbuzz-sections.txt               | 38 ++++++-------
+ src/Makefile.sources                     |  6 +--
+ src/harfbuzz.cc                          |  2 +-
+ src/hb-config.hh                         |  2 +-
+ src/{hb-outline.cc => hb-draw.cc}        | 91 +++++++++++++++----------------
+ src/hb-draw.h                            | 87 ++++++++++++++++++++++++++++++
+ src/{hb-outline.hh => hb-draw.hh}        | 18 +++----
+ src/hb-font.h                            |  5 ++
+ src/hb-ot-cff1-table.cc                  | 12 ++---
+ src/hb-ot-cff1-table.hh                  |  2 +-
+ src/hb-ot-cff2-table.cc                  |  8 +--
+ src/hb-ot-cff2-table.hh                  |  2 +-
+ src/hb-ot-glyf-table.hh                  |  4 +-
+ src/hb-outline.h                         | 92 --------------------------------
+ src/hb.h                                 |  2 +-
+ src/main.cc                              | 26 ++++-----
+ test/api/Makefile.am                     |  2 +-
+ test/api/{test-outline.c => test-draw.c} | 70 ++++++++++++------------
+ test/api/test-ot-face.c                  |  6 +--
+ 19 files changed, 238 insertions(+), 237 deletions(-)
+
+commit cf5f94675669154ab84695e5b24a1d54d2ad8c5e
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Jan 27 23:38:39 2020 +0330
+
+    [outline] use hb_object_is_immutable instead comparing to Null
+
+ src/hb-outline.cc | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 981125aa2adbe4f513d3ecf357459e5bcfd06d0a
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Jan 25 21:31:36 2020 +0330
+
+    Rename hb_ot_glyph_* to hb_outline_*
+
+ docs/harfbuzz-sections.txt                   |  38 +++++-----
+ src/Makefile.sources                         |   6 +-
+ src/harfbuzz.cc                              |   2 +-
+ src/hb-config.hh                             |   2 +-
+ src/hb-ot-cff1-table.cc                      |  12 ++--
+ src/hb-ot-cff1-table.hh                      |   2 +-
+ src/hb-ot-cff2-table.cc                      |   8 +--
+ src/hb-ot-cff2-table.hh                      |   2 +-
+ src/hb-ot-glyf-table.hh                      |   4 +-
+ src/hb-ot-glyph.h                            |  92 ------------------------
+ src/hb-ot.h                                  |   1 -
+ src/{hb-ot-glyph.cc => hb-outline.cc}        |  88 +++++++++++------------
+ src/hb-outline.h                             |  92 ++++++++++++++++++++++++
+ src/{hb-ot-glyph.hh => hb-outline.hh}        |  18 ++---
+ src/hb.h                                     |   1 +
+ src/main.cc                                  |  26 +++----
+ test/api/Makefile.am                         |   2 +-
+ test/api/test-ot-face.c                      |   6 +-
+ test/api/{test-ot-glyph.c => test-outline.c} | 104 +++++++++++++--------------
+ 19 files changed, 253 insertions(+), 253 deletions(-)
+
+commit 30857089a59b673b80b1fbaafe8ed65ae21ed472
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Jan 27 21:16:57 2020 +0330
+
+    [test][glyph] add subcomponent scale test
+
+ test/api/test-ot-glyph.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit d809aca8d05c64c0e871923b36bdd3b17a85358d
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Jan 27 20:52:56 2020 +0330
+
+    [test] test for not applying morx on horizontal runs if gsub exists
+    
+    https://github.com/harfbuzz/harfbuzz/pull/2130
+
+ test/shaping/data/in-house/tests/macos.tests | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit cd7b46ca1569850929974ef146aa1ca083c2557d
+Author: Evgeniy Reizner <razrfalcon at gmail.com>
+Date:   Sun Jan 26 20:46:19 2020 +0200
+
+    Use correct return type in _unsafe_to_break_find_min_cluster.
+
+ src/hb-buffer.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1438bae7a5a2c7cc631e041bcf75745578935014
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Jan 26 23:48:30 2020 +0330
+
+    [ot-glyph] Add fontkit non variables fonts tests
+
+ test/api/fonts/Mada-VF.ttf                         | Bin 0 -> 120384 bytes
+ .../fonts/NotoSansCJKkr-Regular-subset-colon.ttf   | Bin 0 -> 2084 bytes
+ test/api/fonts/OpenSans-Regular.ttf                | Bin 0 -> 217360 bytes
+ test/api/fonts/SourceSansPro-Regular.otf           | Bin 0 -> 220852 bytes
+ test/api/test-ot-glyph.c                           | 113 ++++++++++++++++++++-
+ 5 files changed, 112 insertions(+), 1 deletion(-)
+
+commit 9bb1c79a2c41b85ab48ef0086a412e08ce18acd8
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Jan 26 22:10:47 2020 +0330
+
+    [ot-glyph][test] Avoid sprintf use
+
+ test/api/test-ot-glyph.c | 160 ++++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 116 insertions(+), 44 deletions(-)
+
+commit 99f8e52d5e32b837648550b5cf09267ea7efcb48
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Jan 26 17:02:11 2020 +0330
+
+    [ot-glyph] Add fontkits's variations toSVG tests
+
+ test/api/fonts/AdobeVFPrototype-Subset.otf | Bin 0 -> 7096 bytes
+ test/api/fonts/TestGVARFour.ttf            | Bin 0 -> 3204 bytes
+ test/api/fonts/TestGVAROne.ttf             | Bin 0 -> 14312 bytes
+ test/api/fonts/TestGVARThree.ttf           | Bin 0 -> 14336 bytes
+ test/api/fonts/TestGVARTwo.ttf             | Bin 0 -> 15668 bytes
+ test/api/test-ot-glyph.c                   | 246 ++++++++++++++++++++++++++++-
+ 6 files changed, 244 insertions(+), 2 deletions(-)
+
+commit e44982f5485571e852810cad7e55eca5c14e3758
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Jan 26 14:30:03 2020 +0330
+
+    [ot-glyph] Add ttf-parser's outline_glyph tests
+
+ test/api/fonts/README     |   2 +
+ test/api/fonts/glyphs.ttf | Bin 0 -> 808 bytes
+ test/api/test-ot-glyph.c  |  92 ++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 94 insertions(+)
+
+commit 5440313924172e155e34391f033f5e6c5e2390b3
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Jan 26 00:07:28 2020 +0330
+
+    Update COPYING
+    
+    2020 update and add my name for years had more or less considerable contributions
+
+ COPYING | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit cd266e4f3d3c8ef338c007a93a2ae356467d7953
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Jan 25 21:33:38 2020 +0330
+
+    minor
+
+ src/hb-ot-glyph.hh | 3 ---
+ 1 file changed, 3 deletions(-)
+
+commit f9070cfef8b0bb3e9dc5a934d24ef6348eb19880
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Jan 24 22:19:03 2020 +0330
+
+    Run morx if run is horizontal or GSUB doesn't exist
+
+ src/hb-ot-shape.cc | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+commit 58976972508d6f6d564cb3305bbb6f706bd1ba33
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Jan 25 00:32:46 2020 +0330
+
+    [test] Increase subset timeout
+    
+    No random timeout please
+
+ test/fuzzing/run-subset-fuzzer-tests.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit d1830437c92caf1ba3869c9ddae8acb5f8f96739
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Jan 25 00:09:47 2020 +0330
+
+    [tests] Apply expected results of Mplus1p-Regular subset
+    
+    Related to #2131
+
+ .../japanese/Mplus1p-Regular.default.25771.ttf        | Bin 1976 -> 1824 bytes
+ .../japanese/Mplus1p-Regular.drop-hints.25771.ttf     | Bin 1248 -> 1096 bytes
+ 2 files changed, 0 insertions(+), 0 deletions(-)
+
+commit 8e0898080faf6e8aeee0b1e41e842fe7611d9c44
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Jan 24 23:39:44 2020 +0330
+
+    [sbix] minor style fixes
+
+ src/hb-ot-color-sbix-table.hh | 55 +++++++++++++++++++++++--------------------
+ 1 file changed, 29 insertions(+), 26 deletions(-)
+
+commit 36a5c042d701f19f574442d987b1c3dcf7d5943b
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Jan 21 13:37:28 2020 -0800
+
+    [subset] Add "--name-languages" and "--name-legacy" options
+    Make name table subsetting consistent with fontTools
+
+ src/hb-ot-name-table.hh                            |  11 ++++
+ src/hb-subset-input.cc                             |  23 ++++++++
+ src/hb-subset-input.hh                             |   2 +
+ src/hb-subset-plan.cc                              |   3 ++
+ src/hb-subset-plan.hh                              |   4 ++
+ src/hb-subset.h                                    |   9 ++++
+ test/api/hb-subset-test.h                          |   5 ++
+ .../Comfortaa-Regular-new.default.61,62,63.ttf     | Bin 7460 -> 7392 bytes
+ .../basics/Comfortaa-Regular-new.default.61,63.ttf | Bin 7104 -> 7036 bytes
+ .../basics/Comfortaa-Regular-new.default.61.ttf    | Bin 6752 -> 6684 bytes
+ .../basics/Comfortaa-Regular-new.default.62.ttf    | Bin 6696 -> 6628 bytes
+ .../basics/Comfortaa-Regular-new.default.63.ttf    | Bin 6676 -> 6608 bytes
+ ...aa-Regular-new.default.retain-all-codepoint.ttf | Bin 182944 -> 182876 bytes
+ ...Regular-new.drop-hints-retain-gids.61,62,63.ttf | Bin 4912 -> 4844 bytes
+ ...aa-Regular-new.drop-hints-retain-gids.61,63.ttf | Bin 4620 -> 4552 bytes
+ ...ortaa-Regular-new.drop-hints-retain-gids.61.ttf | Bin 4056 -> 3988 bytes
+ ...ortaa-Regular-new.drop-hints-retain-gids.62.ttf | Bin 4296 -> 4228 bytes
+ ...ortaa-Regular-new.drop-hints-retain-gids.63.ttf | Bin 4304 -> 4236 bytes
+ ...drop-hints-retain-gids.retain-all-codepoint.ttf | Bin 151740 -> 151672 bytes
+ .../Comfortaa-Regular-new.drop-hints.61,62,63.ttf  | Bin 2920 -> 2852 bytes
+ .../Comfortaa-Regular-new.drop-hints.61,63.ttf     | Bin 2620 -> 2552 bytes
+ .../basics/Comfortaa-Regular-new.drop-hints.61.ttf | Bin 2308 -> 2240 bytes
+ .../basics/Comfortaa-Regular-new.drop-hints.62.ttf | Bin 2296 -> 2228 bytes
+ .../basics/Comfortaa-Regular-new.drop-hints.63.ttf | Bin 2296 -> 2228 bytes
+ ...Regular-new.drop-hints.retain-all-codepoint.ttf | Bin 151676 -> 151608 bytes
+ .../Comfortaa-Regular-new.name-ids.61,62,63.ttf    | Bin 7204 -> 7132 bytes
+ .../Comfortaa-Regular-new.name-ids.61,63.ttf       | Bin 6848 -> 6776 bytes
+ .../basics/Comfortaa-Regular-new.name-ids.61.ttf   | Bin 6496 -> 6424 bytes
+ .../basics/Comfortaa-Regular-new.name-ids.62.ttf   | Bin 6440 -> 6368 bytes
+ .../basics/Comfortaa-Regular-new.name-ids.63.ttf   | Bin 6420 -> 6348 bytes
+ ...a-Regular-new.name-ids.retain-all-codepoint.ttf | Bin 182688 -> 182616 bytes
+ ...mfortaa-Regular-new.name-languages.61,62,63.ttf | Bin 0 -> 7392 bytes
+ .../Comfortaa-Regular-new.name-languages.61,63.ttf | Bin 0 -> 7036 bytes
+ .../Comfortaa-Regular-new.name-languages.61.ttf    | Bin 0 -> 6684 bytes
+ .../Comfortaa-Regular-new.name-languages.62.ttf    | Bin 0 -> 6628 bytes
+ .../Comfortaa-Regular-new.name-languages.63.ttf    | Bin 0 -> 6608 bytes
+ ...lar-new.name-languages.retain-all-codepoint.ttf | Bin 0 -> 182876 bytes
+ .../Comfortaa-Regular-new.name-legacy.61,62,63.ttf | Bin 0 -> 7392 bytes
+ .../Comfortaa-Regular-new.name-legacy.61,63.ttf    | Bin 0 -> 7036 bytes
+ .../Comfortaa-Regular-new.name-legacy.61.ttf       | Bin 0 -> 6684 bytes
+ .../Comfortaa-Regular-new.name-legacy.62.ttf       | Bin 0 -> 6628 bytes
+ .../Comfortaa-Regular-new.name-legacy.63.ttf       | Bin 0 -> 6608 bytes
+ ...egular-new.name-legacy.retain-all-codepoint.ttf | Bin 0 -> 182876 bytes
+ .../Comfortaa-Regular-new.retain-gids.61,62,63.ttf | Bin 9452 -> 9384 bytes
+ .../Comfortaa-Regular-new.retain-gids.61,63.ttf    | Bin 9104 -> 9036 bytes
+ .../Comfortaa-Regular-new.retain-gids.61.ttf       | Bin 8500 -> 8432 bytes
+ .../Comfortaa-Regular-new.retain-gids.62.ttf       | Bin 8696 -> 8628 bytes
+ .../Comfortaa-Regular-new.retain-gids.63.ttf       | Bin 8684 -> 8616 bytes
+ ...egular-new.retain-gids.retain-all-codepoint.ttf | Bin 183008 -> 182940 bytes
+ .../Roboto-Regular.abc.name-languages.61,62,63.ttf | Bin 0 -> 2168 bytes
+ .../Roboto-Regular.abc.name-languages.61,63.ttf    | Bin 0 -> 1988 bytes
+ .../Roboto-Regular.abc.name-languages.61.ttf       | Bin 0 -> 1792 bytes
+ .../Roboto-Regular.abc.name-languages.62.ttf       | Bin 0 -> 1740 bytes
+ .../Roboto-Regular.abc.name-languages.63.ttf       | Bin 0 -> 1716 bytes
+ ...lar.abc.name-languages.retain-all-codepoint.ttf | Bin 0 -> 2168 bytes
+ .../Roboto-Regular.abc.name-legacy.61,62,63.ttf    | Bin 0 -> 2168 bytes
+ .../Roboto-Regular.abc.name-legacy.61,63.ttf       | Bin 0 -> 1988 bytes
+ .../basics/Roboto-Regular.abc.name-legacy.61.ttf   | Bin 0 -> 1792 bytes
+ .../basics/Roboto-Regular.abc.name-legacy.62.ttf   | Bin 0 -> 1740 bytes
+ .../basics/Roboto-Regular.abc.name-legacy.63.ttf   | Bin 0 -> 1716 bytes
+ ...egular.abc.name-legacy.retain-all-codepoint.ttf | Bin 0 -> 2168 bytes
+ ...eSansPro-Regular.default.1FC,21,41,20,62,63.otf | Bin 2384 -> 2180 bytes
+ .../SourceSansPro-Regular.default.61,62,63.otf     | Bin 2096 -> 1892 bytes
+ ...ourceSansPro-Regular.default.D7,D8,D9,DA,DE.otf | Bin 2212 -> 2008 bytes
+ ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 20000 -> 19796 bytes
+ ...Regular.desubroutinize-retain-gids.61,62,63.otf | Bin 2196 -> 1992 bytes
+ ...r.desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 30412 -> 30208 bytes
+ ...o-Regular.desubroutinize.1FC,21,41,20,62,63.otf | Bin 2240 -> 2036 bytes
+ ...urceSansPro-Regular.desubroutinize.61,62,63.otf | Bin 2000 -> 1796 bytes
+ ...nsPro-Regular.desubroutinize.D7,D8,D9,DA,DE.otf | Bin 2196 -> 1992 bytes
+ ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 19840 -> 19636 bytes
+ ...p-hints-desubroutinize-retain-gids.61,62,63.otf | Bin 2072 -> 1868 bytes
+ ...s-desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 30264 -> 30060 bytes
+ ...rop-hints-desubroutinize.1FC,21,41,20,62,63.otf | Bin 2080 -> 1876 bytes
+ ...-Regular.drop-hints-desubroutinize.61,62,63.otf | Bin 1876 -> 1672 bytes
+ ...ar.drop-hints-desubroutinize.D7,D8,D9,DA,DE.otf | Bin 2048 -> 1844 bytes
+ ...r.drop-hints-retain-gids.1FC,21,41,20,62,63.otf | Bin 19932 -> 19728 bytes
+ ...Pro-Regular.drop-hints-retain-gids.61,62,63.otf | Bin 2108 -> 1904 bytes
+ ...gular.drop-hints-retain-gids.D7,D8,D9,DA,DE.otf | Bin 30276 -> 30072 bytes
+ ...nsPro-Regular.drop-hints.1FC,21,41,20,62,63.otf | Bin 2164 -> 1960 bytes
+ .../SourceSansPro-Regular.drop-hints.61,62,63.otf  | Bin 1940 -> 1736 bytes
+ ...ceSansPro-Regular.drop-hints.D7,D8,D9,DA,DE.otf | Bin 2064 -> 1860 bytes
+ ...sPro-Regular.retain-gids.1FC,21,41,20,62,63.otf | Bin 20152 -> 19948 bytes
+ .../SourceSansPro-Regular.retain-gids.61,62,63.otf | Bin 2264 -> 2060 bytes
+ ...eSansPro-Regular.retain-gids.D7,D8,D9,DA,DE.otf | Bin 30428 -> 30224 bytes
+ .../Roboto-Regular.default.1FC,21,41,20,62,63.ttf  | Bin 3164 -> 2984 bytes
+ .../full-font/Roboto-Regular.default.61,62,63.ttf  | Bin 2760 -> 2580 bytes
+ .../Roboto-Regular.default.D7,D8,D9,DA,DE.ttf      | Bin 3124 -> 2944 bytes
+ ...oboto-Regular.drop-hints.1FC,21,41,20,62,63.ttf | Bin 1616 -> 1436 bytes
+ .../Roboto-Regular.drop-hints.61,62,63.ttf         | Bin 1408 -> 1228 bytes
+ .../Roboto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf   | Bin 1644 -> 1464 bytes
+ ...ifVariable-Roman.default.1FC,21,41,20,62,63.ttf | Bin 4132 -> 3572 bytes
+ .../SourceSerifVariable-Roman.default.61,62,63.ttf | Bin 4100 -> 3540 bytes
+ ...eSerifVariable-Roman.default.D7,D8,D9,DA,DE.ttf | Bin 4592 -> 4032 bytes
+ ...ariable-Roman.drop-hints.1FC,21,41,20,62,63.ttf | Bin 4132 -> 3572 bytes
+ ...urceSerifVariable-Roman.drop-hints.61,62,63.ttf | Bin 4100 -> 3540 bytes
+ ...rifVariable-Roman.drop-hints.D7,D8,D9,DA,DE.ttf | Bin 4592 -> 4032 bytes
+ .../Mplus1p-Regular.default.1D715,1D7D8,41,42.ttf  | Bin 2260 -> 2108 bytes
+ ...gular.default.3042,3044,3046,3048,304A,304B.ttf | Bin 2684 -> 2532 bytes
+ ...gular.default.3042,3044,3046,73E0,5EA6,8F38.ttf | Bin 2928 -> 2776 bytes
+ .../Mplus1p-Regular.default.61,63,65,6B.ttf        | Bin 2228 -> 2076 bytes
+ ...gular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 3224 -> 3072 bytes
+ .../japanese/Mplus1p-Regular.default.660E.ttf      | Bin 1968 -> 1816 bytes
+ ...plus1p-Regular.drop-hints.1D715,1D7D8,41,42.ttf | Bin 1532 -> 1380 bytes
+ ...ar.drop-hints.3042,3044,3046,3048,304A,304B.ttf | Bin 1956 -> 1804 bytes
+ ...ar.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf | Bin 2200 -> 2048 bytes
+ .../Mplus1p-Regular.drop-hints.61,63,65,6B.ttf     | Bin 1500 -> 1348 bytes
+ ...ar.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 2496 -> 2344 bytes
+ .../japanese/Mplus1p-Regular.drop-hints.660E.ttf   | Bin 1240 -> 1088 bytes
+ test/subset/data/profiles/name-languages.txt       |   1 +
+ test/subset/data/profiles/name-legacy.txt          |   1 +
+ test/subset/data/tests/basics.tests                |   2 +
+ test/subset/generate-expected-outputs.py           |   6 +--
+ util/options-subset.cc                             |  58 +++++++++++++++++++++
+ 114 files changed, 121 insertions(+), 4 deletions(-)
+
+commit b7762c70680324fca0c1ae26ad3b7f432c0c990e
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Jan 24 21:20:07 2020 +0330
+
+    Disable hb_ot_glyph_decompose in HB_TINY
+
+ src/hb-config.hh   | 1 +
+ src/hb-ot-glyph.cc | 2 +-
+ src/main.cc        | 5 +++++
+ 3 files changed, 7 insertions(+), 1 deletion(-)
+
+commit 0e4b2676bdffeef3cb79b235bc9624f2a49dccad
+Author: ckitagawa-work <59700018+ckitagawa-work at users.noreply.github.com>
+Date:   Fri Jan 24 12:16:08 2020 -0500
+
+    [subset] sbix fix missed offset is_null() check
+
+ src/hb-ot-color-sbix-table.hh                           |   9 ++++++---
+ ...testcase-minimized-hb-subset-fuzzer-5747280156295168 | Bin 0 -> 98811 bytes
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+commit 5532374f61284a254d5b2a8de9472c64f138c854
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Jan 23 20:27:21 2020 +0330
+
+    [ot-glyph] Add a test for #2053
+
+ test/api/fonts/README                      |   2 ++
+ test/api/fonts/RanaKufi-Regular.subset.otf | Bin 0 -> 2260 bytes
+ test/api/test-ot-glyph.c                   |  26 ++++++++++++++++++++++++++
+ 3 files changed, 28 insertions(+)
+
+commit f7187e90d2ec703f8f99f94077c5e449541c0462
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Jan 24 20:22:27 2020 +0330
+
+    [cmake] Don't build src/main
+    
+    Closes #2108
+
+ CMakeLists.txt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1a6d53d3c05ee5bce7bd3e2a86471a84377d21c0
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Jan 24 20:00:23 2020 +0330
+
+    [ci] Increase msan and fedora-O0 bots subset fuzzer timeout
+
+ .circleci/config.yml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 2d14735588e8a7a22e2c9801d70374835a058898
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Jan 24 19:41:26 2020 +0330
+
+    [src/main] separate the places use private API, minor
+
+ src/main.cc | 191 +++++++++++++++++++++++++++++++-----------------------------
+ 1 file changed, 100 insertions(+), 91 deletions(-)
+
+commit 23277beef968aae8639f18f913eac8c69d323478
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Jan 24 18:49:48 2020 +0330
+
+    Fold src/test-ot-glyph and src/test-ot-color into src/main
+
+ src/Makefile.am      |  10 --
+ src/main.cc          | 305 ++++++++++++++++++++++++++++++++++++++++++--
+ src/test-ot-color.cc | 347 ---------------------------------------------------
+ src/test-ot-glyph.cc | 143 ---------------------
+ 4 files changed, 297 insertions(+), 508 deletions(-)
+
+commit b72337e57e791dd7f043a910273c0b433922d8e2
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Jan 23 21:23:13 2020 +0330
+
+    [test] Adopt test-ot-color with ot-glyph and remove freetype/cairo dependecy
+
+ src/Makefile.am      |   8 +-
+ src/test-ot-color.cc | 237 +++++++++++++++++++++++++--------------------------
+ 2 files changed, 120 insertions(+), 125 deletions(-)
+
+commit e171beeb5f3f26dee84373b4db223512675f5837
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Jan 24 19:51:21 2020 +0330
+
+    Revert "[subset] Add "--name-languages" and "--name-legacy" options"
+    
+    Causes tests failures, please reapply when tests are fixed, thanks.
+    
+    This reverts commit fd85818b5b85fb0ad2db71c60e94ca0689d38bca.
+
+ src/hb-ot-name-table.hh                            |  11 ----
+ src/hb-subset-input.cc                             |  23 --------
+ src/hb-subset-input.hh                             |   2 -
+ src/hb-subset-plan.cc                              |   3 --
+ src/hb-subset-plan.hh                              |   4 --
+ src/hb-subset.h                                    |   9 ----
+ test/api/hb-subset-test.h                          |   5 --
+ .../Comfortaa-Regular-new.default.61,62,63.ttf     | Bin 7392 -> 7460 bytes
+ .../basics/Comfortaa-Regular-new.default.61,63.ttf | Bin 7036 -> 7104 bytes
+ .../basics/Comfortaa-Regular-new.default.61.ttf    | Bin 6684 -> 6752 bytes
+ .../basics/Comfortaa-Regular-new.default.62.ttf    | Bin 6628 -> 6696 bytes
+ .../basics/Comfortaa-Regular-new.default.63.ttf    | Bin 6608 -> 6676 bytes
+ ...aa-Regular-new.default.retain-all-codepoint.ttf | Bin 182876 -> 182944 bytes
+ ...Regular-new.drop-hints-retain-gids.61,62,63.ttf | Bin 4844 -> 4912 bytes
+ ...aa-Regular-new.drop-hints-retain-gids.61,63.ttf | Bin 4552 -> 4620 bytes
+ ...ortaa-Regular-new.drop-hints-retain-gids.61.ttf | Bin 3988 -> 4056 bytes
+ ...ortaa-Regular-new.drop-hints-retain-gids.62.ttf | Bin 4228 -> 4296 bytes
+ ...ortaa-Regular-new.drop-hints-retain-gids.63.ttf | Bin 4236 -> 4304 bytes
+ ...drop-hints-retain-gids.retain-all-codepoint.ttf | Bin 151672 -> 151740 bytes
+ .../Comfortaa-Regular-new.drop-hints.61,62,63.ttf  | Bin 2852 -> 2920 bytes
+ .../Comfortaa-Regular-new.drop-hints.61,63.ttf     | Bin 2552 -> 2620 bytes
+ .../basics/Comfortaa-Regular-new.drop-hints.61.ttf | Bin 2240 -> 2308 bytes
+ .../basics/Comfortaa-Regular-new.drop-hints.62.ttf | Bin 2228 -> 2296 bytes
+ .../basics/Comfortaa-Regular-new.drop-hints.63.ttf | Bin 2228 -> 2296 bytes
+ ...Regular-new.drop-hints.retain-all-codepoint.ttf | Bin 151608 -> 151676 bytes
+ .../Comfortaa-Regular-new.name-ids.61,62,63.ttf    | Bin 7132 -> 7204 bytes
+ .../Comfortaa-Regular-new.name-ids.61,63.ttf       | Bin 6776 -> 6848 bytes
+ .../basics/Comfortaa-Regular-new.name-ids.61.ttf   | Bin 6424 -> 6496 bytes
+ .../basics/Comfortaa-Regular-new.name-ids.62.ttf   | Bin 6368 -> 6440 bytes
+ .../basics/Comfortaa-Regular-new.name-ids.63.ttf   | Bin 6348 -> 6420 bytes
+ ...a-Regular-new.name-ids.retain-all-codepoint.ttf | Bin 182616 -> 182688 bytes
+ ...mfortaa-Regular-new.name-languages.61,62,63.ttf | Bin 7392 -> 0 bytes
+ .../Comfortaa-Regular-new.name-languages.61,63.ttf | Bin 7036 -> 0 bytes
+ .../Comfortaa-Regular-new.name-languages.61.ttf    | Bin 6684 -> 0 bytes
+ .../Comfortaa-Regular-new.name-languages.62.ttf    | Bin 6628 -> 0 bytes
+ .../Comfortaa-Regular-new.name-languages.63.ttf    | Bin 6608 -> 0 bytes
+ ...lar-new.name-languages.retain-all-codepoint.ttf | Bin 182876 -> 0 bytes
+ .../Comfortaa-Regular-new.name-legacy.61,62,63.ttf | Bin 7392 -> 0 bytes
+ .../Comfortaa-Regular-new.name-legacy.61,63.ttf    | Bin 7036 -> 0 bytes
+ .../Comfortaa-Regular-new.name-legacy.61.ttf       | Bin 6684 -> 0 bytes
+ .../Comfortaa-Regular-new.name-legacy.62.ttf       | Bin 6628 -> 0 bytes
+ .../Comfortaa-Regular-new.name-legacy.63.ttf       | Bin 6608 -> 0 bytes
+ ...egular-new.name-legacy.retain-all-codepoint.ttf | Bin 182876 -> 0 bytes
+ .../Comfortaa-Regular-new.retain-gids.61,62,63.ttf | Bin 9384 -> 9452 bytes
+ .../Comfortaa-Regular-new.retain-gids.61,63.ttf    | Bin 9036 -> 9104 bytes
+ .../Comfortaa-Regular-new.retain-gids.61.ttf       | Bin 8432 -> 8500 bytes
+ .../Comfortaa-Regular-new.retain-gids.62.ttf       | Bin 8628 -> 8696 bytes
+ .../Comfortaa-Regular-new.retain-gids.63.ttf       | Bin 8616 -> 8684 bytes
+ ...egular-new.retain-gids.retain-all-codepoint.ttf | Bin 182940 -> 183008 bytes
+ .../Roboto-Regular.abc.name-languages.61,62,63.ttf | Bin 2168 -> 0 bytes
+ .../Roboto-Regular.abc.name-languages.61,63.ttf    | Bin 1988 -> 0 bytes
+ .../Roboto-Regular.abc.name-languages.61.ttf       | Bin 1792 -> 0 bytes
+ .../Roboto-Regular.abc.name-languages.62.ttf       | Bin 1740 -> 0 bytes
+ .../Roboto-Regular.abc.name-languages.63.ttf       | Bin 1716 -> 0 bytes
+ ...lar.abc.name-languages.retain-all-codepoint.ttf | Bin 2168 -> 0 bytes
+ .../Roboto-Regular.abc.name-legacy.61,62,63.ttf    | Bin 2168 -> 0 bytes
+ .../Roboto-Regular.abc.name-legacy.61,63.ttf       | Bin 1988 -> 0 bytes
+ .../basics/Roboto-Regular.abc.name-legacy.61.ttf   | Bin 1792 -> 0 bytes
+ .../basics/Roboto-Regular.abc.name-legacy.62.ttf   | Bin 1740 -> 0 bytes
+ .../basics/Roboto-Regular.abc.name-legacy.63.ttf   | Bin 1716 -> 0 bytes
+ ...egular.abc.name-legacy.retain-all-codepoint.ttf | Bin 2168 -> 0 bytes
+ ...eSansPro-Regular.default.1FC,21,41,20,62,63.otf | Bin 2180 -> 2384 bytes
+ .../SourceSansPro-Regular.default.61,62,63.otf     | Bin 1892 -> 2096 bytes
+ ...ourceSansPro-Regular.default.D7,D8,D9,DA,DE.otf | Bin 2008 -> 2212 bytes
+ ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 19796 -> 20000 bytes
+ ...Regular.desubroutinize-retain-gids.61,62,63.otf | Bin 1992 -> 2196 bytes
+ ...r.desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 30208 -> 30412 bytes
+ ...o-Regular.desubroutinize.1FC,21,41,20,62,63.otf | Bin 2036 -> 2240 bytes
+ ...urceSansPro-Regular.desubroutinize.61,62,63.otf | Bin 1796 -> 2000 bytes
+ ...nsPro-Regular.desubroutinize.D7,D8,D9,DA,DE.otf | Bin 1992 -> 2196 bytes
+ ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 19636 -> 19840 bytes
+ ...p-hints-desubroutinize-retain-gids.61,62,63.otf | Bin 1868 -> 2072 bytes
+ ...s-desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 30060 -> 30264 bytes
+ ...rop-hints-desubroutinize.1FC,21,41,20,62,63.otf | Bin 1876 -> 2080 bytes
+ ...-Regular.drop-hints-desubroutinize.61,62,63.otf | Bin 1672 -> 1876 bytes
+ ...ar.drop-hints-desubroutinize.D7,D8,D9,DA,DE.otf | Bin 1844 -> 2048 bytes
+ ...r.drop-hints-retain-gids.1FC,21,41,20,62,63.otf | Bin 19728 -> 19932 bytes
+ ...Pro-Regular.drop-hints-retain-gids.61,62,63.otf | Bin 1904 -> 2108 bytes
+ ...gular.drop-hints-retain-gids.D7,D8,D9,DA,DE.otf | Bin 30072 -> 30276 bytes
+ ...nsPro-Regular.drop-hints.1FC,21,41,20,62,63.otf | Bin 1960 -> 2164 bytes
+ .../SourceSansPro-Regular.drop-hints.61,62,63.otf  | Bin 1736 -> 1940 bytes
+ ...ceSansPro-Regular.drop-hints.D7,D8,D9,DA,DE.otf | Bin 1860 -> 2064 bytes
+ ...sPro-Regular.retain-gids.1FC,21,41,20,62,63.otf | Bin 19948 -> 20152 bytes
+ .../SourceSansPro-Regular.retain-gids.61,62,63.otf | Bin 2060 -> 2264 bytes
+ ...eSansPro-Regular.retain-gids.D7,D8,D9,DA,DE.otf | Bin 30224 -> 30428 bytes
+ .../Roboto-Regular.default.1FC,21,41,20,62,63.ttf  | Bin 2984 -> 3164 bytes
+ .../full-font/Roboto-Regular.default.61,62,63.ttf  | Bin 2580 -> 2760 bytes
+ .../Roboto-Regular.default.D7,D8,D9,DA,DE.ttf      | Bin 2944 -> 3124 bytes
+ ...oboto-Regular.drop-hints.1FC,21,41,20,62,63.ttf | Bin 1436 -> 1616 bytes
+ .../Roboto-Regular.drop-hints.61,62,63.ttf         | Bin 1228 -> 1408 bytes
+ .../Roboto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf   | Bin 1464 -> 1644 bytes
+ ...ifVariable-Roman.default.1FC,21,41,20,62,63.ttf | Bin 3572 -> 4132 bytes
+ .../SourceSerifVariable-Roman.default.61,62,63.ttf | Bin 3540 -> 4100 bytes
+ ...eSerifVariable-Roman.default.D7,D8,D9,DA,DE.ttf | Bin 4032 -> 4592 bytes
+ ...ariable-Roman.drop-hints.1FC,21,41,20,62,63.ttf | Bin 3572 -> 4132 bytes
+ ...urceSerifVariable-Roman.drop-hints.61,62,63.ttf | Bin 3540 -> 4100 bytes
+ ...rifVariable-Roman.drop-hints.D7,D8,D9,DA,DE.ttf | Bin 4032 -> 4592 bytes
+ .../Mplus1p-Regular.default.1D715,1D7D8,41,42.ttf  | Bin 2108 -> 2260 bytes
+ ...gular.default.3042,3044,3046,3048,304A,304B.ttf | Bin 2532 -> 2684 bytes
+ ...gular.default.3042,3044,3046,73E0,5EA6,8F38.ttf | Bin 2776 -> 2928 bytes
+ .../Mplus1p-Regular.default.61,63,65,6B.ttf        | Bin 2076 -> 2228 bytes
+ ...gular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 3072 -> 3224 bytes
+ .../japanese/Mplus1p-Regular.default.660E.ttf      | Bin 1816 -> 1968 bytes
+ ...plus1p-Regular.drop-hints.1D715,1D7D8,41,42.ttf | Bin 1380 -> 1532 bytes
+ ...ar.drop-hints.3042,3044,3046,3048,304A,304B.ttf | Bin 1804 -> 1956 bytes
+ ...ar.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf | Bin 2048 -> 2200 bytes
+ .../Mplus1p-Regular.drop-hints.61,63,65,6B.ttf     | Bin 1348 -> 1500 bytes
+ ...ar.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 2344 -> 2496 bytes
+ .../japanese/Mplus1p-Regular.drop-hints.660E.ttf   | Bin 1088 -> 1240 bytes
+ test/subset/data/profiles/name-languages.txt       |   1 -
+ test/subset/data/profiles/name-legacy.txt          |   1 -
+ test/subset/data/tests/basics.tests                |   2 -
+ test/subset/generate-expected-outputs.py           |   6 ++-
+ util/options-subset.cc                             |  58 ---------------------
+ 114 files changed, 4 insertions(+), 121 deletions(-)
+
+commit 298c46afbfd48f014243be7d3e6dbba5e69d242d
+Author: Dominik Röttsches <drott at chromium.org>
+Date:   Fri Jan 24 12:11:07 2020 +0200
+
+    Only prefer AAT morx for horizontal layout
+    
+    Fixes #2124.
+
+ src/hb-ot-shape.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit fd85818b5b85fb0ad2db71c60e94ca0689d38bca
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Jan 21 13:37:28 2020 -0800
+
+    [subset] Add "--name-languages" and "--name-legacy" options
+    Make name table subsetting consistent with fontTools
+
+ src/hb-ot-name-table.hh                            |  11 ++++
+ src/hb-subset-input.cc                             |  23 ++++++++
+ src/hb-subset-input.hh                             |   2 +
+ src/hb-subset-plan.cc                              |   3 ++
+ src/hb-subset-plan.hh                              |   4 ++
+ src/hb-subset.h                                    |   9 ++++
+ test/api/hb-subset-test.h                          |   5 ++
+ .../Comfortaa-Regular-new.default.61,62,63.ttf     | Bin 7460 -> 7392 bytes
+ .../basics/Comfortaa-Regular-new.default.61,63.ttf | Bin 7104 -> 7036 bytes
+ .../basics/Comfortaa-Regular-new.default.61.ttf    | Bin 6752 -> 6684 bytes
+ .../basics/Comfortaa-Regular-new.default.62.ttf    | Bin 6696 -> 6628 bytes
+ .../basics/Comfortaa-Regular-new.default.63.ttf    | Bin 6676 -> 6608 bytes
+ ...aa-Regular-new.default.retain-all-codepoint.ttf | Bin 182944 -> 182876 bytes
+ ...Regular-new.drop-hints-retain-gids.61,62,63.ttf | Bin 4912 -> 4844 bytes
+ ...aa-Regular-new.drop-hints-retain-gids.61,63.ttf | Bin 4620 -> 4552 bytes
+ ...ortaa-Regular-new.drop-hints-retain-gids.61.ttf | Bin 4056 -> 3988 bytes
+ ...ortaa-Regular-new.drop-hints-retain-gids.62.ttf | Bin 4296 -> 4228 bytes
+ ...ortaa-Regular-new.drop-hints-retain-gids.63.ttf | Bin 4304 -> 4236 bytes
+ ...drop-hints-retain-gids.retain-all-codepoint.ttf | Bin 151740 -> 151672 bytes
+ .../Comfortaa-Regular-new.drop-hints.61,62,63.ttf  | Bin 2920 -> 2852 bytes
+ .../Comfortaa-Regular-new.drop-hints.61,63.ttf     | Bin 2620 -> 2552 bytes
+ .../basics/Comfortaa-Regular-new.drop-hints.61.ttf | Bin 2308 -> 2240 bytes
+ .../basics/Comfortaa-Regular-new.drop-hints.62.ttf | Bin 2296 -> 2228 bytes
+ .../basics/Comfortaa-Regular-new.drop-hints.63.ttf | Bin 2296 -> 2228 bytes
+ ...Regular-new.drop-hints.retain-all-codepoint.ttf | Bin 151676 -> 151608 bytes
+ .../Comfortaa-Regular-new.name-ids.61,62,63.ttf    | Bin 7204 -> 7132 bytes
+ .../Comfortaa-Regular-new.name-ids.61,63.ttf       | Bin 6848 -> 6776 bytes
+ .../basics/Comfortaa-Regular-new.name-ids.61.ttf   | Bin 6496 -> 6424 bytes
+ .../basics/Comfortaa-Regular-new.name-ids.62.ttf   | Bin 6440 -> 6368 bytes
+ .../basics/Comfortaa-Regular-new.name-ids.63.ttf   | Bin 6420 -> 6348 bytes
+ ...a-Regular-new.name-ids.retain-all-codepoint.ttf | Bin 182688 -> 182616 bytes
+ ...mfortaa-Regular-new.name-languages.61,62,63.ttf | Bin 0 -> 7392 bytes
+ .../Comfortaa-Regular-new.name-languages.61,63.ttf | Bin 0 -> 7036 bytes
+ .../Comfortaa-Regular-new.name-languages.61.ttf    | Bin 0 -> 6684 bytes
+ .../Comfortaa-Regular-new.name-languages.62.ttf    | Bin 0 -> 6628 bytes
+ .../Comfortaa-Regular-new.name-languages.63.ttf    | Bin 0 -> 6608 bytes
+ ...lar-new.name-languages.retain-all-codepoint.ttf | Bin 0 -> 182876 bytes
+ .../Comfortaa-Regular-new.name-legacy.61,62,63.ttf | Bin 0 -> 7392 bytes
+ .../Comfortaa-Regular-new.name-legacy.61,63.ttf    | Bin 0 -> 7036 bytes
+ .../Comfortaa-Regular-new.name-legacy.61.ttf       | Bin 0 -> 6684 bytes
+ .../Comfortaa-Regular-new.name-legacy.62.ttf       | Bin 0 -> 6628 bytes
+ .../Comfortaa-Regular-new.name-legacy.63.ttf       | Bin 0 -> 6608 bytes
+ ...egular-new.name-legacy.retain-all-codepoint.ttf | Bin 0 -> 182876 bytes
+ .../Comfortaa-Regular-new.retain-gids.61,62,63.ttf | Bin 9452 -> 9384 bytes
+ .../Comfortaa-Regular-new.retain-gids.61,63.ttf    | Bin 9104 -> 9036 bytes
+ .../Comfortaa-Regular-new.retain-gids.61.ttf       | Bin 8500 -> 8432 bytes
+ .../Comfortaa-Regular-new.retain-gids.62.ttf       | Bin 8696 -> 8628 bytes
+ .../Comfortaa-Regular-new.retain-gids.63.ttf       | Bin 8684 -> 8616 bytes
+ ...egular-new.retain-gids.retain-all-codepoint.ttf | Bin 183008 -> 182940 bytes
+ .../Roboto-Regular.abc.name-languages.61,62,63.ttf | Bin 0 -> 2168 bytes
+ .../Roboto-Regular.abc.name-languages.61,63.ttf    | Bin 0 -> 1988 bytes
+ .../Roboto-Regular.abc.name-languages.61.ttf       | Bin 0 -> 1792 bytes
+ .../Roboto-Regular.abc.name-languages.62.ttf       | Bin 0 -> 1740 bytes
+ .../Roboto-Regular.abc.name-languages.63.ttf       | Bin 0 -> 1716 bytes
+ ...lar.abc.name-languages.retain-all-codepoint.ttf | Bin 0 -> 2168 bytes
+ .../Roboto-Regular.abc.name-legacy.61,62,63.ttf    | Bin 0 -> 2168 bytes
+ .../Roboto-Regular.abc.name-legacy.61,63.ttf       | Bin 0 -> 1988 bytes
+ .../basics/Roboto-Regular.abc.name-legacy.61.ttf   | Bin 0 -> 1792 bytes
+ .../basics/Roboto-Regular.abc.name-legacy.62.ttf   | Bin 0 -> 1740 bytes
+ .../basics/Roboto-Regular.abc.name-legacy.63.ttf   | Bin 0 -> 1716 bytes
+ ...egular.abc.name-legacy.retain-all-codepoint.ttf | Bin 0 -> 2168 bytes
+ ...eSansPro-Regular.default.1FC,21,41,20,62,63.otf | Bin 2384 -> 2180 bytes
+ .../SourceSansPro-Regular.default.61,62,63.otf     | Bin 2096 -> 1892 bytes
+ ...ourceSansPro-Regular.default.D7,D8,D9,DA,DE.otf | Bin 2212 -> 2008 bytes
+ ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 20000 -> 19796 bytes
+ ...Regular.desubroutinize-retain-gids.61,62,63.otf | Bin 2196 -> 1992 bytes
+ ...r.desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 30412 -> 30208 bytes
+ ...o-Regular.desubroutinize.1FC,21,41,20,62,63.otf | Bin 2240 -> 2036 bytes
+ ...urceSansPro-Regular.desubroutinize.61,62,63.otf | Bin 2000 -> 1796 bytes
+ ...nsPro-Regular.desubroutinize.D7,D8,D9,DA,DE.otf | Bin 2196 -> 1992 bytes
+ ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 19840 -> 19636 bytes
+ ...p-hints-desubroutinize-retain-gids.61,62,63.otf | Bin 2072 -> 1868 bytes
+ ...s-desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 30264 -> 30060 bytes
+ ...rop-hints-desubroutinize.1FC,21,41,20,62,63.otf | Bin 2080 -> 1876 bytes
+ ...-Regular.drop-hints-desubroutinize.61,62,63.otf | Bin 1876 -> 1672 bytes
+ ...ar.drop-hints-desubroutinize.D7,D8,D9,DA,DE.otf | Bin 2048 -> 1844 bytes
+ ...r.drop-hints-retain-gids.1FC,21,41,20,62,63.otf | Bin 19932 -> 19728 bytes
+ ...Pro-Regular.drop-hints-retain-gids.61,62,63.otf | Bin 2108 -> 1904 bytes
+ ...gular.drop-hints-retain-gids.D7,D8,D9,DA,DE.otf | Bin 30276 -> 30072 bytes
+ ...nsPro-Regular.drop-hints.1FC,21,41,20,62,63.otf | Bin 2164 -> 1960 bytes
+ .../SourceSansPro-Regular.drop-hints.61,62,63.otf  | Bin 1940 -> 1736 bytes
+ ...ceSansPro-Regular.drop-hints.D7,D8,D9,DA,DE.otf | Bin 2064 -> 1860 bytes
+ ...sPro-Regular.retain-gids.1FC,21,41,20,62,63.otf | Bin 20152 -> 19948 bytes
+ .../SourceSansPro-Regular.retain-gids.61,62,63.otf | Bin 2264 -> 2060 bytes
+ ...eSansPro-Regular.retain-gids.D7,D8,D9,DA,DE.otf | Bin 30428 -> 30224 bytes
+ .../Roboto-Regular.default.1FC,21,41,20,62,63.ttf  | Bin 3164 -> 2984 bytes
+ .../full-font/Roboto-Regular.default.61,62,63.ttf  | Bin 2760 -> 2580 bytes
+ .../Roboto-Regular.default.D7,D8,D9,DA,DE.ttf      | Bin 3124 -> 2944 bytes
+ ...oboto-Regular.drop-hints.1FC,21,41,20,62,63.ttf | Bin 1616 -> 1436 bytes
+ .../Roboto-Regular.drop-hints.61,62,63.ttf         | Bin 1408 -> 1228 bytes
+ .../Roboto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf   | Bin 1644 -> 1464 bytes
+ ...ifVariable-Roman.default.1FC,21,41,20,62,63.ttf | Bin 4132 -> 3572 bytes
+ .../SourceSerifVariable-Roman.default.61,62,63.ttf | Bin 4100 -> 3540 bytes
+ ...eSerifVariable-Roman.default.D7,D8,D9,DA,DE.ttf | Bin 4592 -> 4032 bytes
+ ...ariable-Roman.drop-hints.1FC,21,41,20,62,63.ttf | Bin 4132 -> 3572 bytes
+ ...urceSerifVariable-Roman.drop-hints.61,62,63.ttf | Bin 4100 -> 3540 bytes
+ ...rifVariable-Roman.drop-hints.D7,D8,D9,DA,DE.ttf | Bin 4592 -> 4032 bytes
+ .../Mplus1p-Regular.default.1D715,1D7D8,41,42.ttf  | Bin 2260 -> 2108 bytes
+ ...gular.default.3042,3044,3046,3048,304A,304B.ttf | Bin 2684 -> 2532 bytes
+ ...gular.default.3042,3044,3046,73E0,5EA6,8F38.ttf | Bin 2928 -> 2776 bytes
+ .../Mplus1p-Regular.default.61,63,65,6B.ttf        | Bin 2228 -> 2076 bytes
+ ...gular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 3224 -> 3072 bytes
+ .../japanese/Mplus1p-Regular.default.660E.ttf      | Bin 1968 -> 1816 bytes
+ ...plus1p-Regular.drop-hints.1D715,1D7D8,41,42.ttf | Bin 1532 -> 1380 bytes
+ ...ar.drop-hints.3042,3044,3046,3048,304A,304B.ttf | Bin 1956 -> 1804 bytes
+ ...ar.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf | Bin 2200 -> 2048 bytes
+ .../Mplus1p-Regular.drop-hints.61,63,65,6B.ttf     | Bin 1500 -> 1348 bytes
+ ...ar.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 2496 -> 2344 bytes
+ .../japanese/Mplus1p-Regular.drop-hints.660E.ttf   | Bin 1240 -> 1088 bytes
+ test/subset/data/profiles/name-languages.txt       |   1 +
+ test/subset/data/profiles/name-legacy.txt          |   1 +
+ test/subset/data/tests/basics.tests                |   2 +
+ test/subset/generate-expected-outputs.py           |   6 +--
+ util/options-subset.cc                             |  58 +++++++++++++++++++++
+ 114 files changed, 121 insertions(+), 4 deletions(-)
+
+commit c370da45ff0dd64c2868be313e640272931cffed
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Jan 22 11:36:15 2020 -0800
+
+    [subset] Cmap table: remove encodingRecord entry for empty cmap4 subtable
+
+ src/hb-ot-cmap-table.hh                            |  10 ++++++----
+ test/api/fonts/Roboto-Regular.empty.ttf            | Bin 0 -> 1456 bytes
+ test/api/test-subset-cmap.c                        |  21 +++++++++++++++++++++
+ .../japanese/Mplus1p-Regular.default.25771.ttf     | Bin 0 -> 1976 bytes
+ .../japanese/Mplus1p-Regular.drop-hints.25771.ttf  | Bin 0 -> 1248 bytes
+ test/subset/data/tests/japanese.tests              |   1 +
+ 6 files changed, 28 insertions(+), 4 deletions(-)
+
+commit d3fff622b35725bbdfb07fea98a58f56199991f4
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Thu Jan 23 11:36:47 2020 -0500
+
+    Move push call to caller
+
+ src/hb-ot-color-sbix-table.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit 7dc341fe745bc1784b08efd4c658de292b958b0d
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Thu Jan 23 11:09:15 2020 -0500
+
+    [subset] Fix UBSAN issue in sbix
+
+ src/hb-ot-color-sbix-table.hh                             |   5 +++--
+ ...z-testcase-minimized-hb-subset-fuzzer-5753173985984512 | Bin 0 -> 616 bytes
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+commit acb4627ebaf595e266cf294ef047e87084b520da
+Author: ariza <ariza at adobe.com>
+Date:   Wed Jan 22 12:28:30 2020 -0800
+
+    add api test
+
+ test/api/fonts/AdobeVFPrototype.WA.gpos.otf  | Bin 0 -> 3948 bytes
+ test/api/fonts/AdobeVFPrototype.WAV.gpos.otf | Bin 0 -> 4448 bytes
+ test/api/test-subset-gpos.c                  |  27 +++++++++++++++++++++++++++
+ 3 files changed, 27 insertions(+)
+
+commit 1ab3924b3171b408438f5df6a4d48124d9d1bd68
+Author: ariza <ariza at adobe.com>
+Date:   Wed Jan 22 11:20:56 2020 -0800
+
+    refix PR #2087 subset PairPos1
+    
+    also added oss-fuzz 20211 data fixed by this
+
+ src/hb-ot-layout-gpos-table.hh                           |  10 ++++------
+ ...-testcase-minimized-hb-subset-fuzzer-5206191479455744 | Bin 0 -> 3558 bytes
+ 2 files changed, 4 insertions(+), 6 deletions(-)
+
+commit 7633b7695e5b6188d6180fc5592c0678f03327ed
+Merge: 3747b329 02f324c9
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Jan 23 18:51:40 2020 +0330
+
+    Merge pull request #2016 from ebraminio/glyf
+    
+    Implement glyph outline path API
+
+commit 02f324c9499a95463c363926a0f38c261fad7117
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Jan 23 15:12:12 2020 +0330
+
+    [ot-glyph] remove open callback
+    
+    Apparently it wasn't requested actually and can be detected easily
+    as paths are opened usually when move command is issued anyway.
+
+ docs/harfbuzz-sections.txt |  2 --
+ src/hb-ot-cff1-table.cc    |  2 +-
+ src/hb-ot-cff2-table.cc    |  2 +-
+ src/hb-ot-glyf-table.hh    |  1 -
+ src/hb-ot-glyph.cc         | 31 ++++++++-----------------------
+ src/hb-ot-glyph.h          |  5 -----
+ src/hb-ot-glyph.hh         |  1 -
+ src/test-ot-glyph.cc       |  1 +
+ test/api/test-ot-glyph.c   |  4 ----
+ 9 files changed, 11 insertions(+), 38 deletions(-)
+
+commit 684ff3e0cd77dfa5e83c2110ea613b8b9678d4f5
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Jan 23 14:48:59 2020 +0330
+
+    [ot-glyph] noop->nil, fix close path
+
+ src/hb-ot-cff1-table.cc  | 10 +++++-----
+ src/hb-ot-cff2-table.cc  |  6 +++---
+ src/hb-ot-glyph.cc       | 23 ++++++++++-------------
+ test/api/test-ot-glyph.c | 22 +++++++++++-----------
+ 4 files changed, 29 insertions(+), 32 deletions(-)
+
+commit 3747b329b2a8be0f234fca861364951bf9de1797
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Wed Jan 22 09:07:32 2020 -0500
+
+    Address garretrieger@'s comments
+
+ src/hb-ot-color-sbix-table.hh | 18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+commit b18cb5b5ee56477e85cf82b299ac08df6202b148
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Tue Jan 21 15:43:12 2020 -0500
+
+    Add second fixed test
+
+ ...estcase-minimized-hb-subset-fuzzer-5747028458209280 | Bin 0 -> 100109 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit af62c1c3b036904a18e0ed0748ead255029bc9f3
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Tue Jan 21 15:19:33 2020 -0500
+
+    Fix style issue
+
+ src/hb-ot-color-sbix-table.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 8614a30bc9763ba7f8b452df5527d806bacf4fd9
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Tue Jan 21 15:14:03 2020 -0500
+
+    [subset] Fix sbix fuzz problem
+
+ src/hb-ot-color-sbix-table.hh                       |  20 +++++++++++++-------
+ ...case-minimized-hb-subset-fuzzer-5741295280848896 | Bin 0 -> 98822 bytes
+ 2 files changed, 13 insertions(+), 7 deletions(-)
+
+commit 72cbfb9059ac4f041cffaef86a1d8067a93b16ec
+Author: ariza <ariza at adobe.com>
+Date:   Sat Jan 18 16:35:52 2020 -0800
+
+    remove empty lookup subtables
+    
+    Added a variant of subset_offset_array which takes an extra arg passed to serialize_subset for this impl.
+    Added a new api test "test-subset-gpos" for this.
+
+ src/hb-ot-layout-common.hh                 |  70 ++++++++++++++++++++++++-----
+ src/hb-ot-layout-gpos-table.hh             |   6 +++
+ src/hb-ot-layout-gsub-table.hh             |   6 +++
+ test/api/Makefile.am                       |   2 +
+ test/api/fonts/Roboto-Regular-gpos-.aw.ttf | Bin 0 -> 2368 bytes
+ test/api/fonts/Roboto-Regular-gpos-aw.ttf  | Bin 0 -> 2232 bytes
+ test/api/test-subset-gpos.c                |  65 +++++++++++++++++++++++++++
+ 7 files changed, 139 insertions(+), 10 deletions(-)
+
+commit a3cf4ae0804f2971bcda4266dbeec245bce21eb1
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Fri Jan 17 13:02:47 2020 -0800
+
+    [subset] Add more tests for GPOS1 subsetting
+    These tests were left out because of issue: https://github.com/fonttools/fonttools/issues/1709
+    Now re-adding these tests since the issue is resolved.
+
+ .../gpos1_2_font.keep-layout-retain-gids.41.otf          | Bin 0 -> 1932 bytes
+ .../layout.gpos/gpos1_2_font.keep-layout.41,43.otf       | Bin 0 -> 1352 bytes
+ .../layout.gpos/gpos1_2_font.keep-layout.41,46.otf       | Bin 0 -> 1484 bytes
+ .../expected/layout.gpos/gpos1_2_font.keep-layout.41.otf | Bin 0 -> 1232 bytes
+ .../layout.gpos/gpos1_2_font.keep-layout.42,44.otf       | Bin 0 -> 1268 bytes
+ .../layout.gpos/gpos1_2_font.keep-layout.43,46.otf       | Bin 0 -> 1348 bytes
+ .../gpos1_2_font.keep-layout.retain-all-codepoint.otf    | Bin 0 -> 3668 bytes
+ test/subset/data/tests/layout.gpos.tests                 |   2 ++
+ 8 files changed, 2 insertions(+)
+
+commit 8f49aaa16f2dff5902142988b3a5a039a03129eb
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Jan 16 15:15:15 2020 -0800
+
+    minor: un-include glyf.hh in gvar.hh
+
+ src/hb-ot-var-gvar-table.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit c828d7bf76dd039be1775edff1d798dbcc10708b
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Jan 15 15:32:44 2020 -0800
+
+    [subset] fixed GPOS device table sanitize & serialize (#2087)
+
+ src/hb-ot-layout-gpos-table.hh | 112 ++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 93 insertions(+), 19 deletions(-)
+
+commit e565d1f9bcf3d9bf607e194e3a9cf06f5d2e3633
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Fri Nov 1 10:21:36 2019 -0700
+
+    [subset] subset lookup/feature/script lists for GSUB/GPOS
+
+ src/hb-ot-layout-common.hh                         | 396 +++++++++++++++++----
+ src/hb-ot-layout-gpos-table.hh                     |   5 +-
+ src/hb-ot-layout-gsub-table.hh                     |   5 +-
+ src/hb-ot-layout-gsubgpos.hh                       |  41 ++-
+ test/api/test-ot-face.c                            |   7 +
+ .../gpos1_2_font.keep-layout-retain-gids.42,44.otf | Bin 0 -> 1992 bytes
+ ...s2_1_font7.keep-layout-retain-gids.41,42,43.otf | Bin 0 -> 1988 bytes
+ .../gpos2_1_font7.keep-layout.41,42,43.otf         | Bin 0 -> 1288 bytes
+ ...s2_2_font5.keep-layout-retain-gids.41,42,43.otf | Bin 0 -> 1988 bytes
+ .../gpos2_2_font5.keep-layout.41,42,43.otf         | Bin 0 -> 1288 bytes
+ ...pos3_font3.keep-layout-retain-gids.41,42,43.otf | Bin 0 -> 1984 bytes
+ .../gpos3_font3.keep-layout.41,42,43.otf           | Bin 0 -> 1284 bytes
+ ...ubrules_f1.keep-layout-retain-gids.41,42,43.otf | Bin 0 -> 2044 bytes
+ ...1_multiple_subrules_f1.keep-layout.41,42,43.otf | Bin 0 -> 1344 bytes
+ ...ubrules_f1.keep-layout-retain-gids.41,42,43.otf | Bin 0 -> 2044 bytes
+ ...2_multiple_subrules_f1.keep-layout.41,42,43.otf | Bin 0 -> 1344 bytes
+ ..._simple_f2.keep-layout-retain-gids.41,42,43.otf | Bin 0 -> 2020 bytes
+ ...ub_chaining3_simple_f2.keep-layout.41,42,43.otf | Bin 0 -> 1320 bytes
+ test/subset/data/tests/layout.gpos.tests           |   1 +
+ test/subset/data/tests/layout.gpos2.tests          |   1 +
+ test/subset/data/tests/layout.gpos3.tests          |   1 +
+ test/subset/data/tests/layout.gsub6.tests          |   1 +
+ 22 files changed, 380 insertions(+), 78 deletions(-)
+
+commit 93376a64362a0d062aa3f9f39bfe0d7b4328a92e
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Wed Jan 15 13:11:40 2020 -0500
+
+    Add unittests
+
+ src/hb-subset-input.cc                             |   2 -
+ test/api/Makefile.am                               |   2 +
+ test/api/fonts/sbix.ttf                            | Bin 0 -> 193528 bytes
+ test/api/fonts/sbix_X.ttf                          | Bin 0 -> 121168 bytes
+ test/api/test-subset-sbix.c                        |  81 +++++++++++++++++++++
+ .../data/expected/sbix/sbix.default.58,59.ttf      | Bin 196080 -> 193528 bytes
+ test/subset/data/expected/sbix/sbix.default.58.ttf | Bin 122736 -> 121168 bytes
+ test/subset/data/expected/sbix/sbix.default.59.ttf | Bin 90344 -> 89364 bytes
+ .../sbix/sbix.drop-hints-retain-gids.58,59.ttf     | Bin 196080 -> 193528 bytes
+ .../sbix/sbix.drop-hints-retain-gids.58.ttf        | Bin 122736 -> 121168 bytes
+ .../sbix/sbix.drop-hints-retain-gids.59.ttf        | Bin 90384 -> 89404 bytes
+ .../data/expected/sbix/sbix.drop-hints.58,59.ttf   | Bin 196080 -> 193528 bytes
+ .../data/expected/sbix/sbix.drop-hints.58.ttf      | Bin 122736 -> 121168 bytes
+ .../data/expected/sbix/sbix.drop-hints.59.ttf      | Bin 90344 -> 89364 bytes
+ .../data/expected/sbix/sbix.retain-gids.58,59.ttf  | Bin 196080 -> 193528 bytes
+ .../data/expected/sbix/sbix.retain-gids.58.ttf     | Bin 122736 -> 121168 bytes
+ .../data/expected/sbix/sbix.retain-gids.59.ttf     | Bin 90384 -> 89404 bytes
+ test/subset/data/fonts/sbix.ttf                    | Bin 196080 -> 193528 bytes
+ 18 files changed, 83 insertions(+), 2 deletions(-)
+
+commit 6bcf57eaa3d9b1381e384743a2fbee912d72474e
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Tue Jan 14 14:56:02 2020 -0500
+
+    Simplify copy and add fuzzing coverage
+
+ src/hb-ot-color-sbix-table.hh |   7 ++-----
+ test/fuzzing/fonts/sbix.ttf   | Bin 0 -> 196080 bytes
+ 2 files changed, 2 insertions(+), 5 deletions(-)
+
+commit 78b50a67be6fb40e715132eabe9b05c64ddd99c8
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Tue Jan 14 11:01:09 2020 -0500
+
+    Address initial comments
+
+ src/hb-ot-color-sbix-table.hh                      |  49 +++++++++------------
+ .../data/expected/sbix/sbix.default.58,59.ttf      | Bin 0 -> 196080 bytes
+ .../sbix/sbix.drop-hints-retain-gids.58,59.ttf     | Bin 0 -> 196080 bytes
+ .../data/expected/sbix/sbix.drop-hints.58,59.ttf   | Bin 0 -> 196080 bytes
+ .../data/expected/sbix/sbix.retain-gids.58,59.ttf  | Bin 0 -> 196080 bytes
+ test/subset/data/tests/sbix.tests                  |   2 +-
+ 6 files changed, 23 insertions(+), 28 deletions(-)
+
+commit 43b6c865aeb763944362375e1c345afcd60211b4
+Author: ckitagawa <ckitagawa at chromium.org>
+Date:   Thu Jan 9 10:44:20 2020 -0500
+
+    [subset] Support sbix subsetting
+
+ src/hb-ot-color-sbix-table.hh                      | 126 +++++++++++++++++++++
+ src/hb-subset.cc                                   |   4 +
+ test/subset/data/Makefile.am                       |   1 +
+ test/subset/data/Makefile.sources                  |   1 +
+ test/subset/data/expected/sbix/sbix.default.58.ttf | Bin 0 -> 122736 bytes
+ test/subset/data/expected/sbix/sbix.default.59.ttf | Bin 0 -> 90344 bytes
+ .../sbix/sbix.drop-hints-retain-gids.58.ttf        | Bin 0 -> 122736 bytes
+ .../sbix/sbix.drop-hints-retain-gids.59.ttf        | Bin 0 -> 90384 bytes
+ .../data/expected/sbix/sbix.drop-hints.58.ttf      | Bin 0 -> 122736 bytes
+ .../data/expected/sbix/sbix.drop-hints.59.ttf      | Bin 0 -> 90344 bytes
+ .../data/expected/sbix/sbix.retain-gids.58.ttf     | Bin 0 -> 122736 bytes
+ .../data/expected/sbix/sbix.retain-gids.59.ttf     | Bin 0 -> 90384 bytes
+ test/subset/data/fonts/sbix.ttf                    | Bin 0 -> 196080 bytes
+ test/subset/data/tests/sbix.tests                  |  13 +++
+ test/subset/generate-expected-outputs.py           |   1 +
+ test/subset/run-tests.py                           |   3 +-
+ 16 files changed, 148 insertions(+), 1 deletion(-)
+
+commit 79fed9a1e42397ed4044d3ce8f042309f0e4cde8
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Jan 14 17:23:30 2020 +0330
+
+    [ot-glyph] Add open/close callbacks
+
+ docs/harfbuzz-sections.txt |  4 ++++
+ src/hb-ot-cff1-table.cc    |  4 ++--
+ src/hb-ot-cff2-table.cc    |  4 ++--
+ src/hb-ot-glyf-table.hh    |  9 ++++++--
+ src/hb-ot-glyph.cc         | 39 +++++++++++++++++++++++++++++++
+ src/hb-ot-glyph.h          | 10 ++++++++
+ src/hb-ot-glyph.hh         |  2 ++
+ src/test-ot-glyph.cc       |  6 +++++
+ test/api/test-ot-glyph.c   | 57 +++++++++++++++++++++++++++++-----------------
+ 9 files changed, 108 insertions(+), 27 deletions(-)
+
+commit ec1fba1388c329c7216bcdaa9a86627abfc85637
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Jan 13 19:31:18 2020 +0330
+
+    [ot-glyph] make hb_ot_glyph_decompose_funcs_t struct opaque
+
+ docs/harfbuzz-sections.txt |  11 +++-
+ src/Makefile.sources       |   1 +
+ src/hb-ot-cff1-table.cc    |  11 ++--
+ src/hb-ot-cff1-table.hh    |   2 +-
+ src/hb-ot-cff2-table.cc    |   7 +-
+ src/hb-ot-cff2-table.hh    |   2 +-
+ src/hb-ot-glyf-table.hh    |   3 +-
+ src/hb-ot-glyph.cc         | 156 ++++++++++++++++++++++++++++++++++++++++++++-
+ src/hb-ot-glyph.h          |  41 ++++++++----
+ src/hb-ot-glyph.hh         |  44 +++++++++++++
+ src/test-ot-glyph.cc       |  14 ++--
+ test/api/test-ot-face.c    |  34 ++--------
+ test/api/test-ot-glyph.c   |  51 ++++++---------
+ 13 files changed, 281 insertions(+), 96 deletions(-)
+
+commit 8ffc9add2237899afc57184ad3297404659bc1cd
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Oct 31 15:59:02 2019 -0700
+
+    [subset] layout closure_features and store them in subset-plan
+
+ docs/harfbuzz-sections.txt   |  1 +
+ src/hb-ot-layout-common.hh   | 35 ++++++++++++++++++++++++++++
+ src/hb-ot-layout-gsubgpos.hh | 14 +++++++++++
+ src/hb-ot-layout.cc          | 21 +++++++++++++++++
+ src/hb-ot-layout.h           |  6 +++++
+ src/hb-subset-plan.cc        | 55 +++++++++++++++++++++++++++++++-------------
+ src/hb-subset-plan.hh        |  4 ++++
+ 7 files changed, 120 insertions(+), 16 deletions(-)
+
+commit 66dfd605b5b9aaf74ff806ba1719ca09a1003909
+Author: Dominik Röttsches <drott at chromium.org>
+Date:   Mon Jan 13 15:50:27 2020 +0200
+
+    Fix duplicate check in hb_ot_rotate chars
+    
+    Fixes #2099. Fix indentation in mirroring section as well.
+
+ src/hb-ot-shape.cc | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit d7c3cb18ee6b2ffe529c5d703fae1cd965f39dc9
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Jan 13 17:35:57 2020 +0330
+
+    [ot-glyph] minor on tests
+
+ src/test-ot-glyph.cc     | 28 +++++++----------
+ test/api/test-ot-face.c  | 13 ++++----
+ test/api/test-ot-glyph.c | 81 ++++++++++++++++++++++++++++++++++--------------
+ 3 files changed, 77 insertions(+), 45 deletions(-)
+
+commit dc03a993d0f2b6db7c5cfb11eaa6e8a4f6f274e6
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Jan 12 14:21:29 2020 +0330
+
+    Fix collect lookups logic of FeatureTableSubstitution (#2097)
+    
+    https://crbug.com/oss-fuzz/20036
+
+ src/hb-ot-layout-common.hh                               |   6 +++---
+ ...-testcase-minimized-hb-subset-fuzzer-5715299773186048 | Bin 0 -> 6717 bytes
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit a32ecc15aec6518f5a126fb8f3643e563327f74d
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Jan 11 15:37:24 2020 +0330
+
+    Fix collect lookups logic of FeatureVariationRecord
+    
+    As "Offset to a feature table substitution table, from beginning of the FeatureVariations table."
+    from https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2 the record should
+    match its sanitize logic not the reverse way.
+    
+    Fixes https://crbug.com/oss-fuzz/20021 and https://crbug.com/oss-fuzz/20022
+
+ src/hb-ot-layout-common.hh                                 |   7 ++++---
+ ...zz-testcase-minimized-hb-subset-fuzzer-5167653459329024 | Bin 0 -> 46 bytes
+ ...zz-testcase-minimized-hb-subset-fuzzer-5642531954229248 | Bin 0 -> 46 bytes
+ 3 files changed, 4 insertions(+), 3 deletions(-)
+
+commit 1a4c658b43152ab01bcb6d151940c09cc1e8fc56
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Jan 11 01:30:05 2020 +0330
+
+    Use REPLACEME tag
+    
+    So we can use the version we like when we decide what it should be while the next release
+    and can review the API before the release one other time.
+
+ src/hb-ot-layout.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit d7454cf07eeb87600d8fcf23ada3617b6bda0f35
+Merge: 9cd76813 0b39c480
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Jan 11 01:24:39 2020 +0330
+
+    [subset] closure lookups for GSUB/GPOS
+
+commit 0b39c48064864850193bc80e2566839546be3551
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Oct 22 16:00:43 2019 -0700
+
+    [subset] closure lookups for GSUB/GPOS
+
+ docs/harfbuzz-sections.txt     |   1 +
+ src/hb-ot-layout-common.hh     |  30 ++++++++
+ src/hb-ot-layout-gpos-table.hh |  42 +++++++++++
+ src/hb-ot-layout-gsub-table.hh |  39 ++++++++++
+ src/hb-ot-layout-gsubgpos.hh   | 158 ++++++++++++++++++++++++++++++++++++++++-
+ src/hb-ot-layout.cc            |  44 ++++++++++++
+ src/hb-ot-layout.h             |   6 ++
+ src/hb-subset-plan.cc          |  56 +++++++++++++--
+ src/hb-subset-plan.hh          |   4 ++
+ test/api/test-ot-face.c        |   5 ++
+ 10 files changed, 379 insertions(+), 6 deletions(-)
+
+commit 42f4f1ea5013e9879fdb008021956c32247fa3db
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Jan 11 00:00:51 2020 +0330
+
+    [ot-glyph] Add tests for hb_ot_glyph_decompose
+
+ src/hb-ot-glyf-table.hh  |   2 +-
+ test/api/Makefile.am     |   1 +
+ test/api/test-ot-face.c  |  24 +++---
+ test/api/test-ot-glyph.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 207 insertions(+), 10 deletions(-)
+
+commit 06a1fcb3b47050257f7819eb3d6043cf78ebbac2
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Jan 10 23:12:30 2020 +0330
+
+    [ot-glyphs] fix the tests
+
+ src/hb-ot-cff1-table.cc |  4 ++--
+ src/hb-ot-cff2-table.cc |  2 +-
+ src/hb-ot-glyph.h       |  2 +-
+ test/api/test-ot-face.c | 25 +++++++++++++++++++++++--
+ 4 files changed, 27 insertions(+), 6 deletions(-)
+
+commit 084a8182fb5c79cb8ebb41e015992fc4e4daea4a
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Jan 10 22:14:46 2020 +0330
+
+    [ot-glyphs] Move CFF glyph decompose logic to their tables
+    
+    Thus making path decompose zero alloc on CFF/CFF2
+
+ docs/harfbuzz-sections.txt | 14 ++++----
+ src/hb-ot-cff1-table.cc    | 85 +++++++++++++++++++++++++++-------------------
+ src/hb-ot-cff1-table.hh    |  3 +-
+ src/hb-ot-cff2-table.cc    | 62 ++++++++++++++++-----------------
+ src/hb-ot-cff2-table.hh    |  6 ++--
+ src/hb-ot-glyph.cc         | 41 ++--------------------
+ 6 files changed, 93 insertions(+), 118 deletions(-)
+
+commit 61185235025db6b205dea65c5423905d69c457cd
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Jan 10 21:08:21 2020 +0330
+
+    [ot-glyph] move glyph decompose logic of glyf to itself
+    
+    One less vector allocation yet isn't zero alloc yet
+    which needs more work.
+
+ src/hb-ot-glyf-table.hh | 31 +++++++++++++++----------------
+ src/hb-ot-glyph.cc      | 16 ++++++----------
+ src/test-ot-glyph.cc    |  7 ++++++-
+ 3 files changed, 27 insertions(+), 27 deletions(-)
+
+commit 017f606c83cbf410cb61b7a4cdc2e9cd1bb3e1b6
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Jan 10 20:44:15 2020 +0330
+
+    [ot-glyph] rewrite the API
+
+ src/hb-ot-glyph.cc   | 176 ++++++++++++---------------------------------------
+ src/hb-ot-glyph.h    |  59 +++++++++--------
+ src/test-ot-glyph.cc |  83 +++++++++++++++---------
+ 3 files changed, 126 insertions(+), 192 deletions(-)
+
+commit 9cd76813ab0280238dd7baa1bc58405333e5fa5d
+Author: Evgeniy Reizner <razrfalcon at gmail.com>
+Date:   Fri Jan 10 17:36:41 2020 +0200
+
+    Fix malformed readme. (#2093)
+
+ README.md | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 05443e55bc232f0a6a08d5ef6cc58ebf3e373ee7
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Nov 28 09:16:58 2019 +0330
+
+    [ot-glyph] Return empty path for empty faces
+
+ src/hb-ot-glyph.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6e7602c1049a1b409c1db61ac2dfa2d2b57a170d
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Nov 28 08:43:00 2019 +0330
+
+    [ot-glyph] Fix leaks
+
+ src/hb-ot-glyph.cc | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+commit 5b08596d60f4e8b8efb92d3701eeb100bdad71ca
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Nov 28 08:42:45 2019 +0330
+
+    [gvar] Don't apply anything when no coords is given
+
+ src/hb-ot-var-gvar-table.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 742aaa136343e1aed223612f0801a7e17bb92936
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Nov 27 23:18:43 2019 +0330
+
+    [ot-glyf] Fix leak issue
+
+ src/hb-ot-glyph.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit fddf79fc3735274f0252596c28fff8034916b1ca
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Oct 21 14:11:27 2019 +0330
+
+    [glyf] minor
+
+ src/hb-ot-glyf-table.hh | 7 ++-----
+ test/api/test-ot-face.c | 3 +++
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 0b559d750fbc2a99d1605e1c35c228f938bf2bf1
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Oct 21 13:52:48 2019 +0330
+
+    [ot-glyph] Improve API names
+
+ docs/harfbuzz-sections.txt | 12 ++++++++++++
+ src/hb-ot-glyph.cc         | 10 +++++-----
+ src/hb-ot-glyph.h          | 23 ++++++++++++-----------
+ src/test-ot-glyph.cc       | 10 ++++++++--
+ 4 files changed, 37 insertions(+), 18 deletions(-)
+
+commit af08f388ab2c2e48f39c0b31644baab5b37c1975
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Oct 21 13:28:05 2019 +0330
+
+    [ot-glyph] Support CFF1's seac
+
+ src/hb-ot-cff1-table.cc | 45 +++++++++++++++++++++------------------------
+ 1 file changed, 21 insertions(+), 24 deletions(-)
+
+commit 04ac7fb1c9f93c7002792e5d676b6a145d3be628
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Oct 21 13:06:12 2019 +0330
+
+    [ot-glyph] Add cff2 support
+
+ src/hb-ot-cff1-table.cc | 45 +++++++++++++++----------
+ src/hb-ot-cff2-table.cc | 87 +++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-cff2-table.hh |  4 +++
+ src/hb-ot-glyf-table.hh | 26 +++++++++------
+ src/hb-ot-glyph.cc      | 25 +++++++-------
+ src/hb-ot-glyph.h       |  2 +-
+ 6 files changed, 148 insertions(+), 41 deletions(-)
+
+commit 5cc09c462bad8532c220813b1cccb72d2e2ff855
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Oct 20 16:24:14 2019 +0330
+
+    [ot-glyph] Initial cff1 support
+
+ src/hb-ot-cff1-table.cc | 110 ++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-cff1-table.hh |   1 +
+ src/hb-ot-glyph.cc      |   5 +++
+ 3 files changed, 116 insertions(+)
+
+commit 3dcba9f21554db54daf89d4566938c5a69636b5b
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Oct 20 16:23:27 2019 +0330
+
+    [ot-glyph] Redesign the API
+
+ src/hb-ot-glyph.cc   | 143 ++++++++++++++++++++++++++++++++++++++++++++-------
+ src/hb-ot-glyph.h    |  40 +++++++++-----
+ src/test-ot-glyph.cc |  38 ++++++++++----
+ 3 files changed, 179 insertions(+), 42 deletions(-)
+
+commit b8b3ff1a02c637163d8629d51843f6822a12cdef
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Oct 14 15:37:41 2019 +0330
+
+    [glyph] Don't copy, write directly into result
+
+ src/hb-ot-glyf-table.hh | 26 ++++++++++----------------
+ src/hb-ot-glyph.cc      | 25 ++++++++++++++++---------
+ src/test-ot-glyph.cc    |  6 ++++--
+ 3 files changed, 30 insertions(+), 27 deletions(-)
+
+commit f883c31cce18372269fc1e46b3379295de7c9f7c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Oct 13 12:31:53 2019 +0330
+
+    Implement glyph outline path API
+    
+    Got help from https://github.com/opentypejs/opentype.js/blob/4e0bb99/src/tables/glyf.js#L222
+
+ src/Makefile.am             |   5 ++
+ src/Makefile.sources        |   2 +
+ src/harfbuzz.cc             |   1 +
+ src/hb-ot-glyf-table.hh     | 119 +++++++++++++++++++++++++++++++++-----------
+ src/hb-ot-glyph.cc          |  50 +++++++++++++++++++
+ src/hb-ot-glyph.h           |  52 +++++++++++++++++++
+ src/hb-ot-var-gvar-table.hh |   6 ++-
+ src/hb-ot.h                 |   1 +
+ src/test-ot-glyph.cc        |  84 +++++++++++++++++++++++++++++++
+ 9 files changed, 290 insertions(+), 30 deletions(-)
+
+commit d2ab1ec65b1697b113b2b923c63e300659cf1998
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Jan 9 20:24:16 2020 -0800
+
+    fixes oss-fuzz 19978: Null-dereference READ (#2091)
+
+ src/hb-ot-var-hvar-table.hh                              |   1 +
+ ...-testcase-minimized-hb-subset-fuzzer-5148388450631680 | Bin 0 -> 2685 bytes
+ 2 files changed, 1 insertion(+)
+
+commit 5e55a6d6910e3c942638ad6e9fa1e38befb36c12
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Jan 9 23:40:40 2020 +0330
+
+    [subset/hvar] minor
+    
+    not super excited about state of the code around, assuming was needed
+    so let's add this may unlikely check also.
+
+ src/hb-ot-var-hvar-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 257a197ae723b55d26c3254dbe1edd8b0509af1b
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Jan 9 22:55:45 2020 +0330
+
+    Fail serialize when map has incorrect value
+    
+    fixes https://crbug.com/oss-fuzz/19956
+    
+    am not super happy with the fix, guess we should do some check
+    before the memcpy anyway as @blueshade7 thinks also,
+    so let's have it or revert it when we have a better approach for the case.
+
+ src/hb-ot-layout-common.hh                               |   7 ++++++-
+ ...-testcase-minimized-hb-subset-fuzzer-5708764082864128 | Bin 0 -> 6452 bytes
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+commit 1db2c1d0da9eed4b330ca0c6a46c19482c6e377b
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Jan 7 11:10:40 2020 -0800
+
+    fix for cmap4 and OS_2 subsetting: maximum character code allowed is 0xFFFF
+
+ src/hb-ot-cmap-table.hh                            |  14 ++++++++----
+ src/hb-ot-os2-table.hh                             |   4 ++--
+ test/api/fonts/Mplus1p-Regular-cmap4-testing.ttf   | Bin 0 -> 2024 bytes
+ test/api/fonts/Mplus1p-Regular.ttf                 | Bin 0 -> 1757292 bytes
+ test/api/test-subset-cmap.c                        |  24 +++++++++++++++++++++
+ .../Mplus1p-Regular.default.1D715,1D7D8,41,42.ttf  | Bin 0 -> 2260 bytes
+ ...plus1p-Regular.drop-hints.1D715,1D7D8,41,42.ttf | Bin 0 -> 1532 bytes
+ test/subset/data/tests/japanese.tests              |   2 +-
+ 8 files changed, 37 insertions(+), 7 deletions(-)
+
+commit 8ed46c3678cd4518efe5c9907bb9d22e6161bbd5
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Jan 7 23:43:53 2020 +0330
+
+    [fuzz] minor, add another already fixed case
+    
+    https://crbug.com/oss-fuzz/19907
+
+ ...z-testcase-minimized-hb-subset-fuzzer-5695925913911296 | Bin 0 -> 385 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 341407f7a52680be84144eb285e6cb09131b2956
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Jan 7 09:10:24 2020 +0330
+
+    [fuzz] minor, upload another fixed case
+    
+    https://crbug.com/oss-fuzz/19878
+
+ ...z-testcase-minimized-hb-subset-fuzzer-5169035432165376 | Bin 0 -> 108 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 7950beecfcc66194541437349c91625fd27c0071
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Jan 6 21:25:00 2020 +0330
+
+    [subset] Fix null pointer dereference in hvar/vvar subset (#2085)
+    
+    Rest of the code assumes there is at least one subtable, lets return here if not.
+    
+    * https://crbug.com/oss-fuzz/19827
+    * https://crbug.com/oss-fuzz/19847
+
+ src/hb-ot-var-hvar-table.hh                              |   2 ++
+ ...lusterfuzz-testcase-hb-subset-fuzzer-5641053680173056 | Bin 0 -> 4229 bytes
+ ...-testcase-minimized-hb-subset-fuzzer-5650879734874112 | Bin 0 -> 3278 bytes
+ 3 files changed, 2 insertions(+)
+
+commit 8ed27757b197670ee9f91cfb27ec50bcd3045a2f
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Jan 6 19:01:13 2020 +0330
+
+    Remove _POSIX_C_SOURCE definition from the project
+    
+    Added fpr suncc support but apparently is causing more issues
+    even on suncc so let's see if we can go without it.
+    
+    Fixes #2084
+
+ src/hb-blob.cc | 12 ------------
+ 1 file changed, 12 deletions(-)
+
+commit e7d1aeb61023dff22852048561f6161c6972ec75
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Jan 6 12:48:22 2020 +0330
+
+    [hvar] minor, fix unlikely statement
+
+ src/hb-ot-var-hvar-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 57b1534198ae07c840010cff5af7997c5f738e88
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Jan 6 12:46:50 2020 +0330
+
+    [glyf] minor, fix unlikely statements
+
+ src/hb-ot-glyf-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 9e48c6e9ef3f6d398c7140933a2cd90980f0ed5b
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Dec 31 15:57:39 2019 +0330
+
+    minor, use private API of hb_set_t where possible
+
+ src/hb-ot-var-hvar-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit ce114d6b27976f38effba015d9cdf00b96c2fdfc
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Dec 31 15:53:02 2019 +0330
+
+    minor, tweak spaces
+
+ src/hb-aat-fdsc-table.hh                   |  4 ++--
+ src/hb-aat-layout-ankr-table.hh            |  2 +-
+ src/hb-aat-layout-just-table.hh            | 36 +++++++++++++++---------------
+ src/hb-aat-layout-trak-table.hh            |  4 ++--
+ src/hb-debug.hh                            |  2 +-
+ src/hb-ot-cff-common.hh                    |  6 ++---
+ src/hb-ot-cff1-table.hh                    | 12 +++++-----
+ src/hb-ot-color-cbdt-table.hh              |  2 +-
+ src/hb-ot-gasp-table.hh                    |  4 ++--
+ src/hb-ot-layout-common.hh                 | 14 ++++++------
+ src/hb-ot-layout-gsubgpos.hh               |  8 +++----
+ src/hb-ot-layout-jstf-table.hh             |  2 +-
+ src/hb-ot-math-table.hh                    | 33 ++++++++++++++-------------
+ src/hb-ot-shape-complex-indic-machine.rl   |  2 +-
+ src/hb-ot-shape-complex-myanmar-machine.rl |  2 +-
+ src/hb-ot-var-avar-table.hh                |  2 +-
+ src/hb-ot-var-gvar-table.hh                | 18 +++++++--------
+ src/hb-ot-var-hvar-table.hh                | 12 +++++-----
+ src/hb-subset-cff-common.cc                |  2 +-
+ src/hb-subset-cff-common.hh                | 34 ++++++++++++++--------------
+ src/hb-subset-cff1.cc                      | 16 ++++++-------
+ src/hb-subset-cff2.cc                      |  8 +++----
+ util/options.cc                            |  2 +-
+ 23 files changed, 114 insertions(+), 113 deletions(-)
+
+commit 33c3d63a0a9734a9cca9411a666d6ba9793d642f
+Merge: 68c1798a ea8fdfa0
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Dec 31 13:52:50 2019 +0330
+
+    Merge pull request #1594 from harfbuzz/var-subset
+    
+    Issue 1558: [subset] TrueType/CFF2 variable font
+
+commit 68c1798a6703f9476b29c53abe95dd59ae280613
+Author: Khaled Hosny <khaledhosny at eglug.org>
+Date:   Wed Dec 18 15:57:14 2019 +0200
+
+    [coretext] Use kCTFontOpenTypeFeatureTag
+    
+    Instead of trying to map OpenType features to AAT feature selectors
+    which only works for a small subset of OpenType features, use the
+    simpler kCTFontOpenTypeFeatureTag with OpenType feature tags directly.
+    
+    With this change, features like cvXX can be enabled in coretext shaper,
+    while they were previously ignored due to missing mapping.
+    
+    This seems to work even with AAT fonts that don’t have OpenType layout
+    tables, which suggests that CoreText is doing the mapping itself in this
+    case.
+    
+    kCTFontOpenTypeFeatureTag seems to have been introduced in macOS 10.10
+    and iOS 8.0, though, so its use is conditional on version check for now.
+    Not sure how to check iOS version, so I left this out.
+
+ src/hb-coretext.cc | 20 +++++++++++++++++++-
+ 1 file changed, 19 insertions(+), 1 deletion(-)
+
+commit b28c282585afd3bff844e84eae7f29e1a1267aef
+Author: Marcel Fabian Krüger <zauguin at gmail.com>
+Date:   Tue Dec 17 02:58:51 2019 +0100
+
+    Check to avoid overflows
+
+ src/hb-sanitize.hh | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+commit d70afb1e5a32f23d03cc69bbbc725d1e668eb616
+Author: Marcel Fabian Krüger <zauguin at gmail.com>
+Date:   Tue Dec 17 02:29:28 2019 +0100
+
+    Clamp max_ops to upper bound in hb-sanitize.hh
+
+ src/hb-sanitize.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit aa43e183dda2288b9d83fe7473f357422a4771f1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 15 16:04:00 2019 -0800
+
+    [perf Add texts/en-words.txt
+    
+    $ cat docs/usermanual-*.xml src/hb*.cc src/hb*.{h,hh,cc} | sed 's/[^a-zA-Z ]/ /g' | tr ' ' '\n' | sort | uniq | grep . > perf/texts/en-words.txt
+
+ perf/texts/en-words.txt | 12392 ++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 12392 insertions(+)
+
+commit 80762cc4d0663a9ca465e94e73424e3b352de24c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Dec 15 23:21:10 2019 +0330
+
+    [ci] Speedup tsan bot
+    
+    We don't expect fails thus expecting readable failure backtrace so let's speed it up instead
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b79ceac3c68a41a0b7f624c0f172e99eb7498737
+Author: Evgeniy Reizner <razrfalcon at gmail.com>
+Date:   Sun Dec 15 16:50:01 2019 +0200
+
+    Prefer UINT_MAX instead of uint overflow.
+    
+    Also, prefer HB_FEATURE_GLOBAL_START and HB_FEATURE_GLOBAL_END.
+
+ src/hb-buffer.cc                          | 6 +++---
+ src/hb-common.cc                          | 4 ++--
+ src/hb-face.hh                            | 2 +-
+ src/hb-graphite2.cc                       | 2 +-
+ src/hb-ot-map.hh                          | 4 ++--
+ src/hb-ot-shape-complex-arabic.cc         | 6 +++---
+ src/hb-ot-shape.cc                        | 2 +-
+ src/hb-set.hh                             | 4 ++--
+ test/shaping/data/aots/hb-aots-tester.cpp | 4 ++--
+ util/ansi-print.cc                        | 6 +++---
+ util/options.cc                           | 2 +-
+ util/options.hh                           | 2 +-
+ 12 files changed, 22 insertions(+), 22 deletions(-)
+
+commit b618e0ae1368aa22050ce0fe48329b723e2fd632
+Author: Evgeniy Reizner <razrfalcon at gmail.com>
+Date:   Sun Dec 15 16:26:50 2019 +0200
+
+    Remove non-breaking spaces from comments.
+    
+    `0xC2A0` was used, for some reasons. It's not really a problem, but Qt Creator
+    constatly trying to replace them with regular spaces, so I have to edit those
+    files separately.
+
+ src/hb-buffer.cc |  4 ++--
+ src/hb-common.cc | 20 ++++++++++----------
+ 2 files changed, 12 insertions(+), 12 deletions(-)
+
+commit 780d640c02e01664ea13729f4e4b416c440c3cdf
+Author: Evgeniy Reizner <razrfalcon at gmail.com>
+Date:   Sun Dec 15 16:11:37 2019 +0200
+
+    Remove unnecessary check in hb_buffer_t::set_masks.
+    
+    Bounds are already checked by the caller.
+    
+    Closes #2073
+
+ src/hb-buffer.cc | 7 -------
+ 1 file changed, 7 deletions(-)
+
+commit 34ed8e7218d9147a6ccd99198db594cf8f66f61b
+Author: Evgeniy Reizner <razrfalcon at gmail.com>
+Date:   Fri Dec 13 07:25:34 2019 +0200
+
+    Prefer _hb_glyph_info_is_unicode_mark where possible.
+
+ src/hb-ot-shape-fallback.cc  | 6 +++---
+ src/hb-ot-shape-normalize.cc | 6 +++---
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+commit 3e1a2632dce396157a4e8ff6669740a145e7062c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Dec 12 15:48:27 2019 +0330
+
+    [unscribe] fix leak issue
+    
+    with no user_data provided, `free` will be called with `(0)` thus silently having a leak
+
+ src/hb-uniscribe.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e75d785b51d713de2e37ad41c62de5423fc95949
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Dec 12 15:42:37 2019 +0330
+
+    [doc] fix hb_blob_create call example
+    
+    otherwise free(0) will be called that silently makes a leak
+
+ docs/usermanual-object-model.xml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4ef597e17003402c0ceebcb5a0c185f08c97aac1
+Author: Daeren <Daeren at users.noreply.github.com>
+Date:   Wed Dec 11 13:44:05 2019 +0300
+
+    Fix unary minus operator applied to unsigned int
+    
+    Applying unary minus operator to unsigned int causes the following error on MSVS: error C4146
+    This patch fixes the error.
+
+ src/hb-ot-color-sbix-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1770493cf5e0c098a0566281bc1dd089101f0f78
+Author: Daeren <Daeren at users.noreply.github.com>
+Date:   Wed Dec 11 13:44:15 2019 +0300
+
+    Fix unary minus operator applied to unsigned int
+    
+    Applying unary minus operator to unsigned int causes the following error on MSVS: error C4146
+    This patch fixes the error.
+
+ src/hb-ot-color-cbdt-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a061e47fcc84a8947ca478b7ff2d02efeafecbce
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 10 13:31:50 2019 -0600
+
+    Change a few HB_INTERNAL static methods to static inline
+
+ src/hb-ot-layout-gpos-table.hh | 10 +++++-----
+ src/hb-ot-layout-gsub-table.hh | 10 +++++-----
+ src/hb-ot-layout-gsubgpos.hh   |  2 +-
+ 3 files changed, 11 insertions(+), 11 deletions(-)
+
+commit dd3972a3649e30c2bee88303ee56f88b260deb53
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 10 13:21:26 2019 -0600
+
+    [GSUB] Simplify Extension is_reverse()
+    
+    We don't allow extension lookups to chain to another extension lookup.
+    Simplify code for that.
+
+ src/hb-ot-layout-gpos-table.hh | 10 +++++-----
+ src/hb-ot-layout-gsub-table.hh | 14 +++++---------
+ 2 files changed, 10 insertions(+), 14 deletions(-)
+
+commit 858b627984c50e94bc71b9530c340a8fff59d330
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 10 13:18:32 2019 -0600
+
+    [machinery] Remove CastR<>()
+
+ src/hb-machinery.hh            | 8 --------
+ src/hb-open-file.hh            | 2 +-
+ src/hb-ot-layout-common.hh     | 4 ++--
+ src/hb-ot-layout-gpos-table.hh | 2 +-
+ src/hb-ot-layout-gsub-table.hh | 6 +++---
+ src/hb-ot-layout-gsubgpos.hh   | 8 ++++----
+ 6 files changed, 11 insertions(+), 19 deletions(-)
+
+commit b84ceb2fcf7a71fe03f499dd0c4611254b561f1d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 10 13:02:48 2019 -0600
+
+    [machinery] Remove CastP
+
+ src/hb-machinery.hh            | 8 --------
+ src/hb-ot-layout-gpos-table.hh | 8 +++++---
+ src/main.cc                    | 4 ++--
+ 3 files changed, 7 insertions(+), 13 deletions(-)
+
+commit 85574ec28735c1e9d53ccff9abafbbc25cf34f0f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 10 12:52:32 2019 -0600
+
+    [machinery] Minor
+
+ src/hb-machinery.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e101a6725731a2e82f3e2a146c3281111c747d90
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 10 12:46:14 2019 -0600
+
+    [perf] Add texts/fa-thelittleprince.txt
+
+ perf/texts/en-thelittleprince.txt |   3 -
+ perf/texts/fa-thelittleprince.txt | 923 ++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 923 insertions(+), 3 deletions(-)
+
+commit 2c781a670108d52149a61fb7bc5b9b6eb3592b9d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 10 12:43:42 2019 -0600
+
+    [perf] More rename
+
+ perf/run.sh                                 | 2 +-
+ perf/{text => texts}/en-thelittleprince.txt | 0
+ perf/{text => texts}/fa-monologue.txt       | 0
+ 3 files changed, 1 insertion(+), 1 deletion(-)
+
+commit d703392afef578cbeb17968783109c8cbe117890
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 10 12:42:29 2019 -0600
+
+    [perf] Adjust text/fa-monologue.txt
+
+ perf/text/fa-monologue.txt | 17 -----------------
+ 1 file changed, 17 deletions(-)
+
+commit 19d1b9d4f319b75121bfbba677122ca74bf6f796
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 10 12:39:01 2019 -0600
+
+    [perf] Renames
+
+ perf/run.sh                                                    | 2 +-
+ perf/text/{littleprince.txt => en-thelittleprince.txt}         | 0
+ perf/text/{test-long-arabic-paragraph.txt => fa-monologue.txt} | 0
+ 3 files changed, 1 insertion(+), 1 deletion(-)
+
+commit 6a60ca117c51e15279ba39dcae19301d24789c62
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 10 12:32:37 2019 -0600
+
+    [algs] Fold last other bsearch() in
+    
+    Now truly have only one bsearch implementation.
+
+ src/hb-ot-cmap-table.hh | 37 ++++++++++++++++++++-----------------
+ 1 file changed, 20 insertions(+), 17 deletions(-)
+
+commit 53dc8d944f71481ce7f18a32aca63c3f004e6e0c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Dec 10 21:53:30 2019 +0330
+
+    Add initial shaping performance test and profiler
+
+ perf/fonts/Amiri-Regular.ttf              |  Bin 0 -> 551560 bytes
+ perf/fonts/NotoNastaliqUrdu-Regular.ttf   |  Bin 0 -> 497204 bytes
+ perf/fonts/NotoSansDevanagari-Regular.ttf |  Bin 0 -> 212740 bytes
+ perf/fonts/Roboto-Regular.ttf             |  Bin 0 -> 305608 bytes
+ perf/run.sh                               |   25 +
+ perf/text/littleprince.txt                | 1896 +++++++++++++++++++++++++++++
+ perf/text/test-long-arabic-paragraph.txt  |   18 +
+ 7 files changed, 1939 insertions(+)
+
+commit 39afe608b476c3d09460dfceae75df65a9eb22b4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 10 12:04:44 2019 -0600
+
+    [algs] Fold one more custom bsearch() in
+    
+    One more to go.
+
+ src/hb-ot-layout-gpos-table.hh | 49 ++++++++++++++++--------------------------
+ 1 file changed, 19 insertions(+), 30 deletions(-)
+
+commit b1dc676eaa606660584f3c67f0570457e9f09dd3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 10 11:41:24 2019 -0600
+
+    [algs] Reduce one more bsearch() impl
+    
+    Ouch, there were three more left.  Down one.  Two to go.
+
+ src/hb-open-type.hh | 21 +++++++++------------
+ 1 file changed, 9 insertions(+), 12 deletions(-)
+
+commit 6f76c325e5244adfa1599952040ed7f13b10f38c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Dec 10 21:43:11 2019 +0330
+
+    [test] Update 10.15 results
+    
+    Turned out only SFNS, which wasn't available in 10.14 anyway, needed an update
+    See https://crbug.com/1005969#c37 also
+
+ test/shaping/data/in-house/tests/macos.tests | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+commit 2241a676ba084214fdfc6d35f35862a64f296271
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Dec 10 19:50:34 2019 +0330
+
+    [test] Add macOS 10.15 related fonts
+    
+    breaks the test and 10.15 bot, will add the fix in next commit, also adds a broken test for f47cbade1
+
+ test/shaping/data/in-house/tests/macos.tests | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+commit f3de3b6d3db278845bee1392ffdb3659921c6410
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Dec 10 16:37:48 2019 +0330
+
+    [ci] fix macOS 10.15 bot
+    
+    Xcode 11.3.0 image is supposed to work per https://circleci.com/docs/2.0/testing-ios/
+    but isn't https://circleci.com/gh/harfbuzz/harfbuzz/118693 AFAICS
+    
+    Let's try Xcode 11.2.1 image
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 49434bdd49eec61a3bcb18e242b30e72cdc81279
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Dec 10 16:28:04 2019 +0330
+
+    [ci] Add a macOS 10.15 bot
+    
+    Should update macos.tests with the fonts, for now
+
+ .circleci/config.yml | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+commit f47cbade18acc4f9c935ba2c6c863beb6087d781
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 9 18:10:34 2019 -0600
+
+    [aat] Adjust fallback positioning logic
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1528
+    
+    Wish could add a test...
+    
+    $ ./hb-view --font-file Thonburi.ttc --unicodes U+0E17,U+0E35,U+0E48,U+0E4A --shaper ot
+    
+                       ▃
+    
+             ▂▃▃▄▃▂▁▊        ▃  ▃       ▎
+          ▗   ▅▆▆▅          ▌ ▆▆▅▆▙ ▌▗
+         ▗                  ▙ ▂  ▎▗   ▟
+         ▅▆▆▆▇▇▇▇▇▇▇▆▆▅▄     ▇▅▅▅ ▙▆▇
+        ▁▁▂▁       ▁▁
+             ▖                    ▖ ▂▂
+      ▉   ▁        ▆▆        ▌   ▆  ▙▄ ▁▁
+       ▙            ▉      ▃▖           ▟
+          ▊         ▉      ▅▟           ▗▄
+          ▊         ▉     ▗ ▏           ▇▆
+          ▊    ▟    ▉      ▆             ▖
+          ▊         ▉        ▌        ▂
+          ▊   ▏     ▉           ▌ ▗   ▄▟
+          ▊                        ▆
+
+ src/hb-ot-shape-complex-default.cc | 20 ++++++++++++++++++++
+ src/hb-ot-shape-complex.hh         |  5 +++--
+ src/hb-ot-shape.cc                 |  5 +++--
+ 3 files changed, 26 insertions(+), 4 deletions(-)
+
+commit fa7edf87c99a46d29a9f0d58b2896bc24a43853e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 7 22:01:13 2019 -0600
+
+    [bsearch] Massage API some more
+
+ src/hb-algs.hh  | 25 +++++++++++++++----------
+ src/hb-array.hh | 23 ++++++++++-------------
+ 2 files changed, 25 insertions(+), 23 deletions(-)
+
+commit 70aa5071d89dbba792c4c9fb4df7ca716304656a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 7 22:35:34 2019 -0600
+
+    [algs] Adjust return value of hb_ctz(0) to be 32 instead of 0
+
+ src/hb-algs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit eefb78f674c9a71aaaca45cc1246584848622923
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 8 21:07:00 2019 -0600
+
+    Minor
+
+ src/hb-common.cc | 32 --------------------------------
+ src/hb-static.cc | 36 ++++++++++++++++++++++++++++++++++++
+ 2 files changed, 36 insertions(+), 32 deletions(-)
+
+commit 9fb030585a1c429c13e86fbd128d9db004d3a355
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 7 19:45:08 2019 +0000
+
+    Rename start/end to first/last in RangeRecord
+    
+    Because that's what they are.
+
+ src/hb-ot-layout-common.hh | 48 +++++++++++++++++++++++-----------------------
+ 1 file changed, 24 insertions(+), 24 deletions(-)
+
+commit 8ac4ba14dca7c700b6dfdc19ceb5385a7e6fb889
+Author: Evgeniy Reizner <razrfalcon at gmail.com>
+Date:   Mon Dec 9 18:58:28 2019 +0200
+
+    Fix typo in TESTING.md (#2066)
+
+ TESTING.md | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9b1d5c4a59c6d3d9c248eae5d05d801791d42b7a
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Dec 9 12:29:28 2019 +0330
+
+    [number] fix where strtod_l not available
+
+ src/hb-number.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 5c8f96028988f647cace1af9f5a4c33c29b6e562
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Dec 9 10:48:43 2019 +0330
+
+    [number] minor, include the renamed header
+
+ src/hb-number.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 48eef2724c8aa55d081fb742a5e6cef17ff5d4a2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 6 05:04:11 2019 +0000
+
+    [algs/array] Consolidate the last two bsearch implementations!
+    
+    Yay!  Seems to work.
+
+ src/hb-algs.hh  | 31 +++++++++++++++++--------------
+ src/hb-array.hh | 31 +++++++++++--------------------
+ 2 files changed, 28 insertions(+), 34 deletions(-)
+
+commit ed35dea8c07f1ecc50df48657bb330fcd77ca8e3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 6 04:37:11 2019 +0000
+
+    Fourth try... sighs
+
+ src/hb-algs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9168310bb4c9d7d0652c7ead53017e30d1fafda2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 6 04:28:06 2019 +0000
+
+    Fix build, third times...
+
+ src/hb-ot-post-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 34f5cc2cc80cf1fd45bc9697d828d3536e3ac74f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 6 04:09:33 2019 +0000
+
+    Second try at fixing build
+
+ src/hb-algs.hh | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+commit 14ce5ab0b7ae012c6e46511bab399c472eb39eb2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 6 03:54:46 2019 +0000
+
+    First try at fixing build errors
+
+ src/hb-algs.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 2274270c6ac2e170cf939e03a89721f03f2f98bd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 6 03:42:21 2019 +0000
+
+    [algs] Streamline bsearch some more
+
+ src/hb-algs.hh | 46 ++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 32 insertions(+), 14 deletions(-)
+
+commit bd55d4b49fcd1ac1335e60ead1fe9941e7b01f8c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 6 03:35:24 2019 +0000
+
+    [algs] Streamline bsearch() API more towards hb_array_t::bsearch_impl()
+    
+    Preparing to merge the two finally!
+
+ src/hb-aat-layout.cc              |  6 +-----
+ src/hb-aat-layout.hh              | 10 ++--------
+ src/hb-algs.hh                    | 27 +++++++++++++++++++--------
+ src/hb-ot-name-language-static.hh | 15 +++------------
+ src/hb-ot-name-table.hh           | 12 +++++-------
+ src/hb-ot-os2-unicode-ranges.hh   | 20 +++-----------------
+ src/hb-ot-post-table.hh           |  3 +--
+ src/hb-ot-var-mvar-table.hh       |  4 +++-
+ src/hb-ucd.cc                     | 18 ++++++++++--------
+ 9 files changed, 47 insertions(+), 68 deletions(-)
+
+commit fd6df520a1a4aa9cdaa0c2e515f29ba93d2910d1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 6 03:00:23 2019 +0000
+
+    [array] Isolate bsearch implementation more
+
+ src/hb-array.hh | 26 ++++++++++++++++++++------
+ 1 file changed, 20 insertions(+), 6 deletions(-)
+
+commit 06d3c2019fc2dd9a284a3c2471a1eabef47584c5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 6 02:52:54 2019 +0000
+
+    [array] Simplify bfind() positioning
+    
+    I had copied the old scheme from fontconfig's fccharset.c.  I just
+    convinced myself that this change is correct and produces exact
+    same results.  But I also am skeptical.  Anyone else feel like
+    convincing themselves as well please?
+
+ src/hb-array.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit d67ba649a38aec1646525a30f992d5f50c4cf06d
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Dec 5 13:15:21 2019 +0330
+
+    Rename hb_array_t::in_range to hb_array_t::check_range
+
+ src/hb-array.hh             |  2 +-
+ src/hb-ot-glyf-table.hh     | 20 ++++++++++----------
+ src/hb-ot-var-gvar-table.hh | 16 ++++++++--------
+ 3 files changed, 19 insertions(+), 19 deletions(-)
+
+commit 72d83a0280b95f99b94c64380bc46558fc941462
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Dec 5 13:09:48 2019 +0330
+
+    Make hb_array_t::in_range similar to hb_sanitize_context_t::check_range
+
+ src/hb-array.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit b1167d19e9d72bcadc1a71873afa8dcbe0e26f29
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 5 15:46:58 2019 +0000
+
+    Fix!
+
+ .../fonts/2681c1c72d6484ed3410417f521b1b819b4e2392.ttf   | Bin 0 -> 1288 bytes
+ .../fonts/28cbcd9409236705ff14bec11a273d16cffdd543.ttf   | Bin 1080 -> 0 bytes
+ 2 files changed, 0 insertions(+), 0 deletions(-)
+
+commit 5ff410b493f3abadb397347c118fdfbcfd278e69
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 5 15:37:56 2019 +0000
+
+    Add files, oops
+
+ .../fonts/28cbcd9409236705ff14bec11a273d16cffdd543.ttf   | Bin 0 -> 1080 bytes
+ test/shaping/data/in-house/tests/rotation.tests          |   4 ++++
+ 2 files changed, 4 insertions(+)
+
+commit 2dc20e632efd6aab2abe0ad15ed110ca4553f3ba
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 5 15:28:42 2019 +0000
+
+    Implement fallback vertical shaping from Firefox
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/355
+
+ src/hb-ot-shape.cc                          | 92 ++++++++++++++++++++++++-----
+ src/hb-ot-shape.hh                          |  1 +
+ test/shaping/data/in-house/Makefile.sources |  1 +
+ 3 files changed, 80 insertions(+), 14 deletions(-)
+
+commit b6d0f1529df9461f1fdb93fae7b5103702ae1517
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 5 12:19:52 2019 +0000
+
+    [indic] Fix old-spec base-finding logic w vatu feature
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1587
+
+ src/hb-ot-shape-complex-indic.cc | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+commit 0414341ac576c4403231f507e216c7716c8f0828
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 5 11:26:39 2019 +0000
+
+    Prefer AAT shaping over OT if both available
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1529
+
+ src/hb-common.cc    |  1 -
+ src/hb-debug.hh     |  1 -
+ src/hb-ot-layout.cc | 21 ---------------------
+ src/hb-ot-shape.cc  | 25 ++-----------------------
+ 4 files changed, 2 insertions(+), 46 deletions(-)
+
+commit 82545c5e2ba2067f2eb117c7358ed6d5b50ca942
+Author: blueshade7 <ariza at typekit.com>
+Date:   Tue Nov 26 10:24:32 2019 -0800
+
+    more coding style fixes
+
+ src/hb-ot-font.cc | 19 +++++++++----------
+ 1 file changed, 9 insertions(+), 10 deletions(-)
+
+commit 2e7c1239c886ea8fa6ba37b7597d76b2d319f468
+Author: blueshade7 <ariza at typekit.com>
+Date:   Tue Nov 26 09:57:53 2019 -0800
+
+    minor: coding style
+
+ src/hb-ot-font.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit ed94e41065797b3b22860f1aa68a0b2ea47317e7
+Author: blueshade7 <ariza at typekit.com>
+Date:   Wed Nov 20 10:42:50 2019 -0800
+
+    fixed api test test-ot-glyphname
+
+ test/api/test-ot-glyphname.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+commit 7a4745ba8da89f945b7c62f59bbb3d1cc5a45e2d
+Author: blueshade7 <ariza at typekit.com>
+Date:   Wed Nov 20 10:15:41 2019 -0800
+
+    added api test test-ot-glyphname
+
+ test/api/Makefile.am         |  1 +
+ test/api/test-ot-glyphname.c | 83 ++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 84 insertions(+)
+
+commit ab525ac66dc2e72a636d3f04b575f766af76f9e0
+Author: blueshade7 <ariza at typekit.com>
+Date:   Tue Nov 19 20:36:56 2019 -0800
+
+    fix HB_TINY buid
+
+ src/hb-subset-plan.cc | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit ff64652cf6bda18d1d7d54f511eed131464e1f3d
+Author: blueshade7 <ariza at typekit.com>
+Date:   Tue Nov 19 18:50:57 2019 -0800
+
+    fix shape-fuzzer failure
+
+ src/hb-ot-cff1-table.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit a333b0f7172923ff70dcb1bca15a5474fd84f82f
+Author: blueshade7 <ariza at typekit.com>
+Date:   Tue Nov 19 18:01:53 2019 -0800
+
+    add hb-ot-cff1-std-str.hh to Makefile.sources
+
+ src/Makefile.sources | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 61707266a3ea9fc54323742de6559fb00987dc29
+Author: blueshade7 <ariza at typekit.com>
+Date:   Tue Nov 19 17:09:12 2019 -0800
+
+    fix get_sid crash
+
+ src/hb-ot-cff1-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4c4e08a1eff5a4bf355f032f32fb4fa25b9349d7
+Author: blueshade7 <ariza at typekit.com>
+Date:   Tue Nov 19 16:50:28 2019 -0800
+
+    add cff1::accelerator_t::fini
+
+ src/hb-ot-cff1-table.hh | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit ff87465b400af4685680a7a3076533ee6b635dd3
+Author: blueshade7 <ariza at typekit.com>
+Date:   Tue Nov 19 16:18:33 2019 -0800
+
+    add get_glyph_from_name & test. use hb_string_array
+
+ src/Makefile.am           |   5 +
+ src/hb-ot-cff1-std-str.hh | 425 ++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-cff1-table.cc   |  69 --------
+ src/hb-ot-cff1-table.hh   |  85 +++++++++-
+ src/hb-ot-font.cc         |   6 +-
+ src/test-ot-glyphname.cc  |  91 ++++++++++
+ 6 files changed, 602 insertions(+), 79 deletions(-)
+
+commit 51e772852191e99206bd69f2f06d029ba01e5745
+Author: blueshade7 <ariza at typekit.com>
+Date:   Sun Nov 17 02:25:39 2019 -0800
+
+    minor
+
+ src/hb-ot-cff1-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6d9eb9c04095db74f40c00a3d6e5a6432491059d
+Author: blueshade7 <ariza at typekit.com>
+Date:   Sun Nov 17 02:20:22 2019 -0800
+
+    fixed failure with language-tags.tests
+
+ src/hb-ot-cff1-table.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 59fe379797adca37e29c002ffabc27f9c74f8746
+Author: blueshade7 <ariza at typekit.com>
+Date:   Sat Nov 16 19:47:31 2019 -0800
+
+    fixed hb-shape-fuzzer failures in get_sid
+
+ src/hb-ot-cff1-table.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit e26df436bcf215d1a4520e9851aa607b0de0ca84
+Author: blueshade7 <ariza at typekit.com>
+Date:   Sat Nov 16 19:12:34 2019 -0800
+
+    fix test-ot-face crash
+
+ src/hb-ot-cff1-table.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 7b49042ef4812d8550d884a400936331fad9951a
+Author: blueshade7 <ariza at typekit.com>
+Date:   Sat Nov 16 18:20:16 2019 -0800
+
+    add cff1::get_glyph_name
+
+ src/hb-ot-cff1-table.cc |  69 +++++++++++++++++++++++++++
+ src/hb-ot-cff1-table.hh | 124 +++++++++++++++++++++++++++---------------------
+ src/hb-ot-font.cc       |   6 ++-
+ 3 files changed, 144 insertions(+), 55 deletions(-)
+
+commit ea8fdfa07939b97db6636327c8d55cd3b5a62b4c
+Merge: 453050ad d5338ba1
+Author: blueshade7 <ariza at typekit.com>
+Date:   Fri Nov 22 15:59:09 2019 -0800
+
+    Merge branch 'master' into var-subset
+
+commit d5338ba1894f73629528a2a505e30cd681a5f1c6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Nov 22 16:22:27 2019 -0500
+
+    [ft] Add locking FT_Face API
+    
+    Now that we mutex our internal FT_Face, share it with clients.
+    
+    New API:
+    - hb_ft_font_lock_face()
+    - hb_ft_font_unlock_face()
+
+ docs/harfbuzz-sections.txt |  2 ++
+ src/hb-ft.cc               | 56 +++++++++++++++++++++++++++++++++++++++++++---
+ src/hb-ft.h                |  6 +++++
+ 3 files changed, 61 insertions(+), 3 deletions(-)
+
+commit e5c7ee9f757baa166a96d73b7ec0cb2b1ae23385
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 20 14:22:01 2019 -0500
+
+    [set] Fix undefined-behavior shift in _previous()
+    
+    harfbuzz/src/hb-set.hh:138:43: runtime error: shift exponent 64 is too large for 64-bit type 'hb_set_t::page_t::elt_t' (aka 'unsigned long long')
+
+ src/hb-set.hh | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit 5fddc5f1698aa50e1be9cd729032c40fa5bd64b1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Nov 20 13:07:26 2019 -0500
+
+    Use foreach_cluster
+
+ src/hb-buffer.cc | 14 ++------------
+ 1 file changed, 2 insertions(+), 12 deletions(-)
+
+commit e4a101ed38f61b3ac710e483528816372cbeb3d0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Nov 19 20:04:00 2019 -0500
+
+    [ft] Fix for HB_NO_VAR build
+
+ src/hb-ft.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 76c27462c242f00e26d3b172dbdf618121aac306
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Tue Nov 19 16:51:33 2019 -0500
+
+    Don’t modify a ccc to 6
+    
+    ccc=6 will be used in Unicode 13.0.
+
+ src/hb-unicode.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 8fdafee2a621f64101a5d55ded64de9e693db34a
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Mon Nov 18 16:44:25 2019 -0800
+
+    undef HB_STRING_ARRAY_LENG_NAME
+
+ src/hb-string-array.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 5e9863f3c63c6b9060d270d5cf959e16ac1294bb
+Author: blueshade7 <ariza at typekit.com>
+Date:   Mon Nov 18 15:40:43 2019 -0800
+
+    ARRAY_LENGTH fails with -Wglobal-constructors
+
+ src/hb-string-array.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a75983690d0b3575ef208592c51f730410230af7
+Author: blueshade7 <ariza at typekit.com>
+Date:   Mon Nov 18 15:09:24 2019 -0800
+
+    calculate hb_string_array length automatically
+
+ src/hb-ot-post-table.hh | 10 ++++------
+ src/hb-string-array.hh  |  3 +++
+ 2 files changed, 7 insertions(+), 6 deletions(-)
+
+commit 57da16bc5986ce714fb3f57501e5f45a33aaa99a
+Author: Khaled Hosny <khaledhosny at eglug.org>
+Date:   Sun Nov 17 21:32:12 2019 +0200
+
+    [cff] Check rcurveline and rlinecurve arguments
+    
+    Make sure the number of arguments is not too many or too few, otherwise
+    skip the command.
+
+ src/hb-cff-interp-cs-common.hh | 41 +++++++++++++++++++++++------------------
+ 1 file changed, 23 insertions(+), 18 deletions(-)
+
+commit 9f1524ce83ebd2c3320ffc90776cb0f533db143f
+Author: Khaled Hosny <khaledhosny at eglug.org>
+Date:   Sun Nov 17 16:17:20 2019 +0200
+
+    [cff] Fix a typo in processing rlinecurve
+    
+    We want to process all pairs of arguments except the last 6 as lines, so
+    should have been subtracting 6 here, otherwise if the number of
+    arguments happens to be multiples of 6 they will be all treated as
+    curves.
+    
+    See https://github.com/harfbuzz/harfbuzz/pull/2016#issuecomment-554640098
+
+ src/hb-cff-interp-cs-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 78d5eca813250b79e9b1fbfd2de3eae7ccf1fcf3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Nov 18 13:09:29 2019 -0500
+
+    [set] Fix range-based-loop condition
+    
+    Alternative to https://github.com/harfbuzz/harfbuzz/pull/2046
+
+ src/hb-set.hh | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+commit 4dae7cee4b44fd6ffb295f8c99a52e42934d0c3c
+Author: Hal Canary <halcanary at gmail.com>
+Date:   Wed Nov 13 10:08:35 2019 -0500
+
+    [minor] Fix common typos: substition, the the.
+    
+    s/substition/substitution/
+    s/the the/the/
+
+ src/hb-ot-layout.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit e6351d9b2c44c9abde90a6599ae7ebf0f6416c65
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Mon Nov 11 17:39:55 2019 -0500
+
+    Add ms-use/IndicShapingInvalidCluster.txt
+
+ src/Makefile.am                              |   2 +-
+ src/gen-vowel-constraints.py                 |   4 +-
+ src/hb-ot-shape-complex-vowel-constraints.cc |   2 +-
+ src/ms-use/COPYING                           |  21 ++++++
+ src/ms-use/IndicShapingInvalidCluster.txt    | 105 +++++++++++++++++++++++++++
+ 5 files changed, 130 insertions(+), 4 deletions(-)
+
+commit b372c3e95694c8b1cabc0eb01c5abef6c41d3dbd
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Fri Nov 8 20:59:48 2019 -0500
+
+    Insert a dotted circle within <U+0B85, U+0BC2>
+
+ src/HBIndicVowelConstraints.txt              | 97 ----------------------------
+ src/Makefile.am                              |  2 +-
+ src/gen-vowel-constraints.py                 | 25 ++++---
+ src/hb-ot-shape-complex-vowel-constraints.cc | 27 ++++++--
+ 4 files changed, 40 insertions(+), 111 deletions(-)
+
+commit 64a45be5198f6e22c91454bda7bd9a9294552dff
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Nov 9 12:25:33 2019 +0330
+
+    [ubsan] Don't decrease pointer if match_glyph_data is null (#2048)
+    
+    Similar to fix on https://github.com/harfbuzz/harfbuzz/pull/2022
+    
+    Fixes https://crbug.com/1023070
+
+ src/hb-ot-layout-gsubgpos.hh                              |   6 +++++-
+ ...zz-testcase-minimized-harfbuzz_fuzzer-5740518101090304 | Bin 0 -> 439 bytes
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+commit 878e3588a3349c2660b0f9aa6d94a994034d7c10
+Author: Don <don.j.olmstead at gmail.com>
+Date:   Tue Nov 5 15:26:01 2019 -0800
+
+    [cmake] Add harfbuzz-icu library
+
+ CMakeLists.txt | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+commit 84b86a12d99e996cfd85f9fe6fd2c2a593dd5cc2
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Nov 6 09:22:34 2019 +0330
+
+    [fuzz] Remove just added case
+    
+    It didn't fail locally but on bots causing timeout, let remove for now.
+
+ ...estcase-minimized-hb-subset-fuzzer-5121706490593280 | Bin 161328 -> 0 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit a8f049c9a18f166a826c78caa153330a1ec04214
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Tue Nov 5 22:26:36 2019 +0330
+
+    [fuzz] Upload testcase of https://crbug.com/oss-fuzz/18529
+    
+    Apparently false alarm per last comment and was ok locally also but lets have it here also
+
+ ...estcase-minimized-hb-subset-fuzzer-5121706490593280 | Bin 0 -> 161328 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 7cde68f10cdf2c3ff77c1d9077475c0fc034c75c
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Nov 2 19:04:14 2019 +0330
+
+    [ci] install pip in fedora bot
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 46178c0325afc6b3131388fa2496e85d2aacace6
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Nov 2 14:36:30 2019 +0330
+
+    [ci] fix fedora bot
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 486754a888d067c990d6a4351ccd41570f08c956
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Mon Sep 23 23:48:08 2019 +0330
+
+    [serialize] Extract iterable copy, copy_all
+
+ src/hb-ot-cmap-table.hh        | 6 +++---
+ src/hb-ot-layout-gpos-table.hh | 7 ++-----
+ src/hb-ot-name-table.hh        | 2 +-
+ src/hb-ot-vorg-table.hh        | 2 +-
+ src/hb-serialize.hh            | 6 ++++++
+ 5 files changed, 13 insertions(+), 10 deletions(-)
+
+commit 35218c488c3966aa6d459ec5a007a2b43208e97c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 31 13:19:44 2019 -0700
+
+    Minor
+    
+    Allow empty HB_VAR_ARRAY definition.  Though, doesn't compile with any
+    compiler I know of.
+
+ src/hb-machinery.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1a1d64bc6f52b42e21609e8ceb4269bdf53b3c40
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 31 12:50:47 2019 -0700
+
+    If applying morx, apply kern table even if GPOS is present and has kern
+    
+    Since we won't be applying GPOS if morx...
+    
+    To be adjusted as I receive more information from Ned.  But for now
+    fixes this:
+    
+    $ ./hb-shape GillSans.ttc Ty
+    [T=0+1109|y=1 at -128,0+769]
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1982 for now.
+
+ src/hb-ot-shape.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
 commit 3a74ee528255cc027d84b204a87b5c25e47bff79
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Tue Oct 29 12:27:03 2019 -0700
@@ -422,6 +8381,13 @@
  src/hb-common.h | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
+commit 453050ad3083ed344bc2ab3b1651babbed34934d
+Merge: d7df7db1 b0b8551a
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Oct 13 08:38:56 2019 +0330
+
+    Merge remote-tracking branch 'upstream/master' into var-subset
+
 commit b0b8551afc2ff86d027fdb380210601cb465af41
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
 Date:   Sat Oct 12 21:12:19 2019 +0330
@@ -701,6 +8667,26 @@
  test/api/test-ot-extents-cff.c | 20 +++++++--------
  10 files changed, 66 insertions(+), 75 deletions(-)
 
+commit d7df7db160992e92c31afb6c79c7ccdad510fec1
+Merge: 74a2dbbc f2339964
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Oct 6 17:18:59 2019 +0330
+
+    Merge remote-tracking branch 'upstream/master' into var-subset
+
+commit 74a2dbbcedb4647bf14dac17eb4faf1d1d57cf99
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Oct 6 17:06:40 2019 +0330
+
+    minor
+
+ .gitignore                  |  1 -
+ src/Makefile.sources        |  1 -
+ src/hb-ot-font.cc           |  1 -
+ src/hb-ot-hmtx-table.hh     |  1 -
+ src/hb-ot-var-hvar-table.hh | 37 +++++++++++++++++--------------------
+ 5 files changed, 17 insertions(+), 24 deletions(-)
+
 commit f2339964b713815c8e0e33699bf34ee24db12215
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
 Date:   Sun Oct 6 16:41:52 2019 +0330
@@ -748,6 +8734,13 @@
  src/hb-subset-plan.cc   |  10 +--
  2 files changed, 85 insertions(+), 126 deletions(-)
 
+commit 100dbccaa50b2f965f3877f2156d388453f0948a
+Merge: c54ee485 b7684fa9
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sun Oct 6 09:18:22 2019 +0330
+
+    Merge remote-tracking branch 'upstream/master' into var-subset
+
 commit b7684fa9f42dffa6bd81acfade163123b30800b8
 Merge: 79ec65ae 21c80d95
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
@@ -852,6 +8845,13 @@
  test/api/test-ot-metrics-tt-var.c                  | 250 +++++++
  13 files changed, 1588 insertions(+), 109 deletions(-)
 
+commit c54ee4853092b8a7f9a47da36407455992f55d93
+Merge: 19d45dca 79ec65ae
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Oct 3 14:28:37 2019 +0330
+
+    Merge remote-tracking branch 'upstream/master' into var-subset
+
 commit 79ec65ae10f959aeddaa1e39eba5226c604a8c87
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
 Date:   Thu Oct 3 14:27:51 2019 +0330
@@ -861,6 +8861,13 @@
  src/hb-ot-font.cc | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
+commit 19d45dcab732f3a836e17d31be9ca92f01c818b0
+Merge: 8106ba7f 3fd555be
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Oct 3 13:39:17 2019 +0330
+
+    Merge remote-tracking branch 'upstream/master' into var-subset
+
 commit 3fd555be543a3e9bf9fee509327dbbc9a7b51cdb
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
 Date:   Thu Oct 3 13:02:41 2019 +0330
@@ -2214,6 +10221,40 @@
  src/hb-ot-layout-gsub-table.hh | 8 ++++++--
  1 file changed, 6 insertions(+), 2 deletions(-)
 
+commit 8106ba7f882f087be114801e857bc945e42cf45b
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Aug 29 20:33:36 2019 +0430
+
+    [glyf] Reapply use of hb_bytes_t.as<GlyphHeader> ()
+
+ src/hb-ot-glyf-table.hh | 37 ++++++++++++++++++-------------------
+ 1 file changed, 18 insertions(+), 19 deletions(-)
+
+commit 9e80fc683639fc63870f7705feff8fc962363167
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Aug 29 20:17:31 2019 +0430
+
+    [glyf] Reapply common moving logic to GlyphHeader struct
+
+ src/hb-ot-glyf-table.hh | 27 +++++++++++++++++----------
+ 1 file changed, 17 insertions(+), 10 deletions(-)
+
+commit 852c9aa0e33744669cba2343f08cab67376edf14
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Aug 29 20:12:53 2019 +0430
+
+    [glyf] Reapply style fixes
+
+ src/hb-ot-glyf-table.hh | 162 +++++++++++++++++++++++++++---------------------
+ 1 file changed, 90 insertions(+), 72 deletions(-)
+
+commit 9ff32b79b37e686bab0b4baa924c97b841bd8413
+Merge: 6b3e0939 49902964
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Aug 29 19:53:18 2019 +0430
+
+    Merge remote-tracking branch 'upstream/master' into glyf-rebase
+
 commit 499029644f35be7feedca7edf4610b2594855f01
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
 Date:   Thu Aug 29 15:09:39 2019 +0430
@@ -3090,6 +11131,20 @@
  src/hb-ot-meta.h | 8 +++++++-
  1 file changed, 7 insertions(+), 1 deletion(-)
 
+commit 6b3e093911aaf834c0adf5b2a114d357914322ee
+Merge: 07f27acc 521c7013
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Jul 31 16:04:48 2019 -0700
+
+    Merge branch 'master' into var-subset
+
+commit 07f27accb9c3823cef5d652150701f24af89fca2
+Merge: a87fbb87 6e3bfecf
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Jul 31 14:58:53 2019 -0700
+
+    Merge branch 'var-subset' of https://github.com/harfbuzz/harfbuzz into var-subset
+
 commit 521c7013abab84a0994fda3977ccd1ba3d496242
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
 Date:   Tue Jul 30 18:10:40 2019 +0430
@@ -3212,6 +11267,13 @@
 
     Merge branch 'master' into subset-varstore
 
+commit 6e3bfecf358a1785995a64c18eb4c1d7cf926ca5
+Merge: 5988ab8a 4e1da6bb
+Author: blueshade7 <ariza at typekit.com>
+Date:   Mon Jul 29 12:25:43 2019 -0700
+
+    Merge branch 'master' into var-subset
+
 commit 4e1da6bb612b0c6386ab143dbb4ca19ff25bc2ba
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
 Date:   Mon Jul 29 22:03:56 2019 +0430
@@ -3535,6 +11597,13 @@
  src/hb-ot-var.h     | 2 +-
  2 files changed, 3 insertions(+), 3 deletions(-)
 
+commit 5988ab8a4e0d2b6d174f2ff0f18addc3f41b7a94
+Merge: 4cba7bda 636ae422
+Author: blueshade7 <ariza at typekit.com>
+Date:   Mon Jul 22 14:36:16 2019 -0700
+
+    Merge branch 'master' into var-subset
+
 commit 636ae422372ed7f17b695e78c9c9015188b204e8
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
 Date:   Mon Jul 22 22:50:21 2019 +0430
@@ -3861,6 +11930,19 @@
  test/api/test-ot-metrics.c    |  54 +++++++++++++++++
  15 files changed, 467 insertions(+), 36 deletions(-)
 
+commit 4cba7bdae94d21ae780b5a71186c5d6da0800fa2
+Author: blueshade7 <ariza at typekit.com>
+Date:   Thu Jul 18 14:03:33 2019 -0700
+
+    regenerate Confortaa subset test expected results
+
+ ...aa-Regular-new.default.retain-all-codepoint.ttf | Bin 97204 -> 182944 bytes
+ ...drop-hints-retain-gids.retain-all-codepoint.ttf | Bin 65976 -> 151740 bytes
+ ...Regular-new.drop-hints.retain-all-codepoint.ttf | Bin 65936 -> 151676 bytes
+ ...a-Regular-new.name-ids.retain-all-codepoint.ttf | Bin 96948 -> 182688 bytes
+ ...egular-new.retain-gids.retain-all-codepoint.ttf | Bin 97244 -> 183008 bytes
+ 5 files changed, 0 insertions(+), 0 deletions(-)
+
 commit ed67efcc8c3638c625b2904833af3f27ef51db14
 Author: David Corbett <corbett.dav at husky.neu.edu>
 Date:   Mon Jun 17 10:16:24 2019 -0400
@@ -3872,6 +11954,13 @@
  src/hb-unicode.hh | 3 ---
  1 file changed, 3 deletions(-)
 
+commit a76d8b0d5531a6a8d682ea9d5150ee7893932269
+Merge: 386a4a64 504bb172
+Author: blueshade7 <ariza at typekit.com>
+Date:   Wed Jul 17 14:12:06 2019 -0700
+
+    Merge commit '504bb17287c978d60a4a515555852465319f74ed' into var-subset
+
 commit 504bb17287c978d60a4a515555852465319f74ed
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
 Date:   Wed Jul 17 22:57:46 2019 +0430
@@ -4022,6 +12111,30 @@
  src/hb-ot-layout-common.hh | 14 +++++++-------
  2 files changed, 31 insertions(+), 8 deletions(-)
 
+commit 386a4a64f5ae0e2ba941f80966585a0a66813576
+Author: blueshade7 <ariza at typekit.com>
+Date:   Fri Jul 12 17:05:34 2019 -0700
+
+    regenerate subset api test result SourceHanSans-Regular.41,4C2E.retaingids.otf
+
+ .../SourceHanSans-Regular.41,4C2E.retaingids.otf      | Bin 2736 -> 2664 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 670768e5b9f24958f60a74f3d194b24333def446
+Author: blueshade7 <ariza at typekit.com>
+Date:   Fri Jul 12 16:14:23 2019 -0700
+
+    fix inc-bimap for subsetting VarStore with retain-gids
+
+ src/hb-bimap.hh                                    |  19 ++++++++-
+ src/hb-ot-layout-common.hh                         |  43 ++++++++++-----------
+ src/hb-ot-var-hvar-table.hh                        |   5 ++-
+ test/api/fonts/AdobeVFPrototype.ac.retaingids.otf  | Bin 6416 -> 6412 bytes
+ .../SourceHanSans-Regular.41,4C2E.retaingids.otf   | Bin 2656 -> 2736 bytes
+ .../SourceSansVariable-Roman.ac.retaingids.ttf     | Bin 2616 -> 2616 bytes
+ ...ourceSerifVariable-Roman-VVAR.ac.retaingids.ttf | Bin 5296 -> 5288 bytes
+ 7 files changed, 42 insertions(+), 25 deletions(-)
+
 commit 4730b350b7ee90338caf3e962343af42412ce3df
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Fri Jul 12 15:38:35 2019 -0700
@@ -4086,6 +12199,67 @@
  test/fuzzing/hb-subset-fuzzer.cc | 14 ++++++++++++++
  1 file changed, 14 insertions(+)
 
+commit 0eef8113d8a7940b4529a340790976a577fe829e
+Author: blueshade7 <ariza at typekit.com>
+Date:   Tue Jul 9 11:43:59 2019 -0700
+
+    retain gids in HVAR so in sync with fontTools
+    regenerate Comfortaa subset test results
+
+ src/hb-bimap.hh                                    |   6 +
+ src/hb-ot-var-hvar-table.hh                        | 123 +++++++++++++--------
+ .../Comfortaa-Regular-new.default.61,62,63.ttf     | Bin 6492 -> 7460 bytes
+ .../basics/Comfortaa-Regular-new.default.61,63.ttf | Bin 6316 -> 7104 bytes
+ .../basics/Comfortaa-Regular-new.default.61.ttf    | Bin 6148 -> 6752 bytes
+ .../basics/Comfortaa-Regular-new.default.62.ttf    | Bin 6088 -> 6696 bytes
+ .../basics/Comfortaa-Regular-new.default.63.ttf    | Bin 6068 -> 6676 bytes
+ ...Regular-new.drop-hints-retain-gids.61,62,63.ttf | Bin 3284 -> 4912 bytes
+ ...aa-Regular-new.drop-hints-retain-gids.61,63.ttf | Bin 3164 -> 4620 bytes
+ ...ortaa-Regular-new.drop-hints-retain-gids.61.ttf | Bin 2868 -> 4056 bytes
+ ...ortaa-Regular-new.drop-hints-retain-gids.62.ttf | Bin 3020 -> 4296 bytes
+ ...ortaa-Regular-new.drop-hints-retain-gids.63.ttf | Bin 3024 -> 4304 bytes
+ .../Comfortaa-Regular-new.drop-hints.61,62,63.ttf  | Bin 1952 -> 2920 bytes
+ .../Comfortaa-Regular-new.drop-hints.61,63.ttf     | Bin 1832 -> 2620 bytes
+ .../basics/Comfortaa-Regular-new.drop-hints.61.ttf | Bin 1704 -> 2308 bytes
+ .../basics/Comfortaa-Regular-new.drop-hints.62.ttf | Bin 1688 -> 2296 bytes
+ .../basics/Comfortaa-Regular-new.drop-hints.63.ttf | Bin 1688 -> 2296 bytes
+ .../Comfortaa-Regular-new.name-ids.61,62,63.ttf    | Bin 6236 -> 7204 bytes
+ .../Comfortaa-Regular-new.name-ids.61,63.ttf       | Bin 6060 -> 6848 bytes
+ .../basics/Comfortaa-Regular-new.name-ids.61.ttf   | Bin 5892 -> 6496 bytes
+ .../basics/Comfortaa-Regular-new.name-ids.62.ttf   | Bin 5832 -> 6440 bytes
+ .../basics/Comfortaa-Regular-new.name-ids.63.ttf   | Bin 5812 -> 6420 bytes
+ .../Comfortaa-Regular-new.retain-gids.61,62,63.ttf | Bin 7824 -> 9452 bytes
+ .../Comfortaa-Regular-new.retain-gids.61,63.ttf    | Bin 7648 -> 9104 bytes
+ .../Comfortaa-Regular-new.retain-gids.61.ttf       | Bin 7312 -> 8500 bytes
+ .../Comfortaa-Regular-new.retain-gids.62.ttf       | Bin 7420 -> 8696 bytes
+ .../Comfortaa-Regular-new.retain-gids.63.ttf       | Bin 7404 -> 8684 bytes
+ test/subset/run-tests.py                           |   2 +-
+ 28 files changed, 85 insertions(+), 46 deletions(-)
+
+commit a87fbb872b31c7a292ed8b414be728aa951e2833
+Merge: 49252c42 6e35668b
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Jul 9 10:25:54 2019 -0700
+
+    Merge branch 'var-subset' of https://github.com/harfbuzz/harfbuzz into var-subset
+
+commit 6e35668b452cef86702e2563f4006a1db5d8fd74
+Author: blueshade7 <ariza at typekit.com>
+Date:   Tue Jul 9 09:47:54 2019 -0700
+
+    fix var-subset build
+
+ src/harfbuzz.cc          | 1 +
+ test/subset/run-tests.py | 2 +-
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+commit 8bf989ea70804dad66fb1c2d0c625ef5e562a309
+Merge: 5763a927 2e7021da
+Author: blueshade7 <ariza at typekit.com>
+Date:   Mon Jul 8 17:13:29 2019 -0700
+
+    update from master
+
 commit 2e7021da7d1726a37822e6a001b9218f82255bc8
 Author: Dominik Röttsches <drott at chromium.org>
 Date:   Mon Jul 8 10:19:49 2019 +0300
@@ -4436,6 +12610,13 @@
  src/hb-ot-layout-common.hh | 165 ++++++++++++++++++++++++++++++++++++++++++++-
  1 file changed, 163 insertions(+), 2 deletions(-)
 
+commit 5763a92749386e134f2b4073531c10e9586d1d19
+Merge: 6f35cf7a 6bcbe495
+Author: Michiharu Ariza <ariza at typekit.com>
+Date:   Mon Jul 1 15:17:19 2019 -0700
+
+    Merge branch 'master' into var-subset
+
 commit 040b261deeed8924edcb087e27a61392d1f85023
 Author: Michiharu Ariza <ariza at typekit.com>
 Date:   Sun Jun 30 16:13:07 2019 -0700
@@ -6185,6 +14366,21 @@
  src/hb-subset.cc        |  2 +-
  2 files changed, 16 insertions(+), 17 deletions(-)
 
+commit 6f35cf7a637f5efc0ef3888d929a6392cc2863c3
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Jun 6 09:15:34 2019 -0700
+
+    regenerate SourceSerifVariable expected subset results
+
+ .gitignore                                            |   1 +
+ ...SerifVariable-Roman.default.1FC,21,41,20,62,63.ttf | Bin 5464 -> 4132 bytes
+ .../SourceSerifVariable-Roman.default.61,62,63.ttf    | Bin 5432 -> 4100 bytes
+ ...urceSerifVariable-Roman.default.D7,D8,D9,DA,DE.ttf | Bin 5924 -> 4592 bytes
+ ...ifVariable-Roman.drop-hints.1FC,21,41,20,62,63.ttf | Bin 5464 -> 4132 bytes
+ .../SourceSerifVariable-Roman.drop-hints.61,62,63.ttf | Bin 5432 -> 4100 bytes
+ ...eSerifVariable-Roman.drop-hints.D7,D8,D9,DA,DE.ttf | Bin 5924 -> 4592 bytes
+ 7 files changed, 1 insertion(+)
+
 commit db938479d7b1e3ec35a39a9ad31c945e09e6d5e5
 Author: Qunxin Liu <qxliu at google.com>
 Date:   Tue Jun 4 10:30:53 2019 -0700
@@ -6195,6 +14391,16 @@
  src/hb-subset.cc        |  2 +-
  2 files changed, 23 insertions(+), 27 deletions(-)
 
+commit 66361c72f655cc9170fd8c25610ed192fa0ff86d
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Jun 5 14:51:04 2019 -0700
+
+    restore gvar/MVAR/HVAR tables in subset tests
+
+ test/subset/generate-expected-outputs.py | 2 +-
+ test/subset/run-tests.py                 | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
 commit d5e5f378329b6ce21944b79b568369ea7bc36cf3
 Author: Eli Zaretskii <eliz at gnu.org>
 Date:   Wed Jun 5 22:20:03 2019 +0300
@@ -6223,6 +14429,19 @@
  src/hb.hh           | 7 +++++++
  4 files changed, 14 insertions(+), 3 deletions(-)
 
+commit 8f8e8a84795db45098c95e19a7ff83d898d3bc7d
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Jun 5 12:59:09 2019 -0700
+
+    fix build
+
+ src/hb-ot-font.cc           | 2 +-
+ src/hb-ot-glyf-table.hh     | 8 ++++----
+ src/hb-ot-hmtx-table.hh     | 2 +-
+ src/hb-ot-var-gvar-table.hh | 6 +++---
+ src/hb-ot-var-hvar-table.hh | 2 +-
+ 5 files changed, 10 insertions(+), 10 deletions(-)
+
 commit c7439d4e3a76d596845aad4e4bc860bd61ee47e3
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Wed Jun 5 12:13:49 2019 -0700
@@ -6235,6 +14454,13 @@
  src/hb-buffer.hh | 8 +++++++-
  2 files changed, 7 insertions(+), 4 deletions(-)
 
+commit 4ddab6facc0c7ffe7623bf6449ab9b27166924a6
+Merge: 157a414b 4b1b0bf2
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Jun 5 11:21:27 2019 -0700
+
+    Merge branch 'master' into var-subset
+
 commit 4b1b0bf2f51f806d3285a7e7dec378b9eab9333e
 Merge: 659eeddb 815f002b
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
@@ -6949,6 +15175,15 @@
  src/hb-ot-shape-complex-use.hh         |  11 +-
  5 files changed, 315 insertions(+), 327 deletions(-)
 
+commit 322df806eef74247c8bf0da200a2cde29133950e
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Fri May 24 19:49:19 2019 +0100
+
+    [Docs] Usermanual: integration chapter; add GI-Python section.
+
+ docs/usermanual-integration.xml | 35 +++++++++++++++++++++++------------
+ 1 file changed, 23 insertions(+), 12 deletions(-)
+
 commit 487879e013758aef2c7f824033a40cd56361d240
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Fri May 24 12:37:53 2019 -0400
@@ -6967,6 +15202,15 @@
  src/hb-blob.h | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)
 
+commit 773c85f343e8958daf271d91d64033514289c236
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Fri May 24 19:23:19 2019 +0100
+
+    [Docs] Usermanual: integration chapter; add ICU section.
+
+ docs/usermanual-integration.xml | 47 +++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 45 insertions(+), 2 deletions(-)
+
 commit 96de94768b08287325be8947255917502368c337
 Merge: c96c6b28 1197bef2
 Author: rsheeter <rsheeter at google.com>
@@ -6985,6 +15229,15 @@
  src/hb-ot-glyf-table.hh | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)
 
+commit c0bb66ecbff712221fb7c97f628ed026926229b2
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Fri May 24 18:49:40 2019 +0100
+
+    [Docs] Usermanual: integration chapter; add CoreText/Mac section.
+
+ docs/usermanual-integration.xml | 107 +++++++++++++++++++++++++++++++++-------
+ 1 file changed, 89 insertions(+), 18 deletions(-)
+
 commit e66253283385aa67eb9c5ab627139a56f9ae5a71
 Author: Rod Sheeter <rsheeter at google.com>
 Date:   Fri May 24 10:39:56 2019 -0700
@@ -7003,6 +15256,26 @@
  src/hb-ot-glyf-table.hh | 18 ++++++++----------
  1 file changed, 8 insertions(+), 10 deletions(-)
 
+commit dd1c7656a5918702a81bc3aaf66e0e54fdb3c545
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Fri May 24 14:30:15 2019 +0100
+
+    [Docs] Usermanual: integration chapter; add Uniscribe/Windows section.
+
+ docs/usermanual-integration.xml | 110 ++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 105 insertions(+), 5 deletions(-)
+
+commit 2da567e7b69da95738015b445901afb00094d92b
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Fri May 24 11:13:53 2019 +0100
+
+    [Docs] Usermanual: platform integration chapter; add intro, GLib, FreeType sections. Update XML TOCs to match.
+
+ docs/Makefile.am                |   1 +
+ docs/harfbuzz-docs.xml          |   1 +
+ docs/usermanual-integration.xml | 365 ++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 367 insertions(+)
+
 commit c96c6b287ff1d96da6a50a8cb3f641fe8705e5f7
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Thu May 23 21:37:17 2019 -0400
@@ -7608,6 +15881,63 @@
  test/api/test-subset-drop-tables.c | 71 ++++++++++++++++++++++++++++++++++++++
  8 files changed, 95 insertions(+), 1 deletion(-)
 
+commit d00a20bedc5706d4d764f78ea108ca4316651b11
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Mon May 20 17:38:38 2019 +0100
+
+    [Docs] Add gtk-doc comments to hb-graphite2.
+
+ src/hb-graphite2.cc | 16 ++++++++++++++--
+ src/hb-graphite2.h  | 10 +++++++++-
+ 2 files changed, 23 insertions(+), 3 deletions(-)
+
+commit 0a5a8fcbceb49f317a16803da090864f9ea03577
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Mon May 20 17:38:13 2019 +0100
+
+    [Docs] Add gtk-doc comments to hb-icu.
+
+ src/hb-icu.cc | 35 ++++++++++++++++++++++++++++++++++-
+ 1 file changed, 34 insertions(+), 1 deletion(-)
+
+commit 9126a5ff070fe1191dfaf852aa601d506ddcffcb
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Mon May 20 17:37:56 2019 +0100
+
+    [Docs] Add gtk-doc comments to hb-ft.
+
+ src/hb-ft.cc | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 117 insertions(+), 18 deletions(-)
+
+commit bfa7b0af02a6ec66898723fe3e82f74760996a10
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Mon May 20 17:36:55 2019 +0100
+
+    [Docs] Add gtk-doc comments to hb-gobject and hb-glib.
+
+ src/hb-glib.cc            | 44 +++++++++++++++++++++++++++++++++++++++++++-
+ src/hb-gobject-structs.cc | 13 +++++++++++--
+ 2 files changed, 54 insertions(+), 3 deletions(-)
+
+commit 27222253d42d0485ec5a9a3db602f5cba64df94e
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Mon May 20 17:36:18 2019 +0100
+
+    [Docs] Add gtk-doc comments to hb-uniscribe.
+
+ src/hb-uniscribe.cc | 22 +++++++++++++++++++++-
+ 1 file changed, 21 insertions(+), 1 deletion(-)
+
+commit 32ae0d3e78c4e1f7299cb4fa251c0e66b3d5ae78
+Author: Nathan Willis <nwillis at glyphography.com>
+Date:   Mon May 20 17:35:39 2019 +0100
+
+    [Docs] Add gtk-doc comments to hb-coretext.
+
+ src/hb-coretext.cc | 45 +++++++++++++++++++++++++++++++++++++++++----
+ src/hb-coretext.h  | 32 ++++++++++++++++++++++++++++++++
+ 2 files changed, 73 insertions(+), 4 deletions(-)
+
 commit 0ca7ad4352eff357cbb5cc1dfe62aa15b440de84
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Mon May 20 11:39:07 2019 -0400
@@ -10930,6 +19260,15 @@
  src/hb-subset.hh             |  4 ++--
  5 files changed, 24 insertions(+), 11 deletions(-)
 
+commit 49252c42bb00380663ba9612e075c07f1be606b3
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri May 3 10:42:11 2019 -0700
+
+    get rid of O(n^2) loop from apply_deltas_to_points
+
+ src/hb-ot-var-gvar-table.hh | 55 +++++++++++++++++++++++++++++++--------------
+ 1 file changed, 38 insertions(+), 17 deletions(-)
+
 commit 0d5fd168f8e3c1202358a82161a28e407149b1b4
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Fri May 3 10:37:32 2019 -0700
@@ -11102,6 +19441,16 @@
  src/hb-algs.hh | 3 ---
  1 file changed, 3 deletions(-)
 
+commit 157a414bd9fb8b1b7a066603e7c44b8680b48e28
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu May 2 11:25:10 2019 -0700
+
+    fix mixup of TRACE_SUBSET/SERIALIZE
+
+ src/hb-ot-layout-common.hh  | 4 ++--
+ src/hb-ot-var-hvar-table.hh | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
 commit 14e1fabc41a9a5ead3d91d560773050469982f54
 Author: David Corbett <corbett.dav at husky.neu.edu>
 Date:   Wed May 1 21:29:06 2019 -0400
@@ -11175,6 +19524,15 @@
  src/hb-directwrite.cc |  8 ++++++--
  2 files changed, 14 insertions(+), 6 deletions(-)
 
+commit c52294eb28e9b043306f91611e4444651fe5e8ef
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Apr 30 10:40:45 2019 -0700
+
+    renaming & arg reorder
+
+ src/hb-ot-var-hvar-table.hh | 56 ++++++++++++++++++++++-----------------------
+ 1 file changed, 28 insertions(+), 28 deletions(-)
+
 commit fe4a0ac707802b5bb36787723f8d55a58c2946a5
 Author: David Corbett <corbett.dav at husky.neu.edu>
 Date:   Tue Apr 30 13:35:50 2019 -0400
@@ -11241,6 +19599,13 @@
  docs/usermanual-object-model.xml | 35 ++++++++++++++++++++++-------------
  1 file changed, 22 insertions(+), 13 deletions(-)
 
+commit 1223a352b7c8d1cc362693b850f348af4d4d03fb
+Merge: aa3ac592 9542bdd0
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Mon Apr 29 16:43:48 2019 -0700
+
+    Merge branch 'master' into var-subset
+
 commit 9542bdd0ed2d581cdb4bd950ac3cd7e3bf899478
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
 Date:   Mon Apr 29 14:52:28 2019 -0700
@@ -11975,6 +20340,38 @@
  src/hb-serialize.hh | 2 ++
  1 file changed, 2 insertions(+)
 
+commit aa3ac59245a9f90c6636fbf6d3489d2b7caa4fd3
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Apr 17 12:43:53 2019 -0700
+
+    fix build
+
+ src/hb-ot-var-hvar-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c87488b46d1f302e1ad313c365e2cd440e60141a
+Merge: 49fe81fd c67a0d58
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Apr 17 12:07:15 2019 -0700
+
+    Merge branch 'master' into var-subset
+
+commit 49fe81fdeb236e10c1b525b34edb4ec8aaeac35f
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Apr 17 11:48:12 2019 -0700
+
+    updated api test results for HVAR/VVAR subset changes
+
+ test/api/fonts/AdobeVFPrototype.abc.otf               | Bin 6952 -> 6900 bytes
+ test/api/fonts/AdobeVFPrototype.ac.nohints.otf        | Bin 6272 -> 6220 bytes
+ .../api/fonts/AdobeVFPrototype.ac.nosubrs.nohints.otf | Bin 6152 -> 6100 bytes
+ test/api/fonts/AdobeVFPrototype.ac.nosubrs.otf        | Bin 6336 -> 6284 bytes
+ test/api/fonts/AdobeVFPrototype.ac.otf                | Bin 6460 -> 6408 bytes
+ test/api/fonts/AdobeVFPrototype.ac.retaingids.otf     | Bin 6464 -> 6416 bytes
+ .../fonts/SourceSansVariable-Roman.ac.retaingids.ttf  | Bin 3040 -> 2616 bytes
+ .../SourceSerifVariable-Roman-VVAR.ac.retaingids.ttf  | Bin 5288 -> 5296 bytes
+ 8 files changed, 0 insertions(+), 0 deletions(-)
+
 commit efbba7ad26dda5930f5d1bd5292304835432f504
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Wed Apr 17 11:00:08 2019 -0400
@@ -12108,6 +20505,22 @@
  src/hb-null.hh   |  6 +++---
  9 files changed, 19 insertions(+), 18 deletions(-)
 
+commit 6cde814a360eaeab6755685cf7980887af3225d1
+Merge: 007bb3e0 1ce11b44
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Apr 16 11:35:07 2019 -0700
+
+    Merge branch 'master' into var-subset
+
+commit 007bb3e0d1478912f8006f4c440866b4628cc28f
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Apr 16 10:33:51 2019 -0700
+
+    retain-gids in HVAR/VVAR (unused deltas retained)
+
+ src/hb-ot-var-hvar-table.hh | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
 commit 1ce11b44375dae74e8984ace1db4f08c51ac9c38
 Author: David Corbett <corbett.dav at husky.neu.edu>
 Date:   Tue Apr 16 10:04:45 2019 -0400
@@ -12179,6 +20592,15 @@
  src/hb-meta.hh | 7 +++++++
  1 file changed, 7 insertions(+)
 
+commit eb348fc5c00df2330f98ea769699ce586f97e1d6
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Mon Apr 15 16:24:22 2019 -0700
+
+    optimize out regions & region index lists & short count
+
+ src/hb-ot-layout-common.hh | 107 +++++++++++++++++++++++++++++++++------------
+ 1 file changed, 80 insertions(+), 27 deletions(-)
+
 commit 89fea21697adfbba5057dd1d69c9806ee86e5ca8
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Mon Apr 15 17:36:09 2019 -0400
@@ -12456,6 +20878,20 @@
  src/hb-debug.hh | 3 +++
  1 file changed, 3 insertions(+)
 
+commit 3e524bf77280e5f3cd0c4d7429d2a6a5ec49268d
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Apr 12 12:48:48 2019 -0700
+
+    fix VarData serialize to remove unused data sets
+    
+    add api test case for that
+
+ src/hb-ot-layout-common.hh                         |  14 ++++++++++----
+ .../fonts/SourceSansVariable-Roman-modHVAR.abc.ttf | Bin 0 -> 3260 bytes
+ .../fonts/SourceSansVariable-Roman-modHVAR.ac.ttf  | Bin 0 -> 3032 bytes
+ test/api/test-subset-hvar.c                        |  21 +++++++++++++++++++++
+ 4 files changed, 31 insertions(+), 4 deletions(-)
+
 commit 079d2dcbb2607cda3daa497199090c5813a51de5
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Fri Apr 12 15:00:37 2019 -0400
@@ -12544,6 +20980,13 @@
  src/hb-ot-shape-complex-vowel-constraints.cc | 3 +++
  1 file changed, 3 insertions(+)
 
+commit a90e4916df74f6f84ce78eb2a73b6f325e7e8617
+Merge: 94573702 3db22726
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Apr 11 15:57:32 2019 -0700
+
+    Merge branch 'master' into var-subset
+
 commit 3db227265bc0790ffd718bf265d245c78598a49d
 Author: Nathan Willis <nwillis at glyphography.com>
 Date:   Tue Apr 2 18:49:40 2019 +0100
@@ -12617,6 +21060,24 @@
  src/hb-ot-layout.h  |  11 ++
  2 files changed, 462 insertions(+), 5 deletions(-)
 
+commit 945737026d5647c42c1fb897a88364613a7dd51c
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Apr 11 10:52:11 2019 -0700
+
+    tweak: moved xshift code out of get_points_var
+
+ src/hb-ot-glyf-table.hh | 21 +++++++++------------
+ 1 file changed, 9 insertions(+), 12 deletions(-)
+
+commit e8140832025e31d62784ce16a03fc5667b0c4015
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Apr 11 09:59:13 2019 -0700
+
+    undo hb_ot_ge_glyph_v_origin to fix test failures
+
+ src/hb-ot-font.cc | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
 commit b52c0e54b9855a1f3d400e4dbcd0372520f2c2fc
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Thu Apr 11 11:20:10 2019 -0400
@@ -12648,6 +21109,34 @@
  src/hb.hh           | 12 ++++++------
  4 files changed, 13 insertions(+), 13 deletions(-)
 
+commit 9e79285ef3b4d7490b4bbad0eef16dd73fd8fb62
+Merge: 6d79a25b c5509be9
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Apr 10 17:24:29 2019 -0700
+
+    Merge branch 'master' into var-subset
+
+commit 6d79a25bed110b2d8842bd102ffdb5606023b8a1
+Merge: ab9d3096 196481cc
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Apr 10 17:23:00 2019 -0700
+
+    Merge branch 'var-subset' of https://github.com/harfbuzz/harfbuzz into var-subset
+
+commit ab9d30965d298c10e0f1934364b03276067cf8a5
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Apr 10 17:21:37 2019 -0700
+
+    Add tt var metrics test cases & bug fixes
+
+ src/hb-ot-font.cc                                  |   4 +-
+ src/hb-ot-glyf-table.hh                            | 131 ++++++++++-----------
+ src/hb-ot-hmtx-table.hh                            |   4 +-
+ src/hb-ot-var-gvar-table.hh                        |   4 +-
+ .../api/fonts/SourceSansVariable-Roman.modcomp.ttf | Bin 0 -> 3252 bytes
+ test/api/test-ot-metrics-tt-var.c                  |  79 ++++++++++++-
+ 6 files changed, 147 insertions(+), 75 deletions(-)
+
 commit edfc6be4a0362efa5c1d39f4792a28b5726c3ce5
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Wed Apr 10 15:53:48 2019 -0400
@@ -12696,6 +21185,24 @@
  src/hb-coretext.cc | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
+commit 196481ccb913d23e30cbd267df296deada919e88
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Apr 5 16:37:12 2019 -0700
+
+    shift glyph horizontally at top level, not components
+
+ src/hb-ot-glyf-table.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 8a92ffd9bb9357cdf219e166c8a71abc90823976
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Apr 5 15:04:23 2019 -0700
+
+    fix failure to check glyf recursion
+
+ src/hb-ot-glyf-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
 commit 4c19aa26204d0dc2f08b6e4a824e9088301f68d8
 Author: Maks Naumov <maksqwe1 at ukr.net>
 Date:   Fri Apr 5 21:46:27 2019 +0300
@@ -12899,6 +21406,22 @@
  src/hb-meta.hh | 9 ++++++---
  1 file changed, 6 insertions(+), 3 deletions(-)
 
+commit b999ce9bf06fc90c4cb3c531357967835d7e706d
+Merge: c2d727a4 6215fb8e
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Apr 3 10:34:09 2019 -0700
+
+    Merge branch 'master' into var-subset
+
+commit c2d727a479429b7c14126569e0f3e41d4b0beadf
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Apr 3 10:33:55 2019 -0700
+
+    fix xshift by (lsb - xMin)
+
+ src/hb-ot-glyf-table.hh | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
 commit 6215fb8e68bdf69f4af9f7f4959ad55a70723774
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Tue Apr 2 23:10:03 2019 -0700
@@ -13068,6 +21591,15 @@
  src/hb-open-type.hh | 14 +++++---------
  1 file changed, 5 insertions(+), 9 deletions(-)
 
+commit 27d3bac8ef77d56f91a7bd88bed02c3f1aceba0a
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Apr 2 17:02:11 2019 -0700
+
+    fix 2x2 component transform
+
+ src/hb-ot-var-gvar-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
 commit 5a3de4f4f8791139d2c04a66244001aba192ef6b
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Tue Apr 2 16:53:05 2019 -0700
@@ -13088,6 +21620,33 @@
  src/test-iter.cc | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
+commit 8801b80d724d36f9e6547b7975aaf1cc1a355734
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Apr 2 13:10:36 2019 -0700
+
+    refix: orig_points must be saved before any adjustment
+
+ src/hb-ot-var-gvar-table.hh | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+commit ee58f6012e9570c8d56e23d14c605a2186d4a265
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Apr 2 11:24:29 2019 -0700
+
+    infer gvar deltas for each region (not after accumulation)
+
+ src/hb-ot-var-gvar-table.hh | 74 ++++++++++++++++++++++-----------------------
+ 1 file changed, 37 insertions(+), 37 deletions(-)
+
+commit 2c31652c8a9186068ee8958b46139121c51f1bf4
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Apr 2 10:07:43 2019 -0700
+
+    fix private_indices vs shared_indices
+
+ src/hb-ot-var-gvar-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
 commit 062f5d6e7aa061358eb5874a8f3a3f3bd6e9f16f
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
 Date:   Tue Apr 2 20:27:00 2019 +0430
@@ -13135,6 +21694,15 @@
  src/hb-serialize.hh | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
+commit dce9e5e622b94aaf8ba7e81dd6e09a0cead0c51f
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Mon Apr 1 20:55:02 2019 -0700
+
+    fix get_start_tuple, get_end_tuple
+
+ src/hb-ot-var-gvar-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
 commit 64d0f0893812fa1cb2746071d8b021560969526d
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Mon Apr 1 16:50:28 2019 -0700
@@ -13202,6 +21770,15 @@
  src/test-iter.cc |  5 +++++
  2 files changed, 33 insertions(+)
 
+commit 72545cb83949571393f06b0f26c36adf461b967e
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Mon Apr 1 16:49:15 2019 -0700
+
+    fixed off by one bug in apply_deltas_to_points()
+
+ src/hb-ot-var-gvar-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
 commit f3aca6aa267f7687a0406c7c545aefb5eed300b2
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Sun Mar 31 21:37:14 2019 -0700
@@ -13289,6 +21866,24 @@
  src/hb-shaper-list.hh |  4 ----
  2 files changed, 60 deletions(-)
 
+commit ef11305bfda0e261f0793acd81c9478df1719b1e
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sun Mar 31 00:23:58 2019 -0700
+
+    fixed tt var extents
+    
+    max bounds were not correctly initialized
+
+ src/hb-ot-glyf-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f7700fc479c25599e89b9d59edaad66e103a742d
+Merge: 43725d36 d6005b49
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sat Mar 30 20:49:34 2019 -0700
+
+    Merge branch 'master' into var-subset
+
 commit d6005b49b32410543a8dfa93ce2a213223cf8f01
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Sat Mar 30 19:49:56 2019 -0700
@@ -13379,6 +21974,13 @@
  src/hb-serialize.hh | 22 +++++++---------------
  1 file changed, 7 insertions(+), 15 deletions(-)
 
+commit 43725d36322b7277d515b958b5e894e1c892cede
+Merge: 294d520f a7c63cd8
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sat Mar 30 18:51:15 2019 -0700
+
+    Merge branch 'master' into var-subset
+
 commit 0b1fe7b716628f7b7b4098da9ef544e1518008f5
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Sat Mar 30 18:48:26 2019 -0700
@@ -13580,6 +22182,17 @@
  src/hb-map.hh | 65 ++++++++++++++++++++++++++++++++++-------------------------
  1 file changed, 37 insertions(+), 28 deletions(-)
 
+commit 294d520f6542198fa6cf08764f7732fe138e5c97
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sat Mar 30 13:58:22 2019 -0700
+
+    more iter changes from master
+
+ src/hb-iter.hh               |  4 ++--
+ src/hb-ot-layout-gsubgpos.hh | 12 ++++++------
+ src/test-iter.cc             |  2 +-
+ 3 files changed, 9 insertions(+), 9 deletions(-)
+
 commit 4b7f4dbc0cf58d87f4c91f059734e91e4d988480
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Sat Mar 30 13:48:32 2019 -0700
@@ -13590,6 +22203,74 @@
  src/hb-meta.hh |  8 ++++++++
  2 files changed, 21 insertions(+), 5 deletions(-)
 
+commit 8f2ce82f7699e12b80986fcdf408f7b43358bcc8
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sat Mar 30 11:50:24 2019 -0700
+
+    hb.hh from master
+
+ src/hb.hh | 53 -----------------------------------------------------
+ 1 file changed, 53 deletions(-)
+
+commit 3bfd3a367cdd8714b151d2504148b772f1159558
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sat Mar 30 00:27:02 2019 -0700
+
+    fix build
+
+ src/Makefile.sources | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit c7ca8853ae286b685d8e3dea342c044237213341
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sat Mar 30 00:11:58 2019 -0700
+
+    more change set() to =
+
+ src/hb-ot-layout-common.hh | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit d75b73a309d5b6064a6e13d9a7eb998e0ec53822
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sat Mar 30 00:06:54 2019 -0700
+
+    fix rebase errors
+
+ .circleci/config.yml  | 11 -----------
+ src/hb-common.h       |  2 +-
+ src/hb-directwrite.cc | 15 ++++++++++++++-
+ src/hb-directwrite.h  |  3 +++
+ src/hb-null.hh        |  2 +-
+ 5 files changed, 19 insertions(+), 14 deletions(-)
+
+commit 3fbd242ba62835a5c41164807bfdb0e4f63260da
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 29 23:53:06 2019 -0700
+
+    replace .set() with =
+    
+    remove .gitignore
+
+ .gitignore                  |  1 -
+ src/hb-ot-var-gvar-table.hh | 26 +++++++++++++-------------
+ src/hb-ot-var-hvar-table.hh | 18 +++++++++---------
+ 3 files changed, 22 insertions(+), 23 deletions(-)
+
+commit 8a8965be39d909198d6c91d5a45aede6802ebd71
+Merge: cc94a9ed 3236623e
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 29 23:38:16 2019 -0700
+
+    Merge branch 'var-subset' of https://github.com/harfbuzz/harfbuzz into var-subset
+
+commit cc94a9ed3b63cf74aa64c83a203137f16c6e152c
+Merge: 435bc7f3 ce6093a9
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 29 18:41:38 2019 -0700
+
+    Merge branch 'var-subset' of https://github.com/harfbuzz/harfbuzz into var-subset
+    rebase master
+
 commit e5306927994e8e412dea5dd960b8b3ed4ca848eb
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Fri Mar 29 23:31:07 2019 -0700
@@ -13601,6 +22282,22 @@
  src/test-iter.cc             |  2 +-
  3 files changed, 9 insertions(+), 9 deletions(-)
 
+commit ce6093a96ba4c68b4eb4f1cd4b695eb41f1fa334
+Merge: ddb84dce a1177fec
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 29 10:32:45 2019 -0700
+
+    Merge branch 'var-subset' of https://github.com/harfbuzz/harfbuzz into var-subset
+
+commit a1177fec8f43a65bca6696378995d6d39d8f6330
+Merge: 58c8c7a4 f505b5d5
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 29 08:43:47 2019 -0700
+
+    Merge branch 'master' into var-subset
+    
+    rebase master
+
 commit f505b5d5c9c05741a933b4b986503e1697bbdfdb
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Fri Mar 29 22:55:02 2019 -0700
@@ -13849,6 +22546,1061 @@
  src/hb-open-type.hh | 24 ++++++++++++++----------
  1 file changed, 14 insertions(+), 10 deletions(-)
 
+commit 3236623e1f4a11c23f8f2fb41d886d1255c2bc63
+Merge: 435bc7f3 d30e5e74
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 29 18:41:38 2019 -0700
+
+    Merge branch 'var-subset' of https://github.com/harfbuzz/harfbuzz into var-subset
+
+commit 435bc7f3e2290e108550ed460f4fdeacf25e9f28
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 29 18:39:30 2019 -0700
+
+    Update hb-ot-var-gvar-table.hh
+
+ src/hb-ot-var-gvar-table.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 8fdb8fcf808da7d928aa289e0d1c432223fb1a26
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 29 18:39:27 2019 -0700
+
+    fix rebase errors
+
+ src/hb-ot-layout-common.hh  |  21 ++++++--
+ src/hb-ot-var-gvar-table.hh | 119 ++++++++++++++------------------------------
+ 2 files changed, 54 insertions(+), 86 deletions(-)
+
+commit 1ccb457cbb7be2466536661d76d62de9fe582639
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 29 18:28:25 2019 -0700
+
+    fix gvar fuzz bug
+
+ src/hb-ot-var-gvar-table.hh | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+commit 3f84589232b5a6397e711774351bfe8dc6b1cfd7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Mar 28 21:21:26 2019 -0700
+
+    2.4.0
+
+ NEWS             | 11 +++++++++++
+ configure.ac     |  2 +-
+ src/hb-buffer.h  |  2 +-
+ src/hb-version.h |  6 +++---
+ 4 files changed, 16 insertions(+), 5 deletions(-)
+
+commit 282c76d9a01cbe4300d9306d391c387f1890c391
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Mar 28 21:00:58 2019 -0700
+
+    Use internal bsearch() for language tags
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/pull/1639
+
+ src/hb-ot-tag.cc | 46 ++++++++++++++++++++++------------------------
+ 1 file changed, 22 insertions(+), 24 deletions(-)
+
+commit 3bed03dc6aded78037b09f21ea1defe842bfb73c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Mar 28 20:50:04 2019 -0700
+
+    [indic] Add back medial-consonant to grammar
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1592
+
+ src/hb-ot-shape-complex-indic-machine.hh           | 1244 +++++++++++---------
+ src/hb-ot-shape-complex-indic-machine.rl           |    5 +-
+ src/hb-ot-shape-complex-indic.cc                   |    2 +-
+ src/hb-ot-shape-complex-indic.hh                   |    6 +-
+ .../f75c4b05a0a4d67c1a808081ae3d74a9c66509e8.ttf   |  Bin 0 -> 1924 bytes
+ .../data/in-house/tests/indic-syllable.tests       |    2 +
+ 6 files changed, 672 insertions(+), 587 deletions(-)
+
+commit f8803fbacec52d633adc37acfd2c9c79c4c12041
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Mar 28 20:23:12 2019 -0700
+
+    [khmer] Add trailing Coeng to syllable grammar
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1541
+
+ src/hb-ot-shape-complex-khmer-machine.hh           | 248 ++++++++++-----------
+ src/hb-ot-shape-complex-khmer-machine.rl           |   2 +-
+ .../ad01ab2ea1cb1a4d3a2783e2675112ef11ae6404.ttf   | Bin 0 -> 1500 bytes
+ test/shaping/data/in-house/tests/khmer-misc.tests  |   1 +
+ 4 files changed, 122 insertions(+), 129 deletions(-)
+
+commit 93a6a063dc448b7b8303fe10fc9bbf1c2298b5f8
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Mar 28 16:57:56 2019 -0700
+
+    [ci] Tweak macos and psvita bots (#1638)
+    
+    * Add --with-graphite2 to macOS
+    * Add a dummy ragel script for psvita
+
+ .circleci/config.yml | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit f84342c094727a41be6225d484d30170d1ddf118
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Mar 28 16:17:36 2019 -0700
+
+    minor
+
+ src/hb-ot-var-hvar-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7e8c4585accc9608a7cb167279ab1ca9e6e1f779
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Mar 28 15:42:45 2019 -0700
+
+    [ci] Use only CircleCI for macOS (#1637)
+
+ .circleci/config.yml |  5 +++--
+ .travis.yml          | 18 ------------------
+ 2 files changed, 3 insertions(+), 20 deletions(-)
+
+commit 3e18447c6445f4d5e35f706f086872a21f46e9f4
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Mar 28 15:07:49 2019 -0700
+
+    fixed a fuzzer bug
+
+ src/hb-ot-var-hvar-table.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 4774283a2c8c286bc431fa1c56950ece3b57f13f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Mar 28 13:44:38 2019 -0700
+
+    Fix shell syntax error
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1612
+
+ src/check-symbols.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4b763affa640735cf5c7382e15f16dbcb88cf54e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Mar 28 11:11:52 2019 -0700
+
+    Comment
+
+ src/hb.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit d9d6649bf2de061704651eb2b7f57f4434e75c49
+Author: punchcutter <zarijoscha at gmail.com>
+Date:   Wed Mar 27 23:12:58 2019 -0700
+
+    Override USE category for Grantha and Tirhuta visargas to allow marks
+
+ src/gen-use-table.py                 | 3 ++-
+ src/hb-ot-shape-complex-use-table.cc | 4 ++--
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+commit 13ae138af3e108eb81a0df907f1232f581245091
+Author: Egor Pugin <egor.pugin at gmail.com>
+Date:   Thu Mar 28 19:06:12 2019 +0300
+
+    Disable unwanted C++ definitions for MSVC.
+    
+    MSVC does not set __cplusplus to the latest standard and also it does not like redefining some keywords.
+
+ src/hb.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 53d40426e10f14b2b4e583b7d51f23bfefbd0700
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Mar 27 08:52:46 2019 -0700
+
+    tweaked recursion checks
+
+ src/hb-ot-glyf-table.hh | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+commit dc07ecbd80814f79733ce3a2662d17bcbb54b1e9
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Mar 27 16:38:39 2019 +0430
+
+    [ci] remove ragel from psvita compile bot
+
+ .circleci/config.yml | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit dd3624b6d5186e910dd70dd6939192507324b089
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Wed Mar 27 16:21:47 2019 +0430
+
+    [ci] Don't install ragel on cmake build bot images
+    
+    It is not needed anyway
+
+ .circleci/config.yml | 5 -----
+ 1 file changed, 5 deletions(-)
+
+commit 4f351754bbb91795b373e12c2c004f59c071af1d
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Mar 26 20:35:01 2019 -0700
+
+    add recursion checks
+
+ src/hb-ot-glyf-table.hh | 24 ++++++++++++++----------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+commit 0008963b28d57f180bcd7930d63b451381f4a02f
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Mar 26 17:10:46 2019 -0700
+
+    add support of anchor point & SCALED/UNSCALED_COMPONENT_OFFSET
+    
+    some code cleanup
+
+ src/hb-ot-glyf-table.hh                            | 166 ++++++++++++++-------
+ src/hb-ot-var-gvar-table.hh                        |  38 ++++-
+ test/api/fonts/SourceSansVariable-Roman.anchor.ttf | Bin 0 -> 4708 bytes
+ test/api/test-ot-metrics-tt-var.c                  |  33 ++++
+ 4 files changed, 179 insertions(+), 58 deletions(-)
+
+commit ea281aa8d07dac2b90bf4762882a3f3d2bca8249
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Tue Mar 26 16:18:03 2019 -0700
+
+    Use class templates for Null objects
+    
+    This allows partial-instantiating custom Null object for template Lookup<T>.
+    Before, this had to be handcoded per instantiation.  Apparently I missed
+    adding one for AAT::ankr.lookupTable, so it was getting the wrong (generic)
+    null for Lookup object, which is wrong and unsafe.
+    
+    Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=944346
+
+ src/hb-aat-layout-common.hh                        |  14 ++++------
+ src/hb-null.hh                                     |  31 +++++++++++++--------
+ ...case-minimized-harfbuzz_fuzzer-5748102301614080 | Bin 0 -> 213 bytes
+ 3 files changed, 24 insertions(+), 21 deletions(-)
+
+commit 1dfc2dfff57802633d819a66708c210f76174461
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Tue Mar 26 16:17:45 2019 -0700
+
+    [aat] Add missing check to ankr table
+    
+    Isn't absolutely needed.  But helps.
+
+ src/hb-aat-layout-ankr-table.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 782961d216f53ff3237bdb6fd9544f54a1bc69a5
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Mon Mar 25 15:15:37 2019 -0700
+
+    [docs] Update
+
+ docs/harfbuzz-docs.xml | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit d4fb54508d17d1c64636f336a699ef8352d8c863
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Mon Mar 25 15:08:14 2019 -0700
+
+    Update ChangeLog generation
+    
+    Let's see if I can make a release on Mac...
+
+ Makefile.am | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 2f97cd7a525c64a98730466f195d1d3c5cd3ea50
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Mar 26 10:37:24 2019 -0700
+
+    completely remove lines that are commented out
+
+ src/hb-subset-plan.cc | 6 ------
+ src/hb-subset-plan.hh | 3 ---
+ 2 files changed, 9 deletions(-)
+
+commit e74d646d9ee3ecfda4f338a0e3bf2e0564fb1858
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Mar 26 09:15:56 2019 -0700
+
+    update arguments in_populate_gids_to_retain() and _create_old_gid_to_new_gid_map()
+    so they don't use deprecated variable
+
+ src/hb-subset-plan.cc | 36 ++++++++++++++++++------------------
+ 1 file changed, 18 insertions(+), 18 deletions(-)
+
+commit b12a5daad7cd5ec4c019c8d4827bf8456ef632c9
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Mon Mar 25 19:59:37 2019 -0700
+
+    try to remove deprecated variable from struct definition
+
+ src/hb-subset-plan.cc | 9 +++++----
+ src/hb-subset-plan.hh | 2 +-
+ 2 files changed, 6 insertions(+), 5 deletions(-)
+
+commit 9c5d694af2c6146833011498c3adcf68c0123c31
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 22 11:05:23 2019 -0700
+
+    add HVAR & VVAR advance width api test
+
+ test/api/test-ot-metrics-tt-var.c | 41 +++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 39 insertions(+), 2 deletions(-)
+
+commit ae3db1f4e3bb1c451e04b96125cb95cdfce964d4
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Mar 21 18:09:37 2019 -0700
+
+    added api test for subset VVAR & bug fix
+    
+    added a mod copy of SourceSerifVariable-Roman.ttf with VVAR as a test font
+
+ src/hb-ot-var-hvar-table.hh                        |   7 +-
+ test/api/Makefile.am                               |   2 +
+ .../fonts/SourceSerifVariable-Roman-VVAR.abc.ttf   | Bin 0 -> 5632 bytes
+ ...ourceSerifVariable-Roman-VVAR.ac.retaingids.ttf | Bin 0 -> 5288 bytes
+ .../fonts/SourceSerifVariable-Roman-VVAR.ac.ttf    | Bin 0 -> 3224 bytes
+ test/api/test-subset-vvar.c                        | 103 +++++++++++++++++++++
+ 6 files changed, 108 insertions(+), 4 deletions(-)
+
+commit b3007ec2098884721979c1105a0f1e428b95e2ca
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Mar 21 09:50:53 2019 -0700
+
+    regenerated expected full fonts data after fontTools bug 1550 fixed
+
+ ...eSerifVariable-Roman.drop-hints.D7,D8,D9,DA,DE.ttf | Bin 5928 -> 5924 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit fe5aa8b36c040b3561e33aac79006337fffda282
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Mar 20 15:10:59 2019 -0700
+
+    added TT VF full font test & fixed bugs
+    
+    updated CFF2 VF api test results too
+
+ src/hb-ot-layout-common.hh                         |  34 +++++++++++---
+ src/hb-ot-var-hvar-table.hh                        |  51 +++++++++++----------
+ test/api/fonts/AdobeVFPrototype.abc.otf            | Bin 6772 -> 6952 bytes
+ test/api/fonts/AdobeVFPrototype.ac.nohints.otf     | Bin 6096 -> 6272 bytes
+ .../fonts/AdobeVFPrototype.ac.nosubrs.nohints.otf  | Bin 6160 -> 6152 bytes
+ test/api/fonts/AdobeVFPrototype.ac.nosubrs.otf     | Bin 6376 -> 6336 bytes
+ test/api/fonts/AdobeVFPrototype.ac.otf             | Bin 6312 -> 6460 bytes
+ test/api/fonts/AdobeVFPrototype.ac.retaingids.otf  | Bin 6316 -> 6464 bytes
+ ...ifVariable-Roman.default.1FC,21,41,20,62,63.ttf | Bin 0 -> 5464 bytes
+ .../SourceSerifVariable-Roman.default.61,62,63.ttf | Bin 0 -> 5432 bytes
+ ...eSerifVariable-Roman.default.D7,D8,D9,DA,DE.ttf | Bin 0 -> 5924 bytes
+ ...ariable-Roman.drop-hints.1FC,21,41,20,62,63.ttf | Bin 0 -> 5464 bytes
+ ...urceSerifVariable-Roman.drop-hints.61,62,63.ttf | Bin 0 -> 5432 bytes
+ ...rifVariable-Roman.drop-hints.D7,D8,D9,DA,DE.ttf | Bin 0 -> 5928 bytes
+ .../data/fonts/SourceSerifVariable-Roman.ttf       | Bin 0 -> 586100 bytes
+ test/subset/data/tests/full-font.tests             |   1 +
+ 16 files changed, 56 insertions(+), 30 deletions(-)
+
+commit 2bd2e656f96111bc1261e4670851c2dc5f3acfd9
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Mar 19 18:23:14 2019 -0700
+
+    update CFF2 test results
+
+ test/api/fonts/AdobeVFPrototype.abc.otf               | Bin 7456 -> 6772 bytes
+ test/api/fonts/AdobeVFPrototype.ac.nohints.otf        | Bin 6780 -> 6096 bytes
+ .../api/fonts/AdobeVFPrototype.ac.nosubrs.nohints.otf | Bin 6844 -> 6160 bytes
+ test/api/fonts/AdobeVFPrototype.ac.nosubrs.otf        | Bin 7060 -> 6376 bytes
+ test/api/fonts/AdobeVFPrototype.ac.otf                | Bin 6996 -> 6312 bytes
+ test/api/fonts/AdobeVFPrototype.ac.retaingids.otf     | Bin 7000 -> 6316 bytes
+ 6 files changed, 0 insertions(+), 0 deletions(-)
+
+commit 212dcb758c9c43dc74da3d4507a54ac78c6bee57
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Mar 19 16:00:01 2019 -0700
+
+    add api test cases for HVAR with index map (and fix)
+
+ src/hb-ot-var-hvar-table.hh |  2 +-
+ test/api/test-subset-hvar.c | 76 +++++++++++++++++++++++++++++++++++++++++----
+ 2 files changed, 71 insertions(+), 7 deletions(-)
+
+commit dc10a7ef603b911b15596e80f12b702ecfcd60c4
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Mar 19 12:34:03 2019 -0700
+
+    add gvar & HVAR retain-gids test cases
+
+ .../SourceSansVariable-Roman.ac.retaingids.ttf     | Bin 0 -> 3040 bytes
+ test/api/test-subset-gvar.c                        |  22 ++++++++++++++++++++
+ test/api/test-subset-hvar.c                        |  23 +++++++++++++++++++++
+ 3 files changed, 45 insertions(+)
+
+commit 43420dfa964c2ee4ccc359001e5664def5371623
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Mar 19 01:00:53 2019 -0700
+
+    fix test build
+
+ test/api/Makefile.am | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 6ee71166b0003b3464d9a20554a0270f5ead5194
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Mar 19 00:41:41 2019 -0700
+
+    add api tests for subset gvar & HVAR; bug fixes
+
+ src/hb-ot-layout-common.hh                      |   3 +-
+ src/hb-ot-var-gvar-table.hh                     |  24 +++----
+ src/hb-ot-var-hvar-table.hh                     |  19 +++++-
+ test/api/Makefile.am                            |   2 +
+ test/api/fonts/SourceSansVariable-Roman.abc.ttf | Bin 0 -> 3240 bytes
+ test/api/fonts/SourceSansVariable-Roman.ac.ttf  | Bin 0 -> 3028 bytes
+ test/api/test-subset-gvar.c                     |  81 ++++++++++++++++++++++++
+ test/api/test-subset-hvar.c                     |  81 ++++++++++++++++++++++++
+ 8 files changed, 194 insertions(+), 16 deletions(-)
+
+commit 6e066464f0c1611738ff784ee7f8f3d84645e85f
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Mon Mar 18 18:11:00 2019 -0700
+
+    replaced tt var api test with a composite glyph
+    
+    for better coverage
+
+ .../SourceSansVariable-Roman-nohvar-41,C1.ttf      | Bin 0 -> 4696 bytes
+ test/api/fonts/SourceSansVariable-Roman.abc.ttf    | Bin 3168 -> 0 bytes
+ test/api/test-ot-metrics-tt-var.c                  |  36 ++++++++++-----------
+ 3 files changed, 18 insertions(+), 18 deletions(-)
+
+commit 84d0af456bb42f5a468fb5ef9edb04647e7840d8
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Mon Mar 18 17:50:20 2019 -0700
+
+    move rounding advance width to glyf
+
+ src/hb-ot-glyf-table.hh | 24 ++++++++++++++----------
+ src/hb-ot-hmtx-table.cc |  8 ++++----
+ 2 files changed, 18 insertions(+), 14 deletions(-)
+
+commit 10f264da7518ba3cc48b635d00343ecce9d734e7
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Mon Mar 18 17:16:43 2019 -0700
+
+    fix empty glyf's advance width
+
+ src/hb-ot-glyf-table.hh | 8 +++++++-
+ src/hb-ot-hmtx-table.cc | 4 ++--
+ 2 files changed, 9 insertions(+), 3 deletions(-)
+
+commit 511518c759c13ebad32e4879146c036c9af031ac
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Mon Mar 18 15:39:10 2019 -0700
+
+    add api test for tt var advance widths
+    
+    stripped HVAR from SourceSansVariable-Roman.abc.ttf so glyf gets parsed
+
+ src/hb-ot-hmtx-table.hh                         |   1 -
+ test/api/fonts/SourceSansVariable-Roman.abc.ttf | Bin 3240 -> 3168 bytes
+ test/api/test-ot-metrics-tt-var.c               |  37 ++++++++++++++++++++++++
+ 3 files changed, 37 insertions(+), 1 deletion(-)
+
+commit bee8d86671c45b093d4f238ceba9eebe4120e0bb
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Mon Mar 18 10:48:53 2019 -0700
+
+    fix build
+
+ src/hb-ot-hmtx-table.cc     | 15 ++++-----------
+ src/hb-ot-hmtx-table.hh     | 15 +++++++++------
+ src/hb-ot-var-gvar-table.hh |  1 +
+ 3 files changed, 14 insertions(+), 17 deletions(-)
+
+commit f74712a4e025375730176be7578359945bedcef0
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sun Mar 17 22:49:18 2019 -0700
+
+    fix composite glyf extents
+
+ src/hb-ot-glyf-table.hh     | 41 +++++++++++++++++++++++++++--------------
+ src/hb-ot-var-gvar-table.hh |  3 +++
+ 2 files changed, 30 insertions(+), 14 deletions(-)
+
+commit cd817e7955c45c3e56b33a304027e7fd6c6e0520
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sun Mar 17 18:45:30 2019 -0700
+
+    fix unpack_points
+
+ src/hb-ot-var-gvar-table.hh | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+commit a35e3dfc775f8a86b8a95623059f581c02cf8e00
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sun Mar 17 17:48:10 2019 -0700
+
+    fix infer_delta
+    
+    code cleanup
+
+ src/hb-ot-glyf-table.hh     | 22 ++++++++++++++--------
+ src/hb-ot-var-gvar-table.hh |  9 +++++++--
+ 2 files changed, 21 insertions(+), 10 deletions(-)
+
+commit 4f4fbb1d5e4b120336a2f8f6d23417b64888b37e
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sun Mar 17 16:01:49 2019 -0700
+
+    added explicit casts to metrics
+
+ src/hb-ot-hmtx-table.cc | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit c302ec6d945411b3023e9a633ea288aa3024366d
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sun Mar 17 15:36:26 2019 -0700
+
+    moved most of var code from gvar to glyf
+    
+    initialize phantom points from metrics from htmx/vmtx & glyf bbox before execution
+    added source file hb-ot-hmtx-table.cc to call glyf from hmtx/vmtx indirectly & temporarily, workaround a cyclic reference between the two
+
+ src/Makefile.sources        |   1 +
+ src/hb-ot-face.hh           |   1 -
+ src/hb-ot-font.cc           |   8 +-
+ src/hb-ot-glyf-table.hh     | 236 +++++++++++++++++++++++++++++++++++++-------
+ src/hb-ot-hmtx-table.cc     |  61 ++++++++++++
+ src/hb-ot-hmtx-table.hh     |  39 ++++----
+ src/hb-ot-var-gvar-table.hh | 123 ++++++++---------------
+ src/hb-ot-var-hvar-table.hh |  10 +-
+ 8 files changed, 333 insertions(+), 146 deletions(-)
+
+commit bd040a43548b30e8e7ff56cacbf35885becb6173
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sat Mar 16 16:27:33 2019 -0700
+
+    add components transformation
+
+ src/hb-ot-glyf-table.hh     | 44 ++++++++++++++++++++++++++++++++++++++++++--
+ src/hb-ot-var-gvar-table.hh | 31 ++++++++++++++++++-------------
+ 2 files changed, 60 insertions(+), 15 deletions(-)
+
+commit 139e87b56caf46a63bb78290316b3ddeb71e1e65
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sat Mar 16 00:08:03 2019 -0700
+
+    fix tt var extents & add test
+
+ src/hb-ot-glyf-table.hh                         |  32 +--
+ src/hb-ot-var-gvar-table.hh                     | 257 ++++++++++++------------
+ test/api/Makefile.am                            |   1 +
+ test/api/fonts/SourceSansVariable-Roman.abc.ttf | Bin 0 -> 3240 bytes
+ test/api/test-ot-metrics-tt-var.c               |  72 +++++++
+ 5 files changed, 223 insertions(+), 139 deletions(-)
+
+commit 9584b090bbd4286d611dda4de00f81c87f808ec7
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 15 13:46:25 2019 -0700
+
+    cff2 subset fuzzer issues (#1619)
+    
+    * add check to FDArray::serialize
+    
+    * add test files
+    
+    * fix off by one
+
+ src/hb-ot-cff-common.hh                                   |   1 +
+ ...z-testcase-minimized-hb-subset-fuzzer-5739000398086144 | Bin 0 -> 620 bytes
+ ...z-testcase-minimized-hb-subset-fuzzer-5760768497156096 | Bin 0 -> 210 bytes
+ ...z-testcase-minimized-hb-subset-fuzzer-5764268627066880 | Bin 0 -> 687 bytes
+ 4 files changed, 1 insertion(+)
+
+commit 161e61fc3beae6173253f7ec13b504dc70052cc1
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 21:49:04 2019 -0800
+
+    minor edits
+
+ src/hb-ot-layout-common.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit ebbfe36510e50fb713469437d625c5c9293154cd
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 15:14:22 2019 -0800
+
+    calculate VF advance widths from gvar & glyf
+
+ src/hb-ot-glyf-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9690461a91df3a6bb467cc111e0dfe1da20a821e
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Feb 26 11:11:50 2019 -0800
+
+    Added hb-ot-var-gvar-table.hh
+    
+    implemented sanitize()
+    placeholder subset()
+    some code cleanup
+
+ src/hb-ot-gvar-table.hh     | 211 --------------------------------------------
+ src/hb-ot-var-gvar-table.hh |  12 +--
+ 2 files changed, 6 insertions(+), 217 deletions(-)
+
+commit 9168b32a1bb4ce4efbdefbee8ea7d0b73fb84753
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Mon Feb 25 09:59:27 2019 -0800
+
+    renamed hb_map2_t to hb_bimap_h in its own .hh
+
+ src/hb-ot-gvar-table.hh    | 211 +++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-layout-common.hh |  77 -----------------
+ 2 files changed, 211 insertions(+), 77 deletions(-)
+
+commit d102c7a65258b3421f4d5628e5630e8688528743
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Feb 22 10:22:08 2019 -0800
+
+    unuse set in hb_map2_t impl
+    
+    also some code cleanup
+
+ src/hb-ot-layout-common.hh | 46 +++++++++++++++++++++++-----------------------
+ 1 file changed, 23 insertions(+), 23 deletions(-)
+
+commit dd67214210da15c6b61096cde3d60ac3a238967c
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Feb 20 15:48:29 2019 -0800
+
+    subset HVAR
+    
+    Re-implemented & repurposed CFF:remap_t as hb_map2_t (moved to hb-ot-layout-common.hh) for two-way mapping for use by index map subsetting.
+    Hooked up HVAR subsetter through _subset2.
+    Some renaming in CFF code.
+
+ src/hb-ot-layout-common.hh  | 81 +++++++++++++++++++++++++++++++++++++++++++--
+ src/hb-ot-var-hvar-table.hh |  2 +-
+ 2 files changed, 79 insertions(+), 4 deletions(-)
+
+commit 5bbe78a0f353bb806a686fd97ad411fa8a9ebf5b
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Thu Mar 14 16:49:42 2019 -0700
+
+    Allow zero length ranges in sanitization (#1617)
+    
+    Fixes fvar table sanitization where there are no named instance
+    by allowing zero length ranges starting from Null() address.
+    
+    Fixes #1607
+
+ src/hb-machinery.hh      |  30 ++++++++++++++++--------------
+ test/api/fonts/Zycon.ttf | Bin 0 -> 21036 bytes
+ test/api/test-ot-face.c  |   9 +++++++++
+ 3 files changed, 25 insertions(+), 14 deletions(-)
+
+commit ee8719eaaf4d5719053f0ba21a2b116771aa1b2f
+Author: Khaled Hosny <khaledhosny at eglug.org>
+Date:   Thu Mar 14 21:41:25 2019 +0200
+
+    [ci] Cache FreeType build on Travis
+
+ .ci/build-freetype.sh | 17 +++++++++++++++++
+ .travis.yml           | 18 ++++++++++++------
+ 2 files changed, 29 insertions(+), 6 deletions(-)
+
+commit 5d7725ad1a950bceaef184b113fd5a8b7ba3dff7
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Tue Mar 12 19:30:47 2019 -0400
+
+    Categorize U+09FC as Consonant_Placeholder
+
+ src/hb-ot-shape-complex-indic.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit b150bb4a49d9214f747c55d506975ea9b4f0a60e
+Author: Khaled Hosny <khaledhosny at eglug.org>
+Date:   Wed Mar 13 13:21:12 2019 +0200
+
+    [ci] Simplify and fix Travis CI macOS build
+
+ .travis.yml | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+commit 628d457c871954bdbf2bca2cc7b1bb821f4bd638
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Mar 12 11:03:53 2019 -0700
+
+    add gvar::get_extents
+
+ src/hb-ot-face.hh           |   1 +
+ src/hb-ot-font.cc           |   3 +
+ src/hb-ot-glyf-table.hh     |  21 ++++--
+ src/hb-ot-var-gvar-table.hh | 164 +++++++++++++++++++++++++++++++++++++++++---
+ 4 files changed, 175 insertions(+), 14 deletions(-)
+
+commit 7b27fe5255b14e7701966b1435e2bb5585b29cbc
+Author: Behdad Esfahbod <behdad at fb.com>
+Date:   Mon Mar 11 18:09:51 2019 -0700
+
+    Remove redundant hb_ot_layout_lookup_would_substitute_fast
+
+ src/hb-ot-layout.cc              | 13 -------------
+ src/hb-ot-layout.hh              |  7 -------
+ src/hb-ot-shape-complex-indic.cc |  2 +-
+ src/hb-ot-shape-complex-khmer.cc |  2 +-
+ 4 files changed, 2 insertions(+), 22 deletions(-)
+
+commit 56164f754f0302cb99fecc30298699a1216c94ab
+Author: Khaled Hosny <khaledhosny at eglug.org>
+Date:   Tue Mar 12 01:09:27 2019 +0200
+
+    [doc] Add placeholder since version for new flag
+
+ src/hb-buffer.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit cb758f2669cfd04e732788f6ca8bead67a1a5ee8
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Fri Mar 8 09:46:48 2019 -0500
+
+    Remove obsolete overrides from Indic/USE scripts
+
+ src/gen-indic-table.py               |  4 ----
+ src/gen-use-table.py                 | 30 +++++++-----------------------
+ src/hb-ot-shape-complex-use-table.cc |  2 +-
+ 3 files changed, 8 insertions(+), 28 deletions(-)
+
+commit 40c4bd3e123deb97506526d868cbc94b972b4bee
+Author: Eric Muller <emuller at amazon.com>
+Date:   Tue Feb 12 11:41:16 2019 -0800
+
+    Update generation code for hb-ot-shape-complex-vowel-constraints.cc. Remove 'unlikely'
+
+ src/gen-vowel-constraints.py                 | 3 +++
+ src/hb-ot-shape-complex-vowel-constraints.cc | 2 +-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+commit ce7f2c4da3a933444b3c331c08847a9d7d0f2ef0
+Author: Eric Muller <emuller at amazon.com>
+Date:   Sun Feb 10 04:31:41 2019 -0800
+
+    Fix coding style.
+
+ src/hb-ot-shape-complex-hangul.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit a86356913e65efff195697016de27cc8cbd2186f
+Author: Eric Muller <emuller at amazon.com>
+Date:   Sat Feb 9 02:55:27 2019 -0800
+
+    Add a flag to hb_buffer_t to prevent the insertion of dotted circles on incorrect character sequences.
+    
+    Current behavior unchanged if this flag is not set (and it isn't by default).
+
+ src/hb-buffer.h                              | 7 ++++++-
+ src/hb-ot-shape-complex-hangul.cc            | 3 ++-
+ src/hb-ot-shape-complex-indic.cc             | 3 +++
+ src/hb-ot-shape-complex-khmer.cc             | 3 +++
+ src/hb-ot-shape-complex-myanmar.cc           | 3 +++
+ src/hb-ot-shape-complex-use.cc               | 3 +++
+ src/hb-ot-shape-complex-vowel-constraints.cc | 3 +++
+ src/hb-ot-shape.cc                           | 3 +++
+ 8 files changed, 26 insertions(+), 2 deletions(-)
+
+commit 9b5556d985b6d06a2475af588cc329385b29ffa4
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Mar 8 01:33:41 2019 +0330
+
+    Add a macOS 10.14.3 fonts tests (#1608)
+
+ .circleci/config.yml                         | 11 +++++++++++
+ test/shaping/data/in-house/tests/macos.tests | 19 +++++++++++++++++++
+ 2 files changed, 30 insertions(+)
+
+commit 4a19d3b0806ed110ac5f05492ab98caabfa6306e
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Wed Mar 6 12:37:25 2019 -0500
+
+    Update to Unicode 12.0.0
+
+ src/gen-use-table.py                         |    1 -
+ src/gen-vowel-constraints.py                 |    1 +
+ src/hb-common.h                              |    8 +
+ src/hb-ot-shape-complex-arabic-table.hh      |   14 +-
+ src/hb-ot-shape-complex-indic-table.cc       |   56 +-
+ src/hb-ot-shape-complex-use-table.cc         |   49 +-
+ src/hb-ot-shape-complex-vowel-constraints.cc |    4 +-
+ src/hb-ot-shape-complex.hh                   |    3 +
+ src/hb-ot-tag-table.hh                       |   12 +-
+ src/hb-ucdn.cc                               |    4 +
+ src/hb-ucdn/ucdn.h                           |   11 +
+ src/hb-ucdn/ucdn_db.h                        | 2998 +++++++++++++-------------
+ src/hb-unicode-emoji-table.hh                |    6 +-
+ 13 files changed, 1631 insertions(+), 1536 deletions(-)
+
+commit 4f03d5c79d6fccbd63ede421daa9d270e7677964
+Author: Adrian Wong <adrianwjw at gmail.com>
+Date:   Wed Feb 13 21:04:46 2019 +1100
+
+    [indic] Remove superfluous ZWNJ check in final reorder of pre-base matras
+
+ src/hb-ot-shape-complex-indic.cc | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+commit 7b7852efa5422b2e1481addf09e6c0afa0b25830
+Author: Stephan Bergmann <sbergman at redhat.com>
+Date:   Tue Mar 5 17:18:57 2019 +0100
+
+    Fix hb_atomic_* variants based on C++11 atomics
+    
+    I stumbled over this when trying to upgrade the version of HarfBuzz used by
+    LibreOffice to 3.2.1 (see <https://gerrit.libreoffice.org/plugins/gitiles/core/
+    +/b7ddc514bff9bdf682abae537f990aa01dc2c0fb%5E!/> "Upgrade to latest
+    HarfBuzz 2.3.1"), where building with MSVC 2017 failed like
+    
+    > c:\cygwin\home\tdf\lode\jenkins\workspace\gerrit_windows\workdir\unpackedtarball\harfbuzz\src\hb-atomic.hh(272): error C2440: 'reinterpret_cast': cannot convert from 'const int *' to 'std::atomic<int> *'
+    > c:\cygwin\home\tdf\lode\jenkins\workspace\gerrit_windows\workdir\unpackedtarball\harfbuzz\src\hb-atomic.hh(272): note: Conversion loses qualifiers
+    > c:\cygwin\home\tdf\lode\jenkins\workspace\gerrit_windows\workdir\unpackedtarball\harfbuzz\src\hb-atomic.hh(272): error C2227: left of '->load' must point to class/struct/union/generic type
+    
+    (see <https://ci.libreoffice.org/job/gerrit_windows/29916/>).
+    
+    I added all the necessary "const" to make building of HarfBuzz 2.3.1 with
+    MSVC 2017 succeed for me.  There may be more missing at least conceptually.
+
+ src/hb-atomic.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 72962420465f6d4b6b140032f2b14feea0e54fb9
+Author: Martin Hosken <martin_hosken at sil.org>
+Date:   Mon Mar 4 11:12:21 2019 +0700
+
+    Fix offset drift in graphite integration
+
+ src/hb-graphite2.cc | 35 +++++++++++++++++++----------------
+ 1 file changed, 19 insertions(+), 16 deletions(-)
+
+commit 5fc99b3d341a120d22f9789d0ce112af3eaa0d83
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 21:54:49 2019 -0800
+
+    fix build
+
+ src/hb-ot-var-gvar-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 696b841a5a0c8b3d54514e76f442455c31c5107d
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 21:49:04 2019 -0800
+
+    minor edits
+
+ src/hb-ot-cff-common.hh    | 2 +-
+ src/hb-ot-layout-common.hh | 2 ++
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+commit 14be8b9e877c2f3998e28241f1c1cc9aa2d03238
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 21:33:21 2019 -0800
+
+    build fix attempt
+
+ src/hb-ot-glyf-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 618de1c7f9973c2297e4488e2d5e0698e209a87d
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 18:24:56 2019 -0800
+
+    more build fixes
+
+ src/hb-ot-glyf-table.hh     |  2 +-
+ src/hb-ot-var-gvar-table.hh | 13 ++++++-------
+ 2 files changed, 7 insertions(+), 8 deletions(-)
+
+commit f2c556594a54196ed3cce771afc6371249463068
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 18:12:31 2019 -0800
+
+    fix build attempt
+
+ src/hb-ot-var-gvar-table.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 64eb1ddc2685d830fb0f96447dbd3a2734874218
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Sat Mar 2 03:24:49 2019 +0330
+
+    Minor, remove .editorconfig hack
+    
+    As vscode is going to support it soon
+
+ .editorconfig | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+commit 40dfca72132775b8a2fc34b3b9aea0999f1e193a
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 15:14:22 2019 -0800
+
+    calculate VF advance widths from gvar & glyf
+
+ src/hb-ot-glyf-table.hh     | 151 ++++++++++++++++
+ src/hb-ot-hmtx-table.hh     |  23 ++-
+ src/hb-ot-var-gvar-table.hh | 410 +++++++++++++++++++++++++++++++++++++++-----
+ 3 files changed, 542 insertions(+), 42 deletions(-)
+
+commit d0b6d539f6b5424b8f769f800c1126a5cf5374c9
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Feb 28 17:25:05 2019 -0800
+
+    Make hb_subset_input_glyph_set () actually do something.
+
+ src/hb-subset-plan.cc       |  3 +++
+ test/api/hb-subset-test.h   | 11 ++++++++++-
+ test/api/test-subset-glyf.c | 24 ++++++++++++++++++++++++
+ 3 files changed, 37 insertions(+), 1 deletion(-)
+
+commit a842fdfbf0986c05b91efa02a5d95583e80511e9
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Feb 26 16:54:00 2019 -0800
+
+    gvar::subset()
+
+ src/hb-ot-var-gvar-table.hh | 81 +++++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 71 insertions(+), 10 deletions(-)
+
+commit c2e9d750351665324fa86d8d20eace9fe349892d
+Author: Ebrahim Byagowi <ebrahim at gnu.org>
+Date:   Fri Feb 22 13:13:42 2019 +0330
+
+    [dwrite] hb_directwrite_face_create, a new API
+    
+    It makes a hb_face_t from IDWriteFontFace, useful when using
+    DirectWrite facilities for font selection, loading and rendering
+    but using harfbuzz for shaping.
+
+ src/hb-directwrite.cc | 70 +++++++++++++++++++++++++++++++++++++++++++++++----
+ src/hb-directwrite.h  |  5 +++-
+ 2 files changed, 69 insertions(+), 6 deletions(-)
+
+commit 2c5ed7f152afe989e039de4e6d41a7e72f0de80f
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Feb 26 11:11:50 2019 -0800
+
+    Added hb-ot-var-gvar-table.hh
+    
+    implemented sanitize()
+    placeholder subset()
+    some code cleanup
+
+ src/Makefile.sources        |   1 +
+ src/hb-bimap.hh             |   6 +-
+ src/hb-ot-gvar-table.hh     | 211 --------------------------------------------
+ src/hb-ot-var-gvar-table.hh | 207 +++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-var-hvar-table.hh |  14 +--
+ src/hb-subset.cc            |   4 +
+ 6 files changed, 222 insertions(+), 221 deletions(-)
+
+commit 087b9a0ad0759f6c190597ec5ee65d998fd2b829
+Author: David Corbett <corbett.dav at husky.neu.edu>
+Date:   Mon Feb 18 22:30:40 2019 -0500
+
+    Fix or document unsupported font-feature-settings
+
+ src/hb-common.cc | 18 ++++++++++++------
+ util/options.cc  |  3 ++-
+ 2 files changed, 14 insertions(+), 7 deletions(-)
+
+commit bb29ece23ae860f923741bb09af6efcf56ac41c4
+Author: Joël R. Langlois <joel.r.langlois at gmail.com>
+Date:   Mon Feb 25 15:26:58 2019 -0500
+
+    Remove Forcing Diagnostic Colours from CMakeLists.txt (#1597)
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1596
+
+ CMakeLists.txt | 12 ------------
+ 1 file changed, 12 deletions(-)
+
+commit f1e97c189ec506ec1dfd74a413884b63dedcb682
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Mon Feb 25 09:59:27 2019 -0800
+
+    renamed hb_map2_t to hb_bimap_h in its own .hh
+
+ src/Makefile.sources        |   1 +
+ src/hb-bimap.hh             | 109 +++++++++++++++++++++++
+ src/hb-ot-cff-common.hh     |   4 +-
+ src/hb-ot-cff1-table.hh     |   4 +-
+ src/hb-ot-gvar-table.hh     | 211 ++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-layout-common.hh  |  84 +-----------------
+ src/hb-ot-var-hvar-table.hh |  12 +--
+ src/hb-subset-cff-common.cc |   2 +-
+ src/hb-subset-cff-common.hh |   4 +-
+ src/hb-subset-cff1.cc       |   8 +-
+ src/hb-subset-cff2.cc       |   2 +-
+ 11 files changed, 343 insertions(+), 98 deletions(-)
+
+commit 655bc96bc23265f85c1c3c531957ee7e4aa3bf2c
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Feb 22 14:53:06 2019 -0800
+
+    subset VVAR & outer indices
+
+ src/hb-ot-var-hvar-table.hh | 49 ++++++++++++++++++++++++++++++++++++---------
+ src/hb-subset.cc            |  3 +++
+ 2 files changed, 43 insertions(+), 9 deletions(-)
+
+commit 6ecfaaa6d5f0fd7f3ab3e1670a055b372975fffb
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Feb 22 10:22:08 2019 -0800
+
+    unuse set in hb_map2_t impl
+    
+    also some code cleanup
+
+ src/hb-ot-layout-common.hh | 46 +++++++++++++++++++++++-----------------------
+ 1 file changed, 23 insertions(+), 23 deletions(-)
+
+commit a762cf5033e4520cc01949854a772207bb27191f
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Feb 21 16:42:30 2019 -0800
+
+    fixed compiler gripes
+
+ src/hb-ot-var-hvar-table.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit a00d1d5e7454dadf70328c723111f219b0ef9a39
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Feb 21 16:34:49 2019 -0800
+
+    fix CFF2 local subr subsetting
+    
+    bug exposed by impl change of fdmap
+    also fixed name of subr_remap_ts as subr_remaps_t
+
+ src/hb-subset-cff-common.hh |  8 ++++----
+ src/hb-subset-cff2.cc       | 20 +++++++++-----------
+ 2 files changed, 13 insertions(+), 15 deletions(-)
+
+commit 8bd9d28e2a4d21aa939918626121e90e37d1e61f
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Feb 21 15:47:27 2019 -0800
+
+    fix HVAR & VarStore subsetting
+
+ src/hb-ot-layout-common.hh  |  15 +++--
+ src/hb-ot-var-hvar-table.hh | 140 ++++++++++++++++++++++----------------------
+ 2 files changed, 77 insertions(+), 78 deletions(-)
+
 commit 4fd02f6ee58ebf7b4ecf0526328938c5bd74a180
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Fri Mar 29 17:57:59 2019 -0700
@@ -13990,6 +23742,30 @@
  src/test-iter.cc | 2 --
  2 files changed, 10 deletions(-)
 
+commit d30e5e74814c6db23fdedbe75fd9b89c0dfb4dce
+Merge: ddb84dce a252392b
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 29 10:32:45 2019 -0700
+
+    Merge branch 'var-subset' of https://github.com/harfbuzz/harfbuzz into var-subset
+
+commit ddb84dcece8a12a5615cb1609030a52387bd2fce
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 29 10:32:42 2019 -0700
+
+    fix gvar fuzz bug
+
+ .gitignore                  | 1 +
+ src/hb-ot-var-gvar-table.hh | 8 +++++++-
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+commit a252392bc05e8e9e4127e0002b10fe514323730f
+Merge: 58c8c7a4 d6fc1d49
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 29 08:43:47 2019 -0700
+
+    Merge branch 'master' into var-subset
+
 commit bdd5a9c48d644b660f8fcac16902a576cc7ff443
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Thu Mar 28 21:58:07 2019 -0700
@@ -14094,6 +23870,22 @@
  .circleci/config.yml | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)
 
+commit 58c8c7a495fcc353d09158fc23a45f35b2dab2dc
+Merge: 485fe06f a548d1da
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Mar 28 16:17:41 2019 -0700
+
+    Merge branch 'master' into var-subset
+
+commit 485fe06f74d7dce41480d7d6f0dbe0129a7b2a39
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Mar 28 16:17:36 2019 -0700
+
+    minor
+
+ src/hb-ot-var-hvar-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
 commit a548d1da78b506cc6460fdde3715f6ef13ccad48
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
 Date:   Thu Mar 28 15:42:45 2019 -0700
@@ -14104,6 +23896,22 @@
  .travis.yml          | 18 ------------------
  2 files changed, 3 insertions(+), 20 deletions(-)
 
+commit 5f36771c2ab612b403e55504b7901b0390b1b76d
+Merge: 99f0c107 061bd0a9
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Mar 28 15:07:53 2019 -0700
+
+    Merge branch 'var-subset' of https://github.com/harfbuzz/harfbuzz into var-subset
+
+commit 99f0c107f7e1083d3b8ad8354876770f69fddf52
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Mar 28 15:07:49 2019 -0700
+
+    fixed a fuzzer bug
+
+ src/hb-ot-var-hvar-table.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
 commit 160b4a2b01e925812fbf0e7db5bc9dcb90dc81cc
 Author: Behdad Esfahbod <behdad at behdad.org>
 Date:   Thu Mar 28 13:44:38 2019 -0700
@@ -14145,6 +23953,29 @@
  src/hb.hh | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
+commit 061bd0a99b0724953fcbdaaef4ea91a54cd7d3ce
+Merge: d8e3e360 67175987
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Mar 27 08:53:50 2019 -0700
+
+    Merge branch 'var-subset' of https://github.com/harfbuzz/harfbuzz into var-subset
+
+commit d8e3e3607e6435b994a3e2f4285c5b4d17c5dfa4
+Merge: bcd689bb 717181c5
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Mar 27 08:53:48 2019 -0700
+
+    Merge branch 'master' into var-subset
+
+commit 67175987bd6c90ca2e79e8d604a73e6052e82823
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Mar 27 08:52:46 2019 -0700
+
+    tweaked recursion checks
+
+ src/hb-ot-glyf-table.hh | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
 commit 717181c5943c13a682c719dce10bfc3d9cc47e6b
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
 Date:   Wed Mar 27 16:38:39 2019 +0430
@@ -14165,6 +23996,36 @@
  .circleci/config.yml | 5 -----
  1 file changed, 5 deletions(-)
 
+commit feb712d8d80c48e08f3f715a41400e4ef19b80de
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Mar 26 20:35:01 2019 -0700
+
+    add recursion checks
+
+ src/hb-ot-glyf-table.hh | 24 ++++++++++++++----------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+commit bcd689bb1090a1bf5113e67edfce583832bb2187
+Merge: 49f93596 ec2a5dc8
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Mar 26 17:13:31 2019 -0700
+
+    Merge branch 'master' into var-subset
+
+commit 49f9359632c78754b6e1eb32f2505b340cde55c8
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Mar 26 17:10:46 2019 -0700
+
+    add support of anchor point & SCALED/UNSCALED_COMPONENT_OFFSET
+    
+    some code cleanup
+
+ src/hb-ot-glyf-table.hh                            | 166 ++++++++++++++-------
+ src/hb-ot-var-gvar-table.hh                        |  38 ++++-
+ test/api/fonts/SourceSansVariable-Roman.anchor.ttf | Bin 0 -> 4708 bytes
+ test/api/test-ot-metrics-tt-var.c                  |  33 ++++
+ 4 files changed, 179 insertions(+), 58 deletions(-)
+
 commit ec2a5dc859b03ceb92518aa992e4e9c053b30534
 Author: Behdad Esfahbod <behdad at fb.com>
 Date:   Tue Mar 26 16:18:03 2019 -0700
@@ -14244,6 +24105,313 @@
  src/hb-subset-plan.hh | 2 +-
  2 files changed, 6 insertions(+), 5 deletions(-)
 
+commit 94ef1a703ff20614538680587a23cec5f1649189
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 22 11:05:23 2019 -0700
+
+    add HVAR & VVAR advance width api test
+
+ test/api/test-ot-metrics-tt-var.c | 41 +++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 39 insertions(+), 2 deletions(-)
+
+commit 3c4f041e9e8adc5d906a7bd37dc86345c2bf91e8
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 22 10:26:48 2019 -0700
+
+    fix uninitialized memory bug
+
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit d2a0149c2999eab315a0582a5e1fa31a2511b869
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Mar 21 18:09:37 2019 -0700
+
+    added api test for subset VVAR & bug fix
+    
+    added a mod copy of SourceSerifVariable-Roman.ttf with VVAR as a test font
+
+ src/hb-ot-var-hvar-table.hh                        |   7 +-
+ test/api/Makefile.am                               |   2 +
+ .../fonts/SourceSerifVariable-Roman-VVAR.abc.ttf   | Bin 0 -> 5632 bytes
+ ...ourceSerifVariable-Roman-VVAR.ac.retaingids.ttf | Bin 0 -> 5288 bytes
+ .../fonts/SourceSerifVariable-Roman-VVAR.ac.ttf    | Bin 0 -> 3224 bytes
+ test/api/test-subset-vvar.c                        | 103 +++++++++++++++++++++
+ 6 files changed, 108 insertions(+), 4 deletions(-)
+
+commit 8ec279072e039c7a75ea90e2284d46bd9faee8ee
+Merge: 0593a95e 5390e393
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Mar 21 10:38:12 2019 -0700
+
+    Merge branch 'var-subset' of https://github.com/harfbuzz/harfbuzz into var-subset
+
+commit 0593a95e28e08a130c87f23c527156ac1d46219b
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Mar 21 10:36:53 2019 -0700
+
+    refix short count
+
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5390e39342e78566095b580603bd1f76cdafc010
+Merge: 084be9a0 5f15fca6
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Mar 21 10:21:50 2019 -0700
+
+    Merge branch 'var-subset' of https://github.com/harfbuzz/harfbuzz into var-subset
+
+commit 084be9a0f466134998da79e9a81191836f847ab8
+Merge: 3faaa52a bcb4e505
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Mar 21 10:21:31 2019 -0700
+
+    Merge branch 'master' into var-subset
+
+commit 5f15fca66206af36cafc9a7b650462b544460d6e
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Mar 21 10:18:03 2019 -0700
+
+    fix short count optimization
+
+ src/hb-ot-layout-common.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 3faaa52aa7e4c72d94657702047e2d3dddbb3292
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Mar 21 09:50:53 2019 -0700
+
+    regenerated expected full fonts data after fontTools bug 1550 fixed
+
+ ...eSerifVariable-Roman.drop-hints.D7,D8,D9,DA,DE.ttf | Bin 5928 -> 5924 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 325918172e7a346b6de6a8afcd94a4d7fd35d5c0
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Mar 20 15:10:59 2019 -0700
+
+    added TT VF full font test & fixed bugs
+    
+    updated CFF2 VF api test results too
+
+ src/hb-ot-layout-common.hh                         |  53 +++++++++++++++++----
+ src/hb-ot-var-hvar-table.hh                        |  51 +++++++++++---------
+ test/api/fonts/AdobeVFPrototype.abc.otf            | Bin 6772 -> 6952 bytes
+ test/api/fonts/AdobeVFPrototype.ac.nohints.otf     | Bin 6096 -> 6272 bytes
+ .../fonts/AdobeVFPrototype.ac.nosubrs.nohints.otf  | Bin 6160 -> 6152 bytes
+ test/api/fonts/AdobeVFPrototype.ac.nosubrs.otf     | Bin 6376 -> 6336 bytes
+ test/api/fonts/AdobeVFPrototype.ac.otf             | Bin 6312 -> 6460 bytes
+ test/api/fonts/AdobeVFPrototype.ac.retaingids.otf  | Bin 6316 -> 6464 bytes
+ ...ifVariable-Roman.default.1FC,21,41,20,62,63.ttf | Bin 0 -> 5464 bytes
+ .../SourceSerifVariable-Roman.default.61,62,63.ttf | Bin 0 -> 5432 bytes
+ ...eSerifVariable-Roman.default.D7,D8,D9,DA,DE.ttf | Bin 0 -> 5924 bytes
+ ...ariable-Roman.drop-hints.1FC,21,41,20,62,63.ttf | Bin 0 -> 5464 bytes
+ ...urceSerifVariable-Roman.drop-hints.61,62,63.ttf | Bin 0 -> 5432 bytes
+ ...rifVariable-Roman.drop-hints.D7,D8,D9,DA,DE.ttf | Bin 0 -> 5928 bytes
+ .../data/fonts/SourceSerifVariable-Roman.ttf       | Bin 0 -> 586100 bytes
+ test/subset/data/tests/full-font.tests             |   1 +
+ 16 files changed, 72 insertions(+), 33 deletions(-)
+
+commit 92bc74055831acae3d296f6e1470fa4cd4d193fd
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Mar 19 18:23:14 2019 -0700
+
+    update CFF2 test results
+
+ test/api/fonts/AdobeVFPrototype.abc.otf               | Bin 7456 -> 6772 bytes
+ test/api/fonts/AdobeVFPrototype.ac.nohints.otf        | Bin 6780 -> 6096 bytes
+ .../api/fonts/AdobeVFPrototype.ac.nosubrs.nohints.otf | Bin 6844 -> 6160 bytes
+ test/api/fonts/AdobeVFPrototype.ac.nosubrs.otf        | Bin 7060 -> 6376 bytes
+ test/api/fonts/AdobeVFPrototype.ac.otf                | Bin 6996 -> 6312 bytes
+ test/api/fonts/AdobeVFPrototype.ac.retaingids.otf     | Bin 7000 -> 6316 bytes
+ 6 files changed, 0 insertions(+), 0 deletions(-)
+
+commit 1051faf7aa639abc27974da213eb48f549f8c39c
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Mar 19 16:00:01 2019 -0700
+
+    add api test cases for HVAR with index map (and fix)
+
+ src/hb-ot-var-hvar-table.hh |  2 +-
+ test/api/test-subset-hvar.c | 76 +++++++++++++++++++++++++++++++++++++++++----
+ 2 files changed, 71 insertions(+), 7 deletions(-)
+
+commit 0576253a340243eb8e4feabb3481f354a82a11a1
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Mar 19 12:34:03 2019 -0700
+
+    add gvar & HVAR retain-gids test cases
+
+ .../SourceSansVariable-Roman.ac.retaingids.ttf     | Bin 0 -> 3040 bytes
+ test/api/test-subset-gvar.c                        |  22 ++++++++++++++++++++
+ test/api/test-subset-hvar.c                        |  23 +++++++++++++++++++++
+ 3 files changed, 45 insertions(+)
+
+commit 6dd1077b68e20e97b595c676267b964dd5cbbe1c
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Mar 19 01:00:53 2019 -0700
+
+    fix test build
+
+ test/api/Makefile.am | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 2e6038a209022c8b7957daf661488edfc166bdc5
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Mar 19 00:41:41 2019 -0700
+
+    add api tests for subset gvar & HVAR; bug fixes
+
+ src/hb-ot-layout-common.hh                      |   3 +-
+ src/hb-ot-var-gvar-table.hh                     |  24 +++----
+ src/hb-ot-var-hvar-table.hh                     |  19 +++++-
+ test/api/Makefile.am                            |   2 +
+ test/api/fonts/SourceSansVariable-Roman.abc.ttf | Bin 0 -> 3240 bytes
+ test/api/fonts/SourceSansVariable-Roman.ac.ttf  | Bin 0 -> 3028 bytes
+ test/api/test-subset-gvar.c                     |  81 ++++++++++++++++++++++++
+ test/api/test-subset-hvar.c                     |  81 ++++++++++++++++++++++++
+ 8 files changed, 194 insertions(+), 16 deletions(-)
+
+commit aeddb30f87ea957e7e780705c099e849c6d7e27d
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Mon Mar 18 18:11:00 2019 -0700
+
+    replaced tt var api test with a composite glyph
+    
+    for better coverage
+
+ .../SourceSansVariable-Roman-nohvar-41,C1.ttf      | Bin 0 -> 4696 bytes
+ test/api/fonts/SourceSansVariable-Roman.abc.ttf    | Bin 3168 -> 0 bytes
+ test/api/test-ot-metrics-tt-var.c                  |  36 ++++++++++-----------
+ 3 files changed, 18 insertions(+), 18 deletions(-)
+
+commit 560bcd774473691b310e746d2e7c0287c2bea9fe
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Mon Mar 18 17:50:20 2019 -0700
+
+    move rounding advance width to glyf
+
+ src/hb-ot-glyf-table.hh | 24 ++++++++++++++----------
+ src/hb-ot-hmtx-table.cc |  8 ++++----
+ 2 files changed, 18 insertions(+), 14 deletions(-)
+
+commit c7edd14dc96af59cb53e9560a45f48d809fe8bb1
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Mon Mar 18 17:16:43 2019 -0700
+
+    fix empty glyf's advance width
+
+ src/hb-ot-glyf-table.hh | 8 +++++++-
+ src/hb-ot-hmtx-table.cc | 4 ++--
+ 2 files changed, 9 insertions(+), 3 deletions(-)
+
+commit 9d3a252030e8f86aff4a35ce56fe77eb718e2071
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Mon Mar 18 15:39:10 2019 -0700
+
+    add api test for tt var advance widths
+    
+    stripped HVAR from SourceSansVariable-Roman.abc.ttf so glyf gets parsed
+
+ src/hb-ot-hmtx-table.hh                         |   1 -
+ test/api/fonts/SourceSansVariable-Roman.abc.ttf | Bin 3240 -> 3168 bytes
+ test/api/test-ot-metrics-tt-var.c               |  37 ++++++++++++++++++++++++
+ 3 files changed, 37 insertions(+), 1 deletion(-)
+
+commit 9d9d5c706b68a16b2d07f8b8972b2b499c94bf0a
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Mon Mar 18 10:48:53 2019 -0700
+
+    fix build
+
+ src/hb-ot-hmtx-table.cc     | 15 ++++-----------
+ src/hb-ot-hmtx-table.hh     | 15 +++++++++------
+ src/hb-ot-var-gvar-table.hh |  1 +
+ 3 files changed, 14 insertions(+), 17 deletions(-)
+
+commit b6cc838888cc302f0de19030b75773fe0fda372f
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sun Mar 17 22:49:18 2019 -0700
+
+    fix composite glyf extents
+
+ src/hb-ot-glyf-table.hh     | 41 +++++++++++++++++++++++++++--------------
+ src/hb-ot-var-gvar-table.hh |  3 +++
+ 2 files changed, 30 insertions(+), 14 deletions(-)
+
+commit 597ad4df0cdff4a0355121e3da2a59e7fa8ee68f
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sun Mar 17 18:45:30 2019 -0700
+
+    fix unpack_points
+
+ src/hb-ot-var-gvar-table.hh | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+commit cabe22fc6967e6299c3a06bbfa9c19e9a23a0ae3
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sun Mar 17 17:48:10 2019 -0700
+
+    fix infer_delta
+    
+    code cleanup
+
+ src/hb-ot-glyf-table.hh     | 22 ++++++++++++-------
+ src/hb-ot-var-gvar-table.hh | 52 ++++++++++++++++++++++++++++++---------------
+ 2 files changed, 49 insertions(+), 25 deletions(-)
+
+commit c8b31773a6513e7051e5db98d7d26700856a32a3
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sun Mar 17 16:01:49 2019 -0700
+
+    added explicit casts to metrics
+
+ src/hb-ot-hmtx-table.cc | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 8a7998fd6ce730dd0f182d69d598b802476250dc
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sun Mar 17 15:36:26 2019 -0700
+
+    moved most of var code from gvar to glyf
+    
+    initialize phantom points from metrics from htmx/vmtx & glyf bbox before execution
+    added source file hb-ot-hmtx-table.cc to call glyf from hmtx/vmtx indirectly & temporarily, workaround a cyclic reference between the two
+
+ src/Makefile.sources        |   1 +
+ src/hb-ot-face.hh           |   1 -
+ src/hb-ot-font.cc           |   8 +-
+ src/hb-ot-glyf-table.hh     | 236 +++++++++++++++++++++++++++++++++++++-------
+ src/hb-ot-hmtx-table.cc     |  61 ++++++++++++
+ src/hb-ot-hmtx-table.hh     |  39 ++++----
+ src/hb-ot-var-gvar-table.hh | 195 ++++++++----------------------------
+ src/hb-ot-var-hvar-table.hh |  10 +-
+ 8 files changed, 333 insertions(+), 218 deletions(-)
+
+commit 00b2653ac3b927f93ac350dbe1d3711790a50119
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sat Mar 16 16:27:33 2019 -0700
+
+    add components transformation
+
+ src/hb-ot-glyf-table.hh     | 44 ++++++++++++++++++++++++++++++++++++++++++--
+ src/hb-ot-var-gvar-table.hh | 31 ++++++++++++++++++-------------
+ 2 files changed, 60 insertions(+), 15 deletions(-)
+
+commit 434ea06841e60b98601b529ca20cf6bf25f6c165
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Sat Mar 16 00:08:03 2019 -0700
+
+    fix tt var extents & add test
+
+ src/hb-ot-glyf-table.hh                         |  32 +--
+ src/hb-ot-var-gvar-table.hh                     | 270 +++++++++++++-----------
+ test/api/Makefile.am                            |   1 +
+ test/api/fonts/SourceSansVariable-Roman.abc.ttf | Bin 0 -> 3240 bytes
+ test/api/test-ot-metrics-tt-var.c               |  72 +++++++
+ 5 files changed, 236 insertions(+), 139 deletions(-)
+
 commit bcb4e505d6ffe33e3268a06698e75d6be0e64957
 Author: Michiharu Ariza <ariza at adobe.com>
 Date:   Fri Mar 15 13:46:25 2019 -0700
@@ -14262,6 +24430,217 @@
  ...z-testcase-minimized-hb-subset-fuzzer-5764268627066880 | Bin 0 -> 687 bytes
  4 files changed, 1 insertion(+)
 
+commit a5118c1db51d6d3b24622a52e50246e00b07fa74
+Merge: 90ea140a 079c386c
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 15 10:33:03 2019 -0700
+
+    Merge branch 'var-subset' of https://github.com/harfbuzz/harfbuzz into var-subset
+
+commit 079c386ca89b6d2833786db3ba54b7137d045188
+Merge: 99502b32 8aaab78e
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 15 10:12:19 2019 -0700
+
+    Merge branch 'master' into var-subset
+
+commit 90ea140aca18d073401fc971681ce48403fbf399
+Merge: d23c201f 99502b32
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Mar 14 16:58:19 2019 -0700
+
+    Merge branch 'var-subset' of https://github.com/harfbuzz/harfbuzz into var-subset
+
+commit d23c201f5d8af8f9b38c666e1ba6525d38ef0806
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Mar 12 11:03:53 2019 -0700
+
+    add gvar::get_extents
+
+ src/hb-ot-face.hh           |   1 +
+ src/hb-ot-font.cc           |   3 +
+ src/hb-ot-glyf-table.hh     |  21 ++++--
+ src/hb-ot-var-gvar-table.hh | 164 +++++++++++++++++++++++++++++++++++++++++---
+ 4 files changed, 175 insertions(+), 14 deletions(-)
+
+commit dde8bb1f6d0bfaac283fd8c2ad15e354c233bac1
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 21:54:49 2019 -0800
+
+    fix build
+
+ src/hb-ot-var-gvar-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 5ec65f779bef1ebf2479f83f4b76f4e24d69ddad
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 21:49:04 2019 -0800
+
+    minor edits
+
+ src/hb-ot-cff-common.hh    | 2 +-
+ src/hb-ot-layout-common.hh | 2 ++
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+commit 2d7ad3f28ba3a9c97287eb9e1bf75ad353a908c6
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 21:33:21 2019 -0800
+
+    build fix attempt
+
+ src/hb-ot-glyf-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit cf2ef92c741a20158d15d7ea7c14f6ba82906d36
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 18:24:56 2019 -0800
+
+    more build fixes
+
+ src/hb-ot-glyf-table.hh     |  2 +-
+ src/hb-ot-var-gvar-table.hh | 13 ++++++-------
+ 2 files changed, 7 insertions(+), 8 deletions(-)
+
+commit ae0a557c2e56064d204ae549a3be135dca884f67
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 18:12:31 2019 -0800
+
+    fix build attempt
+
+ src/hb-ot-var-gvar-table.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit baf2ccf1471856f948ed8d2d46e4d68b0c0b739a
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 15:14:22 2019 -0800
+
+    calculate VF advance widths from gvar & glyf
+
+ src/hb-ot-glyf-table.hh     | 151 ++++++++++++++++
+ src/hb-ot-hmtx-table.hh     |  23 ++-
+ src/hb-ot-var-gvar-table.hh | 410 +++++++++++++++++++++++++++++++++++++++-----
+ 3 files changed, 542 insertions(+), 42 deletions(-)
+
+commit 0b1ae2385b5564efe3dbcd5d068462bcd55effe2
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Feb 26 16:54:00 2019 -0800
+
+    gvar::subset()
+
+ src/hb-ot-var-gvar-table.hh | 81 +++++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 71 insertions(+), 10 deletions(-)
+
+commit eddbc9d0dbb09589a09e7d8e661004cdd7487e87
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Feb 26 11:11:50 2019 -0800
+
+    Added hb-ot-var-gvar-table.hh
+    
+    implemented sanitize()
+    placeholder subset()
+    some code cleanup
+
+ src/Makefile.sources        |   1 +
+ src/hb-bimap.hh             |   6 +-
+ src/hb-ot-gvar-table.hh     | 211 --------------------------------------------
+ src/hb-ot-var-gvar-table.hh | 207 +++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-var-hvar-table.hh |  14 +--
+ src/hb-subset.cc            |   4 +
+ 6 files changed, 222 insertions(+), 221 deletions(-)
+
+commit f289ffe5eaf1c8cc87f9ee80f77a4af974919611
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Mon Feb 25 09:59:27 2019 -0800
+
+    renamed hb_map2_t to hb_bimap_h in its own .hh
+
+ src/Makefile.sources        |   1 +
+ src/hb-bimap.hh             | 109 +++++++++++++++++++++++
+ src/hb-ot-cff-common.hh     |   4 +-
+ src/hb-ot-cff1-table.hh     |   4 +-
+ src/hb-ot-gvar-table.hh     | 211 ++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-layout-common.hh  |  84 +-----------------
+ src/hb-ot-var-hvar-table.hh |  12 +--
+ src/hb-subset-cff-common.cc |   2 +-
+ src/hb-subset-cff-common.hh |   4 +-
+ src/hb-subset-cff1.cc       |   8 +-
+ src/hb-subset-cff2.cc       |   2 +-
+ 11 files changed, 343 insertions(+), 98 deletions(-)
+
+commit 8563169291bf257400608aa0900fc3ee8c2f9e8b
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Feb 22 14:53:06 2019 -0800
+
+    subset VVAR & outer indices
+
+ src/hb-ot-var-hvar-table.hh | 49 ++++++++++++++++++++++++++++++++++++---------
+ src/hb-subset.cc            |  3 +++
+ 2 files changed, 43 insertions(+), 9 deletions(-)
+
+commit 08dc86594bb17e31df2d5c0e25521ee1f072871b
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Feb 22 10:22:08 2019 -0800
+
+    unuse set in hb_map2_t impl
+    
+    also some code cleanup
+
+ src/hb-ot-layout-common.hh | 46 +++++++++++++++++++++++-----------------------
+ 1 file changed, 23 insertions(+), 23 deletions(-)
+
+commit 1b13cc775c3b8143b1218e205b21b91b0852f8bd
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Feb 21 16:42:30 2019 -0800
+
+    fixed compiler gripes
+
+ src/hb-ot-var-hvar-table.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit c485b77c7c1df2fcd2f21107692d1afd0ed34e1f
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Feb 21 16:34:49 2019 -0800
+
+    fix CFF2 local subr subsetting
+    
+    bug exposed by impl change of fdmap
+    also fixed name of subr_remap_ts as subr_remaps_t
+
+ src/hb-subset-cff-common.hh |  8 ++++----
+ src/hb-subset-cff2.cc       | 20 +++++++++-----------
+ 2 files changed, 13 insertions(+), 15 deletions(-)
+
+commit c9b07c75a14b6efb4b32cb12b2f3e8cfc1953638
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Feb 21 15:47:27 2019 -0800
+
+    fix HVAR & VarStore subsetting
+
+ src/hb-ot-layout-common.hh  |  15 +++--
+ src/hb-ot-var-hvar-table.hh | 140 ++++++++++++++++++++++----------------------
+ 2 files changed, 77 insertions(+), 78 deletions(-)
+
+commit c8420109ccb74a7bf15c4af425f9f58bc315d2ce
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Feb 20 15:48:29 2019 -0800
+
+    subset HVAR
+    
+    Re-implemented & repurposed CFF:remap_t as hb_map2_t (moved to hb-ot-layout-common.hh) for two-way mapping for use by index map subsetting.
+    Hooked up HVAR subsetter through _subset2.
+    Some renaming in CFF code.
+
+ src/hb-ot-cff-common.hh     |  63 ++----------
+ src/hb-ot-cff1-table.hh     |   8 +-
+ src/hb-ot-layout-common.hh  | 158 ++++++++++++++++++++++++++++--
+ src/hb-ot-var-hvar-table.hh | 232 +++++++++++++++++++++++++++++++++++++++++++-
+ src/hb-subset-cff-common.cc |   9 +-
+ src/hb-subset-cff-common.hh |  27 ++----
+ src/hb-subset-cff1.cc       |  29 +++---
+ src/hb-subset-cff2.cc       |  12 +--
+ src/hb-subset.cc            |   4 +
+ 9 files changed, 426 insertions(+), 116 deletions(-)
+
 commit 8aaab78efcac81a05ec919be13792c98741ea1b5
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
 Date:   Thu Mar 14 16:49:42 2019 -0700
@@ -14306,6 +24685,25 @@
  .travis.yml | 16 +++++++++-------
  1 file changed, 9 insertions(+), 7 deletions(-)
 
+commit 99502b324dd6cb45d401bc5f6cc08d7a77677ba5
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Mar 12 11:03:53 2019 -0700
+
+    add gvar::get_extents
+
+ src/hb-ot-face.hh           |   1 +
+ src/hb-ot-font.cc           |   3 +
+ src/hb-ot-glyf-table.hh     |  21 ++++--
+ src/hb-ot-var-gvar-table.hh | 164 +++++++++++++++++++++++++++++++++++++++++---
+ 4 files changed, 175 insertions(+), 14 deletions(-)
+
+commit 23e2d5ac86968c7548df0d212c1a321d09328ffa
+Merge: f5a46638 e52ec3fc
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Mar 12 10:53:15 2019 -0700
+
+    Merge branch 'master' into var-subset
+
 commit e52ec3fc23c2d5a881849f047885e0423bd74740
 Author: Behdad Esfahbod <behdad at fb.com>
 Date:   Mon Mar 11 18:09:51 2019 -0700
@@ -14447,6 +24845,60 @@
  src/hb-graphite2.cc | 35 +++++++++++++++++++----------------
  1 file changed, 19 insertions(+), 16 deletions(-)
 
+commit f5a466389382183cbc009b66734e0fa339f168ff
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 21:54:49 2019 -0800
+
+    fix build
+
+ src/hb-ot-var-gvar-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 2e1965e572f5643c56e5a0c11a8bf7d5cf68a483
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 21:49:04 2019 -0800
+
+    minor edits
+
+ src/hb-ot-cff-common.hh    | 2 +-
+ src/hb-ot-layout-common.hh | 2 ++
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+commit ff60f34dd6b57401c8904a8808c1775ee09f4458
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 21:33:21 2019 -0800
+
+    build fix attempt
+
+ src/hb-ot-glyf-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9aa5805a44e883c3dcb09a43e952b8bf40016423
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 18:24:56 2019 -0800
+
+    more build fixes
+
+ src/hb-ot-glyf-table.hh     |  2 +-
+ src/hb-ot-var-gvar-table.hh | 13 ++++++-------
+ 2 files changed, 7 insertions(+), 8 deletions(-)
+
+commit 3f3da718632e9beef9a1d9cf8b5775025ffe3fd6
+Merge: 21aaf300 f448195a
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 18:12:35 2019 -0800
+
+    Merge branch 'var-subset' of https://github.com/harfbuzz/harfbuzz into var-subset
+
+commit 21aaf30058823e06c121908734b05c6c7f0bdeec
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 18:12:31 2019 -0800
+
+    fix build attempt
+
+ src/hb-ot-var-gvar-table.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
 commit 8a25868e6a41a3d82782aadb3c7b744ad87d20ff
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
 Date:   Sat Mar 2 03:24:49 2019 +0330
@@ -14458,6 +24910,24 @@
  .editorconfig | 7 ++-----
  1 file changed, 2 insertions(+), 5 deletions(-)
 
+commit f448195a4b041db83b0e515c829b99d2349bf73f
+Merge: fa2b3d30 4f37ab63
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 15:22:17 2019 -0800
+
+    Merge branch 'master' into var-subset
+
+commit fa2b3d30f6562a7457acca205f1bf544089c88ba
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Mar 1 15:14:22 2019 -0800
+
+    calculate VF advance widths from gvar & glyf
+
+ src/hb-ot-glyf-table.hh     | 151 ++++++++++++++++
+ src/hb-ot-hmtx-table.hh     |  23 ++-
+ src/hb-ot-var-gvar-table.hh | 410 +++++++++++++++++++++++++++++++++++++++-----
+ 3 files changed, 542 insertions(+), 42 deletions(-)
+
 commit 4f37ab63de9705d7bf74ee75364747e41b7c06a1
 Author: Garret Rieger <grieger at google.com>
 Date:   Thu Feb 28 17:25:05 2019 -0800
@@ -14469,6 +24939,15 @@
  test/api/test-subset-glyf.c | 24 ++++++++++++++++++++++++
  3 files changed, 37 insertions(+), 1 deletion(-)
 
+commit 33354ab6b87211ae2e702bee162fa4260078e70a
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Feb 26 16:54:00 2019 -0800
+
+    gvar::subset()
+
+ src/hb-ot-var-gvar-table.hh | 81 +++++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 71 insertions(+), 10 deletions(-)
+
 commit 45149eb34f9735b5d690a2a7956adb42b938c8d9
 Author: Ebrahim Byagowi <ebrahim at gnu.org>
 Date:   Fri Feb 22 13:13:42 2019 +0330
@@ -14483,6 +24962,24 @@
  src/hb-directwrite.h  |  5 +++-
  2 files changed, 69 insertions(+), 6 deletions(-)
 
+commit 6f91e0d903d7510a4612a9cc7306ec04260cefed
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Tue Feb 26 11:11:50 2019 -0800
+
+    Added hb-ot-var-gvar-table.hh
+    
+    implemented sanitize()
+    placeholder subset()
+    some code cleanup
+
+ src/Makefile.sources        |   1 +
+ src/hb-bimap.hh             |   6 +-
+ src/hb-ot-gvar-table.hh     | 211 --------------------------------------------
+ src/hb-ot-var-gvar-table.hh | 207 +++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-var-hvar-table.hh |  14 +--
+ src/hb-subset.cc            |   4 +
+ 6 files changed, 222 insertions(+), 221 deletions(-)
+
 commit 45adc185260f0fa1fa86472aafb7f91f942c567e
 Author: David Corbett <corbett.dav at husky.neu.edu>
 Date:   Mon Feb 18 22:30:40 2019 -0500
@@ -14504,6 +25001,99 @@
  CMakeLists.txt | 12 ------------
  1 file changed, 12 deletions(-)
 
+commit d817b446a132816e48e9ce4e3619a52a340ab35a
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Mon Feb 25 09:59:27 2019 -0800
+
+    renamed hb_map2_t to hb_bimap_h in its own .hh
+
+ src/Makefile.sources        |   1 +
+ src/hb-bimap.hh             | 109 +++++++++++++++++++++++
+ src/hb-ot-cff-common.hh     |   4 +-
+ src/hb-ot-cff1-table.hh     |   4 +-
+ src/hb-ot-gvar-table.hh     | 211 ++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-layout-common.hh  |  84 +-----------------
+ src/hb-ot-var-hvar-table.hh |  12 +--
+ src/hb-subset-cff-common.cc |   2 +-
+ src/hb-subset-cff-common.hh |   4 +-
+ src/hb-subset-cff1.cc       |   8 +-
+ src/hb-subset-cff2.cc       |   2 +-
+ 11 files changed, 343 insertions(+), 98 deletions(-)
+
+commit 5d781f62ba4df4f322b01ded5008d1c936acd585
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Feb 22 14:53:06 2019 -0800
+
+    subset VVAR & outer indices
+
+ src/hb-ot-var-hvar-table.hh | 49 ++++++++++++++++++++++++++++++++++++---------
+ src/hb-subset.cc            |  3 +++
+ 2 files changed, 43 insertions(+), 9 deletions(-)
+
+commit 2d545e1e86d94af05550118cac20ec097bc843b4
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Fri Feb 22 10:22:08 2019 -0800
+
+    unuse set in hb_map2_t impl
+    
+    also some code cleanup
+
+ src/hb-ot-layout-common.hh | 46 +++++++++++++++++++++++-----------------------
+ 1 file changed, 23 insertions(+), 23 deletions(-)
+
+commit ca3b4a21dff4fcd804b0bf2249fb3f286486d8fa
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Feb 21 16:42:30 2019 -0800
+
+    fixed compiler gripes
+
+ src/hb-ot-var-hvar-table.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit a7b801f6d1410443f518cec5dad4d89a8feaf01d
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Feb 21 16:34:49 2019 -0800
+
+    fix CFF2 local subr subsetting
+    
+    bug exposed by impl change of fdmap
+    also fixed name of subr_remap_ts as subr_remaps_t
+
+ src/hb-subset-cff-common.hh |  8 ++++----
+ src/hb-subset-cff2.cc       | 20 +++++++++-----------
+ 2 files changed, 13 insertions(+), 15 deletions(-)
+
+commit a190140fa47ff5655edbb4eb414175852f722f85
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Thu Feb 21 15:47:27 2019 -0800
+
+    fix HVAR & VarStore subsetting
+
+ src/hb-ot-layout-common.hh  |  15 +++--
+ src/hb-ot-var-hvar-table.hh | 140 ++++++++++++++++++++++----------------------
+ 2 files changed, 77 insertions(+), 78 deletions(-)
+
+commit 09df17e71b1860e250638e8e76deee1da5e7a06b
+Author: Michiharu Ariza <ariza at adobe.com>
+Date:   Wed Feb 20 15:48:29 2019 -0800
+
+    subset HVAR
+    
+    Re-implemented & repurposed CFF:remap_t as hb_map2_t (moved to hb-ot-layout-common.hh) for two-way mapping for use by index map subsetting.
+    Hooked up HVAR subsetter through _subset2.
+    Some renaming in CFF code.
+
+ src/hb-ot-cff-common.hh     |  63 ++----------
+ src/hb-ot-cff1-table.hh     |   8 +-
+ src/hb-ot-layout-common.hh  | 158 ++++++++++++++++++++++++++++--
+ src/hb-ot-var-hvar-table.hh | 232 +++++++++++++++++++++++++++++++++++++++++++-
+ src/hb-subset-cff-common.cc |   9 +-
+ src/hb-subset-cff-common.hh |  27 ++----
+ src/hb-subset-cff1.cc       |  29 +++---
+ src/hb-subset-cff2.cc       |  12 +--
+ src/hb-subset.cc            |   4 +
+ 9 files changed, 426 insertions(+), 116 deletions(-)
+
 commit 93739242e1aab9b745d0ba3c22c33b4acaf9526c
 Author: Michiharu Ariza <ariza at adobe.com>
 Date:   Wed Feb 20 13:23:12 2019 -0800

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/Makefile.am	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/Makefile.am	2020-05-18 10:44:36 UTC (rev 55197)
@@ -18,6 +18,17 @@
 	TESTING.md \
 	CMakeLists.txt \
 	replace-enum-strings.cmake \
+	meson.build \
+	meson_options.txt \
+	subprojects/expat.wrap \
+	subprojects/fontconfig.wrap \
+	subprojects/freetype2.wrap \
+	subprojects/glib.wrap \
+	subprojects/libffi.wrap \
+	subprojects/proxy-libintl.wrap \
+	subprojects/zlib.wrap \
+	meson-cc-tests/intel-atomic-primitives-test.c \
+	meson-cc-tests/solaris-atomic-operations.c \
 	mingw-configure.sh \
 	mingw-ldd.py \
 	mingw32.sh \

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,3 +1,23 @@
+Overview of changes leading to 2.6.6
+Tuesday, May 12, 2020
+====================================
+- A fix in AAT kerning for Geeza Pro.
+- Better support for resource fork fonts on macOS.
+
+
+Overview of changes leading to 2.6.5
+Friday, April 17, 2020
+====================================
+- Add experimental meson build system.  Autotools is still the primary
+  and supported build system.
+- AAT is now always preferred for horizontal scripts when both AAT and OT
+  layout tables exist at the same time.
+- Subsetter improvements.
+- New API:
++hb_ft_font_lock_face()
++hb_ft_font_unlock_face()
+
+
 Overview of changes leading to 2.6.4
 Monday, October 29, 2019
 ====================================

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/README
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/README	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/README	2020-05-18 10:44:36 UTC (rev 55197)
@@ -27,8 +27,8 @@
 
 
 <details>
-  <summary>Packaging status of HarfBuzz</summary
+  <summary>Packaging status of HarfBuzz</summary>
 
-[![Packaging status](https://repology.org/badge/vertical-allrepos/harfbuzz.svg?header=harfbuzz)](https://repology.org/project/harfbuzz/versions)  
+[![Packaging status](https://repology.org/badge/vertical-allrepos/harfbuzz.svg?header=harfbuzz)](https://repology.org/project/harfbuzz/versions)
 
 </details>

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/README.md
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/README.md	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/README.md	2020-05-18 10:44:36 UTC (rev 55197)
@@ -27,8 +27,8 @@
 
 
 <details>
-  <summary>Packaging status of HarfBuzz</summary
+  <summary>Packaging status of HarfBuzz</summary>
 
-[![Packaging status](https://repology.org/badge/vertical-allrepos/harfbuzz.svg?header=harfbuzz)](https://repology.org/project/harfbuzz/versions)  
+[![Packaging status](https://repology.org/badge/vertical-allrepos/harfbuzz.svg?header=harfbuzz)](https://repology.org/project/harfbuzz/versions)
 
 </details>

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/RELEASING.md
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/RELEASING.md	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/RELEASING.md	2020-05-18 10:44:36 UTC (rev 55197)
@@ -22,7 +22,7 @@
 
 4. Make sure you have correct date and new version at the top of NEWS file,
 
-5. Bump version in configure.ac line 3,
+5. Bump version in configure.ac line 3 and meson.build line 4.
 
 6. Do "make distcheck", if it passes, you get a tarball.
    Otherwise, fix things and commit them separately before making release,
@@ -50,23 +50,13 @@
 
    b. Run "make dist-win" to build Win32 bundle.
 
-11. Copy all artefacts to users.freedesktop.org and move them into
-    `/srv/www.freedesktop.org/www/software/harfbuzz/release` There should be four
-    files.  Eg.:
- ```
--rw-r--r--  1 behdad eng 1592693 Jul 18 11:25 harfbuzz-1.4.7.tar.xz
--rw-r--r--  1 behdad eng      89 Jul 18 11:34 harfbuzz-1.4.7.tar.xz.sha256
--rw-r--r--  1 behdad eng     339 Jul 18 11:34 harfbuzz-1.4.7.tar.xz.sha256.asc
--rw-r--r--  1 behdad eng 2895619 Jul 18 11:34 harfbuzz-1.4.7-win32.zip
-```
-
-12. While doing that, quickly double-check the size of the .tar.xz and .zip
-    files against their previous releases to make sure nothing bad happened.
+11. Quickly double-check the size of the .tar.xz and .zip files against their
+    previous releases to make sure nothing bad happened.
     They should be in the ballpark, perhaps slightly larger.  Sometimes they
     do shrink, that's not by itself a stopper.
 
-13. Push the commit and tag out: "git push --follow-tags".  Make sure it's
+12. Push the commit and tag out: "git push --follow-tags".  Make sure it's
     pushed both to freedesktop repo and github.
 
-14. Go to GitHub release page [here](https://github.com/harfbuzz/harfbuzz/releases),
+13. Go to GitHub release page [here](https://github.com/harfbuzz/harfbuzz/releases),
     edit the tag, upload artefacts and NEWS entry and save.

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/TESTING.md
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/TESTING.md	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/TESTING.md	2020-05-18 10:44:36 UTC (rev 55197)
@@ -55,10 +55,9 @@
 Note: You'll need to first install ninja-build via apt-get.
 
 ```shell
-cd harfbuzz
-mkdir buid
-cmake -DHB_CHECK=ON -Bbuild -H. -GNinja && ninja -Cbuild && CTEST_OUTPUT_ON_FAILURE=1 ninja -Cbuild test
+meson build && ninja -Cbuild && ninja -Cbuild test
 ```
+
 ## Test with the Fuzzer
 
 ```shell

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/config.h.in	2020-05-18 10:44:36 UTC (rev 55197)
@@ -81,9 +81,6 @@
 /* Define to 1 if you have the `mprotect' function. */
 #undef HAVE_MPROTECT
 
-/* Define to 1 if you have the `newlocale' function. */
-#undef HAVE_NEWLOCALE
-
 /* Have POSIX threads */
 #undef HAVE_PTHREAD
 
@@ -117,9 +114,6 @@
 /* Define to 1 if you have the <string.h> header file. */
 #undef HAVE_STRING_H
 
-/* Define to 1 if you have the `strtod_l' function. */
-#undef HAVE_STRTOD_L
-
 /* Define to 1 if you have the `sysconf' function. */
 #undef HAVE_SYSCONF
 
@@ -144,9 +138,6 @@
 /* Define to 1 if you have the <windows.h> header file. */
 #undef HAVE_WINDOWS_H
 
-/* Define to 1 if you have the <xlocale.h> header file. */
-#undef HAVE_XLOCALE_H
-
 /* Define to the sub-directory where libtool stores uninstalled libraries. */
 #undef LT_OBJDIR
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,6 +1,6 @@
 AC_PREREQ([2.64])
 AC_INIT([HarfBuzz],
-        [2.6.4],
+        [2.6.6],
         [https://github.com/harfbuzz/harfbuzz/issues/new],
         [harfbuzz],
         [http://harfbuzz.org/])
@@ -23,7 +23,7 @@
 AC_PROG_CC_C99
 AM_PROG_CC_C_O
 AC_PROG_CXX
-AX_CXX_COMPILE_STDCXX(11,, optional)
+AX_CXX_COMPILE_STDCXX(11)
 AC_SYS_LARGEFILE
 PKG_PROG_PKG_CONFIG([0.20])
 AM_MISSING_PROG([RAGEL], [ragel])
@@ -77,8 +77,8 @@
 ])
 
 # Functions and headers
-AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l roundf)
-AC_CHECK_HEADERS(unistd.h sys/mman.h xlocale.h stdbool.h)
+AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty roundf)
+AC_CHECK_HEADERS(unistd.h sys/mman.h stdbool.h)
 
 # Compiler flags
 AC_CANONICAL_HOST

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build	2020-05-18 10:44:36 UTC (rev 55197)
@@ -0,0 +1,345 @@
+project('harfbuzz', 'c', 'cpp',
+  meson_version: '>= 0.47.0',
+  default_options : ['cpp_std=c++11'],
+  version: '2.6.6')
+
+warning('Meson is not our main build system yet, don\'t use it for packaging HarfBuzz for *nix distros for now')
+
+hb_version_arr = meson.project_version().split('.')
+hb_version_major = hb_version_arr[0].to_int()
+hb_version_minor = hb_version_arr[1].to_int()
+hb_version_micro = hb_version_arr[2].to_int()
+
+# libtool versioning
+hb_version_int = hb_version_major*10000 + hb_version_minor*100 + hb_version_micro
+if hb_version_minor % 2 == 1
+  hb_libtool_revision = 0                # for unstable releases
+else
+  hb_libtool_revision = hb_version_micro # for stable releases
+endif
+hb_libtool_age = hb_version_int - hb_libtool_revision
+hb_libtool_current = hb_libtool_age
+hb_libtool_version_info = '@0@:@1@:@2@'.format(hb_libtool_current, hb_libtool_revision, hb_libtool_age)
+
+pkgmod = import('pkgconfig')
+cpp = meson.get_compiler('cpp')
+
+if cpp.get_id() == 'msvc'
+  # Ignore several spurious warnings for things HarfBuzz does very commonly.
+  # If a warning is completely useless and spammy, use '/wdXXXX' to suppress it
+  # If a warning is harmless but hard to fix, use '/woXXXX' so it's shown once
+  # NOTE: Only add warnings here if you are sure they're spurious
+  msvc_args = [
+      '/wd4018', # implicit signed/unsigned conversion
+      '/wd4146', # unary minus on unsigned (beware INT_MIN)
+      '/wd4244', # lossy type conversion (e.g. double -> int)
+      '/wd4305', # truncating type conversion (e.g. double -> float)
+      cpp.get_supported_arguments(['/utf-8']), # set the input encoding to utf-8
+  ]
+  add_project_arguments(msvc_args, language : ['c', 'cpp'])
+  # Disable SAFESEH with MSVC for libs that use external deps that are built with MinGW
+  # noseh_link_args = ['/SAFESEH:NO']
+endif
+
+add_project_arguments(cpp.get_supported_arguments([
+  '-fno-rtti',
+  '-fno-exceptions',
+  '-fno-threadsafe-statics',
+  '-fvisibility-inlines-hidden', # maybe shouldn't be applied for mingw
+]), language : 'cpp')
+
+if host_machine.cpu_family() == 'arm' and cpp.alignment('struct { char c; }') != 1
+  if cpp.has_argument('-mstructure-size-boundary=8')
+    add_project_arguments('-mstructure-size-boundary=8', language : 'cpp')
+  endif
+endif
+
+python3 = import('python').find_installation('python3')
+
+check_headers = [
+  ['unistd.h'],
+  ['sys/mman.h'],
+  ['stdbool.h'],
+]
+
+check_funcs = [
+  ['atexit'],
+  ['mprotect'],
+  ['sysconf'],
+  ['getpagesize'],
+  ['mmap'],
+  ['isatty'],
+  ['roundf'],
+]
+
+freetype_dep = dependency('freetype2', required: false)
+
+if not freetype_dep.found() and cpp.get_id() == 'msvc'
+  if cpp.has_header('ft2build.h')
+    freetype_dep = cpp.find_library('freetype', required: false)
+  endif
+endif
+
+if not freetype_dep.found() and get_option('freetype').enabled()
+  freetype_dep = dependency('freetype2', fallback: ['freetype2', 'freetype_dep'])
+endif
+
+glib_dep = dependency('glib-2.0', required: get_option('glib'),
+                      fallback: ['glib', 'libglib_dep'])
+gobject_dep = dependency('gobject-2.0', required: get_option('gobject'),
+                         fallback: ['glib', 'libgobject_dep'])
+cairo_dep = dependency('cairo', required: false)
+fontconfig_dep = dependency('fontconfig', required: get_option('fontconfig'),
+                            fallback: ['fontconfig', 'fontconfig_dep'])
+graphite2_dep = dependency('graphite2', required: get_option('graphite'))
+icu_dep = dependency('icu-uc', required: false)
+m_dep = cpp.find_library('m', required: false)
+
+if not icu_dep.found() and get_option('icu').enabled()
+  icu_dep = dependency('icu-uc', required: cpp.get_id() != 'msvc')
+endif
+
+if not icu_dep.found() and cpp.get_id() == 'msvc'
+  if cpp.has_header('unicode/uchar.h') and \
+     cpp.has_header('unicode/unorm2.h') and \
+     cpp.has_header('unicode/ustring.h') and \
+     cpp.has_header('unicode/utf16.h') and \
+     cpp.has_header('unicode/uversion.h') and \
+     cpp.has_header('unicode/uscript.h')
+    if get_option('buildtype') == 'debug'
+      icu_dep = cpp.find_library('icuucd', required: get_option('icu'))
+    else
+      icu_dep = cpp.find_library('icuuc', required: get_option('icu'))
+    endif
+  else
+    if get_option('icu').enabled()
+      error('ICU headers and libraries must be present to build ICU support')
+    endif
+  endif
+endif
+
+if not cairo_dep.found() and cpp.get_id() == 'msvc'
+  if cpp.has_header('cairo.h')
+    cairo_dep = cpp.find_library('cairo')
+  endif
+endif
+
+if not cairo_dep.found() and get_option('cairo').enabled()
+  cairo_dep = dependency('cairo', fallback: ['cairo', 'libcairo_dep'])
+endif
+
+# Ensure that cairo-ft is fetched from the same library as cairo itself
+if cairo_dep.found()
+  if cairo_dep.type_name() == 'pkgconfig'
+    cairo_ft_dep = dependency('cairo-ft', required: get_option('cairo'))
+  else
+    if cpp.has_header('cairo-ft.h') and \
+       cpp.has_function('cairo_ft_font_face_create_for_ft_face', dependencies: cairo_dep)
+      cairo_ft_dep = cairo_dep
+    endif
+  endif
+else
+  # Not-found dependency
+  cairo_ft_dep = dependency('', required: false)
+endif
+
+deps = []
+
+conf = configuration_data()
+incconfig = include_directories('.')
+
+add_project_arguments('-DHAVE_CONFIG_H', language: ['c', 'cpp'])
+
+warn_cflags = [
+  '-Wno-non-virtual-dtor',
+]
+
+cpp_args = cpp.get_supported_arguments(warn_cflags)
+
+if m_dep.found()
+  deps += [m_dep]
+endif
+
+if glib_dep.found()
+  conf.set('HAVE_GLIB', 1)
+  deps += [glib_dep]
+endif
+
+if gobject_dep.found()
+  conf.set('HAVE_GOBJECT', 1)
+  deps += [gobject_dep]
+endif
+
+if cairo_dep.found()
+  conf.set('HAVE_CAIRO', 1)
+  deps += [cairo_dep]
+endif
+
+if cairo_ft_dep.found()
+  conf.set('HAVE_CAIRO_FT', 1)
+  deps += [cairo_ft_dep]
+endif
+
+if graphite2_dep.found()
+  conf.set('HAVE_GRAPHITE2', 1)
+  deps += [graphite2_dep]
+endif
+
+if icu_dep.found()
+  conf.set('HAVE_ICU', 1)
+endif
+
+if get_option('icu-builtin')
+  conf.set('HAVE_ICU_BUILTIN', 1)
+endif
+
+if get_option('experimental-api')
+  conf.set('HB_EXPERIMENTAL_API', 1)
+endif
+
+if freetype_dep.found()
+  conf.set('HAVE_FREETYPE', 1)
+  deps += [freetype_dep]
+  check_freetype_funcs = [
+    ['FT_Get_Var_Blend_Coordinates', {'deps': freetype_dep}],
+    ['FT_Set_Var_Blend_Coordinates', {'deps': freetype_dep}],
+    ['FT_Done_MM_Var', {'deps': freetype_dep}],
+  ]
+
+  if freetype_dep.type_name() == 'internal'
+    foreach func: check_freetype_funcs
+      name = func[0]
+      conf.set('HAVE_ at 0@'.format(name.to_upper()), 1)
+    endforeach
+  else
+    check_funcs += check_freetype_funcs
+  endif
+endif
+
+if fontconfig_dep.found()
+  conf.set('HAVE_FONTCONFIG', 1)
+  deps += [fontconfig_dep]
+endif
+
+# GDI (uniscribe) (windows)
+if host_machine.system() == 'windows' and not get_option('gdi').disabled()
+  # TODO: make nicer once we have https://github.com/mesonbuild/meson/issues/3940
+  if cpp.has_header('usp10.h') and cpp.has_header('windows.h')
+    foreach usplib : ['usp10', 'gdi32', 'rpcrt4']
+      deps += [cpp.find_library(usplib, required: true)]
+    endforeach
+    conf.set('HAVE_UNISCRIBE', 1)
+    conf.set('HAVE_GDI', 1)
+  elif get_option('gdi').enabled()
+    error('gdi was enabled explicitly, but some required headers are missing.')
+  endif
+endif
+
+# DirectWrite (windows)
+if host_machine.system() == 'windows' and not get_option('directwrite').disabled()
+  if cpp.has_header('dwrite_1.h')
+    deps += [cpp.find_library('dwrite', required: true)]
+    conf.set('HAVE_DIRECTWRITE', 1)
+  elif get_option('directwrite').enabled()
+    error('DirectWrite was enabled explicitly, but required header is missing.')
+  endif
+endif
+
+# CoreText (macOS) - FIXME: untested
+if host_machine.system() == 'darwin' and not get_option('coretext').disabled()
+  app_services_dep = dependency('appleframeworks', modules : ['ApplicationServices'], required: false)
+  if cpp.has_type('CTFontRef', prefix: '#include <ApplicationServices/ApplicationServices.h>', dependencies: app_services_dep)
+    deps += [app_services_dep]
+    conf.set('HAVE_CORETEXT', 1)
+  # On iOS CoreText and CoreGraphics are stand-alone frameworks
+  # Check for a different symbol to avoid getting cached result
+  else
+    coretext_dep = dependency('appleframeworks', modules : ['CoreText'], required: false)
+    coregraphics_dep = dependency('appleframeworks', modules : ['CoreGraphics'], required: false)
+    corefoundation_dep = dependency('appleframeworks', modules : ['CoreFoundation'], required: false)
+    if cpp.has_type('CTRunRef', prefix: '#include <CoreText/CoreText.h>', dependencies: [coretext_dep, coregraphics_dep, corefoundation_dep])
+      deps += [coretext_dep, coregraphics_dep, corefoundation_dep]
+      conf.set('HAVE_CORETEXT', 1)
+    elif get_option('coretext').enabled()
+      error('CoreText was enabled explicitly, but required headers or frameworks are missing.')
+    endif
+  endif
+endif
+
+# threads
+if host_machine.system() != 'windows'
+  thread_dep = dependency('threads', required: false)
+
+  if thread_dep.found()
+    conf.set('HAVE_PTHREAD', 1)
+    deps += [thread_dep]
+  else
+    check_headers += ['sched.h']
+    check_funcs += ['sched_yield', {'link_with': 'rt'}]
+  endif
+endif
+
+conf.set('HAVE_OT', 1)
+conf.set('HAVE_FALLBACK', 1)
+conf.set_quoted('PACKAGE_NAME', 'HarfBuzz')
+conf.set_quoted('PACKAGE_VERSION', meson.project_version())
+
+foreach check : check_headers
+  name = check[0]
+
+  if cpp.has_header(name)
+    conf.set('HAVE_ at 0@'.format(name.to_upper().underscorify()), 1)
+  endif
+endforeach
+
+foreach check : check_funcs
+  name = check[0]
+  opts = check.get(1, {})
+  link_withs = opts.get('link_with', [])
+  check_deps = opts.get('deps', [])
+  extra_deps = []
+  found = true
+
+  # First try without linking
+
+  found = cpp.has_function(name, dependencies: check_deps)
+
+  if not found and link_withs.length() > 0
+    found = true
+
+    foreach link_with : link_withs
+      dep = cpp.find_library(link_with, required: false)
+      if dep.found()
+        extra_deps += dep
+      else
+        found = false
+      endif
+    endforeach
+
+    if found
+      found = cpp.has_function(name, dependencies: check_deps + extra_deps)
+    endif
+  endif
+
+  if found
+    deps += extra_deps
+    conf.set('HAVE_ at 0@'.format(name.to_upper()), 1)
+  endif
+endforeach
+
+if cpp.links(files('meson-cc-tests/intel-atomic-primitives-test.c'), name: 'Intel atomics')
+  conf.set('HAVE_INTEL_ATOMIC_PRIMITIVES', 1)
+endif
+
+if cpp.links(files('meson-cc-tests/solaris-atomic-operations.c'), name: 'Solaris atomic ops')
+  conf.set('HAVE_SOLARIS_ATOMIC_OPS', 1)
+endif
+
+subdir('src')
+subdir('util')
+
+if not get_option('tests').disabled()
+  subdir('test')
+endif
+
+configure_file(output: 'config.h', configuration: conf)

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson_options.txt
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson_options.txt	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson_options.txt	2020-05-18 10:44:36 UTC (rev 55197)
@@ -0,0 +1,36 @@
+# HarfBuzz feature options
+option('glib', type: 'feature', value: 'auto',
+  description: 'Enable GLib unicode functions')
+option('gobject', type: 'feature', value: 'disabled',
+  description: 'Enable GObject bindings')
+option('cairo', type: 'feature', value: 'auto',
+  description: 'Use Cairo graphics library')
+option('fontconfig', type: 'feature', value: 'auto',
+  description: 'Use fontconfig')
+option('icu', type: 'feature', value: 'auto',
+  description: 'Enable ICU library unicode functions')
+option('graphite', type: 'feature', value: 'disabled',
+  description: 'Enable Graphite2 complementary shaper')
+option('freetype', type: 'feature', value: 'auto',
+  description: 'Enable freetype interop helpers')
+option('gdi', type: 'feature', value: 'disabled',
+  description: 'Enable GDI helpers and Uniscribe shaper backend (Windows only)')
+option('directwrite', type: 'feature', value: 'disabled',
+  description: 'Enable DirectWrite shaper backend on Windows (experimental)')
+option('coretext', type: 'feature', value: 'disabled',
+  description: 'Enable CoreText shaper backend on macOS')
+
+# Common feature options
+option('tests', type : 'feature', value : 'enabled', yield : true,
+  description: 'Enable or disable unit tests')
+option('introspection', type : 'feature', value : 'disabled', yield : true,
+  description : 'Generate gobject-introspection bindings (.gir/.typelib files)')
+
+option('icu-builtin', type: 'boolean', value: false,
+  description: 'Don\'t separate ICU support as harfbuzz-icu module')
+option('with-libstdcxx', type: 'boolean', value: false,
+   description: 'Allow linking with libstdc++ (ignored and always enabled in Windows)')
+option('experimental-api', type: 'boolean', value: false,
+  description: 'Enable experimental APIs')
+option('amalgam', type : 'boolean', value : false,
+  description : 'Enable amalgam builds')


Property changes on: trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson_options.txt
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Rev URL
\ No newline at end of property
Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/mingw-ldd.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/mingw-ldd.py	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/mingw-ldd.py	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,10 +1,9 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 # Copied from https://github.com/xantares/mingw-ldd/blob/master/mingw-ldd.py
 # Modified to point to right prefix location on Fedora.
 
 # WTFPL - Do What the Fuck You Want to Public License
-from __future__ import print_function
 import pefile
 import os
 import sys

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am	2020-05-18 10:44:36 UTC (rev 55197)
@@ -13,6 +13,8 @@
 check_PROGRAMS =
 
 EXTRA_DIST += harfbuzz.cc
+EXTRA_DIST += meson.build
+EXTRA_DIST += fix_get_types.py
 
 # Convenience targets:
 lib: $(BUILT_SOURCES) libharfbuzz.la
@@ -50,12 +52,7 @@
 if HAVE_FREETYPE
 HBCFLAGS += $(FREETYPE_CFLAGS)
 HBLIBS   += $(FREETYPE_LIBS)
-# XXX
-# The following creates a recursive dependency on FreeType if FreeType is
-# built with HarfBuzz support enabled.  Newer pkg-config handles that just
-# fine but pkg-config 0.26 as shipped in Ubuntu 14.04 crashes.  Remove
-# in a year or two, or otherwise work around it...
-#HBDEPS   += $(FREETYPE_DEPS)
+HBDEPS   += $(FREETYPE_DEPS)
 HBSOURCES += $(HB_FT_sources)
 HBHEADERS += $(HB_FT_headers)
 endif
@@ -153,6 +150,7 @@
 EXTRA_DIST += hb-version.h.in harfbuzz.pc.in harfbuzz-config.cmake.in
 
 lib_LTLIBRARIES += libharfbuzz-subset.la
+libharfbuzz_subset_la_LINK = $(chosen_linker) $(libharfbuzz_subset_la_LDFLAGS)
 libharfbuzz_subset_la_SOURCES = $(HB_SUBSET_sources)
 libharfbuzz_subset_la_CPPFLAGS = $(HBCFLAGS) $(CODE_COVERAGE_CFLAGS)
 libharfbuzz_subset_la_LDFLAGS = $(base_link_flags) $(export_symbols_subset) $(CODE_COVERAGE_LDFLAGS)
@@ -290,7 +288,7 @@
 use-table: gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt
 	$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-use-table.cc \
 	|| ($(RM) $(srcdir)/hb-ot-shape-complex-use-table.cc; false)
-vowel-constraints: gen-vowel-constraints.py HBIndicVowelConstraints.txt Scripts.txt
+vowel-constraints: gen-vowel-constraints.py ms-use/IndicShapingInvalidCluster.txt Scripts.txt
 	$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-vowel-constraints.cc \
 	|| ($(RM) $(srcdir)/hb-ot-shape-complex-vowel-constraints.cc; false)
 
@@ -334,6 +332,7 @@
 	test-buffer-serialize \
 	test-ot-meta \
 	test-ot-name \
+	test-ot-glyphname \
 	test-gpos-size-params \
 	test-gsub-would-substitute \
 	$(NULL)
@@ -359,6 +358,10 @@
 test_ot_name_CPPFLAGS = $(HBCFLAGS)
 test_ot_name_LDADD = libharfbuzz.la $(HBLIBS)
 
+test_ot_glyphname_SOURCES = test-ot-glyphname.cc
+test_ot_glyphname_CPPFLAGS = $(HBCFLAGS)
+test_ot_glyphname_LDADD = libharfbuzz.la $(HBLIBS)
+
 test_gpos_size_params_SOURCES = test-gpos-size-params.cc
 test_gpos_size_params_CPPFLAGS = $(HBCFLAGS)
 test_gpos_size_params_LDADD = libharfbuzz.la $(HBLIBS)
@@ -367,31 +370,6 @@
 test_gsub_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS)
 test_gsub_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS)
 
-if HAVE_FREETYPE
-if HAVE_CAIRO_FT
-noinst_PROGRAMS += test-ot-color
-test_ot_color_SOURCES = test-ot-color.cc
-test_ot_color_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS) $(CAIRO_FT_CFLAGS)
-test_ot_color_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS) $(CAIRO_LIBS) $(CAIRO_FT_LIBS)
-endif # HAVE_CAIRO_FT
-endif # HAVE_FREETYPE
-
-dist_check_SCRIPTS = \
-	check-c-linkage-decls.sh \
-	check-externs.sh \
-	check-header-guards.sh \
-	check-includes.sh \
-	check-static-inits.sh \
-	check-symbols.sh \
-	$(NULL)
-TESTS += $(dist_check_SCRIPTS)
-
-if !WITH_LIBSTDCXX
-dist_check_SCRIPTS += \
-	check-libstdc++.sh \
-	$(NULL)
-endif
-
 check_PROGRAMS += \
 	dump-indic-data \
 	dump-khmer-data \
@@ -411,7 +389,7 @@
 dump_use_data_CPPFLAGS = $(HBCFLAGS)
 dump_use_data_LDADD = libharfbuzz.la $(HBLIBS)
 
-COMPILED_TESTS = test-algs test-iter test-meta test-number test-ot-tag test-unicode-ranges test-bimap
+COMPILED_TESTS = test-algs test-array test-iter test-meta test-number test-ot-tag test-unicode-ranges test-bimap
 COMPILED_TESTS_CPPFLAGS = $(HBCFLAGS) -DMAIN -UNDEBUG
 COMPILED_TESTS_LDADD = libharfbuzz.la $(HBLIBS)
 check_PROGRAMS += $(COMPILED_TESTS)
@@ -421,6 +399,10 @@
 test_algs_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_algs_LDADD = $(COMPILED_TESTS_LDADD)
 
+test_array_SOURCES = test-array.cc
+test_array_CPPFLAGS = $(HBCFLAGS)
+test_array_LDADD = libharfbuzz.la $(HBLIBS)
+
 test_iter_SOURCES = test-iter.cc hb-static.cc
 test_iter_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_iter_LDADD = $(COMPILED_TESTS_LDADD)
@@ -445,8 +427,25 @@
 test_bimap_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_bimap_LDADD = $(COMPILED_TESTS_LDADD)
 
+dist_check_SCRIPTS = \
+	check-c-linkage-decls.sh \
+	check-externs.sh \
+	check-header-guards.sh \
+	check-includes.sh \
+	check-static-inits.sh \
+	check-symbols.sh \
+	$(NULL)
+TESTS += $(dist_check_SCRIPTS)
+
+if !WITH_LIBSTDCXX
+dist_check_SCRIPTS += \
+	check-libstdc++.sh \
+	$(NULL)
+endif
+
 TESTS_ENVIRONMENT = \
 	srcdir="$(srcdir)" \
+	builddir="$(builddir)" \
 	MAKE="$(MAKE) $(AM_MAKEFLAGS)" \
 	HBSOURCES="$(HBSOURCES)" \
 	HBHEADERS="$(HBHEADERS)" \
@@ -456,7 +455,16 @@
 
 -include $(INTROSPECTION_MAKEFILE)
 INTROSPECTION_GIRS = HarfBuzz-0.0.gir # What does the 0 mean anyway?!
-INTROSPECTION_SCANNER_ARGS = -I$(srcdir) -n hb --identifier-prefix=hb_ --warn-all
+INTROSPECTION_SCANNER_ARGS = \
+	-I$(srcdir) \
+	--warn-all --verbose \
+	--namespace=HarfBuzz \
+	--nsversion=0.0 \
+	--symbol-prefix=hb \
+	--symbol-prefix=hb_gobject \
+	--identifier-prefix=hb_ \
+	--pkg-export=harfbuzz-gobject \
+	--c-include=hb-gobject.h
 INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir)
 INTROSPECTION_SCANNER_ENV = CC="$(CC)"
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2020-05-18 10:44:36 UTC (rev 55197)
@@ -35,6 +35,8 @@
 	hb-config.hh \
 	hb-debug.hh \
 	hb-dispatch.hh \
+	hb-draw.cc \
+	hb-draw.hh \
 	hb-face.cc \
 	hb-face.hh \
 	hb-fallback-shape.cc \
@@ -57,6 +59,7 @@
 	hb-ot-cff-common.hh \
 	hb-ot-cff1-table.cc \
 	hb-ot-cff1-table.hh \
+	hb-ot-cff1-std-str.hh \
 	hb-ot-cff2-table.cc \
 	hb-ot-cff2-table.hh \
 	hb-ot-cmap-table.hh \
@@ -192,6 +195,7 @@
 	hb-buffer.h \
 	hb-common.h \
 	hb-deprecated.h \
+	hb-draw.h \
 	hb-face.h \
 	hb-font.h \
 	hb-map.h \

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-libstdc++.sh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-libstdc++.sh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-libstdc++.sh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -22,8 +22,7 @@
 
 tested=false
 # harfbuzz-icu links to libstdc++ because icu does.
-# harfbuzz-subset uses libstdc++.
-for soname in harfbuzz harfbuzz-gobject; do
+for soname in harfbuzz harfbuzz-subset harfbuzz-gobject; do
 	for suffix in so dylib; do
 		so=$libs/lib$soname.$suffix
 		if ! test -f "$so"; then continue; fi

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-static-inits.sh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-static-inits.sh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-static-inits.sh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -4,7 +4,7 @@
 export LC_ALL
 
 test -z "$srcdir" && srcdir=.
-test -z "$libs" && libs=.libs
+test -z "$builddir" && builddir=.
 stat=0
 
 if which objdump 2>/dev/null >/dev/null; then
@@ -14,12 +14,14 @@
 	exit 77
 fi
 
-OBJS=$libs/*.o
+OBJS=$(find $builddir/ -name '*.o')
 if test "x`echo $OBJS`" = "x$OBJS" 2>/dev/null >/dev/null; then
 	echo "check-static-inits.sh: object files not found; skipping test"
 	exit 77
 fi
 
+tested=false
+
 echo "Checking that no object file has static initializers"
 for obj in $OBJS; do
 	if objdump -t "$obj" | grep '[.][cd]tors' | grep -v '\<00*\>'; then
@@ -26,6 +28,7 @@
 		echo "Ouch, $obj has static initializers/finalizers"
 		stat=1
 	fi
+	tested=true
 done
 
 echo "Checking that no object file has lazy static C++ constructors/destructors or other such stuff"
@@ -35,6 +38,12 @@
 		echo "Ouch, $obj has lazy static C++ constructors/destructors or other such stuff"
 		stat=1
 	fi
+	tested=true
 done
 
+if ! $tested; then
+	echo "check-static-inits.sh: no objects found; skipping test"
+	exit 77
+fi
+
 exit $stat

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.sh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.sh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.sh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -4,10 +4,11 @@
 export LC_ALL
 
 test -z "$srcdir" && srcdir=.
+test -z "$builddir" && builddir=.
 test -z "$libs" && libs=.libs
 stat=0
 
-IGNORED_SYMBOLS='_fini\|_init\|_fdata\|_ftext\|_fbss\|__bss_start\|__bss_start__\|__bss_end__\|_edata\|_end\|_bss_end__\|__end__\|__gcov_.*\|llvm_.*'
+IGNORED_SYMBOLS='_fini\|_init\|_fdata\|_ftext\|_fbss\|__bss_start\|__bss_start__\|__bss_end__\|_edata\|_end\|_bss_end__\|__end__\|__gcov_.*\|llvm_.*\|flush_fn_list\|writeout_fn_list'
 
 if which nm 2>/dev/null >/dev/null; then
 	:
@@ -26,7 +27,7 @@
 		symprefix=
 		if test $suffix = dylib; then symprefix=_; fi
 
-		EXPORTED_SYMBOLS=`nm "$so" | grep ' [BCDGINRST] .' | grep -v " $symprefix\\($IGNORED_SYMBOLS\\>\\)" | cut -d' ' -f3 | c++filt`
+		EXPORTED_SYMBOLS=`nm "$so" | grep ' [BCDGIRST] .' | grep -v " $symprefix\\($IGNORED_SYMBOLS\\>\\)" | cut -d' ' -f3 | c++filt`
 
 		prefix=$symprefix`basename "$so" | sed 's/libharfbuzz/hb/; s/-/_/g; s/[.].*//'`
 
@@ -36,7 +37,7 @@
 			stat=1
 		fi
 
-		def=$soname.def
+		def=$builddir/$soname.def
 		if ! test -f "$def"; then
 			echo "'$def' not found; skipping"
 		else
@@ -47,9 +48,9 @@
 				# cheat: copy the last line from the def file!
 				tail -n1 "$def"
 			} | c++filt | diff "$def" - >&2 || stat=1
+
+			tested=true
 		fi
-
-		tested=true
 	done
 done
 if ! $tested; then

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/fix_get_types.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/fix_get_types.py	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/fix_get_types.py	2020-05-18 10:44:36 UTC (rev 55197)
@@ -0,0 +1,15 @@
+import re
+import argparse
+
+if __name__=='__main__':
+    parser = argparse.ArgumentParser()
+    parser.add_argument('input')
+    parser.add_argument('output')
+    args = parser.parse_args()
+
+    with open(args.input, 'r') as inp:
+        with open(args.output, 'w') as out:
+            for l in inp.readlines():
+                l = re.sub('_t_get_type', '_get_type', l)
+                l = re.sub('_T \(', ' (', l)
+                out.write(l)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-arabic-table.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-arabic-table.py	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-arabic-table.py	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,11 +1,15 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
-from __future__ import print_function, division, absolute_import
-
 import io, os.path, sys
 
 if len (sys.argv) != 4:
-	print ("usage: ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt", file=sys.stderr)
+	print ("""usage: ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt
+
+Input files, as of Unicode 12:
+* https://unicode.org/Public/UCD/latest/ucd/ArabicShaping.txt
+* https://unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
+* https://unicode.org/Public/UCD/latest/ucd/Blocks.txt
+""", file=sys.stderr)
 	sys.exit (1)
 
 files = [io.open (x, encoding='utf-8') for x in sys.argv[1:]]

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-def.py	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,7 +1,5 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
-from __future__ import print_function, division, absolute_import
-
 import io, os, re, sys
 
 if len (sys.argv) < 3:
@@ -15,10 +13,35 @@
 	if h.endswith (".h"):
 		with io.open (h, encoding='utf-8') as f: headers_content.append (f.read ())
 
-symbols = "\n".join (sorted (re.findall (r"^hb_\w+(?= \()", "\n".join (headers_content), re.M)))
+symbols = sorted (re.findall (r"^hb_\w+(?= \()", "\n".join (headers_content), re.M))
+if '--experimental-api' not in sys.argv:
+	# Move these to harfbuzz-sections.txt when got stable
+	experimental_symbols = \
+"""hb_font_draw_glyph
+hb_draw_funcs_t
+hb_draw_close_path_func_t
+hb_draw_cubic_to_func_t
+hb_draw_line_to_func_t
+hb_draw_move_to_func_t
+hb_draw_quadratic_to_func_t
+hb_draw_funcs_create
+hb_draw_funcs_destroy
+hb_draw_funcs_is_immutable
+hb_draw_funcs_make_immutable
+hb_draw_funcs_reference
+hb_draw_funcs_set_close_path_func
+hb_draw_funcs_set_cubic_to_func
+hb_draw_funcs_set_line_to_func
+hb_draw_funcs_set_move_to_func
+hb_draw_funcs_set_quadratic_to_func
+hb_font_get_var_coords_design
+hb_ot_layout_closure_lookups
+hb_ot_layout_closure_features""".splitlines ()
+	symbols = [x for x in symbols if x not in experimental_symbols]
+symbols = "\n".join (symbols)
 
 result = symbols if os.environ.get('PLAIN_LIST', '') else """EXPORTS
 %s
-LIBRARY lib%s-0.dll""" % (symbols, output_file.replace ('.def', ''))
+LIBRARY lib%s-0.dll""" % (symbols, output_file.replace ('src/', '').replace ('.def', ''))
 
 with open (output_file, "w") as f: f.write (result)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-emoji-table.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-emoji-table.py	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-emoji-table.py	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,6 +1,5 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 
-from __future__ import print_function, division, absolute_import
 import sys
 import os.path
 from collections import OrderedDict
@@ -7,7 +6,10 @@
 import packTab
 
 if len (sys.argv) != 2:
-	print("usage: ./gen-emoji-table.py emoji-data.txt", file=sys.stderr)
+	print("""usage: ./gen-emoji-table.py emoji-data.txt
+
+Input file, as of Unicode 12:
+* https://www.unicode.org/Public/emoji/12.0/emoji-data.txt""", file=sys.stderr)
 	sys.exit (1)
 
 f = open(sys.argv[1])

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-indic-table.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-indic-table.py	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-indic-table.py	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,11 +1,14 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
-from __future__ import print_function, division, absolute_import
-
 import io, sys
 
 if len (sys.argv) != 4:
-	print ("usage: ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt", file=sys.stderr)
+	print ("""usage: ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt
+
+Input files, as of Unicode 12:
+* https://unicode.org/Public/UCD/latest/ucd/IndicSyllabicCategory.txt
+* https://unicode.org/Public/UCD/latest/ucd/IndicPositionalCategory.txt
+* https://unicode.org/Public/UCD/latest/ucd/Blocks.txt""", file=sys.stderr)
 	sys.exit (1)
 
 ALLOWED_SINGLES = [0x00A0, 0x25CC]

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-os2-unicode-ranges.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-os2-unicode-ranges.py	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-os2-unicode-ranges.py	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,22 +1,13 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 
-# -*- coding: utf-8 -*-
-
 # Generates the code for a sorted unicode range array as used in hb-ot-os2-unicode-ranges.hh
 # Input is a tab seperated list of unicode ranges from the otspec
 # (https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ur).
 
-from __future__ import print_function, division, absolute_import
-
 import io
 import re
 import sys
 
-try:
-  reload(sys)
-  sys.setdefaultencoding('utf-8')
-except NameError:
-  pass  # Python 3
 
 print ("""static OS2Range _hb_os2_unicode_ranges[] =
 {""")

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-tag-table.py	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 
 """Generator of the mapping from OpenType tags to BCP 47 tags and vice
 versa.
@@ -18,18 +18,11 @@
 case, the fallback behavior will choose the right tag anyway.
 """
 
-from __future__ import absolute_import, division, print_function, unicode_literals
-
 import collections
-try:
-	from HTMLParser import HTMLParser
-	def write (s):
-		print (s.encode ('utf-8'), end='')
-except ImportError:
-	from html.parser import HTMLParser
-	def write (s):
-		sys.stdout.flush ()
-		sys.stdout.buffer.write (s.encode ('utf-8'))
+from html.parser import HTMLParser
+def write (s):
+	sys.stdout.flush ()
+	sys.stdout.buffer.write (s.encode ('utf-8'))
 import io
 import itertools
 import re
@@ -37,16 +30,16 @@
 import unicodedata
 
 if len (sys.argv) != 3:
-	print ('usage: ./gen-tag-table.py languagetags language-subtag-registry', file=sys.stderr)
+	print ('''usage: ./gen-tag-table.py languagetags language-subtag-registry
+
+Input files, as of Unicode 12:
+* https://docs.microsoft.com/en-us/typography/opentype/spec/languagetags
+* https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry''', file=sys.stderr)
 	sys.exit (1)
 
-try:
-	from html import unescape
-	def html_unescape (parser, entity):
-		return unescape (entity)
-except ImportError:
-	def html_unescape (parser, entity):
-		return parser.unescape (entity)
+from html import unescape
+def html_unescape (parser, entity):
+	return unescape (entity)
 
 def expect (condition, message=None):
 	if not condition:
@@ -54,7 +47,7 @@
 			raise AssertionError
 		raise AssertionError (message)
 
-# from http://www-01.sil.org/iso639-3/iso-639-3.tab
+# from https://www-01.sil.org/iso639-3/iso-639-3.tab
 ISO_639_3_TO_1 = {
 	'aar': 'aa',
 	'abk': 'ab',
@@ -754,7 +747,7 @@
 ot.add_language ('und-Syrj', 'SYRJ')
 ot.add_language ('und-Syrn', 'SYRN')
 
-bcp_47.names['xst'] = u"Silt'e"
+bcp_47.names['xst'] = "Silt'e"
 bcp_47.scopes['xst'] = ' (retired code)'
 bcp_47.macrolanguages['xst'] = {'stv', 'wle'}
 
@@ -861,7 +854,7 @@
 	Returns:
 		A snippet of C++ representing ``tag``.
 	"""
-	return u"HB_TAG('%s','%s','%s','%s')" % tuple (('%-4s' % tag)[:4])
+	return "HB_TAG('%s','%s','%s','%s')" % tuple (('%-4s' % tag)[:4])
 
 def get_variant_set (name):
 	"""Return a set of variant language names from a name.
@@ -873,7 +866,7 @@
 	Returns:
 		A set of normalized language names.
 	"""
-	return set (unicodedata.normalize ('NFD', n.replace ('\u2019', u"'"))
+	return set (unicodedata.normalize ('NFD', n.replace ('\u2019', "'"))
 			.encode ('ASCII', 'ignore')
 			.strip ()
 			for n in re.split ('[\n(),]', name) if n)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-ucd-table.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-ucd-table.py	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-ucd-table.py	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,13 +1,14 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
-from __future__ import print_function, division, absolute_import
-
 import io, os.path, sys, re
 import logging
 logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
 
 if len (sys.argv) not in (2, 3):
-	print("usage: ./gen-ucd-table ucd.nounihan.grouped.xml [/path/to/hb-common.h]", file=sys.stderr)
+	print("""usage: ./gen-ucd-table ucd.nounihan.grouped.xml [/path/to/hb-common.h]
+
+Input file, as of Unicode 12:
+* https://unicode.org/Public/UCD/latest/ucdxml/ucd.nounihan.grouped.zip""", file=sys.stderr)
 	sys.exit(1)
 
 # https://github.com/harfbuzz/packtab

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	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,13 +1,17 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # flake8: noqa
 
-from __future__ import print_function, division, absolute_import
-
 import io
 import sys
 
 if len (sys.argv) != 5:
-	print ("usage: ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt", file=sys.stderr)
+	print ("""usage: ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt
+
+Input file, as of Unicode 12:
+* https://unicode.org/Public/UCD/latest/ucd/IndicSyllabicCategory.txt
+* https://unicode.org/Public/UCD/latest/ucd/IndicPositionalCategory.txt
+* https://unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
+* https://unicode.org/Public/UCD/latest/ucd/Blocks.txt""", file=sys.stderr)
 	sys.exit (1)
 
 BLACKLISTED_BLOCKS = ["Thai", "Lao"]
@@ -147,11 +151,6 @@
 	'Overstruck',
 ]
 
-try:
-	basestring
-except NameError:
-	basestring = str
-
 class PropertyValue(object):
 	def __init__(self, name_):
 		self.name = name_
@@ -158,7 +157,7 @@
 	def __str__(self):
 		return self.name
 	def __eq__(self, other):
-		return self.name == (other if isinstance(other, basestring) else other.name)
+		return self.name == (other if isinstance(other, str) else other.name)
 	def __ne__(self, other):
 		return not (self == other)
 	def __hash__(self):

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-vowel-constraints.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-vowel-constraints.py	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-vowel-constraints.py	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 
 """Generator of the function to prohibit certain vowel sequences.
 
@@ -6,26 +6,23 @@
 circles into sequences prohibited by the USE script development spec.
 This function should be used as the ``preprocess_text`` of an
 ``hb_ot_complex_shaper_t``.
+
 """
 
-from __future__ import absolute_import, division, print_function, unicode_literals
-
 import collections
-try:
-	from HTMLParser import HTMLParser
-	def write (s):
-		print (s.encode ('utf-8'), end='')
-except ImportError:
-	from html.parser import HTMLParser
-	def write (s):
-		sys.stdout.flush ()
-		sys.stdout.buffer.write (s.encode ('utf-8'))
+from html.parser import HTMLParser
+def write (s):
+	sys.stdout.flush ()
+	sys.stdout.buffer.write (s.encode ('utf-8'))
 import itertools
 import io
 import sys
 
 if len (sys.argv) != 3:
-	print ('usage: ./gen-vowel-constraints.py HBIndicVowelConstraints.txt Scripts.txt', file=sys.stderr)
+	print ("""usage: ./gen-vowel-constraints.py ms-use/IndicShapingInvalidCluster.txt Scripts.txt
+
+Input file, as of Unicode 12:
+* https://unicode.org/Public/UCD/latest/ucd/Scripts.txt""", file=sys.stderr)
 	sys.exit (1)
 
 with io.open (sys.argv[2], encoding='utf-8') as f:
@@ -84,7 +81,8 @@
 			else:
 				self._c[first] = ConstraintSet (rest)
 
-	def _indent (self, depth):
+	@staticmethod
+	def _indent (depth):
 		return ('  ' * depth).replace ('        ', '\t')
 
 	def __str__ (self, index=0, depth=4):
@@ -92,17 +90,20 @@
 		indent = self._indent (depth)
 		if isinstance (self._c, list):
 			if len (self._c) == 0:
+				assert index == 2, 'Cannot use `matched` for this constraint; the general case has not been implemented'
 				s.append ('{}matched = true;\n'.format (indent))
 			elif len (self._c) == 1:
+				assert index == 1, 'Cannot use `matched` for this constraint; the general case has not been implemented'
 				s.append ('{}matched = 0x{:04X}u == buffer->cur ({}).codepoint;\n'.format (indent, next (iter (self._c)), index or ''))
 			else:
-				s.append ('{}if (0x{:04X}u == buffer->cur ({}).codepoint &&\n'.format (indent, self._c[0], index))
-				s.append ('{}buffer->idx + {} < count &&\n'.format (self._indent (depth + 2), len (self._c)))
+				s.append ('{}if (0x{:04X}u == buffer->cur ({}).codepoint &&\n'.format (indent, self._c[0], index or ''))
+				if index:
+					s.append ('{}buffer->idx + {} < count &&\n'.format (self._indent (depth + 2), index + 1))
 				for i, cp in enumerate (self._c[1:], start=1):
 					s.append ('{}0x{:04X}u == buffer->cur ({}).codepoint{}\n'.format (
 						self._indent (depth + 2), cp, index + i, ')' if i == len (self._c) - 1 else ' &&'))
 				s.append ('{}{{\n'.format (indent))
-				for i in range (len (self._c)):
+				for i in range (index + 1):
 					s.append ('{}buffer->next_glyph ();\n'.format (self._indent (depth + 1)))
 				s.append ('{}_output_dotted_circle (buffer);\n'.format (self._indent (depth + 1)))
 				s.append ('{}}}\n'.format (indent))
@@ -128,7 +129,12 @@
 
 constraints = {}
 with io.open (sys.argv[1], encoding='utf-8') as f:
-	constraints_header = [f.readline ().strip () for i in range (2)]
+	constraints_header = []
+	while True:
+		line = f.readline ().strip ()
+		if line == '#':
+			break
+		constraints_header.append(line)
 	for line in f:
 		j = line.find ('#')
 		if j >= 0:
@@ -147,7 +153,7 @@
 print ('/*')
 print (' * The following functions are generated by running:')
 print (' *')
-print (' *   %s use Scripts.txt' % sys.argv[0])
+print (' *   %s ms-use/IndicShapingInvalidCluster.txt Scripts.txt' % sys.argv[0])
 print (' *')
 print (' * on files with these headers:')
 print (' *')
@@ -185,7 +191,7 @@
 print ('\t\t\t\t       hb_buffer_t              *buffer,')
 print ('\t\t\t\t       hb_font_t                *font HB_UNUSED)')
 print ('{')
-print ('#if defined(HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS)')
+print ('#ifdef HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS')
 print ('  return;')
 print ('#endif')
 print ('  if (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)')

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -4,6 +4,7 @@
 #include "hb-buffer-serialize.cc"
 #include "hb-buffer.cc"
 #include "hb-common.cc"
+#include "hb-draw.cc"
 #include "hb-face.cc"
 #include "hb-fallback-shape.cc"
 #include "hb-font.cc"

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-fdsc-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-fdsc-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-fdsc-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -65,7 +65,7 @@
   protected:
   Tag		tag;		/* The 4-byte table tag name. */
   union {
-  HBFixed		value;		/* The value for the descriptor tag. */
+  HBFixed	value;		/* The value for the descriptor tag. */
   HBUINT32	nalfType;	/* If the tag is `nalf`, see non_alphabetic_value_t */
   } u;
   public:
@@ -80,10 +80,10 @@
     Weight	 = HB_TAG ('w','g','h','t'),
 				/* Percent weight relative to regular weight.
 				 * (defaul value: 1.0) */
-    Width 	 = HB_TAG ('w','d','t','h'),
+    Width	 = HB_TAG ('w','d','t','h'),
 				/* Percent width relative to regular width.
 				 * (default value: 1.0) */
-    Slant 	 = HB_TAG ('s','l','n','t'),
+    Slant	 = HB_TAG ('s','l','n','t'),
 				/* Angle of slant in degrees, where positive
 				 * is clockwise from straight up.
 				 * (default value: 0.0) */
@@ -108,7 +108,7 @@
   }
 
   protected:
-  HBFixed		version;	/* Version number of the font descriptors
+  HBFixed	version;	/* Version number of the font descriptors
 				 * table (0x00010000 for the current version). */
   LArrayOf<FontDescriptor>
 		descriptors;	/* List of tagged-coordinate pairs style descriptors

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-ankr-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-ankr-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-ankr-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -66,7 +66,7 @@
   {
     const NNOffsetTo<GlyphAnchors> *offset = (this+lookupTable).get_value (glyph_id, num_glyphs);
     if (!offset)
-      return Null(Anchor);
+      return Null (Anchor);
     const GlyphAnchors &anchors = &(this+anchorData) + *offset;
     return anchors[i];
   }
@@ -81,7 +81,7 @@
   }
 
   protected:
-  HBUINT16	version; 	/* Version number (set to zero) */
+  HBUINT16	version;	/* Version number (set to zero) */
   HBUINT16	flags;		/* Flags (currently unused; set to zero) */
   LOffsetTo<Lookup<NNOffsetTo<GlyphAnchors>>>
 		lookupTable;	/* Offset to the table's lookup table */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -303,7 +303,7 @@
   const typename T::type get_value_or_null (hb_codepoint_t glyph_id) const
   {
     if (!(firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount))
-      return Null(T);
+      return Null (T);
 
     const HBUINT8 *p = &valueArrayZ[(glyph_id - firstGlyph) * valueSize];
 
@@ -358,7 +358,7 @@
       case 10: return u.format10.get_value_or_null (glyph_id);
       default:
       const T *v = get_value (glyph_id, num_glyphs);
-      return v ? *v : Null(T);
+      return v ? *v : Null (T);
     }
   }
 
@@ -825,7 +825,7 @@
   HB_INTERNAL hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,
 				      hb_font_t *font_,
 				      hb_buffer_t *buffer_,
-				      hb_blob_t *blob = const_cast<hb_blob_t *> (&Null(hb_blob_t)));
+				      hb_blob_t *blob = const_cast<hb_blob_t *> (&Null (hb_blob_t)));
 
   HB_INTERNAL ~hb_aat_apply_context_t ();
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -129,6 +129,11 @@
 
   hb_ot_name_id_t get_feature_name_id () const { return nameIndex; }
 
+  bool is_exclusive () const { return featureFlags & Exclusive; }
+
+  /* A FeatureName with no settings is meaningless */
+  bool has_data () const { return nSettings; }
+
   bool sanitize (hb_sanitize_context_t *c, const void *base) const
   {
     TRACE_SANITIZE (this);
@@ -139,7 +144,7 @@
   protected:
   HBUINT16	feature;	/* Feature type. */
   HBUINT16	nSettings;	/* The number of records in the setting name array. */
-  LOffsetTo<UnsizedArrayOf<SettingName>, false>
+  LNNOffsetTo<UnsizedArrayOf<SettingName>>
 		settingTableZ;	/* Offset in bytes from the beginning of this table to
 				 * this feature's setting name array. The actual type of
 				 * record this offset refers to will depend on the
@@ -172,6 +177,9 @@
     return featureNameCount;
   }
 
+  bool exposes_feature (hb_aat_layout_feature_type_t feature_type) const
+  { return get_feature (feature_type).has_data (); }
+
   const FeatureName& get_feature (hb_aat_layout_feature_type_t feature_type) const
   { return namesZ.bsearch (featureNameCount, feature_type); }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -51,10 +51,10 @@
     return_trace (likely (c->check_struct (this)));
   }
 
-  HBUINT16 	actionClass; 	/* The JustClass value associated with this
+  HBUINT16	actionClass;	/* The JustClass value associated with this
 				 * ActionSubrecord. */
-  HBUINT16 	actionType; 	/* The type of postcompensation action. */
-  HBUINT16 	actionLength;	/* Length of this ActionSubrecord record, which
+  HBUINT16	actionType;	/* The type of postcompensation action. */
+  HBUINT16	actionLength;	/* Length of this ActionSubrecord record, which
 				 * must be a multiple of 4. */
   public:
   DEFINE_SIZE_STATIC (6);
@@ -70,11 +70,11 @@
 
   ActionSubrecordHeader
 		header;
-  HBFixed		lowerLimit; 	/* If the distance factor is less than this value,
+  HBFixed	lowerLimit;	/* If the distance factor is less than this value,
 				 * then the ligature is decomposed. */
-  HBFixed		upperLimit; 	/* If the distance factor is greater than this value,
+  HBFixed	upperLimit;	/* If the distance factor is greater than this value,
 				 * then the ligature is decomposed. */
-  HBUINT16 	order;		/* Numerical order in which this ligature will
+  HBUINT16	order;		/* Numerical order in which this ligature will
 				 * be decomposed; you may want infrequent ligatures
 				 * to decompose before more frequent ones. The ligatures
 				 * on the line of text will decompose in increasing
@@ -118,14 +118,14 @@
   protected:
   ActionSubrecordHeader
 		header;
-  HBFixed 	substThreshold; /* Distance growth factor (in ems) at which
+  HBFixed	substThreshold; /* Distance growth factor (in ems) at which
 				 * this glyph is replaced and the growth factor
 				 * recalculated. */
-  HBGlyphID 	addGlyph; 	/* Glyph to be added as kashida. If this value is
+  HBGlyphID	addGlyph;	/* Glyph to be added as kashida. If this value is
 				 * 0xFFFF, no extra glyph will be added. Note that
 				 * generally when a glyph is added, justification
 				 * will need to be redone. */
-  HBGlyphID 	substGlyph; 	/* Glyph to be substituted for this glyph if the
+  HBGlyphID	substGlyph;	/* Glyph to be substituted for this glyph if the
 				 * growth factor equals or exceeds the value of
 				 * substThreshold. */
   public:
@@ -143,16 +143,16 @@
   protected:
   ActionSubrecordHeader
 		header;
-  HBUINT32 	variationAxis;	/* The 4-byte tag identifying the ductile axis.
+  HBUINT32	variationAxis;	/* The 4-byte tag identifying the ductile axis.
 				 * This would normally be 0x64756374 ('duct'),
 				 * but you may use any axis the font contains. */
-  HBFixed 	minimumLimit; 	/* The lowest value for the ductility axis tha
+  HBFixed	minimumLimit;	/* The lowest value for the ductility axis tha
 				 * still yields an acceptable appearance. Normally
 				 * this will be 1.0. */
-  HBFixed 	noStretchValue; /* This is the default value that corresponds to
+  HBFixed	noStretchValue; /* This is the default value that corresponds to
 				 * no change in appearance. Normally, this will
 				 * be 1.0. */
-  HBFixed 	maximumLimit; 	/* The highest value for the ductility axis that
+  HBFixed	maximumLimit;	/* The highest value for the ductility axis that
 				 * still yields an acceptable appearance. */
   public:
   DEFINE_SIZE_STATIC (22);
@@ -169,8 +169,8 @@
   protected:
   ActionSubrecordHeader
 		header;
-  HBUINT16 	flags;		/* Currently unused; set to 0. */
-  HBGlyphID 	glyph;		/* Glyph that should be added if the distance factor
+  HBUINT16	flags;		/* Currently unused; set to 0. */
+  HBGlyphID	glyph;		/* Glyph that should be added if the distance factor
 				 * is growing. */
   public:
   DEFINE_SIZE_STATIC (10);
@@ -271,14 +271,14 @@
   };
 
   protected:
-  HBFixed		beforeGrowLimit;/* The ratio by which the advance width of the
+  HBFixed	beforeGrowLimit;/* The ratio by which the advance width of the
 				 * glyph is permitted to grow on the left or top side. */
-  HBFixed		beforeShrinkLimit;
+  HBFixed	beforeShrinkLimit;
 				/* The ratio by which the advance width of the
 				 * glyph is permitted to shrink on the left or top side. */
-  HBFixed		afterGrowLimit;	/* The ratio by which the advance width of the glyph
+  HBFixed	afterGrowLimit;	/* The ratio by which the advance width of the glyph
 				 * is permitted to shrink on the left or top side. */
-  HBFixed		afterShrinkLimit;
+  HBFixed	afterShrinkLimit;
 				/* The ratio by which the advance width of the glyph
 				 * is at most permitted to shrink on the right or
 				 * bottom side. */
@@ -361,7 +361,7 @@
   OffsetTo<JustificationCategory>
 		justClassTable;	/* Offset to the justification category state table. */
   OffsetTo<WidthDeltaCluster>
-  		wdcTable;	/* Offset from start of justification table to start
+		wdcTable;	/* Offset from start of justification table to start
 				 * of the subtable containing the width delta factors
 				 * for the glyphs in your font.
 				 *
@@ -372,7 +372,7 @@
 				 *
 				 * The postcompensation subtable, if present in the font. */
   Lookup<OffsetTo<WidthDeltaCluster>>
-  		lookupTable;	/* Lookup table associating glyphs with width delta
+		lookupTable;	/* Lookup table associating glyphs with width delta
 				 * clusters. See the description of Width Delta Clusters
 				 * table for details on how to interpret the lookup values. */
 
@@ -397,7 +397,7 @@
   protected:
   FixedVersion<>version;	/* Version of the justification table
 				 * (0x00010000u for version 1.0). */
-  HBUINT16	format; 	/* Format of the justification table (set to 0). */
+  HBUINT16	format;		/* Format of the justification table (set to 0). */
   OffsetTo<JustificationHeader>
 		horizData;	/* Byte offset from the start of the justification table
 				 * to the header for tables that contain justification

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -281,35 +281,28 @@
 
 	  hb_glyph_position_t &o = buffer->pos[idx];
 
-	  /* Testing shows that CoreText only applies kern (cross-stream or not)
-	   * if none has been applied by previous subtables.  That is, it does
-	   * NOT seem to accumulate as otherwise implied by specs. */
-
-	  /* The following flag is undocumented in the spec, but described
-	   * in the 'kern' table example. */
-	  if (v == -0x8000)
+	  if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
 	  {
-	    o.attach_type() = ATTACH_TYPE_NONE;
-	    o.attach_chain() = 0;
-	    o.x_offset = o.y_offset = 0;
-	  }
-	  else if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
-	  {
 	    if (crossStream)
 	    {
-	      if (buffer->pos[idx].attach_type() && !buffer->pos[idx].y_offset)
+	      /* The following flag is undocumented in the spec, but described
+	       * in the 'kern' table example. */
+	      if (v == -0x8000)
 	      {
-		o.y_offset = c->font->em_scale_y (v);
+		o.attach_type() = ATTACH_TYPE_NONE;
+		o.attach_chain() = 0;
+		o.y_offset = 0;
+	      }
+	      else if (o.attach_type())
+	      {
+		o.y_offset += c->font->em_scale_y (v);
 		buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
 	      }
 	    }
 	    else if (buffer->info[idx].mask & kern_mask)
 	    {
-	      if (!buffer->pos[idx].x_offset)
-	      {
-		buffer->pos[idx].x_advance += c->font->em_scale_x (v);
-		buffer->pos[idx].x_offset += c->font->em_scale_x (v);
-	      }
+	      o.x_advance += c->font->em_scale_x (v);
+	      o.x_offset += c->font->em_scale_x (v);
 	    }
 	  }
 	  else
@@ -317,19 +310,22 @@
 	    if (crossStream)
 	    {
 	      /* CoreText doesn't do crossStream kerning in vertical.  We do. */
-	      if (buffer->pos[idx].attach_type() && !buffer->pos[idx].x_offset)
+	      if (v == -0x8000)
 	      {
-		o.x_offset = c->font->em_scale_x (v);
+		o.attach_type() = ATTACH_TYPE_NONE;
+		o.attach_chain() = 0;
+		o.x_offset = 0;
+	      }
+	      else if (o.attach_type())
+	      {
+		o.x_offset += c->font->em_scale_x (v);
 		buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
 	      }
 	    }
 	    else if (buffer->info[idx].mask & kern_mask)
 	    {
-	      if (!buffer->pos[idx].y_offset)
-	      {
-		buffer->pos[idx].y_advance += c->font->em_scale_y (v);
-		buffer->pos[idx].y_offset += c->font->em_scale_y (v);
-	      }
+	      o.y_advance += c->font->em_scale_y (v);
+	      o.y_offset += c->font->em_scale_y (v);
 	    }
 	  }
 	}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -948,8 +948,10 @@
 	hb_aat_layout_feature_type_t type = (hb_aat_layout_feature_type_t) (unsigned int) feature.featureType;
 	hb_aat_layout_feature_selector_t setting = (hb_aat_layout_feature_selector_t) (unsigned int) feature.featureSetting;
       retry:
-	const hb_aat_map_builder_t::feature_info_t *info = map->features.bsearch (type);
-	if (info && info->setting == setting)
+	// Check whether this type/setting pair was requested in the map, and if so, apply its flags.
+	// (The search here only looks at the type and setting fields of feature_info_t.)
+	hb_aat_map_builder_t::feature_info_t info = { type, setting, false, 0 };
+	if (map->features.bsearch (info))
 	{
 	  flags &= feature.disableFlags;
 	  flags |= feature.enableFlags;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-opbd-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-opbd-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-opbd-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -160,8 +160,8 @@
 				 * Format 0 indicates distance and Format 1 indicates
 				 * control point. */
   union {
-  opbdFormat0 format0;
-  opbdFormat1 format1;
+  opbdFormat0	format0;
+  opbdFormat1	format1;
   } u;
   public:
   DEFINE_SIZE_MIN (8);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -62,7 +62,7 @@
   }
 
   protected:
-  HBFixed		track;		/* Track value for this record. */
+  HBFixed	track;		/* Track value for this record. */
   NameID	trackNameID;	/* The 'name' table index for this track.
 				 * (a short word or phrase like "loose"
 				 * or "very tight") */
@@ -141,7 +141,7 @@
   protected:
   HBUINT16	nTracks;	/* Number of separate tracks included in this table. */
   HBUINT16	nSizes;		/* Number of point sizes included in this table. */
-  LOffsetTo<UnsizedArrayOf<HBFixed>, false>
+  LNNOffsetTo<UnsizedArrayOf<HBFixed>>
 		sizeTable;	/* Offset from start of the tracking table to
 				 * Array[nSizes] of size values.. */
   UnsizedArrayOf<TrackTableEntry>
@@ -210,8 +210,8 @@
 
   protected:
   FixedVersion<>version;	/* Version of the tracking table
-					 * (0x00010000u for version 1.0). */
-  HBUINT16	format; 	/* Format of the tracking table (set to 0). */
+				 * (0x00010000u for version 1.0). */
+  HBUINT16	format;		/* Format of the tracking table (set to 0). */
   OffsetTo<TrackData>
 		horizData;	/* Offset from start of tracking table to TrackData
 				 * for horizontal text (or 0 if none). */

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	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -55,7 +55,7 @@
 						       face (font->face),
 						       buffer (buffer_),
 						       sanitizer (),
-						       ankr_table (&Null(AAT::ankr)),
+						       ankr_table (&Null (AAT::ankr)),
 						       lookup_index (0),
 						       debug_depth (0)
 {
@@ -172,11 +172,7 @@
 const hb_aat_feature_mapping_t *
 hb_aat_layout_find_feature_mapping (hb_tag_t tag)
 {
-  return (const hb_aat_feature_mapping_t *) hb_bsearch (&tag,
-							feature_mappings,
-							ARRAY_LENGTH (feature_mappings),
-							sizeof (feature_mappings[0]),
-							hb_aat_feature_mapping_t::cmp);
+  return hb_sorted_array (feature_mappings).bsearch (tag);
 }
 #endif
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -39,14 +39,8 @@
   hb_aat_layout_feature_selector_t selectorToEnable;
   hb_aat_layout_feature_selector_t selectorToDisable;
 
-  HB_INTERNAL static int cmp (const void *key_, const void *entry_)
-  {
-    hb_tag_t key = * (unsigned int *) key_;
-    const hb_aat_feature_mapping_t * entry = (const hb_aat_feature_mapping_t *) entry_;
-    return key < entry->otFeatureTag ? -1 :
-	   key > entry->otFeatureTag ? 1 :
-	   0;
-  }
+  int cmp (hb_tag_t key) const
+  { return key < otFeatureTag ? -1 : key > otFeatureTag ? 1 : 0; }
 };
 
 HB_INTERNAL const hb_aat_feature_mapping_t *

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -33,16 +33,22 @@
 #include "hb-aat-map.hh"
 
 #include "hb-aat-layout.hh"
+#include "hb-aat-layout-feat-table.hh"
 
 
-void hb_aat_map_builder_t::add_feature (hb_tag_t tag,
-					unsigned int value)
+void hb_aat_map_builder_t::add_feature (hb_tag_t tag, unsigned value)
 {
+  if (!face->table.feat->has_data ()) return;
+
   if (tag == HB_TAG ('a','a','l','t'))
   {
+    if (!face->table.feat->exposes_feature (HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES))
+      return;
     feature_info_t *info = features.push();
     info->type = HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES;
     info->setting = (hb_aat_layout_feature_selector_t) value;
+    info->seq = features.length;
+    info->is_exclusive = true;
     return;
   }
 
@@ -49,9 +55,26 @@
   const hb_aat_feature_mapping_t *mapping = hb_aat_layout_find_feature_mapping (tag);
   if (!mapping) return;
 
+  const AAT::FeatureName* feature = &face->table.feat->get_feature (mapping->aatFeatureType);
+  if (!feature->has_data ())
+  {
+    /* Special case: Chain::compile_flags will fall back to the deprecated version of
+     * small-caps if necessary, so we need to check for that possibility.
+     * https://github.com/harfbuzz/harfbuzz/issues/2307 */
+    if (mapping->aatFeatureType == HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE &&
+	mapping->selectorToEnable == HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS)
+    {
+      feature = &face->table.feat->get_feature (HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE);
+      if (!feature->has_data ()) return;
+    }
+    else return;
+  }
+
   feature_info_t *info = features.push();
   info->type = mapping->aatFeatureType;
   info->setting = value ? mapping->selectorToEnable : mapping->selectorToDisable;
+  info->seq = features.length;
+  info->is_exclusive = feature->is_exclusive ();
 }
 
 void
@@ -63,7 +86,11 @@
     features.qsort ();
     unsigned int j = 0;
     for (unsigned int i = 1; i < features.length; i++)
-      if (features[i].type != features[j].type)
+      if (features[i].type != features[j].type ||
+	  /* Nonexclusive feature selectors come in even/odd pairs to turn a setting on/off
+	   * respectively, so we mask out the low-order bit when checking for "duplicates"
+	   * (selectors referring to the same feature setting) here. */
+	  (!features[i].is_exclusive && ((features[i].setting & ~1) != (features[j].setting & ~1))))
 	features[++j] = features[i];
     features.shrink (j + 1);
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -64,6 +64,7 @@
   {
     hb_aat_layout_feature_type_t  type;
     hb_aat_layout_feature_selector_t  setting;
+    bool is_exclusive;
     unsigned  seq; /* For stable sorting only. */
 
     HB_INTERNAL static int cmp (const void *pa, const void *pb)
@@ -70,13 +71,17 @@
     {
       const feature_info_t *a = (const feature_info_t *) pa;
       const feature_info_t *b = (const feature_info_t *) pb;
-      return (a->type != b->type) ? (a->type < b->type ? -1 : 1) :
-	     (a->seq < b->seq ? -1 : a->seq > b->seq ? 1 : 0);
+      if (a->type != b->type) return (a->type < b->type ? -1 : 1);
+      if (!a->is_exclusive &&
+	  (a->setting & ~1) != (b->setting & ~1)) return (a->setting < b->setting ? -1 : 1);
+	    return (a->seq < b->seq ? -1 : a->seq > b->seq ? 1 : 0);
     }
 
-    int cmp (hb_aat_layout_feature_type_t ty) const
+    /* compares type & setting only, not is_exclusive flag or seq number */
+    int cmp (const feature_info_t& f) const
     {
-      return (type != ty) ? (type < ty ? -1 : 1) : 0;
+      return (f.type != type) ? (f.type < type ? -1 : 1) :
+	     (f.setting != setting) ? (f.setting < setting ? -1 : 1) : 0;
     }
   };
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -360,6 +360,13 @@
   (hb_forward<T> (a) >= hb_forward<T2> (b) ? hb_forward<T> (a) : hb_forward<T2> (b))
 }
 HB_FUNCOBJ (hb_max);
+struct
+{
+  template <typename T, typename T2, typename T3> constexpr auto
+  operator () (T&& x, T2&& min, T3&& max) const HB_AUTO_RETURN
+  (hb_min (hb_max (hb_forward<T> (x), hb_forward<T2> (min)), hb_forward<T3> (max)))
+}
+HB_FUNCOBJ (hb_clamp);
 
 
 /*
@@ -486,7 +493,7 @@
 static inline HB_CONST_FUNC unsigned int
 hb_ctz (T v)
 {
-  if (unlikely (!v)) return 0;
+  if (unlikely (!v)) return 8 * sizeof (T);
 
 #if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
   if (sizeof (T) <= sizeof (unsigned int))
@@ -600,12 +607,6 @@
   return memset (s, c, n);
 }
 
-static inline bool
-hb_unsigned_mul_overflows (unsigned int count, unsigned int size)
-{
-  return (size > 0) && (count >= ((unsigned int) -1) / size);
-}
-
 static inline unsigned int
 hb_ceil_to_4 (unsigned int v)
 {
@@ -634,32 +635,93 @@
 
 
 /*
+ * Overflow checking.
+ */
+
+/* Consider __builtin_mul_overflow use here also */
+static inline bool
+hb_unsigned_mul_overflows (unsigned int count, unsigned int size)
+{
+  return (size > 0) && (count >= ((unsigned int) -1) / size);
+}
+
+
+/*
  * Sort and search.
  */
-template <typename ...Ts>
-static inline void *
-hb_bsearch (const void *key, const void *base,
-	    size_t nmemb, size_t size,
-	    int (*compar)(const void *_key, const void *_item, Ts... _ds),
-	    Ts... ds)
+
+template <typename K, typename V, typename ...Ts>
+static int
+_hb_cmp_method (const void *pkey, const void *pval, Ts... ds)
 {
+  const K& key = * (const K*) pkey;
+  const V& val = * (const V*) pval;
+
+  return val.cmp (key, ds...);
+}
+
+template <typename V, typename K, typename ...Ts>
+static inline bool
+hb_bsearch_impl (unsigned *pos, /* Out */
+		 const K& key,
+		 V* base, size_t nmemb, size_t stride,
+		 int (*compar)(const void *_key, const void *_item, Ts... _ds),
+		 Ts... ds)
+{
+  /* This is our *only* bsearch implementation. */
+
   int min = 0, max = (int) nmemb - 1;
   while (min <= max)
   {
     int mid = ((unsigned int) min + (unsigned int) max) / 2;
-    const void *p = (const void *) (((const char *) base) + (mid * size));
-    int c = compar (key, p, ds...);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+    V* p = (V*) (((const char *) base) + (mid * stride));
+#pragma GCC diagnostic pop
+    int c = compar ((const void *) hb_addressof (key), (const void *) p, ds...);
     if (c < 0)
       max = mid - 1;
     else if (c > 0)
       min = mid + 1;
     else
-      return (void *) p;
+    {
+      *pos = mid;
+      return true;
+    }
   }
-  return nullptr;
+  *pos = min;
+  return false;
 }
 
+template <typename V, typename K>
+static inline V*
+hb_bsearch (const K& key, V* base,
+	    size_t nmemb, size_t stride = sizeof (V),
+	    int (*compar)(const void *_key, const void *_item) = _hb_cmp_method<K, V>)
+{
+  unsigned pos;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+  return hb_bsearch_impl (&pos, key, base, nmemb, stride, compar) ?
+	 (V*) (((const char *) base) + (pos * stride)) : nullptr;
+#pragma GCC diagnostic pop
+}
+template <typename V, typename K, typename ...Ts>
+static inline V*
+hb_bsearch (const K& key, V* base,
+	    size_t nmemb, size_t stride,
+	    int (*compar)(const void *_key, const void *_item, Ts... _ds),
+	    Ts... ds)
+{
+  unsigned pos;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+  return hb_bsearch_impl (&pos, key, base, nmemb, stride, compar, ds...) ?
+	 (V*) (((const char *) base) + (pos * stride)) : nullptr;
+#pragma GCC diagnostic pop
+}
 
+
 /* From https://github.com/noporpoise/sort_r
    Feb 5, 2019 (c8c65c1e)
    Modified to support optional argument using templates */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -171,6 +171,24 @@
 
   unsigned int get_size () const { return length * this->get_item_size (); }
 
+  /*
+   * Reverse the order of items in this array in the range [start, end).
+   */
+  void reverse (unsigned start = 0, unsigned end = -1)
+  {
+    start = hb_min (start, length);
+    end = hb_min (end, length);
+
+    if (end < start + 2)
+      return;
+
+    for (unsigned lhs = start, rhs = end - 1; lhs < rhs; lhs++, rhs--) {
+      Type temp = arrayZ[rhs];
+      arrayZ[rhs] = arrayZ[lhs];
+      arrayZ[lhs] = temp;
+    }
+  }
+
   hb_array_t sub_array (unsigned int start_offset = 0, unsigned int *seg_count = nullptr /* IN/OUT */) const
   {
     if (!start_offset && !seg_count)
@@ -199,10 +217,11 @@
   template <typename T,
 	    unsigned P = sizeof (Type),
 	    hb_enable_if (P == 1)>
-  bool in_range (const T *p, unsigned int size = T::static_size) const
+  bool check_range (const T *p, unsigned int size = T::static_size) const
   {
-    return ((const char *) p) >= arrayZ
-	&& ((const char *) p + size) <= arrayZ + length;
+    return arrayZ <= ((const char *) p)
+	&& ((const char *) p) <= arrayZ + length
+	&& (unsigned int) (arrayZ + length - (const char *) p) >= size;
   }
 
   /* Only call if you allocated the underlying array using malloc() or similar. */
@@ -300,23 +319,15 @@
 	      hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
 	      unsigned int to_store = (unsigned int) -1) const
   {
-    int min = 0, max = (int) this->length - 1;
-    const Type *array = this->arrayZ;
-    while (min <= max)
+    unsigned pos;
+
+    if (bsearch_impl (x, &pos))
     {
-      int mid = ((unsigned int) min + (unsigned int) max) / 2;
-      int c = array[mid].cmp (x);
-      if (c < 0)
-	max = mid - 1;
-      else if (c > 0)
-	min = mid + 1;
-      else
-      {
-	if (i)
-	  *i = mid;
-	return true;
-      }
+      if (i)
+	*i = pos;
+      return true;
     }
+
     if (i)
     {
       switch (not_found)
@@ -329,14 +340,22 @@
 	  break;
 
 	case HB_BFIND_NOT_FOUND_STORE_CLOSEST:
-	  if (max < 0 || (max < (int) this->length && array[max].cmp (x) > 0))
-	    max++;
-	  *i = max;
+	  *i = pos;
 	  break;
       }
     }
     return false;
   }
+  template <typename T>
+  bool bsearch_impl (const T &x, unsigned *pos) const
+  {
+    return hb_bsearch_impl (pos,
+			    x,
+			    this->arrayZ,
+			    this->length,
+			    sizeof (Type),
+			    _hb_cmp_method<T, Type>);
+  }
 };
 template <typename T> inline hb_sorted_array_t<T>
 hb_sorted_array (T *array, unsigned int length)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -151,9 +151,9 @@
 
     for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
       work[rhs] = back_map[rhs];
-  
+
     work.qsort (cmp_id);
-  
+
     clear ();
     for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
       set (work[rhs], rhs);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -25,18 +25,6 @@
  * Red Hat Author(s): Behdad Esfahbod
  */
 
-
-/* https://github.com/harfbuzz/harfbuzz/issues/1308
- * http://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html
- * https://www.oracle.com/technetwork/articles/servers-storage-dev/standardheaderfiles-453865.html
- */
-#if !defined(_POSIX_C_SOURCE) && !defined(_MSC_VER) && !defined(__NetBSD__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-macros"
-#define _POSIX_C_SOURCE 200809L
-#pragma GCC diagnostic pop
-#endif
-
 #include "hb.hh"
 #include "hb-blob.hh"
 
@@ -201,7 +189,7 @@
 hb_blob_t *
 hb_blob_get_empty ()
 {
-  return const_cast<hb_blob_t *> (&Null(hb_blob_t));
+  return const_cast<hb_blob_t *> (&Null (hb_blob_t));
 }
 
 /**
@@ -488,6 +476,9 @@
 
 #ifndef HB_NO_OPEN
 #ifdef HAVE_MMAP
+# if !defined(HB_NO_RESOURCE_FORK) && defined(__APPLE__)
+#  include <sys/paths.h>
+# endif
 # include <sys/types.h>
 # include <sys/stat.h>
 # include <fcntl.h>
@@ -532,6 +523,39 @@
 }
 #endif
 
+#ifdef _PATH_RSRCFORKSPEC
+static int
+_open_resource_fork (const char *file_name, hb_mapped_file_t *file)
+{
+  size_t name_len = strlen (file_name);
+  size_t len = name_len + sizeof (_PATH_RSRCFORKSPEC);
+
+  char *rsrc_name = (char *) malloc (len);
+  if (unlikely (!rsrc_name)) return -1;
+
+  strncpy (rsrc_name, file_name, name_len);
+  strncpy (rsrc_name + name_len, _PATH_RSRCFORKSPEC,
+	   sizeof (_PATH_RSRCFORKSPEC) - 1);
+
+  int fd = open (rsrc_name, O_RDONLY | O_BINARY, 0);
+  free (rsrc_name);
+
+  if (fd != -1)
+  {
+    struct stat st;
+    if (fstat (fd, &st) != -1)
+      file->length = (unsigned long) st.st_size;
+    else
+    {
+      close (fd);
+      fd = -1;
+    }
+  }
+
+  return fd;
+}
+#endif
+
 /**
  * hb_blob_create_from_file:
  * @file_name: font filename.
@@ -556,6 +580,19 @@
   if (unlikely (fstat (fd, &st) == -1)) goto fail;
 
   file->length = (unsigned long) st.st_size;
+
+#ifdef _PATH_RSRCFORKSPEC
+  if (unlikely (file->length == 0))
+  {
+    int rfd = _open_resource_fork (file_name, file);
+    if (rfd != -1)
+    {
+      close (fd);
+      fd = rfd;
+    }
+  }
+#endif
+
   file->contents = (char *) mmap (nullptr, file->length, PROT_READ,
 				  MAP_PRIVATE | MAP_NORESERVE, fd, 0);
 
@@ -579,7 +616,7 @@
   HANDLE fd;
   unsigned int size = strlen (file_name) + 1;
   wchar_t * wchar_file_name = (wchar_t *) malloc (sizeof (wchar_t) * size);
-  if (unlikely (wchar_file_name == nullptr)) goto fail_without_close;
+  if (unlikely (!wchar_file_name)) goto fail_without_close;
   mbstowcs (wchar_file_name, file_name, size);
 #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
   {
@@ -613,7 +650,7 @@
   file->length = (unsigned long) GetFileSize (fd, nullptr);
   file->mapping = CreateFileMapping (fd, nullptr, PAGE_READONLY, 0, 0, nullptr);
 #endif
-  if (unlikely (file->mapping == nullptr)) goto fail;
+  if (unlikely (!file->mapping)) goto fail;
 
 #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
   file->contents = (char *) MapViewOfFileFromApp (file->mapping, FILE_MAP_READ, 0, 0);
@@ -620,7 +657,7 @@
 #else
   file->contents = (char *) MapViewOfFile (file->mapping, FILE_MAP_READ, 0, 0, 0);
 #endif
-  if (unlikely (file->contents == nullptr)) goto fail;
+  if (unlikely (!file->contents)) goto fail;
 
   CloseHandle (fd);
   return hb_blob_create (file->contents, file->length,
@@ -638,10 +675,10 @@
      It's used as a fallback for systems without mmap or to read from pipes */
   unsigned long len = 0, allocated = BUFSIZ * 16;
   char *data = (char *) malloc (allocated);
-  if (unlikely (data == nullptr)) return hb_blob_get_empty ();
+  if (unlikely (!data)) return hb_blob_get_empty ();
 
   FILE *fp = fopen (file_name, "rb");
-  if (unlikely (fp == nullptr)) goto fread_fail_without_close;
+  if (unlikely (!fp)) goto fread_fail_without_close;
 
   while (!feof (fp))
   {
@@ -652,7 +689,7 @@
 	 can cover files like that but lets limit our fallback reader */
       if (unlikely (allocated > (2 << 28))) goto fread_fail;
       char *new_data = (char *) realloc (data, allocated);
-      if (unlikely (new_data == nullptr)) goto fread_fail;
+      if (unlikely (!new_data)) goto fread_fail;
       data = new_data;
     }
 
@@ -666,6 +703,7 @@
 
     len += addition;
   }
+	fclose (fp);
 
   return hb_blob_create (data, len, HB_MEMORY_MODE_WRITABLE, data,
 			 (hb_destroy_func_t) free);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -438,13 +438,6 @@
   if (!mask)
     return;
 
-  if (cluster_start == 0 && cluster_end == (unsigned int)-1) {
-    unsigned int count = len;
-    for (unsigned int i = 0; i < count; i++)
-      info[i].mask = (info[i].mask & not_mask) | value;
-    return;
-  }
-
   unsigned int count = len;
   for (unsigned int i = 0; i < count; i++)
     if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end)
@@ -455,27 +448,13 @@
 hb_buffer_t::reverse_range (unsigned int start,
 			    unsigned int end)
 {
-  unsigned int i, j;
-
   if (end - start < 2)
     return;
 
-  for (i = start, j = end - 1; i < j; i++, j--) {
-    hb_glyph_info_t t;
+  hb_array_t<hb_glyph_info_t> (info, len).reverse (start, end);
 
-    t = info[i];
-    info[i] = info[j];
-    info[j] = t;
-  }
-
   if (have_positions) {
-    for (i = start, j = end - 1; i < j; i++, j--) {
-      hb_glyph_position_t t;
-
-      t = pos[i];
-      pos[i] = pos[j];
-      pos[j] = t;
-    }
+    hb_array_t<hb_glyph_position_t> (pos, len).reverse (start, end);
   }
 }
 
@@ -612,7 +591,7 @@
 void
 hb_buffer_t::unsafe_to_break_impl (unsigned int start, unsigned int end)
 {
-  unsigned int cluster = (unsigned int) -1;
+  unsigned int cluster = UINT_MAX;
   cluster = _unsafe_to_break_find_min_cluster (info, start, end, cluster);
   _unsafe_to_break_set_mask (info, start, end, cluster);
 }
@@ -628,7 +607,7 @@
   assert (start <= out_len);
   assert (idx <= end);
 
-  unsigned int cluster = (unsigned int) -1;
+  unsigned int cluster = UINT_MAX;
   cluster = _unsafe_to_break_find_min_cluster (out_info, start, out_len, cluster);
   cluster = _unsafe_to_break_find_min_cluster (info, idx, end, cluster);
   _unsafe_to_break_set_mask (out_info, start, out_len, cluster);
@@ -736,7 +715,7 @@
 hb_buffer_t *
 hb_buffer_get_empty ()
 {
-  return const_cast<hb_buffer_t *> (&Null(hb_buffer_t));
+  return const_cast<hb_buffer_t *> (&Null (hb_buffer_t));
 }
 
 /**
@@ -958,7 +937,7 @@
  *
  * You can pass one of the predefined #hb_script_t values, or use
  * hb_script_from_string() or hb_script_from_iso15924_tag() to get the
- * corresponding script from an ISO 15924 script tag.
+ * corresponding script from an ISO 15924 script tag.
  *
  * Since: 0.9.2
  **/
@@ -1001,7 +980,7 @@
  * are orthogonal to the scripts, and though they are related, they are
  * different concepts and should not be confused with each other.
  *
- * Use hb_language_from_string() to convert from BCP 47 language tags to
+ * Use hb_language_from_string() to convert from BCP 47 language tags to
  * #hb_language_t.
  *
  * Since: 0.9.2
@@ -1738,7 +1717,7 @@
  * @buffer: an #hb_buffer_t.
  * @source: source #hb_buffer_t.
  * @start: start index into source buffer to copy.  Use 0 to copy from start of buffer.
- * @end: end index into source buffer to copy.  Use (unsigned int) -1 to copy to end of buffer.
+ * @end: end index into source buffer to copy.  Use @HB_FEATURE_GLOBAL_END to copy to end of buffer.
  *
  * Append (part of) contents of another buffer to this buffer.
  *
@@ -1860,18 +1839,8 @@
 
   bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
 
-  unsigned int count = buffer->len;
-  if (unlikely (!count)) return;
-  hb_glyph_info_t *info = buffer->info;
-
-  unsigned int start = 0;
-  unsigned int end;
-  for (end = start + 1; end < count; end++)
-    if (info[start].cluster != info[end].cluster) {
-      normalize_glyphs_cluster (buffer, start, end, backward);
-      start = end;
-    }
-  normalize_glyphs_cluster (buffer, start, end, backward);
+  foreach_cluster (buffer, start, end)
+    normalize_glyphs_cluster (buffer, start, end, backward);
 }
 
 void

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h	2020-05-18 10:44:36 UTC (rev 55197)
@@ -365,7 +365,7 @@
 
 HB_EXTERN hb_bool_t
 hb_buffer_pre_allocate (hb_buffer_t  *buffer,
-		        unsigned int  size);
+			unsigned int  size);
 
 
 HB_EXTERN hb_bool_t

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -228,10 +228,10 @@
   /* Makes a copy of the glyph at idx to output and replace glyph_index */
   hb_glyph_info_t & output_glyph (hb_codepoint_t glyph_index)
   {
-    if (unlikely (!make_room_for (0, 1))) return Crap(hb_glyph_info_t);
+    if (unlikely (!make_room_for (0, 1))) return Crap (hb_glyph_info_t);
 
     if (unlikely (idx == len && !out_len))
-      return Crap(hb_glyph_info_t);
+      return Crap (hb_glyph_info_t);
 
     out_info[out_len] = idx < len ? info[idx] : out_info[out_len - 1];
     out_info[out_len].codepoint = glyph_index;
@@ -386,7 +386,7 @@
     inf.cluster = cluster;
   }
 
-  int
+  unsigned int
   _unsafe_to_break_find_min_cluster (const hb_glyph_info_t *infos,
 				     unsigned int start, unsigned int end,
 				     unsigned int cluster) const

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -252,30 +252,27 @@
 struct UnsizedByteStr : UnsizedArrayOf <HBUINT8>
 {
   // encode 2-byte int (Dict/CharString) or 4-byte int (Dict)
-  template <typename INTTYPE, int minVal, int maxVal>
-  static bool serialize_int (hb_serialize_context_t *c, op_code_t intOp, int value)
+  template <typename T, typename V>
+  static bool serialize_int (hb_serialize_context_t *c, op_code_t intOp, V value)
   {
     TRACE_SERIALIZE (this);
 
-    if (unlikely ((value < minVal || value > maxVal)))
-      return_trace (false);
-
     HBUINT8 *p = c->allocate_size<HBUINT8> (1);
-    if (unlikely (p == nullptr)) return_trace (false);
+    if (unlikely (!p)) return_trace (false);
     *p = intOp;
 
-    INTTYPE *ip = c->allocate_size<INTTYPE> (INTTYPE::static_size);
-    if (unlikely (ip == nullptr)) return_trace (false);
-    *ip = (unsigned int) value;
-
-    return_trace (true);
+    T *ip = c->allocate_size<T> (T::static_size);
+    if (unlikely (!ip)) return_trace (false);
+    return_trace (c->check_assign (*ip, value));
   }
 
-  static bool serialize_int4 (hb_serialize_context_t *c, int value)
-  { return serialize_int<HBUINT32, 0, 0x7FFFFFFF> (c, OpCode_longintdict, value); }
+  template <typename V>
+  static bool serialize_int4 (hb_serialize_context_t *c, V value)
+  { return serialize_int<HBINT32> (c, OpCode_longintdict, value); }
 
-  static bool serialize_int2 (hb_serialize_context_t *c, int value)
-  { return serialize_int<HBUINT16, 0, 0x7FFF> (c, OpCode_shortint, value); }
+  template <typename V>
+  static bool serialize_int2 (hb_serialize_context_t *c, V value)
+  { return serialize_int<HBINT16> (c, OpCode_shortint, value); }
 
   /* Defining null_size allows a Null object may be created. Should be safe because:
    * A descendent struct Dict uses a Null pointer to indicate a missing table,
@@ -408,7 +405,7 @@
     else
     {
       set_error ();
-      return Crap(ELEM);
+      return Crap (ELEM);
     }
   }
 
@@ -419,7 +416,7 @@
     else
     {
       set_error ();
-      return Crap(ELEM);
+      return Crap (ELEM);
     }
   }
   void pop (unsigned int n)
@@ -435,7 +432,7 @@
     if (unlikely (count < 0))
     {
       set_error ();
-      return Null(ELEM);
+      return Null (ELEM);
     }
     return elements[count - 1];
   }
@@ -542,7 +539,7 @@
     TRACE_SERIALIZE (this);
 
     HBUINT8 *d = c->allocate_size<HBUINT8> (opstr.str.length);
-    if (unlikely (d == nullptr)) return_trace (false);
+    if (unlikely (!d)) return_trace (false);
     memcpy (d, &opstr.str[0], opstr.str.length);
     return_trace (true);
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-cs-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-cs-common.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-cs-common.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -76,13 +76,13 @@
 
   void fini () {}
 
-  unsigned int get_count () const { return (subrs == nullptr) ? 0 : subrs->count; }
+  unsigned int get_count () const { return subrs ? subrs->count : 0; }
   unsigned int get_bias () const  { return bias; }
 
   byte_str_t operator [] (unsigned int index) const
   {
-    if (unlikely ((subrs == nullptr) || index >= subrs->count))
-      return Null(byte_str_t);
+    if (unlikely (!subrs || index >= subrs->count))
+      return Null (byte_str_t);
     else
       return (*subrs)[index];
   }
@@ -551,8 +551,13 @@
 
   static void rcurveline (ENV &env, PARAM& param)
   {
+    unsigned int arg_count = env.argStack.get_count ();
+    if (unlikely (arg_count < 8))
+      return;
+
     unsigned int i = 0;
-    for (; i + 6 <= env.argStack.get_count (); i += 6)
+    unsigned int curve_limit = arg_count - 2;
+    for (; i + 6 <= curve_limit; i += 6)
     {
       point_t pt1 = env.get_pt ();
       pt1.move (env.eval_arg (i), env.eval_arg (i+1));
@@ -562,18 +567,20 @@
       pt3.move (env.eval_arg (i+4), env.eval_arg (i+5));
       PATH::curve (env, param, pt1, pt2, pt3);
     }
-    for (; i + 2 <= env.argStack.get_count (); i += 2)
-    {
-      point_t pt1 = env.get_pt ();
-      pt1.move (env.eval_arg (i), env.eval_arg (i+1));
-      PATH::line (env, param, pt1);
-    }
+
+    point_t pt1 = env.get_pt ();
+    pt1.move (env.eval_arg (i), env.eval_arg (i+1));
+    PATH::line (env, param, pt1);
   }
 
   static void rlinecurve (ENV &env, PARAM& param)
   {
+    unsigned int arg_count = env.argStack.get_count ();
+    if (unlikely (arg_count < 8))
+      return;
+
     unsigned int i = 0;
-    unsigned int line_limit = (env.argStack.get_count () % 6);
+    unsigned int line_limit = arg_count - 6;
     for (; i + 2 <= line_limit; i += 2)
     {
       point_t pt1 = env.get_pt ();
@@ -580,16 +587,14 @@
       pt1.move (env.eval_arg (i), env.eval_arg (i+1));
       PATH::line (env, param, pt1);
     }
-    for (; i + 6 <= env.argStack.get_count (); i += 6)
-    {
-      point_t pt1 = env.get_pt ();
-      pt1.move (env.eval_arg (i), env.eval_arg (i+1));
-      point_t pt2 = pt1;
-      pt2.move (env.eval_arg (i+2), env.eval_arg (i+3));
-      point_t pt3 = pt2;
-      pt3.move (env.eval_arg (i+4), env.eval_arg (i+5));
-      PATH::curve (env, param, pt1, pt2, pt3);
-    }
+
+    point_t pt1 = env.get_pt ();
+    pt1.move (env.eval_arg (i), env.eval_arg (i+1));
+    point_t pt2 = pt1;
+    pt2.move (env.eval_arg (i+2), env.eval_arg (i+3));
+    point_t pt3 = pt2;
+    pt3.move (env.eval_arg (i+4), env.eval_arg (i+5));
+    PATH::curve (env, param, pt1, pt2, pt3);
   }
 
   static void vvcurveto (ENV &env, PARAM& param)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-dict-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-dict-common.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-dict-common.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -27,8 +27,6 @@
 #define HB_CFF_INTERP_DICT_COMMON_HH
 
 #include "hb-cff-interp-common.hh"
-#include <math.h>
-#include <float.h>
 
 namespace CFF {
 
@@ -58,19 +56,6 @@
   }
   void fini () { dict_values_t<OPSTR>::fini (); }
 
-  unsigned int calculate_serialized_op_size (const OPSTR& opstr) const
-  {
-    switch (opstr.op)
-    {
-      case OpCode_CharStrings:
-      case OpCode_FDArray:
-	return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (opstr.op);
-
-      default:
-	return opstr.str.length;
-    }
-  }
-
   unsigned int  charStringsOffset;
   unsigned int  FDArrayOffset;
 };

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -80,7 +80,7 @@
 {
   template <typename ACC>
   void init (const byte_str_t &str, ACC &acc, unsigned int fd,
-		    const int *coords_=nullptr, unsigned int num_coords_=0)
+	     const int *coords_=nullptr, unsigned int num_coords_=0)
   {
     SUPER::init (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs);
 
@@ -90,7 +90,7 @@
     seen_blend = false;
     seen_vsindex_ = false;
     scalars.init ();
-    do_blend = (coords != nullptr) && num_coords && (varStore != &Null(CFF2VariationStore));
+    do_blend = num_coords && coords && varStore->size;
     set_ivs (acc.privateDicts[fd].ivs);
   }
 
@@ -134,8 +134,7 @@
       if (do_blend)
       {
 	scalars.resize (region_count);
-	varStore->varStore.get_scalars (get_ivs (),
-					(int *)coords, num_coords,
+	varStore->varStore.get_scalars (get_ivs (), coords, num_coords,
 					&scalars[0], region_count);
       }
       seen_blend = true;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -69,7 +69,6 @@
 	if (0 == strncmp (c, name, p - c) && strlen (name) == static_cast<size_t>(p - c)) do { u.opts.symbol = true; } while (0)
 
       OPTION ("uniscribe-bug-compatible", uniscribe_bug_compatible);
-      OPTION ("aat", aat);
 
 #undef OPTION
 
@@ -333,14 +332,14 @@
 /**
  * hb_language_from_string:
  * @str: (array length=len) (element-type uint8_t): a string representing
- *       a BCP 47 language tag
+ *       a BCP 47 language tag
  * @len: length of the @str, or -1 if it is %NULL-terminated.
  *
- * Converts @str representing a BCP 47 language tag to the corresponding
+ * Converts @str representing a BCP 47 language tag to the corresponding
  * #hb_language_t.
  *
  * Return value: (transfer none):
- * The #hb_language_t corresponding to the BCP 47 language tag.
+ * The #hb_language_t corresponding to the BCP 47 language tag.
  *
  * Since: 0.9.2
  **/
@@ -422,12 +421,12 @@
 
 /**
  * hb_script_from_iso15924_tag:
- * @tag: an #hb_tag_t representing an ISO 15924 tag.
+ * @tag: an #hb_tag_t representing an ISO 15924 tag.
  *
- * Converts an ISO 15924 script tag to a corresponding #hb_script_t.
+ * Converts an ISO 15924 script tag to a corresponding #hb_script_t.
  *
  * Return value:
- * An #hb_script_t corresponding to the ISO 15924 tag.
+ * An #hb_script_t corresponding to the ISO 15924 tag.
  *
  * Since: 0.9.2
  **/
@@ -468,15 +467,15 @@
 /**
  * hb_script_from_string:
  * @str: (array length=len) (element-type uint8_t): a string representing an
- *       ISO 15924 tag.
+ *       ISO 15924 tag.
  * @len: length of the @str, or -1 if it is %NULL-terminated.
  *
- * Converts a string @str representing an ISO 15924 script tag to a
+ * Converts a string @str representing an ISO 15924 script tag to a
  * corresponding #hb_script_t. Shorthand for hb_tag_from_string() then
  * hb_script_from_iso15924_tag().
  *
  * Return value:
- * An #hb_script_t corresponding to the ISO 15924 tag.
+ * An #hb_script_t corresponding to the ISO 15924 tag.
  *
  * Since: 0.9.2
  **/
@@ -493,7 +492,7 @@
  * See hb_script_from_iso15924_tag().
  *
  * Return value:
- * An #hb_tag_t representing an ISO 15924 script tag.
+ * An #hb_tag_t representing an ISO 15924 script tag.
  *
  * Since: 0.9.2
  **/
@@ -590,38 +589,6 @@
 }
 
 
-/* hb_user_data_array_t */
-
-bool
-hb_user_data_array_t::set (hb_user_data_key_t *key,
-			   void *              data,
-			   hb_destroy_func_t   destroy,
-			   hb_bool_t           replace)
-{
-  if (!key)
-    return false;
-
-  if (replace) {
-    if (!data && !destroy) {
-      items.remove (key, lock);
-      return true;
-    }
-  }
-  hb_user_data_item_t item = {key, data, destroy};
-  bool ret = !!items.replace_or_insert (item, lock, (bool) replace);
-
-  return ret;
-}
-
-void *
-hb_user_data_array_t::get (hb_user_data_key_t *key)
-{
-  hb_user_data_item_t item = {nullptr, nullptr, nullptr};
-
-  return items.find (key, &item, lock) ? item.data : nullptr;
-}
-
-
 /* hb_version */
 
 
@@ -960,7 +927,7 @@
   len += 4;
   while (len && s[len - 1] == ' ')
     len--;
-  if (feature->start != 0 || feature->end != (unsigned int) -1)
+  if (feature->start != HB_FEATURE_GLOBAL_START || feature->end != HB_FEATURE_GLOBAL_END)
   {
     s[len++] = '[';
     if (feature->start)
@@ -967,7 +934,7 @@
       len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->start));
     if (feature->end != feature->start + 1) {
       s[len++] = ':';
-      if (feature->end != (unsigned int) -1)
+      if (feature->end != HB_FEATURE_GLOBAL_END)
 	len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->end));
     }
     s[len++] = ']';

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -58,6 +58,7 @@
 #define HB_NO_BITMAP
 #define HB_NO_CFF
 #define HB_NO_COLOR
+#define HB_NO_DRAW
 #define HB_NO_ERRNO
 #define HB_NO_FACE_COLLECT_UNICODES
 #define HB_NO_GETENV

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -278,6 +278,17 @@
   CFRelease ((CGFontRef) data);
 }
 
+/**
+ * hb_coretext_face_create:
+ * @cg_font: The CGFontRef to work upon
+ *
+ * Creates an #hb_face_t face object from the specified
+ * CGFontRef.
+ *
+ * Return value: the new #hb_face_t face object
+ *
+ * Since: 0.9.10
+ */
 hb_face_t *
 hb_coretext_face_create (CGFontRef cg_font)
 {
@@ -284,7 +295,15 @@
   return hb_face_create_for_tables (_hb_cg_reference_table, CGFontRetain (cg_font), _hb_cg_font_release);
 }
 
-/*
+/**
+ * hb_coretext_face_get_cg_font:
+ * @face: The #hb_face_t to work upon
+ *
+ * Fetches the CGFontRef associated with an #hb_face_t
+ * face object
+ *
+ * Return value: the CGFontRef found
+ *
  * Since: 0.9.10
  */
 CGFontRef
@@ -351,10 +370,17 @@
   return font->data.coretext;
 }
 
-
-/*
+/**
+ * hb_coretext_font_create:
+ * @ct_font: The CTFontRef to work upon
+ *
+ * Creates an #hb_font_t font object from the specified
+ * CTFontRef.
+ *
+ * Return value: the new #hb_font_t font object
+ *
  * Since: 1.7.2
- */
+ **/
 hb_font_t *
 hb_coretext_font_create (CTFontRef ct_font)
 {
@@ -375,6 +401,17 @@
   return font;
 }
 
+/**
+ * hb_coretext_face_get_ct_font:
+ * @font: #hb_font_t to work upon
+ *
+ * Fetches the CTFontRef associated with the specified
+ * #hb_font_t font object.
+ *
+ * Return value: the CTFontRef found
+ *
+ * Since: 0.9.10
+ */
 CTFontRef
 hb_coretext_font_get_ct_font (hb_font_t *font)
 {
@@ -475,13 +512,19 @@
     hb_vector_t<feature_event_t> feature_events;
     for (unsigned int i = 0; i < num_features; i++)
     {
+      active_feature_t feature;
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1010
       const hb_aat_feature_mapping_t * mapping = hb_aat_layout_find_feature_mapping (features[i].tag);
       if (!mapping)
 	continue;
 
-      active_feature_t feature;
       feature.rec.feature = mapping->aatFeatureType;
       feature.rec.setting = features[i].value ? mapping->selectorToEnable : mapping->selectorToDisable;
+#else
+      feature.rec.feature = features[i].tag;
+      feature.rec.setting = features[i].value;
+#endif
       feature.order = i;
 
       feature_event_t *event;
@@ -530,6 +573,7 @@
 	  /* active_features.qsort (); */
 	  for (unsigned int j = 0; j < active_features.length; j++)
 	  {
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1010
 	    CFStringRef keys[] = {
 	      kCTFontFeatureTypeIdentifierKey,
 	      kCTFontFeatureSelectorIdentifierKey
@@ -538,6 +582,17 @@
 	      CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.feature),
 	      CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.setting)
 	    };
+#else
+	    char tag[5] = {HB_UNTAG (active_features[j].rec.feature)};
+	    CFTypeRef keys[] = {
+	      kCTFontOpenTypeFeatureTag,
+	      kCTFontOpenTypeFeatureValue
+	    };
+	    CFTypeRef values[] = {
+	      CFStringCreateWithCString (kCFAllocatorDefault, tag, kCFStringEncodingASCII),
+	      CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.setting)
+	    };
+#endif
 	    static_assert ((ARRAY_LENGTH_CONST (keys) == ARRAY_LENGTH_CONST (values)), "");
 	    CFDictionaryRef dict = CFDictionaryCreate (kCFAllocatorDefault,
 						       (const void **) keys,
@@ -605,7 +660,7 @@
     scratch_size -= _consumed; \
   } while (0)
 
-  ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2, /*nothing*/);
+  ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2, ((void)nullptr) /*nothing*/);
   unsigned int chars_len = 0;
   for (unsigned int i = 0; i < buffer->len; i++) {
     hb_codepoint_t c = buffer->info[i].codepoint;
@@ -619,7 +674,7 @@
     }
   }
 
-  ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len, /*nothing*/);
+  ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len, ((void)nullptr) /*nothing*/);
   chars_len = 0;
   for (unsigned int i = 0; i < buffer->len; i++)
   {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.h	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.h	2020-05-18 10:44:36 UTC (rev 55197)
@@ -40,8 +40,40 @@
 HB_BEGIN_DECLS
 
 
+/**
+ * HB_CORETEXT_TAG_MORT:
+ *
+ * The #hb_tag_t tag for the `mort` (glyph metamorphosis) table,
+ * which holds AAT features. 
+ *
+ * For more information, see 
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6mort.html
+ *
+ **/
 #define HB_CORETEXT_TAG_MORT HB_TAG('m','o','r','t')
+
+/**
+ * HB_CORETEXT_TAG_MORX:
+ *
+ * The #hb_tag_t tag for the `morx` (extended glyph metamorphosis)
+ * table, which holds AAT features. 
+ *
+ * For more information, see
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6morx.html
+ *
+ **/
 #define HB_CORETEXT_TAG_MORX HB_TAG('m','o','r','x')
+
+/**
+ * HB_CORETEXT_TAG_KERX:
+ *
+ * The #hb_tag_t tag for the `kerx` (extended kerning) table, which
+ * holds AAT kerning information. 
+ *
+ * For more information, see 
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kerx.html
+ *
+ **/
 #define HB_CORETEXT_TAG_KERX HB_TAG('k','e','r','x')
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -46,7 +46,6 @@
   bool unused : 1; /* In-case sign bit is here. */
   bool initialized : 1;
   bool uniscribe_bug_compatible : 1;
-  bool aat : 1;
 };
 
 union hb_options_union_t {
@@ -230,7 +229,7 @@
 		  ...) {}
 
 #define DEBUG_MSG_LEVEL(WHAT, OBJ, LEVEL, LEVEL_DIR, ...)	_hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), nullptr,    true, (LEVEL), (LEVEL_DIR), __VA_ARGS__)
-#define DEBUG_MSG(WHAT, OBJ, ...) 				_hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), nullptr,    false, 0, 0, __VA_ARGS__)
+#define DEBUG_MSG(WHAT, OBJ, ...)				_hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), nullptr,    false, 0, 0, __VA_ARGS__)
 #define DEBUG_MSG_FUNC(WHAT, OBJ, ...)				_hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), HB_FUNC, false, 0, 0, __VA_ARGS__)
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -635,7 +635,7 @@
   bool isRightToLeft = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
 
   const wchar_t localeName[20] = {0};
-  if (buffer->props.language != nullptr)
+  if (buffer->props.language)
     mbstowcs ((wchar_t*) localeName,
 	      hb_language_to_string (buffer->props.language), 20);
 

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.cc	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -0,0 +1,261 @@
+/*
+ * Copyright © 2019-2020  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.hh"
+
+#ifndef HB_NO_DRAW
+#ifdef HB_EXPERIMENTAL_API
+
+#include "hb-draw.hh"
+#include "hb-ot.h"
+#include "hb-ot-glyf-table.hh"
+#include "hb-ot-cff1-table.hh"
+#include "hb-ot-cff2-table.hh"
+
+/**
+ * hb_draw_funcs_set_move_to_func:
+ * @funcs: draw functions object
+ * @move_to: move-to callback
+ *
+ * Sets move-to callback to the draw functions object.
+ *
+ * Since: EXPERIMENTAL
+ **/
+void
+hb_draw_funcs_set_move_to_func (hb_draw_funcs_t        *funcs,
+				hb_draw_move_to_func_t  move_to)
+{
+  if (unlikely (hb_object_is_immutable (funcs))) return;
+  funcs->move_to = move_to;
+}
+
+/**
+ * hb_draw_funcs_set_line_to_func:
+ * @funcs: draw functions object
+ * @line_to: line-to callback
+ *
+ * Sets line-to callback to the draw functions object.
+ *
+ * Since: EXPERIMENTAL
+ **/
+void
+hb_draw_funcs_set_line_to_func (hb_draw_funcs_t        *funcs,
+				hb_draw_line_to_func_t  line_to)
+{
+  if (unlikely (hb_object_is_immutable (funcs))) return;
+  funcs->line_to = line_to;
+}
+
+/**
+ * hb_draw_funcs_set_quadratic_to_func:
+ * @funcs: draw functions object
+ * @move_to: quadratic-to callback
+ *
+ * Sets quadratic-to callback to the draw functions object.
+ *
+ * Since: EXPERIMENTAL
+ **/
+void
+hb_draw_funcs_set_quadratic_to_func (hb_draw_funcs_t             *funcs,
+				     hb_draw_quadratic_to_func_t  quadratic_to)
+{
+  if (unlikely (hb_object_is_immutable (funcs))) return;
+  funcs->quadratic_to = quadratic_to;
+  funcs->is_quadratic_to_set = true;
+}
+
+/**
+ * hb_draw_funcs_set_cubic_to_func:
+ * @funcs: draw functions
+ * @cubic_to: cubic-to callback
+ *
+ * Sets cubic-to callback to the draw functions object.
+ *
+ * Since: EXPERIMENTAL
+ **/
+void
+hb_draw_funcs_set_cubic_to_func (hb_draw_funcs_t         *funcs,
+				 hb_draw_cubic_to_func_t  cubic_to)
+{
+  if (unlikely (hb_object_is_immutable (funcs))) return;
+  funcs->cubic_to = cubic_to;
+}
+
+/**
+ * hb_draw_funcs_set_close_path_func:
+ * @funcs: draw functions object
+ * @close_path: close-path callback
+ *
+ * Sets close-path callback to the draw functions object.
+ *
+ * Since: EXPERIMENTAL
+ **/
+void
+hb_draw_funcs_set_close_path_func (hb_draw_funcs_t           *funcs,
+				   hb_draw_close_path_func_t  close_path)
+{
+  if (unlikely (hb_object_is_immutable (funcs))) return;
+  funcs->close_path = close_path;
+}
+
+static void
+_move_to_nil (hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, void *user_data HB_UNUSED) {}
+
+static void
+_line_to_nil (hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, void *user_data HB_UNUSED) {}
+
+static void
+_quadratic_to_nil (hb_position_t control_x HB_UNUSED, hb_position_t control_y HB_UNUSED,
+		   hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED,
+		   void *user_data HB_UNUSED) {}
+
+static void
+_cubic_to_nil (hb_position_t control1_x HB_UNUSED, hb_position_t control1_y HB_UNUSED,
+	       hb_position_t control2_x HB_UNUSED, hb_position_t control2_y HB_UNUSED,
+	       hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED,
+	       void *user_data HB_UNUSED) {}
+
+static void
+_close_path_nil (void *user_data HB_UNUSED) {}
+
+/**
+ * hb_draw_funcs_create:
+ *
+ * Creates a new draw callbacks object.
+ *
+ * Since: EXPERIMENTAL
+ **/
+hb_draw_funcs_t *
+hb_draw_funcs_create ()
+{
+  hb_draw_funcs_t *funcs;
+  if (unlikely (!(funcs = hb_object_create<hb_draw_funcs_t> ())))
+    return const_cast<hb_draw_funcs_t *> (&Null (hb_draw_funcs_t));
+
+  funcs->move_to = (hb_draw_move_to_func_t) _move_to_nil;
+  funcs->line_to = (hb_draw_line_to_func_t) _line_to_nil;
+  funcs->quadratic_to = (hb_draw_quadratic_to_func_t) _quadratic_to_nil;
+  funcs->is_quadratic_to_set = false;
+  funcs->cubic_to = (hb_draw_cubic_to_func_t) _cubic_to_nil;
+  funcs->close_path = (hb_draw_close_path_func_t) _close_path_nil;
+  return funcs;
+}
+
+/**
+ * hb_draw_funcs_reference:
+ * @funcs: draw functions
+ *
+ * Add to callbacks object refcount.
+ *
+ * Returns: The same object.
+ * Since: EXPERIMENTAL
+ **/
+hb_draw_funcs_t *
+hb_draw_funcs_reference (hb_draw_funcs_t *funcs)
+{
+  return hb_object_reference (funcs);
+}
+
+/**
+ * hb_draw_funcs_destroy:
+ * @funcs: draw functions
+ *
+ * Decreases refcount of callbacks object and deletes the object if it reaches
+ * to zero.
+ *
+ * Since: EXPERIMENTAL
+ **/
+void
+hb_draw_funcs_destroy (hb_draw_funcs_t *funcs)
+{
+  if (!hb_object_destroy (funcs)) return;
+
+  free (funcs);
+}
+
+/**
+ * hb_draw_funcs_make_immutable:
+ * @funcs: draw functions
+ *
+ * Makes funcs object immutable.
+ *
+ * Since: EXPERIMENTAL
+ **/
+void
+hb_draw_funcs_make_immutable (hb_draw_funcs_t *funcs)
+{
+  if (hb_object_is_immutable (funcs))
+    return;
+
+  hb_object_make_immutable (funcs);
+}
+
+/**
+ * hb_draw_funcs_is_immutable:
+ * @funcs: draw functions
+ *
+ * Checks whether funcs is immutable.
+ *
+ * Returns: If is immutable.
+ * Since: EXPERIMENTAL
+ **/
+hb_bool_t
+hb_draw_funcs_is_immutable (hb_draw_funcs_t *funcs)
+{
+  return hb_object_is_immutable (funcs);
+}
+
+/**
+ * hb_font_draw_glyph:
+ * @font: a font object
+ * @glyph: a glyph id
+ * @funcs: draw callbacks object
+ * @user_data: parameter you like be passed to the callbacks when are called
+ *
+ * Draw a glyph.
+ *
+ * Returns: Whether the font had the glyph and the operation completed successfully.
+ * Since: EXPERIMENTAL
+ **/
+hb_bool_t
+hb_font_draw_glyph (hb_font_t *font, hb_codepoint_t glyph,
+		    const hb_draw_funcs_t *funcs,
+		    void *user_data)
+{
+  if (unlikely (funcs == &Null (hb_draw_funcs_t) ||
+		glyph >= font->face->get_num_glyphs ()))
+    return false;
+
+  draw_helper_t draw_helper (funcs, user_data);
+  if (font->face->table.glyf->get_path (font, glyph, draw_helper)) return true;
+#ifndef HB_NO_CFF
+  if (font->face->table.cff1->get_path (font, glyph, draw_helper)) return true;
+  if (font->face->table.cff2->get_path (font, glyph, draw_helper)) return true;
+#endif
+
+  return false;
+}
+
+#endif
+#endif

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h	2020-05-18 10:44:36 UTC (rev 55197)
@@ -0,0 +1,98 @@
+/*
+ * Copyright © 2019-2020  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_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_DRAW_H
+#define HB_DRAW_H
+
+#include "hb.h"
+
+HB_BEGIN_DECLS
+
+#ifdef HB_EXPERIMENTAL_API
+typedef void (*hb_draw_move_to_func_t) (hb_position_t to_x, hb_position_t to_y, void *user_data);
+typedef void (*hb_draw_line_to_func_t) (hb_position_t to_x, hb_position_t to_y, void *user_data);
+typedef void (*hb_draw_quadratic_to_func_t) (hb_position_t control_x, hb_position_t control_y,
+					     hb_position_t to_x, hb_position_t to_y,
+					     void *user_data);
+typedef void (*hb_draw_cubic_to_func_t) (hb_position_t control1_x, hb_position_t control1_y,
+					 hb_position_t control2_x, hb_position_t control2_y,
+					 hb_position_t to_x, hb_position_t to_y,
+					 void *user_data);
+typedef void (*hb_draw_close_path_func_t) (void *user_data);
+
+/**
+ * hb_draw_funcs_t:
+ *
+ * Glyph draw callbacks.
+ *
+ * _move_to, _line_to and _cubic_to calls are nessecary to be defined but we
+ * translate _quadratic_to calls to _cubic_to if the callback isn't defined.
+ *
+ * Since: EXPERIMENTAL
+ **/
+typedef struct hb_draw_funcs_t hb_draw_funcs_t;
+
+HB_EXTERN void
+hb_draw_funcs_set_move_to_func (hb_draw_funcs_t        *funcs,
+				hb_draw_move_to_func_t  move_to);
+
+HB_EXTERN void
+hb_draw_funcs_set_line_to_func (hb_draw_funcs_t        *funcs,
+				hb_draw_line_to_func_t  line_to);
+
+HB_EXTERN void
+hb_draw_funcs_set_quadratic_to_func (hb_draw_funcs_t             *funcs,
+				     hb_draw_quadratic_to_func_t  quadratic_to);
+
+HB_EXTERN void
+hb_draw_funcs_set_cubic_to_func (hb_draw_funcs_t         *funcs,
+				 hb_draw_cubic_to_func_t  cubic_to);
+
+HB_EXTERN void
+hb_draw_funcs_set_close_path_func (hb_draw_funcs_t           *funcs,
+				   hb_draw_close_path_func_t  close_path);
+
+HB_EXTERN hb_draw_funcs_t *
+hb_draw_funcs_create (void);
+
+HB_EXTERN hb_draw_funcs_t *
+hb_draw_funcs_reference (hb_draw_funcs_t *funcs);
+
+HB_EXTERN void
+hb_draw_funcs_destroy (hb_draw_funcs_t *funcs);
+
+HB_EXTERN void
+hb_draw_funcs_make_immutable (hb_draw_funcs_t *funcs);
+
+HB_EXTERN hb_bool_t
+hb_draw_funcs_is_immutable (hb_draw_funcs_t *funcs);
+#endif
+
+HB_END_DECLS
+
+#endif /* HB_DRAW_H */


Property changes on: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -0,0 +1,139 @@
+/*
+ * Copyright © 2020  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_DRAW_HH
+#define HB_DRAW_HH
+
+#include "hb.hh"
+
+#ifdef HB_EXPERIMENTAL_API
+struct hb_draw_funcs_t
+{
+  hb_object_header_t header;
+
+  hb_draw_move_to_func_t move_to;
+  hb_draw_line_to_func_t line_to;
+  hb_draw_quadratic_to_func_t quadratic_to;
+  bool is_quadratic_to_set;
+  hb_draw_cubic_to_func_t cubic_to;
+  hb_draw_close_path_func_t close_path;
+};
+
+struct draw_helper_t
+{
+  draw_helper_t (const hb_draw_funcs_t *funcs_, void *user_data_)
+  {
+    funcs = funcs_;
+    user_data = user_data_;
+    path_open = false;
+    path_start_x = current_x = path_start_y = current_y = 0;
+  }
+  ~draw_helper_t () { end_path (); }
+
+  void move_to (hb_position_t x, hb_position_t y)
+  {
+    if (path_open) end_path ();
+    current_x = path_start_x = x;
+    current_y = path_start_y = y;
+  }
+
+  void line_to (hb_position_t x, hb_position_t y)
+  {
+    if (equal_to_current (x, y)) return;
+    if (!path_open) start_path ();
+    funcs->line_to (x, y, user_data);
+    current_x = x;
+    current_y = y;
+  }
+
+  void
+  quadratic_to (hb_position_t control_x, hb_position_t control_y,
+		hb_position_t to_x, hb_position_t to_y)
+  {
+    if (equal_to_current (control_x, control_y) && equal_to_current (to_x, to_y))
+      return;
+    if (!path_open) start_path ();
+    if (funcs->is_quadratic_to_set)
+      funcs->quadratic_to (control_x, control_y, to_x, to_y, user_data);
+    else
+      funcs->cubic_to (roundf ((current_x + 2.f * control_x) / 3.f),
+		       roundf ((current_y + 2.f * control_y) / 3.f),
+		       roundf ((to_x + 2.f * control_x) / 3.f),
+		       roundf ((to_y + 2.f * control_y) / 3.f),
+		       to_x, to_y, user_data);
+    current_x = to_x;
+    current_y = to_y;
+  }
+
+  void
+  cubic_to (hb_position_t control1_x, hb_position_t control1_y,
+	    hb_position_t control2_x, hb_position_t control2_y,
+	    hb_position_t to_x, hb_position_t to_y)
+  {
+    if (equal_to_current (control1_x, control1_y) &&
+	equal_to_current (control2_x, control2_y) &&
+	equal_to_current (to_x, to_y))
+      return;
+    if (!path_open) start_path ();
+    funcs->cubic_to (control1_x, control1_y, control2_x, control2_y, to_x, to_y, user_data);
+    current_x = to_x;
+    current_y = to_y;
+  }
+
+  void end_path ()
+  {
+    if (path_open)
+    {
+      if ((path_start_x != current_x) || (path_start_y != current_y))
+	funcs->line_to (path_start_x, path_start_y, user_data);
+      funcs->close_path (user_data);
+    }
+    path_open = false;
+    path_start_x = current_x = path_start_y = current_y = 0;
+  }
+
+  protected:
+  bool equal_to_current (hb_position_t x, hb_position_t y)
+  { return current_x == x && current_y == y; }
+
+  void start_path ()
+  {
+    if (path_open) end_path ();
+    path_open = true;
+    funcs->move_to (path_start_x, path_start_y, user_data);
+  }
+
+  hb_position_t path_start_x;
+  hb_position_t path_start_y;
+
+  hb_position_t current_x;
+  hb_position_t current_y;
+
+  bool path_open;
+  const hb_draw_funcs_t *funcs;
+  void *user_data;
+};
+#endif
+
+#endif /* HB_DRAW_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -226,7 +226,7 @@
 hb_face_t *
 hb_face_get_empty ()
 {
-  return const_cast<hb_face_t *> (&Null(hb_face_t));
+  return const_cast<hb_face_t *> (&Null (hb_face_t));
 }
 
 
@@ -546,7 +546,7 @@
 hb_face_collect_unicodes (hb_face_t *face,
 			  hb_set_t  *out)
 {
-  face->table.cmap->collect_unicodes (out);
+  face->table.cmap->collect_unicodes (out, face->get_num_glyphs ());
 }
 /**
  * hb_face_collect_variation_selectors:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -94,7 +94,7 @@
   unsigned int get_num_glyphs () const
   {
     unsigned int ret = num_glyphs.get_relaxed ();
-    if (unlikely (ret == (unsigned int) -1))
+    if (unlikely (ret == UINT_MAX))
       return load_num_glyphs ();
     return ret;
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -33,7 +33,10 @@
 
 #include "hb-ot.h"
 
+#include "hb-ot-var-avar-table.hh"
+#include "hb-ot-var-fvar-table.hh"
 
+
 /**
  * SECTION:hb-font
  * @title: hb-font
@@ -674,7 +677,8 @@
 				 void                        *user_data, \
 				 hb_destroy_func_t            destroy)   \
 {                                                                        \
-  if (hb_object_is_immutable (ffuncs)) {                                 \
+  if (hb_object_is_immutable (ffuncs))                                   \
+  {                                                                      \
     if (destroy)                                                         \
       destroy (user_data);                                               \
     return;                                                              \
@@ -1332,6 +1336,7 @@
 
   0, /* num_coords */
   nullptr, /* coords */
+  nullptr, /* design_coords */
 
   const_cast<hb_font_funcs_t *> (&_hb_Null_hb_font_funcs_t),
 
@@ -1383,6 +1388,20 @@
   return font;
 }
 
+static void
+_hb_font_adopt_var_coords (hb_font_t *font,
+			   int *coords, /* 2.14 normalized */
+			   float *design_coords,
+			   unsigned int coords_length)
+{
+  free (font->coords);
+  free (font->design_coords);
+
+  font->coords = coords;
+  font->design_coords = design_coords;
+  font->num_coords = coords_length;
+}
+
 /**
  * hb_font_create_sub_font:
  * @parent: parent font.
@@ -1413,15 +1432,22 @@
   font->y_ppem = parent->y_ppem;
   font->ptem = parent->ptem;
 
-  font->num_coords = parent->num_coords;
-  if (font->num_coords)
+  unsigned int num_coords = parent->num_coords;
+  if (num_coords)
   {
-    unsigned int size = parent->num_coords * sizeof (parent->coords[0]);
-    font->coords = (int *) malloc (size);
-    if (unlikely (!font->coords))
-      font->num_coords = 0;
+    int *coords = (int *) calloc (num_coords, sizeof (parent->coords[0]));
+    float *design_coords = (float *) calloc (num_coords, sizeof (parent->design_coords[0]));
+    if (likely (coords && design_coords))
+    {
+      memcpy (coords, parent->coords, num_coords * sizeof (parent->coords[0]));
+      memcpy (design_coords, parent->design_coords, num_coords * sizeof (parent->design_coords[0]));
+      _hb_font_adopt_var_coords (font, coords, design_coords, num_coords);
+    }
     else
-      memcpy (font->coords, parent->coords, size);
+    {
+      free (coords);
+      free (design_coords);
+    }
   }
 
   return font;
@@ -1439,7 +1465,7 @@
 hb_font_t *
 hb_font_get_empty ()
 {
-  return const_cast<hb_font_t *> (&Null(hb_font_t));
+  return const_cast<hb_font_t *> (&Null (hb_font_t));
 }
 
 /**
@@ -1481,6 +1507,7 @@
   hb_font_funcs_destroy (font->klass);
 
   free (font->coords);
+  free (font->design_coords);
 
   free (font);
 }
@@ -1842,17 +1869,6 @@
  * Variations
  */
 
-static void
-_hb_font_adopt_var_coords_normalized (hb_font_t *font,
-				      int *coords, /* 2.14 normalized */
-				      unsigned int coords_length)
-{
-  free (font->coords);
-
-  font->coords = coords;
-  font->num_coords = coords_length;
-}
-
 /**
  * hb_font_set_variations:
  *
@@ -1875,13 +1891,30 @@
   unsigned int coords_length = hb_ot_var_get_axis_count (font->face);
 
   int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr;
-  if (unlikely (coords_length && !normalized))
+  float *design_coords = coords_length ? (float *) calloc (coords_length, sizeof (float)) : nullptr;
+
+  if (unlikely (coords_length && !(normalized && design_coords)))
+  {
+    free (normalized);
+    free (design_coords);
     return;
+  }
 
-  hb_ot_var_normalize_variations (font->face,
-				  variations, variations_length,
-				  normalized, coords_length);
-  _hb_font_adopt_var_coords_normalized (font, normalized, coords_length);
+  const OT::fvar &fvar = *font->face->table.fvar;
+  for (unsigned int i = 0; i < variations_length; i++)
+  {
+    hb_ot_var_axis_info_t info;
+    if (hb_ot_var_find_axis_info (font->face, variations[i].tag, &info) &&
+	info.axis_index < coords_length)
+    {
+      float v = variations[i].value;
+      design_coords[info.axis_index] = v;
+      normalized[info.axis_index] = fvar.normalize_axis_value (info.axis_index, v);
+    }
+  }
+  font->face->table.avar->map_coords (normalized, coords_length);
+
+  _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
 }
 
 /**
@@ -1898,11 +1931,20 @@
     return;
 
   int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr;
-  if (unlikely (coords_length && !normalized))
+  float *design_coords = coords_length ? (float *) calloc (coords_length, sizeof (float)) : nullptr;
+
+  if (unlikely (coords_length && !(normalized && design_coords)))
+  {
+    free (normalized);
+    free (design_coords);
     return;
+  }
 
+  if (coords_length)
+    memcpy (design_coords, coords, coords_length * sizeof (font->design_coords[0]));
+
   hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized);
-  _hb_font_adopt_var_coords_normalized (font, normalized, coords_length);
+  _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
 }
 
 /**
@@ -1946,13 +1988,30 @@
     return;
 
   int *copy = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : nullptr;
-  if (unlikely (coords_length && !copy))
+  int *unmapped = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : nullptr;
+  float *design_coords = coords_length ? (float *) calloc (coords_length, sizeof (design_coords[0])) : nullptr;
+
+  if (unlikely (coords_length && !(copy && unmapped && design_coords)))
+  {
+    free (copy);
+    free (unmapped);
+    free (design_coords);
     return;
+  }
 
   if (coords_length)
+  {
     memcpy (copy, coords, coords_length * sizeof (coords[0]));
+    memcpy (unmapped, coords, coords_length * sizeof (coords[0]));
+  }
 
-  _hb_font_adopt_var_coords_normalized (font, copy, coords_length);
+  /* Best effort design coords simulation */
+  font->face->table.avar->unmap_coords (unmapped, coords_length);
+  for (unsigned int i = 0; i < coords_length; ++i)
+    design_coords[i] = font->face->table.fvar->unnormalize_axis_value (i, unmapped[i]);
+  free (unmapped);
+
+  _hb_font_adopt_var_coords (font, copy, design_coords, coords_length);
 }
 
 /**
@@ -1972,7 +2031,27 @@
 
   return font->coords;
 }
+
+#ifdef HB_EXPERIMENTAL_API
+/**
+ * hb_font_get_var_coords_design:
+ *
+ * Return value is valid as long as variation coordinates of the font
+ * are not modified.
+ *
+ * Since: EXPERIMENTAL
+ */
+const float *
+hb_font_get_var_coords_design (hb_font_t *font,
+			       unsigned int *length)
+{
+  if (length)
+    *length = font->num_coords;
+
+  return font->design_coords;
+}
 #endif
+#endif
 
 #ifndef HB_DISABLE_DEPRECATED
 /*
@@ -2076,6 +2155,13 @@
 			      hb_font_get_glyph_func_t func,
 			      void *user_data, hb_destroy_func_t destroy)
 {
+  if (hb_object_is_immutable (ffuncs))
+  {
+    if (destroy)
+      destroy (user_data);
+    return;
+  }
+
   hb_font_get_glyph_trampoline_t *trampoline;
 
   trampoline = trampoline_create (func, user_data, destroy);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h	2020-05-18 10:44:36 UTC (rev 55197)
@@ -33,6 +33,7 @@
 
 #include "hb-common.h"
 #include "hb-face.h"
+#include "hb-draw.h"
 
 HB_BEGIN_DECLS
 
@@ -704,6 +705,12 @@
 			       const float *coords,
 			       unsigned int coords_length);
 
+#ifdef HB_EXPERIMENTAL_API
+HB_EXTERN const float *
+hb_font_get_var_coords_design (hb_font_t *font,
+			       unsigned int *length);
+#endif
+
 HB_EXTERN void
 hb_font_set_var_coords_normalized (hb_font_t *font,
 				   const int *coords, /* 2.14 normalized */
@@ -717,6 +724,12 @@
 hb_font_set_var_named_instance (hb_font_t *font,
 				unsigned instance_index);
 
+#ifdef HB_EXPERIMENTAL_API
+HB_EXTERN hb_bool_t
+hb_font_draw_glyph (hb_font_t *font, hb_codepoint_t glyph,
+		    const hb_draw_funcs_t *funcs, void *user_data);
+#endif
+
 HB_END_DECLS
 
 #endif /* HB_FONT_H */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -120,6 +120,7 @@
   /* Font variation coordinates. */
   unsigned int num_coords;
   int *coords;
+  float *design_coords;
 
   hb_font_funcs_t   *klass;
   void              *user_data;
@@ -286,7 +287,7 @@
   }
 
   hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph,
-			        hb_position_t *x, hb_position_t *y)
+				hb_position_t *x, hb_position_t *y)
   {
     *x = *y = 0;
     return klass->get.f.glyph_h_origin (this, user_data,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -48,8 +48,13 @@
  * @short_description: FreeType integration
  * @include: hb-ft.h
  *
- * Functions for using HarfBuzz with the FreeType library to provide face and
+ * Functions for using HarfBuzz with the FreeType library.
+ *
+ * HarfBuzz supports using FreeType to provide face and
  * font data.
+ *
+ * <note>Note that FreeType is not thread-safe, therefore these
+ * functions are not thread-safe either.</note>
  **/
 
 
@@ -127,10 +132,13 @@
 
 /**
  * hb_ft_font_set_load_flags:
- * @font:
- * @load_flags:
+ * @font: #hb_font_t to work upon
+ * @load_flags: The FreeType load flags to set
  *
+ * Sets the FT_Load_Glyph load flags for the specified #hb_font_t.
  *
+ * For more information, see 
+ * https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#ft_load_xxx
  *
  * Since: 1.0.5
  **/
@@ -140,7 +148,7 @@
   if (hb_object_is_immutable (font))
     return;
 
-  if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
+  if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy))
     return;
 
   hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data;
@@ -150,17 +158,21 @@
 
 /**
  * hb_ft_font_get_load_flags:
- * @font:
+ * @font: #hb_font_t to work upon
  *
+ * Fetches the FT_Load_Glyph load flags of the specified #hb_font_t.
  *
+ * For more information, see 
+ * https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#ft_load_xxx
  *
- * Return value:
+ * Return value: FT_Load_Glyph flags found
+ *
  * Since: 1.0.5
  **/
 int
 hb_ft_font_get_load_flags (hb_font_t *font)
 {
-  if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
+  if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy))
     return 0;
 
   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
@@ -168,10 +180,21 @@
   return ft_font->load_flags;
 }
 
+/**
+ * hb_ft_get_face:
+ * @font: #hb_font_t to work upon
+ *
+ * Fetches the FT_Face associated with the specified #hb_font_t
+ * font object.
+ *
+ * Return value: the FT_Face found
+ *
+ * Since: 0.9.2
+ **/
 FT_Face
 hb_ft_font_get_face (hb_font_t *font)
 {
-  if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
+  if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy))
     return nullptr;
 
   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
@@ -179,8 +202,49 @@
   return ft_font->ft_face;
 }
 
+/**
+ * hb_ft_font_lock_face:
+ * @font:
+ *
+ *
+ *
+ * Return value:
+ * Since: 2.6.5
+ **/
+FT_Face
+hb_ft_font_lock_face (hb_font_t *font)
+{
+  if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy))
+    return nullptr;
 
+  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
 
+  ft_font->lock.lock ();
+
+  return ft_font->ft_face;
+}
+
+/**
+ * hb_ft_font_unlock_face:
+ * @font:
+ *
+ *
+ *
+ * Return value:
+ * Since: 2.6.5
+ **/
+void
+hb_ft_font_unlock_face (hb_font_t *font)
+{
+  if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy))
+    return;
+
+  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
+
+  ft_font->lock.unlock ();
+}
+
+
 static hb_bool_t
 hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED,
 			 void *font_data,
@@ -595,12 +659,22 @@
 
 /**
  * hb_ft_face_create:
- * @ft_face: (destroy destroy) (scope notified):
- * @destroy:
+ * @ft_face: (destroy destroy) (scope notified): FT_Face to work upon
+ * @destroy: A callback to call when the face object is not needed anymore
  *
+ * Creates an #hb_face_t face object from the specified FT_Face.
  *
+ * This variant of the function does not provide any life-cycle management.
  *
- * Return value: (transfer full):
+ * Most client programs should use hb_ft_face_create_referenced()
+ * (or, perhaps, hb_ft_face_create_cached()) instead. 
+ *
+ * If you know you have valid reasons not to use hb_ft_face_create_referenced(),
+ * then it is the client program's responsibility to destroy @ft_face 
+ * after the #hb_face_t face object has been destroyed.
+ *
+ * Return value: (transfer full): the new #hb_face_t face object
+ *
  * Since: 0.9.2
  **/
 hb_face_t *
@@ -630,11 +704,20 @@
 
 /**
  * hb_ft_face_create_referenced:
- * @ft_face:
+ * @ft_face: FT_Face to work upon
  *
+ * Creates an #hb_face_t face object from the specified FT_Face.
  *
+ * This is the preferred variant of the hb_ft_face_create*
+ * function family, because it calls FT_Reference_Face() on @ft_face,
+ * ensuring that @ft_face remains alive as long as the resulting
+ * #hb_face_t face object remains alive. Also calls FT_Done_Face()
+ * when the #hb_face_t face object is destroyed.
  *
- * Return value: (transfer full):
+ * Use this version unless you know you have good reasons not to.
+ *
+ * Return value: (transfer full): the new #hb_face_t face object
+ *
  * Since: 0.9.38
  **/
 hb_face_t *
@@ -652,11 +735,21 @@
 
 /**
  * hb_ft_face_create_cached:
- * @ft_face:
+ * @ft_face: FT_Face to work upon
  *
+ * Creates an #hb_face_t face object from the specified FT_Face.
  *
+ * This variant of the function caches the newly created #hb_face_t
+ * face object, using the @generic pointer of @ft_face. Subsequent function
+ * calls that are passed the same @ft_face parameter will have the same
+ * #hb_face_t returned to them, and that #hb_face_t will be correctly
+ * reference counted.
  *
- * Return value: (transfer full):
+ * However, client programs are still responsible for destroying
+ * @ft_face after the last #hb_face_t face object has been destroyed.
+ *
+ * Return value: (transfer full): the new #hb_face_t face object
+ *
  * Since: 0.9.2
  **/
 hb_face_t *
@@ -674,15 +767,34 @@
   return hb_face_reference ((hb_face_t *) ft_face->generic.data);
 }
 
-
 /**
  * hb_ft_font_create:
- * @ft_face: (destroy destroy) (scope notified):
- * @destroy:
+ * @ft_face: (destroy destroy) (scope notified): FT_Face to work upon
+ * @destroy: (optional): A callback to call when the font object is not needed anymore
  *
+ * Creates an #hb_font_t font object from the specified FT_Face.
  *
+ * <note>Note: You must set the face size on @ft_face before calling
+ * hb_ft_font_create() on it. Otherwise, HarfBuzz will not pick up
+ * the face size.</note>
  *
- * Return value: (transfer full):
+ * This variant of the function does not provide any life-cycle management.
+ *
+ * Most client programs should use hb_ft_font_create_referenced()
+ * instead. 
+ *
+ * If you know you have valid reasons not to use hb_ft_font_create_referenced(),
+ * then it is the client program's responsibility to destroy @ft_face 
+ * after the #hb_font_t font object has been destroyed.
+ *
+ * HarfBuzz will use the @destroy callback on the #hb_font_t font object 
+ * if it is supplied when you use this function. However, even if @destroy
+ * is provided, it is the client program's responsibility to destroy @ft_face,
+ * and it is the client program's responsibility to ensure that @ft_face is
+ * destroyed only after the #hb_font_t font object has been destroyed.
+ *
+ * Return value: (transfer full): the new #hb_font_t font object
+ *
  * Since: 0.9.2
  **/
 hb_font_t *
@@ -700,6 +812,16 @@
   return font;
 }
 
+/**
+ * hb_ft_font_has_changed:
+ * @font: #hb_font_t to work upon
+ *
+ * Refreshes the state of @font when the underlying FT_Face has changed.
+ * This function should be called after changing the size or
+ * variation-axis settings on the FT_Face.
+ *
+ * Since: 1.0.5
+ **/
 void
 hb_ft_font_changed (hb_font_t *font)
 {
@@ -718,7 +840,7 @@
 		    ft_face->size->metrics.y_ppem);
 #endif
 
-#ifdef HAVE_FT_GET_VAR_BLEND_COORDINATES
+#if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR)
   FT_MM_Var *mm_var = nullptr;
   if (!FT_Get_MM_Var (ft_face, &mm_var))
   {
@@ -755,11 +877,23 @@
 
 /**
  * hb_ft_font_create_referenced:
- * @ft_face:
+ * @ft_face: FT_Face to work upon
  *
+ * Creates an #hb_font_t font object from the specified FT_Face.
  *
+ * <note>Note: You must set the face size on @ft_face before calling
+ * hb_ft_font_create_references() on it. Otherwise, HarfBuzz will not pick up
+ * the face size.</note>
  *
- * Return value: (transfer full):
+ * This is the preferred variant of the hb_ft_font_create*
+ * function family, because it calls FT_Reference_Face() on @ft_face,
+ * ensuring that @ft_face remains alive as long as the resulting
+ * #hb_font_t font object remains alive.
+ *
+ * Use this version unless you know you have good reasons not to.
+ *
+ * Return value: (transfer full): the new #hb_font_t font object
+ *
  * Since: 0.9.38
  **/
 hb_font_t *
@@ -818,6 +952,28 @@
   hb_blob_destroy ((hb_blob_t *) ft_face->generic.data);
 }
 
+/**
+ * hb_ft_font_set_funcs:
+ * @font: #hb_font_t to work upon
+ *
+ * Configures the font-functions structure of the specified
+ * #hb_font_t font object to use FreeType font functions.
+ *
+ * In particular, you can use this function to configure an
+ * existing #hb_face_t face object for use with FreeType font
+ * functions even if that #hb_face_t face object was initially
+ * created with hb_face_create(), and therefore was not
+ * initially configured to use FreeType font functions.
+ *
+ * An #hb_face_t face object created with hb_ft_face_create()
+ * is preconfigured for FreeType font functions and does not
+ * require this function to be used.
+ *
+ * <note>Note: Internally, this function creates an FT_Face.
+* </note>
+ *
+ * Since: 1.0.5
+ **/
 void
 hb_ft_font_set_funcs (hb_font_t *font)
 {
@@ -857,7 +1013,7 @@
     FT_Set_Transform (ft_face, &matrix, nullptr);
   }
 
-#ifdef HAVE_FT_SET_VAR_BLEND_COORDINATES
+#if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR)
   unsigned int num_coords;
   const int *coords = hb_font_get_var_coords_normalized (font, &num_coords);
   if (num_coords)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.h	2020-05-18 10:44:36 UTC (rev 55197)
@@ -110,7 +110,13 @@
 HB_EXTERN FT_Face
 hb_ft_font_get_face (hb_font_t *font);
 
+HB_EXTERN FT_Face
+hb_ft_font_lock_face (hb_font_t *font);
+
 HB_EXTERN void
+hb_ft_font_unlock_face (hb_font_t *font);
+
+HB_EXTERN void
 hb_ft_font_set_load_flags (hb_font_t *font, int load_flags);
 
 HB_EXTERN int

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-glib.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-glib.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-glib.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -41,7 +41,11 @@
  * @short_description: GLib integration
  * @include: hb-glib.h
  *
- * Functions for using HarfBuzz with the GLib library to provide Unicode data.
+ * Functions for using HarfBuzz with the GLib library. 
+ *
+ * HarfBuzz supports using GLib to provide Unicode data, by attaching
+ * GLib functions to the virtual methods in a #hb_unicode_funcs_t function
+ * structure.
  **/
 
 
@@ -169,6 +173,17 @@
 };
 #endif
 
+/**
+ * hb_glib_script_to_script:
+ * @script: The GUnicodeScript identifier to query
+ *
+ * Fetches the #hb_script_t script that corresponds to the
+ * specified GUnicodeScript identifier.
+ *
+ * Return value: the #hb_script_t script found
+ *
+ * Since: 0.9.38
+ **/
 hb_script_t
 hb_glib_script_to_script (GUnicodeScript script)
 {
@@ -185,6 +200,17 @@
 #endif
 }
 
+/**
+ * hb_glib_script_from_script:
+ * @script: The #hb_script_t to query
+ *
+ * Fetches the GUnicodeScript identifier that corresponds to the
+ * specified #hb_script_t script.
+ *
+ * Return value: the GUnicodeScript identifier found
+ *
+ * Since: 0.9.38
+ **/
 GUnicodeScript
 hb_glib_script_from_script (hb_script_t script)
 {
@@ -373,6 +399,16 @@
 }
 #endif
 
+/**
+ * hb_glib_get_unicode_funcs:
+ *
+ * Fetches a Unicode-functions structure that is populated
+ * with the appropriate GLib function for each method.
+ *
+ * Return value: (transfer none): a pointer to the #hb_unicode_funcs_t Unicode-functions structure
+ *
+ * Since: 0.9.38
+ **/
 hb_unicode_funcs_t *
 hb_glib_get_unicode_funcs ()
 {
@@ -391,7 +427,13 @@
 
 /**
  * hb_glib_blob_create:
+ * @gbytes: the GBytes structure to work upon
  *
+ * Creates an #hb_blob_t blob from the specified
+ * GBytes data structure.
+ *
+ * Return value: (transfer full): the new #hb_blob_t blob object
+ *
  * Since: 0.9.38
  **/
 hb_blob_t *

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-enums.cc.tmpl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-enums.cc.tmpl	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-enums.cc.tmpl	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,6 +1,6 @@
 /*** BEGIN file-header ***/
 /*
- * Copyright © 2011  Google, Inc.
+ * Copyright (C) 2011  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-enums.h.tmpl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-enums.h.tmpl	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-enums.h.tmpl	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,6 +1,6 @@
 /*** BEGIN file-header ***/
 /*
- * Copyright © 2013  Google, Inc.
+ * Copyright (C) 2013  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *

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	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -32,11 +32,20 @@
 /**
  * SECTION:hb-gobject
  * @title: hb-gobject
- * @short_description: GObject integration
+ * @short_description: GObject integration support
  * @include: hb-gobject.h
  *
- * Functions for using HarfBuzz with the GObject library to provide
+ * Support for using HarfBuzz with the GObject library to provide
  * type data.
+ *
+ * The types and functions listed here are solely a linkage between
+ * HarfBuzz's public data types and the GTypes used by the GObject framework.
+ * HarfBuzz uses GObject introspection to generate its Python bindings 
+ * (and potentially other language bindings); client programs should never need
+ * to access the GObject-integration mechanics.
+ *
+ * For client programs using the GNOME and GTK software stack, please see the
+ * GLib and FreeType integration pages.
  **/
 
 

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	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.h	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2011  Google, Inc.
+ * Copyright (C) 2011  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject.h	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject.h	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2011  Google, Inc.
+ * Copyright (C) 2011  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -45,7 +45,11 @@
  * @short_description: Graphite2 integration
  * @include: hb-graphite2.h
  *
- * Functions for using HarfBuzz with the Graphite2 fonts.
+ * Functions for using HarfBuzz with fonts that include Graphite features.
+ * 
+ * For Graphite features to work, you must be sure that HarfBuzz was compiled
+ * with the `graphite2` shaping engine enabled. Currently, the default is to
+ * not enable `graphite2` shaping.
  **/
 
 
@@ -152,7 +156,15 @@
   free (data);
 }
 
-/*
+/**
+ * hb_graphite2_face_get_gr_face:
+ * @face: @hb_face_t to query
+ *
+ * Fetches the Graphite2 gr_face corresponding to the specified
+ * #hb_face_t face object.
+ *
+ * Return value: the gr_face found
+ *
  * Since: 0.9.10
  */
 gr_face *
@@ -376,7 +388,7 @@
   buffer->len = glyph_count;
 
   /* Positioning. */
-  unsigned int currclus = (unsigned int) -1;
+  unsigned int currclus = UINT_MAX;
   const hb_glyph_info_t *info = buffer->info;
   hb_glyph_position_t *pPos = hb_buffer_get_glyph_positions (buffer, nullptr);
   if (!HB_DIRECTION_IS_BACKWARD(buffer->props.direction))

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.h	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.h	2020-05-18 10:44:36 UTC (rev 55197)
@@ -32,7 +32,15 @@
 
 HB_BEGIN_DECLS
 
-
+/**
+ * HB_GRAPHITE2_TAG_SILF:
+ *
+ * The #hb_tag_t tag for the `Silf` table, which holds Graphite
+ * features. 
+ *
+ * For more information, see http://graphite.sil.org/
+ *
+ **/
 #define HB_GRAPHITE2_TAG_SILF HB_TAG('S','i','l','f')
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-icu.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -54,9 +54,23 @@
  * @short_description: ICU integration
  * @include: hb-icu.h
  *
- * Functions for using HarfBuzz with the ICU library to provide Unicode data.
+ * Functions for using HarfBuzz with the International Components for Unicode
+ * (ICU) library. HarfBuzz supports using ICU to provide Unicode data, by attaching
+ * ICU functions to the virtual methods in a #hb_unicode_funcs_t function
+ * structure.
  **/
 
+/**
+ * hb_icu_script_to_script:
+ * @script: The UScriptCode identifier to query
+ *
+ * Fetches the #hb_script_t script that corresponds to the
+ * specified UScriptCode identifier.
+ *
+ * Return value: the #hb_script_t script found
+ *
+ **/
+
 hb_script_t
 hb_icu_script_to_script (UScriptCode script)
 {
@@ -66,6 +80,16 @@
   return hb_script_from_string (uscript_getShortName (script), -1);
 }
 
+/**
+ * hb_icu_script_from_script:
+ * @script: The #hb_script_t script to query
+ *
+ * Fetches the UScriptCode identifier that corresponds to the
+ * specified #hb_script_t script.
+ *
+ * Return value: the UScriptCode identifier found
+ *
+ **/
 UScriptCode
 hb_icu_script_from_script (hb_script_t script)
 {
@@ -350,6 +374,16 @@
 }
 #endif
 
+/**
+ * hb_icu_get_unicode_funcs:
+ *
+ * Fetches a Unicode-functions structure that is populated
+ * with the appropriate ICU function for each method.
+ *
+ * Return value: (transfer none): a pointer to the #hb_unicode_funcs_t Unicode-functions structure
+ *
+ * Since: 0.9.38
+ **/
 hb_unicode_funcs_t *
 hb_icu_get_unicode_funcs ()
 {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-kern.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-kern.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-kern.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -52,8 +52,7 @@
     OT::hb_ot_apply_context_t c (1, font, buffer);
     c.set_lookup_mask (kern_mask);
     c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
-    OT::hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input;
-    skippy_iter.init (&c);
+    auto &skippy_iter = c.iter_input;
 
     bool horizontal = HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction);
     unsigned int count = buffer->len;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -41,22 +41,6 @@
  * 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>
@@ -70,7 +54,7 @@
 {
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wcast-align"
-  return * reinterpret_cast<Type*> ((char *) P + offset);
+  return * reinterpret_cast<const Type*> ((const char *) P + offset);
 #pragma GCC diagnostic pop
 }
 template<typename Type>
@@ -135,7 +119,7 @@
 
 #define DEFINE_SIZE_ARRAY(size, array) \
   DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \
-  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + HB_VAR_ARRAY * sizeof ((array)[0])) \
+  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + (HB_VAR_ARRAY+0) * sizeof ((array)[0])) \
   static constexpr unsigned null_size = (size); \
   static constexpr unsigned min_size = (size)
 
@@ -250,7 +234,7 @@
   static Returned* convert (Stored *p) { return p; }
 
   /* By default null/init/fini the object. */
-  static const Stored* get_null () { return &Null(Stored); }
+  static const Stored* get_null () { return &Null (Stored); }
   static Stored *create (Data *data)
   {
     Stored *p = (Stored *) calloc (1, sizeof (Stored));

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -69,7 +69,7 @@
 hb_map_t *
 hb_map_get_empty ()
 {
-  return const_cast<hb_map_t *> (&Null(hb_map_t));
+  return const_cast<hb_map_t *> (&Null (hb_map_t));
 }
 
 /**

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -135,8 +135,8 @@
       for (unsigned int i = 0; i < old_size; i++)
 	if (old_items[i].is_real ())
 	  set_with_hash (old_items[i].key,
-                         old_items[i].hash,
-                         old_items[i].value);
+			 old_items[i].hash,
+			 old_items[i].value);
 
     free (old_items);
 
@@ -211,7 +211,7 @@
   )
 
   /* Sink interface. */
-  hb_hashmap_t<K, V, kINVALID, vINVALID>& operator << (const hb_pair_t<K, V>& v)
+  hb_hashmap_t& operator << (const hb_pair_t<K, V>& v)
   { set (v.first, v.second); return *this; }
 
   protected:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-meta.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -396,5 +396,16 @@
 >;
 #define hb_is_trivial(T) hb_is_trivial<T>::value
 
+/* hb_unwrap_type (T)
+ * If T has no T::type, returns T. Otherwise calls itself on T::type recursively.
+ */
 
+template <typename T, typename>
+struct _hb_unwrap_type : hb_type_identity_t<T> {};
+template <typename T>
+struct _hb_unwrap_type<T, hb_void_t<typename T::type>> : _hb_unwrap_type<typename T::type, void> {};
+template <typename T>
+using hb_unwrap_type = _hb_unwrap_type<T, void>;
+#define hb_unwrap_type(T) typename hb_unwrap_type<T>::type
+
 #endif /* HB_META_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -104,7 +104,7 @@
 	  } \
 	}; \
 	namespace Namespace { \
-	static_assert (true, "Just so we take semicolon after.")
+	static_assert (true, "") /* Require semicolon after. */
 #define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \
 	const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::null_size]
 
@@ -117,7 +117,7 @@
 	    return _hb_Null_##Type; \
 	  } \
 	}; \
-	static_assert (true, "Just so we take semicolon after.")
+	static_assert (true, "") /* Require semicolon after. */
 #define DEFINE_NULL_INSTANCE(Type) \
 	const Type _hb_Null_##Type
 
@@ -135,7 +135,7 @@
 static inline Type& Crap () {
   static_assert (hb_null_size (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
   Type *obj = reinterpret_cast<Type *> (_hb_CrapPool);
-  memcpy (obj, &Null(Type), sizeof (*obj));
+  memcpy (obj, &Null (Type), sizeof (*obj));
   return *obj;
 }
 template <typename QType>
@@ -148,11 +148,11 @@
 
 template <typename Type>
 struct CrapOrNullHelper {
-  static Type & get () { return Crap(Type); }
+  static Type & get () { return Crap (Type); }
 };
 template <typename Type>
 struct CrapOrNullHelper<const Type> {
-  static const Type & get () { return Null(Type); }
+  static const Type & get () { return Null (Type); }
 };
 #define CrapOrNull(Type) CrapOrNullHelper<Type>::get ()
 
@@ -174,7 +174,7 @@
   /* Only auto-cast to const types. */
   template <typename C> operator const C * () const { return get (); }
   operator const char * () const { return (const char *) get (); }
-  T * get () const { return v ? v : const_cast<T *> (&Null(T)); }
+  T * get () const { return v ? v : const_cast<T *> (&Null (T)); }
   T * get_raw () const { return v; }
 
   T *v;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number-parser.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number-parser.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number-parser.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -30,10 +30,8 @@
 
 #include "hb.hh"
 
-#include <float.h>
 
-
-#line 37 "hb-number-parser.hh"
+#line 35 "hb-number-parser.hh"
 static const unsigned char _double_parser_trans_keys[] = {
 	0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u, 
 	46u, 101u, 0
@@ -93,12 +91,12 @@
 static const int double_parser_en_main = 1;
 
 
-#line 70 "hb-number-parser.rl"
+#line 68 "hb-number-parser.rl"
 
 
 /* Works only for n < 512 */
 static inline double
-_pow10 (unsigned int exponent)
+_pow10 (unsigned exponent)
 {
   static const double _powers_of_10[] =
   {
@@ -112,7 +110,7 @@
     100.,
     10.
   };
-  unsigned int mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
+  unsigned mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
   double result = 1;
   for (const double *power = _powers_of_10; mask; ++power, mask >>= 1)
     if (exponent & mask) result *= *power;
@@ -119,31 +117,30 @@
   return result;
 }
 
+/* a variant of strtod that also gets end of buffer in its second argument */
 static inline double
-strtod_rl (const char *buf, char **end_ptr)
+strtod_rl (const char *p, const char **end_ptr /* IN/OUT */)
 {
-  const char *p, *pe;
   double value = 0;
   double frac = 0;
   double frac_count = 0;
-  unsigned int exp = 0;
+  unsigned exp = 0;
   bool neg = false, exp_neg = false, exp_overflow = false;
-  const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 1^52-1 */
-  const unsigned int MAX_EXP = 0x7FFu; /* 1^11-1 */
-  p = buf;
-  pe = p + strlen (p);
+  const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 2^52-1 */
+  const unsigned MAX_EXP = 0x7FFu; /* 2^11-1 */
 
+  const char *pe = *end_ptr;
   while (p < pe && ISSPACE (*p))
     p++;
 
   int cs;
   
-#line 142 "hb-number-parser.hh"
+#line 139 "hb-number-parser.hh"
 	{
 	cs = double_parser_start;
 	}
 
-#line 147 "hb-number-parser.hh"
+#line 144 "hb-number-parser.hh"
 	{
 	int _slen;
 	int _trans;
@@ -169,21 +166,21 @@
 
 	switch ( _double_parser_trans_actions[_trans] ) {
 	case 1:
-#line 39 "hb-number-parser.rl"
+#line 37 "hb-number-parser.rl"
 	{ neg = true; }
 	break;
 	case 4:
-#line 40 "hb-number-parser.rl"
+#line 38 "hb-number-parser.rl"
 	{ exp_neg = true; }
 	break;
 	case 2:
-#line 42 "hb-number-parser.rl"
+#line 40 "hb-number-parser.rl"
 	{
 	value = value * 10. + ((*p) - '0');
 }
 	break;
 	case 3:
-#line 45 "hb-number-parser.rl"
+#line 43 "hb-number-parser.rl"
 	{
 	if (likely (frac <= MAX_FRACT / 10))
 	{
@@ -193,7 +190,7 @@
 }
 	break;
 	case 5:
-#line 52 "hb-number-parser.rl"
+#line 50 "hb-number-parser.rl"
 	{
 	if (likely (exp * 10 + ((*p) - '0') <= MAX_EXP))
 	  exp = exp * 10 + ((*p) - '0');
@@ -201,7 +198,7 @@
 	  exp_overflow = true;
 }
 	break;
-#line 205 "hb-number-parser.hh"
+#line 202 "hb-number-parser.hh"
 	}
 
 _again:
@@ -213,10 +210,10 @@
 	_out: {}
 	}
 
-#line 116 "hb-number-parser.rl"
+#line 113 "hb-number-parser.rl"
 
 
-  *end_ptr = (char *) p;
+  *end_ptr = p;
 
   if (frac_count) value += frac / _pow10 (frac_count);
   if (neg) value *= -1.;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number-parser.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number-parser.rl	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number-parser.rl	2020-05-18 10:44:36 UTC (rev 55197)
@@ -28,8 +28,6 @@
 
 #include "hb.hh"
 
-#include <float.h>
-
 %%{
 
 machine double_parser;
@@ -71,7 +69,7 @@
 
 /* Works only for n < 512 */
 static inline double
-_pow10 (unsigned int exponent)
+_pow10 (unsigned exponent)
 {
   static const double _powers_of_10[] =
   {
@@ -85,7 +83,7 @@
     100.,
     10.
   };
-  unsigned int mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
+  unsigned mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
   double result = 1;
   for (const double *power = _powers_of_10; mask; ++power, mask >>= 1)
     if (exponent & mask) result *= *power;
@@ -92,20 +90,19 @@
   return result;
 }
 
+/* a variant of strtod that also gets end of buffer in its second argument */
 static inline double
-strtod_rl (const char *buf, char **end_ptr)
+strtod_rl (const char *p, const char **end_ptr /* IN/OUT */)
 {
-  const char *p, *pe;
   double value = 0;
   double frac = 0;
   double frac_count = 0;
-  unsigned int exp = 0;
+  unsigned exp = 0;
   bool neg = false, exp_neg = false, exp_overflow = false;
-  const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 1^52-1 */
-  const unsigned int MAX_EXP = 0x7FFu; /* 1^11-1 */
-  p = buf;
-  pe = p + strlen (p);
+  const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 2^52-1 */
+  const unsigned MAX_EXP = 0x7FFu; /* 2^11-1 */
 
+  const char *pe = *end_ptr;
   while (p < pe && ISSPACE (*p))
     p++;
 
@@ -115,7 +112,7 @@
     write exec;
   }%%
 
-  *end_ptr = (char *) p;
+  *end_ptr = p;
 
   if (frac_count) value += frac / _pow10 (frac_count);
   if (neg) value *= -1.;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -25,13 +25,9 @@
 
 #include "hb.hh"
 #include "hb-machinery.hh"
+#include "hb-number.hh"
 #include "hb-number-parser.hh"
 
-#include <locale.h>
-#ifdef HAVE_XLOCALE_H
-#include <xlocale.h>
-#endif
-
 template<typename T, typename Func>
 static bool
 _parse_number (const char **pp, const char *end, T *pv,
@@ -38,8 +34,7 @@
 	       bool whole_buffer, Func f)
 {
   char buf[32];
-  unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1,
-			     (unsigned int) (end - *pp));
+  unsigned len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned) (end - *pp));
   strncpy (buf, *pp, len);
   buf[len] = '\0';
 
@@ -50,7 +45,8 @@
   *pv = f (p, &pend);
   if (unlikely (errno || p == pend ||
 		/* Check if consumed whole buffer if is requested */
-		(whole_buffer && pend - p != end - *pp))) return false;
+		(whole_buffer && pend - p != end - *pp)))
+    return false;
 
   *pp += pend - p;
   return true;
@@ -65,83 +61,20 @@
 }
 
 bool
-hb_parse_uint (const char **pp, const char *end, unsigned int *pv,
+hb_parse_uint (const char **pp, const char *end, unsigned *pv,
 	       bool whole_buffer, int base)
 {
-  return _parse_number<unsigned int> (pp, end, pv, whole_buffer,
-				      [base] (const char *p, char **end)
-				      { return strtoul (p, end, base); });
+  return _parse_number<unsigned> (pp, end, pv, whole_buffer,
+				  [base] (const char *p, char **end)
+				  { return strtoul (p, end, base); });
 }
 
-
-#if defined (HAVE_NEWLOCALE) && defined (HAVE_STRTOD_L)
-#define USE_XLOCALE 1
-#define HB_LOCALE_T locale_t
-#define HB_CREATE_LOCALE(locName) newlocale (LC_ALL_MASK, locName, nullptr)
-#define HB_FREE_LOCALE(loc) freelocale (loc)
-#elif defined(_MSC_VER)
-#define USE_XLOCALE 1
-#define HB_LOCALE_T _locale_t
-#define HB_CREATE_LOCALE(locName) _create_locale (LC_ALL, locName)
-#define HB_FREE_LOCALE(loc) _free_locale (loc)
-#define strtod_l(a, b, c) _strtod_l ((a), (b), (c))
-#endif
-
-#ifdef USE_XLOCALE
-
-#if HB_USE_ATEXIT
-static void free_static_C_locale ();
-#endif
-
-static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<HB_LOCALE_T>,
-							  hb_C_locale_lazy_loader_t>
-{
-  static HB_LOCALE_T create ()
-  {
-    HB_LOCALE_T C_locale = HB_CREATE_LOCALE ("C");
-
-#if HB_USE_ATEXIT
-    atexit (free_static_C_locale);
-#endif
-
-    return C_locale;
-  }
-  static void destroy (HB_LOCALE_T p)
-  {
-    HB_FREE_LOCALE (p);
-  }
-  static HB_LOCALE_T get_null ()
-  {
-    return nullptr;
-  }
-} static_C_locale;
-
-#if HB_USE_ATEXIT
-static
-void free_static_C_locale ()
-{
-  static_C_locale.free_instance ();
-}
-#endif
-
-static HB_LOCALE_T
-get_C_locale ()
-{
-  return static_C_locale.get_unconst ();
-}
-#endif /* USE_XLOCALE */
-
 bool
-hb_parse_double (const char **pp, const char *end, double *pv,
-		 bool whole_buffer)
+hb_parse_double (const char **pp, const char *end, double *pv, bool whole_buffer)
 {
-  return _parse_number<double> (pp, end, pv, whole_buffer,
-				[] (const char *p, char **end)
-				{
-#ifdef USE_XLOCALE
-				  return strtod_l (p, end, get_C_locale ());
-#else
-				  return strtod_rl (p, end);
-#endif
-				});
+  const char *pend = end;
+  *pv = strtod_rl (*pp, &pend);
+  if (unlikely (*pp == pend)) return false;
+  *pp = pend;
+  return !whole_buffer || end == pend;
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-file.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -249,7 +249,7 @@
     switch (u.header.version.major) {
     case 2: /* version 2 is compatible with version 1 */
     case 1: return u.version1.get_face (i);
-    default:return Null(OpenTypeFontFace);
+    default:return Null (OpenTypeFontFace);
     }
   }
 
@@ -284,7 +284,7 @@
 struct ResourceRecord
 {
   const OpenTypeFontFace & get_face (const void *data_base) const
-  { return CastR<OpenTypeFontFace> ((data_base+offset).arrayZ); }
+  { return * reinterpret_cast<const OpenTypeFontFace *> ((data_base+offset).arrayZ); }
 
   bool sanitize (hb_sanitize_context_t *c,
 		 const void *data_base) const
@@ -478,7 +478,7 @@
     case TrueTypeTag:	return u.fontFace;
     case TTCTag:	return u.ttcHeader.get_face (i);
     case DFontTag:	return u.rfHeader.get_face (i, base_offset);
-    default:		return Null(OpenTypeFontFace);
+    default:		return Null (OpenTypeFontFace);
     }
   }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -73,6 +73,13 @@
 
   HB_INTERNAL static int cmp (const IntType *a, const IntType *b)
   { return b->cmp (*a); }
+  HB_INTERNAL static int cmp (const void *a, const void *b)
+  {
+    IntType *pa = (IntType *) a;
+    IntType *pb = (IntType *) b;
+
+    return pb->cmp (*pa);
+  }
   template <typename Type2>
   int cmp (Type2 a) const
   {
@@ -306,11 +313,8 @@
   }
 
   template <typename ...Ts>
-  bool serialize_subset (hb_subset_context_t *c,
-			 const OffsetTo& src,
-			 const void *src_base,
-			 const void *dst_base,
-			 Ts&&... ds)
+  bool serialize_subset (hb_subset_context_t *c, const OffsetTo& src,
+			 const void *src_base, Ts&&... ds)
   {
     *this = 0;
     if (src.is_null ())
@@ -323,7 +327,7 @@
     bool ret = c->dispatch (src_base+src, hb_forward<Ts> (ds)...);
 
     if (ret || !has_null)
-      s->add_link (*this, s->pop_pack (), dst_base);
+      s->add_link (*this, s->pop_pack ());
     else
       s->pop_discard ();
 
@@ -331,11 +335,13 @@
   }
 
   /* TODO: Somehow merge this with previous function into a serialize_dispatch(). */
+  /* Workaround clang bug: https://bugs.llvm.org/show_bug.cgi?id=23029
+   * Can't compile: whence = hb_serialize_context_t::Head followed by Ts&&...
+   */
   template <typename ...Ts>
-  bool serialize_copy (hb_serialize_context_t *c,
-		       const OffsetTo& src,
-		       const void *src_base,
-		       const void *dst_base,
+  bool serialize_copy (hb_serialize_context_t *c, const OffsetTo& src,
+		       const void *src_base, unsigned dst_bias,
+		       hb_serialize_context_t::whence_t whence,
 		       Ts&&... ds)
   {
     *this = 0;
@@ -346,11 +352,15 @@
 
     bool ret = c->copy (src_base+src, hb_forward<Ts> (ds)...);
 
-    c->add_link (*this, c->pop_pack (), dst_base);
+    c->add_link (*this, c->pop_pack (), whence, dst_bias);
 
     return ret;
   }
 
+  bool serialize_copy (hb_serialize_context_t *c, const OffsetTo& src,
+		       const void *src_base, unsigned dst_bias = 0)
+  { return serialize_copy (c, src, src_base, dst_bias, hb_serialize_context_t::Head); }
+
   bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const
   {
     TRACE_SANITIZE (this);
@@ -594,7 +604,7 @@
   hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
   { return as_array ().sub_array (start_offset, count); }
 
-  bool serialize (hb_serialize_context_t *c, unsigned int items_len)
+  hb_success_t serialize (hb_serialize_context_t *c, unsigned items_len)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
@@ -604,7 +614,7 @@
   }
   template <typename Iterator,
 	    hb_requires (hb_is_source_of (Iterator, Type))>
-  bool serialize (hb_serialize_context_t *c, Iterator items)
+  hb_success_t serialize (hb_serialize_context_t *c, Iterator items)
   {
     TRACE_SERIALIZE (this);
     unsigned count = items.len ();
@@ -1026,18 +1036,15 @@
   template <typename T>
   const Type *bsearch (const T &key) const
   {
-    unsigned int size = header.unitSize;
-    int min = 0, max = (int) get_length () - 1;
-    while (min <= max)
-    {
-      int mid = ((unsigned int) min + (unsigned int) max) / 2;
-      const Type *p = (const Type *) (((const char *) &bytesZ) + (mid * size));
-      int c = p->cmp (key);
-      if (c < 0) max = mid - 1;
-      else if (c > 0) min = mid + 1;
-      else return p;
-    }
-    return nullptr;
+    unsigned pos;
+    return hb_bsearch_impl (&pos,
+			    key,
+			    (const void *) bytesZ,
+			    get_length (),
+			    header.unitSize,
+			    _hb_cmp_method<T, Type>)
+	   ? (const Type *) (((const char *) &bytesZ) + (pos * header.unitSize))
+	   : nullptr;
   }
 
   private:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff-common.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -38,6 +38,9 @@
 
 #define CFF_UNDEF_CODE  0xFFFFFFFF
 
+using objidx_t = hb_serialize_context_t::objidx_t;
+using whence_t = hb_serialize_context_t::whence_t;
+
 /* utility macro */
 template<typename Type>
 static inline const Type& StructAtOffsetOrNull (const void *P, unsigned int offset)
@@ -89,11 +92,14 @@
   unsigned int offset_array_size () const
   { return calculate_offset_array_size (offSize, count); }
 
-  static unsigned int calculate_serialized_size (unsigned int offSize_, unsigned int count,
-						 unsigned int dataSize)
+  CFFIndex *copy (hb_serialize_context_t *c) const
   {
-    if (count == 0) return COUNT::static_size;
-    return min_size + calculate_offset_array_size (offSize_, count) + dataSize;
+    TRACE_SERIALIZE (this);
+    unsigned int size = get_size ();
+    CFFIndex *out = c->allocate_size<CFFIndex> (size);
+    if (likely (out))
+      memcpy (out, this, size);
+    return_trace (out);
   }
 
   bool serialize (hb_serialize_context_t *c, const CFFIndex &src)
@@ -101,7 +107,7 @@
     TRACE_SERIALIZE (this);
     unsigned int size = src.get_size ();
     CFFIndex *dest = c->allocate_size<CFFIndex> (size);
-    if (unlikely (dest == nullptr)) return_trace (false);
+    if (unlikely (!dest)) return_trace (false);
     memcpy (dest, &src, size);
     return_trace (true);
   }
@@ -114,7 +120,7 @@
     if (byteArray.length == 0)
     {
       COUNT *dest = c->allocate_min<COUNT> ();
-      if (unlikely (dest == nullptr)) return_trace (false);
+      if (unlikely (!dest)) return_trace (false);
       *dest = 0;
     }
     else
@@ -139,10 +145,9 @@
       /* serialize data */
       for (unsigned int i = 0; i < byteArray.length; i++)
       {
-      	const byte_str_t &bs = byteArray[i];
-	unsigned char  *dest = c->allocate_size<unsigned char> (bs.length);
-	if (unlikely (dest == nullptr))
-	  return_trace (false);
+	const byte_str_t &bs = byteArray[i];
+	unsigned char *dest = c->allocate_size<unsigned char> (bs.length);
+	if (unlikely (!dest)) return_trace (false);
 	memcpy (dest, &bs[0], bs.length);
       }
     }
@@ -163,6 +168,71 @@
     return result;
   }
 
+  template <typename Iterator,
+	    hb_requires (hb_is_iterator (Iterator))>
+  bool serialize (hb_serialize_context_t *c,
+		  Iterator it)
+  {
+    TRACE_SERIALIZE (this);
+    if (it.len () == 0)
+    {
+      COUNT *dest = c->allocate_min<COUNT> ();
+      if (unlikely (!dest)) return_trace (false);
+      *dest = 0;
+    }
+    else
+    {
+      serialize_header(c, + it | hb_map ([] (const byte_str_t &_) { return _.length; }));
+      for (const byte_str_t &_ : +it)
+	_.copy (c);
+    }
+    return_trace (true);
+  }
+
+  bool serialize (hb_serialize_context_t *c,
+		  const byte_str_array_t &byteArray)
+  { return serialize (c, + hb_iter (byteArray)); }
+
+  bool serialize (hb_serialize_context_t *c,
+		  const str_buff_vec_t &buffArray)
+  {
+    auto it =
+    + hb_iter (buffArray)
+    | hb_map ([] (const str_buff_t &_) { return byte_str_t (_.arrayZ, _.length); })
+    ;
+    return serialize (c, it);
+  }
+
+  template <typename Iterator,
+	    hb_requires (hb_is_iterator (Iterator))>
+  bool serialize_header (hb_serialize_context_t *c,
+			Iterator it)
+  {
+    TRACE_SERIALIZE (this);
+
+    unsigned total = + it | hb_reduce (hb_add, 0);
+    unsigned off_size = calcOffSize (total);
+
+    /* serialize CFFIndex header */
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    this->count = it.len ();
+    this->offSize = off_size;
+    if (unlikely (!c->allocate_size<HBUINT8> (off_size * (it.len () + 1))))
+      return_trace (false);
+
+    /* serialize indices */
+    unsigned int offset = 1;
+    unsigned int i = 0;
+    for (unsigned _ : +it)
+    {
+      CFFIndex<COUNT>::set_offset_at (i++, offset);
+      offset += _;
+    }
+    CFFIndex<COUNT>::set_offset_at (i, offset);
+
+    return_trace (true);
+  }
+
   void set_offset_at (unsigned int index, unsigned int offset)
   {
     HBUINT8 *p = offsets + offSize * index + offSize;
@@ -189,7 +259,7 @@
   unsigned int length_at (unsigned int index) const
   {
     if (unlikely ((offset_at (index + 1) < offset_at (index)) ||
-	          (offset_at (index + 1) > offset_at (count))))
+		  (offset_at (index + 1) > offset_at (count))))
       return 0;
     return offset_at (index + 1) - offset_at (index);
   }
@@ -237,7 +307,8 @@
   public:
   COUNT		count;		/* Number of object data. Note there are (count+1) offsets */
   HBUINT8	offSize;	/* The byte size of each offset in the offsets array. */
-  HBUINT8	offsets[HB_VAR_ARRAY];	/* The array of (count + 1) offsets into objects array (1-base). */
+  HBUINT8	offsets[HB_VAR_ARRAY];
+				/* The array of (count + 1) offsets into objects array (1-base). */
   /* HBUINT8 data[HB_VAR_ARRAY];	Object data */
   public:
   DEFINE_SIZE_ARRAY (COUNT::static_size + HBUINT8::static_size, offsets);
@@ -250,7 +321,7 @@
   {
     if (likely (index < CFFIndex<COUNT>::count))
       return byte_str_t (CFFIndex<COUNT>::data_base () + CFFIndex<COUNT>::offset_at (index) - 1, CFFIndex<COUNT>::length_at (index));
-    return Null(byte_str_t);
+    return Null (byte_str_t);
   }
 
   template <typename DATA, typename PARAM1, typename PARAM2>
@@ -284,85 +355,41 @@
     for (unsigned int i = 0; i < dataArrayLen; i++)
     {
       TYPE *dest = c->start_embed<TYPE> ();
-      if (unlikely (dest == nullptr ||
-		    !dest->serialize (c, dataArray[i], param1, param2)))
+      if (unlikely (!dest || !dest->serialize (c, dataArray[i], param1, param2)))
 	return_trace (false);
     }
     return_trace (true);
   }
-
-  /* in parallel to above */
-  template <typename DATA, typename PARAM>
-  static unsigned int calculate_serialized_size (unsigned int &offSize_ /* OUT */,
-						 const DATA *dataArray,
-						 unsigned int dataArrayLen,
-						 hb_vector_t<unsigned int> &dataSizeArray, /* OUT */
-						 const PARAM &param)
-  {
-    /* determine offset size */
-    unsigned int totalDataSize = 0;
-    for (unsigned int i = 0; i < dataArrayLen; i++)
-    {
-      unsigned int dataSize = TYPE::calculate_serialized_size (dataArray[i], param);
-      dataSizeArray[i] = dataSize;
-      totalDataSize += dataSize;
-    }
-    offSize_ = calcOffSize (totalDataSize);
-
-    return CFFIndex<COUNT>::calculate_serialized_size (offSize_, dataArrayLen, totalDataSize);
-  }
 };
 
 /* Top Dict, Font Dict, Private Dict */
 struct Dict : UnsizedByteStr
 {
-  template <typename DICTVAL, typename OP_SERIALIZER, typename PARAM>
+  template <typename DICTVAL, typename OP_SERIALIZER, typename ...Ts>
   bool serialize (hb_serialize_context_t *c,
 		  const DICTVAL &dictval,
 		  OP_SERIALIZER& opszr,
-		  PARAM& param)
+		  Ts&&... ds)
   {
     TRACE_SERIALIZE (this);
     for (unsigned int i = 0; i < dictval.get_count (); i++)
-      if (unlikely (!opszr.serialize (c, dictval[i], param)))
+      if (unlikely (!opszr.serialize (c, dictval[i], hb_forward<Ts> (ds)...)))
 	return_trace (false);
 
     return_trace (true);
   }
 
-  /* in parallel to above */
-  template <typename DICTVAL, typename OP_SERIALIZER, typename PARAM>
-  static unsigned int calculate_serialized_size (const DICTVAL &dictval,
-						 OP_SERIALIZER& opszr,
-						 PARAM& param)
+  template <typename T, typename V>
+  static bool serialize_int_op (hb_serialize_context_t *c, op_code_t op, V value, op_code_t intOp)
   {
-    unsigned int size = 0;
-    for (unsigned int i = 0; i < dictval.get_count (); i++)
-      size += opszr.calculate_serialized_size (dictval[i], param);
-    return size;
-  }
-
-  template <typename DICTVAL, typename OP_SERIALIZER>
-  static unsigned int calculate_serialized_size (const DICTVAL &dictval,
-						 OP_SERIALIZER& opszr)
-  {
-    unsigned int size = 0;
-    for (unsigned int i = 0; i < dictval.get_count (); i++)
-      size += opszr.calculate_serialized_size (dictval[i]);
-    return size;
-  }
-
-  template <typename INTTYPE, int minVal, int maxVal>
-  static bool serialize_int_op (hb_serialize_context_t *c, op_code_t op, int value, op_code_t intOp)
-  {
     // XXX: not sure why but LLVM fails to compile the following 'unlikely' macro invocation
-    if (/*unlikely*/ (!serialize_int<INTTYPE, minVal, maxVal> (c, intOp, value)))
+    if (/*unlikely*/ (!serialize_int<T, V> (c, intOp, value)))
       return false;
 
     TRACE_SERIALIZE (this);
     /* serialize the opcode */
     HBUINT8 *p = c->allocate_size<HBUINT8> (OpCode_Size (op));
-    if (unlikely (p == nullptr)) return_trace (false);
+    if (unlikely (!p)) return_trace (false);
     if (Is_OpCode_ESC (op))
     {
       *p = OpCode_escape;
@@ -373,17 +400,28 @@
     return_trace (true);
   }
 
-  static bool serialize_uint4_op (hb_serialize_context_t *c, op_code_t op, int value)
-  { return serialize_int_op<HBUINT32, 0, 0x7FFFFFFF> (c, op, value, OpCode_longintdict); }
+  template <typename V>
+  static bool serialize_int4_op (hb_serialize_context_t *c, op_code_t op, V value)
+  { return serialize_int_op<HBINT32> (c, op, value, OpCode_longintdict); }
 
-  static bool serialize_uint2_op (hb_serialize_context_t *c, op_code_t op, int value)
-  { return serialize_int_op<HBUINT16, 0, 0x7FFF> (c, op, value, OpCode_shortint); }
+  template <typename V>
+  static bool serialize_int2_op (hb_serialize_context_t *c, op_code_t op, V value)
+  { return serialize_int_op<HBINT16> (c, op, value, OpCode_shortint); }
 
-  static bool serialize_offset4_op (hb_serialize_context_t *c, op_code_t op, int value)
-  { return serialize_uint4_op (c, op, value); }
+  template <typename T, int int_op>
+  static bool serialize_link_op (hb_serialize_context_t *c, op_code_t op, objidx_t link, whence_t whence)
+  {
+    T &ofs = *(T *) (c->head + OpCode_Size (int_op));
+    if (unlikely (!serialize_int_op<T> (c, op, 0, int_op))) return false;
+    c->add_link (ofs, link, whence);
+    return true;
+  }
 
-  static bool serialize_offset2_op (hb_serialize_context_t *c, op_code_t op, int value)
-  { return serialize_uint2_op (c, op, value); }
+  static bool serialize_link4_op (hb_serialize_context_t *c, op_code_t op, objidx_t link, whence_t whence = whence_t::Head)
+  { return serialize_link_op<HBINT32, OpCode_longintdict> (c, op, link, whence); }
+
+  static bool serialize_link2_op (hb_serialize_context_t *c, op_code_t op, objidx_t link, whence_t whence = whence_t::Head)
+  { return serialize_link_op<HBINT16, OpCode_shortint> (c, op, link, whence); }
 };
 
 struct TopDict : Dict {};
@@ -392,106 +430,40 @@
 
 struct table_info_t
 {
-  void init () { offSize = offset = size = 0; }
+  void init () { offset = size = 0; link = 0; }
 
   unsigned int    offset;
   unsigned int    size;
-  unsigned int    offSize;
+  objidx_t	  link;
 };
 
 template <typename COUNT>
 struct FDArray : CFFIndexOf<COUNT, FontDict>
 {
-  /* used by CFF1 */
-  template <typename DICTVAL, typename OP_SERIALIZER>
+  template <typename DICTVAL, typename INFO, typename Iterator, typename OP_SERIALIZER>
   bool serialize (hb_serialize_context_t *c,
-		  unsigned int offSize_,
-		  const hb_vector_t<DICTVAL> &fontDicts,
+		  Iterator it,
 		  OP_SERIALIZER& opszr)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (*this))) return_trace (false);
-    this->count = fontDicts.length;
-    this->offSize = offSize_;
-    if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (fontDicts.length + 1))))
-      return_trace (false);
 
-    /* serialize font dict offsets */
-    unsigned int offset = 1;
-    unsigned int fid = 0;
-    for (; fid < fontDicts.length; fid++)
+    /* serialize INDEX data */
+    hb_vector_t<unsigned> sizes;
+    c->push ();
+    + it
+    | hb_map ([&] (const hb_pair_t<const DICTVAL&, const INFO&> &_)
     {
-      CFFIndexOf<COUNT, FontDict>::set_offset_at (fid, offset);
-      offset += FontDict::calculate_serialized_size (fontDicts[fid], opszr);
-    }
-    CFFIndexOf<COUNT, FontDict>::set_offset_at (fid, offset);
-
-    /* serialize font dicts */
-    for (unsigned int i = 0; i < fontDicts.length; i++)
-    {
       FontDict *dict = c->start_embed<FontDict> ();
-      if (unlikely (!dict->serialize (c, fontDicts[i], opszr, fontDicts[i])))
-	return_trace (false);
-    }
-    return_trace (true);
-  }
+		dict->serialize (c, _.first, opszr, _.second);
+		return c->head - (const char*)dict;
+	      })
+    | hb_sink (sizes)
+    ;
+    c->pop_pack (false);
 
-  /* used by CFF2 */
-  template <typename DICTVAL, typename OP_SERIALIZER>
-  bool serialize (hb_serialize_context_t *c,
-		  unsigned int offSize_,
-		  const hb_vector_t<DICTVAL> &fontDicts,
-		  unsigned int fdCount,
-		  const hb_inc_bimap_t &fdmap,
-		  OP_SERIALIZER& opszr,
-		  const hb_vector_t<table_info_t> &privateInfos)
-  {
-    TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (*this))) return_trace (false);
-    this->count = fdCount;
-    this->offSize = offSize_;
-    if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (fdCount + 1))))
-      return_trace (false);
-
-    /* serialize font dict offsets */
-    unsigned int  offset = 1;
-    unsigned int  fid = 0;
-    for (unsigned i = 0; i < fontDicts.length; i++)
-      if (fdmap.has (i))
-      {
-      	if (unlikely (fid >= fdCount)) return_trace (false);
-	CFFIndexOf<COUNT, FontDict>::set_offset_at (fid++, offset);
-	offset += FontDict::calculate_serialized_size (fontDicts[i], opszr);
-      }
-    CFFIndexOf<COUNT, FontDict>::set_offset_at (fid, offset);
-
-    /* serialize font dicts */
-    for (unsigned int i = 0; i < fontDicts.length; i++)
-      if (fdmap.has (i))
-      {
-	FontDict *dict = c->start_embed<FontDict> ();
-	if (unlikely (!dict->serialize (c, fontDicts[i], opszr, privateInfos[fdmap[i]])))
-	  return_trace (false);
-      }
-    return_trace (true);
+    /* serialize INDEX header */
+    return_trace (CFFIndex<COUNT>::serialize_header (c, hb_iter (sizes)));
   }
-
-  /* in parallel to above */
-  template <typename OP_SERIALIZER, typename DICTVAL>
-  static unsigned int calculate_serialized_size (unsigned int &offSize_ /* OUT */,
-						 const hb_vector_t<DICTVAL> &fontDicts,
-						 unsigned int fdCount,
-						 const hb_inc_bimap_t &fdmap,
-						 OP_SERIALIZER& opszr)
-  {
-    unsigned int dictsSize = 0;
-    for (unsigned int i = 0; i < fontDicts.len; i++)
-      if (fdmap.has (i))
-	dictsSize += FontDict::calculate_serialized_size (fontDicts[i], opszr);
-
-    offSize_ = calcOffSize (dictsSize);
-    return CFFIndex<COUNT>::calculate_serialized_size (offSize_, fdCount, dictsSize);
-  }
 };
 
 /* FDSelect */
@@ -544,7 +516,7 @@
   {
     TRACE_SANITIZE (this);
     if (unlikely (!c->check_struct (this) || !ranges.sanitize (c, nullptr, fdcount) ||
-    		  (nRanges () == 0) || ranges[0].first != 0))
+		  (nRanges () == 0) || ranges[0].first != 0))
       return_trace (false);
 
     for (unsigned int i = 1; i < nRanges (); i++)
@@ -588,14 +560,11 @@
     TRACE_SERIALIZE (this);
     unsigned int size = src.get_size (num_glyphs);
     FDSelect *dest = c->allocate_size<FDSelect> (size);
-    if (unlikely (dest == nullptr)) return_trace (false);
+    if (unlikely (!dest)) return_trace (false);
     memcpy (dest, &src, size);
     return_trace (true);
   }
 
-  unsigned int calculate_serialized_size (unsigned int num_glyphs) const
-  { return get_size (num_glyphs); }
-
   unsigned int get_size (unsigned int num_glyphs) const
   {
     switch (format)

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-std-str.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-std-str.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-std-str.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -0,0 +1,425 @@
+/*
+ * Copyright © 2019  Adobe, 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.
+ *
+ * Adobe Author(s): Michiharu Ariza
+ */
+
+#ifndef HB_OT_CFF1_STD_STR_HH
+#if 0 /* Make checks happy. */
+#define HB_OT_CFF1_STD_STR_HH
+#include "hb.hh"
+#endif
+
+_S(".notdef")
+_S("space")
+_S("exclam")
+_S("quotedbl")
+_S("numbersign")
+_S("dollar")
+_S("percent")
+_S("ampersand")
+_S("quoteright")
+_S("parenleft")
+_S("parenright")
+_S("asterisk")
+_S("plus")
+_S("comma")
+_S("hyphen")
+_S("period")
+_S("slash")
+_S("zero")
+_S("one")
+_S("two")
+_S("three")
+_S("four")
+_S("five")
+_S("six")
+_S("seven")
+_S("eight")
+_S("nine")
+_S("colon")
+_S("semicolon")
+_S("less")
+_S("equal")
+_S("greater")
+_S("question")
+_S("at")
+_S("A")
+_S("B")
+_S("C")
+_S("D")
+_S("E")
+_S("F")
+_S("G")
+_S("H")
+_S("I")
+_S("J")
+_S("K")
+_S("L")
+_S("M")
+_S("N")
+_S("O")
+_S("P")
+_S("Q")
+_S("R")
+_S("S")
+_S("T")
+_S("U")
+_S("V")
+_S("W")
+_S("X")
+_S("Y")
+_S("Z")
+_S("bracketleft")
+_S("backslash")
+_S("bracketright")
+_S("asciicircum")
+_S("underscore")
+_S("quoteleft")
+_S("a")
+_S("b")
+_S("c")
+_S("d")
+_S("e")
+_S("f")
+_S("g")
+_S("h")
+_S("i")
+_S("j")
+_S("k")
+_S("l")
+_S("m")
+_S("n")
+_S("o")
+_S("p")
+_S("q")
+_S("r")
+_S("s")
+_S("t")
+_S("u")
+_S("v")
+_S("w")
+_S("x")
+_S("y")
+_S("z")
+_S("braceleft")
+_S("bar")
+_S("braceright")
+_S("asciitilde")
+_S("exclamdown")
+_S("cent")
+_S("sterling")
+_S("fraction")
+_S("yen")
+_S("florin")
+_S("section")
+_S("currency")
+_S("quotesingle")
+_S("quotedblleft")
+_S("guillemotleft")
+_S("guilsinglleft")
+_S("guilsinglright")
+_S("fi")
+_S("fl")
+_S("endash")
+_S("dagger")
+_S("daggerdbl")
+_S("periodcentered")
+_S("paragraph")
+_S("bullet")
+_S("quotesinglbase")
+_S("quotedblbase")
+_S("quotedblright")
+_S("guillemotright")
+_S("ellipsis")
+_S("perthousand")
+_S("questiondown")
+_S("grave")
+_S("acute")
+_S("circumflex")
+_S("tilde")
+_S("macron")
+_S("breve")
+_S("dotaccent")
+_S("dieresis")
+_S("ring")
+_S("cedilla")
+_S("hungarumlaut")
+_S("ogonek")
+_S("caron")
+_S("emdash")
+_S("AE")
+_S("ordfeminine")
+_S("Lslash")
+_S("Oslash")
+_S("OE")
+_S("ordmasculine")
+_S("ae")
+_S("dotlessi")
+_S("lslash")
+_S("oslash")
+_S("oe")
+_S("germandbls")
+_S("onesuperior")
+_S("logicalnot")
+_S("mu")
+_S("trademark")
+_S("Eth")
+_S("onehalf")
+_S("plusminus")
+_S("Thorn")
+_S("onequarter")
+_S("divide")
+_S("brokenbar")
+_S("degree")
+_S("thorn")
+_S("threequarters")
+_S("twosuperior")
+_S("registered")
+_S("minus")
+_S("eth")
+_S("multiply")
+_S("threesuperior")
+_S("copyright")
+_S("Aacute")
+_S("Acircumflex")
+_S("Adieresis")
+_S("Agrave")
+_S("Aring")
+_S("Atilde")
+_S("Ccedilla")
+_S("Eacute")
+_S("Ecircumflex")
+_S("Edieresis")
+_S("Egrave")
+_S("Iacute")
+_S("Icircumflex")
+_S("Idieresis")
+_S("Igrave")
+_S("Ntilde")
+_S("Oacute")
+_S("Ocircumflex")
+_S("Odieresis")
+_S("Ograve")
+_S("Otilde")
+_S("Scaron")
+_S("Uacute")
+_S("Ucircumflex")
+_S("Udieresis")
+_S("Ugrave")
+_S("Yacute")
+_S("Ydieresis")
+_S("Zcaron")
+_S("aacute")
+_S("acircumflex")
+_S("adieresis")
+_S("agrave")
+_S("aring")
+_S("atilde")
+_S("ccedilla")
+_S("eacute")
+_S("ecircumflex")
+_S("edieresis")
+_S("egrave")
+_S("iacute")
+_S("icircumflex")
+_S("idieresis")
+_S("igrave")
+_S("ntilde")
+_S("oacute")
+_S("ocircumflex")
+_S("odieresis")
+_S("ograve")
+_S("otilde")
+_S("scaron")
+_S("uacute")
+_S("ucircumflex")
+_S("udieresis")
+_S("ugrave")
+_S("yacute")
+_S("ydieresis")
+_S("zcaron")
+_S("exclamsmall")
+_S("Hungarumlautsmall")
+_S("dollaroldstyle")
+_S("dollarsuperior")
+_S("ampersandsmall")
+_S("Acutesmall")
+_S("parenleftsuperior")
+_S("parenrightsuperior")
+_S("twodotenleader")
+_S("onedotenleader")
+_S("zerooldstyle")
+_S("oneoldstyle")
+_S("twooldstyle")
+_S("threeoldstyle")
+_S("fouroldstyle")
+_S("fiveoldstyle")
+_S("sixoldstyle")
+_S("sevenoldstyle")
+_S("eightoldstyle")
+_S("nineoldstyle")
+_S("commasuperior")
+_S("threequartersemdash")
+_S("periodsuperior")
+_S("questionsmall")
+_S("asuperior")
+_S("bsuperior")
+_S("centsuperior")
+_S("dsuperior")
+_S("esuperior")
+_S("isuperior")
+_S("lsuperior")
+_S("msuperior")
+_S("nsuperior")
+_S("osuperior")
+_S("rsuperior")
+_S("ssuperior")
+_S("tsuperior")
+_S("ff")
+_S("ffi")
+_S("ffl")
+_S("parenleftinferior")
+_S("parenrightinferior")
+_S("Circumflexsmall")
+_S("hyphensuperior")
+_S("Gravesmall")
+_S("Asmall")
+_S("Bsmall")
+_S("Csmall")
+_S("Dsmall")
+_S("Esmall")
+_S("Fsmall")
+_S("Gsmall")
+_S("Hsmall")
+_S("Ismall")
+_S("Jsmall")
+_S("Ksmall")
+_S("Lsmall")
+_S("Msmall")
+_S("Nsmall")
+_S("Osmall")
+_S("Psmall")
+_S("Qsmall")
+_S("Rsmall")
+_S("Ssmall")
+_S("Tsmall")
+_S("Usmall")
+_S("Vsmall")
+_S("Wsmall")
+_S("Xsmall")
+_S("Ysmall")
+_S("Zsmall")
+_S("colonmonetary")
+_S("onefitted")
+_S("rupiah")
+_S("Tildesmall")
+_S("exclamdownsmall")
+_S("centoldstyle")
+_S("Lslashsmall")
+_S("Scaronsmall")
+_S("Zcaronsmall")
+_S("Dieresissmall")
+_S("Brevesmall")
+_S("Caronsmall")
+_S("Dotaccentsmall")
+_S("Macronsmall")
+_S("figuredash")
+_S("hypheninferior")
+_S("Ogoneksmall")
+_S("Ringsmall")
+_S("Cedillasmall")
+_S("questiondownsmall")
+_S("oneeighth")
+_S("threeeighths")
+_S("fiveeighths")
+_S("seveneighths")
+_S("onethird")
+_S("twothirds")
+_S("zerosuperior")
+_S("foursuperior")
+_S("fivesuperior")
+_S("sixsuperior")
+_S("sevensuperior")
+_S("eightsuperior")
+_S("ninesuperior")
+_S("zeroinferior")
+_S("oneinferior")
+_S("twoinferior")
+_S("threeinferior")
+_S("fourinferior")
+_S("fiveinferior")
+_S("sixinferior")
+_S("seveninferior")
+_S("eightinferior")
+_S("nineinferior")
+_S("centinferior")
+_S("dollarinferior")
+_S("periodinferior")
+_S("commainferior")
+_S("Agravesmall")
+_S("Aacutesmall")
+_S("Acircumflexsmall")
+_S("Atildesmall")
+_S("Adieresissmall")
+_S("Aringsmall")
+_S("AEsmall")
+_S("Ccedillasmall")
+_S("Egravesmall")
+_S("Eacutesmall")
+_S("Ecircumflexsmall")
+_S("Edieresissmall")
+_S("Igravesmall")
+_S("Iacutesmall")
+_S("Icircumflexsmall")
+_S("Idieresissmall")
+_S("Ethsmall")
+_S("Ntildesmall")
+_S("Ogravesmall")
+_S("Oacutesmall")
+_S("Ocircumflexsmall")
+_S("Otildesmall")
+_S("Odieresissmall")
+_S("OEsmall")
+_S("Oslashsmall")
+_S("Ugravesmall")
+_S("Uacutesmall")
+_S("Ucircumflexsmall")
+_S("Udieresissmall")
+_S("Yacutesmall")
+_S("Thornsmall")
+_S("Ydieresissmall")
+_S("001.000")
+_S("001.001")
+_S("001.002")
+_S("001.003")
+_S("Black")
+_S("Bold")
+_S("Book")
+_S("Light")
+_S("Medium")
+_S("Regular")
+_S("Roman")
+_S("Semibold")
+
+#endif /* HB_OT_CFF1_STD_STR_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -28,11 +28,25 @@
 
 #ifndef HB_NO_CFF
 
+#include "hb-draw.hh"
+#include "hb-algs.hh"
 #include "hb-ot-cff1-table.hh"
 #include "hb-cff1-interp-cs.hh"
 
 using namespace CFF;
 
+struct sid_to_gid_t
+{
+  uint16_t  sid;
+  uint8_t   gid;
+
+  int cmp (uint16_t a) const
+  {
+    if (a == sid) return 0;
+    return (a < sid) ? -1 : 1;
+  }
+};
+
 /* SID to code */
 static const uint8_t standard_encoding_to_code [] =
 {
@@ -104,6 +118,80 @@
   340,  341,  342,  343,  344,  345,  346
 };
 
+/* SID to glyph ID */
+static const sid_to_gid_t expert_charset_sid_to_gid [] =
+{
+    { 1, 1 },     { 13, 12 },   { 14, 13 },   { 15, 14 },
+    { 27, 26 },   { 28, 27 },   { 99, 15 },   { 109, 46 },
+    { 110, 47 },  { 150, 111 }, { 155, 101 }, { 158, 100 },
+    { 163, 102 }, { 164, 112 }, { 169, 113 }, { 229, 2 },
+    { 230, 3 },   { 231, 4 },   { 232, 5 },   { 233, 6 },
+    { 234, 7 },   { 235, 8 },   { 236, 9 },   { 237, 10 },
+    { 238, 11 },  { 239, 16 },  { 240, 17 },  { 241, 18 },
+    { 242, 19 },  { 243, 20 },  { 244, 21 },  { 245, 22 },
+    { 246, 23 },  { 247, 24 },  { 248, 25 },  { 249, 28 },
+    { 250, 29 },  { 251, 30 },  { 252, 31 },  { 253, 32 },
+    { 254, 33 },  { 255, 34 },  { 256, 35 },  { 257, 36 },
+    { 258, 37 },  { 259, 38 },  { 260, 39 },  { 261, 40 },
+    { 262, 41 },  { 263, 42 },  { 264, 43 },  { 265, 44 },
+    { 266, 45 },  { 267, 48 },  { 268, 49 },  { 269, 50 },
+    { 270, 51 },  { 271, 52 },  { 272, 53 },  { 273, 54 },
+    { 274, 55 },  { 275, 56 },  { 276, 57 },  { 277, 58 },
+    { 278, 59 },  { 279, 60 },  { 280, 61 },  { 281, 62 },
+    { 282, 63 },  { 283, 64 },  { 284, 65 },  { 285, 66 },
+    { 286, 67 },  { 287, 68 },  { 288, 69 },  { 289, 70 },
+    { 290, 71 },  { 291, 72 },  { 292, 73 },  { 293, 74 },
+    { 294, 75 },  { 295, 76 },  { 296, 77 },  { 297, 78 },
+    { 298, 79 },  { 299, 80 },  { 300, 81 },  { 301, 82 },
+    { 302, 83 },  { 303, 84 },  { 304, 85 },  { 305, 86 },
+    { 306, 87 },  { 307, 88 },  { 308, 89 },  { 309, 90 },
+    { 310, 91 },  { 311, 92 },  { 312, 93 },  { 313, 94 },
+    { 314, 95 },  { 315, 96 },  { 316, 97 },  { 317, 98 },
+    { 318, 99 },  { 319, 103 }, { 320, 104 }, { 321, 105 },
+    { 322, 106 }, { 323, 107 }, { 324, 108 }, { 325, 109 },
+    { 326, 110 }, { 327, 114 }, { 328, 115 }, { 329, 116 },
+    { 330, 117 }, { 331, 118 }, { 332, 119 }, { 333, 120 },
+    { 334, 121 }, { 335, 122 }, { 336, 123 }, { 337, 124 },
+    { 338, 125 }, { 339, 126 }, { 340, 127 }, { 341, 128 },
+    { 342, 129 }, { 343, 130 }, { 344, 131 }, { 345, 132 },
+    { 346, 133 }, { 347, 134 }, { 348, 135 }, { 349, 136 },
+    { 350, 137 }, { 351, 138 }, { 352, 139 }, { 353, 140 },
+    { 354, 141 }, { 355, 142 }, { 356, 143 }, { 357, 144 },
+    { 358, 145 }, { 359, 146 }, { 360, 147 }, { 361, 148 },
+    { 362, 149 }, { 363, 150 }, { 364, 151 }, { 365, 152 },
+    { 366, 153 }, { 367, 154 }, { 368, 155 }, { 369, 156 },
+    { 370, 157 }, { 371, 158 }, { 372, 159 }, { 373, 160 },
+    { 374, 161 }, { 375, 162 }, { 376, 163 }, { 377, 164 },
+    { 378, 165 }
+};
+
+/* SID to glyph ID */
+static const sid_to_gid_t expert_subset_charset_sid_to_gid [] =
+{
+  { 1, 1 },       { 13, 8 },      { 14, 9 },      { 15, 10 },
+  { 27, 22 },     { 28, 23 },     { 99, 11 },     { 109, 41 },
+  { 110, 42 },    { 150, 64 },    { 155, 55 },    { 158, 54 },
+  { 163, 56 },    { 164, 65 },    { 169, 66 },    { 231, 2 },
+  { 232, 3 },     { 235, 4 },     { 236, 5 },     { 237, 6 },
+  { 238, 7 },     { 239, 12 },    { 240, 13 },    { 241, 14 },
+  { 242, 15 },    { 243, 16 },    { 244, 17 },    { 245, 18 },
+  { 246, 19 },    { 247, 20 },    { 248, 21 },    { 249, 24 },
+  { 250, 25 },    { 251, 26 },    { 253, 27 },    { 254, 28 },
+  { 255, 29 },    { 256, 30 },    { 257, 31 },    { 258, 32 },
+  { 259, 33 },    { 260, 34 },    { 261, 35 },    { 262, 36 },
+  { 263, 37 },    { 264, 38 },    { 265, 39 },    { 266, 40 },
+  { 267, 43 },    { 268, 44 },    { 269, 45 },    { 270, 46 },
+  { 272, 47 },    { 300, 48 },    { 301, 49 },    { 302, 50 },
+  { 305, 51 },    { 314, 52 },    { 315, 53 },    { 320, 57 },
+  { 321, 58 },    { 322, 59 },    { 323, 60 },    { 324, 61 },
+  { 325, 62 },    { 326, 63 },    { 327, 67 },    { 328, 68 },
+  { 329, 69 },    { 330, 70 },    { 331, 71 },    { 332, 72 },
+  { 333, 73 },    { 334, 74 },    { 335, 75 },    { 336, 76 },
+  { 337, 77 },    { 338, 78 },    { 339, 79 },    { 340, 80 },
+  { 341, 81 },    { 342, 82 },    { 343, 83 },    { 344, 84 },
+  { 345, 85 },    { 346, 86 }
+};
+
 /* code to SID */
 static const uint8_t standard_encoding_to_sid [] =
 {
@@ -157,6 +245,18 @@
     return 0;
 }
 
+hb_codepoint_t OT::cff1::lookup_expert_charset_for_glyph (hb_codepoint_t sid)
+{
+  const auto *pair = hb_sorted_array (expert_charset_sid_to_gid).bsearch (sid);
+  return pair ? pair->gid : 0;
+}
+
+hb_codepoint_t OT::cff1::lookup_expert_subset_charset_for_glyph (hb_codepoint_t sid)
+{
+  const auto *pair = hb_sorted_array (expert_subset_charset_sid_to_gid).bsearch (sid);
+  return pair ? pair->gid : 0;
+}
+
 hb_codepoint_t OT::cff1::lookup_standard_encoding_for_sid (hb_codepoint_t code)
 {
   if (code < ARRAY_LENGTH (standard_encoding_to_sid))
@@ -342,6 +442,130 @@
   return true;
 }
 
+#ifdef HB_EXPERIMENTAL_API
+struct cff1_path_param_t
+{
+  cff1_path_param_t (const OT::cff1::accelerator_t *cff_, hb_font_t *font_,
+		     draw_helper_t &draw_helper_, point_t *delta_)
+  {
+    draw_helper = &draw_helper_;
+    cff = cff_;
+    font = font_;
+    delta = delta_;
+  }
+
+  void move_to (const point_t &p)
+  {
+    point_t point = p;
+    if (delta) point.move (*delta);
+    draw_helper->move_to (font->em_scalef_x (point.x.to_real ()), font->em_scalef_y (point.y.to_real ()));
+  }
+
+  void line_to (const point_t &p)
+  {
+    point_t point = p;
+    if (delta) point.move (*delta);
+    draw_helper->line_to (font->em_scalef_x (point.x.to_real ()), font->em_scalef_y (point.y.to_real ()));
+  }
+
+  void cubic_to (const point_t &p1, const point_t &p2, const point_t &p3)
+  {
+    point_t point1 = p1, point2 = p2, point3 = p3;
+    if (delta)
+    {
+      point1.move (*delta);
+      point2.move (*delta);
+      point3.move (*delta);
+    }
+    draw_helper->cubic_to (font->em_scalef_x (point1.x.to_real ()), font->em_scalef_y (point1.y.to_real ()),
+			   font->em_scalef_x (point2.x.to_real ()), font->em_scalef_y (point2.y.to_real ()),
+			   font->em_scalef_x (point3.x.to_real ()), font->em_scalef_y (point3.y.to_real ()));
+  }
+
+  void end_path () { draw_helper->end_path (); }
+
+  hb_font_t *font;
+  draw_helper_t *draw_helper;
+  point_t *delta;
+
+  const OT::cff1::accelerator_t *cff;
+};
+
+struct cff1_path_procs_path_t : path_procs_t<cff1_path_procs_path_t, cff1_cs_interp_env_t, cff1_path_param_t>
+{
+  static void moveto (cff1_cs_interp_env_t &env, cff1_path_param_t& param, const point_t &pt)
+  {
+    param.move_to (pt);
+    env.moveto (pt);
+  }
+
+  static void line (cff1_cs_interp_env_t &env, cff1_path_param_t &param, const point_t &pt1)
+  {
+    param.line_to (pt1);
+    env.moveto (pt1);
+  }
+
+  static void curve (cff1_cs_interp_env_t &env, cff1_path_param_t &param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
+  {
+    param.cubic_to (pt1, pt2, pt3);
+    env.moveto (pt3);
+  }
+};
+
+static bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoint_t glyph,
+		       draw_helper_t &draw_helper, bool in_seac = false, point_t *delta = nullptr);
+
+struct cff1_cs_opset_path_t : cff1_cs_opset_t<cff1_cs_opset_path_t, cff1_path_param_t, cff1_path_procs_path_t>
+{
+  static void process_seac (cff1_cs_interp_env_t &env, cff1_path_param_t& param)
+  {
+    /* End previous path */
+    param.end_path ();
+
+    unsigned int n = env.argStack.get_count ();
+    point_t delta;
+    delta.x = env.argStack[n-4];
+    delta.y = env.argStack[n-3];
+    hb_codepoint_t base = param.cff->std_code_to_glyph (env.argStack[n-2].to_int ());
+    hb_codepoint_t accent = param.cff->std_code_to_glyph (env.argStack[n-1].to_int ());
+
+    if (unlikely (!(!env.in_seac && base && accent
+		    && _get_path (param.cff, param.font, base, *param.draw_helper, true)
+		    && _get_path (param.cff, param.font, accent, *param.draw_helper, true, &delta))))
+      env.set_error ();
+  }
+};
+
+bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoint_t glyph,
+		draw_helper_t &draw_helper, bool in_seac, point_t *delta)
+{
+  if (unlikely (!cff->is_valid () || (glyph >= cff->num_glyphs))) return false;
+
+  unsigned int fd = cff->fdSelect->get_fd (glyph);
+  cff1_cs_interpreter_t<cff1_cs_opset_path_t, cff1_path_param_t> interp;
+  const byte_str_t str = (*cff->charStrings)[glyph];
+  interp.env.init (str, *cff, fd);
+  interp.env.set_in_seac (in_seac);
+  cff1_path_param_t param (cff, font, draw_helper, delta);
+  if (unlikely (!interp.interpret (param))) return false;
+
+  /* Let's end the path specially since it is called inside seac also */
+  param.end_path ();
+
+  return true;
+}
+
+bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const
+{
+#ifdef HB_NO_OT_FONT_CFF
+  /* XXX Remove check when this code moves to .hh file. */
+  return true;
+#endif
+
+  return _get_path (this, font, glyph, draw_helper);
+}
+#endif
+
 struct get_seac_param_t
 {
   void init (const OT::cff1::accelerator_t *_cff)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -27,15 +27,21 @@
 #ifndef HB_OT_CFF1_TABLE_HH
 #define HB_OT_CFF1_TABLE_HH
 
-#include "hb-ot-head-table.hh"
 #include "hb-ot-cff-common.hh"
 #include "hb-subset-cff1.hh"
+#include "hb-draw.hh"
 
+#define HB_STRING_ARRAY_NAME cff1_std_strings
+#define HB_STRING_ARRAY_LIST "hb-ot-cff1-std-str.hh"
+#include "hb-string-array.hh"
+#undef HB_STRING_ARRAY_LIST
+#undef HB_STRING_ARRAY_NAME
+
 namespace CFF {
 
 /*
  * CFF -- Compact Font Format (CFF)
- * http://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5176.CFF.pdf
+ * https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5176.CFF.pdf
  */
 #define HB_OT_TAG_cff1 HB_TAG('C','F','F',' ')
 
@@ -49,7 +55,6 @@
 
 typedef CFFIndex<HBUINT16> CFF1Index;
 typedef CFF1Index          CFF1CharStrings;
-typedef FDArray<HBUINT16>  CFF1FDArray;
 typedef Subrs<HBUINT16>    CFF1Subrs;
 
 struct CFF1FDSelect : FDSelect {};
@@ -169,7 +174,7 @@
     TRACE_SERIALIZE (this);
     unsigned int size = src.get_size ();
     Encoding *dest = c->allocate_size<Encoding> (size);
-    if (unlikely (dest == nullptr)) return_trace (false);
+    if (unlikely (!dest)) return_trace (false);
     memcpy (dest, &src, size);
     return_trace (true);
   }
@@ -183,13 +188,13 @@
   {
     TRACE_SERIALIZE (this);
     Encoding *dest = c->extend_min (*this);
-    if (unlikely (dest == nullptr)) return_trace (false);
+    if (unlikely (!dest)) return_trace (false);
     dest->format = format | ((supp_codes.length > 0) ? 0x80 : 0);
     switch (format) {
     case 0:
     {
       Encoding0 *fmt0 = c->allocate_size<Encoding0> (Encoding0::min_size + HBUINT8::static_size * enc_count);
-      if (unlikely (fmt0 == nullptr)) return_trace (false);
+      if (unlikely (!fmt0)) return_trace (false);
       fmt0->nCodes () = enc_count;
       unsigned int glyph = 0;
       for (unsigned int i = 0; i < code_ranges.length; i++)
@@ -206,7 +211,7 @@
     case 1:
     {
       Encoding1 *fmt1 = c->allocate_size<Encoding1> (Encoding1::min_size + Encoding1_Range::static_size * code_ranges.length);
-      if (unlikely (fmt1 == nullptr)) return_trace (false);
+      if (unlikely (!fmt1)) return_trace (false);
       fmt1->nRanges () = code_ranges.length;
       for (unsigned int i = 0; i < code_ranges.length; i++)
       {
@@ -223,7 +228,7 @@
     if (supp_codes.length)
     {
       CFF1SuppEncData *suppData = c->allocate_size<CFF1SuppEncData> (CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_codes.length);
-      if (unlikely (suppData == nullptr)) return_trace (false);
+      if (unlikely (!suppData)) return_trace (false);
       suppData->nSups () = supp_codes.length;
       for (unsigned int i = 0; i < supp_codes.length; i++)
       {
@@ -235,23 +240,6 @@
     return_trace (true);
   }
 
-  /* parallel to above: calculate the size of a subset Encoding */
-  static unsigned int calculate_serialized_size (uint8_t format,
-						 unsigned int enc_count,
-						 unsigned int supp_count)
-  {
-    unsigned int size = min_size;
-    switch (format)
-    {
-    case 0: size += Encoding0::min_size + HBUINT8::static_size * enc_count; break;
-    case 1: size += Encoding1::min_size + Encoding1_Range::static_size * enc_count; break;
-    default:return 0;
-    }
-    if (supp_count > 0)
-      size += CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_count;
-    return size;
-  }
-
   unsigned int get_size () const
   {
     unsigned int size = min_size;
@@ -414,7 +402,7 @@
     for (unsigned int i = 0;; i++)
     {
       if (glyph >= num_glyphs)
-      	return 0;
+	return 0;
       if ((ranges[i].first <= sid) && (sid <= ranges[i].first + ranges[i].nLeft))
 	return glyph + (sid - ranges[i].first);
       glyph += (ranges[i].nLeft + 1);
@@ -457,7 +445,7 @@
     TRACE_SERIALIZE (this);
     unsigned int size = src.get_size (num_glyphs);
     Charset *dest = c->allocate_size<Charset> (size);
-    if (unlikely (dest == nullptr)) return_trace (false);
+    if (unlikely (!dest)) return_trace (false);
     memcpy (dest, &src, size);
     return_trace (true);
   }
@@ -470,7 +458,7 @@
   {
     TRACE_SERIALIZE (this);
     Charset *dest = c->extend_min (*this);
-    if (unlikely (dest == nullptr)) return_trace (false);
+    if (unlikely (!dest)) return_trace (false);
     dest->format = format;
     switch (format)
     {
@@ -477,7 +465,7 @@
     case 0:
     {
       Charset0 *fmt0 = c->allocate_size<Charset0> (Charset0::min_size + HBUINT16::static_size * (num_glyphs - 1));
-      if (unlikely (fmt0 == nullptr)) return_trace (false);
+      if (unlikely (!fmt0)) return_trace (false);
       unsigned int glyph = 0;
       for (unsigned int i = 0; i < sid_ranges.length; i++)
       {
@@ -491,10 +479,10 @@
     case 1:
     {
       Charset1 *fmt1 = c->allocate_size<Charset1> (Charset1::min_size + Charset1_Range::static_size * sid_ranges.length);
-      if (unlikely (fmt1 == nullptr)) return_trace (false);
+      if (unlikely (!fmt1)) return_trace (false);
       for (unsigned int i = 0; i < sid_ranges.length; i++)
       {
-      	if (unlikely (!(sid_ranges[i].glyph <= 0xFF)))
+	if (unlikely (!(sid_ranges[i].glyph <= 0xFF)))
 	  return_trace (false);
 	fmt1->ranges[i].first = sid_ranges[i].code;
 	fmt1->ranges[i].nLeft = sid_ranges[i].glyph;
@@ -505,10 +493,10 @@
     case 2:
     {
       Charset2 *fmt2 = c->allocate_size<Charset2> (Charset2::min_size + Charset2_Range::static_size * sid_ranges.length);
-      if (unlikely (fmt2 == nullptr)) return_trace (false);
+      if (unlikely (!fmt2)) return_trace (false);
       for (unsigned int i = 0; i < sid_ranges.length; i++)
       {
-      	if (unlikely (!(sid_ranges[i].glyph <= 0xFFFF)))
+	if (unlikely (!(sid_ranges[i].glyph <= 0xFFFF)))
 	  return_trace (false);
 	fmt2->ranges[i].first = sid_ranges[i].code;
 	fmt2->ranges[i].nLeft = sid_ranges[i].glyph;
@@ -520,19 +508,6 @@
     return_trace (true);
   }
 
-  /* parallel to above: calculate the size of a subset Charset */
-  static unsigned int calculate_serialized_size (uint8_t format,
-						 unsigned int count)
-  {
-    switch (format)
-    {
-    case 0: return min_size + Charset0::min_size + HBUINT16::static_size * (count - 1);
-    case 1: return min_size + Charset1::min_size + Charset1_Range::static_size * count;
-    case 2: return min_size + Charset2::min_size + Charset2_Range::static_size * count;
-    default:return 0;
-    }
-  }
-
   unsigned int get_size (unsigned int num_glyphs) const
   {
     switch (format)
@@ -544,8 +519,9 @@
     }
   }
 
-  hb_codepoint_t get_sid (hb_codepoint_t glyph) const
+  hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned int num_glyphs) const
   {
+    if (unlikely (glyph >= num_glyphs)) return 0;
     switch (format)
     {
     case 0: return u.format0.get_sid (glyph);
@@ -594,7 +570,7 @@
 struct CFF1StringIndex : CFF1Index
 {
   bool serialize (hb_serialize_context_t *c, const CFF1StringIndex &strings,
-		  unsigned int offSize_, const hb_inc_bimap_t &sidmap)
+		  const hb_inc_bimap_t &sidmap)
   {
     TRACE_SERIALIZE (this);
     if (unlikely ((strings.count == 0) || (sidmap.get_population () == 0)))
@@ -612,30 +588,14 @@
     for (unsigned int i = 0; i < strings.count; i++)
     {
       hb_codepoint_t  j = sidmap[i];
-      if (j != CFF_UNDEF_CODE)
+      if (j != HB_MAP_VALUE_INVALID)
 	bytesArray[j] = strings[i];
     }
 
-    bool result = CFF1Index::serialize (c, offSize_, bytesArray);
+    bool result = CFF1Index::serialize (c, bytesArray);
     bytesArray.fini ();
     return_trace (result);
   }
-
-  /* in parallel to above */
-  unsigned int calculate_serialized_size (unsigned int &offSize_ /*OUT*/, const hb_inc_bimap_t &sidmap) const
-  {
-    offSize_ = 0;
-    if ((count == 0) || (sidmap.get_population () == 0))
-      return count.static_size;
-
-    unsigned int dataSize = 0;
-    for (unsigned int i = 0; i < count; i++)
-      if (sidmap[i] != CFF_UNDEF_CODE)
-	dataSize += length_at (i);
-
-    offSize_ = calcOffSize(dataSize);
-    return CFF1Index::calculate_serialized_size (offSize_, sidmap.get_population (), dataSize);
-  }
 };
 
 struct cff1_top_dict_interp_env_t : num_interp_env_t
@@ -738,7 +698,7 @@
   unsigned int    EncodingOffset;
   unsigned int    CharsetOffset;
   unsigned int    FDSelectOffset;
-  table_info_t       privateDictInfo;
+  table_info_t    privateDictInfo;
 };
 
 struct cff1_top_dict_opset_t : top_dict_opset_t<cff1_top_dict_val_t>
@@ -880,21 +840,10 @@
   {
     dict_values_t<VAL>::init ();
     subrsOffset = 0;
-    localSubrs = &Null(CFF1Subrs);
+    localSubrs = &Null (CFF1Subrs);
   }
   void fini () { dict_values_t<VAL>::fini (); }
 
-  unsigned int calculate_serialized_size () const
-  {
-    unsigned int size = 0;
-    for (unsigned int i = 0; i < dict_values_t<VAL>::get_count; i++)
-      if (dict_values_t<VAL>::get_value (i).op == OpCode_Subrs)
-	size += OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (OpCode_Subrs);
-      else
-	size += dict_values_t<VAL>::get_value (i).str.length;
-    return size;
-  }
-
   unsigned int      subrsOffset;
   const CFF1Subrs    *localSubrs;
 };
@@ -997,6 +946,37 @@
 typedef CFF1Index CFF1NameIndex;
 typedef CFF1IndexOf<TopDict> CFF1TopDictIndex;
 
+struct cff1_font_dict_values_mod_t
+{
+  cff1_font_dict_values_mod_t() { init (); }
+
+  void init () { init ( &Null (cff1_font_dict_values_t), CFF_UNDEF_SID ); }
+
+  void init (const cff1_font_dict_values_t *base_,
+	     unsigned int fontName_)
+  {
+    base = base_;
+    fontName = fontName_;
+    privateDictInfo.init ();
+  }
+
+  unsigned get_count () const { return base->get_count (); }
+
+  const op_str_t &operator [] (unsigned int i) const { return (*base)[i]; }
+
+  const cff1_font_dict_values_t    *base;
+  table_info_t		   privateDictInfo;
+  unsigned int		fontName;
+};
+
+struct CFF1FDArray : FDArray<HBUINT16>
+{
+  /* FDArray::serialize() requires this partial specialization to compile */
+  template <typename ITER, typename OP_SERIALIZER>
+  bool serialize (hb_serialize_context_t *c, ITER it, OP_SERIALIZER& opszr)
+  { return FDArray<HBUINT16>::serialize<cff1_font_dict_values_mod_t, cff1_font_dict_values_mod_t> (c, it, opszr); }
+};
+
 } /* namespace CFF */
 
 namespace OT {
@@ -1031,7 +1011,7 @@
 
       const OT::cff1 *cff = this->blob->template as<OT::cff1> ();
 
-      if (cff == &Null(OT::cff1))
+      if (cff == &Null (OT::cff1))
       { fini (); return; }
 
       nameIndex = &cff->nameIndex (cff);
@@ -1052,7 +1032,7 @@
       }
 
       if (is_predef_charset ())
-	charset = &Null(Charset);
+	charset = &Null (Charset);
       else
       {
 	charset = &StructAtOffsetOrNull<Charset> (cff, topDict.CharsetOffset);
@@ -1064,8 +1044,8 @@
       {
 	fdArray = &StructAtOffsetOrNull<CFF1FDArray> (cff, topDict.FDArrayOffset);
 	fdSelect = &StructAtOffsetOrNull<CFF1FDSelect> (cff, topDict.FDSelectOffset);
-	if (unlikely ((fdArray == &Null(CFF1FDArray)) || !fdArray->sanitize (&sc) ||
-	    (fdSelect == &Null(CFF1FDSelect)) || !fdSelect->sanitize (&sc, fdArray->count)))
+	if (unlikely ((fdArray == &Null (CFF1FDArray)) || !fdArray->sanitize (&sc) ||
+	    (fdSelect == &Null (CFF1FDSelect)) || !fdSelect->sanitize (&sc, fdArray->count)))
 	{ fini (); return; }
 
 	fdCount = fdArray->count;
@@ -1072,10 +1052,24 @@
       }
       else
       {
-	fdArray = &Null(CFF1FDArray);
-	fdSelect = &Null(CFF1FDSelect);
+	fdArray = &Null (CFF1FDArray);
+	fdSelect = &Null (CFF1FDSelect);
       }
 
+      encoding = &Null (Encoding);
+      if (is_CID ())
+      {
+	if (unlikely (charset == &Null (Charset))) { fini (); return; }
+      }
+      else
+      {
+	if (!is_predef_encoding ())
+	{
+	  encoding = &StructAtOffsetOrNull<Encoding> (cff, topDict.EncodingOffset);
+	  if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) { fini (); return; }
+	}
+      }
+
       stringIndex = &StructAtOffset<CFF1StringIndex> (topDictIndex, topDictIndex->get_size ());
       if ((stringIndex == &Null (CFF1StringIndex)) || !stringIndex->sanitize (&sc))
       { fini (); return; }
@@ -1086,7 +1080,7 @@
 
       charStrings = &StructAtOffsetOrNull<CFF1CharStrings> (cff, topDict.charStringsOffset);
 
-      if ((charStrings == &Null(CFF1CharStrings)) || unlikely (!charStrings->sanitize (&sc)))
+      if ((charStrings == &Null (CFF1CharStrings)) || unlikely (!charStrings->sanitize (&sc)))
       { fini (); return; }
 
       num_glyphs = charStrings->count;
@@ -1104,14 +1098,14 @@
 	{
 	  byte_str_t fontDictStr = (*fdArray)[i];
 	  if (unlikely (!fontDictStr.sanitize (&sc))) { fini (); return; }
-	  cff1_font_dict_values_t  *font;
+	  cff1_font_dict_values_t *font;
 	  cff1_font_dict_interpreter_t font_interp;
 	  font_interp.env.init (fontDictStr);
 	  font = fontDicts.push ();
-	  if (unlikely (font == &Crap(cff1_font_dict_values_t))) { fini (); return; }
+	  if (unlikely (font == &Crap (cff1_font_dict_values_t))) { fini (); return; }
 	  font->init ();
 	  if (unlikely (!font_interp.interpret (*font))) { fini (); return; }
-	  PRIVDICTVAL  *priv = &privateDicts[i];
+	  PRIVDICTVAL *priv = &privateDicts[i];
 	  const byte_str_t privDictStr (StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset), font->privateDictInfo.size);
 	  if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; }
 	  dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp;
@@ -1120,7 +1114,7 @@
 	  if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; }
 
 	  priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (&privDictStr, priv->subrsOffset);
-	  if (priv->localSubrs != &Null(CFF1Subrs) &&
+	  if (priv->localSubrs != &Null (CFF1Subrs) &&
 	      unlikely (!priv->localSubrs->sanitize (&sc)))
 	  { fini (); return; }
 	}
@@ -1127,8 +1121,8 @@
       }
       else  /* non-CID */
       {
-	cff1_top_dict_values_t  *font = &topDict;
-	PRIVDICTVAL  *priv = &privateDicts[0];
+	cff1_top_dict_values_t *font = &topDict;
+	PRIVDICTVAL *priv = &privateDicts[0];
 
 	const byte_str_t privDictStr (StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset), font->privateDictInfo.size);
 	if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; }
@@ -1138,7 +1132,7 @@
 	if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; }
 
 	priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (&privDictStr, priv->subrsOffset);
-	if (priv->localSubrs != &Null(CFF1Subrs) &&
+	if (priv->localSubrs != &Null (CFF1Subrs) &&
 	    unlikely (!priv->localSubrs->sanitize (&sc)))
 	{ fini (); return; }
       }
@@ -1154,7 +1148,7 @@
       blob = nullptr;
     }
 
-    bool is_valid () const { return blob != nullptr; }
+    bool is_valid () const { return blob; }
     bool   is_CID () const { return topDict.is_CID (); }
 
     bool is_predef_charset () const { return topDict.CharsetOffset <= ExpertSubsetCharset; }
@@ -1165,7 +1159,7 @@
       if (unlikely (sid == CFF_UNDEF_SID))
 	return 0;
 
-      if (charset != &Null(Charset))
+      if (charset != &Null (Charset))
 	return charset->get_glyph (sid, num_glyphs);
       else if ((topDict.CharsetOffset == ISOAdobeCharset)
 	      && (code <= 228 /*zcaron*/)) return sid;
@@ -1172,62 +1166,11 @@
       return 0;
     }
 
-    protected:
-    hb_blob_t	       *blob;
-    hb_sanitize_context_t   sc;
-
-    public:
-    const Charset	   *charset;
-    const CFF1NameIndex     *nameIndex;
-    const CFF1TopDictIndex  *topDictIndex;
-    const CFF1StringIndex   *stringIndex;
-    const CFF1Subrs	 *globalSubrs;
-    const CFF1CharStrings   *charStrings;
-    const CFF1FDArray       *fdArray;
-    const CFF1FDSelect      *fdSelect;
-    unsigned int	    fdCount;
-
-    cff1_top_dict_values_t       topDict;
-    hb_vector_t<cff1_font_dict_values_t>   fontDicts;
-    hb_vector_t<PRIVDICTVAL>	  privateDicts;
-
-    unsigned int	    num_glyphs;
-  };
-
-  struct accelerator_t : accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t>
-  {
-    HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const;
-    HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const;
-  };
-
-  struct accelerator_subset_t : accelerator_templ_t<cff1_private_dict_opset_subset, cff1_private_dict_values_subset_t>
-  {
-    void init (hb_face_t *face)
-    {
-      SUPER::init (face);
-      if (blob == nullptr) return;
-
-      const OT::cff1 *cff = this->blob->as<OT::cff1> ();
-      encoding = &Null(Encoding);
-      if (is_CID ())
-      {
-	if (unlikely (charset == &Null(Charset))) { fini (); return; }
-      }
-      else
-      {
-	if (!is_predef_encoding ())
-	{
-	  encoding = &StructAtOffsetOrNull<Encoding> (cff, topDict.EncodingOffset);
-	  if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) { fini (); return; }
-	}
-      }
-    }
-
     bool is_predef_encoding () const { return topDict.EncodingOffset <= ExpertEncoding; }
 
     hb_codepoint_t glyph_to_code (hb_codepoint_t glyph) const
     {
-      if (encoding != &Null(Encoding))
+      if (encoding != &Null (Encoding))
 	return encoding->get_code (glyph);
       else
       {
@@ -1251,20 +1194,20 @@
 
     hb_codepoint_t glyph_to_sid (hb_codepoint_t glyph) const
     {
-      if (charset != &Null(Charset))
-	return charset->get_sid (glyph);
+      if (charset != &Null (Charset))
+	return charset->get_sid (glyph, num_glyphs);
       else
       {
 	hb_codepoint_t sid = 0;
 	switch (topDict.CharsetOffset)
 	{
-	  case  ISOAdobeCharset:
+	  case ISOAdobeCharset:
 	    if (glyph <= 228 /*zcaron*/) sid = glyph;
 	    break;
-	  case  ExpertCharset:
+	  case ExpertCharset:
 	    sid = lookup_expert_charset_for_sid (glyph);
 	    break;
-	  case  ExpertSubsetCharset:
+	  case ExpertSubsetCharset:
 	      sid = lookup_expert_subset_charset_for_sid (glyph);
 	    break;
 	  default:
@@ -1274,35 +1217,174 @@
       }
     }
 
-    const Encoding	  *encoding;
+    hb_codepoint_t sid_to_glyph (hb_codepoint_t sid) const
+    {
+      if (charset != &Null (Charset))
+	return charset->get_glyph (sid, num_glyphs);
+      else
+      {
+	hb_codepoint_t glyph = 0;
+	switch (topDict.CharsetOffset)
+	{
+	  case ISOAdobeCharset:
+	    if (sid <= 228 /*zcaron*/) glyph = sid;
+	    break;
+	  case ExpertCharset:
+	    glyph = lookup_expert_charset_for_glyph (sid);
+	    break;
+	  case ExpertSubsetCharset:
+	    glyph = lookup_expert_subset_charset_for_glyph (sid);
+	    break;
+	  default:
+	    break;
+	}
+	return glyph;
+      }
+    }
 
-    private:
-    typedef accelerator_templ_t<cff1_private_dict_opset_subset, cff1_private_dict_values_subset_t> SUPER;
+    protected:
+    hb_blob_t	           *blob;
+    hb_sanitize_context_t   sc;
+
+    public:
+    const Encoding	    *encoding;
+    const Charset	    *charset;
+    const CFF1NameIndex     *nameIndex;
+    const CFF1TopDictIndex  *topDictIndex;
+    const CFF1StringIndex   *stringIndex;
+    const CFF1Subrs	    *globalSubrs;
+    const CFF1CharStrings   *charStrings;
+    const CFF1FDArray       *fdArray;
+    const CFF1FDSelect      *fdSelect;
+    unsigned int	     fdCount;
+
+    cff1_top_dict_values_t   topDict;
+    hb_vector_t<cff1_font_dict_values_t>
+			     fontDicts;
+    hb_vector_t<PRIVDICTVAL> privateDicts;
+
+    unsigned int	     num_glyphs;
   };
 
-  bool subset (hb_subset_plan_t *plan) const
+  struct accelerator_t : accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t>
   {
-    hb_blob_t *cff_prime = nullptr;
+    void init (hb_face_t *face)
+    {
+      SUPER::init (face);
 
-    bool success = true;
-    if (hb_subset_cff1 (plan, &cff_prime)) {
-      success = success && plan->add_table (HB_OT_TAG_cff1, cff_prime);
-      hb_blob_t *head_blob = hb_sanitize_context_t().reference_table<head> (plan->source);
-      success = success && head_blob && plan->add_table (HB_OT_TAG_head, head_blob);
-      hb_blob_destroy (head_blob);
-    } else {
-      success = false;
+      if (!is_valid ()) return;
+      if (is_CID ()) return;
+
+      /* fill glyph_names */
+      for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++)
+      {
+	hb_codepoint_t	sid = glyph_to_sid (gid);
+	gname_t	gname;
+	gname.sid = sid;
+	if (sid < cff1_std_strings_length)
+	  gname.name = cff1_std_strings (sid);
+	else
+	{
+	  byte_str_t	ustr = (*stringIndex)[sid - cff1_std_strings_length];
+	  gname.name = hb_bytes_t ((const char*)ustr.arrayZ, ustr.length);
+	}
+	if (unlikely (!gname.name.arrayZ)) { fini (); return; }
+	glyph_names.push (gname);
+      }
+      glyph_names.qsort ();
     }
-    hb_blob_destroy (cff_prime);
 
-    return success;
-  }
+    void fini ()
+    {
+      glyph_names.fini ();
 
+      SUPER::fini ();
+    }
+
+    bool get_glyph_name (hb_codepoint_t glyph,
+			 char *buf, unsigned int buf_len) const
+    {
+      if (!buf) return true;
+      if (unlikely (!is_valid ())) return false;
+      if (is_CID()) return false;
+      hb_codepoint_t sid = glyph_to_sid (glyph);
+      const char *str;
+      size_t str_len;
+      if (sid < cff1_std_strings_length)
+      {
+	hb_bytes_t byte_str = cff1_std_strings (sid);
+	str = byte_str.arrayZ;
+	str_len = byte_str.length;
+      }
+      else
+      {
+	byte_str_t ubyte_str = (*stringIndex)[sid - cff1_std_strings_length];
+	str = (const char *)ubyte_str.arrayZ;
+	str_len = ubyte_str.length;
+      }
+      if (!str_len) return false;
+      unsigned int len = hb_min (buf_len - 1, str_len);
+      strncpy (buf, (const char*)str, len);
+      buf[len] = '\0';
+      return true;
+    }
+
+    bool get_glyph_from_name (const char *name, int len,
+			      hb_codepoint_t *glyph) const
+    {
+      if (len < 0) len = strlen (name);
+      if (unlikely (!len)) return false;
+
+      gname_t key = { hb_bytes_t (name, len), 0 };
+      const gname_t *gname = glyph_names.bsearch (key);
+      if (!gname) return false;
+      hb_codepoint_t gid = sid_to_glyph (gname->sid);
+      if (!gid && gname->sid) return false;
+      *glyph = gid;
+      return true;
+    }
+
+    HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const;
+    HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const;
+#ifdef HB_EXPERIMENTAL_API
+    HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const;
+#endif
+
+    private:
+    struct gname_t
+    {
+      hb_bytes_t	name;
+      uint16_t		sid;
+
+      static int cmp (const void *a_, const void *b_)
+      {
+	const gname_t *a = (const gname_t *)a_;
+	const gname_t *b = (const gname_t *)b_;
+	int minlen = hb_min (a->name.length, b->name.length);
+	int ret = strncmp (a->name.arrayZ, b->name.arrayZ, minlen);
+	if (ret) return ret;
+	return a->name.length - b->name.length;
+      }
+
+      int cmp (const gname_t &a) const { return cmp (&a, this); }
+    };
+
+    hb_sorted_vector_t<gname_t>	glyph_names;
+
+    typedef accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t> SUPER;
+  };
+
+  struct accelerator_subset_t : accelerator_templ_t<cff1_private_dict_opset_subset, cff1_private_dict_values_subset_t> {};
+
+  bool subset (hb_subset_context_t *c) const { return hb_subset_cff1 (c); }
+
   protected:
   HB_INTERNAL static hb_codepoint_t lookup_standard_encoding_for_code (hb_codepoint_t sid);
   HB_INTERNAL static hb_codepoint_t lookup_expert_encoding_for_code (hb_codepoint_t sid);
   HB_INTERNAL static hb_codepoint_t lookup_expert_charset_for_sid (hb_codepoint_t glyph);
   HB_INTERNAL static hb_codepoint_t lookup_expert_subset_charset_for_sid (hb_codepoint_t glyph);
+  HB_INTERNAL static hb_codepoint_t lookup_expert_charset_for_glyph (hb_codepoint_t sid);
+  HB_INTERNAL static hb_codepoint_t lookup_expert_subset_charset_for_glyph (hb_codepoint_t sid);
   HB_INTERNAL static hb_codepoint_t lookup_standard_encoding_for_sid (hb_codepoint_t code);
 
   public:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -30,6 +30,7 @@
 
 #include "hb-ot-cff2-table.hh"
 #include "hb-cff2-interp-cs.hh"
+#include "hb-draw.hh"
 
 using namespace CFF;
 
@@ -142,5 +143,73 @@
   return true;
 }
 
+#ifdef HB_EXPERIMENTAL_API
+struct cff2_path_param_t
+{
+  cff2_path_param_t (hb_font_t *font_, draw_helper_t &draw_helper_)
+  {
+    draw_helper = &draw_helper_;
+    font = font_;
+  }
 
+  void move_to (const point_t &p)
+  { draw_helper->move_to (font->em_scalef_x (p.x.to_real ()), font->em_scalef_y (p.y.to_real ())); }
+
+  void line_to (const point_t &p)
+  { draw_helper->line_to (font->em_scalef_x (p.x.to_real ()), font->em_scalef_y (p.y.to_real ())); }
+
+  void cubic_to (const point_t &p1, const point_t &p2, const point_t &p3)
+  {
+    draw_helper->cubic_to (font->em_scalef_x (p1.x.to_real ()), font->em_scalef_y (p1.y.to_real ()),
+			   font->em_scalef_x (p2.x.to_real ()), font->em_scalef_y (p2.y.to_real ()),
+			   font->em_scalef_x (p3.x.to_real ()), font->em_scalef_y (p3.y.to_real ()));
+  }
+
+  protected:
+  draw_helper_t *draw_helper;
+  hb_font_t *font;
+};
+
+struct cff2_path_procs_path_t : path_procs_t<cff2_path_procs_path_t, cff2_cs_interp_env_t, cff2_path_param_t>
+{
+  static void moveto (cff2_cs_interp_env_t &env, cff2_path_param_t& param, const point_t &pt)
+  {
+    param.move_to (pt);
+    env.moveto (pt);
+  }
+
+  static void line (cff2_cs_interp_env_t &env, cff2_path_param_t& param, const point_t &pt1)
+  {
+    param.line_to (pt1);
+    env.moveto (pt1);
+  }
+
+  static void curve (cff2_cs_interp_env_t &env, cff2_path_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
+  {
+    param.cubic_to (pt1, pt2, pt3);
+    env.moveto (pt3);
+  }
+};
+
+struct cff2_cs_opset_path_t : cff2_cs_opset_t<cff2_cs_opset_path_t, cff2_path_param_t, cff2_path_procs_path_t> {};
+
+bool OT::cff2::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const
+{
+#ifdef HB_NO_OT_FONT_CFF
+  /* XXX Remove check when this code moves to .hh file. */
+  return true;
 #endif
+
+  if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false;
+
+  unsigned int fd = fdSelect->get_fd (glyph);
+  cff2_cs_interpreter_t<cff2_cs_opset_path_t, cff2_path_param_t> interp;
+  const byte_str_t str = (*charStrings)[glyph];
+  interp.env.init (str, *this, fd, font->coords, font->num_coords);
+  cff2_path_param_t param (font, draw_helper);
+  if (unlikely (!interp.interpret (param))) return false;
+  return true;
+}
+#endif
+
+#endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -27,9 +27,9 @@
 #ifndef HB_OT_CFF2_TABLE_HH
 #define HB_OT_CFF2_TABLE_HH
 
-#include "hb-ot-head-table.hh"
 #include "hb-ot-cff-common.hh"
 #include "hb-subset-cff2.hh"
+#include "hb-draw.hh"
 
 namespace CFF {
 
@@ -43,7 +43,6 @@
 template <typename Type> struct CFF2IndexOf : CFFIndexOf<HBUINT32, Type> {};
 
 typedef CFF2Index         CFF2CharStrings;
-typedef FDArray<HBUINT32> CFF2FDArray;
 typedef Subrs<HBUINT32>   CFF2Subrs;
 
 typedef FDSelect3_4<HBUINT32, HBUINT16> FDSelect4;
@@ -56,14 +55,11 @@
     TRACE_SERIALIZE (this);
     unsigned int size = src.get_size (num_glyphs);
     CFF2FDSelect *dest = c->allocate_size<CFF2FDSelect> (size);
-    if (unlikely (dest == nullptr)) return_trace (false);
+    if (unlikely (!dest)) return_trace (false);
     memcpy (dest, &src, size);
     return_trace (true);
   }
 
-  unsigned int calculate_serialized_size (unsigned int num_glyphs) const
-  { return get_size (num_glyphs); }
-
   unsigned int get_size (unsigned int num_glyphs) const
   {
     switch (format)
@@ -127,7 +123,7 @@
     TRACE_SERIALIZE (this);
     unsigned int size_ = varStore->get_size ();
     CFF2VariationStore *dest = c->allocate_size<CFF2VariationStore> (size_);
-    if (unlikely (dest == nullptr)) return_trace (false);
+    if (unlikely (!dest)) return_trace (false);
     memcpy (dest, varStore, size_);
     return_trace (true);
   }
@@ -150,26 +146,6 @@
   }
   void fini () { top_dict_values_t<>::fini (); }
 
-  unsigned int calculate_serialized_size () const
-  {
-    unsigned int size = 0;
-    for (unsigned int i = 0; i < get_count (); i++)
-    {
-      op_code_t op = get_value (i).op;
-      switch (op)
-      {
-	case OpCode_vstore:
-	case OpCode_FDSelect:
-	  size += OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (op);
-	  break;
-	default:
-	  size += top_dict_values_t<>::calculate_serialized_op_size (get_value (i));
-	  break;
-      }
-    }
-    return size;
-  }
-
   unsigned int  vstoreOffset;
   unsigned int  FDSelectOffset;
 };
@@ -256,22 +232,11 @@
   {
     dict_values_t<VAL>::init ();
     subrsOffset = 0;
-    localSubrs = &Null(CFF2Subrs);
+    localSubrs = &Null (CFF2Subrs);
     ivs = 0;
   }
   void fini () { dict_values_t<VAL>::fini (); }
 
-  unsigned int calculate_serialized_size () const
-  {
-    unsigned int size = 0;
-    for (unsigned int i = 0; i < dict_values_t<VAL>::get_count; i++)
-      if (dict_values_t<VAL>::get_value (i).op == OpCode_Subrs)
-	size += OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (OpCode_Subrs);
-      else
-	size += dict_values_t<VAL>::get_value (i).str.length;
-    return size;
-  }
-
   unsigned int      subrsOffset;
   const CFF2Subrs   *localSubrs;
   unsigned int      ivs;
@@ -404,6 +369,14 @@
 typedef dict_interpreter_t<cff2_top_dict_opset_t, cff2_top_dict_values_t> cff2_top_dict_interpreter_t;
 typedef dict_interpreter_t<cff2_font_dict_opset_t, cff2_font_dict_values_t> cff2_font_dict_interpreter_t;
 
+struct CFF2FDArray : FDArray<HBUINT32>
+{
+  /* FDArray::serialize does not compile without this partial specialization */
+  template <typename ITER, typename OP_SERIALIZER>
+  bool serialize (hb_serialize_context_t *c, ITER it, OP_SERIALIZER& opszr)
+  { return FDArray<HBUINT32>::serialize<cff2_font_dict_values_t, table_info_t> (c, it, opszr); }
+};
+
 } /* namespace CFF */
 
 namespace OT {
@@ -438,7 +411,7 @@
 
       const OT::cff2 *cff2 = this->blob->template as<OT::cff2> ();
 
-      if (cff2 == &Null(OT::cff2))
+      if (cff2 == &Null (OT::cff2))
       { fini (); return; }
 
       { /* parse top dict */
@@ -456,11 +429,11 @@
       fdArray = &StructAtOffsetOrNull<CFF2FDArray> (cff2, topDict.FDArrayOffset);
       fdSelect = &StructAtOffsetOrNull<CFF2FDSelect> (cff2, topDict.FDSelectOffset);
 
-      if (((varStore != &Null(CFF2VariationStore)) && unlikely (!varStore->sanitize (&sc))) ||
-	  (charStrings == &Null(CFF2CharStrings)) || unlikely (!charStrings->sanitize (&sc)) ||
-	  (globalSubrs == &Null(CFF2Subrs)) || unlikely (!globalSubrs->sanitize (&sc)) ||
-	  (fdArray == &Null(CFF2FDArray)) || unlikely (!fdArray->sanitize (&sc)) ||
-	  (((fdSelect != &Null(CFF2FDSelect)) && unlikely (!fdSelect->sanitize (&sc, fdArray->count)))))
+      if (((varStore != &Null (CFF2VariationStore)) && unlikely (!varStore->sanitize (&sc))) ||
+	  (charStrings == &Null (CFF2CharStrings)) || unlikely (!charStrings->sanitize (&sc)) ||
+	  (globalSubrs == &Null (CFF2Subrs)) || unlikely (!globalSubrs->sanitize (&sc)) ||
+	  (fdArray == &Null (CFF2FDArray)) || unlikely (!fdArray->sanitize (&sc)) ||
+	  (((fdSelect != &Null (CFF2FDSelect)) && unlikely (!fdSelect->sanitize (&sc, fdArray->count)))))
       { fini (); return; }
 
       num_glyphs = charStrings->count;
@@ -479,7 +452,7 @@
 	cff2_font_dict_interpreter_t font_interp;
 	font_interp.env.init (fontDictStr);
 	font = fontDicts.push ();
-	if (unlikely (font == &Crap(cff2_font_dict_values_t))) { fini (); return; }
+	if (unlikely (font == &Crap (cff2_font_dict_values_t))) { fini (); return; }
 	font->init ();
 	if (unlikely (!font_interp.interpret (*font))) { fini (); return; }
 
@@ -491,7 +464,7 @@
 	if (unlikely (!priv_interp.interpret (privateDicts[i]))) { fini (); return; }
 
 	privateDicts[i].localSubrs = &StructAtOffsetOrNull<CFF2Subrs> (&privDictStr[0], privateDicts[i].subrsOffset);
-	if (privateDicts[i].localSubrs != &Null(CFF2Subrs) &&
+	if (privateDicts[i].localSubrs != &Null (CFF2Subrs) &&
 	  unlikely (!privateDicts[i].localSubrs->sanitize (&sc)))
 	{ fini (); return; }
       }
@@ -507,7 +480,7 @@
       blob = nullptr;
     }
 
-    bool is_valid () const { return blob != nullptr; }
+    bool is_valid () const { return blob; }
 
     protected:
     hb_blob_t			*blob;
@@ -533,28 +506,15 @@
     HB_INTERNAL bool get_extents (hb_font_t *font,
 				  hb_codepoint_t glyph,
 				  hb_glyph_extents_t *extents) const;
+#ifdef HB_EXPERIMENTAL_API
+    HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const;
+#endif
   };
 
   typedef accelerator_templ_t<cff2_private_dict_opset_subset_t, cff2_private_dict_values_subset_t> accelerator_subset_t;
 
-  bool subset (hb_subset_plan_t *plan) const
-  {
-    hb_blob_t *cff2_prime = nullptr;
+  bool subset (hb_subset_context_t *c) const { return hb_subset_cff2 (c); }
 
-    bool success = true;
-    if (hb_subset_cff2 (plan, &cff2_prime)) {
-      success = success && plan->add_table (HB_OT_TAG_cff2, cff2_prime);
-      hb_blob_t *head_blob = hb_sanitize_context_t().reference_table<head> (plan->source);
-      success = success && head_blob && plan->add_table (HB_OT_TAG_head, head_blob);
-      hb_blob_destroy (head_blob);
-    } else {
-      success = false;
-    }
-    hb_blob_destroy (cff2_prime);
-
-    return success;
-  }
-
   public:
   FixedVersion<HBUINT8>		version;	/* Version of CFF2 table. set to 0x0200u */
   NNOffsetTo<TopDict, HBUINT8>	topDict;	/* headerSize = Offset to Top DICT. */

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	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -83,18 +83,16 @@
     HBUINT16 *endCode = c->start_embed<HBUINT16> ();
     hb_codepoint_t prev_endcp = 0xFFFF;
 
-    + it
-    | hb_apply ([&] (const hb_item_type<Iterator> _)
-		{
-		  if (prev_endcp != 0xFFFF && prev_endcp + 1u != _.first)
-		  {
-		    HBUINT16 end_code;
-		    end_code = prev_endcp;
-		    c->copy<HBUINT16> (end_code);
-		  }
-		  prev_endcp = _.first;
-		})
-    ;
+    for (const hb_item_type<Iterator> _ : +it)
+    {
+      if (prev_endcp != 0xFFFF && prev_endcp + 1u != _.first)
+      {
+	HBUINT16 end_code;
+	end_code = prev_endcp;
+	c->copy<HBUINT16> (end_code);
+      }
+      prev_endcp = _.first;
+    }
 
     {
       // last endCode
@@ -121,19 +119,17 @@
     HBUINT16 *startCode = c->start_embed<HBUINT16> ();
     hb_codepoint_t prev_cp = 0xFFFF;
 
-    + it
-    | hb_apply ([&] (const hb_item_type<Iterator> _)
-		{
-		  if (prev_cp == 0xFFFF || prev_cp + 1u != _.first)
-		  {
-		    HBUINT16 start_code;
-		    start_code = _.first;
-		    c->copy<HBUINT16> (start_code);
-		  }
+    for (const hb_item_type<Iterator> _ : +it)
+    {
+      if (prev_cp == 0xFFFF || prev_cp + 1u != _.first)
+      {
+	HBUINT16 start_code;
+	start_code = _.first;
+	c->copy<HBUINT16> (start_code);
+      }
 
-		  prev_cp = _.first;
-		})
-    ;
+      prev_cp = _.first;
+    }
 
     // There must be a final entry with end_code == 0xFFFF.
     if (it.len () == 0 || prev_cp != 0xFFFF)
@@ -162,30 +158,28 @@
     if ((char *)idDelta - (char *)startCode != (int) segcount * (int) HBINT16::static_size)
       return nullptr;
 
-    + it
-    | hb_apply ([&] (const hb_item_type<Iterator> _)
-		{
-		  if (_.first == startCode[i])
-		  {
-		    use_delta = true;
-		    start_gid = _.second;
-		  }
-		  else if (_.second != last_gid + 1) use_delta = false;
+    for (const hb_item_type<Iterator> _ : +it)
+    {
+      if (_.first == startCode[i])
+      {
+	use_delta = true;
+	start_gid = _.second;
+      }
+      else if (_.second != last_gid + 1) use_delta = false;
 
-		  if (_.first == endCode[i])
-		  {
-		    HBINT16 delta;
-		    if (use_delta) delta = (int)start_gid - (int)startCode[i];
-		    else delta = 0;
-		    c->copy<HBINT16> (delta);
+      if (_.first == endCode[i])
+      {
+	HBINT16 delta;
+	if (use_delta) delta = (int)start_gid - (int)startCode[i];
+	else delta = 0;
+	c->copy<HBINT16> (delta);
 
-		    i++;
-		  }
+	i++;
+      }
 
-		  last_gid = _.second;
-		  last_cp = _.first;
-		})
-    ;
+      last_gid = _.second;
+      last_cp = _.first;
+    }
 
     if (it.len () == 0 || last_cp != 0xFFFF)
     {
@@ -238,12 +232,21 @@
   void serialize (hb_serialize_context_t *c,
 		  Iterator it)
   {
+    auto format4_iter =
+    + it
+    | hb_filter ([&] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t> _)
+		 { return _.first <= 0xFFFF; })
+    ;
+
+    //comment off temporarily while we're working on supporting --gids option
+    //if (format4_iter.len () == 0) return;
+
     unsigned table_initpos = c->length ();
     if (unlikely (!c->extend_min (*this))) return;
     this->format = 4;
 
     //serialize endCode[]
-    HBUINT16 *endCode = serialize_endcode_array (c, it);
+    HBUINT16 *endCode = serialize_endcode_array (c, format4_iter);
     if (unlikely (!endCode)) return;
 
     unsigned segcount = (c->length () - min_size) / HBUINT16::static_size;
@@ -252,14 +255,14 @@
     if (unlikely (!c->allocate_size<HBUINT16> (HBUINT16::static_size))) return; // 2 bytes of padding.
 
    // serialize startCode[]
-    HBUINT16 *startCode = serialize_startcode_array (c, it);
+    HBUINT16 *startCode = serialize_startcode_array (c, format4_iter);
     if (unlikely (!startCode)) return;
 
     //serialize idDelta[]
-    HBINT16 *idDelta = serialize_idDelta_array (c, it, endCode, startCode, segcount);
+    HBINT16 *idDelta = serialize_idDelta_array (c, format4_iter, endCode, startCode, segcount);
     if (unlikely (!idDelta)) return;
 
-    HBUINT16 *idRangeOffset = serialize_rangeoffset_glyid (c, it, endCode, startCode, idDelta, segcount);
+    HBUINT16 *idRangeOffset = serialize_rangeoffset_glyid (c, format4_iter, endCode, startCode, idDelta, segcount);
     if (unlikely (!c->check_success (idRangeOffset))) return;
 
     if (unlikely (!c->check_assign(this->length, c->length () - table_initpos))) return;
@@ -291,27 +294,28 @@
 
     bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
     {
-      /* Custom two-array bsearch. */
-      int min = 0, max = (int) this->segCount - 1;
-      const HBUINT16 *startCount = this->startCount;
-      const HBUINT16 *endCount = this->endCount;
-      unsigned int i;
-      while (min <= max)
+      struct CustomRange
       {
-	int mid = ((unsigned int) min + (unsigned int) max) / 2;
-	if (codepoint < startCount[mid])
-	  max = mid - 1;
-	else if (codepoint > endCount[mid])
-	  min = mid + 1;
-	else
+	int cmp (hb_codepoint_t k,
+		 unsigned distance) const
 	{
-	  i = mid;
-	  goto found;
+	  if (k > last) return +1;
+	  if (k < (&last)[distance]) return -1;
+	  return 0;
 	}
-      }
-      return false;
+	HBUINT16 last;
+      };
 
-    found:
+      const HBUINT16 *found =hb_bsearch (codepoint,
+					 this->endCount,
+					 this->segCount,
+					 2,
+					 _hb_cmp_method<hb_codepoint_t, CustomRange, unsigned>,
+					 this->segCount + 1);
+      if (!found)
+	return false;
+      unsigned int i = found - endCount;
+
       hb_codepoint_t gid;
       unsigned int rangeOffset = this->idRangeOffset[i];
       if (rangeOffset == 0)
@@ -333,8 +337,10 @@
       *glyph = gid;
       return true;
     }
+
     HB_INTERNAL static bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph)
     { return ((const accelerator_t *) obj)->get_glyph (codepoint, glyph); }
+
     void collect_unicodes (hb_set_t *out) const
     {
       unsigned int count = this->segCount;
@@ -528,7 +534,7 @@
     return true;
   }
 
-  void collect_unicodes (hb_set_t *out) const
+  void collect_unicodes (hb_set_t *out, unsigned int num_glyphs) const
   {
     for (unsigned int i = 0; i < this->groups.len; i++)
     {
@@ -535,13 +541,19 @@
       hb_codepoint_t start = this->groups[i].startCharCode;
       hb_codepoint_t end = hb_min ((hb_codepoint_t) this->groups[i].endCharCode,
 				   (hb_codepoint_t) HB_UNICODE_MAX);
-      for (hb_codepoint_t codepoint = start; codepoint <= end; codepoint++)
+      hb_codepoint_t gid = this->groups[i].glyphID;
+      if (!gid)
       {
-	hb_codepoint_t gid = T::group_get_glyph (this->groups[i], codepoint);
-	if (unlikely (!gid))
-	  continue;
-	out->add (codepoint);
+	/* Intention is: if (hb_is_same (T, CmapSubtableFormat13)) continue; */
+	if (! T::group_get_glyph (this->groups[i], end)) continue;
+	start++;
+	gid++;
       }
+      if (unlikely ((unsigned int) gid >= num_glyphs)) continue;
+      if (unlikely ((unsigned int) (gid + end - start) >= num_glyphs))
+	end = start + (hb_codepoint_t) num_glyphs - gid;
+
+      out->add_range (start, end);
     }
   }
 
@@ -582,33 +594,29 @@
     hb_codepoint_t startCharCode = 0xFFFF, endCharCode = 0xFFFF;
     hb_codepoint_t glyphID = 0;
 
-    + it
-    | hb_apply ([&] (const hb_item_type<Iterator> _)
-	      {
-		if (startCharCode == 0xFFFF)
-		{
-		  startCharCode = _.first;
-		  endCharCode = _.first;
-		  glyphID = _.second;
-		}
-		else if (!_is_gid_consecutive (endCharCode, startCharCode, glyphID, _.first, _.second))
-		{
-		  CmapSubtableLongGroup  grouprecord;
-		  grouprecord.startCharCode = startCharCode;
-		  grouprecord.endCharCode = endCharCode;
-		  grouprecord.glyphID = glyphID;
-		  c->copy<CmapSubtableLongGroup> (grouprecord);
+    for (const hb_item_type<Iterator> _ : +it)
+    {
+      if (startCharCode == 0xFFFF)
+      {
+	startCharCode = _.first;
+	endCharCode = _.first;
+	glyphID = _.second;
+      }
+      else if (!_is_gid_consecutive (endCharCode, startCharCode, glyphID, _.first, _.second))
+      {
+	CmapSubtableLongGroup  grouprecord;
+	grouprecord.startCharCode = startCharCode;
+	grouprecord.endCharCode = endCharCode;
+	grouprecord.glyphID = glyphID;
+	c->copy<CmapSubtableLongGroup> (grouprecord);
 
-		  startCharCode = _.first;
-		  endCharCode = _.first;
-		  glyphID = _.second;
-		}
-		else
-		{
-		  endCharCode = _.first;
-		}
-	      })
-    ;
+	startCharCode = _.first;
+	endCharCode = _.first;
+	glyphID = _.second;
+      }
+      else
+	endCharCode = _.first;
+    }
 
     CmapSubtableLongGroup record;
     record.startCharCode = startCharCode;
@@ -772,7 +780,7 @@
   {
     unsigned int count = len;
     for (unsigned int i = 0; i < count; i++)
-      out->add (arrayZ[i].glyphID);
+      out->add (arrayZ[i].unicodeValue);
   }
 
   void closure_glyphs (const hb_set_t      *unicodes,
@@ -839,6 +847,20 @@
     return GLYPH_VARIANT_NOT_FOUND;
   }
 
+  VariationSelectorRecord(const VariationSelectorRecord& other)
+  {
+    *this = other;
+  }
+
+  void operator= (const VariationSelectorRecord& other)
+  {
+    varSelector = other.varSelector;
+    HBUINT32 offset = other.defaultUVS;
+    defaultUVS = offset;
+    offset = other.nonDefaultUVS;
+    nonDefaultUVS = offset;
+  }
+
   void collect_unicodes (hb_set_t *out, const void *base) const
   {
     (base+defaultUVS).collect_unicodes (out);
@@ -856,50 +878,43 @@
 		  nonDefaultUVS.sanitize (c, base));
   }
 
-  VariationSelectorRecord* copy (hb_serialize_context_t *c,
-				 const hb_set_t *unicodes,
-				 const hb_set_t *glyphs,
-				 const hb_map_t *glyph_map,
-				 const void *src_base,
-				 const void *dst_base) const
+  hb_pair_t<unsigned, unsigned>
+  copy (hb_serialize_context_t *c,
+	const hb_set_t *unicodes,
+	const hb_set_t *glyphs,
+	const hb_map_t *glyph_map,
+	const void *base) const
   {
     auto snap = c->snapshot ();
     auto *out = c->embed<VariationSelectorRecord> (*this);
-    if (unlikely (!out)) return nullptr;
+    if (unlikely (!out)) return hb_pair (0, 0);
 
     out->defaultUVS = 0;
     out->nonDefaultUVS = 0;
 
-    bool drop = true;
-
-    if (defaultUVS != 0)
+    unsigned non_default_uvs_objidx = 0;
+    if (nonDefaultUVS != 0)
     {
       c->push ();
-      if (c->copy (src_base+defaultUVS, unicodes))
-      {
-	c->add_link (out->defaultUVS, c->pop_pack (), dst_base);
-	drop = false;
-      }
+      if (c->copy (base+nonDefaultUVS, unicodes, glyphs, glyph_map))
+	non_default_uvs_objidx = c->pop_pack ();
       else c->pop_discard ();
     }
 
-    if (nonDefaultUVS != 0)
+    unsigned default_uvs_objidx = 0;
+    if (defaultUVS != 0)
     {
       c->push ();
-      if (c->copy (src_base+nonDefaultUVS, unicodes, glyphs, glyph_map))
-      {
-	c->add_link (out->nonDefaultUVS, c->pop_pack (), dst_base);
-	drop = false;
-      }
+      if (c->copy (base+defaultUVS, unicodes))
+	default_uvs_objidx = c->pop_pack ();
       else c->pop_discard ();
     }
 
-    if (drop)
-    {
+
+    if (!default_uvs_objidx && !non_default_uvs_objidx)
       c->revert (snap);
-      return nullptr;
-    }
-    else return out;
+
+    return hb_pair (default_uvs_objidx, non_default_uvs_objidx);
   }
 
   HBUINT24	varSelector;	/* Variation selector. */
@@ -932,7 +947,7 @@
 		  const hb_set_t *unicodes,
 		  const hb_set_t *glyphs,
 		  const hb_map_t *glyph_map,
-		  const void *src_base)
+		  const void *base)
   {
     auto snap = c->snapshot ();
     unsigned table_initpos = c->length ();
@@ -941,17 +956,67 @@
     if (unlikely (!c->extend_min (*this))) return;
     this->format = 14;
 
-    const CmapSubtableFormat14 *src_tbl = reinterpret_cast<const CmapSubtableFormat14*> (src_base);
-    for (const VariationSelectorRecord& _ : src_tbl->record)
-      c->copy (_, unicodes, glyphs, glyph_map, src_base, this);
+    auto src_tbl = reinterpret_cast<const CmapSubtableFormat14*> (base);
 
+    /*
+     * Some versions of OTS require that offsets are in order. Due to the use
+     * of push()/pop_pack() serializing the variation records in order results
+     * in the offsets being in reverse order (first record has the largest
+     * offset). While this is perfectly valid, it will cause some versions of
+     * OTS to consider this table bad.
+     *
+     * So to prevent this issue we serialize the variation records in reverse
+     * order, so that the offsets are ordered from small to large. Since
+     * variation records are supposed to be in increasing order of varSelector
+     * we then have to reverse the order of the written variation selector
+     * records after everything is finalized.
+     */
+    hb_vector_t<hb_pair_t<unsigned, unsigned>> obj_indices;
+    for (int i = src_tbl->record.len - 1; i >= 0; i--)
+    {
+      hb_pair_t<unsigned, unsigned> result = src_tbl->record[i].copy (c, unicodes, glyphs, glyph_map, base);
+      if (result.first || result.second)
+	obj_indices.push (result);
+    }
+
     if (c->length () - table_initpos == CmapSubtableFormat14::min_size)
+    {
       c->revert (snap);
-    else
+      return;
+    }
+
+    int tail_len = init_tail - c->tail;
+    c->check_assign (this->length, c->length () - table_initpos + tail_len);
+    c->check_assign (this->record.len,
+		     (c->length () - table_initpos - CmapSubtableFormat14::min_size) /
+		     VariationSelectorRecord::static_size);
+
+    /* Correct the incorrect write order by reversing the order of the variation
+       records array. */
+    _reverse_variation_records ();
+
+    /* Now that records are in the right order, we can set up the offsets. */
+    _add_links_to_variation_records (c, obj_indices);
+  }
+
+  void _reverse_variation_records ()
+  {
+    record.as_array ().reverse ();
+  }
+
+  void _add_links_to_variation_records (hb_serialize_context_t *c,
+					const hb_vector_t<hb_pair_t<unsigned, unsigned>>& obj_indices)
+  {
+    for (unsigned i = 0; i < obj_indices.length; i++)
     {
-      int tail_len = init_tail - c->tail;
-      c->check_assign (this->length, c->length () - table_initpos + tail_len);
-      c->check_assign (this->record.len, (c->length () - table_initpos - CmapSubtableFormat14::min_size) / VariationSelectorRecord::static_size);
+      /*
+       * Since the record array has been reversed (see comments in copy())
+       * but obj_indices has not been, the indices at obj_indices[i]
+       * are for the variation record at record[j].
+       */
+      int j = obj_indices.length - 1 - i;
+      c->add_link (record[j].defaultUVS, obj_indices[i].first);
+      c->add_link (record[j].nonDefaultUVS, obj_indices[i].second);
     }
   }
 
@@ -966,6 +1031,12 @@
     ;
   }
 
+  void collect_unicodes (hb_set_t *out) const
+  {
+    for (const VariationSelectorRecord& _ : record)
+      _.collect_unicodes (out, this);
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -1001,7 +1072,7 @@
     default: return false;
     }
   }
-  void collect_unicodes (hb_set_t *out) const
+  void collect_unicodes (hb_set_t *out, unsigned int num_glyphs = UINT_MAX) const
   {
     switch (u.format) {
     case  0: u.format0 .collect_unicodes (out); return;
@@ -1008,8 +1079,8 @@
     case  4: u.format4 .collect_unicodes (out); return;
     case  6: u.format6 .collect_unicodes (out); return;
     case 10: u.format10.collect_unicodes (out); return;
-    case 12: u.format12.collect_unicodes (out); return;
-    case 13: u.format13.collect_unicodes (out); return;
+    case 12: u.format12.collect_unicodes (out, num_glyphs); return;
+    case 13: u.format13.collect_unicodes (out, num_glyphs); return;
     case 14:
     default: return;
     }
@@ -1021,12 +1092,12 @@
 		  Iterator it,
 		  unsigned format,
 		  const hb_subset_plan_t *plan,
-		  const void *src_base)
+		  const void *base)
   {
     switch (format) {
-    case  4: u.format4.serialize (c, it);  return;
-    case 12: u.format12.serialize (c, it); return;
-    case 14: u.format14.serialize (c, plan->unicodes, plan->_glyphset, plan->glyph_map, src_base); return;
+    case  4: return u.format4.serialize (c, it);
+    case 12: return u.format12.serialize (c, it);
+    case 14: return u.format14.serialize (c, plan->unicodes, plan->_glyphset, plan->glyph_map, base);
     default: return;
     }
   }
@@ -1087,8 +1158,7 @@
   EncodingRecord* copy (hb_serialize_context_t *c,
 			Iterator it,
 			unsigned format,
-			const void *src_base,
-			const void *dst_base,
+			const void *base,
 			const hb_subset_plan_t *plan,
 			/* INOUT */ unsigned *objidx) const
   {
@@ -1102,7 +1172,7 @@
     {
       CmapSubtable *cmapsubtable = c->push<CmapSubtable> ();
       unsigned origin_length = c->length ();
-      cmapsubtable->serialize (c, it, format, plan, &(src_base+subtable));
+      cmapsubtable->serialize (c, it, format, plan, &(base+subtable));
       if (c->length () - origin_length > 0) *objidx = c->pop_pack ();
       else c->pop_discard ();
     }
@@ -1113,7 +1183,7 @@
       return_trace (nullptr);
     }
 
-    c->add_link (out->subtable, *objidx, dst_base);
+    c->add_link (out->subtable, *objidx);
     return_trace (out);
   }
 
@@ -1134,7 +1204,7 @@
   void serialize (hb_serialize_context_t *c,
 		  Iterator it,
 		  EncodingRecIter encodingrec_iter,
-		  const void *src_base,
+		  const void *base,
 		  const hb_subset_plan_t *plan)
   {
     if (unlikely (!c->extend_min ((*this))))  return;
@@ -1144,11 +1214,14 @@
 
     for (const EncodingRecord& _ : encodingrec_iter)
     {
-      unsigned format = (src_base+_.subtable).u.format;
+      hb_set_t unicodes_set;
+      (base+_.subtable).collect_unicodes (&unicodes_set);
 
-      if (format == 4) c->copy (_, it, 4u, src_base, this, plan, &format4objidx);
-      else if (format == 12) c->copy (_, it, 12u, src_base, this, plan, &format12objidx);
-      else if (format == 14) c->copy (_, it, 14u, src_base, this, plan, &format14objidx);
+      unsigned format = (base+_.subtable).u.format;
+
+      if (format == 4) c->copy (_, + it | hb_filter (unicodes_set, hb_first), 4u, base, plan, &format4objidx);
+      else if (format == 12) c->copy (_, + it | hb_filter (unicodes_set, hb_first), 12u, base, plan, &format12objidx);
+      else if (format == 14) c->copy (_, it, 14u, base, plan, &format14objidx);
     }
 
     c->check_assign(this->encodingRecord.len, (c->length () - cmap::min_size)/EncodingRecord::static_size);
@@ -1187,7 +1260,6 @@
 		})
     ;
 
-
     if (unlikely (!encodingrec_iter.len ())) return_trace (false);
 
     const EncodingRecord *unicode_bmp= nullptr, *unicode_ucs4 = nullptr, *ms_bmp = nullptr, *ms_ucs4 = nullptr;
@@ -1205,7 +1277,7 @@
       else if (_.platformID == 3 && _.encodingID == 10) ms_ucs4 = table;
     }
 
-    if (unlikely (!unicode_bmp && !ms_bmp)) return_trace (false);
+    if (unlikely (!has_format12 && !unicode_bmp && !ms_bmp)) return_trace (false);
     if (unlikely (has_format12 && (!unicode_ucs4 && !ms_ucs4))) return_trace (false);
 
     auto it =
@@ -1339,8 +1411,8 @@
       return get_nominal_glyph (unicode, glyph);
     }
 
-    void collect_unicodes (hb_set_t *out) const
-    { subtable->collect_unicodes (out); }
+    void collect_unicodes (hb_set_t *out, unsigned int num_glyphs) const
+    { subtable->collect_unicodes (out, num_glyphs); }
     void collect_variation_selectors (hb_set_t *out) const
     { subtable_uvs->collect_variation_selectors (out); }
     void collect_variation_unicodes (hb_codepoint_t variation_selector,
@@ -1413,7 +1485,7 @@
   }
 
   const EncodingRecord *find_encodingrec (unsigned int platform_id,
-				    unsigned int encoding_id) const
+					  unsigned int encoding_id) const
   {
     EncodingRecord key;
     key.platformID = platform_id;
@@ -1445,9 +1517,9 @@
   }
 
   protected:
-  HBUINT16		version;	/* Table version number (0). */
+  HBUINT16	version;	/* Table version number (0). */
   SortedArrayOf<EncodingRecord>
-			encodingRecord;	/* Encoding tables. */
+		encodingRecord;	/* Encoding tables. */
   public:
   DEFINE_SIZE_ARRAY (4, encodingRecord);
 };

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	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -21,7 +21,7 @@
  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  *
- * Google Author(s): Seigo Nonaka
+ * Google Author(s): Seigo Nonaka, Calder Kitagawa
  */
 
 #ifndef HB_OT_COLOR_CBDT_TABLE_HH
@@ -43,6 +43,35 @@
 
 namespace OT {
 
+struct cblc_bitmap_size_subset_context_t
+{
+  const char *cbdt;
+  unsigned int cbdt_length;
+  hb_vector_t<char> *cbdt_prime;
+  unsigned int size;		/* INOUT
+				 *  Input: old size of IndexSubtable
+				 *  Output: new size of IndexSubtable
+				 */
+  unsigned int num_tables;	/* INOUT
+				 *  Input: old number of subtables.
+				 *  Output: new number of subtables.
+				 */
+  hb_codepoint_t start_glyph;	/* OUT */
+  hb_codepoint_t end_glyph;	/* OUT */
+};
+
+static inline bool
+_copy_data_to_cbdt (hb_vector_t<char> *cbdt_prime,
+		    const void        *data,
+		    unsigned           length)
+{
+  unsigned int new_len = cbdt_prime->length + length;
+  if (unlikely (!cbdt_prime->alloc (new_len))) return false;
+  memcpy (cbdt_prime->arrayZ + cbdt_prime->length, data, length);
+  cbdt_prime->length = new_len;
+  return true;
+}
+
 struct SmallGlyphMetrics
 {
   bool sanitize (hb_sanitize_context_t *c) const
@@ -56,7 +85,7 @@
     extents->x_bearing = font->em_scale_x (bearingX);
     extents->y_bearing = font->em_scale_y (bearingY);
     extents->width = font->em_scale_x (width);
-    extents->height = font->em_scale_y (-height);
+    extents->height = font->em_scale_y (-static_cast<int>(height));
   }
 
   HBUINT8	height;
@@ -65,7 +94,7 @@
   HBINT8	bearingY;
   HBUINT8	advance;
   public:
-  DEFINE_SIZE_STATIC(5);
+  DEFINE_SIZE_STATIC (5);
 };
 
 struct BigGlyphMetrics : SmallGlyphMetrics
@@ -74,7 +103,7 @@
   HBINT8	vertBearingY;
   HBUINT8	vertAdvance;
   public:
-  DEFINE_SIZE_STATIC(8);
+  DEFINE_SIZE_STATIC (8);
 };
 
 struct SBitLineMetrics
@@ -98,7 +127,7 @@
   HBINT8	padding1;
   HBINT8	padding2;
   public:
-  DEFINE_SIZE_STATIC(12);
+  DEFINE_SIZE_STATIC (12);
 };
 
 
@@ -118,7 +147,7 @@
   HBUINT16	imageFormat;
   HBUINT32	imageDataOffset;
   public:
-  DEFINE_SIZE_STATIC(8);
+  DEFINE_SIZE_STATIC (8);
 };
 
 template <typename OffsetType>
@@ -143,11 +172,23 @@
     return true;
   }
 
+  bool add_offset (hb_serialize_context_t *c,
+		   unsigned int offset,
+		   unsigned int *size /* OUT (accumulated) */)
+  {
+    TRACE_SERIALIZE (this);
+    Offset<OffsetType> embedded_offset;
+    embedded_offset = offset;
+    *size += sizeof (OffsetType);
+    auto *o = c->embed (embedded_offset);
+    return_trace ((bool) o);
+  }
+
   IndexSubtableHeader	header;
   UnsizedArrayOf<Offset<OffsetType>>
- 			offsetArrayZ;
+			offsetArrayZ;
   public:
-  DEFINE_SIZE_ARRAY(8, offsetArrayZ);
+  DEFINE_SIZE_ARRAY (8, offsetArrayZ);
 };
 
 struct IndexSubtableFormat1 : IndexSubtableFormat1Or3<HBUINT32> {};
@@ -159,7 +200,8 @@
   {
     TRACE_SANITIZE (this);
     if (!u.header.sanitize (c)) return_trace (false);
-    switch (u.header.indexFormat) {
+    switch (u.header.indexFormat)
+    {
     case 1: return_trace (u.format1.sanitize (c, glyph_count));
     case 3: return_trace (u.format3.sanitize (c, glyph_count));
     default:return_trace (true);
@@ -166,9 +208,109 @@
     }
   }
 
+  bool
+  finish_subtable (hb_serialize_context_t *c,
+		   unsigned int cbdt_prime_len,
+		   unsigned int num_glyphs,
+		   unsigned int *size /* OUT (accumulated) */)
+  {
+    TRACE_SERIALIZE (this);
+
+    unsigned int local_offset = cbdt_prime_len - u.header.imageDataOffset;
+    switch (u.header.indexFormat)
+    {
+    case 1: return_trace (u.format1.add_offset (c, local_offset, size));
+    case 3: {
+      if (!u.format3.add_offset (c, local_offset, size))
+	return_trace (false);
+      if (!(num_glyphs & 0x01))  // Pad to 32-bit alignment if needed.
+	return_trace (u.format3.add_offset (c, 0, size));
+      return_trace (true);
+    }
+    // TODO: implement 2, 4, 5.
+    case 2: case 4:  // No-op.
+    case 5:  // Pad to 32-bit aligned.
+    default: return_trace (false);
+    }
+  }
+
+  bool
+  fill_missing_glyphs (hb_serialize_context_t *c,
+		       unsigned int cbdt_prime_len,
+		       unsigned int num_missing,
+		       unsigned int *size /* OUT (accumulated) */,
+		       unsigned int *num_glyphs /* OUT (accumulated) */)
+  {
+    TRACE_SERIALIZE (this);
+
+    unsigned int local_offset = cbdt_prime_len - u.header.imageDataOffset;
+    switch (u.header.indexFormat)
+    {
+    case 1: {
+      for (unsigned int i = 0; i < num_missing; i++)
+      {
+	if (unlikely (!u.format1.add_offset (c, local_offset, size)))
+	  return_trace (false);
+	*num_glyphs += 1;
+      }
+      return_trace (true);
+    }
+    case 3: {
+      for (unsigned int i = 0; i < num_missing; i++)
+      {
+	if (unlikely (!u.format3.add_offset (c, local_offset, size)))
+	  return_trace (false);
+	*num_glyphs += 1;
+      }
+      return_trace (true);
+    }
+    // TODO: implement 2, 4, 5.
+    case 2:  // Add empty space in cbdt_prime?.
+    case 4: case 5:  // No-op as sparse is supported.
+    default: return_trace (false);
+    }
+  }
+
+  bool
+  copy_glyph_at_idx (hb_serialize_context_t *c, unsigned int idx,
+		     const char *cbdt, unsigned int cbdt_length,
+		     hb_vector_t<char> *cbdt_prime /* INOUT */,
+		     IndexSubtable *subtable_prime /* INOUT */,
+		     unsigned int *size /* OUT (accumulated) */) const
+  {
+    TRACE_SERIALIZE (this);
+
+    unsigned int offset, length, format;
+    if (unlikely (!get_image_data (idx, &offset, &length, &format))) return_trace (false);
+    if (unlikely (offset > cbdt_length || cbdt_length - offset < length)) return_trace (false);
+
+    auto *header_prime = subtable_prime->get_header ();
+    unsigned int new_local_offset = cbdt_prime->length - (unsigned int) header_prime->imageDataOffset;
+    if (unlikely (!_copy_data_to_cbdt (cbdt_prime, cbdt + offset, length))) return_trace (false);
+
+    return_trace (subtable_prime->add_offset (c, new_local_offset, size));
+  }
+
+  bool
+  add_offset (hb_serialize_context_t *c, unsigned int local_offset,
+	      unsigned int *size /* OUT (accumulated) */)
+  {
+    TRACE_SERIALIZE (this);
+    switch (u.header.indexFormat)
+    {
+    case 1: return_trace (u.format1.add_offset (c, local_offset, size));
+    case 3: return_trace (u.format3.add_offset (c, local_offset, size));
+    // TODO: Implement tables 2, 4, 5
+    case 2:  // Should be a no-op.
+    case 4: case 5:  // Handle sparse cases.
+    default: return_trace (false);
+    }
+  }
+
   bool get_extents (hb_glyph_extents_t *extents HB_UNUSED) const
   {
-    switch (u.header.indexFormat) {
+    switch (u.header.indexFormat)
+    {
     case 2: case 5: /* TODO */
     case 1: case 3: case 4: /* Variable-metrics formats do not have metrics here. */
     default:return (false);
@@ -175,13 +317,13 @@
     }
   }
 
-  bool get_image_data (unsigned int idx,
-		       unsigned int *offset,
-		       unsigned int *length,
-		       unsigned int *format) const
+  bool
+  get_image_data (unsigned int idx, unsigned int *offset,
+		  unsigned int *length, unsigned int *format) const
   {
     *format = u.header.imageFormat;
-    switch (u.header.indexFormat) {
+    switch (u.header.indexFormat)
+    {
     case 1: return u.format1.get_image_data (idx, offset, length);
     case 3: return u.format3.get_image_data (idx, offset, length);
     default: return false;
@@ -188,6 +330,23 @@
     }
   }
 
+  const IndexSubtableHeader* get_header () const { return &u.header; }
+
+  void populate_header (unsigned index_format,
+			unsigned image_format,
+			unsigned int image_data_offset,
+			unsigned int *size)
+  {
+    u.header.indexFormat = index_format;
+    u.header.imageFormat = image_format;
+    u.header.imageDataOffset = image_data_offset;
+    switch (u.header.indexFormat)
+    {
+    case 1: *size += IndexSubtableFormat1::min_size; break;
+    case 3: *size += IndexSubtableFormat3::min_size; break;
+    }
+  }
+
   protected:
   union {
   IndexSubtableHeader	header;
@@ -209,12 +368,133 @@
 		  offsetToSubtable.sanitize (c, base, lastGlyphIndex - firstGlyphIndex + 1));
   }
 
-  bool get_extents (hb_glyph_extents_t *extents,
-		    const void *base) const
+  const IndexSubtable* get_subtable (const void *base) const
   {
-    return (base+offsetToSubtable).get_extents (extents);
+    return &(base+offsetToSubtable);
   }
 
+  bool add_new_subtable (hb_subset_context_t* c,
+			 cblc_bitmap_size_subset_context_t *bitmap_size_context,
+			 IndexSubtableRecord *record,
+			 const hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> *lookup, /* IN */
+			 const void *base,
+			 unsigned int *start /* INOUT */) const
+  {
+    TRACE_SERIALIZE (this);
+
+    auto *subtable = c->serializer->start_embed<IndexSubtable> ();
+    if (unlikely (!subtable)) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (subtable))) return_trace (false);
+
+    auto *old_subtable = get_subtable (base);
+    auto *old_header = old_subtable->get_header ();
+
+    subtable->populate_header (old_header->indexFormat,
+			       old_header->imageFormat,
+			       bitmap_size_context->cbdt_prime->length,
+			       &bitmap_size_context->size);
+
+    unsigned int num_glyphs = 0;
+    bool early_exit = false;
+    for (unsigned int i = *start; i < lookup->length; i++)
+    {
+      hb_codepoint_t new_gid = (*lookup)[i].first;
+      const IndexSubtableRecord *next_record = (*lookup)[i].second;
+      const IndexSubtable *next_subtable = next_record->get_subtable (base);
+      auto *next_header = next_subtable->get_header ();
+      if (next_header != old_header)
+      {
+	*start = i;
+	early_exit = true;
+	break;
+      }
+      unsigned int num_missing = record->add_glyph_for_subset (new_gid);
+      if (unlikely (!subtable->fill_missing_glyphs (c->serializer,
+						    bitmap_size_context->cbdt_prime->length,
+						    num_missing,
+						    &bitmap_size_context->size,
+						    &num_glyphs)))
+	return_trace (false);
+
+      hb_codepoint_t old_gid = 0;
+      c->plan->old_gid_for_new_gid (new_gid, &old_gid);
+      if (old_gid < next_record->firstGlyphIndex)
+	return_trace (false);
+
+      unsigned int old_idx = (unsigned int) old_gid - next_record->firstGlyphIndex;
+      if (unlikely (!next_subtable->copy_glyph_at_idx (c->serializer,
+						       old_idx,
+						       bitmap_size_context->cbdt,
+						       bitmap_size_context->cbdt_length,
+						       bitmap_size_context->cbdt_prime,
+						       subtable,
+						       &bitmap_size_context->size)))
+	return_trace (false);
+      num_glyphs += 1;
+    }
+    if (!early_exit)
+      *start = lookup->length;
+    if (unlikely (!subtable->finish_subtable (c->serializer,
+					      bitmap_size_context->cbdt_prime->length,
+					      num_glyphs,
+					      &bitmap_size_context->size)))
+      return_trace (false);
+    return_trace (true);
+  }
+
+  bool add_new_record (hb_subset_context_t *c,
+		       cblc_bitmap_size_subset_context_t *bitmap_size_context,
+		       const hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> *lookup, /* IN */
+		       const void *base,
+		       unsigned int *start, /* INOUT */
+		       hb_vector_t<IndexSubtableRecord>* records /* INOUT */) const
+  {
+    TRACE_SERIALIZE (this);
+    auto snap = c->serializer->snapshot ();
+    unsigned int old_size = bitmap_size_context->size;
+    unsigned int old_cbdt_prime_length = bitmap_size_context->cbdt_prime->length;
+
+    // Set to invalid state to indicate filling glyphs is not yet started.
+    records->resize (records->length + 1);
+    (*records)[records->length - 1].firstGlyphIndex = 1;
+    (*records)[records->length - 1].lastGlyphIndex = 0;
+    bitmap_size_context->size += IndexSubtableRecord::min_size;
+
+    c->serializer->push ();
+
+    if (unlikely (!add_new_subtable (c, bitmap_size_context, &((*records)[records->length - 1]), lookup, base, start)))
+    {
+      c->serializer->pop_discard ();
+      c->serializer->revert (snap);
+      bitmap_size_context->cbdt_prime->shrink (old_cbdt_prime_length);
+      bitmap_size_context->size = old_size;
+      records->resize (records->length - 1);
+      return_trace (false);
+    }
+
+    bitmap_size_context->num_tables += 1;
+    return_trace (true);
+  }
+
+  unsigned int add_glyph_for_subset (hb_codepoint_t gid)
+  {
+    if (firstGlyphIndex > lastGlyphIndex)
+    {
+      firstGlyphIndex = gid;
+      lastGlyphIndex = gid;
+      return 0;
+    }
+    // TODO maybe assert? this shouldn't occur.
+    if (lastGlyphIndex > gid)
+      return 0;
+    unsigned int num_missing = (unsigned int) (gid - lastGlyphIndex - 1);
+    lastGlyphIndex = gid;
+    return num_missing;
+  }
+
+  bool get_extents (hb_glyph_extents_t *extents, const void *base) const
+  { return (base+offsetToSubtable).get_extents (extents); }
+
   bool get_image_data (unsigned int  gid,
 		       const void   *base,
 		       unsigned int *offset,
@@ -230,7 +510,7 @@
   HBGlyphID			lastGlyphIndex;
   LOffsetTo<IndexSubtable>	offsetToSubtable;
   public:
-  DEFINE_SIZE_STATIC(8);
+  DEFINE_SIZE_STATIC (8);
 };
 
 struct IndexSubtableArray
@@ -243,6 +523,77 @@
     return_trace (indexSubtablesZ.sanitize (c, count, this));
   }
 
+  void
+  build_lookup (hb_subset_context_t *c, cblc_bitmap_size_subset_context_t *bitmap_size_context,
+		hb_vector_t<hb_pair_t<hb_codepoint_t,
+		const IndexSubtableRecord*>> *lookup /* OUT */) const
+  {
+    bool start_glyph_is_set = false;
+    for (hb_codepoint_t new_gid = 0; new_gid < c->plan->num_output_glyphs (); new_gid++)
+    {
+      hb_codepoint_t old_gid;
+      if (unlikely (!c->plan->old_gid_for_new_gid (new_gid, &old_gid))) continue;
+
+      const IndexSubtableRecord* record = find_table (old_gid, bitmap_size_context->num_tables);
+      if (unlikely (!record)) continue;
+
+      // Don't add gaps to the lookup. The best way to determine if a glyph is a
+      // gap is that it has no image data.
+      unsigned int offset, length, format;
+      if (unlikely (!record->get_image_data (old_gid, this, &offset, &length, &format))) continue;
+
+      lookup->push (hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*> (new_gid, record));
+
+      if (!start_glyph_is_set)
+      {
+	bitmap_size_context->start_glyph = new_gid;
+	start_glyph_is_set = true;
+      }
+
+      bitmap_size_context->end_glyph = new_gid;
+    }
+  }
+
+  bool
+  subset (hb_subset_context_t *c,
+	  cblc_bitmap_size_subset_context_t *bitmap_size_context) const
+  {
+    TRACE_SUBSET (this);
+
+    auto *dst = c->serializer->start_embed<IndexSubtableArray> ();
+    if (unlikely (!dst)) return_trace (false);
+
+    hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> lookup;
+    build_lookup (c, bitmap_size_context, &lookup);
+
+    bitmap_size_context->size = 0;
+    bitmap_size_context->num_tables = 0;
+    hb_vector_t<IndexSubtableRecord> records;
+    for (unsigned int start = 0; start < lookup.length;)
+    {
+      if (unlikely (!lookup[start].second->add_new_record (c, bitmap_size_context, &lookup, this, &start, &records)))
+      {
+	// Discard any leftover pushes to the serializer from successful records.
+	for (unsigned int i = 0; i < records.length; i++)
+	  c->serializer->pop_discard ();
+	return_trace (false);
+      }
+    }
+
+    /* Workaround to ensure offset ordering is from least to greatest when
+     * resolving links. */
+    hb_vector_t<hb_serialize_context_t::objidx_t> objidxs;
+    for (unsigned int i = 0; i < records.length; i++)
+      objidxs.push (c->serializer->pop_pack ());
+    for (unsigned int i = 0; i < records.length; i++)
+    {
+      IndexSubtableRecord* record = c->serializer->embed (records[i]);
+      if (unlikely (!record)) return_trace (false);
+      c->serializer->add_link (record->offsetToSubtable, objidxs[records.length - 1 - i]);
+    }
+    return_trace (true);
+  }
+
   public:
   const IndexSubtableRecord* find_table (hb_codepoint_t glyph, unsigned int numTables) const
   {
@@ -274,14 +625,48 @@
 		  vertical.sanitize (c));
   }
 
-  const IndexSubtableRecord *find_table (hb_codepoint_t glyph,
-					 const void *base,
-					 const void **out_base) const
+  const IndexSubtableRecord *
+  find_table (hb_codepoint_t glyph, const void *base, const void **out_base) const
   {
     *out_base = &(base+indexSubtableArrayOffset);
     return (base+indexSubtableArrayOffset).find_table (glyph, numberOfIndexSubtables);
   }
 
+  bool
+  subset (hb_subset_context_t *c, const void *base,
+	  const char *cbdt, unsigned int cbdt_length,
+	  hb_vector_t<char> *cbdt_prime /* INOUT */) const
+  {
+    TRACE_SUBSET (this);
+    auto *out_table = c->serializer->embed (this);
+    if (unlikely (!out_table)) return_trace (false);
+
+    cblc_bitmap_size_subset_context_t bitmap_size_context;
+    bitmap_size_context.cbdt = cbdt;
+    bitmap_size_context.cbdt_length = cbdt_length;
+    bitmap_size_context.cbdt_prime = cbdt_prime;
+    bitmap_size_context.size = indexTablesSize;
+    bitmap_size_context.num_tables = numberOfIndexSubtables;
+    bitmap_size_context.start_glyph = 1;
+    bitmap_size_context.end_glyph = 0;
+
+    if (!out_table->indexSubtableArrayOffset.serialize_subset (c,
+							       indexSubtableArrayOffset,
+							       base,
+							       &bitmap_size_context))
+      return_trace (false);
+    if (!bitmap_size_context.size ||
+	!bitmap_size_context.num_tables ||
+	bitmap_size_context.start_glyph > bitmap_size_context.end_glyph)
+      return_trace (false);
+
+    out_table->indexTablesSize = bitmap_size_context.size;
+    out_table->numberOfIndexSubtables = bitmap_size_context.num_tables;
+    out_table->startGlyphIndex = bitmap_size_context.start_glyph;
+    out_table->endGlyphIndex = bitmap_size_context.end_glyph;
+    return_trace (true);
+  }
+
   protected:
   LNNOffsetTo<IndexSubtableArray>
 			indexSubtableArrayOffset;
@@ -297,7 +682,7 @@
   HBUINT8		bitDepth;
   HBINT8		flags;
   public:
-  DEFINE_SIZE_STATIC(48);
+  DEFINE_SIZE_STATIC (48);
 };
 
 
@@ -310,7 +695,7 @@
   SmallGlyphMetrics	glyphMetrics;
   LArrayOf<HBUINT8>	data;
   public:
-  DEFINE_SIZE_ARRAY(9, data);
+  DEFINE_SIZE_ARRAY (9, data);
 };
 
 struct GlyphBitmapDataFormat18
@@ -318,7 +703,7 @@
   BigGlyphMetrics	glyphMetrics;
   LArrayOf<HBUINT8>	data;
   public:
-  DEFINE_SIZE_ARRAY(12, data);
+  DEFINE_SIZE_ARRAY (12, data);
 };
 
 struct GlyphBitmapDataFormat19
@@ -325,7 +710,7 @@
 {
   LArrayOf<HBUINT8>	data;
   public:
-  DEFINE_SIZE_ARRAY(4, data);
+  DEFINE_SIZE_ARRAY (4, data);
 };
 
 struct CBLC
@@ -342,12 +727,50 @@
 		  sizeTables.sanitize (c, this));
   }
 
+  static bool
+  sink_cbdt (hb_subset_context_t *c, hb_vector_t<char>* cbdt_prime)
+  {
+    hb_blob_t *cbdt_prime_blob = hb_blob_create (cbdt_prime->arrayZ,
+						 cbdt_prime->length,
+						 HB_MEMORY_MODE_WRITABLE,
+						 cbdt_prime->arrayZ,
+						 free);
+    cbdt_prime->init ();  // Leak arrayZ to the blob.
+    bool ret = c->plan->add_table (HB_OT_TAG_CBDT, cbdt_prime_blob);
+    hb_blob_destroy (cbdt_prime_blob);
+    return ret;
+  }
+
+  bool
+  subset_size_table (hb_subset_context_t *c, const BitmapSizeTable& table,
+		     const char *cbdt /* IN */, unsigned int cbdt_length,
+		     CBLC *cblc_prime /* INOUT */, hb_vector_t<char> *cbdt_prime /* INOUT */) const
+  {
+    TRACE_SUBSET (this);
+    cblc_prime->sizeTables.len++;
+
+    auto snap = c->serializer->snapshot ();
+    auto cbdt_prime_len = cbdt_prime->length;
+
+    if (!table.subset (c, this, cbdt, cbdt_length, cbdt_prime))
+    {
+      cblc_prime->sizeTables.len--;
+      c->serializer->revert (snap);
+      cbdt_prime->shrink (cbdt_prime_len);
+      return_trace (false);
+    }
+    return_trace (true);
+  }
+
+  // Implemented in cc file as it depends on definition of CBDT.
+  HB_INTERNAL bool subset (hb_subset_context_t *c) const;
+
   protected:
   const BitmapSizeTable &choose_strike (hb_font_t *font) const
   {
     unsigned count = sizeTables.len;
     if (unlikely (!count))
-      return Null(BitmapSizeTable);
+      return Null (BitmapSizeTable);
 
     unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem);
     if (!requested_ppem)
@@ -373,7 +796,7 @@
   FixedVersion<>		version;
   LArrayOf<BitmapSizeTable>	sizeTables;
   public:
-  DEFINE_SIZE_ARRAY(8, sizeTables);
+  DEFINE_SIZE_ARRAY (8, sizeTables);
 };
 
 struct CBDT
@@ -384,8 +807,8 @@
   {
     void init (hb_face_t *face)
     {
-      cblc = hb_sanitize_context_t().reference_table<CBLC> (face);
-      cbdt = hb_sanitize_context_t().reference_table<CBDT> (face);
+      cblc = hb_sanitize_context_t ().reference_table<CBLC> (face);
+      cbdt = hb_sanitize_context_t ().reference_table<CBDT> (face);
 
       upem = hb_face_get_upem (face);
     }
@@ -396,8 +819,8 @@
       this->cbdt.destroy ();
     }
 
-    bool get_extents (hb_font_t *font, hb_codepoint_t glyph,
-		      hb_glyph_extents_t *extents) const
+    bool
+    get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
     {
       const void *base;
       const BitmapSizeTable &strike = this->cblc->choose_strike (font);
@@ -412,34 +835,28 @@
       if (!subtable_record->get_image_data (glyph, base, &image_offset, &image_length, &image_format))
 	return false;
 
+      unsigned int cbdt_len = cbdt.get_length ();
+      if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length))
+	return false;
+
+      switch (image_format)
       {
-	unsigned int cbdt_len = cbdt.get_length ();
-	if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length))
+      case 17: {
+	if (unlikely (image_length < GlyphBitmapDataFormat17::min_size))
 	  return false;
-
-	switch (image_format)
-	{
-	  case 17: {
-	    if (unlikely (image_length < GlyphBitmapDataFormat17::min_size))
-	      return false;
-	    const GlyphBitmapDataFormat17& glyphFormat17 =
-		StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
-	    glyphFormat17.glyphMetrics.get_extents (font, extents);
-	    break;
-	  }
-	  case 18: {
-	    if (unlikely (image_length < GlyphBitmapDataFormat18::min_size))
-	      return false;
-	    const GlyphBitmapDataFormat18& glyphFormat18 =
-		StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset);
-	    glyphFormat18.glyphMetrics.get_extents (font, extents);
-	    break;
-	  }
-	  default:
-	    // TODO: Support other image formats.
-	    return false;
-	}
+	auto &glyphFormat17 = StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
+	glyphFormat17.glyphMetrics.get_extents (font, extents);
+	break;
       }
+      case 18: {
+	if (unlikely (image_length < GlyphBitmapDataFormat18::min_size))
+	  return false;
+	auto &glyphFormat18 = StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset);
+	glyphFormat18.glyphMetrics.get_extents (font, extents);
+	break;
+      }
+      default: return false; /* TODO: Support other image formats. */
+      }
 
       /* Convert to font units. */
       float x_scale = upem / (float) strike.ppemX;
@@ -452,8 +869,8 @@
       return true;
     }
 
-    hb_blob_t* reference_png (hb_font_t      *font,
-			      hb_codepoint_t  glyph) const
+    hb_blob_t*
+    reference_png (hb_font_t *font, hb_codepoint_t glyph) const
     {
       const void *base;
       const BitmapSizeTable &strike = this->cblc->choose_strike (font);
@@ -465,44 +882,41 @@
       if (!subtable_record->get_image_data (glyph, base, &image_offset, &image_length, &image_format))
 	return hb_blob_get_empty ();
 
+      unsigned int cbdt_len = cbdt.get_length ();
+      if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length))
+	return hb_blob_get_empty ();
+
+      switch (image_format)
       {
-	unsigned int cbdt_len = cbdt.get_length ();
-	if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length))
+      case 17:
+      {
+	if (unlikely (image_length < GlyphBitmapDataFormat17::min_size))
 	  return hb_blob_get_empty ();
-
-	switch (image_format)
-	{
-	  case 17: {
-	    if (unlikely (image_length < GlyphBitmapDataFormat17::min_size))
-	      return hb_blob_get_empty ();
-	    const GlyphBitmapDataFormat17& glyphFormat17 =
-	      StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
-	    return hb_blob_create_sub_blob (cbdt.get_blob (),
-					    image_offset + GlyphBitmapDataFormat17::min_size,
-					    glyphFormat17.data.len);
-	  }
-	  case 18: {
-	    if (unlikely (image_length < GlyphBitmapDataFormat18::min_size))
-	      return hb_blob_get_empty ();
-	    const GlyphBitmapDataFormat18& glyphFormat18 =
-	      StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset);
-	    return hb_blob_create_sub_blob (cbdt.get_blob (),
-					    image_offset + GlyphBitmapDataFormat18::min_size,
-					    glyphFormat18.data.len);
-	  }
-	  case 19: {
-	    if (unlikely (image_length < GlyphBitmapDataFormat19::min_size))
-	      return hb_blob_get_empty ();
-	    const GlyphBitmapDataFormat19& glyphFormat19 =
-	      StructAtOffset<GlyphBitmapDataFormat19> (this->cbdt, image_offset);
-	    return hb_blob_create_sub_blob (cbdt.get_blob (),
-					    image_offset + GlyphBitmapDataFormat19::min_size,
-					    glyphFormat19.data.len);
-	  }
-	}
+	auto &glyphFormat17 = StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
+	return hb_blob_create_sub_blob (cbdt.get_blob (),
+					image_offset + GlyphBitmapDataFormat17::min_size,
+					glyphFormat17.data.len);
       }
-
-      return hb_blob_get_empty ();
+      case 18:
+      {
+	if (unlikely (image_length < GlyphBitmapDataFormat18::min_size))
+	  return hb_blob_get_empty ();
+	auto &glyphFormat18 = StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset);
+	return hb_blob_create_sub_blob (cbdt.get_blob (),
+					image_offset + GlyphBitmapDataFormat18::min_size,
+					glyphFormat18.data.len);
+      }
+      case 19:
+      {
+	if (unlikely (image_length < GlyphBitmapDataFormat19::min_size))
+	  return hb_blob_get_empty ();
+	auto &glyphFormat19 = StructAtOffset<GlyphBitmapDataFormat19> (this->cbdt, image_offset);
+	return hb_blob_create_sub_blob (cbdt.get_blob (),
+					image_offset + GlyphBitmapDataFormat19::min_size,
+					glyphFormat19.data.len);
+      }
+      default: return hb_blob_get_empty (); /* TODO: Support other image formats. */
+      }
     }
 
     bool has_data () const { return cbdt.get_length (); }
@@ -525,9 +939,41 @@
   FixedVersion<>		version;
   UnsizedArrayOf<HBUINT8>	dataZ;
   public:
-  DEFINE_SIZE_ARRAY(4, dataZ);
+  DEFINE_SIZE_ARRAY (4, dataZ);
 };
 
+inline bool
+CBLC::subset (hb_subset_context_t *c) const
+{
+  TRACE_SUBSET (this);
+
+  auto *cblc_prime = c->serializer->start_embed<CBLC> ();
+
+  // Use a vector as a secondary buffer as the tables need to be built in parallel.
+  hb_vector_t<char> cbdt_prime;
+
+  if (unlikely (!cblc_prime)) return_trace (false);
+  if (unlikely (!c->serializer->extend_min (cblc_prime))) return_trace (false);
+  cblc_prime->version = version;
+
+  hb_blob_t* cbdt_blob = hb_sanitize_context_t ().reference_table<CBDT> (c->plan->source);
+  unsigned int cbdt_length;
+  CBDT* cbdt = (CBDT *) hb_blob_get_data (cbdt_blob, &cbdt_length);
+  if (unlikely (cbdt_length < CBDT::min_size))
+  {
+    hb_blob_destroy (cbdt_blob);
+    return_trace (false);
+  }
+  _copy_data_to_cbdt (&cbdt_prime, cbdt, CBDT::min_size);
+
+  for (const BitmapSizeTable& table : + sizeTables.iter ())
+    subset_size_table (c, table, (const char *) cbdt, cbdt_length, cblc_prime, &cbdt_prime);
+
+  hb_blob_destroy (cbdt_blob);
+
+  return_trace (CBLC::sink_cbdt (c, &cbdt_prime));
+}
+
 struct CBDT_accelerator_t : CBDT::accelerator_t {};
 
 } /* namespace OT */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2018  Ebrahim Byagowi
+ * Copyright © 2020  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -20,6 +21,8 @@
  * 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): Calder Kitagawa
  */
 
 #ifndef HB_OT_COLOR_COLR_TABLE_HH
@@ -47,7 +50,7 @@
     return_trace (c->check_struct (this));
   }
 
-  protected:
+  public:
   HBGlyphID	glyphId;	/* Glyph ID of layer glyph */
   Index		colorIdx;	/* Index value to use with a
 				 * selected color palette.
@@ -112,6 +115,38 @@
     return glyph_layers.length;
   }
 
+  struct accelerator_t
+  {
+    accelerator_t () {}
+    ~accelerator_t () { fini (); }
+
+    void init (hb_face_t *face)
+    { colr = hb_sanitize_context_t ().reference_table<COLR> (face); }
+
+    void fini () { this->colr.destroy (); }
+
+    bool is_valid () { return colr.get_blob ()->length; }
+
+    void closure_glyphs (hb_codepoint_t glyph,
+			 hb_set_t *related_ids /* OUT */) const
+    { colr->closure_glyphs (glyph, related_ids); }
+
+    private:
+    hb_blob_ptr_t<COLR> colr;
+  };
+
+  void closure_glyphs (hb_codepoint_t glyph,
+		       hb_set_t *related_ids /* OUT */) const
+  {
+    const BaseGlyphRecord *record = get_base_glyph_record (glyph);
+    if (!record) return;
+
+    auto glyph_layers = (this+layersZ).as_array (numLayers).sub_array (record->firstLayerIdx,
+								       record->numLayers);
+    if (!glyph_layers.length) return;
+    related_ids->add_array (&glyph_layers[0].glyphId, glyph_layers.length, LayerRecord::min_size);
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -120,6 +155,111 @@
 			  (this+layersZ).sanitize (c, numLayers)));
   }
 
+  template<typename BaseIterator, typename LayerIterator,
+	   hb_requires (hb_is_iterator (BaseIterator)),
+	   hb_requires (hb_is_iterator (LayerIterator))>
+  bool serialize (hb_serialize_context_t *c,
+		  unsigned version,
+		  BaseIterator base_it,
+		  LayerIterator layer_it)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (base_it.len () != layer_it.len ()))
+      return_trace (false);
+
+    if (unlikely (!c->extend_min (this))) return_trace (false);
+    this->version = version;
+    numLayers = 0;
+    numBaseGlyphs = base_it.len ();
+    baseGlyphsZ = COLR::min_size;
+    layersZ = COLR::min_size + numBaseGlyphs * BaseGlyphRecord::min_size;
+
+    for (const hb_item_type<BaseIterator>& _ : + base_it.iter ())
+    {
+      auto* record = c->embed (_);
+      if (unlikely (!record)) return_trace (false);
+      record->firstLayerIdx = numLayers;
+      numLayers += record->numLayers;
+    }
+
+    for (const hb_item_type<LayerIterator>& _ : + layer_it.iter ())
+      _.as_array ().copy (c);
+
+    return_trace (true);
+  }
+
+  const BaseGlyphRecord* get_base_glyph_record (hb_codepoint_t gid) const
+  {
+    if ((unsigned int) gid == 0) // Ignore notdef.
+      return nullptr;
+    const BaseGlyphRecord* record = &(this+baseGlyphsZ).bsearch (numBaseGlyphs, (unsigned int) gid);
+    if ((record && (hb_codepoint_t) record->glyphId != gid))
+      record = nullptr;
+    return record;
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+
+    const hb_map_t &reverse_glyph_map = *c->plan->reverse_glyph_map;
+
+    auto base_it =
+    + hb_range (c->plan->num_output_glyphs ())
+    | hb_map_retains_sorting ([&](hb_codepoint_t new_gid)
+			      {
+				hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
+
+				const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid);
+				if (unlikely (!old_record))
+				  return hb_pair_t<bool, BaseGlyphRecord> (false, Null (BaseGlyphRecord));
+
+				BaseGlyphRecord new_record;
+				new_record.glyphId = new_gid;
+				new_record.numLayers = old_record->numLayers;
+				return hb_pair_t<bool, BaseGlyphRecord> (true, new_record);
+			      })
+    | hb_filter (hb_first)
+    | hb_map_retains_sorting (hb_second)
+    ;
+
+    auto layer_it =
+    + hb_range (c->plan->num_output_glyphs ())
+    | hb_map (reverse_glyph_map)
+    | hb_map_retains_sorting ([&](hb_codepoint_t old_gid)
+			      {
+				const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid);
+				hb_vector_t<LayerRecord> out_layers;
+
+				if (unlikely (!old_record ||
+					      old_record->firstLayerIdx >= numLayers ||
+					      old_record->firstLayerIdx + old_record->numLayers > numLayers))
+				  return hb_pair_t<bool, hb_vector_t<LayerRecord>> (false, out_layers);
+
+				auto layers = (this+layersZ).as_array (numLayers).sub_array (old_record->firstLayerIdx,
+											     old_record->numLayers);
+				out_layers.resize (layers.length);
+				for (unsigned int i = 0; i < layers.length; i++) {
+				  out_layers[i] = layers[i];
+				  hb_codepoint_t new_gid = 0;
+				  if (unlikely (!c->plan->new_gid_for_old_gid (out_layers[i].glyphId, &new_gid)))
+				    return hb_pair_t<bool, hb_vector_t<LayerRecord>> (false, out_layers);
+				  out_layers[i].glyphId = new_gid;
+				}
+
+				return hb_pair_t<bool, hb_vector_t<LayerRecord>> (true, out_layers);
+			      })
+    | hb_filter (hb_first)
+    | hb_map_retains_sorting (hb_second)
+    ;
+
+    if (unlikely (!base_it || !layer_it || base_it.len () != layer_it.len ()))
+      return_trace (false);
+
+    COLR *colr_prime = c->serializer->start_embed<COLR> ();
+    return_trace (colr_prime->serialize (c->serializer, version, base_it, layer_it));
+  }
+
   protected:
   HBUINT16	version;	/* Table version number (starts at 0). */
   HBUINT16	numBaseGlyphs;	/* Number of Base Glyph Records. */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -155,7 +155,7 @@
   private:
   const CPALV1Tail& v1 () const
   {
-    if (version == 0) return Null(CPALV1Tail);
+    if (version == 0) return Null (CPALV1Tail);
     return StructAfter<CPALV1Tail> (*this);
   }
 

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	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2018  Ebrahim Byagowi
+ * Copyright © 2020  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -20,6 +21,8 @@
  * 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): Calder Kitagawa
  */
 
 #ifndef HB_OT_COLOR_SBIX_TABLE_HH
@@ -26,6 +29,7 @@
 #define HB_OT_COLOR_SBIX_TABLE_HH
 
 #include "hb-open-type.hh"
+#include "hb-ot-layout-common.hh"
 
 /*
  * sbix -- Standard Bitmap Graphics
@@ -40,6 +44,20 @@
 
 struct SBIXGlyph
 {
+  SBIXGlyph* copy (hb_serialize_context_t *c, unsigned int data_length) const
+  {
+    TRACE_SERIALIZE (this);
+    SBIXGlyph* new_glyph = c->start_embed<SBIXGlyph> ();
+    if (unlikely (!new_glyph)) return_trace (nullptr);
+    if (unlikely (!c->extend_min (new_glyph))) return_trace (nullptr);
+
+    new_glyph->xOffset = xOffset;
+    new_glyph->yOffset = yOffset;
+    new_glyph->graphicType = graphicType;
+    data.copy (c, data_length);
+    return_trace (new_glyph);
+  }
+
   HBINT16	xOffset;	/* The horizontal (x-axis) offset from the left
 				 * edge of the graphic to the glyph’s origin.
 				 * That is, the x-coordinate of the point on the
@@ -62,6 +80,9 @@
 
 struct SBIXStrike
 {
+  static unsigned int get_size (unsigned num_glyphs)
+  { return min_size + num_glyphs * HBUINT32::static_size; }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -116,6 +137,49 @@
     return hb_blob_create_sub_blob (sbix_blob, glyph_offset, glyph_length);
   }
 
+  bool subset (hb_subset_context_t *c, unsigned int available_len) const
+  {
+    TRACE_SUBSET (this);
+    unsigned int num_output_glyphs = c->plan->num_output_glyphs ();
+
+    auto* out = c->serializer->start_embed<SBIXStrike> ();
+    if (unlikely (!out)) return_trace (false);
+    auto snap = c->serializer->snapshot ();
+    if (unlikely (!c->serializer->extend (*out, num_output_glyphs + 1))) return_trace (false);
+    out->ppem = ppem;
+    out->resolution = resolution;
+    HBUINT32 head;
+    head = get_size (num_output_glyphs + 1);
+
+    bool has_glyphs = false;
+    for (unsigned new_gid = 0; new_gid < num_output_glyphs; new_gid++)
+    {
+      hb_codepoint_t old_gid;
+      if (!c->plan->old_gid_for_new_gid (new_gid, &old_gid) ||
+	  unlikely (imageOffsetsZ[old_gid].is_null () ||
+		    imageOffsetsZ[old_gid + 1].is_null () ||
+		    imageOffsetsZ[old_gid + 1] <= imageOffsetsZ[old_gid] ||
+		    imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid] <= SBIXGlyph::min_size) ||
+		    (unsigned int) imageOffsetsZ[old_gid + 1] > available_len)
+      {
+	out->imageOffsetsZ[new_gid] = head;
+	continue;
+      }
+      has_glyphs = true;
+      unsigned int delta = imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid];
+      unsigned int glyph_data_length = delta - SBIXGlyph::min_size;
+      if (!(this+imageOffsetsZ[old_gid]).copy (c->serializer, glyph_data_length))
+	return_trace (false);
+      out->imageOffsetsZ[new_gid] = head;
+      head += delta;
+    }
+    if (has_glyphs)
+      out->imageOffsetsZ[num_output_glyphs] = head;
+    else
+      c->serializer->revert (snap);
+    return_trace (has_glyphs);
+  }
+
   public:
   HBUINT16	ppem;		/* The PPEM size for which this strike was designed. */
   HBUINT16	resolution;	/* The device pixel density (in PPI) for which this
@@ -140,7 +204,7 @@
   {
     void init (hb_face_t *face)
     {
-      table = hb_sanitize_context_t().reference_table<sbix> (face);
+      table = hb_sanitize_context_t ().reference_table<sbix> (face);
       num_glyphs = face->get_num_glyphs ();
     }
     void fini () { table.destroy (); }
@@ -173,7 +237,7 @@
     {
       unsigned count = table->strikes.len;
       if (unlikely (!count))
-	return Null(SBIXStrike);
+	return Null (SBIXStrike);
 
       unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem);
       if (!requested_ppem)
@@ -237,7 +301,7 @@
       extents->x_bearing = x_offset;
       extents->y_bearing = png.IHDR.height + y_offset;
       extents->width     = png.IHDR.width;
-      extents->height    = -png.IHDR.height;
+      extents->height    = -1 * png.IHDR.height;
 
       /* Convert to font units. */
       if (strike_ppem)
@@ -275,6 +339,63 @@
 			  strikes.sanitize (c, this)));
   }
 
+  bool
+  add_strike (hb_subset_context_t *c, unsigned i) const
+  {
+    if (strikes[i].is_null () || c->source_blob->length < (unsigned) strikes[i])
+      return false;
+
+    return (this+strikes[i]).subset (c, c->source_blob->length - (unsigned) strikes[i]);
+  }
+
+  bool serialize_strike_offsets (hb_subset_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+
+    auto *out = c->serializer->start_embed<LOffsetLArrayOf<SBIXStrike>> ();
+    if (unlikely (!out)) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    hb_vector_t<LOffsetTo<SBIXStrike>*> new_strikes;
+    hb_vector_t<hb_serialize_context_t::objidx_t> objidxs;
+    for (int i = strikes.len - 1; i >= 0; --i)
+    {
+      auto* o = out->serialize_append (c->serializer);
+      if (unlikely (!o)) return_trace (false);
+      *o = 0;
+      auto snap = c->serializer->snapshot ();
+      c->serializer->push ();
+      bool ret = add_strike (c, i);
+      if (!ret)
+      {
+	c->serializer->pop_discard ();
+	out->pop ();
+	c->serializer->revert (snap);
+      }
+      else
+      {
+	objidxs.push (c->serializer->pop_pack ());
+	new_strikes.push (o);
+      }
+    }
+    for (unsigned int i = 0; i < new_strikes.length; ++i)
+      c->serializer->add_link (*new_strikes[i], objidxs[new_strikes.length - 1 - i]);
+
+    return_trace (true);
+  }
+
+  bool subset (hb_subset_context_t* c) const
+  {
+    TRACE_SUBSET (this);
+
+    sbix *sbix_prime = c->serializer->start_embed<sbix> ();
+    if (unlikely (!sbix_prime)) return_trace (false);
+    if (unlikely (!c->serializer->embed (this->version))) return_trace (false);
+    if (unlikely (!c->serializer->embed (this->flags))) return_trace (false);
+
+    return_trace (serialize_strike_offsets (c));
+  }
+
   protected:
   HBUINT16	version;	/* Table version number — set to 1 */
   HBUINT16	flags;		/* Bit 0: Set to 1. Bit 1: Draw outlines.

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	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -80,7 +80,7 @@
   struct accelerator_t
   {
     void init (hb_face_t *face)
-    { table = hb_sanitize_context_t().reference_table<SVG> (face); }
+    { table = hb_sanitize_context_t ().reference_table<SVG> (face); }
     void fini () { table.destroy (); }
 
     hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id) const

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -183,22 +183,21 @@
 			 void *user_data HB_UNUSED)
 {
   const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
-  bool ret = false;
 
 #if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
-  if (!ret) ret = ot_face->sbix->get_extents (font, glyph, extents);
+  if (ot_face->sbix->get_extents (font, glyph, extents)) return true;
 #endif
-  if (!ret) ret = ot_face->glyf->get_extents (font, glyph, extents);
+  if (ot_face->glyf->get_extents (font, glyph, extents)) return true;
 #ifndef HB_NO_OT_FONT_CFF
-  if (!ret) ret = ot_face->cff1->get_extents (font, glyph, extents);
-  if (!ret) ret = ot_face->cff2->get_extents (font, glyph, extents);
+  if (ot_face->cff1->get_extents (font, glyph, extents)) return true;
+  if (ot_face->cff2->get_extents (font, glyph, extents)) return true;
 #endif
 #if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
-  if (!ret) ret = ot_face->CBDT->get_extents (font, glyph, extents);
+  if (ot_face->CBDT->get_extents (font, glyph, extents)) return true;
 #endif
 
   // TODO Hook up side-bearings variations.
-  return ret;
+  return false;
 }
 
 #ifndef HB_NO_OT_FONT_GLYPH_NAMES
@@ -210,7 +209,11 @@
 		      void *user_data HB_UNUSED)
 {
   const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
-  return ot_face->post->get_glyph_name (glyph, name, size);
+  if (ot_face->post->get_glyph_name (glyph, name, size)) return true;
+#ifndef HB_NO_OT_FONT_CFF
+  if (ot_face->cff1->get_glyph_name (glyph, name, size)) return true;
+#endif
+  return false;
 }
 static hb_bool_t
 hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,
@@ -220,7 +223,11 @@
 			   void *user_data HB_UNUSED)
 {
   const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
-  return ot_face->post->get_glyph_from_name (name, len, glyph);
+  if (ot_face->post->get_glyph_from_name (name, len, glyph)) return true;
+#ifndef HB_NO_OT_FONT_CFF
+    if (ot_face->cff1->get_glyph_from_name (name, len, glyph)) return true;
+#endif
+  return false;
 }
 #endif
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-gasp-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-gasp-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-gasp-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -48,8 +48,8 @@
   }
 
   public:
-  HBUINT16 	rangeMaxPPEM;	/* Upper limit of range, in PPEM */
-  HBUINT16 	rangeGaspBehavior;
+  HBUINT16	rangeMaxPPEM;	/* Upper limit of range, in PPEM */
+  HBUINT16	rangeGaspBehavior;
 				/* Flags describing desired rasterizer behavior. */
   public:
   DEFINE_SIZE_STATIC (4);

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	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -34,9 +34,8 @@
 #include "hb-ot-head-table.hh"
 #include "hb-ot-hmtx-table.hh"
 #include "hb-ot-var-gvar-table.hh"
+#include "hb-draw.hh"
 
-#include <float.h>
-
 namespace OT {
 
 
@@ -148,7 +147,19 @@
 		  const hb_subset_plan_t *plan)
   {
     TRACE_SERIALIZE (this);
+    unsigned init_len = c->length ();
     for (const auto &_ : it) _.serialize (c, plan);
+
+    /* As a special case when all glyph in the font are empty, add a zero byte
+     * to the table, so that OTS doesn’t reject it, and to make the table work
+     * on Windows as well.
+     * See https://github.com/khaledhosny/ots/issues/52 */
+    if (init_len == c->length ())
+    {
+      HBUINT8 empty_byte;
+      empty_byte = 0;
+      c->copy (empty_byte);
+    }
     return_trace (true);
   }
 
@@ -229,18 +240,18 @@
   {
     enum composite_glyph_flag_t
     {
-      ARG_1_AND_2_ARE_WORDS =      0x0001,
-      ARGS_ARE_XY_VALUES =         0x0002,
-      ROUND_XY_TO_GRID =           0x0004,
-      WE_HAVE_A_SCALE =            0x0008,
-      MORE_COMPONENTS =            0x0020,
-      WE_HAVE_AN_X_AND_Y_SCALE =   0x0040,
-      WE_HAVE_A_TWO_BY_TWO =       0x0080,
-      WE_HAVE_INSTRUCTIONS =       0x0100,
-      USE_MY_METRICS =             0x0200,
-      OVERLAP_COMPOUND =           0x0400,
-      SCALED_COMPONENT_OFFSET =    0x0800,
-      UNSCALED_COMPONENT_OFFSET =  0x1000
+      ARG_1_AND_2_ARE_WORDS	= 0x0001,
+      ARGS_ARE_XY_VALUES	= 0x0002,
+      ROUND_XY_TO_GRID		= 0x0004,
+      WE_HAVE_A_SCALE		= 0x0008,
+      MORE_COMPONENTS		= 0x0020,
+      WE_HAVE_AN_X_AND_Y_SCALE	= 0x0040,
+      WE_HAVE_A_TWO_BY_TWO	= 0x0080,
+      WE_HAVE_INSTRUCTIONS	= 0x0100,
+      USE_MY_METRICS		= 0x0200,
+      OVERLAP_COMPOUND		= 0x0400,
+      SCALED_COMPONENT_OFFSET	= 0x0800,
+      UNSCALED_COMPONENT_OFFSET = 0x1000
     };
 
     unsigned int get_size () const
@@ -361,7 +372,7 @@
     typedef const CompositeGlyphChain *__item_t__;
     composite_iter_t (hb_bytes_t glyph_, __item_t__ current_) :
       glyph (glyph_), current (current_)
-    { if (!in_range (current)) current = nullptr; }
+    { if (!check_range (current)) current = nullptr; }
     composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr) {}
 
     const CompositeGlyphChain &__item__ () const { return *current; }
@@ -372,16 +383,16 @@
 
       const CompositeGlyphChain *possible = &StructAfter<CompositeGlyphChain,
 							 CompositeGlyphChain> (*current);
-      if (!in_range (possible)) { current = nullptr; return; }
+      if (!check_range (possible)) { current = nullptr; return; }
       current = possible;
     }
     bool operator != (const composite_iter_t& o) const
     { return glyph != o.glyph || current != o.current; }
 
-    bool in_range (const CompositeGlyphChain *composite) const
+    bool check_range (const CompositeGlyphChain *composite) const
     {
-      return glyph.in_range (composite, CompositeGlyphChain::min_size)
-	  && glyph.in_range (composite, composite->get_size ());
+      return glyph.check_range (composite, CompositeGlyphChain::min_size)
+	  && glyph.check_range (composite, composite->get_size ());
     }
 
     private:
@@ -389,8 +400,29 @@
     __item_t__ current;
   };
 
+  enum phantom_point_index_t
+  {
+    PHANTOM_LEFT   = 0,
+    PHANTOM_RIGHT  = 1,
+    PHANTOM_TOP    = 2,
+    PHANTOM_BOTTOM = 3,
+    PHANTOM_COUNT  = 4
+  };
+
   struct Glyph
   {
+    enum simple_glyph_flag_t
+    {
+      FLAG_ON_CURVE  = 0x01,
+      FLAG_X_SHORT   = 0x02,
+      FLAG_Y_SHORT   = 0x04,
+      FLAG_REPEAT    = 0x08,
+      FLAG_X_SAME    = 0x10,
+      FLAG_Y_SAME    = 0x20,
+      FLAG_RESERVED1 = 0x40,
+      FLAG_RESERVED2 = 0x80
+    };
+
     private:
     struct GlyphHeader
     {
@@ -445,18 +477,6 @@
 	return instructionLength;
       }
 
-      enum simple_glyph_flag_t
-      {
-	FLAG_ON_CURVE  = 0x01,
-	FLAG_X_SHORT   = 0x02,
-	FLAG_Y_SHORT   = 0x04,
-	FLAG_REPEAT    = 0x08,
-	FLAG_X_SAME    = 0x10,
-	FLAG_Y_SAME    = 0x20,
-	FLAG_RESERVED1 = 0x40,
-	FLAG_RESERVED2 = 0x80
-      };
-
       const Glyph trim_padding () const
       {
 	/* based on FontTools _g_l_y_f.py::trim */
@@ -470,7 +490,6 @@
 	unsigned int num_instructions = StructAtOffset<HBUINT16> (glyph, 0);
 
 	glyph += 2 + num_instructions;
-	if (unlikely (glyph + 2 >= glyph_end)) return Glyph ();
 
 	unsigned int coord_bytes = 0;
 	unsigned int coords_with_flags = 0;
@@ -519,34 +538,21 @@
 	dest_end = bytes.sub_array (glyph_length, bytes.length - glyph_length);
       }
 
-      struct x_setter_t
-      {
-	void set (contour_point_t &point, float v) const { point.x = v; }
-	bool is_short (uint8_t flag) const { return flag & FLAG_X_SHORT; }
-	bool is_same  (uint8_t flag) const { return flag & FLAG_X_SAME; }
-      };
-
-      struct y_setter_t
-      {
-	void set (contour_point_t &point, float v) const { point.y = v; }
-	bool is_short (uint8_t flag) const { return flag & FLAG_Y_SHORT; }
-	bool is_same  (uint8_t flag) const { return flag & FLAG_Y_SAME; }
-      };
-
-      template <typename T>
       static bool read_points (const HBUINT8 *&p /* IN/OUT */,
 			       contour_point_vector_t &points_ /* IN/OUT */,
-			       const hb_bytes_t &bytes)
+			       const hb_bytes_t &bytes,
+			       void (* setter) (contour_point_t &_, float v),
+			       const simple_glyph_flag_t short_flag,
+			       const simple_glyph_flag_t same_flag)
       {
-	T coord_setter;
 	float v = 0;
-	for (unsigned int i = 0; i < points_.length - PHANTOM_COUNT; i++)
+	for (unsigned i = 0; i < points_.length; i++)
 	{
 	  uint8_t flag = points_[i].flag;
-	  if (coord_setter.is_short (flag))
+	  if (flag & short_flag)
 	  {
-	    if (unlikely (!bytes.in_range (p))) return false;
-	    if (coord_setter.is_same (flag))
+	    if (unlikely (!bytes.check_range (p))) return false;
+	    if (flag & same_flag)
 	      v += *p++;
 	    else
 	      v -= *p++;
@@ -553,36 +559,32 @@
 	  }
 	  else
 	  {
-	    if (!coord_setter.is_same (flag))
+	    if (!(flag & same_flag))
 	    {
-	      if (unlikely (!bytes.in_range ((const HBUINT16 *) p))) return false;
+	      if (unlikely (!bytes.check_range ((const HBUINT16 *) p))) return false;
 	      v += *(const HBINT16 *) p;
 	      p += HBINT16::static_size;
 	    }
 	  }
-	  coord_setter.set (points_[i], v);
+	  setter (points_[i], v);
 	}
 	return true;
       }
 
       bool get_contour_points (contour_point_vector_t &points_ /* OUT */,
-			       hb_vector_t<unsigned int> &end_points_ /* OUT */,
-			       const bool phantom_only=false) const
+			       bool phantom_only = false) const
       {
 	const HBUINT16 *endPtsOfContours = &StructAfter<HBUINT16> (header);
 	int num_contours = header.numberOfContours;
-	if (unlikely (!bytes.in_range (&endPtsOfContours[num_contours + 1]))) return false;
+	if (unlikely (!bytes.check_range (&endPtsOfContours[num_contours + 1]))) return false;
 	unsigned int num_points = endPtsOfContours[num_contours - 1] + 1;
 
-	points_.resize (num_points + PHANTOM_COUNT);
+	points_.resize (num_points);
 	for (unsigned int i = 0; i < points_.length; i++) points_[i].init ();
 	if (phantom_only) return true;
 
-	/* Read simple glyph points if !phantom_only */
-	end_points_.resize (num_contours);
-
 	for (int i = 0; i < num_contours; i++)
-	  end_points_[i] = endPtsOfContours[i];
+	  points_[endPtsOfContours[i]].is_end_point = true;
 
 	/* Skip instructions */
 	const HBUINT8 *p = &StructAtOffset<HBUINT8> (&endPtsOfContours[num_contours + 1],
@@ -591,12 +593,12 @@
 	/* Read flags */
 	for (unsigned int i = 0; i < num_points; i++)
 	{
-	  if (unlikely (!bytes.in_range (p))) return false;
+	  if (unlikely (!bytes.check_range (p))) return false;
 	  uint8_t flag = *p++;
 	  points_[i].flag = flag;
 	  if (flag & FLAG_REPEAT)
 	  {
-	    if (unlikely (!bytes.in_range (p))) return false;
+	    if (unlikely (!bytes.check_range (p))) return false;
 	    unsigned int repeat_count = *p++;
 	    while ((repeat_count-- > 0) && (++i < num_points))
 	      points_[i].flag = flag;
@@ -604,8 +606,10 @@
 	}
 
 	/* Read x & y coordinates */
-	return (read_points<x_setter_t> (p, points_, bytes) &&
-		read_points<y_setter_t> (p, points_, bytes));
+	return (read_points (p, points_, bytes,
+			     [] (contour_point_t &p, float v) { p.x = v; }, FLAG_X_SHORT, FLAG_X_SAME) &&
+		read_points (p, points_, bytes,
+			     [] (contour_point_t &p, float v) { p.y = v; }, FLAG_Y_SHORT, FLAG_Y_SAME));
       }
     };
 
@@ -648,30 +652,10 @@
       /* Chop instructions off the end */
       void drop_hints_bytes (hb_bytes_t &dest_start) const
       { dest_start = bytes.sub_array (0, bytes.length - instructions_length (bytes)); }
-
-      bool get_contour_points (contour_point_vector_t &points_ /* OUT */,
-			       hb_vector_t<unsigned int> &end_points_ /* OUT */,
-			       const bool phantom_only=false) const
-      {
-	/* add one pseudo point for each component in composite glyph */
-	unsigned int num_points = hb_len (get_iterator ());
-	points_.resize (num_points + PHANTOM_COUNT);
-	for (unsigned int i = 0; i < points_.length; i++) points_[i].init ();
-	return true;
-      }
     };
 
     enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE };
 
-    enum phantom_point_index_t
-    {
-      PHANTOM_LEFT   = 0,
-      PHANTOM_RIGHT  = 1,
-      PHANTOM_TOP    = 2,
-      PHANTOM_BOTTOM = 3,
-      PHANTOM_COUNT  = 4
-    };
-
     public:
     composite_iter_t get_composite_iterator () const
     {
@@ -706,39 +690,130 @@
       }
     }
 
-    /* for a simple glyph, return contour end points, flags, along with coordinate points
-     * for a composite glyph, return pseudo component points
-     * in both cases points trailed with four phantom points
+    /* Note: Recursively calls itself.
+     * all_points includes phantom points
      */
-    bool get_contour_points (contour_point_vector_t &points_ /* OUT */,
-			     hb_vector_t<unsigned int> &end_points_ /* OUT */,
-			     const bool phantom_only=false) const
+    template<typename T>
+    bool get_points (T glyph_for_gid, hb_font_t *font,
+		     contour_point_vector_t &all_points /* OUT */,
+		     bool phantom_only = false,
+		     unsigned int depth = 0) const
     {
+      if (unlikely (depth > HB_MAX_NESTING_LEVEL)) return false;
+      contour_point_vector_t points;
+
       switch (type) {
-      case COMPOSITE: return CompositeGlyph (*header, bytes).get_contour_points (points_, end_points_, phantom_only);
-      case SIMPLE:    return SimpleGlyph (*header, bytes).get_contour_points (points_, end_points_, phantom_only);
-      default:
-	/* empty glyph */
-	points_.resize (PHANTOM_COUNT);
-	for (unsigned int i = 0; i < points_.length; i++) points_[i].init ();
-	return true;
+      case COMPOSITE:
+      {
+	/* pseudo component points for each component in composite glyph */
+	unsigned num_points = hb_len (CompositeGlyph (*header, bytes).get_iterator ());
+	if (unlikely (!points.resize (num_points))) return false;
+	for (unsigned i = 0; i < points.length; i++)
+	  points[i].init ();
+	break;
       }
+      case SIMPLE:
+	if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only)))
+	  return false;
+	break;
+      default: return false; /* empty glyph */
+      }
+
+      hb_face_t *face = font->face;
+
+      /* Init phantom points */
+      if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false;
+      hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
+      {
+	for (unsigned i = 0; i < PHANTOM_COUNT; ++i) phantoms[i].init ();
+	int h_delta = (int) header->xMin - face->table.hmtx->get_side_bearing (gid);
+	int v_orig  = (int) header->yMax + face->table.vmtx->get_side_bearing (gid);
+	unsigned h_adv = face->table.hmtx->get_advance (gid);
+	unsigned v_adv = face->table.vmtx->get_advance (gid);
+	phantoms[PHANTOM_LEFT].x = h_delta;
+	phantoms[PHANTOM_RIGHT].x = h_adv + h_delta;
+	phantoms[PHANTOM_TOP].y = v_orig;
+	phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv;
+      }
+
+#ifndef HB_NO_VAR
+      if (unlikely (!face->table.gvar->apply_deltas_to_points (gid, font, points.as_array ())))
+	return false;
+#endif
+
+      switch (type) {
+      case SIMPLE:
+	all_points.extend (points.as_array ());
+	break;
+      case COMPOSITE:
+      {
+	unsigned int comp_index = 0;
+	for (auto &item : get_composite_iterator ())
+	{
+	  contour_point_vector_t comp_points;
+	  if (unlikely (!glyph_for_gid (item.glyphIndex).get_points (glyph_for_gid, font, comp_points, phantom_only, depth + 1))
+			|| comp_points.length < PHANTOM_COUNT)
+	    return false;
+
+	  /* Copy phantom points from component if USE_MY_METRICS flag set */
+	  if (item.is_use_my_metrics ())
+	    for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
+	      phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
+
+	  /* Apply component transformation & translation */
+	  item.transform_points (comp_points);
+
+	  /* Apply translation from gvar */
+	  comp_points.translate (points[comp_index]);
+
+	  if (item.is_anchored ())
+	  {
+	    unsigned int p1, p2;
+	    item.get_anchor_points (p1, p2);
+	    if (likely (p1 < all_points.length && p2 < comp_points.length))
+	    {
+	      contour_point_t delta;
+	      delta.init (all_points[p1].x - comp_points[p2].x,
+			  all_points[p1].y - comp_points[p2].y);
+
+	      comp_points.translate (delta);
+	    }
+	  }
+
+	  all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT));
+
+	  comp_index++;
+	}
+
+	all_points.extend (phantoms);
+      } break;
+      default: return false;
+      }
+
+      if (depth == 0) /* Apply at top level */
+      {
+	/* Undocumented rasterizer behavior:
+	 * Shift points horizontally by the updated left side bearing
+	 */
+	contour_point_t delta;
+	delta.init (-phantoms[PHANTOM_LEFT].x, 0.f);
+	if (delta.x) all_points.translate (delta);
+      }
+
+      return true;
     }
 
-    bool is_simple_glyph ()    const { return type == SIMPLE; }
-    bool is_composite_glyph () const { return type == COMPOSITE; }
-
-    bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const
+    bool get_extents (hb_font_t *font, hb_glyph_extents_t *extents) const
     {
       if (type == EMPTY) return true; /* Empty glyph; zero extents. */
       return header->get_extents (font, gid, extents);
     }
 
-    hb_bytes_t get_bytes ()          const { return bytes; }
-    const GlyphHeader &get_header () const { return *header; }
+    hb_bytes_t get_bytes () const { return bytes; }
 
-    Glyph (hb_bytes_t bytes_ = hb_bytes_t ()) :
-      bytes (bytes_), header (bytes.as<GlyphHeader> ())
+    Glyph (hb_bytes_t bytes_ = hb_bytes_t (),
+	   hb_codepoint_t gid_ = (hb_codepoint_t) -1) : bytes (bytes_), gid (gid_),
+							header (bytes.as<GlyphHeader> ())
     {
       int num_contours = header->numberOfContours;
       if (unlikely (num_contours == 0)) type = EMPTY;
@@ -748,6 +823,7 @@
 
     protected:
     hb_bytes_t bytes;
+    hb_codepoint_t gid;
     const GlyphHeader *header;
     unsigned type;
   };
@@ -771,6 +847,7 @@
       glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face);
 
       num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
+      num_glyphs = hb_min (num_glyphs, face->get_num_glyphs ());
     }
 
     void fini ()
@@ -779,223 +856,137 @@
       glyf_table.destroy ();
     }
 
-    enum phantom_point_index_t
-    {
-      PHANTOM_LEFT   = 0,
-      PHANTOM_RIGHT  = 1,
-      PHANTOM_TOP    = 2,
-      PHANTOM_BOTTOM = 3,
-      PHANTOM_COUNT  = 4
-    };
-
     protected:
-
-    void init_phantom_points (hb_codepoint_t gid, hb_array_t<contour_point_t> &phantoms /* IN/OUT */) const
+    template<typename T>
+    bool get_points (hb_font_t *font, hb_codepoint_t gid, T consumer) const
     {
-      const Glyph &glyph = glyph_for_gid (gid);
-      int h_delta = (int) glyph.get_header ().xMin - face->table.hmtx->get_side_bearing (gid);
-      int v_orig  = (int) glyph.get_header ().yMax + face->table.vmtx->get_side_bearing (gid);
-      unsigned int h_adv = face->table.hmtx->get_advance (gid);
-      unsigned int v_adv = face->table.vmtx->get_advance (gid);
+      /* Making this alloc free is not that easy
+	 https://github.com/harfbuzz/harfbuzz/issues/2095
+	 mostly because of gvar handling in VF fonts,
+	 perhaps a separate path for non-VF fonts can be considered */
+      contour_point_vector_t all_points;
 
-      phantoms[PHANTOM_LEFT].x = h_delta;
-      phantoms[PHANTOM_RIGHT].x = h_adv + h_delta;
-      phantoms[PHANTOM_TOP].y = v_orig;
-      phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv;
-    }
+      bool phantom_only = !consumer.is_consuming_contour_points ();
+      if (unlikely (!glyph_for_gid (gid).get_points ([this] (hb_codepoint_t gid) -> const Glyph { return this->glyph_for_gid (gid); },
+						     font, all_points, phantom_only)))
+	return false;
 
-    struct contour_bounds_t
-    {
-      contour_bounds_t () { min_x = min_y = FLT_MAX; max_x = max_y = -FLT_MAX; }
-
-      void add (const contour_point_t &p)
+      if (consumer.is_consuming_contour_points ())
       {
-	min_x = hb_min (min_x, p.x);
-	min_y = hb_min (min_y, p.y);
-	max_x = hb_max (max_x, p.x);
-	max_y = hb_max (max_y, p.y);
+	for (unsigned point_index = 0; point_index + 4 < all_points.length; ++point_index)
+	  consumer.consume_point (all_points[point_index]);
+	consumer.points_end ();
       }
 
-      bool empty () const { return (min_x >= max_x) || (min_y >= max_y); }
+      /* Where to write phantoms, nullptr if not requested */
+      contour_point_t *phantoms = consumer.get_phantoms_sink ();
+      if (phantoms)
+	for (unsigned i = 0; i < PHANTOM_COUNT; ++i)
+	  phantoms[i] = all_points[all_points.length - PHANTOM_COUNT + i];
 
-      void get_extents (hb_font_t *font, hb_glyph_extents_t *extents)
-      {
-	if (unlikely (empty ()))
-	{
-	  extents->width = 0;
-	  extents->x_bearing = 0;
-	  extents->height = 0;
-	  extents->y_bearing = 0;
-	  return;
-	}
-	extents->x_bearing = font->em_scalef_x (min_x);
-	extents->width = font->em_scalef_x (max_x - min_x);
-	extents->y_bearing = font->em_scalef_y (max_y);
-	extents->height = font->em_scalef_y (min_y - max_y);
-      }
+      return true;
+    }
 
-      protected:
-      float min_x, min_y, max_x, max_y;
-    };
-
+    public:
 #ifndef HB_NO_VAR
-    /* Note: Recursively calls itself.
-     * all_points includes phantom points
-     */
-    bool get_points_var (hb_codepoint_t gid,
-			 const int *coords, unsigned int coord_count,
-			 contour_point_vector_t &all_points /* OUT */,
-			 unsigned int depth = 0) const
+    struct points_aggregator_t
     {
-      if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return false;
-      contour_point_vector_t points;
-      hb_vector_t<unsigned int> end_points;
-      const Glyph &glyph = glyph_for_gid (gid);
-      if (unlikely (!glyph.get_contour_points (points, end_points))) return false;
-      hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
-      init_phantom_points (gid, phantoms);
-      if (unlikely (!face->table.gvar->apply_deltas_to_points (gid, coords, coord_count, points.as_array (), end_points.as_array ()))) return false;
+      hb_font_t *font;
+      hb_glyph_extents_t *extents;
+      contour_point_t *phantoms;
 
-      unsigned int comp_index = 0;
-      if (glyph.is_simple_glyph ())
-	all_points.extend (points.as_array ());
-      else if (glyph.is_composite_glyph ())
+      struct contour_bounds_t
       {
-	for (auto &item : glyph.get_composite_iterator ())
+	contour_bounds_t () { min_x = min_y = FLT_MAX; max_x = max_y = -FLT_MAX; }
+
+	void add (const contour_point_t &p)
 	{
-	  contour_point_vector_t comp_points;
-	  if (unlikely (!get_points_var (item.glyphIndex, coords, coord_count,
-					 comp_points, depth))
-			|| comp_points.length < PHANTOM_COUNT)
-	    return false;
+	  min_x = hb_min (min_x, p.x);
+	  min_y = hb_min (min_y, p.y);
+	  max_x = hb_max (max_x, p.x);
+	  max_y = hb_max (max_y, p.y);
+	}
 
-	  /* Copy phantom points from component if USE_MY_METRICS flag set */
-	  if (item.is_use_my_metrics ())
-	    for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
-	      phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
+	bool empty () const { return (min_x >= max_x) || (min_y >= max_y); }
 
-	  /* Apply component transformation & translation */
-	  item.transform_points (comp_points);
-
-	  /* Apply translatation from gvar */
-	  comp_points.translate (points[comp_index]);
-
-	  if (item.is_anchored ())
+	void get_extents (hb_font_t *font, hb_glyph_extents_t *extents)
+	{
+	  if (unlikely (empty ()))
 	  {
-	    unsigned int p1, p2;
-	    item.get_anchor_points (p1, p2);
-	    if (likely (p1 < all_points.length && p2 < comp_points.length))
-	    {
-	      contour_point_t delta;
-	      delta.init (all_points[p1].x - comp_points[p2].x,
-			  all_points[p1].y - comp_points[p2].y);
-
-	      comp_points.translate (delta);
-	    }
+	    extents->width = 0;
+	    extents->x_bearing = 0;
+	    extents->height = 0;
+	    extents->y_bearing = 0;
+	    return;
 	  }
-
-	  all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT));
-
-	  comp_index++;
+	  extents->x_bearing = font->em_scalef_x (min_x);
+	  extents->width = font->em_scalef_x (max_x - min_x);
+	  extents->y_bearing = font->em_scalef_y (max_y);
+	  extents->height = font->em_scalef_y (min_y - max_y);
 	}
 
-	all_points.extend (phantoms);
-      }
-      else return false;
+	protected:
+	float min_x, min_y, max_x, max_y;
+      } bounds;
 
-      return true;
-    }
-
-    bool get_points_bearing_applied (hb_font_t *font, hb_codepoint_t gid, contour_point_vector_t &all_points) const
-    {
-      if (unlikely (!get_points_var (gid, font->coords, font->num_coords, all_points) ||
-		    all_points.length < PHANTOM_COUNT)) return false;
-
-      /* Undocumented rasterizer behavior:
-       * Shift points horizontally by the updated left side bearing
-       */
-      contour_point_t delta;
-      delta.init (-all_points[all_points.length - PHANTOM_COUNT + PHANTOM_LEFT].x, 0.f);
-      if (delta.x) all_points.translate (delta);
-      return true;
-    }
-
-    protected:
-
-    bool get_var_extents_and_phantoms (hb_font_t *font, hb_codepoint_t gid,
-				       hb_glyph_extents_t *extents=nullptr /* OUT */,
-				       contour_point_vector_t *phantoms=nullptr /* OUT */) const
-    {
-      contour_point_vector_t all_points;
-      if (!unlikely (get_points_bearing_applied (font, gid, all_points))) return false;
-      if (extents)
+      points_aggregator_t (hb_font_t *font_, hb_glyph_extents_t *extents_, contour_point_t *phantoms_)
       {
-	contour_bounds_t bounds;
-	for (unsigned int i = 0; i + PHANTOM_COUNT < all_points.length; i++)
-	  bounds.add (all_points[i]);
-	bounds.get_extents (font, extents);
+	font = font_;
+	extents = extents_;
+	phantoms = phantoms_;
+	if (extents) bounds = contour_bounds_t ();
       }
-      if (phantoms)
-	for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
-	  (*phantoms)[i] = all_points[all_points.length - PHANTOM_COUNT + i];
-      return true;
-    }
 
-    bool get_var_metrics (hb_font_t *font, hb_codepoint_t gid,
-			  contour_point_vector_t &phantoms) const
-    { return get_var_extents_and_phantoms (font, gid, nullptr, &phantoms); }
+      void consume_point (const contour_point_t &point) { bounds.add (point); }
+      void points_end () { bounds.get_extents (font, extents); }
 
-    bool get_extents_var (hb_font_t *font, hb_codepoint_t gid,
-			  hb_glyph_extents_t *extents) const
-    { return get_var_extents_and_phantoms (font, gid, extents); }
-#endif
+      bool is_consuming_contour_points () { return extents; }
+      contour_point_t *get_phantoms_sink () { return phantoms; }
+    };
 
-    public:
-#ifndef HB_NO_VAR
-    unsigned int get_advance_var (hb_font_t *font, hb_codepoint_t gid,
-				  bool is_vertical) const
+    unsigned int
+    get_advance_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const
     {
       bool success = false;
-      contour_point_vector_t phantoms;
-      phantoms.resize (PHANTOM_COUNT);
 
+      contour_point_t phantoms[PHANTOM_COUNT];
       if (likely (font->num_coords == face->table.gvar->get_axis_count ()))
-	success = get_var_metrics (font, gid, phantoms);
+	success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms));
 
       if (unlikely (!success))
-	return is_vertical ? face->table.vmtx->get_advance (gid) : face->table.hmtx->get_advance (gid);
+	return is_vertical
+	     ? face->table.vmtx->get_advance (gid)
+	     : face->table.hmtx->get_advance (gid);
 
-      if (is_vertical)
-	return roundf (phantoms[PHANTOM_TOP].y - phantoms[PHANTOM_BOTTOM].y);
-      else
-	return roundf (phantoms[PHANTOM_RIGHT].x - phantoms[PHANTOM_LEFT].x);
+      return is_vertical
+	   ? roundf (phantoms[PHANTOM_TOP].y - phantoms[PHANTOM_BOTTOM].y)
+	   : roundf (phantoms[PHANTOM_RIGHT].x - phantoms[PHANTOM_LEFT].x);
     }
 
     int get_side_bearing_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const
     {
       hb_glyph_extents_t extents;
-      contour_point_vector_t phantoms;
-      phantoms.resize (PHANTOM_COUNT);
 
-      if (unlikely (!get_var_extents_and_phantoms (font, gid, &extents, &phantoms)))
-	return is_vertical ? face->table.vmtx->get_side_bearing (gid) : face->table.hmtx->get_side_bearing (gid);
+      contour_point_t phantoms[PHANTOM_COUNT];
+      if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms))))
+	return is_vertical
+	     ? face->table.vmtx->get_side_bearing (gid)
+	     : face->table.hmtx->get_side_bearing (gid);
 
-      return is_vertical ? ceil (phantoms[PHANTOM_TOP].y) - extents.y_bearing : floor (phantoms[PHANTOM_LEFT].x);
+      return is_vertical
+	   ? ceilf (phantoms[PHANTOM_TOP].y) - extents.y_bearing
+	   : floorf (phantoms[PHANTOM_LEFT].x);
     }
 #endif
 
     bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const
     {
+      if (unlikely (gid >= num_glyphs)) return false;
 #ifndef HB_NO_VAR
-      unsigned int coord_count;
-      const int *coords = hb_font_get_var_coords_normalized (font, &coord_count);
-      if (coords && coord_count > 0 && coord_count == face->table.gvar->get_axis_count ())
-	return get_extents_var (font, gid, extents);
+      if (font->num_coords && font->num_coords == face->table.gvar->get_axis_count ())
+	return get_points (font, gid, points_aggregator_t (font, extents, nullptr));
 #endif
-
-      if (unlikely (gid >= num_glyphs)) return false;
-
-      return glyph_for_gid (gid).get_extents (font, gid, extents);
+      return glyph_for_gid (gid).get_extents (font, extents);
     }
 
     const Glyph
@@ -1021,7 +1012,7 @@
 	return Glyph ();
 
       Glyph glyph (hb_bytes_t ((const char *) this->glyf_table + start_offset,
-			       end_offset - start_offset));
+			       end_offset - start_offset), gid);
       return needs_padding_removal ? glyph.trim_padding () : glyph;
     }
 
@@ -1036,9 +1027,130 @@
       gids_to_retain->add (gid);
 
       for (auto &item : glyph_for_gid (gid).get_composite_iterator ())
-        add_gid_and_children (item.glyphIndex, gids_to_retain, depth);
+	add_gid_and_children (item.glyphIndex, gids_to_retain, depth);
     }
 
+#ifdef HB_EXPERIMENTAL_API
+    struct path_builder_t
+    {
+      hb_font_t *font;
+      draw_helper_t *draw_helper;
+
+      struct optional_point_t
+      {
+	optional_point_t () { has_data = false; }
+	optional_point_t (float x_, float y_) { x = x_; y = y_; has_data = true; }
+
+	bool has_data;
+	float x;
+	float y;
+
+	optional_point_t lerp (optional_point_t p, float t)
+	{ return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); }
+      } first_oncurve, first_offcurve, last_offcurve;
+
+      path_builder_t (hb_font_t *font_, draw_helper_t &draw_helper_)
+      {
+	font = font_;
+	draw_helper = &draw_helper_;
+	first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
+      }
+
+      /* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287
+	 See also:
+	 * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html
+	 * https://stackoverflow.com/a/20772557 */
+      void consume_point (const contour_point_t &point)
+      {
+	/* Skip empty contours */
+	if (unlikely (point.is_end_point && !first_oncurve.has_data && !first_offcurve.has_data))
+	  return;
+
+	bool is_on_curve = point.flag & Glyph::FLAG_ON_CURVE;
+	optional_point_t p (point.x, point.y);
+	if (!first_oncurve.has_data)
+	{
+	  if (is_on_curve)
+	  {
+	    first_oncurve = p;
+	    draw_helper->move_to (font->em_scalef_x (p.x), font->em_scalef_y (p.y));
+	  }
+	  else
+	  {
+	    if (first_offcurve.has_data)
+	    {
+	      optional_point_t mid = first_offcurve.lerp (p, .5f);
+	      first_oncurve = mid;
+	      last_offcurve = p;
+	      draw_helper->move_to (font->em_scalef_x (mid.x), font->em_scalef_y (mid.y));
+	    }
+	    else
+	      first_offcurve = p;
+	  }
+	}
+	else
+	{
+	  if (last_offcurve.has_data)
+	  {
+	    if (is_on_curve)
+	    {
+	      draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
+					 font->em_scalef_x (p.x), font->em_scalef_y (p.y));
+	      last_offcurve = optional_point_t ();
+	    }
+	    else
+	    {
+	      optional_point_t mid = last_offcurve.lerp (p, .5f);
+	      draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
+					 font->em_scalef_x (mid.x), font->em_scalef_y (mid.y));
+	      last_offcurve = p;
+	    }
+	  }
+	  else
+	  {
+	    if (is_on_curve)
+	      draw_helper->line_to (font->em_scalef_x (p.x), font->em_scalef_y (p.y));
+	    else
+	      last_offcurve = p;
+	  }
+	}
+
+	if (point.is_end_point)
+	{
+	  if (first_offcurve.has_data && last_offcurve.has_data)
+	  {
+	    optional_point_t mid = last_offcurve.lerp (first_offcurve, .5f);
+	    draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
+				       font->em_scalef_x (mid.x), font->em_scalef_y (mid.y));
+	    last_offcurve = optional_point_t ();
+	    /* now check the rest */
+	  }
+
+	  if (first_offcurve.has_data && first_oncurve.has_data)
+	    draw_helper->quadratic_to (font->em_scalef_x (first_offcurve.x), font->em_scalef_y (first_offcurve.y),
+				       font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y));
+	  else if (last_offcurve.has_data && first_oncurve.has_data)
+	    draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
+				       font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y));
+	  else if (first_oncurve.has_data)
+	    draw_helper->line_to (font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y));
+
+	  /* Getting ready for the next contour */
+	  first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
+	  draw_helper->end_path ();
+	}
+      }
+      void points_end () {}
+
+      bool is_consuming_contour_points () { return true; }
+      contour_point_t *get_phantoms_sink () { return nullptr; }
+    };
+
+    bool
+    get_path (hb_font_t *font, hb_codepoint_t gid, draw_helper_t &draw_helper) const
+    { return get_points (font, gid, path_builder_t (font, draw_helper)); }
+#endif
+
     private:
     bool short_offset;
     unsigned int num_glyphs;
@@ -1073,7 +1185,7 @@
 	pad_length--;
       }
 
-      if (!unlikely (dest_glyph.length)) return_trace (true);
+      if (unlikely (!dest_glyph.length)) return_trace (true);
 
       /* update components gids */
       for (auto &_ : Glyph (dest_glyph).get_composite_iterator ())

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -107,11 +107,8 @@
     this->numRecords = it.len ();
     this->sizeDeviceRecord = DeviceRecord::get_size (it ? (*it).second.len () : 0);
 
-    + it
-    | hb_apply ([c] (const hb_item_type<Iterator>& _) {
-		  c->start_embed<DeviceRecord> ()->serialize (c, _.first, _.second);
-		})
-    ;
+    for (const hb_item_type<Iterator>& _ : +it)
+      c->start_embed<DeviceRecord> ()->serialize (c, _.first, _.second);
 
     return_trace (c->successful);
   }
@@ -134,10 +131,10 @@
 	  auto row =
 	    + hb_range (c->plan->num_output_glyphs ())
 	    | hb_map (c->plan->reverse_glyph_map)
-	    | hb_map ([=] (hb_codepoint_t _)
+	    | hb_map ([this, c, device_record] (hb_codepoint_t _)
 		      {
 			if (c->plan->is_empty_glyph (_))
-			  return Null(HBUINT8);
+			  return Null (HBUINT8);
 			return device_record->widthsZ.as_array (get_num_glyphs ()) [_];
 		      })
 	    ;
@@ -164,10 +161,12 @@
   }
 
   protected:
-  HBUINT16		version;		/* Table version number (0) */
-  HBUINT16		numRecords;		/* Number of device records. */
-  HBUINT32		sizeDeviceRecord;	/* Size of a device record, 32-bit aligned. */
-  DeviceRecord		firstDeviceRecord;	/* Array of device records. */
+  HBUINT16	version;	/* Table version number (0) */
+  HBUINT16	numRecords;	/* Number of device records. */
+  HBUINT32	sizeDeviceRecord;
+				/* Size of a device record, 32-bit aligned. */
+  DeviceRecord	firstDeviceRecord;
+				/* Array of device records. */
   public:
   DEFINE_SIZE_MIN (8);
 };

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -54,6 +54,18 @@
     return 16 <= upem && upem <= 16384 ? upem : 1000;
   }
 
+  bool serialize (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    return_trace ((bool) c->embed (this));
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    return_trace (serialize (c->serializer));
+  }
+
   enum mac_style_flag_t {
     BOLD	= 1u<<0,
     ITALIC	= 1u<<1,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hhea-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hhea-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hhea-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -54,35 +54,38 @@
   }
 
   public:
-  FixedVersion<>version;		/* 0x00010000u for version 1.0. */
-  FWORD		ascender;		/* Typographic ascent. */
-  FWORD		descender;		/* Typographic descent. */
-  FWORD		lineGap;		/* Typographic line gap. */
-  UFWORD	advanceMax;		/* Maximum advance width/height value in
-					 * metrics table. */
-  FWORD		minLeadingBearing;	/* Minimum left/top sidebearing value in
-					 * metrics table. */
-  FWORD		minTrailingBearing;	/* Minimum right/bottom sidebearing value;
-					 * calculated as Min(aw - lsb -
-					 * (xMax - xMin)) for horizontal. */
-  FWORD		maxExtent;		/* horizontal: Max(lsb + (xMax - xMin)),
-					 * vertical: minLeadingBearing+(yMax-yMin). */
-  HBINT16		caretSlopeRise;		/* Used to calculate the slope of the
-					 * cursor (rise/run); 1 for vertical caret,
-					 * 0 for horizontal.*/
-  HBINT16		caretSlopeRun;		/* 0 for vertical caret, 1 for horizontal. */
-  HBINT16		caretOffset;		/* The amount by which a slanted
-					 * highlight on a glyph needs
-					 * to be shifted to produce the
-					 * best appearance. Set to 0 for
-					 * non-slanted fonts. */
-  HBINT16		reserved1;		/* Set to 0. */
-  HBINT16		reserved2;		/* Set to 0. */
-  HBINT16		reserved3;		/* Set to 0. */
-  HBINT16		reserved4;		/* Set to 0. */
-  HBINT16		metricDataFormat;	/* 0 for current format. */
-  HBUINT16	numberOfLongMetrics;	/* Number of LongMetric entries in metric
-					 * table. */
+  FixedVersion<>version;	/* 0x00010000u for version 1.0. */
+  FWORD		ascender;	/* Typographic ascent. */
+  FWORD		descender;	/* Typographic descent. */
+  FWORD		lineGap;	/* Typographic line gap. */
+  UFWORD	advanceMax;	/* Maximum advance width/height value in
+				 * metrics table. */
+  FWORD		minLeadingBearing;
+				/* Minimum left/top sidebearing value in
+				 * metrics table. */
+  FWORD		minTrailingBearing;
+				/* Minimum right/bottom sidebearing value;
+				 * calculated as Min(aw - lsb -
+				 * (xMax - xMin)) for horizontal. */
+  FWORD		maxExtent;	/* horizontal: Max(lsb + (xMax - xMin)),
+				 * vertical: minLeadingBearing+(yMax-yMin). */
+  HBINT16	caretSlopeRise;	/* Used to calculate the slope of the
+				 * cursor (rise/run); 1 for vertical caret,
+				 * 0 for horizontal.*/
+  HBINT16	caretSlopeRun;	/* 0 for vertical caret, 1 for horizontal. */
+  HBINT16	caretOffset;	/* The amount by which a slanted
+				 * highlight on a glyph needs
+				 * to be shifted to produce the
+				 * best appearance. Set to 0 for
+				 * non-slanted fonts. */
+  HBINT16	reserved1;	/* Set to 0. */
+  HBINT16	reserved2;	/* Set to 0. */
+  HBINT16	reserved3;	/* Set to 0. */
+  HBINT16	reserved4;	/* Set to 0. */
+  HBINT16	metricDataFormat;/* 0 for current format. */
+  HBUINT16	numberOfLongMetrics;
+				/* Number of LongMetric entries in metric
+				 * table. */
   public:
   DEFINE_SIZE_STATIC (36);
 };

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	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -169,7 +169,7 @@
 
       num_advances = T::is_horizontal ? face->table.hhea->numberOfLongMetrics : face->table.vhea->numberOfLongMetrics;
 
-      table = hb_sanitize_context_t().reference_table<hmtxvmtx> (face, T::tableTag);
+      table = hb_sanitize_context_t ().reference_table<hmtxvmtx> (face, T::tableTag);
 
       /* Cap num_metrics() and num_advances() based on table length. */
       unsigned int len = table.get_length ();
@@ -186,7 +186,7 @@
 	table = hb_blob_get_empty ();
       }
 
-      var_table = hb_sanitize_context_t().reference_table<HVARVVAR> (face, T::variationsTag);
+      var_table = hb_sanitize_context_t ().reference_table<HVARVVAR> (face, T::variationsTag);
     }
 
     void fini ()
@@ -216,7 +216,7 @@
 	return side_bearing;
 
       if (var_table.get_length ())
-        return side_bearing + var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); // TODO Optimize?!
+	return side_bearing + var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); // TODO Optimize?!
 
       return _glyf_get_side_bearing_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
 #else
@@ -250,7 +250,7 @@
 	return advance;
 
       if (var_table.get_length ())
-	return advance + roundf (var_table->get_advance_var (font, glyph)); // TODO Optimize?!
+	return advance + roundf (var_table->get_advance_var (glyph, font)); // TODO Optimize?!
 
       return _glyf_get_advance_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
 #else
@@ -295,27 +295,29 @@
   };
 
   protected:
-  UnsizedArrayOf<LongMetric>longMetricZ;/* Paired advance width and leading
-					 * bearing values for each glyph. The
-					 * value numOfHMetrics comes from
-					 * the 'hhea' table. If the font is
-					 * monospaced, only one entry need
-					 * be in the array, but that entry is
-					 * required. The last entry applies to
-					 * all subsequent glyphs. */
-/*UnsizedArrayOf<FWORD>	leadingBearingX;*//* Here the advance is assumed
-					 * to be the same as the advance
-					 * for the last entry above. The
-					 * number of entries in this array is
-					 * derived from numGlyphs (from 'maxp'
-					 * table) minus numberOfLongMetrics.
-					 * This generally is used with a run
-					 * of monospaced glyphs (e.g., Kanji
-					 * fonts or Courier fonts). Only one
-					 * run is allowed and it must be at
-					 * the end. This allows a monospaced
-					 * font to vary the side bearing
-					 * values for each glyph. */
+  UnsizedArrayOf<LongMetric>
+		longMetricZ;	/* Paired advance width and leading
+				 * bearing values for each glyph. The
+				 * value numOfHMetrics comes from
+				 * the 'hhea' table. If the font is
+				 * monospaced, only one entry need
+				 * be in the array, but that entry is
+				 * required. The last entry applies to
+				 * all subsequent glyphs. */
+/*UnsizedArrayOf<FWORD>	leadingBearingX;*/
+				/* Here the advance is assumed
+				 * to be the same as the advance
+				 * for the last entry above. The
+				 * number of entries in this array is
+				 * derived from numGlyphs (from 'maxp'
+				 * table) minus numberOfLongMetrics.
+				 * This generally is used with a run
+				 * of monospaced glyphs (e.g., Kanji
+				 * fonts or Courier fonts). Only one
+				 * run is allowed and it must be at
+				 * the end. This allows a monospaced
+				 * font to vary the side bearing
+				 * values for each glyph. */
   public:
   DEFINE_SIZE_ARRAY (0, longMetricZ);
 };

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	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -86,21 +86,26 @@
   }
 
   protected:
-  KernSubTableHeader	header;
-  HBUINT16		glyphCount;	/* The number of glyphs in this font. */
-  HBUINT8		kernValueCount;	/* The number of kerning values. */
-  HBUINT8		leftClassCount;	/* The number of left-hand classes. */
-  HBUINT8		rightClassCount;/* The number of right-hand classes. */
-  HBUINT8		flags;		/* Set to zero (reserved for future use). */
-  UnsizedArrayOf<FWORD>	kernValueZ;	/* The kerning values.
-					 * Length kernValueCount. */
+  KernSubTableHeader
+		header;
+  HBUINT16	glyphCount;	/* The number of glyphs in this font. */
+  HBUINT8	kernValueCount;	/* The number of kerning values. */
+  HBUINT8	leftClassCount;	/* The number of left-hand classes. */
+  HBUINT8	rightClassCount;/* The number of right-hand classes. */
+  HBUINT8	flags;		/* Set to zero (reserved for future use). */
+  UnsizedArrayOf<FWORD>
+		kernValueZ;	/* The kerning values.
+				 * Length kernValueCount. */
 #if 0
-  UnsizedArrayOf<HBUINT8>leftClass;	/* The left-hand classes.
-					 * Length glyphCount. */
-  UnsizedArrayOf<HBUINT8>rightClass;	/* The right-hand classes.
-					 * Length glyphCount. */
-  UnsizedArrayOf<HBUINT8>kernIndex;	/* The indices into the kernValue array.
-					 * Length leftClassCount * rightClassCount */
+  UnsizedArrayOf<HBUINT8>
+		leftClass;	/* The left-hand classes.
+				 * Length glyphCount. */
+  UnsizedArrayOf<HBUINT8>
+		rightClass;	/* The right-hand classes.
+				 * Length glyphCount. */
+  UnsizedArrayOf<HBUINT8>kernIndex;
+				/* The indices into the kernValue array.
+				 * Length leftClassCount * rightClassCount */
 #endif
   public:
   DEFINE_SIZE_ARRAY (KernSubTableHeader::static_size + 6, kernValueZ);
@@ -246,8 +251,8 @@
   HBUINT8	coverage;	/* Coverage bits. */
   HBUINT8	format;		/* Subtable format. */
   HBUINT16	tupleIndex;	/* The tuple index (used for variations fonts).
-			       * This value specifies which tuple this subtable covers.
-			       * Note: We don't implement. */
+				 * This value specifies which tuple this subtable covers.
+				 * Note: We don't implement. */
   public:
   DEFINE_SIZE_STATIC (8);
 };

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -60,7 +60,19 @@
 #define HB_MAX_LANGSYS	2000
 #endif
 
+#ifndef HB_MAX_FEATURES
+#define HB_MAX_FEATURES 750
+#endif
 
+#ifndef HB_MAX_FEATURE_INDICES
+#define HB_MAX_FEATURE_INDICES	1500
+#endif
+
+#ifndef HB_MAX_LOOKUP_INDICES
+#define HB_MAX_LOOKUP_INDICES	20000
+#endif
+
+
 namespace OT {
 
 
@@ -73,50 +85,132 @@
 
 template<typename Iterator>
 static inline void ClassDef_serialize (hb_serialize_context_t *c,
-                                       Iterator it);
+				       Iterator it);
 
 static void ClassDef_remap_and_serialize (hb_serialize_context_t *c,
-                                          const hb_set_t &glyphset,
-                                          const hb_map_t &gid_klass_map,
-                                          hb_sorted_vector_t<HBGlyphID> glyphs,
-                                          hb_sorted_vector_t<unsigned> klasses,
-                                          hb_map_t *klass_map /*INOUT*/);
+					  const hb_set_t &glyphset,
+					  const hb_map_t &gid_klass_map,
+					  hb_sorted_vector_t<HBGlyphID> &glyphs,
+					  const hb_set_t &klasses,
+					  hb_map_t *klass_map /*INOUT*/);
 
+struct hb_subset_layout_context_t :
+  hb_dispatch_context_t<hb_subset_layout_context_t, hb_empty_t, HB_DEBUG_SUBSET>
+{
+  const char *get_name () { return "SUBSET_LAYOUT"; }
+  static return_t default_return_value () { return hb_empty_t (); }
 
+  bool visitScript ()
+  {
+    return script_count++ < HB_MAX_SCRIPTS;
+  }
+
+  bool visitLangSys ()
+  {
+    return langsys_count++ < HB_MAX_LANGSYS;
+  }
+
+  bool visitFeatureIndex (int count)
+  {
+    feature_index_count += count;
+    return feature_index_count < HB_MAX_FEATURE_INDICES;
+  }
+
+  bool visitLookupIndex()
+  {
+    lookup_index_count++;
+    return lookup_index_count < HB_MAX_LOOKUP_INDICES;
+  }
+
+  hb_subset_context_t *subset_context;
+  const hb_tag_t table_tag;
+  const hb_map_t *lookup_index_map;
+  const hb_map_t *feature_index_map;
+  unsigned debug_depth;
+
+  hb_subset_layout_context_t (hb_subset_context_t *c_,
+			      hb_tag_t tag_,
+			      hb_map_t *lookup_map_,
+			      hb_map_t *feature_map_) :
+				subset_context (c_),
+				table_tag (tag_),
+				lookup_index_map (lookup_map_),
+				feature_index_map (feature_map_),
+				debug_depth (0),
+				script_count (0),
+				langsys_count (0),
+				feature_index_count (0),
+				lookup_index_count (0)
+  {}
+
+  private:
+  unsigned script_count;
+  unsigned langsys_count;
+  unsigned feature_index_count;
+  unsigned lookup_index_count;
+};
+
 template<typename OutputArray>
 struct subset_offset_array_t
 {
-  subset_offset_array_t
-  (hb_subset_context_t *subset_context,
-   OutputArray& out,
-   const void *src_base,
-   const void *dest_base)
-      : _subset_context(subset_context), _out (out), _src_base (src_base), _dest_base (dest_base) {}
+  subset_offset_array_t (hb_subset_context_t *subset_context_,
+			 OutputArray& out_,
+			 const void *base_) : subset_context (subset_context_),
+					      out (out_), base (base_) {}
 
   template <typename T>
-  bool
-  operator ()
-  (T&& offset)
+  bool operator () (T&& offset)
   {
-    auto *o = _out.serialize_append (_subset_context->serializer);
+    auto *o = out.serialize_append (subset_context->serializer);
     if (unlikely (!o)) return false;
-    auto snap = _subset_context->serializer->snapshot ();
-    bool ret = o->serialize_subset (_subset_context, offset, _src_base, _dest_base);
+    auto snap = subset_context->serializer->snapshot ();
+    bool ret = o->serialize_subset (subset_context, offset, base);
     if (!ret)
     {
-      _out.pop ();
-      _subset_context->serializer->revert (snap);
+      out.pop ();
+      subset_context->serializer->revert (snap);
     }
     return ret;
   }
 
   private:
-  hb_subset_context_t *_subset_context;
-  OutputArray &_out;
-  const void *_src_base;
-  const void *_dest_base;
+  hb_subset_context_t *subset_context;
+  OutputArray &out;
+  const void *base;
 };
 
+
+template<typename OutputArray, typename Arg>
+struct subset_offset_array_arg_t
+{
+  subset_offset_array_arg_t (hb_subset_context_t *subset_context_,
+			     OutputArray& out_,
+			     const void *base_,
+			     Arg &&arg_) : subset_context (subset_context_), out (out_),
+					  base (base_), arg (arg_) {}
+
+  template <typename T>
+  bool operator () (T&& offset)
+  {
+    auto *o = out.serialize_append (subset_context->serializer);
+    if (unlikely (!o)) return false;
+    auto snap = subset_context->serializer->snapshot ();
+    bool ret = o->serialize_subset (subset_context, offset, base, arg);
+    if (!ret)
+    {
+      out.pop ();
+      subset_context->serializer->revert (snap);
+    }
+    return ret;
+  }
+
+  private:
+  hb_subset_context_t *subset_context;
+  OutputArray &out;
+  const void *base;
+  Arg &&arg;
+};
+
 /*
  * Helper to subset an array of offsets. Subsets the thing pointed to by each offset
  * and discards the offset in the array if the subset operation results in an empty
@@ -126,16 +220,55 @@
 {
   template<typename OutputArray>
   subset_offset_array_t<OutputArray>
-  operator ()
-  (hb_subset_context_t *subset_context,
-   OutputArray& out,
-   const void *src_base,
-   const void *dest_base) const
+  operator () (hb_subset_context_t *subset_context, OutputArray& out,
+	       const void *base) const
+  { return subset_offset_array_t<OutputArray> (subset_context, out, base); }
+
+  /* Variant with one extra argument passed to serialize_subset */
+  template<typename OutputArray, typename Arg>
+  subset_offset_array_arg_t<OutputArray, Arg>
+  operator () (hb_subset_context_t *subset_context, OutputArray& out,
+	       const void *base, Arg &&arg) const
+  { return subset_offset_array_arg_t<OutputArray, Arg> (subset_context, out, base, arg); }
+}
+HB_FUNCOBJ (subset_offset_array);
+
+template<typename OutputArray>
+struct subset_record_array_t
+{
+  subset_record_array_t (hb_subset_layout_context_t *c_, OutputArray* out_,
+			 const void *base_) : subset_layout_context (c_),
+					      out (out_), base (base_) {}
+
+  template <typename T>
+  void
+  operator () (T&& record)
   {
-    return subset_offset_array_t<OutputArray> (subset_context, out, src_base, dest_base);
+    auto snap = subset_layout_context->subset_context->serializer->snapshot ();
+    bool ret = record.subset (subset_layout_context, base);
+    if (!ret) subset_layout_context->subset_context->serializer->revert (snap);
+    else out->len++;
   }
+
+  private:
+  hb_subset_layout_context_t *subset_layout_context;
+  OutputArray *out;
+  const void *base;
+};
+
+/*
+ * Helper to subset a RecordList/record array. Subsets each Record in the array and
+ * discards the record if the subset operation returns false.
+ */
+struct
+{
+  template<typename OutputArray>
+  subset_record_array_t<OutputArray>
+  operator () (hb_subset_layout_context_t *c, OutputArray* out,
+	       const void *base) const
+  { return subset_record_array_t<OutputArray> (c, out, base); }
 }
-HB_FUNCOBJ (subset_offset_array);
+HB_FUNCOBJ (subset_record_array);
 
 /*
  *
@@ -153,31 +286,20 @@
   const void *list_base;
 };
 
-struct RecordList_subset_context_t {
-
-  RecordList_subset_context_t() : script_count (0), langsys_count (0)
-  {}
-
-  bool visitScript ()
-  {
-    return script_count++ < HB_MAX_SCRIPTS;
-  }
-
-  bool visitLangSys ()
-  {
-    return langsys_count++ < HB_MAX_LANGSYS;
-  }
-
-  private:
-  unsigned int script_count;
-  unsigned int langsys_count;
-};
-
 template <typename Type>
 struct Record
 {
   int cmp (hb_tag_t a) const { return tag.cmp (a); }
 
+  bool subset (hb_subset_layout_context_t *c, const void *base) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->subset_context->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+    bool ret = out->offset.serialize_subset (c->subset_context, offset, base, c, &tag);
+    return_trace (ret);
+  }
+
   bool sanitize (hb_sanitize_context_t *c, const void *base) const
   {
     TRACE_SANITIZE (this);
@@ -226,29 +348,16 @@
   const Type& operator [] (unsigned int i) const
   { return this+this->get_offset (i); }
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+	       hb_subset_layout_context_t *l) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (*this);
     if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
-    RecordList_subset_context_t record_list_context;
-
-    unsigned int count = this->len;
-    for (unsigned int i = 0; i < count; i++)
-    {
-      auto *record = out->serialize_append (c->serializer);
-      if (unlikely (!record)) return false;
-      auto snap = c->serializer->snapshot ();
-      if (record->offset.serialize_subset (c, this->get_offset (i), this, out, &record_list_context))
-      {
-        record->tag = this->get_tag(i);
-        continue;
-      }
-      out->pop ();
-      c->serializer->revert (snap);
-    }
-
+    + this->iter ()
+    | hb_apply (subset_record_array (l, out, this))
+    ;
     return_trace (true);
   }
 
@@ -259,11 +368,31 @@
   }
 };
 
+struct Feature;
 
+struct RecordListOfFeature : RecordListOf<Feature>
+{
+  bool subset (hb_subset_context_t *c,
+	       hb_subset_layout_context_t *l) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+
+    unsigned count = this->len;
+    + hb_zip (*this, hb_range (count))
+    | hb_filter (l->feature_index_map, hb_second)
+    | hb_map (hb_first)
+    | hb_apply (subset_record_array (l, out, this))
+    ;
+    return_trace (true);
+  }
+};
+
 struct RangeRecord
 {
   int cmp (hb_codepoint_t g) const
-  { return g < start ? -1 : g <= end ? 0 : +1; }
+  { return g < first ? -1 : g <= last ? 0 : +1; }
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -272,14 +401,14 @@
   }
 
   bool intersects (const hb_set_t *glyphs) const
-  { return glyphs->intersects (start, end); }
+  { return glyphs->intersects (first, last); }
 
   template <typename set_t>
-  bool add_coverage (set_t *glyphs) const
-  { return glyphs->add_range (start, end); }
+  bool collect_coverage (set_t *glyphs) const
+  { return glyphs->add_range (first, last); }
 
-  HBGlyphID	start;		/* First GlyphID in the range */
-  HBGlyphID	end;		/* Last GlyphID in the range */
+  HBGlyphID	first;		/* First GlyphID in the range */
+  HBGlyphID	last;		/* Last GlyphID in the range */
   HBUINT16	value;		/* Value */
   public:
   DEFINE_SIZE_STATIC (6);
@@ -289,6 +418,29 @@
 
 struct IndexArray : ArrayOf<Index>
 {
+  bool intersects (const hb_map_t *indexes) const
+  { return hb_any (*this, indexes); }
+
+  template <typename Iterator,
+	    hb_requires (hb_is_iterator (Iterator))>
+  void serialize (hb_serialize_context_t *c,
+		  hb_subset_layout_context_t *l,
+		  Iterator it)
+  {
+    if (!it) return;
+    if (unlikely (!c->extend_min ((*this)))) return;
+
+    for (const auto _ : it)
+    {
+      if (!l->visitLookupIndex()) break;
+
+      Index i;
+      i = _;
+      c->copy (i);
+      this->len++;
+    }
+  }
+
   unsigned int get_indexes (unsigned int start_offset,
 			    unsigned int *_count /* IN/OUT */,
 			    unsigned int *_indexes /* OUT */) const
@@ -309,10 +461,6 @@
 };
 
 
-struct Script;
-struct LangSys;
-struct Feature;
-
 struct LangSys
 {
   unsigned int get_feature_count () const
@@ -340,6 +488,42 @@
     return_trace (c->embed (*this));
   }
 
+  bool operator == (const LangSys& o) const
+  {
+    if (featureIndex.len != o.featureIndex.len ||
+	reqFeatureIndex != o.reqFeatureIndex)
+      return false;
+
+    for (const auto _ : + hb_zip (featureIndex, o.featureIndex))
+      if (_.first != _.second) return false;
+
+    return true;
+  }
+
+  bool subset (hb_subset_context_t        *c,
+	       hb_subset_layout_context_t *l,
+	       const Tag                  *tag = nullptr) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+
+    out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex) ? l->feature_index_map->get (reqFeatureIndex) : 0xFFFFu;
+
+    if (!l->visitFeatureIndex (featureIndex.len))
+      return_trace (false);
+
+    auto it =
+    + hb_iter (featureIndex)
+    | hb_filter (l->feature_index_map)
+    | hb_map (l->feature_index_map)
+    ;
+
+    bool ret = bool (it);
+    out->featureIndex.serialize (c->serializer, l, it);
+    return_trace (ret);
+  }
+
   bool sanitize (hb_sanitize_context_t *c,
 		 const Record_sanitize_closure_t * = nullptr) const
   {
@@ -379,34 +563,46 @@
   bool has_default_lang_sys () const           { return defaultLangSys != 0; }
   const LangSys& get_default_lang_sys () const { return this+defaultLangSys; }
 
-  bool subset (hb_subset_context_t *c, RecordList_subset_context_t *record_list_context) const
+  bool subset (hb_subset_context_t         *c,
+	       hb_subset_layout_context_t  *l,
+	       const Tag                   *tag) const
   {
     TRACE_SUBSET (this);
-    if (!record_list_context->visitScript ()) return_trace (false);
+    if (!l->visitScript ()) return_trace (false);
 
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
 
-    out->defaultLangSys.serialize_copy (c->serializer, defaultLangSys, this, out);
-
-    for (const auto &src: langSys)
+    bool defaultLang = false;
+    if (has_default_lang_sys ())
     {
-      if (!record_list_context->visitLangSys ()) {
-        continue;
+      c->serializer->push ();
+      const LangSys& ls = this+defaultLangSys;
+      bool ret = ls.subset (c, l);
+      if (!ret && tag && *tag != HB_TAG ('D', 'F', 'L', 'T'))
+      {
+	c->serializer->pop_discard ();
+	out->defaultLangSys = 0;
       }
-
-      auto snap = c->serializer->snapshot ();
-      auto *lang_sys = c->serializer->embed (src);
-
-      if (likely(lang_sys)
-          && lang_sys->offset.serialize_copy (c->serializer, src.offset, this, out))
+      else
       {
-        out->langSys.len++;
-        continue;
+	c->serializer->add_link (out->defaultLangSys, c->serializer->pop_pack ());
+	defaultLang = true;
       }
-      c->serializer->revert (snap);
     }
-    return_trace (true);
+
+    + langSys.iter ()
+    | hb_filter ([=] (const Record<LangSys>& record) {return l->visitLangSys (); })
+    | hb_filter ([&] (const Record<LangSys>& record)
+		 {
+		   const LangSys& d = this+defaultLangSys;
+		   const LangSys& l = this+record.offset;
+		   return !(l == d);
+		 })
+    | hb_apply (subset_record_array (l, &(out->langSys), this))
+    ;
+
+    return_trace (bool (out->langSys.len) || defaultLang || l->table_tag == HB_OT_TAG_GSUB);
   }
 
   bool sanitize (hb_sanitize_context_t *c,
@@ -682,13 +878,27 @@
   const FeatureParams &get_feature_params () const
   { return this+featureParams; }
 
-  bool subset (hb_subset_context_t *c, RecordList_subset_context_t *r) const
+  bool intersects_lookup_indexes (const hb_map_t *lookup_indexes) const
+  { return lookupIndex.intersects (lookup_indexes); }
+
+  bool subset (hb_subset_context_t         *c,
+	       hb_subset_layout_context_t  *l,
+	       const Tag                   *tag = nullptr) const
   {
     TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (*this);
-    if (unlikely (!out)) return_trace (false);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+
     out->featureParams = 0; /* TODO(subset) FeatureParams. */
-    return_trace (true);
+
+    auto it =
+    + hb_iter (lookupIndex)
+    | hb_filter (l->lookup_index_map)
+    | hb_map (l->lookup_index_map)
+    ;
+
+    out->lookupIndex.serialize (c->serializer, l, it);
+    return_trace (bool (it) || (tag && *tag == HB_TAG ('p', 'r', 'e', 'f')));
   }
 
   bool sanitize (hb_sanitize_context_t *c,
@@ -775,10 +985,10 @@
 
   template <typename TSubTable>
   const OffsetArrayOf<TSubTable>& get_subtables () const
-  { return CastR<OffsetArrayOf<TSubTable>> (subTable); }
+  { return reinterpret_cast<const OffsetArrayOf<TSubTable> &> (subTable); }
   template <typename TSubTable>
   OffsetArrayOf<TSubTable>& get_subtables ()
-  { return CastR<OffsetArrayOf<TSubTable>> (subTable); }
+  { return reinterpret_cast<OffsetArrayOf<TSubTable> &> (subTable); }
 
   template <typename TSubTable>
   const TSubTable& get_subtable (unsigned int i) const
@@ -848,17 +1058,17 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (*this);
-    if (unlikely (!out)) return_trace (false);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+    out->lookupType = lookupType;
+    out->lookupFlag = lookupFlag;
 
-    /* Subset the actual subtables. */
-    /* TODO Drop empty ones, either by calling intersects() beforehand,
-     * or just dropping null offsets after. */
-    const OffsetArrayOf<TSubTable>& subtables = get_subtables<TSubTable> ();
-    OffsetArrayOf<TSubTable>& out_subtables = out->get_subtables<TSubTable> ();
-    unsigned int count = subTable.len;
-    for (unsigned int i = 0; i < count; i++)
-      out_subtables[i].serialize_subset (c, subtables[i], this, out, get_type ());
+    const hb_set_t *glyphset = c->plan->glyphset ();
+    unsigned int lookup_type = get_type ();
+    + hb_iter (get_subtables <TSubTable> ())
+    | hb_filter ([this, glyphset, lookup_type] (const OffsetTo<TSubTable> &_) { return (this+_).intersects (glyphset, lookup_type); })
+    | hb_apply (subset_offset_array (c, out->get_subtables<TSubTable> (), this, lookup_type))
+    ;
 
     return_trace (true);
   }
@@ -868,6 +1078,10 @@
   {
     TRACE_SANITIZE (this);
     if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false);
+
+    unsigned subtables = get_subtable_count ();
+    if (unlikely (!c->visit_subtables (subtables))) return_trace (false);
+
     if (lookupFlag & LookupFlag::UseMarkFilteringSet)
     {
       const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
@@ -890,8 +1104,7 @@
        * https://bugs.chromium.org/p/chromium/issues/detail?id=960331
        */
       unsigned int type = get_subtable<TSubTable> (0).u.extension.get_type ();
-      unsigned int count = get_subtable_count ();
-      for (unsigned int i = 1; i < count; i++)
+      for (unsigned int i = 1; i < subtables; i++)
 	if (get_subtable<TSubTable> (i).u.extension.get_type () != type)
 	  return_trace (false);
     }
@@ -912,7 +1125,33 @@
 
 typedef OffsetListOf<Lookup> LookupList;
 
+template <typename TLookup>
+struct LookupOffsetList : OffsetListOf<TLookup>
+{
+  bool subset (hb_subset_context_t        *c,
+	       hb_subset_layout_context_t *l) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (this);
+    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
 
+    unsigned count = this->len;
+    + hb_zip (*this, hb_range (count))
+    | hb_filter (l->lookup_index_map, hb_second)
+    | hb_map (hb_first)
+    | hb_apply (subset_offset_array (c, *out, this))
+    ;
+    return_trace (true);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (OffsetListOf<TLookup>::sanitize (c, this));
+  }
+};
+
+
 /*
  * Coverage Table
  */
@@ -956,7 +1195,7 @@
   { return glyphs->has (glyphArray[index]); }
 
   template <typename set_t>
-  bool add_coverage (set_t *glyphs) const
+  bool collect_coverage (set_t *glyphs) const
   { return glyphs->add_sorted_array (glyphArray.arrayZ, glyphArray.len); }
 
   public:
@@ -993,8 +1232,8 @@
   unsigned int get_coverage (hb_codepoint_t glyph_id) const
   {
     const RangeRecord &range = rangeRecord.bsearch (glyph_id);
-    return likely (range.start <= range.end) ?
-	   (unsigned int) range.value + (glyph_id - range.start) :
+    return likely (range.first <= range.last) ?
+	   (unsigned int) range.value + (glyph_id - range.first) :
 	   NOT_COVERED;
   }
 
@@ -1032,10 +1271,10 @@
       if (last + 1 != g)
       {
 	range++;
-	rangeRecord[range].start = g;
+	rangeRecord[range].first = g;
 	rangeRecord[range].value = count;
       }
-      rangeRecord[range].end = g;
+      rangeRecord[range].last = g;
       last = g;
       count++;
     }
@@ -1065,7 +1304,7 @@
     for (i = 0; i < count; i++) {
       const RangeRecord &range = rangeRecord[i];
       if (range.value <= index &&
-	  index < (unsigned int) range.value + (range.end - range.start) &&
+	  index < (unsigned int) range.value + (range.last - range.first) &&
 	  range.intersects (glyphs))
 	return true;
       else if (index < range.value)
@@ -1075,11 +1314,11 @@
   }
 
   template <typename set_t>
-  bool add_coverage (set_t *glyphs) const
+  bool collect_coverage (set_t *glyphs) const
   {
     unsigned int count = rangeRecord.len;
     for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
+      if (unlikely (!rangeRecord[i].collect_coverage (glyphs)))
 	return false;
     return true;
   }
@@ -1093,8 +1332,8 @@
       c = &c_;
       coverage = 0;
       i = 0;
-      j = c->rangeRecord.len ? c->rangeRecord[0].start : 0;
-      if (unlikely (c->rangeRecord[0].start > c->rangeRecord[0].end))
+      j = c->rangeRecord.len ? c->rangeRecord[0].first : 0;
+      if (unlikely (c->rangeRecord[0].first > c->rangeRecord[0].last))
       {
 	/* Broken table. Skip. */
 	i = c->rangeRecord.len;
@@ -1104,13 +1343,13 @@
     bool more () const { return i < c->rangeRecord.len; }
     void next ()
     {
-      if (j >= c->rangeRecord[i].end)
+      if (j >= c->rangeRecord[i].last)
       {
 	i++;
 	if (more ())
 	{
 	  unsigned int old = coverage;
-	  j = c->rangeRecord[i].start;
+	  j = c->rangeRecord[i].first;
 	  coverage = c->rangeRecord[i].value;
 	  if (unlikely (coverage != old + 1))
 	  {
@@ -1246,12 +1485,12 @@
   /* Might return false if array looks unsorted.
    * Used for faster rejection of corrupt data. */
   template <typename set_t>
-  bool add_coverage (set_t *glyphs) const
+  bool collect_coverage (set_t *glyphs) const
   {
     switch (u.format)
     {
-    case 1: return u.format1.add_coverage (glyphs);
-    case 2: return u.format2.add_coverage (glyphs);
+    case 1: return u.format1.collect_coverage (glyphs);
+    case 2: return u.format2.collect_coverage (glyphs);
     default:return false;
     }
   }
@@ -1259,7 +1498,7 @@
   struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t>
   {
     static constexpr bool is_sorted_iterator = true;
-    iter_t (const Coverage &c_ = Null(Coverage))
+    iter_t (const Coverage &c_ = Null (Coverage))
     {
       memset (this, 0, sizeof (*this));
       format = c_.u.format;
@@ -1333,22 +1572,28 @@
 template<typename Iterator>
 static inline void
 Coverage_serialize (hb_serialize_context_t *c,
-                    Iterator it)
+		    Iterator it)
 { c->start_embed<Coverage> ()->serialize (c, it); }
 
 static void ClassDef_remap_and_serialize (hb_serialize_context_t *c,
-                                          const hb_set_t &glyphset,
-                                          const hb_map_t &gid_klass_map,
-                                          hb_sorted_vector_t<HBGlyphID> glyphs,
-                                          hb_sorted_vector_t<unsigned> klasses,
-                                          hb_map_t *klass_map /*INOUT*/)
+					  const hb_set_t &glyphset,
+					  const hb_map_t &gid_klass_map,
+					  hb_sorted_vector_t<HBGlyphID> &glyphs,
+					  const hb_set_t &klasses,
+					  hb_map_t *klass_map /*INOUT*/)
 {
-  bool has_no_match = glyphset.get_population () > gid_klass_map.get_population ();
-  
-  hb_map_t m;
-  if (!klass_map) klass_map = &m;
+  if (!klass_map)
+  {
+    ClassDef_serialize (c, hb_zip (glyphs.iter (), + glyphs.iter ()
+						   | hb_map (gid_klass_map)));
+    return;
+  }
 
-  if (has_no_match) klass_map->set (0, 0);
+  /* any glyph not assigned a class value falls into Class zero (0),
+   * if any glyph assigned to class 0, remapping must start with 0->0*/
+  if (glyphset.get_population () > gid_klass_map.get_population ())
+    klass_map->set (0, 0);
+
   unsigned idx = klass_map->has (0) ? 1 : 0;
   for (const unsigned k: klasses.iter ())
   {
@@ -1356,17 +1601,16 @@
     klass_map->set (k, idx);
     idx++;
   }
-  
+
   auto it =
   + glyphs.iter ()
-  | hb_map_retains_sorting ([&] (const HBGlyphID& gid) -> hb_pair_t<hb_codepoint_t, HBUINT16>
-                            {
-                              HBUINT16 new_klass;
-                              new_klass = klass_map->get (gid_klass_map[gid]);
-                              return hb_pair ((hb_codepoint_t)gid, new_klass);
-                            })
+  | hb_map_retains_sorting ([&] (const HBGlyphID& gid) -> hb_pair_t<hb_codepoint_t, unsigned>
+			    {
+			      unsigned new_klass = klass_map->get (gid_klass_map[gid]);
+			      return hb_pair ((hb_codepoint_t)gid, new_klass);
+			    })
   ;
-  
+
   c->propagate_error (glyphs, klasses);
   ClassDef_serialize (c, it);
 }
@@ -1388,7 +1632,7 @@
   template<typename Iterator,
 	   hb_requires (hb_is_iterator (Iterator))>
   bool serialize (hb_serialize_context_t *c,
-                  Iterator it)
+		  Iterator it)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
@@ -1400,21 +1644,31 @@
       return_trace (true);
     }
 
-    startGlyph = (*it).first;
-    classValue.serialize (c, + it
-                             | hb_map (hb_second));
+    hb_codepoint_t glyph_min = (*it).first;
+    hb_codepoint_t glyph_max = + it
+			       | hb_map (hb_first)
+			       | hb_reduce (hb_max, 0u);
+    unsigned glyph_count = glyph_max - glyph_min + 1;
+
+    startGlyph = glyph_min;
+    if (unlikely (!classValue.serialize (c, glyph_count))) return_trace (false);
+    for (const hb_pair_t<hb_codepoint_t, unsigned>& gid_klass_pair : + it)
+    {
+      unsigned idx = gid_klass_pair.first - glyph_min;
+      classValue[idx] = gid_klass_pair.second;
+    }
     return_trace (true);
   }
 
   bool subset (hb_subset_context_t *c,
-               hb_map_t *klass_map = nullptr /*OUT*/) const
+	       hb_map_t *klass_map = nullptr /*OUT*/) const
   {
     TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_set_t &glyphset = *c->plan->_glyphset_gsub;
     const hb_map_t &glyph_map = *c->plan->glyph_map;
-   
+
     hb_sorted_vector_t<HBGlyphID> glyphs;
-    hb_sorted_vector_t<unsigned> orig_klasses;
+    hb_set_t orig_klasses;
     hb_map_t gid_org_klass_map;
 
     hb_codepoint_t start = startGlyph;
@@ -1427,11 +1681,11 @@
 
       glyphs.push (glyph_map[gid]);
       gid_org_klass_map.set (glyph_map[gid], klass);
-      orig_klasses.push (klass);
+      orig_klasses.add (klass);
     }
 
     ClassDef_remap_and_serialize (c->serializer, glyphset, gid_org_klass_map,
-                                  glyphs, orig_klasses, klass_map);
+				  glyphs, orig_klasses, klass_map);
     return_trace ((bool) glyphs);
   }
 
@@ -1442,7 +1696,7 @@
   }
 
   template <typename set_t>
-  bool add_coverage (set_t *glyphs) const
+  bool collect_coverage (set_t *glyphs) const
   {
     unsigned int start = 0;
     unsigned int count = classValue.len;
@@ -1465,7 +1719,7 @@
   }
 
   template <typename set_t>
-  bool add_class (set_t *glyphs, unsigned int klass) const
+  bool collect_class (set_t *glyphs, unsigned int klass) const
   {
     unsigned int count = classValue.len;
     for (unsigned int i = 0; i < count; i++)
@@ -1524,7 +1778,7 @@
   template<typename Iterator,
 	   hb_requires (hb_is_iterator (Iterator))>
   bool serialize (hb_serialize_context_t *c,
-                  Iterator it)
+		  Iterator it)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
@@ -1540,8 +1794,8 @@
     unsigned prev_klass = (*it).second;
 
     RangeRecord range_rec;
-    range_rec.start = prev_gid;
-    range_rec.end = prev_gid;
+    range_rec.first = prev_gid;
+    range_rec.last = prev_gid;
     range_rec.value = prev_klass;
 
     RangeRecord *record = c->copy (range_rec);
@@ -1553,17 +1807,17 @@
       unsigned cur_klass = gid_klass_pair.second;
 
       if (cur_gid != prev_gid + 1 ||
-          cur_klass != prev_klass)
+	  cur_klass != prev_klass)
       {
-        if (unlikely (!record)) break;
-        record->end = prev_gid;
-        num_ranges++;
+	if (unlikely (!record)) break;
+	record->last = prev_gid;
+	num_ranges++;
 
-        range_rec.start = cur_gid;
-        range_rec.end = cur_gid;
-        range_rec.value = cur_klass;
+	range_rec.first = cur_gid;
+	range_rec.last = cur_gid;
+	range_rec.value = cur_klass;
 
-        record = c->copy (range_rec);
+	record = c->copy (range_rec);
       }
 
       prev_klass = cur_klass;
@@ -1570,20 +1824,20 @@
       prev_gid = cur_gid;
     }
 
-    if (likely (record)) record->end = prev_gid;
+    if (likely (record)) record->last = prev_gid;
     rangeRecord.len = num_ranges;
     return_trace (true);
   }
 
   bool subset (hb_subset_context_t *c,
-               hb_map_t *klass_map = nullptr /*OUT*/) const
+	       hb_map_t *klass_map = nullptr /*OUT*/) const
   {
     TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_set_t &glyphset = *c->plan->_glyphset_gsub;
     const hb_map_t &glyph_map = *c->plan->glyph_map;
 
     hb_sorted_vector_t<HBGlyphID> glyphs;
-    hb_sorted_vector_t<unsigned> orig_klasses;
+    hb_set_t orig_klasses;
     hb_map_t gid_org_klass_map;
 
     unsigned count = rangeRecord.len;
@@ -1591,19 +1845,19 @@
     {
       unsigned klass = rangeRecord[i].value;
       if (!klass) continue;
-      hb_codepoint_t start = rangeRecord[i].start;
-      hb_codepoint_t end   = rangeRecord[i].end + 1;
+      hb_codepoint_t start = rangeRecord[i].first;
+      hb_codepoint_t end   = rangeRecord[i].last + 1;
       for (hb_codepoint_t g = start; g < end; g++)
       {
 	if (!glyphset.has (g)) continue;
 	glyphs.push (glyph_map[g]);
-        gid_org_klass_map.set (glyph_map[g], klass);
-        orig_klasses.push (klass);
+	gid_org_klass_map.set (glyph_map[g], klass);
+	orig_klasses.add (klass);
       }
     }
 
     ClassDef_remap_and_serialize (c->serializer, glyphset, gid_org_klass_map,
-                                  glyphs, orig_klasses, klass_map);
+				  glyphs, orig_klasses, klass_map);
     return_trace ((bool) glyphs);
   }
 
@@ -1614,24 +1868,24 @@
   }
 
   template <typename set_t>
-  bool add_coverage (set_t *glyphs) const
+  bool collect_coverage (set_t *glyphs) const
   {
     unsigned int count = rangeRecord.len;
     for (unsigned int i = 0; i < count; i++)
       if (rangeRecord[i].value)
-	if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
+	if (unlikely (!rangeRecord[i].collect_coverage (glyphs)))
 	  return false;
     return true;
   }
 
   template <typename set_t>
-  bool add_class (set_t *glyphs, unsigned int klass) const
+  bool collect_class (set_t *glyphs, unsigned int klass) const
   {
     unsigned int count = rangeRecord.len;
     for (unsigned int i = 0; i < count; i++)
     {
       if (rangeRecord[i].value == klass)
-	if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
+	if (unlikely (!rangeRecord[i].collect_coverage (glyphs)))
 	  return false;
     }
     return true;
@@ -1657,9 +1911,9 @@
       {
 	if (!hb_set_next (glyphs, &g))
 	  break;
-	if (g < rangeRecord[i].start)
+	if (g < rangeRecord[i].first)
 	  return true;
-	g = rangeRecord[i].end;
+	g = rangeRecord[i].last;
       }
       if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g))
 	return true;
@@ -1713,7 +1967,7 @@
       hb_codepoint_t glyph_min = (*it).first;
       hb_codepoint_t glyph_max = + it
 				 | hb_map (hb_first)
-                                 | hb_reduce (hb_max, 0u);
+				 | hb_reduce (hb_max, 0u);
 
       unsigned num_ranges = 1;
       hb_codepoint_t prev_gid = glyph_min;
@@ -1721,17 +1975,18 @@
 
       for (const auto gid_klass_pair : it)
       {
-        hb_codepoint_t cur_gid = gid_klass_pair.first;
-        unsigned cur_klass = gid_klass_pair.second;
-        if (cur_gid != prev_gid + 1 ||
-            cur_klass != prev_klass)
-          num_ranges++;
+	hb_codepoint_t cur_gid = gid_klass_pair.first;
+	unsigned cur_klass = gid_klass_pair.second;
+	if (cur_gid == glyph_min || !cur_klass) continue;
+	if (cur_gid != prev_gid + 1 ||
+	    cur_klass != prev_klass)
+	  num_ranges++;
 
-        prev_gid = cur_gid;
-        prev_klass = cur_klass;
+	prev_gid = cur_gid;
+	prev_klass = cur_klass;
       }
 
-      if (1 + (glyph_max - glyph_min + 1) < num_ranges * 3)
+      if (1 + (glyph_max - glyph_min + 1) <= num_ranges * 3)
 	format = 1;
     }
     u.format = format;
@@ -1745,7 +2000,7 @@
   }
 
   bool subset (hb_subset_context_t *c,
-               hb_map_t *klass_map = nullptr /*OUT*/) const
+	       hb_map_t *klass_map = nullptr /*OUT*/) const
   {
     TRACE_SUBSET (this);
     switch (u.format) {
@@ -1769,11 +2024,11 @@
   /* Might return false if array looks unsorted.
    * Used for faster rejection of corrupt data. */
   template <typename set_t>
-  bool add_coverage (set_t *glyphs) const
+  bool collect_coverage (set_t *glyphs) const
   {
     switch (u.format) {
-    case 1: return u.format1.add_coverage (glyphs);
-    case 2: return u.format2.add_coverage (glyphs);
+    case 1: return u.format1.collect_coverage (glyphs);
+    case 2: return u.format2.collect_coverage (glyphs);
     default:return false;
     }
   }
@@ -1781,11 +2036,11 @@
   /* Might return false if array looks unsorted.
    * Used for faster rejection of corrupt data. */
   template <typename set_t>
-  bool add_class (set_t *glyphs, unsigned int klass) const
+  bool collect_class (set_t *glyphs, unsigned int klass) const
   {
     switch (u.format) {
-    case 1: return u.format1.add_class (glyphs, klass);
-    case 2: return u.format2.add_class (glyphs, klass);
+    case 1: return u.format1.collect_class (glyphs, klass);
+    case 2: return u.format2.collect_class (glyphs, klass);
     default:return false;
     }
   }
@@ -1819,7 +2074,7 @@
 
 template<typename Iterator>
 static inline void ClassDef_serialize (hb_serialize_context_t *c,
-                                       Iterator it)
+				       Iterator it)
 { c->start_embed<ClassDef> ()->serialize (c, it); }
 
 
@@ -1906,8 +2161,13 @@
     axisCount = src->axisCount;
     regionCount = region_map.get_population ();
     if (unlikely (!c->allocate_size<VarRegionList> (get_size () - min_size))) return_trace (false);
+    unsigned int region_count = src->get_region_count ();
     for (unsigned int r = 0; r < regionCount; r++)
-      memcpy (&axesZ[axisCount * r], &src->axesZ[axisCount * region_map.backward (r)], VarRegionAxis::static_size * axisCount);
+    {
+      unsigned int backward = region_map.backward (r);
+      if (backward >= region_count) return_trace (false);
+      memcpy (&axesZ[axisCount * r], &src->axesZ[axisCount * backward], VarRegionAxis::static_size * axisCount);
+    }
 
     return_trace (true);
   }
@@ -1967,7 +2227,7 @@
    return delta;
   }
 
-  void get_scalars (int *coords, unsigned int coord_count,
+  void get_scalars (const int *coords, unsigned int coord_count,
 		    const VarRegionList &regions,
 		    float *scalars /*OUT */,
 		    unsigned int num_scalars) const
@@ -2031,8 +2291,8 @@
     for (r = 0; r < ri_count; r++)
       if (delta_sz[r])
       {
-      	ri_map[r] = (delta_sz[r] == kShort)? short_index++ : byte_index++;
-      	new_ri_count++;
+	ri_map[r] = (delta_sz[r] == kShort)? short_index++ : byte_index++;
+	new_ri_count++;
       }
 
     shortCount = new_short_count;
@@ -2145,7 +2405,7 @@
 
   bool serialize (hb_serialize_context_t *c,
 		  const VariationStore *src,
-  		  const hb_array_t <hb_inc_bimap_t> &inner_maps)
+		  const hb_array_t <hb_inc_bimap_t> &inner_maps)
   {
     TRACE_SERIALIZE (this);
     unsigned int set_count = 0;
@@ -2184,7 +2444,7 @@
   { return (this+dataSets[ivs]).get_region_index_count (); }
 
   void get_scalars (unsigned int ivs,
-		    int *coords, unsigned int coord_count,
+		    const int *coords, unsigned int coord_count,
 		    float *scalars /*OUT*/,
 		    unsigned int num_scalars) const
   {
@@ -2216,6 +2476,14 @@
 {
   friend struct Condition;
 
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+    return_trace (true);
+  }
+
   private:
   bool evaluate (const int *coords, unsigned int coord_len) const
   {
@@ -2248,6 +2516,17 @@
     }
   }
 
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+  {
+    TRACE_DISPATCH (this, u.format);
+    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -2278,6 +2557,18 @@
     return true;
   }
 
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (this);
+    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+
+    + conditions.iter ()
+    | hb_apply (subset_offset_array (c, out->conditions, this))
+    ;
+    return_trace (true);
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -2294,6 +2585,30 @@
 {
   friend struct FeatureTableSubstitution;
 
+  void collect_lookups (const void *base, hb_set_t *lookup_indexes /* OUT */) const
+  {
+    return (base+feature).add_lookup_indexes_to (lookup_indexes);
+  }
+
+  void closure_features (const void *base,
+			 const hb_map_t *lookup_indexes,
+			 hb_set_t       *feature_indexes /* OUT */) const
+  {
+    if ((base+feature).intersects_lookup_indexes (lookup_indexes))
+      feature_indexes->add (featureIndex);
+  }
+
+  bool subset (hb_subset_layout_context_t *c, const void *base) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->subset_context->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    out->featureIndex = c->feature_index_map->get (featureIndex);
+    bool ret = out->feature.serialize_subset (c->subset_context, feature, base, c);
+    return_trace (ret);
+  }
+
   bool sanitize (hb_sanitize_context_t *c, const void *base) const
   {
     TRACE_SANITIZE (this);
@@ -2321,6 +2636,39 @@
     return nullptr;
   }
 
+  void collect_lookups (const hb_set_t *feature_indexes,
+			hb_set_t       *lookup_indexes /* OUT */) const
+  {
+    + hb_iter (substitutions)
+    | hb_filter (feature_indexes, &FeatureTableSubstitutionRecord::featureIndex)
+    | hb_apply ([this, lookup_indexes] (const FeatureTableSubstitutionRecord& r)
+		{ r.collect_lookups (this, lookup_indexes); })
+    ;
+  }
+
+  void closure_features (const hb_map_t *lookup_indexes,
+			 hb_set_t       *feature_indexes /* OUT */) const
+  {
+    for (const FeatureTableSubstitutionRecord& record : substitutions)
+      record.closure_features (this, lookup_indexes, feature_indexes);
+  }
+
+  bool subset (hb_subset_context_t        *c,
+	       hb_subset_layout_context_t *l) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+
+    out->version.major = version.major;
+    out->version.minor = version.minor;
+
+    + substitutions.iter ()
+    | hb_apply (subset_record_array (l, &(out->substitutions), this))
+    ;
+    return_trace (true);
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -2341,6 +2689,32 @@
 {
   friend struct FeatureVariations;
 
+  void collect_lookups (const void     *base,
+			const hb_set_t *feature_indexes,
+			hb_set_t       *lookup_indexes /* OUT */) const
+  {
+    return (base+substitutions).collect_lookups (feature_indexes, lookup_indexes);
+  }
+
+  void closure_features (const void     *base,
+			 const hb_map_t *lookup_indexes,
+			 hb_set_t       *feature_indexes /* OUT */) const
+  {
+    (base+substitutions).closure_features (lookup_indexes, feature_indexes);
+  }
+
+  bool subset (hb_subset_layout_context_t *c, const void *base) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->subset_context->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    out->conditions.serialize_subset (c->subset_context, conditions, base);
+    out->substitutions.serialize_subset (c->subset_context, substitutions, base, c);
+
+    return_trace (true);
+  }
+
   bool sanitize (hb_sanitize_context_t *c, const void *base) const
   {
     TRACE_SANITIZE (this);
@@ -2391,6 +2765,36 @@
     return_trace (c->embed (*this));
   }
 
+  void collect_lookups (const hb_set_t *feature_indexes,
+			hb_set_t       *lookup_indexes /* OUT */) const
+  {
+    for (const FeatureVariationRecord& r : varRecords)
+      r.collect_lookups (this, feature_indexes, lookup_indexes);
+  }
+
+  void closure_features (const hb_map_t *lookup_indexes,
+			 hb_set_t       *feature_indexes /* OUT */) const
+  {
+    for (const FeatureVariationRecord& record : varRecords)
+      record.closure_features (this, lookup_indexes, feature_indexes);
+  }
+
+  bool subset (hb_subset_context_t *c,
+	       hb_subset_layout_context_t *l) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+
+    out->version.major = version.major;
+    out->version.minor = version.minor;
+
+    + varRecords.iter ()
+    | hb_apply (subset_record_array (l, &(out->varRecords), this))
+    ;
+    return_trace (bool (out->varRecords));
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -96,6 +96,13 @@
 struct CaretValueFormat1
 {
   friend struct CaretValue;
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+    return_trace (true);
+  }
 
   private:
   hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction) const
@@ -119,6 +126,13 @@
 struct CaretValueFormat2
 {
   friend struct CaretValue;
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+    return_trace (true);
+  }
 
   private:
   hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
@@ -153,6 +167,15 @@
 	   font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font, var_store);
   }
 
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->deviceTable.serialize_copy (c->serializer, deviceTable, this));
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -185,6 +208,19 @@
     }
   }
 
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+  {
+    TRACE_DISPATCH (this, u.format);
+    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
+    case 3: return_trace (c->dispatch (u.format3, hb_forward<Ts> (ds)...));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -229,6 +265,19 @@
     return carets.len;
   }
 
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    + hb_iter (carets)
+    | hb_apply (subset_offset_array (c, out->carets, this))
+    ;
+
+    return_trace (bool (out->carets));
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -265,6 +314,28 @@
     return lig_glyph.get_lig_carets (font, direction, glyph_id, var_store, start_offset, caret_count, caret_array);
   }
 
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+    + hb_zip (this+coverage, ligGlyph)
+    | hb_filter (glyphset, hb_first)
+    | hb_filter (subset_offset_array (c, out->ligGlyph, this), hb_second)
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+    out->coverage.serialize (c->serializer, out)
+		 .serialize (c->serializer, new_coverage.iter ());
+    return_trace (bool (new_coverage));
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -288,6 +359,34 @@
   bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
   { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
 
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    out->format = format;
+
+    bool ret = true;
+    for (const LOffsetTo<Coverage>& offset : coverage.iter ())
+    {
+      auto *o = out->coverage.serialize_append (c->serializer);
+      if (unlikely (!o))
+      {
+	ret = false;
+	break;
+      }
+
+      //not using o->serialize_subset (c, offset, this, out) here because
+      //OTS doesn't allow null offset.
+      //See issue: https://github.com/khaledhosny/ots/issues/172
+      c->serializer->push ();
+      c->dispatch (this+offset);
+      c->serializer->add_link (*o, c->serializer->pop_pack ());
+    }
+
+    return_trace (ret && out->coverage.len);
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -313,6 +412,15 @@
     }
   }
 
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    switch (u.format) {
+    case 1: return_trace (u.format1.subset (c));
+    default:return_trace (false);
+    }
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -356,7 +464,7 @@
   unsigned int get_glyph_class (hb_codepoint_t glyph) const
   { return (this+glyphClassDef).get_class (glyph); }
   void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const
-  { (this+glyphClassDef).add_class (glyphs, klass); }
+  { (this+glyphClassDef).collect_class (glyphs, klass); }
 
   bool has_mark_attachment_types () const { return markAttachClassDef != 0; }
   unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const
@@ -386,7 +494,7 @@
 
   bool has_var_store () const { return version.to_int () >= 0x00010003u && varStore != 0; }
   const VariationStore &get_var_store () const
-  { return version.to_int () >= 0x00010003u ? this+varStore : Null(VariationStore); }
+  { return version.to_int () >= 0x00010003u ? this+varStore : Null (VariationStore); }
 
   /* glyph_props is a 16-bit integer where the lower 8-bit have bits representing
    * glyph class and other bits, and high 8-bit the mark attachment type (if any).
@@ -416,7 +524,7 @@
   {
     void init (hb_face_t *face)
     {
-      this->table = hb_sanitize_context_t().reference_table<GDEF> (face);
+      this->table = hb_sanitize_context_t ().reference_table<GDEF> (face);
       if (unlikely (this->table->is_blacklisted (this->table.get_blob (), face)))
       {
 	hb_blob_destroy (this->table.get_blob ());
@@ -442,16 +550,20 @@
     auto *out = c->serializer->embed (*this);
     if (unlikely (!out)) return_trace (false);
 
-    out->glyphClassDef.serialize_subset (c, glyphClassDef, this, out);
-    out->attachList = 0;//TODO(subset) serialize_subset (c, attachList, this, out);
-    out->ligCaretList = 0;//TODO(subset) serialize_subset (c, ligCaretList, this, out);
-    out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, out);
+    out->glyphClassDef.serialize_subset (c, glyphClassDef, this);
+    out->attachList = 0;//TODO(subset) serialize_subset (c, attachList, this);
+    out->ligCaretList.serialize_subset (c, ligCaretList, this);
+    out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this);
 
     if (version.to_int () >= 0x00010002u)
-      out->markGlyphSetsDef = 0;// TODO(subset) serialize_subset (c, markGlyphSetsDef, this, out);
+    {
+      if (!out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this) &&
+	  version.to_int () == 0x00010002u)
+	out->version.minor = 0;
+    }
 
     if (version.to_int () >= 0x00010003u)
-      out->varStore = 0;// TODO(subset) serialize_subset (c, varStore, this, out);
+      out->varStore = 0;// TODO(subset) serialize_subset (c, varStore, this);
 
     return_trace (true);
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -34,6 +34,11 @@
 
 namespace OT {
 
+struct MarkArray;
+static void Markclass_closure_and_remap_indexes (const Coverage  &mark_coverage,
+						 const MarkArray &mark_array,
+						 const hb_set_t  &glyphset,
+						 hb_map_t*        klass_mapping /* INOUT */);
 
 /* buffer **position** var allocations */
 #define attach_chain() var.i16[0] /* glyph to which this attaches to, relative to current glyphs; negative for going back, positive for forward. */
@@ -155,6 +160,22 @@
     return ret;
   }
 
+  void serialize_copy (hb_serialize_context_t *c, const void *base, const Value *values) const
+  {
+    unsigned int format = *this;
+    if (!format) return;
+
+    if (format & xPlacement) c->copy (*values++);
+    if (format & yPlacement) c->copy (*values++);
+    if (format & xAdvance)   c->copy (*values++);
+    if (format & yAdvance)   c->copy (*values++);
+
+    if (format & xPlaDevice) copy_device (c, base, values++);
+    if (format & yPlaDevice) copy_device (c, base, values++);
+    if (format & xAdvDevice) copy_device (c, base, values++);
+    if (format & yAdvDevice) copy_device (c, base, values++);
+  }
+
   private:
   bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base, const Value *values) const
   {
@@ -173,18 +194,41 @@
     return true;
   }
 
-  HB_INTERNAL static OffsetTo<Device>& get_device (Value* value)
-  { return *CastP<OffsetTo<Device>> (value); }
-  HB_INTERNAL static const OffsetTo<Device>& get_device (const Value* value, bool *worked=nullptr)
+  bool copy_device (hb_serialize_context_t *c, const void *base, const Value *src_value) const
   {
+    Value	*dst_value = c->copy (*src_value);
+
+    if (!dst_value) return false;
+    if (*dst_value == 0) return true;
+
+    *dst_value = 0;
+    c->push ();
+    if ((base + get_device (src_value)).copy (c))
+    {
+      c->add_link (*dst_value, c->pop_pack ());
+      return true;
+    }
+    else
+    {
+      c->pop_discard ();
+      return false;
+    }
+  }
+
+  static inline OffsetTo<Device>& get_device (Value* value)
+  {
+    return *static_cast<OffsetTo<Device> *> (value);
+  }
+  static inline const OffsetTo<Device>& get_device (const Value* value, bool *worked=nullptr)
+  {
     if (worked) *worked |= bool (*value);
-    return *CastP<OffsetTo<Device>> (value);
+    return *static_cast<const OffsetTo<Device> *> (value);
   }
 
-  HB_INTERNAL static const HBINT16& get_short (const Value* value, bool *worked=nullptr)
+  static inline const HBINT16& get_short (const Value* value, bool *worked=nullptr)
   {
     if (worked) *worked |= bool (*value);
-    return *CastP<HBINT16> (value);
+    return *reinterpret_cast<const HBINT16 *> (value);
   }
 
   public:
@@ -237,9 +281,10 @@
 };
 
 template<typename Iterator>
-static inline void SinglePos_serialize (hb_serialize_context_t *c,
-					Iterator it,
-					ValueFormat valFormat);
+static void SinglePos_serialize (hb_serialize_context_t *c,
+				 const void *src,
+				 Iterator it,
+				 ValueFormat valFormat);
 
 
 struct AnchorFormat1
@@ -344,8 +389,8 @@
     auto *out = c->embed<AnchorFormat3> (this);
     if (unlikely (!out)) return_trace (nullptr);
 
-    out->xDeviceTable.serialize_copy (c, xDeviceTable, this, out);
-    out->yDeviceTable.serialize_copy (c, yDeviceTable, this, out);
+    out->xDeviceTable.serialize_copy (c, xDeviceTable, this);
+    out->yDeviceTable.serialize_copy (c, yDeviceTable, this);
     return_trace (out);
   }
 
@@ -420,11 +465,33 @@
 			    unsigned int cols, bool *found) const
   {
     *found = false;
-    if (unlikely (row >= rows || col >= cols)) return Null(Anchor);
+    if (unlikely (row >= rows || col >= cols)) return Null (Anchor);
     *found = !matrixZ[row * cols + col].is_null ();
     return this+matrixZ[row * cols + col];
   }
 
+  template <typename Iterator,
+	    hb_requires (hb_is_iterator (Iterator))>
+  bool serialize (hb_serialize_context_t *c,
+		  unsigned                num_rows,
+		  AnchorMatrix const     *offset_matrix,
+		  Iterator                index_iter)
+  {
+    TRACE_SERIALIZE (this);
+    if (!index_iter.len ()) return_trace (false);
+    if (unlikely (!c->extend_min ((*this))))  return_trace (false);
+
+    this->rows = num_rows;
+    for (const unsigned i : index_iter)
+    {
+      auto *offset = c->embed (offset_matrix->matrixZ[i]);
+      if (!offset) return_trace (false);
+      offset->serialize_copy (c, offset_matrix->matrixZ[i], offset_matrix, c->to_bias (this));
+    }
+
+    return_trace (true);
+  }
+
   bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const
   {
     TRACE_SANITIZE (this);
@@ -438,7 +505,6 @@
   }
 
   HBUINT16	rows;			/* Number of rows */
-  protected:
   UnsizedArrayOf<OffsetTo<Anchor>>
 		matrixZ;		/* Matrix of offsets to Anchor tables--
 					 * from beginning of AnchorMatrix table */
@@ -451,6 +517,7 @@
 {
   friend struct MarkArray;
 
+  unsigned get_class () const { return (unsigned) klass; }
   bool sanitize (hb_sanitize_context_t *c, const void *base) const
   {
     TRACE_SANITIZE (this);
@@ -457,6 +524,18 @@
     return_trace (c->check_struct (this) && markAnchor.sanitize (c, base));
   }
 
+  MarkRecord *copy (hb_serialize_context_t *c, const void *base,
+		    unsigned dst_bias, const hb_map_t *klass_mapping) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->embed (this);
+    if (unlikely (!out)) return_trace (nullptr);
+
+    out->klass = klass_mapping->get (klass);
+    out->markAnchor.serialize_copy (c, markAnchor, base, dst_bias);
+    return_trace (out);
+  }
+
   protected:
   HBUINT16	klass;			/* Class defined for this mark */
   OffsetTo<Anchor>
@@ -502,6 +581,20 @@
     return_trace (true);
   }
 
+  template<typename Iterator,
+	   hb_requires (hb_is_source_of (Iterator, MarkRecord))>
+  bool serialize (hb_serialize_context_t *c,
+		  const hb_map_t         *klass_mapping,
+		  const void             *base,
+		  Iterator                it)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    if (unlikely (!c->check_assign (len, it.len ()))) return_trace (false);
+    c->copy_all (it, base, c->to_bias (this), klass_mapping);
+    return_trace (true);
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -517,8 +610,10 @@
   bool intersects (const hb_set_t *glyphs) const
   { return (this+coverage).intersects (glyphs); }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
-  { if (unlikely (!(this+coverage).add_coverage (c->input))) return; }
+  { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; }
 
   const Coverage &get_coverage () const { return this+coverage; }
 
@@ -538,14 +633,19 @@
   template<typename Iterator,
 	   hb_requires (hb_is_iterator (Iterator))>
   void serialize (hb_serialize_context_t *c,
+		  const void *src,
 		  Iterator it,
 		  ValueFormat valFormat)
   {
-    if (unlikely (!c->extend_min (*this))) return;
+    auto out = c->extend_min (*this);
+    if (unlikely (!out)) return;
     if (unlikely (!c->check_assign (valueFormat, valFormat))) return;
 
-    for (const auto &_ : hb_second (*it))
-      c->copy (_);
+    + it
+    | hb_map (hb_second)
+    | hb_apply ([&] (hb_array_t<const Value> _)
+		{ valFormat.serialize_copy (c, src, &_); })
+    ;
 
     auto glyphs =
     + it
@@ -569,7 +669,7 @@
     ;
 
     bool ret = bool (it);
-    SinglePos_serialize (c->serializer, it, valueFormat);
+    SinglePos_serialize (c->serializer, this, it, valueFormat);
     return_trace (ret);
   }
 
@@ -600,8 +700,10 @@
   bool intersects (const hb_set_t *glyphs) const
   { return (this+coverage).intersects (glyphs); }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
-  { if (unlikely (!(this+coverage).add_coverage (c->input))) return; }
+  { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; }
 
   const Coverage &get_coverage () const { return this+coverage; }
 
@@ -625,16 +727,20 @@
   template<typename Iterator,
 	   hb_requires (hb_is_iterator (Iterator))>
   void serialize (hb_serialize_context_t *c,
+		  const void *src,
 		  Iterator it,
 		  ValueFormat valFormat)
   {
-    if (unlikely (!c->extend_min (*this))) return;
+    auto out = c->extend_min (*this);
+    if (unlikely (!out)) return;
     if (unlikely (!c->check_assign (valueFormat, valFormat))) return;
     if (unlikely (!c->check_assign (valueCount, it.len ()))) return;
 
-    for (const auto iter : it)
-      for (const auto &_ : iter.second)
-	c->copy (_);
+    + it
+    | hb_map (hb_second)
+    | hb_apply ([&] (hb_array_t<const Value> _)
+		{ valFormat.serialize_copy (c, src, &_); })
+    ;
 
     auto glyphs =
     + it
@@ -665,7 +771,7 @@
     ;
 
     bool ret = bool (it);
-    SinglePos_serialize (c->serializer, it, valueFormat);
+    SinglePos_serialize (c->serializer, this, it, valueFormat);
     return_trace (ret);
   }
 
@@ -711,6 +817,7 @@
   template<typename Iterator,
 	   hb_requires (hb_is_iterator (Iterator))>
   void serialize (hb_serialize_context_t *c,
+		  const void *src,
 		  Iterator glyph_val_iter_pairs,
 		  ValueFormat valFormat)
   {
@@ -721,9 +828,9 @@
 
     u.format = format;
     switch (u.format) {
-    case 1: u.format1.serialize (c, glyph_val_iter_pairs, valFormat);
+    case 1: u.format1.serialize (c, src, glyph_val_iter_pairs, valFormat);
 	    return;
-    case 2: u.format2.serialize (c, glyph_val_iter_pairs, valFormat);
+    case 2: u.format2.serialize (c, src, glyph_val_iter_pairs, valFormat);
 	    return;
     default:return;
     }
@@ -750,11 +857,12 @@
 };
 
 template<typename Iterator>
-static inline void
+static void
 SinglePos_serialize (hb_serialize_context_t *c,
+		     const void *src,
 		     Iterator it,
 		     ValueFormat valFormat)
-{ c->start_embed<SinglePos> ()->serialize (c, it, valFormat); }
+{ c->start_embed<SinglePos> ()->serialize (c, src, it, valFormat); }
 
 
 struct PairValueRecord
@@ -761,16 +869,30 @@
 {
   friend struct PairSet;
 
+  int cmp (hb_codepoint_t k) const
+  { return secondGlyph.cmp (k); }
+
+  struct serialize_closure_t
+  {
+    const void 		*base;
+    const ValueFormat	*valueFormats;
+    unsigned		len1; /* valueFormats[0].get_len() */
+    const hb_map_t 	*glyph_map;
+  };
+
   bool serialize (hb_serialize_context_t *c,
-                  unsigned length,
-                  const hb_map_t &glyph_map) const
+		  serialize_closure_t *closure) const
   {
     TRACE_SERIALIZE (this);
     auto *out = c->start_embed (*this);
     if (unlikely (!c->extend_min (out))) return_trace (false);
-    
-    out->secondGlyph = glyph_map[secondGlyph];
-    return_trace (c->copy (values, length));
+
+    out->secondGlyph = (*closure->glyph_map)[secondGlyph];
+
+    closure->valueFormats[0].serialize_copy (c, closure->base, &values[0]);
+    closure->valueFormats[1].serialize_copy (c, closure->base, &values[closure->len1]);
+
+    return_trace (true);
   }
 
   protected:
@@ -817,8 +939,8 @@
   }
 
   bool apply (hb_ot_apply_context_t *c,
-		     const ValueFormat *valueFormats,
-		     unsigned int pos) const
+	      const ValueFormat *valueFormats,
+	      unsigned int pos) const
   {
     TRACE_APPLY (this);
     hb_buffer_t *buffer = c->buffer;
@@ -826,40 +948,26 @@
     unsigned int len2 = valueFormats[1].get_len ();
     unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
 
-    unsigned int count = len;
-
-    /* Hand-coded bsearch. */
-    if (unlikely (!count))
-      return_trace (false);
-    hb_codepoint_t x = buffer->info[pos].codepoint;
-    int min = 0, max = (int) count - 1;
-    while (min <= max)
+    const PairValueRecord *record = hb_bsearch (buffer->info[pos].codepoint,
+						&firstPairValueRecord,
+						len,
+						record_size);
+    if (record)
     {
-      int mid = ((unsigned int) min + (unsigned int) max) / 2;
-      const PairValueRecord *record = &StructAtOffset<PairValueRecord> (&firstPairValueRecord, record_size * mid);
-      hb_codepoint_t mid_x = record->secondGlyph;
-      if (x < mid_x)
-	max = mid - 1;
-      else if (x > mid_x)
-	min = mid + 1;
-      else
-      {
-	/* Note the intentional use of "|" instead of short-circuit "||". */
-	if (valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()) |
-	    valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]))
-	  buffer->unsafe_to_break (buffer->idx, pos + 1);
-	if (len2)
-	  pos++;
-	buffer->idx = pos;
-	return_trace (true);
-      }
+      /* Note the intentional use of "|" instead of short-circuit "||". */
+      if (valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()) |
+	  valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]))
+	buffer->unsafe_to_break (buffer->idx, pos + 1);
+      if (len2)
+	pos++;
+      buffer->idx = pos;
+      return_trace (true);
     }
-
     return_trace (false);
   }
 
   bool subset (hb_subset_context_t *c,
-               const ValueFormat valueFormats[2]) const
+	       const ValueFormat valueFormats[2]) const
   {
     TRACE_SUBSET (this);
     auto snap = c->serializer->snapshot ();
@@ -875,12 +983,20 @@
     unsigned len2 = valueFormats[1].get_len ();
     unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
 
+    PairValueRecord::serialize_closure_t closure =
+    {
+      this,
+      valueFormats,
+      len1,
+      &glyph_map
+    };
+
     const PairValueRecord *record = &firstPairValueRecord;
     unsigned count = len, num = 0;
     for (unsigned i = 0; i < count; i++)
     {
-      if (!glyphset.has (record->secondGlyph)) continue;
-      if (record->serialize (c->serializer, len1 + len2, glyph_map)) num++;
+      if (glyphset.has (record->secondGlyph)
+	 && record->serialize (c->serializer, &closure)) num++;
       record = &StructAtOffset<const PairValueRecord> (record, record_size);
     }
 
@@ -891,7 +1007,6 @@
 
   struct sanitize_closure_t
   {
-    const void *base;
     const ValueFormat *valueFormats;
     unsigned int len1; /* valueFormats[0].get_len() */
     unsigned int stride; /* 1 + len1 + len2 */
@@ -908,8 +1023,8 @@
 
     unsigned int count = len;
     const PairValueRecord *record = &firstPairValueRecord;
-    return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride) &&
-		  closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride));
+    return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) &&
+		  closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride));
   }
 
   protected:
@@ -935,9 +1050,11 @@
     ;
   }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    if (unlikely (!(this+coverage).add_coverage (c->input))) return;
+    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
     unsigned int count = pairSet.len;
     for (unsigned int i = 0; i < count; i++)
       (this+pairSet[i]).collect_glyphs (c, valueFormat);
@@ -981,7 +1098,7 @@
 		   auto *o = out->pairSet.serialize_append (c->serializer);
 		   if (unlikely (!o)) return false;
 		   auto snap = c->serializer->snapshot ();
-		   bool ret = o->serialize_subset (c, _, this, out, valueFormat);
+		   bool ret = o->serialize_subset (c, _, this, valueFormat);
 		   if (!ret)
 		   {
 		     out->pairSet.pop ();
@@ -1011,7 +1128,6 @@
     unsigned int len2 = valueFormat[1].get_len ();
     PairSet::sanitize_closure_t closure =
     {
-      this,
       valueFormat,
       len1,
       1 + len1 + len2
@@ -1046,10 +1162,12 @@
 	   (this+classDef2).intersects (glyphs);
   }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    if (unlikely (!(this+coverage).add_coverage (c->input))) return;
-    if (unlikely (!(this+classDef2).add_coverage (c->input))) return;
+    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
+    if (unlikely (!(this+classDef2).collect_coverage (c->input))) return;
   }
 
   const Coverage &get_coverage () const { return this+coverage; }
@@ -1096,32 +1214,33 @@
     out->valueFormat2 = valueFormat2;
 
     hb_map_t klass1_map;
-    out->classDef1.serialize_subset (c, classDef1, this, out, &klass1_map);
+    out->classDef1.serialize_subset (c, classDef1, this, &klass1_map);
     out->class1Count = klass1_map.get_population ();
 
     hb_map_t klass2_map;
-    out->classDef2.serialize_subset (c, classDef2, this, out, &klass2_map);
+    out->classDef2.serialize_subset (c, classDef2, this, &klass2_map);
     out->class2Count = klass2_map.get_population ();
 
-    unsigned record_len = valueFormat1.get_len () + valueFormat2.get_len ();
+    unsigned len1 = valueFormat1.get_len ();
+    unsigned len2 = valueFormat2.get_len ();
 
     + hb_range ((unsigned) class1Count)
     | hb_filter (klass1_map)
     | hb_apply ([&] (const unsigned class1_idx)
-                {
-                  + hb_range ((unsigned) class2Count)
-                  | hb_filter (klass2_map)
-                  | hb_apply ([&] (const unsigned class2_idx)
-                              {
-                                unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * record_len;
-                                for (unsigned i = 0; i < record_len; i++)
-                                  c->serializer->copy (values[idx+i]);
-                              })
-                  ;
-                })
+		{
+		  + hb_range ((unsigned) class2Count)
+		  | hb_filter (klass2_map)
+		  | hb_apply ([&] (const unsigned class2_idx)
+			      {
+				unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2);
+				valueFormat1.serialize_copy (c->serializer, this, &values[idx]);
+				valueFormat2.serialize_copy (c->serializer, this, &values[idx + len1]);
+			      })
+		  ;
+		})
     ;
 
-    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_set_t &glyphset = *c->plan->_glyphset_gsub;
     const hb_map_t &glyph_map = *c->plan->glyph_map;
 
     auto it =
@@ -1217,16 +1336,14 @@
     return_trace (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base));
   }
 
-  EntryExitRecord* copy (hb_serialize_context_t *c,
-			 const void *src_base,
-			 const void *dst_base) const
+  EntryExitRecord* copy (hb_serialize_context_t *c, const void *base) const
   {
     TRACE_SERIALIZE (this);
     auto *out = c->embed (this);
     if (unlikely (!out)) return_trace (nullptr);
 
-    out->entryAnchor.serialize_copy (c, entryAnchor, src_base, dst_base);
-    out->exitAnchor.serialize_copy (c, exitAnchor, src_base, dst_base);
+    out->entryAnchor.serialize_copy (c, entryAnchor, base);
+    out->exitAnchor.serialize_copy (c, exitAnchor, base);
     return_trace (out);
   }
 
@@ -1251,8 +1368,10 @@
   bool intersects (const hb_set_t *glyphs) const
   { return (this+coverage).intersects (glyphs); }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
-  { if (unlikely (!(this+coverage).add_coverage (c->input))) return; }
+  { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; }
 
   const Coverage &get_coverage () const { return this+coverage; }
 
@@ -1359,9 +1478,7 @@
 
   template <typename Iterator,
 	    hb_requires (hb_is_iterator (Iterator))>
-  void serialize (hb_serialize_context_t *c,
-		  Iterator it,
-		  const void *src_base)
+  void serialize (hb_serialize_context_t *c, Iterator it, const void *base)
   {
     if (unlikely (!c->extend_min ((*this)))) return;
     this->format = 1;
@@ -1369,7 +1486,7 @@
 
     for (const EntryExitRecord& entry_record : + it
 					       | hb_map (hb_second))
-      c->copy (entry_record, src_base, this);
+      c->copy (entry_record, base);
 
     auto glyphs =
     + it
@@ -1444,6 +1561,29 @@
 					 * mark-minor--
 					 * ordered by class--zero-based. */
 
+static void Markclass_closure_and_remap_indexes (const Coverage  &mark_coverage,
+						 const MarkArray &mark_array,
+						 const hb_set_t  &glyphset,
+						 hb_map_t*        klass_mapping /* INOUT */)
+{
+  hb_set_t orig_classes;
+
+  + hb_zip (mark_coverage, mark_array)
+  | hb_filter (glyphset, hb_first)
+  | hb_map (hb_second)
+  | hb_map (&MarkRecord::get_class)
+  | hb_sink (orig_classes)
+  ;
+
+  unsigned idx = 0;
+  for (auto klass : orig_classes.iter ())
+  {
+    if (klass_mapping->has (klass)) continue;
+    klass_mapping->set (klass, idx);
+    idx++;
+  }
+}
+
 struct MarkBasePosFormat1
 {
   bool intersects (const hb_set_t *glyphs) const
@@ -1450,10 +1590,12 @@
   { return (this+markCoverage).intersects (glyphs) &&
 	   (this+baseCoverage).intersects (glyphs); }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    if (unlikely (!(this+markCoverage).add_coverage (c->input))) return;
-    if (unlikely (!(this+baseCoverage).add_coverage (c->input))) return;
+    if (unlikely (!(this+markCoverage).collect_coverage (c->input))) return;
+    if (unlikely (!(this+baseCoverage).collect_coverage (c->input))) return;
   }
 
   const Coverage &get_coverage () const { return this+markCoverage; }
@@ -1501,8 +1643,70 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    // TODO(subset)
-    return_trace (false);
+    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    out->format = format;
+
+    hb_map_t klass_mapping;
+    Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, glyphset, &klass_mapping);
+
+    if (!klass_mapping.get_population ()) return_trace (false);
+    out->classCount = klass_mapping.get_population ();
+
+    auto mark_iter =
+    + hb_zip (this+markCoverage, this+markArray)
+    | hb_filter (glyphset, hb_first)
+    ;
+
+    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+    + mark_iter
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+
+    if (!out->markCoverage.serialize (c->serializer, out)
+			  .serialize (c->serializer, new_coverage.iter ()))
+      return_trace (false);
+
+    out->markArray.serialize (c->serializer, out)
+		  .serialize (c->serializer, &klass_mapping, &(this+markArray), + mark_iter
+										| hb_map (hb_second));
+
+    unsigned basecount = (this+baseArray).rows;
+    auto base_iter =
+    + hb_zip (this+baseCoverage, hb_range (basecount))
+    | hb_filter (glyphset, hb_first)
+    ;
+
+    new_coverage.reset ();
+    + base_iter
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+
+    if (!out->baseCoverage.serialize (c->serializer, out)
+			  .serialize (c->serializer, new_coverage.iter ()))
+      return_trace (false);
+
+    hb_sorted_vector_t<unsigned> base_indexes;
+    for (const unsigned row : + base_iter
+			      | hb_map (hb_second))
+    {
+      + hb_range ((unsigned) classCount)
+      | hb_filter (klass_mapping)
+      | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
+      | hb_sink (base_indexes)
+      ;
+    }
+    out->baseArray.serialize (c->serializer, out)
+		  .serialize (c->serializer, base_iter.len (), &(this+baseArray), base_indexes.iter ());
+
+    return_trace (true);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -1571,10 +1775,12 @@
   { return (this+markCoverage).intersects (glyphs) &&
 	   (this+ligatureCoverage).intersects (glyphs); }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    if (unlikely (!(this+markCoverage).add_coverage (c->input))) return;
-    if (unlikely (!(this+ligatureCoverage).add_coverage (c->input))) return;
+    if (unlikely (!(this+markCoverage).collect_coverage (c->input))) return;
+    if (unlikely (!(this+ligatureCoverage).collect_coverage (c->input))) return;
   }
 
   const Coverage &get_coverage () const { return this+markCoverage; }
@@ -1691,10 +1897,12 @@
   { return (this+mark1Coverage).intersects (glyphs) &&
 	   (this+mark2Coverage).intersects (glyphs); }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    if (unlikely (!(this+mark1Coverage).add_coverage (c->input))) return;
-    if (unlikely (!(this+mark2Coverage).add_coverage (c->input))) return;
+    if (unlikely (!(this+mark1Coverage).collect_coverage (c->input))) return;
+    if (unlikely (!(this+mark2Coverage).collect_coverage (c->input))) return;
   }
 
   const Coverage &get_coverage () const { return this+mark1Coverage; }
@@ -1746,8 +1954,70 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    // TODO(subset)
-    return_trace (false);
+    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    out->format = format;
+
+    hb_map_t klass_mapping;
+    Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, glyphset, &klass_mapping);
+
+    if (!klass_mapping.get_population ()) return_trace (false);
+    out->classCount = klass_mapping.get_population ();
+
+    auto mark1_iter =
+    + hb_zip (this+mark1Coverage, this+mark1Array)
+    | hb_filter (glyphset, hb_first)
+    ;
+
+    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+    + mark1_iter
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+
+    if (!out->mark1Coverage.serialize (c->serializer, out)
+			   .serialize (c->serializer, new_coverage.iter ()))
+      return_trace (false);
+
+    out->mark1Array.serialize (c->serializer, out)
+		   .serialize (c->serializer, &klass_mapping, &(this+mark1Array), + mark1_iter
+										  | hb_map (hb_second));
+//////
+    unsigned mark2count = (this+mark2Array).rows;
+    auto mark2_iter =
+    + hb_zip (this+mark2Coverage, hb_range (mark2count))
+    | hb_filter (glyphset, hb_first)
+    ;
+
+    new_coverage.reset ();
+    + mark2_iter
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+
+    if (!out->mark2Coverage.serialize (c->serializer, out)
+			   .serialize (c->serializer, new_coverage.iter ()))
+      return_trace (false);
+
+    hb_sorted_vector_t<unsigned> mark2_indexes;
+    for (const unsigned row : + mark2_iter
+			      | hb_map (hb_second))
+    {
+      + hb_range ((unsigned) classCount)
+      | hb_filter (klass_mapping)
+      | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
+      | hb_sink (mark2_indexes)
+      ;
+    }
+    out->mark2Array.serialize (c->serializer, out)
+		   .serialize (c->serializer, mark2_iter.len (), &(this+mark2Array), mark2_indexes.iter ());
+
+    return_trace (true);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -1853,6 +2123,12 @@
     }
   }
 
+  bool intersects (const hb_set_t *glyphs, unsigned int lookup_type) const
+  {
+    hb_intersects_context_t c (glyphs);
+    return dispatch (&c, lookup_type);
+  }
+
   protected:
   union {
   SinglePos		single;
@@ -1897,18 +2173,37 @@
   hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
   { return dispatch (c); }
 
+  hb_closure_lookups_context_t::return_t closure_lookups (hb_closure_lookups_context_t *c, unsigned this_index) const
+  {
+    if (c->is_lookup_visited (this_index))
+      return hb_closure_lookups_context_t::default_return_value ();
+
+    c->set_lookup_visited (this_index);
+    if (!intersects (c->glyphs))
+    {
+      c->set_lookup_inactive (this_index);
+      return hb_closure_lookups_context_t::default_return_value ();
+    }
+    c->set_recurse_func (dispatch_closure_lookups_recurse_func);
+
+    hb_closure_lookups_context_t::return_t ret = dispatch (c);
+    return ret;
+  }
+
   template <typename set_t>
-  void add_coverage (set_t *glyphs) const
+  void collect_coverage (set_t *glyphs) const
   {
-    hb_add_coverage_context_t<set_t> c (glyphs);
+    hb_collect_coverage_context_t<set_t> c (glyphs);
     dispatch (&c);
   }
 
-  HB_INTERNAL static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
+  static inline bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
 
   template <typename context_t>
   static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
 
+  HB_INTERNAL static hb_closure_lookups_context_t::return_t dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned this_index);
+
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   { return Lookup::dispatch<SubTable> (c, hb_forward<Ts> (ds)...); }
@@ -1930,7 +2225,7 @@
   static constexpr hb_tag_t tableTag = HB_OT_TAG_GPOS;
 
   const PosLookup& get_lookup (unsigned int i) const
-  { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); }
+  { return static_cast<const PosLookup &> (GSUBGPOS::get_lookup (i)); }
 
   static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
   static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buffer);
@@ -1937,7 +2232,10 @@
   static inline void position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer);
 
   bool subset (hb_subset_context_t *c) const
-  { return GSUBGPOS::subset<PosLookup> (c); }
+  {
+    hb_subset_layout_context_t l (c, tableTag, c->plan->gpos_lookups, c->plan->gpos_features);
+    return GSUBGPOS::subset<PosLookup> (&l);
+  }
 
   bool sanitize (hb_sanitize_context_t *c) const
   { return GSUBGPOS::sanitize<PosLookup> (c); }
@@ -2060,13 +2358,20 @@
 
 #ifndef HB_NO_OT_LAYOUT
 template <typename context_t>
-/*static*/ inline typename context_t::return_t PosLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
+/*static*/ typename context_t::return_t PosLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
 {
   const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (lookup_index);
   return l.dispatch (c);
 }
-/*static*/ inline bool PosLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index)
+
+/*static*/ inline hb_closure_lookups_context_t::return_t PosLookup::dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned this_index)
 {
+  const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (this_index);
+  return l.closure_lookups (c, this_index);
+}
+
+/*static*/ bool PosLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index)
+{
   const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (lookup_index);
   unsigned int saved_lookup_props = c->lookup_props;
   unsigned int saved_lookup_index = c->lookup_index;

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	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -37,8 +37,8 @@
 typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> hb_codepoint_pair_t;
 
 template<typename Iterator>
-static inline void SingleSubst_serialize (hb_serialize_context_t *c,
-					  Iterator it);
+static void SingleSubst_serialize (hb_serialize_context_t *c,
+				   Iterator it);
 
 
 struct SingleSubstFormat1
@@ -56,9 +56,11 @@
     ;
   }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    if (unlikely (!(this+coverage).add_coverage (c->input))) return;
+    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
     unsigned d = deltaGlyphID;
     + hb_iter (this+coverage)
     | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; })
@@ -154,9 +156,11 @@
     ;
   }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    if (unlikely (!(this+coverage).add_coverage (c->input))) return;
+    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
     + hb_zip (this+coverage, substitute)
     | hb_map (hb_second)
     | hb_sink (c->output)
@@ -255,9 +259,8 @@
     if (glyphs)
     {
       format = 1;
-      auto get_delta = [=] (hb_codepoint_pair_t _) {
-			 return (unsigned) (_.second - _.first) & 0xFFFF;
-		       };
+      auto get_delta = [=] (hb_codepoint_pair_t _)
+		       { return (unsigned) (_.second - _.first) & 0xFFFF; };
       delta = get_delta (*glyphs);
       if (!hb_all (++(+glyphs), delta, get_delta)) format = 2;
     }
@@ -293,7 +296,7 @@
 };
 
 template<typename Iterator>
-static inline void
+static void
 SingleSubst_serialize (hb_serialize_context_t *c,
 		       Iterator it)
 { c->start_embed<SingleSubst> ()->serialize (c, it); }
@@ -359,9 +362,9 @@
     if (!intersects (&glyphset)) return_trace (false);
 
     auto it =
-      + hb_iter (substitute)
-      | hb_map (glyph_map)
-      ;
+    + hb_iter (substitute)
+    | hb_map (glyph_map)
+    ;
 
     auto *out = c->serializer->start_embed (*this);
     return_trace (out->serialize (c->serializer, it));
@@ -395,9 +398,11 @@
     ;
   }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    if (unlikely (!(this+coverage).add_coverage (c->input))) return;
+    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
     + hb_zip (this+coverage, sequence)
     | hb_map (hb_second)
     | hb_map (hb_add (this))
@@ -452,7 +457,7 @@
     hb_sorted_vector_t<hb_codepoint_t> new_coverage;
     + hb_zip (this+coverage, sequence)
     | hb_filter (glyphset, hb_first)
-    | hb_filter (subset_offset_array (c, out->sequence, this, out), hb_second)
+    | hb_filter (subset_offset_array (c, out->sequence, this), hb_second)
     | hb_map (hb_first)
     | hb_map (glyph_map)
     | hb_sink (new_coverage)
@@ -599,6 +604,7 @@
   void closure (hb_closure_context_t *c) const
   {
     + hb_zip (this+coverage, alternateSet)
+    | hb_filter (c->glyphs, hb_first)
     | hb_map (hb_second)
     | hb_map (hb_add (this))
     | hb_apply ([c] (const AlternateSet &_) { _.closure (c); })
@@ -605,9 +611,11 @@
     ;
   }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    if (unlikely (!(this+coverage).add_coverage (c->input))) return;
+    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
     + hb_zip (this+coverage, alternateSet)
     | hb_map (hb_second)
     | hb_map (hb_add (this))
@@ -662,7 +670,7 @@
     hb_sorted_vector_t<hb_codepoint_t> new_coverage;
     + hb_zip (this+coverage, alternateSet)
     | hb_filter (glyphset, hb_first)
-    | hb_filter (subset_offset_array (c, out->alternateSet, this, out), hb_second)
+    | hb_filter (subset_offset_array (c, out->alternateSet, this), hb_second)
     | hb_map (hb_first)
     | hb_map (glyph_map)
     | hb_sink (new_coverage)
@@ -922,7 +930,7 @@
     if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     + hb_iter (ligature)
-    | hb_filter (subset_offset_array (c, out->ligature, this, out))
+    | hb_filter (subset_offset_array (c, out->ligature, this))
     | hb_drain
     ;
     return_trace (bool (out->ligature));
@@ -966,9 +974,11 @@
     ;
   }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    if (unlikely (!(this+coverage).add_coverage (c->input))) return;
+    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
 
     + hb_zip (this+coverage, ligatureSet)
     | hb_map (hb_second)
@@ -992,7 +1002,7 @@
   {
     TRACE_APPLY (this);
 
-    unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+    unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint);
     if (likely (index == NOT_COVERED)) return_trace (false);
 
     const LigatureSet &lig_set = this+ligatureSet[index];
@@ -1036,7 +1046,7 @@
     hb_sorted_vector_t<hb_codepoint_t> new_coverage;
     + hb_zip (this+coverage, ligatureSet)
     | hb_filter (glyphset, hb_first)
-    | hb_filter (subset_offset_array (c, out->ligatureSet, this, out), hb_second)
+    | hb_filter (subset_offset_array (c, out->ligatureSet, this), hb_second)
     | hb_map (hb_first)
     | hb_map (glyph_map)
     | hb_sink (new_coverage)
@@ -1114,7 +1124,6 @@
 struct ExtensionSubst : Extension<ExtensionSubst>
 {
   typedef struct SubstLookupSubTable SubTable;
-
   bool is_reverse () const;
 };
 
@@ -1157,20 +1166,22 @@
     ;
   }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    if (unlikely (!(this+coverage).add_coverage (c->input))) return;
+    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
 
     unsigned int count;
 
     count = backtrack.len;
     for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!(this+backtrack[i]).add_coverage (c->before))) return;
+      if (unlikely (!(this+backtrack[i]).collect_coverage (c->before))) return;
 
     const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
     count = lookahead.len;
     for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!(this+lookahead[i]).add_coverage (c->after))) return;
+      if (unlikely (!(this+lookahead[i]).collect_coverage (c->after))) return;
 
     const ArrayOf<HBGlyphID> &substitute = StructAfter<ArrayOf<HBGlyphID>> (lookahead);
     count = substitute.len;
@@ -1188,7 +1199,7 @@
     if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL))
       return_trace (false); /* No chaining to this type */
 
-    unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+    unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint);
     if (likely (index == NOT_COVERED)) return_trace (false);
 
     const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
@@ -1313,6 +1324,12 @@
     }
   }
 
+  bool intersects (const hb_set_t *glyphs, unsigned int lookup_type) const
+  {
+    hb_intersects_context_t c (glyphs);
+    return dispatch (&c, lookup_type);
+  }
+
   protected:
   union {
   SingleSubst			single;
@@ -1336,7 +1353,7 @@
   const SubTable& get_subtable (unsigned int i) const
   { return Lookup::get_subtable<SubTable> (i); }
 
-  HB_INTERNAL static bool lookup_type_is_reverse (unsigned int lookup_type)
+  static inline bool lookup_type_is_reverse (unsigned int lookup_type)
   { return lookup_type == SubTable::ReverseChainSingle; }
 
   bool is_reverse () const
@@ -1343,7 +1360,7 @@
   {
     unsigned int type = get_type ();
     if (unlikely (type == SubTable::Extension))
-      return CastR<ExtensionSubst> (get_subtable(0)).is_reverse ();
+      return reinterpret_cast<const ExtensionSubst &> (get_subtable (0)).is_reverse ();
     return lookup_type_is_reverse (type);
   }
 
@@ -1373,6 +1390,24 @@
     return ret;
   }
 
+  hb_closure_lookups_context_t::return_t closure_lookups (hb_closure_lookups_context_t *c, unsigned this_index) const
+  {
+    if (c->is_lookup_visited (this_index))
+      return hb_closure_lookups_context_t::default_return_value ();
+
+    c->set_lookup_visited (this_index);
+    if (!intersects (c->glyphs))
+    {
+      c->set_lookup_inactive (this_index);
+      return hb_closure_lookups_context_t::default_return_value ();
+    }
+
+    c->set_recurse_func (dispatch_closure_lookups_recurse_func);
+
+    hb_closure_lookups_context_t::return_t ret = dispatch (c);
+    return ret;
+  }
+
   hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     c->set_recurse_func (dispatch_recurse_func<hb_collect_glyphs_context_t>);
@@ -1380,9 +1415,9 @@
   }
 
   template <typename set_t>
-  void add_coverage (set_t *glyphs) const
+  void collect_coverage (set_t *glyphs) const
   {
-    hb_add_coverage_context_t<set_t> c (glyphs);
+    hb_collect_coverage_context_t<set_t> c (glyphs);
     dispatch (&c);
   }
 
@@ -1394,7 +1429,7 @@
       return dispatch (c);
   }
 
-  HB_INTERNAL static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
+  static inline bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
 
   SubTable& serialize_subtable (hb_serialize_context_t *c,
 				unsigned int i)
@@ -1461,9 +1496,9 @@
   }
 
   template <typename context_t>
-  HB_INTERNAL static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
+  static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
 
-  HB_INTERNAL static hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index)
+  static inline hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index)
   {
     if (!c->should_visit_lookup (lookup_index))
       return hb_empty_t ();
@@ -1478,6 +1513,8 @@
     return ret;
   }
 
+  HB_INTERNAL static hb_closure_lookups_context_t::return_t dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned lookup_index);
+
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   { return Lookup::dispatch<SubTable> (c, hb_forward<Ts> (ds)...); }
@@ -1499,10 +1536,13 @@
   static constexpr hb_tag_t tableTag = HB_OT_TAG_GSUB;
 
   const SubstLookup& get_lookup (unsigned int i) const
-  { return CastR<SubstLookup> (GSUBGPOS::get_lookup (i)); }
+  { return static_cast<const SubstLookup &> (GSUBGPOS::get_lookup (i)); }
 
   bool subset (hb_subset_context_t *c) const
-  { return GSUBGPOS::subset<SubstLookup> (c); }
+  {
+    hb_subset_layout_context_t l (c, tableTag, c->plan->gsub_lookups, c->plan->gsub_features);
+    return GSUBGPOS::subset<SubstLookup> (&l);
+  }
 
   bool sanitize (hb_sanitize_context_t *c) const
   { return GSUBGPOS::sanitize<SubstLookup> (c); }
@@ -1522,19 +1562,23 @@
 #ifndef HB_NO_OT_LAYOUT
 /*static*/ inline bool ExtensionSubst::is_reverse () const
 {
-  unsigned int type = get_type ();
-  if (unlikely (type == SubTable::Extension))
-    return CastR<ExtensionSubst> (get_subtable<SubTable>()).is_reverse ();
-  return SubstLookup::lookup_type_is_reverse (type);
+  return SubstLookup::lookup_type_is_reverse (get_type ());
 }
 template <typename context_t>
-/*static*/ inline typename context_t::return_t SubstLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
+/*static*/ typename context_t::return_t SubstLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
 {
   const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (lookup_index);
   return l.dispatch (c);
 }
-/*static*/ inline bool SubstLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index)
+
+/*static*/ inline hb_closure_lookups_context_t::return_t SubstLookup::dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned this_index)
 {
+  const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (this_index);
+  return l.closure_lookups (c, this_index);
+}
+
+/*static*/ bool SubstLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index)
+{
   const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (lookup_index);
   unsigned int saved_lookup_props = c->lookup_props;
   unsigned int saved_lookup_index = c->lookup_index;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -76,10 +76,17 @@
     nesting_level_left++;
   }
 
+  bool lookup_limit_exceeded ()
+  { return lookup_count > HB_MAX_LOOKUP_INDICES; }
+
   bool should_visit_lookup (unsigned int lookup_index)
   {
+    if (lookup_count++ > HB_MAX_LOOKUP_INDICES)
+      return false;
+
     if (is_lookup_done (lookup_index))
       return false;
+
     done_lookups->set (lookup_index, glyphs->get_population ());
     return true;
   }
@@ -106,7 +113,9 @@
 			  recurse_func (nullptr),
 			  nesting_level_left (nesting_level_left_),
 			  debug_depth (0),
-			  done_lookups (done_lookups_) {}
+			  done_lookups (done_lookups_),
+			  lookup_count (0)
+  {}
 
   ~hb_closure_context_t () { flush (); }
 
@@ -114,6 +123,7 @@
 
   void flush ()
   {
+    hb_set_del_range (output, face->get_num_glyphs (), hb_set_get_max (output));	/* Remove invalid glyphs. */
     hb_set_union (glyphs, output);
     hb_set_clear (output);
   }
@@ -120,9 +130,77 @@
 
   private:
   hb_map_t *done_lookups;
+  unsigned int lookup_count;
 };
 
+struct hb_closure_lookups_context_t :
+       hb_dispatch_context_t<hb_closure_lookups_context_t, hb_empty_t, 0>
+{
+  const char *get_name () { return "CLOSURE_LOOKUPS"; }
+  typedef return_t (*recurse_func_t) (hb_closure_lookups_context_t *c, unsigned lookup_index);
+  template <typename T>
+  return_t dispatch (const T &obj) { obj.closure_lookups (this); return hb_empty_t (); }
+  static return_t default_return_value () { return hb_empty_t (); }
+  void recurse (unsigned lookup_index)
+  {
+    if (unlikely (nesting_level_left == 0 || !recurse_func))
+      return;
 
+    /* Return if new lookup was recursed to before. */
+    if (is_lookup_visited (lookup_index))
+      return;
+
+    set_lookup_visited (lookup_index);
+    nesting_level_left--;
+    recurse_func (this, lookup_index);
+    nesting_level_left++;
+  }
+
+  void set_lookup_visited (unsigned lookup_index)
+  { visited_lookups->add (lookup_index); }
+
+  void set_lookup_inactive (unsigned lookup_index)
+  { inactive_lookups->add (lookup_index); }
+
+  bool lookup_limit_exceeded ()
+  { return lookup_count > HB_MAX_LOOKUP_INDICES; }
+
+  bool is_lookup_visited (unsigned lookup_index)
+  {
+    if (lookup_count++ > HB_MAX_LOOKUP_INDICES)
+      return true;
+
+    return visited_lookups->has (lookup_index);
+  }
+
+  hb_face_t *face;
+  const hb_set_t *glyphs;
+  recurse_func_t recurse_func;
+  unsigned int nesting_level_left;
+  unsigned int debug_depth;
+
+  hb_closure_lookups_context_t (hb_face_t *face_,
+				const hb_set_t *glyphs_,
+				hb_set_t *visited_lookups_,
+				hb_set_t *inactive_lookups_,
+				unsigned nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
+				face (face_),
+				glyphs (glyphs_),
+				recurse_func (nullptr),
+				nesting_level_left (nesting_level_left_),
+				debug_depth (0),
+				visited_lookups (visited_lookups_),
+				inactive_lookups (inactive_lookups_),
+				lookup_count (0) {}
+
+  void set_recurse_func (recurse_func_t func) { recurse_func = func; }
+
+  private:
+  hb_set_t *visited_lookups;
+  hb_set_t *inactive_lookups;
+  unsigned int lookup_count;
+};
+
 struct hb_would_apply_context_t :
        hb_dispatch_context_t<hb_would_apply_context_t, bool, 0>
 {
@@ -229,23 +307,23 @@
 
 
 template <typename set_t>
-struct hb_add_coverage_context_t :
-       hb_dispatch_context_t<hb_add_coverage_context_t<set_t>, const Coverage &, HB_DEBUG_GET_COVERAGE>
+struct hb_collect_coverage_context_t :
+       hb_dispatch_context_t<hb_collect_coverage_context_t<set_t>, const Coverage &, HB_DEBUG_GET_COVERAGE>
 {
   const char *get_name () { return "GET_COVERAGE"; }
   typedef const Coverage &return_t;
   template <typename T>
   return_t dispatch (const T &obj) { return obj.get_coverage (); }
-  static return_t default_return_value () { return Null(Coverage); }
+  static return_t default_return_value () { return Null (Coverage); }
   bool stop_sublookup_iteration (return_t r) const
   {
-    r.add_coverage (set);
+    r.collect_coverage (set);
     return false;
   }
 
-  hb_add_coverage_context_t (set_t *set_) :
-			    set (set_),
-			    debug_depth (0) {}
+  hb_collect_coverage_context_t (set_t *set_) :
+				   set (set_),
+				   debug_depth (0) {}
 
   set_t *set;
   unsigned int debug_depth;
@@ -355,7 +433,7 @@
     }
 
     void reset (unsigned int start_index_,
-		       unsigned int num_items_)
+		unsigned int num_items_)
     {
       idx = start_index_;
       num_items = num_items_;
@@ -363,7 +441,11 @@
       matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
     }
 
-    void reject () { num_items++; match_glyph_data--; }
+    void reject ()
+    {
+      num_items++;
+      if (match_glyph_data) match_glyph_data--;
+    }
 
     matcher_t::may_skip_t
     may_skip (const hb_glyph_info_t &info) const
@@ -487,7 +569,7 @@
 #ifndef HB_NO_OT_LAYOUT
 			      *face->table.GDEF->table
 #else
-			      Null(GDEF)
+			      Null (GDEF)
 #endif
 			     ),
 			var_store (gdef.get_var_store ()),
@@ -563,17 +645,17 @@
     return true;
   }
 
-  void _set_glyph_props (hb_codepoint_t glyph_index,
-			  unsigned int class_guess = 0,
-			  bool ligature = false,
-			  bool component = false) const
+  void _set_glyph_class (hb_codepoint_t glyph_index,
+			 unsigned int class_guess = 0,
+			 bool ligature = false,
+			 bool component = false) const
   {
-    unsigned int add_in = _hb_glyph_info_get_glyph_props (&buffer->cur()) &
-			  HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
-    add_in |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
+    unsigned int props = _hb_glyph_info_get_glyph_props (&buffer->cur());
+
+    props |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
     if (ligature)
     {
-      add_in |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
+      props |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
       /* In the only place that the MULTIPLIED bit is used, Uniscribe
        * seems to only care about the "last" transformation between
        * Ligature and Multiple substitutions.  Ie. if you ligate, expand,
@@ -580,36 +662,39 @@
        * and ligate again, it forgives the multiplication and acts as
        * if only ligation happened.  As such, clear MULTIPLIED bit.
        */
-      add_in &= ~HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
+      props &= ~HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
     }
     if (component)
-      add_in |= HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
+      props |= HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
+
     if (likely (has_glyph_classes))
-      _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | gdef.get_glyph_props (glyph_index));
+      props = (props & ~HB_OT_LAYOUT_GLYPH_PROPS_CLASS_MASK) | gdef.get_glyph_props (glyph_index);
     else if (class_guess)
-      _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | class_guess);
+      props = (props & ~HB_OT_LAYOUT_GLYPH_PROPS_CLASS_MASK) | class_guess;
+
+    _hb_glyph_info_set_glyph_props (&buffer->cur(), props);
   }
 
   void replace_glyph (hb_codepoint_t glyph_index) const
   {
-    _set_glyph_props (glyph_index);
+    _set_glyph_class (glyph_index);
     buffer->replace_glyph (glyph_index);
   }
   void replace_glyph_inplace (hb_codepoint_t glyph_index) const
   {
-    _set_glyph_props (glyph_index);
+    _set_glyph_class (glyph_index);
     buffer->cur().codepoint = glyph_index;
   }
   void replace_glyph_with_ligature (hb_codepoint_t glyph_index,
-					   unsigned int class_guess) const
+				    unsigned int class_guess) const
   {
-    _set_glyph_props (glyph_index, class_guess, true);
+    _set_glyph_class (glyph_index, class_guess, true);
     buffer->replace_glyph (glyph_index);
   }
   void output_glyph_for_component (hb_codepoint_t glyph_index,
-					  unsigned int class_guess) const
+				   unsigned int class_guess) const
   {
-    _set_glyph_props (glyph_index, class_guess, false, true);
+    _set_glyph_class (glyph_index, class_guess, false, true);
     buffer->output_glyph (glyph_index);
   }
 };
@@ -619,7 +704,7 @@
        hb_dispatch_context_t<hb_get_subtables_context_t, hb_empty_t, HB_DEBUG_APPLY>
 {
   template <typename Type>
-  HB_INTERNAL static bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c)
+  static inline bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c)
   {
     const Type *typed_obj = (const Type *) obj;
     return typed_obj->apply (c);
@@ -635,7 +720,7 @@
       obj = &obj_;
       apply_func = apply_func_;
       digest.init ();
-      obj_.get_coverage ().add_coverage (&digest);
+      obj_.get_coverage ().collect_coverage (&digest);
     }
 
     bool apply (OT::hb_ot_apply_context_t *c) const
@@ -725,12 +810,12 @@
 static inline void collect_class (hb_set_t *glyphs, const HBUINT16 &value, const void *data)
 {
   const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
-  class_def.add_class (glyphs, value);
+  class_def.collect_class (glyphs, value);
 }
 static inline void collect_coverage (hb_set_t *glyphs, const HBUINT16 &value, const void *data)
 {
   const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
-  (data+coverage).add_coverage (glyphs);
+  (data+coverage).collect_coverage (glyphs);
 }
 static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED,
 				  hb_set_t *glyphs,
@@ -991,18 +1076,19 @@
     buffer->idx++;
   }
 
-  if (!is_mark_ligature && last_lig_id) {
+  if (!is_mark_ligature && last_lig_id)
+  {
     /* Re-adjust components for any marks following. */
-    for (unsigned int i = buffer->idx; i < buffer->len; i++) {
-      if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) {
-	unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]);
-	if (!this_comp)
-	  break;
-	unsigned int new_lig_comp = components_so_far - last_num_components +
-				    hb_min (this_comp, last_num_components);
-	_hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp);
-      } else
-	break;
+    for (unsigned i = buffer->idx; i < buffer->len; ++i)
+    {
+      if (last_lig_id != _hb_glyph_info_get_lig_id (&buffer->info[i])) break;
+
+      unsigned this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]);
+      if (!this_comp) break;
+
+      unsigned new_lig_comp = components_so_far - last_num_components +
+			      hb_min (this_comp, last_num_components);
+      _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp);
     }
   }
   return_trace (true);
@@ -1057,6 +1143,17 @@
 
 struct LookupRecord
 {
+  LookupRecord* copy (hb_serialize_context_t *c,
+		      const hb_map_t         *lookup_map)
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->embed (*this);
+    if (unlikely (!out)) return_trace (nullptr);
+
+    out->lookupListIndex = hb_map_get (lookup_map, lookupListIndex);
+    return_trace (out);
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -1303,6 +1400,8 @@
 
   void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
   {
+    if (unlikely (c->lookup_limit_exceeded ())) return;
+
     const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
 						       (inputZ.as_array ((inputCount ? inputCount - 1 : 0)));
     context_closure_lookup (c,
@@ -1311,6 +1410,15 @@
 			    lookup_context);
   }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const
+  {
+    if (unlikely (c->lookup_limit_exceeded ())) return;
+
+    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
+						       (inputZ.as_array (inputCount ? inputCount - 1 : 0));
+    recurse_lookups (c, lookupCount, lookupRecord.arrayZ);
+  }
+
   void collect_glyphs (hb_collect_glyphs_context_t *c,
 		       ContextCollectGlyphsLookupContext &lookup_context) const
   {
@@ -1359,7 +1467,7 @@
 					 * glyph */
   HBUINT16	lookupCount;		/* Number of LookupRecords */
   UnsizedArrayOf<HBUINT16>
- 		inputZ;			/* Array of match inputs--start with
+		inputZ;			/* Array of match inputs--start with
 					 * second glyph */
 /*UnsizedArrayOf<LookupRecord>
 		lookupRecordX;*/	/* Array of LookupRecords--in
@@ -1384,6 +1492,8 @@
   void closure (hb_closure_context_t *c,
 		ContextClosureLookupContext &lookup_context) const
   {
+    if (unlikely (c->lookup_limit_exceeded ())) return;
+
     return
     + hb_iter (rule)
     | hb_map (hb_add (this))
@@ -1391,6 +1501,17 @@
     ;
   }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const
+  {
+    if (unlikely (c->lookup_limit_exceeded ())) return;
+
+    return
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const Rule &_) { _.closure_lookups (c); })
+    ;
+  }
+
   void collect_glyphs (hb_collect_glyphs_context_t *c,
 		       ContextCollectGlyphsLookupContext &lookup_context) const
   {
@@ -1474,9 +1595,17 @@
     ;
   }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const
+  {
+    + hb_iter (ruleSet)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const RuleSet &_) { _.closure_lookups (c); })
+    ;
+  }
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    (this+coverage).add_coverage (c->input);
+    (this+coverage).collect_coverage (c->input);
 
     struct ContextCollectGlyphsLookupContext lookup_context = {
       {collect_glyph},
@@ -1588,9 +1717,17 @@
     ;
   }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const
+  {
+    + hb_iter (ruleSet)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const RuleSet &_) { _.closure_lookups (c); })
+    ;
+  }
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    (this+coverage).add_coverage (c->input);
+    (this+coverage).collect_coverage (c->input);
 
     const ClassDef &class_def = this+classDef;
     struct ContextCollectGlyphsLookupContext lookup_context = {
@@ -1695,9 +1832,15 @@
 			    lookup_context);
   }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const
+  {
+    const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
+    recurse_lookups (c, lookupCount, lookupRecord);
+  }
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    (this+coverageZ[0]).add_coverage (c->input);
+    (this+coverageZ[0]).collect_coverage (c->input);
 
     const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
     struct ContextCollectGlyphsLookupContext lookup_context = {
@@ -1949,6 +2092,8 @@
   void closure (hb_closure_context_t *c,
 		ChainContextClosureLookupContext &lookup_context) const
   {
+    if (unlikely (c->lookup_limit_exceeded ())) return;
+
     const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack);
     const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input);
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
@@ -1960,6 +2105,16 @@
 				  lookup_context);
   }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const
+  {
+    if (unlikely (c->lookup_limit_exceeded ())) return;
+
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack);
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
+    recurse_lookups (c, lookup.len, lookup.arrayZ);
+  }
+
   void collect_glyphs (hb_collect_glyphs_context_t *c,
 		       ChainContextCollectGlyphsLookupContext &lookup_context) const
   {
@@ -2003,8 +2158,8 @@
   template<typename Iterator,
 	   hb_requires (hb_is_iterator (Iterator))>
   void serialize_array (hb_serialize_context_t *c,
-                        HBUINT16 len,
-                        Iterator it) const
+			HBUINT16 len,
+			Iterator it) const
   {
     c->copy (len);
     for (const auto g : it)
@@ -2045,9 +2200,9 @@
   }
 
   bool subset (hb_subset_context_t *c,
-               const hb_map_t *backtrack_map = nullptr,
-               const hb_map_t *input_map = nullptr,
-               const hb_map_t *lookahead_map = nullptr) const
+	       const hb_map_t *backtrack_map = nullptr,
+	       const hb_map_t *input_map = nullptr,
+	       const hb_map_t *lookahead_map = nullptr) const
   {
     TRACE_SUBSET (this);
 
@@ -2058,9 +2213,9 @@
     {
       const hb_set_t &glyphset = *c->plan->glyphset ();
       if (!hb_all (backtrack, glyphset) ||
-          !hb_all (input, glyphset) ||
-          !hb_all (lookahead, glyphset))
-        return_trace (false);
+	  !hb_all (input, glyphset) ||
+	  !hb_all (lookahead, glyphset))
+	return_trace (false);
 
       copy (c->serializer, c->plan->glyph_map);
     }
@@ -2067,9 +2222,9 @@
     else
     {
       if (!hb_all (backtrack, backtrack_map) ||
-          !hb_all (input, input_map) ||
-          !hb_all (lookahead, lookahead_map))
-        return_trace (false);
+	  !hb_all (input, input_map) ||
+	  !hb_all (lookahead, lookahead_map))
+	return_trace (false);
 
       copy (c->serializer, backtrack_map, input_map, lookahead_map);
     }
@@ -2120,6 +2275,8 @@
   }
   void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
   {
+    if (unlikely (c->lookup_limit_exceeded ())) return;
+
     return
     + hb_iter (rule)
     | hb_map (hb_add (this))
@@ -2127,6 +2284,17 @@
     ;
   }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const
+  {
+    if (unlikely (c->lookup_limit_exceeded ())) return;
+
+    return
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const ChainRule &_) { _.closure_lookups (c); })
+    ;
+  }
+
   void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const
   {
     return
@@ -2159,9 +2327,9 @@
   }
 
   bool subset (hb_subset_context_t *c,
-               const hb_map_t *backtrack_klass_map = nullptr,
-               const hb_map_t *input_klass_map = nullptr,
-               const hb_map_t *lookahead_klass_map = nullptr) const
+	       const hb_map_t *backtrack_klass_map = nullptr,
+	       const hb_map_t *input_klass_map = nullptr,
+	       const hb_map_t *lookahead_klass_map = nullptr) const
   {
     TRACE_SUBSET (this);
 
@@ -2176,13 +2344,13 @@
       if (unlikely (!o)) continue;
 
       auto o_snap = c->serializer->snapshot ();
-      if (!o->serialize_subset (c, _, this, out,
-                                backtrack_klass_map,
-                                input_klass_map,
-                                lookahead_klass_map))
+      if (!o->serialize_subset (c, _, this,
+				backtrack_klass_map,
+				input_klass_map,
+				lookahead_klass_map))
       {
-        out->rule.pop ();
-        c->serializer->revert (o_snap);
+	out->rule.pop ();
+	c->serializer->revert (o_snap);
       }
     }
 
@@ -2240,9 +2408,17 @@
     ;
   }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const
+  {
+    + hb_iter (ruleSet)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const ChainRuleSet &_) { _.closure_lookups (c); })
+    ;
+  }
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    (this+coverage).add_coverage (c->input);
+    (this+coverage).collect_coverage (c->input);
 
     struct ChainContextCollectGlyphsLookupContext lookup_context = {
       {collect_glyph},
@@ -2294,7 +2470,7 @@
     hb_sorted_vector_t<hb_codepoint_t> new_coverage;
     + hb_zip (this+coverage, ruleSet)
     | hb_filter (glyphset, hb_first)
-    | hb_filter (subset_offset_array (c, out->ruleSet, this, out), hb_second)
+    | hb_filter (subset_offset_array (c, out->ruleSet, this), hb_second)
     | hb_map (hb_first)
     | hb_map (glyph_map)
     | hb_sink (new_coverage)
@@ -2376,9 +2552,17 @@
     ;
   }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const
+  {
+    + hb_iter (ruleSet)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const ChainRuleSet &_) { _.closure_lookups (c); })
+    ;
+  }
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    (this+coverage).add_coverage (c->input);
+    (this+coverage).collect_coverage (c->input);
 
     const ClassDef &backtrack_class_def = this+backtrackClassDef;
     const ClassDef &input_class_def = this+inputClassDef;
@@ -2443,17 +2627,17 @@
     auto *out = c->serializer->start_embed (*this);
     if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
     out->format = format;
-    out->coverage.serialize_subset (c, coverage, this, out);
+    out->coverage.serialize_subset (c, coverage, this);
 
     hb_map_t backtrack_klass_map;
-    out->backtrackClassDef.serialize_subset (c, backtrackClassDef, this, out, &backtrack_klass_map);
+    out->backtrackClassDef.serialize_subset (c, backtrackClassDef, this, &backtrack_klass_map);
 
     // subset inputClassDef based on glyphs survived in Coverage subsetting
     hb_map_t input_klass_map;
-    out->inputClassDef.serialize_subset (c, inputClassDef, this, out, &input_klass_map);
+    out->inputClassDef.serialize_subset (c, inputClassDef, this, &input_klass_map);
 
     hb_map_t lookahead_klass_map;
-    out->lookaheadClassDef.serialize_subset (c, lookaheadClassDef, this, out, &lookahead_klass_map);
+    out->lookaheadClassDef.serialize_subset (c, lookaheadClassDef, this, &lookahead_klass_map);
 
     hb_vector_t<unsigned> rulesets;
     bool ret = true;
@@ -2464,15 +2648,15 @@
       auto *o = out->ruleSet.serialize_append (c->serializer);
       if (unlikely (!o))
       {
-        ret = false;
-        break;
+	ret = false;
+	break;
       }
-      if (!o->serialize_subset (c, _, this, out,
-                                &backtrack_klass_map,
-                                &input_klass_map,
-                                &lookahead_klass_map))
+      if (!o->serialize_subset (c, _, this,
+				&backtrack_klass_map,
+				&input_klass_map,
+				&lookahead_klass_map))
       {
-        rulesets.push (0);
+	rulesets.push (0);
       }
       else rulesets.push (1);
     }
@@ -2566,11 +2750,19 @@
 				  lookup_context);
   }
 
+  void closure_lookups (hb_closure_lookups_context_t *c) const
+  {
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
+    recurse_lookups (c, lookup.len, lookup.arrayZ);
+  }
+
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
 
-    (this+input[0]).add_coverage (c->input);
+    (this+input[0]).collect_coverage (c->input);
 
     const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
@@ -2631,10 +2823,7 @@
 
   template<typename Iterator,
 	   hb_requires (hb_is_iterator (Iterator))>
-  bool serialize_coverage_offsets (hb_subset_context_t *c,
-                                   Iterator it,
-				   const void* src_base,
-				   const void* dst_base) const
+  bool serialize_coverage_offsets (hb_subset_context_t *c, Iterator it, const void* base) const
   {
     TRACE_SERIALIZE (this);
     auto *out = c->serializer->start_embed<OffsetArrayOf<Coverage>> ();
@@ -2642,7 +2831,7 @@
     if (unlikely (!c->serializer->allocate_size<HBUINT16> (HBUINT16::static_size))) return_trace (false);
 
     + it
-    | hb_apply (subset_offset_array (c, *out, src_base, dst_base))
+    | hb_apply (subset_offset_array (c, *out, base))
     ;
 
     return_trace (out->len);
@@ -2656,15 +2845,15 @@
     if (unlikely (!out)) return_trace (false);
     if (unlikely (!c->serializer->embed (this->format))) return_trace (false);
 
-    if (!serialize_coverage_offsets (c, backtrack.iter (), this, out))
+    if (!serialize_coverage_offsets (c, backtrack.iter (), this))
       return_trace (false);
 
     const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
-    if (!serialize_coverage_offsets (c, input.iter (), this, out))
+    if (!serialize_coverage_offsets (c, input.iter (), this))
       return_trace (false);
 
     const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
-    if (!serialize_coverage_offsets (c, lookahead.iter (), this, out))
+    if (!serialize_coverage_offsets (c, lookahead.iter (), this))
       return_trace (false);
 
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
@@ -2737,7 +2926,7 @@
 
   template <typename X>
   const X& get_subtable () const
-  { return this + CastR<LOffsetTo<typename T::SubTable>> (extensionOffset); }
+  { return this + reinterpret_cast<const LOffsetTo<typename T::SubTable> &> (extensionOffset); }
 
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
@@ -2781,7 +2970,7 @@
   {
     switch (u.format) {
     case 1: return u.format1.template get_subtable<typename T::SubTable> ();
-    default:return Null(typename T::SubTable);
+    default:return Null (typename T::SubTable);
     }
   }
 
@@ -2814,7 +3003,7 @@
   void init (const TLookup &lookup)
   {
     digest.init ();
-    lookup.add_coverage (&digest);
+    lookup.collect_coverage (&digest);
 
     subtables.init ();
     OT::hb_get_subtables_context_t c_get_subtables (subtables);
@@ -2875,10 +3064,11 @@
   bool find_variations_index (const int *coords, unsigned int num_coords,
 			      unsigned int *index) const
   {
-#ifdef HB_NOVAR
+#ifdef HB_NO_VAR
+    *index = FeatureVariations::NOT_FOUND_INDEX;
     return false;
 #endif
-    return (version.to_int () >= 0x00010001u ? this+featureVars : Null(FeatureVariations))
+    return (version.to_int () >= 0x00010001u ? this+featureVars : Null (FeatureVariations))
 	    .find_index (coords, num_coords, index);
   }
   const Feature& get_feature_variation (unsigned int feature_index,
@@ -2897,32 +3087,70 @@
     return get_feature (feature_index);
   }
 
+  void feature_variation_collect_lookups (const hb_set_t *feature_indexes,
+					  hb_set_t       *lookup_indexes /* OUT */) const
+  {
+#ifndef HB_NO_VAR
+    if (version.to_int () >= 0x00010001u)
+      (this+featureVars).collect_lookups (feature_indexes, lookup_indexes);
+#endif
+  }
+
   template <typename TLookup>
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_layout_context_t *c) const
   {
     TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (*this);
+    auto *out = c->subset_context->serializer->embed (*this);
     if (unlikely (!out)) return_trace (false);
 
-    out->scriptList.serialize_subset (c, scriptList, this, out);
-    out->featureList.serialize_subset (c, featureList, this, out);
+    typedef LookupOffsetList<TLookup> TLookupList;
+    reinterpret_cast<OffsetTo<TLookupList> &> (out->lookupList)
+	.serialize_subset (c->subset_context,
+			   reinterpret_cast<const OffsetTo<TLookupList> &> (lookupList),
+			   this,
+			   c);
 
-    typedef OffsetListOf<TLookup> TLookupList;
-    /* TODO Use intersects() to count how many subtables survive? */
-    CastR<OffsetTo<TLookupList>> (out->lookupList)
-      .serialize_subset (c,
-			 CastR<OffsetTo<TLookupList>> (lookupList),
-			 this,
-			 out);
+    reinterpret_cast<OffsetTo<RecordListOfFeature> &> (out->featureList)
+	.serialize_subset (c->subset_context,
+			   reinterpret_cast<const OffsetTo<RecordListOfFeature> &> (featureList),
+			   this,
+			   c);
 
+    out->scriptList.serialize_subset (c->subset_context,
+				      scriptList,
+				      this,
+				      c);
+
 #ifndef HB_NO_VAR
     if (version.to_int () >= 0x00010001u)
-     out->featureVars.serialize_copy (c->serializer, featureVars, this, out);
+    {
+      bool ret = out->featureVars.serialize_subset (c->subset_context, featureVars, this, c);
+      if (!ret)
+      {
+	out->version.major = 1;
+	out->version.minor = 0;
+      }
+    }
 #endif
 
     return_trace (true);
   }
 
+  void closure_features (const hb_map_t *lookup_indexes, /* IN */
+			 hb_set_t       *feature_indexes /* OUT */) const
+  {
+    unsigned int feature_count = hb_min (get_feature_count (), (unsigned) HB_MAX_FEATURES);
+    for (unsigned i = 0; i < feature_count; i++)
+    {
+      if (get_feature (i).intersects_lookup_indexes (lookup_indexes))
+	feature_indexes->add (i);
+    }
+#ifndef HB_NO_VAR
+    if (version.to_int () >= 0x00010001u)
+      (this+featureVars).closure_features (lookup_indexes, feature_indexes);
+#endif
+  }
+
   unsigned int get_size () const
   {
     return min_size +
@@ -2938,7 +3166,7 @@
 		    likely (version.major == 1) &&
 		    scriptList.sanitize (c, this) &&
 		    featureList.sanitize (c, this) &&
-		    CastR<OffsetTo<TLookupList>> (lookupList).sanitize (c, this))))
+		    reinterpret_cast<const OffsetTo<TLookupList> &> (lookupList).sanitize (c, this))))
       return_trace (false);
 
 #ifndef HB_NO_VAR
@@ -2954,7 +3182,7 @@
   {
     void init (hb_face_t *face)
     {
-      this->table = hb_sanitize_context_t().reference_table<T> (face);
+      this->table = hb_sanitize_context_t ().reference_table<T> (face);
       if (unlikely (this->table->is_blacklisted (this->table.get_blob (), face)))
       {
 	hb_blob_destroy (this->table.get_blob ());
@@ -2988,11 +3216,11 @@
   FixedVersion<>version;	/* Version of the GSUB/GPOS table--initially set
 				 * to 0x00010000u */
   OffsetTo<ScriptList>
-		scriptList;  	/* ScriptList table */
+		scriptList;	/* ScriptList table */
   OffsetTo<FeatureList>
-		featureList; 	/* FeatureList table */
+		featureList;	/* FeatureList table */
   OffsetTo<LookupList>
-		lookupList; 	/* LookupList table */
+		lookupList;	/* LookupList table */
   LOffsetTo<FeatureVariations>
 		featureVars;	/* Offset to Feature Variations
 				   table--from beginning of table

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-jstf-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-jstf-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-jstf-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -222,7 +222,7 @@
   FixedVersion<>version;	/* Version of the JSTF table--initially set
 				 * to 0x00010000u */
   RecordArrayOf<JstfScript>
-		scriptList;  	/* Array of JstfScripts--listed
+		scriptList;	/* Array of JstfScripts--listed
 				 * alphabetically by ScriptTag */
   public:
   DEFINE_SIZE_ARRAY (6, scriptList);

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	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -399,27 +399,6 @@
 #ifdef HB_NO_OT_LAYOUT_BLACKLIST
   return false;
 #endif
-
-#ifndef HB_NO_AAT_SHAPE
-  /* Mac OS X prefers morx over GSUB.  It also ships with various Indic fonts,
-   * all by 'MUTF' foundry (Tamil MN, Tamil Sangam MN, etc.), that have broken
-   * GSUB/GPOS tables.  Some have GSUB with zero scripts, those are ignored by
-   * our morx/GSUB preference code.  But if GSUB has non-zero scripts, we tend
-   * to prefer it over morx because we want to be consistent with other OpenType
-   * shapers.
-   *
-   * To work around broken Indic Mac system fonts, we ignore GSUB table if
-   * OS/2 VendorId is 'MUTF' and font has morx table as well.
-   *
-   * https://github.com/harfbuzz/harfbuzz/issues/1410
-   * https://github.com/harfbuzz/harfbuzz/issues/1348
-   * https://github.com/harfbuzz/harfbuzz/issues/1391
-   */
-  if (unlikely (face->table.OS2->achVendID == HB_TAG ('M','U','T','F') &&
-		face->table.morx->has_data ()))
-    return true;
-#endif
-
   return false;
 }
 
@@ -440,7 +419,7 @@
   switch (table_tag) {
     case HB_OT_TAG_GSUB: return *face->table.GSUB->table;
     case HB_OT_TAG_GPOS: return *face->table.GPOS->table;
-    default:             return Null(OT::GSUBGPOS);
+    default:             return Null (OT::GSUBGPOS);
   }
 }
 
@@ -785,7 +764,7 @@
 						  hb_tag_t      table_tag,
 						  unsigned int  script_index,
 						  unsigned int  language_index,
-						  unsigned int *feature_index)
+						  unsigned int *feature_index /* OUT */)
 {
   return hb_ot_layout_language_get_required_feature (face,
 						     table_tag,
@@ -802,7 +781,7 @@
  * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
  * @script_index: The index of the requested script tag
  * @language_index: The index of the requested language tag
- * @feature_index: The index of the requested feature
+ * @feature_index: (out): The index of the requested feature
  * @feature_tag: (out): The #hb_tag_t of the requested feature
  *
  * Fetches the tag of a requested feature index in the given face's GSUB or GPOS table,
@@ -817,8 +796,8 @@
 					    hb_tag_t      table_tag,
 					    unsigned int  script_index,
 					    unsigned int  language_index,
-					    unsigned int *feature_index,
-					    hb_tag_t     *feature_tag)
+					    unsigned int *feature_index /* OUT */,
+					    hb_tag_t     *feature_tag   /* 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);
@@ -1004,7 +983,7 @@
 				 hb_set_t  *feature_indexes_)
     : g (get_gsubgpos_table (face, table_tag)),
       feature_indexes (feature_indexes_),
-      script_count(0),langsys_count(0) {}
+      script_count (0),langsys_count (0), feature_index_count (0) {}
 
   bool visited (const OT::Script &s)
   {
@@ -1033,6 +1012,12 @@
     return visited (l, visited_langsys);
   }
 
+  bool visited_feature_indices (unsigned count)
+  {
+    feature_index_count += count;
+    return feature_index_count > HB_MAX_FEATURE_INDICES;
+  }
+
   private:
   template <typename T>
   bool visited (const T &p, hb_set_t &visited_set)
@@ -1054,6 +1039,7 @@
   hb_set_t visited_langsys;
   unsigned int script_count;
   unsigned int langsys_count;
+  unsigned int feature_index_count;
 };
 
 static void
@@ -1066,10 +1052,11 @@
   if (!features)
   {
     /* All features. */
-    if (l.has_required_feature ())
+    if (l.has_required_feature () && !c->visited_feature_indices (1))
       c->feature_indexes->add (l.get_required_feature_index ());
 
-    l.add_feature_indexes_to (c->feature_indexes);
+    if (!c->visited_feature_indices (l.featureIndex.len))
+      l.add_feature_indexes_to (c->feature_indexes);
   }
   else
   {
@@ -1212,9 +1199,77 @@
   for (hb_codepoint_t feature_index = HB_SET_VALUE_INVALID;
        hb_set_next (&feature_indexes, &feature_index);)
     g.get_feature (feature_index).add_lookup_indexes_to (lookup_indexes);
+
+  g.feature_variation_collect_lookups (&feature_indexes, lookup_indexes);
 }
 
+#ifdef HB_EXPERIMENTAL_API
+/**
+ * hb_ot_layout_closure_lookups:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @lookup_indexes: (inout): lookup_indices collected from feature
+ * list
+ *
+ * Returns all inactive lookups reachable from lookup_indices
+ *
+ * Since: EXPERIMENTAL
+ **/
+void
+hb_ot_layout_closure_lookups (hb_face_t      *face,
+			      hb_tag_t        table_tag,
+			      const hb_set_t *glyphs,
+			      hb_set_t       *lookup_indexes /* IN/OUT */)
+{
+  hb_set_t visited_lookups, inactive_lookups;
+  OT::hb_closure_lookups_context_t c (face, glyphs, &visited_lookups, &inactive_lookups);
 
+  for (unsigned lookup_index : + hb_iter (lookup_indexes))
+  {
+    switch (table_tag)
+    {
+      case HB_OT_TAG_GSUB:
+      {
+	const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index);
+	l.closure_lookups (&c, lookup_index);
+	break;
+      }
+      case HB_OT_TAG_GPOS:
+      {
+	const OT::PosLookup& l = face->table.GPOS->table->get_lookup (lookup_index);
+	l.closure_lookups (&c, lookup_index);
+	break;
+      }
+    }
+  }
+
+  hb_set_union (lookup_indexes, &visited_lookups);
+  hb_set_subtract (lookup_indexes, &inactive_lookups);
+}
+
+/**
+ * hb_ot_layout_closure_features:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @lookup_indexes: (in): collected active lookup_indices
+ * @feature_indexes: (out): all active feature indexes collected
+ *
+ * Returns all active feature indexes
+ *
+ * Since: EXPERIMENTAL
+ **/
+void
+hb_ot_layout_closure_features (hb_face_t      *face,
+			       hb_tag_t        table_tag,
+			       const hb_map_t *lookup_indexes, /* IN */
+			       hb_set_t       *feature_indexes /* OUT */)
+{
+  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+  g.closure_features (lookup_indexes, feature_indexes);
+}
+#endif
+
+
 #ifndef HB_NO_LAYOUT_COLLECT_GLYPHS
 /**
  * hb_ot_layout_lookup_collect_glyphs:
@@ -1223,7 +1278,7 @@
  * @lookup_index: The index of the feature lookup to query
  * @glyphs_before: (out): Array of glyphs preceding the substitution range
  * @glyphs_input: (out): Array of input glyphs that would be substituted by the lookup
- * @glyphs_after: (out): Array of glyphs following the substition range
+ * @glyphs_after: (out): Array of glyphs following the substitution range
  * @glyphs_output: (out): Array of glyphs that would be the substitued output of the lookup
  *
  * Fetches a list of all glyphs affected by the specified lookup in the
@@ -1458,8 +1513,8 @@
  **/
 void
 hb_ot_layout_lookup_substitute_closure (hb_face_t    *face,
-				        unsigned int  lookup_index,
-				        hb_set_t     *glyphs /* OUT */)
+					unsigned int  lookup_index,
+					hb_set_t     *glyphs /* OUT */)
 {
   hb_map_t done_lookups;
   OT::hb_closure_context_t c (face, glyphs, &done_lookups);
@@ -1494,7 +1549,7 @@
   do
   {
     glyphs_length = glyphs->get_population ();
-    if (lookups != nullptr)
+    if (lookups)
     {
       for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; hb_set_next (lookups, &lookup_index);)
 	gsub.get_lookup (lookup_index).closure (&c, lookup_index);
@@ -1587,8 +1642,8 @@
  * specifically in their respective size ranges; other ways to differentiate fonts within
  * a subfamily are not covered by the `size` feature.
  *
- * For more information on this distinction, see the `size` documentation at
- * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-39size39
+ * For more information on this distinction, see the [`size` feature documentation](
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-size).
  *
  * Return value: true if data found, false otherwise
  *
@@ -1957,7 +2012,7 @@
  *
  * Fetches a baseline value from the face.
  *
- * Return value: if found baseline value in the the font.
+ * Return value: if found baseline value in the font.
  *
  * Since: 2.6.0
  **/

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	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h	2020-05-18 10:44:36 UTC (rev 55197)
@@ -161,7 +161,7 @@
 hb_ot_layout_table_find_script (hb_face_t    *face,
 				hb_tag_t      table_tag,
 				hb_tag_t      script_tag,
-				unsigned int *script_index);
+				unsigned int *script_index /* OUT */);
 
 HB_EXTERN hb_bool_t
 hb_ot_layout_table_select_script (hb_face_t      *face,
@@ -199,7 +199,7 @@
 						  hb_tag_t      table_tag,
 						  unsigned int  script_index,
 						  unsigned int  language_index,
-						  unsigned int *feature_index);
+						  unsigned int *feature_index /* OUT */);
 
 HB_EXTERN hb_bool_t
 hb_ot_layout_language_get_required_feature (hb_face_t    *face,
@@ -206,8 +206,8 @@
 					    hb_tag_t      table_tag,
 					    unsigned int  script_index,
 					    unsigned int  language_index,
-					    unsigned int *feature_index,
-					    hb_tag_t     *feature_tag);
+					    unsigned int *feature_index /* OUT */,
+					    hb_tag_t     *feature_tag /* OUT */);
 
 HB_EXTERN unsigned int
 hb_ot_layout_language_get_feature_indexes (hb_face_t    *face,
@@ -233,7 +233,7 @@
 				    unsigned int  script_index,
 				    unsigned int  language_index,
 				    hb_tag_t      feature_tag,
-				    unsigned int *feature_index);
+				    unsigned int *feature_index /* OUT */);
 
 HB_EXTERN unsigned int
 hb_ot_layout_feature_get_lookups (hb_face_t    *face,
@@ -263,7 +263,21 @@
 			      const hb_tag_t *features,
 			      hb_set_t       *lookup_indexes /* OUT */);
 
+#ifdef HB_EXPERIMENTAL_API
 HB_EXTERN void
+hb_ot_layout_closure_lookups (hb_face_t      *face,
+			      hb_tag_t        table_tag,
+			      const hb_set_t *glyphs,
+			      hb_set_t       *lookup_indexes /* IN/OUT */);
+
+HB_EXTERN void
+hb_ot_layout_closure_features (hb_face_t      *face,
+			       hb_tag_t        table_tag,
+			       const hb_map_t *lookup_indexes, /* IN */
+			       hb_set_t       *feature_indexes /* OUT */);
+#endif
+
+HB_EXTERN void
 hb_ot_layout_lookup_collect_glyphs (hb_face_t    *face,
 				    hb_tag_t      table_tag,
 				    unsigned int  lookup_index,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -80,14 +80,14 @@
   HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE	= 0x04u,
   HB_OT_LAYOUT_GLYPH_PROPS_MARK		= 0x08u,
 
+  HB_OT_LAYOUT_GLYPH_PROPS_CLASS_MASK   = HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH |
+					  HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE |
+					  HB_OT_LAYOUT_GLYPH_PROPS_MARK,
+
   /* The following are used internally; not derived from GDEF. */
   HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED	= 0x10u,
   HB_OT_LAYOUT_GLYPH_PROPS_LIGATED	= 0x20u,
   HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED	= 0x40u,
-
-  HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE     = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED |
-					  HB_OT_LAYOUT_GLYPH_PROPS_LIGATED |
-					  HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED
 };
 HB_MARK_AS_FLAG_T (hb_ot_layout_glyph_props_flags_t);
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -134,13 +134,13 @@
   unsigned int get_feature_stage (unsigned int table_index, hb_tag_t feature_tag) const
   {
     const feature_map_t *map = features.bsearch (feature_tag);
-    return map ? map->stage[table_index] : (unsigned int) -1;
+    return map ? map->stage[table_index] : UINT_MAX;
   }
 
   void get_stage_lookups (unsigned int table_index, unsigned int stage,
 			  const struct lookup_map_t **plookups, unsigned int *lookup_count) const
   {
-    if (unlikely (stage == (unsigned int) -1)) {
+    if (unlikely (stage == UINT_MAX)) {
       *plookups = nullptr;
       *lookup_count = 0;
       return;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -48,7 +48,7 @@
   }
 
   protected:
-  HBINT16			value;		/* The X or Y value in design units */
+  HBINT16		value;		/* The X or Y value in design units */
   OffsetTo<Device>	deviceTable;	/* Offset to the device table - from the
 					 * beginning of parent table.  May be NULL.
 					 * Suggested format for device table is 1. */
@@ -279,14 +279,15 @@
   protected:
   HBUINT16	heightCount;
   UnsizedArrayOf<MathValueRecord>
-		mathValueRecordsZ;	/* Array of correction heights at
-					 * which the kern value changes.
-					 * Sorted by the height value in
-					 * design units (heightCount entries),
-					 * Followed by:
-					 * Array of kern values corresponding
-					 * to heights. (heightCount+1 entries).
-					 */
+		mathValueRecordsZ;
+				/* Array of correction heights at
+				 * which the kern value changes.
+				 * Sorted by the height value in
+				 * design units (heightCount entries),
+				 * Followed by:
+				 * Array of kern values corresponding
+				 * to heights. (heightCount+1 entries).
+				 */
 
   public:
   DEFINE_SIZE_ARRAY (2, mathValueRecordsZ);
@@ -345,15 +346,18 @@
   }
 
   protected:
-  OffsetTo<Coverage>		mathKernCoverage;    /* Offset to Coverage table -
-						      * from the beginning of the
-						      * MathKernInfo table. */
-  ArrayOf<MathKernInfoRecord>	mathKernInfoRecords; /* Array of
-						      * MathKernInfoRecords,
-						      * per-glyph information for
-						      * mathematical positioning
-						      * of subscripts and
-						      * superscripts. */
+  OffsetTo<Coverage>
+		mathKernCoverage;
+				/* Offset to Coverage table -
+				 * from the beginning of the
+				 * MathKernInfo table. */
+  ArrayOf<MathKernInfoRecord>
+		mathKernInfoRecords;
+				/* Array of MathKernInfoRecords,
+				 * per-glyph information for
+				 * mathematical positioning
+				 * of subscripts and
+				 * superscripts. */
 
   public:
   DEFINE_SIZE_ARRAY (4, mathKernInfoRecords);
@@ -471,19 +475,21 @@
   }
 
   protected:
-  HBGlyphID   glyph;		  /* Glyph ID for the part. */
-  HBUINT16    startConnectorLength; /* Advance width/ height of the straight bar
-				   * connector material, in design units, is at
-				   * the beginning of the glyph, in the
-				   * direction of the extension. */
-  HBUINT16    endConnectorLength;   /* Advance width/ height of the straight bar
-				   * connector material, in design units, is at
-				   * the end of the glyph, in the direction of
-				   * the extension. */
-  HBUINT16    fullAdvance;	  /* Full advance width/height for this part,
-				   * in the direction of the extension.
-				   * In design units. */
-  PartFlags partFlags;		  /* Part qualifiers. */
+  HBGlyphID	glyph;		/* Glyph ID for the part. */
+  HBUINT16	startConnectorLength;
+				/* Advance width/ height of the straight bar
+				 * connector material, in design units, is at
+				 * the beginning of the glyph, in the
+				 * direction of the extension. */
+  HBUINT16	endConnectorLength;
+				/* Advance width/ height of the straight bar
+				 * connector material, in design units, is at
+				 * the end of the glyph, in the direction of
+				 * the extension. */
+  HBUINT16	fullAdvance;	/* Full advance width/height for this part,
+				 * in the direction of the extension.
+				 * In design units. */
+  PartFlags	partFlags;	/* Part qualifiers. */
 
   public:
   DEFINE_SIZE_STATIC (10);
@@ -522,12 +528,15 @@
   }
 
   protected:
-  MathValueRecord	   italicsCorrection; /* Italics correction of this
-					       * MathGlyphAssembly. Should not
-					       * depend on the assembly size. */
-  ArrayOf<MathGlyphPartRecord> partRecords;   /* Array of part records, from
-					       * left to right and bottom to
-					       * top. */
+  MathValueRecord
+		italicsCorrection;
+				/* Italics correction of this
+				 * MathGlyphAssembly. Should not
+				 * depend on the assembly size. */
+  ArrayOf<MathGlyphPartRecord>
+		partRecords;	/* Array of part records, from
+				 * left to right and bottom to
+				 * top. */
 
   public:
   DEFINE_SIZE_ARRAY (6, partRecords);
@@ -645,27 +654,30 @@
   }
 
   protected:
-  HBUINT16	     minConnectorOverlap; /* Minimum overlap of connecting
-					   * glyphs during glyph construction,
-					   * in design units. */
-  OffsetTo<Coverage> vertGlyphCoverage;   /* Offset to Coverage table -
-					   * from the beginning of MathVariants
-					   * table. */
-  OffsetTo<Coverage> horizGlyphCoverage;  /* Offset to Coverage table -
-					   * from the beginning of MathVariants
-					   * table. */
-  HBUINT16	     vertGlyphCount;      /* Number of glyphs for which
-					   * information is provided for
-					   * vertically growing variants. */
-  HBUINT16	     horizGlyphCount;     /* Number of glyphs for which
-					   * information is provided for
-					   * horizontally growing variants. */
+  HBUINT16	minConnectorOverlap;
+				/* Minimum overlap of connecting
+				 * glyphs during glyph construction,
+				 * in design units. */
+  OffsetTo<Coverage> vertGlyphCoverage;
+				/* Offset to Coverage table -
+				 * from the beginning of MathVariants
+				 * table. */
+  OffsetTo<Coverage> horizGlyphCoverage;
+				/* Offset to Coverage table -
+				 * from the beginning of MathVariants
+				 * table. */
+  HBUINT16	vertGlyphCount;	/* Number of glyphs for which
+				 * information is provided for
+				 * vertically growing variants. */
+  HBUINT16	horizGlyphCount;/* Number of glyphs for which
+				 * information is provided for
+				 * horizontally growing variants. */
 
   /* Array of offsets to MathGlyphConstruction tables - from the beginning of
      the MathVariants table, for shapes growing in vertical/horizontal
      direction. */
   UnsizedArrayOf<OffsetTo<MathGlyphConstruction>>
- 			glyphConstruction;
+			glyphConstruction;
 
   public:
   DEFINE_SIZE_ARRAY (10, glyphConstruction);
@@ -702,11 +714,14 @@
   const MathVariants &get_variants () const    { return this+mathVariants; }
 
   protected:
-  FixedVersion<>version;		/* Version of the MATH table
-					 * initially set to 0x00010000u */
-  OffsetTo<MathConstants> mathConstants;/* MathConstants table */
-  OffsetTo<MathGlyphInfo> mathGlyphInfo;/* MathGlyphInfo table */
-  OffsetTo<MathVariants>  mathVariants;	/* MathVariants table */
+  FixedVersion<>version;	/* Version of the MATH table
+				 * initially set to 0x00010000u */
+  OffsetTo<MathConstants>
+		mathConstants;	/* MathConstants table */
+  OffsetTo<MathGlyphInfo>
+		mathGlyphInfo;	/* MathGlyphInfo table */
+  OffsetTo<MathVariants>
+		mathVariants;	/* MathVariants table */
 
   public:
   DEFINE_SIZE_STATIC (10);

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	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -126,9 +126,10 @@
   }
 
   protected:
-  FixedVersion<>version;		/* Version of the maxp table (0.5 or 1.0),
-					 * 0x00005000u or 0x00010000u. */
-  HBUINT16	numGlyphs;		/* The number of glyphs in the font. */
+  FixedVersion<>version;/* Version of the maxp table (0.5 or 1.0),
+			 * 0x00005000u or 0x00010000u. */
+  HBUINT16	numGlyphs;
+			/* The number of glyphs in the font. */
 /*maxpV1Tail	v1Tail[HB_VAR_ARRAY]; */
   public:
   DEFINE_SIZE_STATIC (6);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-meta-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-meta-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-meta-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -56,7 +56,7 @@
 
   protected:
   Tag		tag;		/* A tag indicating the type of metadata. */
-  LOffsetTo<UnsizedArrayOf<HBUINT8>>
+  LNNOffsetTo<UnsizedArrayOf<HBUINT8>>
 		dataZ;		/* Offset in bytes from the beginning of the
 				 * metadata table to the data for this tag. */
   HBUINT32	dataLength;	/* Length of the data. The data is not required to
@@ -108,12 +108,13 @@
   protected:
   HBUINT32	version;	/* Version number of the metadata table — set to 1. */
   HBUINT32	flags;		/* Flags — currently unused; set to 0. */
-  HBUINT32	dataOffset;	/* Per Apple specification:
+  HBUINT32	dataOffset;
+				/* Per Apple specification:
 				 * Offset from the beginning of the table to the data.
 				 * Per OT specification:
 				 * Reserved. Not used; should be set to 0. */
   LArrayOf<DataMap>
-		dataMaps;	/* Array of data map records. */
+		dataMaps;/* Array of data map records. */
   public:
   DEFINE_SIZE_ARRAY (16, dataMaps);
 };

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-language-static.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-language-static.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-language-static.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -37,12 +37,8 @@
 
 struct hb_ot_language_map_t
 {
-  static int cmp (const void *key, const void *item)
-  {
-    unsigned int a = * (unsigned int *) key;
-    unsigned int b = ((const hb_ot_language_map_t *) item)->code;
-    return a < b ? -1 : a > b ? +1 : 0;
-  }
+  int cmp (unsigned int key) const
+  { return key < code ? -1 : key > code ? +1 : 0; }
 
   uint16_t	code;
   char		lang[6];
@@ -433,12 +429,7 @@
 #ifdef HB_NO_OT_NAME_LANGUAGE
   return HB_LANGUAGE_INVALID;
 #endif
-  const hb_ot_language_map_t *entry = (const hb_ot_language_map_t *)
-				      hb_bsearch (&code,
-						  array,
-						  len,
-						  sizeof (array[0]),
-						  hb_ot_language_map_t::cmp);
+  auto *entry = hb_bsearch (code, array, len);
 
   if (entry)
     return hb_language_from_string (entry->lang, -1);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -97,17 +97,47 @@
     return UNSUPPORTED;
   }
 
-  NameRecord* copy (hb_serialize_context_t *c,
-		    const void *src_base,
-		    const void *dst_base) const
+  NameRecord* copy (hb_serialize_context_t *c, const void *base) const
   {
     TRACE_SERIALIZE (this);
     auto *out = c->embed (this);
     if (unlikely (!out)) return_trace (nullptr);
-    out->offset.serialize_copy (c, offset, src_base, dst_base, length);
+    out->offset.serialize_copy (c, offset, base, 0, hb_serialize_context_t::Tail, length);
     return_trace (out);
   }
 
+  bool isUnicode () const
+  {
+    unsigned int p = platformID;
+    unsigned int e = encodingID;
+
+    return (p == 0 ||
+	    (p == 3 && (e == 0 || e == 1 || e == 10)));
+  }
+
+  static int cmp (const void *pa, const void *pb)
+  {
+    const NameRecord *a = (const NameRecord *)pa;
+    const NameRecord *b = (const NameRecord *)pb;
+
+    if (a->platformID != b->platformID)
+      return a->platformID - b->platformID;
+
+    if (a->encodingID != b->encodingID)
+      return a->encodingID - b->encodingID;
+
+    if (a->languageID != b->languageID)
+      return a->languageID - b->languageID;
+
+    if (a->nameID != b->nameID)
+      return a->nameID - b->nameID;
+
+    if (a->length != b->length)
+      return a->length - b->length;
+
+    return 0;
+  }
+
   bool sanitize (hb_sanitize_context_t *c, const void *base) const
   {
     TRACE_SANITIZE (this);
@@ -134,7 +164,7 @@
   /* Compare by name_id, then language. */
 
   if (a->name_id != b->name_id)
-    return a->name_id < b->name_id ? -1 : +1;
+    return a->name_id - b->name_id;
 
   if (a->language == b->language) return 0;
   if (!a->language) return -1;
@@ -156,10 +186,10 @@
   const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb;
 
   if (a->entry_score != b->entry_score)
-    return a->entry_score < b->entry_score ? -1 : +1;
+    return a->entry_score - b->entry_score;
 
   if (a->entry_index != b->entry_index)
-    return a->entry_index < b->entry_index ? -1 : +1;
+    return a->entry_index - b->entry_index;
 
   return 0;
 }
@@ -184,18 +214,23 @@
     this->format = 0;
     this->count = it.len ();
 
-    auto snap = c->snapshot ();
-    this->nameRecordZ.serialize (c, this->count);
-    if (unlikely (!c->check_assign (this->stringOffset, c->length ()))) return_trace (false);
-    c->revert (snap);
+    NameRecord *name_records = (NameRecord *) calloc (it.len (), NameRecord::static_size);
+    hb_array_t<NameRecord> records (name_records, it.len ());
 
-    const void *dst_string_pool = &(this + this->stringOffset);
+    for (const NameRecord& record : it)
+    {
+      memcpy (name_records, &record, NameRecord::static_size);
+      name_records++;
+    }
 
-    for (const auto &_ : it) c->copy (_, src_string_pool, dst_string_pool);
+    records.qsort ();
 
+    c->copy_all (records, src_string_pool);
+    free (records.arrayZ);
+
     if (unlikely (c->ran_out_of_room)) return_trace (false);
 
-    assert (this->stringOffset == c->length ());
+    this->stringOffset = c->length ();
 
     return_trace (true);
   }
@@ -210,6 +245,8 @@
     auto it =
     + nameRecordZ.as_array (count)
     | hb_filter (c->plan->name_ids, &NameRecord::nameID)
+    | hb_filter (c->plan->name_languages, &NameRecord::languageID)
+    | hb_filter ([&] (const NameRecord& namerecord) { return c->plan->name_legacy || namerecord.isUnicode (); })
     ;
 
     name_prime->serialize (c->serializer, it, hb_addressof (this + stringOffset));
@@ -237,7 +274,7 @@
   {
     void init (hb_face_t *face)
     {
-      this->table = hb_sanitize_context_t().reference_table<name> (face);
+      this->table = hb_sanitize_context_t ().reference_table<name> (face);
       assert (this->table.get_length () >= this->table->stringOffset);
       this->pool = (const char *) (const void *) (this->table+this->table->stringOffset);
       this->pool_len = this->table.get_length () - this->table->stringOffset;
@@ -281,16 +318,14 @@
       this->table.destroy ();
     }
 
-    int get_index (hb_ot_name_id_t   name_id,
-			  hb_language_t     language,
-			  unsigned int     *width=nullptr) const
+    int get_index (hb_ot_name_id_t  name_id,
+		   hb_language_t    language,
+		   unsigned int    *width=nullptr) const
     {
       const hb_ot_name_entry_t key = {name_id, {0}, language};
-      const hb_ot_name_entry_t *entry = (const hb_ot_name_entry_t *)
-					hb_bsearch (&key,
-						    (const hb_ot_name_entry_t *) this->names,
+      const hb_ot_name_entry_t *entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names,
 						    this->names.length,
-						    sizeof (key),
+						    sizeof (hb_ot_name_entry_t),
 						    _hb_ot_name_entry_cmp_key);
       if (!entry)
 	return -1;
@@ -318,12 +353,12 @@
   };
 
   /* We only implement format 0 for now. */
-  HBUINT16	format;			/* Format selector (=0/1). */
-  HBUINT16	count;			/* Number of name records. */
+  HBUINT16	format;		/* Format selector (=0/1). */
+  HBUINT16	count;		/* Number of name records. */
   NNOffsetTo<UnsizedArrayOf<HBUINT8>>
-		stringOffset;		/* Offset to start of string storage (from start of table). */
+		stringOffset;	/* Offset to start of string storage (from start of table). */
   UnsizedArrayOf<NameRecord>
-		nameRecordZ;		/* The name records where count is the number of records. */
+		nameRecordZ;	/* The name records where count is the number of records. */
   public:
   DEFINE_SIZE_ARRAY (6, nameRecordZ);
 };

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	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -216,19 +216,20 @@
 					  uint16_t *min_cp, /* OUT */
 					  uint16_t *max_cp  /* OUT */)
   {
-    *min_cp = codepoints->get_min ();
-    *max_cp = codepoints->get_max ();
+    *min_cp = hb_min (0xFFFFu, codepoints->get_min ());
+    *max_cp = hb_min (0xFFFFu, codepoints->get_max ());
   }
 
   /* https://github.com/Microsoft/Font-Validator/blob/520aaae/OTFontFileVal/val_OS2.cs#L644-L681 */
-  enum font_page_t {
-    HEBREW_FONT_PAGE		= 0xB100, // Hebrew Windows 3.1 font page
-    SIMP_ARABIC_FONT_PAGE	= 0xB200, // Simplified Arabic Windows 3.1 font page
-    TRAD_ARABIC_FONT_PAGE	= 0xB300, // Traditional Arabic Windows 3.1 font page
-    OEM_ARABIC_FONT_PAGE	= 0xB400, // OEM Arabic Windows 3.1 font page
-    SIMP_FARSI_FONT_PAGE	= 0xBA00, // Simplified Farsi Windows 3.1 font page
-    TRAD_FARSI_FONT_PAGE	= 0xBB00, // Traditional Farsi Windows 3.1 font page
-    THAI_FONT_PAGE		= 0xDE00  // Thai Windows 3.1 font page
+  enum font_page_t
+  {
+    FONT_PAGE_HEBREW		= 0xB100, /* Hebrew Windows 3.1 font page */
+    FONT_PAGE_SIMP_ARABIC	= 0xB200, /* Simplified Arabic Windows 3.1 font page */
+    FONT_PAGE_TRAD_ARABIC	= 0xB300, /* Traditional Arabic Windows 3.1 font page */
+    FONT_PAGE_OEM_ARABIC	= 0xB400, /* OEM Arabic Windows 3.1 font page */
+    FONT_PAGE_SIMP_FARSI	= 0xBA00, /* Simplified Farsi Windows 3.1 font page */
+    FONT_PAGE_TRAD_FARSI	= 0xBB00, /* Traditional Farsi Windows 3.1 font page */
+    FONT_PAGE_THAI		= 0xDE00  /* Thai Windows 3.1 font page */
   };
   font_page_t get_font_page () const
   { return (font_page_t) (version == 0 ? fsSelection & 0xFF00 : 0); }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-unicode-ranges.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-unicode-ranges.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-unicode-ranges.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -33,20 +33,9 @@
 
 struct OS2Range
 {
-  static int
-  cmp (const void *_key, const void *_item)
-  {
-    hb_codepoint_t cp = *((hb_codepoint_t *) _key);
-    const OS2Range *range = (OS2Range *) _item;
+  int cmp (hb_codepoint_t key) const
+  { return (key < start) ? -1 : key <= end ? 0 : +1; }
 
-    if (cp < range->start)
-      return -1;
-    else if (cp <= range->end)
-      return 0;
-    else
-      return +1;
-  }
-
   hb_codepoint_t start;
   hb_codepoint_t end;
   unsigned int bit;
@@ -233,13 +222,8 @@
 static unsigned int
 _hb_ot_os2_get_unicode_range_bit (hb_codepoint_t cp)
 {
-  OS2Range *range = (OS2Range*) hb_bsearch (&cp, _hb_os2_unicode_ranges,
-					    ARRAY_LENGTH (_hb_os2_unicode_ranges),
-					    sizeof (OS2Range),
-					    OS2Range::cmp);
-  if (range != nullptr)
-    return range->bit;
-  return -1;
+  auto *range = hb_sorted_array (_hb_os2_unicode_ranges).bsearch (cp);
+  return range ? range->bit : -1;
 }
 
 } /* namespace OT */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -35,8 +35,6 @@
 #undef HB_STRING_ARRAY_LIST
 #undef HB_STRING_ARRAY_NAME
 
-#define NUM_FORMAT1_NAMES 258
-
 /*
  * post -- PostScript
  * https://docs.microsoft.com/en-us/typography/opentype/spec/post
@@ -167,8 +165,7 @@
       }
 
       hb_bytes_t st (name, len);
-      const uint16_t *gid = (const uint16_t *) hb_bsearch (hb_addressof (st), gids, count,
-							   sizeof (gids[0]), cmp_key, (void *) this);
+      auto* gid = hb_bsearch (st, gids, count, sizeof (gids[0]), cmp_key, (void *) this);
       if (gid)
       {
 	*glyph = *gid;
@@ -185,7 +182,7 @@
     unsigned int get_glyph_count () const
     {
       if (version == 0x00010000)
-	return NUM_FORMAT1_NAMES;
+	return format1_names_length;
 
       if (version == 0x00020000)
 	return glyphNameIndex->len;
@@ -213,7 +210,7 @@
     {
       if (version == 0x00010000)
       {
-	if (glyph >= NUM_FORMAT1_NAMES)
+	if (glyph >= format1_names_length)
 	  return hb_bytes_t ();
 
 	return format1_names (glyph);
@@ -223,9 +220,9 @@
 	return hb_bytes_t ();
 
       unsigned int index = glyphNameIndex->arrayZ[glyph];
-      if (index < NUM_FORMAT1_NAMES)
+      if (index < format1_names_length)
 	return format1_names (index);
-      index -= NUM_FORMAT1_NAMES;
+      index -= format1_names_length;
 
       if (index >= index_to_offset.length)
 	return hb_bytes_t ();
@@ -262,7 +259,7 @@
 					 * 0x00020000 for version 2.0
 					 * 0x00025000 for version 2.5 (deprecated)
 					 * 0x00030000 for version 3.0 */
-  HBFixed		italicAngle;		/* Italic angle in counter-clockwise degrees
+  HBFixed	italicAngle;		/* Italic angle in counter-clockwise degrees
 					 * from the vertical. Zero for upright text,
 					 * negative for text that leans to the right
 					 * (forward). */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -292,7 +292,7 @@
 {
   arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) calloc (1, sizeof (arabic_fallback_plan_t));
   if (unlikely (!fallback_plan))
-    return const_cast<arabic_fallback_plan_t *> (&Null(arabic_fallback_plan_t));
+    return const_cast<arabic_fallback_plan_t *> (&Null (arabic_fallback_plan_t));
 
   fallback_plan->num_lookups = 0;
   fallback_plan->free_lookups = false;
@@ -309,7 +309,7 @@
 
   assert (fallback_plan->num_lookups == 0);
   free (fallback_plan);
-  return const_cast<arabic_fallback_plan_t *> (&Null(arabic_fallback_plan_t));
+  return const_cast<arabic_fallback_plan_t *> (&Null (arabic_fallback_plan_t));
 }
 
 static void

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -271,7 +271,7 @@
     arabic_plan->mask_array[i] = plan->map.get_1_mask (arabic_features[i]);
     arabic_plan->do_fallback = arabic_plan->do_fallback &&
 			       (FEATURE_IS_SYRIAC (arabic_features[i]) ||
-			        plan->map.needs_fallback (arabic_features[i]));
+				plan->map.needs_fallback (arabic_features[i]));
   }
 
   return arabic_plan;
@@ -292,7 +292,7 @@
 {
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
-  unsigned int prev = (unsigned int) -1, state = 0;
+  unsigned int prev = UINT_MAX, state = 0;
 
   /* Check pre-context */
   for (unsigned int i = 0; i < buffer->context_len[0]; i++)
@@ -318,7 +318,7 @@
 
     const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
 
-    if (entry->prev_action != NONE && prev != (unsigned int) -1)
+    if (entry->prev_action != NONE && prev != UINT_MAX)
     {
       info[prev].arabic_shaping_action() = entry->prev_action;
       buffer->unsafe_to_break (prev, i + 1);
@@ -338,7 +338,7 @@
       continue;
 
     const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
-    if (entry->prev_action != NONE && prev != (unsigned int) -1)
+    if (entry->prev_action != NONE && prev != UINT_MAX)
       info[prev].arabic_shaping_action() = entry->prev_action;
     break;
   }
@@ -604,7 +604,7 @@
   HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
 }
 
-/* http://www.unicode.org/reports/tr53/ */
+/* https://www.unicode.org/reports/tr53/ */
 
 static hb_codepoint_t
 modifier_combining_marks[] =

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-default.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-default.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-default.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -49,5 +49,25 @@
   true, /* fallback_position */
 };
 
+/* Same as default but no mark advance zeroing / fallback positioning.
+ * Dumbest shaper ever, basically. */
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_dumber =
+{
+  nullptr, /* collect_features */
+  nullptr, /* override_features */
+  nullptr, /* data_create */
+  nullptr, /* data_destroy */
+  nullptr, /* preprocess_text */
+  nullptr, /* postprocess_glyphs */
+  HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
+  nullptr, /* decompose */
+  nullptr, /* compose */
+  nullptr, /* setup_masks */
+  HB_TAG_NONE, /* gpos_tag */
+  nullptr, /* reorder_marks */
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
+  false, /* fallback_position */
+};
 
+
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.rl	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic-machine.rl	2020-05-18 10:44:36 UTC (rev 55197)
@@ -76,7 +76,7 @@
 consonant_syllable =	(Repha|CS)? cn complex_syllable_tail;
 vowel_syllable =	reph? V.n? (ZWJ | complex_syllable_tail);
 standalone_cluster =	((Repha|CS)? PLACEHOLDER | reph? DOTTEDCIRCLE).n? complex_syllable_tail;
-symbol_cluster = 	symbol syllable_tail;
+symbol_cluster =	symbol syllable_tail;
 broken_cluster =	reph? n? complex_syllable_tail;
 other =			any;
 

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	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-indic.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -248,6 +248,7 @@
   hb_indic_would_substitute_feature_t pref;
   hb_indic_would_substitute_feature_t blwf;
   hb_indic_would_substitute_feature_t pstf;
+  hb_indic_would_substitute_feature_t vatu;
 
   hb_mask_t mask_array[INDIC_NUM_FEATURES];
 };
@@ -286,6 +287,7 @@
   indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'), zero_context);
   indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f'), zero_context);
   indic_plan->pstf.init (&plan->map, HB_TAG('p','s','t','f'), zero_context);
+  indic_plan->vatu.init (&plan->map, HB_TAG('v','a','t','u'), zero_context);
 
   for (unsigned int i = 0; i < ARRAY_LENGTH (indic_plan->mask_array); i++)
     indic_plan->mask_array[i] = (indic_features[i].flags & F_GLOBAL) ?
@@ -315,10 +317,16 @@
    * base at 0.  The font however, only has lookups matching
    * 930,94D in 'blwf', not the expected 94D,930 (with new-spec
    * table).  As such, we simply match both sequences.  Seems
-   * to work. */
+   * to work.
+   *
+   * Vatu is done as well, for:
+   * https://github.com/harfbuzz/harfbuzz/issues/1587
+   */
   hb_codepoint_t glyphs[3] = {virama, consonant, virama};
   if (indic_plan->blwf.would_substitute (glyphs  , 2, face) ||
-      indic_plan->blwf.would_substitute (glyphs+1, 2, face))
+      indic_plan->blwf.would_substitute (glyphs+1, 2, face) ||
+      indic_plan->vatu.would_substitute (glyphs  , 2, face) ||
+      indic_plan->vatu.would_substitute (glyphs+1, 2, face))
     return POS_BELOW_C;
   if (indic_plan->pstf.would_substitute (glyphs  , 2, face) ||
       indic_plan->pstf.would_substitute (glyphs+1, 2, face))

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-myanmar-machine.rl	2020-05-18 10:44:36 UTC (rev 55197)
@@ -78,7 +78,7 @@
 syllable_tail = (H (c|IV).VS?)* (H | complex_syllable_tail);
 
 consonant_syllable =	(k|CS)? (c|IV|D|GB).VS? syllable_tail;
-punctuation_cluster = 	P V;
+punctuation_cluster =	P V;
 broken_cluster =	k? VS? syllable_tail;
 other =			any;
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-vowel-constraints.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-vowel-constraints.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-vowel-constraints.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -2,15 +2,16 @@
 /*
  * The following functions are generated by running:
  *
- *   ./gen-vowel-constraints.py use Scripts.txt
+ *   ./gen-vowel-constraints.py ms-use/IndicShapingInvalidCluster.txt Scripts.txt
  *
  * on files with these headers:
  *
- * # Copied from https://docs.microsoft.com/en-us/typography/script-development/use
- * # On October 23, 2018; with documentd dated 02/07/2018.
+ * # IndicShapingInvalidCluster.txt
+ * # Date: 2015-03-12, 21:17:00 GMT [AG]
+ * # Date: 2019-11-08, 23:22:00 GMT [AG]
  *
- * # Scripts-12.0.0.txt
- * # Date: 2019-01-28, 22:16:47 GMT
+ * # Scripts-12.1.0.txt
+ * # Date: 2019-04-01, 09:10:42 GMT
  */
 
 #include "hb.hh"
@@ -211,6 +212,22 @@
       processed = true;
       break;
 
+    case HB_SCRIPT_TAMIL:
+      for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
+      {
+	bool matched = false;
+	if (0x0B85u == buffer->cur ().codepoint &&
+	    0x0BC2u == buffer->cur (1).codepoint)
+	{
+	  buffer->next_glyph ();
+	  _output_dotted_circle (buffer);
+	}
+	buffer->next_glyph ();
+	if (matched) _output_with_dotted_circle (buffer);
+      }
+      processed = true;
+      break;
+
     case HB_SCRIPT_TELUGU:
       for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
       {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -50,8 +50,9 @@
 
 /* Master OT shaper list */
 #define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \
-  HB_COMPLEX_SHAPER_IMPLEMENT (default) /* should be first */ \
   HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \
+  HB_COMPLEX_SHAPER_IMPLEMENT (default) \
+  HB_COMPLEX_SHAPER_IMPLEMENT (dumber) \
   HB_COMPLEX_SHAPER_IMPLEMENT (hangul) \
   HB_COMPLEX_SHAPER_IMPLEMENT (hebrew) \
   HB_COMPLEX_SHAPER_IMPLEMENT (indic) \
@@ -60,7 +61,7 @@
   HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_zawgyi) \
   HB_COMPLEX_SHAPER_IMPLEMENT (thai) \
   HB_COMPLEX_SHAPER_IMPLEMENT (use) \
-  /* ^--- Add new shapers here */
+  /* ^--- Add new shapers here; keep sorted. */
 
 
 struct hb_ot_complex_shaper_t

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -422,12 +422,12 @@
   /* Find the base glyph */
   hb_glyph_info_t *info = buffer->info;
   for (unsigned int i = start; i < end; i++)
-    if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))
+    if (!_hb_glyph_info_is_unicode_mark (&info[i]))
     {
       /* Find mark glyphs */
       unsigned int j;
       for (j = i + 1; j < end; j++)
-	if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[j])))
+	if (!_hb_glyph_info_is_unicode_mark (&info[j]))
 	  break;
 
       position_around_base (plan, font, buffer, i, j, adjust_offsets_when_zeroing);
@@ -452,7 +452,7 @@
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
   for (unsigned int i = 1; i < count; i++)
-    if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))) {
+    if (likely (!_hb_glyph_info_is_unicode_mark (&info[i]))) {
       position_cluster (plan, font, buffer, start, i, adjust_offsets_when_zeroing);
       start = i;
     }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-normalize.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -334,7 +334,7 @@
     {
       unsigned int end;
       for (end = buffer->idx + 1; end < count; end++)
-	if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[end]))))
+	if (unlikely (_hb_glyph_info_is_unicode_mark (&buffer->info[end])))
 	  break;
 
       if (end < count)
@@ -360,7 +360,7 @@
 
       /* Find all the marks now. */
       for (end = buffer->idx + 1; end < count; end++)
-	if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[end])))
+	if (!_hb_glyph_info_is_unicode_mark(&buffer->info[end]))
 	  break;
 
       /* idx to end is one non-simple cluster. */
@@ -435,7 +435,7 @@
 	   * This is both an optimization to avoid trying to compose every two neighboring
 	   * glyphs in most scripts AND a desired feature for Hangul.  Apparently Hangul
 	   * fonts are not designed to mix-and-match pre-composed syllables and Jamo. */
-	  HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())))
+	  _hb_glyph_info_is_unicode_mark(&buffer->cur()))
       {
 	if (/* If there's anything between the starter and this char, they should have CCC
 	     * smaller than this character's. */

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	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -48,6 +48,16 @@
 #include "hb-aat-layout.hh"
 
 
+#ifndef HB_NO_AAT_SHAPE
+static inline bool
+_hb_apply_morx (hb_face_t *face, const hb_segment_properties_t *props)
+{
+  /* https://github.com/harfbuzz/harfbuzz/issues/2124 */
+  return hb_aat_layout_has_substitution (face) &&
+	 (HB_DIRECTION_IS_HORIZONTAL (props->direction) || !hb_ot_layout_has_substitution (face));
+}
+#endif
+
 /**
  * SECTION:hb-ot-shape
  * @title: hb-ot-shape
@@ -63,23 +73,6 @@
 			      const hb_feature_t             *user_features,
 			      unsigned int                    num_user_features);
 
-#ifndef HB_NO_AAT_SHAPE
-static inline bool
-_hb_apply_morx (hb_face_t *face)
-{
-  if (hb_options ().aat &&
-      hb_aat_layout_has_substitution (face))
-    return true;
-
-  /* Ignore empty GSUB tables. */
-  return (!hb_ot_layout_has_substitution (face) ||
-	  !hb_ot_layout_table_get_script_tags (face,
-					       HB_OT_TAG_GSUB,
-					       0, nullptr, nullptr)) &&
-	 hb_aat_layout_has_substitution (face);
-}
-#endif
-
 hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t                     *face,
 					      const hb_segment_properties_t *props) :
 						face (face),
@@ -87,7 +80,7 @@
 						map (face, props),
 						aat_map (face, props)
 #ifndef HB_NO_AAT_SHAPE
-						, apply_morx (_hb_apply_morx (face))
+						, apply_morx (_hb_apply_morx (face, props))
 #endif
 {
   shaper = hb_ot_shape_complex_categorize (this);
@@ -95,8 +88,9 @@
   script_zero_marks = shaper->zero_width_marks != HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE;
   script_fallback_mark_positioning = shaper->fallback_position;
 
-  if (apply_morx)
-    shaper = &_hb_ot_complex_shaper_default;
+  /* https://github.com/harfbuzz/harfbuzz/issues/1528 */
+  if (apply_morx && shaper != &_hb_ot_complex_shaper_default)
+    shaper = &_hb_ot_complex_shaper_dumber;
 }
 
 void
@@ -119,6 +113,8 @@
 #endif
 
   plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m'));
+  plan.has_vert = !!plan.map.get_1_mask (HB_TAG ('v','e','r','t'));
+
   hb_tag_t kern_tag = HB_DIRECTION_IS_HORIZONTAL (props.direction) ?
 		      HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n');
 #ifndef HB_NO_OT_KERN
@@ -156,17 +152,13 @@
   if (0)
     ;
 #ifndef HB_NO_AAT_SHAPE
-  else if (hb_options ().aat && hb_aat_layout_has_positioning (face))
+  else if (hb_aat_layout_has_positioning (face))
     plan.apply_kerx = true;
 #endif
   else if (!apply_morx && !disable_gpos && hb_ot_layout_has_positioning (face))
     plan.apply_gpos = true;
-#ifndef HB_NO_AAT_SHAPE
-  else if (hb_aat_layout_has_positioning (face))
-    plan.apply_kerx = true;
-#endif
 
-  if (!plan.apply_kerx && !has_gpos_kern)
+  if (!plan.apply_kerx && (!has_gpos_kern || !plan.apply_gpos))
   {
     /* Apparently Apple applies kerx if GPOS kern was not applied. */
 #ifndef HB_NO_AAT_SHAPE
@@ -594,25 +586,86 @@
  * Substitute
  */
 
+static hb_codepoint_t
+hb_vert_char_for (hb_codepoint_t u)
+{
+  switch (u >> 8)
+  {
+    case 0x20: switch (u) {
+      case 0x2013u: return 0xfe32u; // EN DASH
+      case 0x2014u: return 0xfe31u; // EM DASH
+      case 0x2025u: return 0xfe30u; // TWO DOT LEADER
+      case 0x2026u: return 0xfe19u; // HORIZONTAL ELLIPSIS
+    } break;
+    case 0x30: switch (u) {
+      case 0x3001u: return 0xfe11u; // IDEOGRAPHIC COMMA
+      case 0x3002u: return 0xfe12u; // IDEOGRAPHIC FULL STOP
+      case 0x3008u: return 0xfe3fu; // LEFT ANGLE BRACKET
+      case 0x3009u: return 0xfe40u; // RIGHT ANGLE BRACKET
+      case 0x300au: return 0xfe3du; // LEFT DOUBLE ANGLE BRACKET
+      case 0x300bu: return 0xfe3eu; // RIGHT DOUBLE ANGLE BRACKET
+      case 0x300cu: return 0xfe41u; // LEFT CORNER BRACKET
+      case 0x300du: return 0xfe42u; // RIGHT CORNER BRACKET
+      case 0x300eu: return 0xfe43u; // LEFT WHITE CORNER BRACKET
+      case 0x300fu: return 0xfe44u; // RIGHT WHITE CORNER BRACKET
+      case 0x3010u: return 0xfe3bu; // LEFT BLACK LENTICULAR BRACKET
+      case 0x3011u: return 0xfe3cu; // RIGHT BLACK LENTICULAR BRACKET
+      case 0x3014u: return 0xfe39u; // LEFT TORTOISE SHELL BRACKET
+      case 0x3015u: return 0xfe3au; // RIGHT TORTOISE SHELL BRACKET
+      case 0x3016u: return 0xfe17u; // LEFT WHITE LENTICULAR BRACKET
+      case 0x3017u: return 0xfe18u; // RIGHT WHITE LENTICULAR BRACKET
+    } break;
+    case 0xfe: switch (u) {
+      case 0xfe4fu: return 0xfe34u; // WAVY LOW LINE
+    } break;
+    case 0xff: switch (u) {
+      case 0xff01u: return 0xfe15u; // FULLWIDTH EXCLAMATION MARK
+      case 0xff08u: return 0xfe35u; // FULLWIDTH LEFT PARENTHESIS
+      case 0xff09u: return 0xfe36u; // FULLWIDTH RIGHT PARENTHESIS
+      case 0xff0cu: return 0xfe10u; // FULLWIDTH COMMA
+      case 0xff1au: return 0xfe13u; // FULLWIDTH COLON
+      case 0xff1bu: return 0xfe14u; // FULLWIDTH SEMICOLON
+      case 0xff1fu: return 0xfe16u; // FULLWIDTH QUESTION MARK
+      case 0xff3bu: return 0xfe47u; // FULLWIDTH LEFT SQUARE BRACKET
+      case 0xff3du: return 0xfe48u; // FULLWIDTH RIGHT SQUARE BRACKET
+      case 0xff3fu: return 0xfe33u; // FULLWIDTH LOW LINE
+      case 0xff5bu: return 0xfe37u; // FULLWIDTH LEFT CURLY BRACKET
+      case 0xff5du: return 0xfe38u; // FULLWIDTH RIGHT CURLY BRACKET
+    } break;
+  }
+
+  return u;
+}
+
 static inline void
-hb_ot_mirror_chars (const hb_ot_shape_context_t *c)
+hb_ot_rotate_chars (const hb_ot_shape_context_t *c)
 {
-  if (HB_DIRECTION_IS_FORWARD (c->target_direction))
-    return;
-
   hb_buffer_t *buffer = c->buffer;
-  hb_unicode_funcs_t *unicode = buffer->unicode;
-  hb_mask_t rtlm_mask = c->plan->rtlm_mask;
-
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
-  for (unsigned int i = 0; i < count; i++) {
-    hb_codepoint_t codepoint = unicode->mirroring (info[i].codepoint);
-    if (likely (codepoint == info[i].codepoint || !c->font->has_glyph (codepoint)))
-      info[i].mask |= rtlm_mask;
-    else
-      info[i].codepoint = codepoint;
+
+  if (HB_DIRECTION_IS_BACKWARD (c->target_direction))
+  {
+    hb_unicode_funcs_t *unicode = buffer->unicode;
+    hb_mask_t rtlm_mask = c->plan->rtlm_mask;
+
+    for (unsigned int i = 0; i < count; i++) {
+      hb_codepoint_t codepoint = unicode->mirroring (info[i].codepoint);
+      if (unlikely (codepoint != info[i].codepoint && c->font->has_glyph (codepoint)))
+	info[i].codepoint = codepoint;
+      else
+	info[i].mask |= rtlm_mask;
+    }
   }
+
+  if (HB_DIRECTION_IS_VERTICAL (c->target_direction) && !c->plan->has_vert)
+  {
+    for (unsigned int i = 0; i < count; i++) {
+      hb_codepoint_t codepoint = hb_vert_char_for (info[i].codepoint);
+      if (unlikely (codepoint != info[i].codepoint && c->font->has_glyph (codepoint)))
+	info[i].codepoint = codepoint;
+    }
+  }
 }
 
 static inline void
@@ -693,7 +746,7 @@
   for (unsigned int i = 0; i < c->num_user_features; i++)
   {
     const hb_feature_t *feature = &c->user_features[i];
-    if (!(feature->start == 0 && feature->end == (unsigned int)-1)) {
+    if (!(feature->start == HB_FEATURE_GLOBAL_START && feature->end == HB_FEATURE_GLOBAL_END)) {
       unsigned int shift;
       hb_mask_t mask = map->get_mask (feature->tag, &shift);
       buffer->set_masks (feature->value << shift, mask, feature->start, feature->end);
@@ -788,7 +841,7 @@
 {
   hb_buffer_t *buffer = c->buffer;
 
-  hb_ot_mirror_chars (c);
+  hb_ot_rotate_chars (c);
 
   HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index);
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -37,9 +37,9 @@
 {
   unsigned int variations_index[2];
 
-  void init (hb_face_t   *face,
-		    const int   *coords,
-		    unsigned int num_coords)
+  void init (hb_face_t *face,
+	     const int *coords,
+	     unsigned   num_coords)
   {
     for (unsigned int table_index = 0; table_index < 2; table_index++)
       hb_ot_layout_table_find_feature_variations (face,
@@ -99,6 +99,7 @@
 #else
   static constexpr bool has_frac = false;
 #endif
+  bool has_vert : 1;
   bool has_gpos_mark : 1;
   bool zero_marks : 1;
   bool fallback_glyph_classes : 1;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -77,7 +77,7 @@
   NameID	valueNameID;	/* The name ID for entries in the 'name' table
 				 * that provide a display string for this
 				 * attribute value. */
-  HBFixed		value;		/* A numeric value for this attribute value. */
+  HBFixed	value;		/* A numeric value for this attribute value. */
   public:
   DEFINE_SIZE_STATIC (12);
 };
@@ -102,10 +102,10 @@
   NameID	valueNameID;	/* The name ID for entries in the 'name' table
 				 * that provide a display string for this
 				 * attribute value. */
-  HBFixed		nominalValue;	/* A numeric value for this attribute value. */
-  HBFixed		rangeMinValue;	/* The minimum value for a range associated
+  HBFixed	nominalValue;	/* A numeric value for this attribute value. */
+  HBFixed	rangeMinValue;	/* The minimum value for a range associated
 				 * with the specified name ID. */
-  HBFixed		rangeMaxValue;	/* The maximum value for a range associated
+  HBFixed	rangeMaxValue;	/* The maximum value for a range associated
 				 * with the specified name ID. */
   public:
   DEFINE_SIZE_STATIC (20);
@@ -131,8 +131,8 @@
   NameID	valueNameID;	/* The name ID for entries in the 'name' table
 				 * that provide a display string for this
 				 * attribute value. */
-  HBFixed		value;		/* A numeric value for this attribute value. */
-  HBFixed		linkedValue;	/* The numeric value for a style-linked mapping
+  HBFixed	value;		/* A numeric value for this attribute value. */
+  HBFixed	linkedValue;	/* The numeric value for a style-linked mapping
 				 * from this value. */
   public:
   DEFINE_SIZE_STATIC (16);
@@ -150,7 +150,7 @@
   HBUINT16	axisIndex;	/* Zero-base index into the axis record array
 				 * identifying the axis to which this value
 				 * applies. Must be less than designAxisCount. */
-  HBFixed		value;		/* A numeric value for this attribute value. */
+  HBFixed	value;		/* A numeric value for this attribute value. */
   public:
   DEFINE_SIZE_STATIC (6);
 };

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -51,7 +51,7 @@
   public:
   F2DOT14	coords[2];
 //   F2DOT14	fromCoord;	/* A normalized coordinate value obtained using
-// 				 * default normalization. */
+//				 * default normalization. */
 //   F2DOT14	toCoord;	/* The modified, normalized coordinate value. */
 
   public:
@@ -79,7 +79,7 @@
       return value - arrayZ[0].fromCoord + arrayZ[0].toCoord;
 
     unsigned int i;
-    unsigned int count = len;
+    unsigned int count = len - 1;
     for (i = 1; i < count && value > arrayZ[i].fromCoord; i++)
       ;
 
@@ -90,9 +90,8 @@
       return arrayZ[i-1].toCoord;
 
     int denom = arrayZ[i].fromCoord - arrayZ[i-1].fromCoord;
-    return arrayZ[i-1].toCoord +
-	   ((arrayZ[i].toCoord - arrayZ[i-1].toCoord) *
-	    (value - arrayZ[i-1].fromCoord) + denom/2) / denom;
+    return roundf (arrayZ[i-1].toCoord + ((float) (arrayZ[i].toCoord - arrayZ[i-1].toCoord) *
+					  (value - arrayZ[i-1].fromCoord)) / denom);
 #undef toCoord
 #undef fromCoord
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -83,9 +83,9 @@
 
   public:
   Tag		axisTag;	/* Tag identifying the design variation for the axis. */
-  HBFixed		minValue;	/* The minimum coordinate value for the axis. */
-  HBFixed		defaultValue;	/* The default coordinate value for the axis. */
-  HBFixed		maxValue;	/* The maximum coordinate value for the axis. */
+  HBFixed	minValue;	/* The minimum coordinate value for the axis. */
+  HBFixed	defaultValue;	/* The default coordinate value for the axis. */
+  HBFixed	maxValue;	/* The maximum coordinate value for the axis. */
   HBUINT16	flags;		/* Axis flags. */
   NameID	axisNameID;	/* The name ID for entries in the 'name' table that
 				 * provide a display name for this axis. */
@@ -150,17 +150,8 @@
   {
     if (axes_count)
     {
-      /* TODO Rewrite as hb_array_t<>::sub-array() */
-      unsigned int count = axisCount;
-      start_offset = hb_min (start_offset, count);
-
-      count -= start_offset;
-      axes_array += start_offset;
-
-      count = hb_min (count, *axes_count);
-      *axes_count = count;
-
-      for (unsigned int i = 0; i < count; i++)
+      hb_array_t<const AxisRecord> arr = hb_array (&(this+firstAxis), axisCount).sub_array (start_offset, axes_count);
+      for (unsigned i = 0; i < arr.length; ++i)
 	get_axis_deprecated (start_offset + i, axes_array + i);
     }
     return axisCount;
@@ -173,17 +164,8 @@
   {
     if (axes_count)
     {
-      /* TODO Rewrite as hb_array_t<>::sub-array() */
-      unsigned int count = axisCount;
-      start_offset = hb_min (start_offset, count);
-
-      count -= start_offset;
-      axes_array += start_offset;
-
-      count = hb_min (count, *axes_count);
-      *axes_count = count;
-
-      for (unsigned int i = 0; i < count; i++)
+      hb_array_t<const AxisRecord> arr = hb_array (&(this+firstAxis), axisCount).sub_array (start_offset, axes_count);
+      for (unsigned i = 0; i < arr.length; ++i)
 	get_axis_info (start_offset + i, axes_array + i);
     }
     return axisCount;
@@ -229,7 +211,7 @@
     hb_ot_var_axis_info_t axis;
     get_axis_info (axis_index, &axis);
 
-    v = hb_max (hb_min (v, axis.max_value), axis.min_value); /* Clamp. */
+    v = hb_clamp (v, axis.min_value, axis.max_value);
 
     if (v == axis.default_value)
       return 0;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -29,8 +29,6 @@
 #define HB_OT_VAR_GVAR_TABLE_HH
 
 #include "hb-open-type.hh"
-#include "hb-ot-glyf-table.hh"
-#include "hb-ot-var-fvar-table.hh"
 
 /*
  * gvar -- Glyph Variation Table
@@ -42,12 +40,14 @@
 
 struct contour_point_t
 {
-  void init (float x_=0.f, float y_=0.f) { flag = 0; x = x_; y = y_; }
+  void init (float x_ = 0.f, float y_ = 0.f, bool is_end_point_ = false)
+  { flag = 0; x = x_; y = y_; is_end_point = is_end_point_; }
 
   void translate (const contour_point_t &p) { x += p.x; y += p.y; }
 
   uint8_t flag;
   float x, y;
+  bool is_end_point;
 };
 
 struct contour_point_vector_t : hb_vector_t<contour_point_t>
@@ -78,50 +78,34 @@
   }
 };
 
-struct Tuple : UnsizedArrayOf<F2DOT14> {};
-
-struct TuppleIndex : HBUINT16
+/* https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader */
+struct TupleVariationHeader
 {
-  enum Flags {
-    EmbeddedPeakTuple   = 0x8000u,
-    IntermediateRegion  = 0x4000u,
-    PrivatePointNumbers = 0x2000u,
-    TupleIndexMask      = 0x0FFFu
-  };
+  unsigned get_size (unsigned axis_count) const
+  { return min_size + get_all_tuples (axis_count).get_size (); }
 
-  DEFINE_SIZE_STATIC (2);
-};
+  unsigned get_data_size () const { return varDataSize; }
 
-struct TupleVarHeader
-{
-  unsigned int get_size (unsigned int axis_count) const
-  {
-    return min_size +
-	   (has_peak () ? get_peak_tuple ().get_size (axis_count) : 0) +
-	   (has_intermediate () ? (get_start_tuple (axis_count).get_size (axis_count) +
-				   get_end_tuple (axis_count).get_size (axis_count)) : 0);
-  }
+  const TupleVariationHeader &get_next (unsigned axis_count) const
+  { return StructAtOffset<TupleVariationHeader> (this, get_size (axis_count)); }
 
-  const TupleVarHeader &get_next (unsigned int axis_count) const
-  { return StructAtOffset<TupleVarHeader> (this, get_size (axis_count)); }
-
   float calculate_scalar (const int *coords, unsigned int coord_count,
-  			  const hb_array_t<const F2DOT14> shared_tuples) const
+			  const hb_array_t<const F2DOT14> shared_tuples) const
   {
-    const F2DOT14 *peak_tuple;
+    hb_array_t<const F2DOT14> peak_tuple;
 
     if (has_peak ())
-      peak_tuple = &(get_peak_tuple ()[0]);
+      peak_tuple = get_peak_tuple (coord_count);
     else
     {
       unsigned int index = get_index ();
       if (unlikely (index * coord_count >= shared_tuples.length))
 	return 0.f;
-      peak_tuple = &shared_tuples[coord_count * index];
+      peak_tuple = shared_tuples.sub_array (coord_count * index, coord_count);
     }
 
-    const F2DOT14 *start_tuple = nullptr;
-    const F2DOT14 *end_tuple = nullptr;
+    hb_array_t<const F2DOT14> start_tuple;
+    hb_array_t<const F2DOT14> end_tuple;
     if (has_intermediate ())
     {
       start_tuple = get_start_tuple (coord_count);
@@ -154,8 +138,6 @@
     return scalar;
   }
 
-  unsigned int get_data_size () const { return varDataSize; }
-
   bool           has_peak () const { return (tupleIndex & TuppleIndex::EmbeddedPeakTuple); }
   bool   has_intermediate () const { return (tupleIndex & TuppleIndex::IntermediateRegion); }
   bool has_private_points () const { return (tupleIndex & TuppleIndex::PrivatePointNumbers); }
@@ -162,50 +144,58 @@
   unsigned int  get_index () const { return (tupleIndex & TuppleIndex::TupleIndexMask); }
 
   protected:
-  const Tuple &get_peak_tuple () const
-  { return StructAfter<Tuple> (tupleIndex); }
-  const Tuple &get_start_tuple (unsigned int axis_count) const
-  { return *(const Tuple *) &get_peak_tuple ()[has_peak () ? axis_count : 0]; }
-  const Tuple &get_end_tuple (unsigned int axis_count) const
-  { return *(const Tuple *) &get_peak_tuple ()[has_peak () ? (axis_count * 2) : axis_count]; }
+  struct TuppleIndex : HBUINT16
+  {
+    enum Flags {
+      EmbeddedPeakTuple   = 0x8000u,
+      IntermediateRegion  = 0x4000u,
+      PrivatePointNumbers = 0x2000u,
+      TupleIndexMask      = 0x0FFFu
+    };
 
-  HBUINT16		varDataSize;
-  TuppleIndex		tupleIndex;
+    DEFINE_SIZE_STATIC (2);
+  };
+
+  hb_array_t<const F2DOT14> get_all_tuples (unsigned axis_count) const
+  { return StructAfter<UnsizedArrayOf<F2DOT14>> (tupleIndex).as_array ((has_peak () + has_intermediate () * 2) * axis_count); }
+  hb_array_t<const F2DOT14> get_peak_tuple (unsigned axis_count) const
+  { return get_all_tuples (axis_count).sub_array (0, axis_count); }
+  hb_array_t<const F2DOT14> get_start_tuple (unsigned axis_count) const
+  { return get_all_tuples (axis_count).sub_array (has_peak () * axis_count, axis_count); }
+  hb_array_t<const F2DOT14> get_end_tuple (unsigned axis_count) const
+  { return get_all_tuples (axis_count).sub_array (has_peak () * axis_count + axis_count, axis_count); }
+
+  HBUINT16	varDataSize;	/* The size in bytes of the serialized
+				 * data for this tuple variation table. */
+  TuppleIndex	tupleIndex;	/* A packed field. The high 4 bits are flags (see below).
+				   The low 12 bits are an index into a shared tuple
+				   records array. */
   /* UnsizedArrayOf<F2DOT14> peakTuple - optional */
+				/* Peak tuple record for this tuple variation table — optional,
+				 * determined by flags in the tupleIndex value.
+				 *
+				 * Note that this must always be included in the 'cvar' table. */
   /* UnsizedArrayOf<F2DOT14> intermediateStartTuple - optional */
+				/* Intermediate start tuple record for this tuple variation table — optional,
+				   determined by flags in the tupleIndex value. */
   /* UnsizedArrayOf<F2DOT14> intermediateEndTuple - optional */
-
+				/* Intermediate end tuple record for this tuple variation table — optional,
+				 * determined by flags in the tupleIndex value. */
   public:
   DEFINE_SIZE_MIN (4);
 };
 
-struct TupleVarCount : HBUINT16
+struct GlyphVariationData
 {
-  bool has_shared_point_numbers () const { return ((*this) & SharedPointNumbers); }
-  unsigned int get_count () const { return (*this) & CountMask; }
+  const TupleVariationHeader &get_tuple_var_header (void) const
+  { return StructAfter<TupleVariationHeader> (data); }
 
-  protected:
-  enum Flags
-  {
-    SharedPointNumbers	= 0x8000u,
-    CountMask		= 0x0FFFu
-  };
-
-  public:
-  DEFINE_SIZE_STATIC (2);
-};
-
-struct GlyphVarData
-{
-  const TupleVarHeader &get_tuple_var_header (void) const
-  { return StructAfter<TupleVarHeader> (data); }
-
   struct tuple_iterator_t
   {
-    void init (const GlyphVarData *var_data_, unsigned int length_, unsigned int axis_count_)
+    void init (hb_bytes_t var_data_bytes_, unsigned int axis_count_)
     {
-      var_data = var_data_;
-      length = length_;
+      var_data_bytes = var_data_bytes_;
+      var_data = var_data_bytes_.as<GlyphVariationData> ();
       index = 0;
       axis_count = axis_count_;
       current_tuple = &var_data->get_tuple_var_header ();
@@ -216,10 +206,9 @@
     {
       if (var_data->has_shared_point_numbers ())
       {
-	hb_bytes_t bytes ((const char *) var_data, length);
 	const HBUINT8 *base = &(var_data+var_data->data);
 	const HBUINT8 *p = base;
-	if (!unpack_points (p, shared_indices, bytes)) return false;
+	if (!unpack_points (p, shared_indices, var_data_bytes)) return false;
 	data_offset = p - base;
       }
       return true;
@@ -228,7 +217,8 @@
     bool is_valid () const
     {
       return (index < var_data->tupleVarCount.get_count ()) &&
-	     in_range (current_tuple) &&
+	     var_data_bytes.check_range (current_tuple, TupleVariationHeader::min_size) &&
+	     var_data_bytes.check_range (current_tuple, hb_max (current_tuple->get_data_size (), current_tuple->get_size (axis_count))) &&
 	     current_tuple->get_size (axis_count);
     }
 
@@ -240,32 +230,25 @@
       return is_valid ();
     }
 
-    bool in_range (const void *p, unsigned int l) const
-    { return (const char*) p >= (const char*) var_data && (const char*) p+l <= (const char*) var_data + length; }
-
-    template <typename T> bool in_range (const T *p) const { return in_range (p, sizeof (*p)); }
-
     const HBUINT8 *get_serialized_data () const
     { return &(var_data+var_data->data) + data_offset; }
 
     private:
-    const GlyphVarData *var_data;
-    unsigned int length;
+    const GlyphVariationData *var_data;
     unsigned int index;
     unsigned int axis_count;
     unsigned int data_offset;
 
     public:
-    const TupleVarHeader *current_tuple;
+    hb_bytes_t var_data_bytes;
+    const TupleVariationHeader *current_tuple;
   };
 
-  static bool get_tuple_iterator (const GlyphVarData *var_data,
-  				  unsigned int length,
-  				  unsigned int axis_count,
-  				  hb_vector_t<unsigned int> &shared_indices /* OUT */,
-  				  tuple_iterator_t *iterator /* OUT */)
+  static bool get_tuple_iterator (hb_bytes_t var_data_bytes, unsigned axis_count,
+				  hb_vector_t<unsigned int> &shared_indices /* OUT */,
+				  tuple_iterator_t *iterator /* OUT */)
   {
-    iterator->init (var_data, length, axis_count);
+    iterator->init (var_data_bytes, axis_count);
     if (!iterator->get_shared_indices (shared_indices))
       return false;
     return iterator->is_valid ();
@@ -283,12 +266,12 @@
       POINT_RUN_COUNT_MASK = 0x7F
     };
 
-    if (unlikely (!bytes.in_range (p))) return false;
+    if (unlikely (!bytes.check_range (p))) return false;
 
     uint16_t count = *p++;
     if (count & POINTS_ARE_WORDS)
     {
-      if (unlikely (!bytes.in_range (p))) return false;
+      if (unlikely (!bytes.check_range (p))) return false;
       count = ((count & POINT_RUN_COUNT_MASK) << 8) | *p++;
     }
     points.resize (count);
@@ -297,7 +280,7 @@
     uint16_t i = 0;
     while (i < count)
     {
-      if (unlikely (!bytes.in_range (p))) return false;
+      if (unlikely (!bytes.check_range (p))) return false;
       uint16_t j;
       uint8_t control = *p++;
       uint16_t run_count = (control & POINT_RUN_COUNT_MASK) + 1;
@@ -305,7 +288,7 @@
       {
 	for (j = 0; j < run_count && i < count; j++, i++)
 	{
-	  if (unlikely (!bytes.in_range ((const HBUINT16 *) p)))
+	  if (unlikely (!bytes.check_range ((const HBUINT16 *) p)))
 	    return false;
 	  n += *(const HBUINT16 *)p;
 	  points[i] = n;
@@ -316,7 +299,7 @@
       {
 	for (j = 0; j < run_count && i < count; j++, i++)
 	{
-	  if (unlikely (!bytes.in_range (p))) return false;
+	  if (unlikely (!bytes.check_range (p))) return false;
 	  n += *p++;
 	  points[i] = n;
 	}
@@ -341,7 +324,7 @@
     unsigned int count = deltas.length;
     while (i < count)
     {
-      if (unlikely (!bytes.in_range (p))) return false;
+      if (unlikely (!bytes.check_range (p))) return false;
       uint8_t control = *p++;
       unsigned int run_count = (control & DELTA_RUN_COUNT_MASK) + 1;
       unsigned int j;
@@ -351,7 +334,7 @@
       else if (control & DELTAS_ARE_WORDS)
 	for (j = 0; j < run_count && i < count; j++, i++)
 	{
-	  if (unlikely (!bytes.in_range ((const HBUINT16 *) p)))
+	  if (unlikely (!bytes.check_range ((const HBUINT16 *) p)))
 	    return false;
 	  deltas[i] = *(const HBINT16 *) p;
 	  p += HBUINT16::static_size;
@@ -359,7 +342,7 @@
       else
 	for (j = 0; j < run_count && i < count; j++, i++)
 	{
-	  if (unlikely (!bytes.in_range (p)))
+	  if (unlikely (!bytes.check_range (p)))
 	    return false;
 	  deltas[i] = *(const HBINT8 *) p++;
 	}
@@ -369,10 +352,32 @@
     return true;
   }
 
+  bool has_data () const { return tupleVarCount; }
+
   protected:
-  TupleVarCount		tupleVarCount;
-  OffsetTo<HBUINT8>	data;
-  /* TupleVarHeader tupleVarHeaders[] */
+  struct TupleVarCount : HBUINT16
+  {
+    bool has_shared_point_numbers () const { return ((*this) & SharedPointNumbers); }
+    unsigned int get_count () const { return (*this) & CountMask; }
+
+    protected:
+    enum Flags
+    {
+      SharedPointNumbers= 0x8000u,
+      CountMask		= 0x0FFFu
+    };
+    public:
+    DEFINE_SIZE_STATIC (2);
+  };
+
+  TupleVarCount	tupleVarCount;  /* A packed field. The high 4 bits are flags, and the
+				 * low 12 bits are the number of tuple variation tables
+				 * for this glyph. The number of tuple variation tables
+				 * can be any number between 1 and 4095. */
+  OffsetTo<HBUINT8>
+		data;		/* Offset from the start of the GlyphVariationData table
+				 * to the serialized data. */
+  /* TupleVariationHeader tupleVariationHeaders[] *//* Array of tuple variation headers. */
   public:
   DEFINE_SIZE_MIN (4);
 };
@@ -386,7 +391,7 @@
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) && (version.major == 1) &&
 		  (glyphCount == c->get_num_glyphs ()) &&
-		  c->check_array (&(this+sharedTuples), axisCount * sharedTupleCount) &&
+		  sharedTuples.sanitize (c, this, axisCount * sharedTupleCount) &&
 		  (is_long_offset () ?
 		     c->check_array (get_long_offset_array (), glyphCount+1) :
 		     c->check_array (get_short_offset_array (), glyphCount+1)) &&
@@ -394,7 +399,7 @@
 				  get_offset (glyphCount) - get_offset (0)));
   }
 
-  /* GlyphVarData not sanitized here; must be checked while accessing each glyph varation data */
+  /* GlyphVariationData not sanitized here; must be checked while accessing each glyph varation data */
   bool sanitize (hb_sanitize_context_t *c) const
   { return sanitize_shallow (c); }
 
@@ -418,7 +423,7 @@
     {
       hb_codepoint_t old_gid;
       if (!c->plan->old_gid_for_new_gid (gid, &old_gid)) continue;
-      subset_data_size += get_glyph_var_data_length (old_gid);
+      subset_data_size += get_glyph_var_data_bytes (c->source_blob, old_gid).length;
     }
 
     bool long_offset = subset_data_size & ~0xFFFFu;
@@ -436,18 +441,20 @@
       F2DOT14 *tuples = c->serializer->allocate_size<F2DOT14> (shared_tuple_size);
       if (!tuples) return_trace (false);
       out->sharedTuples = (char *) tuples - (char *) out;
-      memcpy (tuples, &(this+sharedTuples), shared_tuple_size);
+      memcpy (tuples, this+sharedTuples, shared_tuple_size);
     }
 
     char *subset_data = c->serializer->allocate_size<char> (subset_data_size);
     if (!subset_data) return_trace (false);
-    out->dataZ = subset_data - (char *)out;
+    out->dataZ = subset_data - (char *) out;
 
     unsigned int glyph_offset = 0;
     for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++)
     {
       hb_codepoint_t old_gid;
-      unsigned int length = c->plan->old_gid_for_new_gid (gid, &old_gid) ? get_glyph_var_data_length (old_gid) : 0;
+      hb_bytes_t var_data_bytes = c->plan->old_gid_for_new_gid (gid, &old_gid)
+				? get_glyph_var_data_bytes (c->source_blob, old_gid)
+				: hb_bytes_t ();
 
       if (long_offset)
 	((HBUINT32 *) subset_offsets)[gid] = glyph_offset;
@@ -454,9 +461,10 @@
       else
 	((HBUINT16 *) subset_offsets)[gid] = glyph_offset / 2;
 
-      if (length > 0) memcpy (subset_data, get_glyph_var_data (old_gid), length);
-      subset_data += length;
-      glyph_offset += length;
+      if (var_data_bytes.length > 0)
+	memcpy (subset_data, var_data_bytes.arrayZ, var_data_bytes.length);
+      subset_data += var_data_bytes.length;
+      glyph_offset += var_data_bytes.length;
     }
     if (long_offset)
       ((HBUINT32 *) subset_offsets)[num_glyphs] = glyph_offset;
@@ -467,16 +475,12 @@
   }
 
   protected:
-  const GlyphVarData *get_glyph_var_data (hb_codepoint_t glyph) const
+  const hb_bytes_t get_glyph_var_data_bytes (hb_blob_t *blob, hb_codepoint_t glyph) const
   {
-    unsigned int start_offset = get_offset (glyph);
-    unsigned int end_offset = get_offset (glyph+1);
-
-    if ((start_offset == end_offset) ||
-	unlikely ((start_offset > get_offset (glyphCount)) ||
-		  (start_offset + GlyphVarData::min_size > end_offset)))
-      return &Null (GlyphVarData);
-    return &(((unsigned char *) this + start_offset) + dataZ);
+    unsigned start_offset = get_offset (glyph);
+    unsigned length = get_offset (glyph+1) - start_offset;
+    hb_bytes_t var_data = blob->as_bytes ().sub_array (((unsigned) dataZ) + start_offset, length);
+    return likely (var_data.length >= GlyphVariationData::min_size) ? var_data : hb_bytes_t ();
   }
 
   bool is_long_offset () const { return (flags & 1) != 0; }
@@ -489,15 +493,6 @@
       return get_short_offset_array ()[i] * 2;
   }
 
-  unsigned int get_glyph_var_data_length (unsigned int glyph) const
-  {
-    unsigned int end_offset = get_offset (glyph + 1);
-    unsigned int start_offset = get_offset (glyph);
-    if (unlikely (start_offset > end_offset || end_offset > get_offset (glyphCount)))
-      return 0;
-    return end_offset - start_offset;
-  }
-
   const HBUINT32 * get_long_offset_array () const { return (const HBUINT32 *) &offsetZ; }
   const HBUINT16 *get_short_offset_array () const { return (const HBUINT16 *) &offsetZ; }
 
@@ -505,28 +500,9 @@
   struct accelerator_t
   {
     void init (hb_face_t *face)
-    {
-      gvar_table = hb_sanitize_context_t ().reference_table<gvar> (face);
-      hb_blob_ptr_t<fvar> fvar_table = hb_sanitize_context_t ().reference_table<fvar> (face);
-      unsigned int axis_count = fvar_table->get_axis_count ();
-      fvar_table.destroy ();
+    { table = hb_sanitize_context_t ().reference_table<gvar> (face); }
+    void fini () { table.destroy (); }
 
-      if (unlikely ((gvar_table->glyphCount != face->get_num_glyphs ()) ||
-		    (gvar_table->axisCount != axis_count)))
-      	fini ();
-
-      unsigned int num_shared_coord = gvar_table->sharedTupleCount * gvar_table->axisCount;
-      shared_tuples.resize (num_shared_coord);
-      for (unsigned int i = 0; i < num_shared_coord; i++)
-	shared_tuples[i] = (&(gvar_table + gvar_table->sharedTuples))[i];
-    }
-
-    void fini ()
-    {
-      gvar_table.destroy ();
-      shared_tuples.fini ();
-    }
-
     private:
     struct x_getter { static float get (const contour_point_t &p) { return p.x; } };
     struct y_getter { static float get (const contour_point_t &p) { return p.y; } };
@@ -543,11 +519,11 @@
       float next_delta = T::get (deltas[next]);
 
       if (prev_val == next_val)
-      	return (prev_delta == next_delta) ? prev_delta : 0.f;
+	return (prev_delta == next_delta) ? prev_delta : 0.f;
       else if (target_val <= hb_min (prev_val, next_val))
-      	return (prev_val < next_val) ? prev_delta : next_delta;
+	return (prev_val < next_val) ? prev_delta : next_delta;
       else if (target_val >= hb_max (prev_val, next_val))
-      	return (prev_val > next_val) ? prev_delta : next_delta;
+	return (prev_val > next_val) ? prev_delta : next_delta;
 
       /* linear interpolation */
       float r = (target_val - prev_val) / (next_val - prev_val);
@@ -558,23 +534,19 @@
     { return (i >= end) ? start : (i + 1); }
 
     public:
-    bool apply_deltas_to_points (hb_codepoint_t glyph,
-				 const int *coords, unsigned int coord_count,
-				 const hb_array_t<contour_point_t> points,
-				 const hb_array_t<unsigned int> end_points) const
+    bool apply_deltas_to_points (hb_codepoint_t glyph, hb_font_t *font,
+				 const hb_array_t<contour_point_t> points) const
     {
-      if (unlikely (coord_count != gvar_table->axisCount)) return false;
+      /* num_coords should exactly match gvar's axisCount due to how GlyphVariationData tuples are aligned */
+      if (!font->num_coords || font->num_coords != table->axisCount) return true;
 
-      const GlyphVarData *var_data = gvar_table->get_glyph_var_data (glyph);
-      if (var_data == &Null (GlyphVarData)) return true;
+      hb_bytes_t var_data_bytes = table->get_glyph_var_data_bytes (table.get_blob (), glyph);
+      if (!var_data_bytes.as<GlyphVariationData> ()->has_data ()) return true;
       hb_vector_t<unsigned int> shared_indices;
-      GlyphVarData::tuple_iterator_t iterator;
-      if (!GlyphVarData::get_tuple_iterator (var_data,
-					     gvar_table->get_glyph_var_data_length (glyph),
-					     gvar_table->axisCount,
-					     shared_indices,
-					     &iterator))
-	return false;
+      GlyphVariationData::tuple_iterator_t iterator;
+      if (!GlyphVariationData::get_tuple_iterator (var_data_bytes, table->axisCount,
+					     shared_indices, &iterator))
+	return true; /* so isn't applied at all */
 
       /* Save original points for inferred delta calculation */
       contour_point_vector_t orig_points;
@@ -585,19 +557,27 @@
       contour_point_vector_t deltas; /* flag is used to indicate referenced point */
       deltas.resize (points.length);
 
+      hb_vector_t<unsigned> end_points;
+      for (unsigned i = 0; i < points.length; ++i)
+	if (points[i].is_end_point)
+	  end_points.push (i);
+
+      int *coords = font->coords;
+      unsigned num_coords = font->num_coords;
+      hb_array_t<const F2DOT14> shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount);
       do
       {
-	float scalar = iterator.current_tuple->calculate_scalar (coords, coord_count, shared_tuples.as_array ());
+	float scalar = iterator.current_tuple->calculate_scalar (coords, num_coords, shared_tuples);
 	if (scalar == 0.f) continue;
 	const HBUINT8 *p = iterator.get_serialized_data ();
 	unsigned int length = iterator.current_tuple->get_data_size ();
-	if (unlikely (!iterator.in_range (p, length)))
+	if (unlikely (!iterator.var_data_bytes.check_range (p, length)))
 	  return false;
 
 	hb_bytes_t bytes ((const char *) p, length);
 	hb_vector_t<unsigned int> private_indices;
 	if (iterator.current_tuple->has_private_points () &&
-	    !GlyphVarData::unpack_points (p, private_indices, bytes))
+	    !GlyphVariationData::unpack_points (p, private_indices, bytes))
 	  return false;
 	const hb_array_t<unsigned int> &indices = private_indices.length ? private_indices : shared_indices;
 
@@ -605,11 +585,11 @@
 	unsigned int num_deltas = apply_to_all ? points.length : indices.length;
 	hb_vector_t<int> x_deltas;
 	x_deltas.resize (num_deltas);
-	if (!GlyphVarData::unpack_deltas (p, x_deltas, bytes))
+	if (!GlyphVariationData::unpack_deltas (p, x_deltas, bytes))
 	  return false;
 	hb_vector_t<int> y_deltas;
 	y_deltas.resize (num_deltas);
-	if (!GlyphVarData::unpack_deltas (p, y_deltas, bytes))
+	if (!GlyphVariationData::unpack_deltas (p, y_deltas, bytes))
 	  return false;
 
 	for (unsigned int i = 0; i < deltas.length; i++)
@@ -623,26 +603,26 @@
 	}
 
 	/* infer deltas for unreferenced points */
-	unsigned int start_point = 0;
-	for (unsigned int c = 0; c < end_points.length; c++)
+	unsigned start_point = 0;
+	for (unsigned c = 0; c < end_points.length; c++)
 	{
-	  unsigned int end_point = end_points[c];
-	  unsigned int i, j;
+	  unsigned end_point = end_points[c];
 
 	  /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */
-	  unsigned int unref_count = 0;
-	  for (i = start_point; i <= end_point; i++)
+	  unsigned unref_count = 0;
+	  for (unsigned i = start_point; i <= end_point; i++)
 	    if (!deltas[i].flag) unref_count++;
+
+	  unsigned j = start_point;
 	  if (unref_count == 0 || unref_count > end_point - start_point)
 	    goto no_more_gaps;
 
-	  j = start_point;
 	  for (;;)
 	  {
 	    /* Locate the next gap of unreferenced points between two referenced points prev and next.
 	     * Note that a gap may wrap around at left (start_point) and/or at right (end_point).
 	     */
-	    unsigned int prev, next;
+	    unsigned int prev, next, i;
 	    for (;;)
 	    {
 	      i = j;
@@ -683,29 +663,36 @@
       return true;
     }
 
-    unsigned int get_axis_count () const { return gvar_table->axisCount; }
+    unsigned int get_axis_count () const { return table->axisCount; }
 
-    protected:
-    const GlyphVarData *get_glyph_var_data (hb_codepoint_t glyph) const
-    { return gvar_table->get_glyph_var_data (glyph); }
-
     private:
-    hb_blob_ptr_t<gvar> gvar_table;
-    hb_vector_t<F2DOT14> shared_tuples;
+    hb_blob_ptr_t<gvar> table;
   };
 
   protected:
-  FixedVersion<>version;	/* Version of gvar table. Set to 0x00010000u. */
-  HBUINT16	axisCount;
+  FixedVersion<>version;	/* Version number of the glyph variations table
+				 * Set to 0x00010000u. */
+  HBUINT16	axisCount;	/* The number of variation axes for this font. This must be
+				 * the same number as axisCount in the 'fvar' table. */
   HBUINT16	sharedTupleCount;
-  LOffsetTo<F2DOT14>
-		sharedTuples;	/* LOffsetTo<UnsizedArrayOf<Tupple>> */
-  HBUINT16	glyphCount;
-  HBUINT16	flags;
-  LOffsetTo<GlyphVarData>
-		dataZ;		/* Array of GlyphVarData */
+				/* The number of shared tuple records. Shared tuple records
+				 * can be referenced within glyph variation data tables for
+				 * multiple glyphs, as opposed to other tuple records stored
+				 * directly within a glyph variation data table. */
+  LNNOffsetTo<UnsizedArrayOf<F2DOT14>>
+		sharedTuples;	/* Offset from the start of this table to the shared tuple records.
+				 * Array of tuple records shared across all glyph variation data tables. */
+  HBUINT16	glyphCount;	/* The number of glyphs in this font. This must match the number of
+				 * glyphs stored elsewhere in the font. */
+  HBUINT16	flags;		/* Bit-field that gives the format of the offset array that follows.
+				 * If bit 0 is clear, the offsets are uint16; if bit 0 is set, the
+				 * offsets are uint32. */
+  LOffsetTo<GlyphVariationData>
+		dataZ;		/* Offset from the start of this table to the array of
+				 * GlyphVariationData tables. */
   UnsizedArrayOf<HBUINT8>
-		offsetZ;	/* Array of 16-bit or 32-bit (glyphCount+1) offsets */
+		offsetZ;	/* Offsets from the start of the GlyphVariationData array
+				 * to each GlyphVariationData table. */
   public:
   DEFINE_SIZE_MIN (20);
 };

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -44,6 +44,38 @@
 				  get_width ()));
   }
 
+  template <typename T>
+  bool serialize (hb_serialize_context_t *c, const T &plan)
+  {
+    unsigned int width = plan.get_width ();
+    unsigned int inner_bit_count = plan.get_inner_bit_count ();
+    const hb_array_t<const unsigned int> output_map = plan.get_output_map ();
+
+    TRACE_SERIALIZE (this);
+    if (unlikely (output_map.length && ((((inner_bit_count-1)&~0xF)!=0) || (((width-1)&~0x3)!=0))))
+      return_trace (false);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+
+    format = ((width-1)<<4)|(inner_bit_count-1);
+    mapCount = output_map.length;
+    HBUINT8 *p = c->allocate_size<HBUINT8> (width * output_map.length);
+    if (unlikely (!p)) return_trace (false);
+    for (unsigned int i = 0; i < output_map.length; i++)
+    {
+      unsigned int v = output_map[i];
+      unsigned int outer = v >> 16;
+      unsigned int inner = v & 0xFFFF;
+      unsigned int u = (outer << inner_bit_count) | inner;
+      for (unsigned int w = width; w > 0;)
+      {
+	p[--w] = u;
+	u >>= 8;
+      }
+      p += width;
+    }
+    return_trace (true);
+  }
+
   unsigned int map (unsigned int v) const /* Returns 16.16 outer.inner. */
   {
     /* If count is zero, pass value unchanged.  This takes
@@ -63,7 +95,7 @@
     }
 
     { /* Repack it. */
-      unsigned int n = get_inner_bitcount ();
+      unsigned int n = get_inner_bit_count ();
       unsigned int outer = u >> n;
       unsigned int inner = u & ((1 << n) - 1);
       u = (outer<<16) | inner;
@@ -72,23 +104,231 @@
     return u;
   }
 
-  protected:
-  unsigned int get_width () const          { return ((format >> 4) & 3) + 1; }
+  unsigned int get_map_count () const	    { return mapCount; }
+  unsigned int get_width () const           { return ((format >> 4) & 3) + 1; }
+  unsigned int get_inner_bit_count () const { return (format & 0xF) + 1; }
 
-  unsigned int get_inner_bitcount () const { return (format & 0xF) + 1; }
-
   protected:
   HBUINT16	format;		/* A packed field that describes the compressed
 				 * representation of delta-set indices. */
   HBUINT16	mapCount;	/* The number of mapping entries. */
   UnsizedArrayOf<HBUINT8>
- 		mapDataZ;	/* The delta-set index mapping data. */
+		mapDataZ;	/* The delta-set index mapping data. */
 
   public:
   DEFINE_SIZE_ARRAY (4, mapDataZ);
 };
 
+struct index_map_subset_plan_t
+{
+  enum index_map_index_t {
+    ADV_INDEX,
+    LSB_INDEX,	/* dual as TSB */
+    RSB_INDEX,	/* dual as BSB */
+    VORG_INDEX
+  };
 
+  void init (const DeltaSetIndexMap  &index_map,
+	     hb_inc_bimap_t	     &outer_map,
+	     hb_vector_t<hb_set_t *> &inner_sets,
+	     const hb_subset_plan_t  *plan)
+  {
+    map_count = 0;
+    outer_bit_count = 0;
+    inner_bit_count = 1;
+    max_inners.init ();
+    output_map.init ();
+
+    if (&index_map == &Null (DeltaSetIndexMap)) return;
+
+    unsigned int	last_val = (unsigned int)-1;
+    hb_codepoint_t	last_gid = (hb_codepoint_t)-1;
+    hb_codepoint_t	gid = (hb_codepoint_t) hb_min (index_map.get_map_count (), plan->num_output_glyphs ());
+
+    outer_bit_count = (index_map.get_width () * 8) - index_map.get_inner_bit_count ();
+    max_inners.resize (inner_sets.length);
+    for (unsigned i = 0; i < inner_sets.length; i++) max_inners[i] = 0;
+
+    /* Search backwards for a map value different from the last map value */
+    for (; gid > 0; gid--)
+    {
+      hb_codepoint_t	old_gid;
+      if (!plan->old_gid_for_new_gid (gid - 1, &old_gid))
+      {
+	if (last_gid == (hb_codepoint_t) -1)
+	  continue;
+	else
+	  break;
+      }
+
+      unsigned int v = index_map.map (old_gid);
+      if (last_gid == (hb_codepoint_t) -1)
+      {
+	last_val = v;
+	last_gid = gid;
+	continue;
+      }
+      if (v != last_val) break;
+
+      last_gid = gid;
+    }
+
+    if (unlikely (last_gid == (hb_codepoint_t)-1)) return;
+    map_count = last_gid;
+    for (gid = 0; gid < map_count; gid++)
+    {
+      hb_codepoint_t	old_gid;
+      if (plan->old_gid_for_new_gid (gid, &old_gid))
+      {
+	unsigned int v = index_map.map (old_gid);
+	unsigned int outer = v >> 16;
+	unsigned int inner = v & 0xFFFF;
+	outer_map.add (outer);
+	if (inner > max_inners[outer]) max_inners[outer] = inner;
+	if (outer >= inner_sets.length) return;
+	inner_sets[outer]->add (inner);
+      }
+    }
+  }
+
+  void fini ()
+  {
+    max_inners.fini ();
+    output_map.fini ();
+  }
+
+  void remap (const DeltaSetIndexMap *input_map,
+	      const hb_inc_bimap_t &outer_map,
+	      const hb_vector_t<hb_inc_bimap_t> &inner_maps,
+	      const hb_subset_plan_t *plan)
+  {
+    if (input_map == &Null (DeltaSetIndexMap)) return;
+
+    for (unsigned int i = 0; i < max_inners.length; i++)
+    {
+      if (inner_maps[i].get_population () == 0) continue;
+      unsigned int bit_count = (max_inners[i]==0)? 1: hb_bit_storage (inner_maps[i][max_inners[i]]);
+      if (bit_count > inner_bit_count) inner_bit_count = bit_count;
+    }
+
+    output_map.resize (map_count);
+    for (hb_codepoint_t gid = 0; gid < output_map.length; gid++)
+    {
+      hb_codepoint_t	old_gid;
+      if (plan->old_gid_for_new_gid (gid, &old_gid))
+      {
+	unsigned int v = input_map->map (old_gid);
+	unsigned int outer = v >> 16;
+	output_map[gid] = (outer_map[outer] << 16) | (inner_maps[outer][v & 0xFFFF]);
+      }
+      else
+	output_map[gid] = 0;	/* Map unused glyph to outer/inner=0/0 */
+    }
+  }
+
+  unsigned int get_inner_bit_count () const { return inner_bit_count; }
+  unsigned int get_width ()           const { return ((outer_bit_count + inner_bit_count + 7) / 8); }
+  unsigned int get_map_count ()       const { return map_count; }
+
+  unsigned int get_size () const
+  { return (map_count? (DeltaSetIndexMap::min_size + get_width () * map_count): 0); }
+
+  bool is_identity () const { return get_output_map ().length == 0; }
+  hb_array_t<const unsigned int> get_output_map () const { return output_map.as_array (); }
+
+  protected:
+  unsigned int map_count;
+  hb_vector_t<unsigned int> max_inners;
+  unsigned int outer_bit_count;
+  unsigned int inner_bit_count;
+  hb_vector_t<unsigned int> output_map;
+};
+
+struct hvarvvar_subset_plan_t
+{
+  hvarvvar_subset_plan_t() : inner_maps (), index_map_plans () {}
+  ~hvarvvar_subset_plan_t() { fini (); }
+
+  void init (const hb_array_t<const DeltaSetIndexMap *> &index_maps,
+	     const VariationStore &_var_store,
+	     const hb_subset_plan_t *plan)
+  {
+    index_map_plans.resize (index_maps.length);
+
+    var_store = &_var_store;
+    inner_sets.resize (var_store->get_sub_table_count ());
+    for (unsigned int i = 0; i < inner_sets.length; i++)
+      inner_sets[i] = hb_set_create ();
+    adv_set = hb_set_create ();
+
+    inner_maps.resize (var_store->get_sub_table_count ());
+
+    for (unsigned int i = 0; i < inner_maps.length; i++)
+      inner_maps[i].init ();
+
+    if (unlikely (!index_map_plans.length || !inner_sets.length || !inner_maps.length)) return;
+
+    bool retain_adv_map = false;
+    index_map_plans[0].init (*index_maps[0], outer_map, inner_sets, plan);
+    if (index_maps[0] == &Null (DeltaSetIndexMap))
+    {
+      retain_adv_map = plan->retain_gids;
+      outer_map.add (0);
+      for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++)
+      {
+	hb_codepoint_t old_gid;
+	if (plan->old_gid_for_new_gid (gid, &old_gid))
+	  inner_sets[0]->add (old_gid);
+      }
+      hb_set_union (adv_set, inner_sets[0]);
+    }
+
+    for (unsigned int i = 1; i < index_maps.length; i++)
+      index_map_plans[i].init (*index_maps[i], outer_map, inner_sets, plan);
+
+    outer_map.sort ();
+
+    if (retain_adv_map)
+    {
+      for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++)
+	if (inner_sets[0]->has (gid))
+	  inner_maps[0].add (gid);
+	else
+	  inner_maps[0].skip ();
+    }
+    else
+    {
+      inner_maps[0].add_set (adv_set);
+      hb_set_subtract (inner_sets[0], adv_set);
+      inner_maps[0].add_set (inner_sets[0]);
+    }
+
+    for (unsigned int i = 1; i < inner_maps.length; i++)
+      inner_maps[i].add_set (inner_sets[i]);
+
+    for (unsigned int i = 0; i < index_maps.length; i++)
+      index_map_plans[i].remap (index_maps[i], outer_map, inner_maps, plan);
+  }
+
+  void fini ()
+  {
+    for (unsigned int i = 0; i < inner_sets.length; i++)
+      hb_set_destroy (inner_sets[i]);
+    hb_set_destroy (adv_set);
+    inner_maps.fini_deep ();
+    index_map_plans.fini_deep ();
+  }
+
+  hb_inc_bimap_t outer_map;
+  hb_vector_t<hb_inc_bimap_t> inner_maps;
+  hb_vector_t<index_map_subset_plan_t> index_map_plans;
+  const VariationStore *var_store;
+
+  protected:
+  hb_vector_t<hb_set_t *> inner_sets;
+  hb_set_t *adv_set;
+};
+
 /*
  * HVAR -- Horizontal Metrics Variations
  * https://docs.microsoft.com/en-us/typography/opentype/spec/hvar
@@ -114,8 +354,60 @@
 		  rsbMap.sanitize (c, this));
   }
 
-  float get_advance_var (hb_font_t *font, hb_codepoint_t glyph) const
+  void listup_index_maps (hb_vector_t<const DeltaSetIndexMap *> &index_maps) const
   {
+    index_maps.push (&(this+advMap));
+    index_maps.push (&(this+lsbMap));
+    index_maps.push (&(this+rsbMap));
+  }
+
+  bool serialize_index_maps (hb_serialize_context_t *c,
+			     const hb_array_t<index_map_subset_plan_t> &im_plans)
+  {
+    TRACE_SERIALIZE (this);
+    if (im_plans[index_map_subset_plan_t::ADV_INDEX].is_identity ())
+      advMap = 0;
+    else if (unlikely (!advMap.serialize (c, this).serialize (c, im_plans[index_map_subset_plan_t::ADV_INDEX])))
+      return_trace (false);
+    if (im_plans[index_map_subset_plan_t::LSB_INDEX].is_identity ())
+      lsbMap = 0;
+    else if (unlikely (!lsbMap.serialize (c, this).serialize (c, im_plans[index_map_subset_plan_t::LSB_INDEX])))
+      return_trace (false);
+    if (im_plans[index_map_subset_plan_t::RSB_INDEX].is_identity ())
+      rsbMap = 0;
+    else if (unlikely (!rsbMap.serialize (c, this).serialize (c, im_plans[index_map_subset_plan_t::RSB_INDEX])))
+      return_trace (false);
+
+    return_trace (true);
+  }
+
+  template <typename T>
+  bool _subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    hvarvvar_subset_plan_t	hvar_plan;
+    hb_vector_t<const DeltaSetIndexMap *>
+				index_maps;
+
+    ((T*)this)->listup_index_maps (index_maps);
+    hvar_plan.init (index_maps.as_array (), this+varStore, c->plan);
+
+    T *out = c->serializer->allocate_min<T> ();
+    if (unlikely (!out)) return_trace (false);
+
+    out->version.major = 1;
+    out->version.minor = 0;
+
+    if (unlikely (!out->varStore.serialize (c->serializer, out)
+		     .serialize (c->serializer, hvar_plan.var_store, hvar_plan.inner_maps.as_array ())))
+      return_trace (false);
+
+    return_trace (out->T::serialize_index_maps (c->serializer,
+						hvar_plan.index_map_plans.as_array ()));
+  }
+
+  float get_advance_var (hb_codepoint_t glyph, hb_font_t *font) const
+  {
     unsigned int varidx = (this+advMap).map (glyph);
     return (this+varStore).get_delta (varidx, font->coords, font->num_coords);
   }
@@ -148,6 +440,7 @@
 
 struct HVAR : HVARVVAR {
   static constexpr hb_tag_t tableTag = HB_OT_TAG_HVAR;
+  bool subset (hb_subset_context_t *c) const { return HVARVVAR::_subset<HVAR> (c); }
 };
 struct VVAR : HVARVVAR {
   static constexpr hb_tag_t tableTag = HB_OT_TAG_VVAR;
@@ -159,6 +452,28 @@
 		  vorgMap.sanitize (c, this));
   }
 
+  void listup_index_maps (hb_vector_t<const DeltaSetIndexMap *> &index_maps) const
+  {
+    HVARVVAR::listup_index_maps (index_maps);
+    index_maps.push (&(this+vorgMap));
+  }
+
+  bool serialize_index_maps (hb_serialize_context_t *c,
+			     const hb_array_t<index_map_subset_plan_t> &im_plans)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!HVARVVAR::serialize_index_maps (c, im_plans)))
+      return_trace (false);
+    if (!im_plans[index_map_subset_plan_t::VORG_INDEX].get_map_count ())
+      vorgMap = 0;
+    else if (unlikely (!vorgMap.serialize (c, this).serialize (c, im_plans[index_map_subset_plan_t::VORG_INDEX])))
+      return_trace (false);
+
+    return_trace (true);
+  }
+
+  bool subset (hb_subset_context_t *c) const { return HVARVVAR::_subset<VVAR> (c); }
+
   protected:
   LOffsetTo<DeltaSetIndexMap>
 		vorgMap;	/* Offset to vertical-origin var-idx mapping. */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -77,7 +77,9 @@
 		 const int *coords, unsigned int coord_count) const
   {
     const VariationValueRecord *record;
-    record = (VariationValueRecord *) hb_bsearch (&tag, valuesZ.arrayZ,
+    record = (VariationValueRecord *) hb_bsearch (tag,
+						  (const VariationValueRecord *)
+						    (const HBUINT8 *) valuesZ,
 						  valueRecordCount, valueRecordSize,
 						  tag_compare);
     if (!record)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-vorg-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-vorg-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-vorg-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -84,7 +84,7 @@
     this->defaultVertOriginY = defaultVertOriginY;
     this->vertYOrigins.len = it.len ();
 
-    for (const auto _ : it) c->copy (_);
+    c->copy_all (it);
   }
 
   bool subset (hb_subset_context_t *c) const
@@ -122,10 +122,11 @@
   }
 
   protected:
-  FixedVersion<>	version;		/* Version of VORG table. Set to 0x00010000u. */
-  FWORD			defaultVertOriginY;	/* The default vertical origin. */
+  FixedVersion<>version;	/* Version of VORG table. Set to 0x00010000u. */
+  FWORD		defaultVertOriginY;
+				/* The default vertical origin. */
   SortedArrayOf<VertOriginMetric>
-			vertYOrigins;		/* The array of vertical origins. */
+		vertYOrigins;	/* The array of vertical origins. */
 
   public:
   DEFINE_SIZE_ARRAY(8, vertYOrigins);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -41,9 +41,7 @@
   {
     next = nullptr;
 
-    + hb_iter (chunks)
-    | hb_apply ([] (chunk_t *_) { ::free (_); })
-    ;
+    for (chunk_t *_ : chunks) ::free (_);
 
     chunks.fini ();
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -113,6 +113,9 @@
 #ifndef HB_SANITIZE_MAX_OPS_MAX
 #define HB_SANITIZE_MAX_OPS_MAX 0x3FFFFFFF
 #endif
+#ifndef HB_SANITIZE_MAX_SUTABLES
+#define HB_SANITIZE_MAX_SUTABLES 0x4000
+#endif
 
 struct hb_sanitize_context_t :
        hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE>
@@ -120,7 +123,7 @@
   hb_sanitize_context_t () :
 	debug_depth (0),
 	start (nullptr), end (nullptr),
-	max_ops (0),
+	max_ops (0), max_subtables (0),
 	writable (false), edit_count (0),
 	blob (nullptr),
 	num_glyphs (65536),
@@ -134,6 +137,12 @@
   static return_t no_dispatch_return_value () { return false; }
   bool stop_sublookup_iteration (const return_t r) const { return !r; }
 
+  bool visit_subtables (unsigned count)
+  {
+    max_subtables += count;
+    return max_subtables < HB_SANITIZE_MAX_SUTABLES;
+  }
+
   private:
   template <typename T, typename ...Ts> auto
   _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN
@@ -189,8 +198,12 @@
   void start_processing ()
   {
     reset_object ();
-    this->max_ops = hb_max ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR,
-			 (unsigned) HB_SANITIZE_MAX_OPS_MIN);
+    if (unlikely (hb_unsigned_mul_overflows (this->end - this->start, HB_SANITIZE_MAX_OPS_FACTOR)))
+      this->max_ops = HB_SANITIZE_MAX_OPS_MAX;
+    else
+      this->max_ops = hb_clamp ((unsigned) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR,
+				(unsigned) HB_SANITIZE_MAX_OPS_MIN,
+				(unsigned) HB_SANITIZE_MAX_OPS_MAX);
     this->edit_count = 0;
     this->debug_depth = 0;
 
@@ -376,7 +389,7 @@
 
   mutable unsigned int debug_depth;
   const char *start, *end;
-  mutable int max_ops;
+  mutable int max_ops, max_subtables;
   private:
   bool writable;
   unsigned int edit_count;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -45,12 +45,13 @@
 {
   typedef unsigned objidx_t;
 
-  struct range_t
-  {
-    char *head, *tail;
-  };
+  enum whence_t {
+     Head,	/* Relative to the current object head (default). */
+     Tail,	/* Relative to the current object tail after packed. */
+     Absolute	/* Absolute: from the start of the serialize buffer. */
+   };
 
-  struct object_t : range_t
+  struct object_t
   {
     void fini () { links.fini (); }
 
@@ -70,17 +71,29 @@
     struct link_t
     {
       bool is_wide: 1;
-      unsigned position : 31;
+      bool is_signed: 1;
+      unsigned whence: 2;
+      unsigned position: 28;
       unsigned bias;
       objidx_t objidx;
     };
 
+    char *head;
+    char *tail;
     hb_vector_t<link_t> links;
     object_t *next;
   };
 
-  range_t snapshot () { range_t s = {head, tail} ; return s; }
+  struct snapshot_t
+  {
+    char *head;
+    char *tail;
+    object_t *current; // Just for sanity check
+    unsigned num_links;
+  };
 
+  snapshot_t snapshot ()
+  { return snapshot_t { head, tail, current, current->links.length }; }
 
   hb_serialize_context_t (void *start_, unsigned int size) :
     start ((char *) start_),
@@ -123,7 +136,7 @@
 
   template <typename T1, typename T2>
   bool check_equal (T1 &&v1, T2 &&v2)
-  { return check_success (v1 == v2); }
+  { return check_success ((long long) v1 == (long long) v2); }
 
   template <typename T1, typename T2>
   bool check_assign (T1 &v1, T2 &&v2)
@@ -166,7 +179,7 @@
     if (packed.length <= 1)
       return;
 
-    pop_pack ();
+    pop_pack (false);
 
     resolve_links ();
   }
@@ -191,11 +204,16 @@
     object_t *obj = current;
     if (unlikely (!obj)) return;
     current = current->next;
-    revert (*obj);
+    revert (obj->head, obj->tail);
     obj->fini ();
     object_pool.free (obj);
   }
-  objidx_t pop_pack ()
+
+  /* Set share to false when an object is unlikely sharable with others
+   * so not worth an attempt, or a contiguous table is serialized as
+   * multiple consecutive objects in the reverse order so can't be shared.
+   */
+  objidx_t pop_pack (bool share=true)
   {
     object_t *obj = current;
     if (unlikely (!obj)) return 0;
@@ -211,11 +229,15 @@
       return 0;
     }
 
-    objidx_t objidx = packed_map.get (obj);
-    if (objidx)
+    objidx_t objidx;
+    if (share)
     {
-      obj->fini ();
-      return objidx;
+      objidx = packed_map.get (obj);
+      if (objidx)
+      {
+	obj->fini ();
+	return objidx;
+      }
     }
 
     tail -= len;
@@ -231,17 +253,24 @@
 
     objidx = packed.length - 1;
 
-    packed_map.set (obj, objidx);
+    if (share) packed_map.set (obj, objidx);
 
     return objidx;
   }
 
-  void revert (range_t snap)
+  void revert (snapshot_t snap)
   {
-    assert (snap.head <= head);
-    assert (tail <= snap.tail);
-    head = snap.head;
-    tail = snap.tail;
+    assert (snap.current == current);
+    current->links.shrink (snap.num_links);
+    revert (snap.head, snap.tail);
+  }
+  void revert (char *snap_head,
+	       char *snap_tail)
+  {
+    assert (snap_head <= head);
+    assert (tail <= snap_tail);
+    head = snap_head;
+    tail = snap_tail;
     discard_stale_objects ();
   }
 
@@ -260,7 +289,9 @@
   }
 
   template <typename T>
-  void add_link (T &ofs, objidx_t objidx, const void *base = nullptr)
+  void add_link (T &ofs, objidx_t objidx,
+		 whence_t whence = Head,
+		 unsigned bias = 0)
   {
     static_assert (sizeof (T) == 2 || sizeof (T) == 4, "");
 
@@ -270,18 +301,24 @@
     assert (current);
     assert (current->head <= (const char *) &ofs);
 
-    if (!base)
-      base = current->head;
-    else
-      assert (current->head <= (const char *) base);
+    auto& link = *current->links.push ();
 
-    auto& link = *current->links.push ();
     link.is_wide = sizeof (T) == 4;
+    link.is_signed = hb_is_signed (hb_unwrap_type (T));
+    link.whence = (unsigned) whence;
     link.position = (const char *) &ofs - current->head;
-    link.bias = (const char *) base - current->head;
+    link.bias = bias;
     link.objidx = objidx;
   }
 
+  unsigned to_bias (const void *base) const
+  {
+    if (!base) return 0;
+    assert (current);
+    assert (current->head <= (const char *) base);
+    return (const char *) base - current->head;
+  }
+
   void resolve_links ()
   {
     if (unlikely (in_error ())) return;
@@ -293,20 +330,29 @@
       for (const object_t::link_t &link : parent->links)
       {
 	const object_t* child = packed[link.objidx];
-	assert (link.bias <= (size_t) (parent->tail - parent->head));
-	unsigned offset = (child->head - parent->head) - link.bias;
+	if (unlikely (!child)) { err_other_error(); return; }
+	unsigned offset = 0;
+	switch ((whence_t) link.whence) {
+	case Head:     offset = child->head - parent->head; break;
+	case Tail:     offset = child->head - parent->tail; break;
+	case Absolute: offset = (head - start) + (child->head - tail); break;
+	}
 
-	if (link.is_wide)
+	assert (offset >= link.bias);
+	offset -= link.bias;
+	if (link.is_signed)
 	{
-	  auto &off = * ((BEInt<uint32_t, 4> *) (parent->head + link.position));
-	  assert (0 == off);
-	  check_assign (off, offset);
+	  if (link.is_wide)
+	    assign_offset<int32_t> (parent, link, offset);
+	  else
+	    assign_offset<int16_t> (parent, link, offset);
 	}
 	else
 	{
-	  auto &off = * ((BEInt<uint16_t, 2> *) (parent->head + link.position));
-	  assert (0 == off);
-	  check_assign (off, offset);
+	  if (link.is_wide)
+	    assign_offset<uint32_t> (parent, link, offset);
+	  else
+	    assign_offset<uint16_t> (parent, link, offset);
 	}
       }
   }
@@ -387,6 +433,12 @@
   Type *copy (const Type *src, Ts&&... ds)
   { return copy (*src, hb_forward<Ts> (ds)...); }
 
+  template<typename Iterator,
+	   hb_requires (hb_is_iterator (Iterator)),
+	   typename ...Ts>
+  void copy_all (Iterator it, Ts&&... ds)
+  { for (decltype (*it) _ : it) copy (_, hb_forward<Ts> (ds)...); }
+
   template <typename Type>
   hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; }
 
@@ -441,6 +493,15 @@
 			   (char *) b.arrayZ, free);
   }
 
+  private:
+  template <typename T>
+  void assign_offset (const object_t* parent, const object_t::link_t &link, unsigned offset)
+  {
+    auto &off = * ((BEInt<T, sizeof (T)> *) (parent->head + link.position));
+    assert (0 == off);
+    check_assign (off, offset);
+  }
+
   public: /* TODO Make private. */
   char *start, *head, *tail, *end;
   unsigned int debug_depth;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -69,7 +69,7 @@
 hb_set_t *
 hb_set_get_empty ()
 {
-  return const_cast<hb_set_t *> (&Null(hb_set_t));
+  return const_cast<hb_set_t *> (&Null (hb_set_t));
 }
 
 /**
@@ -145,10 +145,10 @@
  * hb_set_allocation_successful:
  * @set: a set.
  *
- * 
  *
- * Return value: 
  *
+ * Return value:
+ *
  * Since: 0.9.2
  **/
 hb_bool_t
@@ -161,8 +161,8 @@
  * hb_set_clear:
  * @set: a set.
  *
- * 
  *
+ *
  * Since: 0.9.2
  **/
 void
@@ -175,10 +175,10 @@
  * hb_set_is_empty:
  * @set: a set.
  *
- * 
  *
- * Return value: 
  *
+ * Return value:
+ *
  * Since: 0.9.7
  **/
 hb_bool_t
@@ -190,12 +190,12 @@
 /**
  * hb_set_has:
  * @set: a set.
- * @codepoint: 
+ * @codepoint:
  *
- * 
  *
- * Return value: 
  *
+ * Return value:
+ *
  * Since: 0.9.2
  **/
 hb_bool_t
@@ -208,10 +208,10 @@
 /**
  * hb_set_add:
  * @set: a set.
- * @codepoint: 
+ * @codepoint:
  *
- * 
  *
+ *
  * Since: 0.9.2
  **/
 void
@@ -224,11 +224,11 @@
 /**
  * hb_set_add_range:
  * @set: a set.
- * @first: 
- * @last: 
+ * @first:
+ * @last:
  *
- * 
  *
+ *
  * Since: 0.9.7
  **/
 void
@@ -242,10 +242,10 @@
 /**
  * hb_set_del:
  * @set: a set.
- * @codepoint: 
+ * @codepoint:
  *
- * 
  *
+ *
  * Since: 0.9.2
  **/
 void
@@ -258,11 +258,11 @@
 /**
  * hb_set_del_range:
  * @set: a set.
- * @first: 
- * @last: 
+ * @first:
+ * @last:
  *
- * 
  *
+ *
  * Since: 0.9.7
  **/
 void
@@ -278,8 +278,8 @@
  * @set: a set.
  * @other: other set.
  *
- * 
  *
+ *
  * Return value: %TRUE if the two sets are equal, %FALSE otherwise.
  *
  * Since: 0.9.7
@@ -312,10 +312,10 @@
 /**
  * hb_set_set:
  * @set: a set.
- * @other: 
+ * @other:
  *
- * 
  *
+ *
  * Since: 0.9.2
  **/
 void
@@ -328,10 +328,10 @@
 /**
  * hb_set_union:
  * @set: a set.
- * @other: 
+ * @other:
  *
- * 
  *
+ *
  * Since: 0.9.2
  **/
 void
@@ -344,10 +344,10 @@
 /**
  * hb_set_intersect:
  * @set: a set.
- * @other: 
+ * @other:
  *
- * 
  *
+ *
  * Since: 0.9.2
  **/
 void
@@ -360,10 +360,10 @@
 /**
  * hb_set_subtract:
  * @set: a set.
- * @other: 
+ * @other:
  *
- * 
  *
+ *
  * Since: 0.9.2
  **/
 void
@@ -376,10 +376,10 @@
 /**
  * hb_set_symmetric_difference:
  * @set: a set.
- * @other: 
+ * @other:
  *
- * 
  *
+ *
  * Since: 0.9.2
  **/
 void
@@ -394,8 +394,8 @@
  * hb_set_invert:
  * @set: a set.
  *
- * 
  *
+ *
  * Since: 0.9.10
  *
  * Deprecated: 1.6.1

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -89,6 +89,23 @@
       }
     }
 
+    void del_range (hb_codepoint_t a, hb_codepoint_t b)
+    {
+      elt_t *la = &elt (a);
+      elt_t *lb = &elt (b);
+      if (la == lb)
+	*la &= ~((mask (b) << 1) - mask(a));
+      else
+      {
+	*la &= mask (a) - 1;
+	la++;
+
+	memset (la, 0, (char *) lb - (char *) la);
+
+	*lb &= ~((mask (b) << 1) - 1);
+      }
+    }
+
     bool is_equal (const page_t *other) const
     {
       return 0 == hb_memcmp (&v, &other->v, sizeof (v));
@@ -135,7 +152,11 @@
       unsigned int i = m / ELT_BITS;
       unsigned int j = m & ELT_MASK;
 
-      const elt_t vv = v[i] & ((elt_t (1) << (j + 1)) - 1);
+      /* Fancy mask to avoid shifting by elt_t bitsize, which is undefined. */
+      const elt_t mask = j < 8 * sizeof (elt_t) - 1 ?
+			 ((elt_t (1) << (j + 1)) - 1) :
+			 (elt_t) -1;
+      const elt_t vv = v[i] & mask;
       const elt_t *p = &vv;
       while (true)
       {
@@ -258,7 +279,7 @@
     return true;
   }
 
-  void dirty () { population = (unsigned int) -1; }
+  void dirty () { population = UINT_MAX; }
 
   void add (hb_codepoint_t g)
   {
@@ -362,14 +383,56 @@
     dirty ();
     page->del (g);
   }
+
+  private:
+  void del_pages (int ds, int de)
+  {
+    if (ds <= de)
+    {
+      unsigned int write_index = 0;
+      for (unsigned int i = 0; i < page_map.length; i++)
+      {
+	int m = (int) page_map[i].major;
+	if (m < ds || de < m)
+	  page_map[write_index++] = page_map[i];
+      }
+      compact (write_index);
+      resize (write_index);
+    }
+  }
+
+  public:
   void del_range (hb_codepoint_t a, hb_codepoint_t b)
   {
     /* TODO perform op even if !successful. */
-    /* TODO Optimize, like add_range(). */
     if (unlikely (!successful)) return;
-    for (unsigned int i = a; i < b + 1; i++)
-      del (i);
+    if (unlikely (a > b || a == INVALID || b == INVALID)) return;
+    dirty ();
+    unsigned int ma = get_major (a);
+    unsigned int mb = get_major (b);
+    /* Delete pages from ds through de if ds <= de. */
+    int ds = (a == major_start (ma))? (int) ma: (int) (ma + 1);
+    int de = (b + 1 == major_start (mb + 1))? (int) mb: ((int) mb - 1);
+    if (ds > de || (int) ma < ds)
+    {
+      page_t *page = page_for (a);
+      if (page)
+      {
+	if (ma == mb)
+	  page->del_range (a, b);
+	else
+	  page->del_range (a, major_start (ma + 1) - 1);
+      }
+    }
+    if (de < (int) mb && ma != mb)
+    {
+      page_t *page = page_for (b);
+      if (page)
+	page->del_range (major_start (mb), b);
+    }
+    del_pages (ds, de);
   }
+
   bool get (hb_codepoint_t g) const
   {
     const page_t *page = page_for (g);
@@ -387,7 +450,10 @@
   bool operator () (hb_codepoint_t k) const { return has (k); }
 
   /* Sink interface. */
-  hb_set_t& operator << (hb_codepoint_t v) { add (v); return *this; }
+  hb_set_t& operator << (hb_codepoint_t v)
+  { add (v); return *this; }
+  hb_set_t& operator << (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& range)
+  { add_range (range.first, range.second); return *this; }
 
   bool intersects (hb_codepoint_t first, hb_codepoint_t last) const
   {
@@ -446,6 +512,34 @@
     return true;
   }
 
+  void compact (unsigned int length)
+  {
+    hb_vector_t<uint32_t> old_index_to_page_map_index;
+    old_index_to_page_map_index.resize(pages.length);
+    for (uint32_t i = 0; i < old_index_to_page_map_index.length; i++)
+      old_index_to_page_map_index[i] = 0xFFFFFFFF;
+
+    for (uint32_t i = 0; i < length; i++)
+      old_index_to_page_map_index[page_map[i].index] =  i;
+
+    compact_pages (old_index_to_page_map_index);
+  }
+
+  void compact_pages (const hb_vector_t<uint32_t>& old_index_to_page_map_index)
+  {
+    unsigned int write_index = 0;
+    for (unsigned int i = 0; i < pages.length; i++)
+    {
+      if (old_index_to_page_map_index[i] == 0xFFFFFFFF) continue;
+
+      if (write_index < i)
+	pages[write_index] = pages[i];
+
+      page_map[old_index_to_page_map_index[i]].index = write_index;
+      write_index++;
+    }
+  }
+
   template <typename Op>
   void process (const Op& op, const hb_set_t *other)
   {
@@ -459,10 +553,22 @@
 
     unsigned int count = 0, newCount = 0;
     unsigned int a = 0, b = 0;
+    unsigned int write_index = 0;
     for (; a < na && b < nb; )
     {
       if (page_map[a].major == other->page_map[b].major)
       {
+	if (!Op::passthru_left)
+	{
+	  // Move page_map entries that we're keeping from the left side set
+	  // to the front of the page_map vector. This isn't necessary if
+	  // passthru_left is set since no left side pages will be removed
+	  // in that case.
+	  if (write_index < a)
+	    page_map[write_index] = page_map[a];
+	  write_index++;
+	}
+
 	count++;
 	a++;
 	b++;
@@ -485,9 +591,16 @@
     if (Op::passthru_right)
       count += nb - b;
 
-    if (count > pages.length)
-      if (!resize (count))
-	return;
+    if (!Op::passthru_left)
+    {
+      na  = write_index;
+      next_page = write_index;
+      compact (write_index);
+    }
+
+    if (!resize (count))
+      return;
+
     newCount = count;
 
     /* Process in-place backward. */
@@ -662,7 +775,7 @@
 
   unsigned int get_population () const
   {
-    if (population != (unsigned int) -1)
+    if (population != UINT_MAX)
       return population;
 
     unsigned int pop = 0;
@@ -698,8 +811,15 @@
   struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t>
   {
     static constexpr bool is_sorted_iterator = true;
-    iter_t (const hb_set_t &s_ = Null(hb_set_t)) :
-      s (&s_), v (INVALID), l (s->get_population () + 1) { __next__ (); }
+    iter_t (const hb_set_t &s_ = Null (hb_set_t),
+	    bool init = true) : s (&s_), v (INVALID), l(0)
+    {
+      if (init)
+      {
+	l = s->get_population () + 1;
+	__next__ ();
+      }
+    }
 
     typedef hb_codepoint_t __item_t__;
     hb_codepoint_t __item__ () const { return v; }
@@ -707,7 +827,7 @@
     void __next__ () { s->next (&v); if (l) l--; }
     void __prev__ () { s->previous (&v); }
     unsigned __len__ () const { return l; }
-    iter_t end () const { return iter_t (*s); }
+    iter_t end () const { return iter_t (*s, false); }
     bool operator != (const iter_t& o) const
     { return s != o.s || v != o.v; }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -257,7 +257,7 @@
 hb_shape_plan_t *
 hb_shape_plan_get_empty ()
 {
-  return const_cast<hb_shape_plan_t *> (&Null(hb_shape_plan_t));
+  return const_cast<hb_shape_plan_t *> (&Null (hb_shape_plan_t));
 }
 
 /**

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -102,7 +102,7 @@
 	  static void destroy (Type *p) { HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (p); } \
 	}; \
 	\
-	static_assert (true, "") /* Require semicolon. */
+	static_assert (true, "") /* Require semicolon after. */
 
 
 template <typename Object>

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -51,6 +51,9 @@
 const unsigned char _hb_Null_AAT_Lookup[2] = {0xFF, 0xFF};
 
 
+
+/* hb_face_t */
+
 unsigned int
 hb_face_t::load_num_glyphs () const
 {
@@ -73,4 +76,37 @@
   return ret;
 }
 
+
+/* hb_user_data_array_t */
+
+bool
+hb_user_data_array_t::set (hb_user_data_key_t *key,
+			   void *              data,
+			   hb_destroy_func_t   destroy,
+			   hb_bool_t           replace)
+{
+  if (!key)
+    return false;
+
+  if (replace) {
+    if (!data && !destroy) {
+      items.remove (key, lock);
+      return true;
+    }
+  }
+  hb_user_data_item_t item = {key, data, destroy};
+  bool ret = !!items.replace_or_insert (item, lock, (bool) replace);
+
+  return ret;
+}
+
+void *
+hb_user_data_array_t::get (hb_user_data_key_t *key)
+{
+  hb_user_data_item_t item = {nullptr, nullptr, nullptr};
+
+  return items.find (key, &item, lock) ? item.data : nullptr;
+}
+
+
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-string-array.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-string-array.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-string-array.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -37,6 +37,7 @@
 #define HB_STRING_ARRAY_TYPE_NAME	HB_PASTE(HB_STRING_ARRAY_NAME, _msgstr_t)
 #define HB_STRING_ARRAY_POOL_NAME	HB_PASTE(HB_STRING_ARRAY_NAME, _msgstr)
 #define HB_STRING_ARRAY_OFFS_NAME	HB_PASTE(HB_STRING_ARRAY_NAME, _msgidx)
+#define HB_STRING_ARRAY_LENG_NAME	HB_PASTE(HB_STRING_ARRAY_NAME, _length)
 
 static const union HB_STRING_ARRAY_TYPE_NAME {
   struct {
@@ -66,6 +67,8 @@
   sizeof (HB_STRING_ARRAY_TYPE_NAME)
 };
 
+static const unsigned int HB_STRING_ARRAY_LENG_NAME = ARRAY_LENGTH_CONST (HB_STRING_ARRAY_OFFS_NAME) - 1;
+
 static inline hb_bytes_t
 HB_STRING_ARRAY_NAME (unsigned int i)
 {
@@ -77,5 +80,6 @@
 #undef HB_STRING_ARRAY_TYPE_NAME
 #undef HB_STRING_ARRAY_POOL_NAME
 #undef HB_STRING_ARRAY_OFFS_NAME
+#undef HB_STRING_ARRAY_LENG_NAME
 
 #endif /* HB_STRING_ARRAY_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -108,7 +108,7 @@
 	fdmap.add (fd);
       hb_set_destroy (set);
       if (unlikely (fdmap.get_population () != subset_fd_count))
-      	return false;
+	return false;
     }
 
     /* update each font dict index stored as "code" in fdselect_ranges */
@@ -158,7 +158,7 @@
 {
   TRACE_SERIALIZE (this);
   FDSELECT3_4 *p = c->allocate_size<FDSELECT3_4> (size);
-  if (unlikely (p == nullptr)) return_trace (false);
+  if (unlikely (!p)) return_trace (false);
   p->nRanges () = fdselect_ranges.length;
   for (unsigned int i = 0; i < fdselect_ranges.length; i++)
   {
@@ -184,7 +184,7 @@
 {
   TRACE_SERIALIZE (this);
   FDSelect *p = c->allocate_min<FDSelect> ();
-  if (unlikely (p == nullptr)) return_trace (false);
+  if (unlikely (!p)) return_trace (false);
   p->format = fdselect_format;
   size -= FDSelect::min_size;
 
@@ -194,7 +194,7 @@
   case 0:
   {
     FDSelect0 *p = c->allocate_size<FDSelect0> (size);
-    if (unlikely (p == nullptr)) return_trace (false);
+    if (unlikely (!p)) return_trace (false);
     unsigned int range_index = 0;
     unsigned int fd = fdselect_ranges[range_index++].code;
     for (unsigned int i = 0; i < num_glyphs; i++)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -44,7 +44,7 @@
 
   void encode_byte (unsigned char b)
   {
-    if (unlikely (buff.push (b) == &Crap(unsigned char)))
+    if (unlikely (buff.push (b) == &Crap (unsigned char)))
       set_error ();
   }
 
@@ -128,26 +128,17 @@
   bool    error;
 };
 
-struct cff_sub_table_offsets_t {
-  cff_sub_table_offsets_t () : privateDictsOffset (0)
+struct cff_sub_table_info_t {
+  cff_sub_table_info_t ()
+    : fd_array_link (0),
+      char_strings_link (0)
   {
-    topDictInfo.init ();
-    FDSelectInfo.init ();
-    FDArrayInfo.init ();
-    charStringsInfo.init ();
-    globalSubrsInfo.init ();
-    localSubrsInfos.init ();
+    fd_select.init ();
   }
 
-  ~cff_sub_table_offsets_t () { localSubrsInfos.fini (); }
-
-  table_info_t     topDictInfo;
-  table_info_t     FDSelectInfo;
-  table_info_t     FDArrayInfo;
-  table_info_t     charStringsInfo;
-  unsigned int  privateDictsOffset;
-  table_info_t     globalSubrsInfo;
-  hb_vector_t<table_info_t>  localSubrsInfos;
+  table_info_t     fd_select;
+  objidx_t     	   fd_array_link;
+  objidx_t     	   char_strings_link;
 };
 
 template <typename OPSTR=op_str_t>
@@ -155,7 +146,7 @@
 {
   bool serialize (hb_serialize_context_t *c,
 		  const OPSTR &opstr,
-		  const cff_sub_table_offsets_t &offsets) const
+		  const cff_sub_table_info_t &info) const
   {
     TRACE_SERIALIZE (this);
 
@@ -162,13 +153,13 @@
     switch (opstr.op)
     {
       case OpCode_CharStrings:
-	return_trace (FontDict::serialize_offset4_op(c, opstr.op, offsets.charStringsInfo.offset));
+	return_trace (FontDict::serialize_link4_op(c, opstr.op, info.char_strings_link, whence_t::Absolute));
 
       case OpCode_FDArray:
-	return_trace (FontDict::serialize_offset4_op(c, opstr.op, offsets.FDArrayInfo.offset));
+	return_trace (FontDict::serialize_link4_op(c, opstr.op, info.fd_array_link, whence_t::Absolute));
 
       case OpCode_FDSelect:
-	return_trace (FontDict::serialize_offset4_op(c, opstr.op, offsets.FDSelectInfo.offset));
+	return_trace (FontDict::serialize_link4_op(c, opstr.op, info.fd_select.link, whence_t::Absolute));
 
       default:
 	return_trace (copy_opstr (c, opstr));
@@ -175,20 +166,6 @@
     }
     return_trace (true);
   }
-
-  unsigned int calculate_serialized_size (const OPSTR &opstr) const
-  {
-    switch (opstr.op)
-    {
-      case OpCode_CharStrings:
-      case OpCode_FDArray:
-      case OpCode_FDSelect:
-	return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (opstr.op);
-
-      default:
-	return opstr.str.length;
-    }
-  }
 };
 
 struct cff_font_dict_op_serializer_t : op_serializer_t
@@ -202,33 +179,17 @@
     if (opstr.op == OpCode_Private)
     {
       /* serialize the private dict size & offset as 2-byte & 4-byte integers */
-      if (unlikely (!UnsizedByteStr::serialize_int2 (c, privateDictInfo.size) ||
-		    !UnsizedByteStr::serialize_int4 (c, privateDictInfo.offset)))
-	return_trace (false);
-
-      /* serialize the opcode */
-      HBUINT8 *p = c->allocate_size<HBUINT8> (1);
-      if (unlikely (p == nullptr)) return_trace (false);
-      *p = OpCode_Private;
-
-      return_trace (true);
+      return_trace (UnsizedByteStr::serialize_int2 (c, privateDictInfo.size) &&
+		    Dict::serialize_link4_op (c, opstr.op, privateDictInfo.link, whence_t::Absolute));
     }
     else
     {
       HBUINT8 *d = c->allocate_size<HBUINT8> (opstr.str.length);
-      if (unlikely (d == nullptr)) return_trace (false);
+      if (unlikely (!d)) return_trace (false);
       memcpy (d, &opstr.str[0], opstr.str.length);
     }
     return_trace (true);
   }
-
-  unsigned int calculate_serialized_size (const op_str_t &opstr) const
-  {
-    if (opstr.op == OpCode_Private)
-      return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (OpCode_Private);
-    else
-      return opstr.str.length;
-  }
 };
 
 struct cff_private_dict_op_serializer_t : op_serializer_t
@@ -238,7 +199,7 @@
 
   bool serialize (hb_serialize_context_t *c,
 		  const op_str_t &opstr,
-		  const unsigned int subrsOffset) const
+		  objidx_t subrs_link) const
   {
     TRACE_SERIALIZE (this);
 
@@ -246,31 +207,15 @@
       return true;
     if (opstr.op == OpCode_Subrs)
     {
-      if (desubroutinize || (subrsOffset == 0))
+      if (desubroutinize || !subrs_link)
 	return_trace (true);
       else
-	return_trace (FontDict::serialize_offset2_op (c, opstr.op, subrsOffset));
+	return_trace (FontDict::serialize_link2_op (c, opstr.op, subrs_link));
     }
     else
       return_trace (copy_opstr (c, opstr));
   }
 
-  unsigned int calculate_serialized_size (const op_str_t &opstr,
-					  bool has_localsubr=true) const
-  {
-    if (drop_hints && dict_opset_t::is_hint_op (opstr.op))
-      return 0;
-    if (opstr.op == OpCode_Subrs)
-    {
-      if (desubroutinize || !has_localsubr)
-	return 0;
-      else
-	return OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (opstr.op);
-    }
-    else
-      return opstr.str.length;
-  }
-
   protected:
   const bool  desubroutinize;
   const bool  drop_hints;
@@ -300,14 +245,14 @@
       hb_codepoint_t  glyph;
       if (!plan->old_gid_for_new_gid (i, &glyph))
       {
-      	/* add an endchar only charstring for a missing glyph if CFF1 */
-      	if (endchar_op != OpCode_Invalid) flat_charstrings[i].push (endchar_op);
-      	continue;
+	/* add an endchar only charstring for a missing glyph if CFF1 */
+	if (endchar_op != OpCode_Invalid) flat_charstrings[i].push (endchar_op);
+	continue;
       }
       const byte_str_t str = (*acc.charStrings)[glyph];
       unsigned int fd = acc.fdSelect->get_fd (glyph);
       if (unlikely (fd >= acc.fdCount))
-      	return false;
+	return false;
       cs_interpreter_t<ENV, OPSET, flatten_param_t> interp;
       interp.env.init (str, acc, fd);
       flatten_param_t  param = { flat_charstrings[i], plan->drop_hints };
@@ -456,7 +401,7 @@
   bool    vsindex_dropped;
   bool    has_prefix_;
   op_code_t	prefix_op_;
-  number_t 	prefix_num_;
+  number_t	prefix_num_;
 
   private:
   typedef parsed_values_t<parsed_cs_op_t> SUPER;
@@ -516,19 +461,19 @@
   template <typename ENV>
   void set_current_str (ENV &env, bool calling)
   {
-    parsed_cs_str_t  *parsed_str = get_parsed_str_for_context (env.context);
-    if (likely (parsed_str != nullptr))
+    parsed_cs_str_t *parsed_str = get_parsed_str_for_context (env.context);
+    if (unlikely (!parsed_str))
     {
-      /* If the called subroutine is parsed partially but not completely yet,
-       * it must be because we are calling it recursively.
-       * Handle it as an error. */
-      if (unlikely (calling && !parsed_str->is_parsed () && (parsed_str->values.length > 0)))
-      	env.set_error ();
-      else
-      	current_parsed_str = parsed_str;
+      env.set_error ();
+      return;
     }
+    /* If the called subroutine is parsed partially but not completely yet,
+     * it must be because we are calling it recursively.
+     * Handle it as an error. */
+    if (unlikely (calling && !parsed_str->is_parsed () && (parsed_str->values.length > 0)))
+      env.set_error ();
     else
-      env.set_error ();
+      current_parsed_str = parsed_str;
   }
 
   parsed_cs_str_t	*current_parsed_str;
@@ -659,11 +604,11 @@
     {
       hb_codepoint_t  glyph;
       if (!plan->old_gid_for_new_gid (i, &glyph))
-      	continue;
+	continue;
       const byte_str_t str = (*acc.charStrings)[glyph];
       unsigned int fd = acc.fdSelect->get_fd (glyph);
       if (unlikely (fd >= acc.fdCount))
-      	return false;
+	return false;
 
       cs_interpreter_t<ENV, OPSET, subr_subset_param_t> interp;
       interp.env.init (str, acc, fd);
@@ -677,8 +622,8 @@
       if (unlikely (!interp.interpret (param)))
 	return false;
 
-      /* finalize parsed string esp. copy CFF1 width or CFF2 vsindex to the parsed charstring for encoding */
-      SUBSETTER::finalize_parsed_str (interp.env, param, parsed_charstrings[i]);
+      /* complete parsed string esp. copy CFF1 width or CFF2 vsindex to the parsed charstring for encoding */
+      SUBSETTER::complete_parsed_str (interp.env, param, parsed_charstrings[i]);
     }
 
     if (plan->drop_hints)
@@ -740,13 +685,13 @@
       hb_codepoint_t  glyph;
       if (!plan->old_gid_for_new_gid (i, &glyph))
       {
-      	/* add an endchar only charstring for a missing glyph if CFF1 */
-      	if (endchar_op != OpCode_Invalid) buffArray[i].push (endchar_op);
-      	continue;
+	/* add an endchar only charstring for a missing glyph if CFF1 */
+	if (endchar_op != OpCode_Invalid) buffArray[i].push (endchar_op);
+	continue;
       }
       unsigned int  fd = acc.fdSelect->get_fd (glyph);
       if (unlikely (fd >= acc.fdCount))
-      	return false;
+	return false;
       if (unlikely (!encode_str (parsed_charstrings[i], fd, buffArray[i])))
 	return false;
     }
@@ -900,11 +845,11 @@
     {
       parsed_cs_op_t  &csop = str.values[pos];
       if (csop.op == OpCode_return)
-      	break;
+	break;
       if (!csop.for_drop ())
       {
-      	drop.all_dropped = false;
-      	break;
+	drop.all_dropped = false;
+	break;
       }
     }
 
@@ -986,7 +931,7 @@
   }
 
   protected:
-  const ACC   			&acc;
+  const ACC			&acc;
   const hb_subset_plan_t	*plan;
 
   subr_closures_t		closures;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -64,22 +64,18 @@
   static unsigned int unoffset_sid (unsigned int sid) { return sid - num_std_strings; }
 };
 
-struct cff1_sub_table_offsets_t : cff_sub_table_offsets_t
+struct cff1_sub_table_info_t : cff_sub_table_info_t
 {
-  cff1_sub_table_offsets_t ()
-    : cff_sub_table_offsets_t (),
-      nameIndexOffset (0),
-      encodingOffset (0)
-  {
-    stringIndexInfo.init ();
-    charsetInfo.init ();
+  cff1_sub_table_info_t ()
+    : cff_sub_table_info_t (),
+      encoding_link (0),
+      charset_link (0)
+   {
     privateDictInfo.init ();
   }
 
-  unsigned int  nameIndexOffset;
-  table_info_t	stringIndexInfo;
-  unsigned int  encodingOffset;
-  table_info_t	charsetInfo;
+  objidx_t	encoding_link;
+  objidx_t	charset_link;
   table_info_t	privateDictInfo;
 };
 
@@ -86,7 +82,7 @@
 /* a copy of a parsed out cff1_top_dict_values_t augmented with additional operators */
 struct cff1_top_dict_values_mod_t : cff1_top_dict_values_t
 {
-  void init (const cff1_top_dict_values_t *base_= &Null(cff1_top_dict_values_t))
+  void init (const cff1_top_dict_values_t *base_= &Null (cff1_top_dict_values_t))
   {
     SUPER::init ();
     base = base_;
@@ -117,13 +113,13 @@
 
 struct top_dict_modifiers_t
 {
-  top_dict_modifiers_t (const cff1_sub_table_offsets_t &offsets_,
+  top_dict_modifiers_t (const cff1_sub_table_info_t &info_,
 			   const unsigned int (&nameSIDs_)[name_dict_values_t::ValCount])
-    : offsets (offsets_),
+    : info (info_),
       nameSIDs (nameSIDs_)
   {}
 
-  const cff1_sub_table_offsets_t &offsets;
+  const cff1_sub_table_info_t &info;
   const unsigned int	(&nameSIDs)[name_dict_values_t::ValCount];
 };
 
@@ -139,22 +135,20 @@
     switch (op)
     {
       case OpCode_charset:
-	return_trace (FontDict::serialize_offset4_op(c, op, mod.offsets.charsetInfo.offset));
+	if (mod.info.charset_link)
+	  return_trace (FontDict::serialize_link4_op(c, op, mod.info.charset_link, whence_t::Absolute));
+	else
+	  goto fall_back;
 
       case OpCode_Encoding:
-	return_trace (FontDict::serialize_offset4_op(c, op, mod.offsets.encodingOffset));
+	if (mod.info.encoding_link)
+	  return_trace (FontDict::serialize_link4_op(c, op, mod.info.encoding_link, whence_t::Absolute));
+	else
+	  goto fall_back;
 
       case OpCode_Private:
-	{
-	  if (unlikely (!UnsizedByteStr::serialize_int2 (c, mod.offsets.privateDictInfo.size)))
-	    return_trace (false);
-	  if (unlikely (!UnsizedByteStr::serialize_int4 (c, mod.offsets.privateDictInfo.offset)))
-	    return_trace (false);
-	  HBUINT8 *p = c->allocate_size<HBUINT8> (1);
-	  if (unlikely (p == nullptr)) return_trace (false);
-	  *p = OpCode_Private;
-	}
-	break;
+	return_trace (UnsizedByteStr::serialize_int2 (c, mod.info.privateDictInfo.size) &&
+		      Dict::serialize_link4_op (c, op, mod.info.privateDictInfo.link, whence_t::Absolute));
 
       case OpCode_version:
       case OpCode_Notice:
@@ -165,7 +159,7 @@
       case OpCode_PostScript:
       case OpCode_BaseFontName:
       case OpCode_FontName:
-	return_trace (FontDict::serialize_offset2_op(c, op, mod.nameSIDs[name_dict_values_t::name_op_to_index (op)]));
+	return_trace (FontDict::serialize_int2_op (c, op, mod.nameSIDs[name_dict_values_t::name_op_to_index (op)]));
 
       case OpCode_ROS:
 	{
@@ -180,86 +174,29 @@
 			UnsizedByteStr::serialize_int2 (c, mod.nameSIDs[name_dict_values_t::ordering]) &&
 			copy_opstr (c, supp_op));
 	}
+      fall_back:
       default:
-	return_trace (cff_top_dict_op_serializer_t<cff1_top_dict_val_t>::serialize (c, opstr, mod.offsets));
+	return_trace (cff_top_dict_op_serializer_t<cff1_top_dict_val_t>::serialize (c, opstr, mod.info));
     }
     return_trace (true);
   }
 
-  unsigned int calculate_serialized_size (const cff1_top_dict_val_t &opstr) const
-  {
-    op_code_t op = opstr.op;
-    switch (op)
-    {
-      case OpCode_charset:
-      case OpCode_Encoding:
-	return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (op);
-
-      case OpCode_Private:
-	return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (OpCode_Private);
-
-      case OpCode_version:
-      case OpCode_Notice:
-      case OpCode_Copyright:
-      case OpCode_FullName:
-      case OpCode_FamilyName:
-      case OpCode_Weight:
-      case OpCode_PostScript:
-      case OpCode_BaseFontName:
-      case OpCode_FontName:
-	return OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (op);
-
-      case OpCode_ROS:
-	return ((OpCode_Size (OpCode_shortint) + 2) * 2) + (opstr.str.length - opstr.last_arg_offset)/* supplement + op */;
-
-      default:
-	return cff_top_dict_op_serializer_t<cff1_top_dict_val_t>::calculate_serialized_size (opstr);
-    }
-  }
 };
 
-struct font_dict_values_mod_t
-{
-  void init (const cff1_font_dict_values_t *base_,
-	     unsigned int fontName_,
-	     const table_info_t &privateDictInfo_)
-  {
-    base = base_;
-    fontName = fontName_;
-    privateDictInfo = privateDictInfo_;
-  }
-
-  unsigned get_count () const { return base->get_count (); }
-
-  const op_str_t &operator [] (unsigned int i) const { return (*base)[i]; }
-
-  const cff1_font_dict_values_t    *base;
-  table_info_t		   privateDictInfo;
-  unsigned int		fontName;
-};
-
 struct cff1_font_dict_op_serializer_t : cff_font_dict_op_serializer_t
 {
   bool serialize (hb_serialize_context_t *c,
 		  const op_str_t &opstr,
-		  const font_dict_values_mod_t &mod) const
+		  const cff1_font_dict_values_mod_t &mod) const
   {
     TRACE_SERIALIZE (this);
 
     if (opstr.op == OpCode_FontName)
-      return_trace (FontDict::serialize_uint2_op (c, opstr.op, mod.fontName));
+      return_trace (FontDict::serialize_int2_op (c, opstr.op, mod.fontName));
     else
       return_trace (SUPER::serialize (c, opstr, mod.privateDictInfo));
   }
 
-  unsigned int calculate_serialized_size (const op_str_t &opstr) const
-  {
-    if (opstr.op == OpCode_FontName)
-      return OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (OpCode_FontName);
-    else
-      return SUPER::calculate_serialized_size (opstr);
-  }
-
   private:
   typedef cff_font_dict_op_serializer_t SUPER;
 };
@@ -331,7 +268,7 @@
 struct range_list_t : hb_vector_t<code_pair_t>
 {
   /* replace the first glyph ID in the "glyph" field each range with a nLeft value */
-  bool finalize (unsigned int last_glyph)
+  bool complete (unsigned int last_glyph)
   {
     bool  two_byte = false;
     for (unsigned int i = (*this).length; i > 0; i--)
@@ -402,7 +339,7 @@
   cff1_subr_subsetter_t (const OT::cff1::accelerator_subset_t &acc_, const hb_subset_plan_t *plan_)
     : subr_subsetter_t (acc_, plan_) {}
 
-  static void finalize_parsed_str (cff1_cs_interp_env_t &env, subr_subset_param_t& param, parsed_cs_str_t &charstring)
+  static void complete_parsed_str (cff1_cs_interp_env_t &env, subr_subset_param_t& param, parsed_cs_str_t &charstring)
   {
     /* insert width at the beginning of the charstring as necessary */
     if (env.has_width)
@@ -414,8 +351,8 @@
     param.current_parsed_str->set_parsed ();
     for (unsigned int i = 0; i < env.callStack.get_count (); i++)
     {
-      parsed_cs_str_t  *parsed_str = param.get_parsed_str_for_context (env.callStack[i]);
-      if (likely (parsed_str != nullptr))
+      parsed_cs_str_t *parsed_str = param.get_parsed_str_for_context (env.callStack[i]);
+      if (likely (parsed_str))
 	parsed_str->set_parsed ();
       else
 	env.set_error ();
@@ -425,8 +362,7 @@
 
 struct cff_subset_plan {
   cff_subset_plan ()
-    : final_size (0),
-      offsets (),
+    : info (),
       orig_fdcount (0),
       subset_fdcount (1),
       subset_fdselect_format (0),
@@ -433,8 +369,6 @@
       drop_hints (false),
       desubroutinize(false)
   {
-    topdict_sizes.init ();
-    topdict_sizes.resize (1);
     topdict_mod.init ();
     subset_fdselect_ranges.init ();
     fdmap.init ();
@@ -452,7 +386,6 @@
 
   ~cff_subset_plan ()
   {
-    topdict_sizes.fini ();
     topdict_mod.fini ();
     subset_fdselect_ranges.fini ();
     fdmap.fini ();
@@ -466,7 +399,7 @@
     sidmap.fini ();
   }
 
-  unsigned int plan_subset_encoding (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan)
+  void plan_subset_encoding (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan)
   {
     const Encoding *encoding = acc.encoding;
     unsigned int  size0, size1, supp_size;
@@ -484,7 +417,7 @@
       hb_codepoint_t  old_glyph;
       if (!plan->old_gid_for_new_gid (glyph, &old_glyph))
       {
-      	/* Retain the code for the old missing glyph ID */
+	/* Retain the code for the old missing glyph ID */
 	old_glyph = glyph;
       }
       code = acc.glyph_to_code (old_glyph);
@@ -501,7 +434,7 @@
       }
       last_code = code;
 
-      if (encoding != &Null(Encoding))
+      if (encoding != &Null (Encoding))
       {
 	hb_codepoint_t  sid = acc.glyph_to_sid (old_glyph);
 	encoding->get_supplement_codes (sid, supp_codes);
@@ -515,7 +448,7 @@
     }
     supp_codes.fini ();
 
-    subset_enc_code_ranges.finalize (glyph);
+    subset_enc_code_ranges.complete (glyph);
 
     assert (subset_enc_num_codes <= 0xFF);
     size0 = Encoding0::min_size + HBUINT8::static_size * subset_enc_num_codes;
@@ -525,14 +458,9 @@
       subset_enc_format = 0;
     else
       subset_enc_format = 1;
-
-    return Encoding::calculate_serialized_size (
-			subset_enc_format,
-			subset_enc_format? subset_enc_code_ranges.length: subset_enc_num_codes,
-			subset_enc_supp_codes.length);
   }
 
-  unsigned int plan_subset_charset (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan)
+  void plan_subset_charset (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan)
   {
     unsigned int  size0, size_ranges;
     hb_codepoint_t  sid, last_sid = CFF_UNDEF_CODE;
@@ -544,7 +472,7 @@
       hb_codepoint_t  old_glyph;
       if (!plan->old_gid_for_new_gid (glyph, &old_glyph))
       {
-      	/* Retain the SID for the old missing glyph ID */
+	/* Retain the SID for the old missing glyph ID */
 	old_glyph = glyph;
       }
       sid = acc.glyph_to_sid (old_glyph);
@@ -560,7 +488,7 @@
       last_sid = sid;
     }
 
-    bool two_byte = subset_charset_ranges.finalize (glyph);
+    bool two_byte = subset_charset_ranges.complete (glyph);
 
     size0 = Charset0::min_size + HBUINT16::static_size * (plan->num_output_glyphs () - 1);
     if (!two_byte)
@@ -574,10 +502,6 @@
       subset_charset_format = 1;
     else
       subset_charset_format = 2;
-
-    return Charset::calculate_serialized_size (
-			subset_charset_format,
-			subset_charset_format? subset_charset_ranges.length: plan->num_output_glyphs ());
   }
 
   bool collect_sids_in_dicts (const OT::cff1::accelerator_subset_t &acc)
@@ -594,7 +518,7 @@
       }
     }
 
-    if (acc.fdArray != &Null(CFF1FDArray))
+    if (acc.fdArray != &Null (CFF1FDArray))
       for (unsigned int i = 0; i < orig_fdcount; i++)
 	if (fdmap.has (i))
 	  (void)sidmap.add (acc.fontDicts[i].fontName);
@@ -609,7 +533,6 @@
     hb_codepoint_t old_glyph;
     if (!plan->old_gid_for_new_gid (0, &old_glyph) || (old_glyph != 0)) return false;
 
-    final_size = 0;
     num_glyphs = plan->num_output_glyphs ();
     orig_fdcount = acc.fdCount;
     drop_hints = plan->drop_hints;
@@ -620,7 +543,7 @@
     for (hb_codepoint_t new_glyph = 0; new_glyph < plan->num_output_glyphs (); new_glyph++)
     {
       if (!plan->old_gid_for_new_gid(new_glyph, &old_glyph))
-      	continue;
+	continue;
       if (new_glyph != old_glyph) {
 	gid_renum = true;
 	break;
@@ -630,13 +553,6 @@
     subset_charset = gid_renum || !acc.is_predef_charset ();
     subset_encoding = !acc.is_CID() && !acc.is_predef_encoding ();
 
-    /* CFF header */
-    final_size += OT::cff1::static_size;
-
-    /* Name INDEX */
-    offsets.nameIndexOffset = final_size;
-    final_size += acc.nameIndex->get_size ();
-
     /* top dict INDEX */
     {
       /* Add encoding/charset to a (copy of) top dict as necessary */
@@ -650,25 +566,16 @@
 	if (need_to_add_set)
 	  topdict_mod.add_op (OpCode_charset);
       }
-      offsets.topDictInfo.offset = final_size;
-      cff1_top_dict_op_serializer_t topSzr;
-      unsigned int topDictSize = TopDict::calculate_serialized_size (topdict_mod, topSzr);
-      offsets.topDictInfo.offSize = calcOffSize(topDictSize);
-      if (unlikely (offsets.topDictInfo.offSize > 4))
-      	return false;
-      final_size += CFF1IndexOf<TopDict>::calculate_serialized_size<cff1_top_dict_values_mod_t>
-						(offsets.topDictInfo.offSize,
-						 &topdict_mod, 1, topdict_sizes, topSzr);
     }
 
     /* Determine re-mapping of font index as fdmap among other info */
-    if (acc.fdSelect != &Null(CFF1FDSelect))
+    if (acc.fdSelect != &Null (CFF1FDSelect))
     {
 	if (unlikely (!hb_plan_subset_cff_fdselect (plan,
 				  orig_fdcount,
 				  *acc.fdSelect,
 				  subset_fdcount,
-				  offsets.FDSelectInfo.size,
+				  info.fd_select.size,
 				  subset_fdselect_format,
 				  subset_fdselect_ranges,
 				  fdmap)))
@@ -683,20 +590,13 @@
       if (unlikely (!collect_sids_in_dicts (acc)))
 	return false;
       if (unlikely (sidmap.get_population () > 0x8000))	/* assumption: a dict won't reference that many strings */
-      	return false;
-      if (subset_charset)
-	offsets.charsetInfo.size = plan_subset_charset (acc, plan);
+	return false;
 
+      if (subset_charset) plan_subset_charset (acc, plan);
+
       topdict_mod.reassignSIDs (sidmap);
     }
 
-    /* String INDEX */
-    {
-      offsets.stringIndexInfo.offset = final_size;
-      offsets.stringIndexInfo.size = acc.stringIndex->calculate_serialized_size (offsets.stringIndexInfo.offSize, sidmap);
-      final_size += offsets.stringIndexInfo.size;
-    }
-
     if (desubroutinize)
     {
       /* Flatten global & local subrs */
@@ -704,9 +604,6 @@
 		    flattener(acc, plan);
       if (!flattener.flatten (subset_charstrings))
 	return false;
-
-      /* no global/local subroutines */
-      offsets.globalSubrsInfo.size = CFF1Subrs::calculate_serialized_size (1, 0, 0);
     }
     else
     {
@@ -723,131 +620,48 @@
       if (!subr_subsetter.encode_globalsubrs (subset_globalsubrs))
 	return false;
 
-      /* global subrs */
-      unsigned int dataSize = subset_globalsubrs.total_size ();
-      offsets.globalSubrsInfo.offSize = calcOffSize (dataSize);
-      if (unlikely (offsets.globalSubrsInfo.offSize > 4))
-      	return false;
-      offsets.globalSubrsInfo.size = CFF1Subrs::calculate_serialized_size (offsets.globalSubrsInfo.offSize, subset_globalsubrs.length, dataSize);
-
       /* local subrs */
-      if (!offsets.localSubrsInfos.resize (orig_fdcount))
-	return false;
       if (!subset_localsubrs.resize (orig_fdcount))
 	return false;
       for (unsigned int fd = 0; fd < orig_fdcount; fd++)
       {
 	subset_localsubrs[fd].init ();
-	offsets.localSubrsInfos[fd].init ();
 	if (fdmap.has (fd))
 	{
 	  if (!subr_subsetter.encode_localsubrs (fd, subset_localsubrs[fd]))
 	    return false;
-
-	  unsigned int dataSize = subset_localsubrs[fd].total_size ();
-	  if (dataSize > 0)
-	  {
-	    offsets.localSubrsInfos[fd].offset = final_size;
-	    offsets.localSubrsInfos[fd].offSize = calcOffSize (dataSize);
-	    if (unlikely (offsets.localSubrsInfos[fd].offSize > 4))
-	      return false;
-	    offsets.localSubrsInfos[fd].size = CFF1Subrs::calculate_serialized_size (offsets.localSubrsInfos[fd].offSize, subset_localsubrs[fd].length, dataSize);
-	  }
 	}
       }
     }
 
-    /* global subrs */
-    offsets.globalSubrsInfo.offset = final_size;
-    final_size += offsets.globalSubrsInfo.size;
-
     /* Encoding */
-    if (!subset_encoding)
-      offsets.encodingOffset = acc.topDict.EncodingOffset;
-    else
-    {
-      offsets.encodingOffset = final_size;
-      final_size += plan_subset_encoding (acc, plan);
-    }
+    if (subset_encoding)
+      plan_subset_encoding (acc, plan);
 
-    /* Charset */
-    if (!subset_charset && acc.is_predef_charset ())
-      offsets.charsetInfo.offset = acc.topDict.CharsetOffset;
+    /* private dicts & local subrs */
+    if (!acc.is_CID ())
+      fontdicts_mod.push (cff1_font_dict_values_mod_t ());
     else
-      offsets.charsetInfo.offset = final_size;
-    final_size += offsets.charsetInfo.size;
-
-    /* FDSelect */
-    if (acc.fdSelect != &Null(CFF1FDSelect))
     {
-      offsets.FDSelectInfo.offset = final_size;
-      final_size += offsets.FDSelectInfo.size;
-    }
-
-    /* FDArray (FDIndex) */
-    if (acc.fdArray != &Null(CFF1FDArray)) {
-      offsets.FDArrayInfo.offset = final_size;
-      cff1_font_dict_op_serializer_t fontSzr;
-      unsigned int dictsSize = 0;
-      for (unsigned int i = 0; i < acc.fontDicts.length; i++)
-	if (fdmap.has (i))
-	  dictsSize += FontDict::calculate_serialized_size (acc.fontDicts[i], fontSzr);
-
-      offsets.FDArrayInfo.offSize = calcOffSize (dictsSize);
-      if (unlikely (offsets.FDArrayInfo.offSize > 4))
-      	return false;
-      final_size += CFF1Index::calculate_serialized_size (offsets.FDArrayInfo.offSize, subset_fdcount, dictsSize);
-    }
-
-    /* CharStrings */
-    {
-      offsets.charStringsInfo.offset = final_size;
-      unsigned int dataSize = subset_charstrings.total_size ();
-      offsets.charStringsInfo.offSize = calcOffSize (dataSize);
-      if (unlikely (offsets.charStringsInfo.offSize > 4))
-      	return false;
-      final_size += CFF1CharStrings::calculate_serialized_size (offsets.charStringsInfo.offSize, plan->num_output_glyphs (), dataSize);
-    }
-
-    /* private dicts & local subrs */
-    offsets.privateDictInfo.offset = final_size;
-    for (unsigned int i = 0; i < orig_fdcount; i++)
-    {
-      if (fdmap.has (i))
-      {
-	bool  has_localsubrs = offsets.localSubrsInfos[i].size > 0;
-	cff_private_dict_op_serializer_t privSzr (desubroutinize, plan->drop_hints);
-	unsigned int  priv_size = PrivateDict::calculate_serialized_size (acc.privateDicts[i], privSzr, has_localsubrs);
-	table_info_t  privInfo = { final_size, priv_size, 0 };
-	font_dict_values_mod_t fontdict_mod;
-	if (!acc.is_CID ())
-	  fontdict_mod.init ( &Null(cff1_font_dict_values_t), CFF_UNDEF_SID, privInfo );
-	else
-	  fontdict_mod.init ( &acc.fontDicts[i], sidmap[acc.fontDicts[i].fontName], privInfo );
-	fontdicts_mod.push (fontdict_mod);
-	final_size += privInfo.size;
-
-	if (!plan->desubroutinize && has_localsubrs)
+      + hb_iter (acc.fontDicts)
+      | hb_filter ([&] (const cff1_font_dict_values_t &_)
+	{ return fdmap.has (&_ - &acc.fontDicts[0]); } )
+      | hb_map ([&] (const cff1_font_dict_values_t &_)
 	{
-	  offsets.localSubrsInfos[i].offset = final_size;
-	  final_size += offsets.localSubrsInfos[i].size;
-	}
-      }
+	  cff1_font_dict_values_mod_t mod;
+	  mod.init (&_, sidmap[_.fontName]);
+	  return mod;
+	})
+      | hb_sink (fontdicts_mod)
+      ;
     }
 
-    if (!acc.is_CID ())
-      offsets.privateDictInfo = fontdicts_mod[0].privateDictInfo;
-
     return ((subset_charstrings.length == plan->num_output_glyphs ())
 	   && (fontdicts_mod.length == subset_fdcount));
   }
 
-  unsigned int get_final_size () const  { return final_size; }
-
-  unsigned int	      final_size;
-  hb_vector_t<unsigned int>	topdict_sizes;
   cff1_top_dict_values_mod_t	topdict_mod;
-  cff1_sub_table_offsets_t	offsets;
+  cff1_sub_table_info_t		info;
 
   unsigned int    num_glyphs;
   unsigned int    orig_fdcount;
@@ -862,7 +676,7 @@
   str_buff_vec_t		subset_charstrings;
   str_buff_vec_t		subset_globalsubrs;
   hb_vector_t<str_buff_vec_t>	subset_localsubrs;
-  hb_vector_t<font_dict_values_mod_t>  fontdicts_mod;
+  hb_vector_t<cff1_font_dict_values_mod_t>  fontdicts_mod;
 
   bool		drop_hints;
 
@@ -883,74 +697,113 @@
   bool		desubroutinize;
 };
 
-static inline bool _write_cff1 (const cff_subset_plan &plan,
-				const OT::cff1::accelerator_subset_t  &acc,
-				unsigned int num_glyphs,
-				unsigned int dest_sz,
-				void *dest)
+static bool _serialize_cff1 (hb_serialize_context_t *c,
+			     cff_subset_plan &plan,
+			     const OT::cff1::accelerator_subset_t  &acc,
+			     unsigned int num_glyphs)
 {
-  hb_serialize_context_t c (dest, dest_sz);
+  /* private dicts & local subrs */
+  for (int i = (int)acc.privateDicts.length; --i >= 0 ;)
+  {
+    if (plan.fdmap.has (i))
+    {
+      objidx_t	subrs_link = 0;
+      if (plan.subset_localsubrs[i].length > 0)
+      {
+	CFF1Subrs *dest = c->start_embed <CFF1Subrs> ();
+	if (unlikely (!dest)) return false;
+	c->push ();
+	if (likely (dest && dest->serialize (c, plan.subset_localsubrs[i])))
+	  subrs_link = c->pop_pack ();
+	else
+	{
+	  c->pop_discard ();
+	  return false;
+	}
+      }
 
-  OT::cff1 *cff = c.start_serialize<OT::cff1> ();
-  if (unlikely (!c.extend_min (*cff)))
-    return false;
+      PrivateDict *pd = c->start_embed<PrivateDict> ();
+      if (unlikely (!pd)) return false;
+      c->push ();
+      cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
+      /* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
+      if (likely (pd->serialize (c, acc.privateDicts[i], privSzr, subrs_link)))
+      {
+	unsigned fd = plan.fdmap[i];
+	plan.fontdicts_mod[fd].privateDictInfo.size = c->length ();
+	plan.fontdicts_mod[fd].privateDictInfo.link = c->pop_pack ();
+      }
+      else
+      {
+	c->pop_discard ();
+	return false;
+      }
+    }
+  }
 
-  /* header */
-  cff->version.major = 0x01;
-  cff->version.minor = 0x00;
-  cff->nameIndex = cff->min_size;
-  cff->offSize = 4; /* unused? */
+  if (!acc.is_CID ())
+    plan.info.privateDictInfo = plan.fontdicts_mod[0].privateDictInfo;
 
-  /* name INDEX */
+  /* CharStrings */
   {
-    assert (cff->nameIndex == (unsigned) (c.head - c.start));
-    CFF1NameIndex *dest = c.start_embed<CFF1NameIndex> ();
-    if (unlikely (dest == nullptr)) return false;
-    if (unlikely (!dest->serialize (&c, *acc.nameIndex)))
+    CFF1CharStrings  *cs = c->start_embed<CFF1CharStrings> ();
+    if (unlikely (!cs)) return false;
+    c->push ();
+    if (likely (cs->serialize (c, plan.subset_charstrings)))
+      plan.info.char_strings_link = c->pop_pack ();
+    else
     {
-      DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF name INDEX");
+      c->pop_discard ();
       return false;
     }
   }
 
-  /* top dict INDEX */
+  /* FDArray (FD Index) */
+  if (acc.fdArray != &Null (CFF1FDArray))
   {
-    assert (plan.offsets.topDictInfo.offset == (unsigned) (c.head - c.start));
-    CFF1IndexOf<TopDict> *dest = c.start_embed< CFF1IndexOf<TopDict>> ();
-    if (dest == nullptr) return false;
-    cff1_top_dict_op_serializer_t topSzr;
-    top_dict_modifiers_t  modifier (plan.offsets, plan.topDictModSIDs);
-    if (unlikely (!dest->serialize (&c, plan.offsets.topDictInfo.offSize,
-				    &plan.topdict_mod, 1,
-				    plan.topdict_sizes, topSzr, modifier)))
+    CFF1FDArray *fda = c->start_embed<CFF1FDArray> ();
+    if (unlikely (!fda)) return false;
+    c->push ();
+    cff1_font_dict_op_serializer_t  fontSzr;
+    auto it = + hb_zip (+ hb_iter (plan.fontdicts_mod), + hb_iter (plan.fontdicts_mod));
+    if (likely (fda->serialize (c, it, fontSzr)))
+      plan.info.fd_array_link = c->pop_pack (false);
+    else
     {
-      DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF top dict");
+      c->pop_discard ();
       return false;
     }
   }
 
-  /* String INDEX */
+  /* FDSelect */
+  if (acc.fdSelect != &Null (CFF1FDSelect))
   {
-    assert (plan.offsets.stringIndexInfo.offset == (unsigned) (c.head - c.start));
-    CFF1StringIndex *dest = c.start_embed<CFF1StringIndex> ();
-    if (unlikely (dest == nullptr)) return false;
-    if (unlikely (!dest->serialize (&c, *acc.stringIndex, plan.offsets.stringIndexInfo.offSize, plan.sidmap)))
+    c->push ();
+    if (likely (hb_serialize_cff_fdselect (c, num_glyphs, *acc.fdSelect, acc.fdCount,
+					   plan.subset_fdselect_format, plan.info.fd_select.size,
+					   plan.subset_fdselect_ranges)))
+      plan.info.fd_select.link = c->pop_pack ();
+    else
     {
-      DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF string INDEX");
+      c->pop_discard ();
       return false;
     }
   }
 
-  /* global subrs */
+  /* Charset */
+  if (plan.subset_charset)
   {
-    assert (plan.offsets.globalSubrsInfo.offset != 0);
-    assert (plan.offsets.globalSubrsInfo.offset == (unsigned) (c.head - c.start));
-
-    CFF1Subrs *dest = c.start_embed <CFF1Subrs> ();
-    if (unlikely (dest == nullptr)) return false;
-    if (unlikely (!dest->serialize (&c, plan.offsets.globalSubrsInfo.offSize, plan.subset_globalsubrs)))
+    Charset *dest = c->start_embed<Charset> ();
+    if (unlikely (!dest)) return false;
+    c->push ();
+    if (likely (dest->serialize (c,
+				 plan.subset_charset_format,
+				 plan.num_glyphs,
+				 plan.subset_charset_ranges)))
+      plan.info.charset_link = c->pop_pack ();
+    else
     {
-      DEBUG_MSG (SUBSET, nullptr, "failed to serialize global subroutines");
+      c->pop_discard ();
       return false;
     }
   }
@@ -958,146 +811,102 @@
   /* Encoding */
   if (plan.subset_encoding)
   {
-    assert (plan.offsets.encodingOffset == (unsigned) (c.head - c.start));
-    Encoding *dest = c.start_embed<Encoding> ();
-    if (unlikely (dest == nullptr)) return false;
-    if (unlikely (!dest->serialize (&c,
-				    plan.subset_enc_format,
-				    plan.subset_enc_num_codes,
-				    plan.subset_enc_code_ranges,
-				    plan.subset_enc_supp_codes)))
+    Encoding *dest = c->start_embed<Encoding> ();
+    if (unlikely (!dest)) return false;
+    c->push ();
+    if (likely (dest->serialize (c,
+				 plan.subset_enc_format,
+				 plan.subset_enc_num_codes,
+				 plan.subset_enc_code_ranges,
+				 plan.subset_enc_supp_codes)))
+      plan.info.encoding_link = c->pop_pack ();
+    else
     {
-      DEBUG_MSG (SUBSET, nullptr, "failed to serialize Encoding");
+      c->pop_discard ();
       return false;
     }
   }
 
-  /* Charset */
-  if (plan.subset_charset)
+  /* global subrs */
   {
-    assert (plan.offsets.charsetInfo.offset == (unsigned) (c.head - c.start));
-    Charset *dest = c.start_embed<Charset> ();
-    if (unlikely (dest == nullptr)) return false;
-    if (unlikely (!dest->serialize (&c,
-				    plan.subset_charset_format,
-				    plan.num_glyphs,
-				    plan.subset_charset_ranges)))
+    c->push ();
+    CFF1Subrs *dest = c->start_embed <CFF1Subrs> ();
+    if (unlikely (!dest)) return false;
+    if (likely (dest->serialize (c, plan.subset_globalsubrs)))
+      c->pop_pack ();
+    else
     {
-      DEBUG_MSG (SUBSET, nullptr, "failed to serialize Charset");
+      c->pop_discard ();
       return false;
     }
   }
 
-  /* FDSelect */
-  if (acc.fdSelect != &Null(CFF1FDSelect))
+  /* String INDEX */
   {
-    assert (plan.offsets.FDSelectInfo.offset == (unsigned) (c.head - c.start));
-
-    if (unlikely (!hb_serialize_cff_fdselect (&c, num_glyphs, *acc.fdSelect, acc.fdCount,
-					      plan.subset_fdselect_format, plan.offsets.FDSelectInfo.size,
-					      plan.subset_fdselect_ranges)))
+    CFF1StringIndex *dest = c->start_embed<CFF1StringIndex> ();
+    if (unlikely (!dest)) return false;
+    c->push ();
+    if (likely (dest->serialize (c, *acc.stringIndex, plan.sidmap)))
+      c->pop_pack ();
+    else
     {
-      DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF subset FDSelect");
+      c->pop_discard ();
       return false;
     }
   }
 
-  /* FDArray (FD Index) */
-  if (acc.fdArray != &Null(CFF1FDArray))
+  OT::cff1 *cff = c->allocate_min<OT::cff1> ();
+  if (unlikely (!cff))
+    return false;
+
+  /* header */
+  cff->version.major = 0x01;
+  cff->version.minor = 0x00;
+  cff->nameIndex = cff->min_size;
+  cff->offSize = 4; /* unused? */
+
+  /* name INDEX */
+  if (unlikely (!(*acc.nameIndex).copy (c))) return false;
+
+  /* top dict INDEX */
   {
-    assert (plan.offsets.FDArrayInfo.offset == (unsigned) (c.head - c.start));
-    CFF1FDArray  *fda = c.start_embed<CFF1FDArray> ();
-    if (unlikely (fda == nullptr)) return false;
-    cff1_font_dict_op_serializer_t  fontSzr;
-    if (unlikely (!fda->serialize (&c, plan.offsets.FDArrayInfo.offSize,
-				   plan.fontdicts_mod,
-				   fontSzr)))
+    /* serialize singleton TopDict */
+    TopDict *top = c->start_embed<TopDict> ();
+    if (!top) return false;
+    c->push ();
+    cff1_top_dict_op_serializer_t topSzr;
+    unsigned top_size = 0;
+    top_dict_modifiers_t  modifier (plan.info, plan.topDictModSIDs);
+    if (likely (top->serialize (c, plan.topdict_mod, topSzr, modifier)))
     {
-      DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF FDArray");
-      return false;
+      top_size = c->length ();
+      c->pop_pack (false);
     }
-  }
-
-  /* CharStrings */
-  {
-    assert (plan.offsets.charStringsInfo.offset == (unsigned) (c.head - c.start));
-    CFF1CharStrings  *cs = c.start_embed<CFF1CharStrings> ();
-    if (unlikely (cs == nullptr)) return false;
-    if (unlikely (!cs->serialize (&c, plan.offsets.charStringsInfo.offSize, plan.subset_charstrings)))
+    else
     {
-      DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF CharStrings");
+      c->pop_discard ();
       return false;
     }
+    /* serialize INDEX header for above */
+    CFF1Index *dest = c->start_embed<CFF1Index> ();
+    if (!dest) return false;
+    return dest->serialize_header (c, hb_iter (hb_array_t<unsigned> (&top_size, 1)));
   }
-
-  /* private dicts & local subrs */
-  assert (plan.offsets.privateDictInfo.offset == (unsigned) (c.head - c.start));
-  for (unsigned int i = 0; i < acc.privateDicts.length; i++)
-  {
-    if (plan.fdmap.has (i))
-    {
-      PrivateDict  *pd = c.start_embed<PrivateDict> ();
-      if (unlikely (pd == nullptr)) return false;
-      unsigned int priv_size = plan.fontdicts_mod[plan.fdmap[i]].privateDictInfo.size;
-      bool result;
-      cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
-      /* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
-      unsigned int subroffset = (plan.offsets.localSubrsInfos[i].size > 0) ? priv_size : 0;
-      result = pd->serialize (&c, acc.privateDicts[i], privSzr, subroffset);
-      if (unlikely (!result))
-      {
-	DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF Private Dict[%d]", i);
-	return false;
-      }
-      if (plan.offsets.localSubrsInfos[i].size > 0)
-      {
-	CFF1Subrs *dest = c.start_embed <CFF1Subrs> ();
-	if (unlikely (dest == nullptr)) return false;
-	if (unlikely (!dest->serialize (&c, plan.offsets.localSubrsInfos[i].offSize, plan.subset_localsubrs[i])))
-	{
-	  DEBUG_MSG (SUBSET, nullptr, "failed to serialize local subroutines");
-	  return false;
-	}
-      }
-    }
-  }
-
-  assert (c.head == c.end);
-  c.end_serialize ();
-
-  return true;
 }
 
-static inline bool
+static bool
 _hb_subset_cff1 (const OT::cff1::accelerator_subset_t  &acc,
-		const char		*data,
-		hb_subset_plan_t	*plan,
-		hb_blob_t		**prime /* OUT */)
+		hb_subset_context_t	*c)
 {
   cff_subset_plan cff_plan;
 
-  if (unlikely (!cff_plan.create (acc, plan)))
+  if (unlikely (!cff_plan.create (acc, c->plan)))
   {
     DEBUG_MSG(SUBSET, nullptr, "Failed to generate a cff subsetting plan.");
     return false;
   }
 
-  unsigned int  cff_prime_size = cff_plan.get_final_size ();
-  char *cff_prime_data = (char *) calloc (1, cff_prime_size);
-
-  if (unlikely (!_write_cff1 (cff_plan, acc, plan->num_output_glyphs (),
-			      cff_prime_size, cff_prime_data))) {
-    DEBUG_MSG(SUBSET, nullptr, "Failed to write a subset cff.");
-    free (cff_prime_data);
-    return false;
-  }
-
-  *prime = hb_blob_create (cff_prime_data,
-			   cff_prime_size,
-			   HB_MEMORY_MODE_READONLY,
-			   cff_prime_data,
-			   free);
-  return true;
+  return _serialize_cff1 (c->serializer, cff_plan, acc, c->plan->num_output_glyphs ());
 }
 
 /**
@@ -1107,17 +916,11 @@
  * Return value: subsetted cff table.
  **/
 bool
-hb_subset_cff1 (hb_subset_plan_t *plan,
-		hb_blob_t       **prime /* OUT */)
+hb_subset_cff1 (hb_subset_context_t *c)
 {
-  hb_blob_t *cff_blob = hb_sanitize_context_t().reference_table<CFF::cff1> (plan->source);
-  const char *data = hb_blob_get_data(cff_blob, nullptr);
-
   OT::cff1::accelerator_subset_t acc;
-  acc.init(plan->source);
-  bool result = likely (acc.is_valid ()) &&
-			_hb_subset_cff1 (acc, data, plan, prime);
-  hb_blob_destroy (cff_blob);
+  acc.init (c->plan->source);
+  bool result = likely (acc.is_valid ()) && _hb_subset_cff1 (acc, c);
   acc.fini ();
 
   return result;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff1.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -32,7 +32,6 @@
 #include "hb-subset-plan.hh"
 
 HB_INTERNAL bool
-hb_subset_cff1 (hb_subset_plan_t *plan,
-	       hb_blob_t	**cff_prime /* OUT */);
+hb_subset_cff1 (hb_subset_context_t *c);
 
 #endif /* HB_SUBSET_CFF1_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -38,14 +38,14 @@
 
 using namespace CFF;
 
-struct cff2_sub_table_offsets_t : cff_sub_table_offsets_t
+struct cff2_sub_table_info_t : cff_sub_table_info_t
 {
-  cff2_sub_table_offsets_t ()
-    : cff_sub_table_offsets_t (),
-      varStoreOffset (0)
+  cff2_sub_table_info_t ()
+    : cff_sub_table_info_t (),
+      var_store_link (0)
   {}
 
-  unsigned int  varStoreOffset;
+  objidx_t  var_store_link;
 };
 
 struct cff2_top_dict_op_serializer_t : cff_top_dict_op_serializer_t<>
@@ -52,7 +52,7 @@
 {
   bool serialize (hb_serialize_context_t *c,
 		  const op_str_t &opstr,
-		  const cff2_sub_table_offsets_t &offsets) const
+		  const cff2_sub_table_info_t &info) const
   {
     TRACE_SERIALIZE (this);
 
@@ -59,24 +59,12 @@
     switch (opstr.op)
     {
       case OpCode_vstore:
-	return_trace (FontDict::serialize_offset4_op(c, opstr.op, offsets.varStoreOffset));
+	return_trace (FontDict::serialize_link4_op(c, opstr.op, info.var_store_link));
 
       default:
-	return_trace (cff_top_dict_op_serializer_t<>::serialize (c, opstr, offsets));
+	return_trace (cff_top_dict_op_serializer_t<>::serialize (c, opstr, info));
     }
   }
-
-  unsigned int calculate_serialized_size (const op_str_t &opstr) const
-  {
-    switch (opstr.op)
-    {
-      case OpCode_vstore:
-	return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (opstr.op);
-
-      default:
-	return cff_top_dict_op_serializer_t<>::calculate_serialized_size (opstr);
-    }
-  }
 };
 
 struct cff2_cs_opset_flatten_t : cff2_cs_opset_t<cff2_cs_opset_flatten_t, flatten_param_t>
@@ -116,8 +104,8 @@
       const blend_arg_t &arg = env.argStack[i];
       if (arg.blending ())
       {
-      	if (unlikely (!((arg.numValues > 0) && (env.argStack.get_count () >= arg.numValues))))
-      	{
+	if (unlikely (!((arg.numValues > 0) && (env.argStack.get_count () >= arg.numValues))))
+	{
 	  env.set_error ();
 	  return;
 	}
@@ -144,8 +132,8 @@
       if (unlikely (!((arg1.blending () && (arg.numValues == arg1.numValues) && (arg1.valueIndex == j) &&
 	      (arg1.deltas.length == env.get_region_count ())))))
       {
-      	env.set_error ();
-      	return;
+	env.set_error ();
+	return;
       }
       encoder.encode_num (arg1);
     }
@@ -232,7 +220,7 @@
   cff2_subr_subsetter_t (const OT::cff2::accelerator_subset_t &acc_, const hb_subset_plan_t *plan_)
     : subr_subsetter_t (acc_, plan_) {}
 
-  static void finalize_parsed_str (cff2_cs_interp_env_t &env, subr_subset_param_t& param, parsed_cs_str_t &charstring)
+  static void complete_parsed_str (cff2_cs_interp_env_t &env, subr_subset_param_t& param, parsed_cs_str_t &charstring)
   {
     /* vsindex is inserted at the beginning of the charstring as necessary */
     if (env.seen_vsindex ())
@@ -246,9 +234,9 @@
 
 struct cff2_subset_plan {
   cff2_subset_plan ()
-    : final_size (0),
-      orig_fdcount (0),
+    : orig_fdcount (0),
       subset_fdcount(1),
+      subset_fdselect_size (0),
       subset_fdselect_format (0),
       drop_hints (false),
       desubroutinize (false)
@@ -258,7 +246,6 @@
     subset_charstrings.init ();
     subset_globalsubrs.init ();
     subset_localsubrs.init ();
-    privateDictInfos.init ();
   }
 
   ~cff2_subset_plan ()
@@ -268,28 +255,16 @@
     subset_charstrings.fini_deep ();
     subset_globalsubrs.fini_deep ();
     subset_localsubrs.fini_deep ();
-    privateDictInfos.fini ();
   }
 
   bool create (const OT::cff2::accelerator_subset_t &acc,
 	      hb_subset_plan_t *plan)
   {
-    final_size = 0;
     orig_fdcount = acc.fdArray->count;
 
     drop_hints = plan->drop_hints;
     desubroutinize = plan->desubroutinize;
 
-    /* CFF2 header */
-    final_size += OT::cff2::static_size;
-
-    /* top dict */
-    {
-      cff2_top_dict_op_serializer_t topSzr;
-      offsets.topDictInfo.size = TopDict::calculate_serialized_size (acc.topDict, topSzr);
-      final_size += offsets.topDictInfo.size;
-    }
-
     if (desubroutinize)
     {
       /* Flatten global & local subrs */
@@ -297,9 +272,6 @@
 		    flattener(acc, plan);
       if (!flattener.flatten (subset_charstrings))
 	return false;
-
-      /* no global/local subroutines */
-      offsets.globalSubrsInfo.size = CFF2Subrs::calculate_serialized_size (1, 0, 0);
     }
     else
     {
@@ -316,115 +288,41 @@
       if (!subr_subsetter.encode_globalsubrs (subset_globalsubrs))
 	return false;
 
-      /* global subrs */
-      unsigned int dataSize = subset_globalsubrs.total_size ();
-      offsets.globalSubrsInfo.offSize = calcOffSize (dataSize);
-      offsets.globalSubrsInfo.size = CFF2Subrs::calculate_serialized_size (offsets.globalSubrsInfo.offSize, subset_globalsubrs.length, dataSize);
-
       /* local subrs */
-      if (!offsets.localSubrsInfos.resize (orig_fdcount))
-	return false;
       if (!subset_localsubrs.resize (orig_fdcount))
 	return false;
       for (unsigned int fd = 0; fd < orig_fdcount; fd++)
       {
 	subset_localsubrs[fd].init ();
-	offsets.localSubrsInfos[fd].init ();
 	if (!subr_subsetter.encode_localsubrs (fd, subset_localsubrs[fd]))
 	  return false;
-
-	unsigned int dataSize = subset_localsubrs[fd].total_size ();
-	if (dataSize > 0)
-	{
-	  offsets.localSubrsInfos[fd].offset = final_size;
-	  offsets.localSubrsInfos[fd].offSize = calcOffSize (dataSize);
-	  offsets.localSubrsInfos[fd].size = CFF2Subrs::calculate_serialized_size (offsets.localSubrsInfos[fd].offSize, subset_localsubrs[fd].length, dataSize);
-	}
       }
     }
 
-    /* global subrs */
-    offsets.globalSubrsInfo.offset = final_size;
-    final_size += offsets.globalSubrsInfo.size;
-
-    /* variation store */
-    if (acc.varStore != &Null(CFF2VariationStore))
-    {
-      offsets.varStoreOffset = final_size;
-      final_size += acc.varStore->get_size ();
-    }
-
     /* FDSelect */
-    if (acc.fdSelect != &Null(CFF2FDSelect))
+    if (acc.fdSelect != &Null (CFF2FDSelect))
     {
-      offsets.FDSelectInfo.offset = final_size;
       if (unlikely (!hb_plan_subset_cff_fdselect (plan,
 				  orig_fdcount,
 				  *(const FDSelect *)acc.fdSelect,
 				  subset_fdcount,
-				  offsets.FDSelectInfo.size,
+				  subset_fdselect_size,
 				  subset_fdselect_format,
 				  subset_fdselect_ranges,
 				  fdmap)))
 	return false;
-
-      final_size += offsets.FDSelectInfo.size;
     }
     else
       fdmap.identity (1);
 
-    /* FDArray (FDIndex) */
-    {
-      offsets.FDArrayInfo.offset = final_size;
-      cff_font_dict_op_serializer_t fontSzr;
-      unsigned int dictsSize = 0;
-      for (unsigned int i = 0; i < acc.fontDicts.length; i++)
-	if (fdmap.has (i))
-	  dictsSize += FontDict::calculate_serialized_size (acc.fontDicts[i], fontSzr);
-
-      offsets.FDArrayInfo.offSize = calcOffSize (dictsSize);
-      final_size += CFF2Index::calculate_serialized_size (offsets.FDArrayInfo.offSize, subset_fdcount, dictsSize);
-    }
-
-    /* CharStrings */
-    {
-      offsets.charStringsInfo.offset = final_size;
-      unsigned int dataSize = subset_charstrings.total_size ();
-      offsets.charStringsInfo.offSize = calcOffSize (dataSize);
-      final_size += CFF2CharStrings::calculate_serialized_size (offsets.charStringsInfo.offSize, plan->num_output_glyphs (), dataSize);
-    }
-
-    /* private dicts & local subrs */
-    offsets.privateDictsOffset = final_size;
-    for (unsigned int i = 0; i < orig_fdcount; i++)
-    {
-      if (fdmap.has (i))
-      {
-	bool  has_localsubrs = offsets.localSubrsInfos[i].size > 0;
-	cff_private_dict_op_serializer_t privSzr (desubroutinize, drop_hints);
-	unsigned int  priv_size = PrivateDict::calculate_serialized_size (acc.privateDicts[i], privSzr, has_localsubrs);
-	table_info_t  privInfo = { final_size, priv_size, 0 };
-	privateDictInfos.push (privInfo);
-	final_size += privInfo.size;
-
-	if (!plan->desubroutinize && has_localsubrs)
-	{
-	  offsets.localSubrsInfos[i].offset = final_size;
-	  final_size += offsets.localSubrsInfos[i].size;
-	}
-      }
-    }
-
     return true;
   }
 
-  unsigned int get_final_size () const  { return final_size; }
+  cff2_sub_table_info_t info;
 
-  unsigned int	final_size;
-  cff2_sub_table_offsets_t offsets;
-
   unsigned int    orig_fdcount;
   unsigned int    subset_fdcount;
+  unsigned int	  subset_fdselect_size;
   unsigned int    subset_fdselect_format;
   hb_vector_t<code_pair_t>   subset_fdselect_ranges;
 
@@ -433,76 +331,82 @@
   str_buff_vec_t	    subset_charstrings;
   str_buff_vec_t	    subset_globalsubrs;
   hb_vector_t<str_buff_vec_t> subset_localsubrs;
-  hb_vector_t<table_info_t>  privateDictInfos;
 
   bool	    drop_hints;
   bool	    desubroutinize;
 };
 
-static inline bool _write_cff2 (const cff2_subset_plan &plan,
-				const OT::cff2::accelerator_subset_t  &acc,
-				unsigned int num_glyphs,
-				unsigned int dest_sz,
-				void *dest)
+static bool _serialize_cff2 (hb_serialize_context_t *c,
+			     cff2_subset_plan &plan,
+			     const OT::cff2::accelerator_subset_t  &acc,
+			     unsigned int num_glyphs)
 {
-  hb_serialize_context_t c (dest, dest_sz);
+  /* private dicts & local subrs */
+  hb_vector_t<table_info_t>  private_dict_infos;
+  if (unlikely (!private_dict_infos.resize (plan.subset_fdcount))) return false;
 
-  OT::cff2 *cff2 = c.start_serialize<OT::cff2> ();
-  if (unlikely (!c.extend_min (*cff2)))
-    return false;
-
-  /* header */
-  cff2->version.major = 0x02;
-  cff2->version.minor = 0x00;
-  cff2->topDict = OT::cff2::static_size;
-
-  /* top dict */
+  for (int i = (int)acc.privateDicts.length; --i >= 0 ;)
   {
-    assert (cff2->topDict == (unsigned) (c.head - c.start));
-    cff2->topDictSize = plan.offsets.topDictInfo.size;
-    TopDict &dict = cff2 + cff2->topDict;
-    cff2_top_dict_op_serializer_t topSzr;
-    if (unlikely (!dict.serialize (&c, acc.topDict, topSzr, plan.offsets)))
+    if (plan.fdmap.has (i))
     {
-      DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF2 top dict");
-      return false;
-    }
-  }
+      objidx_t	subrs_link = 0;
 
-  /* global subrs */
-  {
-    assert (cff2->topDict + plan.offsets.topDictInfo.size == (unsigned) (c.head - c.start));
-    CFF2Subrs *dest = c.start_embed <CFF2Subrs> ();
-    if (unlikely (dest == nullptr)) return false;
-    if (unlikely (!dest->serialize (&c, plan.offsets.globalSubrsInfo.offSize, plan.subset_globalsubrs)))
-    {
-      DEBUG_MSG (SUBSET, nullptr, "failed to serialize global subroutines");
-      return false;
+      if (plan.subset_localsubrs[i].length > 0)
+      {
+	CFF2Subrs *dest = c->start_embed <CFF2Subrs> ();
+	if (unlikely (!dest)) return false;
+	c->push ();
+	if (likely (dest->serialize (c, plan.subset_localsubrs[i])))
+	  subrs_link = c->pop_pack ();
+	else
+	{
+	  c->pop_discard ();
+	  return false;
+	}
+      }
+      PrivateDict *pd = c->start_embed<PrivateDict> ();
+      if (unlikely (!pd)) return false;
+      c->push ();
+      cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
+      if (likely (pd->serialize (c, acc.privateDicts[i], privSzr, subrs_link)))
+      {
+	unsigned fd = plan.fdmap[i];
+	private_dict_infos[fd].size = c->length ();
+	private_dict_infos[fd].link = c->pop_pack ();
+      }
+      else
+      {
+	c->pop_discard ();
+	return false;
+      }
     }
   }
 
-  /* variation store */
-  if (acc.varStore != &Null(CFF2VariationStore))
+  /* CharStrings */
   {
-    assert (plan.offsets.varStoreOffset == (unsigned) (c.head - c.start));
-    CFF2VariationStore *dest = c.start_embed<CFF2VariationStore> ();
-    if (unlikely (!dest->serialize (&c, acc.varStore)))
+    CFF2CharStrings  *cs = c->start_embed<CFF2CharStrings> ();
+    if (unlikely (!cs)) return false;
+    c->push ();
+    if (likely (cs->serialize (c, plan.subset_charstrings)))
+      plan.info.char_strings_link = c->pop_pack ();
+    else
     {
-      DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF2 Variation Store");
+      c->pop_discard ();
       return false;
     }
   }
 
   /* FDSelect */
-  if (acc.fdSelect != &Null(CFF2FDSelect))
+  if (acc.fdSelect != &Null (CFF2FDSelect))
   {
-    assert (plan.offsets.FDSelectInfo.offset == (unsigned) (c.head - c.start));
-
-    if (unlikely (!hb_serialize_cff_fdselect (&c, num_glyphs, *(const FDSelect *)acc.fdSelect, acc.fdArray->count,
-					      plan.subset_fdselect_format, plan.offsets.FDSelectInfo.size,
-					      plan.subset_fdselect_ranges)))
+    c->push ();
+    if (likely (hb_serialize_cff_fdselect (c, num_glyphs, *(const FDSelect *)acc.fdSelect, 					      plan.orig_fdcount,
+					    plan.subset_fdselect_format, plan.subset_fdselect_size,
+					    plan.subset_fdselect_ranges)))
+      plan.info.fd_select.link = c->pop_pack ();
+    else
     {
-      DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF2 subset FDSelect");
+      c->pop_discard ();
       return false;
     }
   }
@@ -509,124 +413,76 @@
 
   /* FDArray (FD Index) */
   {
-    assert (plan.offsets.FDArrayInfo.offset == (unsigned) (c.head - c.start));
-    CFF2FDArray  *fda = c.start_embed<CFF2FDArray> ();
-    if (unlikely (fda == nullptr)) return false;
-    cff_font_dict_op_serializer_t  fontSzr;
-    if (unlikely (!fda->serialize (&c, plan.offsets.FDArrayInfo.offSize,
-				   acc.fontDicts, plan.subset_fdcount, plan.fdmap,
-				   fontSzr, plan.privateDictInfos)))
-    {
-      DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF2 FDArray");
-      return false;
-    }
+    c->push ();
+    CFF2FDArray *fda = c->start_embed<CFF2FDArray> ();
+    if (unlikely (!fda)) return false;
+    cff_font_dict_op_serializer_t fontSzr;
+    auto it =
+    + hb_zip (+ hb_iter (acc.fontDicts)
+	      | hb_filter ([&] (const cff2_font_dict_values_t &_)
+		{ return plan.fdmap.has (&_ - &acc.fontDicts[0]); }),
+	      hb_iter (private_dict_infos))
+    ;
+    if (unlikely (!fda->serialize (c, it, fontSzr))) return false;
+    plan.info.fd_array_link = c->pop_pack ();
   }
 
-  /* CharStrings */
+  /* variation store */
+  if (acc.varStore != &Null (CFF2VariationStore))
   {
-    assert (plan.offsets.charStringsInfo.offset == (unsigned) (c.head - c.start));
-    CFF2CharStrings  *cs = c.start_embed<CFF2CharStrings> ();
-    if (unlikely (cs == nullptr)) return false;
-    if (unlikely (!cs->serialize (&c, plan.offsets.charStringsInfo.offSize, plan.subset_charstrings)))
-    {
-      DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF2 CharStrings");
-      return false;
-    }
+    c->push ();
+    CFF2VariationStore *dest = c->start_embed<CFF2VariationStore> ();
+    if (unlikely (!dest || !dest->serialize (c, acc.varStore))) return false;
+    plan.info.var_store_link = c->pop_pack ();
   }
 
-  /* private dicts & local subrs */
-  assert (plan.offsets.privateDictsOffset == (unsigned) (c.head - c.start));
-  for (unsigned int i = 0; i < acc.privateDicts.length; i++)
+  OT::cff2 *cff2 = c->allocate_min<OT::cff2> ();
+  if (unlikely (!cff2)) return false;
+
+  /* header */
+  cff2->version.major = 0x02;
+  cff2->version.minor = 0x00;
+  cff2->topDict = OT::cff2::static_size;
+
+  /* top dict */
   {
-    if (plan.fdmap.has (i))
-    {
-      PrivateDict  *pd = c.start_embed<PrivateDict> ();
-      if (unlikely (pd == nullptr)) return false;
-      unsigned int priv_size = plan.privateDictInfos[plan.fdmap[i]].size;
-      bool result;
-      cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
-      /* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
-      unsigned int subroffset = (plan.offsets.localSubrsInfos[i].size > 0) ? priv_size : 0;
-      result = pd->serialize (&c, acc.privateDicts[i], privSzr, subroffset);
-      if (unlikely (!result))
-      {
-	DEBUG_MSG (SUBSET, nullptr, "failed to serialize CFF Private Dict[%d]", i);
-	return false;
-      }
-      if (plan.offsets.localSubrsInfos[i].size > 0)
-      {
-	CFF2Subrs *dest = c.start_embed <CFF2Subrs> ();
-	if (unlikely (dest == nullptr)) return false;
-	if (unlikely (!dest->serialize (&c, plan.offsets.localSubrsInfos[i].offSize, plan.subset_localsubrs[i])))
-	{
-	  DEBUG_MSG (SUBSET, nullptr, "failed to serialize local subroutines");
-	  return false;
-	}
-      }
-    }
+    TopDict &dict = cff2 + cff2->topDict;
+    cff2_top_dict_op_serializer_t topSzr;
+    if (unlikely (!dict.serialize (c, acc.topDict, topSzr, plan.info))) return false;
+    cff2->topDictSize = c->head - (const char *)&dict;
   }
 
-  assert (c.head == c.end);
-  c.end_serialize ();
-
-  return true;
+  /* global subrs */
+  {
+    CFF2Subrs *dest = c->start_embed <CFF2Subrs> ();
+    if (unlikely (!dest)) return false;
+    return dest->serialize (c, plan.subset_globalsubrs);
+  }
 }
 
-static inline bool
+static bool
 _hb_subset_cff2 (const OT::cff2::accelerator_subset_t  &acc,
-		const char		      *data,
-		hb_subset_plan_t		*plan,
-		hb_blob_t		       **prime /* OUT */)
+		 hb_subset_context_t	*c)
 {
   cff2_subset_plan cff2_plan;
 
-  if (unlikely (!cff2_plan.create (acc, plan)))
-  {
-    DEBUG_MSG(SUBSET, nullptr, "Failed to generate a cff2 subsetting plan.");
-    return false;
-  }
-
-  unsigned int  cff2_prime_size = cff2_plan.get_final_size ();
-  char *cff2_prime_data = (char *) calloc (1, cff2_prime_size);
-
-  if (unlikely (!_write_cff2 (cff2_plan, acc, plan->num_output_glyphs (),
-			      cff2_prime_size, cff2_prime_data))) {
-    DEBUG_MSG(SUBSET, nullptr, "Failed to write a subset cff2.");
-    free (cff2_prime_data);
-    return false;
-  }
-
-  *prime = hb_blob_create (cff2_prime_data,
-			   cff2_prime_size,
-			   HB_MEMORY_MODE_READONLY,
-			   cff2_prime_data,
-			   free);
-  return true;
+  if (unlikely (!cff2_plan.create (acc, c->plan))) return false;
+  return _serialize_cff2 (c->serializer, cff2_plan, acc, c->plan->num_output_glyphs ());
 }
 
 /**
  * hb_subset_cff2:
- * Subsets the CFF2 table according to a provided plan.
- *
- * Return value: subsetted cff2 table.
+ * Subsets the CFF2 table according to a provided subset context.
  **/
 bool
-hb_subset_cff2 (hb_subset_plan_t *plan,
-		hb_blob_t       **prime /* OUT */)
+hb_subset_cff2 (hb_subset_context_t *c)
 {
-  hb_blob_t *cff2_blob = hb_sanitize_context_t().reference_table<CFF::cff2> (plan->source);
-  const char *data = hb_blob_get_data(cff2_blob, nullptr);
-
   OT::cff2::accelerator_subset_t acc;
-  acc.init(plan->source);
-  bool result = likely (acc.is_valid ()) &&
-		_hb_subset_cff2 (acc, data, plan, prime);
-
-  hb_blob_destroy (cff2_blob);
+  acc.init (c->plan->source);
+  bool result = likely (acc.is_valid ()) && _hb_subset_cff2 (acc, c);
   acc.fini ();
 
   return result;
 }
 
-
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -32,7 +32,6 @@
 #include "hb-subset-plan.hh"
 
 HB_INTERNAL bool
-hb_subset_cff2 (hb_subset_plan_t *plan,
-	       hb_blob_t       **cff2_prime /* OUT */);
+hb_subset_cff2 (hb_subset_context_t *c);
 
 #endif /* HB_SUBSET_CFF2_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -46,10 +46,13 @@
   input->glyphs = hb_set_create ();
   input->name_ids = hb_set_create ();
   hb_set_add_range (input->name_ids, 0, 6);
+  input->name_languages = hb_set_create ();
+  hb_set_add (input->name_languages, 0x0409);
   input->drop_tables = hb_set_create ();
   input->drop_hints = false;
   input->desubroutinize = false;
   input->retain_gids = false;
+  input->name_legacy = false;
 
   hb_tag_t default_drop_tables[] = {
     // Layout disabled by default
@@ -77,8 +80,6 @@
     HB_TAG ('G', 'l', 'o', 'c'),
     HB_TAG ('S', 'i', 'l', 'f'),
     HB_TAG ('S', 'i', 'l', 'l'),
-    // Colour
-    HB_TAG ('s', 'b', 'i', 'x')
   };
 
   input->drop_tables->add_array (default_drop_tables, ARRAY_LENGTH (default_drop_tables));
@@ -116,6 +117,7 @@
   hb_set_destroy (subset_input->unicodes);
   hb_set_destroy (subset_input->glyphs);
   hb_set_destroy (subset_input->name_ids);
+  hb_set_destroy (subset_input->name_languages);
   hb_set_destroy (subset_input->drop_tables);
 
   free (subset_input);
@@ -152,6 +154,12 @@
 }
 
 HB_EXTERN hb_set_t *
+hb_subset_input_namelangid_set (hb_subset_input_t *subset_input)
+{
+  return subset_input->name_languages;
+}
+
+HB_EXTERN hb_set_t *
 hb_subset_input_drop_tables_set (hb_subset_input_t *subset_input)
 {
   return subset_input->drop_tables;
@@ -206,3 +214,16 @@
 {
   return subset_input->retain_gids;
 }
+
+HB_EXTERN void
+hb_subset_input_set_name_legacy (hb_subset_input_t *subset_input,
+				 hb_bool_t name_legacy)
+{
+  subset_input->name_legacy = name_legacy;
+}
+
+HB_EXTERN hb_bool_t
+hb_subset_input_get_name_legacy (hb_subset_input_t *subset_input)
+{
+  return subset_input->name_legacy;
+}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -41,11 +41,13 @@
   hb_set_t *unicodes;
   hb_set_t *glyphs;
   hb_set_t *name_ids;
+  hb_set_t *name_languages;
   hb_set_t *drop_tables;
 
   bool drop_hints;
   bool desubroutinize;
   bool retain_gids;
+  bool name_legacy;
   /* TODO
    *
    * features

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	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -31,6 +31,7 @@
 #include "hb-ot-cmap-table.hh"
 #include "hb-ot-glyf-table.hh"
 #include "hb-ot-cff1-table.hh"
+#include "hb-ot-color-colr-table.hh"
 #include "hb-ot-var-fvar-table.hh"
 #include "hb-ot-stat-table.hh"
 
@@ -50,8 +51,24 @@
 #endif
 
 #ifndef HB_NO_SUBSET_LAYOUT
+#ifdef HB_EXPERIMENTAL_API
+static void
+_remap_indexes (const hb_set_t *indexes,
+		hb_map_t       *mapping /* OUT */)
+{
+  unsigned count = indexes->get_population ();
+
+  for (auto _ : + hb_zip (indexes->iter (), hb_range (count)))
+    mapping->set (_.first, _.second);
+
+}
+#endif
+
 static inline void
-_gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain)
+_gsub_closure_glyphs_lookups_features (hb_face_t *face,
+				       hb_set_t *gids_to_retain,
+				       hb_map_t *gsub_lookups,
+				       hb_map_t *gsub_features)
 {
   hb_set_t lookup_indices;
   hb_ot_layout_collect_lookups (face,
@@ -63,8 +80,53 @@
   hb_ot_layout_lookups_substitute_closure (face,
 					   &lookup_indices,
 					   gids_to_retain);
+#ifdef HB_EXPERIMENTAL_API
+  hb_ot_layout_closure_lookups (face,
+				HB_OT_TAG_GSUB,
+				gids_to_retain,
+				&lookup_indices);
+  _remap_indexes (&lookup_indices, gsub_lookups);
+
+  //closure features
+  hb_set_t feature_indices;
+  hb_ot_layout_closure_features (face,
+				 HB_OT_TAG_GSUB,
+				 gsub_lookups,
+				 &feature_indices);
+  _remap_indexes (&feature_indices, gsub_features);
+#endif
 }
+
+static inline void
+_gpos_closure_lookups_features (hb_face_t      *face,
+				const hb_set_t *gids_to_retain,
+				hb_map_t       *gpos_lookups,
+				hb_map_t       *gpos_features)
+{
+  hb_set_t lookup_indices;
+  hb_ot_layout_collect_lookups (face,
+				HB_OT_TAG_GPOS,
+				nullptr,
+				nullptr,
+				nullptr,
+				&lookup_indices);
+#ifdef HB_EXPERIMENTAL_API
+  hb_ot_layout_closure_lookups (face,
+				HB_OT_TAG_GPOS,
+				gids_to_retain,
+				&lookup_indices);
+  _remap_indexes (&lookup_indices, gpos_lookups);
+
+  //closure features
+  hb_set_t feature_indices;
+  hb_ot_layout_closure_features (face,
+				 HB_OT_TAG_GPOS,
+				 gpos_lookups,
+				 &feature_indices);
+  _remap_indexes (&feature_indices, gpos_features);
 #endif
+}
+#endif
 
 static inline void
 _cmap_closure (hb_face_t           *face,
@@ -93,14 +155,21 @@
 _populate_gids_to_retain (hb_subset_plan_t* plan,
 			  const hb_set_t *unicodes,
 			  const hb_set_t *input_glyphs_to_retain,
-			  bool close_over_gsub)
+			  bool close_over_gsub,
+			  bool close_over_gpos)
 {
   OT::cmap::accelerator_t cmap;
   OT::glyf::accelerator_t glyf;
+#ifndef HB_NO_SUBSET_CFF
   OT::cff1::accelerator_t cff;
+#endif
+  OT::COLR::accelerator_t colr;
   cmap.init (plan->source);
   glyf.init (plan->source);
+#ifndef HB_NO_SUBSET_CFF
   cff.init (plan->source);
+#endif
+  colr.init (plan->source);
 
   plan->_glyphset_gsub->add (0); // Not-def
   hb_set_union (plan->_glyphset_gsub, input_glyphs_to_retain);
@@ -123,8 +192,11 @@
 
 #ifndef HB_NO_SUBSET_LAYOUT
   if (close_over_gsub)
-    // Add all glyphs needed for GSUB substitutions.
-    _gsub_closure (plan->source, plan->_glyphset_gsub);
+    // closure all glyphs/lookups/features needed for GSUB substitutions.
+    _gsub_closure_glyphs_lookups_features (plan->source, plan->_glyphset_gsub, plan->gsub_lookups, plan->gsub_features);
+
+  if (close_over_gpos)
+    _gpos_closure_lookups_features (plan->source, plan->_glyphset_gsub, plan->gpos_lookups, plan->gpos_features);
 #endif
   _remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ());
 
@@ -138,11 +210,15 @@
     if (cff.is_valid ())
       _add_cff_seac_components (cff, gid, plan->_glyphset);
 #endif
+    if (colr.is_valid ())
+      colr.closure_glyphs (gid, plan->_glyphset);
   }
 
   _remove_invalid_gids (plan->_glyphset, plan->source->get_num_glyphs ());
 
+#ifndef HB_NO_SUBSET_CFF
   cff.fini ();
+#endif
   glyf.fini ();
   cmap.fini ();
 }
@@ -213,9 +289,11 @@
   plan->drop_hints = input->drop_hints;
   plan->desubroutinize = input->desubroutinize;
   plan->retain_gids = input->retain_gids;
+  plan->name_legacy = input->name_legacy;
   plan->unicodes = hb_set_create ();
   plan->name_ids = hb_set_reference (input->name_ids);
   _nameid_closure (face, plan->name_ids);
+  plan->name_languages = hb_set_reference (input->name_languages);
   plan->drop_tables = hb_set_reference (input->drop_tables);
   plan->source = hb_face_reference (face);
   plan->dest = hb_face_builder_create ();
@@ -225,11 +303,16 @@
   plan->codepoint_to_glyph = hb_map_create ();
   plan->glyph_map = hb_map_create ();
   plan->reverse_glyph_map = hb_map_create ();
+  plan->gsub_lookups = hb_map_create ();
+  plan->gpos_lookups = hb_map_create ();
+  plan->gsub_features = hb_map_create ();
+  plan->gpos_features = hb_map_create ();
 
   _populate_gids_to_retain (plan,
 			    input->unicodes,
 			    input->glyphs,
-			    !input->drop_tables->has (HB_OT_TAG_GSUB));
+			    !input->drop_tables->has (HB_OT_TAG_GSUB),
+			    !input->drop_tables->has (HB_OT_TAG_GPOS));
 
   _create_old_gid_to_new_gid_map (face,
 				  input->retain_gids,
@@ -253,6 +336,7 @@
 
   hb_set_destroy (plan->unicodes);
   hb_set_destroy (plan->name_ids);
+  hb_set_destroy (plan->name_languages);
   hb_set_destroy (plan->drop_tables);
   hb_face_destroy (plan->source);
   hb_face_destroy (plan->dest);
@@ -261,6 +345,11 @@
   hb_map_destroy (plan->reverse_glyph_map);
   hb_set_destroy (plan->_glyphset);
   hb_set_destroy (plan->_glyphset_gsub);
+  hb_map_destroy (plan->gsub_lookups);
+  hb_map_destroy (plan->gpos_lookups);
+  hb_map_destroy (plan->gsub_features);
+  hb_map_destroy (plan->gpos_features);
 
+
   free (plan);
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -42,6 +42,7 @@
   bool drop_hints : 1;
   bool desubroutinize : 1;
   bool retain_gids : 1;
+  bool name_legacy : 1;
 
   // For each cp that we'd like to retain maps to the corresponding gid.
   hb_set_t *unicodes;
@@ -49,6 +50,9 @@
   // name_ids we would like to retain
   hb_set_t *name_ids;
 
+  // name_languages we would like to retain
+  hb_set_t *name_languages;
+
   // Tables which should be dropped.
   hb_set_t *drop_tables;
 
@@ -67,6 +71,14 @@
   hb_set_t *_glyphset;
   hb_set_t *_glyphset_gsub;
 
+  //active lookups we'd like to retain
+  hb_map_t *gsub_lookups;
+  hb_map_t *gpos_lookups;
+
+  //active features we'd like to retain
+  hb_map_t *gsub_features;
+  hb_map_t *gpos_features;
+
  public:
 
   /*

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -37,6 +37,8 @@
 #include "hb-ot-hhea-table.hh"
 #include "hb-ot-hmtx-table.hh"
 #include "hb-ot-maxp-table.hh"
+#include "hb-ot-color-sbix-table.hh"
+#include "hb-ot-color-colr-table.hh"
 #include "hb-ot-os2-table.hh"
 #include "hb-ot-post-table.hh"
 #include "hb-ot-cff1-table.hh"
@@ -43,29 +45,28 @@
 #include "hb-ot-cff2-table.hh"
 #include "hb-ot-vorg-table.hh"
 #include "hb-ot-name-table.hh"
+#include "hb-ot-color-cbdt-table.hh"
 #include "hb-ot-layout-gsub-table.hh"
 #include "hb-ot-layout-gpos-table.hh"
+#include "hb-ot-var-gvar-table.hh"
+#include "hb-ot-var-hvar-table.hh"
 
 
-HB_UNUSED static inline unsigned int
-_plan_estimate_subset_table_size (hb_subset_plan_t *plan,
-				  unsigned int table_len);
-static inline unsigned int
-_plan_estimate_subset_table_size (hb_subset_plan_t *plan,
-				  unsigned int table_len)
+static unsigned
+_plan_estimate_subset_table_size (hb_subset_plan_t *plan, unsigned table_len)
 {
-  unsigned int src_glyphs = plan->source->get_num_glyphs ();
-  unsigned int dst_glyphs = plan->glyphset ()->get_population ();
+  unsigned src_glyphs = plan->source->get_num_glyphs ();
+  unsigned dst_glyphs = plan->glyphset ()->get_population ();
 
   if (unlikely (!src_glyphs))
     return 512 + table_len;
 
-  return 512 + (unsigned int) (table_len * sqrt ((double) dst_glyphs / src_glyphs));
+  return 512 + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs));
 }
 
 template<typename TableType>
 static bool
-_subset2 (hb_subset_plan_t *plan)
+_subset (hb_subset_plan_t *plan)
 {
   bool result = false;
   hb_blob_t *source_blob = hb_sanitize_context_t ().reference_table<TableType> (plan->source);
@@ -77,11 +78,11 @@
     hb_vector_t<char> buf;
     /* TODO Not all tables are glyph-related.  'name' table size for example should not be
      * affected by number of glyphs.  Accommodate that. */
-    unsigned int buf_size = _plan_estimate_subset_table_size (plan, source_blob->length);
-    DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size);
+    unsigned buf_size = _plan_estimate_subset_table_size (plan, source_blob->length);
+    DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size);
     if (unlikely (!buf.alloc (buf_size)))
     {
-      DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size);
+      DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size);
       hb_blob_destroy (source_blob);
       return false;
     }
@@ -88,15 +89,15 @@
   retry:
     hb_serialize_context_t serializer ((void *) buf, buf_size);
     serializer.start_serialize<TableType> ();
-    hb_subset_context_t c (plan, &serializer);
+    hb_subset_context_t c (source_blob, plan, &serializer);
     bool needed = table->subset (&c);
     if (serializer.ran_out_of_room)
     {
       buf_size += (buf_size >> 1) + 32;
-      DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG (tag), buf_size);
+      DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG (tag), buf_size);
       if (unlikely (!buf.alloc (buf_size)))
       {
-	DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG (tag), buf_size);
+	DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG (tag), buf_size);
 	hb_blob_destroy (source_blob);
 	return false;
       }
@@ -111,159 +112,119 @@
       if (needed)
       {
 	hb_blob_t *dest_blob = serializer.copy_blob ();
-	DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG (tag), dest_blob->length);
+	DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG (tag), dest_blob->length);
 	result = c.plan->add_table (tag, dest_blob);
 	hb_blob_destroy (dest_blob);
       }
       else
       {
-	DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag));
+	DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag));
       }
     }
   }
   else
-    DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag));
+    DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag));
 
   hb_blob_destroy (source_blob);
-  DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG (tag), result ? "success" : "FAILED!");
+  DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG (tag), result ? "success" : "FAILED!");
   return result;
 }
 
-template<typename TableType>
 static bool
-_subset (hb_subset_plan_t *plan)
+_is_table_present (hb_face_t *source, hb_tag_t tag)
 {
-  hb_blob_t *source_blob = hb_sanitize_context_t ().reference_table<TableType> (plan->source);
-  const TableType *table = source_blob->as<TableType> ();
-
-  hb_tag_t tag = TableType::tableTag;
-  hb_bool_t result = false;
-  if (source_blob->data)
-    result = table->subset (plan);
-  else
-    DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag));
-
-  hb_blob_destroy (source_blob);
-  DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG (tag), result ? "success" : "FAILED!");
-  return result;
+  hb_tag_t table_tags[32];
+  unsigned offset = 0, num_tables = ARRAY_LENGTH (table_tags);
+  while ((hb_face_get_table_tags (source, offset, &num_tables, table_tags), num_tables))
+  {
+    for (unsigned i = 0; i < num_tables; ++i)
+      if (table_tags[i] == tag)
+	return true;
+    offset += num_tables;
+  }
+  return false;
 }
 
-
 static bool
-_subset_table (hb_subset_plan_t *plan,
-	       hb_tag_t          tag)
+_should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag)
 {
-  DEBUG_MSG(SUBSET, nullptr, "begin subset %c%c%c%c", HB_UNTAG (tag));
-  bool result = true;
-  switch (tag) {
-    case HB_OT_TAG_glyf:
-      result = _subset2<const OT::glyf> (plan);
-      break;
-    case HB_OT_TAG_hdmx:
-      result = _subset2<const OT::hdmx> (plan);
-      break;
-    case HB_OT_TAG_name:
-      result = _subset2<const OT::name> (plan);
-      break;
-    case HB_OT_TAG_head:
-      // TODO that won't work well if there is no glyf
-      DEBUG_MSG(SUBSET, nullptr, "skip head, handled by glyf");
-      result = true;
-      break;
-    case HB_OT_TAG_hhea:
-      DEBUG_MSG(SUBSET, nullptr, "skip hhea handled by hmtx");
-      return true;
-    case HB_OT_TAG_hmtx:
-      result = _subset2<const OT::hmtx> (plan);
-      break;
-    case HB_OT_TAG_vhea:
-      DEBUG_MSG(SUBSET, nullptr, "skip vhea handled by vmtx");
-      return true;
-    case HB_OT_TAG_vmtx:
-      result = _subset2<const OT::vmtx> (plan);
-      break;
-    case HB_OT_TAG_maxp:
-      result = _subset2<const OT::maxp> (plan);
-      break;
-    case HB_OT_TAG_loca:
-      DEBUG_MSG(SUBSET, nullptr, "skip loca handled by glyf");
-      return true;
-    case HB_OT_TAG_cmap:
-      result = _subset2<const OT::cmap> (plan);
-      break;
-    case HB_OT_TAG_OS2:
-      result = _subset2<const OT::OS2> (plan);
-      break;
-    case HB_OT_TAG_post:
-      result = _subset2<const OT::post> (plan);
-      break;
+  if (plan->drop_tables->has (tag))
+    return true;
 
-#ifndef HB_NO_SUBSET_CFF
-    case HB_OT_TAG_cff1:
-      result = _subset<const OT::cff1> (plan);
-      break;
-    case HB_OT_TAG_cff2:
-      result = _subset<const OT::cff2> (plan);
-      break;
-    case HB_OT_TAG_VORG:
-      result = _subset2<const OT::VORG> (plan);
-      break;
-#endif
+  switch (tag)
+  {
+  case HB_TAG ('c','v','a','r'): /* hint table, fallthrough */
+  case HB_TAG ('c','v','t',' '): /* hint table, fallthrough */
+  case HB_TAG ('f','p','g','m'): /* hint table, fallthrough */
+  case HB_TAG ('p','r','e','p'): /* hint table, fallthrough */
+  case HB_TAG ('h','d','m','x'): /* hint table, fallthrough */
+  case HB_TAG ('V','D','M','X'): /* hint table, fallthrough */
+    return plan->drop_hints;
 
-#ifndef HB_NO_SUBSET_LAYOUT
-    case HB_OT_TAG_GDEF:
-      result = _subset2<const OT::GDEF> (plan);
-      break;
-    case HB_OT_TAG_GSUB:
-      result = _subset2<const OT::GSUB> (plan);
-      break;
-    case HB_OT_TAG_GPOS:
-      result = _subset2<const OT::GPOS> (plan);
-      break;
+#ifdef HB_NO_SUBSET_LAYOUT
+    // Drop Layout Tables if requested.
+  case HB_OT_TAG_GDEF:
+  case HB_OT_TAG_GPOS:
+  case HB_OT_TAG_GSUB:
+  case HB_TAG ('m','o','r','x'):
+  case HB_TAG ('m','o','r','t'):
+  case HB_TAG ('k','e','r','x'):
+  case HB_TAG ('k','e','r','n'):
+    return true;
 #endif
 
-    default:
-      hb_blob_t *source_table = hb_face_reference_table (plan->source, tag);
-      if (likely (source_table))
-	result = plan->add_table (tag, source_table);
-      else
-	result = false;
-      hb_blob_destroy (source_table);
-      break;
+  default:
+    return false;
   }
-  DEBUG_MSG(SUBSET, nullptr, "subset %c%c%c%c %s", HB_UNTAG (tag), result ? "ok" : "FAILED");
-  return result;
 }
 
 static bool
-_should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag)
+_subset_table (hb_subset_plan_t *plan, hb_tag_t tag)
 {
-  if (plan->drop_tables->has (tag))
-    return true;
+  DEBUG_MSG (SUBSET, nullptr, "subset %c%c%c%c", HB_UNTAG (tag));
+  switch (tag)
+  {
+  case HB_OT_TAG_glyf: return _subset<const OT::glyf> (plan);
+  case HB_OT_TAG_hdmx: return _subset<const OT::hdmx> (plan);
+  case HB_OT_TAG_name: return _subset<const OT::name> (plan);
+  case HB_OT_TAG_head:
+    if (_is_table_present (plan->source, HB_OT_TAG_glyf) && !_should_drop_table (plan, HB_OT_TAG_glyf))
+      return true; /* skip head, handled by glyf */
+    return _subset<const OT::head> (plan);
+  case HB_OT_TAG_hhea: return true; /* skip hhea, handled by hmtx */
+  case HB_OT_TAG_hmtx: return _subset<const OT::hmtx> (plan);
+  case HB_OT_TAG_vhea: return true; /* skip vhea, handled by vmtx */
+  case HB_OT_TAG_vmtx: return _subset<const OT::vmtx> (plan);
+  case HB_OT_TAG_maxp: return _subset<const OT::maxp> (plan);
+  case HB_OT_TAG_sbix: return _subset<const OT::sbix> (plan);
+  case HB_OT_TAG_loca: return true; /* skip loca, handled by glyf */
+  case HB_OT_TAG_cmap: return _subset<const OT::cmap> (plan);
+  case HB_OT_TAG_OS2 : return _subset<const OT::OS2 > (plan);
+  case HB_OT_TAG_post: return _subset<const OT::post> (plan);
+  case HB_OT_TAG_COLR: return _subset<const OT::COLR> (plan);
+  case HB_OT_TAG_CBLC: return _subset<const OT::CBLC> (plan);
+  case HB_OT_TAG_CBDT: return true; /* skip CBDT, handled by CBLC */
 
-  switch (tag) {
-    case HB_TAG ('c', 'v', 'a', 'r'): /* hint table, fallthrough */
-    case HB_TAG ('c', 'v', 't', ' '): /* hint table, fallthrough */
-    case HB_TAG ('f', 'p', 'g', 'm'): /* hint table, fallthrough */
-    case HB_TAG ('p', 'r', 'e', 'p'): /* hint table, fallthrough */
-    case HB_TAG ('h', 'd', 'm', 'x'): /* hint table, fallthrough */
-    case HB_TAG ('V', 'D', 'M', 'X'): /* hint table, fallthrough */
-      return plan->drop_hints;
+#ifndef HB_NO_SUBSET_CFF
+  case HB_OT_TAG_cff1: return _subset<const OT::cff1> (plan);
+  case HB_OT_TAG_cff2: return _subset<const OT::cff2> (plan);
+  case HB_OT_TAG_VORG: return _subset<const OT::VORG> (plan);
+#endif
 
-#ifdef HB_NO_SUBSET_LAYOUT
-    // Drop Layout Tables if requested.
-    case HB_OT_TAG_GDEF:
-    case HB_OT_TAG_GPOS:
-    case HB_OT_TAG_GSUB:
-    case HB_TAG ('m', 'o', 'r', 'x'):
-    case HB_TAG ('m', 'o', 'r', 't'):
-    case HB_TAG ('k', 'e', 'r', 'x'):
-    case HB_TAG ('k', 'e', 'r', 'n'):
-      return true;
+#ifndef HB_NO_SUBSET_LAYOUT
+  case HB_OT_TAG_GDEF: return _subset<const OT::GDEF> (plan);
+  case HB_OT_TAG_GSUB: return _subset<const OT::GSUB> (plan);
+  case HB_OT_TAG_GPOS: return _subset<const OT::GPOS> (plan);
+  case HB_OT_TAG_gvar: return _subset<const OT::gvar> (plan);
+  case HB_OT_TAG_HVAR: return _subset<const OT::HVAR> (plan);
+  case HB_OT_TAG_VVAR: return _subset<const OT::VVAR> (plan);
 #endif
 
-    default:
-      return false;
+  default:
+    hb_blob_t *source_table = hb_face_reference_table (plan->source, tag);
+    bool result = plan->add_table (tag, source_table);
+    hb_blob_destroy (source_table);
+    return result;
   }
 }
 
@@ -275,33 +236,29 @@
  * Subsets a font according to provided input.
  **/
 hb_face_t *
-hb_subset (hb_face_t *source,
-	   hb_subset_input_t *input)
+hb_subset (hb_face_t *source, hb_subset_input_t *input)
 {
   if (unlikely (!input || !source)) return hb_face_get_empty ();
 
   hb_subset_plan_t *plan = hb_subset_plan_create (source, input);
 
+  hb_set_t tags_set;
+  bool success = true;
   hb_tag_t table_tags[32];
-  unsigned int offset = 0, count;
-  bool success = true;
-  hb_set_t tags_set;
-  do {
-    count = ARRAY_LENGTH (table_tags);
-    hb_face_get_table_tags (source, offset, &count, table_tags);
-    for (unsigned int i = 0; i < count; i++)
+  unsigned offset = 0, num_tables = ARRAY_LENGTH (table_tags);
+  while ((hb_face_get_table_tags (source, offset, &num_tables, table_tags), num_tables))
+  {
+    for (unsigned i = 0; i < num_tables; ++i)
     {
       hb_tag_t tag = table_tags[i];
-      if (_should_drop_table (plan, tag) && !tags_set.has (tag))
-      {
-	DEBUG_MSG(SUBSET, nullptr, "drop %c%c%c%c", HB_UNTAG (tag));
-	continue;
-      }
+      if (_should_drop_table (plan, tag) && !tags_set.has (tag)) continue;
       tags_set.add (tag);
-      success = success && _subset_table (plan, tag);
+      success = _subset_table (plan, tag);
+      if (unlikely (!success)) goto end;
     }
-    offset += count;
-  } while (success && count == ARRAY_LENGTH (table_tags));
+    offset += num_tables;
+  }
+end:
 
   hb_face_t *result = success ? hb_face_reference (plan->dest) : hb_face_get_empty ();
   hb_subset_plan_destroy (plan);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h	2020-05-18 10:44:36 UTC (rev 55197)
@@ -58,6 +58,9 @@
 hb_subset_input_nameid_set (hb_subset_input_t *subset_input);
 
 HB_EXTERN hb_set_t *
+hb_subset_input_namelangid_set (hb_subset_input_t *subset_input);
+
+HB_EXTERN hb_set_t *
 hb_subset_input_drop_tables_set (hb_subset_input_t *subset_input);
 
 HB_EXTERN void
@@ -78,6 +81,12 @@
 HB_EXTERN hb_bool_t
 hb_subset_input_get_retain_gids (hb_subset_input_t *subset_input);
 
+HB_EXTERN void
+hb_subset_input_set_name_legacy (hb_subset_input_t *subset_input,
+				 hb_bool_t name_legacy);
+HB_EXTERN hb_bool_t
+hb_subset_input_get_name_legacy (hb_subset_input_t *subset_input);
+
 /* hb_subset () */
 HB_EXTERN hb_face_t *
 hb_subset (hb_face_t *source, hb_subset_input_t *input);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -54,12 +54,15 @@
   dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
   ( _dispatch (obj, hb_prioritize, hb_forward<Ts> (ds)...) )
 
+  hb_blob_t *source_blob;
   hb_subset_plan_t *plan;
   hb_serialize_context_t *serializer;
   unsigned int debug_depth;
 
-  hb_subset_context_t (hb_subset_plan_t *plan_,
+  hb_subset_context_t (hb_blob_t *source_blob_,
+		       hb_subset_plan_t *plan_,
 		       hb_serialize_context_t *serializer_) :
+			source_blob (source_blob_),
 			plan (plan_),
 			serializer (serializer_),
 			debug_depth (0) {}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ucd.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -136,10 +136,11 @@
   if ((a & 0xFFFFF800u) == 0x0000u && (b & 0xFFFFFF80) == 0x0300u)
   {
     uint32_t k = HB_CODEPOINT_ENCODE3_11_7_14 (a, b, 0);
-    uint32_t *v = (uint32_t*) hb_bsearch (&k, _hb_ucd_dm2_u32_map,
-					  ARRAY_LENGTH (_hb_ucd_dm2_u32_map),
-					  sizeof (*_hb_ucd_dm2_u32_map),
-					  _cmp_pair_11_7_14);
+    const uint32_t *v = hb_bsearch (k,
+				    _hb_ucd_dm2_u32_map,
+				    ARRAY_LENGTH (_hb_ucd_dm2_u32_map),
+				    sizeof (*_hb_ucd_dm2_u32_map),
+				    _cmp_pair_11_7_14);
     if (likely (!v)) return false;
     u = HB_CODEPOINT_DECODE3_11_7_14_3 (*v);
   }
@@ -146,10 +147,11 @@
   else
   {
     uint64_t k = HB_CODEPOINT_ENCODE3 (a, b, 0);
-    uint64_t *v = (uint64_t*) hb_bsearch (&k, _hb_ucd_dm2_u64_map,
-					  ARRAY_LENGTH (_hb_ucd_dm2_u64_map),
-					  sizeof (*_hb_ucd_dm2_u64_map),
-					  _cmp_pair);
+    const uint64_t *v = hb_bsearch (k,
+				    _hb_ucd_dm2_u64_map,
+				    ARRAY_LENGTH (_hb_ucd_dm2_u64_map),
+				    sizeof (*_hb_ucd_dm2_u64_map),
+				    _cmp_pair);
     if (likely (!v)) return false;
     u = HB_CODEPOINT_DECODE3_3 (*v);
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-emoji-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-emoji-table.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode-emoji-table.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -10,12 +10,12 @@
  * # Date: 2019-01-15, 12:10:05 GMT
  * # © 2019 Unicode®, Inc.
  * # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
- * # For terms of use, see http://www.unicode.org/terms_of_use.html
+ * # For terms of use, see https://www.unicode.org/terms_of_use.html
  * #
  * # Emoji Data for UTS #51
  * # Version: 12.0
  * #
- * # For documentation and usage, see http://www.unicode.org/reports/tr51
+ * # For documentation and usage, see https://www.unicode.org/reports/tr51
  */
 
 #ifndef HB_UNICODE_EMOJI_TABLE_HH

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -212,7 +212,7 @@
 hb_unicode_funcs_t *
 hb_unicode_funcs_get_empty ()
 {
-  return const_cast<hb_unicode_funcs_t *> (&Null(hb_unicode_funcs_t));
+  return const_cast<hb_unicode_funcs_t *> (&Null (hb_unicode_funcs_t));
 }
 
 /**

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -324,10 +324,10 @@
  * Modify Telugu length marks (ccc=84, ccc=91).
  * These are the only matras in the main Indic scripts range that have
  * a non-zero ccc.  That makes them reorder with the Halant (ccc=9).
- * Assign 5 and 6, which are otherwise unassigned.
+ * Assign 4 and 5, which are otherwise unassigned.
  */
-#define HB_MODIFIED_COMBINING_CLASS_CCC84 5 /* length mark */
-#define HB_MODIFIED_COMBINING_CLASS_CCC91 6 /* ai length mark */
+#define HB_MODIFIED_COMBINING_CLASS_CCC84 4 /* length mark */
+#define HB_MODIFIED_COMBINING_CLASS_CCC91 5 /* ai length mark */
 
 /* Thai
  *

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -55,7 +55,7 @@
  * @short_description: Windows integration
  * @include: hb-uniscribe.h
  *
- * Functions for using HarfBuzz with the Windows fonts.
+ * Functions for using HarfBuzz with Windows fonts.
  **/
 
 typedef HRESULT (WINAPI *SIOT) /*ScriptItemizeOpenType*/(
@@ -453,7 +453,7 @@
 
   hb_blob_destroy (blob);
   return hb_blob_create ((const char *) new_sfnt_data, new_length,
-			 HB_MEMORY_MODE_WRITABLE, nullptr, free);
+			 HB_MEMORY_MODE_WRITABLE, new_sfnt_data, free);
 }
 
 hb_uniscribe_face_data_t *
@@ -583,6 +583,16 @@
   free (data);
 }
 
+/**
+ * hb_uniscribe_font_get_logfontw:
+ * @font: The #hb_font_t to work upon
+ *
+ * Fetches the LOGFONTW structure that corresponds to the
+ * specified #hb_font_t font.
+ *
+ * Return value: a pointer to the LOGFONTW retrieved
+ *
+ **/
 LOGFONTW *
 hb_uniscribe_font_get_logfontw (hb_font_t *font)
 {
@@ -590,6 +600,16 @@
   return data ? &data->log_font : nullptr;
 }
 
+/**
+ * hb_uniscribe_font_get_hfont:
+ * @font: The #hb_font_t to work upon
+ *
+ * Fetches the HFONT handle that corresponds to the
+ * specified #hb_font_t font.
+ *
+ * Return value: the HFONT retreieved
+ *
+ **/
 HFONT
 hb_uniscribe_font_get_hfont (hb_font_t *font)
 {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -117,7 +117,7 @@
   {
     unsigned int i = (unsigned int) i_;
     if (unlikely (i >= length))
-      return Null(Type);
+      return Null (Type);
     return arrayZ[i];
   }
 
@@ -165,7 +165,7 @@
   Type *push ()
   {
     if (unlikely (!resize (length + 1)))
-      return &Crap(Type);
+      return &Crap (Type);
     return &arrayZ[length - 1];
   }
   template <typename T>
@@ -228,7 +228,7 @@
 
   Type pop ()
   {
-    if (!length) return Null(Type);
+    if (!length) return Null (Type);
     return hb_move (arrayZ[--length]); /* Does this move actually work? */
   }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.h	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.h	2020-05-18 10:44:36 UTC (rev 55197)
@@ -32,6 +32,7 @@
 #include "hb-buffer.h"
 #include "hb-common.h"
 #include "hb-deprecated.h"
+#include "hb-draw.h"
 #include "hb-face.h"
 #include "hb-font.h"
 #include "hb-map.h"

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh	2020-05-18 10:44:36 UTC (rev 55197)
@@ -176,6 +176,7 @@
 
 #include <limits.h>
 #include <math.h>
+#include <float.h>
 #include <stdlib.h>
 #include <stddef.h>
 #include <string.h>
@@ -317,6 +318,18 @@
 #  define HB_FALLTHROUGH /* FALLTHROUGH */
 #endif
 
+/* A tag to enforce use of return value for a function */
+#if __cplusplus >= 201703L
+#  define HB_NODISCARD [[nodiscard]]
+#elif defined(__GNUC__) || defined(__clang__)
+#  define HB_NODISCARD __attribute__((warn_unused_result))
+#elif defined(_MSC_VER)
+#  define HB_NODISCARD _Check_return_
+#else
+#  define HB_NODISCARD
+#endif
+#define hb_success_t HB_NODISCARD bool
+
 /* https://github.com/harfbuzz/harfbuzz/issues/1852 */
 #if defined(__clang__) && !(defined(_AIX) && (defined(__IBMCPP__) || defined(__ibmxl__)))
 /* Disable certain sanitizer errors. */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,5 +1,7 @@
 /*
  * Copyright © 2007,2008,2009  Red Hat, Inc.
+ * Copyright © 2018,2019,2020  Ebrahim Byagowi
+ * Copyright © 2018  Khaled Hosny
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -24,48 +26,335 @@
  * Red Hat Author(s): Behdad Esfahbod
  */
 
-#include "hb-static.cc"
-#include "hb-open-file.hh"
-#include "hb-ot-layout-gdef-table.hh"
-#include "hb-ot-layout-gsubgpos.hh"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 
-#ifdef HAVE_GLIB
-#include <glib.h>
-#endif
+#include "hb.h"
+#include "hb-ot.h"
+
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 
-
-using namespace OT;
-
 #ifdef HB_NO_OPEN
 #define hb_blob_create_from_file(x)  hb_blob_get_empty ()
 #endif
 
-int
-main (int argc, char **argv)
+#if !defined(HB_NO_COLOR) && !defined(HB_NO_DRAW) && defined(HB_EXPERIMENTAL_API)
+static void
+svg_dump (hb_face_t *face, unsigned face_index)
 {
-  if (argc != 2)
+  unsigned glyph_count = hb_face_get_glyph_count (face);
+
+  for (unsigned glyph_id = 0; glyph_id < glyph_count; ++glyph_id)
   {
-    fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]);
-    exit (1);
+    hb_blob_t *blob = hb_ot_color_glyph_reference_svg (face, glyph_id);
+
+    if (hb_blob_get_length (blob) == 0) continue;
+
+    unsigned length;
+    const char *data = hb_blob_get_data (blob, &length);
+
+    char output_path[255];
+    sprintf (output_path, "out/svg-%u-%u.svg%s",
+	     glyph_id,
+	     face_index,
+	     // append "z" if the content is gzipped, https://stackoverflow.com/a/6059405
+	     (length > 2 && (data[0] == '\x1F') && (data[1] == '\x8B')) ? "z" : "");
+
+    FILE *f = fopen (output_path, "wb");
+    fwrite (data, 1, length, f);
+    fclose (f);
+
+    hb_blob_destroy (blob);
   }
+}
 
-  hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
-  unsigned int len;
-  const char *font_data = hb_blob_get_data (blob, &len);
-  printf ("Opened font file %s: %d bytes long\n", argv[1], len);
+/* _png API is so easy to use unlike the below code, don't get confused */
+static void
+png_dump (hb_face_t *face, unsigned face_index)
+{
+  unsigned glyph_count = hb_face_get_glyph_count (face);
+  hb_font_t *font = hb_font_create (face);
 
-  hb_blob_t *font_blob = hb_sanitize_context_t().sanitize_blob<OpenTypeFontFile> (blob);
+  /* scans the font for strikes */
+  unsigned sample_glyph_id;
+  /* we don't care about different strikes for different glyphs at this point */
+  for (sample_glyph_id = 0; sample_glyph_id < glyph_count; ++sample_glyph_id)
+  {
+    hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id);
+    unsigned blob_length = hb_blob_get_length (blob);
+    hb_blob_destroy (blob);
+    if (blob_length != 0)
+      break;
+  }
+
+  unsigned upem = hb_face_get_upem (face);
+  unsigned blob_length = 0;
+  unsigned strike = 0;
+  for (unsigned ppem = 1; ppem < upem; ++ppem)
+  {
+    hb_font_set_ppem (font, ppem, ppem);
+    hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id);
+    unsigned new_blob_length = hb_blob_get_length (blob);
+    hb_blob_destroy (blob);
+    if (new_blob_length != blob_length)
+    {
+      for (unsigned glyph_id = 0; glyph_id < glyph_count; ++glyph_id)
+      {
+	hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, glyph_id);
+
+	if (hb_blob_get_length (blob) == 0) continue;
+
+	unsigned length;
+	const char *data = hb_blob_get_data (blob, &length);
+
+	char output_path[255];
+	sprintf (output_path, "out/png-%u-%u-%u.png", glyph_id, strike, face_index);
+
+	FILE *f = fopen (output_path, "wb");
+	fwrite (data, 1, length, f);
+	fclose (f);
+
+	hb_blob_destroy (blob);
+      }
+
+      strike++;
+      blob_length = new_blob_length;
+    }
+  }
+
+  hb_font_destroy (font);
+}
+
+struct user_data_t
+{
+  FILE *f;
+  hb_position_t ascender;
+};
+
+static void
+move_to (hb_position_t to_x, hb_position_t to_y, user_data_t &user_data)
+{
+  fprintf (user_data.f, "M%d,%d", to_x, user_data.ascender - to_y);
+}
+
+static void
+line_to (hb_position_t to_x, hb_position_t to_y, user_data_t &user_data)
+{
+  fprintf (user_data.f, "L%d,%d", to_x, user_data.ascender - to_y);
+}
+
+static void
+quadratic_to (hb_position_t control_x, hb_position_t control_y,
+	      hb_position_t to_x, hb_position_t to_y,
+	      user_data_t &user_data)
+{
+  fprintf (user_data.f, "Q%d,%d %d,%d", control_x, user_data.ascender - control_y,
+					to_x, user_data.ascender - to_y);
+}
+
+static void
+cubic_to (hb_position_t control1_x, hb_position_t control1_y,
+	  hb_position_t control2_x, hb_position_t control2_y,
+	  hb_position_t to_x, hb_position_t to_y,
+	  user_data_t &user_data)
+{
+  fprintf (user_data.f, "C%d,%d %d,%d %d,%d", control1_x, user_data.ascender - control1_y,
+					       control2_x, user_data.ascender - control2_y,
+					       to_x, user_data.ascender - to_y);
+}
+
+static void
+close_path (user_data_t &user_data)
+{
+  fprintf (user_data.f, "Z");
+}
+
+static void
+layered_glyph_dump (hb_font_t *font, hb_draw_funcs_t *funcs, unsigned face_index)
+{
+  hb_face_t *face = hb_font_get_face (font);
+  unsigned palette_count = hb_ot_color_palette_get_count (face);
+  for (unsigned palette = 0; palette < palette_count; ++palette)
+  {
+    unsigned num_colors = hb_ot_color_palette_get_colors (face, palette, 0, nullptr, nullptr);
+    if (!num_colors) continue;
+
+    hb_color_t *colors = (hb_color_t*) calloc (num_colors, sizeof (hb_color_t));
+    hb_ot_color_palette_get_colors (face, palette, 0, &num_colors, colors);
+    if (!num_colors)
+    {
+      free (colors);
+      continue;
+    }
+
+    unsigned num_glyphs = hb_face_get_glyph_count (face);
+    for (hb_codepoint_t gid = 0; gid < num_glyphs; ++gid)
+    {
+      unsigned num_layers = hb_ot_color_glyph_get_layers (face, gid, 0, nullptr, nullptr);
+      if (!num_layers) continue;
+
+      hb_ot_color_layer_t *layers = (hb_ot_color_layer_t*) malloc (num_layers * sizeof (hb_ot_color_layer_t));
+
+      hb_ot_color_glyph_get_layers (face, gid, 0, &num_layers, layers);
+      if (num_layers)
+      {
+	hb_font_extents_t font_extents;
+	hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents);
+	hb_glyph_extents_t extents = {0};
+	if (!hb_font_get_glyph_extents (font, gid, &extents))
+	{
+	  printf ("Skip gid: %d\n", gid);
+	  continue;
+	}
+
+	char output_path[255];
+	sprintf (output_path, "out/colr-%u-%u-%u.svg", gid, palette, face_index);
+	FILE *f = fopen (output_path, "wb");
+	fprintf (f, "<svg xmlns=\"http://www.w3.org/2000/svg\""
+		    " viewBox=\"%d %d %d %d\">\n",
+		    extents.x_bearing, 0,
+		    extents.x_bearing + extents.width, -extents.height);
+	user_data_t user_data;
+	user_data.ascender = extents.y_bearing;
+	user_data.f = f;
+
+	for (unsigned layer = 0; layer < num_layers; ++layer)
+	{
+	  hb_color_t color = 0x000000FF;
+	  if (layers[layer].color_index != 0xFFFF)
+	    color = colors[layers[layer].color_index];
+	  fprintf (f, "<path fill=\"#%02X%02X%02X\" ",
+		   hb_color_get_red (color), hb_color_get_green (color), hb_color_get_green (color));
+	  if (hb_color_get_alpha (color) != 255)
+	    fprintf (f, "fill-opacity=\"%.3f\"", (double) hb_color_get_alpha (color) / 255.);
+	  fprintf (f, "d=\"");
+	  if (!hb_font_draw_glyph (font, layers[layer].glyph, funcs, &user_data))
+	    printf ("Failed to decompose layer %d while %d\n", layers[layer].glyph, gid);
+	  fprintf (f, "\"/>\n");
+	}
+
+	fprintf (f, "</svg>");
+	fclose (f);
+      }
+      free (layers);
+    }
+
+    free (colors);
+  }
+}
+
+static void
+dump_glyphs (hb_font_t *font, hb_draw_funcs_t *funcs, unsigned face_index)
+{
+  unsigned num_glyphs = hb_face_get_glyph_count (hb_font_get_face (font));
+  for (unsigned gid = 0; gid < num_glyphs; ++gid)
+  {
+    hb_font_extents_t font_extents;
+    hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents);
+    hb_glyph_extents_t extents = {0};
+    if (!hb_font_get_glyph_extents (font, gid, &extents))
+    {
+      printf ("Skip gid: %d\n", gid);
+      continue;
+    }
+
+    char output_path[255];
+    sprintf (output_path, "out/%u-%u.svg", face_index, gid);
+    FILE *f = fopen (output_path, "wb");
+    fprintf (f, "<svg xmlns=\"http://www.w3.org/2000/svg\""
+		" viewBox=\"%d %d %d %d\"><path d=\"",
+		extents.x_bearing, 0,
+		extents.x_bearing + extents.width, font_extents.ascender - font_extents.descender);
+    user_data_t user_data;
+    user_data.ascender = font_extents.ascender;
+    user_data.f = f;
+    if (!hb_font_draw_glyph (font, gid, funcs, &user_data))
+      printf ("Failed to decompose gid: %d\n", gid);
+    fprintf (f, "\"/></svg>");
+    fclose (f);
+  }
+}
+
+static void
+dump_glyphs (hb_blob_t *blob, const char *font_name)
+{
+  FILE *font_name_file = fopen ("out/.dumped_font_name", "r");
+  if (font_name_file)
+  {
+    fprintf (stderr, "Purge or rename ./out folder if you like to run a glyph dump,\n"
+		     "run it like `rm -rf out && mkdir out && src/main font-file.ttf`\n");
+    return;
+  }
+
+  font_name_file = fopen ("out/.dumped_font_name", "w");
+  if (!font_name_file)
+  {
+    fprintf (stderr, "./out is not accessible as a folder, create it please\n");
+    return;
+  }
+  fwrite (font_name, 1, strlen (font_name), font_name_file);
+  fclose (font_name_file);
+
+  hb_draw_funcs_t *funcs = hb_draw_funcs_create ();
+  hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) move_to);
+  hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) line_to);
+  hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) quadratic_to);
+  hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to);
+  hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path);
+
+  unsigned num_faces = hb_face_count (blob);
+  for (unsigned face_index = 0; face_index < num_faces; ++face_index)
+  {
+    hb_face_t *face = hb_face_create (blob, face_index);
+    hb_font_t *font = hb_font_create (face);
+
+    if (hb_ot_color_has_png (face))
+      printf ("Dumping png (CBDT/sbix)...\n");
+    png_dump (face, face_index);
+
+    if (hb_ot_color_has_svg (face))
+      printf ("Dumping svg (SVG )...\n");
+    svg_dump (face, face_index);
+
+    if (hb_ot_color_has_layers (face) && hb_ot_color_has_palettes (face))
+      printf ("Dumping layered color glyphs (COLR/CPAL)...\n");
+    layered_glyph_dump (font, funcs, face_index);
+
+    dump_glyphs (font, funcs, face_index);
+
+    hb_font_destroy (font);
+    hb_face_destroy (face);
+  }
+
+  hb_draw_funcs_destroy (funcs);
+}
+#endif
+
+#ifndef MAIN_CC_NO_PRIVATE_API
+/* Only this part of this mini app uses private API */
+#include "hb-static.cc"
+#include "hb-open-file.hh"
+#include "hb-ot-layout-gdef-table.hh"
+#include "hb-ot-layout-gsubgpos.hh"
+
+using namespace OT;
+
+static void
+print_layout_info_using_private_api (hb_blob_t *blob)
+{
+  const char *font_data = hb_blob_get_data (blob, nullptr);
+  hb_blob_t *font_blob = hb_sanitize_context_t ().sanitize_blob<OpenTypeFontFile> (blob);
   const OpenTypeFontFile* sanitized = font_blob->as<OpenTypeFontFile> ();
   if (!font_blob->data)
   {
     printf ("Sanitization of the file wasn't successful. Exit");
-    return 1;
+    exit (1);
   }
   const OpenTypeFontFile& ot = *sanitized;
 
-
   switch (ot.get_tag ())
   {
   case OpenTypeFontFile::TrueTypeTag:
@@ -91,22 +380,22 @@
     break;
   }
 
-  int num_fonts = ot.get_face_count ();
-  printf ("%d font(s) found in file\n", num_fonts);
-  for (int n_font = 0; n_font < num_fonts; n_font++)
+  unsigned num_faces = hb_face_count (blob);
+  printf ("%d font(s) found in file\n", num_faces);
+  for (unsigned n_font = 0; n_font < num_faces; ++n_font)
   {
     const OpenTypeFontFace &font = ot.get_face (n_font);
-    printf ("Font %d of %d:\n", n_font, num_fonts);
+    printf ("Font %d of %d:\n", n_font, num_faces);
 
-    int num_tables = font.get_table_count ();
+    unsigned num_tables = font.get_table_count ();
     printf ("  %d table(s) found in font\n", num_tables);
-    for (int n_table = 0; n_table < num_tables; n_table++)
+    for (unsigned n_table = 0; n_table < num_tables; ++n_table)
     {
       const OpenTypeTable &table = font.get_table (n_table);
       printf ("  Table %2d of %2d: %.4s (0x%08x+0x%08x)\n", n_table, num_tables,
 	      (const char *) table.tag,
-	      (unsigned int) table.offset,
-	      (unsigned int) table.length);
+	      (unsigned) table.offset,
+	      (unsigned) table.length);
 
       switch (table.tag)
       {
@@ -115,21 +404,22 @@
       case HB_OT_TAG_GPOS:
 	{
 
-	const GSUBGPOS &g = *CastP<GSUBGPOS> (font_data + table.offset);
+	const GSUBGPOS &g = *reinterpret_cast<const GSUBGPOS *> (font_data + table.offset);
 
-	int num_scripts = g.get_script_count ();
+	unsigned num_scripts = g.get_script_count ();
 	printf ("    %d script(s) found in table\n", num_scripts);
-	for (int n_script = 0; n_script < num_scripts; n_script++)
+	for (unsigned n_script = 0; n_script < num_scripts; ++n_script)
 	{
 	  const Script &script = g.get_script (n_script);
 	  printf ("    Script %2d of %2d: %.4s\n", n_script, num_scripts,
-		  (const char *)g.get_script_tag(n_script));
+		  (const char *) g.get_script_tag (n_script));
 
-	  if (!script.has_default_lang_sys())
+	  if (!script.has_default_lang_sys ())
 	    printf ("      No default language system\n");
 	  int num_langsys = script.get_lang_sys_count ();
 	  printf ("      %d language system(s) found in script\n", num_langsys);
-	  for (int n_langsys = script.has_default_lang_sys() ? -1 : 0; n_langsys < num_langsys; n_langsys++) {
+	  for (int n_langsys = script.has_default_lang_sys () ? -1 : 0; n_langsys < num_langsys; ++n_langsys)
+	  {
 	    const LangSys &langsys = n_langsys == -1
 				   ? script.get_default_lang_sys ()
 				   : script.get_lang_sys (n_langsys);
@@ -137,7 +427,7 @@
 	      printf ("      Default Language System\n");
 	    else
 	      printf ("      Language System %2d of %2d: %.4s\n", n_langsys, num_langsys,
-		      (const char *)script.get_lang_sys_tag (n_langsys));
+		      (const char *) script.get_lang_sys_tag (n_langsys));
 	    if (!langsys.has_required_feature ())
 	      printf ("        No required feature\n");
 	    else
@@ -144,9 +434,9 @@
 	      printf ("        Required feature index: %d\n",
 		      langsys.get_required_feature_index ());
 
-	    int num_features = langsys.get_feature_count ();
+	    unsigned num_features = langsys.get_feature_count ();
 	    printf ("        %d feature(s) found in language system\n", num_features);
-	    for (int n_feature = 0; n_feature < num_features; n_feature++)
+	    for (unsigned n_feature = 0; n_feature < num_features; ++n_feature)
 	    {
 	      printf ("        Feature index %2d of %2d: %d\n", n_feature, num_features,
 		      langsys.get_feature_index (n_feature));
@@ -154,29 +444,29 @@
 	  }
 	}
 
-	int num_features = g.get_feature_count ();
+	unsigned num_features = g.get_feature_count ();
 	printf ("    %d feature(s) found in table\n", num_features);
-	for (int n_feature = 0; n_feature < num_features; n_feature++)
+	for (unsigned n_feature = 0; n_feature < num_features; ++n_feature)
 	{
 	  const Feature &feature = g.get_feature (n_feature);
-	  int num_lookups = feature.get_lookup_count ();
+	  unsigned num_lookups = feature.get_lookup_count ();
 	  printf ("    Feature %2d of %2d: %c%c%c%c\n", n_feature, num_features,
-		  HB_UNTAG(g.get_feature_tag(n_feature)));
+		  HB_UNTAG (g.get_feature_tag (n_feature)));
 
 	  printf ("        %d lookup(s) found in feature\n", num_lookups);
-	  for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) {
+	  for (unsigned n_lookup = 0; n_lookup < num_lookups; ++n_lookup) {
 	    printf ("        Lookup index %2d of %2d: %d\n", n_lookup, num_lookups,
 		    feature.get_lookup_index (n_lookup));
 	  }
 	}
 
-	int num_lookups = g.get_lookup_count ();
+	unsigned num_lookups = g.get_lookup_count ();
 	printf ("    %d lookup(s) found in table\n", num_lookups);
-	for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++)
+	for (unsigned n_lookup = 0; n_lookup < num_lookups; ++n_lookup)
 	{
 	  const Lookup &lookup = g.get_lookup (n_lookup);
 	  printf ("    Lookup %2d of %2d: type %d, props 0x%04X\n", n_lookup, num_lookups,
-		  lookup.get_type(), lookup.get_props());
+		  lookup.get_type (), lookup.get_props ());
 	}
 
 	}
@@ -185,7 +475,7 @@
       case GDEF::tableTag:
 	{
 
-	const GDEF &gdef = *CastP<GDEF> (font_data + table.offset);
+	const GDEF &gdef = *reinterpret_cast<const GDEF *> (font_data + table.offset);
 
 	printf ("    Has %sglyph classes\n",
 		  gdef.has_glyph_classes () ? "" : "no ");
@@ -202,6 +492,28 @@
       }
     }
   }
+}
+/* end of private API use */
+#endif
 
+int
+main (int argc, char **argv)
+{
+  if (argc != 2)
+  {
+    fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]);
+    exit (1);
+  }
+
+  hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
+  printf ("Opened font file %s: %d bytes long\n", argv[1], hb_blob_get_length (blob));
+#ifndef MAIN_CC_NO_PRIVATE_API
+  print_layout_info_using_private_api (blob);
+#endif
+#if !defined(HB_NO_COLOR) && !defined(HB_NO_DRAW) && defined(HB_EXPERIMENTAL_API)
+  dump_glyphs (blob, argv[1]);
+#endif
+  hb_blob_destroy (blob);
+
   return 0;
 }

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build	2020-05-18 10:44:36 UTC (rev 55197)
@@ -0,0 +1,669 @@
+# Base and default-included sources and headers
+hb_base_sources = [
+  'hb-aat-fdsc-table.hh',
+  'hb-aat-layout-ankr-table.hh',
+  'hb-aat-layout-bsln-table.hh',
+  'hb-aat-layout-common.hh',
+  'hb-aat-layout-feat-table.hh',
+  'hb-aat-layout-just-table.hh',
+  'hb-aat-layout-kerx-table.hh',
+  'hb-aat-layout-lcar-table.hh',
+  'hb-aat-layout-morx-table.hh',
+  'hb-aat-layout-opbd-table.hh',
+  'hb-aat-layout-trak-table.hh',
+  'hb-aat-layout.cc',
+  'hb-aat-layout.hh',
+  'hb-aat-ltag-table.hh',
+  'hb-aat-map.cc',
+  'hb-aat-map.hh',
+  'hb-algs.hh',
+  'hb-array.hh',
+  'hb-atomic.hh',
+  'hb-blob.cc',
+  'hb-blob.hh',
+  'hb-buffer-serialize.cc',
+  'hb-buffer.cc',
+  'hb-buffer.hh',
+  'hb-cache.hh',
+  'hb-cff-interp-common.hh',
+  'hb-cff-interp-cs-common.hh',
+  'hb-cff-interp-dict-common.hh',
+  'hb-cff1-interp-cs.hh',
+  'hb-cff2-interp-cs.hh',
+  'hb-common.cc',
+  'hb-config.hh',
+  'hb-debug.hh',
+  'hb-dispatch.hh',
+  'hb-draw.cc',
+  'hb-draw.hh',
+  'hb-face.cc',
+  'hb-face.hh',
+  'hb-fallback-shape.cc',
+  'hb-font.cc',
+  'hb-font.hh',
+  'hb-iter.hh',
+  'hb-kern.hh',
+  'hb-machinery.hh',
+  'hb-map.cc',
+  'hb-map.hh',
+  'hb-bimap.hh',
+  'hb-meta.hh',
+  'hb-mutex.hh',
+  'hb-null.hh',
+  'hb-number.cc',
+  'hb-number.hh',
+  'hb-object.hh',
+  'hb-open-file.hh',
+  'hb-open-type.hh',
+  'hb-ot-cff-common.hh',
+  'hb-ot-cff1-table.cc',
+  'hb-ot-cff1-table.hh',
+  'hb-ot-cff1-std-str.hh',
+  'hb-ot-cff2-table.cc',
+  'hb-ot-cff2-table.hh',
+  'hb-ot-cmap-table.hh',
+  'hb-ot-color-cbdt-table.hh',
+  'hb-ot-color-colr-table.hh',
+  'hb-ot-color-cpal-table.hh',
+  'hb-ot-color-sbix-table.hh',
+  'hb-ot-color-svg-table.hh',
+  'hb-ot-color.cc',
+  'hb-ot-face.cc',
+  'hb-ot-face.hh',
+  'hb-ot-face-table-list.hh',
+  'hb-ot-font.cc',
+  'hb-ot-gasp-table.hh',
+  'hb-ot-glyf-table.hh',
+  'hb-ot-hdmx-table.hh',
+  'hb-ot-head-table.hh',
+  'hb-ot-hhea-table.hh',
+  'hb-ot-hmtx-table.hh',
+  'hb-ot-kern-table.hh',
+  'hb-ot-layout-base-table.hh',
+  'hb-ot-layout-common.hh',
+  'hb-ot-layout-gdef-table.hh',
+  'hb-ot-layout-gpos-table.hh',
+  'hb-ot-layout-gsub-table.hh',
+  'hb-ot-layout-gsubgpos.hh',
+  'hb-ot-layout-jstf-table.hh',
+  'hb-ot-layout.cc',
+  'hb-ot-layout.hh',
+  'hb-ot-map.cc',
+  'hb-ot-map.hh',
+  'hb-ot-math-table.hh',
+  'hb-ot-math.cc',
+  'hb-ot-maxp-table.hh',
+  'hb-ot-meta-table.hh',
+  'hb-ot-meta.cc',
+  'hb-ot-metrics.cc',
+  'hb-ot-metrics.hh',
+  'hb-ot-name-language-static.hh',
+  'hb-ot-name-language.hh',
+  'hb-ot-name-table.hh',
+  'hb-ot-name.cc',
+  'hb-ot-os2-table.hh',
+  'hb-ot-os2-unicode-ranges.hh',
+  'hb-ot-post-macroman.hh',
+  'hb-ot-post-table.hh',
+  'hb-ot-shape-complex-arabic-fallback.hh',
+  'hb-ot-shape-complex-arabic-table.hh',
+  'hb-ot-shape-complex-arabic-win1256.hh',
+  'hb-ot-shape-complex-arabic.cc',
+  'hb-ot-shape-complex-arabic.hh',
+  'hb-ot-shape-complex-default.cc',
+  'hb-ot-shape-complex-hangul.cc',
+  'hb-ot-shape-complex-hebrew.cc',
+  'hb-ot-shape-complex-indic-table.cc',
+  'hb-ot-shape-complex-indic.cc',
+  'hb-ot-shape-complex-indic.hh',
+  'hb-ot-shape-complex-khmer.cc',
+  'hb-ot-shape-complex-khmer.hh',
+  'hb-ot-shape-complex-myanmar.cc',
+  'hb-ot-shape-complex-myanmar.hh',
+  'hb-ot-shape-complex-thai.cc',
+  'hb-ot-shape-complex-use-table.cc',
+  'hb-ot-shape-complex-use.cc',
+  'hb-ot-shape-complex-use.hh',
+  'hb-ot-shape-complex-vowel-constraints.cc',
+  'hb-ot-shape-complex-vowel-constraints.hh',
+  'hb-ot-shape-complex.hh',
+  'hb-ot-shape-fallback.cc',
+  'hb-ot-shape-fallback.hh',
+  'hb-ot-shape-normalize.cc',
+  'hb-ot-shape-normalize.hh',
+  'hb-ot-shape.cc',
+  'hb-ot-shape.hh',
+  'hb-ot-stat-table.hh',
+  'hb-ot-tag-table.hh',
+  'hb-ot-tag.cc',
+  'hb-ot-var-avar-table.hh',
+  'hb-ot-var-fvar-table.hh',
+  'hb-ot-var-gvar-table.hh',
+  'hb-ot-var-hvar-table.hh',
+  'hb-ot-var-mvar-table.hh',
+  'hb-ot-var.cc',
+  'hb-ot-vorg-table.hh',
+  'hb-pool.hh',
+  'hb-sanitize.hh',
+  'hb-serialize.hh',
+  'hb-set-digest.hh',
+  'hb-set.cc',
+  'hb-set.hh',
+  'hb-shape-plan.cc',
+  'hb-shape-plan.hh',
+  'hb-shape.cc',
+  'hb-shaper-impl.hh',
+  'hb-shaper-list.hh',
+  'hb-shaper.cc',
+  'hb-shaper.hh',
+  'hb-static.cc',
+  'hb-string-array.hh',
+  'hb-ucd-table.hh',
+  'hb-ucd.cc',
+  'hb-unicode-emoji-table.hh',
+  'hb-unicode.cc',
+  'hb-unicode.hh',
+  'hb-utf.hh',
+  'hb-vector.hh',
+  'hb.hh',
+]
+
+hb_base_ragel_generated_sources = [
+  'hb-buffer-deserialize-json.hh',
+  'hb-buffer-deserialize-text.hh',
+  'hb-number-parser.hh',
+  'hb-ot-shape-complex-indic-machine.hh',
+  'hb-ot-shape-complex-khmer-machine.hh',
+  'hb-ot-shape-complex-myanmar-machine.hh',
+  'hb-ot-shape-complex-use-machine.hh',
+]
+hb_base_ragel_sources = [
+  'hb-buffer-deserialize-json.rl',
+  'hb-buffer-deserialize-text.rl',
+  'hb-number-parser.rl',
+  'hb-ot-shape-complex-indic-machine.rl',
+  'hb-ot-shape-complex-khmer-machine.rl',
+  'hb-ot-shape-complex-myanmar-machine.rl',
+  'hb-ot-shape-complex-use-machine.rl',
+]
+
+hb_base_headers = [
+  'hb-aat-layout.h',
+  'hb-aat.h',
+  'hb-blob.h',
+  'hb-buffer.h',
+  'hb-common.h',
+  'hb-deprecated.h',
+  'hb-draw.h',
+  'hb-face.h',
+  'hb-font.h',
+  'hb-map.h',
+  'hb-ot-color.h',
+  'hb-ot-deprecated.h',
+  'hb-ot-font.h',
+  'hb-ot-layout.h',
+  'hb-ot-math.h',
+  'hb-ot-meta.h',
+  'hb-ot-metrics.h',
+  'hb-ot-name.h',
+  'hb-ot-shape.h',
+  'hb-ot-var.h',
+  'hb-ot.h',
+  'hb-set.h',
+  'hb-shape-plan.h',
+  'hb-shape.h',
+  'hb-unicode.h',
+  'hb-version.h',
+  'hb.h',
+]
+
+# Optional Sources and Headers with external deps
+
+hb_ft_sources = ['hb-ft.cc']
+hb_ft_headers = ['hb-ft.h']
+
+hb_glib_sources = ['hb-glib.cc']
+hb_glib_headers = ['hb-glib.h']
+
+hb_graphite2_sources = ['hb-graphite2.cc']
+hb_graphite2_headers = ['hb-graphite2.h']
+
+# System-dependent sources and headers
+
+hb_coretext_sources = ['hb-coretext.cc']
+hb_coretext_headers = ['hb-coretext.h']
+
+hb_directwrite_sources = ['hb-directwrite.cc']
+hb_directwrite_headers = ['hb-directwrite.h']
+
+hb_gdi_sources = ['hb-gdi.cc']
+hb_gdi_headers = ['hb-gdi.h']
+
+hb_uniscribe_sources = ['hb-uniscribe.cc']
+hb_uniscribe_headers = ['hb-uniscribe.h']
+
+# Sources for libharfbuzz-gobject and libharfbuzz-icu
+hb_icu_sources = ['hb-icu.cc']
+hb_icu_headers = ['hb-icu.h']
+
+# Sources for libharfbuzz-subset
+hb_subset_sources = [
+  'hb-number.cc',
+  'hb-number.hh',
+  'hb-ot-cff1-table.cc',
+  'hb-ot-cff2-table.cc',
+  'hb-static.cc',
+  'hb-subset-cff-common.cc',
+  'hb-subset-cff-common.hh',
+  'hb-subset-cff1.cc',
+  'hb-subset-cff1.hh',
+  'hb-subset-cff2.cc',
+  'hb-subset-cff2.hh',
+  'hb-subset-input.cc',
+  'hb-subset-input.hh',
+  'hb-subset-plan.cc',
+  'hb-subset-plan.hh',
+  'hb-subset-plan.hh',
+  'hb-subset.cc',
+  'hb-subset.hh',
+  'hb-subset.hh',
+]
+
+hb_subset_headers = ['hb-subset.h']
+
+hb_gobject_sources = [
+  'hb-gobject-structs.cc'
+]
+
+hb_gobject_headers = [
+  'hb-gobject.h',
+  'hb-gobject-structs.h',
+]
+
+incsrc = include_directories('.')
+
+hb_sources = hb_base_sources + hb_base_ragel_generated_sources
+hb_headers = hb_base_headers
+
+if conf.get('HAVE_FREETYPE', 0) == 1
+  hb_sources += hb_ft_sources
+  hb_headers += hb_ft_headers
+endif
+
+if conf.get('HAVE_GDI', 0) == 1
+  hb_sources += hb_gdi_sources
+  hb_headers += hb_gdi_headers
+endif
+
+if conf.get('HAVE_GRAPHITE2', 0) == 1
+  hb_sources += hb_graphite2_sources
+  hb_headers += hb_graphite2_headers
+endif
+
+if conf.get('HAVE_GLIB', 0) == 1
+  hb_sources += hb_glib_sources
+  hb_headers += hb_glib_headers
+endif
+
+if conf.get('HAVE_UNISCRIBE', 0) == 1
+  hb_sources += hb_uniscribe_sources
+  hb_headers += hb_uniscribe_headers
+endif
+
+if conf.get('HAVE_DIRECTWRITE', 0) == 1
+  hb_sources += hb_directwrite_sources
+  hb_headers += hb_directwrite_headers
+endif
+
+if conf.get('HAVE_CORETEXT', 0) == 1
+  hb_sources += hb_coretext_sources
+  hb_headers += hb_coretext_headers
+endif
+
+if get_option('amalgam')
+  # replace the array if is amalgam build
+  hb_sources = ['harfbuzz.cc']
+endif
+
+have_icu = conf.get('HAVE_ICU', 0) == 1
+have_icu_builtin = conf.get('HAVE_ICU_BUILTIN', 0) == 1
+
+if have_icu and have_icu_builtin
+  hb_sources += hb_icu_sources
+  hb_headers += hb_icu_headers
+  deps += [icu_dep]
+endif
+
+if host_machine.system() == 'windows' or get_option('with-libstdcxx')
+  chosen_linker = 'cpp'
+else
+  # our autotools port was limiting this to HAVE_GCC as https://github.com/harfbuzz/harfbuzz/commit/e784632
+  # let's see if that is needed anymore
+
+  # Use a C linker, not C++; Don't link to libstdc++
+  chosen_linker = 'c'
+endif
+
+# harfbuzz
+gen_def = find_program('gen-def.py')
+
+harfbuzz_def_command_args = [gen_def, '@OUTPUT@', '@INPUT@']
+if get_option('experimental-api')
+  harfbuzz_def_command_args += '--experimental-api'
+endif
+
+harfbuzz_def = custom_target('harfbuzz.def',
+    command: harfbuzz_def_command_args,
+    input: hb_headers,
+    output: 'harfbuzz.def')
+defs_list = [harfbuzz_def]
+
+version = '0.' + '0'.join(meson.project_version().split('.')) + '.0'
+
+extra_hb_cpp_args = []
+if cpp.get_id() == 'msvc'
+  if get_option('default_library') == 'shared'
+    extra_hb_cpp_args += '-DHB_DLL_EXPORT'
+  endif
+  hb_so_version = ''
+else
+  hb_so_version = '0'
+endif
+
+libharfbuzz = library('harfbuzz', hb_sources,
+  include_directories: incconfig,
+  dependencies: deps,
+  cpp_args: cpp_args + extra_hb_cpp_args,
+  soversion: hb_so_version,
+  version: version,
+  install: true,
+  link_language: chosen_linker,
+)
+
+libharfbuzz_dep = declare_dependency(
+  link_with: libharfbuzz,
+  include_directories: incsrc,
+  dependencies: deps)
+
+# harfbuzz-subset
+harfbuzz_subset_def = custom_target('harfbuzz-subset.def',
+    command: [gen_def, '@OUTPUT@', '@INPUT@'],
+    input: hb_subset_headers,
+    output: 'harfbuzz-subset.def')
+defs_list += [harfbuzz_subset_def]
+
+libharfbuzz_subset = library('harfbuzz-subset', hb_subset_sources,
+  include_directories: incconfig,
+  dependencies: deps,
+  link_with: [libharfbuzz],
+  cpp_args: cpp_args + extra_hb_cpp_args,
+  soversion: hb_so_version,
+  version: version,
+  install: true,
+  link_language: chosen_linker,
+)
+
+libharfbuzz_subset_dep = declare_dependency(
+  link_with: libharfbuzz_subset,
+  include_directories: incsrc,
+  dependencies: deps)
+
+if get_option('tests').enabled()
+  # TODO: MSVC gives the following,
+  # error LNK2019: unresolved external symbol "unsigned __int64 const * const _hb_NullPool"
+  if cpp.get_id() != 'msvc'
+    noinst_programs = {
+      'main': 'main.cc',
+      'test-basics': 'test.cc',
+      'test-buffer-serialize': 'test-buffer-serialize.cc',
+      'test-ot-meta': 'test-ot-meta.cc',
+      'test-ot-name': 'test-ot-name.cc',
+      'test-ot-glyphname': 'test-ot-glyphname.cc',
+      'test-ot-gpos-size-params': 'test-gpos-size-params.cc',
+      'test-ot-gsub-would-substitute': 'test-gsub-would-substitute.cc',
+    }
+    foreach name, source : noinst_programs
+      executable(name, source,
+        include_directories: incconfig,
+        cpp_args: cpp_args,
+        dependencies: libharfbuzz_dep,
+        install: false,
+      )
+    endforeach
+  endif
+
+  check_programs = {
+    'dump-indic-data': ['dump-indic-data.cc', 'hb-ot-shape-complex-indic-table.cc'],
+    'dump-khmer-data': ['dump-khmer-data.cc', 'hb-ot-shape-complex-indic-table.cc'],
+    'dump-myanmar-data': ['dump-myanmar-data.cc', 'hb-ot-shape-complex-indic-table.cc'],
+    'dump-use-data': ['dump-use-data.cc', 'hb-ot-shape-complex-use-table.cc'],
+  }
+  foreach name, source : check_programs
+    executable(name, source,
+      include_directories: incconfig,
+      cpp_args: cpp_args,
+      dependencies: libharfbuzz_dep,
+      install: false,
+    )
+  endforeach
+
+  compiled_tests = {
+    'test-array': 'test-array.cc',
+    'test-number': ['test-number.cc', 'hb-number.cc'],
+    'test-ot-tag': 'hb-ot-tag.cc',
+    'test-unicode-ranges': 'test-unicode-ranges.cc',
+  }
+  if cpp.get_id() != 'msvc'
+    # TODO: MSVC doesn't like these, fix them
+    compiled_tests += {
+      'test-algs': ['test-algs.cc', 'hb-static.cc'],
+      'test-bimap': ['test-bimap.cc', 'hb-static.cc'],
+      'test-iter': ['test-iter.cc', 'hb-static.cc'],
+      'test-meta': ['test-meta.cc', 'hb-static.cc'],
+    }
+  endif
+  foreach name, source : compiled_tests
+    test(name, executable(name, source,
+      include_directories: incconfig,
+      cpp_args: cpp_args + ['-DMAIN', '-UNDEBUG'],
+      dependencies: libharfbuzz_dep,
+      install: false,
+    ))
+  endforeach
+
+  if host_machine.system() != 'windows' and not meson.is_cross_build()
+    # Some of them should be ported to python
+    dist_check_script = [
+      'check-c-linkage-decls.sh',
+      'check-externs.sh',
+      'check-header-guards.sh',
+      'check-static-inits.sh',
+    ]
+    if not get_option('amalgam')
+      dist_check_script += 'check-includes.sh'
+    endif
+    if false and not get_option('with-libstdcxx')
+      # enable this once https://github.com/mesonbuild/meson/pull/6838 hits a release
+      # and make that version (i.e. 0.55) our minimum build requirement
+      dist_check_script += 'check-libstdc++.sh' # See https://github.com/harfbuzz/harfbuzz/issues/2276
+    endif
+
+    env = environment()
+    env.set('srcdir', meson.current_source_dir())
+    env.set('builddir', meson.current_build_dir())
+    env.set('libs', meson.current_build_dir()) # TODO: Merge this with builddir after autotools removal
+    env.set('HBSOURCES', ' '.join(hb_sources))
+    env.set('HBHEADERS', ' '.join(hb_headers))
+
+    foreach name : dist_check_script
+      test(name, find_program(name), env: env)
+    endforeach
+  endif
+endif
+
+pkgmod.generate(libharfbuzz,
+  description: 'HarfBuzz text shaping library',
+  subdirs: [meson.project_name()],
+  version: meson.project_version(),
+)
+
+pkgmod.generate(libharfbuzz_subset,
+  description: 'HarfBuzz font subsetter',
+  subdirs: [meson.project_name()],
+  version: meson.project_version(),
+)
+
+if have_icu and not have_icu_builtin
+  harfbuzz_icu_def = custom_target('harfbuzz-icu.def',
+    command: [gen_def, '@OUTPUT@', '@INPUT@'],
+    input: [hb_icu_headers],
+    output: 'harfbuzz-icu.def')
+  defs_list += [harfbuzz_icu_def]
+
+  libharfbuzz_icu = library('harfbuzz-icu', [hb_icu_sources, hb_icu_headers],
+    include_directories: incconfig,
+    dependencies: icu_dep,
+    link_with: [libharfbuzz],
+    cpp_args: cpp_args + extra_hb_cpp_args,
+    soversion: hb_so_version,
+    version: version,
+    install: true,
+    # ICU links to stdc++ anyway so the default linker is good
+    # link_language: chosen_linker,
+  )
+
+  libharfbuzz_icu_dep = declare_dependency(
+    link_with: libharfbuzz_icu,
+    include_directories: incsrc,
+    dependencies: deps)
+
+  pkgmod.generate(libharfbuzz_icu,
+    description: 'HarfBuzz text shaping library ICU integration',
+    subdirs: [meson.project_name()],
+    version: meson.project_version(),
+  )
+
+  install_headers(hb_icu_headers, subdir: meson.project_name())
+else
+  libharfbuzz_icu_dep = dependency('', required: false)
+endif
+
+have_gobject = conf.get('HAVE_GOBJECT', 0) == 1
+
+cmake_config = configuration_data()
+cmake_config.set('libdir', '${prefix}/@0@'.format(get_option('libdir')))
+cmake_config.set('includedir', '${prefix}/@0@'.format(get_option('includedir')))
+cmake_config.set('HB_LIBTOOL_VERSION_INFO', hb_libtool_version_info)
+cmake_config.set('have_gobject', have_gobject ? 'true' : 'false')
+configure_file(input: 'harfbuzz-config.cmake.in',
+  output: 'harfbuzz-config.cmake',
+  configuration: cmake_config,
+  install_dir: join_paths(get_option('libdir'), 'cmake', 'harfbuzz'))
+
+if have_gobject
+  gnome = import('gnome')
+
+  h_templ = configure_file(
+    input: 'hb-gobject-enums.h.tmpl',
+    output: 'hb-gobject-enums-tmp.h.tmpl',
+    configuration: configuration_data(),
+    format: 'cmake')
+
+  cc_templ = configure_file(
+    input: 'hb-gobject-enums.cc.tmpl',
+    output: 'hb-gobject-enums-tmp.cc.tmpl',
+    configuration: configuration_data(),
+    format: 'cmake')
+
+  enums = gnome.mkenums('hb-gobject',
+    sources: hb_headers,
+    h_template: h_templ,
+    c_template: cc_templ,
+    identifier_prefix: 'hb_',
+    symbol_prefix: 'hb_gobject',
+  )
+
+  enum_c = custom_target('hb-gobject-enums.cc',
+    input: enums[0],
+    output: 'hb-gobject-enums.cc',
+    command: [python3, files('fix_get_types.py')[0], '@INPUT@', '@OUTPUT@']
+  )
+
+  enum_h = custom_target('hb-gobject-enums.h',
+    input: enums[1],
+    output: 'hb-gobject-enums.h',
+    command: [python3, files('fix_get_types.py')[0], '@INPUT@', '@OUTPUT@'],
+    install: true,
+    install_dir: join_paths(get_option('prefix'), get_option('includedir'), meson.project_name()),
+  )
+
+  hb_gobject_sources += [enum_c]
+
+  harfbuzz_gobject_def = custom_target('harfbuzz-gobject.def',
+    command: [gen_def, '@OUTPUT@', '@INPUT@'],
+    input: [hb_gobject_headers, enum_h],
+    output: 'harfbuzz-gobject.def')
+  defs_list += [harfbuzz_gobject_def]
+
+  libharfbuzz_gobject = library('harfbuzz-gobject', [hb_gobject_sources, enum_c, enum_h],
+    include_directories: incconfig,
+    dependencies: deps,
+    link_with: [libharfbuzz],
+    cpp_args: cpp_args + extra_hb_cpp_args,
+    soversion: hb_so_version,
+    version: version,
+    install: true,
+    link_language: chosen_linker,
+  )
+
+  gir = find_program('g-ir-scanner', required: get_option('introspection'))
+  build_gir = gir.found() and not meson.is_cross_build()
+
+  if build_gir
+    hb_gen_files_gir = gnome.generate_gir(libharfbuzz, libharfbuzz_gobject,
+      sources: [hb_headers, hb_sources, hb_gobject_headers, hb_gobject_sources, enum_h],
+      namespace: 'HarfBuzz',
+      nsversion: '0.0',
+      identifier_prefix: 'hb_',
+      symbol_prefix: ['hb', 'hb_gobject'],
+      includes: ['GObject-2.0'],
+      export_packages: ['harfbuzz-gobject'],
+      header: 'hb-gobject.h',
+      install: true,
+      extra_args:  ['--cflags-begin',
+                    '-DHB_H',
+                    '-DHB_H_IN',
+                    '-DHB_OT_H',
+                    '-DHB_OT_H_IN',
+                    '-DHB_AAT_H',
+                    '-DHB_AAT_H_IN',
+                    '-DHB_GOBJECT_H',
+                    '-DHB_GOBJECT_H_IN',
+                    '-DHB_EXTERN=',
+                    '--cflags-end'])
+  endif
+
+  libharfbuzz_gobject_dep = declare_dependency(
+    link_with: libharfbuzz_gobject,
+    include_directories: incsrc,
+    sources: build_gir ? hb_gen_files_gir : hb_gobject_sources,
+    dependencies: deps)
+
+  pkgmod.generate(libharfbuzz_gobject,
+    description: 'HarfBuzz text shaping library GObject integration',
+    subdirs: [meson.project_name()],
+    version: meson.project_version(),
+  )
+
+  install_headers(hb_gobject_headers, subdir: meson.project_name())
+else
+  libharfbuzz_gobject_dep = dependency('', required: false)
+endif
+
+if get_option('tests').enabled() and host_machine.system() != 'windows' and not meson.is_cross_build()
+  test('check-symbols.sh', find_program('check-symbols.sh'),
+    depends: defs_list,
+    env: env)
+endif
+
+install_headers(hb_headers + hb_subset_headers, subdir: meson.project_name())

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-array.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-array.cc	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-array.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -0,0 +1,76 @@
+/*
+ * Copyright © 2020  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Garret Rieger
+ */
+
+#include "hb.hh"
+#include "hb-array.hh"
+
+static void
+test_reverse ()
+{
+  int values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+  hb_array_t<int> a (values, 9);
+  a.reverse();
+
+  int expected_values[] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
+  hb_array_t<int> expected (expected_values, 9);
+  assert (a == expected);
+}
+
+static void
+test_reverse_range ()
+{
+  int values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+  hb_array_t<int> a (values, 9);
+  a.reverse(2, 6);
+
+  int expected_values[] = {1, 2, 6, 5, 4, 3, 7, 8, 9};
+  hb_array_t<int> expected (expected_values, 9);
+  assert (a == expected);
+}
+
+static void
+test_reverse_invalid ()
+{
+  int values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+  hb_array_t<int> a (values, 9);
+
+  a.reverse(4, 3);
+  a.reverse(2, 3);
+  a.reverse(5, 5);
+  a.reverse(12, 15);
+
+  int expected_values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+  hb_array_t<int> expected (expected_values, 9);
+  assert (a == expected);
+}
+
+int
+main (int argc, char **argv)
+{
+  test_reverse ();
+  test_reverse_range ();
+  test_reverse_invalid ();
+}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-buffer-serialize.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-buffer-serialize.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-buffer-serialize.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -68,7 +68,7 @@
   buf = hb_buffer_create ();
 
   char line[BUFSIZ], out[BUFSIZ];
-  while (fgets (line, sizeof(line), stdin) != nullptr)
+  while (fgets (line, sizeof(line), stdin))
   {
     hb_buffer_clear_contents (buf);
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-iter.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-iter.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-iter.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -105,7 +105,7 @@
 template <typename Iterable,
 	  hb_requires (hb_is_iterable (Iterable))>
 static void
-test_iterable (const Iterable &lst = Null(Iterable))
+test_iterable (const Iterable &lst = Null (Iterable))
 {
   for (auto _ : lst)
     (void) _;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-meta.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-meta.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-meta.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -29,6 +29,8 @@
 
 #include <type_traits>
 
+template <typename T> struct U { typedef T type; };
+
 int
 main (int argc, char **argv)
 {
@@ -122,6 +124,9 @@
   static_assert (hb_is_trivial (X), "");
   static_assert (hb_is_trivial (Y), "");
 
+  static_assert (hb_is_signed (hb_unwrap_type (U<U<U<int>>>)), "");
+  static_assert (hb_is_unsigned (hb_unwrap_type (U<U<U<U<unsigned>>>>)), "");
+
   /* TODO Add more meaningful tests. */
 
   return 0;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-number.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-number.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-number.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -25,7 +25,6 @@
 
 #include "hb.hh"
 #include "hb-number.hh"
-#include "hb-number-parser.hh"
 
 
 int
@@ -146,11 +145,6 @@
     assert ((int) roundf (pv * 1000.) == 123);
     assert (pp - str == 4);
     assert (end - pp == 1);
-
-    /* Test strtod_rl even if libc's strtod_l is used */
-    char *pend;
-    assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
-    assert (pend - str == 4);
   }
 
   {
@@ -163,10 +157,6 @@
     assert ((int) roundf (pv * 1000.) == 123);
     assert (pp - str == 5);
     assert (end - pp == 0);
-
-    char *pend;
-    assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
-    assert (pend - str == 5);
   }
 
   {
@@ -179,10 +169,6 @@
     assert ((int) roundf (pv * 1000.) == 123);
     assert (pp - str == 7);
     assert (end - pp == 0);
-
-    char *pend;
-    assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
-    assert (pend - str == 7);
   }
 
   {
@@ -195,10 +181,6 @@
     assert ((int) roundf (pv * 1000.) == 123);
     assert (pp - str == 6);
     assert (end - pp == 0);
-
-    char *pend;
-    assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
-    assert (pend - str == 6);
   }
 
   {
@@ -211,10 +193,6 @@
     assert ((int) roundf (pv * 1000.) == 123);
     assert (pp - str == 10);
     assert (end - pp == 0);
-
-    char *pend;
-    assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
-    assert (pend - str == 10);
   }
 
   {
@@ -228,9 +206,6 @@
     assert (pp - str == 13);
     assert (end - pp == 0);
 
-    char *pend;
-    assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == -123);
-    assert (pend - str == 13);
   }
 
   {
@@ -243,10 +218,6 @@
     assert ((int) roundf (pv * 1000.) == -123);
     assert (pp - str == 8);
     assert (end - pp == 0);
-
-    char *pend;
-    assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == -123);
-    assert (pend - str == 8);
   }
 
   return 0;

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-ot-color.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-ot-color.cc	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-ot-color.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -1,348 +0,0 @@
-/*
- * Copyright © 2018  Ebrahim Byagowi
- * Copyright © 2018  Khaled Hosny
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "hb.hh"
-
-#include <cairo.h>
-
-#ifdef HB_NO_OPEN
-#define hb_blob_create_from_file(x)  hb_blob_get_empty ()
-#endif
-
-#if !defined(HB_NO_COLOR) && defined(CAIRO_HAS_SVG_SURFACE)
-
-#include "hb-ot.h"
-
-#include "hb-ft.h"
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_GLYPH_H
-
-#include <cairo-ft.h>
-#include <cairo-svg.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-
-static void
-svg_dump (hb_face_t *face, unsigned int face_index)
-{
-  unsigned glyph_count = hb_face_get_glyph_count (face);
-
-  for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++)
-  {
-    hb_blob_t *blob = hb_ot_color_glyph_reference_svg (face, glyph_id);
-
-    if (hb_blob_get_length (blob) == 0) continue;
-
-    unsigned int length;
-    const char *data = hb_blob_get_data (blob, &length);
-
-    char output_path[255];
-    sprintf (output_path, "out/svg-%u-%u.svg%s",
-	     glyph_id,
-	     face_index,
-	     // append "z" if the content is gzipped, https://stackoverflow.com/a/6059405
-	     (length > 2 && (data[0] == '\x1F') && (data[1] == '\x8B')) ? "z" : "");
-
-    FILE *f = fopen (output_path, "wb");
-    fwrite (data, 1, length, f);
-    fclose (f);
-
-    hb_blob_destroy (blob);
-  }
-}
-
-/* _png API is so easy to use unlike the below code, don't get confused */
-static void
-png_dump (hb_face_t *face, unsigned int face_index)
-{
-  unsigned glyph_count = hb_face_get_glyph_count (face);
-  hb_font_t *font = hb_font_create (face);
-
-  /* scans the font for strikes */
-  unsigned int sample_glyph_id;
-  /* we don't care about different strikes for different glyphs at this point */
-  for (sample_glyph_id = 0; sample_glyph_id < glyph_count; sample_glyph_id++)
-  {
-    hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id);
-    unsigned int blob_length = hb_blob_get_length (blob);
-    hb_blob_destroy (blob);
-    if (blob_length != 0)
-      break;
-  }
-
-  unsigned int upem = hb_face_get_upem (face);
-  unsigned int blob_length = 0;
-  unsigned int strike = 0;
-  for (unsigned int ppem = 1; ppem < upem; ppem++)
-  {
-    hb_font_set_ppem (font, ppem, ppem);
-    hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id);
-    unsigned int new_blob_length = hb_blob_get_length (blob);
-    hb_blob_destroy (blob);
-    if (new_blob_length != blob_length)
-    {
-      for (unsigned int glyph_id = 0; glyph_id < glyph_count; glyph_id++)
-      {
-	hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, glyph_id);
-
-	if (hb_blob_get_length (blob) == 0) continue;
-
-	unsigned int length;
-	const char *data = hb_blob_get_data (blob, &length);
-
-	char output_path[255];
-	sprintf (output_path, "out/png-%u-%u-%u.png", glyph_id, strike, face_index);
-
-	FILE *f = fopen (output_path, "wb");
-	fwrite (data, 1, length, f);
-	fclose (f);
-
-	hb_blob_destroy (blob);
-      }
-
-      strike++;
-      blob_length = new_blob_length;
-    }
-  }
-
-  hb_font_destroy (font);
-}
-
-static void
-layered_glyph_dump (hb_face_t *face, cairo_font_face_t *cairo_face, unsigned int face_index)
-{
-  unsigned int upem = hb_face_get_upem (face);
-
-  unsigned glyph_count = hb_face_get_glyph_count (face);
-  for (hb_codepoint_t gid = 0; gid < glyph_count; ++gid)
-  {
-    unsigned int num_layers = hb_ot_color_glyph_get_layers (face, gid, 0, nullptr, nullptr);
-    if (!num_layers)
-      continue;
-
-    hb_ot_color_layer_t *layers = (hb_ot_color_layer_t*) malloc (num_layers * sizeof (hb_ot_color_layer_t));
-
-    hb_ot_color_glyph_get_layers (face, gid, 0, &num_layers, layers);
-    if (num_layers)
-    {
-      // Measure
-      cairo_text_extents_t extents;
-      {
-	cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
-	cairo_t *cr = cairo_create (surface);
-	cairo_set_font_face (cr, cairo_face);
-	cairo_set_font_size (cr, upem);
-
-	cairo_glyph_t *glyphs = (cairo_glyph_t *) calloc (num_layers, sizeof (cairo_glyph_t));
-	for (unsigned int j = 0; j < num_layers; ++j)
-	  glyphs[j].index = layers[j].glyph;
-	cairo_glyph_extents (cr, glyphs, num_layers, &extents);
-	free (glyphs);
-	cairo_surface_destroy (surface);
-	cairo_destroy (cr);
-      }
-
-      // Add a slight margin
-      extents.width += extents.width / 10;
-      extents.height += extents.height / 10;
-      extents.x_bearing -= extents.width / 20;
-      extents.y_bearing -= extents.height / 20;
-
-      // Render
-      unsigned int palette_count = hb_ot_color_palette_get_count (face);
-      for (unsigned int palette = 0; palette < palette_count; palette++)
-      {
-	unsigned int num_colors = hb_ot_color_palette_get_colors (face, palette, 0, nullptr, nullptr);
-	if (!num_colors)
-	  continue;
-
-	hb_color_t *colors = (hb_color_t*) calloc (num_colors, sizeof (hb_color_t));
-	hb_ot_color_palette_get_colors (face, palette, 0, &num_colors, colors);
-	if (num_colors)
-	{
-	  char output_path[255];
-	  sprintf (output_path, "out/colr-%u-%u-%u.svg", gid, palette, face_index);
-
-	  cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height);
-	  cairo_t *cr = cairo_create (surface);
-	  cairo_set_font_face (cr, cairo_face);
-	  cairo_set_font_size (cr, upem);
-
-	  for (unsigned int layer = 0; layer < num_layers; ++layer)
-	  {
-	    hb_color_t color = 0x000000FF;
-	    if (layers[layer].color_index != 0xFFFF)
-	      color = colors[layers[layer].color_index];
-	    cairo_set_source_rgba (cr,
-				   hb_color_get_red (color) / 255.,
-				   hb_color_get_green (color) / 255.,
-				   hb_color_get_blue (color) / 255.,
-				   hb_color_get_alpha (color) / 255.);
-
-	    cairo_glyph_t glyph;
-	    glyph.index = layers[layer].glyph;
-	    glyph.x = -extents.x_bearing;
-	    glyph.y = -extents.y_bearing;
-	    cairo_show_glyphs (cr, &glyph, 1);
-	  }
-
-	  cairo_surface_destroy (surface);
-	  cairo_destroy (cr);
-	}
-	free (colors);
-      }
-    }
-
-    free (layers);
-  }
-}
-
-static void
-dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem,
-	     unsigned int num_glyphs, unsigned int face_index)
-{
-  for (unsigned int i = 0; i < num_glyphs; ++i)
-  {
-    cairo_text_extents_t extents;
-    cairo_glyph_t glyph = {0};
-    glyph.index = i;
-
-    // Measure
-    {
-      cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
-      cairo_t *cr = cairo_create (surface);
-      cairo_set_font_face (cr, cairo_face);
-      cairo_set_font_size (cr, upem);
-
-      cairo_glyph_extents (cr, &glyph, 1, &extents);
-      cairo_surface_destroy (surface);
-      cairo_destroy (cr);
-    }
-
-    // Add a slight margin
-    extents.width += extents.width / 10;
-    extents.height += extents.height / 10;
-    extents.x_bearing -= extents.width / 20;
-    extents.y_bearing -= extents.height / 20;
-
-    // Render
-    {
-      char output_path[255];
-      sprintf (output_path, "out/%u-%u.svg", face_index, i);
-      cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height);
-      cairo_t *cr = cairo_create (surface);
-      cairo_set_font_face (cr, cairo_face);
-      cairo_set_font_size (cr, upem);
-      glyph.x = -extents.x_bearing;
-      glyph.y = -extents.y_bearing;
-      cairo_show_glyphs (cr, &glyph, 1);
-      cairo_surface_destroy (surface);
-      cairo_destroy (cr);
-    }
-  }
-}
-
-int
-main (int argc, char **argv)
-{
-  if (argc != 2) {
-    fprintf (stderr, "usage: %s font-file.ttf\n"
-		     "run it like `rm -rf out && mkdir out && %s font-file.ttf`\n",
-		     argv[0], argv[0]);
-    exit (1);
-  }
-
-
-  FILE *font_name_file = fopen ("out/.dumped_font_name", "r");
-  if (font_name_file != nullptr)
-  {
-    fprintf (stderr, "Purge or move ./out folder in order to run a new dump\n");
-    exit (1);
-  }
-
-  font_name_file = fopen ("out/.dumped_font_name", "w");
-  if (font_name_file == nullptr)
-  {
-    fprintf (stderr, "./out is not accessible as a folder, create it please\n");
-    exit (1);
-  }
-  fwrite (argv[1], 1, strlen (argv[1]), font_name_file);
-  fclose (font_name_file);
-
-  hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
-  unsigned int num_faces = hb_face_count (blob);
-  if (num_faces == 0)
-  {
-    fprintf (stderr, "error: The file (%s) was corrupted, empty or not found", argv[1]);
-    exit (1);
-  }
-
-  for (unsigned int face_index = 0; face_index < hb_face_count (blob); face_index++)
-  {
-    hb_face_t *face = hb_face_create (blob, face_index);
-    hb_font_t *font = hb_font_create (face);
-
-    if (hb_ot_color_has_png (face)) printf ("Dumping png (cbdt/sbix)...\n");
-    png_dump (face, face_index);
-
-    if (hb_ot_color_has_svg (face)) printf ("Dumping svg...\n");
-    svg_dump (face, face_index);
-
-    cairo_font_face_t *cairo_face;
-    {
-      FT_Library library;
-      FT_Init_FreeType (&library);
-      FT_Face ft_face;
-      FT_New_Face (library, argv[1], 0, &ft_face);
-      cairo_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0);
-    }
-    if (hb_ot_color_has_layers (face) && hb_ot_color_has_palettes (face))
-      printf ("Dumping layered color glyphs...\n");
-    layered_glyph_dump (face, cairo_face, face_index);
-
-    unsigned int num_glyphs = hb_face_get_glyph_count (face);
-    unsigned int upem = hb_face_get_upem (face);
-
-    // disabled when color font as cairo rendering of NotoColorEmoji is soooo slow
-    if (!hb_ot_color_has_layers (face) &&
-	!hb_ot_color_has_png (face) &&
-	!hb_ot_color_has_svg (face))
-      dump_glyphs (cairo_face, upem, num_glyphs, face_index);
-
-    hb_font_destroy (font);
-    hb_face_destroy (face);
-    }
-
-  hb_blob_destroy (blob);
-
-  return 0;
-}
-
-#else
-int main (int argc, char **argv) { return 0; }
-#endif

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-ot-glyphname.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-ot-glyphname.cc	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-ot-glyphname.cc	2020-05-18 10:44:36 UTC (rev 55197)
@@ -0,0 +1,91 @@
+/*
+ * Copyright © 2019  Adobe, 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.
+ *
+ * Adobe Author(s): Michiharu Ariza
+ */
+
+#include "hb.hh"
+#include "hb-ot.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef HB_NO_OPEN
+#define hb_blob_create_from_file(x)  hb_blob_get_empty ()
+#endif
+
+int
+main (int argc, char **argv)
+{
+  if (argc != 2) {
+    fprintf (stderr, "usage: %s font-file\n", argv[0]);
+    exit (1);
+  }
+
+  hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
+  hb_face_t *face = hb_face_create (blob, 0 /* first face */);
+  hb_font_t *font = hb_font_create (face);
+  hb_blob_destroy (blob);
+  blob = nullptr;
+  
+
+  const unsigned int num_glyphs = hb_face_get_glyph_count (face);
+  int	result = 1;
+
+  for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++)
+  {
+    char buf[64];
+    unsigned int buf_size = sizeof (buf);
+    if (hb_font_get_glyph_name (font, gid, buf, buf_size))
+    {
+      hb_codepoint_t	gid_inv;
+      if (hb_font_get_glyph_from_name(font, buf, strlen (buf), &gid_inv))
+      {
+	if (gid == gid_inv)
+	{
+	  printf ("%u <-> %s\n", gid, buf);
+	}
+	else
+	{
+	  printf ("%u -> %s -> %u\n", gid, buf, gid_inv);
+	  result = 0;
+	}
+      }
+      else
+      {
+	printf ("%u -> %s -> ?\n", gid, buf);
+	result = 0;
+      }
+    }
+    else
+    {
+      printf ("%u -> ?\n", gid);
+      result = 0;
+    }
+  }
+
+  hb_font_destroy (font);
+  hb_face_destroy (face);
+
+  return result;
+}

Modified: trunk/Build/source/libs/harfbuzz/include/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/include/Makefile.am	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/include/Makefile.am	2020-05-18 10:44:36 UTC (rev 55197)
@@ -20,6 +20,7 @@
 	$(HARFBUZZ_SRC)/hb-buffer.h \
 	$(HARFBUZZ_SRC)/hb-common.h \
 	$(HARFBUZZ_SRC)/hb-deprecated.h \
+	$(HARFBUZZ_SRC)/hb-draw.h \
 	$(HARFBUZZ_SRC)/hb-face.h \
 	$(HARFBUZZ_SRC)/hb-font.h \
 	$(HARFBUZZ_SRC)/hb-map.h \

Modified: trunk/Build/source/libs/harfbuzz/include/Makefile.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/include/Makefile.in	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/include/Makefile.in	2020-05-18 10:44:36 UTC (rev 55197)
@@ -248,17 +248,17 @@
 hdr_links = $(HARFBUZZ_SRC)/hb.h $(HARFBUZZ_SRC)/hb-aat-layout.h \
 	$(HARFBUZZ_SRC)/hb-aat.h $(HARFBUZZ_SRC)/hb-blob.h \
 	$(HARFBUZZ_SRC)/hb-buffer.h $(HARFBUZZ_SRC)/hb-common.h \
-	$(HARFBUZZ_SRC)/hb-deprecated.h $(HARFBUZZ_SRC)/hb-face.h \
-	$(HARFBUZZ_SRC)/hb-font.h $(HARFBUZZ_SRC)/hb-map.h \
-	$(HARFBUZZ_SRC)/hb-ot-deprecated.h $(HARFBUZZ_SRC)/hb-set.h \
-	$(HARFBUZZ_SRC)/hb-shape.h $(HARFBUZZ_SRC)/hb-shape-plan.h \
-	$(HARFBUZZ_SRC)/hb-unicode.h $(HARFBUZZ_BLD)/hb-version.h \
-	$(HARFBUZZ_SRC)/hb-ot.h $(HARFBUZZ_SRC)/hb-ot-color.h \
-	$(HARFBUZZ_SRC)/hb-ot-font.h $(HARFBUZZ_SRC)/hb-ot-layout.h \
-	$(HARFBUZZ_SRC)/hb-ot-math.h $(HARFBUZZ_SRC)/hb-ot-meta.h \
-	$(HARFBUZZ_SRC)/hb-ot-metrics.h $(HARFBUZZ_SRC)/hb-ot-name.h \
-	$(HARFBUZZ_SRC)/hb-ot-shape.h $(HARFBUZZ_SRC)/hb-ot-var.h \
-	$(HARFBUZZ_SRC)/hb-graphite2.h
+	$(HARFBUZZ_SRC)/hb-deprecated.h $(HARFBUZZ_SRC)/hb-draw.h \
+	$(HARFBUZZ_SRC)/hb-face.h $(HARFBUZZ_SRC)/hb-font.h \
+	$(HARFBUZZ_SRC)/hb-map.h $(HARFBUZZ_SRC)/hb-ot-deprecated.h \
+	$(HARFBUZZ_SRC)/hb-set.h $(HARFBUZZ_SRC)/hb-shape.h \
+	$(HARFBUZZ_SRC)/hb-shape-plan.h $(HARFBUZZ_SRC)/hb-unicode.h \
+	$(HARFBUZZ_BLD)/hb-version.h $(HARFBUZZ_SRC)/hb-ot.h \
+	$(HARFBUZZ_SRC)/hb-ot-color.h $(HARFBUZZ_SRC)/hb-ot-font.h \
+	$(HARFBUZZ_SRC)/hb-ot-layout.h $(HARFBUZZ_SRC)/hb-ot-math.h \
+	$(HARFBUZZ_SRC)/hb-ot-meta.h $(HARFBUZZ_SRC)/hb-ot-metrics.h \
+	$(HARFBUZZ_SRC)/hb-ot-name.h $(HARFBUZZ_SRC)/hb-ot-shape.h \
+	$(HARFBUZZ_SRC)/hb-ot-var.h $(HARFBUZZ_SRC)/hb-graphite2.h
 all: all-am
 
 .SUFFIXES:

Modified: trunk/Build/source/libs/harfbuzz/version.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/version.ac	2020-05-17 22:58:24 UTC (rev 55196)
+++ trunk/Build/source/libs/harfbuzz/version.ac	2020-05-18 10:44:36 UTC (rev 55197)
@@ -8,4 +8,4 @@
 dnl --------------------------------------------------------
 dnl
 dnl  m4-include this file to define the current harfbuzz version
-m4_define([harfbuzz_version], [2.6.4])
+m4_define([harfbuzz_version], [2.6.6])



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