texlive[68575] Build/source/libs:

commits+kakuto at tug.org commits+kakuto at tug.org
Wed Oct 18 00:55:49 CEST 2023


Revision: 68575
          https://tug.org/svn/texlive?view=revision&revision=68575
Author:   kakuto
Date:     2023-10-18 00:55:48 +0200 (Wed, 18 Oct 2023)
Log Message:
-----------


Modified Paths:
--------------
    trunk/Build/source/libs/README
    trunk/Build/source/libs/harfbuzz/ChangeLog
    trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
    trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes
    trunk/Build/source/libs/harfbuzz/configure
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson_options.txt
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GDEF/GDEF.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/AnchorFormat3.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/markbasepos-graph.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-cvar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan-member-list.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-priority-queue.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-tuple-varstore.cc
    trunk/Build/source/libs/harfbuzz/version.ac

Added Paths:
-----------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/relative_to.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-item-varstore.cc

Modified: trunk/Build/source/libs/README
===================================================================
--- trunk/Build/source/libs/README	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/README	2023-10-17 22:55:48 UTC (rev 68575)
@@ -25,8 +25,8 @@
   http://sourceforge.net/projects/silgraphite/files/graphite2/
   (requires C++11)
 
-harfbuzz 8.2.1 - checked 19sep23
-  https://github.com/harfbuzz/harfbuzz/releases/tag/8.2.1
+harfbuzz 8.2.2 - checked 18oct23
+  https://github.com/harfbuzz/harfbuzz/releases/tag/8.2.2
 
 icu 72.1 - checked 07jan23
   https://github.com/unicode-org/icu/releases/

Modified: trunk/Build/source/libs/harfbuzz/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/ChangeLog	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/ChangeLog	2023-10-17 22:55:48 UTC (rev 68575)
@@ -1,3 +1,8 @@
+2023-10-18  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
+
+	Import harfbuzz-8.2.2.
+	* version.ac: Adjusted.
+
 2023-09-19  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
 
 	Import harfbuzz-8.2.1.

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2023-10-17 22:55:48 UTC (rev 68575)
@@ -1,3 +1,8 @@
+2023-10-18  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
+
+	Imported harfbuzz-8.2.2 source tree from:
+	https://github.com/harfbuzz/harfbuzz/releases/download/8.2.2/
+
 2023-09-19  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
 
 	Imported harfbuzz-8.2.1 source tree from:

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2023-10-17 22:55:48 UTC (rev 68575)
@@ -1,5 +1,5 @@
-Changes applied to the harfbuzz-8.2.1/ tree as obtained from:
-	https://github.com/harfbuzz/harfbuzz/releases/download/8.2.1/
+Changes applied to the harfbuzz-8.2.2/ tree as obtained from:
+	https://github.com/harfbuzz/harfbuzz/releases/download/8.2.2/
 
 Removed:
 	COPYING

Modified: trunk/Build/source/libs/harfbuzz/configure
===================================================================
--- trunk/Build/source/libs/harfbuzz/configure	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/configure	2023-10-17 22:55:48 UTC (rev 68575)
@@ -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) 8.2.1.
+# Generated by GNU Autoconf 2.71 for harfbuzz (TeX Live) 8.2.2.
 #
 # Report bugs to <tex-k at tug.org>.
 #
@@ -611,8 +611,8 @@
 # Identity of this package.
 PACKAGE_NAME='harfbuzz (TeX Live)'
 PACKAGE_TARNAME='harfbuzz--tex-live-'
-PACKAGE_VERSION='8.2.1'
-PACKAGE_STRING='harfbuzz (TeX Live) 8.2.1'
+PACKAGE_VERSION='8.2.2'
+PACKAGE_STRING='harfbuzz (TeX Live) 8.2.2'
 PACKAGE_BUGREPORT='tex-k at tug.org'
 PACKAGE_URL=''
 
