diff --git a/libs/README b/libs/README index dffed34f99..2761db8d4d 100644 --- a/libs/README +++ b/libs/README @@ -25,8 +25,8 @@ graphite2 1.3.14 - checked 10apr20 http://sourceforge.net/projects/silgraphite/files/graphite2/ (requires C++11) -harfbuzz 7.1.0 - checked 28mar23 - https://github.com/harfbuzz/harfbuzz/releases/tag/7.1.0 +harfbuzz 7.2.0 - checked 28apr23 + https://github.com/harfbuzz/harfbuzz/releases/tag/7.2.0 icu 72.1 - checked 07jan23 https://github.com/unicode-org/icu/releases/ diff --git a/libs/harfbuzz/ChangeLog b/libs/harfbuzz/ChangeLog index b023344e02..80b2e7e84d 100644 --- a/libs/harfbuzz/ChangeLog +++ b/libs/harfbuzz/ChangeLog @@ -1,3 +1,8 @@ +2023-04-28 Akira Kakuto + + Import harfbuzz-7.2.0. + * version.ac: Adjusted. + 2023-03-28 Akira Kakuto Import harfbuzz-7.1.0. diff --git a/libs/harfbuzz/TLpatches/ChangeLog b/libs/harfbuzz/TLpatches/ChangeLog index f59e55f504..7819c9e535 100644 --- a/libs/harfbuzz/TLpatches/ChangeLog +++ b/libs/harfbuzz/TLpatches/ChangeLog @@ -1,3 +1,8 @@ +2023-04-28 Akira Kakuto + + Imported harfbuzz-7.2.0 source tree from: + https://github.com/harfbuzz/harfbuzz/releases/download/7.2.0/ + 2023-03-28 Akira Kakuto Imported harfbuzz-7.1.0 source tree from: diff --git a/libs/harfbuzz/TLpatches/TL-Changes b/libs/harfbuzz/TLpatches/TL-Changes index a22b47ec07..124cc3fd7b 100644 --- a/libs/harfbuzz/TLpatches/TL-Changes +++ b/libs/harfbuzz/TLpatches/TL-Changes @@ -1,5 +1,5 @@ -Changes applied to the harfbuzz-7.1.0/ tree as obtained from: - https://github.com/harfbuzz/harfbuzz/releases/download/7.1.0/ +Changes applied to the harfbuzz-7.2.0/ tree as obtained from: + https://github.com/harfbuzz/harfbuzz/releases/download/7.2.0/ Removed: COPYING diff --git a/libs/harfbuzz/configure b/libs/harfbuzz/configure index fd8ba8ff07..279c26bb95 100755 --- a/libs/harfbuzz/configure +++ b/libs/harfbuzz/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for harfbuzz (TeX Live) 7.1.0. +# Generated by GNU Autoconf 2.71 for harfbuzz (TeX Live) 7.2.0. # # Report bugs to . # @@ -611,8 +611,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='harfbuzz (TeX Live)' PACKAGE_TARNAME='harfbuzz--tex-live-' -PACKAGE_VERSION='7.1.0' -PACKAGE_STRING='harfbuzz (TeX Live) 7.1.0' +PACKAGE_VERSION='7.2.0' +PACKAGE_STRING='harfbuzz (TeX Live) 7.2.0' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1346,7 +1346,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures harfbuzz (TeX Live) 7.1.0 to adapt to many kinds of systems. +\`configure' configures harfbuzz (TeX Live) 7.2.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1418,7 +1418,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of harfbuzz (TeX Live) 7.1.0:";; + short | recursive ) echo "Configuration of harfbuzz (TeX Live) 7.2.0:";; esac cat <<\_ACEOF @@ -1523,7 +1523,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -harfbuzz (TeX Live) configure 7.1.0 +harfbuzz (TeX Live) configure 7.2.0 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2064,7 +2064,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by harfbuzz (TeX Live) $as_me 7.1.0, which was +It was created by harfbuzz (TeX Live) $as_me 7.2.0, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -4823,7 +4823,7 @@ fi # Define the identity of the package. PACKAGE='harfbuzz--tex-live-' - VERSION='7.1.0' + VERSION='7.2.0' # Some tools Automake needs. @@ -5034,9 +5034,9 @@ WARNING_CFLAGS=$kpse_cv_warning_cflags HB_VERSION_MAJOR=7 -HB_VERSION_MINOR=1 +HB_VERSION_MINOR=2 HB_VERSION_MICRO=0 -HB_VERSION=7.1.0 +HB_VERSION=7.2.0 ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -8817,7 +8817,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by harfbuzz (TeX Live) $as_me 7.1.0, which was +This file was extended by harfbuzz (TeX Live) $as_me 7.2.0, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -8885,7 +8885,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -harfbuzz (TeX Live) config.status 7.1.0 +harfbuzz (TeX Live) config.status 7.2.0 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/libs/harfbuzz/harfbuzz-src/ChangeLog b/libs/harfbuzz/harfbuzz-src/ChangeLog index 1111f51303..eba3425ff1 100644 --- a/libs/harfbuzz/harfbuzz-src/ChangeLog +++ b/libs/harfbuzz/harfbuzz-src/ChangeLog @@ -1,3 +1,1444 @@ +commit a321c4fee56b15247c10f9aa3db7e7ccb3b8173b +Author: Khaled Hosny +Date: Thu Apr 27 00:48:00 2023 +0200 + + 7.2.0 + + NEWS | 29 +++++++++++++++++++++++++++++ + configure.ac | 2 +- + meson.build | 2 +- + src/hb-deprecated.h | 2 +- + src/hb-subset.h | 2 +- + src/hb-unicode.h | 2 +- + src/hb-version.h | 4 ++-- + 7 files changed, 36 insertions(+), 7 deletions(-) + +commit fd52c4cf7b97b7d16b442d369ae1d8ad18efa36e +Author: Behdad Esfahbod +Date: Wed Apr 26 16:27:51 2023 -0600 + + [gvar] Comment + + src/hb-ot-var-gvar-table.hh | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 0c59c629c1d46067bca26e10e051eaabd87ff0b2 +Author: Behdad Esfahbod +Date: Wed Apr 26 16:20:16 2023 -0600 + + [gvar] Micro-optimize + + For cases where no deltaset applies. + + src/hb-ot-var-gvar-table.hh | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +commit 5d1a603ad1556f8797180aea0f7201f3bad66441 +Author: Behdad Esfahbod +Date: Wed Apr 26 16:25:15 2023 -0600 + + [var] Fix compiler warnings + + src/hb-ot-var-common.hh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit af393e9652aa746c42652e3590dfb12724dd0877 +Author: Behdad Esfahbod +Date: Wed Apr 26 16:02:06 2023 -0600 + + [gvar] Refactor a variable + + src/hb-ot-var-common.hh | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +commit 2a3bf5a542aaefb72bac4708ca9ded99b2ec62cb +Author: Behdad Esfahbod +Date: Wed Apr 26 15:58:55 2023 -0600 + + [gvar] Minor error-handling + + src/hb-ot-var-gvar-table.hh | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +commit 57faabb78e030388dca2cd6b6ec7d94a484c0956 +Author: Behdad Esfahbod +Date: Wed Apr 26 15:56:04 2023 -0600 + + [gvar] Micro-optimize + + src/hb-ot-var-gvar-table.hh | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +commit 76e269af9e87d95415564d75a3aabc2ecec262cd +Author: Behdad Esfahbod +Date: Wed Apr 26 15:47:12 2023 -0600 + + [gvar] Micro-optimize + + src/hb-ot-var-common.hh | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +commit 7349cea127599d4d164b3ef4b05aee80451bc26b +Author: Behdad Esfahbod +Date: Wed Apr 26 14:27:24 2023 -0600 + + [gvar] Micro-optimization + + src/hb-ot-var-common.hh | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +commit bc535870025dbb78e83ebad1e01aba8644825e87 +Author: Behdad Esfahbod +Date: Wed Apr 26 13:57:11 2023 -0600 + + [deprecated] Add HB_UNICODE_COMBINING_CLASS_CCC133 + + https://github.com/harfbuzz/harfbuzz/pull/4207 + + docs/harfbuzz-sections.txt | 1 + + src/hb-deprecated.h | 11 +++++++++++ + 2 files changed, 12 insertions(+) + +commit c5afe026bdf784d05f32d9be31a38c077746d210 +Author: Behdad Esfahbod +Date: Wed Apr 26 13:44:03 2023 -0600 + + [gvar] Comment + + src/hb-ot-var-gvar-table.hh | 3 +++ + 1 file changed, 3 insertions(+) + +commit 87c6e68ec31260fb51d67d563c61adb61041bb41 +Author: Behdad Esfahbod +Date: Wed Apr 26 13:20:51 2023 -0600 + + [gvar] Assertion + + src/hb-ot-var-common.hh | 1 + + 1 file changed, 1 insertion(+) + +commit 09386737312ddae4d850334cd55063de935cf6d5 +Author: Behdad Esfahbod +Date: Wed Apr 26 13:19:27 2023 -0600 + + [gvar] Error handling & micro-optimization + + src/hb-ot-var-common.hh | 2 +- + src/hb-ot-var-gvar-table.hh | 5 +++-- + 2 files changed, 4 insertions(+), 3 deletions(-) + +commit b6aa2d71f39473d1d927376a4959bb73398aa4ca +Author: Behdad Esfahbod +Date: Wed Apr 26 13:06:24 2023 -0600 + + [gvar] Speed up calculate_scalar more + + Use a gvar-wide cache of the one active peak index for shared-tuples + that have only one active peak. This speeds up the scalar calculation. + + This shows significant speedup for the CJK VarComposite font for + example since that has tens of axes with mostly only one active peak. + + src/hb-ot-var-common.hh | 18 ++++++++++++++++-- + src/hb-ot-var-gvar-table.hh | 27 ++++++++++++++++++++++++++- + 2 files changed, 42 insertions(+), 3 deletions(-) + +commit ffbfab123f0966f4ee1c00b24fcb7158b1b3857d +Author: Han Seung Min - 한승민 +Date: Thu Apr 27 00:43:48 2023 +0900 + + oops docs + + src/hb-unicode.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit e428edc3714eebe68981c579bda9412f303f538d +Author: Han Seung Min - 한승민 +Date: Wed Apr 26 23:57:21 2023 +0900 + + [unicode] Fix typo + + I believe the `hb-unicode.h` has a typo where `HB_UNICODE_COMBINING_CLASS_CCC133 = 132,` is supposed to be `HB_UNICODE_COMBINING_CLASS_CCC132` + + src/hb-unicode.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 63afb4f2e7cc6053fb884108b360f19d1103b065 +Author: Behdad Esfahbod +Date: Wed Apr 26 10:29:25 2023 -0600 + + [syllabic] Better fix for previous issue + + With previous fix the GPOS application was still reading the syllable() + member, which was already freed. This fix is more correct. + + src/hb-ot-layout-gsubgpos.hh | 3 ++- + src/hb-ot-shaper-syllabic.cc | 4 ---- + 2 files changed, 2 insertions(+), 5 deletions(-) + +commit c5f3b3feb1d2845b46e19f7e01605bbcf3e7f480 +Author: Behdad Esfahbod +Date: Wed Apr 26 10:17:37 2023 -0600 + + [syllabic] Actually clear syllables + + Such that they don't affect GPOS. + + I broke this in 044d7a06db552e1564b8575f4d23798f009d9dde. + + src/hb-ot-shaper-syllabic.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 9ee7c2ea63416a6e7e98461d9b5480e7af22c427 +Author: Behdad Esfahbod +Date: Tue Apr 25 16:13:54 2023 -0600 + + [cmap] Minor remove magic number + + src/hb-ot-cmap-table.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 580b0dc1c353c5cf2d2b6ba63f17043baf050d8d +Author: Behdad Esfahbod +Date: Tue Apr 25 16:11:01 2023 -0600 + + [cmap] Comment + + src/hb-ot-cmap-table.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 1d31da91ce02bf01947f1533d896dc4a4a5f6bcb +Merge: f6803b06b e41f31719 +Author: Behdad Esfahbod +Date: Tue Apr 25 15:34:06 2023 -0600 + + Merge pull request #4205 from harfbuzz/gvar-optimize + + Gvar optimize + +commit e41f3171994a739ff966735b78e1777ab5933471 +Author: Garret Rieger +Date: Tue Apr 25 20:54:27 2023 +0000 + + [subset] Update expectation files for full_instance tests. + + ...fault.retain-all-codepoint.wght=300,wdth=90.ttf | Bin 114300 -> 114300 bytes + ...anges.retain-all-codepoint.wght=300,wdth=90.ttf | Bin 114300 -> 114300 bytes + test/subset/data/tests/full_instance.tests | 3 +++ + 3 files changed, 3 insertions(+) + +commit f6803b06bf7ef6b6a480e9dd489a8fa693d7b403 +Author: Behdad Esfahbod +Date: Tue Apr 25 14:46:44 2023 -0600 + + [VarRegionAxis] Micro-optimize + + peak==0 is common. + + src/hb-ot-layout-common.hh | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +commit f91929d6da527e42b4f46c7738d40e118107163a +Author: Behdad Esfahbod +Date: Tue Apr 25 14:42:00 2023 -0600 + + Minor return floats instead of doubles from function + + Not that any compiler complained... + + src/hb-ot-layout-common.hh | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit 808a21f8de7523b26ddad2316e55fafa6daf4fe2 +Author: Behdad Esfahbod +Date: Tue Apr 25 14:03:52 2023 -0600 + + [gvar] Simplify ref_points logic + + src/hb-ot-var-gvar-table.hh | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +commit 78a0216a031234fdcc14448f906649bd83bb7118 +Author: Behdad Esfahbod +Date: Tue Apr 25 13:52:00 2023 -0600 + + [gvar] Write a for loop as range loop + + src/hb-ot-var-gvar-table.hh | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +commit f654823fe0639bf6c71d77f53c34b4b2f878eb2e +Author: Behdad Esfahbod +Date: Tue Apr 25 13:09:40 2023 -0600 + + [gvar] Handle an error case + + src/hb-ot-var-gvar-table.hh | 1 + + 1 file changed, 1 insertion(+) + +commit 30d08dc62cfab0f5f8d8d4491f91eb352eebfb3e +Author: Behdad Esfahbod +Date: Tue Apr 25 12:13:57 2023 -0600 + + [gvar] Populate end_points lazily + + Tiny micro-optimization... + + src/hb-ot-var-gvar-table.hh | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +commit fe8c91707b5579f77505e37ebea8578e1282db38 +Author: Behdad Esfahbod +Date: Tue Apr 25 11:30:36 2023 -0600 + + [gvar] Micro-optimize has_intermediate() access + + src/hb-ot-var-common.hh | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +commit 2175f5d050743317c563ec9414e0f83a47f7fbc4 +Author: Garret Rieger +Date: Mon Apr 24 21:13:18 2023 +0000 + + [subset] Fix inefficient ItemVariationStore subsetting w/ retain_gids. + + ItemVariationStore is relying on the assumption that the inner_map is populated for all output glyphs, this is not true for subsetting operations with retain gids enabled. Fixes fuzzer timeout: https://oss-fuzz.com/testcase-detail/4575222591520768. + + src/hb-bimap.hh | 9 +++++++++ + src/hb-ot-layout-common.hh | 14 ++++++-------- + src/hb-ot-var-hvar-table.hh | 10 ++++------ + ...testcase-minimized-hb-subset-fuzzer-4575222591520768 | Bin 0 -> 91107 bytes + .../variable/Fraunces.retain-gids.26,66,69,124,125.ttf | Bin 0 -> 21296 bytes + .../data/expected/variable/Fraunces.retain-gids.61.ttf | Bin 0 -> 4508 bytes + test/subset/data/tests/variable.tests | 1 + + 7 files changed, 20 insertions(+), 14 deletions(-) + +commit 385e23762dc18659c4cc0c69e17549fe3e00d74e +Author: Behdad Esfahbod +Date: Mon Apr 24 17:51:07 2023 -0600 + + [var] Optimize calculate_scalar more + + This change alone is showing me 14% scalar in a benchmark. + The reason being that the array::operator[] is not being invoked + a lot of time, which was, many times, hitting the unlikely() path. + Weird! + + src/hb-ot-var-common.hh | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +commit 7a3928e2b6099c5c334ca0b2469a567b529bcf34 +Author: Behdad Esfahbod +Date: Mon Apr 24 17:38:20 2023 -0600 + + [var] Optimize calculate_scalar + + For varfonts with lots of deltasets, the loop in this function is + *really* hot... + + src/hb-ot-var-common.hh | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit 89296036317bf718c99fdd1dc0d1bf4f1c34323a +Author: Behdad Esfahbod +Date: Mon Apr 24 16:16:27 2023 -0600 + + [gvar] Another minor optimization + + Allocate orig_points lazily only when needed. + + src/hb-ot-var-gvar-table.hh | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +commit 20454eaa399abe28db485b2ccb461c30861023e0 +Author: Behdad Esfahbod +Date: Mon Apr 24 15:50:58 2023 -0600 + + [gvar] Optimize by applying deltas in batches + + Shows up to 7% speedup in one of my benchmarks. + + One test fails by one rounding issue. To be updated. + + src/hb-ot-var-gvar-table.hh | 22 +++++++++++++++++----- + 1 file changed, 17 insertions(+), 5 deletions(-) + +commit 491aa572ce9c845afa40cfdcded4959add46fd5c +Author: Behdad Esfahbod +Date: Mon Apr 24 15:05:18 2023 -0600 + + [gvar] Minor call a function instead of handcoding + + src/hb-ot-var-gvar-table.hh | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +commit cf95f3193bfb85ec4d14041e93df8a03909f40a1 +Author: Behdad Esfahbod +Date: Mon Apr 24 14:45:52 2023 -0600 + + [VarComposite] Another minor resue of num_points + + src/OT/glyf/Glyph.hh | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +commit fc8dfe64d04e3d429f9c8c7f39e52c619c4bba13 +Author: Behdad Esfahbod +Date: Mon Apr 24 14:39:20 2023 -0600 + + [benchmark-font] Minor rename + + perf/benchmark-font.cc | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 0a5208422821471d2904e164cad651bd8dadcfb4 +Author: Behdad Esfahbod +Date: Mon Apr 24 14:23:24 2023 -0600 + + [VarComposite] Minor resue of num_points + + src/OT/glyf/VarCompositeGlyph.hh | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +commit a9a9f278b81f6a855afce1bf668410d3ccceb682 +Author: Behdad Esfahbod +Date: Mon Apr 24 14:16:48 2023 -0600 + + [atomic] Remove incomplete comment + + src/hb-atomic.hh | 4 ---- + 1 file changed, 4 deletions(-) + +commit d1c00c047030226b6b5255cc4b7cdeb738ee0ccc +Author: Behdad Esfahbod +Date: Mon Apr 24 13:24:47 2023 -0600 + + [COLR] Respect HB_NO_PAINT + + Fixes https://github.com/harfbuzz/harfbuzz/issues/4204 + + src/OT/Color/COLR/COLR.hh | 4 ++++ + src/hb-ot-font.cc | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +commit 4129061e37824433f9c81eaa99d1618af2f2d69a +Author: Behdad Esfahbod +Date: Mon Apr 24 13:04:05 2023 -0600 + + Revert "Move hb-ot-name-language-static.hh out of hb-static.cc" + + This reverts commit 7b5f0dd3a8b4a126b7952fea1c4c30b8b456083e. + + Fixes https://github.com/harfbuzz/harfbuzz/issues/4203 + + src/hb-ot-name.cc | 2 -- + src/hb-static.cc | 1 + + src/hb-subset.cc | 5 ----- + 3 files changed, 1 insertion(+), 7 deletions(-) + +commit e76a3649db4611ac0531cbb5fc8e555a039b93f3 +Author: Behdad Esfahbod +Date: Sat Apr 22 10:20:25 2023 -0600 + + [atomic] Comment + + src/hb-atomic.hh | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 8e43e3a8ce72a3888e9bfbc9f2975fc56e139836 +Author: Behdad Esfahbod +Date: Sat Apr 22 10:16:43 2023 -0600 + + [priority-heap] Comment + + src/hb-priority-queue.hh | 6 ++++++ + 1 file changed, 6 insertions(+) + +commit 48f8ed7e0205e1c0dcf0a19c1bfc9b515182563a +Author: Behdad Esfahbod +Date: Sat Apr 22 10:11:22 2023 -0600 + + Docs + + src/hb-buffer.cc | 5 +++++ + src/hb-face.cc | 6 ++++++ + src/hb-font.cc | 5 +++++ + src/hb-ot-layout.cc | 2 ++ + 4 files changed, 18 insertions(+) + +commit b31684dca478da09d9ae5063658d5663fa5cbce0 +Author: Behdad Esfahbod +Date: Sat Apr 22 09:47:58 2023 -0600 + + [cache] Add some AI-generated comments + + src/hb-cache.hh | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +commit bffdca89f7977e7a4b84a69196ac48f1df6d3c6f +Author: Behdad Esfahbod +Date: Sat Apr 22 09:32:57 2023 -0600 + + [pool] Add funny Copilot comment + + src/hb-pool.hh | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +commit a960571f24b0383dedd958df4f268fcb877fe94d +Author: Behdad Esfahbod +Date: Fri Apr 21 16:45:08 2023 -0600 + + [glyf] Comments + + src/OT/glyf/Glyph.hh | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit 2b042cc5c6e90736754acdbbd035fe4a230b9fd6 +Author: Behdad Esfahbod +Date: Fri Apr 21 16:43:47 2023 -0600 + + [VarComposite] Implement trim_padding() + + src/OT/glyf/Glyph.hh | 2 +- + src/OT/glyf/VarCompositeGlyph.hh | 7 +++++++ + 2 files changed, 8 insertions(+), 1 deletion(-) + +commit 591c9460dc28967c5db11e9301d81d08c2773217 +Author: Qunxin Liu +Date: Fri Apr 21 14:12:27 2023 -0700 + + [instancer] compile composite glyphs directly with shifted component + points instead of deltas + + src/OT/glyf/CompositeGlyph.hh | 25 ++++++++++++------------- + src/OT/glyf/Glyph.hh | 27 +++++++++------------------ + 2 files changed, 21 insertions(+), 31 deletions(-) + +commit 3520f528aaba200ab2e3f1edfe746c7963a7ce54 +Author: Behdad Esfahbod +Date: Fri Apr 21 15:46:36 2023 -0600 + + [CompositeGlyph] Apply gvar deltas with component transform + + This was being done wrong for one of the scaled_offsets() cases. + + src/OT/glyf/CompositeGlyph.hh | 37 ++++++++++++++++++++++--------------- + src/OT/glyf/Glyph.hh | 14 +++++++------- + 2 files changed, 29 insertions(+), 22 deletions(-) + +commit 33972b3bf6cd9a63424a2213e5b80bff474b7d10 +Author: Behdad Esfahbod +Date: Fri Apr 21 12:37:51 2023 -0600 + + [glyf] Increase CompositeGlyf memory allocation + + The 50% wasn't justified by logic. + + src/OT/glyf/CompositeGlyph.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 290cef39bed5fcc05e3a424ce05b1797507a0a03 +Author: Behdad Esfahbod +Date: Fri Apr 21 12:22:30 2023 -0600 + + [glyf] When instancing, just spew empty VarComposites + + Before we were dropping the entire glyf table. + + src/OT/glyf/Glyph.hh | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 4353192d057fe3583a4ad234e478a407e9d1eb1a +Author: Behdad Esfahbod +Date: Fri Apr 21 11:59:15 2023 -0600 + + [aat] Tweak a couple sanitize calls that are never called + + src/hb-aat-layout-common.hh | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +commit 305012609bddba97a2fbc5080a146bc3d3feaa06 +Author: Behdad Esfahbod +Date: Fri Apr 21 11:42:18 2023 -0600 + + [hdmx] Remove unused unsafe function + + src/hb-ot-hdmx-table.hh | 10 +--------- + 1 file changed, 1 insertion(+), 9 deletions(-) + +commit f74abc307d742f6f90b0012dc1cef66da149742e +Author: Behdad Esfahbod +Date: Fri Apr 21 11:37:37 2023 -0600 + + [face] Comment + + src/hb-face.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit d1f49ba6d2dc7f8c316f055a9e4f9cdf4dafdcad +Author: Behdad Esfahbod +Date: Thu Apr 20 18:17:14 2023 -0600 + + [VarComposites] More ifdef guards + + src/OT/glyf/Glyph.hh | 33 ++++++++++++++++++++++++++++----- + 1 file changed, 28 insertions(+), 5 deletions(-) + +commit 1e9a0511f33a851b27d6d0320b0d426bf95c97ce +Author: Behdad Esfahbod +Date: Thu Apr 20 17:47:04 2023 -0600 + + [subset] Fix HB_TINY build + + src/hb-subset-plan.cc | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 106a237e404b4942803a52a8ab4114b2f3034c77 +Author: Behdad Esfahbod +Date: Thu Apr 20 17:44:59 2023 -0600 + + [subset/glyf] Close over VarComposite glyphs + + Subsetting VarComposite glyphs works now. + + src/hb-subset-plan.cc | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +commit f2d21425a353728fa69680eff24421cce22981de +Author: Behdad Esfahbod +Date: Thu Apr 20 17:31:58 2023 -0600 + + [VarC/subset] Support subsetting VarComposites + + By renumbering components. + + src/OT/glyf/SubsetGlyph.hh | 15 +++++++++++++-- + src/OT/glyf/VarCompositeGlyph.hh | 8 ++++++++ + 2 files changed, 21 insertions(+), 2 deletions(-) + +commit 15d0a1dcfd192fda87c4877da2029c14d0bd5bd2 +Author: Behdad Esfahbod +Date: Thu Apr 20 17:28:10 2023 -0600 + + [glyf] TODO + + src/OT/glyf/SubsetGlyph.hh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 85d0c3b5f1158eedc7ead3cae55adb026456352b +Author: Behdad Esfahbod +Date: Thu Apr 20 17:17:28 2023 -0600 + + [glyf] Comment + + src/OT/glyf/CompositeGlyph.hh | 2 ++ + 1 file changed, 2 insertions(+) + +commit 5d74b42b9e3e2a591071d196d9d2b2dd537a496b +Author: Behdad Esfahbod +Date: Thu Apr 20 17:15:57 2023 -0600 + + [glyf] Change variable name + + src/OT/glyf/SubsetGlyph.hh | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +commit c997e490c78f8e643f9d8ff8c712cc1856b4979f +Author: Behdad Esfahbod +Date: Thu Apr 20 17:02:38 2023 -0600 + + Remove unnecessary return + + src/OT/glyf/CompositeGlyph.hh | 1 - + 1 file changed, 1 deletion(-) + +commit 781da13e99d1373b4e33a84b40e01923e6f64e49 +Author: Behdad Esfahbod +Date: Thu Apr 20 16:59:25 2023 -0600 + + [glyf] Comment + + src/OT/glyf/SubsetGlyph.hh | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit 0e4bcf908ca4bf394a326970490ae1943966a410 +Author: Behdad Esfahbod +Date: Thu Apr 20 16:23:41 2023 -0600 + + [hmtx] Add TODO + + src/hb-ot-hmtx-table.hh | 1 + + 1 file changed, 1 insertion(+) + +commit 639f45ef9e9bcb9b3a4c380e41d4a574156f41c0 +Author: Behdad Esfahbod +Date: Thu Apr 20 16:21:08 2023 -0600 + + [beyond-64k/subset] Implement subsetting of hmtx beyond64k + + src/hb-ot-hmtx-table.hh | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +commit b3da715b9c0a5d0354cabb8a7e9117622643c119 +Author: Behdad Esfahbod +Date: Thu Apr 20 16:05:03 2023 -0600 + + Fix HB_TINY build + + src/OT/glyf/glyf.hh | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +commit 32f145ff9cd87a97d5eb265e29689c304799ebf3 +Author: Behdad Esfahbod +Date: Thu Apr 20 15:58:26 2023 -0600 + + Fix build + + src/OT/glyf/Glyph.hh | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit 000a3c5dca1deb811646cf94e705733f5e9ee422 +Author: Behdad Esfahbod +Date: Thu Apr 20 15:53:10 2023 -0600 + + [beyond-64k/subset] Fetch lsb from glyph table if not available + + The beyond-64k hmtx table doesn't encode LSB. If subsetting brings + the glyph under 64k (which currently is the only mode we support), + then we need to encode the LSB, which wasn't available. We need to + fetch xMin from glyf table and set it as LSB. + + src/OT/glyf/Glyph.hh | 1 + + src/OT/glyf/glyf.hh | 9 +++++++++ + src/hb-ot-font.cc | 16 ---------------- + src/hb-ot-hmtx-table.hh | 6 +++++- + src/hb-static.cc | 23 +++++++++++++++++++++++ + 5 files changed, 38 insertions(+), 17 deletions(-) + +commit 1111c7578ed76f9b338c5cbc13792ff638e22783 +Author: Behdad Esfahbod +Date: Thu Apr 20 15:17:23 2023 -0600 + + hb_memset + + src/OT/glyf/SubsetGlyph.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 219e739c9f21a16942162a53935f1dfbaf0414fa +Author: Behdad Esfahbod +Date: Thu Apr 20 15:10:29 2023 -0600 + + [beyond-64k/subset] Lower CompositeGlyph GID24's when possible + + src/OT/glyf/CompositeGlyph.hh | 20 ++++++++++++++++++++ + src/OT/glyf/SubsetGlyph.hh | 41 +++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 61 insertions(+) + +commit a2e8ecf9969b0657221f7d0ad6e6aeca5c20cd11 +Author: Behdad Esfahbod +Date: Thu Apr 20 13:59:49 2023 -0600 + + [Glyph] Minor change type of type to enum type + + Say that thrice. + + src/OT/glyf/Glyph.hh | 30 +++++++++++++++++++++--------- + 1 file changed, 21 insertions(+), 9 deletions(-) + +commit 317e3693da558087ab92d2c896be463311e737d6 +Author: Behdad Esfahbod +Date: Thu Apr 20 11:48:43 2023 -0600 + + [beyond-64k] Fail hmtx subsetting if subset too large + + src/hb-ot-hmtx-table.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 64ecf8720c959617e0b0a5d10002089a05f28f98 +Author: Behdad Esfahbod +Date: Thu Apr 20 11:42:45 2023 -0600 + + [beyond-64k] Fix subsetting of maxp + + src/hb-ot-maxp-table.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 7f629c0df20a52fb9aabecb657552c0703b70c58 +Author: Behdad Esfahbod +Date: Wed Apr 19 13:16:18 2023 -0600 + + [docs] clarify purpose of FreeType integration + + Fixes https://github.com/harfbuzz/harfbuzz/issues/4200 + + docs/usermanual-integration.xml | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +commit 19e1b698c59e56b6e3530220866be0cd0754d1bd +Author: Garret Rieger +Date: Tue Apr 18 18:49:26 2023 +0000 + + [subset] Fix ubsan failure. + + src/OT/glyf/Glyph.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 647b024784e1346f6886565f570cdf940d7b82b4 +Author: Garret Rieger +Date: Mon Apr 17 22:47:47 2023 +0000 + + [subset] Fix fuzzer issue https://oss-fuzz.com/testcase-detail/6521393809588224 + + src/OT/glyf/SimpleGlyph.hh | 6 ++++++ + src/OT/glyf/SubsetGlyph.hh | 7 ++++++- + ...testcase-minimized-hb-subset-fuzzer-6521393809588224 | Bin 0 -> 15886 bytes + 3 files changed, 12 insertions(+), 1 deletion(-) + +commit 3db6baa20e0a4661f99654860000e74a2770c2e0 +Author: Garret Rieger +Date: Mon Apr 17 20:01:17 2023 +0000 + + [subset] add test for lig glyph fix. + + ...oboto-Regular.no-layout-closure-gids2.no-unicodes.ttf | Bin 0 -> 2800 bytes + test/subset/data/profiles/no-layout-closure-gids2.txt | 3 +++ + test/subset/data/tests/no_layout_closure.tests | 1 + + 3 files changed, 4 insertions(+) + +commit 8658c257c45f11ed28a8fcd621b35261fadffcfa +Author: Garret Rieger +Date: Mon Apr 17 19:46:46 2023 +0000 + + [subset] In LigatureSubst subsetting, check if the ligature glyph is in glyphset. + + Otherwise coverage will not match the retained ligature sets. + + src/OT/Layout/GSUB/Ligature.hh | 3 +++ + src/OT/Layout/GSUB/LigatureSet.hh | 12 ++++++++++++ + src/OT/Layout/GSUB/LigatureSubstFormat1.hh | 2 +- + 3 files changed, 16 insertions(+), 1 deletion(-) + +commit ac4c3b3e8552d401977bcbba668f45d4e4f2cdd6 +Author: Josef Friedrich +Date: Mon Apr 17 20:13:43 2023 +0200 + + Fix typos in the source code docs + + src/hb-face.cc | 2 +- + src/hb-subset-instancer-solver.cc | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit ef6adadba92d605d54cf344962206cfbf421193d +Author: DeadSix27 +Date: Mon Apr 17 12:53:49 2023 +0200 + + meson: add an option to disable utilities building + + Adds the missing utilities option to meson builds for parity with CMake builds + + meson.build | 5 ++++- + meson_options.txt | 2 ++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +commit 90356eb226f633c8a7c9250b2653da75eaf51cfb +Author: Garret Rieger +Date: Fri Apr 14 20:52:35 2023 +0000 + + [subset] Note --no-layout-closure is only for GSUB. + + src/hb-subset.h | 2 +- + util/hb-subset.cc | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +commit 14b9d8d53432da0a53122ae62ac125f5a67f456a +Author: Garret Rieger +Date: Fri Apr 14 20:44:15 2023 +0000 + + [subset] add --no-layout-closure flag. + + Disables layout glyph closure. Fixes #4192. + + src/hb-subset-plan.cc | 2 +- + src/hb-subset.h | 3 +++ + test/subset/data/Makefile.am | 1 + + test/subset/data/Makefile.sources | 1 + + ...Roboto-Regular.no-layout-closure-gids.no-unicodes.ttf | Bin 0 -> 2612 bytes + test/subset/data/profiles/no-layout-closure-gids.txt | 2 ++ + test/subset/data/tests/no_layout_closure.tests | 8 ++++++++ + test/subset/generate-expected-outputs.py | 7 +++++-- + test/subset/meson.build | 1 + + test/subset/subset_test_suite.py | 7 +++++++ + util/hb-subset.cc | 1 + + 11 files changed, 30 insertions(+), 3 deletions(-) + +commit 9c258936e7638e9e39976ae6afdc0b05a3065e16 +Author: Behdad Esfahbod +Date: Fri Apr 14 11:35:34 2023 -0600 + + [SECURITY] Update + + SECURITY.md | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +commit feb1f6d39e186421cc309ca137852ecb5fb8f65e +Author: Pedro Kaj Kjellerup Nacht +Date: Fri Apr 14 15:17:54 2023 +0000 + + Add security policy + + Signed-off-by: Pedro Kaj Kjellerup Nacht + + SECURITY.md | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +commit 26c719e8cd767e984daec3656be10b8ceec7832c +Author: Pedro Kaj Kjellerup Nacht +Date: Wed Apr 12 13:38:49 2023 +0000 + + Add read-only top-level permissions to cifuzz.yml + + Signed-off-by: Pedro Kaj Kjellerup Nacht + + .github/workflows/cifuzz.yml | 4 ++++ + 1 file changed, 4 insertions(+) + +commit 96ed20725c99275f286a9a9cf461548731b6828c +Author: Qunxin Liu +Date: Tue Apr 4 10:33:58 2023 -0700 + + [instancer] update bound metrics for CFF2 instancing + + src/hb-ot-head-table.hh | 20 ++++- + src/hb-ot-var-hvar-table.hh | 3 + + src/hb-subset-plan.cc | 88 +++++++++++++++++++++ + test/subset/data/Makefile.am | 1 + + test/subset/data/Makefile.sources | 1 + + ...fault.retain-all-codepoint.wght=650,CNTR=50.otf | Bin 41760 -> 41760 bytes + ...F-ABC.default.retain-all-codepoint.wght=800.otf | Bin 0 -> 1508 bytes + ...C.retain-gids.retain-all-codepoint.wght=800.otf | Bin 0 -> 1508 bytes + test/subset/data/fonts/Cantarell-VF-ABC.otf | Bin 0 -> 2508 bytes + .../tests/instantiate_cff2_update_metrics.tests | 15 ++++ + test/subset/meson.build | 1 + + 11 files changed, 128 insertions(+), 1 deletion(-) + +commit 04a47932a3844f7e73e3af8b05fb98c8b54fb779 +Author: Behdad Esfahbod +Date: Fri Mar 31 11:44:08 2023 -0600 + + [paint] Remove enum trailing comma in C header + + Fixes https://github.com/harfbuzz/harfbuzz/discussions/4188 + + src/hb-paint.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 2cd81fdfb6ccc6ba7ec63abe14e0126ece71f304 +Author: Garret Rieger +Date: Thu Mar 30 22:11:43 2023 +0000 + + [subset] fix memory leak. + + Fixes fuzzer issue https://oss-fuzz.com/testcase-detail/6169920089227264 + + src/hb-subset-plan.cc | 3 ++- + ...-testcase-minimized-hb-subset-fuzzer-6169920089227264 | Bin 0 -> 1214 bytes + 2 files changed, 2 insertions(+), 1 deletion(-) + +commit 453ded05392af38bba9f89587edce465e86ffa6b +Author: Behdad Esfahbod +Date: Tue Mar 28 13:17:15 2023 -0600 + + [indic] Tighten up base-finding + + Fixes https://github.com/harfbuzz/harfbuzz/issues/4185 + + src/hb-ot-shaper-indic.cc | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +commit c1acfe9966b1d2bd74c80de4aefcccc309664822 +Author: Qunxin Liu +Date: Wed Mar 22 19:06:58 2023 -0700 + + [instancer] bug fix in TupleVariationData get_size () + + We need to iterate TupleVariationHeader when calculating the total size + + src/hb-ot-var-common.hh | 7 +++++-- + .../Muli-ABC.default.retain-all-codepoint.wght=300.ttf | Bin 0 -> 5808 bytes + .../Muli-ABC.default.retain-all-codepoint.wght=700.ttf | Bin 0 -> 5804 bytes + test/subset/data/fonts/Muli-ABC.ttf | Bin 0 -> 6996 bytes + test/subset/data/tests/apply_cvar_delta.tests | 1 + + 5 files changed, 6 insertions(+), 2 deletions(-) + +commit be872001063d263efe708c4db5af569cfaedd3fe +Author: Garret Rieger +Date: Fri Mar 24 17:30:53 2023 +0000 + + [subset] fix buffer overflow fuzzer reported issue. + + src/hb-subset-plan.cc | 14 ++++++++------ + ...-testcase-minimized-hb-subset-fuzzer-5120246288875520 | Bin 0 -> 2501 bytes + 2 files changed, 8 insertions(+), 6 deletions(-) + +commit 79ae6b657f9c7bff8c97eb8ee7d2dbeb2217868e +Author: Garret Rieger +Date: Fri Mar 24 17:14:55 2023 +0000 + + [subset] Fix fuzzer found memory leaks. + + src/hb-subset-plan.cc | 9 +++++++-- + ...-testcase-minimized-hb-subset-fuzzer-5793182905663488 | Bin 0 -> 803 bytes + ...-testcase-minimized-hb-subset-fuzzer-6742230974201856 | Bin 0 -> 1214 bytes + 3 files changed, 7 insertions(+), 2 deletions(-) + +commit ab87d7d22545f6774a12688708d21e6e18ae7fb4 +Author: Qunxin Liu +Date: Mon Mar 20 12:24:22 2023 -0700 + + [instance] add tests for colrv1 full instancing + + test/subset/data/Makefile.am | 1 + + test/subset/data/Makefile.sources | 1 + + .../Foldit.default.retain-all-codepoint.wght=900.ttf | Bin 0 -> 2508 bytes + test/subset/data/tests/instantiate_colrv1.tests | 14 ++++++++++++++ + test/subset/meson.build | 1 + + 5 files changed, 17 insertions(+) + +commit fe671a5ac811e542071a7cd2151d6c045b77158a +Author: Qunxin Liu +Date: Thu Mar 16 14:10:21 2023 -0700 + + [instancer] support COLRv1 full instancing + + src/OT/Color/COLR/COLR.hh | 379 +++++++++++++++++++++++++++++++++++++--------- + src/hb-ot-var-common.hh | 14 +- + 2 files changed, 312 insertions(+), 81 deletions(-) + +commit f0f7f22525d20ba05e9b69ba40b352cb89b506ae +Author: Garret Rieger +Date: Mon Mar 20 18:39:49 2023 +0000 + + [subset] fix fuzzer found null deref. + + https://oss-fuzz.com/testcase-detail/5844352760152064 + + src/hb-subset-plan.cc | 9 +++++++-- + ...-testcase-minimized-hb-subset-fuzzer-5844352760152064 | Bin 0 -> 1214 bytes + 2 files changed, 7 insertions(+), 2 deletions(-) + +commit 79233a149209e3da199bb4e2f74271668502c574 +Author: Garret Rieger +Date: Fri Mar 17 00:58:58 2023 +0000 + + [subset] fix incorrectly specified lock. + + Lock variable must have a name or it will immediately destruct. + + src/hb-subset-plan.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 8d8bcde8cfe214855fdde15b5d9448e87d3ec734 +Author: Garret Rieger +Date: Wed Mar 15 17:29:08 2023 +0000 + + [set] don't allow -1 (HB_SET_VALUE_INVALID) to be inserted into a hb_set_t. + + Add tests that check all of the addition methods. + + src/hb-bit-set.hh | 4 ++-- + src/test-set.cc | 24 ++++++++++++++++++++++++ + 2 files changed, 26 insertions(+), 2 deletions(-) + +commit a84cae424d7b315336a191d13a2bef8a9d3635d2 +Author: Garret Rieger +Date: Wed Mar 15 02:39:57 2023 +0000 + + [subset] Don't add invalid gids (-1) to the glyphset when loading glyph map from the accelerator. + + src/OT/Layout/GPOS/PairPosFormat1.hh | 2 +- + src/hb-subset-plan.cc | 9 ++++++--- + test/subset/data/Makefile.am | 1 + + test/subset/data/Makefile.sources | 1 + + .../preprocess/Roboto-Regular.gids.61,62,63,30D9.ttf | Bin 0 -> 2680 bytes + test/subset/data/tests/preprocess.tests | 8 ++++++++ + test/subset/meson.build | 1 + + 7 files changed, 18 insertions(+), 4 deletions(-) + +commit 09a266236147497bd8149240062c31c16fbc81e3 +Merge: 75e6498d9 204e155ac +Author: Behdad Esfahbod +Date: Tue Mar 14 12:48:12 2023 -0600 + + Merge pull request #4168 from googlefonts/subset_name_collect + + [subset] name_id closure + +commit 75e6498d9a8b600ab7f00b3d279f1054dd72feec +Author: Behdad Esfahbod +Date: Tue Mar 14 12:41:46 2023 -0600 + + Don't use M_PI + + Fixes https://github.com/harfbuzz/harfbuzz/issues/4166 + + Happy Pi Day! + + src/OT/Color/COLR/COLR.hh | 4 ++-- + src/OT/glyf/VarCompositeGlyph.hh | 6 +++--- + src/hb-cairo-utils.cc | 24 +++++++++++------------- + src/hb-ft-colr.hh | 4 ++-- + src/hb-paint.hh | 8 ++++---- + src/hb-style.cc | 4 ++-- + src/hb.hh | 6 ++++++ + 7 files changed, 30 insertions(+), 26 deletions(-) + +commit 204e155acbf6a9311a13efd4400d2a7b52ca609a +Author: Qunxin Liu +Date: Tue Mar 14 10:25:31 2023 -0700 + + [subset] Add tests for collecting name_ids from STAT and FeatureParams + + test/subset/data/Makefile.am | 1 + + test/subset/data/Makefile.sources | 1 + + ...et.keep-all-layout-features.retain-all-codepoint.otf | Bin 0 -> 12796 bytes + .../data/fonts/SourceSerif4Variable-Roman_subset.otf | Bin 0 -> 12784 bytes + test/subset/data/tests/collect_name_ids.tests | 11 +++++++++++ + test/subset/meson.build | 1 + + 6 files changed, 14 insertions(+) + +commit 32c889f1d66e7a990c9e80e3c4cc0bd8f62da601 +Author: Jason Simmons +Date: Mon Mar 13 18:24:39 2023 -0700 + + Remove extra blank line in hb-outline.cc + + src/hb-outline.cc | 1 - + 1 file changed, 1 deletion(-) + +commit 0d65738633f84cfbf69325edb8189ee0184d50cf +Author: Qunxin Liu +Date: Mon Mar 13 15:51:45 2023 -0700 + + [subset] collect elidedFallbackNameID in STAT table + + src/hb-ot-stat-table.hh | 2 ++ + 1 file changed, 2 insertions(+) + +commit 125450d2f220821e63fe748475611c66905904e8 +Author: Qunxin Liu +Date: Mon Mar 13 15:43:29 2023 -0700 + + [subset] collect name_ids for FeratureParams + + src/hb-ot-layout-common.hh | 39 +++++++++++++++++++++++++++++++++++++++ + src/hb-ot-layout-gsubgpos.hh | 12 ++++++++++++ + src/hb-subset-plan.cc | 38 +++++++++++++++++++++++--------------- + 3 files changed, 74 insertions(+), 15 deletions(-) + +commit 663ecc01d8cd32c3fcb8421ee157815ecab413db +Author: Garret Rieger +Date: Mon Mar 13 22:12:59 2023 +0000 + + [subset] don't free glyphs by range. + + The iterator in this loop is a map iterator so glyphs are not necessarily traveresed in order. + + src/OT/glyf/glyf.hh | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +commit 3d05b96181b259593047f592df4df33a3658e472 +Author: Garret Rieger +Date: Mon Mar 13 21:34:26 2023 +0000 + + [subset] track which glyphs have allocated memory so we can clean up correctly. + + Fixes https://oss-fuzz.com/testcase-detail/5388270411579392 + + src/OT/glyf/CompositeGlyph.hh | 5 ++++- + src/OT/glyf/SubsetGlyph.hh | 13 ++++++++++--- + src/OT/glyf/glyf.hh | 6 ++---- + ...-testcase-minimized-hb-subset-fuzzer-5388270411579392 | Bin 0 -> 4844 bytes + 4 files changed, 16 insertions(+), 8 deletions(-) + +commit 7a87b17742a0cec36ad21d9fddc1c605597eea14 +Author: Garret Rieger +Date: Mon Mar 13 19:50:28 2023 +0000 + + Check for failed subset input creation in the fuzzer. + + ...z-testcase-minimized-hb-subset-fuzzer-4801020053291008 | Bin 0 -> 311 bytes + test/fuzzing/hb-subset-fuzzer.cc | 12 ++++++++++++ + 2 files changed, 12 insertions(+) + +commit de6533d8850944e71d5d69c6257ef85f1bf16b1f +Author: Qunxin Liu +Date: Mon Mar 13 13:36:00 2023 -0700 + + [subset] collect name_ids from CPAL table + + src/OT/Color/CPAL/CPAL.hh | 31 +++++++++++++++++++++++++++++++ + src/hb-subset-plan.cc | 41 +++++++++++++++++++++++++---------------- + 2 files changed, 56 insertions(+), 16 deletions(-) + +commit 7b77cd198c0352b6ed2a0adbee68bb3e246b9658 +Author: Qunxin Liu +Date: Mon Mar 13 12:45:43 2023 -0700 + + [subset] fix bug in CPAL V1tail serialization + + We should serialize nameIDs rather than retained color index + + src/OT/Color/CPAL/CPAL.hh | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +commit 6d2705a719222adaa4d56a5df589f0c1c81e9bfc +Author: Behdad Esfahbod +Date: Fri Mar 10 12:40:43 2023 -0700 + + [justify-demo] Help message + + src/justify.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +commit 2d8634624ccec268aaac097763f544aafcae8ba8 +Author: Simon Cozens +Date: Fri Mar 10 14:32:39 2023 +0000 + + Add Tifinagh to list of both-directions scripts + + src/hb-common.cc | 1 + + 1 file changed, 1 insertion(+) + +commit 905eeee4a4ebfbc8ed4f07d3ae0c730dd54eb334 +Author: Jean-Michaël Celerier +Date: Mon Mar 6 13:21:33 2023 -0500 + + harfbuzz-config.cmake: support static library build + + src/harfbuzz-config.cmake.in | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +commit 28b05e1cb6116b07b95af799ff68b883c3f590d1 +Author: Garret Rieger +Date: Wed Mar 8 23:59:04 2023 +0000 + + [subset] Fix memory leak in glyf subset. + + Fixes fuzzer issue: https://oss-fuzz.com/testcase-detail/6525813890875392. + + src/OT/glyf/glyf.hh | 9 +++++++++ + ...testcase-minimized-hb-subset-fuzzer-6525813890875392 | Bin 0 -> 73882 bytes + 2 files changed, 9 insertions(+) + +commit 9286e125250c7724a5d7eece0fff4284f73341b6 +Author: Garret Rieger +Date: Wed Mar 8 20:02:26 2023 +0000 + + Don't subset a glyf table with an unknown format. + + Fixes fuzzer issue: https://oss-fuzz.com/testcase-detail/4875306193518592 + + src/OT/glyf/glyf.hh | 15 ++++++++++++++- + ...case-minimized-hb-subset-fuzzer-4875306193518592.fuzz | Bin 0 -> 1044 bytes + 2 files changed, 14 insertions(+), 1 deletion(-) + +commit cfa9541daa86c659ea935bbd4507cc620658c6d4 +Author: Behdad Esfahbod +Date: Wed Mar 8 10:35:39 2023 -0700 + + [glyf] "Support" glyf version 1 + + src/OT/glyf/glyf.hh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +commit 552290f60437ceaa5aa299a2db726046c0385f80 +Author: Behdad Esfahbod +Date: Wed Mar 8 10:25:26 2023 -0700 + + [gvar] Fix out-of-memory access issue + + Fixes https://oss-fuzz.com/testcase-detail/5953342850596864 + + src/hb-ot-var-gvar-table.hh | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +commit 7327006d686c149cefdc7ee6047d2b426ac1ac75 +Author: Behdad Esfahbod +Date: Tue Mar 7 21:06:01 2023 -0700 + + [GSUB] Support SingleSubst in get_glyph_alternates + + Fixes https://github.com/harfbuzz/harfbuzz/discussions/4146 + + src/OT/Layout/GSUB/SingleSubstFormat1.hh | 28 ++++++++++++++++++++++++++++ + src/OT/Layout/GSUB/SingleSubstFormat2.hh | 25 +++++++++++++++++++++++++ + 2 files changed, 53 insertions(+) + +commit 69183217dfbd6380f2c57e3a9a793559874667e5 +Author: Behdad Esfahbod +Date: Tue Mar 7 20:56:56 2023 -0700 + + Add test-gsub-get-alternates.cc + + src/Makefile.am | 5 +++ + src/meson.build | 1 + + src/test-gsub-get-alternates.cc | 86 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 92 insertions(+) + +commit ea17c7a81a743d7e319da0ff4111bcf650d2011b +Author: Behdad Esfahbod +Date: Tue Mar 7 14:23:39 2023 -0700 + + [beyond-64k] Implement gvar support + + https://github.com/harfbuzz/boring-expansion-spec/issues/85 + + src/hb-ot-var-gvar-table.hh | 38 ++++++++++++++++++++++++-------------- + 1 file changed, 24 insertions(+), 14 deletions(-) + +commit f325aba561335a4f0f3c71aa59e42f1a23c774f2 +Author: Behdad Esfahbod +Date: Mon Mar 6 13:07:42 2023 -0700 + + [VarComposites] Minor rename + + src/OT/glyf/VarCompositeGlyph.hh | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +commit b4b089c4278f041f69c3253f84901de226d38558 +Author: Khaled Hosny +Date: Mon Mar 6 04:40:04 2023 +0200 + + [docs] Disable gtdoc-check by default + + It slows build as it causes documentation to be always rebuilt. We now + disable it by default and enable it on relevant CI jobs. + + .github/workflows/linux-ci.yml | 1 + + docs/meson.build | 2 +- + meson_options.txt | 2 ++ + 3 files changed, 4 insertions(+), 1 deletion(-) + +commit d165afec1d301167754c4152f868a0110b3144a6 +Author: Behdad Esfahbod +Date: Sat Mar 4 21:09:26 2023 -0700 + + [justify-demo] Create new fonts all the time + + The hb.shape_justify() call modifies the font. This was messing + up justification. Create new fonts all the time. + + src/justify.py | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +commit 690145fa009b4a705065549474a81113e609419f +Author: Khaled Hosny +Date: Sat Mar 4 07:19:20 2023 +0200 + + [justify-demo] Rewrite in a simpler way + + No need to overthink it, append text words to the line and reshape, no + need to shape the whole text first and do complicated glyph/input + mapping. Much simpler code and as fast. + + src/justify.py | 323 +++++++++++++++++++++------------------------------------ + 1 file changed, 118 insertions(+), 205 deletions(-) + +commit e9d6f23b5d4779e08cd27f38fd92860cb9cbe1da +Author: Behdad Esfahbod +Date: Fri Mar 3 17:15:18 2023 -0700 + + [justify-demo] Fix for LTR typesetting + + src/justify.py | 24 +++++++++++++++--------- + 1 file changed, 15 insertions(+), 9 deletions(-) + +commit 5cf54aeddec47aea380bfa39d543b8fe373c6873 +Author: Behdad Esfahbod +Date: Fri Mar 3 17:01:12 2023 -0700 + + [justify-demo] Guess segment properties + + src/justify.py | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +commit 5c334b9686064aa0d1d41d8935e713c70c43589b +Author: Behdad Esfahbod +Date: Fri Mar 3 16:53:44 2023 -0700 + + [justify-demo] Fix crash if font has no variation axis + + src/justify.py | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +commit ab249fd24b355ead23ab23f481bd219e0d95faaa +Author: Behdad Esfahbod +Date: Sat Mar 4 01:46:07 2023 +0200 + + [justify] Fix shrink/expand conditions + + src/justify.py | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +commit 039ea9adda1ab9338165469982ae1be6dcce3ae7 +Author: Khaled Hosny +Date: Sat Mar 4 01:41:34 2023 +0200 + + [justify] Add demo GTK app + + src/justify.py | 364 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 364 insertions(+) + +commit be47182d4897de6b875101a1d258877ed525a24b +Author: Behdad Esfahbod +Date: Fri Mar 3 11:10:16 2023 -0700 + + [hb-cairo] Add Black Foundry copyright + + src/hb-cairo-utils.cc | 7 +++++++ + 1 file changed, 7 insertions(+) + +commit ab4c32118025822094ef9197ad105e7460230be4 +Author: Behdad Esfahbod +Date: Fri Mar 3 09:31:16 2023 -0700 + + [justify] Set out params in more cases + + src/hb-shape.cc | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +commit e57defc07c83f1012fac0f213d636698d86a76c1 +Author: Khaled Hosny +Date: Fri Mar 3 13:05:30 2023 +0200 + + [justify] Set var_value when expanding/shrinking to max + + When expanding/shrinking the buffer to max (and still not fitting), we + need to also set var_value to the axis max/min otherwise client not have + the correct axis value to draw with. + + src/hb-shape.cc | 2 ++ + 1 file changed, 2 insertions(+) + +commit a2efa5b4895bc90a89be43196e56de276a5fcf00 +Author: Behdad Esfahbod +Date: Fri Mar 3 09:15:46 2023 -0700 + + [map] Another try at fixing old Mac build + + https://github.com/harfbuzz/harfbuzz/issues/4138 + + src/hb-map.hh | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +commit bfab56d3b5d2d11416375d03c7440f9d6e262f62 +Author: Khaled Hosny +Date: Fri Mar 3 13:14:05 2023 +0200 + + [font] Typo + + src/hb-font.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + commit 60841e26187576bff477c1a09ee2ffe544844abc Author: Khaled Hosny Date: Fri Mar 3 01:01:49 2023 +0200 diff --git a/libs/harfbuzz/harfbuzz-src/NEWS b/libs/harfbuzz/harfbuzz-src/NEWS index 5ed287822d..e53a244f1b 100644 --- a/libs/harfbuzz/harfbuzz-src/NEWS +++ b/libs/harfbuzz/harfbuzz-src/NEWS @@ -1,3 +1,31 @@ +Overview of changes leading to 7.2.0 +Thursday, April 27, 2023 +==================================== +- Add Tifinagh to the list of scripts that can natively be either right-to-left + or left-to-right, to improve handling of its glyph positioning. + (Simon Cozens) +- Return also single substitution from hb_ot_layout_lookup_get_glyph_alternates() + (Behdad Esfahbod) +- Fix 4.2.0 regression in applying across syllables in syllabic scripts. + (Behdad Esfahbod) +- Add flag to avoid glyph substitution closure during subsetting, and the + corresponding “--no-layout-closure” option to “hb-subset” command line tool. + (Garret Rieger) +- Support instancing COLRv1 table. (Qunxin Liu) +- Don’t drop used user-defined name table entries during subsetting. + (Qunxin Liu) +- Optimize handling of “gvar” table. (Behdad Esfahbod) +- Various subsetter bug fixes and improvements. (Garret Rieger, Qunxin Liu) +- Various documentation improvements. (Behdad Esfahbod, Josef Friedrich) + +- New API: ++HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE ++HB_UNICODE_COMBINING_CLASS_CCC132 + +- Deprecated API: ++HB_UNICODE_COMBINING_CLASS_CCC133 + + Overview of changes leading to 7.1.0 Friday, March 3, 2023 ==================================== @@ -8,6 +36,7 @@ Friday, March 3, 2023 - New API: +hb_font_set_variation() + Overview of changes leading to 7.0.1 Monday, February 20, 2023 ==================================== diff --git a/libs/harfbuzz/harfbuzz-src/configure.ac b/libs/harfbuzz/harfbuzz-src/configure.ac index c863ab83b0..33c19b35f0 100644 --- a/libs/harfbuzz/harfbuzz-src/configure.ac +++ b/libs/harfbuzz/harfbuzz-src/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ([2.64]) AC_INIT([HarfBuzz], - [7.1.0], + [7.2.0], [https://github.com/harfbuzz/harfbuzz/issues/new], [harfbuzz], [http://harfbuzz.org/]) diff --git a/libs/harfbuzz/harfbuzz-src/meson.build b/libs/harfbuzz/harfbuzz-src/meson.build index 6bf8d05da9..b862d24ca9 100644 --- a/libs/harfbuzz/harfbuzz-src/meson.build +++ b/libs/harfbuzz/harfbuzz-src/meson.build @@ -1,6 +1,6 @@ project('harfbuzz', 'c', 'cpp', meson_version: '>= 0.55.0', - version: '7.1.0', + version: '7.2.0', default_options: [ 'cpp_eh=none', # Just to support msvc, we are passing -fno-exceptions also anyway 'cpp_rtti=false', # Just to support msvc, we are passing -fno-rtti also anyway @@ -373,7 +373,10 @@ foreach check : check_funcs endforeach subdir('src') -subdir('util') + +if not get_option('utilities').disabled() + subdir('util') +endif if not get_option('tests').disabled() subdir('test') diff --git a/libs/harfbuzz/harfbuzz-src/meson_options.txt b/libs/harfbuzz/harfbuzz-src/meson_options.txt index 9ebba72c6d..9438202e1b 100644 --- a/libs/harfbuzz/harfbuzz-src/meson_options.txt +++ b/libs/harfbuzz/harfbuzz-src/meson_options.txt @@ -29,6 +29,10 @@ option('introspection', type: 'feature', value: 'auto', yield: true, description: 'Generate gobject-introspection bindings (.gir/.typelib files)') option('docs', type: 'feature', value: 'auto', yield: true, description: 'Generate documentation with gtk-doc') +option('doc_tests', type: 'boolean', value: false, + description: 'Run gtkdoc-check tests') +option('utilities', type: 'feature', value: 'enabled', yield: true, + description: 'Build harfbuzz utils') option('benchmark', type: 'feature', value: 'disabled', description: 'Enable benchmark tests') diff --git a/libs/harfbuzz/harfbuzz-src/src/Makefile.am b/libs/harfbuzz/harfbuzz-src/src/Makefile.am index 52bd92b79b..56dc32d9a7 100644 --- a/libs/harfbuzz/harfbuzz-src/src/Makefile.am +++ b/libs/harfbuzz/harfbuzz-src/src/Makefile.am @@ -382,6 +382,7 @@ noinst_PROGRAMS = \ test-ot-name \ test-ot-glyphname \ test-gpos-size-params \ + test-gsub-get-alternates \ test-gsub-would-substitute \ test-use-table \ $(NULL) @@ -419,6 +420,10 @@ test_gpos_size_params_SOURCES = test-gpos-size-params.cc test_gpos_size_params_CPPFLAGS = $(HBCFLAGS) test_gpos_size_params_LDADD = libharfbuzz.la $(HBLIBS) +test_gsub_get_alternates_SOURCES = test-gsub-get-alternates.cc +test_gsub_get_alternates_CPPFLAGS = $(HBCFLAGS) +test_gsub_get_alternates_LDADD = libharfbuzz.la $(HBLIBS) + test_gsub_would_substitute_SOURCES = test-gsub-would-substitute.cc test_gsub_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS) test_gsub_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS) diff --git a/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh b/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh index 31be6585dd..191812f48e 100644 --- a/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh +++ b/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh @@ -40,7 +40,6 @@ */ #define HB_OT_TAG_COLR HB_TAG('C','O','L','R') - namespace OT { struct hb_paint_context_t; } @@ -242,10 +241,15 @@ struct Variable void closurev1 (hb_colrv1_closure_context_t* c) const { value.closurev1 (c); } - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer) const { TRACE_SUBSET (this); - if (!value.subset (c)) return_trace (false); + if (!value.subset (c, instancer, varIdxBase)) return_trace (false); + if (c->plan->all_axes_pinned) + return_trace (true); + + //TODO: update varIdxBase for partial-instancing return_trace (c->serializer->embed (varIdxBase)); } @@ -296,10 +300,11 @@ struct NoVariable void closurev1 (hb_colrv1_closure_context_t* c) const { value.closurev1 (c); } - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer) const { TRACE_SUBSET (this); - return_trace (value.subset (c)); + return_trace (value.subset (c, instancer, varIdxBase)); } bool sanitize (hb_sanitize_context_t *c) const @@ -337,11 +342,20 @@ struct ColorStop void closurev1 (hb_colrv1_closure_context_t* c) const { c->add_palette_index (paletteIndex); } - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer, + uint32_t varIdxBase) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (*this); if (unlikely (!out)) return_trace (false); + + if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION) + { + out->stopOffset.set_float (stopOffset.to_float(instancer (varIdxBase, 0))); + out->alpha.set_float (alpha.to_float (instancer (varIdxBase, 1))); + } + return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes.get (paletteIndex), HB_SERIALIZE_ERROR_INT_OVERFLOW)); } @@ -390,7 +404,8 @@ struct ColorLine stop.closurev1 (c); } - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); @@ -402,7 +417,7 @@ struct ColorLine for (const auto& stop : stops.iter ()) { - if (!stop.subset (c)) return_trace (false); + if (!stop.subset (c, instancer)) return_trace (false); } return_trace (true); } @@ -523,6 +538,25 @@ struct Affine2x3 return_trace (c->check_struct (this)); } + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer, + uint32_t varIdxBase) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION) + { + out->xx.set_float (xx.to_float(instancer (varIdxBase, 0))); + out->yx.set_float (yx.to_float(instancer (varIdxBase, 1))); + out->xy.set_float (xy.to_float(instancer (varIdxBase, 2))); + out->yy.set_float (yy.to_float(instancer (varIdxBase, 3))); + out->dx.set_float (dx.to_float(instancer (varIdxBase, 4))); + out->dy.set_float (dy.to_float(instancer (varIdxBase, 5))); + } + return_trace (true); + } + void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { c->funcs->push_transform (c->data, @@ -548,7 +582,8 @@ struct PaintColrLayers { void closurev1 (hb_colrv1_closure_context_t* c) const; - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer HB_UNUSED) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -579,11 +614,20 @@ struct PaintSolid void closurev1 (hb_colrv1_closure_context_t* c) const { c->add_palette_index (paletteIndex); } - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer, + uint32_t varIdxBase) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (*this); if (unlikely (!out)) return_trace (false); + + if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION) + out->alpha.set_float (alpha.to_float (instancer (varIdxBase, 0))); + + if (format == 3 && c->plan->all_axes_pinned) + out->format = 2; + return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes.get (paletteIndex), HB_SERIALIZE_ERROR_INT_OVERFLOW)); } @@ -618,13 +662,28 @@ struct PaintLinearGradient void closurev1 (hb_colrv1_closure_context_t* c) const { (this+colorLine).closurev1 (c); } - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer, + uint32_t varIdxBase) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - return_trace (out->colorLine.serialize_subset (c, colorLine, this)); + if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION) + { + out->x0 = x0 + (int) roundf (instancer (varIdxBase, 0)); + out->y0 = y0 + (int) roundf (instancer (varIdxBase, 1)); + out->x1 = x1 + (int) roundf (instancer (varIdxBase, 2)); + out->y1 = y1 + (int) roundf (instancer (varIdxBase, 3)); + out->x2 = x2 + (int) roundf (instancer (varIdxBase, 4)); + out->y2 = y2 + (int) roundf (instancer (varIdxBase, 5)); + } + + if (format == 5 && c->plan->all_axes_pinned) + out->format = 4; + + return_trace (out->colorLine.serialize_subset (c, colorLine, this, instancer)); } bool sanitize (hb_sanitize_context_t *c) const @@ -669,13 +728,28 @@ struct PaintRadialGradient void closurev1 (hb_colrv1_closure_context_t* c) const { (this+colorLine).closurev1 (c); } - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer, + uint32_t varIdxBase) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - return_trace (out->colorLine.serialize_subset (c, colorLine, this)); + if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION) + { + out->x0 = x0 + (int) roundf (instancer (varIdxBase, 0)); + out->y0 = y0 + (int) roundf (instancer (varIdxBase, 1)); + out->radius0 = radius0 + (unsigned) roundf (instancer (varIdxBase, 2)); + out->x1 = x1 + (int) roundf (instancer (varIdxBase, 3)); + out->y1 = y1 + (int) roundf (instancer (varIdxBase, 4)); + out->radius1 = radius1 + (unsigned) roundf (instancer (varIdxBase, 5)); + } + + if (format == 7 && c->plan->all_axes_pinned) + out->format = 6; + + return_trace (out->colorLine.serialize_subset (c, colorLine, this, instancer)); } bool sanitize (hb_sanitize_context_t *c) const @@ -720,13 +794,26 @@ struct PaintSweepGradient void closurev1 (hb_colrv1_closure_context_t* c) const { (this+colorLine).closurev1 (c); } - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer, + uint32_t varIdxBase) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - return_trace (out->colorLine.serialize_subset (c, colorLine, this)); + if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION) + { + out->centerX = centerX + (int) roundf (instancer (varIdxBase, 0)); + out->centerY = centerY + (int) roundf (instancer (varIdxBase, 1)); + out->startAngle.set_float (startAngle.to_float (instancer (varIdxBase, 2))); + out->endAngle.set_float (endAngle.to_float (instancer (varIdxBase, 3))); + } + + if (format == 9 && c->plan->all_axes_pinned) + out->format = 8; + + return_trace (out->colorLine.serialize_subset (c, colorLine, this, instancer)); } bool sanitize (hb_sanitize_context_t *c) const @@ -746,8 +833,8 @@ struct PaintSweepGradient c->funcs->sweep_gradient (c->data, &cl, centerX + c->instancer (varIdxBase, 0), centerY + c->instancer (varIdxBase, 1), - (startAngle.to_float (c->instancer (varIdxBase, 2)) + 1) * (float) M_PI, - (endAngle.to_float (c->instancer (varIdxBase, 3)) + 1) * (float) M_PI); + (startAngle.to_float (c->instancer (varIdxBase, 2)) + 1) * HB_PI, + (endAngle.to_float (c->instancer (varIdxBase, 3)) + 1) * HB_PI); } HBUINT8 format; /* format = 8(noVar) or 9 (Var) */ @@ -766,7 +853,8 @@ struct PaintGlyph { void closurev1 (hb_colrv1_closure_context_t* c) const; - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -776,7 +864,7 @@ struct PaintGlyph HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false); - return_trace (out->paint.serialize_subset (c, paint, this)); + return_trace (out->paint.serialize_subset (c, paint, this, instancer)); } bool sanitize (hb_sanitize_context_t *c) const @@ -807,7 +895,8 @@ struct PaintColrGlyph { void closurev1 (hb_colrv1_closure_context_t* c) const; - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer HB_UNUSED) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -836,13 +925,16 @@ struct PaintTransform { HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - if (!out->transform.serialize_copy (c->serializer, transform, this)) return_trace (false); - return_trace (out->src.serialize_subset (c, src, this)); + if (!out->transform.serialize_subset (c, transform, this, instancer)) return_trace (false); + if (format == 13 && c->plan->all_axes_pinned) + out->format = 12; + return_trace (out->src.serialize_subset (c, src, this, instancer)); } bool sanitize (hb_sanitize_context_t *c) const @@ -871,13 +963,24 @@ struct PaintTranslate { HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer, + uint32_t varIdxBase) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - return_trace (out->src.serialize_subset (c, src, this)); + if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION) + { + out->dx = dx + (int) roundf (instancer (varIdxBase, 0)); + out->dy = dy + (int) roundf (instancer (varIdxBase, 1)); + } + + if (format == 15 && c->plan->all_axes_pinned) + out->format = 14; + + return_trace (out->src.serialize_subset (c, src, this, instancer)); } bool sanitize (hb_sanitize_context_t *c) const @@ -908,13 +1011,24 @@ struct PaintScale { HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer, + uint32_t varIdxBase) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - return_trace (out->src.serialize_subset (c, src, this)); + if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION) + { + out->scaleX.set_float (scaleX.to_float (instancer (varIdxBase, 0))); + out->scaleY.set_float (scaleY.to_float (instancer (varIdxBase, 1))); + } + + if (format == 17 && c->plan->all_axes_pinned) + out->format = 16; + + return_trace (out->src.serialize_subset (c, src, this, instancer)); } bool sanitize (hb_sanitize_context_t *c) const @@ -945,13 +1059,26 @@ struct PaintScaleAroundCenter { HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer, + uint32_t varIdxBase) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - return_trace (out->src.serialize_subset (c, src, this)); + if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION) + { + out->scaleX.set_float (scaleX.to_float (instancer (varIdxBase, 0))); + out->scaleY.set_float (scaleY.to_float (instancer (varIdxBase, 1))); + out->centerX = centerX + (int) roundf (instancer (varIdxBase, 2)); + out->centerY = centerY + (int) roundf (instancer (varIdxBase, 3)); + } + + if (format == 19 && c->plan->all_axes_pinned) + out->format = 18; + + return_trace (out->src.serialize_subset (c, src, this, instancer)); } bool sanitize (hb_sanitize_context_t *c) const @@ -990,13 +1117,21 @@ struct PaintScaleUniform { HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer, + uint32_t varIdxBase) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - return_trace (out->src.serialize_subset (c, src, this)); + if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION) + out->scale.set_float (scale.to_float (instancer (varIdxBase, 0))); + + if (format == 21 && c->plan->all_axes_pinned) + out->format = 20; + + return_trace (out->src.serialize_subset (c, src, this, instancer)); } bool sanitize (hb_sanitize_context_t *c) const @@ -1025,13 +1160,25 @@ struct PaintScaleUniformAroundCenter { HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer, + uint32_t varIdxBase) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - return_trace (out->src.serialize_subset (c, src, this)); + if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION) + { + out->scale.set_float (scale.to_float (instancer (varIdxBase, 0))); + out->centerX = centerX + (int) roundf (instancer (varIdxBase, 1)); + out->centerY = centerY + (int) roundf (instancer (varIdxBase, 2)); + } + + if (format == 23 && c->plan->all_axes_pinned) + out->format = 22; + + return_trace (out->src.serialize_subset (c, src, this, instancer)); } bool sanitize (hb_sanitize_context_t *c) const @@ -1068,13 +1215,21 @@ struct PaintRotate { HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer, + uint32_t varIdxBase) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - return_trace (out->src.serialize_subset (c, src, this)); + if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION) + out->angle.set_float (angle.to_float (instancer (varIdxBase, 0))); + + if (format == 25 && c->plan->all_axes_pinned) + out->format = 24; + + return_trace (out->src.serialize_subset (c, src, this, instancer)); } bool sanitize (hb_sanitize_context_t *c) const @@ -1103,13 +1258,25 @@ struct PaintRotateAroundCenter { HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer, + uint32_t varIdxBase) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - return_trace (out->src.serialize_subset (c, src, this)); + if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION) + { + out->angle.set_float (angle.to_float (instancer (varIdxBase, 0))); + out->centerX = centerX + (int) roundf (instancer (varIdxBase, 1)); + out->centerY = centerY + (int) roundf (instancer (varIdxBase, 2)); + } + + if (format ==27 && c->plan->all_axes_pinned) + out->format = 26; + + return_trace (out->src.serialize_subset (c, src, this, instancer)); } bool sanitize (hb_sanitize_context_t *c) const @@ -1146,13 +1313,24 @@ struct PaintSkew { HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer, + uint32_t varIdxBase) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - return_trace (out->src.serialize_subset (c, src, this)); + if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION) + { + out->xSkewAngle.set_float (xSkewAngle.to_float (instancer (varIdxBase, 0))); + out->ySkewAngle.set_float (ySkewAngle.to_float (instancer (varIdxBase, 1))); + } + + if (format == 29 && c->plan->all_axes_pinned) + out->format = 28; + + return_trace (out->src.serialize_subset (c, src, this, instancer)); } bool sanitize (hb_sanitize_context_t *c) const @@ -1183,13 +1361,26 @@ struct PaintSkewAroundCenter { HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer, + uint32_t varIdxBase) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - return_trace (out->src.serialize_subset (c, src, this)); + if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION) + { + out->xSkewAngle.set_float (xSkewAngle.to_float (instancer (varIdxBase, 0))); + out->ySkewAngle.set_float (ySkewAngle.to_float (instancer (varIdxBase, 1))); + out->centerX = centerX + (int) roundf (instancer (varIdxBase, 2)); + out->centerY = centerY + (int) roundf (instancer (varIdxBase, 3)); + } + + if (format == 31 && c->plan->all_axes_pinned) + out->format = 30; + + return_trace (out->src.serialize_subset (c, src, this, instancer)); } bool sanitize (hb_sanitize_context_t *c) const @@ -1228,14 +1419,15 @@ struct PaintComposite { void closurev1 (hb_colrv1_closure_context_t* c) const; - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - if (!out->src.serialize_subset (c, src, this)) return_trace (false); - return_trace (out->backdrop.serialize_subset (c, backdrop, this)); + if (!out->src.serialize_subset (c, src, this, instancer)) return_trace (false); + return_trace (out->backdrop.serialize_subset (c, backdrop, this, instancer)); } bool sanitize (hb_sanitize_context_t *c) const @@ -1283,6 +1475,28 @@ struct ClipBoxFormat1 clip_box.yMax = yMax; } + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer, + uint32_t varIdxBase) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION) + { + out->xMin = xMin + (int) roundf (instancer (varIdxBase, 0)); + out->yMin = yMin + (int) roundf (instancer (varIdxBase, 1)); + out->xMax = xMax + (int) roundf (instancer (varIdxBase, 2)); + out->yMax = yMax + (int) roundf (instancer (varIdxBase, 3)); + } + + if (format == 2 && c->plan->all_axes_pinned) + out->format = 1; + + return_trace (true); + } + public: HBUINT8 format; /* format = 1(noVar) or 2(Var)*/ FWORD xMin; @@ -1310,13 +1524,14 @@ struct ClipBoxFormat2 : Variable struct ClipBox { - ClipBox* copy (hb_serialize_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer) const { - TRACE_SERIALIZE (this); + TRACE_SUBSET (this); switch (u.format) { - case 1: return_trace (reinterpret_cast (c->embed (u.format1))); - case 2: return_trace (reinterpret_cast (c->embed (u.format2))); - default:return_trace (nullptr); + case 1: return_trace (u.format1.subset (c, instancer, VarIdx::NO_VARIATION)); + case 2: return_trace (u.format2.subset (c, instancer)); + default:return_trace (c->default_return_value ()); } } @@ -1367,13 +1582,15 @@ struct ClipRecord int cmp (hb_codepoint_t g) const { return g < startGlyphID ? -1 : g <= endGlyphID ? 0 : +1; } - ClipRecord* copy (hb_serialize_context_t *c, const void *base) const + bool subset (hb_subset_context_t *c, + const void *base, + const VarStoreInstancer &instancer) const { - TRACE_SERIALIZE (this); - auto *out = c->embed (this); - if (unlikely (!out)) return_trace (nullptr); - if (!out->clipBox.serialize_copy (c, clipBox, base)) return_trace (nullptr); - return_trace (out); + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + return_trace (out->clipBox.serialize_subset (c, clipBox, base, instancer)); } bool sanitize (hb_sanitize_context_t *c, const void *base) const @@ -1400,7 +1617,8 @@ DECLARE_NULL_NAMESPACE_BYTES (OT, ClipRecord); struct ClipList { - unsigned serialize_clip_records (hb_serialize_context_t *c, + unsigned serialize_clip_records (hb_subset_context_t *c, + const VarStoreInstancer &instancer, const hb_set_t& gids, const hb_map_t& gid_offset_map) const { @@ -1432,7 +1650,7 @@ struct ClipList record.endGlyphID = prev_gid; record.clipBox = prev_offset; - if (!c->copy (record, this)) return_trace (0); + if (!record.subset (c, this, instancer)) return_trace (0); count++; start_gid = _; @@ -1446,13 +1664,14 @@ struct ClipList record.startGlyphID = start_gid; record.endGlyphID = prev_gid; record.clipBox = prev_offset; - if (!c->copy (record, this)) return_trace (0); + if (!record.subset (c, this, instancer)) return_trace (0); count++; } return_trace (count); } - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (*this); @@ -1477,7 +1696,7 @@ struct ClipList } } - unsigned count = serialize_clip_records (c->serializer, new_gids, new_gid_offset_map); + unsigned count = serialize_clip_records (c, instancer, new_gids, new_gid_offset_map); if (!count) return_trace (false); return_trace (c->serializer->check_assign (out->clips.len, count, HB_SERIALIZE_ERROR_INT_OVERFLOW)); } @@ -1611,7 +1830,8 @@ struct BaseGlyphPaintRecord { return g < glyphId ? -1 : g > glyphId ? 1 : 0; } bool serialize (hb_serialize_context_t *s, const hb_map_t* glyph_map, - const void* src_base, hb_subset_context_t *c) const + const void* src_base, hb_subset_context_t *c, + const VarStoreInstancer &instancer) const { TRACE_SERIALIZE (this); auto *out = s->embed (this); @@ -1620,7 +1840,7 @@ struct BaseGlyphPaintRecord HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false); - return_trace (out->paint.serialize_subset (c, paint, src_base)); + return_trace (out->paint.serialize_subset (c, paint, src_base, instancer)); } bool sanitize (hb_sanitize_context_t *c, const void *base) const @@ -1639,7 +1859,8 @@ struct BaseGlyphPaintRecord struct BaseGlyphList : SortedArray32Of { - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); @@ -1651,7 +1872,7 @@ struct BaseGlyphList : SortedArray32Of unsigned gid = _.glyphId; if (!glyphset->has (gid)) continue; - if (_.serialize (c->serializer, c->plan->glyph_map, this, c)) out->len++; + if (_.serialize (c->serializer, c->plan->glyph_map, this, c, instancer)) out->len++; else return_trace (false); } @@ -1670,7 +1891,8 @@ struct LayerList : Array32OfOffset32To const Paint& get_paint (unsigned i) const { return this+(*this)[i]; } - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, + const VarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); @@ -1681,7 +1903,7 @@ struct LayerList : Array32OfOffset32To { auto *o = out->serialize_append (c->serializer); - if (unlikely (!o) || !o->serialize_subset (c, _.second, this)) + if (unlikely (!o) || !o->serialize_subset (c, _.second, this, instancer)) return_trace (false); } return_trace (true); @@ -1883,7 +2105,6 @@ struct COLR bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - const hb_map_t &reverse_glyph_map = *c->plan->reverse_glyph_map; const hb_set_t& glyphset = c->plan->_glyphset_colred; @@ -1954,7 +2175,12 @@ struct COLR auto snap = c->serializer->snapshot (); if (!c->serializer->allocate_size (5 * HBUINT32::static_size)) return_trace (false); - if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this)) + + VarStoreInstancer instancer (varStore ? &(this+varStore) : nullptr, + varIdxMap ? &(this+varIdxMap) : nullptr, + c->plan->normalized_coords.as_array ()); + + if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this, instancer)) { if (c->serializer->in_error ()) return_trace (false); //no more COLRv1 glyphs: downgrade to version 0 @@ -1964,8 +2190,11 @@ struct COLR if (!colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)) return_trace (false); - colr_prime->layerList.serialize_subset (c, layerList, this); - colr_prime->clipList.serialize_subset (c, clipList, this); + colr_prime->layerList.serialize_subset (c, layerList, this, instancer); + colr_prime->clipList.serialize_subset (c, clipList, this, instancer); + if (!varStore || c->plan->all_axes_pinned) + return_trace (true); + colr_prime->varIdxMap.serialize_copy (c->serializer, varIdxMap, this); colr_prime->varStore.serialize_copy (c->serializer, varStore, this); return_trace (true); @@ -1984,14 +2213,15 @@ struct COLR return nullptr; } +#ifndef HB_NO_PAINT bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const { if (version != 1) return false; - VarStoreInstancer instancer (this+varStore, - this+varIdxMap, + VarStoreInstancer instancer (&(this+varStore), + &(this+varIdxMap), hb_array (font->coords, font->num_coords)); if (get_clip (glyph, extents, instancer)) @@ -2022,6 +2252,7 @@ struct COLR return ret; } +#endif bool has_paint_for_glyph (hb_codepoint_t glyph) const @@ -2045,11 +2276,12 @@ struct COLR instancer); } +#ifndef HB_NO_PAINT bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette_index, hb_color_t foreground, bool clip = true) const { - VarStoreInstancer instancer (this+varStore, - this+varIdxMap, + VarStoreInstancer instancer (&(this+varStore), + &(this+varIdxMap), hb_array (font->coords, font->num_coords)); hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer); @@ -2060,8 +2292,8 @@ struct COLR { // COLRv1 glyph - VarStoreInstancer instancer (this+varStore, - this+varIdxMap, + VarStoreInstancer instancer (&(this+varStore), + &(this+varIdxMap), hb_array (font->coords, font->num_coords)); bool is_bounded = true; @@ -2131,6 +2363,7 @@ struct COLR return false; } +#endif protected: HBUINT16 version; /* Table version number (starts at 0). */ diff --git a/libs/harfbuzz/harfbuzz-src/src/OT/Color/CPAL/CPAL.hh b/libs/harfbuzz/harfbuzz-src/src/OT/Color/CPAL/CPAL.hh index 4914a0ed57..c07716c1c9 100644 --- a/libs/harfbuzz/harfbuzz-src/src/OT/Color/CPAL/CPAL.hh +++ b/libs/harfbuzz/harfbuzz-src/src/OT/Color/CPAL/CPAL.hh @@ -73,6 +73,30 @@ struct CPALV1Tail } public: + void collect_name_ids (const void *base, + unsigned palette_count, + unsigned color_count, + const hb_map_t *color_index_map, + hb_set_t *nameids_to_retain /* OUT */) const + { + if (paletteLabelsZ) + { + + (base+paletteLabelsZ).as_array (palette_count) + | hb_sink (nameids_to_retain) + ; + } + + if (colorLabelsZ) + { + const hb_array_t colorLabels = (base+colorLabelsZ).as_array (color_count); + for (unsigned i = 0; i < color_count; i++) + { + if (!color_index_map->has (i)) continue; + nameids_to_retain->add (colorLabels[i]); + } + } + } + bool serialize (hb_serialize_context_t *c, unsigned palette_count, unsigned color_count, @@ -95,13 +119,10 @@ struct CPALV1Tail if (colorLabelsZ) { c->push (); - for (const auto _ : colorLabels) + for (unsigned i = 0; i < color_count; i++) { - const hb_codepoint_t *v; - if (!color_index_map->has (_, &v)) continue; - NameID new_color_idx; - new_color_idx = *v; - if (!c->copy (new_color_idx)) + if (!color_index_map->has (i)) continue; + if (!c->copy (colorLabels[i])) { c->pop_discard (); return_trace (false); @@ -189,6 +210,13 @@ struct CPAL return numColors; } + void collect_name_ids (const hb_map_t *color_index_map, + hb_set_t *nameids_to_retain /* OUT */) const + { + if (version == 1) + v1 ().collect_name_ids (this, numPalettes, numColors, color_index_map, nameids_to_retain); + } + private: const CPALV1Tail& v1 () const { diff --git a/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh b/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh index b4a9a9ad53..4dada1c830 100644 --- a/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh +++ b/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh @@ -55,7 +55,7 @@ struct PairPosFormat1_3 if (pairSet.len > glyphs->get_population () * hb_bit_storage ((unsigned) pairSet.len) / 4) { - for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);) + for (hb_codepoint_t g : glyphs->iter()) { unsigned i = cov.get_coverage (g); if ((this+pairSet[i]).intersects (glyphs, valueFormat)) diff --git a/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh b/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh index ffe39d52ab..38057cb60c 100644 --- a/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh +++ b/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh @@ -29,6 +29,9 @@ struct Ligature bool intersects (const hb_set_t *glyphs) const { return hb_all (component, glyphs); } + bool intersects_lig_glyph (const hb_set_t *glyphs) const + { return glyphs->has(ligGlyph); } + void closure (hb_closure_context_t *c) const { if (!intersects (c->glyphs)) return; diff --git a/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSet.hh b/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSet.hh index 637cec7137..9db25cf567 100644 --- a/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSet.hh +++ b/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSet.hh @@ -34,6 +34,18 @@ struct LigatureSet ; } + bool intersects_lig_glyph (const hb_set_t *glyphs) const + { + return + + hb_iter (ligature) + | hb_map (hb_add (this)) + | hb_map ([glyphs] (const Ligature &_) { + return _.intersects_lig_glyph (glyphs) && _.intersects (glyphs); + }) + | hb_any + ; + } + void closure (hb_closure_context_t *c) const { + hb_iter (ligature) diff --git a/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh b/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh index 32b642c38a..5c7df97d13 100644 --- a/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh +++ b/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubstFormat1.hh @@ -130,7 +130,7 @@ struct LigatureSubstFormat1_2 + hb_zip (this+coverage, hb_iter (ligatureSet) | hb_map (hb_add (this))) | hb_filter (glyphset, hb_first) | hb_filter ([&] (const LigatureSet& _) { - return _.intersects (&glyphset); + return _.intersects_lig_glyph (&glyphset); }, hb_second) | hb_map (hb_first) | hb_sink (new_coverage); diff --git a/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh b/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh index 5b54fdb078..850be86c04 100644 --- a/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh +++ b/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh @@ -95,6 +95,34 @@ struct SingleSubstFormat1_3 bool would_apply (hb_would_apply_context_t *c) const { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; } + unsigned + get_glyph_alternates (hb_codepoint_t glyph_id, + unsigned start_offset, + unsigned *alternate_count /* IN/OUT. May be NULL. */, + hb_codepoint_t *alternate_glyphs /* OUT. May be NULL. */) const + { + unsigned int index = (this+coverage).get_coverage (glyph_id); + if (likely (index == NOT_COVERED)) + { + if (alternate_count) + *alternate_count = 0; + return 0; + } + + if (alternate_count && *alternate_count) + { + hb_codepoint_t d = deltaGlyphID; + hb_codepoint_t mask = get_mask (); + + glyph_id = (glyph_id + d) & mask; + + *alternate_glyphs = glyph_id; + *alternate_count = 1; + } + + return 1; + } + bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); diff --git a/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh b/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh index 17aa087363..9c651abe71 100644 --- a/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh +++ b/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh @@ -75,6 +75,31 @@ struct SingleSubstFormat2_4 bool would_apply (hb_would_apply_context_t *c) const { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; } + unsigned + get_glyph_alternates (hb_codepoint_t glyph_id, + unsigned start_offset, + unsigned *alternate_count /* IN/OUT. May be NULL. */, + hb_codepoint_t *alternate_glyphs /* OUT. May be NULL. */) const + { + unsigned int index = (this+coverage).get_coverage (glyph_id); + if (likely (index == NOT_COVERED)) + { + if (alternate_count) + *alternate_count = 0; + return 0; + } + + if (alternate_count && *alternate_count) + { + glyph_id = substitute[index]; + + *alternate_glyphs = glyph_id; + *alternate_count = 1; + } + + return 1; + } + bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); diff --git a/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh b/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh index edf8cd8797..94e00d3aea 100644 --- a/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh +++ b/libs/harfbuzz/harfbuzz-src/src/OT/glyf/CompositeGlyph.hh @@ -87,27 +87,34 @@ struct CompositeGlyphRecord } } - void transform_points (contour_point_vector_t &points) const + void transform_points (contour_point_vector_t &points, + const float (&matrix)[4], + const contour_point_t &trans) const { - float matrix[4]; - contour_point_t trans; - if (get_transformation (matrix, trans)) + if (scaled_offsets ()) { - if (scaled_offsets ()) - { - points.translate (trans); - points.transform (matrix); - } - else - { - points.transform (matrix); - points.translate (trans); - } + points.translate (trans); + points.transform (matrix); + } + else + { + points.transform (matrix); + points.translate (trans); } } - unsigned compile_with_deltas (const contour_point_t &p_delta, - char *out) const + bool get_points (contour_point_vector_t &points) const + { + float matrix[4]; + contour_point_t trans; + get_transformation (matrix, trans); + if (unlikely (!points.resize (points.length + 1))) return false; + points[points.length - 1] = trans; + return true; + } + + unsigned compile_with_point (const contour_point_t &point, + char *out) const { const HBINT8 *p = &StructAfter (flags); #ifndef HB_NO_BEYOND_64K @@ -121,18 +128,17 @@ struct CompositeGlyphRecord unsigned len_before_val = (const char *)p - (const char *)this; if (flags & ARG_1_AND_2_ARE_WORDS) { - // no overflow, copy and update value with deltas + // no overflow, copy value hb_memcpy (out, this, len); - const HBINT16 *px = reinterpret_cast (p); HBINT16 *o = reinterpret_cast (out + len_before_val); - o[0] = px[0] + roundf (p_delta.x); - o[1] = px[1] + roundf (p_delta.y); + o[0] = roundf (point.x); + o[1] = roundf (point.y); } else { - int new_x = p[0] + roundf (p_delta.x); - int new_y = p[1] + roundf (p_delta.y); + int new_x = roundf (point.x); + int new_y = roundf (point.y); if (new_x <= 127 && new_x >= -128 && new_y <= 127 && new_y >= -128) { @@ -143,7 +149,7 @@ struct CompositeGlyphRecord } else { - // int8 overflows after deltas applied + // new point value has an int8 overflow hb_memcpy (out, this, len_before_val); //update flags @@ -171,6 +177,7 @@ struct CompositeGlyphRecord bool scaled_offsets () const { return (flags & (SCALED_COMPONENT_OFFSET | UNSCALED_COMPONENT_OFFSET)) == SCALED_COMPONENT_OFFSET; } + public: bool get_transformation (float (&matrix)[4], contour_point_t &trans) const { matrix[0] = matrix[3] = 1.f; @@ -225,7 +232,6 @@ struct CompositeGlyphRecord return tx || ty; } - public: hb_codepoint_t get_gid () const { #ifndef HB_NO_BEYOND_64K @@ -246,6 +252,27 @@ struct CompositeGlyphRecord StructAfter (flags) = gid; } +#ifndef HB_NO_BEYOND_64K + void lower_gid_24_to_16 () + { + hb_codepoint_t gid = get_gid (); + if (!(flags & GID_IS_24BIT) || gid > 0xFFFFu) + return; + + /* Lower the flag and move the rest of the struct down. */ + + unsigned size = get_size (); + char *end = (char *) this + size; + char *p = &StructAfter (flags); + p += HBGlyphID24::static_size; + + flags = flags & ~GID_IS_24BIT; + set_gid (gid); + + memmove (p - HBGlyphID24::static_size + HBGlyphID16::static_size, p, end - p); + } +#endif + protected: HBUINT16 flags; HBUINT24 pad; @@ -304,7 +331,7 @@ struct CompositeGlyph } bool compile_bytes_with_deltas (const hb_bytes_t &source_bytes, - const contour_point_vector_t &deltas, + const contour_point_vector_t &points_with_deltas, hb_bytes_t &dest_bytes /* OUT */) { if (source_bytes.length <= GlyphHeader::static_size || @@ -319,7 +346,7 @@ struct CompositeGlyph /* try to allocate more memories than source glyph bytes * in case that there might be an overflow for int8 value * and we would need to use int16 instead */ - char *o = (char *) hb_calloc (source_len + source_len/2, sizeof (char)); + char *o = (char *) hb_calloc (source_len * 2, sizeof (char)); if (unlikely (!o)) return false; const CompositeGlyphRecord *c = reinterpret_cast (source_bytes.arrayZ + GlyphHeader::static_size); @@ -329,8 +356,11 @@ struct CompositeGlyph unsigned i = 0, source_comp_len = 0; for (const auto &component : it) { - /* last 4 points in deltas are phantom points and should not be included */ - if (i >= deltas.length - 4) return false; + /* last 4 points in points_with_deltas are phantom points and should not be included */ + if (i >= points_with_deltas.length - 4) { + free (o); + return false; + } unsigned comp_len = component.get_size (); if (component.is_anchored ()) @@ -340,7 +370,7 @@ struct CompositeGlyph } else { - unsigned new_len = component.compile_with_deltas (deltas[i], p); + unsigned new_len = component.compile_with_point (points_with_deltas[i], p); p += new_len; } i++; diff --git a/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh b/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh index 5574ae0722..9e15a6e6d0 100644 --- a/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh +++ b/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh @@ -29,7 +29,14 @@ enum phantom_point_index_t struct Glyph { - enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE, VAR_COMPOSITE }; + enum glyph_type_t { + EMPTY, + SIMPLE, + COMPOSITE, +#ifndef HB_NO_VAR_COMPOSITES + VAR_COMPOSITE, +#endif + }; public: composite_iter_t get_composite_iterator () const @@ -39,15 +46,23 @@ struct Glyph } var_composite_iter_t get_var_composite_iterator () const { +#ifndef HB_NO_VAR_COMPOSITES if (type != VAR_COMPOSITE) return var_composite_iter_t (); return VarCompositeGlyph (*header, bytes).iter (); +#else + return var_composite_iter_t (); +#endif } const hb_bytes_t trim_padding () const { switch (type) { +#ifndef HB_NO_VAR_COMPOSITES + case VAR_COMPOSITE: return VarCompositeGlyph (*header, bytes).trim_padding (); +#endif case COMPOSITE: return CompositeGlyph (*header, bytes).trim_padding (); case SIMPLE: return SimpleGlyph (*header, bytes).trim_padding (); + case EMPTY: return bytes; default: return bytes; } } @@ -55,27 +70,36 @@ struct Glyph void drop_hints () { switch (type) { +#ifndef HB_NO_VAR_COMPOSITES + case VAR_COMPOSITE: return; // No hinting +#endif case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints (); return; case SIMPLE: SimpleGlyph (*header, bytes).drop_hints (); return; - default: return; + case EMPTY: return; } } void set_overlaps_flag () { switch (type) { +#ifndef HB_NO_VAR_COMPOSITES + case VAR_COMPOSITE: return; // No overlaps flag +#endif case COMPOSITE: CompositeGlyph (*header, bytes).set_overlaps_flag (); return; case SIMPLE: SimpleGlyph (*header, bytes).set_overlaps_flag (); return; - default: return; + case EMPTY: return; } } void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const { switch (type) { +#ifndef HB_NO_VAR_COMPOSITES + case VAR_COMPOSITE: return; // No hinting +#endif case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints_bytes (dest_start); return; case SIMPLE: SimpleGlyph (*header, bytes).drop_hints_bytes (dest_start, dest_end); return; - default: return; + case EMPTY: return; } } @@ -181,7 +205,7 @@ struct Glyph hb_bytes_t &dest_start, /* IN/OUT */ hb_bytes_t &dest_end /* OUT */) { - contour_point_vector_t all_points, deltas; + contour_point_vector_t all_points, points_with_deltas; unsigned composite_contours = 0; head_maxp_info_t *head_maxp_info_p = &plan->head_maxp_info; unsigned *composite_contours_p = &composite_contours; @@ -195,7 +219,7 @@ struct Glyph composite_contours_p = nullptr; } - if (!get_points (font, glyf, all_points, &deltas, head_maxp_info_p, composite_contours_p, false, false)) + if (!get_points (font, glyf, all_points, &points_with_deltas, head_maxp_info_p, composite_contours_p, false, false)) return false; // .notdef, set type to empty so we only update metrics and don't compile bytes for @@ -209,11 +233,20 @@ struct Glyph } //dont compile bytes when pinned at default, just recalculate bounds - if (!plan->pinned_at_default) { - switch (type) { + if (!plan->pinned_at_default) + { + switch (type) + { +#ifndef HB_NO_VAR_COMPOSITES + case VAR_COMPOSITE: + // TODO + dest_end = hb_bytes_t (); + break; +#endif + case COMPOSITE: if (!CompositeGlyph (*header, bytes).compile_bytes_with_deltas (dest_start, - deltas, + points_with_deltas, dest_end)) return false; break; @@ -223,7 +256,7 @@ struct Glyph dest_end)) return false; break; - default: + case EMPTY: /* set empty bytes for empty glyph * do not use source glyph's pointers */ dest_start = hb_bytes_t (); @@ -247,7 +280,7 @@ struct Glyph template bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator, contour_point_vector_t &all_points /* OUT */, - contour_point_vector_t *deltas = nullptr, /* OUT */ + contour_point_vector_t *points_with_deltas = nullptr, /* OUT */ head_maxp_info_t * head_maxp_info = nullptr, /* OUT */ unsigned *composite_contours = nullptr, /* OUT */ bool shift_points_hori = true, @@ -287,9 +320,8 @@ struct Glyph break; case COMPOSITE: { - /* pseudo component points for each component in composite glyph */ - unsigned num_points = hb_len (CompositeGlyph (*header, bytes).iter ()); - if (unlikely (!points.resize (num_points))) return false; + for (auto &item : get_composite_iterator ()) + if (unlikely (!item.get_points (points))) return false; break; } #ifndef HB_NO_VAR_COMPOSITES @@ -299,7 +331,7 @@ struct Glyph if (unlikely (!item.get_points (points))) return false; } #endif - default: + case EMPTY: break; } @@ -327,17 +359,11 @@ struct Glyph #endif ; phantoms[PHANTOM_LEFT].x = h_delta; - phantoms[PHANTOM_RIGHT].x = h_adv + h_delta; + phantoms[PHANTOM_RIGHT].x = (int) h_adv + h_delta; phantoms[PHANTOM_TOP].y = v_orig; phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv; } - if (deltas != nullptr && depth == 0 && type == COMPOSITE) - { - if (unlikely (!deltas->resize (points.length))) return false; - deltas->copy_vector (points); - } - #ifndef HB_NO_VAR glyf_accelerator.gvar->apply_deltas_to_points (gid, coords, @@ -346,13 +372,10 @@ struct Glyph // mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it // with child glyphs' points - if (deltas != nullptr && depth == 0 && type == COMPOSITE) + if (points_with_deltas != nullptr && depth == 0 && type == COMPOSITE) { - for (unsigned i = 0 ; i < points.length; i++) - { - deltas->arrayZ[i].x = points.arrayZ[i].x - deltas->arrayZ[i].x; - deltas->arrayZ[i].y = points.arrayZ[i].y - deltas->arrayZ[i].y; - } + if (unlikely (!points_with_deltas->resize (points.length))) return false; + points_with_deltas->copy_vector (points); } switch (type) { @@ -373,7 +396,7 @@ struct Glyph .get_points (font, glyf_accelerator, comp_points, - deltas, + points_with_deltas, head_maxp_info, composite_contours, shift_points_hori, @@ -389,11 +412,12 @@ struct Glyph for (unsigned int i = 0; i < PHANTOM_COUNT; i++) phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i]; - /* Apply component transformation & translation */ - item.transform_points (comp_points); + float matrix[4]; + contour_point_t default_trans; + item.get_transformation (matrix, default_trans); - /* Apply translation from gvar */ - comp_points.translate (points[comp_index]); + /* Apply component transformation & translation (with deltas applied) */ + item.transform_points (comp_points, matrix, points[comp_index]); if (item.is_anchored ()) { @@ -433,7 +457,8 @@ struct Glyph hb_array_t points_left = points.as_array (); for (auto &item : get_var_composite_iterator ()) { - hb_array_t record_points = points_left.sub_array (0, item.get_num_points ()); + unsigned item_num_points = item.get_num_points (); + hb_array_t record_points = points_left.sub_array (0, item_num_points); comp_points.reset (); @@ -448,7 +473,7 @@ struct Glyph .get_points (font, glyf_accelerator, comp_points, - deltas, + points_with_deltas, head_maxp_info, nullptr, shift_points_hori, @@ -472,12 +497,12 @@ struct Glyph if (all_points.length > HB_GLYF_MAX_POINTS) return false; - points_left += item.get_num_points (); + points_left += item_num_points; } all_points.extend (phantoms); } break; #endif - default: + case EMPTY: all_points.extend (phantoms); break; } @@ -503,6 +528,8 @@ struct Glyph } hb_bytes_t get_bytes () const { return bytes; } + glyph_type_t get_type () const { return type; } + const GlyphHeader *get_header () const { return header; } Glyph () : bytes (), header (bytes.as ()), @@ -518,7 +545,9 @@ struct Glyph int num_contours = header->numberOfContours; if (unlikely (num_contours == 0)) type = EMPTY; else if (num_contours > 0) type = SIMPLE; +#ifndef HB_NO_VAR_COMPOSITES else if (num_contours == -2) type = VAR_COMPOSITE; +#endif else type = COMPOSITE; /* negative numbers */ } @@ -526,7 +555,7 @@ struct Glyph hb_bytes_t bytes; const GlyphHeader *header; hb_codepoint_t gid; - unsigned type; + glyph_type_t type; }; diff --git a/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh b/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh index b6fefce1ac..b6679b2dae 100644 --- a/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh +++ b/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh @@ -34,6 +34,11 @@ struct SimpleGlyph unsigned int length (unsigned int instruction_len) const { return instruction_len_offset () + 2 + instruction_len; } + bool has_instructions_length () const + { + return instruction_len_offset () + 2 <= bytes.length; + } + unsigned int instructions_length () const { unsigned int instruction_length_offset = instruction_len_offset (); @@ -94,6 +99,7 @@ struct SimpleGlyph /* zero instruction length */ void drop_hints () { + if (!has_instructions_length ()) return; GlyphHeader &glyph_header = const_cast (header); (HBUINT16 &) StructAtOffset (&glyph_header, instruction_len_offset ()) = 0; } diff --git a/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SubsetGlyph.hh b/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SubsetGlyph.hh index 795925bba5..26dc374eab 100644 --- a/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SubsetGlyph.hh +++ b/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SubsetGlyph.hh @@ -18,6 +18,7 @@ struct SubsetGlyph Glyph source_glyph; hb_bytes_t dest_start; /* region of source_glyph to copy first */ hb_bytes_t dest_end; /* region of source_glyph to copy second */ + bool allocated; bool serialize (hb_serialize_context_t *c, bool use_short_loca, @@ -26,7 +27,12 @@ struct SubsetGlyph TRACE_SERIALIZE (this); hb_bytes_t dest_glyph = dest_start.copy (c); - dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length); + hb_bytes_t end_copy = dest_end.copy (c); + if (!end_copy.arrayZ || !dest_glyph.arrayZ) { + return false; + } + + dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + end_copy.length); unsigned int pad_length = use_short_loca ? padding () : 0; DEBUG_MSG (SUBSET, nullptr, "serialize %u byte glyph, width %u pad %u", dest_glyph.length, dest_glyph.length + pad_length, pad_length); @@ -40,13 +46,68 @@ struct SubsetGlyph if (unlikely (!dest_glyph.length)) return_trace (true); - /* update components gids */ + /* update components gids. */ for (auto &_ : Glyph (dest_glyph).get_composite_iterator ()) { hb_codepoint_t new_gid; if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid)) const_cast (_).set_gid (new_gid); } +#ifndef HB_NO_VAR_COMPOSITES + for (auto &_ : Glyph (dest_glyph).get_var_composite_iterator ()) + { + hb_codepoint_t new_gid; + if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid)) + const_cast (_).set_gid (new_gid); + } +#endif + +#ifndef HB_NO_BEYOND_64K + auto it = Glyph (dest_glyph).get_composite_iterator (); + if (it) + { + /* lower GID24 to GID16 in components if possible. + * + * TODO: VarComposite. Not as critical, since VarComposite supports + * gid24 from the first version. */ + char *p = it ? (char *) &*it : nullptr; + char *q = p; + const char *end = dest_glyph.arrayZ + dest_glyph.length; + while (it) + { + auto &rec = const_cast (*it); + ++it; + + q += rec.get_size (); + + rec.lower_gid_24_to_16 (); + + unsigned size = rec.get_size (); + + memmove (p, &rec, size); + + p += size; + } + memmove (p, q, end - q); + p += end - q; + + /* We want to shorten the glyph, but we can't do that without + * updating the length in the loca table, which is already + * written out :-(. So we just fill the rest of the glyph with + * harmless instructions, since that's what they will be + * interpreted as. + * + * Should move the lowering to _populate_subset_glyphs() to + * fix this issue. */ + + hb_memset (p, 0x7A /* TrueType instruction ROFF; harmless */, end - p); + p += end - p; + dest_glyph = hb_bytes_t (dest_glyph.arrayZ, p - (char *) dest_glyph.arrayZ); + + // TODO: Padding; & trim serialized bytes. + // TODO: Update length in loca. Ugh. + } +#endif if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) Glyph (dest_glyph).drop_hints (); @@ -60,12 +121,18 @@ struct SubsetGlyph bool compile_bytes_with_deltas (const hb_subset_plan_t *plan, hb_font_t *font, const glyf_accelerator_t &glyf) - { return source_glyph.compile_bytes_with_deltas (plan, font, glyf, dest_start, dest_end); } + { + allocated = source_glyph.compile_bytes_with_deltas (plan, font, glyf, dest_start, dest_end); + return allocated; + } void free_compiled_bytes () { - dest_start.fini (); - dest_end.fini (); + if (likely (allocated)) { + allocated = false; + dest_start.fini (); + dest_end.fini (); + } } void drop_hints_bytes () diff --git a/libs/harfbuzz/harfbuzz-src/src/OT/glyf/VarCompositeGlyph.hh b/libs/harfbuzz/harfbuzz-src/src/OT/glyf/VarCompositeGlyph.hh index 3685da7913..309ec473aa 100644 --- a/libs/harfbuzz/harfbuzz-src/src/OT/glyf/VarCompositeGlyph.hh +++ b/libs/harfbuzz/harfbuzz-src/src/OT/glyf/VarCompositeGlyph.hh @@ -27,7 +27,7 @@ struct VarCompositeGlyphRecord HAVE_SKEW_Y = 0x0200, HAVE_TCENTER_X = 0x0400, HAVE_TCENTER_Y = 0x0800, - GID_IS_24 = 0x1000, + GID_IS_24BIT = 0x1000, AXES_HAVE_VARIATION = 0x2000, RESET_UNSPECIFIED_AXES = 0x4000, }; @@ -43,7 +43,7 @@ struct VarCompositeGlyphRecord // gid size += 2; - if (flags & GID_IS_24) size += 1; + if (flags & GID_IS_24BIT) size += 1; if (flags & HAVE_TRANSLATE_X) size += 2; if (flags & HAVE_TRANSLATE_Y) size += 2; @@ -65,12 +65,20 @@ struct VarCompositeGlyphRecord hb_codepoint_t get_gid () const { - if (flags & GID_IS_24) + if (flags & GID_IS_24BIT) return StructAfter (numAxes); else return StructAfter (numAxes); } + void set_gid (hb_codepoint_t gid) + { + if (flags & GID_IS_24BIT) + StructAfter (numAxes) = gid; + else + StructAfter (numAxes) = gid; + } + unsigned get_numAxes () const { return numAxes; @@ -145,7 +153,7 @@ struct VarCompositeGlyphRecord float rotation) { // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240 - rotation = rotation * float (M_PI); + rotation = rotation * HB_PI; float c = cosf (rotation); float s = sinf (rotation); float other[6] = {c, s, -s, c, 0.f, 0.f}; @@ -156,8 +164,8 @@ struct VarCompositeGlyphRecord float skewX, float skewY) { // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255 - skewX = skewX * float (M_PI); - skewY = skewY * float (M_PI); + skewX = skewX * HB_PI; + skewY = skewY * HB_PI; float other[6] = {1.f, tanf (skewY), tanf (skewX), 1.f, 0.f, 0.f}; transform (matrix, trans, other); } @@ -174,16 +182,18 @@ struct VarCompositeGlyphRecord float tCenterX = 0.f; float tCenterY = 0.f; - if (unlikely (!points.resize (points.length + get_num_points ()))) return false; + unsigned num_points = get_num_points (); + + if (unlikely (!points.resize (points.length + num_points))) return false; unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1; unsigned axes_size = numAxes * axis_width; const F2DOT14 *q = (const F2DOT14 *) (axes_size + - (flags & GID_IS_24 ? 3 : 2) + + (flags & GID_IS_24BIT ? 3 : 2) + &StructAfter (numAxes)); - hb_array_t rec_points = points.as_array ().sub_array (points.length - get_num_points ()); + hb_array_t rec_points = points.as_array ().sub_array (points.length - num_points); unsigned count = numAxes; if (flags & AXES_HAVE_VARIATION) @@ -308,8 +318,8 @@ struct VarCompositeGlyphRecord bool have_variations = flags & AXES_HAVE_VARIATION; unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1; - const HBUINT8 *p = (const HBUINT8 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24 ? 3 : 2)); - const HBUINT16 *q = (const HBUINT16 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24 ? 3 : 2)); + const HBUINT8 *p = (const HBUINT8 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24BIT ? 3 : 2)); + const HBUINT16 *q = (const HBUINT16 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24BIT ? 3 : 2)); const F2DOT14 *a = (const F2DOT14 *) ((HBUINT8 *) (axis_width == 1 ? (p + numAxes) : (HBUINT8 *) (q + numAxes))); @@ -344,6 +354,13 @@ struct VarCompositeGlyph var_composite_iter_t iter () const { return var_composite_iter_t (bytes, &StructAfter (header)); } + const hb_bytes_t trim_padding () const + { + unsigned length = GlyphHeader::static_size; + for (auto &comp : iter ()) + length += comp.get_size (); + return bytes.sub_array (0, length); + } }; diff --git a/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh b/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh index 29328c7627..dd08dda6ee 100644 --- a/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh +++ b/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh @@ -31,6 +31,12 @@ struct glyf static constexpr hb_tag_t tableTag = HB_OT_TAG_glyf; + static bool has_valid_glyf_format(const hb_face_t* face) + { + const OT::head &head = *face->table.head; + return head.indexToLocFormat <= 1 && head.glyphDataFormat <= 1; + } + bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const { TRACE_SANITIZE (this); @@ -72,6 +78,13 @@ struct glyf { TRACE_SUBSET (this); + if (!has_valid_glyf_format (c->plan->source)) { + // glyf format is unknown don't attempt to subset it. + DEBUG_MSG (SUBSET, nullptr, + "unkown glyf format, dropping from subset."); + return_trace (false); + } + glyf *glyf_prime = c->serializer->start_embed (); if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false); @@ -85,11 +98,17 @@ struct glyf hb_vector_t padded_offsets; unsigned num_glyphs = c->plan->num_output_glyphs (); if (unlikely (!padded_offsets.resize (num_glyphs))) + { + hb_font_destroy (font); return false; + } hb_vector_t glyphs; if (!_populate_subset_glyphs (c->plan, font, glyphs)) + { + hb_font_destroy (font); return false; + } if (font) hb_font_destroy (font); @@ -112,7 +131,7 @@ struct glyf bool result = glyf_prime->serialize (c->serializer, glyphs.writer (), use_short_loca, c->plan); if (c->plan->normalized_coords && !c->plan->pinned_at_default) - _free_compiled_subset_glyphs (glyphs, glyphs.length - 1); + _free_compiled_subset_glyphs (glyphs); if (!result) return false; @@ -131,9 +150,9 @@ struct glyf hb_font_t * _create_font_for_instancing (const hb_subset_plan_t *plan) const; - void _free_compiled_subset_glyphs (hb_vector_t &glyphs, unsigned index) const + void _free_compiled_subset_glyphs (hb_vector_t &glyphs) const { - for (unsigned i = 0; i <= index && i < glyphs.length; i++) + for (unsigned i = 0; i < glyphs.length; i++) glyphs[i].free_compiled_bytes (); } @@ -162,7 +181,7 @@ struct glyf_accelerator_t vmtx = nullptr; #endif const OT::head &head = *face->table.head; - if (head.indexToLocFormat > 1 || head.glyphDataFormat > 0) + if (!glyf::has_valid_glyf_format (face)) /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */ return; short_offset = 0 == head.indexToLocFormat; @@ -222,6 +241,8 @@ struct glyf_accelerator_t return true; } + public: + #ifndef HB_NO_VAR struct points_aggregator_t { @@ -285,7 +306,6 @@ struct glyf_accelerator_t contour_point_t *get_phantoms_sink () { return phantoms; } }; - public: unsigned get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const { @@ -327,6 +347,15 @@ struct glyf_accelerator_t } #endif + bool get_leading_bearing_without_var_unscaled (hb_codepoint_t gid, bool is_vertical, int *lsb) const + { + if (unlikely (gid >= num_glyphs)) return false; + if (is_vertical) return false; // TODO Humm, what to do here? + + *lsb = glyph_for_gid (gid).get_header ()->xMin; + return true; + } + public: bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const { @@ -405,7 +434,6 @@ glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan, unsigned num_glyphs = plan->num_output_glyphs (); if (!glyphs.resize (num_glyphs)) return false; - unsigned idx = 0; for (auto p : plan->glyph_map->iter ()) { unsigned new_gid = p.second; @@ -433,11 +461,10 @@ glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan, if (unlikely (!subset_glyph.compile_bytes_with_deltas (plan, font, glyf))) { // when pinned at default, only bounds are updated, thus no need to free - if (!plan->pinned_at_default && idx > 0) - _free_compiled_subset_glyphs (glyphs, idx - 1); + if (!plan->pinned_at_default) + _free_compiled_subset_glyphs (glyphs); return false; } - idx++; } } return true; @@ -451,7 +478,10 @@ glyf::_create_font_for_instancing (const hb_subset_plan_t *plan) const hb_vector_t vars; if (unlikely (!vars.alloc (plan->user_axes_location.get_population (), true))) + { + hb_font_destroy (font); return nullptr; + } for (auto _ : plan->user_axes_location) { diff --git a/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in b/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in index 0de082c2a6..ced97919a2 100644 --- a/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in +++ b/libs/harfbuzz/harfbuzz-src/src/harfbuzz-config.cmake.in @@ -12,13 +12,17 @@ list(GET _harfbuzz_version_info 2 _harfbuzz_age) unset(_harfbuzz_version_info) -if (APPLE) - set(_harfbuzz_lib_suffix ".0${CMAKE_SHARED_LIBRARY_SUFFIX}") -elseif (UNIX) - set(_harfbuzz_lib_suffix "${CMAKE_SHARED_LIBRARY_SUFFIX}.0.${_harfbuzz_current}.${_harfbuzz_revision}") +if ("@default_library@" MATCHES "static") + set(_harfbuzz_lib_suffix ".a") else () - # Unsupported. - set(harfbuzz_FOUND 0) + if (APPLE) + set(_harfbuzz_lib_suffix ".0${CMAKE_SHARED_LIBRARY_SUFFIX}") + elseif (UNIX) + set(_harfbuzz_lib_suffix "${CMAKE_SHARED_LIBRARY_SUFFIX}.0.${_harfbuzz_current}.${_harfbuzz_revision}") + else () + # Unsupported. + set(harfbuzz_FOUND 0) + endif () endif () # Add the libraries. diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh b/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh index efbb623efc..7d53c354da 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh @@ -464,7 +464,8 @@ enum { DELETED_GLYPH = 0xFFFF }; template struct Entry { - bool sanitize (hb_sanitize_context_t *c, unsigned int count) const + // This does seem like it's ever called. + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); /* Note, we don't recurse-sanitize data because we don't access it. @@ -492,7 +493,8 @@ struct Entry template <> struct Entry { - bool sanitize (hb_sanitize_context_t *c, unsigned int count /*XXX Unused?*/) const + // This does seem like it's ever called. + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this)); diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh b/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh index 8e8c988716..9edefd9710 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-bimap.hh @@ -83,9 +83,15 @@ struct hb_bimap_t unsigned int get_population () const { return forw_map.get_population (); } + protected: hb_map_t forw_map; hb_map_t back_map; + + public: + auto keys () const HB_AUTO_RETURN (+ forw_map.keys()) + auto values () const HB_AUTO_RETURN (+ forw_map.values()) + auto iter () const HB_AUTO_RETURN (+ forw_map.iter()) }; /* Inremental bimap: only lhs is given, rhs is incrementally assigned */ @@ -108,6 +114,9 @@ struct hb_inc_bimap_t : hb_bimap_t hb_codepoint_t skip () { return next_value++; } + hb_codepoint_t skip (unsigned count) + { return next_value += count; } + hb_codepoint_t get_next_value () const { return next_value; } diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh b/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh index 475b07b810..c30b2af7b0 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh @@ -194,7 +194,7 @@ struct hb_bit_set_t unsigned int end = major_start (m + 1); do { - if (v || page) /* The v check is to optimize out the page check if v is true. */ + if (g != INVALID && (v || page)) /* The v check is to optimize out the page check if v is true. */ page->set (g, v); array = &StructAtOffsetUnaligned (array, stride); @@ -238,7 +238,7 @@ struct hb_bit_set_t if (g < last_g) return false; last_g = g; - if (v || page) /* The v check is to optimize out the page check if v is true. */ + if (g != INVALID && (v || page)) /* The v check is to optimize out the page check if v is true. */ page->add (g); array = &StructAtOffsetUnaligned (array, stride); diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc b/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc index f557ceee56..616cee807f 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc +++ b/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc @@ -40,6 +40,11 @@ * Buffers serve a dual role in HarfBuzz; before shaping, they hold * the input characters that are passed to hb_shape(), and after * shaping they hold the output glyphs. + * + * The input buffer is a sequence of Unicode codepoints, with + * associated attributes such as direction and script. The output + * buffer is a sequence of glyphs, with associated attributes such + * as position and cluster. **/ diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh b/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh index 2e98187b50..8371465c6c 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh @@ -30,7 +30,19 @@ #include "hb.hh" -/* Implements a lockfree cache for int->int functions. */ +/* Implements a lockfree cache for int->int functions. + * + * The cache is a fixed-size array of 16-bit or 32-bit integers. + * The key is split into two parts: the cache index and the rest. + * + * The cache index is used to index into the array. The rest is used + * to store the key and the value. + * + * The value is stored in the least significant bits of the integer. + * The key is stored in the most significant bits of the integer. + * The key is shifted by cache_bits to the left to make room for the + * value. + */ template -#define PREALLOCATED_COLOR_STOPS 16 +/* Some routines in this file were ported from BlackRenderer by Black Foundry. + * Used by permission to relicense to HarfBuzz license. + * + * https://github.com/BlackFoundryCom/black-renderer + */ -#define _2_M_PIf (2.f * float (M_PI)) +#define PREALLOCATED_COLOR_STOPS 16 typedef struct { float r, g, b, a; @@ -518,7 +523,7 @@ _hb_cairo_add_patch (cairo_pattern_t *pattern, hb_cairo_point_t *center, hb_cair cairo_mesh_pattern_end_patch (pattern); } -#define MAX_ANGLE ((float) M_PI / 8.f) +#define MAX_ANGLE (HB_PI / 8.f) static void _hb_cairo_add_sweep_gradient_patches1 (float cx, float cy, float radius, @@ -601,7 +606,7 @@ _hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops, start_angle, &c, pattern); } - if (end_angle < _2_M_PIf) + if (end_angle < HB_2_PI) { c.r = hb_color_get_red (stops[n_stops - 1].color) / 255.; c.g = hb_color_get_green (stops[n_stops - 1].color) / 255.; @@ -609,7 +614,7 @@ _hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops, c.a = hb_color_get_alpha (stops[n_stops - 1].color) / 255.; _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius, end_angle, &c, - _2_M_PIf, &c, + HB_2_PI, &c, pattern); } } @@ -673,7 +678,7 @@ _hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops, color0 = colors[n_stops-1]; _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius, 0., &color0, - _2_M_PIf, &color0, + HB_2_PI, &color0, pattern); goto done; } @@ -685,7 +690,7 @@ _hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops, for (pos++; pos < n_stops; pos++) { - if (angles[pos] <= _2_M_PIf) + if (angles[pos] <= HB_2_PI) { _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius, angles[pos - 1], &colors[pos-1], @@ -694,11 +699,11 @@ _hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops, } else { - float k = (_2_M_PIf - angles[pos - 1]) / (angles[pos] - angles[pos - 1]); + float k = (HB_2_PI - angles[pos - 1]) / (angles[pos] - angles[pos - 1]); _hb_cairo_interpolate_colors (&colors[pos - 1], &colors[pos], k, &color1); _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius, angles[pos - 1], &colors[pos - 1], - _2_M_PIf, &color1, + HB_2_PI, &color1, pattern); break; } @@ -710,7 +715,7 @@ _hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops, color0 = colors[n_stops - 1]; _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius, angles[n_stops - 1], &color0, - _2_M_PIf, &color0, + HB_2_PI, &color0, pattern); goto done; } @@ -794,14 +799,14 @@ _hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops, a1, c1, pattern); } - else if (a1 >= _2_M_PIf) + else if (a1 >= HB_2_PI) { hb_cairo_color_t color; - float f = (_2_M_PIf - a0)/(a1 - a0); + float f = (HB_2_PI - a0)/(a1 - a0); _hb_cairo_interpolate_colors (c0, c1, f, &color); _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius, a0, c0, - _2_M_PIf, &color, + HB_2_PI, &color, pattern); goto done; } diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-common.cc b/libs/harfbuzz/harfbuzz-src/src/hb-common.cc index c9a40295a3..282a8e4d0f 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-common.cc +++ b/libs/harfbuzz/harfbuzz-src/src/hb-common.cc @@ -632,6 +632,7 @@ hb_script_get_horizontal_direction (hb_script_t script) case HB_SCRIPT_OLD_HUNGARIAN: case HB_SCRIPT_OLD_ITALIC: case HB_SCRIPT_RUNIC: + case HB_SCRIPT_TIFINAGH: return HB_DIRECTION_INVALID; } diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h b/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h index edacfd064c..b032a941b2 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h +++ b/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h @@ -108,6 +108,16 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_func_t func, void *user_data, hb_destroy_func_t destroy); +/* https://github.com/harfbuzz/harfbuzz/pull/4207 */ +/** + * HB_UNICODE_COMBINING_CLASS_CCC133: + * + * [Tibetan] + * + * Deprecated: 7.2.0 + **/ +#define HB_UNICODE_COMBINING_CLASS_CCC133 133 + /** * hb_unicode_eastasian_width_func_t: * @ufuncs: A Unicode-functions structure @@ -247,6 +257,7 @@ hb_font_get_glyph_v_kerning (hb_font_t *font, #endif + HB_END_DECLS #endif /* HB_DEPRECATED_H */ diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-face.cc b/libs/harfbuzz/harfbuzz-src/src/hb-face.cc index 5fcc4e93d9..e340710586 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-face.cc +++ b/libs/harfbuzz/harfbuzz-src/src/hb-face.cc @@ -47,6 +47,12 @@ * More precisely, a font face represents a single face in a binary font file. * Font faces are typically built from a binary blob and a face index. * Font faces are used to create fonts. + * + * A font face can be created from a binary blob using hb_face_create(). + * The face index is used to select a face from a binary blob that contains + * multiple faces. For example, a binary blob that contains both a regular + * and a bold face can be used to create two font faces, one for each face + * index. **/ @@ -197,7 +203,7 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void * a face index into that blob. * * The face index is used for blobs of file formats such as TTC and - * and DFont that can contain more than one face. Face indices within + * DFont that can contain more than one face. Face indices within * such collections are zero-based. * * Note: If the blob font format is not a collection, @index diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-face.hh b/libs/harfbuzz/harfbuzz-src/src/hb-face.hh index 1bf0606e52..aff3ff0d07 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-face.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-face.hh @@ -76,7 +76,7 @@ struct hb_face_t if (unlikely (!reference_table_func)) return hb_blob_get_empty (); - blob = reference_table_func (/*XXX*/const_cast (this), tag, user_data); + blob = reference_table_func (/*Oh, well.*/const_cast (this), tag, user_data); if (unlikely (!blob)) return hb_blob_get_empty (); diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-font.cc b/libs/harfbuzz/harfbuzz-src/src/hb-font.cc index 1b345a9447..688513112a 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-font.cc +++ b/libs/harfbuzz/harfbuzz-src/src/hb-font.cc @@ -59,6 +59,11 @@ * * HarfBuzz provides a built-in set of lightweight default * functions for each method in #hb_font_funcs_t. + * + * The default font functions are implemented in terms of the + * #hb_font_funcs_t methods of the parent font object. This allows + * client programs to override only the methods they need to, and + * otherwise inherit the parent font's implementation, if any. **/ @@ -1387,7 +1392,7 @@ hb_font_get_glyph_from_name (hb_font_t *font, /** * hb_font_get_glyph_shape: * @font: #hb_font_t to work upon - * @glyph: : The glyph ID + * @glyph: The glyph ID * @dfuncs: #hb_draw_funcs_t to draw to * @draw_data: User data to pass to draw callbacks * @@ -1409,7 +1414,7 @@ hb_font_get_glyph_shape (hb_font_t *font, /** * hb_font_draw_glyph: * @font: #hb_font_t to work upon - * @glyph: : The glyph ID + * @glyph: The glyph ID * @dfuncs: #hb_draw_funcs_t to draw to * @draw_data: User data to pass to draw callbacks * diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh b/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh index b3457933c0..fa5712f9b3 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh @@ -301,8 +301,8 @@ _hb_ft_paint (hb_ft_paint_context_t *c, c->funcs->sweep_gradient (c->data, &cl, paint.u.sweep_gradient.center.x / 65536.f, paint.u.sweep_gradient.center.y / 65536.f, - (paint.u.sweep_gradient.start_angle / 65536.f + 1) * (float) M_PI, - (paint.u.sweep_gradient.end_angle / 65536.f + 1) * (float) M_PI); + (paint.u.sweep_gradient.start_angle / 65536.f + 1) * HB_PI, + (paint.u.sweep_gradient.end_angle / 65536.f + 1) * HB_PI); } break; case FT_COLR_PAINTFORMAT_GLYPH: diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-map.hh b/libs/harfbuzz/harfbuzz-src/src/hb-map.hh index 552b406651..041b8829af 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-map.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-map.hh @@ -343,7 +343,8 @@ struct hb_hashmap_t ) auto keys () const HB_AUTO_RETURN ( - + keys_ref () + + iter_items () + | hb_map (&item_t::key) | hb_map (hb_ridentity) ) auto values_ref () const HB_AUTO_RETURN @@ -353,7 +354,8 @@ struct hb_hashmap_t ) auto values () const HB_AUTO_RETURN ( - + values_ref () + + iter_items () + | hb_map (&item_t::value) | hb_map (hb_ridentity) ) diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh b/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh index f5a03d2b00..cf5ccd53e9 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh @@ -404,7 +404,7 @@ struct CmapSubtableFormat4 unsigned distance) const { if (k > last) return +1; - if (k < (&last)[distance]) return -1; + if (k < (&last)[distance]/*first*/) return -1; return 0; } HBUINT16 last; @@ -413,7 +413,7 @@ struct CmapSubtableFormat4 const HBUINT16 *found = hb_bsearch (codepoint, this->endCount, this->segCount, - 2, + sizeof (CustomRange), _hb_cmp_method, this->segCount + 1); if (unlikely (!found)) diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc b/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc index 19ae02e28b..06f7092a59 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc +++ b/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc @@ -413,7 +413,7 @@ hb_ot_get_glyph_extents (hb_font_t *font, if (ot_face->sbix->get_extents (font, glyph, extents)) return true; if (ot_face->CBDT->get_extents (font, glyph, extents)) return true; #endif -#if !defined(HB_NO_COLOR) +#if !defined(HB_NO_COLOR) && !defined(HB_NO_PAINT) if (ot_face->COLR->get_extents (font, glyph, extents)) return true; #endif if (ot_face->glyf->get_extents (font, glyph, extents)) return true; @@ -633,20 +633,4 @@ hb_ot_font_set_funcs (hb_font_t *font) _hb_ot_font_destroy); } -#ifndef HB_NO_VAR -bool -_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical, - int *lsb) -{ - return font->face->table.glyf->get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb); -} - -unsigned -_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical) -{ - return font->face->table.glyf->get_advance_with_var_unscaled (font, glyph, is_vertical); -} -#endif - - #endif diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh b/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh index a86cc3c311..3bfd75502a 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh @@ -76,7 +76,7 @@ struct DeviceRecord HBUINT8 maxWidth; /* Maximum width. */ UnsizedArrayOf widthsZ; /* Array of widths (numGlyphs is from the 'maxp' table). */ public: - DEFINE_SIZE_ARRAY (2, widthsZ); + DEFINE_SIZE_UNBOUNDED (2); }; @@ -87,14 +87,6 @@ struct hdmx unsigned int get_size () const { return min_size + numRecords * sizeDeviceRecord; } - const DeviceRecord& operator [] (unsigned int i) const - { - /* XXX Null(DeviceRecord) is NOT safe as it's num-glyphs lengthed. - * https://github.com/harfbuzz/harfbuzz/issues/1300 */ - if (unlikely (i >= numRecords)) return Null (DeviceRecord); - return StructAtOffset (&this->firstDeviceRecord, i * sizeDeviceRecord); - } - template bool serialize (hb_serialize_context_t *c, unsigned version, Iterator it) diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh b/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh index 798e82da6c..770cf52d17 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh @@ -63,7 +63,25 @@ struct head bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - return_trace (serialize (c->serializer)); + head *out = c->serializer->embed (this); + if (unlikely (!out)) return_trace (false); + + if (c->plan->normalized_coords) + { + if (unlikely (!c->serializer->check_assign (out->xMin, c->plan->head_maxp_info.xMin, + HB_SERIALIZE_ERROR_INT_OVERFLOW))) + return_trace (false); + if (unlikely (!c->serializer->check_assign (out->xMax, c->plan->head_maxp_info.xMax, + HB_SERIALIZE_ERROR_INT_OVERFLOW))) + return_trace (false); + if (unlikely (!c->serializer->check_assign (out->yMin, c->plan->head_maxp_info.yMin, + HB_SERIALIZE_ERROR_INT_OVERFLOW))) + return_trace (false); + if (unlikely (!c->serializer->check_assign (out->yMax, c->plan->head_maxp_info.yMax, + HB_SERIALIZE_ERROR_INT_OVERFLOW))) + return_trace (false); + } + return_trace (true); } enum mac_style_flag_t { diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh b/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh index 16eb1eb912..835a1a585e 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh @@ -50,6 +50,9 @@ _glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t gly HB_INTERNAL unsigned _glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical); +HB_INTERNAL bool +_glyf_get_leading_bearing_without_var_unscaled (hb_face_t *face, hb_codepoint_t gid, bool is_vertical, int *lsb); + namespace OT { @@ -92,7 +95,7 @@ struct hmtxvmtx unsigned int length; H *table = (H *) hb_blob_get_data (dest_blob, &length); - table->numberOfLongMetrics = num_hmetrics; + c->serializer->check_assign (table->numberOfLongMetrics, num_hmetrics, HB_SERIALIZE_ERROR_INT_OVERFLOW); #ifndef HB_NO_VAR if (c->plan->normalized_coords) @@ -165,12 +168,19 @@ struct hmtxvmtx lm.sb = _.second; if (unlikely (!c->embed (&lm))) return; } - else + else if (idx < 0x10000u) { FWORD *sb = c->allocate_size (FWORD::static_size); if (unlikely (!sb)) return; *sb = _.second; } + else + { + // TODO: This does not do tail optimization. + UFWORD *adv = c->allocate_size (UFWORD::static_size); + if (unlikely (!adv)) return; + *adv = _.first; + } idx++; } } @@ -189,7 +199,7 @@ struct hmtxvmtx /* Determine num_long_metrics to encode. */ auto& plan = c->plan; - num_long_metrics = plan->num_output_glyphs (); + num_long_metrics = hb_min (plan->num_output_glyphs (), 0xFFFFu); unsigned int last_advance = get_new_gid_advance_unscaled (plan, mtx_map, num_long_metrics - 1, _mtx); while (num_long_metrics > 1 && last_advance == get_new_gid_advance_unscaled (plan, mtx_map, num_long_metrics - 2, _mtx)) @@ -208,7 +218,8 @@ struct hmtxvmtx if (!c->plan->old_gid_for_new_gid (_, &old_gid)) return hb_pair (0u, 0); int lsb = 0; - (void) _mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb); + if (!_mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb)) + (void) _glyf_get_leading_bearing_without_var_unscaled (c->plan->source, old_gid, !T::is_horizontal, &lsb); return hb_pair (_mtx.get_advance_without_var_unscaled (old_gid), +lsb); } return mtx_map->get (_); diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh b/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh index b53f2e9276..52b7dc254b 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh @@ -529,6 +529,9 @@ struct FeatureParamsSize return_trace (true); } + void collect_name_ids (hb_set_t *nameids_to_retain /* OUT */) const + { nameids_to_retain->add (subfamilyNameID); } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -585,6 +588,9 @@ struct FeatureParamsStylisticSet return_trace (c->check_struct (this)); } + void collect_name_ids (hb_set_t *nameids_to_retain /* OUT */) const + { nameids_to_retain->add (uiNameID); } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -632,6 +638,20 @@ struct FeatureParamsCharacterVariants unsigned get_size () const { return min_size + characters.len * HBUINT24::static_size; } + void collect_name_ids (hb_set_t *nameids_to_retain /* OUT */) const + { + if (featUILableNameID) nameids_to_retain->add (featUILableNameID); + if (featUITooltipTextNameID) nameids_to_retain->add (featUITooltipTextNameID); + if (sampleTextNameID) nameids_to_retain->add (sampleTextNameID); + + if (!firstParamUILabelNameID || !numNamedParameters || numNamedParameters >= 0x7FFF) + return; + + unsigned last_name_id = (unsigned) firstParamUILabelNameID + (unsigned) numNamedParameters - 1; + if (last_name_id >= 256 && last_name_id <= 32767) + nameids_to_retain->add_range (firstParamUILabelNameID, last_name_id); + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -694,6 +714,19 @@ struct FeatureParams return_trace (true); } + void collect_name_ids (hb_tag_t tag, hb_set_t *nameids_to_retain /* OUT */) const + { +#ifdef HB_NO_LAYOUT_FEATURE_PARAMS + return; +#endif + if (tag == HB_TAG ('s','i','z','e')) + return (u.size.collect_name_ids (nameids_to_retain)); + if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */ + return (u.stylisticSet.collect_name_ids (nameids_to_retain)); + if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */ + return (u.characterVariants.collect_name_ids (nameids_to_retain)); + } + bool subset (hb_subset_context_t *c, const Tag* tag) const { TRACE_SUBSET (this); @@ -762,6 +795,12 @@ struct Feature bool intersects_lookup_indexes (const hb_map_t *lookup_indexes) const { return lookupIndex.intersects (lookup_indexes); } + void collect_name_ids (hb_tag_t tag, hb_set_t *nameids_to_retain /* OUT */) const + { + if (featureParams) + get_feature_params ().collect_name_ids (tag, nameids_to_retain); + } + bool subset (hb_subset_context_t *c, hb_subset_layout_context_t *l, const Tag *tag = nullptr) const @@ -2233,19 +2272,20 @@ struct VarRegionAxis { float evaluate (int coord) const { - int start = startCoord.to_int (), peak = peakCoord.to_int (), end = endCoord.to_int (); + int peak = peakCoord.to_int (); + if (peak == 0 || coord == peak) + return 1.f; + + int start = startCoord.to_int (), end = endCoord.to_int (); /* TODO Move these to sanitize(). */ if (unlikely (start > peak || peak > end)) - return 1.; + return 1.f; if (unlikely (start < 0 && end > 0 && peak != 0)) - return 1.; - - if (peak == 0 || coord == peak) - return 1.; + return 1.f; if (coord <= start || end <= coord) - return 0.; + return 0.f; /* Interpolate */ if (coord < peak) @@ -2462,10 +2502,9 @@ struct VarData { for (r = 0; r < src_word_count; r++) { - for (unsigned int i = 0; i < inner_map.get_next_value (); i++) + for (unsigned old_gid : inner_map.keys()) { - unsigned int old = inner_map.backward (i); - int32_t delta = src->get_item_delta_fast (old, r, src_delta_bytes, src_row_size); + int32_t delta = src->get_item_delta_fast (old_gid, r, src_delta_bytes, src_row_size); if (delta < -65536 || 65535 < delta) { has_long = true; @@ -2482,10 +2521,9 @@ struct VarData bool short_circuit = src_long_words == has_long && src_word_count <= r; delta_sz[r] = kZero; - for (unsigned int i = 0; i < inner_map.get_next_value (); i++) + for (unsigned old_gid : inner_map.keys()) { - unsigned int old = inner_map.backward (i); - int32_t delta = src->get_item_delta_fast (old, r, src_delta_bytes, src_row_size); + int32_t delta = src->get_item_delta_fast (old_gid, r, src_delta_bytes, src_row_size); if (delta < min_threshold || max_threshold < delta) { delta_sz[r] = kWord; @@ -2546,8 +2584,8 @@ struct VarData { unsigned int region = regionIndices.arrayZ[r]; if (region_indices.has (region)) continue; - for (unsigned int i = 0; i < inner_map.get_next_value (); i++) - if (get_item_delta_fast (inner_map.backward (i), r, delta_bytes, row_size) != 0) + for (hb_codepoint_t old_gid : inner_map.keys()) + if (get_item_delta_fast (old_gid, r, delta_bytes, row_size) != 0) { region_indices.add (region); break; diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh b/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh index 10cc105de4..e1b66a199a 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh @@ -487,7 +487,8 @@ struct hb_ot_apply_context_t : /* Ignore ZWJ if we are matching context, or asked to. */ matcher.set_ignore_zwj (context_match || c->auto_zwj); matcher.set_mask (context_match ? -1 : c->lookup_mask); - matcher.set_per_syllable (c->per_syllable); + /* Per syllable matching is only for GSUB. */ + matcher.set_per_syllable (c->table_index == 0 && c->per_syllable); } void set_lookup_props (unsigned int lookup_props) { @@ -4461,6 +4462,18 @@ struct GSUBGPOS } } + void collect_name_ids (const hb_map_t *feature_index_map, + hb_set_t *nameids_to_retain /* OUT */) const + { + unsigned count = get_feature_count (); + for (unsigned i = 0 ; i < count; i++) + { + if (!feature_index_map->has (i)) continue; + hb_tag_t tag = get_feature_tag (i); + get_feature (i).collect_name_ids (tag, nameids_to_retain); + } + } + template struct accelerator_t { diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc b/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc index 6c4055e046..256a055863 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc +++ b/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc @@ -64,6 +64,8 @@ using OT::Layout::GPOS; * @include: hb-ot.h * * Functions for querying OpenType Layout features in the font face. + * See the OpenType + * specification for details. **/ diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh b/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh index 05cbf2cedf..0f4cc414ef 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh @@ -100,7 +100,7 @@ struct maxp maxp *maxp_prime = c->serializer->embed (this); if (unlikely (!maxp_prime)) return_trace (false); - maxp_prime->numGlyphs = c->plan->num_output_glyphs (); + maxp_prime->numGlyphs = hb_min (c->plan->num_output_glyphs (), 0xFFFFu); if (maxp_prime->version.major == 1) { const maxpV1Tail *src_v1 = &StructAfter (*this); diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc b/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc index 0323364aef..6adf1e8fbe 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc +++ b/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc @@ -181,6 +181,4 @@ hb_ot_name_get_utf32 (hb_face_t *face, return hb_ot_name_get_utf (face, name_id, language, text_size, text); } -#include "hb-ot-name-language-static.hh" - #endif diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc b/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc index e3818cc37f..f8c970fc3e 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc +++ b/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc @@ -1067,12 +1067,15 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, base = i; while (base < end && is_halant (info[base])) base++; - info[base].indic_position() = POS_BASE_C; + if (base < end) + info[base].indic_position() = POS_BASE_C; try_pref = false; } break; } + if (base == end) + break; } /* For Malayalam, skip over unformed below- (but NOT post-) forms. */ if (buffer->props.script == HB_SCRIPT_MALAYALAM) diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh b/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh index 2006f677d1..de553dd72f 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh @@ -536,6 +536,8 @@ struct STAT | hb_map (&AxisValue::get_value_name_id) | hb_sink (nameids_to_retain) ; + + nameids_to_retain->add (elidedFallbackNameID); } bool subset (hb_subset_context_t *c) const diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh b/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh index cdc6a274ce..853fe3839b 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-common.hh @@ -222,18 +222,20 @@ struct DeltaSetIndexMap struct VarStoreInstancer { - VarStoreInstancer (const VariationStore &varStore, - const DeltaSetIndexMap &varIdxMap, + VarStoreInstancer (const VariationStore *varStore, + const DeltaSetIndexMap *varIdxMap, hb_array_t coords) : varStore (varStore), varIdxMap (varIdxMap), coords (coords) {} - operator bool () const { return bool (coords); } + operator bool () const { return varStore && bool (coords); } + /* according to the spec, if colr table has varStore but does not have + * varIdxMap, then an implicit identity mapping is used */ float operator() (uint32_t varIdx, unsigned short offset = 0) const - { return varStore.get_delta (varIdxMap.map (VarIdx::add (varIdx, offset)), coords); } + { return varStore->get_delta (varIdxMap ? varIdxMap->map (VarIdx::add (varIdx, offset)) : varIdx + offset, coords); } - const VariationStore &varStore; - const DeltaSetIndexMap &varIdxMap; + const VariationStore *varStore; + const DeltaSetIndexMap *varIdxMap; hb_array_t coords; }; @@ -249,36 +251,54 @@ struct TupleVariationHeader { return StructAtOffset (this, get_size (axis_count)); } float calculate_scalar (hb_array_t coords, unsigned int coord_count, - const hb_array_t shared_tuples) const + const hb_array_t shared_tuples, + const hb_vector_t *shared_tuple_active_idx = nullptr) const { - hb_array_t peak_tuple; + const F2DOT14 *peak_tuple; + + unsigned start_idx = 0; + unsigned end_idx = coord_count; if (has_peak ()) - peak_tuple = get_peak_tuple (coord_count); + peak_tuple = get_peak_tuple (coord_count).arrayZ; else { unsigned int index = get_index (); - if (unlikely (index * coord_count >= shared_tuples.length)) + if (unlikely ((index + 1) * coord_count > shared_tuples.length)) return 0.f; - peak_tuple = shared_tuples.sub_array (coord_count * index, coord_count); + peak_tuple = shared_tuples.sub_array (coord_count * index, coord_count).arrayZ; + + if (shared_tuple_active_idx) + { + assert (index < shared_tuple_active_idx->length); + int v = (*shared_tuple_active_idx).arrayZ[index]; + if (v != -1) + { + start_idx = v; + end_idx = start_idx + 1; + } + } } - hb_array_t start_tuple; - hb_array_t end_tuple; - if (has_intermediate ()) + const F2DOT14 *start_tuple = nullptr; + const F2DOT14 *end_tuple = nullptr; + bool has_interm = has_intermediate (); + if (has_interm) { - start_tuple = get_start_tuple (coord_count); - end_tuple = get_end_tuple (coord_count); + start_tuple = get_start_tuple (coord_count).arrayZ; + end_tuple = get_end_tuple (coord_count).arrayZ; } float scalar = 1.f; - for (unsigned int i = 0; i < coord_count; i++) + for (unsigned int i = start_idx; i < end_idx; i++) { - int v = coords[i]; int peak = peak_tuple[i].to_int (); - if (!peak || v == peak) continue; + if (!peak) continue; - if (has_intermediate ()) + int v = coords[i]; + if (v == peak) continue; + + if (has_interm) { int start = start_tuple[i].to_int (); int end = end_tuple[i].to_int (); @@ -358,9 +378,12 @@ struct TupleVariationData { unsigned total_size = min_size; unsigned count = tupleVarCount; - const TupleVariationHeader& tuple_var_header = get_tuple_var_header(); + const TupleVariationHeader *tuple_var_header = &(get_tuple_var_header()); for (unsigned i = 0; i < count; i++) - total_size += tuple_var_header.get_size (axis_count) + tuple_var_header.get_data_size (); + { + total_size += tuple_var_header->get_size (axis_count) + tuple_var_header->get_data_size (); + tuple_var_header = &tuple_var_header->get_next (axis_count); + } return total_size; } @@ -464,12 +487,12 @@ struct TupleVariationData if (unlikely (p + 1 > end)) return false; unsigned control = *p++; unsigned run_count = (control & POINT_RUN_COUNT_MASK) + 1; - if (unlikely (i + run_count > count)) return false; - unsigned j; + unsigned stop = i + run_count; + if (unlikely (stop > count)) return false; if (control & POINTS_ARE_WORDS) { if (unlikely (p + run_count * HBUINT16::static_size > end)) return false; - for (j = 0; j < run_count; j++, i++) + for (; i < stop; i++) { n += *(const HBUINT16 *)p; points.arrayZ[i] = n; @@ -479,7 +502,7 @@ struct TupleVariationData else { if (unlikely (p + run_count > end)) return false; - for (j = 0; j < run_count; j++, i++) + for (; i < stop; i++) { n += *p++; points.arrayZ[i] = n; @@ -507,17 +530,17 @@ struct TupleVariationData if (unlikely (p + 1 > end)) return false; unsigned control = *p++; unsigned run_count = (control & DELTA_RUN_COUNT_MASK) + 1; - if (unlikely (i + run_count > count)) return false; - unsigned j; + unsigned stop = i + run_count; + if (unlikely (stop > count)) return false; if (control & DELTAS_ARE_ZERO) { - for (j = 0; j < run_count; j++, i++) + for (; i < stop; i++) deltas.arrayZ[i] = 0; } else if (control & DELTAS_ARE_WORDS) { if (unlikely (p + run_count * HBUINT16::static_size > end)) return false; - for (j = 0; j < run_count; j++, i++) + for (; i < stop; i++) { deltas.arrayZ[i] = * (const HBINT16 *) p; p += HBUINT16::static_size; @@ -526,7 +549,7 @@ struct TupleVariationData else { if (unlikely (p + run_count > end)) return false; - for (j = 0; j < run_count; j++, i++) + for (; i < stop; i++) { deltas.arrayZ[i] = * (const HBINT8 *) p++; } diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh b/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh index d707a46333..4752a08fbe 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh @@ -104,8 +104,8 @@ struct gvar return_trace (c->check_struct (this) && (version.major == 1) && sharedTuples.sanitize (c, this, axisCount * sharedTupleCount) && (is_long_offset () ? - c->check_array (get_long_offset_array (), glyphCount+1) : - c->check_array (get_short_offset_array (), glyphCount+1))); + c->check_array (get_long_offset_array (), c->get_num_glyphs () + 1) : + c->check_array (get_short_offset_array (), c->get_num_glyphs () + 1))); } /* GlyphVariationData not sanitized here; must be checked while accessing each glyph variation data */ @@ -116,6 +116,8 @@ struct gvar { TRACE_SUBSET (this); + unsigned glyph_count = version.to_int () ? c->plan->source->get_num_glyphs () : 0; + gvar *out = c->serializer->allocate_min (); if (unlikely (!out)) return_trace (false); @@ -125,7 +127,7 @@ struct gvar out->sharedTupleCount = sharedTupleCount; unsigned int num_glyphs = c->plan->num_output_glyphs (); - out->glyphCount = num_glyphs; + out->glyphCountX = hb_min (0xFFFFu, num_glyphs); unsigned int subset_data_size = 0; for (hb_codepoint_t gid = (c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE) ? 0 : 1; @@ -134,7 +136,7 @@ struct gvar { hb_codepoint_t old_gid; if (!c->plan->old_gid_for_new_gid (gid, &old_gid)) continue; - subset_data_size += get_glyph_var_data_bytes (c->source_blob, old_gid).length; + subset_data_size += get_glyph_var_data_bytes (c->source_blob, glyph_count, old_gid).length; } bool long_offset = subset_data_size & ~0xFFFFu; @@ -166,7 +168,9 @@ struct gvar { hb_codepoint_t old_gid; hb_bytes_t var_data_bytes = c->plan->old_gid_for_new_gid (gid, &old_gid) - ? get_glyph_var_data_bytes (c->source_blob, old_gid) + ? get_glyph_var_data_bytes (c->source_blob, + glyph_count, + old_gid) : hb_bytes_t (); if (long_offset) @@ -188,10 +192,12 @@ struct gvar } protected: - const hb_bytes_t get_glyph_var_data_bytes (hb_blob_t *blob, hb_codepoint_t glyph) const + const hb_bytes_t get_glyph_var_data_bytes (hb_blob_t *blob, + unsigned glyph_count, + hb_codepoint_t glyph) const { - unsigned start_offset = get_offset (glyph); - unsigned end_offset = get_offset (glyph+1); + unsigned start_offset = get_offset (glyph_count, glyph); + unsigned end_offset = get_offset (glyph_count, glyph+1); if (unlikely (end_offset < start_offset)) return hb_bytes_t (); unsigned length = end_offset - start_offset; hb_bytes_t var_data = blob->as_bytes ().sub_array (((unsigned) dataZ) + start_offset, length); @@ -200,9 +206,9 @@ struct gvar bool is_long_offset () const { return flags & 1; } - unsigned get_offset (unsigned i) const + unsigned get_offset (unsigned glyph_count, unsigned i) const { - if (unlikely (i > glyphCount)) return 0; + if (unlikely (i > glyph_count)) return 0; _hb_compiler_memory_r_barrier (); return is_long_offset () ? get_long_offset_array ()[i] : get_short_offset_array ()[i] * 2; } @@ -214,7 +220,38 @@ struct gvar struct accelerator_t { accelerator_t (hb_face_t *face) - { table = hb_sanitize_context_t ().reference_table (face); } + { + table = hb_sanitize_context_t ().reference_table (face); + /* If sanitize failed, set glyphCount to 0. */ + glyphCount = table->version.to_int () ? face->get_num_glyphs () : 0; + + /* For shared tuples that only have one axis active, shared the index of + * that axis as a cache. This will speed up caclulate_scalar() a lot + * for fonts with lots of axes and many "monovar" tuples. */ + hb_array_t shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount); + unsigned count = table->sharedTupleCount; + if (unlikely (!shared_tuple_active_idx.resize (count, false))) return; + unsigned axis_count = table->axisCount; + for (unsigned i = 0; i < count; i++) + { + hb_array_t tuple = shared_tuples.sub_array (axis_count * i, axis_count); + int idx = -1; + for (unsigned j = 0; j < axis_count; j++) + { + F2DOT14 peak = tuple.arrayZ[j]; + if (peak.to_int () != 0) + { + if (idx != -1) + { + idx = -1; + break; + } + idx = j; + } + } + shared_tuple_active_idx[i] = idx; + } + } ~accelerator_t () { table.destroy (); } private: @@ -252,9 +289,9 @@ struct gvar { if (!coords) return true; - if (unlikely (glyph >= table->glyphCount)) return true; + if (unlikely (glyph >= glyphCount)) return true; - hb_bytes_t var_data_bytes = table->get_glyph_var_data_bytes (table.get_blob (), glyph); + hb_bytes_t var_data_bytes = table->get_glyph_var_data_bytes (table.get_blob (), glyphCount, glyph); if (!var_data_bytes.as ()->has_data ()) return true; hb_vector_t shared_indices; GlyphVariationData::tuple_iterator_t iterator; @@ -264,19 +301,14 @@ struct gvar return true; /* so isn't applied at all */ /* Save original points for inferred delta calculation */ - contour_point_vector_t orig_points_vec; - orig_points_vec.extend (points); - if (unlikely (orig_points_vec.in_error ())) return false; + contour_point_vector_t orig_points_vec; // Populated lazily auto orig_points = orig_points_vec.as_array (); - contour_point_vector_t deltas_vec; /* flag is used to indicate referenced point */ - if (unlikely (!deltas_vec.resize (points.length, false))) return false; + /* flag is used to indicate referenced point */ + contour_point_vector_t deltas_vec; // Populated lazily auto deltas = deltas_vec.as_array (); - hb_vector_t end_points; - for (unsigned i = 0; i < points.length; ++i) - if (points.arrayZ[i].is_end_point) - end_points.push (i); + hb_vector_t end_points; // Populated lazily unsigned num_coords = table->axisCount; hb_array_t shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount); @@ -284,15 +316,23 @@ struct gvar hb_vector_t private_indices; hb_vector_t x_deltas; hb_vector_t y_deltas; + bool flush = false; do { - float scalar = iterator.current_tuple->calculate_scalar (coords, num_coords, shared_tuples); + float scalar = iterator.current_tuple->calculate_scalar (coords, num_coords, shared_tuples, + shared_tuple_active_idx.in_error () ? nullptr : &shared_tuple_active_idx); if (scalar == 0.f) continue; const HBUINT8 *p = iterator.get_serialized_data (); unsigned int length = iterator.current_tuple->get_data_size (); if (unlikely (!iterator.var_data_bytes.check_range (p, length))) return false; + if (!deltas) + { + if (unlikely (!deltas_vec.resize (points.length))) return false; + deltas = deltas_vec.as_array (); + } + const HBUINT8 *end = p + length; bool has_private_points = iterator.current_tuple->has_private_points (); @@ -308,16 +348,37 @@ struct gvar if (unlikely (!y_deltas.resize (num_deltas, false))) return false; if (unlikely (!GlyphVariationData::unpack_deltas (p, y_deltas, end))) return false; - hb_memset (deltas.arrayZ, 0, deltas.get_size ()); + if (!apply_to_all) + { + if (!orig_points) + { + orig_points_vec.extend (points); + if (unlikely (orig_points_vec.in_error ())) return false; + orig_points = orig_points_vec.as_array (); + } + + if (flush) + { + for (unsigned int i = 0; i < points.length; i++) + points.arrayZ[i].translate (deltas.arrayZ[i]); + flush = false; + + } + hb_memset (deltas.arrayZ, 0, deltas.get_size ()); + } - unsigned ref_points = 0; if (scalar != 1.0f) for (unsigned int i = 0; i < num_deltas; i++) { - unsigned int pt_index = apply_to_all ? i : indices[i]; - if (unlikely (pt_index >= deltas.length)) continue; + unsigned int pt_index; + if (apply_to_all) + pt_index = i; + else + { + pt_index = indices[i]; + if (unlikely (pt_index >= deltas.length)) continue; + } auto &delta = deltas.arrayZ[pt_index]; - ref_points += !delta.flag; delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */ delta.x += x_deltas.arrayZ[i] * scalar; delta.y += y_deltas.arrayZ[i] * scalar; @@ -325,23 +386,34 @@ struct gvar else for (unsigned int i = 0; i < num_deltas; i++) { - unsigned int pt_index = apply_to_all ? i : indices[i]; - if (unlikely (pt_index >= deltas.length)) continue; + unsigned int pt_index; + if (apply_to_all) + pt_index = i; + else + { + pt_index = indices[i]; + if (unlikely (pt_index >= deltas.length)) continue; + } auto &delta = deltas.arrayZ[pt_index]; - ref_points += !delta.flag; delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */ delta.x += x_deltas.arrayZ[i]; delta.y += y_deltas.arrayZ[i]; } /* infer deltas for unreferenced points */ - if (ref_points && ref_points < orig_points.length) + if (!apply_to_all) { - unsigned start_point = 0; - for (unsigned c = 0; c < end_points.length; c++) + if (!end_points) { - unsigned end_point = end_points.arrayZ[c]; + for (unsigned i = 0; i < points.length; ++i) + if (points.arrayZ[i].is_end_point) + end_points.push (i); + if (unlikely (end_points.in_error ())) return false; + } + unsigned start_point = 0; + for (unsigned end_point : end_points) + { /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */ unsigned unref_count = 0; for (unsigned i = start_point; i < end_point + 1; i++) @@ -388,14 +460,14 @@ struct gvar } } - /* apply specified / inferred deltas to points */ - for (unsigned int i = 0; i < points.length; i++) - { - points.arrayZ[i].x += deltas.arrayZ[i].x; - points.arrayZ[i].y += deltas.arrayZ[i].y; - } + flush = true; + } while (iterator.move_to_next ()); + if (flush) + for (unsigned int i = 0; i < points.length; i++) + points.arrayZ[i].translate (deltas.arrayZ[i]); + return true; } @@ -403,6 +475,8 @@ struct gvar private: hb_blob_ptr_t table; + unsigned glyphCount; + hb_vector_t shared_tuple_active_idx; }; protected: @@ -418,7 +492,7 @@ struct gvar NNOffset32To> sharedTuples; /* Offset from the start of this table to the shared tuple records. * Array of tuple records shared across all glyph variation data tables. */ - HBUINT16 glyphCount; /* The number of glyphs in this font. This must match the number of + HBUINT16 glyphCountX; /* The number of glyphs in this font. This must match the number of * glyphs stored elsewhere in the font. */ HBUINT16 flags; /* Bit-field that gives the format of the offset array that follows. * If bit 0 is clear, the offsets are uint16; if bit 0 is set, the diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh b/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh index 53355c5077..461b2b9cdb 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh @@ -185,12 +185,8 @@ struct hvarvvar_subset_plan_t { retain_adv_map = plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS; outer_map.add (0); - for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++) - { - hb_codepoint_t old_gid; - if (plan->old_gid_for_new_gid (gid, &old_gid)) - inner_sets[0]->add (old_gid); - } + for (hb_codepoint_t old_gid : plan->glyphset()->iter()) + inner_sets[0]->add (old_gid); hb_set_union (adv_set, inner_sets[0]); } @@ -202,10 +198,12 @@ struct hvarvvar_subset_plan_t if (retain_adv_map) { for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++) + { if (inner_sets[0]->has (gid)) inner_maps[0].add (gid); else inner_maps[0].skip (); + } } else { @@ -265,6 +263,9 @@ struct HVARVVAR rsbMap.sanitize (c, this)); } + const VariationStore& get_var_store () const + { return this+varStore; } + void listup_index_maps (hb_vector_t &index_maps) const { index_maps.push (&(this+advMap)); diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-outline.cc b/libs/harfbuzz/harfbuzz-src/src/hb-outline.cc index 0657e0e1d3..29b1f530d5 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-outline.cc +++ b/libs/harfbuzz/harfbuzz-src/src/hb-outline.cc @@ -4,7 +4,6 @@ * Copyright © 2005 Werner Lemberg * Copyright © 2013-2015 Alexei Podtelezhnikov * - * * This is part of HarfBuzz, a text shaping library. * * Permission is hereby granted, without written agreement and without diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-paint.h b/libs/harfbuzz/harfbuzz-src/src/hb-paint.h index a734f112cc..543382780d 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-paint.h +++ b/libs/harfbuzz/harfbuzz-src/src/hb-paint.h @@ -616,7 +616,7 @@ typedef enum { HB_PAINT_COMPOSITE_MODE_HSL_HUE, HB_PAINT_COMPOSITE_MODE_HSL_SATURATION, HB_PAINT_COMPOSITE_MODE_HSL_COLOR, - HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY, + HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY } hb_paint_composite_mode_t; /** diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-paint.hh b/libs/harfbuzz/harfbuzz-src/src/hb-paint.hh index f7b71aa19b..d291a4b973 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-paint.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-paint.hh @@ -203,8 +203,8 @@ struct hb_paint_funcs_t if (!a) return false; - float cc = cosf (a * (float) M_PI); - float ss = sinf (a * (float) M_PI); + float cc = cosf (a * HB_PI); + float ss = sinf (a * HB_PI); push_transform (paint_data, cc, ss, -ss, cc, 0.f, 0.f); return true; } @@ -216,8 +216,8 @@ struct hb_paint_funcs_t if (!sx && !sy) return false; - float x = tanf (-sx * (float) M_PI); - float y = tanf (+sy * (float) M_PI); + float x = tanf (-sx * HB_PI); + float y = tanf (+sy * HB_PI); push_transform (paint_data, 1.f, y, x, 1.f, 0.f, 0.f); return true; } diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh b/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh index ee43721a38..d6eb778f5d 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh @@ -29,7 +29,16 @@ #include "hb.hh" -/* Memory pool for persistent allocation of small objects. */ +/* Memory pool for persistent allocation of small objects. + * + * Some AI musings on this, not necessarily true: + * + * This is a very simple implementation, but it's good enough for our + * purposes. It's not thread-safe. It's not very fast. It's not + * very memory efficient. It's not very cache efficient. It's not + * very anything efficient. But it's simple and it works. And it's + * good enough for our purposes. If you need something more + * sophisticated, use a real allocator. Or use a real language. */ template struct hb_pool_t diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh b/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh index 93a7842eb0..bf1b282d3d 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh @@ -35,6 +35,12 @@ * * Priority queue implemented as a binary heap. Supports extract minimum * and insert operations. + * + * The priority queue is implemented as a binary heap, which is a complete + * binary tree. The root of the tree is the minimum element. The heap + * property is that the priority of a node is less than or equal to the + * priority of its children. The heap is stored in an array, with the + * children of node i stored at indices 2i + 1 and 2i + 2. */ struct hb_priority_queue_t { diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc b/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc index 89d354fc01..d9598fc704 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc +++ b/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc @@ -271,9 +271,13 @@ hb_shape_justify (hb_font_t *font, /* If default advance already matches target, nothing to do. Shape and return. */ if (min_target_advance <= *advance && *advance <= max_target_advance) + { + *var_tag = HB_TAG_NONE; + *var_value = 0.0f; return hb_shape_full (font, buffer, features, num_features, shaper_list); + } hb_face_t *face = font->face; @@ -297,6 +301,8 @@ hb_shape_justify (hb_font_t *font, /* If no suitable variation axis found, can't justify. Just shape and return. */ if (!tag) { + *var_tag = HB_TAG_NONE; + *var_value = 0.0f; if (hb_shape_full (font, buffer, features, num_features, shaper_list)) @@ -331,7 +337,11 @@ hb_shape_justify (hb_font_t *font, * Do this again, in case advance was just calculated. */ if (min_target_advance <= *advance && *advance <= max_target_advance) + { + *var_tag = HB_TAG_NONE; + *var_value = 0.0f; return true; + } /* Prepare for running the solver. */ double a, b, ya, yb; @@ -355,6 +365,7 @@ hb_shape_justify (hb_font_t *font, * there's nothing to solve for. Just return it. */ if (yb <= (double) max_target_advance) { + *var_value = (float) b; *advance = (float) yb; return true; } @@ -379,6 +390,7 @@ hb_shape_justify (hb_font_t *font, * there's nothing to solve for. Just return it. */ if (ya >= (double) min_target_advance) { + *var_value = (float) a; *advance = (float) ya; return true; } diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-static.cc b/libs/harfbuzz/harfbuzz-src/src/hb-static.cc index 5f647c6ad9..a1a2522edf 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-static.cc +++ b/libs/harfbuzz/harfbuzz-src/src/hb-static.cc @@ -36,9 +36,11 @@ #include "OT/Color/COLR/COLR.hh" #include "hb-ot-glyf-table.hh" #include "hb-ot-head-table.hh" +#include "hb-ot-hmtx-table.hh" #include "hb-ot-maxp-table.hh" #ifndef HB_NO_VISIBILITY +#include "hb-ot-name-language-static.hh" uint64_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = {}; /*thread_local*/ uint64_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = {}; @@ -108,4 +110,26 @@ hb_face_t::load_upem () const } +#ifndef HB_NO_VAR +bool +_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical, + int *lsb) +{ + return font->face->table.glyf->get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb); +} + +unsigned +_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical) +{ + return font->face->table.glyf->get_advance_with_var_unscaled (font, glyph, is_vertical); +} +#endif + +bool +_glyf_get_leading_bearing_without_var_unscaled (hb_face_t *face, hb_codepoint_t gid, bool is_vertical, int *lsb) +{ + return face->table.glyf->get_leading_bearing_without_var_unscaled (gid, is_vertical, lsb); +} + + #endif diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-style.cc b/libs/harfbuzz/harfbuzz-src/src/hb-style.cc index c7d7d713c2..bd5cb5c6be 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-style.cc +++ b/libs/harfbuzz/harfbuzz-src/src/hb-style.cc @@ -46,13 +46,13 @@ static inline float _hb_angle_to_ratio (float a) { - return tanf (a * float (-M_PI / 180.)); + return tanf (a * -HB_PI / 180.f); } static inline float _hb_ratio_to_angle (float r) { - return atanf (r) * float (-180. / M_PI); + return atanf (r) * -180.f / HB_PI; } /** diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-subset-instancer-solver.cc b/libs/harfbuzz/harfbuzz-src/src/hb-subset-instancer-solver.cc index 5c0f43ad4b..7a2735c529 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-subset-instancer-solver.cc +++ b/libs/harfbuzz/harfbuzz-src/src/hb-subset-instancer-solver.cc @@ -125,7 +125,7 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) return result_t{}; // No overlap /* case 2: Only the peak and outermost bound fall outside the new limit; - * we keep the deltaset, update peak and outermost bound and and scale deltas + * we keep the deltaset, update peak and outermost bound and scale deltas * by the scalar value for the restricted axis at the new limit, and solve * recursively. * diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc b/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc index 088fdca07b..aea886864d 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc +++ b/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc @@ -36,8 +36,10 @@ #include "hb-ot-layout-gpos-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-cff1-table.hh" +#include "hb-ot-cff2-table.hh" #include "OT/Color/COLR/COLR.hh" #include "OT/Color/COLR/colrv1-closure.hh" +#include "OT/Color/CPAL/CPAL.hh" #include "hb-ot-var-fvar-table.hh" #include "hb-ot-var-avar-table.hh" #include "hb-ot-stat-table.hh" @@ -293,7 +295,7 @@ _closure_glyphs_lookups_features (hb_subset_plan_t *plan, feature_record_cond_idx_map, feature_substitutes_map); - if (table_tag == HB_OT_TAG_GSUB) + if (table_tag == HB_OT_TAG_GSUB && !(plan->flags & HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE)) hb_ot_layout_lookups_substitute_closure (plan->source, &lookup_indices, gids_to_retain); @@ -345,7 +347,10 @@ _get_hb_font_with_variations (const hb_subset_plan_t *plan) hb_font_t *font = hb_font_create (plan->source); hb_vector_t vars; - vars.alloc (plan->user_axes_location.get_population ()); + if (!vars.alloc (plan->user_axes_location.get_population ())) { + hb_font_destroy (font); + return nullptr; + } for (auto _ : plan->user_axes_location) { @@ -381,7 +386,13 @@ _collect_layout_variation_indices (hb_subset_plan_t* plan) bool collect_delta = plan->pinned_at_default ? false : true; if (collect_delta) { - font = _get_hb_font_with_variations (plan); + if (unlikely (!plan->check_success (font = _get_hb_font_with_variations (plan)))) { + hb_font_destroy (font); + gdef.destroy (); + gpos.destroy (); + return; + } + if (gdef->has_var_store ()) { var_store = &(gdef->get_var_store ()); @@ -555,9 +566,12 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, if (plan->codepoint_to_glyph->has (cp)) continue; - hb_codepoint_t gid = (*unicode_glyphid_map)[cp]; - plan->codepoint_to_glyph->set (cp, gid); - plan->unicode_to_new_gid_list.push (hb_pair (cp, gid)); + hb_codepoint_t *gid; + if (!unicode_glyphid_map->has(cp, &gid)) + continue; + + plan->codepoint_to_glyph->set (cp, *gid); + plan->unicode_to_new_gid_list.push (hb_pair (cp, *gid)); } plan->unicode_to_new_gid_list.qsort (); } @@ -609,7 +623,7 @@ _glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf, gids_to_retain->add (gid); - for (auto item : glyf.glyph_for_gid (gid).get_composite_iterator ()) + for (auto &item : glyf.glyph_for_gid (gid).get_composite_iterator ()) operation_count = _glyf_add_gid_and_children (glyf, item.get_gid (), @@ -617,9 +631,53 @@ _glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf, operation_count, depth); +#ifndef HB_NO_VAR_COMPOSITES + for (auto &item : glyf.glyph_for_gid (gid).get_var_composite_iterator ()) + { + operation_count = + _glyf_add_gid_and_children (glyf, + item.get_gid (), + gids_to_retain, + operation_count, + depth); + } +#endif + return operation_count; } +static void +_nameid_closure (hb_subset_plan_t* plan, + hb_set_t* drop_tables) +{ +#ifndef HB_NO_STYLE + plan->source->table.STAT->collect_name_ids (&plan->user_axes_location, &plan->name_ids); +#endif +#ifndef HB_NO_VAR + if (!plan->all_axes_pinned) + plan->source->table.fvar->collect_name_ids (&plan->user_axes_location, &plan->name_ids); +#endif +#ifndef HB_NO_COLOR + if (!drop_tables->has (HB_OT_TAG_CPAL)) + plan->source->table.CPAL->collect_name_ids (&plan->colr_palettes, &plan->name_ids); +#endif + +#ifndef HB_NO_SUBSET_LAYOUT + if (!drop_tables->has (HB_OT_TAG_GPOS)) + { + hb_blob_ptr_t gpos = plan->source_table (); + gpos->collect_name_ids (&plan->gpos_features, &plan->name_ids); + gpos.destroy (); + } + if (!drop_tables->has (HB_OT_TAG_GSUB)) + { + hb_blob_ptr_t gsub = plan->source_table (); + gsub->collect_name_ids (&plan->gsub_features, &plan->name_ids); + gsub.destroy (); + } +#endif +} + static void _populate_gids_to_retain (hb_subset_plan_t* plan, hb_set_t* drop_tables) @@ -673,6 +731,7 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, plan->_glyphset_colred = cur_glyphset; + _nameid_closure (plan, drop_tables); /* Populate a full set of glyphs to retain by adding all referenced * composite glyphs. */ if (glyf.has_data ()) @@ -756,21 +815,6 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face, ; } -static void -_nameid_closure (hb_face_t *face, - hb_set_t *nameids, - bool all_axes_pinned, - hb_hashmap_t *user_axes_location) -{ -#ifndef HB_NO_STYLE - face->table.STAT->collect_name_ids (user_axes_location, nameids); -#endif -#ifndef HB_NO_VAR - if (!all_axes_pinned) - face->table.fvar->collect_name_ids (user_axes_location, nameids); -#endif -} - #ifndef HB_NO_VAR static void _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan) @@ -783,12 +827,15 @@ _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan) bool has_avar = face->table.avar->has_data (); const OT::SegmentMaps *seg_maps = nullptr; + unsigned avar_axis_count = 0; if (has_avar) + { seg_maps = face->table.avar->get_segment_maps (); + avar_axis_count = face->table.avar->get_axis_count(); + } bool axis_not_pinned = false; unsigned old_axis_idx = 0, new_axis_idx = 0; - unsigned int i = 0; for (const auto& axis : axes) { hb_tag_t axis_tag = axis.get_axis_tag (); @@ -803,7 +850,7 @@ _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan) else { int normalized_v = axis.normalize_axis_value (plan->user_axes_location.get (axis_tag)); - if (has_avar && old_axis_idx < face->table.avar->get_axis_count ()) + if (has_avar && old_axis_idx < avar_axis_count) { normalized_v = seg_maps->map (normalized_v); } @@ -811,17 +858,99 @@ _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan) if (normalized_v != 0) plan->pinned_at_default = false; - plan->normalized_coords[i] = normalized_v; + plan->normalized_coords[old_axis_idx] = normalized_v; } - if (has_avar) - seg_maps = &StructAfter (*seg_maps); old_axis_idx++; - i++; + if (has_avar && old_axis_idx < avar_axis_count) + seg_maps = &StructAfter (*seg_maps); } plan->all_axes_pinned = !axis_not_pinned; } + +static void +_update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) +{ + if (!plan->normalized_coords) return; + OT::cff2::accelerator_t cff2 (plan->source); + if (!cff2.is_valid ()) return; + + hb_font_t *font = nullptr; + if (unlikely (!plan->check_success (font = _get_hb_font_with_variations (plan)))) + { + hb_font_destroy (font); + return; + } + + hb_glyph_extents_t extents = {0x7FFF, -0x7FFF}; + OT::hmtx_accelerator_t _hmtx (plan->source); + float *hvar_store_cache = nullptr; + if (_hmtx.has_data () && _hmtx.var_table.get_length ()) + hvar_store_cache = _hmtx.var_table->get_var_store ().create_cache (); + + OT::vmtx_accelerator_t _vmtx (plan->source); + float *vvar_store_cache = nullptr; + if (_vmtx.has_data () && _vmtx.var_table.get_length ()) + vvar_store_cache = _vmtx.var_table->get_var_store ().create_cache (); + + for (auto p : *plan->glyph_map) + { + hb_codepoint_t old_gid = p.first; + hb_codepoint_t new_gid = p.second; + if (!cff2.get_extents (font, old_gid, &extents)) continue; + bool has_bounds_info = true; + if (extents.x_bearing == 0 && extents.width == 0 && + extents.height == 0 && extents.y_bearing == 0) + has_bounds_info = false; + + if (has_bounds_info) + { + plan->head_maxp_info.xMin = hb_min (plan->head_maxp_info.xMin, extents.x_bearing); + plan->head_maxp_info.xMax = hb_max (plan->head_maxp_info.xMax, extents.x_bearing + extents.width); + plan->head_maxp_info.yMax = hb_max (plan->head_maxp_info.yMax, extents.y_bearing); + plan->head_maxp_info.yMin = hb_min (plan->head_maxp_info.yMin, extents.y_bearing + extents.height); + } + + if (_hmtx.has_data ()) + { + int hori_aw = _hmtx.get_advance_without_var_unscaled (old_gid); + if (_hmtx.var_table.get_length ()) + hori_aw += (int) roundf (_hmtx.var_table->get_advance_delta_unscaled (old_gid, font->coords, font->num_coords, + hvar_store_cache)); + int lsb = extents.x_bearing; + if (!has_bounds_info) + { + if (!_hmtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb)) + continue; + } + plan->hmtx_map.set (new_gid, hb_pair ((unsigned) hori_aw, lsb)); + plan->bounds_width_map.set (new_gid, extents.width); + } + + if (_vmtx.has_data ()) + { + int vert_aw = _vmtx.get_advance_without_var_unscaled (old_gid); + if (_vmtx.var_table.get_length ()) + vert_aw += (int) roundf (_vmtx.var_table->get_advance_delta_unscaled (old_gid, font->coords, font->num_coords, + vvar_store_cache)); + + int tsb = extents.y_bearing; + if (!has_bounds_info) + { + if (!_vmtx.get_leading_bearing_without_var_unscaled (old_gid, &tsb)) + continue; + } + plan->vmtx_map.set (new_gid, hb_pair ((unsigned) vert_aw, tsb)); + plan->bounds_height_map.set (new_gid, extents.height); + } + } + hb_font_destroy (font); + if (hvar_store_cache) + _hmtx.var_table->get_var_store ().destroy_cache (hvar_store_cache); + if (vvar_store_cache) + _vmtx.var_table->get_var_store ().destroy_cache (vvar_store_cache); +} #endif hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, @@ -884,6 +1013,8 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, _populate_unicodes_to_retain (input->sets.unicodes, input->sets.glyphs, this); _populate_gids_to_retain (this, input->sets.drop_tables); + if (unlikely (in_error ())) + return; _create_old_gid_to_new_gid_map (face, input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS, @@ -905,10 +1036,13 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, glyph_map->get(unicode_to_new_gid_list.arrayZ[i].second); } - _nameid_closure (face, &name_ids, all_axes_pinned, &user_axes_location); if (unlikely (in_error ())) return; +#ifndef HB_NO_VAR + _update_instance_metrics_map_from_cff2 (this); +#endif + if (attach_accelerator_data) { hb_multimap_t gid_to_unicodes; diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh b/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh index c0a85e12dc..e34eeb89ae 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh @@ -211,7 +211,7 @@ struct hb_subset_plan_t template hb_blob_ptr_t source_table() { - hb_lock_t (accelerator ? &accelerator->sanitized_table_cache_lock : nullptr); + hb_lock_t lock (accelerator ? &accelerator->sanitized_table_cache_lock : nullptr); auto *cache = accelerator ? &accelerator->sanitized_table_cache : &sanitized_table_cache; if (cache diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc b/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc index e0b1ed6442..5ea422983c 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc +++ b/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc @@ -637,8 +637,3 @@ hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan) end: return success ? hb_face_reference (plan->dest) : nullptr; } - -#ifndef HB_NO_VISIBILITY -/* If NO_VISIBILITY, libharfbuzz has this. */ -#include "hb-ot-name-language-static.hh" -#endif diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-subset.h b/libs/harfbuzz/harfbuzz-src/src/hb-subset.h index c14b1b1803..41d9587052 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-subset.h +++ b/libs/harfbuzz/harfbuzz-src/src/hb-subset.h @@ -71,6 +71,8 @@ typedef struct hb_subset_plan_t hb_subset_plan_t; * in the final subset. * @HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES: If set then the unicode ranges in * OS/2 will not be recalculated. + * @HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE: If set don't perform glyph closure on layout + * substitution rules (GSUB). Since: 7.2.0. * * List of boolean properties that can be configured on the subset input. * @@ -87,6 +89,7 @@ typedef enum { /*< flags >*/ HB_SUBSET_FLAGS_NOTDEF_OUTLINE = 0x00000040u, HB_SUBSET_FLAGS_GLYPH_NAMES = 0x00000080u, HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES = 0x00000100u, + HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE = 0x00000200u, } hb_subset_flags_t; /** diff --git a/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h b/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h index faa8d67924..5b5c45cae3 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h +++ b/libs/harfbuzz/harfbuzz-src/src/hb-unicode.h @@ -164,7 +164,7 @@ typedef enum * @HB_UNICODE_COMBINING_CLASS_CCC122: [Lao] * @HB_UNICODE_COMBINING_CLASS_CCC129: [Tibetan] * @HB_UNICODE_COMBINING_CLASS_CCC130: [Tibetan] - * @HB_UNICODE_COMBINING_CLASS_CCC133: [Tibetan] + * @HB_UNICODE_COMBINING_CLASS_CCC132: [Tibetan] Since: 7.2.0 * @HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT: Marks attached at the bottom left * @HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW: Marks attached directly below * @HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE: Marks attached directly above @@ -246,7 +246,7 @@ typedef enum /* Tibetan */ HB_UNICODE_COMBINING_CLASS_CCC129 = 129, HB_UNICODE_COMBINING_CLASS_CCC130 = 130, - HB_UNICODE_COMBINING_CLASS_CCC133 = 132, + HB_UNICODE_COMBINING_CLASS_CCC132 = 132, HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT = 200, diff --git a/libs/harfbuzz/harfbuzz-src/src/hb.hh b/libs/harfbuzz/harfbuzz-src/src/hb.hh index d09849e565..30b3de499a 100644 --- a/libs/harfbuzz/harfbuzz-src/src/hb.hh +++ b/libs/harfbuzz/harfbuzz-src/src/hb.hh @@ -509,6 +509,12 @@ static_assert ((sizeof (hb_mask_t) == 4), ""); static_assert ((sizeof (hb_var_int_t) == 4), ""); +/* Pie time. */ +// https://github.com/harfbuzz/harfbuzz/issues/4166 +#define HB_PI 3.14159265358979f +#define HB_2_PI (2.f * HB_PI) + + /* Headers we include for everyone. Keep topologically sorted by dependency. * They express dependency amongst themselves, but no other file should include * them directly.*/ diff --git a/libs/harfbuzz/harfbuzz-src/src/meson.build b/libs/harfbuzz/harfbuzz-src/src/meson.build index 93991abd9f..30b99cf340 100644 --- a/libs/harfbuzz/harfbuzz-src/src/meson.build +++ b/libs/harfbuzz/harfbuzz-src/src/meson.build @@ -668,6 +668,7 @@ if get_option('tests').enabled() 'test-ot-name': 'test-ot-name.cc', 'test-ot-glyphname': 'test-ot-glyphname.cc', 'test-ot-gpos-size-params': 'test-gpos-size-params.cc', + 'test-ot-gsub-get-alternates': 'test-gsub-get-alternates.cc', 'test-ot-gsub-would-substitute': 'test-gsub-would-substitute.cc', 'test-use-table': 'test-use-table.cc', } diff --git a/libs/harfbuzz/harfbuzz-src/src/test-gsub-get-alternates.cc b/libs/harfbuzz/harfbuzz-src/src/test-gsub-get-alternates.cc new file mode 100644 index 0000000000..c9f3b4edb5 --- /dev/null +++ b/libs/harfbuzz/harfbuzz-src/src/test-gsub-get-alternates.cc @@ -0,0 +1,86 @@ +/* + * Copyright © 2010,2011 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#include +#include + +#include +#include + +int +main (int argc, char **argv) +{ + if (argc != 3) { + fprintf (stderr, "usage: %s font-file text\n", argv[0]); + exit (1); + } + + /* Create the face */ + hb_blob_t *blob = hb_blob_create_from_file_or_fail (argv[1]); + hb_face_t *face = hb_face_create (blob, 0 /* first face */); + hb_blob_destroy (blob); + blob = nullptr; + + hb_font_t *font = hb_font_create (face); + hb_buffer_t *buffer = hb_buffer_create (); + + hb_buffer_add_utf8 (buffer, argv[2], -1, 0, -1); + hb_buffer_guess_segment_properties (buffer); + hb_shape (font, buffer, NULL, 0); + + hb_tag_t features[] = {HB_TAG('a','a','l','t'), HB_TAG_NONE}; + hb_set_t *lookup_indexes = hb_set_create (); + hb_ot_layout_collect_lookups (face, + HB_OT_TAG_GSUB, + NULL, NULL, + features, + lookup_indexes); + printf ("lookups %u\n", hb_set_get_population (lookup_indexes)); + + unsigned count; + hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &count); + for (unsigned i = 0; i < count; i++) + { + unsigned alt_count = 0; + for (unsigned lookup_index = HB_SET_VALUE_INVALID; + hb_set_next (lookup_indexes, &lookup_index);) + if ((alt_count = hb_ot_layout_lookup_get_glyph_alternates (face, + lookup_index, + info[i].codepoint, + 0, + NULL, + NULL))) + break; + printf ("glyph %u alt count %u\n", info[i].codepoint, alt_count); + } + + hb_set_destroy (lookup_indexes); + hb_buffer_destroy (buffer); + hb_font_destroy (font); + hb_face_destroy (face); + + return 0; +} diff --git a/libs/harfbuzz/harfbuzz-src/src/test-set.cc b/libs/harfbuzz/harfbuzz-src/src/test-set.cc index 9fe319da69..5f13ab3225 100644 --- a/libs/harfbuzz/harfbuzz-src/src/test-set.cc +++ b/libs/harfbuzz/harfbuzz-src/src/test-set.cc @@ -137,5 +137,29 @@ main (int argc, char **argv) assert (s.has (HB_SET_VALUE_INVALID)); } + /* Adding HB_SET_VALUE_INVALID */ + { + hb_set_t s; + + s.add(HB_SET_VALUE_INVALID); + assert(!s.has(HB_SET_VALUE_INVALID)); + + s.clear(); + assert(!s.add_range(HB_SET_VALUE_INVALID - 2, HB_SET_VALUE_INVALID)); + assert(!s.has(HB_SET_VALUE_INVALID)); + + hb_codepoint_t array[] = {(unsigned) HB_SET_VALUE_INVALID, 0, 2}; + s.clear(); + s.add_array(array, 3); + assert(!s.has(HB_SET_VALUE_INVALID)); + assert(s.has(2)); + + hb_codepoint_t sorted_array[] = {0, 2, (unsigned) HB_SET_VALUE_INVALID}; + s.clear(); + s.add_sorted_array(sorted_array, 3); + assert(!s.has(HB_SET_VALUE_INVALID)); + assert(s.has(2)); + } + return 0; } diff --git a/libs/harfbuzz/version.ac b/libs/harfbuzz/version.ac index 8d98b1fa32..eaafd5b890 100644 --- a/libs/harfbuzz/version.ac +++ b/libs/harfbuzz/version.ac @@ -8,4 +8,4 @@ dnl dnl -------------------------------------------------------- dnl dnl m4-include this file to define the current harfbuzz version -m4_define([harfbuzz_version], [7.1.0]) +m4_define([harfbuzz_version], [7.2.0])