diff --git a/source/configure b/source/configure
index 046037f8a176ef1e659ab17d96f8b4a3c0c29bd0..5e2e2edfaa605b6d078a0404cec32c9bcc430f0b 100755
--- a/source/configure
+++ b/source/configure
@@ -817,6 +817,23 @@ enable_native_texlive_build
 enable_multiplatform
 enable_cxx_runtime_hack
 enable_libtool_hack
+enable_autosp
+enable_axodraw2
+enable_devnag
+enable_lacheck
+enable_m_tx
+enable_pmx
+enable_ps2eps
+enable_t1utils
+enable_texdoctk
+enable_tpic2pdftex
+enable_vlna
+enable_xindy
+enable_xindy_rules
+enable_xindy_docs
+with_clisp_runtime
+enable_xml2pmx
+enable_xpdfopen
 enable_web2c
 with_banner_add
 with_editor
@@ -865,15 +882,84 @@ enable_tektronixwin
 enable_unitermwin
 enable_web_progs
 enable_synctex
+enable_afm2pl
+enable_bibtex_x
+enable_bibtex8
+enable_bibtexu
+enable_chktex
+enable_cjkutils
+enable_detex
+enable_dtl
+enable_dvi2tty
+enable_dvidvi
+enable_dviljk
+enable_dviout_util
+enable_dvipdfm_x
+enable_dvipng
+enable_debug
+enable_timing
+with_gs
+enable_dvipos
+enable_dvipsk
+enable_dvisvgm
+enable_gregorio
+enable_gsftopk
+enable_lcdf_typetools
+enable_cfftot1
+enable_mmafm
+enable_mmpfb
+enable_otfinfo
+enable_otftotfm
+enable_t1dotlessj
+enable_t1lint
+enable_t1rawafm
+enable_t1reencode
+enable_t1testpage
+enable_ttftotype42
+enable_updmap
+enable_makeindexk
+enable_makejvf
+enable_mendexk
+enable_musixtnt
+enable_ps2pk
+enable_psutils
+enable_seetexk
+enable_tex4htk
+enable_ttf2pk2
+enable_ttfdump
+enable_upmendex
+enable_xdvik
+with_xdvi_x_toolkit
 enable_texlive
 enable_linked_scripts
 with_system_harfbuzz
+with_system_icu
+with_system_teckit
 with_system_graphite2
 with_system_zziplib
+with_system_mpfr
+with_mpfr_includes
+with_mpfr_libdir
+with_system_gmp
+with_gmp_includes
+with_gmp_libdir
+with_system_cairo
+with_system_pixman
+with_system_gd
+with_gd_includes
+with_gd_libdir
+with_system_potrace
+with_potrace_includes
+with_potrace_libdir
+with_system_freetype2
 with_system_libpng
+with_system_libpaper
+with_libpaper_includes
+with_libpaper_libdir
 with_system_zlib
 with_zlib_includes
 with_zlib_libdir
+with_system_ptexenc
 with_system_kpathsea
 enable_mktexmf_default
 enable_mktexpk_default
@@ -1553,6 +1639,22 @@ Optional Features:
                           lib/PLATFORM
   --enable-cxx-runtime-hack  link C++ runtime statically
   --enable-libtool-hack   ignore libtool dependency_libs
+  --disable-autosp        do not build the autosp package
+  --disable-axodraw2      do not build the axodraw2 package
+  --disable-devnag        do not build the devnag package
+  --disable-lacheck       do not build the lacheck package
+  --disable-m-tx          do not build the m-tx package
+  --disable-pmx           do not build the pmx package
+  --disable-ps2eps        do not build the ps2eps package
+  --disable-t1utils       do not build the t1utils package
+  --disable-texdoctk      do not build the texdoctk package
+  --disable-tpic2pdftex   do not build the tpic2pdftex package
+  --disable-vlna          do not build the vlna package
+  --enable-xindy          build the xindy package
+  --enable-xindy-rules      build and install make-rules package
+  --enable-xindy-docs       build and install documentation
+  --disable-xml2pmx       do not build the xml2pmx package
+  --disable-xpdfopen      do not build the xpdfopen package
   --disable-web2c         do not build the web2c (TeX & Co.) package
   --enable-auto-core        cause TeX&MF to dump core, given a certain
                             filename
@@ -1601,6 +1703,57 @@ Optional Features:
   --enable-unitermwin         include Uniterm window support
   --disable-web-progs       do not build WEB programs bibtex ... weave
   --disable-synctex         do not build the SyncTeX library and tool
+  --disable-afm2pl        do not build the afm2pl package
+  --disable-bibtex-x      do not build the bibtex-x package
+  --disable-bibtex8         do not build the bibtex8 program
+  --disable-bibtexu         do not build the bibtexu program
+  --disable-chktex        do not build the chktex package
+  --disable-cjkutils      do not build the cjkutils package
+  --disable-detex         do not build the detex package
+  --disable-dtl           do not build the dtl package
+  --disable-dvi2tty       do not build the dvi2tty package
+  --disable-dvidvi        do not build the dvidvi package
+  --disable-dviljk        do not build the dviljk package
+  --disable-dviout-util   do not build the dviout-util package
+  --disable-dvipdfm-x     do not build the dvipdfm-x package
+  --disable-dvipng        do not build the dvipng package
+  --disable-debug           Compile without debug (-d) option
+  --enable-timing           Output execution time of dvipng
+  --disable-dvipos        do not build the dvipos package
+  --disable-dvipsk        do not build the dvipsk package
+  --disable-dvisvgm       do not build the dvisvgm package
+  --disable-gregorio      do not build the gregorio package
+  --disable-gsftopk       do not build the gsftopk package
+  --disable-lcdf-typetools
+                          do not build the lcdf-typetools package
+  --disable-cfftot1         do not build the cfftot1 program
+  --disable-mmafm           do not build the mmafm program
+  --disable-mmpfb           do not build the mmpfb program
+  --disable-otfinfo         do not build the otfinfo program
+  --disable-otftotfm        do not build the otftotfm program
+  --disable-t1dotlessj      do not build the t1dotlessj program
+  --disable-t1lint          do not build the t1lint program
+  --disable-t1rawafm        do not build the t1rawafm program
+  --disable-t1reencode      do not build the t1reencode program
+  --disable-t1testpage      do not build the t1testpage program
+  --disable-ttftotype42     do not build the ttftotype42 program
+  --disable-auto-cfftot1    disable running cfftot1 from otftotfm
+  --disable-auto-t1dotlessj disable running t1dotlessj from otftotfm
+  --disable-auto-ttftotype42
+                            disable running ttftotype42 from otftotfm
+  --disable-auto-updmap     disable running updmap from otftotfm
+  --disable-makeindexk    do not build the makeindexk package
+  --disable-makejvf       do not build the makejvf package
+  --disable-mendexk       do not build the mendexk package
+  --disable-musixtnt      do not build the musixtnt package
+  --disable-ps2pk         do not build the ps2pk package
+  --disable-psutils       do not build the psutils package
+  --disable-seetexk       do not build the seetexk package
+  --disable-tex4htk       do not build the tex4htk package
+  --disable-ttf2pk2       do not build the ttf2pk2 package
+  --disable-ttfdump       do not build the ttfdump package
+  --disable-upmendex      do not build the upmendex package
+  --disable-xdvik         do not build the xdvik package
   --disable-texlive       do not build the texlive (TeX Live scripts) package
   --disable-linked-scripts  do not install the linked scripts
   --disable-mktexmf-default   do not run mktexmf if MF source missing
