diff options
author | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2023-09-09 09:06:21 +0000 |
---|---|---|
committer | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2023-09-09 09:06:21 +0000 |
commit | 0be1c6e7c65f80a069441cf6e473fb38bc2c4bbc (patch) | |
tree | 17ba75c79855490fd0a5e897006b05e85032b3fc /Build/source/libs | |
parent | 4ceadf705835c6adae4375125c756a5b72b49cea (diff) |
harfbuzz 8.2.0
git-svn-id: svn://tug.org/texlive/trunk@68217 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs')
67 files changed, 2132 insertions, 244 deletions
diff --git a/Build/source/libs/README b/Build/source/libs/README index 355403d7c7f..9afbe1ac0c1 100644 --- a/Build/source/libs/README +++ b/Build/source/libs/README @@ -25,8 +25,8 @@ graphite2 1.3.14 - checked 10apr20 http://sourceforge.net/projects/silgraphite/files/graphite2/ (requires C++11) -harfbuzz 8.1.1 - checked 03aug23 - https://github.com/harfbuzz/harfbuzz/releases/tag/8.1.1 +harfbuzz 8.2.0 - checked 09sep23 + https://github.com/harfbuzz/harfbuzz/releases/tag/8.2.0 icu 72.1 - checked 07jan23 https://github.com/unicode-org/icu/releases/ diff --git a/Build/source/libs/harfbuzz/ChangeLog b/Build/source/libs/harfbuzz/ChangeLog index 435ee883232..152bfef41a7 100644 --- a/Build/source/libs/harfbuzz/ChangeLog +++ b/Build/source/libs/harfbuzz/ChangeLog @@ -1,3 +1,8 @@ +2023-09-09 Akira Kakuto <kakuto@jcom.zaq.ne.jp> + + Import harfbuzz-8.2.0. + * version.ac: Adjusted. + 2023-08-03 Akira Kakuto <kakuto@jcom.zaq.ne.jp> Import harfbuzz-8.1.1. diff --git a/Build/source/libs/harfbuzz/TLpatches/ChangeLog b/Build/source/libs/harfbuzz/TLpatches/ChangeLog index 3fb6ef3a444..31f486c858e 100644 --- a/Build/source/libs/harfbuzz/TLpatches/ChangeLog +++ b/Build/source/libs/harfbuzz/TLpatches/ChangeLog @@ -1,3 +1,8 @@ +2023-09-09 Akira Kakuto <kakuto@jcom.zaq.ne.jp> + + Imported harfbuzz-8.2.0 source tree from: + https://github.com/harfbuzz/harfbuzz/releases/download/8.2.0/ + 2023-08-03 Akira Kakuto <kakuto@jcom.zaq.ne.jp> Imported harfbuzz-8.1.1 source tree from: diff --git a/Build/source/libs/harfbuzz/TLpatches/TL-Changes b/Build/source/libs/harfbuzz/TLpatches/TL-Changes index c64947e5988..dc4d3fd2f78 100644 --- a/Build/source/libs/harfbuzz/TLpatches/TL-Changes +++ b/Build/source/libs/harfbuzz/TLpatches/TL-Changes @@ -1,5 +1,5 @@ -Changes applied to the harfbuzz-8.1.1/ tree as obtained from: - https://github.com/harfbuzz/harfbuzz/releases/download/8.1.1/ +Changes applied to the harfbuzz-8.2.0/ tree as obtained from: + https://github.com/harfbuzz/harfbuzz/releases/download/8.2.0/ Removed: COPYING diff --git a/Build/source/libs/harfbuzz/configure b/Build/source/libs/harfbuzz/configure index 90404b9eeff..c1c6cbd90c1 100755 --- a/Build/source/libs/harfbuzz/configure +++ b/Build/source/libs/harfbuzz/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for harfbuzz (TeX Live) 8.1.1. +# Generated by GNU Autoconf 2.71 for harfbuzz (TeX Live) 8.2.0. # # Report bugs to <tex-k@tug.org>. # @@ -611,8 +611,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='harfbuzz (TeX Live)' PACKAGE_TARNAME='harfbuzz--tex-live-' -PACKAGE_VERSION='8.1.1' -PACKAGE_STRING='harfbuzz (TeX Live) 8.1.1' +PACKAGE_VERSION='8.2.0' +PACKAGE_STRING='harfbuzz (TeX Live) 8.2.0' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1346,7 +1346,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures harfbuzz (TeX Live) 8.1.1 to adapt to many kinds of systems. +\`configure' configures harfbuzz (TeX Live) 8.2.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1418,7 +1418,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of harfbuzz (TeX Live) 8.1.1:";; + short | recursive ) echo "Configuration of harfbuzz (TeX Live) 8.2.0:";; esac cat <<\_ACEOF @@ -1523,7 +1523,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -harfbuzz (TeX Live) configure 8.1.1 +harfbuzz (TeX Live) configure 8.2.0 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2064,7 +2064,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by harfbuzz (TeX Live) $as_me 8.1.1, which was +It was created by harfbuzz (TeX Live) $as_me 8.2.0, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -4823,7 +4823,7 @@ fi # Define the identity of the package. PACKAGE='harfbuzz--tex-live-' - VERSION='8.1.1' + VERSION='8.2.0' # Some tools Automake needs. @@ -5034,9 +5034,9 @@ WARNING_CFLAGS=$kpse_cv_warning_cflags HB_VERSION_MAJOR=8 -HB_VERSION_MINOR=1 -HB_VERSION_MICRO=1 -HB_VERSION=8.1.1 +HB_VERSION_MINOR=2 +HB_VERSION_MICRO=0 +HB_VERSION=8.2.0 ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -8817,7 +8817,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by harfbuzz (TeX Live) $as_me 8.1.1, which was +This file was extended by harfbuzz (TeX Live) $as_me 8.2.0, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -8885,7 +8885,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -harfbuzz (TeX Live) config.status 8.1.1 +harfbuzz (TeX Live) config.status 8.2.0 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/BUILD.md b/Build/source/libs/harfbuzz/harfbuzz-src/BUILD.md index 8e822738c5c..55e950ea7d2 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/BUILD.md +++ b/Build/source/libs/harfbuzz/harfbuzz-src/BUILD.md @@ -1,20 +1,23 @@ On Linux, install the development packages for FreeType, Cairo, and GLib. For example, on Ubuntu / Debian, you would do: -$ sudo apt-get install meson pkg-config ragel gtk-doc-tools gcc g++ libfreetype6-dev libglib2.0-dev libcairo2-dev + $ sudo apt-get install meson pkg-config ragel gtk-doc-tools gcc g++ libfreetype6-dev libglib2.0-dev libcairo2-dev whereas on Fedora, RHEL, CentOS, and other Red Hat based systems you would do: -$ sudo dnf install meson pkgconfig gtk-doc gcc gcc-c++ freetype-devel glib2-devel cairo-devel + $ sudo dnf install meson pkgconfig gtk-doc gcc gcc-c++ freetype-devel glib2-devel cairo-devel and on ArchLinux and Manjaro: -$ sudo pacman -Suy meson pkg-config ragel gcc freetype2 glib2 cairo + $ sudo pacman -Suy meson pkg-config ragel gcc freetype2 glib2 cairo -then use meson to build the project like `meson build && meson test -Cbuild`. +On macOS: -On macOS, `brew install pkg-config ragel gtk-doc freetype glib cairo meson` -then use meson like above. + brew install pkg-config ragel gtk-doc freetype glib cairo meson + +Then use meson to build the project like: + + meson build && meson test -Cbuild On Windows, meson can build the project like above if a working MSVC's cl.exe (`vcvarsall.bat`) or gcc/clang is already on your path, and if you use @@ -22,8 +25,8 @@ something like `meson build --wrap-mode=default` it fetches and compiles most of the dependencies also. It is recommended to install CMake either manually or via the Visual Studio installer when building with MSVC, using meson. -Our CI configurations is also a good source of learning how to build HarfBuzz. +Our CI configurations are also a good source of learning how to build HarfBuzz. -There is also amalgam source provided with HarfBuzz which reduces whole process -of building HarfBuzz like `g++ src/harfbuzz.cc -fno-exceptions` but there is -not guarantee provided with buildability and reliability of features you get. +There is also amalgamated source provided with HarfBuzz which reduces whole process +of building HarfBuzz to `g++ src/harfbuzz.cc -fno-exceptions` but there is +no guarantee provided with buildability and reliability of features you get. diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/CONFIG.md b/Build/source/libs/harfbuzz/harfbuzz-src/CONFIG.md index 0faa359e6bb..f0fc065c7f6 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/CONFIG.md +++ b/Build/source/libs/harfbuzz/harfbuzz-src/CONFIG.md @@ -144,7 +144,7 @@ the macro `HB_CONFIG_OVERRIDE_H` to the string containing to that header file's name. HarfBuzz will then include that file at the appropriate place during configuration. -Up until HarfBuzz 3.1.2 the the configuration override header file's name was +Up until HarfBuzz 3.1.2, the configuration override header file's name was fixed and called `config-override.h`, and was activated by defining the macro `HAVE_CONFIG_OVERRIDE_H`. That still works. diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog b/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog index 5641d060e88..66b7308ed5e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog +++ b/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog @@ -1,3 +1,859 @@ +commit c1eb66d4159fec311334aee5c0a59384491d3989 +Author: Khaled Hosny <khaled@aliftype.com> +Date: Fri Sep 8 21:54:32 2023 +0300 + + 8.2.0 + + NEWS | 12 ++++++++++++ + configure.ac | 2 +- + docs/harfbuzz-docs.xml | 1 + + meson.build | 2 +- + src/hb-paint.cc | 2 +- + src/hb-paint.h | 4 ++-- + src/hb-version.h | 6 +++--- + 7 files changed, 21 insertions(+), 8 deletions(-) + +commit d5cb1a315380e9bd78ff377a586b78bc42abafa6 +Author: L. E. Segovia <amy@amyspark.me> +Date: Thu Aug 31 23:41:10 2023 -0300 + + [meson] Add gitignore entries for wrap sources + + subprojects/.gitignore | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit 617e44785476178107c4216964f185937e312a09 +Author: L. E. Segovia <amy@amyspark.me> +Date: Thu Aug 31 23:39:29 2023 -0300 + + [meson] Set C++14 as minimum as implied by MSVC support + + Microsoft's STL uses C++14 as minimum. Using C++11 is actually enforced + by clang-cl and clang, which will lead to all sorts of compilation + errors. + + meson.build | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +commit 15bc9e342f989c7cd27de3a3fb68933259bf59e2 +Author: L. E. Segovia <amy@amyspark.me> +Date: Thu Aug 31 23:37:08 2023 -0300 + + [meson] Detect Microsoft compilers through _MSC_FULL_VER + + Microsoft ships three compilers nowadays: MSVC, clang-cl, and Clang. + The latter is always skipped by `compiler.get_argument_syntax()`, + which leads to the incorrect export macro being applied. + + This commit also removes the tests that are affected in Microsoft Clang. + + src/meson.build | 30 +++++++++++++++--------------- + 1 file changed, 15 insertions(+), 15 deletions(-) + +commit fd3eb2c6723c3ce241011f1d3429e48c3226af1c +Author: Qunxin Liu <qxliu@google.com> +Date: Thu Aug 24 08:59:18 2023 -0700 + + fuzzer fix: https://oss-fuzz.com/testcase-detail/6032126569742336 + + src/hb-ot-var-gvar-table.hh | 24 ++++++--------------- + ...ase-minimized-hb-subset-fuzzer-6032126569742336 | Bin 0 -> 1970 bytes + 2 files changed, 6 insertions(+), 18 deletions(-) + +commit 0340ba1c50da110787a420a633a7b8b2dabe42c4 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Sep 5 14:56:09 2023 +0300 + + [bit-page] Add a few operators + + src/hb-bit-page.hh | 3 +++ + 1 file changed, 3 insertions(+) + +commit a0b758f7d779376f4582c968d6fc3c5e7cde1e50 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Sep 4 10:34:27 2023 +0000 + + Bump github/codeql-action from 2.21.4 to 2.21.5 + + Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.21.4 to 2.21.5. + - [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/a09933a12a80f87b87005513f0abb1494c27a716...00e563ead9f72a8461b24876bee2d0c2e8bd2ee8) + + --- + updated-dependencies: + - dependency-name: github/codeql-action + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/scorecard.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 4cfc6d8e173e800df086d7be078da2e8c5cfca19 +Author: Ben Wagner <bungeman@chromium.org> +Date: Thu Aug 31 13:54:34 2023 -0400 + + Specify tuple_variations_t special member functions + + Building with clang complains about the use of `tuple_variations_t`'s + implicit copy constructor and copy assignment operator, since automatic + generation of these is deprecated when declaring a non-default + destructor. This is a good warning because it isn't obvious that copies + were being made instead of the object being moved and this struct should + be moved and not copied. Declare all the special member functions, + defaulting the moves and deleting the copies. + + After making `tuple_variations_t` move only, an issue is revealed in + `hb_vector_t::push` which has been requiring that objects be copyable. + Remove the old non-emplacing `push` now that this works with all + existing objects and make a single `push` which is more like + `std::vector::emplace_back` since that is somewhat what the newer `push` + is attempting to do. + + src/hb-ot-var-common.hh | 5 +++++ + src/hb-vector.hh | 22 ++-------------------- + 2 files changed, 7 insertions(+), 20 deletions(-) + +commit 4668b43e2cbc9d2ae19a9e9b53ad694da35240a1 +Author: Benoit Pierre <benoit.pierre@gmail.com> +Date: Thu Aug 31 19:33:29 2023 +0200 + + [meson] add source fallback URL to freetype2 wrap + + subprojects/freetype2.wrap | 1 + + 1 file changed, 1 insertion(+) + +commit 8d22a57065d286dd2e920ece70c12bba5f59a8b1 +Author: Garret Rieger <grieger@google.com> +Date: Mon Aug 28 18:33:31 2023 +0000 + + [repacker] fix potential use after free in repacker. + + During table splitting we iterate over the lookups map which can be modified during table splitting. This can result in a use after free in the iterator. Create a local copy of the lookup indices to avoid this. + + src/hb-repacker.hh | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +commit a1f034eaacb5547fdfc62fd1c4df23f9d2b40104 +Author: Garret Rieger <grieger@google.com> +Date: Mon Aug 28 21:10:16 2023 +0000 + + [repacker] fix fuzzer failure. + + Fixes: https://oss-fuzz.com/testcase-detail/6490945267564544 + + src/graph/markbasepos-graph.hh | 4 +++- + ...tcase-minimized-hb-repacker-fuzzer-6490945267564544 | Bin 0 -> 358352 bytes + 2 files changed, 3 insertions(+), 1 deletion(-) + +commit f380a32825a1b2c51bbe21dc7acb9b3cc0921f69 +Author: Bruce Mitchener <bruce.mitchener@gmail.com> +Date: Fri Aug 25 14:01:01 2023 +0700 + + Fix some typos. + + CONFIG.md | 2 +- + src/OT/Layout/GPOS/PairPosFormat2.hh | 2 +- + src/hb-bimap.hh | 2 +- + src/hb-bit-set.hh | 4 ++-- + src/hb-buffer.cc | 4 ++-- + src/hb-buffer.h | 2 +- + src/hb-font.cc | 2 +- + src/hb-map.cc | 2 +- + src/hb-ot-shape.cc | 2 +- + src/hb-sanitize.hh | 2 +- + src/hb-set.cc | 24 ++++++++++++------------ + src/hb-vector.hh | 2 +- + src/hb-wasm-shape.cc | 2 +- + 13 files changed, 26 insertions(+), 26 deletions(-) + +commit c28fdc39b25269aadafca2ba0507c149b2779da2 +Author: Garret Rieger <grieger@google.com> +Date: Wed Aug 23 22:16:39 2023 +0000 + + [repacker] fix bot failure. + + src/graph/gsubgpos-context.hh | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +commit d7ee328f807cd4890b701d5b2dab5993270ace7f +Author: Garret Rieger <grieger@google.com> +Date: Wed Aug 23 22:06:55 2023 +0000 + + [repacker] include the size of all lookup tables in the layer size estimates from the start. + + In extension promotion previously we incrementally added the contribution of the lookup table to the layer size estimates as the lookups were processed. However, this isn't quite correct as regardless of the promotion decision the full lookup table size will be incurred. So the size should be added to the initial sizes. + + src/hb-repacker.hh | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +commit 5587247d5bb46e3ff5d0c4601b145dfbae50e27c +Author: Garret Rieger <grieger@google.com> +Date: Wed Aug 23 21:54:15 2023 +0000 + + [repacker] create only one extension subtable per physical subtable. + + During extension promotion when multiple lookups refer to a shared subtable node create and reuse a single extension subtable for it. Fixes: https://github.com/fonttools/fonttools/issues/3260. + + src/graph/graph.hh | 12 +++++++++++ + src/graph/gsubgpos-context.hh | 1 + + src/graph/gsubgpos-graph.hh | 19 +++++++++++++---- + src/test-repacker.cc | 47 +++++++++++++++++++++++++++++++++++++------ + 4 files changed, 69 insertions(+), 10 deletions(-) + +commit 56e8a290328c6628a92971c7837f773194e7584f +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Aug 22 15:49:00 2023 -0600 + + Fix static_size declaration + + I have a vague memory that it was intentionally written + that way, but I can't recall :-(. + + src/OT/Color/COLR/COLR.hh | 4 ++-- + src/hb-null.hh | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +commit 2023384bdf74992c2a38ed7ddc81dfd14d8a6649 +Merge: 970d2c438 dd8d35766 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Aug 22 13:09:26 2023 -0700 + + Merge pull request #4368 from googlefonts/support_gvar + + Initial implementation for gvar partial instancing + +commit dd8d35766bb31ef43848180c419c621be302ac5d +Author: Qunxin Liu <qxliu@google.com> +Date: Tue Aug 22 12:54:50 2023 -0700 + + [instancer] enable partial instancing tests when experimental api is on + + src/hb-ot-var-common.hh | 2 +- + test/subset/meson.build | 5 ++++- + 2 files changed, 5 insertions(+), 2 deletions(-) + +commit 970d2c438f849700b879d76e8c183c2edfbaccdb +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Aug 21 10:10:17 2023 +0000 + + Bump github/codeql-action from 2.21.3 to 2.21.4 + + Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.21.3 to 2.21.4. + - [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/5b6282e01c62d02e720b81eb8a51204f527c3624...a09933a12a80f87b87005513f0abb1494c27a716) + + --- + updated-dependencies: + - dependency-name: github/codeql-action + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/scorecard.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 6c7aed1000c52a7236f2368aae2bbedab6b133ff +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Aug 21 10:52:43 2023 +0000 + + Bump fonttools from 4.42.0 to 4.42.1 in /.ci + + Bumps [fonttools](https://github.com/fonttools/fonttools) from 4.42.0 to 4.42.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.42.0...4.42.1) + + --- + updated-dependencies: + - dependency-name: fonttools + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .ci/requirements-fonttools.txt | 70 +++++++++++++++++++++--------------------- + .ci/requirements.txt | 70 +++++++++++++++++++++--------------------- + 2 files changed, 70 insertions(+), 70 deletions(-) + +commit ca906e8747ac45ccf235c3f3e9ee9b69a693d7e4 +Author: Garret Rieger <grieger@google.com> +Date: Wed Aug 16 23:37:03 2023 +0000 + + [repacker] fix fuzzer timeout. + + Corrects some mistakes in the handling of incoming_edges_ when memory allocation failures happen. + + src/graph/graph.hh | 11 +++++++++-- + ...stcase-minimized-hb-repacker-fuzzer-6697168080338944 | Bin 0 -> 68766 bytes + 2 files changed, 9 insertions(+), 2 deletions(-) + +commit c7f2d440f463be31ae24cbae7ceb6ea72a15e990 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Aug 16 09:55:23 2023 -0700 + + [hb-view] Better cairo version check + + util/view-cairo.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit e714e7d4f3d3bd1a49c460f6c3bd2c3f09192722 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Aug 16 09:54:08 2023 -0700 + + [hb-view] Work around old cairo + + Fixes https://github.com/harfbuzz/harfbuzz/issues/4378 + + util/view-cairo.hh | 3 +++ + 1 file changed, 3 insertions(+) + +commit bea26446d2063cadb0cd83c1c627d3eed95cbcf6 +Author: Qunxin Liu <qxliu@google.com> +Date: Tue Aug 15 14:20:54 2023 -0700 + + [instancer] reference all points for gvar + + If a point is not referenced and delta is not inferred, set delta to 0 + + src/hb-ot-var-common.hh | 16 ++++++++++++++-- + ...tain-all-codepoint.wght=200-300-500,wdth=80-90.ttf | Bin 7452 -> 7292 bytes + ...ions.retain-all-codepoint.wght=300-600,wdth=85.ttf | Bin 6780 -> 6760 bytes + 3 files changed, 14 insertions(+), 2 deletions(-) + +commit 06ff3bcb8db2ac9eac80bef21644c4d70f60573a +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Aug 15 14:41:18 2023 -0600 + + [COLR,glyf] Use map instead of set for tracking current glyphs / layers + + src/OT/Color/COLR/COLR.hh | 4 ++-- + src/OT/glyf/Glyph.hh | 4 ++-- + src/hb-ft-colr.hh | 4 ++-- + src/hb-map.hh | 5 +++++ + 4 files changed, 11 insertions(+), 6 deletions(-) + +commit b530e485cdcd466cdfd7f80fd341a67883fb8c71 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Aug 15 14:31:40 2023 -0600 + + [glyf] Don't recuse into alread-active composite glyphs + + Deny loops. + + src/OT/glyf/Glyph.hh | 40 ++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 38 insertions(+), 2 deletions(-) + +commit 8f039ab4d624c545dd472e477c705c3f013f66c6 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Aug 15 11:27:19 2023 -0600 + + [COLR] Avoid infinite-loop through PaintColrLayers + + Fixes https://github.com/harfbuzz/harfbuzz/issues/4376 + Fixes https://oss-fuzz.com/testcase-detail/5717524023738368 + + src/OT/Color/COLR/COLR.hh | 8 ++++++++ + src/hb-ft-colr.hh | 10 ++++++++++ + 2 files changed, 18 insertions(+) + +commit 0c80aec10b38c8880b0f353b4774b8843a4b4126 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Aug 15 10:30:38 2023 -0600 + + [COLR] Move cycle-detection to the renderer instead of cairo + + Alternative fix for https://github.com/harfbuzz/harfbuzz/issues/4375 + + src/OT/Color/COLR/COLR.hh | 10 ++ + src/hb-cairo-utils.hh | 3 - + src/hb-cairo.cc | 8 - + src/hb-ft-colr.hh | 17 +- + test/api/results/bad-154 | 440 +--------------------------------------------- + 5 files changed, 26 insertions(+), 452 deletions(-) + +commit 21a894f055bbff6afb45cbcceed89ac92091bb3e +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Aug 15 10:21:26 2023 -0600 + + [cairo] Protect against infinite loops + + Fixes https://github.com/harfbuzz/harfbuzz/issues/4375 + + Maybe we should do this in hb-ft and COLR instead? + + src/hb-cairo-utils.hh | 3 +++ + src/hb-cairo.cc | 8 ++++++++ + 2 files changed, 11 insertions(+) + +commit 7d7541e35d5701953e5e768ac1ef41b23223edb1 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Aug 14 17:55:09 2023 -0600 + + [test-paint] Print paint-color-glyph + + test/api/results/bad-154 | 34 +++++++++++++++++++++++++++++++++- + test/api/results/test-154 | 4 +++- + test/api/results/testvf-154 | 4 +++- + test/api/test-paint.c | 15 +++++++++++++++ + 4 files changed, 54 insertions(+), 3 deletions(-) + +commit 5560eb60d75945a331427b0e8112282dc4ff0d94 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Aug 14 17:05:22 2023 -0600 + + [paint] Fix docs + + src/hb-paint.h | 9 --------- + 1 file changed, 9 deletions(-) + +commit 47231bdc701df1f3ba0dafb901dc92db54e7ff78 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Aug 14 16:52:44 2023 -0600 + + [COLR/cairo/ft] Fixups to paint-color-glyph and implement for hb-ft + + docs/harfbuzz-sections.txt | 3 +++ + src/hb-ft-colr.hh | 11 ++++++++ + test/api/results/bad-154 | 66 ++++++++++++++++++++++++++++++++++++++++++++- + test/api/results/testvf-154 | 6 ++++- + 4 files changed, 84 insertions(+), 2 deletions(-) + +commit 58effbcc4f1b6aa1870738f0da3d999f4f1810be +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Aug 14 16:47:01 2023 -0600 + + . + + src/OT/Color/COLR/COLR.hh | 5 +++++ + src/hb-cairo.cc | 10 +++++++++- + test/api/results/test-154 | 6 +++++- + test/api/test-paint.c | 2 +- + 4 files changed, 20 insertions(+), 3 deletions(-) + +commit 74527670fc5b0517e1d2cba2c26e3695547302e1 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Aug 14 15:57:24 2023 -0600 + + [COLR/cairo] Add paint_color_glyph func + + Implement in cairo to use scaled-font's glyph cache. + + src/OT/Color/COLR/COLR.hh | 4 ++++ + src/hb-cairo.cc | 19 ++++++++++++++++++ + src/hb-paint.cc | 25 +++++++++++++++++++++++ + src/hb-paint.h | 51 +++++++++++++++++++++++++++++++++++++++++++++++ + src/hb-paint.hh | 8 ++++++++ + 5 files changed, 107 insertions(+) + +commit 8d19274c2d6e7205dc32d416c60c3542a3f353e9 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Mon Aug 14 14:40:26 2023 -0600 + + [layout] Speed up VarStoreInstancer + + src/hb-ot-var-common.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 1da4c61550ed8216c811765de6d8904727df0e65 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Aug 14 10:51:00 2023 +0000 + + Bump github/codeql-action from 2.21.2 to 2.21.3 + + Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.21.2 to 2.21.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/0ba4244466797eb048eb91a6cd43d5c03ca8bd05...5b6282e01c62d02e720b81eb8a51204f527c3624) + + --- + updated-dependencies: + - dependency-name: github/codeql-action + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/scorecard.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 8d44562b429afc1cca8cf5472905ae189929a506 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Aug 14 10:50:49 2023 +0000 + + Bump hendrikmuhs/ccache-action from 1.2.9 to 1.2.10 + + Bumps [hendrikmuhs/ccache-action](https://github.com/hendrikmuhs/ccache-action) from 1.2.9 to 1.2.10. + - [Release notes](https://github.com/hendrikmuhs/ccache-action/releases) + - [Commits](https://github.com/hendrikmuhs/ccache-action/compare/ca3acd2731eef11f1572ccb126356c2f9298d35e...6d1841ec156c39a52b1b23a810da917ab98da1f4) + + --- + updated-dependencies: + - dependency-name: hendrikmuhs/ccache-action + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .github/workflows/linux-ci.yml | 2 +- + .github/workflows/macos-ci.yml | 2 +- + .github/workflows/msvc-ci.yml | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +commit a8fb56e0f313558dc1f18df2d76ca691567330b9 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Aug 14 10:36:33 2023 +0000 + + Bump meson from 1.2.0 to 1.2.1 in /.ci + + Bumps [meson](https://github.com/mesonbuild/meson) from 1.2.0 to 1.2.1. + - [Release notes](https://github.com/mesonbuild/meson/releases) + - [Commits](https://github.com/mesonbuild/meson/compare/1.2.0...1.2.1) + + --- + updated-dependencies: + - dependency-name: meson + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] <support@github.com> + + .ci/requirements.in | 2 +- + .ci/requirements.txt | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +commit e8eb1dc5ff695427abc137d3d15c4eec64ab6c78 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Aug 9 15:35:59 2023 -0600 + + [parse_tag] Accept non-ALNUM in tag name + + src/hb-common.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 9a7afe922b7c661267ecd2211b5199f5ae4df180 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Aug 9 12:00:41 2023 -0600 + + [perf] Benchmark glyph painting + + perf/benchmark-font.cc | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +commit 077c4308cc2650bcd761b60c2b64eea77c5d399c +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Aug 9 10:41:04 2023 -0600 + + [limits] Increase COLRv1 edge-count + + We have a "pixel" color font that was easily hitting the limit... + + src/hb-limits.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 45c1ad05126c33408ccf862a0fde69f608147f04 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Wed Aug 9 10:27:45 2023 -0600 + + [paint] Add tracing + + src/OT/Color/COLR/COLR.hh | 22 ++++++++++++++++++++++ + src/hb-debug.hh | 19 +++++++++++++++++-- + 2 files changed, 39 insertions(+), 2 deletions(-) + +commit 483bc0a3847ae55860bd55fa0eb214f899a02b31 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Aug 8 15:58:20 2023 -0600 + + [arabic/stch] Center the stretched group over the digits + + Mostly relevant when there's one digit only. + + https://github.com/harfbuzz/harfbuzz/issues/4369#issuecomment-1670361856 + + src/hb-ot-shaper-arabic.cc | 5 ++++- + test/shape/data/in-house/tests/arabic-stch.tests | 1 + + 2 files changed, 5 insertions(+), 1 deletion(-) + +commit 9daef6ed4eda12e13628b1ae8bff590d4e6adaf6 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Aug 8 13:33:11 2023 -0600 + + [arabic] Add test for previous commit + + .../fonts/507637795ce4f2975593da54d12b46f76c7cc4cc.ttf | Bin 0 -> 2200 bytes + test/shape/data/in-house/tests/arabic-stch.tests | 1 + + 2 files changed, 1 insertion(+) + +commit 313c772989ca838f7ba9c2119ffb953ba8a4418b +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Aug 8 13:06:12 2023 -0600 + + [arabic/stch] Also work in left-to-right direction + + Fixes https://github.com/harfbuzz/harfbuzz/issues/4369 + + src/hb-ot-shaper-arabic.cc | 25 ++++++++++++++++++++----- + 1 file changed, 20 insertions(+), 5 deletions(-) + +commit 40bfabd1f97d7ad665140ba764157a6058e6a3b7 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Tue Aug 8 12:17:25 2023 -0600 + + [arabic/stch] Zero advances + + This was working for our test suite because those glyphs were + declared mark and their advances zeroed automatically. But is + not the case in eg. the font posted at: + + https://github.com/harfbuzz/harfbuzz/issues/4369 + + src/hb-ot-shaper-arabic.cc | 1 + + 1 file changed, 1 insertion(+) + +commit 0aa5dafefd85d01d486d0d26b75387df3a2927e3 +Author: Qunxin Liu <qxliu@google.com> +Date: Tue Aug 8 08:33:11 2023 -0700 + + fix bots. + + -Also disable partial instancing tests for now, cause the command option + is wrapped by experimental_api + + test/subset/data/Makefile.am | 1 - + test/subset/data/Makefile.sources | 1 - + test/subset/meson.build | 2 +- + util/hb-subset.cc | 4 ++++ + 4 files changed, 5 insertions(+), 3 deletions(-) + +commit 77b158c72d355e8e5e32f0d9748174041fddc8dd +Author: Qunxin Liu <qxliu@google.com> +Date: Mon Aug 7 16:02:02 2023 -0700 + + [instancer] add tests for gvar partial instancing + + test/subset/data/Makefile.am | 1 + + test/subset/data/Makefile.sources | 1 + + ....retain-all-codepoint.wght=200-300-500,wdth=80-90.ttf | Bin 0 -> 8256 bytes + ...iations.retain-all-codepoint.wght=300-600,wdth=85.ttf | Bin 0 -> 7244 bytes + ....retain-all-codepoint.wght=200-300-500,wdth=80-90.ttf | Bin 0 -> 7452 bytes + ...iations.retain-all-codepoint.wght=300-600,wdth=85.ttf | Bin 0 -> 6780 bytes + .../data/profiles/no-tables-with-item-variations.txt | 1 + + test/subset/data/tests/glyf_partial_instancing.tests | 13 +++++++++++++ + test/subset/generate-expected-outputs.py | 1 + + test/subset/meson.build | 1 + + 10 files changed, 18 insertions(+) + +commit 32cfa37e2edd6a8dbc07c75c010fd2fc68c4346a +Author: Qunxin Liu <qxliu@google.com> +Date: Mon May 8 13:30:39 2023 -0700 + + [instancer] command line support for partial instancing + + -Also updated hb_subset_input_set_axis_range (), so user can define + default value as well + + src/hb-subset-input.cc | 19 ++++++++---- + src/hb-subset.h | 3 +- + util/hb-subset.cc | 80 ++++++++++++++++++++++++++++++++++++++++---------- + 3 files changed, 80 insertions(+), 22 deletions(-) + +commit 0065658e96c79f8b51c2a702908e84d9d23e0971 +Author: Qunxin Liu <qxliu@google.com> +Date: Mon Aug 7 11:12:02 2023 -0700 + + [instancer] enable cvar instancing code + + src/hb-subset-input.cc | 1 - + src/hb-subset.cc | 3 +++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +commit 0ba4d539b365039b602d9f88133fc0cae9cd0e30 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Aug 7 11:49:03 2023 -0600 + + Bump fonttools from 4.41.1 to 4.42.0 in /.ci (#4365) + + Bumps [fonttools](https://github.com/fonttools/fonttools) from 4.41.1 to 4.42.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.41.1...4.42.0) + + --- + updated-dependencies: + - dependency-name: fonttools + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] <support@github.com> + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + + .ci/requirements-fonttools.txt | 70 +++++++++++++++++++++--------------------- + .ci/requirements.txt | 70 +++++++++++++++++++++--------------------- + 2 files changed, 70 insertions(+), 70 deletions(-) + +commit 366ffd1ef0f26cf719ee45e08f59fc9fb4b38a05 +Author: Qunxin Liu <qxliu@google.com> +Date: Mon Aug 7 10:32:47 2023 -0700 + + [instancer] fix move constructor for tuple_delta_t + + src/hb-ot-var-common.hh | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +commit 1d91622ddf082cd0777e9ae67876fe13fc7e454d +Author: Qunxin Liu <qxliu@google.com> +Date: Tue Jul 18 09:52:40 2023 -0700 + + [instancer] add a hashing impl for floating point type + + src/hb-algs.hh | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 5a4694b6934f9e3ca3dc89cc905b4351920085b6 +Author: Qunxin Liu <qxliu@google.com> +Date: Mon Aug 7 09:55:30 2023 -0700 + + [instancer] add calc_inferred_deltas() for gvar + + src/hb-ot-var-common.hh | 104 +++++++++++++++++++++++++++++++++++++++++++++ + src/test-tuple-varstore.cc | 3 +- + 2 files changed, 105 insertions(+), 2 deletions(-) + +commit fb44727401d36adc14615deda91574a6e7ec2cd6 +Author: Qunxin Liu <qxliu@google.com> +Date: Mon Aug 7 09:44:41 2023 -0700 + + [instancer] add instantiate () for gvar + + src/hb-ot-var-common.hh | 11 ++++++++--- + src/hb-ot-var-gvar-table.hh | 22 ++++++++++++++++++++++ + 2 files changed, 30 insertions(+), 3 deletions(-) + +commit 746b112faf6adcd4a9d7325b067c4ba46a973a95 +Author: Qunxin Liu <qxliu@google.com> +Date: Mon Aug 7 09:26:42 2023 -0700 + + [instancer] add serialize () for gvar + + src/hb-ot-var-common.hh | 6 ++- + src/hb-ot-var-cvar-table.hh | 1 + + src/hb-ot-var-gvar-table.hh | 114 ++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 120 insertions(+), 1 deletion(-) + +commit 3c86b096a9bf310a00086a7ed566cf1436da786c +Author: Qunxin Liu <qxliu@google.com> +Date: Fri Jul 28 16:18:51 2023 -0700 + + [instancer] Add instantiate () and compile_bytes() for gvar + + -Also add support for using shared_points and shared_tuples + + src/hb-ot-var-common.hh | 85 +++++++++++++++++++++++++++++++++++++-------- + src/hb-ot-var-cvar-table.hh | 7 ++-- + src/hb-ot-var-gvar-table.hh | 29 ++++++++++++++++ + src/test-tuple-varstore.cc | 2 +- + 4 files changed, 106 insertions(+), 17 deletions(-) + +commit 198612c1c83d3b19b953a2fcc73406287104e5a2 +Author: Qunxin Liu <qxliu@google.com> +Date: Fri Jul 28 15:41:54 2023 -0700 + + [instancer] add decompile_glyph_variations () for gvar + + src/hb-ot-var-common.hh | 1 + + src/hb-ot-var-gvar-table.hh | 81 +++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 82 insertions(+) + +commit eb116e163e0bb8476cdd53a07630389d25ec3b97 +Author: Qunxin Liu <qxliu@google.com> +Date: Fri Jul 28 15:27:07 2023 -0700 + + [instancer] Add new_gid->contour_points vector map in subset plan + + - Add an API in Glyph to export original contour_points vector, which is + needed by infer_deltas when merging tuple variations with the same + tent + + src/OT/glyf/Glyph.hh | 57 +++++++++++++++++++++++++++++++++++++++ + src/hb-ot-var-gvar-table.hh | 34 ----------------------- + src/hb-subset-plan-member-list.hh | 3 +++ + src/hb-subset-plan.cc | 32 ++++++++++++++++++++++ + src/hb-subset-plan.hh | 34 +++++++++++++++++++++++ + 5 files changed, 126 insertions(+), 34 deletions(-) + +commit a0f810effcb497e77be25328a251e608b5863999 +Author: Qunxin Liu <qxliu@google.com> +Date: Fri Jul 28 15:04:47 2023 -0700 + + [instancer] add struct glyph_variations_t for gvar + + -Add compile_peak_coords () in tuple_delta_t + -Add compile_shared_tuples () for glyph_variations_t + + src/hb-ot-var-common.hh | 33 ++++++++++++++ + src/hb-ot-var-gvar-table.hh | 105 ++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 138 insertions(+) + +commit cb92210b4cf93f6d7986dc75632c831092b4de19 +Author: Bruce Mitchener <bruce.mitchener@gmail.com> +Date: Tue Aug 8 00:19:30 2023 +0700 + + Improve Markdown formatting. (#4366) + + BUILD.md | 23 +++++++++++++---------- + README.md | 4 ++-- + 2 files changed, 15 insertions(+), 12 deletions(-) + +commit 49dbe0cd30a47258af0523822c924e9698a3e845 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Aug 6 15:07:57 2023 -0600 + + Another try + + src/OT/Color/COLR/COLR.hh | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +commit 483d4a8741890ac72fa22d167ed53d4e39e9bd1d +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Aug 6 14:40:45 2023 -0600 + + Fix bot + + src/OT/Layout/GPOS/CursivePosFormat1.hh | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +commit 7989702abadc8fff69a99a47cfad2db08f5b8184 +Author: Behdad Esfahbod <behdad@behdad.org> +Date: Sun Aug 6 14:17:50 2023 -0600 + + Audit and fix up serialize_subset uses + + Fixes https://github.com/harfbuzz/harfbuzz/issues/4362 + + src/OT/Color/COLR/COLR.hh | 11 ++++++----- + src/OT/Layout/GPOS/AnchorMatrix.hh | 5 +++-- + src/OT/Layout/GPOS/CursivePosFormat1.hh | 11 +++++------ + src/OT/Layout/GPOS/LigatureArray.hh | 13 +++++++------ + src/OT/Layout/GPOS/MarkArray.hh | 6 +++--- + src/OT/Layout/GPOS/MarkBasePosFormat1.hh | 15 +++++++-------- + src/OT/Layout/GPOS/MarkLigPosFormat1.hh | 14 +++++++------- + src/OT/Layout/GPOS/MarkMarkPosFormat1.hh | 12 +++++++----- + src/OT/Layout/GPOS/MarkRecord.hh | 11 +++++------ + src/hb-ot-layout-common.hh | 3 +-- + 10 files changed, 51 insertions(+), 50 deletions(-) + commit 1d665c2b521512cdd56964138fc601debd1f1177 Author: Khaled Hosny <khaled@aliftype.com> Date: Wed Aug 2 23:44:56 2023 +0300 diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/NEWS b/Build/source/libs/harfbuzz/harfbuzz-src/NEWS index 0a7b94b58a9..35e9eefdc1a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/NEWS +++ b/Build/source/libs/harfbuzz/harfbuzz-src/NEWS @@ -1,3 +1,15 @@ +Overview of changes leading to 8.2.0 +Friday, September 8, 2023 +==================================== +- Various build and fuzzing fixes +- Improvements to COLRv1 painting. + +- New API: ++hb_paint_color_glyph_func_t ++hb_paint_funcs_set_color_glyph_func ++hb_paint_color_glyph + + Overview of changes leading to 8.1.1 Wednesday, August 2, 2023 ==================================== diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/README b/Build/source/libs/harfbuzz/harfbuzz-src/README index cb075e3afd3..099d4b7719c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/README +++ b/Build/source/libs/harfbuzz/harfbuzz-src/README @@ -29,8 +29,8 @@ For user manual as well as API documentation, check: https://harfbuzz.github.io ## Download For tarball releases of HarfBuzz, look [here][3]. At the same place you -will also find Win32/Win64 binary bundles that include libharfbuzz DLL, -hb-view.exe, hb-shape.exe, and all dependencies. +will also find Win32/Win64 binary bundles that include `libharfbuzz` DLL, +`hb-view.exe`, `hb-shape.exe`, and all dependencies. The canonical source tree is available on [github][4]. diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/README.md b/Build/source/libs/harfbuzz/harfbuzz-src/README.md index cb075e3afd3..099d4b7719c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/README.md +++ b/Build/source/libs/harfbuzz/harfbuzz-src/README.md @@ -29,8 +29,8 @@ For user manual as well as API documentation, check: https://harfbuzz.github.io ## Download For tarball releases of HarfBuzz, look [here][3]. At the same place you -will also find Win32/Win64 binary bundles that include libharfbuzz DLL, -hb-view.exe, hb-shape.exe, and all dependencies. +will also find Win32/Win64 binary bundles that include `libharfbuzz` DLL, +`hb-view.exe`, `hb-shape.exe`, and all dependencies. The canonical source tree is available on [github][4]. diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac b/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac index 94257081be1..6de79ae086c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac +++ b/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ([2.64]) AC_INIT([HarfBuzz], - [8.1.1], + [8.2.0], [https://github.com/harfbuzz/harfbuzz/issues/new], [harfbuzz], [http://harfbuzz.org/]) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/meson.build b/Build/source/libs/harfbuzz/harfbuzz-src/meson.build index 85e453d7274..3bc98e2bedc 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/meson.build +++ b/Build/source/libs/harfbuzz/harfbuzz-src/meson.build @@ -1,9 +1,9 @@ project('harfbuzz', 'c', 'cpp', meson_version: '>= 0.55.0', - version: '8.1.1', + version: '8.2.0', default_options: [ 'cpp_eh=none', # Just to support msvc, we are passing -fno-exceptions also anyway - 'cpp_rtti=false', # Just to support msvc, we are passing -fno-rtti also anyway + # 'cpp_rtti=false', # Do NOT enable, wraps inherit it and ICU needs RTTI 'cpp_std=c++11', 'wrap_mode=nofallback', # Use --wrap-mode=default to revert, https://github.com/harfbuzz/harfbuzz/pull/2548 ], @@ -22,6 +22,11 @@ pkgmod = import('pkgconfig') cpp = meson.get_compiler('cpp') null_dep = dependency('', required: false) +# Enforce C++14 requirement for MSVC STL +if ['clang', 'clang-cl'].contains(cpp.get_id()) and cpp.get_define('_MSC_FULL_VER') != '' + add_project_arguments('-std=c++14', language: 'cpp') +endif + if cpp.get_argument_syntax() == 'msvc' # Ignore several spurious warnings for things HarfBuzz does very commonly. # If a warning is completely useless and spammy, use '/wdXXXX' to suppress it diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh index 6591bb4380a..60b094ecbc8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh @@ -53,6 +53,7 @@ struct Paint; struct hb_paint_context_t : hb_dispatch_context_t<hb_paint_context_t> { + const char *get_name () { return "PAINT"; } template <typename T> return_t dispatch (const T &obj) { obj.paint_glyph (this); return hb_empty_t (); } static return_t default_return_value () { return hb_empty_t (); } @@ -68,6 +69,8 @@ public: unsigned int palette_index; hb_color_t foreground; VarStoreInstancer &instancer; + hb_map_t current_glyphs; + hb_map_t current_layers; int depth_left = HB_MAX_NESTING_LEVEL; int edge_count = HB_COLRV1_MAX_EDGE_COUNT; @@ -261,6 +264,7 @@ struct Variable void paint_glyph (hb_paint_context_t *c) const { + TRACE_PAINT (this); value.paint_glyph (c, varIdxBase); } @@ -281,7 +285,7 @@ struct Variable public: VarIdx varIdxBase; public: - DEFINE_SIZE_STATIC (4 + T::static_size); + DEFINE_SIZE_MIN (VarIdx::static_size + T::min_size); }; template <typename T> @@ -315,6 +319,7 @@ struct NoVariable void paint_glyph (hb_paint_context_t *c) const { + TRACE_PAINT (this); value.paint_glyph (c, varIdxBase); } @@ -332,7 +337,7 @@ struct NoVariable T value; public: - DEFINE_SIZE_STATIC (T::static_size); + DEFINE_SIZE_MIN (T::min_size); }; // Color structures @@ -558,6 +563,7 @@ struct Affine2x3 void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); c->funcs->push_transform (c->data, xx.to_float (c->instancer (varIdxBase, 0)), yx.to_float (c->instancer (varIdxBase, 1)), @@ -639,6 +645,7 @@ struct PaintSolid void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); hb_bool_t is_foreground; hb_color_t color; @@ -693,6 +700,7 @@ struct PaintLinearGradient void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); hb_color_line_t cl = { (void *) &(this+colorLine), (this+colorLine).static_get_color_stops, c, @@ -759,6 +767,7 @@ struct PaintRadialGradient void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); hb_color_line_t cl = { (void *) &(this+colorLine), (this+colorLine).static_get_color_stops, c, @@ -823,6 +832,7 @@ struct PaintSweepGradient void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); hb_color_line_t cl = { (void *) &(this+colorLine), (this+colorLine).static_get_color_stops, c, @@ -874,6 +884,7 @@ struct PaintGlyph void paint_glyph (hb_paint_context_t *c) const { + TRACE_PAINT (this); c->funcs->push_inverse_root_transform (c->data, c->font); c->funcs->push_clip_glyph (c->data, gid, c->font); c->funcs->push_root_transform (c->data, c->font); @@ -946,6 +957,7 @@ struct PaintTransform void paint_glyph (hb_paint_context_t *c) const { + TRACE_PAINT (this); (this+transform).paint_glyph (c); c->recurse (this+src); c->funcs->pop_transform (c->data); @@ -990,6 +1002,7 @@ struct PaintTranslate void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); float ddx = dx + c->instancer (varIdxBase, 0); float ddy = dy + c->instancer (varIdxBase, 1); @@ -1038,6 +1051,7 @@ struct PaintScale void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); float sx = scaleX.to_float (c->instancer (varIdxBase, 0)); float sy = scaleY.to_float (c->instancer (varIdxBase, 1)); @@ -1088,6 +1102,7 @@ struct PaintScaleAroundCenter void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); float sx = scaleX.to_float (c->instancer (varIdxBase, 0)); float sy = scaleY.to_float (c->instancer (varIdxBase, 1)); float tCenterX = centerX + c->instancer (varIdxBase, 2); @@ -1141,6 +1156,7 @@ struct PaintScaleUniform void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); float s = scale.to_float (c->instancer (varIdxBase, 0)); bool p1 = c->funcs->push_scale (c->data, s, s); @@ -1188,6 +1204,7 @@ struct PaintScaleUniformAroundCenter void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); float s = scale.to_float (c->instancer (varIdxBase, 0)); float tCenterX = centerX + c->instancer (varIdxBase, 1); float tCenterY = centerY + c->instancer (varIdxBase, 2); @@ -1239,6 +1256,7 @@ struct PaintRotate void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); float a = angle.to_float (c->instancer (varIdxBase, 0)); bool p1 = c->funcs->push_rotate (c->data, a); @@ -1286,6 +1304,7 @@ struct PaintRotateAroundCenter void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); float a = angle.to_float (c->instancer (varIdxBase, 0)); float tCenterX = centerX + c->instancer (varIdxBase, 1); float tCenterY = centerY + c->instancer (varIdxBase, 2); @@ -1340,6 +1359,7 @@ struct PaintSkew void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0)); float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1)); @@ -1390,6 +1410,7 @@ struct PaintSkewAroundCenter void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0)); float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1)); float tCenterX = centerX + c->instancer (varIdxBase, 2); @@ -1425,8 +1446,10 @@ struct PaintComposite auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - if (!out->src.serialize_subset (c, src, this, instancer)) return_trace (false); - return_trace (out->backdrop.serialize_subset (c, backdrop, this, instancer)); + bool ret = false; + ret |= out->src.serialize_subset (c, src, this, instancer); + ret |= out->backdrop.serialize_subset (c, backdrop, this, instancer); + return_trace (ret); } bool sanitize (hb_sanitize_context_t *c) const @@ -1440,6 +1463,7 @@ struct PaintComposite void paint_glyph (hb_paint_context_t *c) const { + TRACE_PAINT (this); c->recurse (this+backdrop); c->funcs->push_group (c->data); c->recurse (this+src); @@ -1898,15 +1922,16 @@ struct LayerList : Array32OfOffset32To<Paint> auto *out = c->serializer->start_embed (this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + bool ret = false; for (const auto& _ : + hb_enumerate (*this) | hb_filter (c->plan->colrv1_layers, hb_first)) { auto *o = out->serialize_append (c->serializer); - if (unlikely (!o) || !o->serialize_subset (c, _.second, this, instancer)) - return_trace (false); + if (unlikely (!o)) return_trace (false); + ret |= o->serialize_subset (c, _.second, this, instancer); } - return_trace (true); + return_trace (ret); } bool sanitize (hb_sanitize_context_t *c) const @@ -2284,6 +2309,7 @@ struct COLR &(this+varIdxMap), hb_array (font->coords, font->num_coords)); hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer); + c.current_glyphs.add (glyph); if (version == 1) { @@ -2399,18 +2425,42 @@ hb_paint_context_t::recurse (const Paint &paint) void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const { + TRACE_PAINT (this); const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList (); for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++) { + if (unlikely (c->current_layers.has (i))) + continue; + + c->current_layers.add (i); + const Paint &paint = paint_offset_lists.get_paint (i); c->funcs->push_group (c->data); c->recurse (paint); c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); + + c->current_layers.del (i); } } void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const { + TRACE_PAINT (this); + + if (unlikely (c->current_glyphs.has (gid))) + return; + + c->current_glyphs.add (gid); + + c->funcs->push_inverse_root_transform (c->data, c->font); + if (c->funcs->color_glyph (c->data, gid, c->font)) + { + c->funcs->pop_transform (c->data); + c->current_glyphs.del (gid); + return; + } + c->funcs->pop_transform (c->data); + const COLR *colr_table = c->get_colr_table (); const Paint *paint = colr_table->get_base_glyph_paint (gid); @@ -2429,6 +2479,8 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const if (has_clip_box) c->funcs->pop_clip (c->data); + + c->current_glyphs.del (gid); } } /* namespace OT */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/AnchorMatrix.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/AnchorMatrix.hh index bd9b1897397..37ba7916f2a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/AnchorMatrix.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/AnchorMatrix.hh @@ -65,14 +65,15 @@ struct AnchorMatrix if (unlikely (!c->serializer->extend_min (out))) return_trace (false); out->rows = num_rows; + bool ret = false; for (const unsigned i : index_iter) { auto *offset = c->serializer->embed (matrixZ[i]); if (!offset) return_trace (false); - offset->serialize_subset (c, matrixZ[i], this); + ret |= offset->serialize_subset (c, matrixZ[i], this); } - return_trace (true); + return_trace (ret); } }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/CursivePosFormat1.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/CursivePosFormat1.hh index 54852aae75a..7c42c3f777a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/CursivePosFormat1.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/CursivePosFormat1.hh @@ -24,16 +24,17 @@ struct EntryExitRecord (src_base+exitAnchor).collect_variation_indices (c); } - EntryExitRecord* subset (hb_subset_context_t *c, - const void *src_base) const + bool subset (hb_subset_context_t *c, + const void *src_base) const { TRACE_SERIALIZE (this); auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (nullptr); + if (unlikely (!out)) return_trace (false); - out->entryAnchor.serialize_subset (c, entryAnchor, src_base); - out->exitAnchor.serialize_subset (c, exitAnchor, src_base); - return_trace (out); + bool ret = false; + ret |= out->entryAnchor.serialize_subset (c, entryAnchor, src_base); + ret |= out->exitAnchor.serialize_subset (c, exitAnchor, src_base); + return_trace (ret); } protected: diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/LigatureArray.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/LigatureArray.hh index a2d807cc320..59cca40aadc 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/LigatureArray.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/LigatureArray.hh @@ -27,6 +27,7 @@ struct LigatureArray : List16OfOffset16To<LigatureAttach> auto *out = c->serializer->start_embed (this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + bool ret = false; for (const auto _ : + hb_zip (coverage, *this) | hb_filter (glyphset, hb_first)) { @@ -38,13 +39,13 @@ struct LigatureArray : List16OfOffset16To<LigatureAttach> + hb_range (src.rows * class_count) | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); }) ; - matrix->serialize_subset (c, - _.second, - this, - src.rows, - indexes); + ret |= matrix->serialize_subset (c, + _.second, + this, + src.rows, + indexes); } - return_trace (this->len); + return_trace (ret); } }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkArray.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkArray.hh index 34e2ab8f6e3..0887cc158b1 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkArray.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkArray.hh @@ -82,10 +82,10 @@ struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Cove | hb_map (hb_second) ; + bool ret = false; unsigned new_length = 0; for (const auto& mark_record : mark_iter) { - if (unlikely (!mark_record.subset (c, this, klass_mapping))) - return_trace (false); + ret |= mark_record.subset (c, this, klass_mapping); new_length++; } @@ -93,7 +93,7 @@ struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Cove HB_SERIALIZE_ERROR_ARRAY_OVERFLOW))) return_trace (false); - return_trace (true); + return_trace (ret); } }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkBasePosFormat1.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkBasePosFormat1.hh index eb4712049b1..1b8f3c80a9a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkBasePosFormat1.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkBasePosFormat1.hh @@ -197,9 +197,10 @@ struct MarkBasePosFormat1_2 if (!out->markCoverage.serialize_serialize (c->serializer, new_coverage.iter ())) return_trace (false); - out->markArray.serialize_subset (c, markArray, this, - (this+markCoverage).iter (), - &klass_mapping); + if (unlikely (!out->markArray.serialize_subset (c, markArray, this, + (this+markCoverage).iter (), + &klass_mapping))) + return_trace (false); unsigned basecount = (this+baseArray).rows; auto base_iter = @@ -228,11 +229,9 @@ struct MarkBasePosFormat1_2 ; } - out->baseArray.serialize_subset (c, baseArray, this, - base_iter.len (), - base_indexes.iter ()); - - return_trace (true); + return_trace (out->baseArray.serialize_subset (c, baseArray, this, + base_iter.len (), + base_indexes.iter ())); } }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPosFormat1.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPosFormat1.hh index 92e83a0e994..af8b4723aef 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPosFormat1.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPosFormat1.hh @@ -195,9 +195,10 @@ struct MarkLigPosFormat1_2 if (!out->markCoverage.serialize_serialize (c->serializer, new_mark_coverage)) return_trace (false); - out->markArray.serialize_subset (c, markArray, this, - (this+markCoverage).iter (), - &klass_mapping); + if (unlikely (!out->markArray.serialize_subset (c, markArray, this, + (this+markCoverage).iter (), + &klass_mapping))) + return_trace (false); auto new_ligature_coverage = + hb_iter (this + ligatureCoverage) @@ -208,10 +209,9 @@ struct MarkLigPosFormat1_2 if (!out->ligatureCoverage.serialize_serialize (c->serializer, new_ligature_coverage)) return_trace (false); - out->ligatureArray.serialize_subset (c, ligatureArray, this, - hb_iter (this+ligatureCoverage), classCount, &klass_mapping); - - return_trace (true); + return_trace (out->ligatureArray.serialize_subset (c, ligatureArray, this, + hb_iter (this+ligatureCoverage), + classCount, &klass_mapping)); } }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh index 72535f4c983..70cf071668e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh @@ -183,9 +183,10 @@ struct MarkMarkPosFormat1_2 if (!out->mark1Coverage.serialize_serialize (c->serializer, new_coverage.iter ())) return_trace (false); - out->mark1Array.serialize_subset (c, mark1Array, this, - (this+mark1Coverage).iter (), - &klass_mapping); + if (unlikely (!out->mark1Array.serialize_subset (c, mark1Array, this, + (this+mark1Coverage).iter (), + &klass_mapping))) + return_trace (false); unsigned mark2count = (this+mark2Array).rows; auto mark2_iter = @@ -214,9 +215,10 @@ struct MarkMarkPosFormat1_2 ; } - out->mark2Array.serialize_subset (c, mark2Array, this, mark2_iter.len (), mark2_indexes.iter ()); + return_trace (out->mark2Array.serialize_subset (c, mark2Array, this, + mark2_iter.len (), + mark2_indexes.iter ())); - return_trace (true); } }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkRecord.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkRecord.hh index a7d489d2a51..3d11c7773cf 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkRecord.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkRecord.hh @@ -24,17 +24,16 @@ struct MarkRecord return_trace (c->check_struct (this) && markAnchor.sanitize (c, base)); } - MarkRecord *subset (hb_subset_context_t *c, - const void *src_base, - const hb_map_t *klass_mapping) const + bool subset (hb_subset_context_t *c, + const void *src_base, + const hb_map_t *klass_mapping) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (nullptr); + if (unlikely (!out)) return_trace (false); out->klass = klass_mapping->get (klass); - out->markAnchor.serialize_subset (c, markAnchor, src_base); - return_trace (out); + return_trace (out->markAnchor.serialize_subset (c, markAnchor, src_base)); } void collect_variation_indices (hb_collect_variation_indices_context_t *c, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh index 1bde9e755e9..4adb1ef606c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh @@ -163,7 +163,7 @@ struct PairPosFormat2_4 /* Isolate simple kerning and apply it half to each side. - * Results in better cursor positinoing / underline drawing. + * Results in better cursor positioning / underline drawing. * * Disabled, because causes issues... :-( * https://github.com/harfbuzz/harfbuzz/issues/3408 diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh index 2611c1e21dd..5ea611948f8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh @@ -103,6 +103,63 @@ struct Glyph } } + bool get_all_points_without_var (const hb_face_t *face, + contour_point_vector_t &points /* OUT */) const + { + switch (type) { + case SIMPLE: + if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points))) + return false; + break; + case COMPOSITE: + { + for (auto &item : get_composite_iterator ()) + if (unlikely (!item.get_points (points))) return false; + break; + } +#ifndef HB_NO_VAR_COMPOSITES + case VAR_COMPOSITE: + { + for (auto &item : get_var_composite_iterator ()) + if (unlikely (!item.get_points (points))) return false; + break; + } +#endif + case EMPTY: + break; + } + + /* Init phantom points */ + if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false; + hb_array_t<contour_point_t> phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); + { + int lsb = 0; + int h_delta = face->table.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ? + (int) header->xMin - lsb : 0; + HB_UNUSED int tsb = 0; + int v_orig = (int) header->yMax + +#ifndef HB_NO_VERTICAL + ((void) face->table.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb) +#else + 0 +#endif + ; + unsigned h_adv = face->table.hmtx->get_advance_without_var_unscaled (gid); + unsigned v_adv = +#ifndef HB_NO_VERTICAL + face->table.vmtx->get_advance_without_var_unscaled (gid) +#else + - face->get_upem () +#endif + ; + phantoms[PHANTOM_LEFT].x = h_delta; + phantoms[PHANTOM_RIGHT].x = (int) h_adv + h_delta; + phantoms[PHANTOM_TOP].y = v_orig; + phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv; + } + return true; + } + void update_mtx (const hb_subset_plan_t *plan, int xMin, int xMax, int yMin, int yMax, @@ -293,6 +350,7 @@ struct Glyph bool use_my_metrics = true, bool phantom_only = false, hb_array_t<int> coords = hb_array_t<int> (), + hb_map_t *current_glyphs = nullptr, unsigned int depth = 0, unsigned *edge_count = nullptr) const { @@ -302,6 +360,10 @@ struct Glyph if (unlikely (*edge_count > HB_GLYF_MAX_EDGE_COUNT)) return false; (*edge_count)++; + hb_map_t current_glyphs_stack; + if (current_glyphs == nullptr) + current_glyphs = ¤t_glyphs_stack; + if (head_maxp_info) { head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth); @@ -396,10 +458,17 @@ struct Glyph unsigned int comp_index = 0; for (auto &item : get_composite_iterator ()) { + hb_codepoint_t item_gid = item.get_gid (); + + if (unlikely (current_glyphs->has (item_gid))) + continue; + + current_glyphs->add (item_gid); + unsigned old_count = all_points.length; if (unlikely ((!phantom_only || (use_my_metrics && item.is_use_my_metrics ())) && - !glyf_accelerator.glyph_for_gid (item.get_gid ()) + !glyf_accelerator.glyph_for_gid (item_gid) .get_points (font, glyf_accelerator, all_points, @@ -410,9 +479,13 @@ struct Glyph use_my_metrics, phantom_only, coords, + current_glyphs, depth + 1, edge_count))) + { + current_glyphs->del (item_gid); return false; + } auto comp_points = all_points.as_array ().sub_array (old_count); @@ -448,9 +521,13 @@ struct Glyph all_points.resize (all_points.length - PHANTOM_COUNT); if (all_points.length > HB_GLYF_MAX_POINTS) + { + current_glyphs->del (item_gid); return false; + } comp_index++; + current_glyphs->del (item_gid); } if (head_maxp_info && depth == 0) @@ -468,6 +545,13 @@ struct Glyph hb_array_t<contour_point_t> points_left = points.as_array (); for (auto &item : get_var_composite_iterator ()) { + hb_codepoint_t item_gid = item.get_gid (); + + if (unlikely (current_glyphs->has (item_gid))) + continue; + + current_glyphs->add (item_gid); + unsigned item_num_points = item.get_num_points (); hb_array_t<contour_point_t> record_points = points_left.sub_array (0, item_num_points); assert (record_points.length == item_num_points); @@ -485,7 +569,7 @@ struct Glyph unsigned old_count = all_points.length; if (unlikely ((!phantom_only || (use_my_metrics && item.is_use_my_metrics ())) && - !glyf_accelerator.glyph_for_gid (item.get_gid ()) + !glyf_accelerator.glyph_for_gid (item_gid) .get_points (font, glyf_accelerator, all_points, @@ -496,9 +580,13 @@ struct Glyph use_my_metrics, phantom_only, coord_setter.get_coords (), + current_glyphs, depth + 1, edge_count))) + { + current_glyphs->del (item_gid); return false; + } auto comp_points = all_points.as_array ().sub_array (old_count); @@ -514,9 +602,14 @@ struct Glyph all_points.resize (all_points.length - PHANTOM_COUNT); if (all_points.length > HB_GLYF_MAX_POINTS) + { + current_glyphs->del (item_gid); return false; + } points_left += item_num_points; + + current_glyphs->del (item_gid); } all_points.extend (phantoms); } break; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh index 06809581904..2b742eff2ec 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh @@ -290,7 +290,7 @@ struct graph_t new_parents.set (id_map[_.first], _.second); } - if (new_parents.in_error ()) + if (parents.in_error() || new_parents.in_error ()) return false; parents = std::move (new_parents); @@ -310,8 +310,15 @@ struct graph_t if (parents.has (old_index, &pv)) { unsigned v = *pv; - parents.set (new_index, v); + if (!parents.set (new_index, v)) + incoming_edges_ -= v; parents.del (old_index); + + if (incoming_edges_ == 1) + { + single_parent = *parents.keys (); + parents.reset (); + } } } @@ -467,6 +474,18 @@ struct graph_t return root ().equals (other.root (), *this, other, 0); } + void print () const { + for (int i = vertices_.length - 1; i >= 0; i--) + { + const auto& v = vertices_[i]; + printf("%d: %lu [", i, v.table_size()); + for (const auto &l : v.obj.real_links) { + printf("%u, ", l.objidx); + } + printf("]\n"); + } + } + // Sorts links of all objects in a consistent manner and zeroes all offsets. void normalize () { diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/gsubgpos-context.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/gsubgpos-context.hh index 26b7cfe4d43..b25d538fe3d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/gsubgpos-context.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/gsubgpos-context.hh @@ -40,7 +40,7 @@ struct gsubgpos_graph_context_t graph_t& graph; unsigned lookup_list_index; hb_hashmap_t<unsigned, graph::Lookup*> lookups; - + hb_hashmap_t<unsigned, unsigned> subtable_to_extension; HB_INTERNAL gsubgpos_graph_context_t (hb_tag_t table_tag_, graph_t& graph_); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/gsubgpos-graph.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/gsubgpos-graph.hh index 303517f687e..12fcbdc497f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/gsubgpos-graph.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/gsubgpos-graph.hh @@ -299,24 +299,35 @@ struct Lookup : public OT::Lookup unsigned subtable_index) { unsigned type = lookupType; + unsigned ext_index = -1; + unsigned* existing_ext_index = nullptr; + if (c.subtable_to_extension.has(subtable_index, &existing_ext_index)) { + ext_index = *existing_ext_index; + } else { + ext_index = create_extension_subtable(c, subtable_index, type); + c.subtable_to_extension.set(subtable_index, ext_index); + } - unsigned ext_index = create_extension_subtable(c, subtable_index, type); if (ext_index == (unsigned) -1) return false; + auto& subtable_vertex = c.graph.vertices_[subtable_index]; auto& lookup_vertex = c.graph.vertices_[lookup_index]; for (auto& l : lookup_vertex.obj.real_links.writer ()) { - if (l.objidx == subtable_index) + if (l.objidx == subtable_index) { // Change lookup to point at the extension. l.objidx = ext_index; + if (existing_ext_index) + subtable_vertex.remove_parent(lookup_index); + } } // Make extension point at the subtable. auto& ext_vertex = c.graph.vertices_[ext_index]; - auto& subtable_vertex = c.graph.vertices_[subtable_index]; ext_vertex.add_parent (lookup_index); - subtable_vertex.remap_parent (lookup_index, ext_index); + if (!existing_ext_index) + subtable_vertex.remap_parent (lookup_index, ext_index); return true; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/markbasepos-graph.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/markbasepos-graph.hh index 5e9d5aea3a5..e10e1cf3e3c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/markbasepos-graph.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/markbasepos-graph.hh @@ -318,7 +318,9 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2<S { hb_vector_t<class_info_t> class_to_info; - unsigned class_count= classCount; + unsigned class_count = classCount; + if (!class_count) return class_to_info; + if (!class_to_info.resize (class_count)) return hb_vector_t<class_info_t>(); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh index 6cabc7fb02d..ea970571654 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh @@ -367,6 +367,10 @@ struct hb_enable_if (std::is_integral<T>::value && sizeof (T) > sizeof (uint32_t))> constexpr auto impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, (uint32_t) (v ^ (v >> 32)) * 2654435761u /* Knuth's multiplicative hash */) + template <typename T, + hb_enable_if (std::is_floating_point<T>::value)> constexpr auto + impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, fasthash32 (std::addressof (v), sizeof (T), 0xf437ffe6)) + template <typename T> constexpr auto impl (const T& v, hb_priority<0>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v))>>{} (hb_deref (v))) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh index 64dbf2e8699..f541472544a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh @@ -93,7 +93,7 @@ struct hb_bimap_t auto iter () const HB_AUTO_RETURN (+ forw_map.iter()) }; -/* Inremental bimap: only lhs is given, rhs is incrementally assigned */ +/* Incremental bimap: only lhs is given, rhs is incrementally assigned */ struct hb_inc_bimap_t { bool in_error () const { return forw_map.in_error () || back_map.in_error (); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-page.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-page.hh index e1826e12a59..869c6789573 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-page.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-page.hh @@ -97,6 +97,7 @@ struct hb_bit_page_t static inline constexpr unsigned len () { return ARRAY_LENGTH_CONST (v); } + operator bool () const { return !is_empty (); } bool is_empty () const { if (has_population ()) return !population; @@ -218,6 +219,7 @@ struct hb_bit_page_t return count; } + bool operator == (const hb_bit_page_t &other) const { return is_equal (other); } bool is_equal (const hb_bit_page_t &other) const { for (unsigned i = 0; i < len (); i++) @@ -225,6 +227,7 @@ struct hb_bit_page_t return false; return true; } + bool operator <= (const hb_bit_page_t &larger_page) const { return is_subset (larger_page); } bool is_subset (const hb_bit_page_t &larger_page) const { if (has_population () && larger_page.has_population () && diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh index 9e60cb934aa..1dbcce5cbd5 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh @@ -913,7 +913,7 @@ struct hb_bit_set_t /* The extra page_map length is necessary; can't just rely on vector here, * since the next check would be tricked because a null page also has - * major==0, which we can't distinguish from an actualy major==0 page... */ + * major==0, which we can't distinguish from an actually major==0 page... */ unsigned i = last_page_lookup; if (likely (i < page_map.length)) { @@ -947,7 +947,7 @@ struct hb_bit_set_t /* The extra page_map length is necessary; can't just rely on vector here, * since the next check would be tricked because a null page also has - * major==0, which we can't distinguish from an actualy major==0 page... */ + * major==0, which we can't distinguish from an actually major==0 page... */ unsigned i = last_page_lookup; if (likely (i < page_map.length)) { diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc index 749ef9bd497..934c6c21294 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc @@ -1327,7 +1327,7 @@ hb_buffer_get_invisible_glyph (const hb_buffer_t *buffer) * Sets the #hb_codepoint_t that replaces characters not found in * the font during shaping. * - * The not-found glyph defaults to zero, sometimes knows as the + * The not-found glyph defaults to zero, sometimes known as the * ".notdef" glyph. This API allows for differentiating the two. * * Since: 3.1.0 @@ -2076,7 +2076,7 @@ hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_g * hb_buffer_diff: * @buffer: a buffer. * @reference: other buffer to compare to. - * @dottedcircle_glyph: glyph id of U+25CC DOTTED CIRCLE, or (hb_codepont_t) -1. + * @dottedcircle_glyph: glyph id of U+25CC DOTTED CIRCLE, or (hb_codepoint_t) -1. * @position_fuzz: allowed absolute difference in position values. * * If dottedcircle_glyph is (hb_codepoint_t) -1 then #HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h index bff78543c87..3573127ff00 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h @@ -99,7 +99,7 @@ typedef struct hb_glyph_info_t { * layout, by avoiding re-shaping of each line * after line-breaking, by limiting the * reshaping to a small piece around the - * breaking positin only, even if the breaking + * breaking position only, even if the breaking * position carries the * #HB_GLYPH_FLAG_UNSAFE_TO_BREAK or when * hyphenation or other text transformation diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo.cc index 68c7bc064ff..f4f9f54ab3b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo.cc @@ -166,6 +166,32 @@ hb_cairo_pop_transform (hb_paint_funcs_t *pfuncs HB_UNUSED, cairo_restore (cr); } +static hb_bool_t +hb_cairo_paint_color_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED, + void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font, + void *user_data HB_UNUSED) +{ + hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data; + cairo_t *cr = c->cr; + + cairo_save (cr); + + hb_position_t x_scale, y_scale; + hb_font_get_scale (font, &x_scale, &y_scale); + cairo_scale (cr, x_scale, y_scale); + + cairo_glyph_t cairo_glyph = { glyph, 0, 0 }; + cairo_set_scaled_font (cr, c->scaled_font); + cairo_set_font_size (cr, 1); + cairo_show_glyphs (cr, &cairo_glyph, 1); + + cairo_restore (cr); + + return true; +} + static void hb_cairo_push_clip_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED, void *paint_data, @@ -397,6 +423,7 @@ static struct hb_cairo_paint_funcs_lazy_loader_t : hb_paint_funcs_lazy_loader_t< hb_paint_funcs_set_push_transform_func (funcs, hb_cairo_push_transform, nullptr, nullptr); hb_paint_funcs_set_pop_transform_func (funcs, hb_cairo_pop_transform, nullptr, nullptr); + hb_paint_funcs_set_color_glyph_func (funcs, hb_cairo_paint_color_glyph, nullptr, nullptr); hb_paint_funcs_set_push_clip_glyph_func (funcs, hb_cairo_push_clip_glyph, nullptr, nullptr); hb_paint_funcs_set_push_clip_rectangle_func (funcs, hb_cairo_push_clip_rectangle, nullptr, nullptr); hb_paint_funcs_set_pop_clip_func (funcs, hb_cairo_pop_clip, nullptr, nullptr); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc index 282a8e4d0f6..bd4cd88e34f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.cc @@ -815,7 +815,7 @@ parse_tag (const char **pp, const char *end, hb_tag_t *tag) } const char *p = *pp; - while (*pp < end && (ISALNUM(**pp) || **pp == '_')) + while (*pp < end && (**pp != ' ' && **pp != '=' && **pp != '[')) (*pp)++; if (p == *pp || *pp - p > 4) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh index 6055fce962c..559db4067e2 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh @@ -265,8 +265,9 @@ static inline void _hb_warn_no_return (bool returned) } } template <> -/*static*/ inline void _hb_warn_no_return<hb_empty_t> (bool returned HB_UNUSED) -{} +/*static*/ inline void _hb_warn_no_return<hb_empty_t> (bool returned HB_UNUSED) {} +template <> +/*static*/ inline void _hb_warn_no_return<void> (bool returned HB_UNUSED) {} template <int max_level, typename ret_t> struct hb_auto_trace_t @@ -450,12 +451,26 @@ struct hb_no_trace_t { #define HB_DEBUG_SUBSET_REPACK (HB_DEBUG+0) #endif +#ifndef HB_DEBUG_PAINT +#define HB_DEBUG_PAINT (HB_DEBUG+0) +#endif +#if HB_DEBUG_PAINT +#define TRACE_PAINT(this) \ + HB_UNUSED hb_auto_trace_t<HB_DEBUG_PAINT, void> trace \ + (&c->debug_depth, c->get_name (), this, HB_FUNC, \ + " ") +#else +#define TRACE_PAINT(this) HB_UNUSED hb_no_trace_t<void> trace +#endif + + #ifndef HB_DEBUG_DISPATCH #define HB_DEBUG_DISPATCH ( \ HB_DEBUG_APPLY + \ HB_DEBUG_SANITIZE + \ HB_DEBUG_SERIALIZE + \ HB_DEBUG_SUBSET + \ + HB_DEBUG_PAINT + \ 0) #endif #if HB_DEBUG_DISPATCH diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc index f062bfaf757..00f1f6d3825 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc @@ -1066,7 +1066,7 @@ hb_font_get_nominal_glyph (hb_font_t *font, * @glyph_stride: The stride between successive glyph IDs * * Fetches the nominal glyph IDs for a sequence of Unicode code points. Glyph - * IDs must be returned in a #hb_codepoint_t output parameter. Stopes at the + * IDs must be returned in a #hb_codepoint_t output parameter. Stops at the * first unsupported glyph ID. * * Return value: the number of code points processed diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh index fa5712f9b33..1afbbbb1836 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh @@ -105,6 +105,8 @@ struct hb_ft_paint_context_t FT_Color *palette; unsigned palette_index; hb_color_t foreground; + hb_map_t current_glyphs; + hb_map_t current_layers; int depth_left = HB_MAX_NESTING_LEVEL; int edge_count = HB_COLRV1_MAX_EDGE_COUNT; }; @@ -220,9 +222,18 @@ _hb_ft_paint (hb_ft_paint_context_t *c, &paint.u.colr_layers.layer_iterator, &other_paint)) { + unsigned i = paint.u.colr_layers.layer_iterator.layer; + + if (unlikely (c->current_layers.has (i))) + continue; + + c->current_layers.add (i); + c->funcs->push_group (c->data); c->recurse (other_paint); c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); + + c->current_layers.del (i); } } break; @@ -320,8 +331,27 @@ _hb_ft_paint (hb_ft_paint_context_t *c, break; case FT_COLR_PAINTFORMAT_COLR_GLYPH: { + hb_codepoint_t gid = paint.u.colr_glyph.glyphID; + + if (unlikely (c->current_glyphs.has (gid))) + return; + + c->current_glyphs.add (gid); + + c->funcs->push_inverse_root_transform (c->data, c->font); + c->ft_font->lock.unlock (); + if (c->funcs->color_glyph (c->data, gid, c->font)) + { + c->ft_font->lock.lock (); + c->funcs->pop_transform (c->data); + c->current_glyphs.del (gid); + return; + } + c->ft_font->lock.lock (); + c->funcs->pop_transform (c->data); + FT_OpaquePaint other_paint = {0}; - if (FT_Get_Color_Glyph_Paint (ft_face, paint.u.colr_glyph.glyphID, + if (FT_Get_Color_Glyph_Paint (ft_face, gid, FT_COLOR_NO_ROOT_TRANSFORM, &other_paint)) { @@ -350,6 +380,8 @@ _hb_ft_paint (hb_ft_paint_context_t *c, if (has_clip_box) c->funcs->pop_clip (c->data); + + c->current_glyphs.del (gid); } } break; @@ -474,6 +506,7 @@ hb_ft_paint_glyph_colr (hb_font_t *font, hb_ft_paint_context_t c (ft_font, font, paint_funcs, paint_data, palette, palette_index, foreground); + c.current_glyphs.add (gid); bool is_bounded = true; FT_ClipBox clip_box; @@ -497,6 +530,7 @@ hb_ft_paint_glyph_colr (hb_font_t *font, hb_ft_paint_context_t ce (ft_font, font, extents_funcs, &extents_data, palette, palette_index, foreground); + ce.current_glyphs.add (gid); ce.funcs->push_root_transform (ce.data, font); ce.recurse (paint); ce.funcs->pop_transform (ce.data); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh index c503b30652b..25c1e71e133 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh @@ -106,7 +106,7 @@ #endif #ifndef HB_COLRV1_MAX_EDGE_COUNT -#define HB_COLRV1_MAX_EDGE_COUNT 1024 +#define HB_COLRV1_MAX_EDGE_COUNT 65536 #endif diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc index 5d67cd9a12d..0dc9246f129 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc @@ -365,7 +365,7 @@ hb_map_update (hb_map_t *map, * @key: (out): Key retrieved * @value: (out): Value retrieved * - * Fetches the next key/value paire in @map. + * Fetches the next key/value pair in @map. * * Set @idx to -1 to get started. * diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh index 42604ef7c2c..6ea41665899 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh @@ -276,6 +276,11 @@ struct hb_hashmap_t uint32_t hash = hb_hash (key); return set_with_hash (std::move (key), hash, std::forward<VV> (value), overwrite); } + bool add (const K &key) + { + uint32_t hash = hb_hash (key); + return set_with_hash (key, hash, item_t::default_value ()); + } const V& get_with_hash (const K &key, uint32_t hash) const { diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh index 6796906ba82..854485d3df8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-null.hh @@ -85,7 +85,7 @@ using hb_null_size = _hb_null_size<T, void>; template <typename T, typename> struct _hb_static_size : hb_integral_constant<unsigned, sizeof (T)> {}; template <typename T> -struct _hb_static_size<T, hb_void_t<decltype (T::min_size)>> : hb_integral_constant<unsigned, T::static_size> {}; +struct _hb_static_size<T, hb_void_t<decltype (T::static_size)>> : hb_integral_constant<unsigned, T::static_size> {}; template <typename T> using hb_static_size = _hb_static_size<T, void>; #define hb_static_size(T) hb_static_size<T>::value diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh index 0831e4499e1..2cc50980233 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh @@ -3215,8 +3215,7 @@ struct FeatureTableSubstitutionRecord if (unlikely (!out)) return_trace (false); out->featureIndex = c->feature_index_map->get (featureIndex); - bool ret = out->feature.serialize_subset (c->subset_context, feature, base, c); - return_trace (ret); + return_trace (out->feature.serialize_subset (c->subset_context, feature, base, c)); } bool sanitize (hb_sanitize_context_t *c, const void *base) const diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc index 9c1c2a950e7..90f596ae79d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc @@ -1054,7 +1054,7 @@ hb_ot_position_plan (const hb_ot_shape_context_t *c) * direction is backward we don't shift and it will end up * hanging over the next glyph after the final reordering. * - * Note: If fallback positinoing happens, we don't care about + * Note: If fallback positioning happens, we don't care about * this as it will be overridden. */ bool adjust_offsets_when_zeroing = c->plan->adjust_mark_positioning_when_zeroing && diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc index 256f8f1d14e..72dcc84df5e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc @@ -486,8 +486,10 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH))) return; - /* The Arabic shaper currently always processes in RTL mode, so we should - * stretch / position the stretched pieces to the left / preceding glyphs. */ + bool rtl = buffer->props.direction == HB_DIRECTION_RTL; + + if (!rtl) + buffer->reverse (); /* We do a two pass implementation: * First pass calculates the exact number of extra glyphs we need, @@ -577,7 +579,10 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, ++n_copies; hb_position_t excess = (n_copies + 1) * sign * w_repeating - sign * w_remaining; if (excess > 0) + { extra_repeat_overlap = excess / (n_copies * n_repeating); + w_remaining = 0; + } } if (step == MEASURE) @@ -588,7 +593,7 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, else { buffer->unsafe_to_break (context, end); - hb_position_t x_offset = 0; + hb_position_t x_offset = w_remaining / 2; for (unsigned int k = end; k > start; k--) { hb_position_t width = font->get_glyph_h_advance (info[k - 1].codepoint); @@ -599,16 +604,27 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, DEBUG_MSG (ARABIC, nullptr, "appending %u copies of glyph %u; j=%u", repeat, info[k - 1].codepoint, j); + pos[k - 1].x_advance = 0; for (unsigned int n = 0; n < repeat; n++) { - x_offset -= width; - if (n > 0) - x_offset += extra_repeat_overlap; + if (rtl) + { + x_offset -= width; + if (n > 0) + x_offset += extra_repeat_overlap; + } pos[k - 1].x_offset = x_offset; /* Append copy. */ --j; info[j] = info[k - 1]; pos[j] = pos[k - 1]; + + if (!rtl) + { + x_offset += width; + if (n > 0) + x_offset -= extra_repeat_overlap; + } } } } @@ -625,6 +641,9 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, buffer->len = new_len; } } + + if (!rtl) + buffer->reverse (); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh index 9e813f6d2df..23d7f7cc3d0 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh @@ -230,7 +230,7 @@ struct VarStoreInstancer /* according to the spec, if colr table has varStore but does not have * varIdxMap, then an implicit identity mapping is used */ float operator() (uint32_t varIdx, unsigned short offset = 0) const - { return varStore->get_delta (varIdxMap ? varIdxMap->map (VarIdx::add (varIdx, offset)) : varIdx + offset, coords); } + { return coords ? varStore->get_delta (varIdxMap ? varIdxMap->map (VarIdx::add (varIdx, offset)) : varIdx + offset, coords) : 0; } const VariationStore *varStore; const DeltaSetIndexMap *varIdxMap; @@ -449,17 +449,26 @@ struct tuple_delta_t hb_vector_t<char> compiled_tuple_header; hb_vector_t<char> compiled_deltas; + /* compiled peak coords, empty for non-gvar tuples */ + hb_vector_t<char> compiled_peak_coords; + tuple_delta_t () = default; tuple_delta_t (const tuple_delta_t& o) = default; - tuple_delta_t (tuple_delta_t&& o) : tuple_delta_t () + friend void swap (tuple_delta_t& a, tuple_delta_t& b) { - axis_tuples = std::move (o.axis_tuples); - indices = std::move (o.indices); - deltas_x = std::move (o.deltas_x); - deltas_y = std::move (o.deltas_y); + hb_swap (a.axis_tuples, b.axis_tuples); + hb_swap (a.indices, b.indices); + hb_swap (a.deltas_x, b.deltas_x); + hb_swap (a.deltas_y, b.deltas_y); + hb_swap (a.compiled_tuple_header, b.compiled_tuple_header); + hb_swap (a.compiled_deltas, b.compiled_deltas); + hb_swap (a.compiled_peak_coords, b.compiled_peak_coords); } + tuple_delta_t (tuple_delta_t&& o) : tuple_delta_t () + { hb_swap (*this, o); } + tuple_delta_t& operator = (tuple_delta_t&& o) { hb_swap (*this, o); @@ -552,13 +561,43 @@ struct tuple_delta_t return out; } + bool compile_peak_coords (const hb_map_t& axes_index_map, + const hb_map_t& axes_old_index_tag_map) + { + unsigned axis_count = axes_index_map.get_population (); + if (unlikely (!compiled_peak_coords.alloc (axis_count * F2DOT14::static_size))) + return false; + + unsigned orig_axis_count = axes_old_index_tag_map.get_population (); + for (unsigned i = 0; i < orig_axis_count; i++) + { + if (!axes_index_map.has (i)) + continue; + + hb_tag_t axis_tag = axes_old_index_tag_map.get (i); + Triple *coords; + F2DOT14 peak_coord; + if (axis_tuples.has (axis_tag, &coords)) + peak_coord.set_float (coords->middle); + else + peak_coord.set_int (0); + + /* push F2DOT14 value into char vector */ + int16_t val = peak_coord.to_int (); + compiled_peak_coords.push (static_cast<char> (val >> 8)); + compiled_peak_coords.push (static_cast<char> (val & 0xFF)); + } + + return !compiled_peak_coords.in_error (); + } + /* deltas should be compiled already before we compile tuple * variation header cause we need to fill in the size of the * serialized data for this tuple variation */ - //TODO(qxliu):add option to use sharedTuples in gvar bool compile_tuple_var_header (const hb_map_t& axes_index_map, unsigned points_data_length, - const hb_map_t& axes_old_index_tag_map) + const hb_map_t& axes_old_index_tag_map, + const hb_hashmap_t<const hb_vector_t<char>*, unsigned>* shared_tuples_idx_map) { if (!compiled_deltas) return false; @@ -574,14 +613,25 @@ struct tuple_delta_t hb_array_t<F2DOT14> coords (p, end - p); /* encode peak coords */ - unsigned peak_count = encode_peak_coords(coords, flag, axes_index_map, axes_old_index_tag_map); - if (!peak_count) return false; + unsigned peak_count = 0; + unsigned *shared_tuple_idx; + if (shared_tuples_idx_map && + shared_tuples_idx_map->has (&compiled_peak_coords, &shared_tuple_idx)) + { + flag = *shared_tuple_idx; + } + else + { + peak_count = encode_peak_coords(coords, flag, axes_index_map, axes_old_index_tag_map); + if (!peak_count) return false; + } /* encode interim coords, it's optional so returned num could be 0 */ unsigned interim_count = encode_interm_coords (coords.sub_array (peak_count), flag, axes_index_map, axes_old_index_tag_map); - //TODO(qxliu): add option to use shared_points in gvar - flag |= TupleVariationHeader::TuppleIndex::PrivatePointNumbers; + /* pointdata length = 0 implies "use shared points" */ + if (points_data_length) + flag |= TupleVariationHeader::TuppleIndex::PrivatePointNumbers; unsigned serialized_data_size = points_data_length + compiled_deltas.length; TupleVariationHeader *o = reinterpret_cast<TupleVariationHeader *> (compiled_tuple_header.begin ()); @@ -870,6 +920,111 @@ struct tuple_delta_t } return encoded_len; } + + bool calc_inferred_deltas (const contour_point_vector_t& orig_points) + { + unsigned point_count = orig_points.length; + if (point_count != indices.length) + return false; + + unsigned ref_count = 0; + hb_vector_t<unsigned> end_points; + + for (unsigned i = 0; i < point_count; i++) + { + if (indices.arrayZ[i]) + ref_count++; + if (orig_points.arrayZ[i].is_end_point) + end_points.push (i); + } + /* all points are referenced, nothing to do */ + if (ref_count == point_count) + return true; + if (unlikely (end_points.in_error ())) return false; + + hb_set_t inferred_idxes; + unsigned start_point = 0; + for (unsigned end_point : end_points) + { + /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */ + unsigned unref_count = 0; + for (unsigned i = start_point; i < end_point + 1; i++) + unref_count += indices.arrayZ[i]; + unref_count = (end_point - start_point + 1) - unref_count; + + unsigned j = start_point; + if (unref_count == 0 || unref_count > end_point - start_point) + goto no_more_gaps; + for (;;) + { + /* Locate the next gap of unreferenced points between two referenced points prev and next. + * Note that a gap may wrap around at left (start_point) and/or at right (end_point). + */ + unsigned int prev, next, i; + for (;;) + { + i = j; + j = next_index (i, start_point, end_point); + if (indices.arrayZ[i] && !indices.arrayZ[j]) break; + } + prev = j = i; + for (;;) + { + i = j; + j = next_index (i, start_point, end_point); + if (!indices.arrayZ[i] && indices.arrayZ[j]) break; + } + next = j; + /* Infer deltas for all unref points in the gap between prev and next */ + i = prev; + for (;;) + { + i = next_index (i, start_point, end_point); + if (i == next) break; + deltas_x.arrayZ[i] = infer_delta (orig_points.arrayZ[i].x, orig_points.arrayZ[prev].x, orig_points.arrayZ[next].x, + deltas_x.arrayZ[prev], deltas_x.arrayZ[next]); + deltas_y.arrayZ[i] = infer_delta (orig_points.arrayZ[i].y, orig_points.arrayZ[prev].y, orig_points.arrayZ[next].y, + deltas_y.arrayZ[prev], deltas_y.arrayZ[next]); + inferred_idxes.add (i); + if (--unref_count == 0) goto no_more_gaps; + } + } + no_more_gaps: + start_point = end_point + 1; + } + + for (unsigned i = 0; i < point_count; i++) + { + /* if points are not referenced and deltas are not inferred, set to 0. + * reference all points for gvar */ + if ( !indices[i]) + { + if (!inferred_idxes.has (i)) + { + deltas_x.arrayZ[i] = 0.f; + deltas_y.arrayZ[i] = 0.f; + } + indices[i] = true; + } + } + return true; + } + + static float infer_delta (float target_val, float prev_val, float next_val, float prev_delta, float next_delta) + { + if (prev_val == next_val) + return (prev_delta == next_delta) ? prev_delta : 0.f; + else if (target_val <= hb_min (prev_val, next_val)) + return (prev_val < next_val) ? prev_delta : next_delta; + else if (target_val >= hb_max (prev_val, next_val)) + return (prev_val > next_val) ? prev_delta : next_delta; + + float r = (target_val - prev_val) / (next_val - prev_val); + return prev_delta + r * (next_delta - prev_delta); + } + + static unsigned int next_index (unsigned int i, unsigned int start, unsigned int end) + { return (i >= end) ? start : (i + 1); } }; struct TupleVariationData @@ -910,7 +1065,22 @@ struct TupleVariationData /* referenced point set-> count map, used in finding shared points */ hb_hashmap_t<const hb_vector_t<bool>*, unsigned> point_set_count_map; + /* empty for non-gvar tuples. + * shared_points_bytes is just a copy of some value in the point_data_map, + * which will be freed during map destruction. Save it for serialization, so + * no need to do find_shared_points () again */ + hb_bytes_t shared_points_bytes; + + /* total compiled byte size as TupleVariationData format, initialized to its + * min_size: 4 */ + unsigned compiled_byte_size = 4; + public: + tuple_variations_t () = default; + tuple_variations_t (const tuple_variations_t&) = delete; + tuple_variations_t& operator=(const tuple_variations_t&) = delete; + tuple_variations_t (tuple_variations_t&&) = default; + tuple_variations_t& operator=(tuple_variations_t&&) = default; ~tuple_variations_t () { fini (); } void fini () { @@ -921,8 +1091,17 @@ struct TupleVariationData tuple_vars.fini (); } + explicit operator bool () const { return bool (tuple_vars); } unsigned get_var_count () const - { return tuple_vars.length; } + { + unsigned count = tuple_vars.length; + if (shared_points_bytes.length) + count |= TupleVarCount::SharedPointNumbers; + return count; + } + + unsigned get_compiled_byte_size () const + { return compiled_byte_size; } bool create_from_tuple_var_data (tuple_iterator_t iterator, unsigned tuple_var_count, @@ -992,6 +1171,7 @@ struct TupleVariationData return true; } + private: void 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) { @@ -1025,7 +1205,7 @@ struct TupleVariationData void merge_tuple_variations () { hb_vector_t<tuple_delta_t> new_vars; - hb_hashmap_t<hb_hashmap_t<hb_tag_t, Triple>, unsigned> m; + hb_hashmap_t<const hb_hashmap_t<hb_tag_t, Triple>*, unsigned> m; unsigned i = 0; for (const tuple_delta_t& var : tuple_vars) { @@ -1033,14 +1213,14 @@ struct TupleVariationData if (var.axis_tuples.is_empty ()) continue; unsigned *idx; - if (m.has (var.axis_tuples, &idx)) + if (m.has (&(var.axis_tuples), &idx)) { new_vars[*idx] += var; } else { new_vars.push (var); - m.set (var.axis_tuples, i); + m.set (&(var.axis_tuples), i); i++; } } @@ -1187,19 +1367,45 @@ struct TupleVariationData return res; } - void instantiate (const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location, - const hb_hashmap_t<hb_tag_t, TripleDistances>& axes_triple_distances) + bool calc_inferred_deltas (contour_point_vector_t& contour_points) { + for (tuple_delta_t& var : tuple_vars) + if (!var.calc_inferred_deltas (contour_points)) + return false; + + return true; + } + + public: + bool instantiate (const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location, + const hb_hashmap_t<hb_tag_t, TripleDistances>& axes_triple_distances, + contour_point_vector_t* contour_points = nullptr) + { + if (!tuple_vars) return true; change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances); + /* compute inferred deltas only for gvar */ + if (contour_points) + if (!calc_inferred_deltas (*contour_points)) + return false; + merge_tuple_variations (); + return !tuple_vars.in_error (); } bool compile_bytes (const hb_map_t& axes_index_map, - const hb_map_t& axes_old_index_tag_map) + const hb_map_t& axes_old_index_tag_map, + bool use_shared_points, + const hb_hashmap_t<const hb_vector_t<char>*, unsigned>* shared_tuples_idx_map = nullptr) { // compile points set and store data in hashmap if (!compile_all_point_sets ()) return false; + + if (use_shared_points) + { + shared_points_bytes = find_shared_points (); + compiled_byte_size += shared_points_bytes.length; + } // compile delta and tuple var header for each tuple variation for (auto& tuple: tuple_vars) { @@ -1211,8 +1417,11 @@ struct TupleVariationData if (!tuple.compile_deltas ()) return false; - if (!tuple.compile_tuple_var_header (axes_index_map, points_data->length, axes_old_index_tag_map)) + unsigned points_data_length = (*points_data != shared_points_bytes) ? points_data->length : 0; + if (!tuple.compile_tuple_var_header (axes_index_map, points_data_length, axes_old_index_tag_map, + shared_tuples_idx_map)) return false; + compiled_byte_size += tuple.compiled_tuple_header.length + points_data_length + tuple.compiled_deltas.length; } return true; } @@ -1229,9 +1438,12 @@ struct TupleVariationData return_trace (true); } - bool serialize_var_data (hb_serialize_context_t *c) const + bool serialize_var_data (hb_serialize_context_t *c, bool is_gvar) const { TRACE_SERIALIZE (this); + if (is_gvar) + shared_points_bytes.copy (c); + for (const auto& tuple: tuple_vars) { const hb_vector_t<bool>* points_set = &(tuple.indices); @@ -1239,10 +1451,20 @@ struct TupleVariationData if (!point_data_map.has (points_set, &point_data)) return_trace (false); - point_data->copy (c); + if (!is_gvar || *point_data != shared_points_bytes) + point_data->copy (c); + tuple.compiled_deltas.as_array ().copy (c); if (c->in_error ()) return_trace (false); } + + /* padding for gvar */ + if (is_gvar && (compiled_byte_size % 2)) + { + HBUINT8 pad; + pad = 0; + if (!c->embed (pad)) return_trace (false); + } return_trace (true); } }; @@ -1428,9 +1650,12 @@ struct TupleVariationData bool serialize (hb_serialize_context_t *c, bool is_gvar, - tuple_variations_t& tuple_variations) const + const tuple_variations_t& tuple_variations) const { TRACE_SERIALIZE (this); + /* empty tuple variations, just return and skip serialization. */ + if (!tuple_variations) return_trace (true); + auto *out = c->start_embed (this); if (unlikely (!c->extend_min (out))) return_trace (false); @@ -1446,15 +1671,17 @@ struct TupleVariationData if (!is_gvar) data_offset += 4; if (!c->check_assign (out->data, data_offset, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false); - return tuple_variations.serialize_var_data (c); + return tuple_variations.serialize_var_data (c, is_gvar); } protected: struct TupleVarCount : HBUINT16 { + friend struct tuple_variations_t; bool has_shared_point_numbers () const { return ((*this) & SharedPointNumbers); } unsigned int get_count () const { return (*this) & CountMask; } TupleVarCount& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; } + explicit operator bool () const { return get_count (); } protected: enum Flags diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-cvar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-cvar-table.hh index fee39eff386..adb81769bdc 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-cvar-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-cvar-table.hh @@ -131,6 +131,7 @@ struct cvar TupleVariationData::tuple_variations_t& tuple_variations) const { TRACE_SERIALIZE (this); + if (!tuple_variations) return_trace (false); if (unlikely (!c->embed (version))) return_trace (false); return_trace (tupleVariationData.serialize (c, false, tuple_variations)); @@ -168,8 +169,11 @@ struct cvar tuple_variations)) return_trace (false); - tuple_variations.instantiate (c->plan->axes_location, c->plan->axes_triple_distances); - if (!tuple_variations.compile_bytes (c->plan->axes_index_map, c->plan->axes_old_index_tag_map)) + if (!tuple_variations.instantiate (c->plan->axes_location, c->plan->axes_triple_distances)) + return_trace (false); + + if (!tuple_variations.compile_bytes (c->plan->axes_index_map, c->plan->axes_old_index_tag_map, + false /* do not use shared points */)) return_trace (false); return_trace (serialize (c->serializer, tuple_variations)); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh index b5099ac0748..8ef9f0ec45c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh @@ -39,42 +39,255 @@ namespace OT { -struct contour_point_t +struct GlyphVariationData : TupleVariationData +{}; + +struct glyph_variations_t { - void init (float x_ = 0.f, float y_ = 0.f, bool is_end_point_ = false) - { flag = 0; x = x_; y = y_; is_end_point = is_end_point_; } + using tuple_variations_t = TupleVariationData::tuple_variations_t; + hb_vector_t<tuple_variations_t> glyph_variations; + + hb_vector_t<char> compiled_shared_tuples; + private: + unsigned shared_tuples_count = 0; - void transform (const float (&matrix)[4]) + /* shared coords-> index map after instantiation */ + hb_hashmap_t<const hb_vector_t<char>*, unsigned> shared_tuples_idx_map; + + public: + unsigned compiled_shared_tuples_count () const + { return shared_tuples_count; } + + unsigned compiled_byte_size () const { - float x_ = x * matrix[0] + y * matrix[2]; - y = x * matrix[1] + y * matrix[3]; - x = x_; + unsigned byte_size = 0; + for (const auto& _ : glyph_variations) + byte_size += _.get_compiled_byte_size (); + + return byte_size; } - HB_ALWAYS_INLINE - void translate (const contour_point_t &p) { x += p.x; y += p.y; } + bool create_from_glyphs_var_data (unsigned axis_count, + const hb_array_t<const F2DOT14> shared_tuples, + const hb_subset_plan_t *plan, + const hb_hashmap_t<hb_codepoint_t, hb_bytes_t>& new_gid_var_data_map) + { + if (unlikely (!glyph_variations.alloc (plan->new_to_old_gid_list.length, true))) + return false; - float x; - float y; - uint8_t flag; - bool is_end_point; -}; + auto it = hb_iter (plan->new_to_old_gid_list); + for (auto &_ : it) + { + hb_codepoint_t new_gid = _.first; + contour_point_vector_t *all_contour_points; + if (!new_gid_var_data_map.has (new_gid) || + !plan->new_gid_contour_points_map.has (new_gid, &all_contour_points)) + return false; + hb_bytes_t var_data = new_gid_var_data_map.get (new_gid); + + const GlyphVariationData* p = reinterpret_cast<const GlyphVariationData*> (var_data.arrayZ); + hb_vector_t<unsigned> shared_indices; + GlyphVariationData::tuple_iterator_t iterator; + tuple_variations_t tuple_vars; + + /* in case variation data is empty, push an empty struct into the vector, + * keep the vector in sync with the new_to_old_gid_list */ + if (!var_data || ! p->has_data () || !all_contour_points->length || + !GlyphVariationData::get_tuple_iterator (var_data, axis_count, + var_data.arrayZ, + shared_indices, &iterator)) + { + glyph_variations.push (std::move (tuple_vars)); + continue; + } -struct contour_point_vector_t : hb_vector_t<contour_point_t> -{ - void extend (const hb_array_t<contour_point_t> &a) + if (!p->decompile_tuple_variations (all_contour_points->length, true /* is_gvar */, + iterator, &(plan->axes_old_index_tag_map), + shared_indices, shared_tuples, + tuple_vars /* OUT */)) + return false; + glyph_variations.push (std::move (tuple_vars)); + } + return !glyph_variations.in_error () && glyph_variations.length == plan->new_to_old_gid_list.length; + } + + bool instantiate (const hb_subset_plan_t *plan) { - unsigned int old_len = length; - if (unlikely (!resize (old_len + a.length, false))) - return; - auto arrayZ = this->arrayZ + old_len; - unsigned count = a.length; - hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0])); + unsigned count = plan->new_to_old_gid_list.length; + for (unsigned i = 0; i < count; i++) + { + hb_codepoint_t new_gid = plan->new_to_old_gid_list[i].first; + contour_point_vector_t *all_points; + if (!plan->new_gid_contour_points_map.has (new_gid, &all_points)) + return false; + if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, all_points)) + return false; + } + return true; } -}; -struct GlyphVariationData : TupleVariationData -{}; + bool compile_bytes (const hb_map_t& axes_index_map, + const hb_map_t& axes_old_index_tag_map) + { + if (!compile_shared_tuples (axes_index_map, axes_old_index_tag_map)) + return false; + for (tuple_variations_t& vars: glyph_variations) + if (!vars.compile_bytes (axes_index_map, axes_old_index_tag_map, + true, /* use shared points*/ + &shared_tuples_idx_map)) + return false; + + return true; + } + + bool compile_shared_tuples (const hb_map_t& axes_index_map, + const hb_map_t& axes_old_index_tag_map) + { + /* key is pointer to compiled_peak_coords inside each tuple, hashing + * function will always deref pointers first */ + hb_hashmap_t<const hb_vector_t<char>*, unsigned> coords_count_map; + + /* count the num of shared coords */ + for (tuple_variations_t& vars: glyph_variations) + { + for (tuple_delta_t& var : vars.tuple_vars) + { + if (!var.compile_peak_coords (axes_index_map, axes_old_index_tag_map)) + return false; + unsigned* count; + if (coords_count_map.has (&(var.compiled_peak_coords), &count)) + coords_count_map.set (&(var.compiled_peak_coords), *count + 1); + else + coords_count_map.set (&(var.compiled_peak_coords), 1); + } + } + + if (!coords_count_map || coords_count_map.in_error ()) + return false; + + /* add only those coords that are used more than once into the vector and sort */ + hb_vector_t<const hb_vector_t<char>*> shared_coords; + if (unlikely (!shared_coords.alloc (coords_count_map.get_population ()))) + return false; + + for (const auto _ : coords_count_map.iter ()) + { + if (_.second == 1) continue; + shared_coords.push (_.first); + } + + /* no shared tuples: no coords are used more than once */ + if (!shared_coords) return true; + /* sorting based on the coords frequency first (high to low), then compare + * the coords bytes */ + hb_qsort (shared_coords.arrayZ, shared_coords.length, sizeof (hb_vector_t<char>*), _cmp_coords, (void *) (&coords_count_map)); + + /* build shared_coords->idx map and shared tuples byte array */ + + shared_tuples_count = hb_min (0xFFFu + 1, shared_coords.length); + unsigned len = shared_tuples_count * (shared_coords[0]->length); + if (unlikely (!compiled_shared_tuples.alloc (len))) + return false; + + for (unsigned i = 0; i < shared_tuples_count; i++) + { + shared_tuples_idx_map.set (shared_coords[i], i); + /* add a concat() in hb_vector_t? */ + for (char c : shared_coords[i]->iter ()) + compiled_shared_tuples.push (c); + } + + return true; + } + + static int _cmp_coords (const void *pa, const void *pb, void *arg) + { + const hb_hashmap_t<const hb_vector_t<char>*, unsigned>* coords_count_map = + reinterpret_cast<const hb_hashmap_t<const hb_vector_t<char>*, unsigned>*> (arg); + + /* shared_coords is hb_vector_t<const hb_vector_t<char>*> so casting pa/pb + * to be a pointer to a pointer */ + const hb_vector_t<char>** a = reinterpret_cast<const hb_vector_t<char>**> (const_cast<void*>(pa)); + const hb_vector_t<char>** b = reinterpret_cast<const hb_vector_t<char>**> (const_cast<void*>(pb)); + + bool has_a = coords_count_map->has (*a); + bool has_b = coords_count_map->has (*b); + + if (has_a && has_b) + { + unsigned a_num = coords_count_map->get (*a); + unsigned b_num = coords_count_map->get (*b); + + if (a_num != b_num) + return b_num - a_num; + + return (*b)->as_array().cmp ((*a)->as_array ()); + } + else if (has_a) return -1; + else if (has_b) return 1; + else return 0; + } + + template<typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + bool serialize_glyph_var_data (hb_serialize_context_t *c, + Iterator it, + bool long_offset, + unsigned num_glyphs, + char* glyph_var_data_offsets /* OUT: glyph var data offsets array */) const + { + TRACE_SERIALIZE (this); + + if (long_offset) + { + ((HBUINT32 *) glyph_var_data_offsets)[0] = 0; + glyph_var_data_offsets += 4; + } + else + { + ((HBUINT16 *) glyph_var_data_offsets)[0] = 0; + glyph_var_data_offsets += 2; + } + unsigned glyph_offset = 0; + hb_codepoint_t last_gid = 0; + unsigned idx = 0; + + TupleVariationData* cur_glyph = c->start_embed<TupleVariationData> (); + if (!cur_glyph) return_trace (false); + for (auto &_ : it) + { + hb_codepoint_t gid = _.first; + if (long_offset) + for (; last_gid < gid; last_gid++) + ((HBUINT32 *) glyph_var_data_offsets)[last_gid] = glyph_offset; + else + for (; last_gid < gid; last_gid++) + ((HBUINT16 *) glyph_var_data_offsets)[last_gid] = glyph_offset / 2; + + if (idx >= glyph_variations.length) return_trace (false); + if (!cur_glyph->serialize (c, true, glyph_variations[idx])) return_trace (false); + TupleVariationData* next_glyph = c->start_embed<TupleVariationData> (); + glyph_offset += (char *) next_glyph - (char *) cur_glyph; + + if (long_offset) + ((HBUINT32 *) glyph_var_data_offsets)[gid] = glyph_offset; + else + ((HBUINT16 *) glyph_var_data_offsets)[gid] = glyph_offset / 2; + + last_gid++; + idx++; + cur_glyph = next_glyph; + } + + if (long_offset) + for (; last_gid < num_glyphs; last_gid++) + ((HBUINT32 *) glyph_var_data_offsets)[last_gid] = glyph_offset; + else + for (; last_gid < num_glyphs; last_gid++) + ((HBUINT16 *) glyph_var_data_offsets)[last_gid] = glyph_offset / 2; + return_trace (true); + } +}; struct gvar { @@ -94,9 +307,101 @@ struct gvar bool sanitize (hb_sanitize_context_t *c) const { return sanitize_shallow (c); } + bool decompile_glyph_variations (hb_subset_context_t *c, + glyph_variations_t& glyph_vars /* OUT */) const + { + hb_hashmap_t<hb_codepoint_t, hb_bytes_t> new_gid_var_data_map; + auto it = hb_iter (c->plan->new_to_old_gid_list); + if (it->first == 0 && !(c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) + { + new_gid_var_data_map.set (0, hb_bytes_t ()); + it++; + } + + for (auto &_ : it) + { + hb_codepoint_t new_gid = _.first; + hb_codepoint_t old_gid = _.second; + hb_bytes_t var_data_bytes = get_glyph_var_data_bytes (c->source_blob, glyphCountX, old_gid); + new_gid_var_data_map.set (new_gid, var_data_bytes); + } + + if (new_gid_var_data_map.in_error ()) return false; + + hb_array_t<const F2DOT14> shared_tuples = (this+sharedTuples).as_array ((unsigned) sharedTupleCount * (unsigned) axisCount); + return glyph_vars.create_from_glyphs_var_data (axisCount, shared_tuples, c->plan, new_gid_var_data_map); + } + + template<typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + bool serialize (hb_serialize_context_t *c, + const glyph_variations_t& glyph_vars, + Iterator it, + unsigned axis_count, + unsigned num_glyphs) const + { + TRACE_SERIALIZE (this); + gvar *out = c->allocate_min<gvar> (); + if (unlikely (!out)) return_trace (false); + + out->version.major = 1; + out->version.minor = 0; + out->axisCount = axis_count; + out->glyphCountX = hb_min (0xFFFFu, num_glyphs); + + unsigned glyph_var_data_size = glyph_vars.compiled_byte_size (); + bool long_offset = glyph_var_data_size & ~0xFFFFu; + out->flags = long_offset ? 1 : 0; + + HBUINT8 *glyph_var_data_offsets = c->allocate_size<HBUINT8> ((long_offset ? 4 : 2) * (num_glyphs + 1), false); + if (!glyph_var_data_offsets) return_trace (false); + + /* shared tuples */ + unsigned shared_tuple_count = glyph_vars.compiled_shared_tuples_count (); + out->sharedTupleCount = shared_tuple_count; + + if (!shared_tuple_count) + out->sharedTuples = 0; + else + { + hb_array_t<const char> shared_tuples = glyph_vars.compiled_shared_tuples.as_array ().copy (c); + if (!shared_tuples.arrayZ) return_trace (false); + out->sharedTuples = shared_tuples.arrayZ - (char *) out; + } + + char *glyph_var_data = c->start_embed<char> (); + if (!glyph_var_data) return_trace (false); + out->dataZ = glyph_var_data - (char *) out; + + return_trace (glyph_vars.serialize_glyph_var_data (c, it, long_offset, num_glyphs, + (char *) glyph_var_data_offsets)); + } + + bool instantiate (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + glyph_variations_t glyph_vars; + if (!decompile_glyph_variations (c, glyph_vars)) + return_trace (false); + + if (!glyph_vars.instantiate (c->plan)) return_trace (false); + if (!glyph_vars.compile_bytes (c->plan->axes_index_map, c->plan->axes_old_index_tag_map)) + return_trace (false); + + unsigned axis_count = c->plan->axes_index_map.get_population (); + unsigned num_glyphs = c->plan->num_output_glyphs (); + auto it = hb_iter (c->plan->new_to_old_gid_list); + return_trace (serialize (c->serializer, glyph_vars, it, axis_count, num_glyphs)); + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); + if (c->plan->all_axes_pinned) + return_trace (false); + + if (c->plan->normalized_coords) + return_trace (instantiate (c)); unsigned glyph_count = version.to_int () ? c->plan->source->get_num_glyphs () : 0; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.cc index 28150f1638d..8eb24eb28b2 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.cc @@ -54,6 +54,12 @@ static void hb_paint_pop_transform_nil (hb_paint_funcs_t *funcs, void *paint_data, void *user_data) {} +static hb_bool_t +hb_paint_color_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font, + void *user_data) { return false; } + static void hb_paint_push_clip_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, @@ -474,6 +480,25 @@ hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data) } /** + * hb_paint_color_glyph: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * @glyph: the glyph ID + * @font: the font + * + * Perform a "color-glyph" paint operation. + * + * Since: 8.2.0 + */ +hb_bool_t +hb_paint_color_glyph (hb_paint_funcs_t *funcs, void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font) +{ + return funcs->color_glyph (paint_data, glyph, font); +} + +/** * hb_paint_push_clip_glyph: * @funcs: paint functions * @paint_data: associated data passed by the caller diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.h index 543382780d1..b0cd384e286 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.h @@ -137,6 +137,26 @@ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, void *user_data); /** + * hb_paint_color_glyph_func_t: + * @funcs: paint functions object + * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() + * @glyph: the glyph ID + * @font: the font + * @user_data: User data pointer passed to hb_paint_funcs_set_color_glyph_func() + * + * A virtual method for the #hb_paint_funcs_t to render a color glyph by glyph index. + * + * Return value: %true if the glyph was painted, %false otherwise. + * + * Since: 8.2.0 + */ +typedef hb_bool_t (*hb_paint_color_glyph_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font, + void *user_data); + +/** * hb_paint_push_clip_glyph_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() @@ -724,6 +744,23 @@ hb_paint_funcs_set_pop_transform_func (hb_paint_funcs_t *funcs, hb_destroy_func_t destroy); /** + * hb_paint_funcs_set_color_glyph_func: + * @funcs: A paint functions struct + * @func: (closure user_data) (destroy destroy) (scope notified): The color-glyph callback + * @user_data: Data to pass to @func + * @destroy: (nullable): Function to call when @user_data is no longer needed + * + * Sets the color-glyph callback on the paint functions struct. + * + * Since: 8.2.0 + */ +HB_EXTERN void +hb_paint_funcs_set_color_glyph_func (hb_paint_funcs_t *funcs, + hb_paint_color_glyph_func_t func, + void *user_data, + hb_destroy_func_t destroy); + +/** * hb_paint_funcs_set_push_clip_glyph_func: * @funcs: A paint functions struct * @func: (closure user_data) (destroy destroy) (scope notified): The push-clip-glyph callback @@ -922,6 +959,11 @@ hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, HB_EXTERN void hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data); +HB_EXTERN hb_bool_t +hb_paint_color_glyph (hb_paint_funcs_t *funcs, void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font); + HB_EXTERN void hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.hh index d291a4b9731..56b790dbee9 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.hh @@ -32,6 +32,7 @@ #define HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS \ HB_PAINT_FUNC_IMPLEMENT (push_transform) \ HB_PAINT_FUNC_IMPLEMENT (pop_transform) \ + HB_PAINT_FUNC_IMPLEMENT (color_glyph) \ HB_PAINT_FUNC_IMPLEMENT (push_clip_glyph) \ HB_PAINT_FUNC_IMPLEMENT (push_clip_rectangle) \ HB_PAINT_FUNC_IMPLEMENT (pop_clip) \ @@ -77,6 +78,13 @@ struct hb_paint_funcs_t void pop_transform (void *paint_data) { func.pop_transform (this, paint_data, !user_data ? nullptr : user_data->pop_transform); } + bool color_glyph (void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font) + { return func.color_glyph (this, paint_data, + glyph, + font, + !user_data ? nullptr : user_data->push_clip_glyph); } void push_clip_glyph (void *paint_data, hb_codepoint_t glyph, hb_font_t *font) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh index cd57ade0722..e9cd376ad37 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh @@ -79,7 +79,12 @@ bool _presplit_subtables_if_needed (graph::gsubgpos_graph_context_t& ext_context // pass after this processing is done. Not super necessary as splits are // only done where overflow is likely, so de-dup probably will get undone // later anyways. - for (unsigned lookup_index : ext_context.lookups.keys ()) + + // The loop below can modify the contents of ext_context.lookups if new subtables are added + // to a lookup during a split. So save the initial set of lookup indices so the iteration doesn't + // risk access free'd memory if ext_context.lookups gets resized. + hb_set_t lookup_indices(ext_context.lookups.keys ()); + for (unsigned lookup_index : lookup_indices) { graph::Lookup* lookup = ext_context.lookups.get(lookup_index); if (!lookup->split_subtables_if_needed (ext_context, lookup_index)) @@ -114,11 +119,15 @@ bool _promote_extensions_if_needed (graph::gsubgpos_graph_context_t& ext_context // TODO(grieger): skip this for the 24 bit case. if (!ext_context.lookups) return true; + unsigned total_lookup_table_sizes = 0; hb_vector_t<lookup_size_t> lookup_sizes; lookup_sizes.alloc (ext_context.lookups.get_population (), true); for (unsigned lookup_index : ext_context.lookups.keys ()) { + const auto& lookup_v = ext_context.graph.vertices_[lookup_index]; + total_lookup_table_sizes += lookup_v.table_size (); + const graph::Lookup* lookup = ext_context.lookups.get(lookup_index); hb_set_t visited; lookup_sizes.push (lookup_size_t { @@ -131,14 +140,16 @@ bool _promote_extensions_if_needed (graph::gsubgpos_graph_context_t& ext_context lookup_sizes.qsort (); size_t lookup_list_size = ext_context.graph.vertices_[ext_context.lookup_list_index].table_size (); - size_t l2_l3_size = lookup_list_size; // Lookup List + Lookups - size_t l3_l4_size = 0; // Lookups + SubTables + size_t l2_l3_size = lookup_list_size + total_lookup_table_sizes; // Lookup List + Lookups + size_t l3_l4_size = total_lookup_table_sizes; // Lookups + SubTables size_t l4_plus_size = 0; // SubTables + their descendants // Start by assuming all lookups are using extension subtables, this size will be removed later // if it's decided to not make a lookup extension. for (auto p : lookup_sizes) { + // TODO(garretrieger): this overestimates the extension subtables size because some extension subtables may be + // reused. However, we can't correct this until we have connected component analysis in place. unsigned subtables_size = p.num_subtables * 8; l3_l4_size += subtables_size; l4_plus_size += subtables_size; @@ -159,8 +170,7 @@ bool _promote_extensions_if_needed (graph::gsubgpos_graph_context_t& ext_context size_t subtables_size = ext_context.graph.find_subgraph_size (p.lookup_index, visited, 1) - lookup_size; size_t remaining_size = p.size - subtables_size - lookup_size; - l2_l3_size += lookup_size; - l3_l4_size += lookup_size + subtables_size; + l3_l4_size += subtables_size; l3_l4_size -= p.num_subtables * 8; l4_plus_size += subtables_size + remaining_size; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh index efb5adde5f3..f2b7da1674b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh @@ -453,7 +453,7 @@ struct hb_sanitize_context_t : edit_count = 0; sane = t->sanitize (this); if (edit_count) { - DEBUG_MSG_FUNC (SANITIZE, start, "requested %u edits in second round; FAILLING", edit_count); + DEBUG_MSG_FUNC (SANITIZE, start, "requested %u edits in second round; FAILING", edit_count); sane = false; } } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc index 97caddb2262..a9386c5c911 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc @@ -200,7 +200,7 @@ hb_set_copy (const hb_set_t *set) void hb_set_clear (hb_set_t *set) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->clear (); } @@ -251,7 +251,7 @@ void hb_set_add (hb_set_t *set, hb_codepoint_t codepoint) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->add (codepoint); } @@ -272,7 +272,7 @@ hb_set_add_sorted_array (hb_set_t *set, const hb_codepoint_t *sorted_codepoints, unsigned int num_codepoints) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->add_sorted_array (sorted_codepoints, num_codepoints, sizeof(hb_codepoint_t)); @@ -294,7 +294,7 @@ hb_set_add_range (hb_set_t *set, hb_codepoint_t first, hb_codepoint_t last) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->add_range (first, last); } @@ -311,7 +311,7 @@ void hb_set_del (hb_set_t *set, hb_codepoint_t codepoint) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->del (codepoint); } @@ -334,7 +334,7 @@ hb_set_del_range (hb_set_t *set, hb_codepoint_t first, hb_codepoint_t last) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->del_range (first, last); } @@ -405,7 +405,7 @@ void hb_set_set (hb_set_t *set, const hb_set_t *other) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->set (*other); } @@ -422,7 +422,7 @@ void hb_set_union (hb_set_t *set, const hb_set_t *other) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->union_ (*other); } @@ -439,7 +439,7 @@ void hb_set_intersect (hb_set_t *set, const hb_set_t *other) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->intersect (*other); } @@ -456,7 +456,7 @@ void hb_set_subtract (hb_set_t *set, const hb_set_t *other) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->subtract (*other); } @@ -474,7 +474,7 @@ void hb_set_symmetric_difference (hb_set_t *set, const hb_set_t *other) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->symmetric_difference (*other); } @@ -489,7 +489,7 @@ hb_set_symmetric_difference (hb_set_t *set, void hb_set_invert (hb_set_t *set) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->invert (); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc index 93f961f2d8b..aade5585fa4 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc @@ -75,7 +75,6 @@ hb_subset_input_t::hb_subset_input_t () HB_TAG ('V', 'D', 'M', 'X'), HB_TAG ('D', 'S', 'I', 'G'), HB_TAG ('M', 'V', 'A', 'R'), - HB_TAG ('c', 'v', 'a', 'r'), }; sets.no_subset_tables->add_array (default_no_subset_tables, ARRAY_LENGTH (default_no_subset_tables)); @@ -479,16 +478,21 @@ hb_subset_input_pin_axis_location (hb_subset_input_t *input, * @axis_tag: Tag of the axis * @axis_min_value: Minimum value of the axis variation range to set * @axis_max_value: Maximum value of the axis variation range to set + * @axis_def_value: Default value of the axis variation range to set, in case of + * null, it'll be determined automatically * * Restricting the range of variation on an axis in the given subset input object. - * New min/max values will be clamped if they're not within the fvar axis range. + * New min/default/max values will be clamped if they're not within the fvar axis range. + * If the new default value is null: + * If the fvar axis default value is within the new range, then new default + * value is the same as original default value. * If the fvar axis default value is not within the new range, the new default * value will be changed to the new min or max value, whichever is closer to the fvar * axis default. * - * Note: input min value can not be bigger than input max value - * Note: currently this API does not support changing axis limits yet.It'd be only - * used internally for setting axis limits in the internal data structures + * Note: input min value can not be bigger than input max value. If the input + * default value is not within the new min/max range, it'll be clamped. + * Note: currently it supports gvar and cvar tables only. * * Return value: `true` if success, `false` otherwise * @@ -499,7 +503,8 @@ hb_subset_input_set_axis_range (hb_subset_input_t *input, hb_face_t *face, hb_tag_t axis_tag, float axis_min_value, - float axis_max_value) + float axis_max_value, + float *axis_def_value /* IN, maybe NULL */) { if (axis_min_value > axis_max_value) return false; @@ -510,7 +515,8 @@ hb_subset_input_set_axis_range (hb_subset_input_t *input, float new_min_val = hb_clamp(axis_min_value, axis_info.min_value, axis_info.max_value); float new_max_val = hb_clamp(axis_max_value, axis_info.min_value, axis_info.max_value); - float new_default_val = hb_clamp(axis_info.default_value, new_min_val, new_max_val); + float new_default_val = axis_def_value ? *axis_def_value : axis_info.default_value; + new_default_val = hb_clamp(new_default_val, new_min_val, new_max_val); return input->axes_location.set (axis_tag, Triple (new_min_val, new_default_val, new_max_val)); } #endif diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan-member-list.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan-member-list.hh index 8e61055f4af..01d8b0f8bea 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan-member-list.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan-member-list.hh @@ -123,6 +123,9 @@ HB_SUBSET_PLAN_MEMBER (mutable hb_vector_t<unsigned>, bounds_width_vec) //boundsHeight map: new gid->boundsHeight, boundsHeight=yMax - yMin HB_SUBSET_PLAN_MEMBER (mutable hb_vector_t<unsigned>, bounds_height_vec) +//map: new_gid -> contour points vector +HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(<hb_codepoint_t, contour_point_vector_t>), new_gid_contour_points_map) + #ifdef HB_EXPERIMENTAL_API // name table overrides map: hb_ot_name_record_ids_t-> name string new value or // None to indicate should remove diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc index a2090b727cb..c293ba3bafd 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc @@ -1045,6 +1045,36 @@ _update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) if (vvar_store_cache) _vmtx.var_table->get_var_store ().destroy_cache (vvar_store_cache); } + +static bool +_get_instance_glyphs_contour_points (hb_subset_plan_t *plan) +{ + /* contour_points vector only needed for updating gvar table (infer delta) + * during partial instancing */ + if (plan->user_axes_location.is_empty () || plan->all_axes_pinned) + return true; + + OT::glyf_accelerator_t glyf (plan->source); + + for (auto &_ : plan->new_to_old_gid_list) + { + hb_codepoint_t new_gid = _.first; + contour_point_vector_t all_points; + if (new_gid == 0 && !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) + { + if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points))) + return false; + continue; + } + + hb_codepoint_t old_gid = _.second; + if (unlikely (!glyf.glyph_for_gid (old_gid).get_all_points_without_var (plan->source, all_points))) + return false; + if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points))) + return false; + } + return true; +} #endif hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, @@ -1148,6 +1178,8 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, #ifndef HB_NO_VAR _update_instance_metrics_map_from_cff2 (this); + if (!check_success (_get_instance_glyphs_contour_points (this))) + return; #endif if (attach_accelerator_data) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh index d156de05d79..a05d1d1a620 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh @@ -67,6 +67,40 @@ struct head_maxp_info_t typedef struct head_maxp_info_t head_maxp_info_t; +struct contour_point_t +{ + void init (float x_ = 0.f, float y_ = 0.f, bool is_end_point_ = false) + { flag = 0; x = x_; y = y_; is_end_point = is_end_point_; } + + void transform (const float (&matrix)[4]) + { + float x_ = x * matrix[0] + y * matrix[2]; + y = x * matrix[1] + y * matrix[3]; + x = x_; + } + HB_ALWAYS_INLINE + void translate (const contour_point_t &p) { x += p.x; y += p.y; } + + + float x; + float y; + uint8_t flag; + bool is_end_point; +}; + +struct contour_point_vector_t : hb_vector_t<contour_point_t> +{ + void extend (const hb_array_t<contour_point_t> &a) + { + unsigned int old_len = length; + if (unlikely (!resize (old_len + a.length, false))) + return; + auto arrayZ = this->arrayZ + old_len; + unsigned count = a.length; + hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0])); + } +}; + namespace OT { struct cff1_subset_accelerator_t; struct cff2_subset_accelerator_t; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc index 1f97dbed290..100ce87d50c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc @@ -520,6 +520,9 @@ _subset_table (hb_subset_plan_t *plan, case HB_OT_TAG_avar: if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); return _subset<const OT::avar> (plan, buf); + 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_STAT: if (!plan->user_axes_location.is_empty ()) return _subset<const OT::STAT> (plan, buf); else return _passthrough (plan, tag); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h index 93f1f7f10c2..4c356997f12 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h @@ -181,7 +181,8 @@ hb_subset_input_set_axis_range (hb_subset_input_t *input, hb_face_t *face, hb_tag_t axis_tag, float axis_min_value, - float axis_max_value); + float axis_max_value, + float *axis_def_value); HB_EXTERN hb_bool_t hb_subset_input_override_name_table (hb_subset_input_t *input, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh index 23a96d70810..66e687a1a20 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh @@ -102,7 +102,7 @@ struct hb_vector_t void fini () { - /* We allow a hack to make the vector point to a foriegn array + /* We allow a hack to make the vector point to a foreign array * by the user. In that case length/arrayZ are non-zero but * allocated is zero. Don't free anything. */ if (allocated) @@ -208,25 +208,7 @@ struct hb_vector_t return std::addressof (Crap (Type)); return std::addressof (arrayZ[length - 1]); } - template <typename T, - typename T2 = Type, - hb_enable_if (!std::is_copy_constructible<T2>::value && - std::is_copy_assignable<T>::value)> - Type *push (T&& v) - { - Type *p = push (); - if (p == std::addressof (Crap (Type))) - // If push failed to allocate then don't copy v, since this may cause - // the created copy to leak memory since we won't have stored a - // reference to it. - return p; - *p = std::forward<T> (v); - return p; - } - template <typename T, - typename T2 = Type, - hb_enable_if (std::is_copy_constructible<T2>::value)> - Type *push (T&& v) + template <typename... Args> Type *push (Args&&... args) { if (unlikely ((int) length >= allocated && !alloc (length + 1))) // If push failed to allocate then don't copy v, since this may cause @@ -236,7 +218,7 @@ struct hb_vector_t /* Emplace. */ Type *p = std::addressof (arrayZ[length++]); - return new (p) Type (std::forward<T> (v)); + return new (p) Type (std::forward<Args> (args)...); } bool in_error () const { return allocated < 0; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-wasm-shape.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-wasm-shape.cc index 79442e99ed7..a70b7666465 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-wasm-shape.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-wasm-shape.cc @@ -48,7 +48,7 @@ * * - Build your font's wasm code importing the shared modules with the desired * name. This can be done eg.: __attribute__((import_module("graphite2"))) - * before each symbol in the the shared-module's headers. + * before each symbol in the shared-module's headers. * * - Try shaping your font and hope for the best... * diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build b/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build index 4d63ecf90ae..87e8962d540 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build @@ -560,7 +560,7 @@ defs_list = [harfbuzz_def] version = '0.@0@.0'.format(hb_version_int) extra_hb_cpp_args = [] -if cpp.get_argument_syntax() == 'msvc' +if cpp.get_define('_MSC_FULL_VER') != '' if get_option('default_library') != 'static' extra_hb_cpp_args += '-DHB_DLL_EXPORT' endif @@ -680,18 +680,31 @@ endif if get_option('tests').enabled() # TODO: MSVC gives the following, # error LNK2019: unresolved external symbol "unsigned __int64 const * const _hb_NullPool" - if cpp.get_argument_syntax() != 'msvc' + if cpp.get_define('_MSC_FULL_VER') == '' noinst_programs = { 'main': 'main.cc', + 'test-algs': ['test-algs.cc', 'hb-static.cc'], 'test-basics': 'test.cc', + 'test-bimap': ['test-bimap.cc', 'hb-static.cc'], 'test-buffer-serialize': 'test-buffer-serialize.cc', + 'test-classdef-graph': ['graph/test-classdef-graph.cc', 'hb-static.cc', 'graph/gsubgpos-context.cc'], + 'test-instancer-solver': ['test-subset-instancer-solver.cc', 'hb-subset-instancer-solver.cc', 'hb-static.cc'], + 'test-iter': ['test-iter.cc', 'hb-static.cc'], + 'test-map': ['test-map.cc', 'hb-static.cc'], + 'test-multimap': ['test-multimap.cc', 'hb-static.cc'], 'test-ot-meta': 'test-ot-meta.cc', 'test-ot-name': 'test-ot-name.cc', 'test-ot-glyphname': 'test-ot-glyphname.cc', 'test-ot-gpos-size-params': 'test-gpos-size-params.cc', 'test-ot-gsub-get-alternates': 'test-gsub-get-alternates.cc', 'test-ot-gsub-would-substitute': 'test-gsub-would-substitute.cc', + 'test-priority-queue': ['test-priority-queue.cc', 'hb-static.cc'], + 'test-repacker': ['test-repacker.cc', 'hb-static.cc', 'graph/gsubgpos-context.cc'], + '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-use-table': 'test-use-table.cc', + 'test-vector': ['test-vector.cc', 'hb-static.cc'], } foreach name, source : noinst_programs executable(name, source, @@ -704,24 +717,11 @@ if get_option('tests').enabled() endif compiled_tests = { - 'test-algs': ['test-algs.cc', 'hb-static.cc'], 'test-array': ['test-array.cc'], - 'test-iter': ['test-iter.cc', 'hb-static.cc'], 'test-machinery': ['test-machinery.cc', 'hb-static.cc'], - 'test-map': ['test-map.cc', 'hb-static.cc'], - 'test-multimap': ['test-multimap.cc', 'hb-static.cc'], 'test-number': ['test-number.cc', 'hb-number.cc'], 'test-ot-tag': ['hb-ot-tag.cc'], - 'test-priority-queue': ['test-priority-queue.cc', 'hb-static.cc'], - 'test-repacker': ['test-repacker.cc', 'hb-static.cc', 'graph/gsubgpos-context.cc'], - 'test-classdef-graph': ['graph/test-classdef-graph.cc', 'hb-static.cc', 'graph/gsubgpos-context.cc'], - 'test-set': ['test-set.cc', 'hb-static.cc'], - 'test-serialize': ['test-serialize.cc', 'hb-static.cc'], 'test-unicode-ranges': ['test-unicode-ranges.cc'], - 'test-vector': ['test-vector.cc', 'hb-static.cc'], - 'test-bimap': ['test-bimap.cc', 'hb-static.cc'], - 'test-instancer-solver': ['test-subset-instancer-solver.cc', 'hb-subset-instancer-solver.cc', 'hb-static.cc'], - 'test-tuple-varstore': ['test-tuple-varstore.cc', 'hb-subset-instancer-solver.cc', 'hb-static.cc'], } foreach name, source : compiled_tests if cpp.get_argument_syntax() == 'msvc' and source.contains('hb-static.cc') diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc index 94ff0849a68..950e7d26705 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-repacker.cc @@ -448,6 +448,7 @@ static void run_resolve_overflow_test (const char* name, name); graph_t graph (overflowing.object_graph ()); + graph_t expected_graph (expected.object_graph ()); if (graph::will_overflow (expected_graph)) { @@ -473,6 +474,12 @@ static void run_resolve_overflow_test (const char* name, // Check the graphs are equivalent graph.normalize (); expected_graph.normalize (); + if (!(graph == expected_graph)) { + printf("## Expected:\n"); + expected_graph.print(); + printf("## Result:\n"); + graph.print(); + } assert (graph == expected_graph); } @@ -1239,7 +1246,8 @@ populate_serializer_with_24_and_32_bit_offsets (hb_serialize_context_t* c) static void populate_serializer_with_extension_promotion (hb_serialize_context_t* c, - int num_extensions = 0) + int num_extensions = 0, + bool shared_subtables = false) { constexpr int num_lookups = 5; constexpr int num_subtables = num_lookups * 2; @@ -1252,15 +1260,13 @@ populate_serializer_with_extension_promotion (hb_serialize_context_t* c, for (int i = num_subtables - 1; i >= 0; i--) - subtables[i] = add_object(large_string.c_str (), 15000, c); + subtables[i] = add_object(large_string.c_str (), 15000 + i, c); for (int i = num_subtables - 1; i >= (num_lookups - num_extensions) * 2; i--) { - unsigned ext_index = i - (num_lookups - num_extensions) * 2; - unsigned subtable_index = num_subtables - ext_index - 1; - extensions[i] = add_extension (subtables[subtable_index], 5, c); + extensions[i] = add_extension (subtables[i], 5, c); } for (int i = num_lookups - 1; i >= 0; i--) @@ -1268,13 +1274,19 @@ populate_serializer_with_extension_promotion (hb_serialize_context_t* c, bool is_ext = (i >= (num_lookups - num_extensions)); start_lookup (is_ext ? (char) 7 : (char) 5, - 2, + shared_subtables && i > 2 ? 3 : 2, c); if (is_ext) { + if (shared_subtables && i > 2) { + add_offset (extensions[i * 2 - 1], c); + } add_offset (extensions[i * 2], c); add_offset (extensions[i * 2 + 1], c); } else { + if (shared_subtables && i > 2) { + add_offset (subtables[i * 2 - 1], c); + } add_offset (subtables[i * 2], c); add_offset (subtables[i * 2 + 1], c); } @@ -1837,6 +1849,28 @@ static void test_resolve_with_extension_promotion () free (expected_buffer); } +static void test_resolve_with_shared_extension_promotion () +{ + size_t buffer_size = 200000; + void* buffer = malloc (buffer_size); + assert (buffer); + hb_serialize_context_t c (buffer, buffer_size); + populate_serializer_with_extension_promotion (&c, 0, true); + + void* expected_buffer = malloc (buffer_size); + assert (expected_buffer); + hb_serialize_context_t e (expected_buffer, buffer_size); + populate_serializer_with_extension_promotion (&e, 3, true); + + run_resolve_overflow_test ("test_resolve_with_extension_promotion", + c, + e, + 20, + true); + free (buffer); + free (expected_buffer); +} + static void test_resolve_with_basic_pair_pos_1_split () { size_t buffer_size = 200000; @@ -2122,6 +2156,7 @@ main (int argc, char **argv) test_virtual_link (); test_shared_node_with_virtual_links (); test_resolve_with_extension_promotion (); + test_resolve_with_shared_extension_promotion (); test_resolve_with_basic_pair_pos_1_split (); test_resolve_with_extension_pair_pos_1_split (); test_resolve_with_basic_pair_pos_2_split (); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-tuple-varstore.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-tuple-varstore.cc index 32d2ea4579d..f1286e749ac 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/test-tuple-varstore.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/test-tuple-varstore.cc @@ -83,8 +83,7 @@ test_decompile_cvar () hb_hashmap_t<hb_tag_t, TripleDistances> axes_triple_distances; axes_triple_distances.set (axis_tag, TripleDistances (1.f, 1.f)); - tuple_variations.change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances); - tuple_variations.merge_tuple_variations (); + tuple_variations.instantiate (normalized_axes_location, axes_triple_distances); assert (tuple_variations.tuple_vars[0].indices.length == 65); assert (tuple_variations.tuple_vars[1].indices.length == 65); @@ -115,7 +114,7 @@ test_decompile_cvar () hb_map_t axes_index_map; axes_index_map.set (0, 0); - bool res = tuple_variations.compile_bytes (axes_index_map, axis_idx_tag_map); + bool res = tuple_variations.compile_bytes (axes_index_map, axis_idx_tag_map, false); assert (res); assert (tuple_variations.tuple_vars[0].compiled_tuple_header.length == 6); const char tuple_var_header_1[] = "\x0\x51\xa0\x0\xc0\x0"; diff --git a/Build/source/libs/harfbuzz/version.ac b/Build/source/libs/harfbuzz/version.ac index fd38c3ca76a..579e440e8a5 100644 --- a/Build/source/libs/harfbuzz/version.ac +++ b/Build/source/libs/harfbuzz/version.ac @@ -8,4 +8,4 @@ dnl dnl -------------------------------------------------------- dnl dnl m4-include this file to define the current harfbuzz version -m4_define([harfbuzz_version], [8.1.1]) +m4_define([harfbuzz_version], [8.2.0]) |