@@ -1346,7 +1346,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures harfbuzz (TeX Live) 8.2.1 to adapt to many kinds of systems.
+\`configure' configures harfbuzz (TeX Live) 8.2.2 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1418,7 +1418,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 8.2.1:";;
+     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 8.2.2:";;
    esac
   cat <<\_ACEOF
 
@@ -1523,7 +1523,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-harfbuzz (TeX Live) configure 8.2.1
+harfbuzz (TeX Live) configure 8.2.2
 generated by GNU Autoconf 2.71
 
 Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2064,7 +2064,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by harfbuzz (TeX Live) $as_me 8.2.1, which was
+It was created by harfbuzz (TeX Live) $as_me 8.2.2, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -4823,7 +4823,7 @@
 
 # Define the identity of the package.
  PACKAGE='harfbuzz--tex-live-'
- VERSION='8.2.1'
+ VERSION='8.2.2'
 
 
 # Some tools Automake needs.
@@ -5035,8 +5035,8 @@
 
 HB_VERSION_MAJOR=8
 HB_VERSION_MINOR=2
-HB_VERSION_MICRO=1
-HB_VERSION=8.2.1
+HB_VERSION_MICRO=2
+HB_VERSION=8.2.2
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -8817,7 +8817,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by harfbuzz (TeX Live) $as_me 8.2.1, which was
+This file was extended by harfbuzz (TeX Live) $as_me 8.2.2, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -8885,7 +8885,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-harfbuzz (TeX Live) config.status 8.2.1
+harfbuzz (TeX Live) config.status 8.2.2
 configured by $0, generated by GNU Autoconf 2.71,
   with options \\"\$ac_cs_config\\"
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2023-10-17 22:55:48 UTC (rev 68575)
@@ -1,3 +1,877 @@
+commit 18a6e78549e8e04a281129ea8ca784ce85f111b8
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Wed Oct 18 01:10:44 2023 +0300
+
+    8.2.2
+
+ NEWS             | 11 +++++++++++
+ configure.ac     |  2 +-
+ meson.build      |  2 +-
+ src/hb-version.h |  4 ++--
+ 4 files changed, 15 insertions(+), 4 deletions(-)
+
+commit 52bc78e70de9f8288e3412a8017f88d2e0a31dea
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Oct 10 21:44:52 2023 +0000
+
+    s/PairPos/MarkBasePos/ in MarkBasePos repacking implementation.
+
+ src/graph/markbasepos-graph.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 6190bb0b8ed8af3d182d1936fbe859c15fb0f817
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Oct 16 14:08:31 2023 -0400
+
+    [layout] Change order of feature collection
+    
+    See comments for rationale.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4445
+
+ src/hb-ot-layout.cc | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+commit 4992456cfadabb6ecbc7b4efc5c1af9ec91f6dd3
+Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
+Date:   Mon Oct 16 10:07:42 2023 +0000
+
+    Bump ninja from 1.11.1 to 1.11.1.1 in /.ci
+    
+    Bumps [ninja](https://github.com/ninja-build/ninja) from 1.11.1 to 1.11.1.1.
+    - [Release notes](https://github.com/ninja-build/ninja/releases)
+    - [Commits](https://github.com/ninja-build/ninja/commits)
+    
+    ---
+    updated-dependencies:
+    - dependency-name: ninja
+      dependency-type: direct:production
+      update-type: version-update:semver-patch
+    ...
+    
+    Signed-off-by: dependabot[bot] <support at github.com>
+
+ .ci/requirements.txt | 34 ++++++++++++++++------------------
+ 1 file changed, 16 insertions(+), 18 deletions(-)
+
+commit 397b32e585cbb29349e0e97fad2e84cb57a9a6d1
+Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
+Date:   Mon Oct 16 10:29:00 2023 +0000
+
+    Bump github/codeql-action from 2.22.0 to 2.22.3
+    
+    Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.22.0 to 2.22.3.
+    - [Release notes](https://github.com/github/codeql-action/releases)
+    - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
+    - [Commits](https://github.com/github/codeql-action/compare/2cb752a87e96af96708ab57187ab6372ee1973ab...0116bc2df50751f9724a2e35ef1f24d22f90e4e1)
+    
+    ---
+    updated-dependencies:
+    - dependency-name: github/codeql-action
+      dependency-type: direct:production
+      update-type: version-update:semver-patch
+    ...
+    
+    Signed-off-by: dependabot[bot] <support at github.com>
+
+ .github/workflows/scorecard.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1f395cbaf91be284f443c27b8b35be0edd788c34
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Oct 12 10:06:00 2023 -0700
+
+    [instancer] templatize the priority queue, use custom type for varstore
+    
+    when instantiating varstore, we need to pop a tuple like
+    (combined_gain, i, j), if combined gain is the same then we compare the
+    value of i, and then j. So we'd like to use custom type as the key when
+    popping from the queue. This would match fonttool's algorithm cause it
+    uses heappop().
+
+ src/graph/graph.hh         |  4 ++--
+ src/hb-ot-var-common.hh    | 47 ++++++++++++++++++++++++++++++++++------------
+ src/hb-priority-queue.hh   |  5 +++--
+ src/test-priority-queue.cc |  4 ++--
+ 4 files changed, 42 insertions(+), 18 deletions(-)
+
+commit bbd53fcfa49e9d4a8b3899ce2c109377886a3ba9
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Oct 10 21:41:42 2023 +0000
+
+    Remove glyph_map test that uses retain gids.
+    
+    We no longer allow the use of glyph map + retain gids (see: https://github.com/harfbuzz/harfbuzz/blob/main/src/hb-subset-plan.cc#L817). Also add the test to the meson file so it will be run by default.
+
+ test/subset/data/Makefile.am                             |   1 +
+ test/subset/data/Makefile.sources                        |   1 +
+ ...gular.glyph_map_roboto_retain_gids.41,43,61,66,69.ttf | Bin 7936 -> 0 bytes
+ .../data/profiles/glyph_map_roboto_retain_gids.txt       |   4 ----
+ test/subset/data/tests/glyph_map.tests                   |   1 -
+ test/subset/meson.build                                  |   1 +
+ 6 files changed, 3 insertions(+), 5 deletions(-)
+
+commit 9648799e53edae7072505849fb551a6e621b8f6c
+Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
+Date:   Mon Oct 9 10:34:48 2023 +0000
+
+    Bump ossf/scorecard-action from 2.2.0 to 2.3.0
+    
+    Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.2.0 to 2.3.0.
+    - [Release notes](https://github.com/ossf/scorecard-action/releases)
+    - [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md)
+    - [Commits](https://github.com/ossf/scorecard-action/compare/08b4669551908b1024bb425080c797723083c031...483ef80eb98fb506c348f7d62e28055e49fe2398)
+    
+    ---
+    updated-dependencies:
+    - dependency-name: ossf/scorecard-action
+      dependency-type: direct:production
+      update-type: version-update:semver-minor
+    ...
+    
+    Signed-off-by: dependabot[bot] <support at github.com>
+
+ .github/workflows/scorecard.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit cf930decce6cffabff55a8a314eb7f9f34cff322
+Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
+Date:   Mon Oct 9 10:34:42 2023 +0000
+
+    Bump actions/setup-python from 4.7.0 to 4.7.1
+    
+    Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4.7.0 to 4.7.1.
+    - [Release notes](https://github.com/actions/setup-python/releases)
+    - [Commits](https://github.com/actions/setup-python/compare/61a6322f88396a6271a6ee3565807d608ecaddd1...65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236)
+    
+    ---
+    updated-dependencies:
+    - dependency-name: actions/setup-python
+      dependency-type: direct:production
+      update-type: version-update:semver-patch
+    ...
+    
+    Signed-off-by: dependabot[bot] <support at github.com>
+
+ .github/workflows/msvc-ci.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0cfc4ebfbade5b794956f0eae3939e7b1fade2b8
+Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
+Date:   Mon Oct 9 10:34:36 2023 +0000
+
+    Bump github/codeql-action from 2.21.9 to 2.22.0
+    
+    Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.21.9 to 2.22.0.
+    - [Release notes](https://github.com/github/codeql-action/releases)
+    - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
+    - [Commits](https://github.com/github/codeql-action/compare/ddccb873888234080b77e9bc2d4764d5ccaaccf9...2cb752a87e96af96708ab57187ab6372ee1973ab)
+    
+    ---
+    updated-dependencies:
+    - dependency-name: github/codeql-action
+      dependency-type: direct:production
+      update-type: version-update:semver-minor
+    ...
+    
+    Signed-off-by: dependabot[bot] <support at github.com>
+
+ .github/workflows/scorecard.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a317b5a7ea49c08e21a0e47beaaa5c31f52f28ea
+Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
+Date:   Mon Oct 9 10:06:13 2023 +0000
+
+    Bump fonttools from 4.43.0 to 4.43.1 in /.ci
+    
+    Bumps [fonttools](https://github.com/fonttools/fonttools) from 4.43.0 to 4.43.1.
+    - [Release notes](https://github.com/fonttools/fonttools/releases)
+    - [Changelog](https://github.com/fonttools/fonttools/blob/main/NEWS.rst)
+    - [Commits](https://github.com/fonttools/fonttools/compare/4.43.0...4.43.1)
+    
+    ---
+    updated-dependencies:
+    - dependency-name: fonttools
+      dependency-type: direct:production
+      update-type: version-update:semver-patch
+    ...
+    
+    Signed-off-by: dependabot[bot] <support at github.com>
+
+ .ci/requirements-fonttools.txt | 86 +++++++++++++++++++++---------------------
+ .ci/requirements.txt           | 86 +++++++++++++++++++++---------------------
+ 2 files changed, 86 insertions(+), 86 deletions(-)
+
+commit a7b3fe3523891a81be501c907b6bf817615df174
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 5 12:16:00 2023 -0600
+
+    Fix test
+
+ src/test-tuple-varstore.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit fc563bb437b379334913b15489caec98a504fcd3
+Merge: f26fd69d8 2415d5f23
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Oct 5 11:07:17 2023 -0600
+
+    Merge pull request #4421 from googlefonts/GDEF_GPOS
+    
+    [instancer] support GDEF/GPOS tables
+
+commit f26fd69d858642d76413b8f4068eaf9b57c40a5f
+Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
+Date:   Mon Oct 2 10:06:40 2023 +0000
+
+    Bump github/codeql-action from 2.21.8 to 2.21.9
+    
+    Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.21.8 to 2.21.9.
+    - [Release notes](https://github.com/github/codeql-action/releases)
+    - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
+    - [Commits](https://github.com/github/codeql-action/compare/6a28655e3dcb49cb0840ea372fd6d17733edd8a4...ddccb873888234080b77e9bc2d4764d5ccaaccf9)
+    
+    ---
+    updated-dependencies:
+    - dependency-name: github/codeql-action
+      dependency-type: direct:production
+      update-type: version-update:semver-patch
+    ...
+    
+    Signed-off-by: dependabot[bot] <support at github.com>
+
+ .github/workflows/scorecard.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1522eb9199ed07b8fba9c3131806205834b0a18a
+Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
+Date:   Mon Oct 2 10:48:02 2023 +0000
+
+    Bump fonttools from 4.42.1 to 4.43.0 in /.ci
+    
+    Bumps [fonttools](https://github.com/fonttools/fonttools) from 4.42.1 to 4.43.0.
+    - [Release notes](https://github.com/fonttools/fonttools/releases)
+    - [Changelog](https://github.com/fonttools/fonttools/blob/main/NEWS.rst)
+    - [Commits](https://github.com/fonttools/fonttools/compare/4.42.1...4.43.0)
+    
+    ---
+    updated-dependencies:
+    - dependency-name: fonttools
+      dependency-type: direct:production
+      update-type: version-update:semver-minor
+    ...
+    
+    Signed-off-by: dependabot[bot] <support at github.com>
+
+ .ci/requirements-fonttools.txt | 78 +++++++++++++++++++++++-------------------
+ .ci/requirements.txt           | 78 +++++++++++++++++++++++-------------------
+ 2 files changed, 86 insertions(+), 70 deletions(-)
+
+commit 2d67e52a47945e2563b12e681336ab9d04613aad
+Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
+Date:   Mon Oct 2 10:47:40 2023 +0000
+
+    Bump meson from 1.2.1 to 1.2.2 in /.ci
+    
+    Bumps [meson](https://github.com/mesonbuild/meson) from 1.2.1 to 1.2.2.
+    - [Release notes](https://github.com/mesonbuild/meson/releases)
+    - [Commits](https://github.com/mesonbuild/meson/compare/1.2.1...1.2.2)
+    
+    ---
+    updated-dependencies:
+    - dependency-name: meson
+      dependency-type: direct:production
+      update-type: version-update:semver-patch
+    ...
+    
+    Signed-off-by: dependabot[bot] <support at github.com>
+
+ .ci/requirements.in  | 2 +-
+ .ci/requirements.txt | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 6e06a193b3e6784b87380641d693fee1e507228e
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Sep 30 01:12:16 2023 +0300
+
+    Add some tests for hb_feature_[from|to]_string()
+
+ test/api/test-common.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 108 insertions(+)
+
+commit f360d704fad6551dd05fe62bf9c4ce2f9a857e03
+Author: jfkthame <jfkthame at gmail.com>
+Date:   Fri Sep 29 13:15:01 2023 +0100
+
+    Check for closing quote in parse_tag
+    
+    Fixes #4414.
+
+ src/hb-common.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 333946b00e849ff6722781bc5e46bd9fcc83311a
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Sep 28 19:02:37 2023 +0000
+
+    [subset] Fix fuzzer timeout.
+    
+    Fixes https://oss-fuzz.com/testcase-detail/5458896606855168. Limit iteration over coverage in MarkLigPosFormat1 subsetting to the number of glyphs in the liga array.
+
+ src/OT/Layout/GPOS/MarkLigPosFormat1.hh                  |   5 +++--
+ ...-testcase-minimized-hb-subset-fuzzer-5458896606855168 | Bin 0 -> 2410 bytes
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+commit 9ceb800ac26fd81a5eaf27ef366d5fce47e80447
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Sep 28 10:37:48 2023 -0700
+
+    fuzzer fix https://oss-fuzz.com/testcase-detail/5842152921628672
+    
+    Access TupleVariationData through blob, because we don't sanitize
+    var_data
+
+ src/hb-ot-var-cvar-table.hh                             |   7 ++++---
+ src/test-tuple-varstore.cc                              |  16 +++++++++++++++-
+ ...testcase-minimized-hb-subset-fuzzer-5842152921628672 | Bin 0 -> 2501 bytes
+ 3 files changed, 19 insertions(+), 4 deletions(-)
+
+commit 7cb7a7999b542cb4ae75a3d289a429a68df6a86a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Sep 28 09:24:06 2023 -0600
+
+    [map] Fix undefined integer-overflow
+    
+    Fixes https://oss-fuzz.com/testcase-detail/5814850435284992
+
+ src/hb-map.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 2415d5f23927cbfcd8a2928f7ecadf7e9626cd51
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Sep 27 13:33:09 2023 -0700
+
+    [instancer] update tests to include GDEF/GPOS tables
+
+ ...n-all-codepoint.wght=200-300-500,wdth=80-90.ttf | Bin 8432 -> 8728 bytes
+ ...s.retain-all-codepoint.wght=300-600,wdth=85.ttf | Bin 7336 -> 7612 bytes
+ ...n-all-codepoint.wght=200-300-500,wdth=80-90.ttf | Bin 7484 -> 7592 bytes
+ ...s.retain-all-codepoint.wght=300-600,wdth=85.ttf | Bin 6848 -> 6956 bytes
+ ...odepoint.wght=200-600,wdth=80-90,CTGR=20-60.ttf | Bin 4108 -> 4340 bytes
+ ...ariations.retain-all-codepoint.wght=300-600.ttf | Bin 6616 -> 6848 bytes
+ ...ariations.retain-all-codepoint.wght=500-800.ttf | Bin 7096 -> 7328 bytes
+ ...ariations.retain-all-codepoint.wght=300-600.ttf | Bin 197056 -> 305092 bytes
+ ...ariations.retain-all-codepoint.wght=500-800.ttf | Bin 145004 -> 250164 bytes
+ .../profiles/no-tables-with-item-variations.txt    |   2 +-
+ 10 files changed, 1 insertion(+), 1 deletion(-)
+
+commit f9b04b2145a2021cc56868daca89c3514f6a8966
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Sep 27 09:36:52 2023 -0700
+
+    [instancer] match fonttools'r order when calculating chars
+    
+    Also fix a bug, make sure map set is happening before std::move
+
+ src/hb-ot-layout-common.hh | 6 ++++--
+ src/hb-ot-var-common.hh    | 4 ++--
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+commit f39e9bf1ed52140d2658b4d845f3bbacc215221b
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Mon Sep 25 08:59:11 2023 -0700
+
+    [instancer] instantiate GPOS
+    
+    Just need to update var_idxes and deltas
+
+ src/OT/Layout/GDEF/GDEF.hh          | 18 ++++++++++--------
+ src/OT/Layout/GPOS/AnchorFormat3.hh | 23 ++++++++++++++++++-----
+ src/hb-ot-layout-common.hh          |  4 ++--
+ 3 files changed, 30 insertions(+), 15 deletions(-)
+
+commit 5c6795e2701d7c2031bc3e7c6c1b356961350291
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Sep 21 12:04:03 2023 -0700
+
+    [instancer] make GPOS depend on GDEF when partial instancing
+    
+    GPOS needs to wait for GDEF remapping layout var idxes
+
+ src/hb-subset.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit c8594baa478d09b60e1553dacae32345efef4272
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Sep 21 11:45:01 2023 -0700
+
+    [instancer] instantiate GDEF varStore
+    
+    And update layout var idxes accordingly
+
+ src/OT/Layout/GDEF/GDEF.hh        | 38 +++++++++++++++++++++++++++++++++++++-
+ src/hb-subset-plan-member-list.hh |  2 +-
+ 2 files changed, 38 insertions(+), 2 deletions(-)
+
+commit 77f24d822e726b0075d9aab4dc8600eb1b7dc481
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Fri Sep 22 14:47:11 2023 -0700
+
+    [instancer] remap layout var_idxes code update
+    
+    make hb_collect_variation_indices_context_t only collect layout
+    variation indices.
+
+ src/OT/Layout/GDEF/GDEF.hh | 26 +++++++++++++++++++-------
+ src/hb-ot-layout-common.hh | 28 +++-------------------------
+ src/hb-subset-plan.cc      | 26 ++++++--------------------
+ 3 files changed, 28 insertions(+), 52 deletions(-)
+
+commit c8c97864e8c810068123ef62947be13675df54c2
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Sep 21 11:29:43 2023 -0700
+
+    [instancer] simplify item_variations_t API calls
+    
+    merge create,instantiate and as_item_varstore into one API
+
+ src/hb-ot-var-common.hh     | 19 +++++++++++++++++--
+ src/hb-ot-var-hvar-table.hh | 18 ++++--------------
+ src/hb-ot-var-mvar-table.hh |  7 +------
+ src/test-item-varstore.cc   |  2 +-
+ 4 files changed, 23 insertions(+), 23 deletions(-)
+
+commit 00de5d0068d189a7dcbd1ccb10f55db95d240340
+Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
+Date:   Mon Sep 25 10:25:15 2023 +0000
+
+    Bump actions/checkout from 4.0.0 to 4.1.0
+    
+    Bumps [actions/checkout](https://github.com/actions/checkout) from 4.0.0 to 4.1.0.
+    - [Release notes](https://github.com/actions/checkout/releases)
+    - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
+    - [Commits](https://github.com/actions/checkout/compare/3df4ab11eba7bda6032a0b82a6bb43b11571feac...8ade135a41bc03ea155e62e844d188df1ea18608)
+    
+    ---
+    updated-dependencies:
+    - dependency-name: actions/checkout
+      dependency-type: direct:production
+      update-type: version-update:semver-minor
+    ...
+    
+    Signed-off-by: dependabot[bot] <support at github.com>
+
+ .github/workflows/arm-ci.yml        | 2 +-
+ .github/workflows/configs-build.yml | 2 +-
+ .github/workflows/coverity-scan.yml | 2 +-
+ .github/workflows/linux-ci.yml      | 2 +-
+ .github/workflows/macos-ci.yml      | 2 +-
+ .github/workflows/msvc-ci.yml       | 2 +-
+ .github/workflows/msys2-ci.yml      | 2 +-
+ .github/workflows/scorecard.yml     | 2 +-
+ 8 files changed, 8 insertions(+), 8 deletions(-)
+
+commit 42b8534b14419580dd35f865944081196217cb6c
+Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
+Date:   Mon Sep 25 10:25:08 2023 +0000
+
+    Bump github/codeql-action from 2.21.7 to 2.21.8
+    
+    Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.21.7 to 2.21.8.
+    - [Release notes](https://github.com/github/codeql-action/releases)
+    - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
+    - [Commits](https://github.com/github/codeql-action/compare/04daf014b50eaf774287bf3f0f1869d4b4c4b913...6a28655e3dcb49cb0840ea372fd6d17733edd8a4)
+    
+    ---
+    updated-dependencies:
+    - dependency-name: github/codeql-action
+      dependency-type: direct:production
+      update-type: version-update:semver-patch
+    ...
+    
+    Signed-off-by: dependabot[bot] <support at github.com>
+
+ .github/workflows/scorecard.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 69da5aae028417dacf4c6617e49beb7dfbeb20e3
+Author: inobelar <inobelar at gmail.com>
+Date:   Fri Sep 22 21:27:12 2023 +0000
+
+    Added minor fixes to build without errors with gcc 4.9.2
+
+ src/hb-map.hh    | 22 +++++++++++-----------
+ src/hb-vector.hh |  2 +-
+ 2 files changed, 12 insertions(+), 12 deletions(-)
+
+commit b8121ccbb687dc853118e81810cc0565ce0037d4
+Author: Duncan Overbruck <mail at duncano.de>
+Date:   Thu Sep 21 15:41:09 2023 +0200
+
+    [meson] keep asserts in test programs
+
+ src/meson.build | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5aa4865a86fd97e76e857823dd4b32c65d2fa0ad
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Sep 20 14:52:58 2023 -0700
+
+    [instancer] fix compile warnings
+    
+    In constructor ‘OT::delta_row_encoding_t::delta_row_encoding_t(OT::delta_row_encoding_t&&)’,
+        inlined from ‘Type* hb_vector_t<Type, sorted>::push(Args&& ...) [with Args = {OT::delta_row_encoding_t}; Type = OT::delta_row_encoding_t; bool sorted = false]’ at ../src/hb-vector.hh:221:12,
+        inlined from ‘bool OT::item_variations_t::as_item_varstore(bool, bool)’ at ../src/hb-ot-var-common.hh:1985:24:
+    ../src/hb-ot-layout-common.hh:2304:8: warning: ‘obj.OT::delta_row_encoding_t::width’ may be used uninitialized [-Wmaybe-uninitialized]
+     2304 | struct delta_row_encoding_t
+          |        ^~~~~~~~~~~~~~~~~~~~
+    ../src/hb-ot-var-common.hh: In member function ‘bool OT::item_variations_t::as_item_varstore(bool, bool)’:
+    ../src/hb-ot-var-common.hh:1981:30: note: ‘obj.OT::delta_row_encoding_t::width’ was declared here
+     1981 |         delta_row_encoding_t obj;
+          |                              ^~~
+    In constructor ‘OT::delta_row_encoding_t::delta_row_encoding_t(OT::delta_row_encoding_t&&)’,
+        inlined from ‘Type* hb_vector_t<Type, sorted>::push(Args&& ...) [with Args = {OT::delta_row_encoding_t}; Type = OT::delta_row_encoding_t; bool sorted = false]’ at ../src/hb-vector.hh:221:12,
+        inlined from ‘bool OT::item_variations_t::as_item_varstore(bool, bool)’ at ../src/hb-ot-var-common.hh:1985:24:
+    ../src/hb-ot-layout-common.hh:2304:8: warning: ‘obj.OT::delta_row_encoding_t::overhead’ may be used uninitialized [-Wmaybe-uninitialized]
+     2304 | struct delta_row_encoding_t
+          |        ^~~~~~~~~~~~~~~~~~~~
+    ../src/hb-ot-var-common.hh: In member function ‘bool OT::item_variations_t::as_item_varstore(bool, bool)’:
+    ../src/hb-ot-var-common.hh:1981:30: note: ‘obj.OT::delta_row_encoding_t::overhead’ was declared here
+     1981 |         delta_row_encoding_t obj;
+
+ src/hb-ot-layout-common.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 4b3aa0104ea4c7859095b0e78662e440483068da
+Merge: da2c59d71 ef4ff1d6a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Sep 20 14:37:42 2023 -0600
+
+    Merge pull request #4410 from googlefonts/HVAR_instance
+    
+    [instancer] instantiate HVAR/VVAR
+
+commit da2c59d71f687c38a29389d81d6d6f911994c403
+Author: Thomas Petillon <tpetillon at gmail.com>
+Date:   Tue Sep 19 17:01:04 2023 +0200
+
+    [instancer] Delete redundant code block in cvar subsetting
+    
+    That case is handled in hb-subset.cc.
+    
+    It also made compilation with HB_NO_VAR fail because it accessed table.fvar.
+
+ src/hb-ot-var-cvar-table.hh | 13 -------------
+ 1 file changed, 13 deletions(-)
+
+commit 284889b0317c317ae00fe1a6e32db1f9213cb5e2
+Author: Thomas Petillon <tpetillon at gmail.com>
+Date:   Wed Sep 20 20:17:48 2023 +0200
+
+    [subset] Drop fvar, avar, cvar, MVAR tables when in HB_NO_VAR mode
+
+ src/hb-subset.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit ef4ff1d6a4f2343440e278ef1177b07f6af8f5dc
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Sep 20 11:35:33 2023 -0700
+
+    [instancer] make varstore items sorting method match fonttool's
+    
+    Also update expected tests
+
+ src/hb-ot-var-common.hh                            |   9 ++++++++-
+ ...n-all-codepoint.wght=200-300-500,wdth=80-90.ttf | Bin 8432 -> 8432 bytes
+ ...s.retain-all-codepoint.wght=300-600,wdth=85.ttf | Bin 7336 -> 7336 bytes
+ ...n-all-codepoint.wght=200-300-500,wdth=80-90.ttf | Bin 7484 -> 7484 bytes
+ ...s.retain-all-codepoint.wght=300-600,wdth=85.ttf | Bin 6848 -> 6848 bytes
+ ...odepoint.wght=200-600,wdth=80-90,CTGR=20-60.ttf | Bin 4108 -> 4108 bytes
+ ...ariations.retain-all-codepoint.wght=300-600.ttf | Bin 6616 -> 6616 bytes
+ ...ariations.retain-all-codepoint.wght=300-600.ttf | Bin 197056 -> 197056 bytes
+ ...ariations.retain-all-codepoint.wght=500-800.ttf | Bin 145004 -> 145004 bytes
+ 9 files changed, 8 insertions(+), 1 deletion(-)
+
+commit b5f7ca1ab49b3842d3c2ba4ac9fbd0531378d7b6
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Sep 20 11:28:15 2023 -0700
+
+    [instancer] fix bots
+
+ src/hb-ot-var-common.hh     | 2 +-
+ src/hb-ot-var-hvar-table.hh | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit 5ec21d4af4bc620cb58ff715e2a66288128c8d6f
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Sep 20 09:31:03 2023 -0700
+
+    [instancer] fix delta_row_encoding_t constructor
+    
+    always move chars_
+
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 2d2818c0963d44cde07e612c5310ac2dc85cc846
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Sep 20 10:30:47 2023 -0700
+
+    [instancer] update expected tests to include HVAR/VVAR tables
+
+ ...n-all-codepoint.wght=200-300-500,wdth=80-90.ttf | Bin 8256 -> 8432 bytes
+ ...s.retain-all-codepoint.wght=300-600,wdth=85.ttf | Bin 7244 -> 7336 bytes
+ ...n-all-codepoint.wght=200-300-500,wdth=80-90.ttf | Bin 7292 -> 7484 bytes
+ ...s.retain-all-codepoint.wght=300-600,wdth=85.ttf | Bin 6760 -> 6848 bytes
+ ...odepoint.wght=200-600,wdth=80-90,CTGR=20-60.ttf | Bin 3800 -> 4108 bytes
+ ...ariations.retain-all-codepoint.wght=300-600.ttf | Bin 6280 -> 6616 bytes
+ ...ariations.retain-all-codepoint.wght=500-800.ttf | Bin 6760 -> 7096 bytes
+ ...ariations.retain-all-codepoint.wght=300-600.ttf | Bin 194432 -> 197056 bytes
+ ...ariations.retain-all-codepoint.wght=500-800.ttf | Bin 143840 -> 145004 bytes
+ .../profiles/no-tables-with-item-variations.txt    |   2 +-
+ 10 files changed, 1 insertion(+), 1 deletion(-)
+
+commit 58e5d45de886319104007249d7e6a2b5b6584247
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Sep 19 10:33:32 2023 -0700
+
+    [instancer] instantiate HVAR/VVAR
+
+ src/hb-ot-var-hvar-table.hh | 87 ++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 83 insertions(+), 4 deletions(-)
+
+commit e81ad14dba9ddc70aca11a46242cfc20b593e878
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Sep 19 13:23:58 2023 -0700
+
+    [instancer] change optimize() to as_item_varstore()
+    
+    which allows another option to skip optimization
+
+ src/hb-ot-var-common.hh     | 23 +++++++++++++++++++++--
+ src/hb-ot-var-mvar-table.hh |  2 +-
+ src/test-item-varstore.cc   |  2 +-
+ 3 files changed, 23 insertions(+), 4 deletions(-)
+
+commit 97d0e7a19f5e341a77c156faaa37eed8df6d8db7
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Sep 19 11:25:14 2023 -0700
+
+    [instancer] add inner_maps as optional argument when creating item_variations_t
+    
+    This allows that we create item_variations_t with only a subset of
+    the original varstore
+
+ src/hb-ot-var-common.hh | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+commit 005582e0cb80821fb5bbbdfb6cef4be05078d060
+Merge: d69813374 da9b83891
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Sep 20 09:10:10 2023 -0600
+
+    Merge pull request #4370 from 2xsaiko/outgoing/cmake-now-for-real
+    
+    Re-do and clean up CMake support, making it use relocatable paths
+
+commit da9b838910e62825717a8b2de8ce9c92e396136e
+Author: Marco Rebhan <me at dblsaiko.net>
+Date:   Tue Aug 8 14:33:03 2023 +0200
+
+    Re-do and clean up CMake support, making it use relocatable paths
+    
+    Closes #4025.
+
+ meson.build                  | 21 ++++++++++
+ meson_options.txt            |  4 ++
+ src/Makefile.am              |  2 +-
+ src/harfbuzz-config.cmake.in | 97 ++++++++------------------------------------
+ src/meson.build              | 92 ++++++++++++++++++++++++++++++++++++++---
+ src/relative_to.py           |  6 +++
+ 6 files changed, 135 insertions(+), 87 deletions(-)
+
+commit d698133743caffe9611b57137cd5027ce076613f
+Merge: 0967a3e24 c330c2917
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Sep 19 13:30:43 2023 -0600
+
+    Merge pull request #4393 from googlefonts/instantiate_item_varstore
+    
+    [instancer] instantiate item varstore
+
+commit b5a1c2b483263896e563402cd285a46229e42f3c
+Author: Marco Rebhan <me at dblsaiko.net>
+Date:   Mon Aug 7 01:55:10 2023 +0200
+
+    Revert "Pass through absolute paths to cmake config directly"
+    
+    This reverts commit db292f6f0238581a489aa8cddc585129b6e920cd.
+
+ src/harfbuzz-config.cmake.in | 44 ++++++++++++++++++++++++++++++++++++--------
+ src/meson.build              |  4 ++--
+ 2 files changed, 38 insertions(+), 10 deletions(-)
+
+commit c330c2917524ad8a15340e5fa1df5a57a1409efa
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Mon Sep 18 12:14:21 2023 -0700
+
+    [instancer] add a unit testcase for instantiating item variations
+
+ src/Makefile.am           |  5 ++++
+ src/meson.build           |  1 +
+ src/test-item-varstore.cc | 66 +++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 72 insertions(+)
+
+commit 7741fa329998f23ef1495f9828c919ae2f6ada1e
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Mon Sep 18 10:44:47 2023 -0700
+
+    [instancer] bug fix: dont add duplicate rows into delta_row_encoding_t
+    
+    Also fix compile_varidx_map()
+
+ src/hb-ot-var-common.hh | 57 ++++++++++++++++++++++++++++---------------------
+ 1 file changed, 33 insertions(+), 24 deletions(-)
+
+commit 6c658b410593e15416a800daf8fd0492c69d9ba5
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Fri Sep 15 11:49:47 2023 -0700
+
+    [instancer] bug fix
+
+ src/hb-ot-var-common.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 11cc47964695661c2a0e8ba24d80304ac1457ab6
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Mon Sep 11 09:57:14 2023 -0700
+
+    [instancer] fix columns and get_chars_overhead() in delta_row_encoding_t
+    
+    make columns a vector of uint8_t so it supports more than 32 columns
+
+ src/hb-ot-layout-common.hh | 29 +++++++++++++++++++----------
+ src/hb-ot-var-common.hh    |  1 +
+ 2 files changed, 20 insertions(+), 10 deletions(-)
+
+commit 6e49128afda813238cfbccd304db1c55ed98f0e5
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Fri Sep 1 10:27:40 2023 -0700
+
+    [instancer] always check and update default wght/width/slnt if necessary
+    
+    Sometimes default values in original file are incorrect, and if default value for an axis is not changed, then these values won't be updated
+
+ src/hb-ot-os2-table.hh                             |  23 ++++++++-------------
+ src/hb-ot-post-table.hh                            |  10 ++++-----
+ ...ariations.retain-all-codepoint.wght=300-600.ttf | Bin 0 -> 194432 bytes
+ ...ariations.retain-all-codepoint.wght=500-800.ttf | Bin 0 -> 143840 bytes
+ test/subset/data/tests/update_def_wght.tests       |  12 +++++++++++
+ test/subset/meson.build                            |   6 +++++-
+ 6 files changed, 31 insertions(+), 20 deletions(-)
+
+commit 7b5daff5eb347a29d9d9d59f2a41f938781d84de
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Aug 31 17:50:34 2023 -0700
+
+    [instancer] add tests for mvar partial instancing
+
+ ...-all-codepoint.wght=200-600,wdth=80-90,CTGR=20-60.ttf | Bin 0 -> 3800 bytes
+ ...item-variations.retain-all-codepoint.wght=300-600.ttf | Bin 0 -> 6280 bytes
+ ...item-variations.retain-all-codepoint.wght=500-800.ttf | Bin 0 -> 6760 bytes
+ .../data/profiles/no-tables-with-item-variations.txt     |   2 +-
+ test/subset/data/tests/mvar_partial_instance.tests       |  13 +++++++++++++
+ test/subset/meson.build                                  |   2 +-
+ 6 files changed, 15 insertions(+), 2 deletions(-)
+
+commit 45c2d05d0068ebd4fe5a9ea6ca38af5d8bab57c9
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Aug 31 15:45:22 2023 -0700
+
+    [instancer] add subset() for MVAR
+
+ src/hb-ot-var-mvar-table.hh | 61 ++++++++++++++++++++++++++++++++++++++++++++-
+ src/hb-subset-input.cc      |  1 -
+ src/hb-subset.cc            |  4 +++
+ 3 files changed, 64 insertions(+), 2 deletions(-)
+
+commit e4e1ac44f062078ed7da04321f8269df9f202c7b
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Aug 31 15:34:26 2023 -0700
+
+    [instancer] add serialize() for VariationStore
+    
+    Input region_list and encoding_rows are from item_variations_t
+
+ src/hb-ot-layout-common.hh | 106 +++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 106 insertions(+)
+
+commit 2326879229535f97ce099958e494005d1092ee5b
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Aug 31 15:28:06 2023 -0700
+
+    [instancer] add serialize() for VarRegionList
+    
+    The region list argument comes from item_variations_t.get_region_list()
+
+ src/hb-ot-layout-common.hh        | 47 +++++++++++++++++++++++++++++++++++++++
+ src/hb-subset-plan-member-list.hh |  2 ++
+ src/hb-subset-plan.cc             |  1 +
+ 3 files changed, 50 insertions(+)
+
+commit b153af8553a8cce1c93682b63a2b4756e44986be
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Aug 31 13:12:08 2023 -0700
+
+    [instancer] add optimize(), which optimizes varstore's storage
+
+ src/hb-ot-var-common.hh | 225 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 225 insertions(+)
+
+commit 3565ad815009ff74fc42dc5ef23ad8a2bf8fdecf
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Aug 31 13:07:54 2023 -0700
+
+    [instancer] add build_region_list() method
+
+ src/hb-ot-var-common.hh | 73 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 73 insertions(+)
+
+commit e4db29b102c78cec7c42469e01656c3ac5365863
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Aug 31 12:59:39 2023 -0700
+
+    [instancer] add instantiate() method
+    
+    Also make change_tuple_variations_axis_limits() deterministic, use
+    sorted vector instead of iterating map keys
+
+ src/hb-ot-var-common.hh | 44 +++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 37 insertions(+), 7 deletions(-)
+
+commit 5f058a93388caa0ce5c6d3800d7dbf97e3273dc8
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Aug 31 12:55:04 2023 -0700
+
+    [instancer] add create_from_item_varstore () method
+
+ src/hb-ot-layout-common.hh | 63 +++++++++++++++++++++++++++++++++++++++++++++-
+ src/hb-ot-var-common.hh    | 62 +++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 124 insertions(+), 1 deletion(-)
+
+commit 152448881fffbe46ae6ffb884351b86dcc7354d8
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Thu Aug 31 12:40:30 2023 -0700
+
+    [instancer] add struct definition item_variations_t
+    
+    And struct delta_row_encoding_t
+
+ src/hb-ot-layout-common.hh | 141 +++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-var-common.hh    |  47 +++++++++++++++
+ 2 files changed, 188 insertions(+)
+
 commit 0967a3e24ab5d79cc55dbe224652d8aabd942def
 Author: Khaled Hosny <khaled at aliftype.com>
 Date:   Mon Sep 18 21:18:27 2023 +0300

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2023-10-17 22:55:48 UTC (rev 68575)
@@ -1,3 +1,14 @@
+Overview of changes leading to 8.2.2
+Wednesday, October 18, 2023
+“From the river to the sea, Palestine will be free”
+====================================
+- Fix regression from 8.1.0 in shaping fonts with duplicate feature tags.
+- Fix regression from 8.2.0 in parsing CSS-style feature strings.
+- Variable fonts instanciation now handles more tables.
+- Various CMake build improvements.
+- various fixes to build without errors with gcc 4.9.2.
+
+
 Overview of changes leading to 8.2.1
 Monday, September 18, 2023
 ====================================

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2023-10-17 22:55:48 UTC (rev 68575)
@@ -1,6 +1,6 @@
 AC_PREREQ([2.64])
 AC_INIT([HarfBuzz],
-        [8.2.1],
+        [8.2.2],
         [https://github.com/harfbuzz/harfbuzz/issues/new],
         [harfbuzz],
         [http://harfbuzz.org/])

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build	2023-10-17 22:55:48 UTC (rev 68575)
@@ -1,6 +1,6 @@
 project('harfbuzz', 'c', 'cpp',
   meson_version: '>= 0.55.0',
-  version: '8.2.1',
+  version: '8.2.2',
   default_options: [
     'cpp_eh=none',          # Just to support msvc, we are passing -fno-exceptions also anyway
     # 'cpp_rtti=false',     # Do NOT enable, wraps inherit it and ICU needs RTTI
@@ -385,6 +385,26 @@
   endif
 endforeach
 
+# CMake support (package install dir)
+
+# Equivalent to configure_package_config_file(INSTALL_DESTINATION ...), see
+# https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html#command:configure_package_config_file.
+# In certain unusual packaging layouts such as Nixpkgs, the Harfbuzz package
+# is installed into two Nix store paths, "out" and "dev", where "out" contains
+# libraries only (i.e. lib/libharfbuzz.so) and "dev" contains development
+# files, i.e. include and lib/cmake. If CMake package files are installed to
+# "out", Nixpkgs will move them to "dev", which breaks assumptions about
+# our file paths. Since we need to figure out relative install paths here
+# to make a relocatable package, we do need to know the final path of our
+# CMake files to calculate the correct relative paths.
+# Of course, this still defaults to $libdir/cmake if unset, which works for
+# most packaging layouts.
+cmake_package_install_dir = get_option('cmakepackagedir')
+
+if cmake_package_install_dir == ''
+  cmake_package_install_dir = get_option('libdir') / 'cmake'
+endif
+
 subdir('src')
 
 if not get_option('utilities').disabled()
@@ -415,6 +435,7 @@
      'libdir': get_option('libdir'),
      'includedir': get_option('includedir'),
      'datadir': get_option('datadir'),
+     'cmakepackagedir': cmake_package_install_dir
     },
   'Unicode callbacks (you want at least one)':
     {'Builtin': true,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson_options.txt
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson_options.txt	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson_options.txt	2023-10-17 22:55:48 UTC (rev 68575)
@@ -46,3 +46,7 @@
   description: 'Build Ragel subproject if no suitable version is found')
 option('fuzzer_ldflags', type: 'string',
   description: 'Extra LDFLAGS used during linking of fuzzing binaries')
+
+# Install directory options
+option('cmakepackagedir', type: 'string',
+  description: 'CMake package configuration install directory')

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am	2023-10-17 22:55:48 UTC (rev 68575)
@@ -14,7 +14,7 @@
 
 EXTRA_DIST += harfbuzz.cc harfbuzz-subset.cc
 EXTRA_DIST += meson.build
-EXTRA_DIST += fix_get_types.py
+EXTRA_DIST += fix_get_types.py relative_to.py
 
 # Convenience targets:
 lib: $(BUILT_SOURCES) libharfbuzz.la
@@ -458,6 +458,7 @@
 	test-classdef-graph \
 	test-instancer-solver \
 	test-tuple-varstore \
+	test-item-varstore \
 	$(NULL)
 COMPILED_TESTS_CPPFLAGS = $(HBCFLAGS) -DMAIN -UNDEBUG
 COMPILED_TESTS_LDADD = libharfbuzz.la $(HBLIBS)
@@ -536,6 +537,10 @@
 test_tuple_varstore_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_tuple_varstore_LDADD = $(COMPILED_TESTS_LDADD)
 
+test_item_varstore_SOURCES = test-item-varstore.cc hb-subset-instancer-solver.cc hb-static.cc
+test_item_varstore_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
+test_item_varstore_LDADD = $(COMPILED_TESTS_LDADD)
+
 dist_check_SCRIPTS = \
 	check-c-linkage-decls.py \
 	check-externs.py \

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GDEF/GDEF.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GDEF/GDEF.hh	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GDEF/GDEF.hh	2023-10-17 22:55:48 UTC (rev 68575)
@@ -29,7 +29,7 @@
 #ifndef OT_LAYOUT_GDEF_GDEF_HH
 #define OT_LAYOUT_GDEF_GDEF_HH
 
-#include "../../../hb-ot-layout-common.hh"
+#include "../../../hb-ot-var-common.hh"
 
 #include "../../../hb-font.hh"
 #include "../../../hb-cache.hh"
@@ -204,17 +204,19 @@
     if (!c->serializer->embed (coordinate)) return_trace (false);
 
     unsigned varidx = (this+deviceTable).get_variation_index ();
-    if (c->plan->layout_variation_idx_delta_map.has (varidx))
+    hb_pair_t<unsigned, int> *new_varidx_delta;
+    if (!c->plan->layout_variation_idx_delta_map.has (varidx, &new_varidx_delta))
+      return_trace (false);
+
+    uint32_t new_varidx = hb_first (*new_varidx_delta);
+    int delta = hb_second (*new_varidx_delta);
+    if (delta != 0)
     {
-      int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (varidx));
-      if (delta != 0)
-      {
-        if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW))
-          return_trace (false);
-      }
+      if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW))
+        return_trace (false);
     }
 
-    if (c->plan->all_axes_pinned)
+    if (new_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
       return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW));
 
     if (!c->serializer->embed (deviceTable))
@@ -602,6 +604,26 @@
 		  (version.to_int () < 0x00010003u || varStore.sanitize (c, this)));
   }
 
+  static void remap_varidx_after_instantiation (const hb_map_t& varidx_map,
+                                                hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>>& layout_variation_idx_delta_map /* IN/OUT */)
+  {
+    /* varidx_map is empty which means varstore is empty after instantiation,
+     * no variations, map all varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX.
+     * varidx_map doesn't have original varidx, indicating delta row is all
+     * zeros, map varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX */
+    for (auto _ : layout_variation_idx_delta_map.iter_ref ())
+    {
+      /* old_varidx->(varidx, delta) mapping generated for subsetting, then this
+       * varidx is used as key of varidx_map during instantiation */
+      uint32_t varidx = _.second.first;
+      uint32_t *new_varidx;
+      if (varidx_map.has (varidx, &new_varidx))
+        _.second.first = *new_varidx;
+      else
+        _.second.first = HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
+    }
+  }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
@@ -624,6 +646,22 @@
     {
       if (c->plan->all_axes_pinned)
         out->varStore = 0;
+      else if (c->plan->normalized_coords)
+      {
+        if (varStore)
+        {
+          item_variations_t item_vars;
+          if (item_vars.instantiate (this+varStore, c->plan, true, true,
+                                     c->plan->gdef_varstore_inner_maps.as_array ()))
+            subset_varstore = out->varStore.serialize_serialize (c->serializer,
+                                                                 item_vars.has_long_word (),
+                                                                 c->plan->axis_tags,
+                                                                 item_vars.get_region_list (),
+                                                                 item_vars.get_vardata_encodings ());
+          remap_varidx_after_instantiation (item_vars.get_varidx_map (),
+                                            c->plan->layout_variation_idx_delta_map);
+        }
+      }
       else
         subset_varstore = out->varStore.serialize_subset (c, varStore, this, c->plan->gdef_varstore_inner_maps.as_array ());
     }
@@ -922,17 +960,32 @@
   { get_lig_caret_list ().collect_variation_indices (c); }
 
   void remap_layout_variation_indices (const hb_set_t *layout_variation_indices,
+				       const hb_vector_t<int>& normalized_coords,
+				       bool calculate_delta, /* not pinned at default */
+				       bool no_variations, /* all axes pinned */
 				       hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map /* OUT */) const
   {
     if (!has_var_store ()) return;
-    if (layout_variation_indices->is_empty ()) return;
-
+    const VariationStore &var_store = get_var_store ();
+    float *store_cache = var_store.create_cache ();
+    
     unsigned new_major = 0, new_minor = 0;
     unsigned last_major = (layout_variation_indices->get_min ()) >> 16;
     for (unsigned idx : layout_variation_indices->iter ())
     {
+      int delta = 0;
+      if (calculate_delta)
+        delta = roundf (var_store.get_delta (idx, normalized_coords.arrayZ,
+                                             normalized_coords.length, store_cache));
+
+      if (no_variations)
+      {
+        layout_variation_idx_delta_map->set (idx, hb_pair_t<unsigned, int> (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta));
+        continue;
+      }
+
       uint16_t major = idx >> 16;
-      if (major >= get_var_store ().get_sub_table_count ()) break;
+      if (major >= var_store.get_sub_table_count ()) break;
       if (major != last_major)
       {
 	new_minor = 0;
@@ -940,14 +993,11 @@
       }
 
       unsigned new_idx = (new_major << 16) + new_minor;
-      if (!layout_variation_idx_delta_map->has (idx))
-        continue;
-      int delta = hb_second (layout_variation_idx_delta_map->get (idx));
-
       layout_variation_idx_delta_map->set (idx, hb_pair_t<unsigned, int> (new_idx, delta));
       ++new_minor;
       last_major = major;
     }
+    var_store.destroy_cache (store_cache);
   }
 
   protected:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/AnchorFormat3.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/AnchorFormat3.hh	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/AnchorFormat3.hh	2023-10-17 22:55:48 UTC (rev 68575)
@@ -52,9 +52,14 @@
     if (unlikely (!c->serializer->embed (yCoordinate))) return_trace (false);
 
     unsigned x_varidx = xDeviceTable ? (this+xDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
-    if (c->plan->layout_variation_idx_delta_map.has (x_varidx))
+    if (x_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
     {
-      int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (x_varidx));
+      hb_pair_t<unsigned, int> *new_varidx_delta;
+      if (!c->plan->layout_variation_idx_delta_map.has (x_varidx, &new_varidx_delta))
+        return_trace (false);
+     
+      x_varidx = hb_first (*new_varidx_delta);
+      int delta = hb_second (*new_varidx_delta);
       if (delta != 0)
       {
         if (!c->serializer->check_assign (out->xCoordinate, xCoordinate + delta,
@@ -64,9 +69,14 @@
     }
 
     unsigned y_varidx = yDeviceTable ? (this+yDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
-    if (c->plan->layout_variation_idx_delta_map.has (y_varidx))
+    if (y_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
     {
-      int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (y_varidx));
+      hb_pair_t<unsigned, int> *new_varidx_delta;
+      if (!c->plan->layout_variation_idx_delta_map.has (y_varidx, &new_varidx_delta))
+        return_trace (false);
+
+      y_varidx = hb_first (*new_varidx_delta);
+      int delta = hb_second (*new_varidx_delta);
       if (delta != 0)
       {
         if (!c->serializer->check_assign (out->yCoordinate, yCoordinate + delta,
@@ -75,7 +85,10 @@
       }
     }
 
-    if (c->plan->all_axes_pinned)
+    /* in case that all axes are pinned or no variations after instantiation,
+     * both var_idxes will be mapped to HB_OT_LAYOUT_NO_VARIATIONS_INDEX */
+    if (x_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX &&
+        y_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
       return_trace (c->serializer->check_assign (out->format, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW));
 
     if (!c->serializer->embed (xDeviceTable)) return_trace (false);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPosFormat1.hh	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPosFormat1.hh	2023-10-17 22:55:48 UTC (rev 68575)
@@ -169,7 +169,7 @@
   {
     TRACE_SUBSET (this);
     const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
-    const hb_map_t &glyph_map = *c->plan->glyph_map;
+    const hb_map_t &glyph_map = c->plan->glyph_map_gsub;
 
     auto *out = c->serializer->start_embed (*this);
     if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
@@ -202,8 +202,9 @@
 
     auto new_ligature_coverage =
     + hb_iter (this + ligatureCoverage)
-    | hb_filter (glyphset)
+    | hb_take ((this + ligatureArray).len)
     | hb_map_retains_sorting (glyph_map)
+    | hb_filter ([] (hb_codepoint_t glyph) { return glyph != HB_MAP_VALUE_INVALID; })
     ;
 
     if (!out->ligatureCoverage.serialize_serialize (c->serializer, new_ligature_coverage))

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh	2023-10-17 22:55:48 UTC (rev 68575)
@@ -566,7 +566,7 @@
 
     update_distances ();
 
-    hb_priority_queue_t queue;
+    hb_priority_queue_t<int64_t> queue;
     hb_vector_t<vertex_t> &sorted_graph = vertices_scratch_;
     if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return;
     hb_vector_t<unsigned> id_map;
@@ -1369,7 +1369,7 @@
       vertices_.arrayZ[i].distance = hb_int_max (int64_t);
     vertices_.tail ().distance = 0;
 
-    hb_priority_queue_t queue;
+    hb_priority_queue_t<int64_t> queue;
     queue.insert (0, vertices_.length - 1);
 
     hb_vector_t<bool> visited;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/markbasepos-graph.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/markbasepos-graph.hh	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/markbasepos-graph.hh	2023-10-17 22:55:48 UTC (rev 68575)
@@ -217,7 +217,7 @@
 
     const unsigned base_coverage_id = c.graph.index_for_offset (this_index, &baseCoverage);
     const unsigned base_size =
-        OT::Layout::GPOS_impl::PairPosFormat1_3<SmallTypes>::min_size +
+        OT::Layout::GPOS_impl::MarkBasePosFormat1_2<SmallTypes>::min_size +
         MarkArray::min_size +
         AnchorMatrix::min_size +
         c.graph.vertices_[base_coverage_id].table_size ();
@@ -484,7 +484,7 @@
       return ((MarkBasePosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index);
 #ifndef HB_NO_BEYOND_64K
     case 2: HB_FALLTHROUGH;
-      // Don't split 24bit PairPos's.
+      // Don't split 24bit MarkBasePos's.
 #endif
     default:
       return hb_vector_t<unsigned> ();

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in	2023-10-17 22:55:48 UTC (rev 68575)
@@ -1,69 +1,32 @@
-set(_harfbuzz_libdir "@libdir@")
-set(_harfbuzz_includedir "@includedir@")
+ at PACKAGE_INIT@
 
-# Extract version information from libtool.
-set(_harfbuzz_version_info "@HB_LIBTOOL_VERSION_INFO@")
-string(REPLACE ":" ";" _harfbuzz_version_info "${_harfbuzz_version_info}")
-list(GET _harfbuzz_version_info 0
-  _harfbuzz_current)
-list(GET _harfbuzz_version_info 1
-  _harfbuzz_revision)
-list(GET _harfbuzz_version_info 2
-  _harfbuzz_age)
-unset(_harfbuzz_version_info)
+set_and_check(HARFBUZZ_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
 
-if ("@default_library@" MATCHES "static")
-  set(_harfbuzz_lib_prefix "lib")
-  set(_harfbuzz_lib_suffix ".a")
-else ()
-  if (APPLE)
-    set(_harfbuzz_lib_prefix "${CMAKE_SHARED_LIBRARY_PREFIX}")
-    set(_harfbuzz_lib_suffix ".0${CMAKE_SHARED_LIBRARY_SUFFIX}")
-  elseif (UNIX)
-    set(_harfbuzz_lib_prefix "${CMAKE_SHARED_LIBRARY_PREFIX}")
-    set(_harfbuzz_lib_suffix "${CMAKE_SHARED_LIBRARY_SUFFIX}.0.${_harfbuzz_current}.${_harfbuzz_revision}")
-  elseif (WIN32)
-    set(_harfbuzz_lib_prefix "${CMAKE_IMPORT_LIBRARY_PREFIX}")
-    set(_harfbuzz_lib_suffix "${CMAKE_IMPORT_LIBRARY_SUFFIX}")
-  else ()
-    # Unsupported.
-    set(harfbuzz_FOUND 0)
-  endif ()
-endif ()
-
 # Add the libraries.
-add_library(harfbuzz::harfbuzz SHARED IMPORTED)
+add_library(harfbuzz::harfbuzz @HB_LIBRARY_TYPE@ IMPORTED)
 set_target_properties(harfbuzz::harfbuzz PROPERTIES
-  INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_includedir}/harfbuzz"
-  IMPORTED_LOCATION "${_harfbuzz_libdir}/${_harfbuzz_lib_prefix}harfbuzz${_harfbuzz_lib_suffix}")
+  INTERFACE_INCLUDE_DIRECTORIES "@PACKAGE_INCLUDE_INSTALL_DIR@"
+  IMPORTED_LOCATION "@PACKAGE_CMAKE_INSTALL_LIBDIR@/@HB_LIB_PREFIX at harfbuzz@HB_LIB_SUFFIX@")
 
-add_library(harfbuzz::icu SHARED IMPORTED)
+add_library(harfbuzz::icu @HB_LIBRARY_TYPE@ IMPORTED)
 set_target_properties(harfbuzz::icu PROPERTIES
-  INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_includedir}/harfbuzz"
+  INTERFACE_INCLUDE_DIRECTORIES "@PACKAGE_INCLUDE_INSTALL_DIR@"
   INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz"
-  IMPORTED_LOCATION "${_harfbuzz_libdir}/${_harfbuzz_lib_prefix}harfbuzz-icu${_harfbuzz_lib_suffix}")
+  IMPORTED_LOCATION "@PACKAGE_CMAKE_INSTALL_LIBDIR@/@HB_LIB_PREFIX at harfbuzz-icu@HB_LIB_SUFFIX@")
 
-add_library(harfbuzz::subset SHARED IMPORTED)
+add_library(harfbuzz::subset @HB_LIBRARY_TYPE@ IMPORTED)
 set_target_properties(harfbuzz::subset PROPERTIES
-  INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_includedir}/harfbuzz"
+  INTERFACE_INCLUDE_DIRECTORIES "@PACKAGE_INCLUDE_INSTALL_DIR@"
   INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz"
-  IMPORTED_LOCATION "${_harfbuzz_libdir}/${_harfbuzz_lib_prefix}harfbuzz-subset${_harfbuzz_lib_suffix}")
+  IMPORTED_LOCATION "@PACKAGE_CMAKE_INSTALL_LIBDIR@/@HB_LIB_PREFIX at harfbuzz-subset@HB_LIB_SUFFIX@")
 
 # Only add the gobject library if it was built.
-set(_harfbuzz_have_gobject "@have_gobject@")
-if (_harfbuzz_have_gobject)
-  add_library(harfbuzz::gobject SHARED IMPORTED)
+if (@HB_HAVE_GOBJECT@)
+  add_library(harfbuzz::gobject @HB_LIBRARY_TYPE@ IMPORTED)
   set_target_properties(harfbuzz::gobject PROPERTIES
-    INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_includedir}/harfbuzz"
+    INTERFACE_INCLUDE_DIRECTORIES "@PACKAGE_INCLUDE_INSTALL_DIR@"
     INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz"
-    IMPORTED_LOCATION "${_harfbuzz_libdir}/${_harfbuzz_lib_prefix}harfbuzz-gobject${_harfbuzz_lib_suffix}")
+    IMPORTED_LOCATION "@PACKAGE_CMAKE_INSTALL_LIBDIR@/@HB_LIB_PREFIX at harfbuzz-gobject@HB_LIB_SUFFIX@")
 endif ()
 
-# Clean out variables we used in our scope.
-unset(_harfbuzz_lib_prefix)
-unset(_harfbuzz_lib_suffix)
-unset(_harfbuzz_current)
-unset(_harfbuzz_revision)
-unset(_harfbuzz_age)
-unset(_harfbuzz_includedir)
-unset(_harfbuzz_libdir)
+check_required_components(harfbuzz)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc	2023-10-17 22:55:48 UTC (rev 68575)
@@ -815,7 +815,7 @@
   }
 
   const char *p = *pp;
-  while (*pp < end && (**pp != ' ' && **pp != '=' && **pp != '['))
+  while (*pp < end && (**pp != ' ' && **pp != '=' && **pp != '[' && **pp != quote))
     (*pp)++;
 
   if (p == *pp || *pp - p > 4)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh	2023-10-17 22:55:48 UTC (rev 68575)
@@ -104,12 +104,12 @@
     hb_pair_t<const K &, V &> get_pair_ref() { return hb_pair_t<const K &, V &> (key, value); }
 
     uint32_t total_hash () const
-    { return (hash * 31) + hb_hash (value); }
+    { return (hash * 31u) + hb_hash (value); }
 
-    static constexpr bool is_trivial = std::is_trivially_constructible<K>::value &&
-				       std::is_trivially_destructible<K>::value &&
-				       std::is_trivially_constructible<V>::value &&
-				       std::is_trivially_destructible<V>::value;
+    static constexpr bool is_trivial = hb_is_trivially_constructible(K) &&
+				       hb_is_trivially_destructible(K) &&
+				       hb_is_trivially_constructible(V) &&
+				       hb_is_trivially_destructible(V);
   };
 
   hb_object_header_t header;
@@ -398,37 +398,37 @@
 
   auto iter_items () const HB_AUTO_RETURN
   (
-    + hb_iter (items, size ())
+    + hb_iter (items, this->size ())
     | hb_filter (&item_t::is_real)
   )
   auto iter_ref () const HB_AUTO_RETURN
   (
-    + iter_items ()
+    + this->iter_items ()
     | hb_map (&item_t::get_pair_ref)
   )
   auto iter () const HB_AUTO_RETURN
   (
-    + iter_items ()
+    + this->iter_items ()
     | hb_map (&item_t::get_pair)
   )
   auto keys_ref () const HB_AUTO_RETURN
   (
-    + iter_items ()
+    + this->iter_items ()
     | hb_map (&item_t::get_key)
   )
   auto keys () const HB_AUTO_RETURN
   (
-    + keys_ref ()
+    + this->keys_ref ()
     | hb_map (hb_ridentity)
   )
   auto values_ref () const HB_AUTO_RETURN
   (
-    + iter_items ()
+    + this->iter_items ()
     | hb_map (&item_t::get_value)
   )
   auto values () const HB_AUTO_RETURN
   (
-    + values_ref ()
+    + this->values_ref ()
     | hb_map (hb_ridentity)
   )
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh	2023-10-17 22:55:48 UTC (rev 68575)
@@ -191,27 +191,15 @@
   static return_t default_return_value () { return hb_empty_t (); }
 
   hb_set_t *layout_variation_indices;
-  hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *varidx_delta_map;
-  hb_vector_t<int> *normalized_coords;
-  const VariationStore *var_store;
   const hb_set_t *glyph_set;
   const hb_map_t *gpos_lookups;
-  float *store_cache;
 
   hb_collect_variation_indices_context_t (hb_set_t *layout_variation_indices_,
-					  hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *varidx_delta_map_,
-					  hb_vector_t<int> *normalized_coords_,
-					  const VariationStore *var_store_,
 					  const hb_set_t *glyph_set_,
-					  const hb_map_t *gpos_lookups_,
-					  float *store_cache_) :
+					  const hb_map_t *gpos_lookups_) :
 					layout_variation_indices (layout_variation_indices_),
-					varidx_delta_map (varidx_delta_map_),
-					normalized_coords (normalized_coords_),
-					var_store (var_store_),
 					glyph_set (glyph_set_),
-					gpos_lookups (gpos_lookups_),
-					store_cache (store_cache_) {}
+					gpos_lookups (gpos_lookups_) {}
 };
 
 template<typename OutputArray>
@@ -2300,6 +2288,158 @@
  * Item Variation Store
  */
 
+/* ported from fonttools (class _Encoding) */
+struct delta_row_encoding_t
+{
+  /* each byte represents a region, value is one of 0/1/2/4, which means bytes
+   * needed for this region */
+  hb_vector_t<uint8_t> chars;
+  unsigned width = 0;
+  hb_vector_t<uint8_t> columns;
+  unsigned overhead = 0;
+  hb_vector_t<const hb_vector_t<int>*> items;
+
+  delta_row_encoding_t () = default;
+  delta_row_encoding_t (hb_vector_t<uint8_t>&& chars_,
+                        const hb_vector_t<int>* row = nullptr) :
+                        delta_row_encoding_t ()
+
+  {
+    chars = std::move (chars_);
+    width = get_width ();
+    columns = get_columns ();
+    overhead = get_chars_overhead (columns);
+    if (row) items.push (row);
+  }
+
+  bool is_empty () const
+  { return !items; }
+
+  static hb_vector_t<uint8_t> get_row_chars (const hb_vector_t<int>& row)
+  {
+    hb_vector_t<uint8_t> ret;
+    if (!ret.alloc (row.length)) return ret;
+
+    bool long_words = false;
+
+    /* 0/1/2 byte encoding */
+    for (int i = row.length - 1; i >= 0; i--)
+    {
+      int v =  row.arrayZ[i];
+      if (v == 0)
+        ret.push (0);
+      else if (v > 32767 || v < -32768)
+      {
+        long_words = true;
+        break;
+      }
+      else if (v > 127 || v < -128)
+        ret.push (2);
+      else
+        ret.push (1);
+    }
+
+    if (!long_words)
+      return ret;
+
+    /* redo, 0/2/4 bytes encoding */
+    ret.reset ();
+    for (int i = row.length - 1; i >= 0; i--)
+    {
+      int v =  row.arrayZ[i];
+      if (v == 0)
+        ret.push (0);
+      else if (v > 32767 || v < -32768)
+        ret.push (4);
+      else
+        ret.push (2);
+    }
+    return ret;
+  }
+
+  inline unsigned get_width ()
+  {
+    unsigned ret = + hb_iter (chars)
+                   | hb_reduce (hb_add, 0u)
+                   ;
+    return ret;
+  }
+
+  hb_vector_t<uint8_t> get_columns ()
+  {
+    hb_vector_t<uint8_t> cols;
+    cols.alloc (chars.length);
+    for (auto v : chars)
+    {
+      uint8_t flag = v ? 1 : 0;
+      cols.push (flag);
+    }
+    return cols;
+  }
+
+  static inline unsigned get_chars_overhead (const hb_vector_t<uint8_t>& cols)
+  {
+    unsigned c = 4 + 6; // 4 bytes for LOffset, 6 bytes for VarData header
+    unsigned cols_bit_count = 0;
+    for (auto v : cols)
+      if (v) cols_bit_count++;
+    return c + cols_bit_count * 2;
+  }
+
+  unsigned get_gain () const
+  {
+    int count = items.length;
+    return hb_max (0, (int) overhead - count);
+  }
+
+  int gain_from_merging (const delta_row_encoding_t& other_encoding) const
+  {
+    int combined_width = 0;
+    for (unsigned i = 0; i < chars.length; i++)
+      combined_width += hb_max (chars.arrayZ[i], other_encoding.chars.arrayZ[i]);
+   
+    hb_vector_t<uint8_t> combined_columns;
+    combined_columns.alloc (columns.length);
+    for (unsigned i = 0; i < columns.length; i++)
+      combined_columns.push (columns.arrayZ[i] | other_encoding.columns.arrayZ[i]);
+    
+    int combined_overhead = get_chars_overhead (combined_columns);
+    int combined_gain = (int) overhead + (int) other_encoding.overhead - combined_overhead
+                        - (combined_width - (int) width) * items.length
+                        - (combined_width - (int) other_encoding.width) * other_encoding.items.length;
+
+    return combined_gain;
+  }
+
+  static int cmp (const void *pa, const void *pb)
+  {
+    const delta_row_encoding_t *a = (const delta_row_encoding_t *)pa;
+    const delta_row_encoding_t *b = (const delta_row_encoding_t *)pb;
+
+    int gain_a = a->get_gain ();
+    int gain_b = b->get_gain ();
+
+    if (gain_a != gain_b)
+      return gain_a - gain_b;
+
+    return (b->chars).as_array ().cmp ((a->chars).as_array ());
+  }
+
+  static int cmp_width (const void *pa, const void *pb)
+  {
+    const delta_row_encoding_t *a = (const delta_row_encoding_t *)pa;
+    const delta_row_encoding_t *b = (const delta_row_encoding_t *)pb;
+
+    if (a->width != b->width)
+      return (int) a->width - (int) b->width;
+
+    return (b->chars).as_array ().cmp ((a->chars).as_array ());
+  }
+
+  bool add_row (const hb_vector_t<int>* row)
+  { return items.push (row); }
+};
+
 struct VarRegionAxis
 {
   float evaluate (int coord) const
@@ -2334,6 +2474,12 @@
      * have to do that at runtime. */
   }
 
+  bool serialize (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed (this));
+  }
+
   public:
   F2DOT14	startCoord;
   F2DOT14	peakCoord;
@@ -2391,6 +2537,47 @@
     return_trace (c->check_struct (this) && axesZ.sanitize (c, axisCount * regionCount));
   }
 
+  bool serialize (hb_serialize_context_t *c,
+                  const hb_vector_t<hb_tag_t>& axis_tags,
+                  const hb_vector_t<const hb_hashmap_t<hb_tag_t, Triple>*>& regions)
+  {
+    TRACE_SERIALIZE (this);
+    unsigned axis_count = axis_tags.length;
+    unsigned region_count = regions.length;
+    if (!axis_count || !region_count) return_trace (false);
+    if (unlikely (hb_unsigned_mul_overflows (axis_count * region_count,
+                                             VarRegionAxis::static_size))) return_trace (false);
+    if (unlikely (!c->extend_min (this))) return_trace (false);
+    axisCount = axis_count;
+    regionCount = region_count;
+
+    for (unsigned r = 0; r < region_count; r++)
+    {
+      const auto& region = regions[r];
+      for (unsigned i = 0; i < axis_count; i++)
+      {
+        hb_tag_t tag = axis_tags.arrayZ[i];
+        VarRegionAxis var_region_rec;
+        Triple *coords;
+        if (region->has (tag, &coords))
+        {
+          var_region_rec.startCoord.set_float (coords->minimum);
+          var_region_rec.peakCoord.set_float (coords->middle);
+          var_region_rec.endCoord.set_float (coords->maximum);
+        }
+        else
+        {
+          var_region_rec.startCoord.set_int (0);
+          var_region_rec.peakCoord.set_int (0);
+          var_region_rec.endCoord.set_int (0);
+        }
+        if (!var_region_rec.serialize (c))
+          return_trace (false);
+      }
+    }
+    return_trace (true);
+  }
+
   bool serialize (hb_serialize_context_t *c, const VarRegionList *src, const hb_inc_bimap_t &region_map)
   {
     TRACE_SERIALIZE (this);
@@ -2411,6 +2598,45 @@
     return_trace (true);
   }
 
+  bool get_var_region (unsigned region_index,
+                       const hb_map_t& axes_old_index_tag_map,
+                       hb_hashmap_t<hb_tag_t, Triple>& axis_tuples /* OUT */) const
+  {
+    if (region_index >= regionCount) return false;
+    const VarRegionAxis* axis_region = axesZ.arrayZ + (region_index * axisCount);
+    for (unsigned i = 0; i < axisCount; i++)
+    {
+      hb_tag_t *axis_tag;
+      if (!axes_old_index_tag_map.has (i, &axis_tag))
+        return false;
+
+      float min_val = axis_region->startCoord.to_float ();
+      float def_val = axis_region->peakCoord.to_float ();
+      float max_val = axis_region->endCoord.to_float ();
+
+      if (def_val != 0.f)
+        axis_tuples.set (*axis_tag, Triple (min_val, def_val, max_val));
+      axis_region++;
+    }
+    return !axis_tuples.in_error ();
+  }
+
+  bool get_var_regions (const hb_map_t& axes_old_index_tag_map,
+                        hb_vector_t<hb_hashmap_t<hb_tag_t, Triple>>& regions /* OUT */) const
+  {
+    if (!regions.alloc (regionCount))
+      return false;
+
+    for (unsigned i = 0; i < regionCount; i++)
+    {
+      hb_hashmap_t<hb_tag_t, Triple> axis_tuples;
+      if (!get_var_region (i, axes_old_index_tag_map, axis_tuples))
+        return false;
+      regions.push (std::move (axis_tuples));
+    }
+    return !regions.in_error ();
+  }
+
   unsigned int get_size () const { return min_size + VarRegionAxis::static_size * axisCount * regionCount; }
 
   public:
@@ -2430,6 +2656,9 @@
 
   unsigned int get_region_index_count () const
   { return regionIndices.len; }
+  
+  unsigned get_region_index (unsigned i) const
+  { return i >= regionIndices.len ? -1 : regionIndices[i]; }
 
   unsigned int get_row_size () const
   { return (wordCount () + regionIndices.len) * (longWords () ? 2 : 1); }
@@ -2506,6 +2735,81 @@
   }
 
   bool serialize (hb_serialize_context_t *c,
+                  bool has_long,
+                  const hb_vector_t<const hb_vector_t<int>*>& rows)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (this))) return_trace (false);
+    unsigned row_count = rows.length;
+    itemCount = row_count;
+
+    int min_threshold = has_long ? -65536 : -128;
+    int max_threshold = has_long ? +65535 : +127;
+    enum delta_size_t { kZero=0, kNonWord, kWord };
+    hb_vector_t<delta_size_t> delta_sz;
+    unsigned num_regions = rows[0]->length;
+    if (!delta_sz.resize (num_regions))
+      return_trace (false);
+
+    unsigned word_count = 0;
+    for (unsigned r = 0; r < num_regions; r++)
+    {
+      for (unsigned i = 0; i < row_count; i++)
+      {
+        int delta = rows[i]->arrayZ[r];
+        if (delta < min_threshold || delta > max_threshold)
+        {
+          delta_sz[r] = kWord;
+          word_count++;
+          break;
+        }
+        else if (delta != 0)
+        {
+          delta_sz[r] = kNonWord;
+        }
+      }
+    }
+
+    /* reorder regions: words and then non-words*/
+    unsigned word_index = 0;
+    unsigned non_word_index = word_count;
+    hb_map_t ri_map;
+    for (unsigned r = 0; r < num_regions; r++)
+    {
+      if (!delta_sz[r]) continue;
+      unsigned new_r = (delta_sz[r] == kWord)? word_index++ : non_word_index++;
+      if (!ri_map.set (new_r, r))
+        return_trace (false);
+    }
+
+    wordSizeCount = word_count | (has_long ? 0x8000u /* LONG_WORDS */ : 0);
+
+    unsigned ri_count = ri_map.get_population ();
+    regionIndices.len = ri_count;
+    if (unlikely (!c->extend (this))) return_trace (false);
+
+    for (unsigned r = 0; r < ri_count; r++)
+    {
+      hb_codepoint_t *idx;
+      if (!ri_map.has (r, &idx))
+        return_trace (false);
+      regionIndices[r] = *idx;
+    }
+
+    HBUINT8 *delta_bytes = get_delta_bytes ();
+    unsigned row_size = get_row_size ();
+    for (unsigned int i = 0; i < row_count; i++)
+    {
+      for (unsigned int r = 0; r < ri_count; r++)
+      {
+        int delta = rows[i]->arrayZ[ri_map[r]];
+        set_item_delta_fast (i, r, delta, delta_bytes, row_size);
+      }
+    }
+    return_trace (true);
+  }
+
+  bool serialize (hb_serialize_context_t *c,
 		  const VarData *src,
 		  const hb_inc_bimap_t &inner_map,
 		  const hb_inc_bimap_t &region_map)
@@ -2625,13 +2929,15 @@
     }
   }
 
-  protected:
+  public:
   const HBUINT8 *get_delta_bytes () const
   { return &StructAfter<HBUINT8> (regionIndices); }
 
+  protected:
   HBUINT8 *get_delta_bytes ()
   { return &StructAfter<HBUINT8> (regionIndices); }
 
+  public:
   int32_t get_item_delta_fast (unsigned int item, unsigned int region,
 			       const HBUINT8 *delta_bytes, unsigned row_size) const
   {
@@ -2662,6 +2968,7 @@
 				 get_row_size ());
   }
 
+  protected:
   void set_item_delta_fast (unsigned int item, unsigned int region, int32_t delta,
 			    HBUINT8 *delta_bytes, unsigned row_size)
   {
@@ -2704,6 +3011,7 @@
 
 struct VariationStore
 {
+  friend struct item_variations_t;
   using cache_t = VarRegionList::cache_t;
 
   cache_t *create_cache () const
@@ -2775,6 +3083,36 @@
   }
 
   bool serialize (hb_serialize_context_t *c,
+                  bool has_long,
+                  const hb_vector_t<hb_tag_t>& axis_tags,
+                  const hb_vector_t<const hb_hashmap_t<hb_tag_t, Triple>*>& region_list,
+                  const hb_vector_t<delta_row_encoding_t>& vardata_encodings)
+  {
+    TRACE_SERIALIZE (this);
+#ifdef HB_NO_VAR
+    return_trace (false);
+#endif
+    if (unlikely (!c->extend_min (this))) return_trace (false);
+    
+    format = 1;
+    if (!regions.serialize_serialize (c, axis_tags, region_list))
+      return_trace (false);
+
+    unsigned num_var_data = vardata_encodings.length;
+    if (!num_var_data) return_trace (false);
+    if (unlikely (!c->check_assign (dataSets.len, num_var_data,
+                                    HB_SERIALIZE_ERROR_INT_OVERFLOW)))
+      return_trace (false);
+
+    if (unlikely (!c->extend (dataSets))) return_trace (false);
+    for (unsigned i = 0; i < num_var_data; i++)
+      if (!dataSets[i].serialize_serialize (c, has_long, vardata_encodings[i].items))
+        return_trace (false);
+    
+    return_trace (true);
+  }
+
+  bool serialize (hb_serialize_context_t *c,
 		  const VariationStore *src,
 		  const hb_array_t <const hb_inc_bimap_t> &inner_maps)
   {
@@ -2903,6 +3241,22 @@
      return dataSets.len;
    }
 
+  const VarData& get_sub_table (unsigned i) const
+  {
+#ifdef HB_NO_VAR
+     return Null (VarData);
+#endif
+     return this+dataSets[i];
+  }
+
+  const VarRegionList& get_region_list () const
+  {
+#ifdef HB_NO_VAR
+     return Null (VarRegionList);
+#endif
+     return this+regions;
+  }
+
   protected:
   HBUINT16				format;
   Offset32To<VarRegionList>		regions;
@@ -3614,24 +3968,14 @@
     auto *out = c->embed (this);
     if (unlikely (!out)) return_trace (nullptr);
 
-    unsigned new_idx = hb_first (*v);
-    out->varIdx = new_idx;
+    if (!c->check_assign (out->varIdx, hb_first (*v), HB_SERIALIZE_ERROR_INT_OVERFLOW))
+      return_trace (nullptr);
     return_trace (out);
   }
 
   void collect_variation_index (hb_collect_variation_indices_context_t *c) const
-  {
-    c->layout_variation_indices->add (varIdx);
-    int delta = 0;
-    if (c->normalized_coords && c->var_store)
-      delta = roundf (c->var_store->get_delta (varIdx, c->normalized_coords->arrayZ,
-                                               c->normalized_coords->length, c->store_cache));
+  { c->layout_variation_indices->add (varIdx); }
 
-    /* set new varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX here, will remap
-     * varidx later*/
-    c->varidx_delta_map->set (varIdx, hb_pair_t<unsigned, int> (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta));
-  }
-
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc	2023-10-17 22:55:48 UTC (rev 68575)
@@ -1308,11 +1308,16 @@
   unsigned int count = l.get_feature_indexes (0, nullptr, nullptr);
   feature_map->alloc (count);
 
-  for (unsigned int i = 0; i < count; i++)
+  /* Loop in reverse, such that earlier entries win. That emulates
+   * a linear search, which seems to be what other implementations do.
+   * We found that with arialuni_t.ttf, the "ur" language system has
+   * duplicate features, and the earlier ones work but not later ones.
+   */
+  for (unsigned int i = count; i; i--)
   {
     unsigned feature_index = 0;
     unsigned feature_count = 1;
-    l.get_feature_indexes (i, &feature_count, &feature_index);
+    l.get_feature_indexes (i - 1, &feature_count, &feature_index);
     if (!feature_count)
       break;
     hb_tag_t feature_tag = g.get_feature_tag (feature_index);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh	2023-10-17 22:55:48 UTC (rev 68575)
@@ -246,24 +246,19 @@
     }
 #endif
 
-    if (c->plan->user_axes_location.has (HB_TAG ('w','g','h','t')) &&
-        !c->plan->pinned_at_default)
+    Triple *axis_range;
+    if (c->plan->user_axes_location.has (HB_TAG ('w','g','h','t'), &axis_range))
     {
-      float weight_class = c->plan->user_axes_location.get (HB_TAG ('w','g','h','t')).middle;
-      if (!c->serializer->check_assign (os2_prime->usWeightClass,
-                                        roundf (hb_clamp (weight_class, 1.0f, 1000.0f)),
-                                        HB_SERIALIZE_ERROR_INT_OVERFLOW))
-        return_trace (false);
+      unsigned weight_class = static_cast<unsigned> (roundf (hb_clamp (axis_range->middle, 1.0f, 1000.0f)));
+      if (os2_prime->usWeightClass != weight_class)
+        os2_prime->usWeightClass = weight_class;
     }
 
-    if (c->plan->user_axes_location.has (HB_TAG ('w','d','t','h')) &&
-        !c->plan->pinned_at_default)
+    if (c->plan->user_axes_location.has (HB_TAG ('w','d','t','h'), &axis_range))
     {
-      float width = c->plan->user_axes_location.get (HB_TAG ('w','d','t','h')).middle;
-      if (!c->serializer->check_assign (os2_prime->usWidthClass,
-                                        roundf (map_wdth_to_widthclass (width)),
-                                        HB_SERIALIZE_ERROR_INT_OVERFLOW))
-        return_trace (false);
+      unsigned width_class = static_cast<unsigned> (roundf (map_wdth_to_widthclass (axis_range->middle)));
+      if (os2_prime->usWidthClass != width_class)
+        os2_prime->usWidthClass = width_class;
     }
 
     if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh	2023-10-17 22:55:48 UTC (rev 68575)
@@ -113,12 +113,12 @@
     }
 #endif
 
-    if (c->plan->user_axes_location.has (HB_TAG ('s','l','n','t')) &&
-        !c->plan->pinned_at_default)
+    Triple *axis_range;
+    if (c->plan->user_axes_location.has (HB_TAG ('s','l','n','t'), &axis_range))
     {
-      float italic_angle = c->plan->user_axes_location.get (HB_TAG ('s','l','n','t')).middle;
-      italic_angle = hb_max (-90.f, hb_min (italic_angle, 90.f));
-      post_prime->italicAngle.set_float (italic_angle);
+      float italic_angle = hb_max (-90.f, hb_min (axis_range->middle, 90.f));
+      if (post_prime->italicAngle.to_float () != italic_angle)
+        post_prime->italicAngle.set_float (italic_angle);
     }
 
     if (glyph_names && version.major == 2)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh	2023-10-17 22:55:48 UTC (rev 68575)
@@ -27,6 +27,7 @@
 #define HB_OT_VAR_COMMON_HH
 
 #include "hb-ot-layout-common.hh"
+#include "hb-priority-queue.hh"
 
 
 namespace OT {
@@ -1171,14 +1172,71 @@
       return true;
     }
 
+    bool create_from_item_var_data (const VarData &var_data,
+                                    const hb_vector_t<hb_hashmap_t<hb_tag_t, Triple>>& regions,
+                                    const hb_map_t& axes_old_index_tag_map,
+                                    const hb_inc_bimap_t* inner_map = nullptr)
+    {
+      /* NULL offset, to keep original varidx valid, just return */
+      if (&var_data == &Null (VarData))
+        return true;
+  
+      unsigned num_regions = var_data.get_region_index_count ();
+      if (!tuple_vars.alloc (num_regions)) return false;
+  
+      unsigned item_count = inner_map ? inner_map->get_population () : var_data.get_item_count ();
+      unsigned row_size = var_data.get_row_size ();
+      const HBUINT8 *delta_bytes = var_data.get_delta_bytes ();
+  
+      for (unsigned r = 0; r < num_regions; r++)
+      {
+        /* In VarData, deltas are organized in rows, convert them into
+         * column(region) based tuples, resize deltas_x first */
+        tuple_delta_t tuple;
+        if (!tuple.deltas_x.resize (item_count, false) ||
+            !tuple.indices.resize (item_count, false))
+          return false;
+  
+        for (unsigned i = 0; i < item_count; i++)
+        {
+          tuple.indices.arrayZ[i] = true;
+          tuple.deltas_x.arrayZ[i] = var_data.get_item_delta_fast (inner_map ? inner_map->backward (i) : i,
+                                                                   r, delta_bytes, row_size);
+        }
+  
+        unsigned region_index = var_data.get_region_index (r);
+        if (region_index >= regions.length) return false;
+        tuple.axis_tuples = regions.arrayZ[region_index];
+
+        tuple_vars.push (std::move (tuple));
+      }
+      return !tuple_vars.in_error ();
+    }
+
     private:
-    void change_tuple_variations_axis_limits (const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location,
+    static int _cmp_axis_tag (const void *pa, const void *pb)
+    {
+      const hb_tag_t *a = (const hb_tag_t*) pa;
+      const hb_tag_t *b = (const hb_tag_t*) pb;
+      return (int)(*a) - (int)(*b);
+    }
+
+    bool change_tuple_variations_axis_limits (const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location,
                                               const hb_hashmap_t<hb_tag_t, TripleDistances>& axes_triple_distances)
     {
-      for (auto _ : normalized_axes_location)
+      /* sort axis_tag/axis_limits, make result deterministic */
+      hb_vector_t<hb_tag_t> axis_tags;
+      if (!axis_tags.alloc (normalized_axes_location.get_population ()))
+        return false;
+      for (auto t : normalized_axes_location.keys ())
+        axis_tags.push (t);
+
+      axis_tags.qsort (_cmp_axis_tag);
+      for (auto axis_tag : axis_tags)
       {
-        hb_tag_t axis_tag = _.first;
-        Triple axis_limit = _.second;
+        Triple *axis_limit;
+        if (!normalized_axes_location.has (axis_tag, &axis_limit))
+          return false;
         TripleDistances axis_triple_distances{1.f, 1.f};
         if (axes_triple_distances.has (axis_tag))
           axis_triple_distances = axes_triple_distances.get (axis_tag);
@@ -1186,12 +1244,13 @@
         hb_vector_t<tuple_delta_t> new_vars;
         for (const tuple_delta_t& var : tuple_vars)
         {
-          hb_vector_t<tuple_delta_t> out = var.change_tuple_var_axis_limit (axis_tag, axis_limit, axis_triple_distances);
+          hb_vector_t<tuple_delta_t> out = var.change_tuple_var_axis_limit (axis_tag, *axis_limit, axis_triple_distances);
           if (!out) continue;
+
           unsigned new_len = new_vars.length + out.length;
 
           if (unlikely (!new_vars.alloc (new_len, false)))
-          { fini (); return;}
+          { fini (); return false;}
 
           for (unsigned i = 0; i < out.length; i++)
             new_vars.push (std::move (out[i]));
@@ -1199,6 +1258,7 @@
         tuple_vars.fini ();
         tuple_vars = std::move (new_vars);
       }
+      return true;
     }
 
     /* merge tuple variations with overlapping tents */
@@ -1382,7 +1442,8 @@
                       contour_point_vector_t* contour_points = nullptr)
     {
       if (!tuple_vars) return true;
-      change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances);
+      if (!change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances))
+        return false;
       /* compute inferred deltas only for gvar */
       if (contour_points)
         if (!calc_inferred_deltas (*contour_points))
@@ -1705,6 +1766,463 @@
   DEFINE_SIZE_MIN (4);
 };
 
+using tuple_variations_t = TupleVariationData::tuple_variations_t;
+struct item_variations_t
+{
+  using region_t = const hb_hashmap_t<hb_tag_t, Triple>*;
+  private:
+  /* each subtable is decompiled into a tuple_variations_t, in which all tuples
+   * have the same num of deltas (rows) */
+  hb_vector_t<tuple_variations_t> vars;
+
+  /* original region list, decompiled from item varstore, used when rebuilding
+   * region list after instantiation */
+  hb_vector_t<hb_hashmap_t<hb_tag_t, Triple>> orig_region_list;
+
+  /* region list: vector of Regions, maintain the original order for the regions
+   * that existed before instantiate (), append the new regions at the end.
+   * Regions are stored in each tuple already, save pointers only.
+   * When converting back to item varstore, unused regions will be pruned */
+  hb_vector_t<region_t> region_list;
+
+  /* region -> idx map after instantiation and pruning unused regions */
+  hb_hashmap_t<region_t, unsigned> region_map;
+
+  /* all delta rows after instantiation */
+  hb_vector_t<hb_vector_t<int>> delta_rows;
+  /* final optimized vector of encoding objects used to assemble the varstore */
+  hb_vector_t<delta_row_encoding_t> encodings;
+
+  /* old varidxes -> new var_idxes map */
+  hb_map_t varidx_map;
+
+  /* has long words */
+  bool has_long = false;
+
+  public:
+  bool has_long_word () const
+  { return has_long; }
+
+  const hb_vector_t<region_t>& get_region_list () const
+  { return region_list; }
+
+  const hb_vector_t<delta_row_encoding_t>& get_vardata_encodings () const
+  { return encodings; }
+
+  const hb_map_t& get_varidx_map () const
+  { return varidx_map; }
+
+  bool instantiate (const VariationStore& varStore,
+                    const hb_subset_plan_t *plan,
+                    bool optimize=true,
+                    bool use_no_variation_idx=true,
+                    const hb_array_t <const hb_inc_bimap_t> inner_maps = hb_array_t<const hb_inc_bimap_t> ())
+  {
+    if (!create_from_item_varstore (varStore, plan->axes_old_index_tag_map, inner_maps))
+      return false;
+    if (!instantiate_tuple_vars (plan->axes_location, plan->axes_triple_distances))
+      return false;
+    return as_item_varstore (optimize, use_no_variation_idx);
+  }
+
+  /* keep below APIs public only for unit test: test-item-varstore */
+  bool create_from_item_varstore (const VariationStore& varStore,
+                                  const hb_map_t& axes_old_index_tag_map,
+                                  const hb_array_t <const hb_inc_bimap_t> inner_maps = hb_array_t<const hb_inc_bimap_t> ())
+  {
+    const VarRegionList& regionList = varStore.get_region_list ();
+    if (!regionList.get_var_regions (axes_old_index_tag_map, orig_region_list))
+      return false;
+
+    unsigned num_var_data = varStore.get_sub_table_count ();
+    if (inner_maps && inner_maps.length != num_var_data) return false;
+    if (!vars.alloc (num_var_data)) return false;
+
+    for (unsigned i = 0; i < num_var_data; i++)
+    {
+      if (inner_maps && !inner_maps.arrayZ[i].get_population ())
+          continue;
+      tuple_variations_t var_data_tuples;
+      if (!var_data_tuples.create_from_item_var_data (varStore.get_sub_table (i),
+                                                      orig_region_list,
+                                                      axes_old_index_tag_map,
+                                                      inner_maps ? &(inner_maps.arrayZ[i]) : nullptr))
+        return false;
+
+      vars.push (std::move (var_data_tuples));
+    }
+    return !vars.in_error ();
+  }
+
+  bool instantiate_tuple_vars (const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location,
+                               const hb_hashmap_t<hb_tag_t, TripleDistances>& axes_triple_distances)
+  {
+    for (tuple_variations_t& tuple_vars : vars)
+      if (!tuple_vars.instantiate (normalized_axes_location, axes_triple_distances))
+        return false;
+
+    if (!build_region_list ()) return false;
+    return true;
+  }
+
+  bool build_region_list ()
+  {
+    /* scan all tuples and collect all unique regions, prune unused regions */
+    hb_hashmap_t<region_t, unsigned> all_regions;
+    hb_hashmap_t<region_t, unsigned> used_regions;
+
+    /* use a vector when inserting new regions, make result deterministic */
+    hb_vector_t<region_t> all_unique_regions;
+    for (const tuple_variations_t& sub_table : vars)
+    {
+      for (const tuple_delta_t& tuple : sub_table.tuple_vars)
+      {
+        region_t r = &(tuple.axis_tuples);
+        if (!used_regions.has (r))
+        {
+          bool all_zeros = true;
+          for (float d : tuple.deltas_x)
+          {
+            int delta = (int) roundf (d);
+            if (delta != 0)
+            {
+              all_zeros = false;
+              break;
+            }
+          }
+          if (!all_zeros)
+          {
+            if (!used_regions.set (r, 1))
+              return false;
+          }
+        }
+        if (all_regions.has (r))
+          continue;
+        if (!all_regions.set (r, 1))
+          return false;
+        all_unique_regions.push (r);
+      }
+    }
+
+    if (!all_regions || !all_unique_regions) return false;
+    if (!region_list.alloc (all_regions.get_population ()))
+      return false;
+
+    unsigned idx = 0;
+    /* append the original regions that pre-existed */
+    for (const auto& r : orig_region_list)
+    {
+      if (!all_regions.has (&r) || !used_regions.has (&r))
+        continue;
+
+      region_list.push (&r);
+      if (!region_map.set (&r, idx))
+        return false;
+      all_regions.del (&r);
+      idx++;
+    }
+
+    /* append the new regions at the end */
+    for (const auto& r: all_unique_regions)
+    {
+      if (!all_regions.has (r) || !used_regions.has (r))
+        continue;
+      region_list.push (r);
+      if (!region_map.set (r, idx))
+        return false;
+      all_regions.del (r);
+      idx++;
+    }
+    return (!region_list.in_error ()) && (!region_map.in_error ());
+  }
+
+  /* main algorithm ported from fonttools VarStore_optimize() method, optimize
+   * varstore by default */
+
+  struct combined_gain_idx_tuple_t
+  {
+    int gain;
+    unsigned idx_1;
+    unsigned idx_2;
+
+    combined_gain_idx_tuple_t () = default;
+    combined_gain_idx_tuple_t (int gain_, unsigned i, unsigned j)
+        :gain (gain_), idx_1 (i), idx_2 (j) {}
+
+    bool operator < (const combined_gain_idx_tuple_t& o)
+    {
+      if (gain != o.gain)
+        return gain < o.gain;
+
+      if (idx_1 != o.idx_1)
+        return idx_1 < o.idx_1;
+
+      return idx_2 < o.idx_2;
+    }
+
+    bool operator <= (const combined_gain_idx_tuple_t& o)
+    {
+      if (*this < o) return true;
+      return gain == o.gain && idx_1 == o.idx_1 && idx_2 == o.idx_2;
+    }
+  };
+
+  bool as_item_varstore (bool optimize=true, bool use_no_variation_idx=true)
+  {
+    if (!region_list) return false;
+    unsigned num_cols = region_list.length;
+    /* pre-alloc a 2D vector for all sub_table's VarData rows */
+    unsigned total_rows = 0;
+    for (unsigned major = 0; major < vars.length; major++)
+    {
+      const tuple_variations_t& tuples = vars[major];
+      /* all tuples in each sub_table should have same num of deltas(num rows) */
+      total_rows += tuples.tuple_vars[0].deltas_x.length;
+    }
+
+    if (!delta_rows.resize (total_rows)) return false;
+    /* init all rows to [0]*num_cols */
+    for (unsigned i = 0; i < total_rows; i++)
+      if (!(delta_rows[i].resize (num_cols))) return false;
+
+    /* old VarIdxes -> full encoding_row mapping */
+    hb_hashmap_t<unsigned, const hb_vector_t<int>*> front_mapping;
+    unsigned start_row = 0;
+    hb_vector_t<delta_row_encoding_t> encoding_objs;
+    hb_hashmap_t<hb_vector_t<uint8_t>, unsigned> chars_idx_map;
+
+    /* delta_rows map, used for filtering out duplicate rows */
+    hb_hashmap_t<const hb_vector_t<int>*, unsigned> delta_rows_map;
+    for (unsigned major = 0; major < vars.length; major++)
+    {
+      /* deltas are stored in tuples(column based), convert them back into items
+       * (row based) delta */
+      const tuple_variations_t& tuples = vars[major];
+      unsigned num_rows = tuples.tuple_vars[0].deltas_x.length;
+      for (const tuple_delta_t& tuple: tuples.tuple_vars)
+      {
+        if (tuple.deltas_x.length != num_rows)
+          return false;
+
+        /* skip unused regions */
+        unsigned *col_idx;
+        if (!region_map.has (&(tuple.axis_tuples), &col_idx))
+          continue;
+
+        for (unsigned i = 0; i < num_rows; i++)
+        {
+          int rounded_delta = roundf (tuple.deltas_x[i]);
+          delta_rows[start_row + i][*col_idx] += rounded_delta;
+          if ((!has_long) && (rounded_delta < -65536 || rounded_delta > 65535))
+            has_long = true;
+        }
+      }
+
+      if (!optimize)
+      {
+        /* assemble a delta_row_encoding_t for this subtable, skip optimization so
+         * chars is not initialized, we only need delta rows for serialization */
+        delta_row_encoding_t obj;
+        for (unsigned r = start_row; r < start_row + num_rows; r++)
+          obj.add_row (&(delta_rows.arrayZ[r]));
+
+        encodings.push (std::move (obj));
+        start_row += num_rows;
+        continue;
+      }
+
+      for (unsigned minor = 0; minor < num_rows; minor++)
+      {
+        const hb_vector_t<int>& row = delta_rows[start_row + minor];
+        if (use_no_variation_idx)
+        {
+          bool all_zeros = true;
+          for (int delta : row)
+          {
+            if (delta != 0)
+            {
+              all_zeros = false;
+              break;
+            }
+          }
+          if (all_zeros)
+            continue;
+        }
+
+        if (!front_mapping.set ((major<<16) + minor, &row))
+          return false;
+
+        hb_vector_t<uint8_t> chars = delta_row_encoding_t::get_row_chars (row);
+        if (!chars) return false;
+
+        if (delta_rows_map.has (&row))
+          continue;
+
+        delta_rows_map.set (&row, 1);
+        unsigned *obj_idx;
+        if (chars_idx_map.has (chars, &obj_idx))
+        {
+          delta_row_encoding_t& obj = encoding_objs[*obj_idx];
+          if (!obj.add_row (&row))
+            return false;
+        }
+        else
+        {
+          if (!chars_idx_map.set (chars, encoding_objs.length))
+            return false;
+          delta_row_encoding_t obj (std::move (chars), &row);
+          encoding_objs.push (std::move (obj));
+        }
+      }
+
+      start_row += num_rows;
+    }
+
+    /* return directly if no optimization, maintain original VariationIndex so
+     * varidx_map would be empty */
+    if (!optimize) return !encodings.in_error ();
+
+    /* sort encoding_objs */
+    encoding_objs.qsort ();
+
+    /* main algorithm: repeatedly pick 2 best encodings to combine, and combine
+     * them */
+    hb_priority_queue_t<combined_gain_idx_tuple_t> queue;
+    unsigned num_todos = encoding_objs.length;
+    for (unsigned i = 0; i < num_todos; i++)
+    {
+      for (unsigned j = i + 1; j < num_todos; j++)
+      {
+        int combining_gain = encoding_objs.arrayZ[i].gain_from_merging (encoding_objs.arrayZ[j]);
+        if (combining_gain > 0)
+          queue.insert (combined_gain_idx_tuple_t (-combining_gain, i, j), 0);
+      }
+    }
+
+    hb_set_t removed_todo_idxes;
+    while (queue)
+    {
+      auto t = queue.pop_minimum ().first;
+      unsigned i = t.idx_1;
+      unsigned j = t.idx_2;
+
+      if (removed_todo_idxes.has (i) || removed_todo_idxes.has (j))
+        continue;
+
+      delta_row_encoding_t& encoding = encoding_objs.arrayZ[i];
+      delta_row_encoding_t& other_encoding = encoding_objs.arrayZ[j];
+
+      removed_todo_idxes.add (i);
+      removed_todo_idxes.add (j);
+
+      hb_vector_t<uint8_t> combined_chars;
+      if (!combined_chars.alloc (encoding.chars.length))
+        return false;
+
+      for (unsigned idx = 0; idx < encoding.chars.length; idx++)
+      {
+        uint8_t v = hb_max (encoding.chars.arrayZ[idx], other_encoding.chars.arrayZ[idx]);
+        combined_chars.push (v);
+      }
+
+      delta_row_encoding_t combined_encoding_obj (std::move (combined_chars));
+      for (const auto& row : hb_concat (encoding.items, other_encoding.items))
+        combined_encoding_obj.add_row (row);
+
+      for (unsigned idx = 0; idx < encoding_objs.length; idx++)
+      {
+        if (removed_todo_idxes.has (idx)) continue;
+
+        const delta_row_encoding_t& obj = encoding_objs.arrayZ[idx];
+        if (obj.chars == combined_chars)
+        {
+          for (const auto& row : obj.items)
+            combined_encoding_obj.add_row (row);
+
+          removed_todo_idxes.add (idx);
+          continue;
+        }
+
+        int combined_gain = combined_encoding_obj.gain_from_merging (obj);
+        if (combined_gain > 0)
+          queue.insert (combined_gain_idx_tuple_t (-combined_gain, idx, encoding_objs.length), 0);
+      }
+
+      encoding_objs.push (std::move (combined_encoding_obj));
+    }
+
+    int num_final_encodings = (int) encoding_objs.length - (int) removed_todo_idxes.get_population ();
+    if (num_final_encodings <= 0) return false;
+
+    if (!encodings.alloc (num_final_encodings)) return false;
+    for (unsigned i = 0; i < encoding_objs.length; i++)
+    {
+      if (removed_todo_idxes.has (i)) continue;
+      encodings.push (std::move (encoding_objs.arrayZ[i]));
+    }
+
+    /* sort again based on width, make result deterministic */
+    encodings.qsort (delta_row_encoding_t::cmp_width);
+
+    return compile_varidx_map (front_mapping);
+  }
+
+  private:
+  /* compile varidx_map for one VarData subtable (index specified by major) */
+  bool compile_varidx_map (const hb_hashmap_t<unsigned, const hb_vector_t<int>*>& front_mapping)
+  {
+    /* full encoding_row -> new VarIdxes mapping */
+    hb_hashmap_t<const hb_vector_t<int>*, unsigned> back_mapping;
+
+    for (unsigned major = 0; major < encodings.length; major++)
+    {
+      delta_row_encoding_t& encoding = encodings[major];
+      /* just sanity check, this shouldn't happen */
+      if (encoding.is_empty ())
+        return false;
+  
+      unsigned num_rows = encoding.items.length;
+  
+      /* sort rows, make result deterministic */
+      encoding.items.qsort (_cmp_row);
+  
+      /* compile old to new var_idxes mapping */
+      for (unsigned minor = 0; minor < num_rows; minor++)
+      {
+        unsigned new_varidx = (major << 16) + minor;
+        back_mapping.set (encoding.items.arrayZ[minor], new_varidx);
+      }
+    }
+
+    for (auto _ : front_mapping.iter ())
+    {
+      unsigned old_varidx = _.first;
+      unsigned *new_varidx;
+      if (back_mapping.has (_.second, &new_varidx))
+        varidx_map.set (old_varidx, *new_varidx);
+      else
+        varidx_map.set (old_varidx, HB_OT_LAYOUT_NO_VARIATIONS_INDEX);
+    }
+    return !varidx_map.in_error ();
+  }
+
+  static int _cmp_row (const void *pa, const void *pb)
+  {
+    /* compare pointers of vectors(const hb_vector_t<int>*) that represent a row */
+    const hb_vector_t<int>** a = (const hb_vector_t<int>**) pa;
+    const hb_vector_t<int>** b = (const hb_vector_t<int>**) pb;
+
+    for (unsigned i = 0; i < (*b)->length; i++)
+    {
+      int va = (*a)->arrayZ[i];
+      int vb = (*b)->arrayZ[i];
+      if (va != vb)
+        return va < vb ? -1 : 1;
+    }
+    return 0;
+  }
+};
+
 } /* namespace OT */
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-cvar-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-cvar-table.hh	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-cvar-table.hh	2023-10-17 22:55:48 UTC (rev 68575)
@@ -54,6 +54,7 @@
 
   bool decompile_tuple_variations (unsigned axis_count,
                                    unsigned point_count,
+                                   hb_blob_t *blob,
                                    bool is_gvar,
                                    const hb_map_t *axes_old_index_tag_map,
                                    TupleVariationData::tuple_variations_t& tuple_variations /* OUT */) const
@@ -60,8 +61,7 @@
   {
     hb_vector_t<unsigned> shared_indices;
     TupleVariationData::tuple_iterator_t iterator;
-    unsigned var_data_length = tupleVariationData.get_size (axis_count);
-    hb_bytes_t var_data_bytes = hb_bytes_t (reinterpret_cast<const char*> (get_tuple_var_data ()), var_data_length);
+    hb_bytes_t var_data_bytes = blob->as_bytes ().sub_array (4);
     if (!TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, this,
                                                  shared_indices, &iterator))
       return false;
@@ -143,19 +143,6 @@
     if (c->plan->all_axes_pinned)
       return_trace (false);
 
-    /* subset() for cvar is called by partial instancing only, we always pass
-     * through cvar table in other cases */
-    if (!c->plan->normalized_coords)
-    {
-      unsigned axis_count = c->plan->source->table.fvar->get_axis_count ();
-      unsigned total_size = min_size + tupleVariationData.get_size (axis_count);
-      char *out = c->serializer->allocate_size<char> (total_size);
-      if (unlikely (!out)) return_trace (false);
-
-      hb_memcpy (out, this, total_size);
-      return_trace (true);
-    }
-
     OT::TupleVariationData::tuple_variations_t tuple_variations;
     unsigned axis_count = c->plan->axes_old_index_tag_map.get_population ();
 
@@ -164,7 +151,8 @@
     unsigned point_count = hb_blob_get_length (cvt_blob) / FWORD::static_size;
     hb_blob_destroy (cvt_blob);
 
-    if (!decompile_tuple_variations (axis_count, point_count, false,
+    if (!decompile_tuple_variations (axis_count, point_count,
+                                     c->source_blob, false,
                                      &(c->plan->axes_old_index_tag_map),
                                      tuple_variations))
       return_trace (false);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh	2023-10-17 22:55:48 UTC (rev 68575)
@@ -134,6 +134,36 @@
     }
   }
 
+  bool remap_after_instantiation (const hb_subset_plan_t *plan,
+                                  const hb_map_t& varidx_map)
+  {
+    /* recalculate bit_count after remapping */
+    outer_bit_count = 1;
+    inner_bit_count = 1;
+
+    for (const auto &_ : plan->new_to_old_gid_list)
+    {
+      hb_codepoint_t new_gid = _.first;
+      if (unlikely (new_gid >= map_count)) break;
+
+      uint32_t v = output_map.arrayZ[new_gid];
+      uint32_t *new_varidx;
+      if (!varidx_map.has (v, &new_varidx))
+        return false;
+
+      output_map.arrayZ[new_gid] = *new_varidx;
+
+      unsigned outer = (*new_varidx) >> 16;
+      unsigned bit_count = (outer == 0) ? 1 : hb_bit_storage (outer);
+      outer_bit_count = hb_max (bit_count, outer_bit_count);
+      
+      unsigned inner = (*new_varidx) & 0xFFFF;
+      bit_count = (inner == 0) ? 1 : hb_bit_storage (inner);
+      inner_bit_count = hb_max (bit_count, inner_bit_count);
+    }
+    return true;
+  }
+
   unsigned int get_inner_bit_count () const { return inner_bit_count; }
   unsigned int get_width ()           const { return ((outer_bit_count + inner_bit_count + 7) / 8); }
   unsigned int get_map_count ()       const { return map_count; }
@@ -211,6 +241,16 @@
       index_map_plans[i].remap (index_maps[i], outer_map, inner_maps, plan);
   }
 
+  /* remap */
+  bool remap_index_map_plans (const hb_subset_plan_t *plan,
+                              const hb_map_t& varidx_map)
+  {
+    for (unsigned i = 0; i < index_map_plans.length; i++)
+      if (!index_map_plans[i].remap_after_instantiation (plan, varidx_map))
+        return false;
+    return true;
+  }
+
   void fini ()
   {
     for (unsigned int i = 0; i < inner_sets.length; i++)
@@ -289,6 +329,9 @@
   bool _subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
+    if (c->plan->all_axes_pinned)
+      return_trace (false);
+
     hvarvvar_subset_plan_t	hvar_plan;
     hb_vector_t<const DeltaSetIndexMap *>
 				index_maps;
@@ -302,11 +345,37 @@
     out->version.major = 1;
     out->version.minor = 0;
 
-    if (unlikely (!out->varStore
-		      .serialize_serialize (c->serializer,
-					    hvar_plan.var_store,
-					    hvar_plan.inner_maps.as_array ())))
+    if (c->plan->normalized_coords)
+    {
+      item_variations_t item_vars;
+      if (!item_vars.instantiate (this+varStore, c->plan,
+                                  advMap == 0 ? false : true,
+                                  false, /* use_no_variation_idx = false */
+                                  hvar_plan.inner_maps.as_array ()))
+        return_trace (false);
+
+      if (!out->varStore.serialize_serialize (c->serializer,
+                                              item_vars.has_long_word (),
+                                              c->plan->axis_tags,
+                                              item_vars.get_region_list (),
+                                              item_vars.get_vardata_encodings ()))
+        return_trace (false);
+
+      /* if varstore is optimized, remap output_map */
+      if (advMap)
+      {
+        if (!hvar_plan.remap_index_map_plans (c->plan, item_vars.get_varidx_map ()))
+          return_trace (false);
+      }
+    }
+    else
+    {
+      if (unlikely (!out->varStore
+		    .serialize_serialize (c->serializer,
+					  hvar_plan.var_store,
+					  hvar_plan.inner_maps.as_array ())))
       return_trace (false);
+    }
 
     return_trace (out->T::serialize_index_maps (c->serializer,
 						hvar_plan.index_map_plans.as_array ()));

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh	2023-10-17 22:55:48 UTC (rev 68575)
@@ -27,7 +27,7 @@
 #ifndef HB_OT_VAR_MVAR_TABLE_HH
 #define HB_OT_VAR_MVAR_TABLE_HH
 
-#include "hb-ot-layout-common.hh"
+#include "hb-ot-var-common.hh"
 
 
 namespace OT {
@@ -41,6 +41,19 @@
     return_trace (c->check_struct (this));
   }
 
+  bool subset (hb_subset_context_t *c,
+               const hb_map_t& varidx_map) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+
+    hb_codepoint_t *new_idx;
+    return_trace (c->serializer->check_assign (out->varIdx,
+                                               (varidx_map.has (varIdx, &new_idx)) ? *new_idx : HB_OT_LAYOUT_NO_VARIATIONS_INDEX,
+                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
+  }
+
   public:
   Tag		valueTag;	/* Four-byte tag identifying a font-wide measure. */
   VarIdx	varIdx;		/* Outer/inner index into VariationStore item. */
@@ -73,6 +86,47 @@
 				  valueRecordSize));
   }
 
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+#ifdef HB_NO_VAR
+    return_trace (false);
+#endif
+
+    if (c->plan->all_axes_pinned)
+      return_trace (false);
+
+    MVAR *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    out->version = version;
+    out->reserved = reserved;
+    out->valueRecordSize = valueRecordSize;
+    out->valueRecordCount = valueRecordCount;
+
+    item_variations_t item_vars;
+    const VariationStore& src_var_store = this+varStore;
+
+    if (!item_vars.instantiate (src_var_store, c->plan))
+      return_trace (false);
+
+    /* serialize varstore */
+    if (!out->varStore.serialize_serialize (c->serializer, item_vars.has_long_word (),
+                                            c->plan->axis_tags,
+                                            item_vars.get_region_list (),
+                                            item_vars.get_vardata_encodings ()))
+      return_trace (false);
+
+    /* serialize value records array */
+    unsigned value_rec_count = valueRecordCount;
+    const VariationValueRecord *record = reinterpret_cast<const VariationValueRecord*> (valuesZ.arrayZ);
+    for (unsigned i = 0; i < value_rec_count; i++)
+    {
+      if (!record->subset (c, item_vars.get_varidx_map ())) return_trace (false);
+      record++;
+    }
+    return_trace (true);
+  }
+
   float get_var (hb_tag_t tag,
 		 const int *coords, unsigned int coord_count) const
   {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh	2023-10-17 22:55:48 UTC (rev 68575)
@@ -42,10 +42,11 @@
  * 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.
  */
+template <typename K>
 struct hb_priority_queue_t
 {
  private:
-  typedef hb_pair_t<int64_t, unsigned> item_t;
+  typedef hb_pair_t<K, unsigned> item_t;
   hb_vector_t<item_t> heap;
 
  public:
@@ -57,7 +58,7 @@
 #ifndef HB_OPTIMIZE_SIZE
   HB_ALWAYS_INLINE
 #endif
-  void insert (int64_t priority, unsigned value)
+  void insert (K priority, unsigned value)
   {
     heap.push (item_t (priority, value));
     if (unlikely (heap.in_error ())) return;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc	2023-10-17 22:55:48 UTC (rev 68575)
@@ -74,7 +74,6 @@
     HB_TAG ('p', 'r', 'e', 'p'),
     HB_TAG ('V', 'D', 'M', 'X'),
     HB_TAG ('D', 'S', 'I', 'G'),
-    HB_TAG ('M', 'V', 'A', 'R'),
   };
   sets.no_subset_tables->add_array (default_no_subset_tables,
 					 ARRAY_LENGTH (default_no_subset_tables));

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan-member-list.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan-member-list.hh	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan-member-list.hh	2023-10-17 22:55:48 UTC (rev 68575)
@@ -92,7 +92,7 @@
 HB_SUBSET_PLAN_MEMBER (hb_map_t, colr_palettes)
 
 //Old layout item variation index -> (New varidx, delta) mapping
-HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<unsigned, hb_pair_t E(<unsigned, int>)>), layout_variation_idx_delta_map)
+HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(<unsigned, hb_pair_t E(<unsigned, int>)>), layout_variation_idx_delta_map)
 
 //gdef varstore retained varidx mapping
 HB_SUBSET_PLAN_MEMBER (hb_vector_t<hb_inc_bimap_t>, gdef_varstore_inner_maps)
@@ -113,6 +113,8 @@
 
 //axis_index->axis_tag mapping in fvar axis array
 HB_SUBSET_PLAN_MEMBER (hb_map_t, axes_old_index_tag_map)
+//vector of retained axis tags in the order of axes given in the 'fvar' table
+HB_SUBSET_PLAN_MEMBER (hb_vector_t<hb_tag_t>, axis_tags)
 
 //hmtx metrics map: new gid->(advance, lsb)
 HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(<hb_codepoint_t, hb_pair_t E(<unsigned, int>)>), hmtx_map)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc	2023-10-17 22:55:48 UTC (rev 68575)
@@ -399,35 +399,21 @@
     return;
   }
 
-  const OT::VariationStore *var_store = nullptr;
   hb_set_t varidx_set;
-  float *store_cache = nullptr;
-  bool collect_delta = plan->pinned_at_default ? false : true;
-  if (collect_delta)
-  {
-    if (gdef->has_var_store ())
-    {
-      var_store = &(gdef->get_var_store ());
-      store_cache = var_store->create_cache ();
-    }
-  }
-
   OT::hb_collect_variation_indices_context_t c (&varidx_set,
-                                                &plan->layout_variation_idx_delta_map,
-                                                plan->normalized_coords ? &(plan->normalized_coords) : nullptr,
-                                                var_store,
                                                 &plan->_glyphset_gsub,
-                                                &plan->gpos_lookups,
-                                                store_cache);
+                                                &plan->gpos_lookups);
   gdef->collect_variation_indices (&c);
 
   if (hb_ot_layout_has_positioning (plan->source))
     gpos->collect_variation_indices (&c);
 
-  var_store->destroy_cache (store_cache);
+  gdef->remap_layout_variation_indices (&varidx_set,
+                                        plan->normalized_coords,
+                                        !plan->pinned_at_default,
+                                        plan->all_axes_pinned,
+                                        &plan->layout_variation_idx_delta_map);
 
-  gdef->remap_layout_variation_indices (&varidx_set, &plan->layout_variation_idx_delta_map);
-
   unsigned subtable_count = gdef->has_var_store () ? gdef->get_var_store ().get_sub_table_count () : 0;
   _generate_varstore_inner_maps (varidx_set, subtable_count, plan->gdef_varstore_inner_maps);
 
@@ -927,6 +913,7 @@
     {
       axis_not_pinned = true;
       plan->axes_index_map.set (old_axis_idx, new_axis_idx);
+      plan->axis_tags.push (axis_tag);
       new_axis_idx++;
     }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc	2023-10-17 22:55:48 UTC (rev 68575)
@@ -55,6 +55,7 @@
 #include "hb-ot-var-fvar-table.hh"
 #include "hb-ot-var-gvar-table.hh"
 #include "hb-ot-var-hvar-table.hh"
+#include "hb-ot-var-mvar-table.hh"
 #include "hb-ot-math-table.hh"
 #include "hb-ot-stat-table.hh"
 #include "hb-repacker.hh"
@@ -460,6 +461,8 @@
   case HB_OT_TAG_vmtx:
   case HB_OT_TAG_maxp:
     return !plan->normalized_coords || !pending_subset_tags.has (HB_OT_TAG_glyf);
+  case HB_OT_TAG_GPOS:
+    return !plan->normalized_coords || plan->all_axes_pinned || !pending_subset_tags.has (HB_OT_TAG_GDEF);
   default:
     return true;
   }
@@ -514,6 +517,8 @@
   case HB_OT_TAG_HVAR: return _subset<const OT::HVAR> (plan, buf);
   case HB_OT_TAG_VVAR: return _subset<const OT::VVAR> (plan, buf);
 #endif
+
+#ifndef HB_NO_VAR
   case HB_OT_TAG_fvar:
     if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
     return _subset<const OT::fvar> (plan, buf);
@@ -523,6 +528,11 @@
   case HB_OT_TAG_cvar:
     if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
     return _subset<const OT::cvar> (plan, buf);
+  case HB_OT_TAG_MVAR:
+    if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
+    return _subset<const OT::MVAR> (plan, buf);
+#endif
+
   case HB_OT_TAG_STAT:
     if (!plan->user_axes_location.is_empty ()) return _subset<const OT::STAT> (plan, buf);
     else return _passthrough (plan, tag);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh	2023-10-17 22:55:48 UTC (rev 68575)
@@ -460,7 +460,7 @@
   Type pop ()
   {
     if (!length) return Null (Type);
-    Type v {std::move (arrayZ[length - 1])};
+    Type v (std::move (arrayZ[length - 1]));
     arrayZ[length - 1].~Type ();
     length--;
     return v;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build	2023-10-17 22:55:48 UTC (rev 68575)
@@ -1,3 +1,5 @@
+fs = import('fs')
+
 hb_version_h = configure_file(
                command: [find_program('gen-hb-version.py'), meson.project_version(), '@OUTPUT@', '@INPUT@'],
                input: 'hb-version.h.in',
@@ -703,6 +705,7 @@
       'test-serialize': ['test-serialize.cc', 'hb-static.cc'],
       'test-set': ['test-set.cc', 'hb-static.cc'],
       'test-tuple-varstore': ['test-tuple-varstore.cc', 'hb-subset-instancer-solver.cc', 'hb-static.cc'],
+      'test-item-varstore': ['test-item-varstore.cc', 'hb-subset-instancer-solver.cc', 'hb-static.cc'],
       'test-use-table': 'test-use-table.cc',
       'test-vector': ['test-vector.cc', 'hb-static.cc'],
     }
@@ -709,7 +712,7 @@
     foreach name, source : noinst_programs
       executable(name, source,
         include_directories: incconfig,
-        cpp_args: cpp_args,
+        cpp_args: cpp_args + ['-UNDEBUG'],
         dependencies: libharfbuzz_dep,
         install: false,
       )
@@ -789,15 +792,95 @@
 
 have_gobject = conf.get('HAVE_GOBJECT', 0) == 1
 
+# This code (especially PACKAGE_INIT) kept similar to what CMake's own
+# configure_package_config_file() generates, see
+# https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html#command:configure_package_config_file
+
 cmake_config = configuration_data()
-cmake_config.set('libdir', get_option('prefix') / get_option('libdir'))
-cmake_config.set('includedir', get_option('prefix') / get_option('includedir'))
-cmake_config.set('HB_LIBTOOL_VERSION_INFO', hb_libtool_version_info)
-cmake_config.set('have_gobject', '@0@'.format(have_gobject))
+cmake_config_dir = cmake_package_install_dir / 'harfbuzz'
+
+have_fs_relative_to = meson.version().version_compare('>=1.3.0')
+
+if not have_fs_relative_to
+  relative_to = find_program('relative_to.py')
+endif
+
+if have_fs_relative_to
+  cmake_package_prefix_dir = fs.relative_to(get_option('prefix'), get_option('prefix') / cmake_config_dir)
+else
+  cmake_package_prefix_dir = run_command(relative_to, get_option('prefix'), get_option('prefix') / cmake_config_dir, check: true).stdout().strip()
+endif
+
+cmake_package_prefix_dir = '${CMAKE_CURRENT_LIST_DIR}/@0@'.format(cmake_package_prefix_dir)
+
+# Make all the relevant paths relative to our prefix, so we can later append
+# them onto ${PACKAGE_PREFIX_DIR} to get the correct paths.
+
+cmake_install_includedir = get_option('includedir')
+
+if fs.is_absolute(cmake_install_includedir)
+  if have_fs_relative_to
+    cmake_install_includedir = fs.relative_to(cmake_install_includedir, get_option('prefix'))
+  else
+    cmake_install_includedir = run_command(relative_to, cmake_install_includedir, get_option('prefix'), check: true).stdout().strip()
+  endif
+endif
+
+cmake_install_libdir = get_option('libdir')
+
+if fs.is_absolute(cmake_install_libdir)
+  if have_fs_relative_to
+    cmake_install_libdir = fs.relative_to(cmake_install_libdir, get_option('prefix'))
+  else
+    cmake_install_libdir = run_command(relative_to, cmake_install_libdir, get_option('prefix'), check: true).stdout().strip()
+  endif
+endif
+
+cmake_config.set('PACKAGE_INIT', '''
+get_filename_component(PACKAGE_PREFIX_DIR "@0@" ABSOLUTE)
+
+macro(set_and_check _var _file)
+  set(${_var} "${_file}")
+  if(NOT EXISTS "${_file}")
+    message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
+  endif()
+endmacro()
+
+macro(check_required_components _NAME)
+  foreach(comp ${${_NAME}_FIND_COMPONENTS})
+    if(NOT ${_NAME}_${comp}_FOUND)
+      if(${_NAME}_FIND_REQUIRED_${comp})
+        set(${_NAME}_FOUND FALSE)
+      endif()
+    endif()
+  endforeach()
+endmacro()
+'''.format(cmake_package_prefix_dir))
+
+cmake_config.set('PACKAGE_CMAKE_INSTALL_INCLUDEDIR', '${PACKAGE_PREFIX_DIR}/@0@'.format(cmake_install_includedir))
+cmake_config.set('PACKAGE_CMAKE_INSTALL_LIBDIR', '${PACKAGE_PREFIX_DIR}/@0@'.format(cmake_install_libdir))
+cmake_config.set('PACKAGE_INCLUDE_INSTALL_DIR', '${PACKAGE_PREFIX_DIR}/@0@/@1@'.format(cmake_install_includedir, meson.project_name()))
+cmake_config.set('HB_HAVE_GOBJECT', have_gobject ? 'YES' : 'NO')
+cmake_config.set('HB_LIBRARY_TYPE', get_option('default_library') == 'static' ? 'STATIC' : 'SHARED')
+
+if get_option('default_library') == 'static'
+  cmake_config.set('HB_LIB_PREFIX', '${CMAKE_STATIC_LIBRARY_PREFIX}')
+  cmake_config.set('HB_LIB_SUFFIX', '${CMAKE_STATIC_LIBRARY_SUFFIX}')
+elif host_machine.system() == 'darwin'
+  cmake_config.set('HB_LIB_PREFIX', '${CMAKE_SHARED_LIBRARY_PREFIX}')
+  cmake_config.set('HB_LIB_SUFFIX', '. at 0@.${CMAKE_SHARED_LIBRARY_SUFFIX}'.format(hb_so_version))
+elif host_machine.system() == 'windows'
+  cmake_config.set('HB_LIB_PREFIX', '${CMAKE_IMPORT_LIBRARY_PREFIX}')
+  cmake_config.set('HB_LIB_SUFFIX', '${CMAKE_IMPORT_LIBRARY_SUFFIX}')
+else
+  cmake_config.set('HB_LIB_PREFIX', '${CMAKE_SHARED_LIBRARY_PREFIX}')
+  cmake_config.set('HB_LIB_SUFFIX', '${CMAKE_SHARED_LIBRARY_SUFFIX}. at 0@'.format(version))
+endif
+
 configure_file(input: 'harfbuzz-config.cmake.in',
   output: 'harfbuzz-config.cmake',
   configuration: cmake_config,
-  install_dir: get_option('libdir') / 'cmake' / 'harfbuzz',
+  install_dir: cmake_config_dir,
 )
 
 gobject_enums_c = []

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/relative_to.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/relative_to.py	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/relative_to.py	2023-10-17 22:55:48 UTC (rev 68575)
@@ -0,0 +1,6 @@
+#!/usr/bin/python3
+
+import sys
+from os import path
+
+print(path.relpath(sys.argv[1], sys.argv[2]))

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-item-varstore.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-item-varstore.cc	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-item-varstore.cc	2023-10-17 22:55:48 UTC (rev 68575)
@@ -0,0 +1,66 @@
+/*
+ * Copyright © 2020  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ */
+#include "hb-ot-var-common.hh"
+#include "hb-ot-var-hvar-table.hh"
+// HVAR table data from SourceSerif4Variable-Roman_subset.otf
+const char hvar_data[] = "\x0\x1\x0\x0\x0\x0\x0\x14\x0\x0\x0\xc4\x0\x0\x0\x0\x0\x0\x0\x0\x0\x1\x0\x0\x0\x10\x0\x2\x0\x0\x0\x74\x0\x0\x0\x7a\x0\x2\x0\x8\xc0\x0\xc0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x40\x0\x40\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\xc0\x0\xc0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x40\x0\x40\x0\xc0\x0\xc0\x0\x0\x0\xc0\x0\xc0\x0\x0\x0\xc0\x0\xc0\x0\x0\x0\x0\x0\x40\x0\x40\x0\x0\x0\x40\x0\x40\x0\xc0\x0\xc0\x0\x0\x0\x0\x0\x40\x0\x40\x0\x0\x0\x40\x0\x40\x0\x0\x1\x0\x0\x0\x0\x0\x4\x0\x0\x0\x8\x0\x0\x0\x1\x0\x2\x0\x3\x0\x4\x0\x5\x0\x6\x0\x7\xf9\xf\x2f\xbf\xfb\xfb\x35\xf9\x4\x4\xf3\xb4\xf2\xfb\x2e\xf3\x4\x4\xe\xad\xfa\x1\x1a\x1\x15\x22\x59\xd6\xe3\xf6\x6\xf5\x0\x1\x0\x5\x0\x4\x7\x5\x6";
+
+static void
+test_item_variations ()
+{
+  const OT::HVAR* hvar_table = reinterpret_cast<const OT::HVAR*> (hvar_data);
+
+  hb_tag_t axis_tag = HB_TAG ('w', 'g', 'h', 't');
+  hb_map_t axis_idx_tag_map;
+  axis_idx_tag_map.set (0, axis_tag);
+
+  axis_tag = HB_TAG ('o', 'p', 's', 'z');
+  axis_idx_tag_map.set (1, axis_tag);
+
+  OT::item_variations_t item_vars;
+  const OT::VariationStore& src_var_store = hvar_table+(hvar_table->varStore);
+  bool result = item_vars.create_from_item_varstore (src_var_store, axis_idx_tag_map);
+      
+  assert (result);
+
+  /* partial instancing wght=300:800 */
+  hb_hashmap_t<hb_tag_t, Triple> normalized_axes_location;
+  normalized_axes_location.set (axis_tag, Triple (-0.512817f, 0.f, 0.700012f));
+
+  hb_hashmap_t<hb_tag_t, TripleDistances> axes_triple_distances;
+  axes_triple_distances.set (axis_tag, TripleDistances (200.f, 500.f));
+
+  result = item_vars.instantiate_tuple_vars (normalized_axes_location, axes_triple_distances);
+  assert (result);
+  result = item_vars.as_item_varstore (false);
+  assert (result);
+  assert (item_vars.get_region_list().length == 8);
+}
+
+int
+main (int argc, char **argv)
+{
+  test_item_variations ();
+}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-priority-queue.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-priority-queue.cc	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-priority-queue.cc	2023-10-17 22:55:48 UTC (rev 68575)
@@ -30,7 +30,7 @@
 static void
 test_insert ()
 {
-  hb_priority_queue_t queue;
+  hb_priority_queue_t<int64_t> queue;
   assert (queue.is_empty ());
 
   queue.insert (10, 0);
@@ -53,7 +53,7 @@
 static void
 test_extract ()
 {
-  hb_priority_queue_t queue;
+  hb_priority_queue_t<int32_t> queue;
   queue.insert (0, 0);
   queue.insert (60, 6);
   queue.insert (30, 3);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-tuple-varstore.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-tuple-varstore.cc	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-tuple-varstore.cc	2023-10-17 22:55:48 UTC (rev 68575)
@@ -39,8 +39,22 @@
   axis_idx_tag_map.set (0, axis_tag);
 
   OT::TupleVariationData::tuple_variations_t tuple_variations;
-  bool result = cvar_table->decompile_tuple_variations (axis_count, point_count, false, &axis_idx_tag_map, tuple_variations);
+  hb_vector_t<unsigned> shared_indices;
+  OT::TupleVariationData::tuple_iterator_t iterator;
+
+  const OT::TupleVariationData* tuple_var_data = reinterpret_cast<const OT::TupleVariationData*> (cvar_data + 4);
+
+  unsigned len = sizeof (cvar_data);
+  hb_bytes_t var_data_bytes{cvar_data+4, len - 4};
+  bool result = OT::TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, cvar_table,
+                                                            shared_indices, &iterator);
   assert (result);
+
+  result = tuple_var_data->decompile_tuple_variations (point_count, false, iterator, &axis_idx_tag_map,
+                                                       shared_indices, hb_array<const OT::F2DOT14> (),
+                                                       tuple_variations);
+
+  assert (result);
   assert (tuple_variations.tuple_vars.length == 2);
   for (unsigned i = 0; i < 2; i++)
   {

Modified: trunk/Build/source/libs/harfbuzz/version.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/version.ac	2023-10-17 19:22:04 UTC (rev 68574)
+++ trunk/Build/source/libs/harfbuzz/version.ac	2023-10-17 22:55:48 UTC (rev 68575)
@@ -8,4 +8,4 @@
 dnl --------------------------------------------------------
 dnl
 dnl  m4-include this file to define the current harfbuzz version
-m4_define([harfbuzz_version], [8.2.1])
+m4_define([harfbuzz_version], [8.2.2])



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