@@ -1632,22 +1785,62 @@ Optional Features:
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-clisp-runtime=PATH
+                          pathname of clisp runtime to install for `xindy',
+                          `default' to derive from clisp, or `system' to use
+                          installed version
   --with-banner-add=STR   add STR to version string appended to banner lines
   --with-editor=CMD       invoke CMD from the `e' option [vi +%d '%s'] or
                           [texworks --position=%d "%s"]
   --with-mf-x-toolkit     use X toolkit for METAFONT
+  --with-gs=/PATH/TO/gs   Hard-wire the location of GhostScript
+  --with-xdvi-x-toolkit=KIT
+                          Use toolkit KIT (xaw/motif/xaw3d/neXtaw) for xdvi
+                          [default: Xaw]
   --with-system-harfbuzz  use installed harfbuzz headers and library (requires
                           pkg-config)
+  --with-system-icu       use installed ICU headers and libraries (requires
+                          pkg-config or icu-config)
+  --with-system-teckit    use installed teckit headers and library (requires
+                          pkg-config)
   --with-system-graphite2 use installed graphite2 headers and library
                           (requires pkg-config)
   --with-system-zziplib   use installed zziplib headers and library (requires
                           pkg-config)
+  --with-system-mpfr      use installed mpfr headers and library
+  --with-mpfr-includes=DIR
+                          mpfr headers installed in DIR
+  --with-mpfr-libdir=DIR  mpfr library installed in DIR
+  --with-system-gmp       use installed gmp headers and library
+  --with-gmp-includes=DIR gmp headers installed in DIR
+  --with-gmp-libdir=DIR   gmp library installed in DIR
+  --with-system-cairo     use installed cairo headers and library (requires
+                          pkg-config)
+  --with-system-pixman    use installed pixman headers and library (requires
+                          pkg-config)
+  --with-system-gd        use installed gd headers and library
+  --with-gd-includes=DIR  gd headers installed in DIR
+  --with-gd-libdir=DIR    gd library installed in DIR
+  --with-system-potrace   use installed potrace headers and library
+  --with-potrace-includes=DIR
+                          potrace headers installed in DIR
+  --with-potrace-libdir=DIR
+                          potrace library installed in DIR
+  --with-system-freetype2 use installed freetype2 headers and library
+                          (requires freetype-config)
   --with-system-libpng    use installed libpng headers and library (requires
                           pkg-config)
+  --with-system-libpaper  use installed libpaper headers and library
+  --with-libpaper-includes=DIR
+                          libpaper headers installed in DIR
+  --with-libpaper-libdir=DIR
+                          libpaper library installed in DIR
   --with-system-zlib      use installed zlib headers and library
   --with-zlib-includes=DIR
                           zlib headers installed in DIR
   --with-zlib-libdir=DIR  zlib library installed in DIR
+  --with-system-ptexenc   use installed ptexenc headers and library (requires
+                          pkg-config)
   --with-system-kpathsea  use installed kpathsea headers and library (requires
                           pkg-config)
   --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
@@ -4788,6 +4981,332 @@ printf "%s\n" "$as_me: $host -> \`--disable-mfluajit-nowin'" >&6;}
 esac ;;
 esac
 
+## utils/autosp/ac/withenable.ac: configure.ac fragment for Tl subdir
+## configure options and TL libraries required for autosp.
+# Check whether --enable-autosp was given.
+if test ${enable_autosp+y}
+then :
+  enableval=$enable_autosp;
+fi
+case $enable_autosp in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_autosp=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-autosp=$enable_autosp'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-autosp=$enable_autosp'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-autosp=$enable_autosp'"
+    ;;
+esac
+
+## utils/axodraw2/ac/withenable.ac: configure.ac fragment for TL subdir
+## configure options and TL libraries for axodraw2.
+# Check whether --enable-axodraw2 was given.
+if test ${enable_axodraw2+y}
+then :
+  enableval=$enable_axodraw2;
+fi
+case $enable_axodraw2 in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_axodraw2=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-axodraw2=$enable_axodraw2'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-axodraw2=$enable_axodraw2'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-axodraw2=$enable_axodraw2'"
+    ;;
+esac
+
+## utils/devnag/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/devnag/
+## configure options and TL libraries required for devnag
+# Check whether --enable-devnag was given.
+if test ${enable_devnag+y}
+then :
+  enableval=$enable_devnag;
+fi
+case $enable_devnag in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_devnag=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-devnag=$enable_devnag'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-devnag=$enable_devnag'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-devnag=$enable_devnag'"
+    ;;
+esac
+
+## utils/lacheck/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/lacheck/
+## configure options and TL libraries required for lacheck
+# Check whether --enable-lacheck was given.
+if test ${enable_lacheck+y}
+then :
+  enableval=$enable_lacheck;
+fi
+case $enable_lacheck in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_lacheck=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-lacheck=$enable_lacheck'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-lacheck=$enable_lacheck'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-lacheck=$enable_lacheck'"
+    ;;
+esac
+
+## utils/m-tx/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/m-tx/
+## configure options and TL libraries required for mtx
+# Check whether --enable-m-tx was given.
+if test ${enable_m_tx+y}
+then :
+  enableval=$enable_m_tx;
+fi
+case $enable_m_tx in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_m_tx=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-m-tx=$enable_m_tx'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-m-tx=$enable_m_tx'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-m-tx=$enable_m_tx'"
+    ;;
+esac
+
+## utils/pmx/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/pmx/
+## configure options and TL libraries required for pmx
+# Check whether --enable-pmx was given.
+if test ${enable_pmx+y}
+then :
+  enableval=$enable_pmx;
+fi
+case $enable_pmx in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_pmx=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-pmx=$enable_pmx'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-pmx=$enable_pmx'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-pmx=$enable_pmx'"
+    ;;
+esac
+
+## utils/ps2eps/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/ps2eps/
+## configure options and TL libraries required for ps2eps
+# Check whether --enable-ps2eps was given.
+if test ${enable_ps2eps+y}
+then :
+  enableval=$enable_ps2eps;
+fi
+case $enable_ps2eps in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_ps2eps=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-ps2eps=$enable_ps2eps'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-ps2eps=$enable_ps2eps'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-ps2eps=$enable_ps2eps'"
+    ;;
+esac
+
+## utils/t1utils/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/t1utils/
+## configure options and TL libraries required for t1utils
+# Check whether --enable-t1utils was given.
+if test ${enable_t1utils+y}
+then :
+  enableval=$enable_t1utils;
+fi
+case $enable_t1utils in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_t1utils=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-t1utils=$enable_t1utils'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-t1utils=$enable_t1utils'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-t1utils=$enable_t1utils'"
+    ;;
+esac
+
+## utils/texdoctk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/texdoctk/
+## configure options and TL libraries required for texdoctk
+# Check whether --enable-texdoctk was given.
+if test ${enable_texdoctk+y}
+then :
+  enableval=$enable_texdoctk;
+fi
+case $enable_texdoctk in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_texdoctk=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-texdoctk=$enable_texdoctk'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-texdoctk=$enable_texdoctk'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-texdoctk=$enable_texdoctk'"
+    ;;
+esac
+
+## utils/tpic2pdftex/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/tpic2pdftex/
+## configure options and TL libraries required for tpic2pdftex
+# Check whether --enable-tpic2pdftex was given.
+if test ${enable_tpic2pdftex+y}
+then :
+  enableval=$enable_tpic2pdftex;
+fi
+case $enable_tpic2pdftex in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_tpic2pdftex=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-tpic2pdftex=$enable_tpic2pdftex'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-tpic2pdftex=$enable_tpic2pdftex'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-tpic2pdftex=$enable_tpic2pdftex'"
+    ;;
+esac
+
+## utils/vlna/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/vlna/
+## configure options and TL libraries required for vlna
+# Check whether --enable-vlna was given.
+if test ${enable_vlna+y}
+then :
+  enableval=$enable_vlna;
+fi
+case $enable_vlna in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_vlna=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-vlna=$enable_vlna'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-vlna=$enable_vlna'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-vlna=$enable_vlna'"
+    ;;
+esac
+
+## utils/xindy/ac/withenable.ac: configure.ac fragment for TL subdir
+## configure options and TL libraries required for xindy.
+# Check whether --enable-xindy was given.
+if test ${enable_xindy+y}
+then :
+  enableval=$enable_xindy;
+fi
+case $enable_xindy in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_xindy=no
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-xindy=$enable_xindy'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-xindy=$enable_xindy'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-xindy=$enable_xindy'"
+    ;;
+esac
+
+## utils/xindy/ac/xindy.ac: configure.ac fragment for the TeX Live subdirectory utils/xindy/
+## configure options for xindy
+# Check whether --enable-xindy-rules was given.
+if test ${enable_xindy_rules+y}
+then :
+  enableval=$enable_xindy_rules;
+fi
+# Check whether --enable-xindy-docs was given.
+if test ${enable_xindy_docs+y}
+then :
+  enableval=$enable_xindy_docs;
+fi
+
+# Check whether --with-clisp-runtime was given.
+if test ${with_clisp_runtime+y}
+then :
+  withval=$with_clisp_runtime;
+fi
+
+## utils/xindy/ac/clisp.ac: configure.ac fragment for the TeX Live subdirectory utils/xindy/
+## configure checks for xindy and clisp
+case $with_clisp_runtime in #(
+  default) :
+     ;; #(
+  system) :
+    if test "x$enable_native_texlive_build" = xyes
+then :
+  as_fn_error $? "you can not use the installed clisp for a native TeX Live build" "$LINENO" 5
+fi ;; #(
+  "") :
+    if test "x$enable_native_texlive_build" = xyes
+then :
+  with_clisp_runtime=default
+else $as_nop
+  with_clisp_runtime=system
+fi
+               { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--with-clisp-runtime=$with_clisp_runtime'" >&5
+printf "%s\n" "$as_me: Assuming \`--with-clisp-runtime=$with_clisp_runtime'" >&6;}
+               ac_configure_args="$ac_configure_args '--with-clisp-runtime=$with_clisp_runtime'" ;; #(
+  *) :
+    if test ! -f "$with_clisp_runtime"
+then :
+  as_fn_error $? "no such file: \"$with_clisp_runtime\"" "$LINENO" 5
+fi ;;
+esac
+
+## utils/xml2pmx/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/xml2pmx/
+## configure options and TL libraries required for xml2pmx
+# Check whether --enable-xml2pmx was given.
+if test ${enable_xml2pmx+y}
+then :
+  enableval=$enable_xml2pmx;
+fi
+case $enable_xml2pmx in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_xml2pmx=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-xml2pmx=$enable_xml2pmx'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-xml2pmx=$enable_xml2pmx'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-xml2pmx=$enable_xml2pmx'"
+    ;;
+esac
+
+## utils/xpdfopen/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory utils/xpdfopen/
+## configure options and TL libraries required for xpdfopen
+# Check whether --enable-xpdfopen was given.
+if test ${enable_xpdfopen+y}
+then :
+  enableval=$enable_xpdfopen;
+fi
+if test "x$with_x" = xno
+then :
+  case $enable_xpdfopen in #(
+  "") :
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \`--without-x' -> \`--disable-xpdfopen'" >&5
+printf "%s\n" "$as_me: \`--without-x' -> \`--disable-xpdfopen'" >&6;}
+                      enable_xpdfopen=no
+                      ac_configure_args="$ac_configure_args '--disable-xpdfopen'" ;; #(
+  yes) :
+    as_fn_error $? "Sorry, incompatible options \`--without-x' and \`--enable-xpdfopen'" "$LINENO" 5 ;; #(
+  *) :
+     ;;
+esac
+fi
+case $enable_xpdfopen in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_xpdfopen=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-xpdfopen=$enable_xpdfopen'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-xpdfopen=$enable_xpdfopen'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-xpdfopen=$enable_xpdfopen'"
+    ;;
+esac
+
 
 ## texk/web2c/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/web2c/
 ## configure options and TL libraries required for web2c
@@ -5310,107 +5829,1038 @@ then :
 fi
 
 
-## texk/texlive/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/texlive/
-## configure options and TL libraries required for texlive
-# Check whether --enable-texlive was given.
-if test ${enable_texlive+y}
+## texk/afm2pl/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/afm2pl/
+## configure options and TL libraries required for afm2pl
+# Check whether --enable-afm2pl was given.
+if test ${enable_afm2pl+y}
 then :
-  enableval=$enable_texlive;
+  enableval=$enable_afm2pl;
 fi
-case $enable_texlive in #(
+case $enable_afm2pl in #(
   yes|no) :
      ;; #(
   *) :
 
-   enable_texlive=$enable_all_pkgs
-     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-texlive=$enable_texlive'" >&5
-printf "%s\n" "$as_me: Assuming \`--enable-texlive=$enable_texlive'" >&6;}
-     ac_configure_args="$ac_configure_args '--enable-texlive=$enable_texlive'"
+   enable_afm2pl=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-afm2pl=$enable_afm2pl'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-afm2pl=$enable_afm2pl'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-afm2pl=$enable_afm2pl'"
     ;;
 esac
 
-## texk/texlive/ac/texlive.ac: configure.ac fragment for the TeX Live subdirectory texk/texlive/
-## configure options for texlive
-# Check whether --enable-linked-scripts was given.
-if test ${enable_linked_scripts+y}
+test "x$enable_afm2pl" = xno || {
+  need_kpathsea=yes
+}
+
+## texk/bibtex-x/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/bibtex-x/
+## configure options and TL libraries required for bibtex-x
+# Check whether --enable-bibtex-x was given.
+if test ${enable_bibtex_x+y}
 then :
-  enableval=$enable_linked_scripts;
+  enableval=$enable_bibtex_x;
 fi
+case $enable_bibtex_x in #(
+  yes|no) :
+     ;; #(
+  *) :
 
+   enable_bibtex_x=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-bibtex-x=$enable_bibtex_x'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-bibtex-x=$enable_bibtex_x'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-bibtex-x=$enable_bibtex_x'"
+    ;;
+esac
 
-## libs/pplib/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/pplib/
-## configure options and TL libraries required for pplib
-
-## libs/harfbuzz/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/harfbuzz/
-## configure options and TL libraries required for harfbuzz
+test "x$enable_bibtex_x" = xno || {
+  need_kpathsea=yes
+}
 
-# Check whether --with-system-harfbuzz was given.
-if test ${with_system_harfbuzz+y}
+## texk/bibtex-x/ac/bibtex-x.ac: configure.ac fragment for the TeX Live subdirectory texk/bibtex-x/
+## configure options for bibtex-x
+# Check whether --enable-bibtex8 was given.
+if test ${enable_bibtex8+y}
 then :
-  withval=$with_system_harfbuzz;
-fi
-if test "x$with_system_harfbuzz" = x; then
-  if test -f $srcdir/libs/harfbuzz/configure; then
-    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`harfbuzz' headers and library from TL tree" >&5
-printf "%s\n" "$as_me: Assuming \`harfbuzz' headers and library from TL tree" >&6;}
-    with_system_harfbuzz=no
-  else
-    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`harfbuzz' headers and library" >&5
-printf "%s\n" "$as_me: Assuming installed \`harfbuzz' headers and library" >&6;}
-    with_system_harfbuzz=yes
-  fi
-  ac_configure_args="$ac_configure_args '--with-system-harfbuzz=$with_system_harfbuzz'"
-elif test "x$with_system_harfbuzz" = xyes; then
-  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`harfbuzz' headers and library" >&5
-printf "%s\n" "$as_me: Using installed \`harfbuzz' headers and library" >&6;}
-else
-  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`harfbuzz' headers and library from TL tree" >&5
-printf "%s\n" "$as_me: Using \`harfbuzz' headers and library from TL tree" >&6;}
-  if test "x$with_system_harfbuzz" != xno; then
-    with_system_harfbuzz=no
-    ac_configure_args="$ac_configure_args '--without-system-harfbuzz'"
-  fi
+  enableval=$enable_bibtex8;
 fi
-if test "x$with_system_harfbuzz" = xyes; then
-  if test "x$with_system_graphite2" = x; then
-    { printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ->  installed \`graphite2' headers and library" >&5
-printf "%s\n" "$as_me:   ->  installed \`graphite2' headers and library" >&6;}
-    with_system_graphite2=yes
-    ac_configure_args="$ac_configure_args '--with-system-graphite2'"
-  elif test "x$with_system_graphite2" != xyes; then
-    as_fn_error $? "Sorry, \`--with-system-harfbuzz' requires \`--with-system-graphite2'" "$LINENO" 5
-  fi
-  if test "x$with_system_icu" = x; then
-    { printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ->  installed \`icu' headers and library" >&5
-printf "%s\n" "$as_me:   ->  installed \`icu' headers and library" >&6;}
-    with_system_icu=yes
-    ac_configure_args="$ac_configure_args '--with-system-icu'"
-  elif test "x$with_system_icu" != xyes; then
-    as_fn_error $? "Sorry, \`--with-system-harfbuzz' requires \`--with-system-icu'" "$LINENO" 5
-  fi
+
+case $enable_bibtex8 in #(
+  yes | no) :
+     ;; #(
+  *) :
+    enable_bibtex8=yes ;;
+esac
+# Check whether --enable-bibtexu was given.
+if test ${enable_bibtexu+y}
+then :
+  enableval=$enable_bibtexu;
 fi
 
-test "x$need_harfbuzz" = xyes && {
-  need_graphite2=yes
-  need_icu=yes
-}
+case $enable_bibtexu in #(
+  yes | no) :
+     ;; #(
+  *) :
+    enable_bibtexu=yes ;;
+esac
 
-## libs/graphite2/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/graphite2/
-## configure options and TL libraries required for graphite2
+test "x$enable_bibtex_x:$enable_bibtexu" = xyes:yes && need_icu=yes
 
-# Check whether --with-system-graphite2 was given.
-if test ${with_system_graphite2+y}
+## texk/chktex/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/chktex/
+## configure options and TL libraries required for chktex
+# Check whether --enable-chktex was given.
+if test ${enable_chktex+y}
 then :
-  withval=$with_system_graphite2;
+  enableval=$enable_chktex;
 fi
-if test "x$with_system_graphite2" = x; then
-  if test -f $srcdir/libs/graphite2/configure; then
-    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`graphite2' headers and library from TL tree" >&5
-printf "%s\n" "$as_me: Assuming \`graphite2' headers and library from TL tree" >&6;}
-    with_system_graphite2=no
-  else
-    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`graphite2' headers and library" >&5
-printf "%s\n" "$as_me: Assuming installed \`graphite2' headers and library" >&6;}
+case $enable_chktex in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_chktex=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-chktex=$enable_chktex'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-chktex=$enable_chktex'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-chktex=$enable_chktex'"
+    ;;
+esac
+
+test "x$enable_chktex" = xno || {
+  need_kpathsea=yes
+}
+
+## texk/cjkutils/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/cjkutils/
+## configure options and TL libraries required for cjkutils
+# Check whether --enable-cjkutils was given.
+if test ${enable_cjkutils+y}
+then :
+  enableval=$enable_cjkutils;
+fi
+case $enable_cjkutils in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_cjkutils=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-cjkutils=$enable_cjkutils'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-cjkutils=$enable_cjkutils'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-cjkutils=$enable_cjkutils'"
+    ;;
+esac
+
+test "x$enable_cjkutils" = xno || {
+  need_kpathsea=yes
+}
+
+## texk/detex/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/detex/
+## configure options and TL libraries required for detex
+# Check whether --enable-detex was given.
+if test ${enable_detex+y}
+then :
+  enableval=$enable_detex;
+fi
+case $enable_detex in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_detex=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-detex=$enable_detex'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-detex=$enable_detex'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-detex=$enable_detex'"
+    ;;
+esac
+
+test "x$enable_detex" = xno || {
+  need_kpathsea=yes
+}
+
+## texk/dtl/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dtl/
+## configure options and TL libraries required for dtl
+# Check whether --enable-dtl was given.
+if test ${enable_dtl+y}
+then :
+  enableval=$enable_dtl;
+fi
+case $enable_dtl in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_dtl=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dtl=$enable_dtl'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-dtl=$enable_dtl'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-dtl=$enable_dtl'"
+    ;;
+esac
+
+test "x$enable_dtl" = xno || {
+  need_kpathsea=yes
+}
+
+## texk/dvi2tty/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvi2tty/
+## configure options and TL libraries required for dvi2tty
+# Check whether --enable-dvi2tty was given.
+if test ${enable_dvi2tty+y}
+then :
+  enableval=$enable_dvi2tty;
+fi
+case $enable_dvi2tty in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_dvi2tty=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvi2tty=$enable_dvi2tty'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-dvi2tty=$enable_dvi2tty'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-dvi2tty=$enable_dvi2tty'"
+    ;;
+esac
+
+test "x$enable_dvi2tty" = xno || {
+  need_ptexenc=yes
+}
+
+## texk/dvidvi/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvidvi/
+## configure options and TL libraries required for dvidvi
+# Check whether --enable-dvidvi was given.
+if test ${enable_dvidvi+y}
+then :
+  enableval=$enable_dvidvi;
+fi
+case $enable_dvidvi in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_dvidvi=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvidvi=$enable_dvidvi'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-dvidvi=$enable_dvidvi'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-dvidvi=$enable_dvidvi'"
+    ;;
+esac
+
+test "x$enable_dvidvi" = xno || {
+  need_kpathsea=yes
+}
+
+## texk/dviljk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dviljk/
+## configure options and TL libraries required for dviljk
+# Check whether --enable-dviljk was given.
+if test ${enable_dviljk+y}
+then :
+  enableval=$enable_dviljk;
+fi
+case $enable_dviljk in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_dviljk=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dviljk=$enable_dviljk'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-dviljk=$enable_dviljk'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-dviljk=$enable_dviljk'"
+    ;;
+esac
+
+test "x$enable_dviljk" = xno || {
+  need_kpathsea=yes
+}
+
+## texk/dviout-util/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dviout-util/
+## configure options and TL libraries required for dviout-util
+# Check whether --enable-dviout-util was given.
+if test ${enable_dviout_util+y}
+then :
+  enableval=$enable_dviout_util;
+fi
+case $enable_dviout_util in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_dviout_util=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dviout-util=$enable_dviout_util'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-dviout-util=$enable_dviout_util'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-dviout-util=$enable_dviout_util'"
+    ;;
+esac
+
+test "x$enable_dviout_util" = xno || {
+  need_ptexenc=yes
+}
+
+## texk/dvipdfm-x/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipdfm-x/
+## configure options and TL libraries required for dvipdfm-x
+# Check whether --enable-dvipdfm-x was given.
+if test ${enable_dvipdfm_x+y}
+then :
+  enableval=$enable_dvipdfm_x;
+fi
+case $enable_dvipdfm_x in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_dvipdfm_x=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvipdfm-x=$enable_dvipdfm_x'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-dvipdfm-x=$enable_dvipdfm_x'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-dvipdfm-x=$enable_dvipdfm_x'"
+    ;;
+esac
+
+test "x$enable_dvipdfm_x" = xno || {
+  need_kpathsea=yes
+  need_libpng=yes
+  need_libpaper=yes
+}
+
+## texk/dvipng/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipng/
+## configure options and TL libraries required for dvipng
+# Check whether --enable-dvipng was given.
+if test ${enable_dvipng+y}
+then :
+  enableval=$enable_dvipng;
+fi
+case $enable_dvipng in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_dvipng=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvipng=$enable_dvipng'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-dvipng=$enable_dvipng'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-dvipng=$enable_dvipng'"
+    ;;
+esac
+
+test "x$enable_dvipng" = xno || {
+  need_kpathsea=yes
+  need_gd=yes
+}
+
+## texk/dvipng/ac/dvipng.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipng/
+## configure options for dvipng
+# Check whether --enable-debug was given.
+if test ${enable_debug+y}
+then :
+  enableval=$enable_debug;
+fi
+
+# Check whether --enable-timing was given.
+if test ${enable_timing+y}
+then :
+  enableval=$enable_timing;
+fi
+
+
+# Check whether --with-gs was given.
+if test ${with_gs+y}
+then :
+  withval=$with_gs;
+fi
+
+
+## texk/dvipos/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipos/
+## configure options and TL libraries required for dvipos
+# Check whether --enable-dvipos was given.
+if test ${enable_dvipos+y}
+then :
+  enableval=$enable_dvipos;
+fi
+case $enable_dvipos in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_dvipos=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvipos=$enable_dvipos'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-dvipos=$enable_dvipos'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-dvipos=$enable_dvipos'"
+    ;;
+esac
+
+test "x$enable_dvipos" = xno || {
+  need_kpathsea=yes
+}
+
+## texk/dvipsk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/dvipsk/
+## configure options and TL libraries required for dvipsk
+# Check whether --enable-dvipsk was given.
+if test ${enable_dvipsk+y}
+then :
+  enableval=$enable_dvipsk;
+fi
+case $enable_dvipsk in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_dvipsk=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvipsk=$enable_dvipsk'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-dvipsk=$enable_dvipsk'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-dvipsk=$enable_dvipsk'"
+    ;;
+esac
+
+test "x$enable_dvipsk" = xno || {
+  need_kpathsea=yes
+}
+
+# texk/dvisvgm/ac/withenable.ac: configure.ac fragment
+## configure options and TL libraries required for dvisvgm
+# Check whether --enable-dvisvgm was given.
+if test ${enable_dvisvgm+y}
+then :
+  enableval=$enable_dvisvgm;
+fi
+case $enable_dvisvgm in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_dvisvgm=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-dvisvgm=$enable_dvisvgm'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-dvisvgm=$enable_dvisvgm'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-dvisvgm=$enable_dvisvgm'"
+    ;;
+esac
+
+test "x$enable_dvisvgm" = xno || {
+  need_kpathsea=yes
+  need_potrace=yes
+  need_freetype2=yes
+  need_zlib=yes
+}
+
+## texk/gregorio/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/gregorio/
+## configure options and TL libraries required for gregorio
+# Check whether --enable-gregorio was given.
+if test ${enable_gregorio+y}
+then :
+  enableval=$enable_gregorio;
+fi
+case $enable_gregorio in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_gregorio=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-gregorio=$enable_gregorio'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-gregorio=$enable_gregorio'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-gregorio=$enable_gregorio'"
+    ;;
+esac
+
+test "x$enable_gregorio" = xno || {
+  need_kpathsea=yes
+}
+
+## texk/gsftopk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/gsftopk/
+## configure options and TL libraries required for gsftopk
+# Check whether --enable-gsftopk was given.
+if test ${enable_gsftopk+y}
+then :
+  enableval=$enable_gsftopk;
+fi
+case $enable_gsftopk in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_gsftopk=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-gsftopk=$enable_gsftopk'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-gsftopk=$enable_gsftopk'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-gsftopk=$enable_gsftopk'"
+    ;;
+esac
+
+test "x$enable_gsftopk" = xno || {
+  need_kpathsea=yes
+}
+
+## texk/lcdf-typetools/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/lcdf-typetools/
+## configure options and TL libraries required for lcdf-typetools
+# Check whether --enable-lcdf-typetools was given.
+if test ${enable_lcdf_typetools+y}
+then :
+  enableval=$enable_lcdf_typetools;
+fi
+case $enable_lcdf_typetools in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_lcdf_typetools=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-lcdf-typetools=$enable_lcdf_typetools'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-lcdf-typetools=$enable_lcdf_typetools'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-lcdf-typetools=$enable_lcdf_typetools'"
+    ;;
+esac
+
+test "x$enable_lcdf_typetools" = xno || {
+  need_kpathsea=yes
+}
+
+## Define configure options for lcdf-typetools.  Extracted from configure.ac
+## for ease of building TeX Live.
+# Check whether --enable-cfftot1 was given.
+if test ${enable_cfftot1+y}
+then :
+  enableval=$enable_cfftot1;
+fi
+# Check whether --enable-mmafm was given.
+if test ${enable_mmafm+y}
+then :
+  enableval=$enable_mmafm;
+fi
+# Check whether --enable-mmpfb was given.
+if test ${enable_mmpfb+y}
+then :
+  enableval=$enable_mmpfb;
+fi
+# Check whether --enable-otfinfo was given.
+if test ${enable_otfinfo+y}
+then :
+  enableval=$enable_otfinfo;
+fi
+# Check whether --enable-otftotfm was given.
+if test ${enable_otftotfm+y}
+then :
+  enableval=$enable_otftotfm;
+fi
+# Check whether --enable-t1dotlessj was given.
+if test ${enable_t1dotlessj+y}
+then :
+  enableval=$enable_t1dotlessj;
+fi
+# Check whether --enable-t1lint was given.
+if test ${enable_t1lint+y}
+then :
+  enableval=$enable_t1lint;
+fi
+# Check whether --enable-t1rawafm was given.
+if test ${enable_t1rawafm+y}
+then :
+  enableval=$enable_t1rawafm;
+fi
+# Check whether --enable-t1reencode was given.
+if test ${enable_t1reencode+y}
+then :
+  enableval=$enable_t1reencode;
+fi
+# Check whether --enable-t1testpage was given.
+if test ${enable_t1testpage+y}
+then :
+  enableval=$enable_t1testpage;
+fi
+# Check whether --enable-ttftotype42 was given.
+if test ${enable_ttftotype42+y}
+then :
+  enableval=$enable_ttftotype42;
+fi
+
+# Check whether --enable-cfftot1 was given.
+if test ${enable_cfftot1+y}
+then :
+  enableval=$enable_cfftot1;
+fi
+# Check whether --enable-t1dotlessj was given.
+if test ${enable_t1dotlessj+y}
+then :
+  enableval=$enable_t1dotlessj;
+fi
+# Check whether --enable-ttftotype42 was given.
+if test ${enable_ttftotype42+y}
+then :
+  enableval=$enable_ttftotype42;
+fi
+# Check whether --enable-updmap was given.
+if test ${enable_updmap+y}
+then :
+  enableval=$enable_updmap;
+fi
+
+
+## texk/makeindexk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/makeindexk/
+## configure options and TL libraries required for makeindexk
+# Check whether --enable-makeindexk was given.
+if test ${enable_makeindexk+y}
+then :
+  enableval=$enable_makeindexk;
+fi
+case $enable_makeindexk in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_makeindexk=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-makeindexk=$enable_makeindexk'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-makeindexk=$enable_makeindexk'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-makeindexk=$enable_makeindexk'"
+    ;;
+esac
+
+test "x$enable_makeindexk" = xno || {
+  need_kpathsea=yes
+}
+
+## texk/makejvf/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/makejvf/
+## configure options and TL libraries required for makejvf
+# Check whether --enable-makejvf was given.
+if test ${enable_makejvf+y}
+then :
+  enableval=$enable_makejvf;
+fi
+case $enable_makejvf in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_makejvf=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-makejvf=$enable_makejvf'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-makejvf=$enable_makejvf'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-makejvf=$enable_makejvf'"
+    ;;
+esac
+
+test "x$enable_makejvf" = xno || {
+  need_ptexenc=yes
+}
+
+## texk/mendexk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/mendexk/
+## configure options and TL libraries required for mendexk
+# Check whether --enable-mendexk was given.
+if test ${enable_mendexk+y}
+then :
+  enableval=$enable_mendexk;
+fi
+case $enable_mendexk in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_mendexk=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-mendexk=$enable_mendexk'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-mendexk=$enable_mendexk'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-mendexk=$enable_mendexk'"
+    ;;
+esac
+
+test "x$enable_mendexk" = xno || {
+  need_ptexenc=yes
+}
+
+## texk/musixtnt/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/musixtnt/
+## configure options and TL libraries required for musixtnt
+# Check whether --enable-musixtnt was given.
+if test ${enable_musixtnt+y}
+then :
+  enableval=$enable_musixtnt;
+fi
+case $enable_musixtnt in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_musixtnt=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-musixtnt=$enable_musixtnt'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-musixtnt=$enable_musixtnt'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-musixtnt=$enable_musixtnt'"
+    ;;
+esac
+
+test "x$enable_musixtnt" = xno || {
+  need_kpathsea=yes
+}
+
+## texk/ps2pk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/ps2pk/
+## configure options and TL libraries required for ps2pk
+# Check whether --enable-ps2pk was given.
+if test ${enable_ps2pk+y}
+then :
+  enableval=$enable_ps2pk;
+fi
+case $enable_ps2pk in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_ps2pk=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-ps2pk=$enable_ps2pk'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-ps2pk=$enable_ps2pk'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-ps2pk=$enable_ps2pk'"
+    ;;
+esac
+
+test "x$enable_ps2pk" = xno || {
+  need_kpathsea=yes
+}
+
+## texk/psutils/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/psutils/
+## configure options and TL libraries required for psutils
+# Check whether --enable-psutils was given.
+if test ${enable_psutils+y}
+then :
+  enableval=$enable_psutils;
+fi
+case $enable_psutils in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_psutils=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-psutils=$enable_psutils'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-psutils=$enable_psutils'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-psutils=$enable_psutils'"
+    ;;
+esac
+
+test "x$enable_psutils" = xno || {
+  need_kpathsea=yes
+  need_libpaper=yes
+}
+
+## texk/seetexk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/seetexk/
+## configure options and TL libraries required for seetexk
+# Check whether --enable-seetexk was given.
+if test ${enable_seetexk+y}
+then :
+  enableval=$enable_seetexk;
+fi
+case $enable_seetexk in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_seetexk=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-seetexk=$enable_seetexk'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-seetexk=$enable_seetexk'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-seetexk=$enable_seetexk'"
+    ;;
+esac
+
+test "x$enable_seetexk" = xno || {
+  need_kpathsea=yes
+}
+
+## texk/tex4htk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/tex4htk/
+## configure options and TL libraries required for tex4htk
+# Check whether --enable-tex4htk was given.
+if test ${enable_tex4htk+y}
+then :
+  enableval=$enable_tex4htk;
+fi
+case $enable_tex4htk in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_tex4htk=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-tex4htk=$enable_tex4htk'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-tex4htk=$enable_tex4htk'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-tex4htk=$enable_tex4htk'"
+    ;;
+esac
+
+test "x$enable_tex4htk" = xno || {
+  need_kpathsea=yes
+}
+
+## texk/ttf2pk2/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/ttf2pk2/
+## configure options and TL libraries required for ttf2pk
+# Check whether --enable-ttf2pk2 was given.
+if test ${enable_ttf2pk2+y}
+then :
+  enableval=$enable_ttf2pk2;
+fi
+case $enable_ttf2pk2 in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_ttf2pk2=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-ttf2pk2=$enable_ttf2pk2'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-ttf2pk2=$enable_ttf2pk2'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-ttf2pk2=$enable_ttf2pk2'"
+    ;;
+esac
+
+test "x$enable_ttf2pk2" = xno || {
+  need_kpathsea=yes
+  need_freetype2=yes
+}
+
+## texk/ttfdump/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/ttfdump/
+## configure options and TL libraries required for ttfdump
+# Check whether --enable-ttfdump was given.
+if test ${enable_ttfdump+y}
+then :
+  enableval=$enable_ttfdump;
+fi
+case $enable_ttfdump in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_ttfdump=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-ttfdump=$enable_ttfdump'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-ttfdump=$enable_ttfdump'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-ttfdump=$enable_ttfdump'"
+    ;;
+esac
+
+test "x$enable_ttfdump" = xno || {
+  need_kpathsea=yes
+}
+
+## texk/upmendex/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/upmendex/
+## configure options and TL libraries required for upmendex
+# Check whether --enable-upmendex was given.
+if test ${enable_upmendex+y}
+then :
+  enableval=$enable_upmendex;
+fi
+case $enable_upmendex in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_upmendex=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-upmendex=$enable_upmendex'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-upmendex=$enable_upmendex'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-upmendex=$enable_upmendex'"
+    ;;
+esac
+
+test "x$enable_upmendex" = xno || {
+  need_kpathsea=yes
+  need_icu=yes
+}
+
+## texk/xdvik/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/xdvik/
+## configure options and TL libraries required for xdvik
+# Check whether --enable-xdvik was given.
+if test ${enable_xdvik+y}
+then :
+  enableval=$enable_xdvik;
+fi
+if test "x$with_x" = xno
+then :
+  case $enable_xdvik in #(
+  "") :
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \`--without-x' -> \`--disable-xdvik'" >&5
+printf "%s\n" "$as_me: \`--without-x' -> \`--disable-xdvik'" >&6;}
+                      enable_xdvik=no
+                      ac_configure_args="$ac_configure_args '--disable-xdvik'" ;; #(
+  yes) :
+    as_fn_error $? "Sorry, incompatible options \`--without-x' and \`--enable-xdvik'" "$LINENO" 5 ;; #(
+  *) :
+     ;;
+esac
+fi
+case $enable_xdvik in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_xdvik=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-xdvik=$enable_xdvik'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-xdvik=$enable_xdvik'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-xdvik=$enable_xdvik'"
+    ;;
+esac
+
+test "x$enable_xdvik" = xno || {
+  need_kpathsea=yes
+  need_freetype2=yes
+}
+
+## texk/xdvik/ac/xdvik.ac: configure.ac fragment for the TeX Live subdirectory texk/xdvik/
+## configure options for xdvik
+
+# Check whether --with-xdvi-x-toolkit was given.
+if test ${with_xdvi_x_toolkit+y}
+then :
+  withval=$with_xdvi_x_toolkit;
+fi
+
+
+## texk/texlive/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/texlive/
+## configure options and TL libraries required for texlive
+# Check whether --enable-texlive was given.
+if test ${enable_texlive+y}
+then :
+  enableval=$enable_texlive;
+fi
+case $enable_texlive in #(
+  yes|no) :
+     ;; #(
+  *) :
+
+   enable_texlive=$enable_all_pkgs
+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`--enable-texlive=$enable_texlive'" >&5
+printf "%s\n" "$as_me: Assuming \`--enable-texlive=$enable_texlive'" >&6;}
+     ac_configure_args="$ac_configure_args '--enable-texlive=$enable_texlive'"
+    ;;
+esac
+
+## texk/texlive/ac/texlive.ac: configure.ac fragment for the TeX Live subdirectory texk/texlive/
+## configure options for texlive
+# Check whether --enable-linked-scripts was given.
+if test ${enable_linked_scripts+y}
+then :
+  enableval=$enable_linked_scripts;
+fi
+
+
+## libs/pplib/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/pplib/
+## configure options and TL libraries required for pplib
+
+## libs/harfbuzz/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/harfbuzz/
+## configure options and TL libraries required for harfbuzz
+
+# Check whether --with-system-harfbuzz was given.
+if test ${with_system_harfbuzz+y}
+then :
+  withval=$with_system_harfbuzz;
+fi
+if test "x$with_system_harfbuzz" = x; then
+  if test -f $srcdir/libs/harfbuzz/configure; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`harfbuzz' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Assuming \`harfbuzz' headers and library from TL tree" >&6;}
+    with_system_harfbuzz=no
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`harfbuzz' headers and library" >&5
+printf "%s\n" "$as_me: Assuming installed \`harfbuzz' headers and library" >&6;}
+    with_system_harfbuzz=yes
+  fi
+  ac_configure_args="$ac_configure_args '--with-system-harfbuzz=$with_system_harfbuzz'"
+elif test "x$with_system_harfbuzz" = xyes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`harfbuzz' headers and library" >&5
+printf "%s\n" "$as_me: Using installed \`harfbuzz' headers and library" >&6;}
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`harfbuzz' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Using \`harfbuzz' headers and library from TL tree" >&6;}
+  if test "x$with_system_harfbuzz" != xno; then
+    with_system_harfbuzz=no
+    ac_configure_args="$ac_configure_args '--without-system-harfbuzz'"
+  fi
+fi
+if test "x$with_system_harfbuzz" = xyes; then
+  if test "x$with_system_graphite2" = x; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ->  installed \`graphite2' headers and library" >&5
+printf "%s\n" "$as_me:   ->  installed \`graphite2' headers and library" >&6;}
+    with_system_graphite2=yes
+    ac_configure_args="$ac_configure_args '--with-system-graphite2'"
+  elif test "x$with_system_graphite2" != xyes; then
+    as_fn_error $? "Sorry, \`--with-system-harfbuzz' requires \`--with-system-graphite2'" "$LINENO" 5
+  fi
+  if test "x$with_system_icu" = x; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ->  installed \`icu' headers and library" >&5
+printf "%s\n" "$as_me:   ->  installed \`icu' headers and library" >&6;}
+    with_system_icu=yes
+    ac_configure_args="$ac_configure_args '--with-system-icu'"
+  elif test "x$with_system_icu" != xyes; then
+    as_fn_error $? "Sorry, \`--with-system-harfbuzz' requires \`--with-system-icu'" "$LINENO" 5
+  fi
+fi
+
+test "x$need_harfbuzz" = xyes && {
+  need_graphite2=yes
+  need_icu=yes
+}
+
+## libs/icu/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/icu/
+## configure options and TL libraries required for icu (modified for XeTeX)
+
+# Check whether --with-system-icu was given.
+if test ${with_system_icu+y}
+then :
+  withval=$with_system_icu;
+fi
+if test "x$with_system_icu" = x; then
+  if test -f $srcdir/libs/icu/configure; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`icu' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Assuming \`icu' headers and library from TL tree" >&6;}
+    with_system_icu=no
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`icu' headers and library" >&5
+printf "%s\n" "$as_me: Assuming installed \`icu' headers and library" >&6;}
+    with_system_icu=yes
+  fi
+  ac_configure_args="$ac_configure_args '--with-system-icu=$with_system_icu'"
+elif test "x$with_system_icu" = xyes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`icu' headers and library" >&5
+printf "%s\n" "$as_me: Using installed \`icu' headers and library" >&6;}
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`icu' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Using \`icu' headers and library from TL tree" >&6;}
+  if test "x$with_system_icu" != xno; then
+    with_system_icu=no
+    ac_configure_args="$ac_configure_args '--without-system-icu'"
+  fi
+fi
+
+## libs/teckit/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/teckit/
+## configure options and TL libraries required for teckit
+
+# Check whether --with-system-teckit was given.
+if test ${with_system_teckit+y}
+then :
+  withval=$with_system_teckit;
+fi
+if test "x$with_system_teckit" = x; then
+  if test -f $srcdir/libs/teckit/configure; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`teckit' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Assuming \`teckit' headers and library from TL tree" >&6;}
+    with_system_teckit=no
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`teckit' headers and library" >&5
+printf "%s\n" "$as_me: Assuming installed \`teckit' headers and library" >&6;}
+    with_system_teckit=yes
+  fi
+  ac_configure_args="$ac_configure_args '--with-system-teckit=$with_system_teckit'"
+elif test "x$with_system_teckit" = xyes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`teckit' headers and library" >&5
+printf "%s\n" "$as_me: Using installed \`teckit' headers and library" >&6;}
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`teckit' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Using \`teckit' headers and library from TL tree" >&6;}
+  if test "x$with_system_teckit" != xno; then
+    with_system_teckit=no
+    ac_configure_args="$ac_configure_args '--without-system-teckit'"
+  fi
+fi
+if test "x$with_system_teckit" = xyes; then
+  if test "x$with_system_zlib" = x; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ->  installed \`zlib' headers and library" >&5
+printf "%s\n" "$as_me:   ->  installed \`zlib' headers and library" >&6;}
+    with_system_zlib=yes
+    ac_configure_args="$ac_configure_args '--with-system-zlib'"
+  elif test "x$with_system_zlib" != xyes; then
+    as_fn_error $? "Sorry, \`--with-system-teckit' requires \`--with-system-zlib'" "$LINENO" 5
+  fi
+fi
+
+test "x$need_teckit" = xyes && {
+  need_zlib=yes
+}
+
+## libs/graphite2/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/graphite2/
+## configure options and TL libraries required for graphite2
+
+# Check whether --with-system-graphite2 was given.
+if test ${with_system_graphite2+y}
+then :
+  withval=$with_system_graphite2;
+fi
+if test "x$with_system_graphite2" = x; then
+  if test -f $srcdir/libs/graphite2/configure; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`graphite2' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Assuming \`graphite2' headers and library from TL tree" >&6;}
+    with_system_graphite2=no
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`graphite2' headers and library" >&5
+printf "%s\n" "$as_me: Assuming installed \`graphite2' headers and library" >&6;}
     with_system_graphite2=yes
   fi
   ac_configure_args="$ac_configure_args '--with-system-graphite2=$with_system_graphite2'"
@@ -5471,6 +6921,362 @@ test "x$need_zziplib" = xyes && {
   need_zlib=yes
 }
 
+## libs/xpdf/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/xpdf/
+## configure options and TL libraries required for xpdf
+: "kpse_xpdf_options - no-op"
+if test "x$with_system_xpdf" = x; then
+  if test -f $srcdir/libs/xpdf/configure; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`xpdf' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Assuming \`xpdf' headers and library from TL tree" >&6;}
+    with_system_xpdf=no
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`xpdf' headers and library" >&5
+printf "%s\n" "$as_me: Assuming installed \`xpdf' headers and library" >&6;}
+    with_system_xpdf=yes
+  fi
+  ac_configure_args="$ac_configure_args '--with-system-xpdf=$with_system_xpdf'"
+elif test "x$with_system_xpdf" = xyes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`xpdf' headers and library" >&5
+printf "%s\n" "$as_me: Using installed \`xpdf' headers and library" >&6;}
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`xpdf' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Using \`xpdf' headers and library from TL tree" >&6;}
+  if test "x$with_system_xpdf" != xno; then
+    with_system_xpdf=no
+    ac_configure_args="$ac_configure_args '--without-system-xpdf'"
+  fi
+fi
+
+## libs/mpfr/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/mpfr/
+## configure options and TL libraries required for mpfr
+
+# Check whether --with-system-mpfr was given.
+if test ${with_system_mpfr+y}
+then :
+  withval=$with_system_mpfr;
+fi
+
+# Check whether --with-mpfr-includes was given.
+if test ${with_mpfr_includes+y}
+then :
+  withval=$with_mpfr_includes;
+fi
+
+# Check whether --with-mpfr-libdir was given.
+if test ${with_mpfr_libdir+y}
+then :
+  withval=$with_mpfr_libdir;
+fi
+if test "x$with_system_mpfr" = x; then
+  if test -f $srcdir/libs/mpfr/configure; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`mpfr' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Assuming \`mpfr' headers and library from TL tree" >&6;}
+    with_system_mpfr=no
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`mpfr' headers and library" >&5
+printf "%s\n" "$as_me: Assuming installed \`mpfr' headers and library" >&6;}
+    with_system_mpfr=yes
+  fi
+  ac_configure_args="$ac_configure_args '--with-system-mpfr=$with_system_mpfr'"
+elif test "x$with_system_mpfr" = xyes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`mpfr' headers and library" >&5
+printf "%s\n" "$as_me: Using installed \`mpfr' headers and library" >&6;}
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`mpfr' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Using \`mpfr' headers and library from TL tree" >&6;}
+  if test "x$with_system_mpfr" != xno; then
+    with_system_mpfr=no
+    ac_configure_args="$ac_configure_args '--without-system-mpfr'"
+  fi
+fi
+if test "x$with_system_mpfr" = xyes; then
+  if test "x$with_system_gmp" = x; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ->  installed \`gmp' headers and library" >&5
+printf "%s\n" "$as_me:   ->  installed \`gmp' headers and library" >&6;}
+    with_system_gmp=yes
+    ac_configure_args="$ac_configure_args '--with-system-gmp'"
+  elif test "x$with_system_gmp" != xyes; then
+    as_fn_error $? "Sorry, \`--with-system-mpfr' requires \`--with-system-gmp'" "$LINENO" 5
+  fi
+fi
+
+test "x$need_mpfr" = xyes && {
+  need_gmp=yes
+}
+
+## libs/gmp/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/gmp/
+## configure options and TL libraries required for gmp
+
+# Check whether --with-system-gmp was given.
+if test ${with_system_gmp+y}
+then :
+  withval=$with_system_gmp;
+fi
+
+# Check whether --with-gmp-includes was given.
+if test ${with_gmp_includes+y}
+then :
+  withval=$with_gmp_includes;
+fi
+
+# Check whether --with-gmp-libdir was given.
+if test ${with_gmp_libdir+y}
+then :
+  withval=$with_gmp_libdir;
+fi
+if test "x$with_system_gmp" = x; then
+  if test -f $srcdir/libs/gmp/configure; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`gmp' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Assuming \`gmp' headers and library from TL tree" >&6;}
+    with_system_gmp=no
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`gmp' headers and library" >&5
+printf "%s\n" "$as_me: Assuming installed \`gmp' headers and library" >&6;}
+    with_system_gmp=yes
+  fi
+  ac_configure_args="$ac_configure_args '--with-system-gmp=$with_system_gmp'"
+elif test "x$with_system_gmp" = xyes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`gmp' headers and library" >&5
+printf "%s\n" "$as_me: Using installed \`gmp' headers and library" >&6;}
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`gmp' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Using \`gmp' headers and library from TL tree" >&6;}
+  if test "x$with_system_gmp" != xno; then
+    with_system_gmp=no
+    ac_configure_args="$ac_configure_args '--without-system-gmp'"
+  fi
+fi
+
+## libs/cairo/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/cairo/
+## configure options and TL libraries required for cairo
+
+# Check whether --with-system-cairo was given.
+if test ${with_system_cairo+y}
+then :
+  withval=$with_system_cairo;
+fi
+if test "x$with_system_cairo" = x; then
+  if test -f $srcdir/libs/cairo/configure; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`cairo' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Assuming \`cairo' headers and library from TL tree" >&6;}
+    with_system_cairo=no
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`cairo' headers and library" >&5
+printf "%s\n" "$as_me: Assuming installed \`cairo' headers and library" >&6;}
+    with_system_cairo=yes
+  fi
+  ac_configure_args="$ac_configure_args '--with-system-cairo=$with_system_cairo'"
+elif test "x$with_system_cairo" = xyes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`cairo' headers and library" >&5
+printf "%s\n" "$as_me: Using installed \`cairo' headers and library" >&6;}
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`cairo' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Using \`cairo' headers and library from TL tree" >&6;}
+  if test "x$with_system_cairo" != xno; then
+    with_system_cairo=no
+    ac_configure_args="$ac_configure_args '--without-system-cairo'"
+  fi
+fi
+if test "x$with_system_cairo" = xyes; then
+  if test "x$with_system_pixman" = x; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ->  installed \`pixman' headers and library" >&5
+printf "%s\n" "$as_me:   ->  installed \`pixman' headers and library" >&6;}
+    with_system_pixman=yes
+    ac_configure_args="$ac_configure_args '--with-system-pixman'"
+  elif test "x$with_system_pixman" != xyes; then
+    as_fn_error $? "Sorry, \`--with-system-cairo' requires \`--with-system-pixman'" "$LINENO" 5
+  fi
+fi
+
+test "x$need_cairo" = xyes && {
+  need_pixman=yes
+}
+
+## libs/pixman/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/pixman/
+## configure options and TL libraries required for pixman
+
+# Check whether --with-system-pixman was given.
+if test ${with_system_pixman+y}
+then :
+  withval=$with_system_pixman;
+fi
+if test "x$with_system_pixman" = x; then
+  if test -f $srcdir/libs/pixman/configure; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`pixman' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Assuming \`pixman' headers and library from TL tree" >&6;}
+    with_system_pixman=no
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`pixman' headers and library" >&5
+printf "%s\n" "$as_me: Assuming installed \`pixman' headers and library" >&6;}
+    with_system_pixman=yes
+  fi
+  ac_configure_args="$ac_configure_args '--with-system-pixman=$with_system_pixman'"
+elif test "x$with_system_pixman" = xyes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`pixman' headers and library" >&5
+printf "%s\n" "$as_me: Using installed \`pixman' headers and library" >&6;}
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`pixman' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Using \`pixman' headers and library from TL tree" >&6;}
+  if test "x$with_system_pixman" != xno; then
+    with_system_pixman=no
+    ac_configure_args="$ac_configure_args '--without-system-pixman'"
+  fi
+fi
+
+## libs/gd/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/gd/
+## configure options and TL libraries required for gd
+
+# Check whether --with-system-gd was given.
+if test ${with_system_gd+y}
+then :
+  withval=$with_system_gd;
+fi
+
+# Check whether --with-gd-includes was given.
+if test ${with_gd_includes+y}
+then :
+  withval=$with_gd_includes;
+fi
+
+# Check whether --with-gd-libdir was given.
+if test ${with_gd_libdir+y}
+then :
+  withval=$with_gd_libdir;
+fi
+if test "x$with_system_gd" = x; then
+  if test -f $srcdir/libs/gd/configure; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`gd' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Assuming \`gd' headers and library from TL tree" >&6;}
+    with_system_gd=no
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`gd' headers and library" >&5
+printf "%s\n" "$as_me: Assuming installed \`gd' headers and library" >&6;}
+    with_system_gd=yes
+  fi
+  ac_configure_args="$ac_configure_args '--with-system-gd=$with_system_gd'"
+elif test "x$with_system_gd" = xyes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`gd' headers and library" >&5
+printf "%s\n" "$as_me: Using installed \`gd' headers and library" >&6;}
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`gd' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Using \`gd' headers and library from TL tree" >&6;}
+  if test "x$with_system_gd" != xno; then
+    with_system_gd=no
+    ac_configure_args="$ac_configure_args '--without-system-gd'"
+  fi
+fi
+if test "x$with_system_gd" = xyes; then
+  if test "x$with_system_libpng" = x; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ->  installed \`libpng' headers and library" >&5
+printf "%s\n" "$as_me:   ->  installed \`libpng' headers and library" >&6;}
+    with_system_libpng=yes
+    ac_configure_args="$ac_configure_args '--with-system-libpng'"
+  elif test "x$with_system_libpng" != xyes; then
+    as_fn_error $? "Sorry, \`--with-system-gd' requires \`--with-system-libpng'" "$LINENO" 5
+  fi
+  if test "x$with_system_freetype2" = x; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ->  installed \`freetype2' headers and library" >&5
+printf "%s\n" "$as_me:   ->  installed \`freetype2' headers and library" >&6;}
+    with_system_freetype2=yes
+    ac_configure_args="$ac_configure_args '--with-system-freetype2'"
+  elif test "x$with_system_freetype2" != xyes; then
+    as_fn_error $? "Sorry, \`--with-system-gd' requires \`--with-system-freetype2'" "$LINENO" 5
+  fi
+fi
+
+test "x$need_gd" = xyes && {
+  need_libpng=yes
+  need_freetype2=yes
+}
+
+## libs/potrace/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/potrace/
+## configure options and TL libraries required for potrace
+
+# Check whether --with-system-potrace was given.
+if test ${with_system_potrace+y}
+then :
+  withval=$with_system_potrace;
+fi
+
+# Check whether --with-potrace-includes was given.
+if test ${with_potrace_includes+y}
+then :
+  withval=$with_potrace_includes;
+fi
+
+# Check whether --with-potrace-libdir was given.
+if test ${with_potrace_libdir+y}
+then :
+  withval=$with_potrace_libdir;
+fi
+if test "x$with_system_potrace" = x; then
+  if test -f $srcdir/libs/potrace/configure; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`potrace' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Assuming \`potrace' headers and library from TL tree" >&6;}
+    with_system_potrace=no
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`potrace' headers and library" >&5
+printf "%s\n" "$as_me: Assuming installed \`potrace' headers and library" >&6;}
+    with_system_potrace=yes
+  fi
+  ac_configure_args="$ac_configure_args '--with-system-potrace=$with_system_potrace'"
+elif test "x$with_system_potrace" = xyes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`potrace' headers and library" >&5
+printf "%s\n" "$as_me: Using installed \`potrace' headers and library" >&6;}
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`potrace' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Using \`potrace' headers and library from TL tree" >&6;}
+  if test "x$with_system_potrace" != xno; then
+    with_system_potrace=no
+    ac_configure_args="$ac_configure_args '--without-system-potrace'"
+  fi
+fi
+
+## libs/freetype2/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/freetype2/
+## configure options and TL libraries required for freetype2
+
+# Check whether --with-system-freetype2 was given.
+if test ${with_system_freetype2+y}
+then :
+  withval=$with_system_freetype2;
+fi
+if test "x$with_system_freetype2" = x; then
+  if test -f $srcdir/libs/freetype2/configure; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`freetype2' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Assuming \`freetype2' headers and library from TL tree" >&6;}
+    with_system_freetype2=no
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`freetype2' headers and library" >&5
+printf "%s\n" "$as_me: Assuming installed \`freetype2' headers and library" >&6;}
+    with_system_freetype2=yes
+  fi
+  ac_configure_args="$ac_configure_args '--with-system-freetype2=$with_system_freetype2'"
+elif test "x$with_system_freetype2" = xyes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`freetype2' headers and library" >&5
+printf "%s\n" "$as_me: Using installed \`freetype2' headers and library" >&6;}
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`freetype2' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Using \`freetype2' headers and library from TL tree" >&6;}
+  if test "x$with_system_freetype2" != xno; then
+    with_system_freetype2=no
+    ac_configure_args="$ac_configure_args '--without-system-freetype2'"
+  fi
+fi
+if test "x$with_system_freetype2" = xyes; then
+  if test "x$with_system_zlib" = x; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ->  installed \`zlib' headers and library" >&5
+printf "%s\n" "$as_me:   ->  installed \`zlib' headers and library" >&6;}
+    with_system_zlib=yes
+    ac_configure_args="$ac_configure_args '--with-system-zlib'"
+  elif test "x$with_system_zlib" != xyes; then
+    as_fn_error $? "Sorry, \`--with-system-freetype2' requires \`--with-system-zlib'" "$LINENO" 5
+  fi
+fi
+
+test "x$need_freetype2" = xyes && {
+  need_zlib=yes
+}
+
 ## libs/libpng/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/libpng/
 ## configure options and TL libraries required for libpng
 
@@ -5516,6 +7322,49 @@ test "x$need_libpng" = xyes && {
   need_zlib=yes
 }
 
+## libs/libpaper/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/libpaper/
+## configure options and TL libraries required for libpaper
+
+# Check whether --with-system-libpaper was given.
+if test ${with_system_libpaper+y}
+then :
+  withval=$with_system_libpaper;
+fi
+
+# Check whether --with-libpaper-includes was given.
+if test ${with_libpaper_includes+y}
+then :
+  withval=$with_libpaper_includes;
+fi
+
+# Check whether --with-libpaper-libdir was given.
+if test ${with_libpaper_libdir+y}
+then :
+  withval=$with_libpaper_libdir;
+fi
+if test "x$with_system_libpaper" = x; then
+  if test -f $srcdir/libs/libpaper/configure; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`libpaper' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Assuming \`libpaper' headers and library from TL tree" >&6;}
+    with_system_libpaper=no
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`libpaper' headers and library" >&5
+printf "%s\n" "$as_me: Assuming installed \`libpaper' headers and library" >&6;}
+    with_system_libpaper=yes
+  fi
+  ac_configure_args="$ac_configure_args '--with-system-libpaper=$with_system_libpaper'"
+elif test "x$with_system_libpaper" = xyes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`libpaper' headers and library" >&5
+printf "%s\n" "$as_me: Using installed \`libpaper' headers and library" >&6;}
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`libpaper' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Using \`libpaper' headers and library from TL tree" >&6;}
+  if test "x$with_system_libpaper" != xno; then
+    with_system_libpaper=no
+    ac_configure_args="$ac_configure_args '--without-system-libpaper'"
+  fi
+fi
+
 ## libs/luajit/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/luajit/
 ## configure options and TL libraries required for luajit
 
@@ -5566,6 +7415,51 @@ printf "%s\n" "$as_me: Using \`zlib' headers and library from TL tree" >&6;}
 fi
 
 
+## texk/ptexenc/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/ptexenc/
+## configure options and TL libraries required for ptexenc
+
+# Check whether --with-system-ptexenc was given.
+if test ${with_system_ptexenc+y}
+then :
+  withval=$with_system_ptexenc;
+fi
+if test "x$with_system_ptexenc" = x; then
+  if test -f $srcdir/texk/ptexenc/configure; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming \`ptexenc' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Assuming \`ptexenc' headers and library from TL tree" >&6;}
+    with_system_ptexenc=no
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Assuming installed \`ptexenc' headers and library" >&5
+printf "%s\n" "$as_me: Assuming installed \`ptexenc' headers and library" >&6;}
+    with_system_ptexenc=yes
+  fi
+  ac_configure_args="$ac_configure_args '--with-system-ptexenc=$with_system_ptexenc'"
+elif test "x$with_system_ptexenc" = xyes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using installed \`ptexenc' headers and library" >&5
+printf "%s\n" "$as_me: Using installed \`ptexenc' headers and library" >&6;}
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using \`ptexenc' headers and library from TL tree" >&5
+printf "%s\n" "$as_me: Using \`ptexenc' headers and library from TL tree" >&6;}
+  if test "x$with_system_ptexenc" != xno; then
+    with_system_ptexenc=no
+    ac_configure_args="$ac_configure_args '--without-system-ptexenc'"
+  fi
+fi
+if test "x$with_system_ptexenc" = xyes; then
+  if test "x$with_system_kpathsea" = x; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ->  installed \`kpathsea' headers and library" >&5
+printf "%s\n" "$as_me:   ->  installed \`kpathsea' headers and library" >&6;}
+    with_system_kpathsea=yes
+    ac_configure_args="$ac_configure_args '--with-system-kpathsea'"
+  elif test "x$with_system_kpathsea" != xyes; then
+    as_fn_error $? "Sorry, \`--with-system-ptexenc' requires \`--with-system-kpathsea'" "$LINENO" 5
+  fi
+fi
+
+test "x$need_ptexenc" = xyes && {
+  need_kpathsea=yes
+}
+
 ## texk/kpathsea/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/kpathsea/
 ## configure options and TL libraries required for kpathsea
 
@@ -20792,6 +22686,12 @@ printf %s "checking for TeX specific libraries to build... " >&6; }
 echo 'tldbg:_KPSE_RECURSE called: list=texlibs, text=TeX specific libraries, cond=test "x$with_system_[]Kpse_pkg" != xyes && test "x$need_[]Kpse_pkg" = xyes, prefix=texk/.' >&5
 MAKE_SUBDIRS=
 CONF_SUBDIRS=
+if test -x $srcdir/texk/ptexenc/configure; then
+  test "x$with_system_ptexenc" != xyes && test "x$need_ptexenc" = xyes && MAKE_SUBDIRS="texk/ptexenc $MAKE_SUBDIRS"
+  CONF_SUBDIRS="texk/ptexenc $CONF_SUBDIRS"
+else
+  echo 'tldbg:_KPSE_RECURSE skipping subdir, no (executable) configure: '"$srcdir"'/texk/ptexenc/configure' >&5
+fi
 if test -x $srcdir/texk/kpathsea/configure; then
   test "x$with_system_kpathsea" != xyes && test "x$need_kpathsea" = xyes && MAKE_SUBDIRS="texk/kpathsea $MAKE_SUBDIRS"
   CONF_SUBDIRS="texk/kpathsea $CONF_SUBDIRS"
@@ -21375,112 +23275,419 @@ IFS=$as_save_IFS
 
 fi
 fi
-PKG_CONFIG=$ac_cv_prog_PKG_CONFIG
-if test -n "$PKG_CONFIG"; then
-  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
-printf "%s\n" "$PKG_CONFIG" >&6; }
-else
-  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
+PKG_CONFIG=$ac_cv_prog_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+printf "%s\n" "$PKG_CONFIG" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_PKG_CONFIG"; then
+  ac_ct_PKG_CONFIG=$PKG_CONFIG
+  # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_PKG_CONFIG+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_PKG_CONFIG"; then
+  ac_cv_prog_ac_ct_PKG_CONFIG="$ac_ct_PKG_CONFIG" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_PKG_CONFIG="pkg-config"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_PKG_CONFIG=$ac_cv_prog_ac_ct_PKG_CONFIG
+if test -n "$ac_ct_PKG_CONFIG"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_PKG_CONFIG" >&5
+printf "%s\n" "$ac_ct_PKG_CONFIG" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+  if test "x$ac_ct_PKG_CONFIG" = x; then
+    PKG_CONFIG="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    PKG_CONFIG=$ac_ct_PKG_CONFIG
+  fi
+else
+  PKG_CONFIG="$ac_cv_prog_PKG_CONFIG"
+fi
+if $ICU_CONFIG --version >/dev/null 2>&1; then
+  ICU_INCLUDES=`$ICU_CONFIG --cppflags`
+  ICU_LIBS=`$ICU_CONFIG --ldflags-searchpath --ldflags-libsonly --ldflags-system`
+elif $PKG_CONFIG --libs icu-uc icu-io >/dev/null 2>&1; then
+  ICU_INCLUDES=`$PKG_CONFIG --cflags icu-uc icu-io`
+  ICU_LIBS=`$PKG_CONFIG --libs icu-uc icu-io`
+elif test "x$need_icu:$with_system_icu" = xyes:yes; then
+  as_fn_error $? "did not find either pkg-config or icu-config; one is required for system icu library support" "$LINENO" 5
+fi
+
+if $PKG_CONFIG harfbuzz; then
+  HARFBUZZ_INCLUDES=`$PKG_CONFIG harfbuzz --cflags`
+  HARFBUZZ_LIBS=`$PKG_CONFIG harfbuzz --libs`
+elif test "x$need_harfbuzz:$with_system_harfbuzz" = xyes:yes; then
+  as_fn_error $? "did not find harfbuzz" "$LINENO" 5
+fi
+
+
+
+
+
+
+## texk/kpathsea/ac/kpathsea.ac: configure.ac fragment for the TeX Live subdirectory texk/kpathsea/
+## basic check of system kpathsea
+if test "x$need_kpathsea:$with_system_kpathsea" = xyes:yes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`kpathsea' library" >&5
+printf %s "checking requested system \`kpathsea' library... " >&6; }
+  CPPFLAGS="$KPATHSEA_INCLUDES $CPPFLAGS"
+  LIBS="$KPATHSEA_LIBS $LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <kpathsea/kpathsea.h>
+#include <kpathsea/version.h>
+int
+main (void)
+{
+const char *version = kpathsea_version_string;
+kpse_set_program_name("prog", "name");
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  syslib_used=yes kpse_res=ok
+else $as_nop
+  syslib_status=no kpse_res=failed
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5
+printf "%s\n" "$kpse_res" >&6; }
+fi
+
+## texk/ptexenc/ac/ptexenc.ac: configure.ac fragment for the TeX Live subdirectory texk/ptexenc/
+## basic check of system ptexenc
+if test "x$need_ptexenc:$with_system_ptexenc" = xyes:yes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`ptexenc' library" >&5
+printf %s "checking requested system \`ptexenc' library... " >&6; }
+  CPPFLAGS="$PTEXENC_INCLUDES $CPPFLAGS"
+  LIBS="$PTEXENC_LIBS $LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ptexenc/ptexenc.h>
+int
+main (void)
+{
+const char *version = ptexenc_version_string;
+set_enc_string("prog", "name");
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  syslib_used=yes kpse_res=ok
+else $as_nop
+  syslib_status=no kpse_res=failed
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5
+printf "%s\n" "$kpse_res" >&6; }
+fi
+
+## libs/zlib/ac/zlib.ac: configure.ac fragment for the TeX Live subdirectory libs/zlib/
+## basic check of system zlib
+if test "x$need_zlib:$with_system_zlib" = xyes:yes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`zlib' library" >&5
+printf %s "checking requested system \`zlib' library... " >&6; }
+  CPPFLAGS="$ZLIB_INCLUDES $CPPFLAGS"
+  LIBS="$ZLIB_LIBS $LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <zlib.h>
+int
+main (void)
+{
+z_stream stream;
+const char *version = zlibVersion();
+deflate(&stream, 0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  syslib_used=yes kpse_res=ok
+else $as_nop
+  syslib_status=no kpse_res=failed
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5
+printf "%s\n" "$kpse_res" >&6; }
+fi
+
+## libs/libpaper/ac/libpaper.ac: configure.ac fragment for the TeX Live subdirectory libs/libpaper/
+## basic check of system libpaper
+if test "x$need_libpaper:$with_system_libpaper" = xyes:yes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`libpaper' library" >&5
+printf %s "checking requested system \`libpaper' library... " >&6; }
+  CPPFLAGS="$LIBPAPER_INCLUDES $CPPFLAGS"
+  LIBS="$LIBPAPER_LIBS $LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <paper.h>
+int
+main (void)
+{
+const char *v = defaultpapername();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  syslib_used=yes kpse_res=ok
+else $as_nop
+  syslib_status=no kpse_res=failed
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5
+printf "%s\n" "$kpse_res" >&6; }
+fi
+
+## libs/libpng/ac/libpng.ac: configure.ac fragment for the TeX Live subdirectory libs/libpng/
+## basic check of system libpng
+if test "x$need_libpng:$with_system_libpng" = xyes:yes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`libpng' library" >&5
+printf %s "checking requested system \`libpng' library... " >&6; }
+  CPPFLAGS="$LIBPNG_INCLUDES $CPPFLAGS"
+  LIBS="$LIBPNG_LIBS $LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <png.h>
+int
+main (void)
+{
+png_structp png; png_voidp io; png_rw_ptr fn;
+png_set_read_fn(png, io, fn);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  syslib_used=yes kpse_res=ok
+else $as_nop
+  syslib_status=no kpse_res=failed
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5
+printf "%s\n" "$kpse_res" >&6; }
+fi
+
+## libs/freetype2/ac/freetype2.ac: configure.ac fragment for the TeX Live subdirectory libs/freetype2/
+## basic check of system freetype2
+if test "x$need_freetype2:$with_system_freetype2" = xyes:yes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`freetype2' library" >&5
+printf %s "checking requested system \`freetype2' library... " >&6; }
+  CPPFLAGS="$FREETYPE2_INCLUDES $CPPFLAGS"
+  LIBS="$FREETYPE2_LIBS $LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ft2build.h>
+#include FT_FREETYPE_H
+int
+main (void)
+{
+FT_Library library; FT_Init_FreeType(&library);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  syslib_used=yes kpse_res=ok
+else $as_nop
+  syslib_status=no kpse_res=failed
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5
+printf "%s\n" "$kpse_res" >&6; }
+fi
+
+## libs/potrace/ac/potrace.ac: configure.ac fragment for the TeX Live subdirectory libs/potrace/
+## basic check of system potrace
+if test "x$need_potrace:$with_system_potrace" = xyes:yes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`potrace' library" >&5
+printf %s "checking requested system \`potrace' library... " >&6; }
+  CPPFLAGS="$POTRACE_INCLUDES $CPPFLAGS"
+  LIBS="$POTRACE_LIBS $LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <potracelib.h>
+int
+main (void)
+{
+potrace_state_t st;
+const char *version = potrace_version();
+potrace_state_free(&st);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  syslib_used=yes kpse_res=ok
+else $as_nop
+  syslib_status=no kpse_res=failed
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5
+printf "%s\n" "$kpse_res" >&6; }
 fi
 
-
-fi
-if test -z "$ac_cv_prog_PKG_CONFIG"; then
-  ac_ct_PKG_CONFIG=$PKG_CONFIG
-  # Extract the first word of "pkg-config", so it can be a program name with args.
-set dummy pkg-config; ac_word=$2
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-printf %s "checking for $ac_word... " >&6; }
-if test ${ac_cv_prog_ac_ct_PKG_CONFIG+y}
+## libs/gd/ac/gd.ac: configure.ac fragment for the TeX Live subdirectory libs/gd/
+## basic check of system gd
+if test "x$need_gd:$with_system_gd" = xyes:yes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`gd' library" >&5
+printf %s "checking requested system \`gd' library... " >&6; }
+  CPPFLAGS="$GD_INCLUDES $CPPFLAGS"
+  LIBS="$GD_LIBS $LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <gd.h>
+int
+main (void)
+{
+gdImageCreate(1, 2);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
 then :
-  printf %s "(cached) " >&6
+  syslib_used=yes kpse_res=ok
 else $as_nop
-  if test -n "$ac_ct_PKG_CONFIG"; then
-  ac_cv_prog_ac_ct_PKG_CONFIG="$ac_ct_PKG_CONFIG" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  case $as_dir in #(((
-    '') as_dir=./ ;;
-    */) ;;
-    *) as_dir=$as_dir/ ;;
-  esac
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_PKG_CONFIG="pkg-config"
-    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
+  syslib_status=no kpse_res=failed
 fi
-ac_ct_PKG_CONFIG=$ac_cv_prog_ac_ct_PKG_CONFIG
-if test -n "$ac_ct_PKG_CONFIG"; then
-  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_PKG_CONFIG" >&5
-printf "%s\n" "$ac_ct_PKG_CONFIG" >&6; }
-else
-  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5
+printf "%s\n" "$kpse_res" >&6; }
 fi
 
-  if test "x$ac_ct_PKG_CONFIG" = x; then
-    PKG_CONFIG="false"
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    PKG_CONFIG=$ac_ct_PKG_CONFIG
-  fi
-else
-  PKG_CONFIG="$ac_cv_prog_PKG_CONFIG"
+## libs/pixman/ac/pixman.ac: configure.ac fragment for the TeX Live subdirectory libs/pixman/
+## basic check of system pixman
+if test "x$need_pixman:$with_system_pixman" = xyes:yes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`pixman' library" >&5
+printf %s "checking requested system \`pixman' library... " >&6; }
+  CPPFLAGS="$PIXMAN_INCLUDES $CPPFLAGS"
+  LIBS="$PIXMAN_LIBS $LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pixman.h>
+int
+main (void)
+{
+const char *s = pixman_version_string();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  syslib_used=yes kpse_res=ok
+else $as_nop
+  syslib_status=no kpse_res=failed
 fi
-if $ICU_CONFIG --version >/dev/null 2>&1; then
-  ICU_INCLUDES=`$ICU_CONFIG --cppflags`
-  ICU_LIBS=`$ICU_CONFIG --ldflags-searchpath --ldflags-libsonly --ldflags-system`
-elif $PKG_CONFIG --libs icu-uc icu-io >/dev/null 2>&1; then
-  ICU_INCLUDES=`$PKG_CONFIG --cflags icu-uc icu-io`
-  ICU_LIBS=`$PKG_CONFIG --libs icu-uc icu-io`
-elif test "x$need_icu:$with_system_icu" = xyes:yes; then
-  as_fn_error $? "did not find either pkg-config or icu-config; one is required for system icu library support" "$LINENO" 5
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5
+printf "%s\n" "$kpse_res" >&6; }
 fi
 
-if $PKG_CONFIG harfbuzz; then
-  HARFBUZZ_INCLUDES=`$PKG_CONFIG harfbuzz --cflags`
-  HARFBUZZ_LIBS=`$PKG_CONFIG harfbuzz --libs`
-elif test "x$need_harfbuzz:$with_system_harfbuzz" = xyes:yes; then
-  as_fn_error $? "did not find harfbuzz" "$LINENO" 5
+## libs/cairo/ac/cairo.ac: configure.ac fragment for the TeX Live subdirectory libs/cairo/
+## basic check of system cairo
+if test "x$need_cairo:$with_system_cairo" = xyes:yes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`cairo' library" >&5
+printf %s "checking requested system \`cairo' library... " >&6; }
+  CPPFLAGS="$CAIRO_INCLUDES $CPPFLAGS"
+  LIBS="$CAIRO_LIBS $LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <cairo.h>
+int
+main (void)
+{
+const char *s = cairo_version_string();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  syslib_used=yes kpse_res=ok
+else $as_nop
+  syslib_status=no kpse_res=failed
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5
+printf "%s\n" "$kpse_res" >&6; }
 fi
 
-
-
-
-
-
-## texk/kpathsea/ac/kpathsea.ac: configure.ac fragment for the TeX Live subdirectory texk/kpathsea/
-## basic check of system kpathsea
-if test "x$need_kpathsea:$with_system_kpathsea" = xyes:yes; then
-  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`kpathsea' library" >&5
-printf %s "checking requested system \`kpathsea' library... " >&6; }
-  CPPFLAGS="$KPATHSEA_INCLUDES $CPPFLAGS"
-  LIBS="$KPATHSEA_LIBS $LIBS"
+## libs/gmp/ac/gmp.ac: configure.ac fragment for the TeX Live subdirectory libs/gmp/
+## basic check of system gmp
+if test "x$need_gmp:$with_system_gmp" = xyes:yes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`gmp' library" >&5
+printf %s "checking requested system \`gmp' library... " >&6; }
+  CPPFLAGS="$GMP_INCLUDES $CPPFLAGS"
+  LIBS="$GMP_LIBS $LIBS"
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <kpathsea/kpathsea.h>
-#include <kpathsea/version.h>
+#include <gmp.h>
 int
 main (void)
 {
-const char *version = kpathsea_version_string;
-kpse_set_program_name("prog", "name");
+const char *s = gmp_version;
   ;
   return 0;
 }
@@ -21497,22 +23704,20 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \
 printf "%s\n" "$kpse_res" >&6; }
 fi
 
-## libs/zlib/ac/zlib.ac: configure.ac fragment for the TeX Live subdirectory libs/zlib/
-## basic check of system zlib
-if test "x$need_zlib:$with_system_zlib" = xyes:yes; then
-  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`zlib' library" >&5
-printf %s "checking requested system \`zlib' library... " >&6; }
-  CPPFLAGS="$ZLIB_INCLUDES $CPPFLAGS"
-  LIBS="$ZLIB_LIBS $LIBS"
+## libs/mpfr/ac/mpfr.ac: configure.ac fragment for the TeX Live subdirectory libs/mpfr/
+## basic check of system mpfr
+if test "x$need_mpfr:$with_system_mpfr" = xyes:yes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`mpfr' library" >&5
+printf %s "checking requested system \`mpfr' library... " >&6; }
+  CPPFLAGS="$MPFR_INCLUDES $CPPFLAGS"
+  LIBS="$MPFR_LIBS $LIBS"
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <zlib.h>
+#include <mpfr.h>
 int
 main (void)
 {
-z_stream stream;
-const char *version = zlibVersion();
-deflate(&stream, 0);
+const char *s = mpfr_get_version();
   ;
   return 0;
 }
@@ -21529,26 +23734,31 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \
 printf "%s\n" "$kpse_res" >&6; }
 fi
 
-## libs/libpng/ac/libpng.ac: configure.ac fragment for the TeX Live subdirectory libs/libpng/
-## basic check of system libpng
-if test "x$need_libpng:$with_system_libpng" = xyes:yes; then
-  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`libpng' library" >&5
-printf %s "checking requested system \`libpng' library... " >&6; }
-  CPPFLAGS="$LIBPNG_INCLUDES $CPPFLAGS"
-  LIBS="$LIBPNG_LIBS $LIBS"
+## libs/xpdf/ac/xpdf.ac: configure.ac fragment for the TeX Live subdirectory libs/xpdf/
+## basic check of system xpdf (a.k.a. poppler, no longer supported in
+## TL sources)
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test "x$need_xpdf:$with_system_xpdf" = xyes:yes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`xpdf' library" >&5
+printf %s "checking requested system \`xpdf' library... " >&6; }
+  CPPFLAGS="$XPDF_INCLUDES $CPPFLAGS"
+  LIBS="$XPDF_LIBS $LIBS"
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <png.h>
+#include <GfxFont.h>
 int
 main (void)
 {
-png_structp png; png_voidp io; png_rw_ptr fn;
-png_set_read_fn(png, io, fn);
+GfxFont *gfxFont; gfxFont->decRefCnt();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"
+if ac_fn_cxx_try_link "$LINENO"
 then :
   syslib_used=yes kpse_res=ok
 else $as_nop
@@ -21559,6 +23769,11 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \
   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5
 printf "%s\n" "$kpse_res" >&6; }
 fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 ## libs/zziplib/ac/zziplib.ac: configure.ac fragment for the TeX Live subdirectory libs/zziplib/
 ## basic check of system zziplib
@@ -21621,6 +23836,87 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \
 printf "%s\n" "$kpse_res" >&6; }
 fi
 
+## libs/teckit/ac/teckit.ac: configure.ac fragment for the TeX Live subdirectory libs/teckit/
+## basic check of system teckit
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test "x$need_teckit:$with_system_teckit" = xyes:yes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`teckit' library" >&5
+printf %s "checking requested system \`teckit' library... " >&6; }
+  CPPFLAGS="$TECKIT_INCLUDES $CPPFLAGS"
+  LIBS="$TECKIT_LIBS $LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <teckit/TECkit_Engine.h>
+int
+main (void)
+{
+TECkit_Converter converter; TECkit_DisposeConverter(converter);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"
+then :
+  syslib_used=yes kpse_res=ok
+else $as_nop
+  syslib_status=no kpse_res=failed
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5
+printf "%s\n" "$kpse_res" >&6; }
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+## libs/icu/ac/icu.ac: configure.ac fragment for the TeX Live subdirectory libs/icu/
+## basic check of system icu
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test "x$need_icu:$with_system_icu" = xyes:yes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking requested system \`icu' library" >&5
+printf %s "checking requested system \`icu' library... " >&6; }
+  CPPFLAGS="$ICU_INCLUDES $CPPFLAGS"
+  LIBS="$ICU_LIBS $LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <unicode/ustring.h>
+int
+main (void)
+{
+UErrorCode code; const UChar *src; UChar *dst;
+u_strToLower(dst, -1, src, -1, NULL, &code);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"
+then :
+  syslib_used=yes kpse_res=ok
+else $as_nop
+  syslib_status=no kpse_res=failed
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5
+printf "%s\n" "$kpse_res" >&6; }
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
 ## libs/harfbuzz/ac/harfbuzz.ac: configure.ac fragment for the TeX Live subdirectory libs/harfbuzz/
 ## basic check of system harfbuzz
 if test "x$need_harfbuzz:$with_system_harfbuzz" = xyes:yes; then
diff --git a/source/libs/README b/source/libs/README
index 31b0362e3567ce1a233da9412268e1ba5cacc8cd..d0ebcb6c604a7c328a4cb46cd2a3b20db2cd9758 100644
--- a/source/libs/README
+++ b/source/libs/README
@@ -1,4 +1,4 @@
-$Id: README 66694 2023-03-28 06:08:03Z kakuto $
+$Id: README 66959 2023-04-28 00:33:16Z kakuto $
 Public domain.  Originally created by Karl Berry, 2005.
 
 Libraries we compile for TeX Live.
@@ -25,8 +25,8 @@ graphite2 1.3.14 - checked 10apr20
   http://sourceforge.net/projects/silgraphite/files/graphite2/
   (requires C++11)
 
-harfbuzz 7.1.0 - checked 28mar23
-  https://github.com/harfbuzz/harfbuzz/releases/tag/7.1.0
+harfbuzz 7.2.0 - checked 28apr23
+  https://github.com/harfbuzz/harfbuzz/releases/tag/7.2.0
 
 icu 72.1 - checked 07jan23
   https://github.com/unicode-org/icu/releases/
diff --git a/source/libs/harfbuzz/ChangeLog b/source/libs/harfbuzz/ChangeLog
index b023344e02572b7c9d98ea97c10de4fdb47ff5d2..80b2e7e84d6a1b159e642e69012493651e787755 100644
--- a/source/libs/harfbuzz/ChangeLog
+++ b/source/libs/harfbuzz/ChangeLog
@@ -1,3 +1,8 @@
+2023-04-28  Akira Kakuto  <kakuto@jcom.zaq.ne.jp>
+
+	Import harfbuzz-7.2.0.
+	* version.ac: Adjusted.
+
 2023-03-28  Akira Kakuto  <kakuto@jcom.zaq.ne.jp>
 
 	Import harfbuzz-7.1.0.
diff --git a/source/libs/harfbuzz/TLpatches/ChangeLog b/source/libs/harfbuzz/TLpatches/ChangeLog
index f59e55f504dd52f22d082a003a07488684a032ea..7819c9e535ced4057cb49f916261bc6a77ef7c9d 100644
--- a/source/libs/harfbuzz/TLpatches/ChangeLog
+++ b/source/libs/harfbuzz/TLpatches/ChangeLog
@@ -1,3 +1,8 @@
+2023-04-28  Akira Kakuto  <kakuto@jcom.zaq.ne.jp>
+
+	Imported harfbuzz-7.2.0 source tree from:
+	https://github.com/harfbuzz/harfbuzz/releases/download/7.2.0/
+
 2023-03-28  Akira Kakuto  <kakuto@jcom.zaq.ne.jp>
 
 	Imported harfbuzz-7.1.0 source tree from:
diff --git a/source/libs/harfbuzz/TLpatches/TL-Changes b/source/libs/harfbuzz/TLpatches/TL-Changes
index a22b47ec07aad73981c4f2fcd88665dc4ff61e41..124cc3fd7b4df5fc3be4a184f68b48ac16d525a0 100644
--- a/source/libs/harfbuzz/TLpatches/TL-Changes
+++ b/source/libs/harfbuzz/TLpatches/TL-Changes
@@ -1,5 +1,5 @@
-Changes applied to the harfbuzz-7.1.0/ tree as obtained from:
-	https://github.com/harfbuzz/harfbuzz/releases/download/7.1.0/
+Changes applied to the harfbuzz-7.2.0/ tree as obtained from:
+	https://github.com/harfbuzz/harfbuzz/releases/download/7.2.0/
 
 Removed:
 	COPYING
diff --git a/source/libs/harfbuzz/configure b/source/libs/harfbuzz/configure
index fd8ba8ff07916706503750a34db6cdc97f07755f..279c26bb953c7fe368d3f04d90e1f0f06335c6a4 100755
--- a/source/libs/harfbuzz/configure
+++ b/source/libs/harfbuzz/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for harfbuzz (TeX Live) 7.1.0.
+# Generated by GNU Autoconf 2.71 for harfbuzz (TeX Live) 7.2.0.
 #
 # Report bugs to <tex-k@tug.org>.
 #
@@ -611,8 +611,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='harfbuzz (TeX Live)'
 PACKAGE_TARNAME='harfbuzz--tex-live-'
-PACKAGE_VERSION='7.1.0'
-PACKAGE_STRING='harfbuzz (TeX Live) 7.1.0'
+PACKAGE_VERSION='7.2.0'
+PACKAGE_STRING='harfbuzz (TeX Live) 7.2.0'
 PACKAGE_BUGREPORT='tex-k@tug.org'
 PACKAGE_URL=''
 
@@ -1346,7 +1346,7 @@ if test "$ac_init_help" = "long"; then
   # 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) 7.1.0 to adapt to many kinds of systems.
+\`configure' configures harfbuzz (TeX Live) 7.2.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1418,7 +1418,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 7.1.0:";;
+     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 7.2.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1523,7 +1523,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-harfbuzz (TeX Live) configure 7.1.0
+harfbuzz (TeX Live) configure 7.2.0
 generated by GNU Autoconf 2.71
 
 Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2064,7 +2064,7 @@ cat >config.log <<_ACEOF
 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 7.1.0, which was
+It was created by harfbuzz (TeX Live) $as_me 7.2.0, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -4823,7 +4823,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='harfbuzz--tex-live-'
- VERSION='7.1.0'
+ VERSION='7.2.0'
 
 
 # Some tools Automake needs.
@@ -5034,9 +5034,9 @@ WARNING_CFLAGS=$kpse_cv_warning_cflags
 
 
 HB_VERSION_MAJOR=7
-HB_VERSION_MINOR=1
+HB_VERSION_MINOR=2
 HB_VERSION_MICRO=0
-HB_VERSION=7.1.0
+HB_VERSION=7.2.0
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -8817,7 +8817,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # 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 7.1.0, which was
+This file was extended by harfbuzz (TeX Live) $as_me 7.2.0, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -8885,7 +8885,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-harfbuzz (TeX Live) config.status 7.1.0
+harfbuzz (TeX Live) config.status 7.2.0
 configured by $0, generated by GNU Autoconf 2.71,
   with options \\"\$ac_cs_config\\"
 
diff --git a/source/libs/harfbuzz/harfbuzz-src/ChangeLog b/source/libs/harfbuzz/harfbuzz-src/ChangeLog
index 1111f51303fd2b2f3fffbe90350d92fe2fa50835..eba3425ff122ce72456465080a116b96e9e50fae 100644
--- a/source/libs/harfbuzz/harfbuzz-src/ChangeLog
+++ b/source/libs/harfbuzz/harfbuzz-src/ChangeLog
@@ -1,3 +1,1444 @@
+commit a321c4fee56b15247c10f9aa3db7e7ccb3b8173b
+Author: Khaled Hosny <khaled@aliftype.com>
+Date:   Thu Apr 27 00:48:00 2023 +0200
+
+    7.2.0
+
+ NEWS                | 29 +++++++++++++++++++++++++++++
+ configure.ac        |  2 +-
+ meson.build         |  2 +-
+ src/hb-deprecated.h |  2 +-
+ src/hb-subset.h     |  2 +-
+ src/hb-unicode.h    |  2 +-
+ src/hb-version.h    |  4 ++--
+ 7 files changed, 36 insertions(+), 7 deletions(-)
+
+commit fd52c4cf7b97b7d16b442d369ae1d8ad18efa36e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 26 16:27:51 2023 -0600
+
+    [gvar] Comment
+
+ src/hb-ot-var-gvar-table.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 0c59c629c1d46067bca26e10e051eaabd87ff0b2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 26 16:20:16 2023 -0600
+
+    [gvar] Micro-optimize
+    
+    For cases where no deltaset applies.
+
+ src/hb-ot-var-gvar-table.hh | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit 5d1a603ad1556f8797180aea0f7201f3bad66441
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 26 16:25:15 2023 -0600
+
+    [var] Fix compiler warnings
+
+ src/hb-ot-var-common.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit af393e9652aa746c42652e3590dfb12724dd0877
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 26 16:02:06 2023 -0600
+
+    [gvar] Refactor a variable
+
+ src/hb-ot-var-common.hh | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+commit 2a3bf5a542aaefb72bac4708ca9ded99b2ec62cb
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 26 15:58:55 2023 -0600
+
+    [gvar] Minor error-handling
+
+ src/hb-ot-var-gvar-table.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 57faabb78e030388dca2cd6b6ec7d94a484c0956
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 26 15:56:04 2023 -0600
+
+    [gvar] Micro-optimize
+
+ src/hb-ot-var-gvar-table.hh | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+commit 76e269af9e87d95415564d75a3aabc2ecec262cd
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 26 15:47:12 2023 -0600
+
+    [gvar] Micro-optimize
+
+ src/hb-ot-var-common.hh | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+commit 7349cea127599d4d164b3ef4b05aee80451bc26b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 26 14:27:24 2023 -0600
+
+    [gvar] Micro-optimization
+
+ src/hb-ot-var-common.hh | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+commit bc535870025dbb78e83ebad1e01aba8644825e87
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 26 13:57:11 2023 -0600
+
+    [deprecated] Add HB_UNICODE_COMBINING_CLASS_CCC133
+    
+    https://github.com/harfbuzz/harfbuzz/pull/4207
+
+ docs/harfbuzz-sections.txt |  1 +
+ src/hb-deprecated.h        | 11 +++++++++++
+ 2 files changed, 12 insertions(+)
+
+commit c5afe026bdf784d05f32d9be31a38c077746d210
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 26 13:44:03 2023 -0600
+
+    [gvar] Comment
+
+ src/hb-ot-var-gvar-table.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 87c6e68ec31260fb51d67d563c61adb61041bb41
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 26 13:20:51 2023 -0600
+
+    [gvar] Assertion
+
+ src/hb-ot-var-common.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 09386737312ddae4d850334cd55063de935cf6d5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 26 13:19:27 2023 -0600
+
+    [gvar] Error handling & micro-optimization
+
+ src/hb-ot-var-common.hh     | 2 +-
+ src/hb-ot-var-gvar-table.hh | 5 +++--
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+commit b6aa2d71f39473d1d927376a4959bb73398aa4ca
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 26 13:06:24 2023 -0600
+
+    [gvar] Speed up calculate_scalar more
+    
+    Use a gvar-wide cache of the one active peak index for shared-tuples
+    that have only one active peak. This speeds up the scalar calculation.
+    
+    This shows significant speedup for the CJK VarComposite font for
+    example since that has tens of axes with mostly only one active peak.
+
+ src/hb-ot-var-common.hh     | 18 ++++++++++++++++--
+ src/hb-ot-var-gvar-table.hh | 27 ++++++++++++++++++++++++++-
+ 2 files changed, 42 insertions(+), 3 deletions(-)
+
+commit ffbfab123f0966f4ee1c00b24fcb7158b1b3857d
+Author: Han Seung Min - 한승민 <hanseungmin.ar@gmail.com>
+Date:   Thu Apr 27 00:43:48 2023 +0900
+
+    oops docs
+
+ src/hb-unicode.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e428edc3714eebe68981c579bda9412f303f538d
+Author: Han Seung Min - 한승민 <hanseungmin.ar@gmail.com>
+Date:   Wed Apr 26 23:57:21 2023 +0900
+
+    [unicode] Fix typo
+    
+    I believe the `hb-unicode.h` has a typo where `HB_UNICODE_COMBINING_CLASS_CCC133        = 132,` is supposed to be `HB_UNICODE_COMBINING_CLASS_CCC132`
+
+ src/hb-unicode.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 63afb4f2e7cc6053fb884108b360f19d1103b065
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 26 10:29:25 2023 -0600
+
+    [syllabic] Better fix for previous issue
+    
+    With previous fix the GPOS application was still reading the syllable()
+    member, which was already freed.  This fix is more correct.
+
+ src/hb-ot-layout-gsubgpos.hh | 3 ++-
+ src/hb-ot-shaper-syllabic.cc | 4 ----
+ 2 files changed, 2 insertions(+), 5 deletions(-)
+
+commit c5f3b3feb1d2845b46e19f7e01605bbcf3e7f480
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 26 10:17:37 2023 -0600
+
+    [syllabic] Actually clear syllables
+    
+    Such that they don't affect GPOS.
+    
+    I broke this in 044d7a06db552e1564b8575f4d23798f009d9dde.
+
+ src/hb-ot-shaper-syllabic.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 9ee7c2ea63416a6e7e98461d9b5480e7af22c427
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 25 16:13:54 2023 -0600
+
+    [cmap] Minor remove magic number
+
+ src/hb-ot-cmap-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 580b0dc1c353c5cf2d2b6ba63f17043baf050d8d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 25 16:11:01 2023 -0600
+
+    [cmap] Comment
+
+ src/hb-ot-cmap-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1d31da91ce02bf01947f1533d896dc4a4a5f6bcb
+Merge: f6803b06b e41f31719
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 25 15:34:06 2023 -0600
+
+    Merge pull request #4205 from harfbuzz/gvar-optimize
+    
+    Gvar optimize
+
+commit e41f3171994a739ff966735b78e1777ab5933471
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Apr 25 20:54:27 2023 +0000
+
+    [subset] Update expectation files for full_instance tests.
+
+ ...fault.retain-all-codepoint.wght=300,wdth=90.ttf | Bin 114300 -> 114300 bytes
+ ...anges.retain-all-codepoint.wght=300,wdth=90.ttf | Bin 114300 -> 114300 bytes
+ test/subset/data/tests/full_instance.tests         |   3 +++
+ 3 files changed, 3 insertions(+)
+
+commit f6803b06bf7ef6b6a480e9dd489a8fa693d7b403
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 25 14:46:44 2023 -0600
+
+    [VarRegionAxis] Micro-optimize
+    
+    peak==0 is common.
+
+ src/hb-ot-layout-common.hh | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+commit f91929d6da527e42b4f46c7738d40e118107163a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 25 14:42:00 2023 -0600
+
+    Minor return floats instead of doubles from function
+    
+    Not that any compiler complained...
+
+ src/hb-ot-layout-common.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 808a21f8de7523b26ddad2316e55fafa6daf4fe2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 25 14:03:52 2023 -0600
+
+    [gvar] Simplify ref_points logic
+
+ src/hb-ot-var-gvar-table.hh | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+commit 78a0216a031234fdcc14448f906649bd83bb7118
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 25 13:52:00 2023 -0600
+
+    [gvar] Write a for loop as range loop
+
+ src/hb-ot-var-gvar-table.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit f654823fe0639bf6c71d77f53c34b4b2f878eb2e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 25 13:09:40 2023 -0600
+
+    [gvar] Handle an error case
+
+ src/hb-ot-var-gvar-table.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 30d08dc62cfab0f5f8d8d4491f91eb352eebfb3e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 25 12:13:57 2023 -0600
+
+    [gvar] Populate end_points lazily
+    
+    Tiny micro-optimization...
+
+ src/hb-ot-var-gvar-table.hh | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+commit fe8c91707b5579f77505e37ebea8578e1282db38
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 25 11:30:36 2023 -0600
+
+    [gvar] Micro-optimize has_intermediate() access
+
+ src/hb-ot-var-common.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 2175f5d050743317c563ec9414e0f83a47f7fbc4
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Apr 24 21:13:18 2023 +0000
+
+    [subset] Fix inefficient ItemVariationStore subsetting w/ retain_gids.
+    
+    ItemVariationStore is relying on the assumption that the inner_map is populated for all output glyphs, this is not true for subsetting operations with retain gids enabled. Fixes fuzzer timeout: https://oss-fuzz.com/testcase-detail/4575222591520768.
+
+ src/hb-bimap.hh                                         |   9 +++++++++
+ src/hb-ot-layout-common.hh                              |  14 ++++++--------
+ src/hb-ot-var-hvar-table.hh                             |  10 ++++------
+ ...testcase-minimized-hb-subset-fuzzer-4575222591520768 | Bin 0 -> 91107 bytes
+ .../variable/Fraunces.retain-gids.26,66,69,124,125.ttf  | Bin 0 -> 21296 bytes
+ .../data/expected/variable/Fraunces.retain-gids.61.ttf  | Bin 0 -> 4508 bytes
+ test/subset/data/tests/variable.tests                   |   1 +
+ 7 files changed, 20 insertions(+), 14 deletions(-)
+
+commit 385e23762dc18659c4cc0c69e17549fe3e00d74e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 24 17:51:07 2023 -0600
+
+    [var] Optimize calculate_scalar more
+    
+    This change alone is showing me 14% scalar in a benchmark.
+    The reason being that the array::operator[] is not being invoked
+    a lot of time, which was, many times, hitting the unlikely() path.
+    Weird!
+
+ src/hb-ot-var-common.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 7a3928e2b6099c5c334ca0b2469a567b529bcf34
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 24 17:38:20 2023 -0600
+
+    [var] Optimize calculate_scalar
+    
+    For varfonts with lots of deltasets, the loop in this function is
+    *really* hot...
+
+ src/hb-ot-var-common.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 89296036317bf718c99fdd1dc0d1bf4f1c34323a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 24 16:16:27 2023 -0600
+
+    [gvar] Another minor optimization
+    
+    Allocate orig_points lazily only when needed.
+
+ src/hb-ot-var-gvar-table.hh | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+commit 20454eaa399abe28db485b2ccb461c30861023e0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 24 15:50:58 2023 -0600
+
+    [gvar] Optimize by applying deltas in batches
+    
+    Shows up to 7% speedup in one of my benchmarks.
+    
+    One test fails by one rounding issue. To be updated.
+
+ src/hb-ot-var-gvar-table.hh | 22 +++++++++++++++++-----
+ 1 file changed, 17 insertions(+), 5 deletions(-)
+
+commit 491aa572ce9c845afa40cfdcded4959add46fd5c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 24 15:05:18 2023 -0600
+
+    [gvar] Minor call a function instead of handcoding
+
+ src/hb-ot-var-gvar-table.hh | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+commit cf95f3193bfb85ec4d14041e93df8a03909f40a1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 24 14:45:52 2023 -0600
+
+    [VarComposite] Another minor resue of num_points
+
+ src/OT/glyf/Glyph.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit fc8dfe64d04e3d429f9c8c7f39e52c619c4bba13
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 24 14:39:20 2023 -0600
+
+    [benchmark-font] Minor rename
+
+ perf/benchmark-font.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 0a5208422821471d2904e164cad651bd8dadcfb4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 24 14:23:24 2023 -0600
+
+    [VarComposite] Minor resue of num_points
+
+ src/OT/glyf/VarCompositeGlyph.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit a9a9f278b81f6a855afce1bf668410d3ccceb682
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 24 14:16:48 2023 -0600
+
+    [atomic] Remove incomplete comment
+
+ src/hb-atomic.hh | 4 ----
+ 1 file changed, 4 deletions(-)
+
+commit d1c00c047030226b6b5255cc4b7cdeb738ee0ccc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 24 13:24:47 2023 -0600
+
+    [COLR] Respect HB_NO_PAINT
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4204
+
+ src/OT/Color/COLR/COLR.hh | 4 ++++
+ src/hb-ot-font.cc         | 2 +-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+commit 4129061e37824433f9c81eaa99d1618af2f2d69a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 24 13:04:05 2023 -0600
+
+    Revert "Move hb-ot-name-language-static.hh out of hb-static.cc"
+    
+    This reverts commit 7b5f0dd3a8b4a126b7952fea1c4c30b8b456083e.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4203
+
+ src/hb-ot-name.cc | 2 --
+ src/hb-static.cc  | 1 +
+ src/hb-subset.cc  | 5 -----
+ 3 files changed, 1 insertion(+), 7 deletions(-)
+
+commit e76a3649db4611ac0531cbb5fc8e555a039b93f3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Apr 22 10:20:25 2023 -0600
+
+    [atomic] Comment
+
+ src/hb-atomic.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 8e43e3a8ce72a3888e9bfbc9f2975fc56e139836
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Apr 22 10:16:43 2023 -0600
+
+    [priority-heap] Comment
+
+ src/hb-priority-queue.hh | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 48f8ed7e0205e1c0dcf0a19c1bfc9b515182563a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Apr 22 10:11:22 2023 -0600
+
+    Docs
+
+ src/hb-buffer.cc    | 5 +++++
+ src/hb-face.cc      | 6 ++++++
+ src/hb-font.cc      | 5 +++++
+ src/hb-ot-layout.cc | 2 ++
+ 4 files changed, 18 insertions(+)
+
+commit b31684dca478da09d9ae5063658d5663fa5cbce0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Apr 22 09:47:58 2023 -0600
+
+    [cache] Add some AI-generated comments
+
+ src/hb-cache.hh | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+commit bffdca89f7977e7a4b84a69196ac48f1df6d3c6f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Apr 22 09:32:57 2023 -0600
+
+    [pool] Add funny Copilot comment
+
+ src/hb-pool.hh | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+commit a960571f24b0383dedd958df4f268fcb877fe94d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 21 16:45:08 2023 -0600
+
+    [glyf] Comments
+
+ src/OT/glyf/Glyph.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 2b042cc5c6e90736754acdbbd035fe4a230b9fd6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 21 16:43:47 2023 -0600
+
+    [VarComposite] Implement trim_padding()
+
+ src/OT/glyf/Glyph.hh             | 2 +-
+ src/OT/glyf/VarCompositeGlyph.hh | 7 +++++++
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+commit 591c9460dc28967c5db11e9301d81d08c2773217
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Fri Apr 21 14:12:27 2023 -0700
+
+    [instancer] compile composite glyphs directly with shifted component
+    points instead of deltas
+
+ src/OT/glyf/CompositeGlyph.hh | 25 ++++++++++++-------------
+ src/OT/glyf/Glyph.hh          | 27 +++++++++------------------
+ 2 files changed, 21 insertions(+), 31 deletions(-)
+
+commit 3520f528aaba200ab2e3f1edfe746c7963a7ce54
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 21 15:46:36 2023 -0600
+
+    [CompositeGlyph] Apply gvar deltas with component transform
+    
+    This was being done wrong for one of the scaled_offsets() cases.
+
+ src/OT/glyf/CompositeGlyph.hh | 37 ++++++++++++++++++++++---------------
+ src/OT/glyf/Glyph.hh          | 14 +++++++-------
+ 2 files changed, 29 insertions(+), 22 deletions(-)
+
+commit 33972b3bf6cd9a63424a2213e5b80bff474b7d10
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 21 12:37:51 2023 -0600
+
+    [glyf] Increase CompositeGlyf memory allocation
+    
+    The 50% wasn't justified by logic.
+
+ src/OT/glyf/CompositeGlyph.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 290cef39bed5fcc05e3a424ce05b1797507a0a03
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 21 12:22:30 2023 -0600
+
+    [glyf] When instancing, just spew empty VarComposites
+    
+    Before we were dropping the entire glyf table.
+
+ src/OT/glyf/Glyph.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 4353192d057fe3583a4ad234e478a407e9d1eb1a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 21 11:59:15 2023 -0600
+
+    [aat] Tweak a couple sanitize calls that are never called
+
+ src/hb-aat-layout-common.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 305012609bddba97a2fbc5080a146bc3d3feaa06
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 21 11:42:18 2023 -0600
+
+    [hdmx] Remove unused unsafe function
+
+ src/hb-ot-hdmx-table.hh | 10 +---------
+ 1 file changed, 1 insertion(+), 9 deletions(-)
+
+commit f74abc307d742f6f90b0012dc1cef66da149742e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 21 11:37:37 2023 -0600
+
+    [face] Comment
+
+ src/hb-face.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit d1f49ba6d2dc7f8c316f055a9e4f9cdf4dafdcad
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 20 18:17:14 2023 -0600
+
+    [VarComposites] More ifdef guards
+
+ src/OT/glyf/Glyph.hh | 33 ++++++++++++++++++++++++++++-----
+ 1 file changed, 28 insertions(+), 5 deletions(-)
+
+commit 1e9a0511f33a851b27d6d0320b0d426bf95c97ce
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 20 17:47:04 2023 -0600
+
+    [subset] Fix HB_TINY build
+
+ src/hb-subset-plan.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 106a237e404b4942803a52a8ab4114b2f3034c77
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 20 17:44:59 2023 -0600
+
+    [subset/glyf] Close over VarComposite glyphs
+    
+    Subsetting VarComposite glyphs works now.
+
+ src/hb-subset-plan.cc | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+commit f2d21425a353728fa69680eff24421cce22981de
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 20 17:31:58 2023 -0600
+
+    [VarC/subset] Support subsetting VarComposites
+    
+    By renumbering components.
+
+ src/OT/glyf/SubsetGlyph.hh       | 15 +++++++++++++--
+ src/OT/glyf/VarCompositeGlyph.hh |  8 ++++++++
+ 2 files changed, 21 insertions(+), 2 deletions(-)
+
+commit 15d0a1dcfd192fda87c4877da2029c14d0bd5bd2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 20 17:28:10 2023 -0600
+
+    [glyf] TODO
+
+ src/OT/glyf/SubsetGlyph.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 85d0c3b5f1158eedc7ead3cae55adb026456352b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 20 17:17:28 2023 -0600
+
+    [glyf] Comment
+
+ src/OT/glyf/CompositeGlyph.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 5d74b42b9e3e2a591071d196d9d2b2dd537a496b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 20 17:15:57 2023 -0600
+
+    [glyf] Change variable name
+
+ src/OT/glyf/SubsetGlyph.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit c997e490c78f8e643f9d8ff8c712cc1856b4979f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 20 17:02:38 2023 -0600
+
+    Remove unnecessary return
+
+ src/OT/glyf/CompositeGlyph.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 781da13e99d1373b4e33a84b40e01923e6f64e49
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 20 16:59:25 2023 -0600
+
+    [glyf] Comment
+
+ src/OT/glyf/SubsetGlyph.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 0e4bcf908ca4bf394a326970490ae1943966a410
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 20 16:23:41 2023 -0600
+
+    [hmtx] Add TODO
+
+ src/hb-ot-hmtx-table.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 639f45ef9e9bcb9b3a4c380e41d4a574156f41c0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 20 16:21:08 2023 -0600
+
+    [beyond-64k/subset] Implement subsetting of hmtx beyond64k
+
+ src/hb-ot-hmtx-table.hh | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+commit b3da715b9c0a5d0354cabb8a7e9117622643c119
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 20 16:05:03 2023 -0600
+
+    Fix HB_TINY build
+
+ src/OT/glyf/glyf.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 32f145ff9cd87a97d5eb265e29689c304799ebf3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 20 15:58:26 2023 -0600
+
+    Fix build
+
+ src/OT/glyf/Glyph.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 000a3c5dca1deb811646cf94e705733f5e9ee422
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 20 15:53:10 2023 -0600
+
+    [beyond-64k/subset] Fetch lsb from glyph table if not available
+    
+    The beyond-64k hmtx table doesn't encode LSB. If subsetting brings
+    the glyph under 64k (which currently is the only mode we support),
+    then we need to encode the LSB, which wasn't available. We need to
+    fetch xMin from glyf table and set it as LSB.
+
+ src/OT/glyf/Glyph.hh    |  1 +
+ src/OT/glyf/glyf.hh     |  9 +++++++++
+ src/hb-ot-font.cc       | 16 ----------------
+ src/hb-ot-hmtx-table.hh |  6 +++++-
+ src/hb-static.cc        | 23 +++++++++++++++++++++++
+ 5 files changed, 38 insertions(+), 17 deletions(-)
+
+commit 1111c7578ed76f9b338c5cbc13792ff638e22783
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 20 15:17:23 2023 -0600
+
+    hb_memset
+
+ src/OT/glyf/SubsetGlyph.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 219e739c9f21a16942162a53935f1dfbaf0414fa
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 20 15:10:29 2023 -0600
+
+    [beyond-64k/subset] Lower CompositeGlyph GID24's when possible
+
+ src/OT/glyf/CompositeGlyph.hh | 20 ++++++++++++++++++++
+ src/OT/glyf/SubsetGlyph.hh    | 41 +++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 61 insertions(+)
+
+commit a2e8ecf9969b0657221f7d0ad6e6aeca5c20cd11
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 20 13:59:49 2023 -0600
+
+    [Glyph] Minor change type of type to enum type
+    
+    Say that thrice.
+
+ src/OT/glyf/Glyph.hh | 30 +++++++++++++++++++++---------
+ 1 file changed, 21 insertions(+), 9 deletions(-)
+
+commit 317e3693da558087ab92d2c896be463311e737d6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 20 11:48:43 2023 -0600
+
+    [beyond-64k] Fail hmtx subsetting if subset too large
+
+ src/hb-ot-hmtx-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 64ecf8720c959617e0b0a5d10002089a05f28f98
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 20 11:42:45 2023 -0600
+
+    [beyond-64k] Fix subsetting of maxp
+
+ src/hb-ot-maxp-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7f629c0df20a52fb9aabecb657552c0703b70c58
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 19 13:16:18 2023 -0600
+
+    [docs] clarify purpose of FreeType integration
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4200
+
+ docs/usermanual-integration.xml | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 19e1b698c59e56b6e3530220866be0cd0754d1bd
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Apr 18 18:49:26 2023 +0000
+
+    [subset] Fix ubsan failure.
+
+ src/OT/glyf/Glyph.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 647b024784e1346f6886565f570cdf940d7b82b4
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Apr 17 22:47:47 2023 +0000
+
+    [subset] Fix fuzzer issue https://oss-fuzz.com/testcase-detail/6521393809588224
+
+ src/OT/glyf/SimpleGlyph.hh                              |   6 ++++++
+ src/OT/glyf/SubsetGlyph.hh                              |   7 ++++++-
+ ...testcase-minimized-hb-subset-fuzzer-6521393809588224 | Bin 0 -> 15886 bytes
+ 3 files changed, 12 insertions(+), 1 deletion(-)
+
+commit 3db6baa20e0a4661f99654860000e74a2770c2e0
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Apr 17 20:01:17 2023 +0000
+
+    [subset] add test for lig glyph fix.
+
+ ...oboto-Regular.no-layout-closure-gids2.no-unicodes.ttf | Bin 0 -> 2800 bytes
+ test/subset/data/profiles/no-layout-closure-gids2.txt    |   3 +++
+ test/subset/data/tests/no_layout_closure.tests           |   1 +
+ 3 files changed, 4 insertions(+)
+
+commit 8658c257c45f11ed28a8fcd621b35261fadffcfa
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Apr 17 19:46:46 2023 +0000
+
+    [subset] In LigatureSubst subsetting, check if the ligature glyph is in glyphset.
+    
+    Otherwise coverage will not match the retained ligature sets.
+
+ src/OT/Layout/GSUB/Ligature.hh             |  3 +++
+ src/OT/Layout/GSUB/LigatureSet.hh          | 12 ++++++++++++
+ src/OT/Layout/GSUB/LigatureSubstFormat1.hh |  2 +-
+ 3 files changed, 16 insertions(+), 1 deletion(-)
+
+commit ac4c3b3e8552d401977bcbba668f45d4e4f2cdd6
+Author: Josef Friedrich <josef@friedrich.rocks>
+Date:   Mon Apr 17 20:13:43 2023 +0200
+
+    Fix typos in the source code docs
+
+ src/hb-face.cc                    | 2 +-
+ src/hb-subset-instancer-solver.cc | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit ef6adadba92d605d54cf344962206cfbf421193d
+Author: DeadSix27 <DeadSix27@users.noreply.github.com>
+Date:   Mon Apr 17 12:53:49 2023 +0200
+
+    meson: add an option to disable utilities building
+    
+    Adds the missing utilities option to meson builds for parity with CMake builds
+
+ meson.build       | 5 ++++-
+ meson_options.txt | 2 ++
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+commit 90356eb226f633c8a7c9250b2653da75eaf51cfb
+Author: Garret Rieger <grieger@google.com>
+Date:   Fri Apr 14 20:52:35 2023 +0000
+
+    [subset] Note --no-layout-closure is only for GSUB.
+
+ src/hb-subset.h   | 2 +-
+ util/hb-subset.cc | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 14b9d8d53432da0a53122ae62ac125f5a67f456a
+Author: Garret Rieger <grieger@google.com>
+Date:   Fri Apr 14 20:44:15 2023 +0000
+
+    [subset] add --no-layout-closure flag.
+    
+    Disables layout glyph closure. Fixes #4192.
+
+ src/hb-subset-plan.cc                                    |   2 +-
+ src/hb-subset.h                                          |   3 +++
+ test/subset/data/Makefile.am                             |   1 +
+ test/subset/data/Makefile.sources                        |   1 +
+ ...Roboto-Regular.no-layout-closure-gids.no-unicodes.ttf | Bin 0 -> 2612 bytes
+ test/subset/data/profiles/no-layout-closure-gids.txt     |   2 ++
+ test/subset/data/tests/no_layout_closure.tests           |   8 ++++++++
+ test/subset/generate-expected-outputs.py                 |   7 +++++--
+ test/subset/meson.build                                  |   1 +
+ test/subset/subset_test_suite.py                         |   7 +++++++
+ util/hb-subset.cc                                        |   1 +
+ 11 files changed, 30 insertions(+), 3 deletions(-)
+
+commit 9c258936e7638e9e39976ae6afdc0b05a3065e16
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 14 11:35:34 2023 -0600
+
+    [SECURITY] Update
+
+ SECURITY.md | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit feb1f6d39e186421cc309ca137852ecb5fb8f65e
+Author: Pedro Kaj Kjellerup Nacht <pnacht@google.com>
+Date:   Fri Apr 14 15:17:54 2023 +0000
+
+     Add security policy
+    
+    Signed-off-by: Pedro Kaj Kjellerup Nacht <pnacht@google.com>
+
+ SECURITY.md | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+commit 26c719e8cd767e984daec3656be10b8ceec7832c
+Author: Pedro Kaj Kjellerup Nacht <pnacht@google.com>
+Date:   Wed Apr 12 13:38:49 2023 +0000
+
+     Add read-only top-level permissions to cifuzz.yml
+    
+    Signed-off-by: Pedro Kaj Kjellerup Nacht <pnacht@google.com>
+
+ .github/workflows/cifuzz.yml | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 96ed20725c99275f286a9a9cf461548731b6828c
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Tue Apr 4 10:33:58 2023 -0700
+
+    [instancer] update bound metrics for CFF2 instancing
+
+ src/hb-ot-head-table.hh                            |  20 ++++-
+ src/hb-ot-var-hvar-table.hh                        |   3 +
+ src/hb-subset-plan.cc                              |  88 +++++++++++++++++++++
+ test/subset/data/Makefile.am                       |   1 +
+ test/subset/data/Makefile.sources                  |   1 +
+ ...fault.retain-all-codepoint.wght=650,CNTR=50.otf | Bin 41760 -> 41760 bytes
+ ...F-ABC.default.retain-all-codepoint.wght=800.otf | Bin 0 -> 1508 bytes
+ ...C.retain-gids.retain-all-codepoint.wght=800.otf | Bin 0 -> 1508 bytes
+ test/subset/data/fonts/Cantarell-VF-ABC.otf        | Bin 0 -> 2508 bytes
+ .../tests/instantiate_cff2_update_metrics.tests    |  15 ++++
+ test/subset/meson.build                            |   1 +
+ 11 files changed, 128 insertions(+), 1 deletion(-)
+
+commit 04a47932a3844f7e73e3af8b05fb98c8b54fb779
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 31 11:44:08 2023 -0600
+
+    [paint] Remove enum trailing comma in C header
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/discussions/4188
+
+ src/hb-paint.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 2cd81fdfb6ccc6ba7ec63abe14e0126ece71f304
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Mar 30 22:11:43 2023 +0000
+
+    [subset] fix memory leak.
+    
+    Fixes fuzzer issue https://oss-fuzz.com/testcase-detail/6169920089227264
+
+ src/hb-subset-plan.cc                                    |   3 ++-
+ ...-testcase-minimized-hb-subset-fuzzer-6169920089227264 | Bin 0 -> 1214 bytes
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+commit 453ded05392af38bba9f89587edce465e86ffa6b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Mar 28 13:17:15 2023 -0600
+
+    [indic] Tighten up base-finding
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4185
+
+ src/hb-ot-shaper-indic.cc | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit c1acfe9966b1d2bd74c80de4aefcccc309664822
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Wed Mar 22 19:06:58 2023 -0700
+
+    [instancer] bug fix in TupleVariationData get_size ()
+    
+    We need to iterate TupleVariationHeader when calculating the total size
+
+ src/hb-ot-var-common.hh                                  |   7 +++++--
+ .../Muli-ABC.default.retain-all-codepoint.wght=300.ttf   | Bin 0 -> 5808 bytes
+ .../Muli-ABC.default.retain-all-codepoint.wght=700.ttf   | Bin 0 -> 5804 bytes
+ test/subset/data/fonts/Muli-ABC.ttf                      | Bin 0 -> 6996 bytes
+ test/subset/data/tests/apply_cvar_delta.tests            |   1 +
+ 5 files changed, 6 insertions(+), 2 deletions(-)
+
+commit be872001063d263efe708c4db5af569cfaedd3fe
+Author: Garret Rieger <grieger@google.com>
+Date:   Fri Mar 24 17:30:53 2023 +0000
+
+    [subset] fix buffer overflow fuzzer reported issue.
+
+ src/hb-subset-plan.cc                                    |  14 ++++++++------
+ ...-testcase-minimized-hb-subset-fuzzer-5120246288875520 | Bin 0 -> 2501 bytes
+ 2 files changed, 8 insertions(+), 6 deletions(-)
+
+commit 79ae6b657f9c7bff8c97eb8ee7d2dbeb2217868e
+Author: Garret Rieger <grieger@google.com>
+Date:   Fri Mar 24 17:14:55 2023 +0000
+
+    [subset] Fix fuzzer found memory leaks.
+
+ src/hb-subset-plan.cc                                    |   9 +++++++--
+ ...-testcase-minimized-hb-subset-fuzzer-5793182905663488 | Bin 0 -> 803 bytes
+ ...-testcase-minimized-hb-subset-fuzzer-6742230974201856 | Bin 0 -> 1214 bytes
+ 3 files changed, 7 insertions(+), 2 deletions(-)
+
+commit ab87d7d22545f6774a12688708d21e6e18ae7fb4
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Mon Mar 20 12:24:22 2023 -0700
+
+    [instance] add tests for colrv1 full instancing
+
+ test/subset/data/Makefile.am                             |   1 +
+ test/subset/data/Makefile.sources                        |   1 +
+ .../Foldit.default.retain-all-codepoint.wght=900.ttf     | Bin 0 -> 2508 bytes
+ test/subset/data/tests/instantiate_colrv1.tests          |  14 ++++++++++++++
+ test/subset/meson.build                                  |   1 +
+ 5 files changed, 17 insertions(+)
+
+commit fe671a5ac811e542071a7cd2151d6c045b77158a
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Thu Mar 16 14:10:21 2023 -0700
+
+    [instancer] support COLRv1 full instancing
+
+ src/OT/Color/COLR/COLR.hh | 379 +++++++++++++++++++++++++++++++++++++---------
+ src/hb-ot-var-common.hh   |  14 +-
+ 2 files changed, 312 insertions(+), 81 deletions(-)
+
+commit f0f7f22525d20ba05e9b69ba40b352cb89b506ae
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Mar 20 18:39:49 2023 +0000
+
+    [subset] fix fuzzer found null deref.
+    
+    https://oss-fuzz.com/testcase-detail/5844352760152064
+
+ src/hb-subset-plan.cc                                    |   9 +++++++--
+ ...-testcase-minimized-hb-subset-fuzzer-5844352760152064 | Bin 0 -> 1214 bytes
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+commit 79233a149209e3da199bb4e2f74271668502c574
+Author: Garret Rieger <grieger@google.com>
+Date:   Fri Mar 17 00:58:58 2023 +0000
+
+    [subset] fix incorrectly specified lock.
+    
+    Lock variable must have a name or it will immediately destruct.
+
+ src/hb-subset-plan.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8d8bcde8cfe214855fdde15b5d9448e87d3ec734
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Mar 15 17:29:08 2023 +0000
+
+    [set] don't allow -1 (HB_SET_VALUE_INVALID) to be inserted into a hb_set_t.
+    
+    Add tests that check all of the addition methods.
+
+ src/hb-bit-set.hh |  4 ++--
+ src/test-set.cc   | 24 ++++++++++++++++++++++++
+ 2 files changed, 26 insertions(+), 2 deletions(-)
+
+commit a84cae424d7b315336a191d13a2bef8a9d3635d2
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Mar 15 02:39:57 2023 +0000
+
+    [subset] Don't add invalid gids (-1) to the glyphset when loading glyph map from the accelerator.
+
+ src/OT/Layout/GPOS/PairPosFormat1.hh                     |   2 +-
+ src/hb-subset-plan.cc                                    |   9 ++++++---
+ test/subset/data/Makefile.am                             |   1 +
+ test/subset/data/Makefile.sources                        |   1 +
+ .../preprocess/Roboto-Regular.gids.61,62,63,30D9.ttf     | Bin 0 -> 2680 bytes
+ test/subset/data/tests/preprocess.tests                  |   8 ++++++++
+ test/subset/meson.build                                  |   1 +
+ 7 files changed, 18 insertions(+), 4 deletions(-)
+
+commit 09a266236147497bd8149240062c31c16fbc81e3
+Merge: 75e6498d9 204e155ac
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Mar 14 12:48:12 2023 -0600
+
+    Merge pull request #4168 from googlefonts/subset_name_collect
+    
+    [subset] name_id closure
+
+commit 75e6498d9a8b600ab7f00b3d279f1054dd72feec
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Mar 14 12:41:46 2023 -0600
+
+    Don't use M_PI
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4166
+    
+    Happy Pi Day!
+
+ src/OT/Color/COLR/COLR.hh        |  4 ++--
+ src/OT/glyf/VarCompositeGlyph.hh |  6 +++---
+ src/hb-cairo-utils.cc            | 24 +++++++++++-------------
+ src/hb-ft-colr.hh                |  4 ++--
+ src/hb-paint.hh                  |  8 ++++----
+ src/hb-style.cc                  |  4 ++--
+ src/hb.hh                        |  6 ++++++
+ 7 files changed, 30 insertions(+), 26 deletions(-)
+
+commit 204e155acbf6a9311a13efd4400d2a7b52ca609a
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Tue Mar 14 10:25:31 2023 -0700
+
+    [subset] Add tests for collecting name_ids from STAT and FeatureParams
+
+ test/subset/data/Makefile.am                            |   1 +
+ test/subset/data/Makefile.sources                       |   1 +
+ ...et.keep-all-layout-features.retain-all-codepoint.otf | Bin 0 -> 12796 bytes
+ .../data/fonts/SourceSerif4Variable-Roman_subset.otf    | Bin 0 -> 12784 bytes
+ test/subset/data/tests/collect_name_ids.tests           |  11 +++++++++++
+ test/subset/meson.build                                 |   1 +
+ 6 files changed, 14 insertions(+)
+
+commit 32c889f1d66e7a990c9e80e3c4cc0bd8f62da601
+Author: Jason Simmons <jsimmons@google.com>
+Date:   Mon Mar 13 18:24:39 2023 -0700
+
+    Remove extra blank line in hb-outline.cc
+
+ src/hb-outline.cc | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 0d65738633f84cfbf69325edb8189ee0184d50cf
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Mon Mar 13 15:51:45 2023 -0700
+
+    [subset] collect elidedFallbackNameID in STAT table
+
+ src/hb-ot-stat-table.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 125450d2f220821e63fe748475611c66905904e8
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Mon Mar 13 15:43:29 2023 -0700
+
+    [subset] collect name_ids for FeratureParams
+
+ src/hb-ot-layout-common.hh   | 39 +++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-layout-gsubgpos.hh | 12 ++++++++++++
+ src/hb-subset-plan.cc        | 38 +++++++++++++++++++++++---------------
+ 3 files changed, 74 insertions(+), 15 deletions(-)
+
+commit 663ecc01d8cd32c3fcb8421ee157815ecab413db
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Mar 13 22:12:59 2023 +0000
+
+    [subset] don't free glyphs by range.
+    
+    The iterator in this loop is a map iterator so glyphs are not necessarily traveresed in order.
+
+ src/OT/glyf/glyf.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 3d05b96181b259593047f592df4df33a3658e472
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Mar 13 21:34:26 2023 +0000
+
+    [subset] track which glyphs have allocated memory so we can clean up correctly.
+    
+    Fixes https://oss-fuzz.com/testcase-detail/5388270411579392
+
+ src/OT/glyf/CompositeGlyph.hh                            |   5 ++++-
+ src/OT/glyf/SubsetGlyph.hh                               |  13 ++++++++++---
+ src/OT/glyf/glyf.hh                                      |   6 ++----
+ ...-testcase-minimized-hb-subset-fuzzer-5388270411579392 | Bin 0 -> 4844 bytes
+ 4 files changed, 16 insertions(+), 8 deletions(-)
+
+commit 7a87b17742a0cec36ad21d9fddc1c605597eea14
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Mar 13 19:50:28 2023 +0000
+
+    Check for failed subset input creation in the fuzzer.
+
+ ...z-testcase-minimized-hb-subset-fuzzer-4801020053291008 | Bin 0 -> 311 bytes
+ test/fuzzing/hb-subset-fuzzer.cc                          |  12 ++++++++++++
+ 2 files changed, 12 insertions(+)
+
+commit de6533d8850944e71d5d69c6257ef85f1bf16b1f
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Mon Mar 13 13:36:00 2023 -0700
+
+    [subset] collect name_ids from CPAL table
+
+ src/OT/Color/CPAL/CPAL.hh | 31 +++++++++++++++++++++++++++++++
+ src/hb-subset-plan.cc     | 41 +++++++++++++++++++++++++----------------
+ 2 files changed, 56 insertions(+), 16 deletions(-)
+
+commit 7b77cd198c0352b6ed2a0adbee68bb3e246b9658
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Mon Mar 13 12:45:43 2023 -0700
+
+    [subset] fix bug in CPAL V1tail serialization
+    
+    We should serialize nameIDs rather than retained color index
+
+ src/OT/Color/CPAL/CPAL.hh | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+commit 6d2705a719222adaa4d56a5df589f0c1c81e9bfc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 10 12:40:43 2023 -0700
+
+    [justify-demo] Help message
+
+ src/justify.py | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 2d8634624ccec268aaac097763f544aafcae8ba8
+Author: Simon Cozens <simon@simon-cozens.org>
+Date:   Fri Mar 10 14:32:39 2023 +0000
+
+    Add Tifinagh to list of both-directions scripts
+
+ src/hb-common.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 905eeee4a4ebfbc8ed4f07d3ae0c730dd54eb334
+Author: Jean-Michaël Celerier <jeanmichael.celerier+github@gmail.com>
+Date:   Mon Mar 6 13:21:33 2023 -0500
+
+    harfbuzz-config.cmake: support static library build
+
+ src/harfbuzz-config.cmake.in | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+commit 28b05e1cb6116b07b95af799ff68b883c3f590d1
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Mar 8 23:59:04 2023 +0000
+
+    [subset] Fix memory leak in glyf subset.
+    
+    Fixes fuzzer issue: https://oss-fuzz.com/testcase-detail/6525813890875392.
+
+ src/OT/glyf/glyf.hh                                     |   9 +++++++++
+ ...testcase-minimized-hb-subset-fuzzer-6525813890875392 | Bin 0 -> 73882 bytes
+ 2 files changed, 9 insertions(+)
+
+commit 9286e125250c7724a5d7eece0fff4284f73341b6
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Mar 8 20:02:26 2023 +0000
+
+    Don't subset a glyf table with an unknown format.
+    
+    Fixes fuzzer issue: https://oss-fuzz.com/testcase-detail/4875306193518592
+
+ src/OT/glyf/glyf.hh                                      |  15 ++++++++++++++-
+ ...case-minimized-hb-subset-fuzzer-4875306193518592.fuzz | Bin 0 -> 1044 bytes
+ 2 files changed, 14 insertions(+), 1 deletion(-)
+
+commit cfa9541daa86c659ea935bbd4507cc620658c6d4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Mar 8 10:35:39 2023 -0700
+
+    [glyf] "Support" glyf version 1
+
+ src/OT/glyf/glyf.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 552290f60437ceaa5aa299a2db726046c0385f80
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Mar 8 10:25:26 2023 -0700
+
+    [gvar] Fix out-of-memory access issue
+    
+    Fixes https://oss-fuzz.com/testcase-detail/5953342850596864
+
+ src/hb-ot-var-gvar-table.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 7327006d686c149cefdc7ee6047d2b426ac1ac75
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Mar 7 21:06:01 2023 -0700
+
+    [GSUB] Support SingleSubst in get_glyph_alternates
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/discussions/4146
+
+ src/OT/Layout/GSUB/SingleSubstFormat1.hh | 28 ++++++++++++++++++++++++++++
+ src/OT/Layout/GSUB/SingleSubstFormat2.hh | 25 +++++++++++++++++++++++++
+ 2 files changed, 53 insertions(+)
+
+commit 69183217dfbd6380f2c57e3a9a793559874667e5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Mar 7 20:56:56 2023 -0700
+
+    Add test-gsub-get-alternates.cc
+
+ src/Makefile.am                 |  5 +++
+ src/meson.build                 |  1 +
+ src/test-gsub-get-alternates.cc | 86 +++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 92 insertions(+)
+
+commit ea17c7a81a743d7e319da0ff4111bcf650d2011b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Mar 7 14:23:39 2023 -0700
+
+    [beyond-64k] Implement gvar support
+    
+    https://github.com/harfbuzz/boring-expansion-spec/issues/85
+
+ src/hb-ot-var-gvar-table.hh | 38 ++++++++++++++++++++++++--------------
+ 1 file changed, 24 insertions(+), 14 deletions(-)
+
+commit f325aba561335a4f0f3c71aa59e42f1a23c774f2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Mar 6 13:07:42 2023 -0700
+
+    [VarComposites] Minor rename
+
+ src/OT/glyf/VarCompositeGlyph.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit b4b089c4278f041f69c3253f84901de226d38558
+Author: Khaled Hosny <khaled@aliftype.com>
+Date:   Mon Mar 6 04:40:04 2023 +0200
+
+    [docs] Disable gtdoc-check by default
+    
+    It slows build as it causes documentation to be always rebuilt. We now
+    disable it by default and enable it on relevant CI jobs.
+
+ .github/workflows/linux-ci.yml | 1 +
+ docs/meson.build               | 2 +-
+ meson_options.txt              | 2 ++
+ 3 files changed, 4 insertions(+), 1 deletion(-)
+
+commit d165afec1d301167754c4152f868a0110b3144a6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 4 21:09:26 2023 -0700
+
+    [justify-demo] Create new fonts all the time
+    
+    The hb.shape_justify() call modifies the font. This was messing
+    up justification. Create new fonts all the time.
+
+ src/justify.py | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+commit 690145fa009b4a705065549474a81113e609419f
+Author: Khaled Hosny <khaled@aliftype.com>
+Date:   Sat Mar 4 07:19:20 2023 +0200
+
+    [justify-demo] Rewrite in a simpler way
+    
+    No need to overthink it, append text words to the line and reshape, no
+    need to shape the whole text first and do complicated glyph/input
+    mapping. Much simpler code and as fast.
+
+ src/justify.py | 323 +++++++++++++++++++++------------------------------------
+ 1 file changed, 118 insertions(+), 205 deletions(-)
+
+commit e9d6f23b5d4779e08cd27f38fd92860cb9cbe1da
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 3 17:15:18 2023 -0700
+
+    [justify-demo] Fix for LTR typesetting
+
+ src/justify.py | 24 +++++++++++++++---------
+ 1 file changed, 15 insertions(+), 9 deletions(-)
+
+commit 5cf54aeddec47aea380bfa39d543b8fe373c6873
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 3 17:01:12 2023 -0700
+
+    [justify-demo] Guess segment properties
+
+ src/justify.py | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+commit 5c334b9686064aa0d1d41d8935e713c70c43589b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 3 16:53:44 2023 -0700
+
+    [justify-demo] Fix crash if font has no variation axis
+
+ src/justify.py | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit ab249fd24b355ead23ab23f481bd219e0d95faaa
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 4 01:46:07 2023 +0200
+
+    [justify] Fix shrink/expand conditions
+
+ src/justify.py | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+commit 039ea9adda1ab9338165469982ae1be6dcce3ae7
+Author: Khaled Hosny <khaled@aliftype.com>
+Date:   Sat Mar 4 01:41:34 2023 +0200
+
+    [justify] Add demo GTK app
+
+ src/justify.py | 364 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 364 insertions(+)
+
+commit be47182d4897de6b875101a1d258877ed525a24b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 3 11:10:16 2023 -0700
+
+    [hb-cairo] Add Black Foundry copyright
+
+ src/hb-cairo-utils.cc | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit ab4c32118025822094ef9197ad105e7460230be4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 3 09:31:16 2023 -0700
+
+    [justify] Set out params in more cases
+
+ src/hb-shape.cc | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+commit e57defc07c83f1012fac0f213d636698d86a76c1
+Author: Khaled Hosny <khaled@aliftype.com>
+Date:   Fri Mar 3 13:05:30 2023 +0200
+
+    [justify] Set var_value when expanding/shrinking to max
+    
+    When expanding/shrinking the buffer to max (and still not fitting), we
+    need to also set var_value to the axis max/min otherwise client not have
+    the correct axis value to draw with.
+
+ src/hb-shape.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit a2efa5b4895bc90a89be43196e56de276a5fcf00
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 3 09:15:46 2023 -0700
+
+    [map] Another try at fixing old Mac build
+    
+    https://github.com/harfbuzz/harfbuzz/issues/4138
+
+ src/hb-map.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit bfab56d3b5d2d11416375d03c7440f9d6e262f62
+Author: Khaled Hosny <khaled@aliftype.com>
+Date:   Fri Mar 3 13:14:05 2023 +0200
+
+    [font] Typo
+
+ src/hb-font.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
 commit 60841e26187576bff477c1a09ee2ffe544844abc
 Author: Khaled Hosny <khaled@aliftype.com>
 Date:   Fri Mar 3 01:01:49 2023 +0200
diff --git a/source/libs/harfbuzz/harfbuzz-src/NEWS b/source/libs/harfbuzz/harfbuzz-src/NEWS
index 5ed287822d003c3374d5d00f557b292d6b5c0d11..e53a244f1b3b5ca1020e2a8addec8a3c191ee8b7 100644
--- a/source/libs/harfbuzz/harfbuzz-src/NEWS
+++ b/source/libs/harfbuzz/harfbuzz-src/NEWS
@@ -1,3 +1,31 @@
+Overview of changes leading to 7.2.0
+Thursday, April 27, 2023
+====================================
+- Add Tifinagh to the list of scripts that can natively be either right-to-left
+  or left-to-right, to improve handling of its glyph positioning.
+  (Simon Cozens)
+- Return also single substitution from hb_ot_layout_lookup_get_glyph_alternates()
+  (Behdad Esfahbod)
+- Fix 4.2.0 regression in applying across syllables in syllabic scripts.
+  (Behdad Esfahbod)
+- Add flag to avoid glyph substitution closure during subsetting, and the
+  corresponding “--no-layout-closure” option to “hb-subset” command line tool.
+  (Garret Rieger)
+- Support instancing COLRv1 table. (Qunxin Liu)
+- Don’t drop used user-defined name table entries during subsetting.
+  (Qunxin Liu)
+- Optimize handling of “gvar” table. (Behdad Esfahbod)
+- Various subsetter bug fixes and improvements. (Garret Rieger, Qunxin Liu)
+- Various documentation improvements. (Behdad Esfahbod, Josef Friedrich)
+
+- New API:
++HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE
++HB_UNICODE_COMBINING_CLASS_CCC132
+
+- Deprecated API:
++HB_UNICODE_COMBINING_CLASS_CCC133
+
+
 Overview of changes leading to 7.1.0
 Friday, March 3, 2023
 ====================================
@@ -8,6 +36,7 @@ Friday, March 3, 2023
 - New API:
 +hb_font_set_variation()
 
+
 Overview of changes leading to 7.0.1
 Monday, February 20, 2023
 ====================================
diff --git a/source/libs/harfbuzz/harfbuzz-src/configure.ac b/source/libs/harfbuzz/harfbuzz-src/configure.ac
index c863ab83b0b2aae1a8c105f340e7caa69be59b58..33c19b35f007dbdfaa0ca8f4053e28457af0d901 100644
--- a/source/libs/harfbuzz/harfbuzz-src/configure.ac
+++ b/source/libs/harfbuzz/harfbuzz-src/configure.ac
@@ -1,6 +1,6 @@
 AC_PREREQ([2.64])
 AC_INIT([HarfBuzz],
-        [7.1.0],
+        [7.2.0],
         [https://github.com/harfbuzz/harfbuzz/issues/new],
         [harfbuzz],
         [http://harfbuzz.org/])
diff --git a/source/libs/harfbuzz/harfbuzz-src/meson.build b/source/libs/harfbuzz/harfbuzz-src/meson.build
index 6bf8d05da94faa07b0c0237a6583fc79ceaffc50..b862d24ca97cb04ffdab2b8a4c717645cc6d5f5d 100644
--- a/source/libs/harfbuzz/harfbuzz-src/meson.build
+++ b/source/libs/harfbuzz/harfbuzz-src/meson.build
@@ -1,6 +1,6 @@
 project('harfbuzz', 'c', 'cpp',
   meson_version: '>= 0.55.0',
-  version: '7.1.0',
+  version: '7.2.0',
   default_options: [
     'cpp_eh=none',          # Just to support msvc, we are passing -fno-exceptions also anyway
     'cpp_rtti=false',       # Just to support msvc, we are passing -fno-rtti also anyway
@@ -373,7 +373,10 @@ foreach check : check_funcs
 endforeach
 
 subdir('src')
-subdir('util')
+
+if not get_option('utilities').disabled()
+  subdir('util')
+endif
 
 if not get_option('tests').disabled()
   subdir('test')
diff --git a/source/libs/harfbuzz/harfbuzz-src/meson_options.txt b/source/libs/harfbuzz/harfbuzz-src/meson_options.txt
index 9ebba72c6d39f1e64cfdb2f1eea39842be52a1a4..9438202e1bdfdc405bae832d441a7e4772c13cd5 100644
--- a/source/libs/harfbuzz/harfbuzz-src/meson_options.txt
+++ b/source/libs/harfbuzz/harfbuzz-src/meson_options.txt
@@ -29,6 +29,10 @@ option('introspection', type: 'feature', value: 'auto', yield: true,
   description: 'Generate gobject-introspection bindings (.gir/.typelib files)')
 option('docs', type: 'feature', value: 'auto', yield: true,
   description: 'Generate documentation with gtk-doc')
+option('doc_tests', type: 'boolean', value: false,
+  description: 'Run gtkdoc-check tests')
+option('utilities', type: 'feature', value: 'enabled', yield: true,
+  description: 'Build harfbuzz utils')
 
 option('benchmark', type: 'feature', value: 'disabled',
   description: 'Enable benchmark tests')
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am b/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am
index 52bd92b79b9aca06e7e68daeedf728ad8c02cc53..56dc32d9a78a4dd972f289af96b31278196154ea 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am
+++ b/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am
@@ -382,6 +382,7 @@ noinst_PROGRAMS = \
 	test-ot-name \
 	test-ot-glyphname \
 	test-gpos-size-params \
+	test-gsub-get-alternates \
 	test-gsub-would-substitute \
 	test-use-table \
 	$(NULL)
@@ -419,6 +420,10 @@ test_gpos_size_params_SOURCES = test-gpos-size-params.cc
 test_gpos_size_params_CPPFLAGS = $(HBCFLAGS)
 test_gpos_size_params_LDADD = libharfbuzz.la $(HBLIBS)
 
+test_gsub_get_alternates_SOURCES = test-gsub-get-alternates.cc
+test_gsub_get_alternates_CPPFLAGS = $(HBCFLAGS)
+test_gsub_get_alternates_LDADD = libharfbuzz.la $(HBLIBS)
+
 test_gsub_would_substitute_SOURCES = test-gsub-would-substitute.cc
 test_gsub_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS)
 test_gsub_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS)
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh
index 31be6585dd4764cb66cb2fbe57cb7e2023faf53d..191812f48eebdb48532dff0a81df91a757250f45 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh
@@ -40,7 +40,6 @@
  */
 #define HB_OT_TAG_COLR HB_TAG('C','O','L','R')
 
-
 namespace OT {
 struct hb_paint_context_t;
 }
@@ -242,10 +241,15 @@ struct Variable
   void closurev1 (hb_colrv1_closure_context_t* c) const
   { value.closurev1 (c); }
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer) const
   {
     TRACE_SUBSET (this);
-    if (!value.subset (c)) return_trace (false);
+    if (!value.subset (c, instancer, varIdxBase)) return_trace (false);
+    if (c->plan->all_axes_pinned)
+      return_trace (true);
+
+    //TODO: update varIdxBase for partial-instancing
     return_trace (c->serializer->embed (varIdxBase));
   }
 
@@ -296,10 +300,11 @@ struct NoVariable
   void closurev1 (hb_colrv1_closure_context_t* c) const
   { value.closurev1 (c); }
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer) const
   {
     TRACE_SUBSET (this);
-    return_trace (value.subset (c));
+    return_trace (value.subset (c, instancer, varIdxBase));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -337,11 +342,20 @@ struct ColorStop
   void closurev1 (hb_colrv1_closure_context_t* c) const
   { c->add_palette_index (paletteIndex); }
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (*this);
     if (unlikely (!out)) return_trace (false);
+
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->stopOffset.set_float (stopOffset.to_float(instancer (varIdxBase, 0)));
+      out->alpha.set_float (alpha.to_float (instancer (varIdxBase, 1)));
+    }
+
     return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes.get (paletteIndex),
                                                HB_SERIALIZE_ERROR_INT_OVERFLOW));
   }
@@ -390,7 +404,8 @@ struct ColorLine
       stop.closurev1 (c);
   }
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (this);
@@ -402,7 +417,7 @@ struct ColorLine
 
     for (const auto& stop : stops.iter ())
     {
-      if (!stop.subset (c)) return_trace (false);
+      if (!stop.subset (c, instancer)) return_trace (false);
     }
     return_trace (true);
   }
@@ -523,6 +538,25 @@ struct Affine2x3
     return_trace (c->check_struct (this));
   }
 
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->xx.set_float (xx.to_float(instancer (varIdxBase, 0)));
+      out->yx.set_float (yx.to_float(instancer (varIdxBase, 1)));
+      out->xy.set_float (xy.to_float(instancer (varIdxBase, 2)));
+      out->yy.set_float (yy.to_float(instancer (varIdxBase, 3)));
+      out->dx.set_float (dx.to_float(instancer (varIdxBase, 4)));
+      out->dy.set_float (dy.to_float(instancer (varIdxBase, 5)));
+    }
+    return_trace (true);
+  }
+
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
     c->funcs->push_transform (c->data,
@@ -548,7 +582,8 @@ struct PaintColrLayers
 {
   void closurev1 (hb_colrv1_closure_context_t* c) const;
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer HB_UNUSED) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
@@ -579,11 +614,20 @@ struct PaintSolid
   void closurev1 (hb_colrv1_closure_context_t* c) const
   { c->add_palette_index (paletteIndex); }
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (*this);
     if (unlikely (!out)) return_trace (false);
+
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+      out->alpha.set_float (alpha.to_float (instancer (varIdxBase, 0)));
+
+    if (format == 3 && c->plan->all_axes_pinned)
+        out->format = 2;
+
     return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes.get (paletteIndex),
                                                HB_SERIALIZE_ERROR_INT_OVERFLOW));
   }
@@ -618,13 +662,28 @@ struct PaintLinearGradient
   void closurev1 (hb_colrv1_closure_context_t* c) const
   { (this+colorLine).closurev1 (c); }
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
     if (unlikely (!out)) return_trace (false);
 
-    return_trace (out->colorLine.serialize_subset (c, colorLine, this));
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->x0 = x0 + (int) roundf (instancer (varIdxBase, 0));
+      out->y0 = y0 + (int) roundf (instancer (varIdxBase, 1));
+      out->x1 = x1 + (int) roundf (instancer (varIdxBase, 2));
+      out->y1 = y1 + (int) roundf (instancer (varIdxBase, 3));
+      out->x2 = x2 + (int) roundf (instancer (varIdxBase, 4));
+      out->y2 = y2 + (int) roundf (instancer (varIdxBase, 5));
+    }
+
+    if (format == 5 && c->plan->all_axes_pinned)
+        out->format = 4;
+
+    return_trace (out->colorLine.serialize_subset (c, colorLine, this, instancer));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -669,13 +728,28 @@ struct PaintRadialGradient
   void closurev1 (hb_colrv1_closure_context_t* c) const
   { (this+colorLine).closurev1 (c); }
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
     if (unlikely (!out)) return_trace (false);
 
-    return_trace (out->colorLine.serialize_subset (c, colorLine, this));
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->x0 = x0 + (int) roundf (instancer (varIdxBase, 0));
+      out->y0 = y0 + (int) roundf (instancer (varIdxBase, 1));
+      out->radius0 = radius0 + (unsigned) roundf (instancer (varIdxBase, 2));
+      out->x1 = x1 + (int) roundf (instancer (varIdxBase, 3));
+      out->y1 = y1 + (int) roundf (instancer (varIdxBase, 4));
+      out->radius1 = radius1 + (unsigned) roundf (instancer (varIdxBase, 5));
+    }
+
+    if (format == 7 && c->plan->all_axes_pinned)
+        out->format = 6;
+
+    return_trace (out->colorLine.serialize_subset (c, colorLine, this, instancer));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -720,13 +794,26 @@ struct PaintSweepGradient
   void closurev1 (hb_colrv1_closure_context_t* c) const
   { (this+colorLine).closurev1 (c); }
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
     if (unlikely (!out)) return_trace (false);
 
-    return_trace (out->colorLine.serialize_subset (c, colorLine, this));
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->centerX = centerX + (int) roundf (instancer (varIdxBase, 0));
+      out->centerY = centerY + (int) roundf (instancer (varIdxBase, 1));
+      out->startAngle.set_float (startAngle.to_float (instancer (varIdxBase, 2)));
+      out->endAngle.set_float (endAngle.to_float (instancer (varIdxBase, 3)));
+    }
+
+    if (format == 9 && c->plan->all_axes_pinned)
+        out->format = 8;
+
+    return_trace (out->colorLine.serialize_subset (c, colorLine, this, instancer));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -746,8 +833,8 @@ struct PaintSweepGradient
     c->funcs->sweep_gradient (c->data, &cl,
 			      centerX + c->instancer (varIdxBase, 0),
 			      centerY + c->instancer (varIdxBase, 1),
-                              (startAngle.to_float (c->instancer (varIdxBase, 2)) + 1) * (float) M_PI,
-                              (endAngle.to_float   (c->instancer (varIdxBase, 3)) + 1) * (float) M_PI);
+                              (startAngle.to_float (c->instancer (varIdxBase, 2)) + 1) * HB_PI,
+                              (endAngle.to_float   (c->instancer (varIdxBase, 3)) + 1) * HB_PI);
   }
 
   HBUINT8			format; /* format = 8(noVar) or 9 (Var) */
@@ -766,7 +853,8 @@ struct PaintGlyph
 {
   void closurev1 (hb_colrv1_closure_context_t* c) const;
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
@@ -776,7 +864,7 @@ struct PaintGlyph
                                        HB_SERIALIZE_ERROR_INT_OVERFLOW))
       return_trace (false);
 
-    return_trace (out->paint.serialize_subset (c, paint, this));
+    return_trace (out->paint.serialize_subset (c, paint, this, instancer));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -807,7 +895,8 @@ struct PaintColrGlyph
 {
   void closurev1 (hb_colrv1_closure_context_t* c) const;
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer HB_UNUSED) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
@@ -836,13 +925,16 @@ struct PaintTransform
 {
   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
     if (unlikely (!out)) return_trace (false);
-    if (!out->transform.serialize_copy (c->serializer, transform, this)) return_trace (false);
-    return_trace (out->src.serialize_subset (c, src, this));
+    if (!out->transform.serialize_subset (c, transform, this, instancer)) return_trace (false);
+    if (format == 13 && c->plan->all_axes_pinned)
+      out->format = 12;
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -871,13 +963,24 @@ struct PaintTranslate
 {
   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
     if (unlikely (!out)) return_trace (false);
 
-    return_trace (out->src.serialize_subset (c, src, this));
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->dx = dx + (int) roundf (instancer (varIdxBase, 0));
+      out->dy = dy + (int) roundf (instancer (varIdxBase, 1));
+    }
+
+    if (format == 15 && c->plan->all_axes_pinned)
+        out->format = 14;
+
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -908,13 +1011,24 @@ struct PaintScale
 {
   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
     if (unlikely (!out)) return_trace (false);
 
-    return_trace (out->src.serialize_subset (c, src, this));
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->scaleX.set_float (scaleX.to_float (instancer (varIdxBase, 0)));
+      out->scaleY.set_float (scaleY.to_float (instancer (varIdxBase, 1)));
+    }
+
+    if (format == 17 && c->plan->all_axes_pinned)
+        out->format = 16;
+
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -945,13 +1059,26 @@ struct PaintScaleAroundCenter
 {
   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
     if (unlikely (!out)) return_trace (false);
 
-    return_trace (out->src.serialize_subset (c, src, this));
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->scaleX.set_float (scaleX.to_float (instancer (varIdxBase, 0)));
+      out->scaleY.set_float (scaleY.to_float (instancer (varIdxBase, 1)));
+      out->centerX = centerX + (int) roundf (instancer (varIdxBase, 2));
+      out->centerY = centerY + (int) roundf (instancer (varIdxBase, 3));
+    }
+
+    if (format == 19 && c->plan->all_axes_pinned)
+        out->format = 18;
+
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -990,13 +1117,21 @@ struct PaintScaleUniform
 {
   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
     if (unlikely (!out)) return_trace (false);
 
-    return_trace (out->src.serialize_subset (c, src, this));
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+      out->scale.set_float (scale.to_float (instancer (varIdxBase, 0)));
+
+    if (format == 21 && c->plan->all_axes_pinned)
+        out->format = 20;
+
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -1025,13 +1160,25 @@ struct PaintScaleUniformAroundCenter
 {
   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
     if (unlikely (!out)) return_trace (false);
 
-    return_trace (out->src.serialize_subset (c, src, this));
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->scale.set_float (scale.to_float (instancer (varIdxBase, 0)));
+      out->centerX = centerX + (int) roundf (instancer (varIdxBase, 1));
+      out->centerY = centerY + (int) roundf (instancer (varIdxBase, 2));
+    }
+
+    if (format == 23 && c->plan->all_axes_pinned)
+        out->format = 22;
+
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -1068,13 +1215,21 @@ struct PaintRotate
 {
   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
     if (unlikely (!out)) return_trace (false);
 
-    return_trace (out->src.serialize_subset (c, src, this));
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+      out->angle.set_float (angle.to_float (instancer (varIdxBase, 0)));
+
+    if (format == 25 && c->plan->all_axes_pinned)
+      out->format = 24;
+
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -1103,13 +1258,25 @@ struct PaintRotateAroundCenter
 {
   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
     if (unlikely (!out)) return_trace (false);
 
-    return_trace (out->src.serialize_subset (c, src, this));
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->angle.set_float (angle.to_float (instancer (varIdxBase, 0)));
+      out->centerX = centerX + (int) roundf (instancer (varIdxBase, 1));
+      out->centerY = centerY + (int) roundf (instancer (varIdxBase, 2));
+    }
+
+    if (format ==27 && c->plan->all_axes_pinned)
+        out->format = 26;
+
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -1146,13 +1313,24 @@ struct PaintSkew
 {
   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
     if (unlikely (!out)) return_trace (false);
 
-    return_trace (out->src.serialize_subset (c, src, this));
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->xSkewAngle.set_float (xSkewAngle.to_float (instancer (varIdxBase, 0)));
+      out->ySkewAngle.set_float (ySkewAngle.to_float (instancer (varIdxBase, 1)));
+    }
+
+    if (format == 29 && c->plan->all_axes_pinned)
+        out->format = 28;
+
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -1183,13 +1361,26 @@ struct PaintSkewAroundCenter
 {
   HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
     if (unlikely (!out)) return_trace (false);
 
-    return_trace (out->src.serialize_subset (c, src, this));
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->xSkewAngle.set_float (xSkewAngle.to_float (instancer (varIdxBase, 0)));
+      out->ySkewAngle.set_float (ySkewAngle.to_float (instancer (varIdxBase, 1)));
+      out->centerX = centerX + (int) roundf (instancer (varIdxBase, 2));
+      out->centerY = centerY + (int) roundf (instancer (varIdxBase, 3));
+    }
+
+    if (format == 31 && c->plan->all_axes_pinned)
+        out->format = 30;
+
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -1228,14 +1419,15 @@ struct PaintComposite
 {
   void closurev1 (hb_colrv1_closure_context_t* c) const;
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
     if (unlikely (!out)) return_trace (false);
 
-    if (!out->src.serialize_subset (c, src, this)) return_trace (false);
-    return_trace (out->backdrop.serialize_subset (c, backdrop, this));
+    if (!out->src.serialize_subset (c, src, this, instancer)) return_trace (false);
+    return_trace (out->backdrop.serialize_subset (c, backdrop, this, instancer));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -1283,6 +1475,28 @@ struct ClipBoxFormat1
     clip_box.yMax = yMax;
   }
 
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->xMin = xMin + (int) roundf (instancer (varIdxBase, 0));
+      out->yMin = yMin + (int) roundf (instancer (varIdxBase, 1));
+      out->xMax = xMax + (int) roundf (instancer (varIdxBase, 2));
+      out->yMax = yMax + (int) roundf (instancer (varIdxBase, 3));
+    }
+
+    if (format == 2 && c->plan->all_axes_pinned)
+        out->format = 1;
+
+    return_trace (true);
+  }
+
   public:
   HBUINT8	format; /* format = 1(noVar) or 2(Var)*/
   FWORD		xMin;
@@ -1310,13 +1524,14 @@ struct ClipBoxFormat2 : Variable<ClipBoxFormat1>
 
 struct ClipBox
 {
-  ClipBox* copy (hb_serialize_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer) const
   {
-    TRACE_SERIALIZE (this);
+    TRACE_SUBSET (this);
     switch (u.format) {
-    case 1: return_trace (reinterpret_cast<ClipBox *> (c->embed (u.format1)));
-    case 2: return_trace (reinterpret_cast<ClipBox *> (c->embed (u.format2)));
-    default:return_trace (nullptr);
+    case 1: return_trace (u.format1.subset (c, instancer, VarIdx::NO_VARIATION));
+    case 2: return_trace (u.format2.subset (c, instancer));
+    default:return_trace (c->default_return_value ());
     }
   }
 
@@ -1367,13 +1582,15 @@ struct ClipRecord
   int cmp (hb_codepoint_t g) const
   { return g < startGlyphID ? -1 : g <= endGlyphID ? 0 : +1; }
 
-  ClipRecord* copy (hb_serialize_context_t *c, const void *base) const
+  bool subset (hb_subset_context_t *c,
+               const void *base,
+               const VarStoreInstancer &instancer) const
   {
-    TRACE_SERIALIZE (this);
-    auto *out = c->embed (this);
-    if (unlikely (!out)) return_trace (nullptr);
-    if (!out->clipBox.serialize_copy (c, clipBox, base)) return_trace (nullptr);
-    return_trace (out);
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->clipBox.serialize_subset (c, clipBox, base, instancer));
   }
 
   bool sanitize (hb_sanitize_context_t *c, const void *base) const
@@ -1400,7 +1617,8 @@ DECLARE_NULL_NAMESPACE_BYTES (OT, ClipRecord);
 
 struct ClipList
 {
-  unsigned serialize_clip_records (hb_serialize_context_t *c,
+  unsigned serialize_clip_records (hb_subset_context_t *c,
+                                   const VarStoreInstancer &instancer,
                                    const hb_set_t& gids,
                                    const hb_map_t& gid_offset_map) const
   {
@@ -1432,7 +1650,7 @@ struct ClipList
       record.endGlyphID = prev_gid;
       record.clipBox = prev_offset;
 
-      if (!c->copy (record, this)) return_trace (0);
+      if (!record.subset (c, this, instancer)) return_trace (0);
       count++;
 
       start_gid = _;
@@ -1446,13 +1664,14 @@ struct ClipList
       record.startGlyphID = start_gid;
       record.endGlyphID = prev_gid;
       record.clipBox = prev_offset;
-      if (!c->copy (record, this)) return_trace (0);
+      if (!record.subset (c, this, instancer)) return_trace (0);
       count++;
     }
     return_trace (count);
   }
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (*this);
@@ -1477,7 +1696,7 @@ struct ClipList
       }
     }
 
-    unsigned count = serialize_clip_records (c->serializer, new_gids, new_gid_offset_map);
+    unsigned count = serialize_clip_records (c, instancer, new_gids, new_gid_offset_map);
     if (!count) return_trace (false);
     return_trace (c->serializer->check_assign (out->clips.len, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
   }
@@ -1611,7 +1830,8 @@ struct BaseGlyphPaintRecord
   { return g < glyphId ? -1 : g > glyphId ? 1 : 0; }
 
   bool serialize (hb_serialize_context_t *s, const hb_map_t* glyph_map,
-                  const void* src_base, hb_subset_context_t *c) const
+                  const void* src_base, hb_subset_context_t *c,
+                  const VarStoreInstancer &instancer) const
   {
     TRACE_SERIALIZE (this);
     auto *out = s->embed (this);
@@ -1620,7 +1840,7 @@ struct BaseGlyphPaintRecord
                           HB_SERIALIZE_ERROR_INT_OVERFLOW))
       return_trace (false);
 
-    return_trace (out->paint.serialize_subset (c, paint, src_base));
+    return_trace (out->paint.serialize_subset (c, paint, src_base, instancer));
   }
 
   bool sanitize (hb_sanitize_context_t *c, const void *base) const
@@ -1639,7 +1859,8 @@ struct BaseGlyphPaintRecord
 
 struct BaseGlyphList : SortedArray32Of<BaseGlyphPaintRecord>
 {
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (this);
@@ -1651,7 +1872,7 @@ struct BaseGlyphList : SortedArray32Of<BaseGlyphPaintRecord>
       unsigned gid = _.glyphId;
       if (!glyphset->has (gid)) continue;
 
-      if (_.serialize (c->serializer, c->plan->glyph_map, this, c)) out->len++;
+      if (_.serialize (c->serializer, c->plan->glyph_map, this, c, instancer)) out->len++;
       else return_trace (false);
     }
 
@@ -1670,7 +1891,8 @@ struct LayerList : Array32OfOffset32To<Paint>
   const Paint& get_paint (unsigned i) const
   { return this+(*this)[i]; }
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               const VarStoreInstancer &instancer) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (this);
@@ -1681,7 +1903,7 @@ struct LayerList : Array32OfOffset32To<Paint>
 
     {
       auto *o = out->serialize_append (c->serializer);
-      if (unlikely (!o) || !o->serialize_subset (c, _.second, this))
+      if (unlikely (!o) || !o->serialize_subset (c, _.second, this, instancer))
         return_trace (false);
     }
     return_trace (true);
@@ -1883,7 +2105,6 @@ struct COLR
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-
     const hb_map_t &reverse_glyph_map = *c->plan->reverse_glyph_map;
     const hb_set_t& glyphset = c->plan->_glyphset_colred;
 
@@ -1954,7 +2175,12 @@ struct COLR
 
     auto snap = c->serializer->snapshot ();
     if (!c->serializer->allocate_size<void> (5 * HBUINT32::static_size)) return_trace (false);
-    if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this))
+
+    VarStoreInstancer instancer (varStore ? &(this+varStore) : nullptr,
+	                         varIdxMap ? &(this+varIdxMap) : nullptr,
+	                         c->plan->normalized_coords.as_array ());
+
+    if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this, instancer))
     {
       if (c->serializer->in_error ()) return_trace (false);
       //no more COLRv1 glyphs: downgrade to version 0
@@ -1964,8 +2190,11 @@ struct COLR
 
     if (!colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)) return_trace (false);
 
-    colr_prime->layerList.serialize_subset (c, layerList, this);
-    colr_prime->clipList.serialize_subset (c, clipList, this);
+    colr_prime->layerList.serialize_subset (c, layerList, this, instancer);
+    colr_prime->clipList.serialize_subset (c, clipList, this, instancer);
+    if (!varStore || c->plan->all_axes_pinned)
+      return_trace (true);
+
     colr_prime->varIdxMap.serialize_copy (c->serializer, varIdxMap, this);
     colr_prime->varStore.serialize_copy (c->serializer, varStore, this);
     return_trace (true);
@@ -1984,14 +2213,15 @@ struct COLR
       return nullptr;
   }
 
+#ifndef HB_NO_PAINT
   bool
   get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
   {
     if (version != 1)
       return false;
 
-    VarStoreInstancer instancer (this+varStore,
-				 this+varIdxMap,
+    VarStoreInstancer instancer (&(this+varStore),
+				 &(this+varIdxMap),
 				 hb_array (font->coords, font->num_coords));
 
     if (get_clip (glyph, extents, instancer))
@@ -2022,6 +2252,7 @@ struct COLR
 
     return ret;
   }
+#endif
 
   bool
   has_paint_for_glyph (hb_codepoint_t glyph) const
@@ -2045,11 +2276,12 @@ struct COLR
 					instancer);
   }
 
+#ifndef HB_NO_PAINT
   bool
   paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette_index, hb_color_t foreground, bool clip = true) const
   {
-    VarStoreInstancer instancer (this+varStore,
-	                         this+varIdxMap,
+    VarStoreInstancer instancer (&(this+varStore),
+	                         &(this+varIdxMap),
 	                         hb_array (font->coords, font->num_coords));
     hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer);
 
@@ -2060,8 +2292,8 @@ struct COLR
       {
         // COLRv1 glyph
 
-	VarStoreInstancer instancer (this+varStore,
-				     this+varIdxMap,
+	VarStoreInstancer instancer (&(this+varStore),
+				     &(this+varIdxMap),
 				     hb_array (font->coords, font->num_coords));
 
 	bool is_bounded = true;
@@ -2131,6 +2363,7 @@ struct COLR
 
     return false;
   }
+#endif
 
   protected:
   HBUINT16	version;	/* Table version number (starts at 0). */
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CPAL/CPAL.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CPAL/CPAL.hh
index 4914a0ed57af416392da57d4f32bb12209b00a5a..c07716c1c987e084160e13426ade728356dd7e33 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CPAL/CPAL.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CPAL/CPAL.hh
@@ -73,6 +73,30 @@ struct CPALV1Tail
   }
 
   public:
+  void collect_name_ids (const void *base,
+                         unsigned palette_count,
+                         unsigned color_count,
+                         const hb_map_t *color_index_map,
+                         hb_set_t *nameids_to_retain /* OUT */) const
+  {
+    if (paletteLabelsZ)
+    {
+      + (base+paletteLabelsZ).as_array (palette_count)
+      | hb_sink (nameids_to_retain)
+      ;
+    }
+
+    if (colorLabelsZ)
+    {
+      const hb_array_t<const NameID> colorLabels = (base+colorLabelsZ).as_array (color_count);
+      for (unsigned i = 0; i < color_count; i++)
+      {
+        if (!color_index_map->has (i)) continue;
+        nameids_to_retain->add (colorLabels[i]);
+      }
+    }
+  }
+
   bool serialize (hb_serialize_context_t *c,
                   unsigned palette_count,
                   unsigned color_count,
@@ -95,13 +119,10 @@ struct CPALV1Tail
     if (colorLabelsZ)
     {
       c->push ();
-      for (const auto _ : colorLabels)
+      for (unsigned i = 0; i < color_count; i++)
       {
-	const hb_codepoint_t *v;
-        if (!color_index_map->has (_, &v)) continue;
-        NameID new_color_idx;
-	new_color_idx = *v;
-        if (!c->copy<NameID> (new_color_idx))
+        if (!color_index_map->has (i)) continue;
+        if (!c->copy<NameID> (colorLabels[i]))
         {
           c->pop_discard ();
           return_trace (false);
@@ -189,6 +210,13 @@ struct CPAL
     return numColors;
   }
 
+  void collect_name_ids (const hb_map_t *color_index_map,
+                         hb_set_t *nameids_to_retain /* OUT */) const
+  {
+    if (version == 1)
+      v1 ().collect_name_ids (this, numPalettes, numColors, color_index_map, nameids_to_retain);
+  }
+
   private:
   const CPALV1Tail& v1 () const
   {
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh
index b4a9a9ad539ccd14add1985270c5e602e62e8132..4dada1c8301166a576f7209fc929c049470ddc71 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh
@@ -55,7 +55,7 @@ struct PairPosFormat1_3
 
     if (pairSet.len > glyphs->get_population () * hb_bit_storage ((unsigned) pairSet.len) / 4)
     {
-      for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
+      for (hb_codepoint_t g : glyphs->iter())
       {
 	unsigned i = cov.get_coverage (g);
 	if ((this+pairSet[i]).intersects (glyphs, valueFormat))
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh
index ffe39d52abd74598ddb0fe3e3c3025aeb6dfa35d..38057cb60c953ca5180db5e796a9dc8a134b9ae8 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh
@@ -29,6 +29,9 @@ struct Ligature
   bool intersects (const hb_set_t *glyphs) const
   { return hb_all (component, glyphs); }
 
+  bool intersects_lig_glyph (const hb_set_t *glyphs) const
+  { return glyphs->has(ligGlyph); }
+
   void closure (hb_closure_context_t *c) const
   {
     if (!intersects (c->glyphs)) return;
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSet.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSet.hh
index 637cec713777f08f74a53d8639f03a9d419e4ecf..9db25cf567b4a8442d0c709fa8c43cda378cae82 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSet.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSet.hh
@@ -34,6 +34,18 @@ struct LigatureSet
     ;
   }
 
+  bool intersects_lig_glyph (const hb_set_t *glyphs) const
+  {
+    return
+    + hb_iter (ligature)
+    | hb_map (hb_add (this))
+    | hb_map ([glyphs] (const Ligature<Types> &_) { 
+      return _.intersects_lig_glyph (glyphs) && _.intersects (glyphs);
+    })
+    | hb_any
+    ;
+  }
+
   void closure (hb_closure_context_t *c) const
   {
     + hb_iter (ligature)
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh
index 32b642c38ad7ee3cd8a8997b0036638d805c00ce..5c7df97d13aeaee6d3c1648a65cf4795e92ee5ed 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh
@@ -130,7 +130,7 @@ struct LigatureSubstFormat1_2
     + hb_zip (this+coverage, hb_iter (ligatureSet) | hb_map (hb_add (this)))
     | hb_filter (glyphset, hb_first)
     | hb_filter ([&] (const LigatureSet<Types>& _) {
-      return _.intersects (&glyphset);
+      return _.intersects_lig_glyph (&glyphset);
     }, hb_second)
     | hb_map (hb_first)
     | hb_sink (new_coverage);
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh
index 5b54fdb0788ac118a7422be6ab65f08cb5e0c224..850be86c0436235646b82024fa992c12e0eb809f 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh
@@ -95,6 +95,34 @@ struct SingleSubstFormat1_3
   bool would_apply (hb_would_apply_context_t *c) const
   { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
 
+  unsigned
+  get_glyph_alternates (hb_codepoint_t  glyph_id,
+                        unsigned        start_offset,
+                        unsigned       *alternate_count  /* IN/OUT.  May be NULL. */,
+                        hb_codepoint_t *alternate_glyphs /* OUT.     May be NULL. */) const
+  {
+    unsigned int index = (this+coverage).get_coverage (glyph_id);
+    if (likely (index == NOT_COVERED))
+    {
+      if (alternate_count)
+        *alternate_count = 0;
+      return 0;
+    }
+
+    if (alternate_count && *alternate_count)
+    {
+      hb_codepoint_t d = deltaGlyphID;
+      hb_codepoint_t mask = get_mask ();
+
+      glyph_id = (glyph_id + d) & mask;
+
+      *alternate_glyphs = glyph_id;
+      *alternate_count = 1;
+    }
+
+    return 1;
+  }
+
   bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh
index 17aa0873632f24324368cd34d41c5ce4090e896e..9c651abe71d98e2028870dd0f06eaa7a387d6265 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh
@@ -75,6 +75,31 @@ struct SingleSubstFormat2_4
   bool would_apply (hb_would_apply_context_t *c) const
   { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
 
+  unsigned
+  get_glyph_alternates (hb_codepoint_t  glyph_id,
+                        unsigned        start_offset,
+                        unsigned       *alternate_count  /* IN/OUT.  May be NULL. */,
+                        hb_codepoint_t *alternate_glyphs /* OUT.     May be NULL. */) const
+  {
+    unsigned int index = (this+coverage).get_coverage (glyph_id);
+    if (likely (index == NOT_COVERED))
+    {
+      if (alternate_count)
+        *alternate_count = 0;
+      return 0;
+    }
+
+    if (alternate_count && *alternate_count)
+    {
+      glyph_id = substitute[index];
+
+      *alternate_glyphs = glyph_id;
+      *alternate_count = 1;
+    }
+
+    return 1;
+  }
+
   bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh
index edf8cd8797da21f4f3098f117e9b0dc1b47e8378..94e00d3aea3221662585eaf52a9501e287d586ec 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh
@@ -87,27 +87,34 @@ struct CompositeGlyphRecord
     }
   }
 
-  void transform_points (contour_point_vector_t &points) const
+  void transform_points (contour_point_vector_t &points,
+			 const float (&matrix)[4],
+			 const contour_point_t &trans) const
   {
-    float matrix[4];
-    contour_point_t trans;
-    if (get_transformation (matrix, trans))
+    if (scaled_offsets ())
     {
-      if (scaled_offsets ())
-      {
-	points.translate (trans);
-	points.transform (matrix);
-      }
-      else
-      {
-	points.transform (matrix);
-	points.translate (trans);
-      }
+      points.translate (trans);
+      points.transform (matrix);
+    }
+    else
+    {
+      points.transform (matrix);
+      points.translate (trans);
     }
   }
 
-  unsigned compile_with_deltas (const contour_point_t &p_delta,
-                                char *out) const
+  bool get_points (contour_point_vector_t &points) const
+  {
+    float matrix[4];
+    contour_point_t trans;
+    get_transformation (matrix, trans);
+    if (unlikely (!points.resize (points.length + 1))) return false;
+    points[points.length - 1] = trans;
+    return true;
+  }
+
+  unsigned compile_with_point (const contour_point_t &point,
+                               char *out) const
   {
     const HBINT8 *p = &StructAfter<const HBINT8> (flags);
 #ifndef HB_NO_BEYOND_64K
@@ -121,18 +128,17 @@ struct CompositeGlyphRecord
     unsigned len_before_val = (const char *)p - (const char *)this;
     if (flags & ARG_1_AND_2_ARE_WORDS)
     {
-      // no overflow, copy and update value with deltas
+      // no overflow, copy value
       hb_memcpy (out, this, len);
 
-      const HBINT16 *px = reinterpret_cast<const HBINT16 *> (p);
       HBINT16 *o = reinterpret_cast<HBINT16 *> (out + len_before_val);
-      o[0] = px[0] + roundf (p_delta.x);
-      o[1] = px[1] + roundf (p_delta.y);
+      o[0] = roundf (point.x);
+      o[1] = roundf (point.y);
     }
     else
     {
-      int new_x = p[0] + roundf (p_delta.x);
-      int new_y = p[1] + roundf (p_delta.y);
+      int new_x = roundf (point.x);
+      int new_y = roundf (point.y);
       if (new_x <= 127 && new_x >= -128 &&
           new_y <= 127 && new_y >= -128)
       {
@@ -143,7 +149,7 @@ struct CompositeGlyphRecord
       }
       else
       {
-        // int8 overflows after deltas applied
+        // new point value has an int8 overflow
         hb_memcpy (out, this, len_before_val);
         
         //update flags
@@ -171,6 +177,7 @@ struct CompositeGlyphRecord
   bool scaled_offsets () const
   { return (flags & (SCALED_COMPONENT_OFFSET | UNSCALED_COMPONENT_OFFSET)) == SCALED_COMPONENT_OFFSET; }
 
+  public:
   bool get_transformation (float (&matrix)[4], contour_point_t &trans) const
   {
     matrix[0] = matrix[3] = 1.f;
@@ -225,7 +232,6 @@ struct CompositeGlyphRecord
     return tx || ty;
   }
 
-  public:
   hb_codepoint_t get_gid () const
   {
 #ifndef HB_NO_BEYOND_64K
@@ -246,6 +252,27 @@ struct CompositeGlyphRecord
       StructAfter<HBGlyphID16> (flags) = gid;
   }
 
+#ifndef HB_NO_BEYOND_64K
+  void lower_gid_24_to_16 ()
+  {
+    hb_codepoint_t gid = get_gid ();
+    if (!(flags & GID_IS_24BIT) || gid > 0xFFFFu)
+      return;
+
+    /* Lower the flag and move the rest of the struct down. */
+
+    unsigned size = get_size ();
+    char *end = (char *) this + size;
+    char *p = &StructAfter<char> (flags);
+    p += HBGlyphID24::static_size;
+
+    flags = flags & ~GID_IS_24BIT;
+    set_gid (gid);
+
+    memmove (p - HBGlyphID24::static_size + HBGlyphID16::static_size, p, end - p);
+  }
+#endif
+
   protected:
   HBUINT16	flags;
   HBUINT24	pad;
@@ -304,7 +331,7 @@ struct CompositeGlyph
   }
 
   bool compile_bytes_with_deltas (const hb_bytes_t &source_bytes,
-                                  const contour_point_vector_t &deltas,
+                                  const contour_point_vector_t &points_with_deltas,
                                   hb_bytes_t &dest_bytes /* OUT */)
   {
     if (source_bytes.length <= GlyphHeader::static_size ||
@@ -319,7 +346,7 @@ struct CompositeGlyph
     /* try to allocate more memories than source glyph bytes
      * in case that there might be an overflow for int8 value
      * and we would need to use int16 instead */
-    char *o = (char *) hb_calloc (source_len + source_len/2, sizeof (char));
+    char *o = (char *) hb_calloc (source_len * 2, sizeof (char));
     if (unlikely (!o)) return false;
 
     const CompositeGlyphRecord *c = reinterpret_cast<const CompositeGlyphRecord *> (source_bytes.arrayZ + GlyphHeader::static_size);
@@ -329,8 +356,11 @@ struct CompositeGlyph
     unsigned i = 0, source_comp_len = 0;
     for (const auto &component : it)
     {
-      /* last 4 points in deltas are phantom points and should not be included */
-      if (i >= deltas.length - 4) return false;
+      /* last 4 points in points_with_deltas are phantom points and should not be included */
+      if (i >= points_with_deltas.length - 4) {
+        free (o);
+        return false;
+      }
 
       unsigned comp_len = component.get_size ();
       if (component.is_anchored ())
@@ -340,7 +370,7 @@ struct CompositeGlyph
       }
       else
       {
-        unsigned new_len = component.compile_with_deltas (deltas[i], p);
+        unsigned new_len = component.compile_with_point (points_with_deltas[i], p);
         p += new_len;
       }
       i++;
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh
index 5574ae0722d0738fc371453aeb0cbf4d38357368..9e15a6e6d03b355a8aca00eec49c7e087bae21f5 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh
@@ -29,7 +29,14 @@ enum phantom_point_index_t
 
 struct Glyph
 {
-  enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE, VAR_COMPOSITE };
+  enum glyph_type_t {
+    EMPTY,
+    SIMPLE,
+    COMPOSITE,
+#ifndef HB_NO_VAR_COMPOSITES
+    VAR_COMPOSITE,
+#endif
+  };
 
   public:
   composite_iter_t get_composite_iterator () const
@@ -39,15 +46,23 @@ struct Glyph
   }
   var_composite_iter_t get_var_composite_iterator () const
   {
+#ifndef HB_NO_VAR_COMPOSITES
     if (type != VAR_COMPOSITE) return var_composite_iter_t ();
     return VarCompositeGlyph (*header, bytes).iter ();
+#else
+    return var_composite_iter_t ();
+#endif
   }
 
   const hb_bytes_t trim_padding () const
   {
     switch (type) {
+#ifndef HB_NO_VAR_COMPOSITES
+    case VAR_COMPOSITE: return VarCompositeGlyph (*header, bytes).trim_padding ();
+#endif
     case COMPOSITE: return CompositeGlyph (*header, bytes).trim_padding ();
     case SIMPLE:    return SimpleGlyph (*header, bytes).trim_padding ();
+    case EMPTY:     return bytes;
     default:        return bytes;
     }
   }
@@ -55,27 +70,36 @@ struct Glyph
   void drop_hints ()
   {
     switch (type) {
+#ifndef HB_NO_VAR_COMPOSITES
+    case VAR_COMPOSITE: return; // No hinting
+#endif
     case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints (); return;
     case SIMPLE:    SimpleGlyph (*header, bytes).drop_hints (); return;
-    default:        return;
+    case EMPTY:     return;
     }
   }
 
   void set_overlaps_flag ()
   {
     switch (type) {
+#ifndef HB_NO_VAR_COMPOSITES
+    case VAR_COMPOSITE: return; // No overlaps flag
+#endif
     case COMPOSITE: CompositeGlyph (*header, bytes).set_overlaps_flag (); return;
     case SIMPLE:    SimpleGlyph (*header, bytes).set_overlaps_flag (); return;
-    default:        return;
+    case EMPTY:     return;
     }
   }
 
   void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const
   {
     switch (type) {
+#ifndef HB_NO_VAR_COMPOSITES
+    case VAR_COMPOSITE: return; // No hinting
+#endif
     case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints_bytes (dest_start); return;
     case SIMPLE:    SimpleGlyph (*header, bytes).drop_hints_bytes (dest_start, dest_end); return;
-    default:        return;
+    case EMPTY:     return;
     }
   }
 
@@ -181,7 +205,7 @@ struct Glyph
                                   hb_bytes_t &dest_start,  /* IN/OUT */
                                   hb_bytes_t &dest_end /* OUT */)
   {
-    contour_point_vector_t all_points, deltas;
+    contour_point_vector_t all_points, points_with_deltas;
     unsigned composite_contours = 0;
     head_maxp_info_t *head_maxp_info_p = &plan->head_maxp_info;
     unsigned *composite_contours_p = &composite_contours;
@@ -195,7 +219,7 @@ struct Glyph
       composite_contours_p = nullptr;
     }
 
-    if (!get_points (font, glyf, all_points, &deltas, head_maxp_info_p, composite_contours_p, false, false))
+    if (!get_points (font, glyf, all_points, &points_with_deltas, head_maxp_info_p, composite_contours_p, false, false))
       return false;
 
     // .notdef, set type to empty so we only update metrics and don't compile bytes for
@@ -209,11 +233,20 @@ struct Glyph
     }
 
     //dont compile bytes when pinned at default, just recalculate bounds
-    if (!plan->pinned_at_default) {
-      switch (type) {
+    if (!plan->pinned_at_default)
+    {
+      switch (type)
+      {
+#ifndef HB_NO_VAR_COMPOSITES
+      case VAR_COMPOSITE:
+	// TODO
+	dest_end = hb_bytes_t ();
+	break;
+#endif
+
       case COMPOSITE:
         if (!CompositeGlyph (*header, bytes).compile_bytes_with_deltas (dest_start,
-                                                                        deltas,
+                                                                        points_with_deltas,
                                                                         dest_end))
           return false;
         break;
@@ -223,7 +256,7 @@ struct Glyph
                                                                      dest_end))
           return false;
         break;
-      default:
+      case EMPTY:
         /* set empty bytes for empty glyph
          * do not use source glyph's pointers */
         dest_start = hb_bytes_t ();
@@ -247,7 +280,7 @@ struct Glyph
   template <typename accelerator_t>
   bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator,
 		   contour_point_vector_t &all_points /* OUT */,
-		   contour_point_vector_t *deltas = nullptr, /* OUT */
+		   contour_point_vector_t *points_with_deltas = nullptr, /* OUT */
 		   head_maxp_info_t * head_maxp_info = nullptr, /* OUT */
 		   unsigned *composite_contours = nullptr, /* OUT */
 		   bool shift_points_hori = true,
@@ -287,9 +320,8 @@ struct Glyph
       break;
     case COMPOSITE:
     {
-      /* pseudo component points for each component in composite glyph */
-      unsigned num_points = hb_len (CompositeGlyph (*header, bytes).iter ());
-      if (unlikely (!points.resize (num_points))) return false;
+      for (auto &item : get_composite_iterator ())
+        if (unlikely (!item.get_points (points))) return false;
       break;
     }
 #ifndef HB_NO_VAR_COMPOSITES
@@ -299,7 +331,7 @@ struct Glyph
         if (unlikely (!item.get_points (points))) return false;
     }
 #endif
-    default:
+    case EMPTY:
       break;
     }
 
@@ -327,17 +359,11 @@ struct Glyph
 #endif
 		       ;
       phantoms[PHANTOM_LEFT].x = h_delta;
-      phantoms[PHANTOM_RIGHT].x = h_adv + h_delta;
+      phantoms[PHANTOM_RIGHT].x = (int) h_adv + h_delta;
       phantoms[PHANTOM_TOP].y = v_orig;
       phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv;
     }
 
-    if (deltas != nullptr && depth == 0 && type == COMPOSITE)
-    {
-      if (unlikely (!deltas->resize (points.length))) return false;
-      deltas->copy_vector (points);
-    }
-
 #ifndef HB_NO_VAR
     glyf_accelerator.gvar->apply_deltas_to_points (gid,
 						   coords,
@@ -346,13 +372,10 @@ struct Glyph
 
     // mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it
     // with child glyphs' points
-    if (deltas != nullptr && depth == 0 && type == COMPOSITE)
+    if (points_with_deltas != nullptr && depth == 0 && type == COMPOSITE)
     {
-      for (unsigned i = 0 ; i < points.length; i++)
-      {
-        deltas->arrayZ[i].x = points.arrayZ[i].x - deltas->arrayZ[i].x;
-        deltas->arrayZ[i].y = points.arrayZ[i].y - deltas->arrayZ[i].y;
-      }
+      if (unlikely (!points_with_deltas->resize (points.length))) return false;
+      points_with_deltas->copy_vector (points);
     }
 
     switch (type) {
@@ -373,7 +396,7 @@ struct Glyph
 				       .get_points (font,
 						    glyf_accelerator,
 						    comp_points,
-						    deltas,
+						    points_with_deltas,
 						    head_maxp_info,
 						    composite_contours,
 						    shift_points_hori,
@@ -389,11 +412,12 @@ struct Glyph
 	  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);
+	float matrix[4];
+	contour_point_t default_trans;
+	item.get_transformation (matrix, default_trans);
 
-	/* Apply translation from gvar */
-	comp_points.translate (points[comp_index]);
+	/* Apply component transformation & translation (with deltas applied) */
+	item.transform_points (comp_points, matrix, points[comp_index]);
 
 	if (item.is_anchored ())
 	{
@@ -433,7 +457,8 @@ struct Glyph
       hb_array_t<contour_point_t> points_left = points.as_array ();
       for (auto &item : get_var_composite_iterator ())
       {
-	hb_array_t<contour_point_t> record_points = points_left.sub_array (0, item.get_num_points ());
+	unsigned item_num_points = item.get_num_points ();
+	hb_array_t<contour_point_t> record_points = points_left.sub_array (0, item_num_points);
 
         comp_points.reset ();
 
@@ -448,7 +473,7 @@ struct Glyph
 				       .get_points (font,
 						    glyf_accelerator,
 						    comp_points,
-						    deltas,
+						    points_with_deltas,
 						    head_maxp_info,
 						    nullptr,
 						    shift_points_hori,
@@ -472,12 +497,12 @@ struct Glyph
 	if (all_points.length > HB_GLYF_MAX_POINTS)
 	  return false;
 
-	points_left += item.get_num_points ();
+	points_left += item_num_points;
       }
       all_points.extend (phantoms);
     } break;
 #endif
-    default:
+    case EMPTY:
       all_points.extend (phantoms);
       break;
     }
@@ -503,6 +528,8 @@ struct Glyph
   }
 
   hb_bytes_t get_bytes () const { return bytes; }
+  glyph_type_t get_type () const { return type; }
+  const GlyphHeader *get_header () const { return header; }
 
   Glyph () : bytes (),
              header (bytes.as<GlyphHeader> ()),
@@ -518,7 +545,9 @@ struct Glyph
     int num_contours = header->numberOfContours;
     if (unlikely (num_contours == 0)) type = EMPTY;
     else if (num_contours > 0) type = SIMPLE;
+#ifndef HB_NO_VAR_COMPOSITES
     else if (num_contours == -2) type = VAR_COMPOSITE;
+#endif
     else type = COMPOSITE; /* negative numbers */
   }
 
@@ -526,7 +555,7 @@ struct Glyph
   hb_bytes_t bytes;
   const GlyphHeader *header;
   hb_codepoint_t gid;
-  unsigned type;
+  glyph_type_t type;
 };
 
 
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh
index b6fefce1ac99532cdfa98c5f0b20f377b47a266d..b6679b2dae86fa78a0157005b48d4f92f2650eb1 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh
@@ -34,6 +34,11 @@ struct SimpleGlyph
   unsigned int length (unsigned int instruction_len) const
   { return instruction_len_offset () + 2 + instruction_len; }
 
+  bool has_instructions_length () const
+  {
+    return instruction_len_offset () + 2 <= bytes.length;
+  }
+
   unsigned int instructions_length () const
   {
     unsigned int instruction_length_offset = instruction_len_offset ();
@@ -94,6 +99,7 @@ struct SimpleGlyph
   /* zero instruction length */
   void drop_hints ()
   {
+    if (!has_instructions_length ()) return;
     GlyphHeader &glyph_header = const_cast<GlyphHeader &> (header);
     (HBUINT16 &) StructAtOffset<HBUINT16> (&glyph_header, instruction_len_offset ()) = 0;
   }
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SubsetGlyph.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SubsetGlyph.hh
index 795925bba525bae439b0f8ed776023bb9034c1fd..26dc374eab64701972e82cc5785481fac77cf0a6 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SubsetGlyph.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SubsetGlyph.hh
@@ -18,6 +18,7 @@ struct SubsetGlyph
   Glyph source_glyph;
   hb_bytes_t dest_start;  /* region of source_glyph to copy first */
   hb_bytes_t dest_end;    /* region of source_glyph to copy second */
+  bool allocated;
 
   bool serialize (hb_serialize_context_t *c,
 		  bool use_short_loca,
@@ -26,7 +27,12 @@ struct SubsetGlyph
     TRACE_SERIALIZE (this);
 
     hb_bytes_t dest_glyph = dest_start.copy (c);
-    dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length);
+    hb_bytes_t end_copy = dest_end.copy (c);
+    if (!end_copy.arrayZ || !dest_glyph.arrayZ) {
+      return false;
+    }
+
+    dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + end_copy.length);
     unsigned int pad_length = use_short_loca ? padding () : 0;
     DEBUG_MSG (SUBSET, nullptr, "serialize %u byte glyph, width %u pad %u", dest_glyph.length, dest_glyph.length + pad_length, pad_length);
 
@@ -40,13 +46,68 @@ struct SubsetGlyph
 
     if (unlikely (!dest_glyph.length)) return_trace (true);
 
-    /* update components gids */
+    /* update components gids. */
     for (auto &_ : Glyph (dest_glyph).get_composite_iterator ())
     {
       hb_codepoint_t new_gid;
       if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid))
 	const_cast<CompositeGlyphRecord &> (_).set_gid (new_gid);
     }
+#ifndef HB_NO_VAR_COMPOSITES
+    for (auto &_ : Glyph (dest_glyph).get_var_composite_iterator ())
+    {
+      hb_codepoint_t new_gid;
+      if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid))
+	const_cast<VarCompositeGlyphRecord &> (_).set_gid (new_gid);
+    }
+#endif
+
+#ifndef HB_NO_BEYOND_64K
+    auto it = Glyph (dest_glyph).get_composite_iterator ();
+    if (it)
+    {
+      /* lower GID24 to GID16 in components if possible.
+       *
+       * TODO: VarComposite. Not as critical, since VarComposite supports
+       * gid24 from the first version. */
+      char *p = it ? (char *) &*it : nullptr;
+      char *q = p;
+      const char *end = dest_glyph.arrayZ + dest_glyph.length;
+      while (it)
+      {
+	auto &rec = const_cast<CompositeGlyphRecord &> (*it);
+	++it;
+
+	q += rec.get_size ();
+
+	rec.lower_gid_24_to_16 ();
+
+	unsigned size = rec.get_size ();
+
+	memmove (p, &rec, size);
+
+	p += size;
+      }
+      memmove (p, q, end - q);
+      p += end - q;
+
+      /* We want to shorten the glyph, but we can't do that without
+       * updating the length in the loca table, which is already
+       * written out :-(.  So we just fill the rest of the glyph with
+       * harmless instructions, since that's what they will be
+       * interpreted as.
+       *
+       * Should move the lowering to _populate_subset_glyphs() to
+       * fix this issue. */
+
+      hb_memset (p, 0x7A /* TrueType instruction ROFF; harmless */, end - p);
+      p += end - p;
+      dest_glyph = hb_bytes_t (dest_glyph.arrayZ, p - (char *) dest_glyph.arrayZ);
+
+      // TODO: Padding; & trim serialized bytes.
+      // TODO: Update length in loca. Ugh.
+    }
+#endif
 
     if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
       Glyph (dest_glyph).drop_hints ();
@@ -60,12 +121,18 @@ struct SubsetGlyph
   bool compile_bytes_with_deltas (const hb_subset_plan_t *plan,
                                   hb_font_t *font,
                                   const glyf_accelerator_t &glyf)
-  { return source_glyph.compile_bytes_with_deltas (plan, font, glyf, dest_start, dest_end); }
+  {
+    allocated = source_glyph.compile_bytes_with_deltas (plan, font, glyf, dest_start, dest_end);
+    return allocated;
+  }
 
   void free_compiled_bytes ()
   {
-    dest_start.fini ();
-    dest_end.fini ();
+    if (likely (allocated)) {
+      allocated = false;
+      dest_start.fini ();
+      dest_end.fini ();
+    }
   }
 
   void drop_hints_bytes ()
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/VarCompositeGlyph.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/VarCompositeGlyph.hh
index 3685da7913a2b129924f83c0b9a69509cb3175e4..309ec473aa29f0d4ee0a5ad927e57332003dabdd 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/VarCompositeGlyph.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/VarCompositeGlyph.hh
@@ -27,7 +27,7 @@ struct VarCompositeGlyphRecord
     HAVE_SKEW_Y			= 0x0200,
     HAVE_TCENTER_X		= 0x0400,
     HAVE_TCENTER_Y		= 0x0800,
-    GID_IS_24			= 0x1000,
+    GID_IS_24BIT		= 0x1000,
     AXES_HAVE_VARIATION		= 0x2000,
     RESET_UNSPECIFIED_AXES	= 0x4000,
   };
@@ -43,7 +43,7 @@ struct VarCompositeGlyphRecord
 
     // gid
     size += 2;
-    if (flags & GID_IS_24)		size += 1;
+    if (flags & GID_IS_24BIT)		size += 1;
 
     if (flags & HAVE_TRANSLATE_X)	size += 2;
     if (flags & HAVE_TRANSLATE_Y)	size += 2;
@@ -65,12 +65,20 @@ struct VarCompositeGlyphRecord
 
   hb_codepoint_t get_gid () const
   {
-    if (flags & GID_IS_24)
+    if (flags & GID_IS_24BIT)
       return StructAfter<const HBGlyphID24> (numAxes);
     else
       return StructAfter<const HBGlyphID16> (numAxes);
   }
 
+  void set_gid (hb_codepoint_t gid)
+  {
+    if (flags & GID_IS_24BIT)
+      StructAfter<HBGlyphID24> (numAxes) = gid;
+    else
+      StructAfter<HBGlyphID16> (numAxes) = gid;
+  }
+
   unsigned get_numAxes () const
   {
     return numAxes;
@@ -145,7 +153,7 @@ struct VarCompositeGlyphRecord
 		      float rotation)
   {
     // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240
-    rotation = rotation * float (M_PI);
+    rotation = rotation * HB_PI;
     float c = cosf (rotation);
     float s = sinf (rotation);
     float other[6] = {c, s, -s, c, 0.f, 0.f};
@@ -156,8 +164,8 @@ struct VarCompositeGlyphRecord
 		    float skewX, float skewY)
   {
     // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255
-    skewX = skewX * float (M_PI);
-    skewY = skewY * float (M_PI);
+    skewX = skewX * HB_PI;
+    skewY = skewY * HB_PI;
     float other[6] = {1.f, tanf (skewY), tanf (skewX), 1.f, 0.f, 0.f};
     transform (matrix, trans, other);
   }
@@ -174,16 +182,18 @@ struct VarCompositeGlyphRecord
     float tCenterX = 0.f;
     float tCenterY = 0.f;
 
-    if (unlikely (!points.resize (points.length + get_num_points ()))) return false;
+    unsigned num_points = get_num_points ();
+
+    if (unlikely (!points.resize (points.length + num_points))) return false;
 
     unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1;
     unsigned axes_size = numAxes * axis_width;
 
     const F2DOT14 *q = (const F2DOT14 *) (axes_size +
-					  (flags & GID_IS_24 ? 3 : 2) +
+					  (flags & GID_IS_24BIT ? 3 : 2) +
 					  &StructAfter<const HBUINT8> (numAxes));
 
-    hb_array_t<contour_point_t> rec_points = points.as_array ().sub_array (points.length - get_num_points ());
+    hb_array_t<contour_point_t> rec_points = points.as_array ().sub_array (points.length - num_points);
 
     unsigned count = numAxes;
     if (flags & AXES_HAVE_VARIATION)
@@ -308,8 +318,8 @@ struct VarCompositeGlyphRecord
     bool have_variations = flags & AXES_HAVE_VARIATION;
     unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1;
 
-    const HBUINT8  *p = (const HBUINT8 *)  (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24 ? 3 : 2));
-    const HBUINT16 *q = (const HBUINT16 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24 ? 3 : 2));
+    const HBUINT8  *p = (const HBUINT8 *)  (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24BIT ? 3 : 2));
+    const HBUINT16 *q = (const HBUINT16 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24BIT ? 3 : 2));
 
     const F2DOT14 *a = (const F2DOT14 *) ((HBUINT8 *) (axis_width == 1 ? (p + numAxes) : (HBUINT8 *) (q + numAxes)));
 
@@ -344,6 +354,13 @@ struct VarCompositeGlyph
   var_composite_iter_t iter () const
   { return var_composite_iter_t (bytes, &StructAfter<VarCompositeGlyphRecord, GlyphHeader> (header)); }
 
+  const hb_bytes_t trim_padding () const
+  {
+    unsigned length = GlyphHeader::static_size;
+    for (auto &comp : iter ())
+      length += comp.get_size ();
+    return bytes.sub_array (0, length);
+  }
 };
 
 
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh
index 29328c7627b96535e2c4e8811c35502f13659170..dd08dda6ee19647c1cab5234bc56d29b2dad1d4a 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh
@@ -31,6 +31,12 @@ struct glyf
 
   static constexpr hb_tag_t tableTag = HB_OT_TAG_glyf;
 
+  static bool has_valid_glyf_format(const hb_face_t* face)
+  {
+    const OT::head &head = *face->table.head;
+    return head.indexToLocFormat <= 1 && head.glyphDataFormat <= 1;
+  }
+
   bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const
   {
     TRACE_SANITIZE (this);
@@ -72,6 +78,13 @@ struct glyf
   {
     TRACE_SUBSET (this);
 
+    if (!has_valid_glyf_format (c->plan->source)) {
+      // glyf format is unknown don't attempt to subset it.
+      DEBUG_MSG (SUBSET, nullptr,
+                 "unkown glyf format, dropping from subset.");
+      return_trace (false);
+    }
+
     glyf *glyf_prime = c->serializer->start_embed <glyf> ();
     if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false);
 
@@ -85,11 +98,17 @@ struct glyf
     hb_vector_t<unsigned> padded_offsets;
     unsigned num_glyphs = c->plan->num_output_glyphs ();
     if (unlikely (!padded_offsets.resize (num_glyphs)))
+    {
+      hb_font_destroy (font);
       return false;
+    }
 
     hb_vector_t<glyf_impl::SubsetGlyph> glyphs;
     if (!_populate_subset_glyphs (c->plan, font, glyphs))
+    {
+      hb_font_destroy (font);
       return false;
+    }
 
     if (font)
       hb_font_destroy (font);
@@ -112,7 +131,7 @@ struct glyf
 
     bool result = glyf_prime->serialize (c->serializer, glyphs.writer (), use_short_loca, c->plan);
     if (c->plan->normalized_coords && !c->plan->pinned_at_default)
-      _free_compiled_subset_glyphs (glyphs, glyphs.length - 1);
+      _free_compiled_subset_glyphs (glyphs);
 
     if (!result) return false;
 
@@ -131,9 +150,9 @@ struct glyf
   hb_font_t *
   _create_font_for_instancing (const hb_subset_plan_t *plan) const;
 
-  void _free_compiled_subset_glyphs (hb_vector_t<glyf_impl::SubsetGlyph> &glyphs, unsigned index) const
+  void _free_compiled_subset_glyphs (hb_vector_t<glyf_impl::SubsetGlyph> &glyphs) const
   {
-    for (unsigned i = 0; i <= index && i < glyphs.length; i++)
+    for (unsigned i = 0; i < glyphs.length; i++)
       glyphs[i].free_compiled_bytes ();
   }
 
@@ -162,7 +181,7 @@ struct glyf_accelerator_t
     vmtx = nullptr;
 #endif
     const OT::head &head = *face->table.head;
-    if (head.indexToLocFormat > 1 || head.glyphDataFormat > 0)
+    if (!glyf::has_valid_glyf_format (face))
       /* Unknown format.  Leave num_glyphs=0, that takes care of disabling us. */
       return;
     short_offset = 0 == head.indexToLocFormat;
@@ -222,6 +241,8 @@ struct glyf_accelerator_t
     return true;
   }
 
+  public:
+
 #ifndef HB_NO_VAR
   struct points_aggregator_t
   {
@@ -285,7 +306,6 @@ struct glyf_accelerator_t
     contour_point_t *get_phantoms_sink () { return phantoms; }
   };
 
-  public:
   unsigned
   get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const
   {
@@ -327,6 +347,15 @@ struct glyf_accelerator_t
   }
 #endif
 
+  bool get_leading_bearing_without_var_unscaled (hb_codepoint_t gid, bool is_vertical, int *lsb) const
+  {
+    if (unlikely (gid >= num_glyphs)) return false;
+    if (is_vertical) return false; // TODO Humm, what to do here?
+
+    *lsb = glyph_for_gid (gid).get_header ()->xMin;
+    return true;
+  }
+
   public:
   bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const
   {
@@ -405,7 +434,6 @@ glyf::_populate_subset_glyphs (const hb_subset_plan_t   *plan,
   unsigned num_glyphs = plan->num_output_glyphs ();
   if (!glyphs.resize (num_glyphs)) return false;
 
-  unsigned idx = 0;
   for (auto p : plan->glyph_map->iter ())
   {
     unsigned new_gid = p.second;
@@ -433,11 +461,10 @@ glyf::_populate_subset_glyphs (const hb_subset_plan_t   *plan,
       if (unlikely (!subset_glyph.compile_bytes_with_deltas (plan, font, glyf)))
       {
         // when pinned at default, only bounds are updated, thus no need to free
-        if (!plan->pinned_at_default && idx > 0)
-          _free_compiled_subset_glyphs (glyphs, idx - 1);
+        if (!plan->pinned_at_default)
+          _free_compiled_subset_glyphs (glyphs);
         return false;
       }
-      idx++;
     }
   }
   return true;
@@ -451,7 +478,10 @@ glyf::_create_font_for_instancing (const hb_subset_plan_t *plan) const
 
   hb_vector_t<hb_variation_t> vars;
   if (unlikely (!vars.alloc (plan->user_axes_location.get_population (), true)))
+  {
+    hb_font_destroy (font);
     return nullptr;
+  }
 
   for (auto _ : plan->user_axes_location)
   {
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in b/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in
index 0de082c2a63eeccd1c4681d16c10d608f4d55ed1..ced97919a23d24fb13ab99b8a4c6e081770f999f 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in
+++ b/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in
@@ -12,13 +12,17 @@ list(GET _harfbuzz_version_info 2
   _harfbuzz_age)
 unset(_harfbuzz_version_info)
 
-if (APPLE)
-  set(_harfbuzz_lib_suffix ".0${CMAKE_SHARED_LIBRARY_SUFFIX}")
-elseif (UNIX)
-  set(_harfbuzz_lib_suffix "${CMAKE_SHARED_LIBRARY_SUFFIX}.0.${_harfbuzz_current}.${_harfbuzz_revision}")
+if ("@default_library@" MATCHES "static")
+  set(_harfbuzz_lib_suffix ".a")
 else ()
-  # Unsupported.
-  set(harfbuzz_FOUND 0)
+  if (APPLE)
+    set(_harfbuzz_lib_suffix ".0${CMAKE_SHARED_LIBRARY_SUFFIX}")
+  elseif (UNIX)
+    set(_harfbuzz_lib_suffix "${CMAKE_SHARED_LIBRARY_SUFFIX}.0.${_harfbuzz_current}.${_harfbuzz_revision}")
+  else ()
+    # Unsupported.
+    set(harfbuzz_FOUND 0)
+  endif ()
 endif ()
 
 # Add the libraries.
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh
index efbb623efcaf918d24f515c32ed4e9433ac4e1ee..7d53c354dabce6019bed83bc4dbd702ae6583fdf 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh
@@ -464,7 +464,8 @@ enum { DELETED_GLYPH = 0xFFFF };
 template <typename T>
 struct Entry
 {
-  bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
+  // This does seem like it's ever called.
+  bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
     /* Note, we don't recurse-sanitize data because we don't access it.
@@ -492,7 +493,8 @@ struct Entry
 template <>
 struct Entry<void>
 {
-  bool sanitize (hb_sanitize_context_t *c, unsigned int count /*XXX Unused?*/) const
+  // This does seem like it's ever called.
+  bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this));
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh
index 8e8c988716d6826a7c430475246a63a811fd3c5f..9edefd9710657f5df3a55e931389d617b17a23ab 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh
@@ -83,9 +83,15 @@ struct hb_bimap_t
 
   unsigned int get_population () const { return forw_map.get_population (); }
 
+
   protected:
   hb_map_t  forw_map;
   hb_map_t  back_map;
+
+  public:
+  auto keys () const HB_AUTO_RETURN (+ forw_map.keys())
+  auto values () const HB_AUTO_RETURN (+ forw_map.values())
+  auto iter () const HB_AUTO_RETURN (+ forw_map.iter())
 };
 
 /* Inremental bimap: only lhs is given, rhs is incrementally assigned */
@@ -108,6 +114,9 @@ struct hb_inc_bimap_t : hb_bimap_t
   hb_codepoint_t skip ()
   { return next_value++; }
 
+  hb_codepoint_t skip (unsigned count)
+  { return next_value += count; }
+
   hb_codepoint_t get_next_value () const
   { return next_value; }
 
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh
index 475b07b810bae2528d1522cccc3a6ebea7a80d36..c30b2af7b0d9efec5f057f7865611e06b29eccbe 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh
@@ -194,7 +194,7 @@ struct hb_bit_set_t
       unsigned int end = major_start (m + 1);
       do
       {
-        if (v || page) /* The v check is to optimize out the page check if v is true. */
+        if (g != INVALID && (v || page)) /* The v check is to optimize out the page check if v is true. */
 	  page->set (g, v);
 
 	array = &StructAtOffsetUnaligned<T> (array, stride);
@@ -238,7 +238,7 @@ struct hb_bit_set_t
 	if (g < last_g) return false;
 	last_g = g;
 
-        if (v || page) /* The v check is to optimize out the page check if v is true. */
+        if (g != INVALID && (v || page)) /* The v check is to optimize out the page check if v is true. */
 	  page->add (g);
 
 	array = &StructAtOffsetUnaligned<T> (array, stride);
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
index f557ceee561459fa88acbb332b40737fb0a1dea6..616cee807f6a47bebb688465fb85f2ba1aa10bcc 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
@@ -40,6 +40,11 @@
  * Buffers serve a dual role in HarfBuzz; before shaping, they hold
  * the input characters that are passed to hb_shape(), and after
  * shaping they hold the output glyphs.
+ *
+ * The input buffer is a sequence of Unicode codepoints, with
+ * associated attributes such as direction and script.  The output
+ * buffer is a sequence of glyphs, with associated attributes such
+ * as position and cluster.
  **/
 
 
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh
index 2e98187b5021a9bcaf346185d3d55136984ef44b..8371465c6c2cbd2af22063e46a34247b168ddd7a 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh
@@ -30,7 +30,19 @@
 #include "hb.hh"
 
 
-/* Implements a lockfree cache for int->int functions. */
+/* Implements a lockfree cache for int->int functions.
+ *
+ * The cache is a fixed-size array of 16-bit or 32-bit integers.
+ * The key is split into two parts: the cache index and the rest.
+ *
+ * The cache index is used to index into the array.  The rest is used
+ * to store the key and the value.
+ *
+ * The value is stored in the least significant bits of the integer.
+ * The key is stored in the most significant bits of the integer.
+ * The key is shifted by cache_bits to the left to make room for the
+ * value.
+ */
 
 template <unsigned int key_bits=16,
 	 unsigned int value_bits=8 + 32 - key_bits,
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo-utils.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo-utils.cc
index 3e5118f213f0f9ee2769adf07cd9cf3190ab46a5..0f94d8169f24599518d66d2f0e62fdf310e48d09 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo-utils.cc
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo-utils.cc
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2022  Red Hat, Inc
+ * Copyright © 2021, 2022  Black Foundry
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -32,9 +33,13 @@
 
 #include <cairo.h>
 
-#define PREALLOCATED_COLOR_STOPS 16
+/* Some routines in this file were ported from BlackRenderer by Black Foundry.
+ * Used by permission to relicense to HarfBuzz license.
+ *
+ * https://github.com/BlackFoundryCom/black-renderer
+ */
 
-#define _2_M_PIf (2.f * float (M_PI))
+#define PREALLOCATED_COLOR_STOPS 16
 
 typedef struct {
   float r, g, b, a;
@@ -518,7 +523,7 @@ _hb_cairo_add_patch (cairo_pattern_t *pattern, hb_cairo_point_t *center, hb_cair
   cairo_mesh_pattern_end_patch (pattern);
 }
 
-#define MAX_ANGLE ((float) M_PI / 8.f)
+#define MAX_ANGLE (HB_PI / 8.f)
 
 static void
 _hb_cairo_add_sweep_gradient_patches1 (float cx, float cy, float radius,
@@ -601,7 +606,7 @@ _hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops,
 					       start_angle, &c,
 					       pattern);
       }
-      if (end_angle < _2_M_PIf)
+      if (end_angle < HB_2_PI)
       {
 	c.r = hb_color_get_red (stops[n_stops - 1].color) / 255.;
 	c.g = hb_color_get_green (stops[n_stops - 1].color) / 255.;
@@ -609,7 +614,7 @@ _hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops,
 	c.a = hb_color_get_alpha (stops[n_stops - 1].color) / 255.;
 	_hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
 					       end_angle, &c,
-					       _2_M_PIf,  &c,
+					       HB_2_PI,  &c,
 					       pattern);
       }
     }
@@ -673,7 +678,7 @@ _hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops,
       color0 = colors[n_stops-1];
       _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
 					     0.,       &color0,
-					     _2_M_PIf, &color0,
+					     HB_2_PI, &color0,
 					     pattern);
       goto done;
     }
@@ -685,7 +690,7 @@ _hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops,
 
     for (pos++; pos < n_stops; pos++)
     {
-      if (angles[pos] <= _2_M_PIf)
+      if (angles[pos] <= HB_2_PI)
       {
 	_hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
 					       angles[pos - 1], &colors[pos-1],
@@ -694,11 +699,11 @@ _hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops,
       }
       else
       {
-	float k = (_2_M_PIf - angles[pos - 1]) / (angles[pos] - angles[pos - 1]);
+	float k = (HB_2_PI - angles[pos - 1]) / (angles[pos] - angles[pos - 1]);
 	_hb_cairo_interpolate_colors (&colors[pos - 1], &colors[pos], k, &color1);
 	_hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
 					       angles[pos - 1], &colors[pos - 1],
-					       _2_M_PIf,        &color1,
+					       HB_2_PI,        &color1,
 					       pattern);
 	break;
       }
@@ -710,7 +715,7 @@ _hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops,
       color0 = colors[n_stops - 1];
       _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
 					     angles[n_stops - 1], &color0,
-					     _2_M_PIf,            &color0,
+					     HB_2_PI,            &color0,
 					     pattern);
       goto done;
     }
@@ -794,14 +799,14 @@ _hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops,
 						 a1, c1,
 						 pattern);
 	}
-	else if (a1 >= _2_M_PIf)
+	else if (a1 >= HB_2_PI)
 	{
 	  hb_cairo_color_t color;
-	  float f = (_2_M_PIf - a0)/(a1 - a0);
+	  float f = (HB_2_PI - a0)/(a1 - a0);
 	  _hb_cairo_interpolate_colors (c0, c1, f, &color);
 	  _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
 						 a0,       c0,
-						 _2_M_PIf, &color,
+						 HB_2_PI, &color,
 						 pattern);
 	  goto done;
 	}
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc
index c9a40295a3d7208ca35119c50834c542c13ee264..282a8e4d0f61e821546f58f3d6f80c13db0b6846 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc
@@ -632,6 +632,7 @@ hb_script_get_horizontal_direction (hb_script_t script)
     case HB_SCRIPT_OLD_HUNGARIAN:
     case HB_SCRIPT_OLD_ITALIC:
     case HB_SCRIPT_RUNIC:
+    case HB_SCRIPT_TIFINAGH:
 
       return HB_DIRECTION_INVALID;
   }
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h b/source/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h
index edacfd064c349148f062b85f7f54127f9852555d..b032a941b286e49fc08890c1cebe9791ceb93609 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h
@@ -108,6 +108,16 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
 			      hb_font_get_glyph_func_t func,
 			      void *user_data, hb_destroy_func_t destroy);
 
+/* https://github.com/harfbuzz/harfbuzz/pull/4207 */
+/**
+ * HB_UNICODE_COMBINING_CLASS_CCC133:
+ *
+ * [Tibetan]
+ *
+ * Deprecated: 7.2.0
+ **/
+#define HB_UNICODE_COMBINING_CLASS_CCC133 133
+
 /**
  * hb_unicode_eastasian_width_func_t:
  * @ufuncs: A Unicode-functions structure
@@ -247,6 +257,7 @@ hb_font_get_glyph_v_kerning (hb_font_t *font,
 
 #endif
 
+
 HB_END_DECLS
 
 #endif /* HB_DEPRECATED_H */
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc
index 5fcc4e93d9ab363586932898a8048663425e1331..e340710586c15b7610af29da7a7fa272d86f9c27 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc
@@ -47,6 +47,12 @@
  * More precisely, a font face represents a single face in a binary font file.
  * Font faces are typically built from a binary blob and a face index.
  * Font faces are used to create fonts.
+ *
+ * A font face can be created from a binary blob using hb_face_create().
+ * The face index is used to select a face from a binary blob that contains
+ * multiple faces.  For example, a binary blob that contains both a regular
+ * and a bold face can be used to create two font faces, one for each face
+ * index.
  **/
 
 
@@ -197,7 +203,7 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
  * a face index into that blob.
  *
  * The face index is used for blobs of file formats such as TTC and
- * and DFont that can contain more than one face.  Face indices within
+ * DFont that can contain more than one face.  Face indices within
  * such collections are zero-based.
  *
  * <note>Note: If the blob font format is not a collection, @index
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh
index 1bf0606e5262493235ac0449fa579c03853f0928..aff3ff0d07ceb403b779ddd255c74ebc7031bde6 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh
@@ -76,7 +76,7 @@ struct hb_face_t
     if (unlikely (!reference_table_func))
       return hb_blob_get_empty ();
 
-    blob = reference_table_func (/*XXX*/const_cast<hb_face_t *> (this), tag, user_data);
+    blob = reference_table_func (/*Oh, well.*/const_cast<hb_face_t *> (this), tag, user_data);
     if (unlikely (!blob))
       return hb_blob_get_empty ();
 
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
index 1b345a9447cb23ece5d0f7a1b6fcd0927dfff3c2..688513112a7dc7b1e91a70e9f0596e349ef830d0 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
@@ -59,6 +59,11 @@
  *
  * HarfBuzz provides a built-in set of lightweight default
  * functions for each method in #hb_font_funcs_t.
+ *
+ * The default font functions are implemented in terms of the
+ * #hb_font_funcs_t methods of the parent font object.  This allows
+ * client programs to override only the methods they need to, and
+ * otherwise inherit the parent font's implementation, if any.
  **/
 
 
@@ -1387,7 +1392,7 @@ hb_font_get_glyph_from_name (hb_font_t      *font,
 /**
  * hb_font_get_glyph_shape:
  * @font: #hb_font_t to work upon
- * @glyph: : The glyph ID
+ * @glyph: The glyph ID
  * @dfuncs: #hb_draw_funcs_t to draw to
  * @draw_data: User data to pass to draw callbacks
  *
@@ -1409,7 +1414,7 @@ hb_font_get_glyph_shape (hb_font_t *font,
 /**
  * hb_font_draw_glyph:
  * @font: #hb_font_t to work upon
- * @glyph: : The glyph ID
+ * @glyph: The glyph ID
  * @dfuncs: #hb_draw_funcs_t to draw to
  * @draw_data: User data to pass to draw callbacks
  *
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh
index b3457933c01d91663efd24dbfaf6210225dde679..fa5712f9b3363ee4da311d1865ac15bb4691141a 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh
@@ -301,8 +301,8 @@ _hb_ft_paint (hb_ft_paint_context_t *c,
       c->funcs->sweep_gradient (c->data, &cl,
 				paint.u.sweep_gradient.center.x / 65536.f,
 				paint.u.sweep_gradient.center.y / 65536.f,
-				(paint.u.sweep_gradient.start_angle / 65536.f + 1) * (float) M_PI,
-				(paint.u.sweep_gradient.end_angle / 65536.f + 1) * (float) M_PI);
+				(paint.u.sweep_gradient.start_angle / 65536.f + 1) * HB_PI,
+				(paint.u.sweep_gradient.end_angle / 65536.f + 1) * HB_PI);
     }
     break;
     case FT_COLR_PAINTFORMAT_GLYPH:
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
index 552b4066518f75d3c187eb37cf471f1d96e1e0ee..041b8829afbf3ef6009632973e404171f4908602 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
@@ -343,7 +343,8 @@ struct hb_hashmap_t
   )
   auto keys () const HB_AUTO_RETURN
   (
-    + keys_ref ()
+    + iter_items ()
+    | hb_map (&item_t::key)
     | hb_map (hb_ridentity)
   )
   auto values_ref () const HB_AUTO_RETURN
@@ -353,7 +354,8 @@ struct hb_hashmap_t
   )
   auto values () const HB_AUTO_RETURN
   (
-    + values_ref ()
+    + iter_items ()
+    | hb_map (&item_t::value)
     | hb_map (hb_ridentity)
   )
 
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh
index f5a03d2b00ebf4d41f5d055d7b0c62142c96d18b..cf5ccd53e954ec880e62e2fc6330e7c5585e4519 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh
@@ -404,7 +404,7 @@ struct CmapSubtableFormat4
 		 unsigned distance) const
 	{
 	  if (k > last) return +1;
-	  if (k < (&last)[distance]) return -1;
+	  if (k < (&last)[distance]/*first*/) return -1;
 	  return 0;
 	}
 	HBUINT16 last;
@@ -413,7 +413,7 @@ struct CmapSubtableFormat4
       const HBUINT16 *found = hb_bsearch (codepoint,
 					  this->endCount,
 					  this->segCount,
-					  2,
+					  sizeof (CustomRange),
 					  _hb_cmp_method<hb_codepoint_t, CustomRange, unsigned>,
 					  this->segCount + 1);
       if (unlikely (!found))
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
index 19ae02e28b620967949369a3523f9be95be3c0a7..06f7092a59d1bbe3cc60e5a2c9f4dba2b5a36823 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
@@ -413,7 +413,7 @@ hb_ot_get_glyph_extents (hb_font_t *font,
   if (ot_face->sbix->get_extents (font, glyph, extents)) return true;
   if (ot_face->CBDT->get_extents (font, glyph, extents)) return true;
 #endif
-#if !defined(HB_NO_COLOR)
+#if !defined(HB_NO_COLOR) && !defined(HB_NO_PAINT)
   if (ot_face->COLR->get_extents (font, glyph, extents)) return true;
 #endif
   if (ot_face->glyf->get_extents (font, glyph, extents)) return true;
@@ -633,20 +633,4 @@ hb_ot_font_set_funcs (hb_font_t *font)
 		     _hb_ot_font_destroy);
 }
 
-#ifndef HB_NO_VAR
-bool
-_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical,
-					     int *lsb)
-{
-  return font->face->table.glyf->get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb);
-}
-
-unsigned
-_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical)
-{
-  return font->face->table.glyf->get_advance_with_var_unscaled (font, glyph, is_vertical);
-}
-#endif
-
-
 #endif
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh
index a86cc3c31151cb6f213c4860cb372de17fb5f962..3bfd75502a48e99f4403fe708042b1de8e5cae01 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh
@@ -76,7 +76,7 @@ struct DeviceRecord
   HBUINT8			maxWidth;	/* Maximum width. */
   UnsizedArrayOf<HBUINT8>	widthsZ;	/* Array of widths (numGlyphs is from the 'maxp' table). */
   public:
-  DEFINE_SIZE_ARRAY (2, widthsZ);
+  DEFINE_SIZE_UNBOUNDED (2);
 };
 
 
@@ -87,14 +87,6 @@ struct hdmx
   unsigned int get_size () const
   { return min_size + numRecords * sizeDeviceRecord; }
 
-  const DeviceRecord& operator [] (unsigned int i) const
-  {
-    /* XXX Null(DeviceRecord) is NOT safe as it's num-glyphs lengthed.
-     * https://github.com/harfbuzz/harfbuzz/issues/1300 */
-    if (unlikely (i >= numRecords)) return Null (DeviceRecord);
-    return StructAtOffset<DeviceRecord> (&this->firstDeviceRecord, i * sizeDeviceRecord);
-  }
-
   template<typename Iterator,
 	   hb_requires (hb_is_iterator (Iterator))>
   bool serialize (hb_serialize_context_t *c, unsigned version, Iterator it)
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh
index 798e82da6ca2858d28a2bf49ae64a22d34ffa7e6..770cf52d1735e39ed9f8be78c5a32277fdaee089 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh
@@ -63,7 +63,25 @@ struct head
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    return_trace (serialize (c->serializer));
+    head *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (c->plan->normalized_coords)
+    {
+      if (unlikely (!c->serializer->check_assign (out->xMin, c->plan->head_maxp_info.xMin,
+                                                  HB_SERIALIZE_ERROR_INT_OVERFLOW)))
+        return_trace (false);
+      if (unlikely (!c->serializer->check_assign (out->xMax, c->plan->head_maxp_info.xMax,
+                                                  HB_SERIALIZE_ERROR_INT_OVERFLOW)))
+        return_trace (false);
+      if (unlikely (!c->serializer->check_assign (out->yMin, c->plan->head_maxp_info.yMin,
+                                                  HB_SERIALIZE_ERROR_INT_OVERFLOW)))
+        return_trace (false);
+      if (unlikely (!c->serializer->check_assign (out->yMax, c->plan->head_maxp_info.yMax,
+                                                  HB_SERIALIZE_ERROR_INT_OVERFLOW)))
+        return_trace (false);
+    }
+    return_trace (true);
   }
 
   enum mac_style_flag_t {
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh
index 16eb1eb912bcb1eb842c2cee5e17c6bdc01421f9..835a1a585e86ba3e20685a92f866f62a5c37a64c 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh
@@ -50,6 +50,9 @@ _glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t gly
 HB_INTERNAL unsigned
 _glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical);
 
+HB_INTERNAL bool
+_glyf_get_leading_bearing_without_var_unscaled (hb_face_t *face, hb_codepoint_t gid, bool is_vertical, int *lsb);
+
 
 namespace OT {
 
@@ -92,7 +95,7 @@ struct hmtxvmtx
 
     unsigned int length;
     H *table = (H *) hb_blob_get_data (dest_blob, &length);
-    table->numberOfLongMetrics = num_hmetrics;
+    c->serializer->check_assign (table->numberOfLongMetrics, num_hmetrics, HB_SERIALIZE_ERROR_INT_OVERFLOW);
 
 #ifndef HB_NO_VAR
     if (c->plan->normalized_coords)
@@ -165,12 +168,19 @@ struct hmtxvmtx
 	lm.sb = _.second;
 	if (unlikely (!c->embed<LongMetric> (&lm))) return;
       }
-      else
+      else if (idx < 0x10000u)
       {
 	FWORD *sb = c->allocate_size<FWORD> (FWORD::static_size);
 	if (unlikely (!sb)) return;
 	*sb = _.second;
       }
+      else
+      {
+        // TODO: This does not do tail optimization.
+	UFWORD *adv = c->allocate_size<UFWORD> (UFWORD::static_size);
+	if (unlikely (!adv)) return;
+	*adv = _.first;
+      }
       idx++;
     }
   }
@@ -189,7 +199,7 @@ struct hmtxvmtx
       /* Determine num_long_metrics to encode. */
       auto& plan = c->plan;
 
-      num_long_metrics = plan->num_output_glyphs ();
+      num_long_metrics = hb_min (plan->num_output_glyphs (), 0xFFFFu);
       unsigned int last_advance = get_new_gid_advance_unscaled (plan, mtx_map, num_long_metrics - 1, _mtx);
       while (num_long_metrics > 1 &&
 	     last_advance == get_new_gid_advance_unscaled (plan, mtx_map, num_long_metrics - 2, _mtx))
@@ -208,7 +218,8 @@ struct hmtxvmtx
 		  if (!c->plan->old_gid_for_new_gid (_, &old_gid))
 		    return hb_pair (0u, 0);
 		  int lsb = 0;
-		  (void) _mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb);
+		  if (!_mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb))
+		    (void) _glyf_get_leading_bearing_without_var_unscaled (c->plan->source, old_gid, !T::is_horizontal, &lsb);
 		  return hb_pair (_mtx.get_advance_without_var_unscaled (old_gid), +lsb);
 		}
 		return mtx_map->get (_);
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh
index b53f2e92762a7abc6e96a3dc9561f4dc99392a07..52b7dc254bbc530c9fc53dc306b5e4edc0fb6474 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh
@@ -529,6 +529,9 @@ struct FeatureParamsSize
       return_trace (true);
   }
 
+  void collect_name_ids (hb_set_t *nameids_to_retain /* OUT */) const
+  { nameids_to_retain->add (subfamilyNameID); }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
@@ -585,6 +588,9 @@ struct FeatureParamsStylisticSet
     return_trace (c->check_struct (this));
   }
 
+  void collect_name_ids (hb_set_t *nameids_to_retain /* OUT */) const
+  { nameids_to_retain->add (uiNameID); }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
@@ -632,6 +638,20 @@ struct FeatureParamsCharacterVariants
   unsigned get_size () const
   { return min_size + characters.len * HBUINT24::static_size; }
 
+  void collect_name_ids (hb_set_t *nameids_to_retain /* OUT */) const
+  {
+    if (featUILableNameID) nameids_to_retain->add (featUILableNameID);
+    if (featUITooltipTextNameID) nameids_to_retain->add (featUITooltipTextNameID);
+    if (sampleTextNameID) nameids_to_retain->add (sampleTextNameID);
+
+    if (!firstParamUILabelNameID || !numNamedParameters || numNamedParameters >= 0x7FFF)
+      return;
+
+    unsigned last_name_id = (unsigned) firstParamUILabelNameID + (unsigned) numNamedParameters - 1;
+    if (last_name_id >= 256 && last_name_id <= 32767)
+      nameids_to_retain->add_range (firstParamUILabelNameID, last_name_id);
+  }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
@@ -694,6 +714,19 @@ struct FeatureParams
     return_trace (true);
   }
 
+  void collect_name_ids (hb_tag_t tag, hb_set_t *nameids_to_retain /* OUT */) const
+  {
+#ifdef HB_NO_LAYOUT_FEATURE_PARAMS
+    return;
+#endif
+    if (tag == HB_TAG ('s','i','z','e'))
+      return (u.size.collect_name_ids (nameids_to_retain));
+    if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
+      return (u.stylisticSet.collect_name_ids (nameids_to_retain));
+    if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
+      return (u.characterVariants.collect_name_ids (nameids_to_retain));
+  }
+
   bool subset (hb_subset_context_t *c, const Tag* tag) const
   {
     TRACE_SUBSET (this);
@@ -762,6 +795,12 @@ struct Feature
   bool intersects_lookup_indexes (const hb_map_t *lookup_indexes) const
   { return lookupIndex.intersects (lookup_indexes); }
 
+  void collect_name_ids (hb_tag_t tag, hb_set_t *nameids_to_retain /* OUT */) const
+  {
+    if (featureParams)
+      get_feature_params ().collect_name_ids (tag, nameids_to_retain);
+  }
+
   bool subset (hb_subset_context_t         *c,
 	       hb_subset_layout_context_t  *l,
 	       const Tag                   *tag = nullptr) const
@@ -2233,19 +2272,20 @@ struct VarRegionAxis
 {
   float evaluate (int coord) const
   {
-    int start = startCoord.to_int (), peak = peakCoord.to_int (), end = endCoord.to_int ();
+    int peak = peakCoord.to_int ();
+    if (peak == 0 || coord == peak)
+      return 1.f;
+
+    int start = startCoord.to_int (), end = endCoord.to_int ();
 
     /* TODO Move these to sanitize(). */
     if (unlikely (start > peak || peak > end))
-      return 1.;
+      return 1.f;
     if (unlikely (start < 0 && end > 0 && peak != 0))
-      return 1.;
-
-    if (peak == 0 || coord == peak)
-      return 1.;
+      return 1.f;
 
     if (coord <= start || end <= coord)
-      return 0.;
+      return 0.f;
 
     /* Interpolate */
     if (coord < peak)
@@ -2462,10 +2502,9 @@ struct VarData
     {
       for (r = 0; r < src_word_count; r++)
       {
-	for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
+        for (unsigned old_gid : inner_map.keys())
 	{
-	  unsigned int old = inner_map.backward (i);
-	  int32_t delta = src->get_item_delta_fast (old, r, src_delta_bytes, src_row_size);
+	  int32_t delta = src->get_item_delta_fast (old_gid, r, src_delta_bytes, src_row_size);
 	  if (delta < -65536 || 65535 < delta)
 	  {
 	    has_long = true;
@@ -2482,10 +2521,9 @@ struct VarData
       bool short_circuit = src_long_words == has_long && src_word_count <= r;
 
       delta_sz[r] = kZero;
-      for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
+      for (unsigned old_gid : inner_map.keys())
       {
-	unsigned int old = inner_map.backward (i);
-	int32_t delta = src->get_item_delta_fast (old, r, src_delta_bytes, src_row_size);
+	int32_t delta = src->get_item_delta_fast (old_gid, r, src_delta_bytes, src_row_size);
 	if (delta < min_threshold || max_threshold < delta)
 	{
 	  delta_sz[r] = kWord;
@@ -2546,8 +2584,8 @@ struct VarData
     {
       unsigned int region = regionIndices.arrayZ[r];
       if (region_indices.has (region)) continue;
-      for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
-	if (get_item_delta_fast (inner_map.backward (i), r, delta_bytes, row_size) != 0)
+      for (hb_codepoint_t old_gid : inner_map.keys())
+	if (get_item_delta_fast (old_gid, r, delta_bytes, row_size) != 0)
 	{
 	  region_indices.add (region);
 	  break;
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
index 10cc105de4967f0605e6e553ae2201bdb9dd8b1f..e1b66a199a3a7a2b75a582f6eec24de8cc972a17 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
@@ -487,7 +487,8 @@ struct hb_ot_apply_context_t :
       /* Ignore ZWJ if we are matching context, or asked to. */
       matcher.set_ignore_zwj  (context_match || c->auto_zwj);
       matcher.set_mask (context_match ? -1 : c->lookup_mask);
-      matcher.set_per_syllable (c->per_syllable);
+      /* Per syllable matching is only for GSUB. */
+      matcher.set_per_syllable (c->table_index == 0 && c->per_syllable);
     }
     void set_lookup_props (unsigned int lookup_props)
     {
@@ -4461,6 +4462,18 @@ struct GSUBGPOS
     }
   }
 
+  void collect_name_ids (const hb_map_t *feature_index_map,
+                         hb_set_t *nameids_to_retain /* OUT */) const
+  {
+    unsigned count = get_feature_count ();
+    for (unsigned i = 0 ; i < count; i++)
+    {
+      if (!feature_index_map->has (i)) continue;
+      hb_tag_t tag = get_feature_tag (i);
+      get_feature (i).collect_name_ids (tag, nameids_to_retain);
+    }
+  }
+
   template <typename T>
   struct accelerator_t
   {
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc
index 6c4055e0461b96fc1a40c33c7dbd95fe6b0f0f81..256a055863b3911ff8f72dd2a019575bc0a4d0af 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc
@@ -64,6 +64,8 @@ using OT::Layout::GPOS;
  * @include: hb-ot.h
  *
  * Functions for querying OpenType Layout features in the font face.
+ * See the <ulink url="http://www.microsoft.com/typography/otspec/">OpenType
+ * specification</ulink> for details.
  **/
 
 
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh
index 05cbf2cedfeda8772524ac9a733be119781acbdf..0f4cc414ef87e89374e492231e0a87b5e219331a 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh
@@ -100,7 +100,7 @@ struct maxp
     maxp *maxp_prime = c->serializer->embed (this);
     if (unlikely (!maxp_prime)) return_trace (false);
 
-    maxp_prime->numGlyphs = c->plan->num_output_glyphs ();
+    maxp_prime->numGlyphs = hb_min (c->plan->num_output_glyphs (), 0xFFFFu);
     if (maxp_prime->version.major == 1)
     {
       const maxpV1Tail *src_v1 = &StructAfter<maxpV1Tail> (*this);
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc
index 0323364aefed9eec350eba94975aee4431068416..6adf1e8fbea5a38651625fcebf622eb339bace41 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc
@@ -181,6 +181,4 @@ hb_ot_name_get_utf32 (hb_face_t       *face,
   return hb_ot_name_get_utf<hb_utf32_t> (face, name_id, language, text_size, text);
 }
 
-#include "hb-ot-name-language-static.hh"
-
 #endif
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc
index e3818cc37fbe8a7e1e2c6dff527b881e343cf7eb..f8c970fc3eb5e3c26f69a834181cffc37b8935aa 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc
@@ -1067,12 +1067,15 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
 	      base = i;
 	      while (base < end && is_halant (info[base]))
 		base++;
-	      info[base].indic_position() = POS_BASE_C;
+	      if (base < end)
+		info[base].indic_position() = POS_BASE_C;
 
 	      try_pref = false;
 	    }
 	    break;
 	  }
+	if (base == end)
+	  break;
       }
       /* For Malayalam, skip over unformed below- (but NOT post-) forms. */
       if (buffer->props.script == HB_SCRIPT_MALAYALAM)
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh
index 2006f677d1a6297399be290e16f229ffef856e7d..de553dd72ff0a4412a29051890425198482d928b 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh
@@ -536,6 +536,8 @@ struct STAT
     | hb_map (&AxisValue::get_value_name_id)
     | hb_sink (nameids_to_retain)
     ;
+
+    nameids_to_retain->add (elidedFallbackNameID);
   }
 
   bool subset (hb_subset_context_t *c) const
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh
index cdc6a274ce1100f467f480c684d01152114a2e05..853fe3839bd0a8360f024a01f7637914e8cdbf3e 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh
@@ -222,18 +222,20 @@ struct DeltaSetIndexMap
 
 struct VarStoreInstancer
 {
-  VarStoreInstancer (const VariationStore &varStore,
-		     const DeltaSetIndexMap &varIdxMap,
+  VarStoreInstancer (const VariationStore *varStore,
+		     const DeltaSetIndexMap *varIdxMap,
 		     hb_array_t<int> coords) :
     varStore (varStore), varIdxMap (varIdxMap), coords (coords) {}
 
-  operator bool () const { return bool (coords); }
+  operator bool () const { return varStore && bool (coords); }
 
+  /* according to the spec, if colr table has varStore but does not have
+   * varIdxMap, then an implicit identity mapping is used */
   float operator() (uint32_t varIdx, unsigned short offset = 0) const
-  { return varStore.get_delta (varIdxMap.map (VarIdx::add (varIdx, offset)), coords); }
+  { return varStore->get_delta (varIdxMap ? varIdxMap->map (VarIdx::add (varIdx, offset)) : varIdx + offset, coords); }
 
-  const VariationStore &varStore;
-  const DeltaSetIndexMap &varIdxMap;
+  const VariationStore *varStore;
+  const DeltaSetIndexMap *varIdxMap;
   hb_array_t<int> coords;
 };
 
@@ -249,36 +251,54 @@ struct TupleVariationHeader
   { return StructAtOffset<TupleVariationHeader> (this, get_size (axis_count)); }
 
   float calculate_scalar (hb_array_t<int> coords, unsigned int coord_count,
-                          const hb_array_t<const F2DOT14> shared_tuples) const
+                          const hb_array_t<const F2DOT14> shared_tuples,
+			  const hb_vector_t<int> *shared_tuple_active_idx = nullptr) const
   {
-    hb_array_t<const F2DOT14> peak_tuple;
+    const F2DOT14 *peak_tuple;
+
+    unsigned start_idx = 0;
+    unsigned end_idx = coord_count;
 
     if (has_peak ())
-      peak_tuple = get_peak_tuple (coord_count);
+      peak_tuple = get_peak_tuple (coord_count).arrayZ;
     else
     {
       unsigned int index = get_index ();
-      if (unlikely (index * coord_count >= shared_tuples.length))
+      if (unlikely ((index + 1) * coord_count > shared_tuples.length))
         return 0.f;
-      peak_tuple = shared_tuples.sub_array (coord_count * index, coord_count);
+      peak_tuple = shared_tuples.sub_array (coord_count * index, coord_count).arrayZ;
+
+      if (shared_tuple_active_idx)
+      {
+        assert (index < shared_tuple_active_idx->length);
+	int v = (*shared_tuple_active_idx).arrayZ[index];
+	if (v != -1)
+	{
+	  start_idx = v;
+	  end_idx = start_idx + 1;
+	}
+      }
     }
 
-    hb_array_t<const F2DOT14> start_tuple;
-    hb_array_t<const F2DOT14> end_tuple;
-    if (has_intermediate ())
+    const F2DOT14 *start_tuple = nullptr;
+    const F2DOT14 *end_tuple = nullptr;
+    bool has_interm = has_intermediate ();
+    if (has_interm)
     {
-      start_tuple = get_start_tuple (coord_count);
-      end_tuple = get_end_tuple (coord_count);
+      start_tuple = get_start_tuple (coord_count).arrayZ;
+      end_tuple = get_end_tuple (coord_count).arrayZ;
     }
 
     float scalar = 1.f;
-    for (unsigned int i = 0; i < coord_count; i++)
+    for (unsigned int i = start_idx; i < end_idx; i++)
     {
-      int v = coords[i];
       int peak = peak_tuple[i].to_int ();
-      if (!peak || v == peak) continue;
+      if (!peak) continue;
 
-      if (has_intermediate ())
+      int v = coords[i];
+      if (v == peak) continue;
+
+      if (has_interm)
       {
         int start = start_tuple[i].to_int ();
         int end = end_tuple[i].to_int ();
@@ -358,9 +378,12 @@ struct TupleVariationData
   {
     unsigned total_size = min_size;
     unsigned count = tupleVarCount;
-    const TupleVariationHeader& tuple_var_header = get_tuple_var_header();
+    const TupleVariationHeader *tuple_var_header = &(get_tuple_var_header());
     for (unsigned i = 0; i < count; i++)
-      total_size += tuple_var_header.get_size (axis_count) + tuple_var_header.get_data_size ();
+    {
+      total_size += tuple_var_header->get_size (axis_count) + tuple_var_header->get_data_size ();
+      tuple_var_header = &tuple_var_header->get_next (axis_count);
+    }
 
     return total_size;
   }
@@ -464,12 +487,12 @@ struct TupleVariationData
       if (unlikely (p + 1 > end)) return false;
       unsigned control = *p++;
       unsigned run_count = (control & POINT_RUN_COUNT_MASK) + 1;
-      if (unlikely (i + run_count > count)) return false;
-      unsigned j;
+      unsigned stop = i + run_count;
+      if (unlikely (stop > count)) return false;
       if (control & POINTS_ARE_WORDS)
       {
         if (unlikely (p + run_count * HBUINT16::static_size > end)) return false;
-        for (j = 0; j < run_count; j++, i++)
+        for (; i < stop; i++)
         {
           n += *(const HBUINT16 *)p;
           points.arrayZ[i] = n;
@@ -479,7 +502,7 @@ struct TupleVariationData
       else
       {
         if (unlikely (p + run_count > end)) return false;
-        for (j = 0; j < run_count; j++, i++)
+        for (; i < stop; i++)
         {
           n += *p++;
           points.arrayZ[i] = n;
@@ -507,17 +530,17 @@ struct TupleVariationData
       if (unlikely (p + 1 > end)) return false;
       unsigned control = *p++;
       unsigned run_count = (control & DELTA_RUN_COUNT_MASK) + 1;
-      if (unlikely (i + run_count > count)) return false;
-      unsigned j;
+      unsigned stop = i + run_count;
+      if (unlikely (stop > count)) return false;
       if (control & DELTAS_ARE_ZERO)
       {
-        for (j = 0; j < run_count; j++, i++)
+        for (; i < stop; i++)
           deltas.arrayZ[i] = 0;
       }
       else if (control & DELTAS_ARE_WORDS)
       {
         if (unlikely (p + run_count * HBUINT16::static_size > end)) return false;
-        for (j = 0; j < run_count; j++, i++)
+        for (; i < stop; i++)
         {
           deltas.arrayZ[i] = * (const HBINT16 *) p;
           p += HBUINT16::static_size;
@@ -526,7 +549,7 @@ struct TupleVariationData
       else
       {
         if (unlikely (p + run_count > end)) return false;
-        for (j = 0; j < run_count; j++, i++)
+        for (; i < stop; i++)
         {
           deltas.arrayZ[i] = * (const HBINT8 *) p++;
         }
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh
index d707a463338b46e73f854e9add305264926652b6..4752a08fbe03090b895ac1c71d7ebba6c0a97e8d 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh
@@ -104,8 +104,8 @@ struct gvar
     return_trace (c->check_struct (this) && (version.major == 1) &&
 		  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)));
+		     c->check_array (get_long_offset_array (), c->get_num_glyphs () + 1) :
+		     c->check_array (get_short_offset_array (), c->get_num_glyphs () + 1)));
   }
 
   /* GlyphVariationData not sanitized here; must be checked while accessing each glyph variation data */
@@ -116,6 +116,8 @@ struct gvar
   {
     TRACE_SUBSET (this);
 
+    unsigned glyph_count = version.to_int () ? c->plan->source->get_num_glyphs () : 0;
+
     gvar *out = c->serializer->allocate_min<gvar> ();
     if (unlikely (!out)) return_trace (false);
 
@@ -125,7 +127,7 @@ struct gvar
     out->sharedTupleCount = sharedTupleCount;
 
     unsigned int num_glyphs = c->plan->num_output_glyphs ();
-    out->glyphCount = num_glyphs;
+    out->glyphCountX = hb_min (0xFFFFu, num_glyphs);
 
     unsigned int subset_data_size = 0;
     for (hb_codepoint_t gid = (c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE) ? 0 : 1;
@@ -134,7 +136,7 @@ struct gvar
     {
       hb_codepoint_t old_gid;
       if (!c->plan->old_gid_for_new_gid (gid, &old_gid)) continue;
-      subset_data_size += get_glyph_var_data_bytes (c->source_blob, old_gid).length;
+      subset_data_size += get_glyph_var_data_bytes (c->source_blob, glyph_count, old_gid).length;
     }
 
     bool long_offset = subset_data_size & ~0xFFFFu;
@@ -166,7 +168,9 @@ struct gvar
     {
       hb_codepoint_t old_gid;
       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)
+				? get_glyph_var_data_bytes (c->source_blob,
+							    glyph_count,
+							    old_gid)
 				: hb_bytes_t ();
 
       if (long_offset)
@@ -188,10 +192,12 @@ struct gvar
   }
 
   protected:
-  const hb_bytes_t get_glyph_var_data_bytes (hb_blob_t *blob, hb_codepoint_t glyph) const
+  const hb_bytes_t get_glyph_var_data_bytes (hb_blob_t *blob,
+					     unsigned glyph_count,
+					     hb_codepoint_t glyph) const
   {
-    unsigned start_offset = get_offset (glyph);
-    unsigned end_offset = get_offset (glyph+1);
+    unsigned start_offset = get_offset (glyph_count, glyph);
+    unsigned end_offset = get_offset (glyph_count, glyph+1);
     if (unlikely (end_offset < start_offset)) return hb_bytes_t ();
     unsigned length = end_offset - start_offset;
     hb_bytes_t var_data = blob->as_bytes ().sub_array (((unsigned) dataZ) + start_offset, length);
@@ -200,9 +206,9 @@ struct gvar
 
   bool is_long_offset () const { return flags & 1; }
 
-  unsigned get_offset (unsigned i) const
+  unsigned get_offset (unsigned glyph_count, unsigned i) const
   {
-    if (unlikely (i > glyphCount)) return 0;
+    if (unlikely (i > glyph_count)) return 0;
     _hb_compiler_memory_r_barrier ();
     return is_long_offset () ? get_long_offset_array ()[i] : get_short_offset_array ()[i] * 2;
   }
@@ -214,7 +220,38 @@ struct gvar
   struct accelerator_t
   {
     accelerator_t (hb_face_t *face)
-    { table = hb_sanitize_context_t ().reference_table<gvar> (face); }
+    {
+      table = hb_sanitize_context_t ().reference_table<gvar> (face);
+      /* If sanitize failed, set glyphCount to 0. */
+      glyphCount = table->version.to_int () ? face->get_num_glyphs () : 0;
+
+      /* For shared tuples that only have one axis active, shared the index of
+       * that axis as a cache. This will speed up caclulate_scalar() a lot
+       * for fonts with lots of axes and many "monovar" tuples. */
+      hb_array_t<const F2DOT14> shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount);
+      unsigned count = table->sharedTupleCount;
+      if (unlikely (!shared_tuple_active_idx.resize (count, false))) return;
+      unsigned axis_count = table->axisCount;
+      for (unsigned i = 0; i < count; i++)
+      {
+	hb_array_t<const F2DOT14> tuple = shared_tuples.sub_array (axis_count * i, axis_count);
+	int idx = -1;
+	for (unsigned j = 0; j < axis_count; j++)
+	{
+	  F2DOT14 peak = tuple.arrayZ[j];
+	  if (peak.to_int () != 0)
+	  {
+	    if (idx != -1)
+	    {
+	      idx = -1;
+	      break;
+	    }
+	    idx = j;
+	  }
+	}
+	shared_tuple_active_idx[i] = idx;
+      }
+    }
     ~accelerator_t () { table.destroy (); }
 
     private:
@@ -252,9 +289,9 @@ struct gvar
     {
       if (!coords) return true;
 
-      if (unlikely (glyph >= table->glyphCount)) return true;
+      if (unlikely (glyph >= glyphCount)) return true;
 
-      hb_bytes_t var_data_bytes = table->get_glyph_var_data_bytes (table.get_blob (), glyph);
+      hb_bytes_t var_data_bytes = table->get_glyph_var_data_bytes (table.get_blob (), glyphCount, glyph);
       if (!var_data_bytes.as<GlyphVariationData> ()->has_data ()) return true;
       hb_vector_t<unsigned int> shared_indices;
       GlyphVariationData::tuple_iterator_t iterator;
@@ -264,19 +301,14 @@ struct gvar
 	return true; /* so isn't applied at all */
 
       /* Save original points for inferred delta calculation */
-      contour_point_vector_t orig_points_vec;
-      orig_points_vec.extend (points);
-      if (unlikely (orig_points_vec.in_error ())) return false;
+      contour_point_vector_t orig_points_vec; // Populated lazily
       auto orig_points = orig_points_vec.as_array ();
 
-      contour_point_vector_t deltas_vec; /* flag is used to indicate referenced point */
-      if (unlikely (!deltas_vec.resize (points.length, false))) return false;
+      /* flag is used to indicate referenced point */
+      contour_point_vector_t deltas_vec; // Populated lazily
       auto deltas = deltas_vec.as_array ();
 
-      hb_vector_t<unsigned> end_points;
-      for (unsigned i = 0; i < points.length; ++i)
-	if (points.arrayZ[i].is_end_point)
-	  end_points.push (i);
+      hb_vector_t<unsigned> end_points; // Populated lazily
 
       unsigned num_coords = table->axisCount;
       hb_array_t<const F2DOT14> shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount);
@@ -284,15 +316,23 @@ struct gvar
       hb_vector_t<unsigned int> private_indices;
       hb_vector_t<int> x_deltas;
       hb_vector_t<int> y_deltas;
+      bool flush = false;
       do
       {
-	float scalar = iterator.current_tuple->calculate_scalar (coords, num_coords, shared_tuples);
+	float scalar = iterator.current_tuple->calculate_scalar (coords, num_coords, shared_tuples,
+								 shared_tuple_active_idx.in_error () ? nullptr : &shared_tuple_active_idx);
 	if (scalar == 0.f) continue;
 	const HBUINT8 *p = iterator.get_serialized_data ();
 	unsigned int length = iterator.current_tuple->get_data_size ();
 	if (unlikely (!iterator.var_data_bytes.check_range (p, length)))
 	  return false;
 
+	if (!deltas)
+	{
+	  if (unlikely (!deltas_vec.resize (points.length))) return false;
+	  deltas = deltas_vec.as_array ();
+	}
+
 	const HBUINT8 *end = p + length;
 
 	bool has_private_points = iterator.current_tuple->has_private_points ();
@@ -308,16 +348,37 @@ struct gvar
 	if (unlikely (!y_deltas.resize (num_deltas, false))) return false;
 	if (unlikely (!GlyphVariationData::unpack_deltas (p, y_deltas, end))) return false;
 
-	hb_memset (deltas.arrayZ, 0, deltas.get_size ());
+	if (!apply_to_all)
+	{
+	  if (!orig_points)
+	  {
+	    orig_points_vec.extend (points);
+	    if (unlikely (orig_points_vec.in_error ())) return false;
+	    orig_points = orig_points_vec.as_array ();
+	  }
+
+	  if (flush)
+	  {
+	    for (unsigned int i = 0; i < points.length; i++)
+	      points.arrayZ[i].translate (deltas.arrayZ[i]);
+	    flush = false;
+
+	  }
+	  hb_memset (deltas.arrayZ, 0, deltas.get_size ());
+	}
 
-	unsigned ref_points = 0;
 	if (scalar != 1.0f)
 	  for (unsigned int i = 0; i < num_deltas; i++)
 	  {
-	    unsigned int pt_index = apply_to_all ? i : indices[i];
-	    if (unlikely (pt_index >= deltas.length)) continue;
+	    unsigned int pt_index;
+	    if (apply_to_all)
+	      pt_index = i;
+	    else
+	    {
+	      pt_index = indices[i];
+	      if (unlikely (pt_index >= deltas.length)) continue;
+	    }
 	    auto &delta = deltas.arrayZ[pt_index];
-	    ref_points += !delta.flag;
 	    delta.flag = 1;	/* this point is referenced, i.e., explicit deltas specified */
 	    delta.x += x_deltas.arrayZ[i] * scalar;
 	    delta.y += y_deltas.arrayZ[i] * scalar;
@@ -325,23 +386,34 @@ struct gvar
 	else
 	  for (unsigned int i = 0; i < num_deltas; i++)
 	  {
-	    unsigned int pt_index = apply_to_all ? i : indices[i];
-	    if (unlikely (pt_index >= deltas.length)) continue;
+	    unsigned int pt_index;
+	    if (apply_to_all)
+	      pt_index = i;
+	    else
+	    {
+	      pt_index = indices[i];
+	      if (unlikely (pt_index >= deltas.length)) continue;
+	    }
 	    auto &delta = deltas.arrayZ[pt_index];
-	    ref_points += !delta.flag;
 	    delta.flag = 1;	/* this point is referenced, i.e., explicit deltas specified */
 	    delta.x += x_deltas.arrayZ[i];
 	    delta.y += y_deltas.arrayZ[i];
 	  }
 
 	/* infer deltas for unreferenced points */
-	if (ref_points && ref_points < orig_points.length)
+	if (!apply_to_all)
 	{
-	  unsigned start_point = 0;
-	  for (unsigned c = 0; c < end_points.length; c++)
+	  if (!end_points)
 	  {
-	    unsigned end_point = end_points.arrayZ[c];
+	    for (unsigned i = 0; i < points.length; ++i)
+	      if (points.arrayZ[i].is_end_point)
+		end_points.push (i);
+	    if (unlikely (end_points.in_error ())) return false;
+	  }
 
+	  unsigned start_point = 0;
+	  for (unsigned end_point : end_points)
+	  {
 	    /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */
 	    unsigned unref_count = 0;
 	    for (unsigned i = start_point; i < end_point + 1; i++)
@@ -388,14 +460,14 @@ struct gvar
 	  }
 	}
 
-	/* apply specified / inferred deltas to points */
-	for (unsigned int i = 0; i < points.length; i++)
-	{
-	  points.arrayZ[i].x += deltas.arrayZ[i].x;
-	  points.arrayZ[i].y += deltas.arrayZ[i].y;
-	}
+	flush = true;
+
       } while (iterator.move_to_next ());
 
+      if (flush)
+	for (unsigned int i = 0; i < points.length; i++)
+	  points.arrayZ[i].translate (deltas.arrayZ[i]);
+
       return true;
     }
 
@@ -403,6 +475,8 @@ struct gvar
 
     private:
     hb_blob_ptr_t<gvar> table;
+    unsigned glyphCount;
+    hb_vector_t<signed> shared_tuple_active_idx;
   };
 
   protected:
@@ -418,7 +492,7 @@ struct gvar
   NNOffset32To<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
+  HBUINT16	glyphCountX;	/* 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
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh
index 53355c50779105333a38f07f33c96a99c52b7ddb..461b2b9cdbcf4780e74262dd30e369ddb67c9635 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh
@@ -185,12 +185,8 @@ struct hvarvvar_subset_plan_t
     {
       retain_adv_map = plan->flags & HB_SUBSET_FLAGS_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);
-      }
+      for (hb_codepoint_t old_gid : plan->glyphset()->iter())
+        inner_sets[0]->add (old_gid);
       hb_set_union (adv_set, inner_sets[0]);
     }
 
@@ -202,10 +198,12 @@ struct hvarvvar_subset_plan_t
     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
     {
@@ -265,6 +263,9 @@ struct HVARVVAR
 		  rsbMap.sanitize (c, this));
   }
 
+  const VariationStore& get_var_store () const
+  { return this+varStore; }
+
   void listup_index_maps (hb_vector_t<const DeltaSetIndexMap *> &index_maps) const
   {
     index_maps.push (&(this+advMap));
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-outline.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-outline.cc
index 0657e0e1d3dfcd1fb906f2400ad6f410929dbe11..29b1f530d5a4c6dd8dd002a9e3076c2eb010480c 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-outline.cc
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-outline.cc
@@ -4,7 +4,6 @@
  * Copyright © 2005  Werner Lemberg
  * Copyright © 2013-2015  Alexei Podtelezhnikov
  *
- *
  *  This is part of HarfBuzz, a text shaping library.
  *
  * Permission is hereby granted, without written agreement and without
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.h b/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.h
index a734f112cc7e6099316081623876233124b3ab7d..543382780d117697320d39e2d88f6366a0148a68 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.h
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.h
@@ -616,7 +616,7 @@ typedef enum {
   HB_PAINT_COMPOSITE_MODE_HSL_HUE,
   HB_PAINT_COMPOSITE_MODE_HSL_SATURATION,
   HB_PAINT_COMPOSITE_MODE_HSL_COLOR,
-  HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY,
+  HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY
 } hb_paint_composite_mode_t;
 
 /**
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.hh
index f7b71aa19b06dcbe059c35b5ef26564a640ff4a1..d291a4b973121f8f22a59de682c43518a817fd08 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.hh
@@ -203,8 +203,8 @@ struct hb_paint_funcs_t
     if (!a)
       return false;
 
-    float cc = cosf (a * (float) M_PI);
-    float ss = sinf (a * (float) M_PI);
+    float cc = cosf (a * HB_PI);
+    float ss = sinf (a * HB_PI);
     push_transform (paint_data, cc, ss, -ss, cc, 0.f, 0.f);
     return true;
   }
@@ -216,8 +216,8 @@ struct hb_paint_funcs_t
     if (!sx && !sy)
       return false;
 
-    float x = tanf (-sx * (float) M_PI);
-    float y = tanf (+sy * (float) M_PI);
+    float x = tanf (-sx * HB_PI);
+    float y = tanf (+sy * HB_PI);
     push_transform (paint_data, 1.f, y, x, 1.f, 0.f, 0.f);
     return true;
   }
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh
index ee43721a384c162cc3b6c705731d7c24bedf509e..d6eb778f5dde567348dd8b531dfd9951406c9a3d 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh
@@ -29,7 +29,16 @@
 
 #include "hb.hh"
 
-/* Memory pool for persistent allocation of small objects. */
+/* Memory pool for persistent allocation of small objects.
+ *
+ * Some AI musings on this, not necessarily true:
+ *
+ * This is a very simple implementation, but it's good enough for our
+ * purposes.  It's not thread-safe.  It's not very fast.  It's not
+ * very memory efficient.  It's not very cache efficient.  It's not
+ * very anything efficient.  But it's simple and it works.  And it's
+ * good enough for our purposes.  If you need something more
+ * sophisticated, use a real allocator.  Or use a real language. */
 
 template <typename T, unsigned ChunkLen = 32>
 struct hb_pool_t
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh
index 93a7842eb0a2ac6220422879ef79bbf53835097d..bf1b282d3d8f6d58121ad45246e4c7b26f49f12a 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh
@@ -35,6 +35,12 @@
  *
  * Priority queue implemented as a binary heap. Supports extract minimum
  * and insert operations.
+ *
+ * The priority queue is implemented as a binary heap, which is a complete
+ * binary tree. The root of the tree is the minimum element. The heap
+ * property is that the priority of a node is less than or equal to the
+ * priority of its children. The heap is stored in an array, with the
+ * children of node i stored at indices 2i + 1 and 2i + 2.
  */
 struct hb_priority_queue_t
 {
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc
index 89d354fc012289d0896e38c566c55b735a4d0bf1..d9598fc7044a0f10de350f288e9ce33f4e65bd31 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc
@@ -271,9 +271,13 @@ hb_shape_justify (hb_font_t          *font,
 
   /* If default advance already matches target, nothing to do. Shape and return. */
   if (min_target_advance <= *advance && *advance <= max_target_advance)
+  {
+    *var_tag = HB_TAG_NONE;
+    *var_value = 0.0f;
     return hb_shape_full (font, buffer,
 			  features, num_features,
 			  shaper_list);
+  }
 
   hb_face_t *face = font->face;
 
@@ -297,6 +301,8 @@ hb_shape_justify (hb_font_t          *font,
   /* If no suitable variation axis found, can't justify.  Just shape and return. */
   if (!tag)
   {
+    *var_tag = HB_TAG_NONE;
+    *var_value = 0.0f;
     if (hb_shape_full (font, buffer,
 		       features, num_features,
 		       shaper_list))
@@ -331,7 +337,11 @@ hb_shape_justify (hb_font_t          *font,
    * Do this again, in case advance was just calculated.
    */
   if (min_target_advance <= *advance && *advance <= max_target_advance)
+  {
+    *var_tag = HB_TAG_NONE;
+    *var_value = 0.0f;
     return true;
+  }
 
   /* Prepare for running the solver. */
   double a, b, ya, yb;
@@ -355,6 +365,7 @@ hb_shape_justify (hb_font_t          *font,
      * there's nothing to solve for. Just return it. */
     if (yb <= (double) max_target_advance)
     {
+      *var_value = (float) b;
       *advance = (float) yb;
       return true;
     }
@@ -379,6 +390,7 @@ hb_shape_justify (hb_font_t          *font,
      * there's nothing to solve for. Just return it. */
     if (ya >= (double) min_target_advance)
     {
+      *var_value = (float) a;
       *advance = (float) ya;
       return true;
     }
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc
index 5f647c6ad9ba520bff086a89520abe9d6692c602..a1a2522edf9dd89d1d1b6accab6aab422869e83f 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc
@@ -36,9 +36,11 @@
 #include "OT/Color/COLR/COLR.hh"
 #include "hb-ot-glyf-table.hh"
 #include "hb-ot-head-table.hh"
+#include "hb-ot-hmtx-table.hh"
 #include "hb-ot-maxp-table.hh"
 
 #ifndef HB_NO_VISIBILITY
+#include "hb-ot-name-language-static.hh"
 
 uint64_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = {};
 /*thread_local*/ uint64_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = {};
@@ -108,4 +110,26 @@ hb_face_t::load_upem () const
 }
 
 
+#ifndef HB_NO_VAR
+bool
+_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical,
+					     int *lsb)
+{
+  return font->face->table.glyf->get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb);
+}
+
+unsigned
+_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical)
+{
+  return font->face->table.glyf->get_advance_with_var_unscaled (font, glyph, is_vertical);
+}
+#endif
+
+bool
+_glyf_get_leading_bearing_without_var_unscaled (hb_face_t *face, hb_codepoint_t gid, bool is_vertical, int *lsb)
+{
+  return face->table.glyf->get_leading_bearing_without_var_unscaled (gid, is_vertical, lsb);
+}
+
+
 #endif
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-style.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-style.cc
index c7d7d713c256f62633c33ce156056a2e764f51f5..bd5cb5c6be04618390b299d32f4da844fb566ba3 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-style.cc
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-style.cc
@@ -46,13 +46,13 @@
 static inline float
 _hb_angle_to_ratio (float a)
 {
-  return tanf (a * float (-M_PI / 180.));
+  return tanf (a * -HB_PI / 180.f);
 }
 
 static inline float
 _hb_ratio_to_angle (float r)
 {
-  return atanf (r) * float (-180. / M_PI);
+  return atanf (r) * -180.f / HB_PI;
 }
 
 /**
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-instancer-solver.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-instancer-solver.cc
index 5c0f43ad4b1f1085dfefa5796f013c54420178cc..7a2735c529e924aa33b1fa5b61c1fdf52c18e678 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-instancer-solver.cc
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-instancer-solver.cc
@@ -125,7 +125,7 @@ _solve (Triple tent, Triple axisLimit, bool negative = false)
       return result_t{};  // No overlap
 
   /* case 2: Only the peak and outermost bound fall outside the new limit;
-   * we keep the deltaset, update peak and outermost bound and and scale deltas
+   * we keep the deltaset, update peak and outermost bound and scale deltas
    * by the scalar value for the restricted axis at the new limit, and solve
    * recursively.
    *
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc
index 088fdca07b8e4cfb240456670cb87b3f38a2954b..aea886864d52f9540bc22d4fda54fc5bef821377 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc
@@ -36,8 +36,10 @@
 #include "hb-ot-layout-gpos-table.hh"
 #include "hb-ot-layout-gsub-table.hh"
 #include "hb-ot-cff1-table.hh"
+#include "hb-ot-cff2-table.hh"
 #include "OT/Color/COLR/COLR.hh"
 #include "OT/Color/COLR/colrv1-closure.hh"
+#include "OT/Color/CPAL/CPAL.hh"
 #include "hb-ot-var-fvar-table.hh"
 #include "hb-ot-var-avar-table.hh"
 #include "hb-ot-stat-table.hh"
@@ -293,7 +295,7 @@ _closure_glyphs_lookups_features (hb_subset_plan_t   *plan,
                               feature_record_cond_idx_map,
                               feature_substitutes_map);
 
-  if (table_tag == HB_OT_TAG_GSUB)
+  if (table_tag == HB_OT_TAG_GSUB && !(plan->flags & HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE))
     hb_ot_layout_lookups_substitute_closure (plan->source,
                                              &lookup_indices,
 					     gids_to_retain);
@@ -345,7 +347,10 @@ _get_hb_font_with_variations (const hb_subset_plan_t *plan)
   hb_font_t *font = hb_font_create (plan->source);
 
   hb_vector_t<hb_variation_t> vars;
-  vars.alloc (plan->user_axes_location.get_population ());
+  if (!vars.alloc (plan->user_axes_location.get_population ())) {
+    hb_font_destroy (font);
+    return nullptr;
+  }
 
   for (auto _ : plan->user_axes_location)
   {
@@ -381,7 +386,13 @@ _collect_layout_variation_indices (hb_subset_plan_t* plan)
   bool collect_delta = plan->pinned_at_default ? false : true;
   if (collect_delta)
   {
-    font = _get_hb_font_with_variations (plan);
+    if (unlikely (!plan->check_success (font = _get_hb_font_with_variations (plan)))) {
+      hb_font_destroy (font);
+      gdef.destroy ();
+      gpos.destroy ();
+      return;
+    }
+
     if (gdef->has_var_store ())
     {
       var_store = &(gdef->get_var_store ());
@@ -555,9 +566,12 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes,
 	if (plan->codepoint_to_glyph->has (cp))
 	  continue;
 
-	hb_codepoint_t gid = (*unicode_glyphid_map)[cp];
-	plan->codepoint_to_glyph->set (cp, gid);
-	plan->unicode_to_new_gid_list.push (hb_pair (cp, gid));
+        hb_codepoint_t *gid;
+        if (!unicode_glyphid_map->has(cp, &gid))
+          continue;
+
+	plan->codepoint_to_glyph->set (cp, *gid);
+	plan->unicode_to_new_gid_list.push (hb_pair (cp, *gid));
       }
       plan->unicode_to_new_gid_list.qsort ();
     }
@@ -609,7 +623,7 @@ _glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf,
 
   gids_to_retain->add (gid);
 
-  for (auto item : glyf.glyph_for_gid (gid).get_composite_iterator ())
+  for (auto &item : glyf.glyph_for_gid (gid).get_composite_iterator ())
     operation_count =
       _glyf_add_gid_and_children (glyf,
 				  item.get_gid (),
@@ -617,9 +631,53 @@ _glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf,
 				  operation_count,
 				  depth);
 
+#ifndef HB_NO_VAR_COMPOSITES
+  for (auto &item : glyf.glyph_for_gid (gid).get_var_composite_iterator ())
+   {
+    operation_count =
+      _glyf_add_gid_and_children (glyf,
+				  item.get_gid (),
+				  gids_to_retain,
+				  operation_count,
+				  depth);
+   }
+#endif
+
   return operation_count;
 }
 
+static void
+_nameid_closure (hb_subset_plan_t* plan,
+		 hb_set_t* drop_tables)
+{
+#ifndef HB_NO_STYLE
+  plan->source->table.STAT->collect_name_ids (&plan->user_axes_location, &plan->name_ids);
+#endif
+#ifndef HB_NO_VAR
+  if (!plan->all_axes_pinned)
+    plan->source->table.fvar->collect_name_ids (&plan->user_axes_location, &plan->name_ids);
+#endif
+#ifndef HB_NO_COLOR
+  if (!drop_tables->has (HB_OT_TAG_CPAL))
+    plan->source->table.CPAL->collect_name_ids (&plan->colr_palettes, &plan->name_ids);
+#endif
+
+#ifndef HB_NO_SUBSET_LAYOUT
+  if (!drop_tables->has (HB_OT_TAG_GPOS))
+  {
+    hb_blob_ptr_t<GPOS> gpos = plan->source_table<GPOS> ();
+    gpos->collect_name_ids (&plan->gpos_features, &plan->name_ids);
+    gpos.destroy ();
+  }
+  if (!drop_tables->has (HB_OT_TAG_GSUB))
+  {
+    hb_blob_ptr_t<GSUB> gsub = plan->source_table<GSUB> ();
+    gsub->collect_name_ids (&plan->gsub_features, &plan->name_ids);
+    gsub.destroy ();
+  }
+#endif
+}
+
 static void
 _populate_gids_to_retain (hb_subset_plan_t* plan,
 		          hb_set_t* drop_tables)
@@ -673,6 +731,7 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
 
   plan->_glyphset_colred = cur_glyphset;
 
+  _nameid_closure (plan, drop_tables);
   /* Populate a full set of glyphs to retain by adding all referenced
    * composite glyphs. */
   if (glyf.has_data ())
@@ -756,21 +815,6 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face,
   ;
 }
 
-static void
-_nameid_closure (hb_face_t *face,
-		 hb_set_t  *nameids,
-		 bool all_axes_pinned,
-		 hb_hashmap_t<hb_tag_t, float> *user_axes_location)
-{
-#ifndef HB_NO_STYLE
-  face->table.STAT->collect_name_ids (user_axes_location, nameids);
-#endif
-#ifndef HB_NO_VAR
-  if (!all_axes_pinned)
-    face->table.fvar->collect_name_ids (user_axes_location, nameids);
-#endif
-}
-
 #ifndef HB_NO_VAR
 static void
 _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan)
@@ -783,12 +827,15 @@ _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan)
 
   bool has_avar = face->table.avar->has_data ();
   const OT::SegmentMaps *seg_maps = nullptr;
+  unsigned avar_axis_count = 0;
   if (has_avar)
+  {
     seg_maps = face->table.avar->get_segment_maps ();
+    avar_axis_count = face->table.avar->get_axis_count();
+  }
 
   bool axis_not_pinned = false;
   unsigned old_axis_idx = 0, new_axis_idx = 0;
-  unsigned int i = 0;
   for (const auto& axis : axes)
   {
     hb_tag_t axis_tag = axis.get_axis_tag ();
@@ -803,7 +850,7 @@ _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan)
     else
     {
       int normalized_v = axis.normalize_axis_value (plan->user_axes_location.get (axis_tag));
-      if (has_avar && old_axis_idx < face->table.avar->get_axis_count ())
+      if (has_avar && old_axis_idx < avar_axis_count)
       {
         normalized_v = seg_maps->map (normalized_v);
       }
@@ -811,17 +858,99 @@ _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan)
       if (normalized_v != 0)
         plan->pinned_at_default = false;
 
-      plan->normalized_coords[i] = normalized_v;
+      plan->normalized_coords[old_axis_idx] = normalized_v;
     }
-    if (has_avar)
-      seg_maps = &StructAfter<OT::SegmentMaps> (*seg_maps);
 
     old_axis_idx++;
 
-    i++;
+    if (has_avar && old_axis_idx < avar_axis_count)
+      seg_maps = &StructAfter<OT::SegmentMaps> (*seg_maps);
   }
   plan->all_axes_pinned = !axis_not_pinned;
 }
+
+static void
+_update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan)
+{
+  if (!plan->normalized_coords) return;
+  OT::cff2::accelerator_t cff2 (plan->source);
+  if (!cff2.is_valid ()) return;
+
+  hb_font_t *font = nullptr;
+  if (unlikely (!plan->check_success (font = _get_hb_font_with_variations (plan))))
+  {
+    hb_font_destroy (font);
+    return;
+  }
+
+  hb_glyph_extents_t extents = {0x7FFF, -0x7FFF};
+  OT::hmtx_accelerator_t _hmtx (plan->source);
+  float *hvar_store_cache = nullptr;
+  if (_hmtx.has_data () && _hmtx.var_table.get_length ())
+    hvar_store_cache = _hmtx.var_table->get_var_store ().create_cache ();
+  
+  OT::vmtx_accelerator_t _vmtx (plan->source);
+  float *vvar_store_cache = nullptr;
+  if (_vmtx.has_data () && _vmtx.var_table.get_length ())
+    vvar_store_cache = _vmtx.var_table->get_var_store ().create_cache ();
+
+  for (auto p : *plan->glyph_map)
+  {
+    hb_codepoint_t old_gid = p.first;
+    hb_codepoint_t new_gid = p.second;
+    if (!cff2.get_extents (font, old_gid, &extents)) continue;
+    bool has_bounds_info = true;
+    if (extents.x_bearing == 0 && extents.width == 0 &&
+        extents.height == 0 && extents.y_bearing == 0)
+      has_bounds_info = false;
+
+    if (has_bounds_info)
+    {
+      plan->head_maxp_info.xMin = hb_min (plan->head_maxp_info.xMin, extents.x_bearing);
+      plan->head_maxp_info.xMax = hb_max (plan->head_maxp_info.xMax, extents.x_bearing + extents.width);
+      plan->head_maxp_info.yMax = hb_max (plan->head_maxp_info.yMax, extents.y_bearing);
+      plan->head_maxp_info.yMin = hb_min (plan->head_maxp_info.yMin, extents.y_bearing + extents.height);
+    }
+
+    if (_hmtx.has_data ())
+    {
+      int hori_aw = _hmtx.get_advance_without_var_unscaled (old_gid);
+      if (_hmtx.var_table.get_length ())
+        hori_aw += (int) roundf (_hmtx.var_table->get_advance_delta_unscaled (old_gid, font->coords, font->num_coords,
+                                                                              hvar_store_cache));
+      int lsb = extents.x_bearing;
+      if (!has_bounds_info)
+      {
+        if (!_hmtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb))
+          continue;
+      }
+      plan->hmtx_map.set (new_gid, hb_pair ((unsigned) hori_aw, lsb));
+      plan->bounds_width_map.set (new_gid, extents.width);
+    }
+
+    if (_vmtx.has_data ())
+    {
+      int vert_aw = _vmtx.get_advance_without_var_unscaled (old_gid);
+      if (_vmtx.var_table.get_length ())
+        vert_aw += (int) roundf (_vmtx.var_table->get_advance_delta_unscaled (old_gid, font->coords, font->num_coords,
+                                                                              vvar_store_cache));
+
+      int tsb = extents.y_bearing;
+      if (!has_bounds_info)
+      {
+        if (!_vmtx.get_leading_bearing_without_var_unscaled (old_gid, &tsb))
+          continue;
+      }
+      plan->vmtx_map.set (new_gid, hb_pair ((unsigned) vert_aw, tsb));
+      plan->bounds_height_map.set (new_gid, extents.height);
+    }
+  }
+  hb_font_destroy (font);
+  if (hvar_store_cache)
+    _hmtx.var_table->get_var_store ().destroy_cache (hvar_store_cache);
+  if (vvar_store_cache)
+    _vmtx.var_table->get_var_store ().destroy_cache (vvar_store_cache);
+}
 #endif
 
 hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face,
@@ -884,6 +1013,8 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face,
   _populate_unicodes_to_retain (input->sets.unicodes, input->sets.glyphs, this);
 
   _populate_gids_to_retain (this, input->sets.drop_tables);
+  if (unlikely (in_error ()))
+    return;
 
   _create_old_gid_to_new_gid_map (face,
                                   input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS,
@@ -905,10 +1036,13 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face,
         glyph_map->get(unicode_to_new_gid_list.arrayZ[i].second);
   }
 
-  _nameid_closure (face, &name_ids, all_axes_pinned, &user_axes_location);
   if (unlikely (in_error ()))
     return;
 
+#ifndef HB_NO_VAR
+  _update_instance_metrics_map_from_cff2 (this);
+#endif
+
   if (attach_accelerator_data)
   {
     hb_multimap_t gid_to_unicodes;
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh
index c0a85e12dc1e3808de9ff47071284268a11f6377..e34eeb89ae81d3b33f87f56d611081a757b41526 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh
@@ -211,7 +211,7 @@ struct hb_subset_plan_t
   template<typename T>
   hb_blob_ptr_t<T> source_table()
   {
-    hb_lock_t (accelerator ? &accelerator->sanitized_table_cache_lock : nullptr);
+    hb_lock_t lock (accelerator ? &accelerator->sanitized_table_cache_lock : nullptr);
 
     auto *cache = accelerator ? &accelerator->sanitized_table_cache : &sanitized_table_cache;
     if (cache
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
index e0b1ed644250292ea164ce762836d975fc71a8e7..5ea422983c544bdbaeb263e4c76464cd02db0651 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
@@ -637,8 +637,3 @@ hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan)
 end:
   return success ? hb_face_reference (plan->dest) : nullptr;
 }
-
-#ifndef HB_NO_VISIBILITY
-/* If NO_VISIBILITY, libharfbuzz has this. */
-#include "hb-ot-name-language-static.hh"
-#endif
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h
index c14b1b1803473cbb63432a4fea4e3e14fcd1db33..41d9587052a95e7c395daf19143c6ac8c0191ca9 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h
@@ -71,6 +71,8 @@ typedef struct hb_subset_plan_t hb_subset_plan_t;
  * in the final subset.
  * @HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES: If set then the unicode ranges in
  * OS/2 will not be recalculated.
+ * @HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE: If set don't perform glyph closure on layout
+ * substitution rules (GSUB). Since: 7.2.0.
  *
  * List of boolean properties that can be configured on the subset input.
  *
@@ -87,6 +89,7 @@ typedef enum { /*< flags >*/
   HB_SUBSET_FLAGS_NOTDEF_OUTLINE =	     0x00000040u,
   HB_SUBSET_FLAGS_GLYPH_NAMES =		     0x00000080u,
   HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES =  0x00000100u,
+  HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE =        0x00000200u,
 } hb_subset_flags_t;
 
 /**
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h b/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h
index faa8d67924eaba1a79e879c929cb66121ac308d0..5b5c45cae3212c68e92f73b7b697808286c74f24 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h
@@ -164,7 +164,7 @@ typedef enum
  * @HB_UNICODE_COMBINING_CLASS_CCC122: [Lao]
  * @HB_UNICODE_COMBINING_CLASS_CCC129: [Tibetan]
  * @HB_UNICODE_COMBINING_CLASS_CCC130: [Tibetan]
- * @HB_UNICODE_COMBINING_CLASS_CCC133: [Tibetan]
+ * @HB_UNICODE_COMBINING_CLASS_CCC132: [Tibetan] Since: 7.2.0
  * @HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT: Marks attached at the bottom left
  * @HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW: Marks attached directly below
  * @HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE: Marks attached directly above
@@ -246,7 +246,7 @@ typedef enum
   /* Tibetan */
   HB_UNICODE_COMBINING_CLASS_CCC129	= 129,
   HB_UNICODE_COMBINING_CLASS_CCC130	= 130,
-  HB_UNICODE_COMBINING_CLASS_CCC133	= 132,
+  HB_UNICODE_COMBINING_CLASS_CCC132	= 132,
 
 
   HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT	= 200,
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/hb.hh b/source/libs/harfbuzz/harfbuzz-src/src/hb.hh
index d09849e5653933fc7efa793505040e41301a73c7..30b3de499a1153d24d3d23c0f6dea1c5334b2310 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/hb.hh
+++ b/source/libs/harfbuzz/harfbuzz-src/src/hb.hh
@@ -509,6 +509,12 @@ static_assert ((sizeof (hb_mask_t) == 4), "");
 static_assert ((sizeof (hb_var_int_t) == 4), "");
 
 
+/* Pie time. */
+// https://github.com/harfbuzz/harfbuzz/issues/4166
+#define HB_PI 3.14159265358979f
+#define HB_2_PI (2.f * HB_PI)
+
+
 /* Headers we include for everyone.  Keep topologically sorted by dependency.
  * They express dependency amongst themselves, but no other file should include
  * them directly.*/
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/meson.build b/source/libs/harfbuzz/harfbuzz-src/src/meson.build
index 93991abd9f7d09fed31a49d5430447480b3e4f9a..30b99cf340a2f48231ed3b4a22295fc81d493186 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/meson.build
+++ b/source/libs/harfbuzz/harfbuzz-src/src/meson.build
@@ -668,6 +668,7 @@ if get_option('tests').enabled()
       '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-get-alternates': 'test-gsub-get-alternates.cc',
       'test-ot-gsub-would-substitute': 'test-gsub-would-substitute.cc',
       'test-use-table': 'test-use-table.cc',
     }
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/test-gsub-get-alternates.cc b/source/libs/harfbuzz/harfbuzz-src/src/test-gsub-get-alternates.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c9f3b4edb53786e82218382e36a4114272add16f
--- /dev/null
+++ b/source/libs/harfbuzz/harfbuzz-src/src/test-gsub-get-alternates.cc
@@ -0,0 +1,86 @@
+/*
+ * Copyright © 2010,2011  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include <hb.h>
+#include <hb-ot.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int
+main (int argc, char **argv)
+{
+  if (argc != 3) {
+    fprintf (stderr, "usage: %s font-file text\n", argv[0]);
+    exit (1);
+  }
+
+  /* Create the face */
+  hb_blob_t *blob = hb_blob_create_from_file_or_fail (argv[1]);
+  hb_face_t *face = hb_face_create (blob, 0 /* first face */);
+  hb_blob_destroy (blob);
+  blob = nullptr;
+
+  hb_font_t *font = hb_font_create (face);
+  hb_buffer_t *buffer = hb_buffer_create ();
+
+  hb_buffer_add_utf8 (buffer, argv[2], -1, 0, -1);
+  hb_buffer_guess_segment_properties (buffer);
+  hb_shape (font, buffer, NULL, 0);
+
+  hb_tag_t features[] = {HB_TAG('a','a','l','t'), HB_TAG_NONE};
+  hb_set_t *lookup_indexes = hb_set_create ();
+  hb_ot_layout_collect_lookups (face,
+				HB_OT_TAG_GSUB,
+				NULL, NULL,
+				features,
+				lookup_indexes);
+  printf ("lookups %u\n", hb_set_get_population (lookup_indexes));
+
+  unsigned count;
+  hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &count);
+  for (unsigned i = 0; i < count; i++)
+  {
+    unsigned alt_count = 0;
+    for (unsigned lookup_index = HB_SET_VALUE_INVALID;
+	 hb_set_next (lookup_indexes, &lookup_index);)
+      if ((alt_count = hb_ot_layout_lookup_get_glyph_alternates (face,
+								 lookup_index,
+								 info[i].codepoint,
+								 0,
+								 NULL,
+								 NULL)))
+        break;
+    printf ("glyph %u alt count %u\n", info[i].codepoint, alt_count);
+  }
+
+  hb_set_destroy (lookup_indexes);
+  hb_buffer_destroy (buffer);
+  hb_font_destroy (font);
+  hb_face_destroy (face);
+
+  return 0;
+}
diff --git a/source/libs/harfbuzz/harfbuzz-src/src/test-set.cc b/source/libs/harfbuzz/harfbuzz-src/src/test-set.cc
index 9fe319da697093d40aec194a9115aee9806590a8..5f13ab3225c03fd63958f57d7a8c56f579f7ad5b 100644
--- a/source/libs/harfbuzz/harfbuzz-src/src/test-set.cc
+++ b/source/libs/harfbuzz/harfbuzz-src/src/test-set.cc
@@ -137,5 +137,29 @@ main (int argc, char **argv)
     assert (s.has (HB_SET_VALUE_INVALID));
   }
 
+  /* Adding HB_SET_VALUE_INVALID */
+  {
+    hb_set_t s;
+
+    s.add(HB_SET_VALUE_INVALID);
+    assert(!s.has(HB_SET_VALUE_INVALID));
+
+    s.clear();
+    assert(!s.add_range(HB_SET_VALUE_INVALID - 2, HB_SET_VALUE_INVALID));
+    assert(!s.has(HB_SET_VALUE_INVALID));
+
+    hb_codepoint_t array[] = {(unsigned) HB_SET_VALUE_INVALID, 0, 2};
+    s.clear();
+    s.add_array(array, 3);
+    assert(!s.has(HB_SET_VALUE_INVALID));
+    assert(s.has(2));
+
+    hb_codepoint_t sorted_array[] = {0, 2, (unsigned) HB_SET_VALUE_INVALID};
+    s.clear();
+    s.add_sorted_array(sorted_array, 3);
+    assert(!s.has(HB_SET_VALUE_INVALID));
+    assert(s.has(2));
+  }
+
   return 0;
 }
diff --git a/source/libs/harfbuzz/version.ac b/source/libs/harfbuzz/version.ac
index 8d98b1fa32e9e9dcbc61812e92e2e7469b5c0742..eaafd5b890a16e27c138812c3b4982731b5b6b79 100644
--- a/source/libs/harfbuzz/version.ac
+++ b/source/libs/harfbuzz/version.ac
@@ -8,4 +8,4 @@ dnl
 dnl --------------------------------------------------------
 dnl
 dnl  m4-include this file to define the current harfbuzz version
-m4_define([harfbuzz_version], [7.1.0])
+m4_define([harfbuzz_version], [7.2.0])
diff --git a/source/texk/kpathsea/ChangeLog b/source/texk/kpathsea/ChangeLog
index 7b38a5539ec0864f584d5dd70b9f12e81183447d..66e2d043bab7176feb4d08e49f78cc247c744662 100644
--- a/source/texk/kpathsea/ChangeLog
+++ b/source/texk/kpathsea/ChangeLog
@@ -1,3 +1,8 @@
+2023-04-11  Karl Berry  <karl@tug.org>
+
+	* texmf.cnf: doc; explicitly mention that all the texmf trees need
+	to follow the TDS.
+
 2023-03-09  Karl Berry  <karl@tug.org>
 
 	* TL'23 release.
diff --git a/source/texk/kpathsea/texmf.cnf b/source/texk/kpathsea/texmf.cnf
index 0927bed4688fb18b07cd370c155e44aed4fa9e57..ec58bb91b4ff52a47e6b44840fc3d0ddf552f4fa 100644
--- a/source/texk/kpathsea/texmf.cnf
+++ b/source/texk/kpathsea/texmf.cnf
@@ -61,6 +61,9 @@
 % Sorry for the off-by-one-generation names.
 TEXMFROOT = $SELFAUTOPARENT
 
+% The various texmf trees used by TeX Live, follow.
+% They must must all have the TDS directory structure (https://tug.org/tds).
+
 % The main tree of distributed packages and programs:
 TEXMFDIST = $TEXMFROOT/texmf-dist
 
@@ -94,7 +97,7 @@ TEXMFCONFIG = ~/.texlive2023/texmf-config
 % value, hence the empty braces.
 TEXMFAUXTREES = {}
 
-% List all the texmf trees. For an explanation of what they are, see the
+% List of all the texmf trees. For an explanation of what they are, see the
 % TeX Live manual.
 %
 % For texconfig to work properly, TEXMFCONFIG and TEXMFVAR should be named
@@ -105,8 +108,8 @@ TEXMFAUXTREES = {}
 % generally a source of confusion to have different versions of a
 % package installed, whatever the trees, so try to avoid it.
 % 
-% The odd-looking $TEXMFAUXTREES$TEXMF... construct is so that if no auxtree is
-% ever defined (the 99% common case), no extra elements will be added to
+% The odd-looking $TEXMFAUXTREES$TEXMF... construct is so that if no auxtree
+% is defined (99% common case), no extra elements will be added to
 % the search paths. tlmgr takes care to end any value with a trailing comma.
 TEXMF = {$TEXMFAUXTREES$TEXMFCONFIG,$TEXMFVAR,$TEXMFHOME,!!$TEXMFLOCAL,!!$TEXMFSYSCONFIG,!!$TEXMFSYSVAR,!!$TEXMFDIST}
 
@@ -114,7 +117,7 @@ TEXMF = {$TEXMFAUXTREES$TEXMFCONFIG,$TEXMFVAR,$TEXMFHOME,!!$TEXMFLOCAL,!!$TEXMFS
 % this is all and only the !! elements of TEXMF, so that mktexlsr does not
 % create ls-R files in the non-!! elements -- because if an ls-R is
 % present, it will be used, and the disk will not (usually) be searched,
-% regardless of !!.  Although in principle a directory listed here need
+% regardless of !!.  Although in theory a directory listed here need
 % not contain an ls-R file, in practice they all should.
 TEXMFDBS = {!!$TEXMFLOCAL,!!$TEXMFSYSCONFIG,!!$TEXMFSYSVAR,!!$TEXMFDIST}
 
@@ -157,9 +160,11 @@ WEB2C = $TEXMF/web2c
 % This variable exists only to be redefined; it is used in nearly all
 % search paths. If a document has source files not only in the current
 % directory but also in subdirectories, it is convenient to set
-% TEXMFDOTDIR=.// so that everything will be searched automatically.
+% TEXMFDOTDIR=.// so that everything will be searched automatically,
+% without the need to set up the TDS directory structure (since this is
+% a "directory" and not a "tree").
 % On the other hand, if you never want the current directory to be
-% searched at all, setting TEXMFDOTDIR=/nonesuch should come close.
+% searched at all, setting TEXMFDOTDIR=/nonesuch comes close.
 %
 TEXMFDOTDIR = .
 
diff --git a/source/texk/texlive/linked_scripts/Makefile.am b/source/texk/texlive/linked_scripts/Makefile.am
index 810c524e81cee5175f8cd96aa5250637e9844661..5988043a83ed88ab2328c7687130df6202ecfefc 100644
--- a/source/texk/texlive/linked_scripts/Makefile.am
+++ b/source/texk/texlive/linked_scripts/Makefile.am
@@ -1,4 +1,4 @@
-## $Id: Makefile.am 66269 2023-03-01 01:59:43Z karl $
+## $Id: Makefile.am 66777 2023-04-05 20:09:08Z karl $
 ## Makefile.am for the TeX Live subdirectory texk/texlive/linked_scripts/
 ##
 ## Copyright 2016-2023 Karl Berry <tex-live@tug.org>
@@ -221,6 +221,7 @@ texmf_other_scripts = \
 	texdef/texdef.pl \
 	texdiff/texdiff \
 	texdirflatten/texdirflatten \
+	texfindpkg/texfindpkg.lua \
 	texdoc/texdoc.tlu \
 	texfot/texfot.pl \
 	texlive/fmtutil-sys.sh \
diff --git a/source/texk/texlive/linked_scripts/Makefile.in b/source/texk/texlive/linked_scripts/Makefile.in
index 8792c79a62a764848a8aca46f3b3e5f06f29c72b..23ab0d974297c794013606ad6fb1e16728308e45 100644
--- a/source/texk/texlive/linked_scripts/Makefile.in
+++ b/source/texk/texlive/linked_scripts/Makefile.in
@@ -437,6 +437,7 @@ texmf_other_scripts = \
 	texdef/texdef.pl \
 	texdiff/texdiff \
 	texdirflatten/texdirflatten \
+	texfindpkg/texfindpkg.lua \
 	texdoc/texdoc.tlu \
 	texfot/texfot.pl \
 	texlive/fmtutil-sys.sh \
diff --git a/source/texk/web2c/cwebdir/ChangeLog b/source/texk/web2c/cwebdir/ChangeLog
index 1587dc98a6af1126800f7cfc0f2310c299e8d836..8105b2d716c0251246e4abfc2431bb48e18599b6 100644
--- a/source/texk/web2c/cwebdir/ChangeLog
+++ b/source/texk/web2c/cwebdir/ChangeLog
@@ -1,3 +1,11 @@
+2023-04-20  Andreas Scherer  <https://ascherer.github.io>
+
+	* cweave.w: Reduce whitespace in output section.
+
+2023-04-05  Andreas Scherer  <https://ascherer.github.io>
+
+	* cwebmac.tex: Revert a few \ifacro from version 4.8.
+
 2023-01-08  Andreas Scherer  <https://ascherer.github.io>
 
 	* comm-mac.ch,
diff --git a/source/texk/web2c/cwebdir/cweave.w b/source/texk/web2c/cwebdir/cweave.w
index 17cb9ae4b5549bbdd12082206248e13d4a2cc385..cd95be4ca03200a21fa6be9e142dc7c0e8f1b38a 100644
--- a/source/texk/web2c/cwebdir/cweave.w
+++ b/source/texk/web2c/cwebdir/cweave.w
@@ -2124,7 +2124,7 @@ identifier&|exp|: \.{\\\\\{}identifier with underlines and
  \.{\\X}$n$\.:translated section name\.{\\X}&maybe\cr
 \.{@@(@q)@>}\thinspace section name\thinspace\.{@@>}&|section_scrap|:
  \.{\\X}$n$\.{:\\.\{}section name with special characters
-      quoted\.{\ \}\\X}&maybe\cr
+      quoted\.{\\,\}\\X}&maybe\cr
 \.{/*}\thinspace comment\thinspace\.{*/}&|insert|: |cancel|
       \.{\\C\{}translated comment\.\} |force|&no\cr
 \.{//}\thinspace comment&|insert|: |cancel|
@@ -4093,7 +4093,7 @@ out(':');
 if (an_output) out_str("\\.{"@q}@>);
 @.\\.@>
 @<Output the text of the section name@>@;
-if (an_output) out_str(@q{@>" }");
+if (an_output) out_str(@q{@>"\\,}");
 out_str("\\X");
 
 @ @<Output the text...@>=
diff --git a/source/texk/web2c/cwebdir/cwebmac.tex b/source/texk/web2c/cwebdir/cwebmac.tex
index 4dcbd9b09d73bfa0b15a50fafbce0cffbbee9d75..3f058c5435aa66c5ef4cc6f6db84f4f53fdd5b8f 100644
--- a/source/texk/web2c/cwebdir/cwebmac.tex
+++ b/source/texk/web2c/cwebdir/cwebmac.tex
@@ -14,7 +14,7 @@
   \def\Blue{\pdfliteral{\pdflinkcolor\space rg \pdflinkcolor\space RG}}
 \fi
 \let\ifacro=\ifpdf
-\newif\ifacrohint \ifpdf\acrohinttrue\fi \ifhint\acrohinttrue\fi
+\newif\ifacrohint \ifacro\acrohinttrue\fi \ifhint\acrohinttrue\fi
 
 \let\:=\. % preserve a way to get the dot accent
  % (all other accents will still work as usual)
@@ -134,7 +134,7 @@
 \newif\iftokprocessed \newif\ifTnum \newif\ifinstr
 {\def\\{\global\let\spacechar= }\\ }
 
-\ifpdf % The following are pdf macros
+\ifacro % The following are pdf macros
 \def\thewidth{\the\wd0 \space}
 \def\theheight{\the\ht\strutbox\space}
 \def\thedepth{\the\dp\strutbox\space}
@@ -262,7 +262,7 @@
 \let\pdflink=\HINTlink
 \fi % End of HINT macros
 
-% Common macros for \ifpdf and \ifhint
+% Common macros for \ifacro and \ifhint
 \ifacrohint
 \def\pdfnote#1.{\setbox0=\hbox{\toksA={#1.}\toksB={}\maketoks}\the\toksA}
 \def\firstsecno#1.{\setbox0=\hbox{\toksA={#1.}\toksB={}%
@@ -305,7 +305,7 @@
   \sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50
   \ifhint\HINTlabel\fi% Start page before section
   \noindent{\let\*=\lapstar\bf\secstar.\quad}%
-  \ifpdf \smash{\raise\baselineskip\hbox to0pt{\let\*=\empty
+  \ifacro \smash{\raise\baselineskip\hbox to0pt{\let\*=\empty
     \ifpdftex \pdfdest num \secstar fith%
     \else \special{pdf: dest (\romannumeral\secstar)
       [ @thispage /FitH @ypos ]}\fi}}\fi}
@@ -338,7 +338,7 @@
 \outer\def\M#1{\MN{#1}\ifon\vfil\penalty-100\vfilneg % beginning of section
   \vskip\intersecskip\startsection\ignorespaces}
 \outer\def\N#1#2#3.{% beginning of starred section
-  \ifpdf{\toksF={}\makeoutlinetoks#3\outlinedone\outlinedone}\fi
+  \ifacro{\toksF={}\makeoutlinetoks#3\outlinedone\outlinedone}\fi
   \gdepth=#1\gtitle={#3}\MN{#2}%
   \ifon\ifnum#1<\secpagedepth \vfil\eject % force page break if depth is small
     \else\vfil\penalty-100\vfilneg\vskip\intersecskip\fi\fi
@@ -504,7 +504,7 @@
   \def\U{\note{Used in section}} % crossref for use of a section
   \def\Us{\note{Used in sections}} % crossref for uses of a section
   \def\I{\par\hangindent 2em}\let\*=*
-  \ifpdf \def\outsecname{Names of the sections} \let\Xpdf\X
+  \ifacro \def\outsecname{Names of the sections} \let\Xpdf\X
 %  \ifpdftex \makebookmarks \pdfdest name {NOS} fitb % in versions < 3.68
   \ifpdftex \pdfdest name {NOS} fith % changed in version 3.69
     \pdfoutline goto name {NOS} count -\the\countD {\outsecname}
@@ -551,7 +551,7 @@
       \ \ifhint
           \HINTlink{#3}{\romannumeral#3}% No page numbers in HINT
           \HINTcontents{#1}{#2}{#3}%
-        \else\ifpdf\pdflink{#3}{\romannumeral#3}\else#3\fi
+        \else\ifacro\pdflink{#3}{\romannumeral#3}\else#3\fi
           \hbox to3em{\hss#4}\fi}}
 \def\consetup#1{\ifcase#1 \bf % depth -1 (@**)
   \or % depth 0 (@*)
diff --git a/source/texk/web2c/luatexdir/ChangeLog b/source/texk/web2c/luatexdir/ChangeLog
index 20e2ea7bb93a5a3d4944f479d916ae42a21a490d..f182f16e4c5d55dd9931398bdf14ed904b9c271b 100644
--- a/source/texk/web2c/luatexdir/ChangeLog
+++ b/source/texk/web2c/luatexdir/ChangeLog
@@ -1,3 +1,6 @@
+2023-04-29  Luigi Scarso <luigi.scarso@gmail.com> 
+    * LuaTeX 1.17.0
+
 2023-04-28  Luigi Scarso <luigi.scarso@gmail.com> 
     * new option --no-socket, same as --nosocket
 
diff --git a/source/texk/web2c/luatexdir/lua/luainit.c b/source/texk/web2c/luatexdir/lua/luainit.c
index 0fb0171969a4aa84e3ca0b66eeb703ae72c349d8..bac5444c2a465a27a8197b7f8458617689143dd9 100644
--- a/source/texk/web2c/luatexdir/lua/luainit.c
+++ b/source/texk/web2c/luatexdir/lua/luainit.c
@@ -110,6 +110,7 @@ const_string LUATEX_IHELP[] = {
 #endif
     "",
     "See the reference manual for more information about the startup process.",
+    "LuaTeX package page: https://ctan.org/pkg/luatex",
     NULL
 };
 
diff --git a/source/texk/web2c/luatexdir/luatex_svnversion.h b/source/texk/web2c/luatexdir/luatex_svnversion.h
index 8f32bd54800890c46631e52dd78e8619971dfe10..6b6137b1b2ff78e819795f68b51156f121051c57 100644
--- a/source/texk/web2c/luatexdir/luatex_svnversion.h
+++ b/source/texk/web2c/luatexdir/luatex_svnversion.h
@@ -1,4 +1,4 @@
 #ifndef luatex_svn_revision_h
 #define luatex_svn_revision_h
-#define luatex_svn_revision 7580
+#define luatex_svn_revision 7581
 #endif