Compare commits

..

1103 commits
10.0.1 ... main

Author SHA1 Message Date
jfkthame
4e7b178f3c Avoid unannotated-fallthrough in hb-ot-layout-base-table.hh
Some checks failed
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
arm / arm-none-eabi (push) Has been cancelled
configs-ci / build (push) Has been cancelled
fontations / build (push) Has been cancelled
linux-ci / build (push) Has been cancelled
macos-ci / build (push) Has been cancelled
msvc / msvc-2019-amd64 (push) Has been cancelled
msvc / msvc-2019-x86 (push) Has been cancelled
msys2 / CLANG64 (push) Has been cancelled
msys2 / MINGW32 (push) Has been cancelled
msys2 / MINGW64 (push) Has been cancelled
2025-04-17 11:57:15 -06:00
jfkthame
2602f7292c Avoid unannotated-fallthrough warning in COLR.hh 2025-04-17 11:56:46 -06:00
Khaled Hosny
416e6b6921 11.1.0
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
2025-04-16 20:35:58 +02:00
Behdad Esfahbod
32b36fa84c [atexit] Fix extra semicolon
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 3s
Fixes https://github.com/harfbuzz/harfbuzz/issues/5290
2025-04-15 12:37:43 -06:00
Behdad Esfahbod
bc15ebdea1 [font] Fix abs of int value 2025-04-15 12:37:11 -06:00
Behdad Esfahbod
8f413a533c [layout] Docs
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 7s
2025-04-15 10:03:16 -06:00
Behdad Esfahbod
21516f74d2 [cmake] Add hb-script-list.h
Fixes https://github.com/harfbuzz/harfbuzz/issues/5288
2025-04-15 09:58:42 -06:00
Behdad Esfahbod
7bb3000a31 [font] Allow negative emboldening strength to enlighten 2025-04-15 09:58:42 -06:00
dependabot[bot]
4da8671b50 Bump github/codeql-action from 3.28.14 to 3.28.15
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.14 to 3.28.15.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](fc7e4a0fa0...45775bd823)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.28.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-15 17:02:15 +02:00
Khaled Hosny
e192a584a8 [check-symbols] Ignore another rust symbol
Fixes https://github.com/harfbuzz/harfbuzz/issues/5287
2025-04-15 16:59:46 +02:00
robxnano
cf7bffb690 meson: Use full path in HBSOURCES
Some checks failed
Scorecard supply-chain security / Scorecard analysis (push) Failing after 6s
arm / arm-none-eabi (push) Has been cancelled
configs-ci / build (push) Has been cancelled
fontations / build (push) Has been cancelled
linux-ci / build (push) Has been cancelled
macos-ci / build (push) Has been cancelled
msvc / msvc-2019-amd64 (push) Has been cancelled
msvc / msvc-2019-x86 (push) Has been cancelled
msys2 / CLANG64 (push) Has been cancelled
msys2 / MINGW32 (push) Has been cancelled
msys2 / MINGW64 (push) Has been cancelled
Using the file object directly in a format string is broken
and now deprecated.
2025-04-13 02:59:31 +02:00
robxnano
9def626d4a meson: Fix warnings about features in later versions
By using the fs.relative_to() function inside version_compare
blocks, Meson can suppress warning messages about it being used
in a project with a lower minimum version.
2025-04-13 02:59:31 +02:00
robxnano
e2a865f024 meson: Only check for _MSC_FULL_VER once
Prevents the log from filling with repeated calls to check the
value of the define.
2025-04-13 02:59:31 +02:00
Garret Rieger
efcb7d3de1 [subset] close unicodes over bidi mirror variants during subsetting.
Some checks failed
Scorecard supply-chain security / Scorecard analysis (push) Failing after 3s
arm / arm-none-eabi (push) Has been cancelled
configs-ci / build (push) Has been cancelled
macos-ci / build (push) Has been cancelled
fontations / build (push) Has been cancelled
linux-ci / build (push) Has been cancelled
msvc / msvc-2019-amd64 (push) Has been cancelled
msvc / msvc-2019-x86 (push) Has been cancelled
msys2 / CLANG64 (push) Has been cancelled
msys2 / MINGW32 (push) Has been cancelled
msys2 / MINGW64 (push) Has been cancelled
Fixes #5281. Does the closure by default, but I've introduced a new flag and option to disable this behaviour since some users may want to get the minimal set if they know they don't need the mirrored variants.
2025-04-11 18:13:28 -06:00
Garret Rieger
5afbd187b6 [subset] Split subset plan variations function into separate file.
Some checks failed
Scorecard supply-chain security / Scorecard analysis (push) Failing after 7s
arm / arm-none-eabi (push) Has been cancelled
configs-ci / build (push) Has been cancelled
fontations / build (push) Has been cancelled
linux-ci / build (push) Has been cancelled
macos-ci / build (push) Has been cancelled
msvc / msvc-2019-amd64 (push) Has been cancelled
msvc / msvc-2019-x86 (push) Has been cancelled
msys2 / CLANG64 (push) Has been cancelled
msys2 / MINGW32 (push) Has been cancelled
msys2 / MINGW64 (push) Has been cancelled
Compile times for hb-subset-plan.cc go from 16s -> 13s.
2025-04-09 17:08:06 -06:00
Behdad Esfahbod
e6b5dba369 [README] Add Subsetter study 2025-04-09 16:53:22 -06:00
Garret Rieger
d3ccdcdd80 [subset] Move GDEF subset planning into hb-subset-plan-layout.cc 2025-04-09 16:45:07 -06:00
Garret Rieger
b33f2e26ee [subset] Start splitting layout specific subset plan functionality.
The aim is to reduce the compiled time of hb-subset-plan.cc which on my machine takes almost 30s to compile.
2025-04-09 16:45:07 -06:00
Behdad Esfahbod
ab3235150d [common] Move hb_script_t enum to a separate file
Fixes https://github.com/harfbuzz/harfbuzz/issues/5271
2025-04-09 10:43:02 -06:00
Behdad Esfahbod
5f80cc1600 [directwrite] Fix build
Some checks failed
Scorecard supply-chain security / Scorecard analysis (push) Failing after 13m20s
arm / arm-none-eabi (push) Has been cancelled
configs-ci / build (push) Has been cancelled
fontations / build (push) Has been cancelled
linux-ci / build (push) Has been cancelled
macos-ci / build (push) Has been cancelled
msys2 / CLANG64 (push) Has been cancelled
msys2 / MINGW32 (push) Has been cancelled
msys2 / MINGW64 (push) Has been cancelled
msvc / msvc-2019-amd64 (push) Has been cancelled
msvc / msvc-2019-x86 (push) Has been cancelled
2025-04-08 02:13:39 -06:00
Behdad Esfahbod
6b0124284b [mutex] Delete copy constructors 2025-04-08 01:58:10 -06:00
Behdad Esfahbod
caa9cf2e85 [atomic] Remove unnecessary macro
Had typo in it as well.
2025-04-08 01:50:51 -06:00
Behdad Esfahbod
c7f980907f [GPOS] Short-circuit variations if no axis set
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 5s
2025-04-07 16:37:00 -06:00
Garret Rieger
b1a0a4c228 In OT::VarData::Serialize don't attempt to serialize an empty set of rows.
Protects against incorrectly accessing rows[0] when rows is empty.
2025-04-07 13:11:39 -06:00
dependabot[bot]
6dff699f3f Bump fonttools from 4.56.0 to 4.57.0 in /.ci
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 2s
Bumps [fonttools](https://github.com/fonttools/fonttools) from 4.56.0 to 4.57.0.
- [Release notes](https://github.com/fonttools/fonttools/releases)
- [Changelog](https://github.com/fonttools/fonttools/blob/main/NEWS.rst)
- [Commits](https://github.com/fonttools/fonttools/compare/4.56.0...4.57.0)

---
updated-dependencies:
- dependency-name: fonttools
  dependency-version: 4.57.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 14:00:02 +02:00
dependabot[bot]
6697cd833a Bump github/codeql-action from 3.28.13 to 3.28.14
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.13 to 3.28.14.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](1b549b9259...fc7e4a0fa0)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.28.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 13:52:23 +02:00
Khaled Hosny
2c4bc83244 [ot-math] Fix build with HB_NO_MATH 2025-04-07 13:43:16 +02:00
Behdad Esfahbod
e31721b5cf [test/shape] Write cmdline as test description
Some checks failed
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 5s
2025-04-06 21:41:09 -06:00
Behdad Esfahbod
a9e2c8f3aa
Merge pull request #5264 from harfbuzz/tap2
Tap2
2025-04-06 19:34:18 -06:00
Behdad Esfahbod
a3d626b4b9 [test-object] Hopefully last ubsan fix
API change:
- hb_face_is_immutable() now takes `hb_face_t *` instead of previous
  `const hb_face_t *`.  This should not pose any problem for any
  clients in our belief.
2025-04-06 19:16:43 -06:00
Behdad Esfahbod
b99382e292 [test-unicode] Try disabling one test under ubsan 2025-04-06 18:53:53 -06:00
Behdad Esfahbod
ba4a92c53b [test-object] Fix ubsan issues 2025-04-06 18:48:39 -06:00
Behdad Esfahbod
8a1ba4d151 [test-object] See if this helps make ubsan happy 2025-04-06 18:12:22 -06:00
Behdad Esfahbod
fb04a306fc [test/api] Fix a few ubsan issues 2025-04-06 18:08:50 -06:00
Behdad Esfahbod
b43901151f [test-draw] Make ubsan happy 2025-04-06 17:28:03 -06:00
Behdad Esfahbod
b106a9ef58 [CI] Put back the meson-default sanitizer options 2025-04-06 16:36:50 -06:00
Behdad Esfahbod
59771e5613 [CI] Redirect sanitizer outputs to stderr 2025-04-06 16:28:40 -06:00
Behdad Esfahbod
fd9903fc4e [hb-subset] Try to fix leak 2025-04-06 16:20:23 -06:00
Behdad Esfahbod
f09c4d6dd8 [test/subset] Fix a regular expression 2025-04-06 15:54:21 -06:00
Behdad Esfahbod
1f0559392d [test/subset] Massage more 2025-04-06 15:50:20 -06:00
Behdad Esfahbod
d8f00171d7 [test/subset] black 2025-04-06 15:33:25 -06:00
Behdad Esfahbod
cc065cf2e5 [test/subset] Better report passed tests 2025-04-06 15:33:08 -06:00
Behdad Esfahbod
c60067c675 [test/subset] See if this fixes CI
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 0s
2025-04-06 15:25:58 -06:00
Behdad Esfahbod
8456c33ac3 [test/shape] Respect @face-loaders directive 2025-04-06 14:33:44 -06:00
Behdad Esfahbod
1f1cbb64ee
Merge pull request #5260 from harfbuzz/tap
Use TAP protocol for tests
2025-04-06 14:30:07 -06:00
Behdad Esfahbod
aa6a37de61 [test/subset] Port to TAP 2025-04-06 14:18:18 -06:00
Behdad Esfahbod
ba309a1826 [test/fuzzing] Port all to TAP 2025-04-06 13:54:47 -06:00
Behdad Esfahbod
58d7ab2d59 [meson] Remove unneeded dependencies 2025-04-06 13:42:13 -06:00
Behdad Esfahbod
328509ef66 [tap] Try to fix cross64 build 2025-04-06 13:34:04 -06:00
Behdad Esfahbod
03f4230188 [mac] Add tests for --face-loader
https://github.com/harfbuzz/harfbuzz/issues/5142
2025-04-06 13:32:28 -06:00
Behdad Esfahbod
5a46872853 Add test for https://github.com/harfbuzz/harfbuzz/issues/5232 2025-04-06 13:32:28 -06:00
Khaled Hosny
9718681c99 [meson] Require 0.60.0
Fixes https://github.com/harfbuzz/harfbuzz/issues/5261
2025-04-06 13:23:43 -06:00
Behdad Esfahbod
2b5ae9dec3 [meson] Use a glob.py instead of ls / dir 2025-04-06 12:52:31 -06:00
Behdad Esfahbod
155e1e633b [test/api] Use g_assert_true instead of g_assert
The latter terminates the program. The former marks the test
as failing.
2025-04-06 03:49:15 -06:00
Behdad Esfahbod
f73039422e [CI] See if this fixes crossbuild 64 2025-04-06 03:35:05 -06:00
Behdad Esfahbod
5efdb884a5 [run-tests] Fix remaining bot fails, fingers crossed 2025-04-06 03:21:15 -06:00
Behdad Esfahbod
8132a6607f [shape/run-tests] Don't return non-zero
TAP protocol.
2025-04-06 03:12:38 -06:00
Behdad Esfahbod
b2179dcfcd [meson.build] Another try 2025-04-06 03:03:41 -06:00
Behdad Esfahbod
a777a9c535 [meson.build] Try fix using of find 2025-04-06 02:47:06 -06:00
Behdad Esfahbod
e332777763 [fuzzing/subset] Make TAP protocol 2025-04-06 02:34:48 -06:00
Behdad Esfahbod
740a103ba1 [meson] See if this fixes bots 2025-04-06 02:34:48 -06:00
Behdad Esfahbod
a530672f04 [meson.build] Don't use str.replace() method
Too recent.
2025-04-06 02:34:48 -06:00
Behdad Esfahbod
628a9ee28a [check-static-inits] objdump all objects together
We won't see which object has the bad initializers anymore.
We can later adapt to objdump each object one by one if
any error was found.

Changes test runtime from 1s down to 0.15s.
2025-04-06 02:34:48 -06:00
Behdad Esfahbod
fbda749bdb [meson.build] Try to bring down required version
range() not found
2025-04-06 02:34:48 -06:00
Behdad Esfahbod
da5a9fb860 [meson.build] Remove unused fs module 2025-04-06 02:34:48 -06:00
Behdad Esfahbod
b01cea95e1 [meson] Cosmetic 2025-04-06 02:34:48 -06:00
Behdad Esfahbod
1db93d2f6d [test/fuzzing/subset] Run chunks in parallel 2025-04-06 02:34:48 -06:00
Behdad Esfahbod
ee50fad676 [run-tests] black 2025-04-06 02:34:48 -06:00
Behdad Esfahbod
db953a43d0 [meson.build] Cosmetic 2025-04-06 02:34:48 -06:00
Behdad Esfahbod
69fd949014 [test/shape] Run using TAP protocol
Run all tests for a suite in one process. Saves runtime from
3s to 2s.
2025-04-06 02:34:48 -06:00
Behdad Esfahbod
2834900d92 [test/shape] Run each test suite in one process 2025-04-06 02:34:48 -06:00
Behdad Esfahbod
e4e4d66523 [test/api] Test remaining tests to TAP 2025-04-06 02:34:48 -06:00
Behdad Esfahbod
c523f9ac13 [test/shape] Use TAP
Checkpoint.
2025-04-06 02:34:48 -06:00
Behdad Esfahbod
f69ecc9438 [test/api] Set protocol:tap 2025-04-06 02:34:48 -06:00
Behdad Esfahbod
6acb2942e8 [ft] Fix compiler warnings
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 5s
2025-04-06 02:34:34 -06:00
Behdad Esfahbod
bee08cf290 [hb-test] Don't convert _ in test names to /
Some checks failed
msys2 / MINGW64 (push) Waiting to run
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
Slash is used for grouping...
2025-04-05 23:27:26 -06:00
Behdad Esfahbod
a46b93208a [subset] Remove printf from library! 2025-04-05 23:27:15 -06:00
Behdad Esfahbod
3cf48234b9 [hb-test.h] Remove unsed functions 2025-04-05 23:26:59 -06:00
Behdad Esfahbod
112b599826 [test] Minor use hb_test_init 2025-04-05 22:37:10 -06:00
Behdad Esfahbod
6c98519c7e [test/api] Simplify deps 2025-04-05 21:41:01 -06:00
Khaled Hosny
0a5cc89e00 Improve OSS-Fuzz build log URL [ci skip] 2025-04-06 04:08:22 +02:00
Behdad Esfahbod
d9304b69e0 [subset] Fix i686 oss-fuzz build hopefully 2025-04-05 20:04:10 -06:00
Khaled Hosny
58170206a1 Typo [ci skip] 2025-04-06 03:55:56 +02:00
Khaled Hosny
a24c40dfb4 [test/ot-math] Do away with global variables 2025-04-06 03:22:20 +02:00
Khaled Hosny
d74606bbff [test/ot-math] Port to use hb_test_open_font_file()
Avoids the unnecessary dependency on FreeType.
2025-04-06 03:22:20 +02:00
Khaled Hosny
2d8e5255f3 [test/ot-math] Add a test for the Cambria Math workaround 2025-04-06 02:48:49 +02:00
Khaled Hosny
f57b43c980 [ot-math] Workaround bad displayOperatorMinHeight in Cambria Math
See https://github.com/harfbuzz/harfbuzz/issues/4653 for details
2025-04-06 02:48:49 +02:00
Behdad Esfahbod
52a4bea109
Merge pull request #5255 from harfbuzz/subset-test-less
Reduce tested combinations of subset & threads tests
2025-04-05 17:26:09 -06:00
Behdad Esfahbod
b53000403e [run-fuzzer-tests] Remove duplicate chunksize 2025-04-05 17:15:50 -06:00
Behdad Esfahbod
7dcd69544b [test/shape/threads] Reduce number of tested combinations 2025-04-05 17:08:31 -06:00
Behdad Esfahbod
c42b6ea829 [test] Adjust subdir order 2025-04-05 17:04:56 -06:00
Behdad Esfahbod
e5541a0b63 [subset/test/cmap14] Reduce tested combinations
Fixes https://github.com/harfbuzz/harfbuzz/issues/5254
2025-04-05 17:02:31 -06:00
Behdad Esfahbod
d65fa93440 [subset/test/basics.tests] Reduce tested combinations 2025-04-05 16:58:06 -06:00
Behdad Esfahbod
00b4f86e5f [hb-subset] In batch mode preprocess font once
Speeds up cmap.tests from 3s to under .5s.
2025-04-05 16:20:05 -06:00
Behdad Esfahbod
267de2bb90 [hb-view] Report success/failure in --batch mode
Otherwise client can't know when the job is done.
2025-04-05 16:14:24 -06:00
Behdad Esfahbod
5194ec4758 [test/subset] Use --preprocess instead of --preprocess-face
The latter is obsolete and alias to the former.
2025-04-05 16:08:18 -06:00
Behdad Esfahbod
fa737da022 [hb-subset] Speed up parsing glyphs-file
Cache the font used to load glyph names.
2025-04-05 16:02:09 -06:00
Behdad Esfahbod
54295ccf45 [hb-subset] Speed up parsing glyphs-file
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
Cache the font used to load glyph names.
2025-04-05 15:26:07 -06:00
Behdad Esfahbod
0fecd2ecc3 [hb-subset] Accept gidXXX-style glyph names 2025-04-05 15:20:49 -06:00
Behdad Esfahbod
a637c08d5a [hb-subset] Fix leak 2025-04-05 15:02:28 -06:00
Khaled Hosny
866096d04a [ci] Install help2man on the linux-ci workflow
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
Generating manpages is not tested on any CI jobs otherwise.
2025-04-05 13:43:04 +02:00
Behdad Esfahbod
b6cbd6a0fc [README] Add another link
Some checks failed
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
2025-04-04 19:07:04 -06:00
Behdad Esfahbod
2f86ab8d47 [README] Cosmetic 2025-04-04 18:29:33 -06:00
Behdad Esfahbod
9971d84ea7 [README] Cosmetic 2025-04-04 18:28:14 -06:00
Behdad Esfahbod
bf3ce2cb6b [README] Cosmetic 2025-04-04 18:27:01 -06:00
Behdad Esfahbod
90331b41ef [README] Cosmetic 2025-04-04 18:26:06 -06:00
Behdad Esfahbod
3207575979 [subset] Allow options before --font-file
Fixes https://github.com/harfbuzz/harfbuzz/issues/4913
2025-04-04 18:13:36 -06:00
Behdad Esfahbod
0457d3d734 [buffer-deserialize] Ignore glyph extents
Fixes https://github.com/harfbuzz/harfbuzz/issues/5169
2025-04-04 16:17:32 -06:00
Behdad Esfahbod
9ddf3da71e [benchmark-shape] Accept one variation on the cmd-line 2025-04-04 16:04:07 -06:00
Khaled Hosny
43a7784922 11.0.1
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
2025-04-04 22:41:26 +02:00
Behdad Esfahbod
13752124d7 Fix compiler warnings 2025-04-04 14:00:25 -06:00
Behdad Esfahbod
623a7a4198 Whitespace 2025-04-04 13:25:06 -06:00
Behdad Esfahbod
c44f1e71d7 Cosmetic 2025-04-04 13:23:42 -06:00
Behdad Esfahbod
1337912680 Cosmetic 2025-04-04 13:00:30 -06:00
Behdad Esfahbod
cc782b5427 [RELEASING] Cosmetic 2025-04-04 12:59:43 -06:00
Behdad Esfahbod
7ba4e87934 [VarStore] Fix storage shift
Use all bits. That's what I meant.
2025-04-04 12:41:38 -06:00
Behdad Esfahbod
089a9961ad [README] Expand on API/ABI guarantee 2025-04-04 12:30:13 -06:00
Khaled Hosny
a55305038c [coretext] Fix -Wformat warning
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
../src/hb-coretext.cc:202:62: warning: format specifies type 'int' but the argument has type 'unsigned int' [-Wformat]
  202 |     DEBUG_MSG (CORETEXT, blob, "TTC index %d not supported", ttc_index);
      |                                           ~~                 ^~~~~~~~~
      |                                           %u

../src/hb-coretext.cc:417:65: warning: format specifies type 'int' but the argument has type 'unsigned int' [-Wformat]
  417 |     DEBUG_MSG (CORETEXT, nullptr, "TTC index %d not supported", ttc_index);
      |                                              ~~                 ^~~~~~~~~
      |                                              %u
2025-04-04 13:27:31 +02:00
Behdad Esfahbod
8994e91487
Merge pull request #5241 from harfbuzz/font-gdef-varstore
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
[shape] Use font-data for GDEF varStore cache
2025-04-03 22:50:49 -06:00
Behdad Esfahbod
d515630f6b [shape-font] Simplify logic 2025-04-03 22:31:13 -06:00
Behdad Esfahbod
d30d7f6b2b [ItemVariationStore] Use atomic int for cache 2025-04-03 22:25:34 -06:00
Behdad Esfahbod
9cae040bb4 [ItemVariationStore] Make cache atomic floats
Doesn't work with intrinsic atomic implementations. Disabled that.
Going through the C++11 atomics path now.

Will fix in next commit.
2025-04-03 22:18:14 -06:00
Behdad Esfahbod
810fbedf27 [shape] Use font-data for GDEF varStore cache
Last remaining alloc during shaping is gone!

Fixes https://github.com/harfbuzz/harfbuzz/issues/5237
2025-04-03 22:13:10 -06:00
Behdad Esfahbod
6cc9c01aaa
Merge pull request #5242 from harfbuzz/c++-atomics
Do our C++11 atomics build anywhere??
2025-04-03 22:12:26 -06:00
Behdad Esfahbod
e10d647a73 [atomic] Re-enable intrinsics implementation 2025-04-03 22:01:37 -06:00
Behdad Esfahbod
e404cf0860 [atomic] Fix C++11 implementation
Surprised no one has been using it.
2025-04-03 21:57:15 -06:00
Behdad Esfahbod
e480d9de96 Do our C++11 atomics build anywhere?? 2025-04-03 21:44:23 -06:00
Behdad Esfahbod
60fc8b4cbc [README] Add Python 2025-04-03 16:18:38 -06:00
Behdad Esfahbod
062c3b4d80 [README] Remove stale text 2025-04-03 16:16:57 -06:00
Behdad Esfahbod
2152ff779c [README] Link some developer documents 2025-04-03 16:15:00 -06:00
Behdad Esfahbod
18ab0f5522 [font] Fix serial_coords
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 2s
2025-04-03 04:04:40 -06:00
Behdad Esfahbod
c6c8dcdeca
Merge pull request #5239 from harfbuzz/alloc-free-var-shaping
Alloc free var shaping
2025-04-03 03:18:53 -06:00
Behdad Esfahbod
6f5b8d59c7 [ot-font] Streamline advance cache management 2025-04-03 02:57:48 -06:00
Behdad Esfahbod
7da049ed42 [varStore] Add clear_cache() 2025-04-02 15:22:13 -06:00
Behdad Esfahbod
da0c459dd4 [ot-font] Use helpers to acquire/release varStore cache 2025-04-02 15:22:13 -06:00
Behdad Esfahbod
37989fb4cd [ot-font] Adjust cache creation criteria for v_advances
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
2025-04-02 15:03:07 -06:00
Behdad Esfahbod
d3e4977c70 [gvar] Comment
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
2025-04-02 14:04:16 -06:00
Behdad Esfahbod
ef8c25ad9f [ot-font] Make advance-cache invalidation threadsafe
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
Hopefully.
2025-04-02 04:00:03 -06:00
Behdad Esfahbod
bbf0c6e781 [font] Bump coords serial if face changed
Such that ot-font clears its advance cache
2025-04-02 02:11:25 -06:00
Behdad Esfahbod
321c14c920
Merge pull request #5236 from harfbuzz/cmap-cache
Some checks failed
arm / arm-none-eabi (push) Waiting to run
fontations / build (push) Waiting to run
configs-ci / build (push) Waiting to run
linux-ci / build (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 2s
[cmap] Move cache from face user-data to cmap accelerator
2025-04-01 21:39:00 -06:00
Behdad Esfahbod
7f5fafec0d [GDEF] Simplify cache declaration 2025-04-01 21:35:28 -06:00
Behdad Esfahbod
8864c264b9 [cmap] Fix initialization 2025-04-01 21:22:16 -06:00
Behdad Esfahbod
3d0816c7c4 [cache] Simplify cache declarations 2025-04-01 21:18:29 -06:00
Behdad Esfahbod
591f00a281 [cmap] Move cache from face to cmap accelerator
No need to use user-data for it.

Fixes https://github.com/harfbuzz/harfbuzz/issues/5235
2025-04-01 21:09:06 -06:00
Behdad Esfahbod
7ebe6b48b6 [cmap] Whitespace 2025-04-01 20:46:55 -06:00
Behdad Esfahbod
4d5348d660 [set-digest] Comments 2025-04-01 18:12:56 -06:00
Behdad Esfahbod
bed2d3dd2b [cache] Add assertion for cache size
Expand cmap cache since free.
2025-04-01 17:52:57 -06:00
Behdad Esfahbod
89ab5f2b21 [cache] Comments 2025-04-01 17:48:08 -06:00
Behdad Esfahbod
48e7e5a008 [cache] Document 2025-04-01 17:43:35 -06:00
Behdad Esfahbod
9f83bbbe64
Merge pull request #5233 from harfbuzz/aat-deleted-glyph-marks
Some checks failed
Scorecard supply-chain security / Scorecard analysis (push) Failing after 2s
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Fix AAT deleted glyph marks interaction with fallback mark positioning
2025-04-01 04:15:24 -06:00
Behdad Esfahbod
91fd40ac7c [shape] Skip hidden / ignorables during fallback mark positioning
Fixes https://github.com/harfbuzz/harfbuzz/issues/5232
2025-04-01 04:03:41 -06:00
Behdad Esfahbod
ca66c64655 [aat] Better handle deleted-glyphs
1. Set their GDEF property. Probably irrelevant to morx shaping.
2. Add them to buffer contents, since that can trigger a state
machine start action too.
2025-04-01 03:25:41 -06:00
Garret Rieger
a1e587b75a [subset] Add hb_subset_cff_get_charstrings_index and hb_subset_cff2_get_charstrings_index.
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
These methods allow retrieving the entire charstrings index structure from a CFF or CFF2 table.
2025-03-31 16:28:28 -06:00
Behdad Esfahbod
a5b00faaf8 Fix build with HB_NO_DRAW 2025-03-31 14:29:16 -06:00
Behdad Esfahbod
d53cbeee41 [font] Fix warnings 2025-03-31 14:29:16 -06:00
dependabot[bot]
7c368dabae Bump setuptools from 77.0.3 to 78.1.0 in /.ci
Bumps [setuptools](https://github.com/pypa/setuptools) from 77.0.3 to 78.1.0.
- [Release notes](https://github.com/pypa/setuptools/releases)
- [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/setuptools/compare/v77.0.3...v78.1.0)

---
updated-dependencies:
- dependency-name: setuptools
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-31 14:23:31 -06:00
dependabot[bot]
674ce63021 Bump github/codeql-action from 3.28.12 to 3.28.13
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.12 to 3.28.13.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](5f8171a638...1b549b9259)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-31 14:23:19 -06:00
dependabot[bot]
4f5b31b7ea Bump actions/setup-python from 5.4.0 to 5.5.0
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.4.0 to 5.5.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](42375524e2...8d9ed9ac5c)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-31 14:23:07 -06:00
Behdad Esfahbod
4cf4099f07 [ot/ft] Round glyph extents instead of floor/ceil
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
1. The floor/ceil was being applied in the wrong order for y direction.
2. If the scale is negative, the floor/ceil should be reversed.

Just round them instead. That's what coretext / directwrite / fontations
font-funcs do.
2025-03-30 22:59:54 -06:00
Behdad Esfahbod
4954edb2b1 [test/vertical] Add more tests
Some checks failed
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
arm / arm-none-eabi (push) Has been cancelled
configs-ci / build (push) Has been cancelled
fontations / build (push) Has been cancelled
linux-ci / build (push) Has been cancelled
macos-ci / build (push) Has been cancelled
msys2 / CLANG64 (push) Has been cancelled
msys2 / MINGW32 (push) Has been cancelled
msys2 / MINGW64 (push) Has been cancelled
msvc / msvc-2019-amd64 (push) Has been cancelled
msvc / msvc-2019-x86 (push) Has been cancelled
2025-03-28 19:19:57 -06:00
Behdad Esfahbod
afa0549dff [fontations] More idiomatic 2025-03-28 18:38:40 -06:00
Behdad Esfahbod
67314b205a [test/vertical] Enable some on fontations 2025-03-28 16:41:41 -06:00
Behdad Esfahbod
c260550ae5 [test/shape] Improve run-tests output on failure 2025-03-28 16:34:12 -06:00
Behdad Esfahbod
18ced8dbb1 [test/vertical] Add more tests 2025-03-28 16:31:46 -06:00
Behdad Esfahbod
17c875c309 [buffer] Minor add a function 2025-03-28 16:26:27 -06:00
Behdad Esfahbod
ea08b04752 [util] Fix --glyphs output with negative numbers 2025-03-28 16:25:58 -06:00
Behdad Esfahbod
cb44134cbf [test/vertical] Test more font-funcs 2025-03-28 15:56:13 -06:00
Behdad Esfahbod
ef95dc0e7f [vmtx] Fix v_origin when no vmtx available 2025-03-28 15:50:05 -06:00
Behdad Esfahbod
c39ac0e171 [ot] Make v_origin work for more glyph formats 2025-03-28 14:24:39 -06:00
Behdad Esfahbod
1358e38154 [fontations] Implement last bits of v_origin 2025-03-28 13:15:37 -06:00
Behdad Esfahbod
1dac21c177 [errors] Add -Wuninitialized
Works with newer clang I think.
2025-03-28 12:44:20 -06:00
Behdad Esfahbod
22f81f70cb [font] Fix var initialization 2025-03-28 12:41:01 -06:00
Behdad Esfahbod
aad5780f53 [font] Move outline emboldening to font layer
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
Such that it works on all font-funcs.
2025-03-28 00:37:20 -06:00
Behdad Esfahbod
83481d65d0 [font] Move emboldening advances to the font layer
Instead of each font-funcs impl.

TODO: Do the same for draw_glyphs.
2025-03-28 00:21:20 -06:00
Behdad Esfahbod
a588761198 [font] Fix void return 2025-03-28 00:09:26 -06:00
Behdad Esfahbod
1f6da390e0 [fontations] Implement one fallback case in get_v_origin 2025-03-27 20:05:13 -06:00
Behdad Esfahbod
449752c57c [fontations] Fix get_v_advances() fallback
Was crashing without vmtx before.
2025-03-27 20:02:08 -06:00
Behdad Esfahbod
b808d1746d [fontations] Move variable scope 2025-03-27 19:52:42 -06:00
Behdad Esfahbod
9d584c4d3d [fontations] Remove stale comment 2025-03-27 19:34:54 -06:00
Behdad Esfahbod
82d664519c [subset] Fix check-symbols test
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
2025-03-27 17:47:56 -06:00
Behdad Esfahbod
7ba0368200 [test] Enable aat-trak on all font funcs now 2025-03-27 17:14:22 -06:00
Garret Rieger
283ab21841 [subset] remove CFF/CFF2 table presence checks.
Not needed now that we are checking accelerator validity.
2025-03-27 16:35:35 -06:00
Behdad Esfahbod
0752e5852b
Merge pull request #5219 from harfbuzz/gid_data
[subset] Add API for retrieving the raw per glyph outline data from CFF and CFF2.
2025-03-27 16:12:14 -06:00
Garret Rieger
ae8b288db7 [subset] Correctly handle lifetime of charstrings data blob returned by hb_subset_cff_get_charstring_data. 2025-03-27 22:07:06 +00:00
Behdad Esfahbod
c50c0a39e5
Merge pull request #5223 from harfbuzz/trak-back
Revert "[ot-font/trak] Move trak application to ot-font instead of ot…
2025-03-27 15:43:49 -06:00
Behdad Esfahbod
b4fd777c23 [aat] Remove hb_aat_layout_get_tracking() again
https://github.com/harfbuzz/harfbuzz/pull/5223
2025-03-27 15:37:01 -06:00
Qunxin Liu
5ebe36e1ac [subset] bug fix for CaretValueFormat3
Don't return false in case of a Hinting Device table
2025-03-27 15:12:42 -06:00
Behdad Esfahbod
208ffb3f1f [coretext-font] Undo tracking in get_[hv]_advances()
Fixes https://github.com/harfbuzz/harfbuzz/issues/5221
2025-03-27 15:10:52 -06:00
Behdad Esfahbod
dda1d95af2 Revert "[ot-font/trak] Move trak application to ot-font instead of ot-shape"
This reverts commits ffae5b040d and
17c11ec523.

Plus manual modifications.

See https://github.com/harfbuzz/harfbuzz/issues/5221
2025-03-27 14:44:52 -06:00
Garret Rieger
0d4053b11d [subset] Add hb-subset.h API for retrieving the raw per glyph outline data from CFF and CFF2. 2025-03-27 20:20:52 +00:00
Behdad Esfahbod
7c90f446c2
Merge pull request #5216 from harfbuzz/manpages
[util] Towards building manpages
2025-03-27 14:13:04 -06:00
Behdad Esfahbod
d47a47e20b [util] Make --help less verbose again
Just the main page gets env-vars, exit-codes, and see-also.
2025-03-27 13:59:08 -06:00
Khaled Hosny
7ab42f9af3 [util] Build man pages only if docs are enabled 2025-03-27 21:31:29 +02:00
Khaled Hosny
9609f50bad [util] Build man page only if the corresponding util is built 2025-03-27 21:31:29 +02:00
Khaled Hosny
9a80c0da84 [util] Install man pages 2025-03-27 21:16:12 +02:00
John Bampton
ba6869848f src: fix spelling in code comments
Co-authored-by: Max Base <MaxBaseCode@gmail.com>
2025-03-27 12:18:07 -06:00
Behdad Esfahbod
7f10c0edfd [util] Towards building manpages
TODO:
1. Only when docs are enabled?
2. Installdir
3. How to include in release?

Fixes https://github.com/harfbuzz/harfbuzz/issues/5208
2025-03-26 22:21:51 -06:00
Behdad Esfahbod
bd5b8a1feb [util] Report exit codes in help
Some checks failed
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
arm / arm-none-eabi (push) Waiting to run
2025-03-26 21:35:32 -06:00
Behdad Esfahbod
e4410a85fa [util] Simplify envvar reporting 2025-03-26 21:35:32 -06:00
Khaled Hosny
a6f563247e [util] Fix Windows build
Windows headers define `environ`.
2025-03-27 03:26:20 +02:00
Behdad Esfahbod
93288a1ced [util] Fix crasher 2025-03-27 03:26:20 +02:00
Behdad Esfahbod
a410a042c7 [util] Add environment and see also sections
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
Part of https://github.com/harfbuzz/harfbuzz/issues/5208
2025-03-26 18:09:07 -06:00
Behdad Esfahbod
4d83b238ea [util] Link to website for more info / reporting bugs
Part of https://github.com/harfbuzz/harfbuzz/issues/5208
2025-03-26 13:01:34 -06:00
Behdad Esfahbod
59001aa952 [util] Add brief --help descriptions
Part of https://github.com/harfbuzz/harfbuzz/issues/5208
2025-03-26 12:33:06 -06:00
Behdad Esfahbod
3d3f241941 [util] Improve help messages a bit
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
Part of https://github.com/harfbuzz/harfbuzz/issues/5208
2025-03-26 01:18:09 -06:00
Behdad Esfahbod
75643768de [util] List available shapers in --help-all
Remove it from --version.

Part of https://github.com/harfbuzz/harfbuzz/issues/5208
2025-03-26 01:00:38 -06:00
Behdad Esfahbod
29c800bd8d [util] Return diff values for diff failures
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 0s
Need documentation in the help output...

Fixes https://github.com/harfbuzz/harfbuzz/issues/5164
2025-03-25 16:55:03 -06:00
Qunxin Liu
192d264ae7 [subset] remove divisions when computing the cost of binary search 2025-03-25 15:37:14 -06:00
Behdad Esfahbod
4d2a362f84 [test/subset] Remove tempdir
Was creating a tempdir in /tmp for every single test item,
and not removing it.  Create one per test file, and remove
if test successful.
2025-03-25 15:36:39 -06:00
Behdad Esfahbod
bed29d1cd3
Merge pull request #5211 from harfbuzz/aots-update
Aots update
2025-03-25 15:19:56 -06:00
Behdad Esfahbod
e16a985798 [test/shape/aots] Add directive to run with ot shaper only 2025-03-25 15:17:23 -06:00
Behdad Esfahbod
851d3e33b5 [aots] Fix compile error
Also requires https://github.com/adobe-type-tools/aots/pull/5 to
be merged. Or if that repo is inactive, we can switch to my fork.
2025-03-25 15:06:24 -06:00
Behdad Esfahbod
2b5f244639 [util] Remove hb-ot-shape-closure
Not used...
2025-03-25 14:12:36 -06:00
Behdad Esfahbod
eec9108416 [test/shape] Adjust uniscribe test 2025-03-25 13:56:12 -06:00
Behdad Esfahbod
fea0c0df33 [fontations] More idiomatic 2025-03-25 12:34:00 -06:00
Behdad Esfahbod
fe51e23738
Merge pull request #5206 from harfbuzz/tests-improvements
Some small test improvements
2025-03-25 12:20:02 -06:00
Khaled Hosny
188531b3ba [circleci] Drop minsize job
It is causing trouble again and it was never that useful.
2025-03-25 19:24:00 +02:00
Khaled Hosny
d81d4dfbd3 [circleci] Lets see of using Ubuntu 24.04 fixes the minsize job 2025-03-25 19:24:00 +02:00
Khaled Hosny
614013940d [test/shape] Update comment 2025-03-25 19:24:00 +02:00
Khaled Hosny
190ad35f71 [test/shape] Don’t skip test if hb-shape --list-* fails
This can happen with Wine when, e.g., `WINEPATH` is not set, and we
would silently skip the tests because lists of supported shapers etc.
are empty.
2025-03-25 16:34:19 +02:00
Khaled Hosny
6cf308c857 [test/shape] Remove @font-funcs-=directwrite from directwrite test
The directwrite font functions support variations now, so this is no
longer needed.
2025-03-25 10:34:43 +02:00
Khaled Hosny
1402ecfecf [test/shape] Use @shapers directive in uniscribe test 2025-03-25 10:33:38 +02:00
Behdad Esfahbod
46a30fe390 [test/shape] Respect @shapers directive
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
2025-03-24 18:23:34 -06:00
Behdad Esfahbod
bb3a55a61a [fontations] Add TODO
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
msys2 / CLANG64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
2025-03-24 17:05:58 -06:00
Behdad Esfahbod
0affe12785 [fontations] Apply variations to glyph_v_advances 2025-03-24 17:00:57 -06:00
Behdad Esfahbod
83d3ffc5d1 [fontations] Hook up variations to v_origin
Output matches ot backend, but not ft. Not gonna dig down there
right now. I *think* ft doesn't implement VORG table IIRC.
2025-03-24 16:58:12 -06:00
Behdad Esfahbod
0ae4b8f48e [fontations] Implement glyph_v_advances
Without variations for now.
2025-03-24 16:45:35 -06:00
Behdad Esfahbod
aa450db1f7 [README.mingw.md] Update for newer meson
https://github.com/mesonbuild/meson/issues/14400
2025-03-24 16:35:51 -06:00
Behdad Esfahbod
10256a9fc7 [README.mingw] Reword 2025-03-24 16:13:14 -06:00
Behdad Esfahbod
6c337ddc24 [README.mingw] Add note re Apple silicon 2025-03-24 16:04:49 -06:00
Christoph Reiter
59c0deba8f [ci/msys2] Remove workaround for meson preferring system libraries
The workaround was added in #4354 to avoid the linker using system harfbuzz
over the just built one.

This is/was most likely https://github.com/mesonbuild/meson/pull/12861
which hopefully should be merged upstream for meson 1.8.

In MSYS2 we have backported this fix for over a year since
https://github.com/msys2/MINGW-packages/pull/20058 so using the meson
package provided by MSYS2 (as is the case here) should avoid the problem
already.
2025-03-24 13:36:00 -06:00
Christoph Reiter
7876aac4eb [ci/msys2] install pkgconf instead of pkg-config
It's the default implementation in MSYS2 and pacman was not installing
it anyway since it conflicted with pkgconf which was required by other
packages earlier in the install list.
2025-03-24 13:36:00 -06:00
Christoph Reiter
4901ecd66e [ci/msys2] Remove winjitdebug workaround
This was added in #3903 to workaround a Python crasher. The issue
has been fixed for a while now, so remove the workaround.
2025-03-24 13:36:00 -06:00
Behdad Esfahbod
589e78cec5 [fontations] Handle recursive clip-glyphs
This reverts 852f66a418 in spirit,
using a malloc-free implementation and keeping the fill-glyph
optimization.
2025-03-24 13:21:56 -06:00
Christoph Reiter
5c3f23c09c [ci/msys2] Add a job building in the clang/llvm environment
Clang is more strict in certain areas and will fail, like
https://github.com/harfbuzz/harfbuzz/pull/5079#issuecomment-2673805310
https://github.com/harfbuzz/harfbuzz/issues/5197

* Add CLANG64 to the matrix
* Install the virtual "cc" package which pulls in the default compiler
  for the respective environment
* Remove gcc-libs, it should be pulled in automatically
* Depend on MSYSTEM_PREFIX for deleting files to be environment agnostic
2025-03-24 20:53:59 +02:00
Behdad Esfahbod
b114518310 [directwrite] Link to library
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 0s
Instead of loading at runtime. I just want to see how CI deals with
this. Otherwise, not depending on dwrite is probably desired.
2025-03-24 15:31:36 +02:00
dependabot[bot]
eda33efc88 Bump ninja from 1.11.1.3 to 1.11.1.4 in /.ci
Bumps [ninja](https://github.com/scikit-build/ninja-python-distributions) from 1.11.1.3 to 1.11.1.4.
- [Release notes](https://github.com/scikit-build/ninja-python-distributions/releases)
- [Changelog](https://github.com/scikit-build/ninja-python-distributions/blob/master/HISTORY.rst)
- [Commits](https://github.com/scikit-build/ninja-python-distributions/compare/1.11.1.3...1.11.1.4)

---
updated-dependencies:
- dependency-name: ninja
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-24 15:18:36 +02:00
Khaled Hosny
c141541159 [circleci] Add timeout multiplier when running tests under wine
We are getting occasional timeout.
2025-03-24 15:17:51 +02:00
dependabot[bot]
2fd2f8e711 Bump setuptools from 76.0.0 to 77.0.3 in /.ci
Bumps [setuptools](https://github.com/pypa/setuptools) from 76.0.0 to 77.0.3.
- [Release notes](https://github.com/pypa/setuptools/releases)
- [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/setuptools/compare/v76.0.0...v77.0.3)

---
updated-dependencies:
- dependency-name: setuptools
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-24 15:14:49 +02:00
dependabot[bot]
b690de572c Bump github/codeql-action from 3.28.11 to 3.28.12
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.11 to 3.28.12.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](6bb031afdd...5f8171a638)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-24 15:14:25 +02:00
dependabot[bot]
9c63dcb3fe Bump actions/upload-artifact from 4.6.1 to 4.6.2
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.1 to 4.6.2.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](4cec3d8aa0...ea165f8d65)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-24 15:14:07 +02:00
Behdad Esfahbod
ba709a385e [dwrite] Fix cast-align error-warning
Fixes https://github.com/harfbuzz/harfbuzz/issues/5197
2025-03-24 02:08:04 -06:00
Behdad Esfahbod
0849d3d8b6 [fontations] Minor shuffle 2025-03-24 02:08:04 -06:00
Behdad Esfahbod
8e1502cce8 [fontations] Implement glyph_v_origin 2025-03-24 02:08:04 -06:00
Khaled Hosny
2ed9c2826a [circleci] Fix YAML lint error [ci skip] 2025-03-24 01:24:39 +02:00
Khaled Hosny
48ce9c397e [ci] Try to fix uploading Windows binaries [ci skip]
We will find out if it works when cutting the next release.
2025-03-24 01:05:24 +02:00
Khaled Hosny
ea6a172f84 11.0.0 2025-03-24 00:33:53 +02:00
Behdad Esfahbod
7599d097c9 [README.mingw] Adjust
Installing system HarfBuzz makes it override our own build.
2025-03-23 15:12:02 -06:00
Behdad Esfahbod
7612ec44dc [util] Show glyph extents only if available 2025-03-23 13:11:23 -06:00
Behdad Esfahbod
391cbed883 [fontations] Support non-uniform scales 2025-03-23 12:58:34 -06:00
Behdad Esfahbod
4cc66435f9
Merge pull request #5188 from harfbuzz/text-rendering-tests-fontations
Text rendering tests fontations
2025-03-23 12:06:54 -06:00
Behdad Esfahbod
74c82b3a29 Blacken 2025-03-23 11:52:45 -06:00
Behdad Esfahbod
f0e260ad73 [text-rendering-tests] Run against ot,ft only
See https://github.com/harfbuzz/harfbuzz/pull/5188
2025-03-23 11:51:58 -06:00
Behdad Esfahbod
af6b6b4828 [README] More 2025-03-23 09:54:49 -06:00
Behdad Esfahbod
4f12035e5d [README.mingw] Update as per recent changes 2025-03-23 09:52:00 -06:00
Behdad Esfahbod
e4b633deb8
Merge pull request #5194 from harfbuzz/test-directwite-variations
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 1s
[test/directwrite] Make the variations test actually test variations
2025-03-23 09:21:47 -06:00
Khaled Hosny
8d62ad3b35 [directwrite] Don’t release IDWriteFace pass to hb_directwrite_font_create
That was a leftover from previous code and is incorrect now as we would
be double releasing it.
2025-03-23 15:40:41 +02:00
Khaled Hosny
c226da8c35 [test/directwrite] Make the variations test actually test variations 2025-03-23 15:40:41 +02:00
Behdad Esfahbod
f48d641483
Merge pull request #5191 from harfbuzz/ci-exe-wrapper
Some checks failed
arm / arm-none-eabi (push) Waiting to run
configs-ci / build (push) Waiting to run
fontations / build (push) Waiting to run
linux-ci / build (push) Waiting to run
macos-ci / build (push) Waiting to run
msvc / msvc-2019-amd64 (push) Waiting to run
msvc / msvc-2019-x86 (push) Waiting to run
msys2 / MINGW32 (push) Waiting to run
msys2 / MINGW64 (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Failing after 7s
Revert "[ci] Don’t set exe_wrapper in the cross files"
2025-03-22 20:36:59 -06:00
Behdad Esfahbod
018858b2ce
Merge branch 'main' into ci-exe-wrapper 2025-03-22 20:24:44 -06:00
Behdad Esfahbod
2421efc17b
Merge pull request #5192 from harfbuzz/dwrite-font-vars
[directwrite] Clean up API / font handling and make variations work on font-funcs
2025-03-22 20:23:29 -06:00
Behdad Esfahbod
3259f9f89a [test-directwrite] Fix test 2025-03-22 20:14:01 -06:00
Behdad Esfahbod
55743b239f [test/shape] Skip uniscribe/directwrite shapers under Wine 2025-03-22 19:56:00 -06:00
Behdad Esfahbod
9afdc7e1d2 [test-directwrite] Simplify 2025-03-22 19:48:15 -06:00
Khaled Hosny
1c7a1c7b04 [test-directwrite] Don’t fail if Bahnschrift can’t be loaded under Wine
It is unlikely to be present if one is not running on Windows.
2025-03-23 02:10:06 +02:00
Khaled Hosny
ed558e5da4 [test] Add name table to test/api/fonts/glyphs.ttf
Some version of Wine fails to load the font otherwise.
2025-03-23 01:28:41 +02:00
Behdad Esfahbod
45a724b90c [coretext] Make font-funcs respond to font changes
Fixes https://github.com/harfbuzz/harfbuzz/issues/5173
2025-03-22 17:20:07 -06:00
Behdad Esfahbod
f53befb6a0 [test/directwrite] Fix a leak 2025-03-22 16:54:56 -06:00
Behdad Esfahbod
b159f5c74e [directwrite] Fix docs 2025-03-22 16:46:43 -06:00
Behdad Esfahbod
298a367ad3 [directwrite] Graduate from experimental 2025-03-22 16:42:56 -06:00
Behdad Esfahbod
24a23aca69 [directwrite] Make font-funcs respond to font changes 2025-03-22 16:41:39 -06:00
Behdad Esfahbod
91bd6bf0df [directwrite] Make variations work on font-funcs 2025-03-22 16:38:56 -06:00
Khaled Hosny
40ef946ec5 [circleci] Set LANG=en_US.UTF-8 on cross-compile jobs
Otherwise GLib fails when running the tests under Wine with:
GLib-WARNING (recursed) **: Failed to determine console output code page: Invalid access.. Falling back to UTF-8
2025-03-23 00:16:02 +02:00
Khaled Hosny
b205a7fbe8 [circleci] Run tests on cross-compile jobs 2025-03-23 00:03:16 +02:00
Behdad Esfahbod
c274ee7b3e [directwrite] Add hb_font_t setter/getter from IDWriteFontFace
Changed API:
+hb_directwrite_font_create()

New API:
+hb_directwrite_font_get_dw_font_face()
2025-03-22 16:02:39 -06:00
Behdad Esfahbod
f0b0d92ab5 [directwrite] Deprecate hb_directwrite_font_get_dw_font() 2025-03-22 15:44:50 -06:00
Behdad Esfahbod
201a0fe361 [coretext] Fix a warning 2025-03-22 15:32:22 -06:00
Behdad Esfahbod
6e17bd374f [README.mingw] Add a couple Ubuntu lines 2025-03-22 15:15:19 -06:00
Khaled Hosny
7153e7814b [circleci] Install wine on cross-compile jobs 2025-03-22 23:09:33 +02:00
Khaled Hosny
8db34adc37 Revert "[ci] Don’t set exe_wrapper in the cross files"
This reverts commit e3dc86bb0f.
2025-03-22 23:04:23 +02:00
Behdad Esfahbod
e0aee5815a [test] Respect MESON_EXE_WRAPPER in more test runners
It's not working for me though. Meson doesn't seem to set WINEPATH
during testing.
2025-03-22 14:56:37 -06:00
Behdad Esfahbod
c3bc5e4c68
Merge pull request #5189 from harfbuzz/font-changed
[font] Simplify changed mechanism
2025-03-22 14:23:07 -06:00
Behdad Esfahbod
6509414227 [fontations] Make serial tracking atomic
Would shut up tsan if we ever tried it on this.
2025-03-22 14:19:34 -06:00
Behdad Esfahbod
977e4f94e0 [font] Simplify changed mechanism 2025-03-22 14:09:26 -06:00
Behdad Esfahbod
8ae92d0d83 [text-rendering-tests] Run against all font-funcs
One test is failing with fontations, and a few with directwrite.
2025-03-22 13:22:37 -06:00
Behdad Esfahbod
51a5618c54 [test] Update text-rendering-tests 2025-03-22 13:20:16 -06:00
Behdad Esfahbod
a388989af4 [README.mingw.md] Final touches, hopefully 2025-03-22 12:31:21 -06:00
Behdad Esfahbod
f7f9cd1296 [README.mingw.md] Review feedback 2025-03-22 11:42:32 -06:00
Behdad Esfahbod
e320109e5d
Merge pull request #5160 from harfbuzz/mingw-readme
[doc] Restore README.mingw.md
2025-03-22 01:30:45 -06:00
Behdad Esfahbod
f9ad7c37b1 [README.mingw.md] Update 2025-03-22 01:20:57 -06:00
Behdad Esfahbod
0b139a81fe [.ci/build-win.sh] Enable tests 2025-03-22 01:05:26 -06:00
Khaled Hosny
4fd4dbb896 [doc] Restore README.mingw.md
It got deleted in cf1fdf1632 but it is
still useful. Needs to be updated to meson world, though.
2025-03-22 00:34:27 -06:00
Behdad Esfahbod
475afee0b8 Change file permission 2025-03-22 00:21:20 -06:00
Behdad Esfahbod
0eeb6ccb42 [perf] Bikeshedding 2025-03-21 17:36:43 -06:00
Behdad Esfahbod
cfb962d73c [fontations] Use the proposed pop_layer_with_mode
Reduces the last Vec use.

https://github.com/googlefonts/fontations/pull/1419
2025-03-21 15:03:28 -06:00
Behdad Esfahbod
9fa31d1ed2 [fontations] Enable lto in dev builds as well
Otherwise our check-symbols test will fail.
2025-03-21 14:44:03 -06:00
Behdad Esfahbod
852f66a418 [fontations] Implement fill-glyph
Gets rid of one Vec.

Supersedes:
https://github.com/harfbuzz/harfbuzz/pull/5180
https://github.com/harfbuzz/harfbuzz/pull/5184
2025-03-21 14:14:12 -06:00
Behdad Esfahbod
c867bc976a [test] Minor, adjust usage 2025-03-21 00:59:35 -06:00
Behdad Esfahbod
a551736532 [test] Add hb-paint-all 2025-03-20 23:23:58 -06:00
Behdad Esfahbod
6a82561f00 [hb-draw-all] Error handling 2025-03-20 23:21:28 -06:00
Behdad Esfahbod
cc0451c949 [cff2] Malloc-free draw of var blends 2025-03-20 20:57:31 -06:00
Behdad Esfahbod
e2a24ce13a
Merge pull request #5177 from harfbuzz/exe_wrapper
[test] Allow running test suite under wine
2025-03-20 19:14:58 -06:00
Behdad Esfahbod
be90974de8 [test/draw] Add meson.build 2025-03-20 19:12:29 -06:00
Behdad Esfahbod
1d25de8316 [test] Add draw/hb-draw-all 2025-03-20 19:11:26 -06:00
Khaled Hosny
e3dc86bb0f [ci] Don’t set exe_wrapper in the cross files
Complicates the build setup. Keep it commented in case one wants to
enable it locally.
2025-03-21 03:02:56 +02:00
Khaled Hosny
a189b0f772 Revert "[ci] Install wine on Windows cross-compile jobs"
This reverts commit ca14981262.
2025-03-21 03:02:19 +02:00
Khaled Hosny
ca14981262 [ci] Install wine on Windows cross-compile jobs 2025-03-21 02:34:40 +02:00
Khaled Hosny
12e31ab7e8 [test] Allow running test suite under wine
Set exe_wrapper in the Windows cross files, which will cause unit tests
to be run with wine.

When we call the binary ourselves, e.g. in shape run-tests.py, we need
to check for MESON_EXE_WRAPPER env var (which meson sets automatically
if exe_wrapper is set) and use it.
2025-03-21 02:27:45 +02:00
Khaled Hosny
14c07dcfa7 [test] Make context-matching test pass with coretext font functions
Remove the CBDT/CBLC tables not needed for the test and a glyf/loca
tables with blank glyphs to make Core Text load the font.
2025-03-20 18:05:30 -06:00
Behdad Esfahbod
b2f7f6db1a
Merge pull request #5165 from harfbuzz/fontations-glyph-name
Fontations glyph name
2025-03-20 14:35:55 -06:00
Behdad Esfahbod
64dcece342 [fontations] Clean up atomic initialization based on review 2025-03-20 14:05:57 -06:00
Behdad Esfahbod
4107cceea1 [fontations] Roll skrifa forward
Tests pass now.
2025-03-20 14:00:06 -06:00
Behdad Esfahbod
c84b9dca24
Merge pull request #5170 from harfbuzz/directwrite-shape-variations
[directwrite] Copy font variations when shaping
2025-03-20 11:18:58 -06:00
Ozkan Sezer
e57e728532 cmake: add missing FT_Get_Transform check 2025-03-20 13:18:45 +02:00
Khaled Hosny
686503e2e0 [directwrite] Copy font variations when shaping 2025-03-20 01:59:56 +02:00
Behdad Esfahbod
24ad0dd46b [fontations] Implement glyph_from_name (with caching) 2025-03-19 16:09:05 -06:00
Behdad Esfahbod
b3d48c2c1b [coretext] Only try setting variations if a variable font
Seems to fix https://github.com/harfbuzz/harfbuzz/issues/5163
2025-03-19 15:16:11 -06:00
Behdad Esfahbod
4822cb7672 [hb-info] Report WebAssembly in technology 2025-03-19 15:14:58 -06:00
Behdad Esfahbod
60ce16f221 [CI] Fix build 2025-03-19 13:22:27 -06:00
Behdad Esfahbod
34b9100c67 [hb-info] Fix argument parsing vs default behavior
Default was if no args other than one font was provided, then
--show-all was enabled. This broke if eg. --face-loader=ft was
provided, then suddenly nothing was shown. Fix it to --show-all
if no "query" options are provided.
2025-03-19 13:15:44 -06:00
Behdad Esfahbod
82e0ff6da0 [fontations] Implement get_glyph_name 2025-03-19 12:52:22 -06:00
Behdad Esfahbod
1a8352cfdb [fontations] Roll skrifa to 0.29 2025-03-19 12:51:29 -06:00
Khaled Hosny
59aee7f3e8 [directwrite] Fix copying variations in hb_directwrite_font_create()
I missed the endianness mismatch between HarfBuzz and DirectWrite tags.
2025-03-19 14:47:22 +02:00
Behdad Esfahbod
0349359ce6 [tests] Fix one test 2025-03-18 14:59:26 -06:00
Behdad Esfahbod
38889c3ad6 [coretext] Fix loading named instances
Needs tests...

TTC indices > 0 can't be loaded with CoreText API it seems.

Fixes https://github.com/harfbuzz/harfbuzz/issues/5158
2025-03-18 03:28:44 -06:00
Behdad Esfahbod
472e65dd0f [cff] Allow empty private dict (again)
Fixes https://github.com/harfbuzz/harfbuzz/issues/5162
2025-03-18 03:17:49 -06:00
Behdad Esfahbod
0ebcc66506 [coretext] Fix glyph bounds 2025-03-17 21:05:21 -06:00
Behdad Esfahbod
696b4a26a8 [coretext] Blocklist one more shape test 2025-03-17 21:05:21 -06:00
Behdad Esfahbod
ad9c473759 [test/shape] Make output less verbose 2025-03-17 21:05:21 -06:00
Behdad Esfahbod
630bc9b45d [coretext] Disable variation-selectors test :-( 2025-03-17 21:05:21 -06:00
Behdad Esfahbod
719dafdaad [test/shape] Allow comments in directives
Also adjust tests for directwrite font-funcs.
2025-03-17 21:05:21 -06:00
Behdad Esfahbod
27bb37c5d0 [test/shape] Fix reporting 2025-03-17 21:05:21 -06:00
Behdad Esfahbod
b24a93c68e [util] Reload face if face-loader changed 2025-03-17 21:05:21 -06:00
Behdad Esfahbod
9a0802dbe5 [test/shape] Comments 2025-03-17 21:05:21 -06:00
Behdad Esfahbod
ee34711d64 [test/shape] Allow directives to instruct what backends to test 2025-03-17 21:05:21 -06:00
Behdad Esfahbod
220a8b9496 [test/shape] Massage script some more 2025-03-17 21:05:21 -06:00
Behdad Esfahbod
7c248cccb5 [test/shape] Var rename 2025-03-17 21:05:21 -06:00
Behdad Esfahbod
3e137c8e8a [test/shape] Minor massage the runner 2025-03-17 21:05:21 -06:00
Behdad Esfahbod
cf1772a492 [test/shape] Compare results without glyph names if needed
Enable fontations font-funcs, which mostly passes now.
2025-03-17 21:05:21 -06:00
Behdad Esfahbod
a37fb2fbf7 [test/shape] Rename a couple of variables 2025-03-17 21:05:21 -06:00
Behdad Esfahbod
24f9fd46ce [test/shape] Restart hb-shape --batch process if killed 2025-03-17 21:05:21 -06:00
Behdad Esfahbod
5b3bf25bb8 [test/shape] Test all font-funcs backends if none specified
Disable fontations as it doesn't implement glyph names currently.
2025-03-17 21:05:21 -06:00
Behdad Esfahbod
f16196a00e [test-shape] Assume ot shaper is default 2025-03-17 21:05:21 -06:00
Behdad Esfahbod
0d5795c0a5 [test/shape] Report shaper, face-loader, font-funcs 2025-03-17 21:05:21 -06:00
Behdad Esfahbod
aacc667e51 [test/shape/run-tests] Streamline testing other backends 2025-03-17 21:05:21 -06:00
Behdad Esfahbod
cdfbb7efb9 [ci] Massage cross-win building
Move install dir inside build dir.
2025-03-17 18:02:08 -06:00
Khaled Hosny
ee15f723fd [ci] Remove the unused second argument to build-win.sh 2025-03-18 01:33:23 +02:00
Khaled Hosny
9298b31046 [ci] Pass the rest of arguments to meson 2025-03-18 01:26:43 +02:00
Khaled Hosny
286e832854 [ci] Use release buildtype when cross-compiling 2025-03-17 22:03:59 +02:00
Khaled Hosny
a520ee9503 [ci] Simplify cross-build script
Tell meson to strip the binaries and call meson install so they are
actually striped, and copy binaries from install dir.
2025-03-17 22:03:59 +02:00
Khaled Hosny
d65fd65608 [ci] Explicitly disabled more auto options when cross-compiling 2025-03-17 22:03:59 +02:00
Khaled Hosny
1a7b31f260 [ci] Fix meson deprecation warning
DEPRECATION: c_args in the [properties] section of the machine file is deprecated, use the [built-in options] section.
DEPRECATION: c_link_args in the [properties] section of the machine file is deprecated, use the [built-in options] section.
DEPRECATION: cpp_args in the [properties] section of the machine file is deprecated, use the [built-in options] section.
DEPRECATION: cpp_link_args in the [properties] section of the machine file is deprecated, use the [built-in options] section.
2025-03-17 22:03:59 +02:00
Khaled Hosny
7272abc35e [ci] Merge build-win32.sh and build-win64.sh 2025-03-17 22:03:59 +02:00
Khaled Hosny
6a50badb57 [ci] Disable libffi tests
They don’t build on MingW with -fno-exceptions
2025-03-17 17:41:27 +02:00
Khaled Hosny
4dc25e7066 [ci] Add libffi warp with fallback download URL
To fix failing CI runs because freedesktop.org is down.
2025-03-17 17:41:27 +02:00
Behdad Esfahbod
f9aabf7062
Merge pull request #5156 from harfbuzz/coretext-variations-always
[coretext] Always set all variation axes
2025-03-17 09:02:41 -06:00
Behdad Esfahbod
38db0f4c12 [coretext] Always set all variation axes 2025-03-17 08:51:39 -06:00
Behdad Esfahbod
6ccfadb911
Merge pull request #5153 from harfbuzz/coretext-variations
[coretext] Always set all variations
2025-03-16 21:12:14 -06:00
Behdad Esfahbod
422ffff15c [coretext] Always set all variations
Even when at default, looks like this is necessary.

Fixes https://github.com/harfbuzz/harfbuzz/issues/5142
2025-03-16 21:03:46 -06:00
Behdad Esfahbod
bd2bf3536c
Merge pull request #5152 from harfbuzz/fix-trak-finding
[trak] Fix track finding logic
2025-03-16 17:30:57 -06:00
Behdad Esfahbod
a9a3fd33a2 [trak] Fix track finding logic 2025-03-16 17:10:19 -06:00
Behdad Esfahbod
0a991cc543
Merge pull request #5151 from harfbuzz/slant-extents
[font] Move synthetic glyph extents into font layer
2025-03-16 11:46:44 -06:00
Behdad Esfahbod
14e5a046c8 [font] Move synthetic glyph extents into font layer
So it applies to all font-funcs.
2025-03-16 01:02:55 -06:00
Behdad Esfahbod
a95a500d3d
Merge pull request #5149 from harfbuzz/dwrite-fontfuncs
[directwrite] Add fontfuncs

Fixes #5143.
2025-03-15 21:27:17 -06:00
Behdad Esfahbod
8d8fe19099 [dwrite] Add font-funcs sketch
Small steps.

Fixes https://github.com/harfbuzz/harfbuzz/issues/5144
2025-03-15 21:03:30 -06:00
Behdad Esfahbod
08781f6f7d [dwrite] Set face index / glyph_count on hb-face 2025-03-15 20:05:01 -06:00
Behdad Esfahbod
93f8cbf4fa [meson] Add missing .hh files to sources
Manually checked with find and grep...
2025-03-15 19:23:52 -06:00
Behdad Esfahbod
6958064c7f
Merge pull request #5148 from harfbuzz/paint-font-transform
[paint] Add push_font_transform() / push_inverse_font_transform()
2025-03-15 18:45:00 -06:00
Behdad Esfahbod
000a0ad7a6 [paint] Add push_font_transform() / push_inverse_font_transform()
Fixes https://github.com/harfbuzz/harfbuzz/issues/5146
2025-03-15 18:35:32 -06:00
Behdad Esfahbod
e6519fcb2b
Merge pull request #5147 from harfbuzz/dwrite2
[dwrite] More work
2025-03-15 14:27:04 -06:00
Behdad Esfahbod
e1d395f4b5 [dwrite] Minor cleanup 2025-03-15 14:13:02 -06:00
Behdad Esfahbod
db8d099d4d [dwrite] Split shape code into its own file 2025-03-15 13:59:16 -06:00
Behdad Esfahbod
13849d4205 [dwrite] More cleanup 2025-03-15 13:25:49 -06:00
Behdad Esfahbod
e9d5ecca1d [directwrite] Simplify more 2025-03-15 13:15:03 -06:00
Behdad Esfahbod
d2b722803f [directwrite] Rely on more reference-counting for lifetime 2025-03-15 12:55:27 -06:00
Behdad Esfahbod
41d722c3d2 [directwrite] Remove unused member 2025-03-15 12:52:24 -06:00
Behdad Esfahbod
9d6e24a1d2 [draw] Fix build 2025-03-14 22:32:17 -06:00
Behdad Esfahbod
c1ed463195 [fontations] rustfmt 2025-03-14 22:14:28 -06:00
Behdad Esfahbod
bd05b260af [draw] Document slant_xy 2025-03-14 22:10:29 -06:00
Behdad Esfahbod
da4758e791 [draw] Apply synthetic slant to hb_draw_move_to() etc
Makes fontations draw slanted as well.

Fixes https://github.com/harfbuzz/harfbuzz/issues/5145
2025-03-14 22:07:45 -06:00
Behdad Esfahbod
b3a293813a [directwrite] Minor cleanup 2025-03-14 17:26:33 -06:00
Behdad Esfahbod
bda5b832b0 [directwrite] Mutex for font registration 2025-03-14 03:40:15 -06:00
Behdad Esfahbod
09d983258b [directwrite] Rename a function 2025-03-14 03:13:32 -06:00
Behdad Esfahbod
d441b4cbc7
Merge pull request #5140 from harfbuzz/directwrite-loader
[directwrite] Add hb_directwrite_face_create_from_blob_or_fail()
2025-03-14 03:05:26 -06:00
Behdad Esfahbod
e92cd9f769 [directwrite] Massage more
I think this is it!
2025-03-14 02:46:11 -06:00
Behdad Esfahbod
1e9d101ed7 [directwrite] Add hb_directwrite_face_create_from_file_or_fail()
Just loads the blob from file and creates a face from it.

New API:
+hb_directwrite_face_create_from_file_or_fail()
2025-03-14 02:14:23 -06:00
Behdad Esfahbod
c73b54bcca [directwrite] Massage more 2025-03-14 02:09:01 -06:00
Behdad Esfahbod
db93dbb286 [directwrite] More cleanup 2025-03-14 01:50:08 -06:00
Behdad Esfahbod
9e5a767855 [directwrite] Add singleton dwrite_dll 2025-03-14 01:22:05 -06:00
Behdad Esfahbod
64716226d2 [directwrite] Shuffle code around 2025-03-14 01:13:04 -06:00
Behdad Esfahbod
27fc376fe9 [directwrite] Addd lifecycle management to a few of objects 2025-03-13 18:27:59 -06:00
Behdad Esfahbod
aacaa8bba3 [directwrite] Flip loader & stream around 2025-03-13 17:18:31 -06:00
Behdad Esfahbod
2502d0b698 [directwrite] Use blob directly in the interface 2025-03-13 17:00:50 -06:00
Behdad Esfahbod
d0fef9a1fc [directwrite] Don't release the library
It crashes. Going to fix it to use a singleton, but for now
just not crash.
2025-03-13 16:56:47 -06:00
Behdad Esfahbod
ad3225c648 [direcwrite] Make blob immutable 2025-03-13 16:30:09 -06:00
Behdad Esfahbod
00360049e3 [directwrite] Handle failures in new API
Still crashes...
2025-03-13 16:22:45 -06:00
Behdad Esfahbod
f6744c2c73 [ci] Add pkg-config to win cross-compiling environment 2025-03-13 15:55:57 -06:00
Behdad Esfahbod
379688c566 [test-face] Relax on face load failure 2025-03-13 14:47:34 -06:00
Behdad Esfahbod
344915c9ea [face] Hook up directwrite face loader 2025-03-13 14:30:56 -06:00
Behdad Esfahbod
b0a5920d1a [directwrite] Add hb_directwrite_face_create_from_blob_or_fail()
Part of https://github.com/harfbuzz/harfbuzz/issues/5082

New API:
+hb_directwrite_face_create_from_blob_or_fail()
2025-03-13 14:27:37 -06:00
Behdad Esfahbod
7e4698abe2 [coretext] Move more code around 2025-03-13 14:16:08 -06:00
Behdad Esfahbod
471ac1cdc0
Merge pull request #5139 from harfbuzz/set-malloc-fix
[set] Fix reallocation
2025-03-13 13:41:43 -06:00
Behdad Esfahbod
5f61ccf07d [set] Fix reallocation
Was shrinking malloced vectors inadverently.
2025-03-13 13:22:28 -06:00
Behdad Esfahbod
a0fbd25e10
Merge pull request #5138 from harfbuzz/kerx-malloc
[kern/kerx]  zero-malloc
2025-03-13 12:01:01 -06:00
Behdad Esfahbod
c2f8066b2f [aat] Fix another malloc-fail crasher 2025-03-13 11:43:03 -06:00
Behdad Esfahbod
b57d2a2050 [aat] Fix a leak 2025-03-13 11:19:48 -06:00
Behdad Esfahbod
d6f5cbdd8c [aat] Fix a compiler warning 2025-03-13 11:14:54 -06:00
Behdad Esfahbod
64240602b4 [aat] Fix memfail crash 2025-03-13 10:56:39 -06:00
Behdad Esfahbod
7b8ae3d067 [kern/kerx] Make zero-malloc 2025-03-13 10:44:40 -06:00
Behdad Esfahbod
0f18838c69 [mort] Update with morx change 2025-03-13 08:52:19 -06:00
Behdad Esfahbod
a115228329
Merge pull request #5137 from harfbuzz/aat-mallocs
[aat] Reduce mallocs
2025-03-13 08:32:30 -06:00
Behdad Esfahbod
e5a01efd07 [aat] Put back one set of compiled map in the plan
Use it if there's no user features. Reduces mallocs.
2025-03-13 02:47:20 -06:00
Behdad Esfahbod
7b48aa37a7 [aat] Reduce mallocs
Untested.
2025-03-13 01:07:35 -06:00
Behdad Esfahbod
792b9b9337 [bit-vector] Add a has() 2025-03-12 23:56:52 -06:00
Behdad Esfahbod
43d421d388 [aat] Speed up deleted-glyph removal 2025-03-12 23:36:09 -06:00
Behdad Esfahbod
aa233ecedc [bit-vector] Add a hb_bit_vector_t type
Unused.
2025-03-12 23:05:04 -06:00
Behdad Esfahbod
402876d489
Merge pull request #5136 from harfbuzz/kerx-fix
Kerx fix
2025-03-12 22:48:59 -06:00
Behdad Esfahbod
c38d518718 [aat/kerx] Fix initial-glyph collection logic
Test:
$ hb-shape GeezaPro.ttc --unicodes U+064A,U+064E,U+0651,U+0629
2025-03-12 22:39:33 -06:00
Behdad Esfahbod
2449eb0882 [aat] Adjust filtering to match collect_glyphs() 2025-03-12 21:03:24 -06:00
Behdad Esfahbod
6388ce2224 [kerx] We don't need right_set in machine kerning 2025-03-12 20:58:06 -06:00
Behdad Esfahbod
b861b54178 [kerx] Cosmetic 2025-03-12 20:56:16 -06:00
Behdad Esfahbod
7146e5818f [kerx] Remove redundant check 2025-03-12 20:11:30 -06:00
Behdad Esfahbod
41b396c64b [kerx] Setup buffer glyphset 2025-03-12 20:02:58 -06:00
Behdad Esfahbod
83e0944f0f [kerx] Use a machine class cache
Like in morx.
2025-03-12 19:58:35 -06:00
Behdad Esfahbod
02733deded [kerx] Skip machine subtables that don't intersect the buffer
We do this extensively in morx. Do it here too.

Still no machine class cache in kerx.

Speeds up GeezaPro shaping Arabic text by 20%.
2025-03-12 19:44:07 -06:00
Behdad Esfahbod
45b2d28d04 Revert "[aat] Clear buffer glyph set"
This reverts commit b1a9219ac5.

Was unnecessary. collect_codepoints() clears the set.
2025-03-12 19:18:12 -06:00
Behdad Esfahbod
d76a23a3f1 [aat] Micro-optimize 2025-03-12 19:16:59 -06:00
Behdad Esfahbod
b1a9219ac5 [aat] Clear buffer glyph set
Should be clear already but no harm.
2025-03-12 19:13:14 -06:00
Behdad Esfahbod
54962b3fce [morx] Consolidate a check 2025-03-12 19:03:50 -06:00
Behdad Esfahbod
4807a021a1 [atomic] Kill hb_atomic_ptr_t<T>
Use hb_atomic_t<T *> instead.
2025-03-12 18:27:27 -06:00
Behdad Esfahbod
829d1eda16 [atomic] Clean up atomic_ptr_t 2025-03-12 18:19:04 -06:00
Behdad Esfahbod
a0d76c5b37 [atomic] Templatize 2025-03-12 17:16:55 -06:00
Behdad Esfahbod
bdee8658c6 [post] Fix a pointer type 2025-03-12 17:13:48 -06:00
Behdad Esfahbod
469502c99b [test-paint] Test fontations too
Luckily it passes!
2025-03-12 11:02:43 -06:00
Behdad Esfahbod
fbb81e344b [fontations] Adjust alignment requirement 2025-03-12 00:52:12 -06:00
Behdad Esfahbod
8d300049f5 [fontations] Assert layout alignment 2025-03-12 00:43:10 -06:00
Behdad Esfahbod
05cfdb9105 [fontations] link_with instead of link_whole
Now that the hb-fontations symbol is called from libharfbuzz,
it gets pulled in properly.
2025-03-12 00:08:42 -06:00
Behdad Esfahbod
0b2a0bac47
Merge pull request #5130 from harfbuzz/malloc-rust
[fontations] Make fontations use hb_malloc et al
2025-03-11 23:04:11 -06:00
Behdad Esfahbod
5bf81c3758 [common] Make hb_malloc() et al public
New API:
+hb_malloc()
+hb_calloc()
+hb_realloc()
+hb_free()
2025-03-11 22:52:34 -06:00
Behdad Esfahbod
a2c7dc0669
Merge pull request #5133 from harfbuzz/hb-coretext.cc
[coretext] Split common code into hb-coretext.cc
2025-03-11 20:43:32 -06:00
Behdad Esfahbod
f0a67e9948 [coretext] Split common code into hb-coretext.cc 2025-03-11 20:37:30 -06:00
Behdad Esfahbod
d014efd03d
Merge pull request #5131 from harfbuzz/using2
Add hb_ft_face_create_from_blob_or_fail() et al
2025-03-11 13:37:48 -06:00
Behdad Esfahbod
759e1881e8 [coretext] Fix loading TTC files 2025-03-11 12:46:27 -06:00
Behdad Esfahbod
15fcfcb606
Merge pull request #5129 from harfbuzz/buffer-deserialize
Fix buffer deserialize
2025-03-11 12:01:20 -06:00
Behdad Esfahbod
5e6da54166 [test] Minor, accept absolute font paths 2025-03-11 12:00:18 -06:00
Behdad Esfahbod
8687f5c38e [face] Add tests for new constructors 2025-03-11 11:56:00 -06:00
Behdad Esfahbod
8e8a9f6f40 [face] Add hb_face_create_or_fail_using()
Fixes https://github.com/harfbuzz/harfbuzz/issues/5117

Untested.

New API:
+hb_face_create_or_fail_using
2025-03-11 11:56:00 -06:00
Behdad Esfahbod
cbc205c2f0 [font/face] Refactor some code 2025-03-11 11:56:00 -06:00
Behdad Esfahbod
b1c50eb938 [face] Rename a variable 2025-03-11 11:56:00 -06:00
Behdad Esfahbod
f98c203e7a [coretext] Add hb_coretext_face_create_from_blob_or_fail()
Part of https://github.com/harfbuzz/harfbuzz/issues/5117

Untested.

New API:
+hb_coretext_face_create_from_blob_or_fail()
2025-03-11 11:56:00 -06:00
Behdad Esfahbod
8ca9fe7617 [face] Avoid edit-sanitizing in hb_face_count() 2025-03-11 11:56:00 -06:00
Behdad Esfahbod
e4fe8bf95e [ft] Add hb_ft_face_create_from_blob_or_fail()
Part of https://github.com/harfbuzz/harfbuzz/issues/5117

Untested.

New API:
+hb_ft_face_create_from_blob_or_fail()
2025-03-11 11:56:00 -06:00
Behdad Esfahbod
3c30562dc7
Merge pull request #5132 from harfbuzz/cplusplus-more
[test-cplusplus] Add more headers
2025-03-11 11:55:46 -06:00
Behdad Esfahbod
756668d35c [directwrite] Drop dependency again as per review
https://github.com/harfbuzz/harfbuzz/pull/5132#issuecomment-2714186460
2025-03-11 11:27:02 -06:00
Behdad Esfahbod
6b2f859232 [test-c] Disable gobject include
It can't find its dependent headers since not installed.
2025-03-11 00:37:11 -06:00
Behdad Esfahbod
8ca892b0e2 [directwrite] Simplify headers 2025-03-11 00:24:11 -06:00
Behdad Esfahbod
d247c116fb [test-draw] Test all font funcs 2025-03-11 00:15:40 -06:00
Behdad Esfahbod
d2ccf595bd Directwrite is a C++ header? 2025-03-11 00:15:19 -06:00
Behdad Esfahbod
41dcc493e5 [test-cplusplus] Simplify 2025-03-10 23:49:05 -06:00
Behdad Esfahbod
57deae5fd4 [meson] Check correct dependency
Ouch!
2025-03-10 23:40:22 -06:00
Behdad Esfahbod
dbad6cdfec [test-c(plusplus)] Add more headers 2025-03-10 23:23:16 -06:00
Behdad Esfahbod
3c02fcd0e8 [test-multithread] Simplify 2025-03-10 23:16:30 -06:00
Behdad Esfahbod
4323c6643b [fontations] Make fontations use hb_malloc et al 2025-03-10 20:09:34 -06:00
Behdad Esfahbod
7a912c4746 [buffer-deserialize] Fix return value and parsing
I think I got it right.

Alternative to https://github.com/harfbuzz/harfbuzz/pull/5028
2025-03-10 16:20:16 -06:00
Behdad Esfahbod
c2e92b6f7b [ragel] Update output files 2025-03-10 16:18:48 -06:00
Behdad Esfahbod
5a03844914 [gen-ragel-artifacts] Fail if ragel failed 2025-03-10 14:54:13 -06:00
dependabot[bot]
2edab536bd Bump setuptools from 75.8.2 to 76.0.0 in /.ci
Bumps [setuptools](https://github.com/pypa/setuptools) from 75.8.2 to 76.0.0.
- [Release notes](https://github.com/pypa/setuptools/releases)
- [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/setuptools/compare/v75.8.2...v76.0.0)

---
updated-dependencies:
- dependency-name: setuptools
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-10 14:57:08 +02:00
dependabot[bot]
18e9550579 Bump github/codeql-action from 3.28.10 to 3.28.11
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.10 to 3.28.11.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](b56ba49b26...6bb031afdd)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-10 14:56:55 +02:00
Behdad Esfahbod
9c0ac9aec4
Merge pull request #5069 from harfbuzz/cluster-level-graphemes
[buffer] Add HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES
2025-03-10 02:52:26 -06:00
Khaled Hosny
8ee8e0a213 [ci] Enable doc_tests on linux-ci only
One workflow is enough.
2025-03-10 10:36:55 +02:00
Khaled Hosny
885eef8ea5 [buffer/doc] Add docs for the new cluster level macros 2025-03-10 10:34:43 +02:00
Behdad Esfahbod
d8a774c011 [test] Add test for new grapheme cluster level 2025-03-10 01:04:35 -06:00
Behdad Esfahbod
f88fe4d403 [util] Update for new grapheme cluster level 2025-03-10 01:02:56 -06:00
Behdad Esfahbod
1531be8a1d [buffer] Add docs for the new cluster level 2025-03-10 01:02:11 -06:00
Behdad Esfahbod
9305aae476 [ot-layout] Revert back logic 2025-03-10 00:52:00 -06:00
Behdad Esfahbod
7518718671 [buffer] Add HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES
https://github.com/harfbuzz/harfbuzz/discussions/5026#discussioncomment-12168668
2025-03-10 00:52:00 -06:00
Behdad Esfahbod
62c320a2d6
Merge pull request #5126 from harfbuzz/aat-deleted-glyph-more
[aat/morx] Use a separate bit for deleted-glyphs
2025-03-09 21:02:48 -06:00
Behdad Esfahbod
0b62666ece [aat/morx] Use a separate bit for deleted-glyphs
Should address:
https://github.com/harfbuzz/harfbuzz/pull/5119#issuecomment-2709170388
2025-03-09 19:38:32 -06:00
Behdad Esfahbod
bcbd1df3dd
Merge pull request #5125 from harfbuzz/fontations-serial
[fontations] Check for font serial change automatically
2025-03-09 19:03:05 -06:00
Behdad Esfahbod
e77fb46335 [fontations] Do double-checked locking
See if tsan likes this. It liked the previous version.
2025-03-09 18:53:36 -06:00
Behdad Esfahbod
780809fb0c [fontations] Check for font serial change automatically
Let's see what tsan thinks... I also have not profiled this.

It also doesn't hold the mutex for the whole use time. It
probably should or bad things might happen.
2025-03-09 18:43:47 -06:00
Behdad Esfahbod
9f8e7ebf24
Merge pull request #5119 from harfbuzz/aat-deleted-glyph
[AAT] Clean up deleted-glyph handling
2025-03-09 18:09:58 -06:00
Behdad Esfahbod
ff76244ea6 [aat/morx] Delete deleted glyphs again
But also check for default-ignorable bit this time.
2025-03-09 17:24:40 -06:00
Behdad Esfahbod
dc048b7c88 [aat/morx] Set glyph props consistently 2025-03-09 16:53:24 -06:00
Behdad Esfahbod
4ec560dd02 [aat/morx] Refactor all glyph replacements into the context 2025-03-09 16:53:24 -06:00
Behdad Esfahbod
c6972ac6dd [aat] Towards removing special deleting of 0xFFFF
See https://github.com/harfbuzz/harfbuzz/discussions/5118

Remove the removal. Depend on the default_ignorable flag
to hide them later.

Test output adjusted.
2025-03-09 16:53:24 -06:00
Behdad Esfahbod
ec4d4b01e8 [morx] Update buffer on changes, in one more place
Was missed out before I believe.
2025-03-09 16:53:24 -06:00
Behdad Esfahbod
c88e819965 Fix compiler warning 2025-03-09 16:53:03 -06:00
Behdad Esfahbod
d067f2b224 [font] get_acquire() the serial 2025-03-09 06:17:48 -06:00
Behdad Esfahbod
0a01fc558b
Merge pull request #5122 from harfbuzz/using
Add API for querying font-funcs / face-loaders and setting them using strings
2025-03-09 05:28:09 -06:00
Behdad Esfahbod
ec6f99c5ea [fontations] Give clippy test more time 2025-03-09 05:18:13 -06:00
Behdad Esfahbod
9e639e676a [face] Review 2025-03-09 05:10:50 -06:00
Behdad Esfahbod
1e812e43b3 [ft] Another try at making tsan happy maybe 2025-03-09 03:39:52 -06:00
Behdad Esfahbod
7791f50e3a [ft] Use a lock-guard 2025-03-09 03:34:28 -06:00
Behdad Esfahbod
aa268fc8ef [font/ft] See if tsan is happy with atomic_int_t serials 2025-03-09 03:31:01 -06:00
Behdad Esfahbod
6ae7ef0659 [ft] See if I can make tsan happy 2025-03-09 03:19:22 -06:00
Behdad Esfahbod
a83faa061c [ft] Automatically pick up font serial changes
Part of https://github.com/harfbuzz/harfbuzz/issues/5124
2025-03-09 03:07:45 -06:00
Behdad Esfahbod
402f89cb79 [face] Rename a variable 2025-03-09 01:52:28 -07:00
Behdad Esfahbod
5cf1fa3add [face] Fix docs 2025-03-09 01:47:23 -07:00
Behdad Esfahbod
2ecc68c12f [face] Fix HB_LEAN build 2025-03-09 01:46:07 -07:00
Behdad Esfahbod
6b9d9f7259 [face] Add HB_FACE_LOADER env var 2025-03-09 01:41:49 -07:00
Behdad Esfahbod
9d05b03f83 [font] Add HB_FONT_FUNCS work into hb_font_set_funcs_using() 2025-03-09 01:34:37 -07:00
Behdad Esfahbod
39ade99d47 [face] Two new APIs:
+ hb_face_create_from_file_or_fail_using()
+ hb_face_list_loaders()
2025-03-09 01:25:52 -07:00
Matthias Clasen
79c991e143 Improve docs for feature and variation serialization
Clarify that the serialized forms of features and variations
won't have any whitespace in them. This can help for parsing
when embedding these strings into larger serializations.
2025-03-08 18:00:43 -07:00
Behdad Esfahbod
50ea460b93 Review 2025-03-08 16:07:44 -07:00
Behdad Esfahbod
43ff0f73cc [fontations] Relax dependency numbers 2025-03-08 13:30:10 -07:00
Behdad Esfahbod
437ce95059 [util] Add --list-font-funcs 2025-03-08 13:12:15 -07:00
Behdad Esfahbod
68b07475a7 [font-funcs] Support HB_FONT_FUNCS env var 2025-03-08 12:41:50 -07:00
Behdad Esfahbod
5a12bf417b [font-funcs-using] Treat empty string like nullptr 2025-03-08 12:31:07 -07:00
Behdad Esfahbod
712a403bec [font-funcs-using] Apply review feedback 2025-03-08 12:23:41 -07:00
Behdad Esfahbod
fae9d2ab27 [fontations] Add dependencies 2025-03-08 12:15:25 -07:00
Behdad Esfahbod
e8ddb4325b [fontations] Consolidate args a bit 2025-03-08 12:13:31 -07:00
Behdad Esfahbod
c3eac5c0f3 [test-threads] Test all font-funcs
Fontations & Coretext are new and seems to pass.
2025-03-08 11:57:31 -07:00
Behdad Esfahbod
2a878b1b76 [font-funcs] Add two new API
+ hb_font_set_funcs_using()
+ hb_font_list_funcs()

Part of https://github.com/harfbuzz/harfbuzz/issues/5117
2025-03-08 11:50:53 -07:00
Khaled Hosny
e9348cd76d [ci] Port minsize job from Alpine to Ubuntu
Alpine is frequently failing with compiler crashing, but we don’t really
need Alpine. No other job building with --buildtype=minsize, so keep it
but use Ubuntu.
2025-03-08 12:43:49 +02:00
Behdad Esfahbod
27fa1c4229
Merge pull request #5120 from harfbuzz/fontations-shrink
Fontations shrink
2025-03-07 22:01:23 -07:00
Behdad Esfahbod
080bd09db3 [fontations/ci] Fix 2025-03-07 21:48:17 -07:00
Behdad Esfahbod
3f6da0a367 [fontations] Run rustfmt & clippy as tests 2025-03-07 21:43:34 -07:00
Behdad Esfahbod
4bb7f61050 [fontations] Minor remove a type 2025-03-07 21:33:53 -07:00
Behdad Esfahbod
aabf8aadf8 [fontations] Use proper meson function for running commands 2025-03-07 21:32:05 -07:00
Behdad Esfahbod
52852c6cb6 [check-symbols] Ignore another rust symbol 2025-03-07 21:28:25 -07:00
Behdad Esfahbod
77314a3be7 [check-symbols] Don't run c++filt
For adding to ignore list, we want to see the original symbol
name. One can always c++filt themselves.
2025-03-07 21:19:09 -07:00
Behdad Esfahbod
5c01d8298c [fontations/ci] Try to fix 2025-03-07 21:15:08 -07:00
Behdad Esfahbod
bd66336d45 [fontations] Add clippy-check target 2025-03-07 21:13:28 -07:00
Behdad Esfahbod
8fd718c9eb [fontations] Add fmt-check target 2025-03-07 21:09:17 -07:00
Behdad Esfahbod
a68f458612 [fontations] Make 'ninja -Cbuild clippy' apply fixes 2025-03-07 21:05:59 -07:00
Behdad Esfahbod
f7cb3a3c8e [ci/fontations] Directly ask for nightly 2025-03-07 21:00:13 -07:00
Behdad Esfahbod
6c1f27faab [fontations] Disable overflow-checks 2025-03-07 18:38:54 -07:00
Behdad Esfahbod
514b28af3c [fontations] Pass optimization-level from meson to rustc 2025-03-07 18:37:17 -07:00
Behdad Esfahbod
55ca000b0e [fontations] Re-enable check-symbols test
Now that we build with lto, not many extra symbols are exported.
Ignore them.
2025-03-07 18:20:57 -07:00
Behdad Esfahbod
73f1c2ba43 Just a chmod a+x two Python scripts 2025-03-07 18:19:29 -07:00
Behdad Esfahbod
ecb9e393f2 [fontations] Shrink the library more 2025-03-07 17:57:11 -07:00
Behdad Esfahbod
493bf07596 [fontations] One more shrinkage 2025-03-07 17:50:20 -07:00
Behdad Esfahbod
78b3234396 [fontations] Shrink a bit more
Going through ideas from:
https://github.com/googlefonts/use-skrifa?tab=readme-ov-file
https://github.com/johnthagen/min-sized-rust
2025-03-07 17:48:38 -07:00
Behdad Esfahbod
52ad51382a [fontations] Enable lto
Makes library size shrink by half, as well as remove all the cruft
from the public symbol list.
2025-03-07 17:45:31 -07:00
Behdad Esfahbod
4e5358a288 [COLRv1] Fix comments
Fixes https://github.com/harfbuzz/harfbuzz/issues/5116
2025-03-07 15:18:28 -07:00
Behdad Esfahbod
e27e7f1c7d [perf] README minor 2025-03-07 14:01:57 -07:00
Behdad Esfahbod
460a8225ba [perf] Improve README 2025-03-07 13:33:08 -07:00
Behdad Esfahbod
575e70b063 [COLR] Use palette 0 if palette index out of range
Fixes https://github.com/harfbuzz/harfbuzz/issues/5112
2025-03-07 12:51:44 -07:00
Matthias Clasen
41e14f7029 [test-paint] Use latest test fonts
Update the color test fonts from https://github.com/googlefonts/color-fonts/
repository and update the test results.
2025-03-07 10:48:46 -07:00
Khaled Hosny
b8b56c4a67 [directwrite] Add comment [ci skip] 2025-03-07 14:30:53 +02:00
Khaled Hosny
a356603061 [directwrite/test] Add test that actually works
Apparently DirectWrite does not allow disabling calt in Arabic, so test
liga in Latin and ss01 in Arabic.
2025-03-07 14:30:53 +02:00
Khaled Hosny
9abaf193d3 [directwrite] Fix applying features to directwrite shaper
The range_features was ending up with random data because
hb_ms_make_feature_ranges() keeps pointers to data allocated in
feature_records and range_records, but that data was getting freed
before range_features was used. Change the variable scope to avoid
freeing the data too early.

Fixes https://github.com/harfbuzz/harfbuzz/issues/5113
2025-03-07 14:30:53 +02:00
Behdad Esfahbod
fe8a3972dd [fontations] Speed up glyph_extents if x_scale == y_scale 2025-03-06 23:52:08 -07:00
Behdad Esfahbod
abc468275b [fontations] Cache GlyphMetrics objects 2025-03-06 23:50:05 -07:00
Behdad Esfahbod
6506bd7e82
Merge pull request #4498 from harfbuzz/PaintColrLayers
[COLRv1] Optimize PaintColrLayers instead of PaintComposite
2025-03-06 20:00:54 -07:00
Matthias Clasen
9fbc2d23b5 [test-paint] Regenerate the test output
This commit updates the expected output of the paint tests
to what the current code produces.
2025-03-06 20:11:23 -05:00
Matthias Clasen
0ce90f60ab [test-paint] Make it easier to regenerate test output
This command will regenerate the expected output for all the
paint tests:

GENERATE_DATA=1 G_TEST_SRCDIR=./test/api ./build/test/api/test-paint
2025-03-06 20:10:13 -05:00
Behdad Esfahbod
bf55e33287 [ft-colr] Protect against out-of-bounds color indices 2025-03-06 17:38:50 -07:00
Behdad Esfahbod
8685653cc7 [ft-colr] Fix crash if palette index is out-of-range 2025-03-06 17:28:09 -07:00
Behdad Esfahbod
ad9fa13d23 [fontations] Render nothing if palette index out of range
Matches ot. Ft crashes currently.
2025-03-06 17:25:56 -07:00
Behdad Esfahbod
cd45a7f531 [fontations] Add a constructor 2025-03-06 16:11:01 -07:00
Behdad Esfahbod
44705c1acb [fontations] Fix clippy target
To build in the build dir
2025-03-06 15:34:27 -07:00
Simon Cozens
cda4b56bfe "where" not needed for trait impl 2025-03-06 15:29:21 -07:00
Simon Cozens
e8bed99b16 Banish static lifetimes 2025-03-06 15:29:21 -07:00
Behdad Esfahbod
1147c0e1ca [fontations] Clean up data passing 2025-03-06 14:57:06 -07:00
Behdad Esfahbod
ad0bcec378 [cairo] More printf removal 2025-03-06 14:51:06 -07:00
Behdad Esfahbod
0d70cfacb2 Revert accidental changes 2025-03-06 14:50:39 -07:00
Behdad Esfahbod
77a319daa6 [fontations] Fix color-line extend fetching
This fixes the last bug I know.
2025-03-06 14:48:51 -07:00
Garret Rieger
fc8334d96b Final cleanups. 2025-03-06 14:04:37 -07:00
Garret Rieger
a20138dcfc More cleanups 2025-03-06 14:04:37 -07:00
Garret Rieger
f379505d4d Add struct_at/struct_at_mut helpers for accessing c arrays. 2025-03-06 14:04:37 -07:00
Khaled Hosny
123a0d68a1 Use gnu_printf format annotation under MingW with GCC only
Fixes https://github.com/harfbuzz/harfbuzz/issues/5106
2025-03-06 22:21:35 +02:00
Khaled Hosny
462a54895b [ci] Use newer Ubuntu release for cross compilation
Cairo sets -D_FORTIFY_SOURCE when building with optimizations, but it
was broken in some MingW releases. Updating seems to fix it.
2025-03-06 22:08:13 +02:00
Khaled Hosny
3985939842 Reapply "[meson] Add buildtype=debugoptimize by default"
This reverts commit 958e2c5331.
2025-03-06 22:08:13 +02:00
Behdad Esfahbod
597a934368 [fontations] Add target fmt for rustfmt 2025-03-06 12:50:42 -07:00
Behdad Esfahbod
4a3329dafb [fontations] Fix clippy rule 2025-03-06 12:46:35 -07:00
Behdad Esfahbod
4b035ae611 Fix build 2025-03-06 12:44:49 -07:00
Behdad Esfahbod
34a919b980 [fontations] Clippy 2025-03-06 12:42:42 -07:00
Behdad Esfahbod
547027837e [fontations] Add clippy target 2025-03-06 12:40:50 -07:00
Behdad Esfahbod
d9b1101de6 [fontations] Mark the whole public function unsafe 2025-03-06 12:06:12 -07:00
Behdad Esfahbod
b5d2ec4f83 [fontations] clippy 2025-03-06 12:02:12 -07:00
Behdad Esfahbod
92af2e47fc [fontations] Do a bounds check 2025-03-06 11:33:22 -07:00
Khaled Hosny
3ce6b720ac [fontations] slice::from_raw_parts requires the pointer to be non-null 2025-03-06 04:23:24 +02:00
Khaled Hosny
aecc9110a3 [fontations/test] Add to test-draw 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
a6d295fa1e [fontations] Disable symbol check
Since all of rust crates become public symbols. Sigh.
2025-03-06 04:23:24 +02:00
Khaled Hosny
6b035cd7b7 [fontations] Make check-header-guards happy 2025-03-06 04:23:24 +02:00
Khaled Hosny
83e58980a6 [fontations/ci] Fix package name 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
91f4a67d5d [fontations] Fix translucent foreground colors 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
43e82682c5 [cairo] Fix infinite loop in sweep-gradient code
Tested with U+F1314 from var font from:
https://github.com/googlefonts/color-fonts/blob/main/glyph_descriptions.md
2025-03-06 04:23:24 +02:00
Khaled Hosny
2c11c9db52 [ci] Give fontations a try 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
dedc05c220 [paint] Fix typo in radial-gradients! 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
9b4eaff867 [fontations] Fix palette handling
What a pain...
2025-03-06 04:23:24 +02:00
Behdad Esfahbod
3a699c3764 [fontations] Fix anchor unreduction 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
b5ad6de8d6 [fontations] Unreduce LinearGradient anchors
Oh well...
2025-03-06 04:23:24 +02:00
Behdad Esfahbod
a2d9c29b08 [fontations] Comment 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
b5a04a9600 [fontations] Fix sweep gradients 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
e10e5c3764 [fontations] Implement sweep gradients
Untested. Also, radial gradients seem faulty.
2025-03-06 04:23:24 +02:00
Behdad Esfahbod
865d75ef30 [fontations] Implement radial gradients 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
d72968efac [fontations] Refactor make_color_line 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
4b1f655a83 [fontations] Implement LinearGradients 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
1a39f8935e [fontations] Implement solid paint 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
5b27f32876 [fontations] Implement most of paint API 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
d069e79016 [fontations] Fix pointer unsafe play 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
dbc04d1c7d [fontations] Roll skrifa forward
Remove the rest.
2025-03-06 04:23:24 +02:00
Behdad Esfahbod
6e472748d7 [fontations] Set Location only if non-zero 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
024e9356eb [fontations] Use a slice 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
3f57f76e99 [fontations] Cache OutlineGlyphCollection
As advised by Chad.  Speeds up drawing benchmark 2x.
2025-03-06 04:23:24 +02:00
Behdad Esfahbod
c4932fa57a [fontations] Fix life-cycle double-free 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
e054db4ae2 [fontations] Hook up to benchmark-font 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
ea5a14f7bc [fontations] Implement draw_glyph 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
87c62f4ebb [fontations] Boilerplate for draw_glyph 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
bc2851b407 [fontations] Implement font_h_extents 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
b9a4d148c9 [fontations] Implement get_glyph_extents 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
f2e5955e1e [fontations] Cache a x_size and y_size 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
166e630768 [fontations] Implement get_variation_glyph 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
83e85d2ac1 [fontations] rustfmt 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
156b77327e [fontations] Don't derive Copy et al since our types are not 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
74bd99e40e [fontations] Set font variations 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
7a65fdcabf [fontations] Cache location 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
c969c2dec0 [fontations] Cache Size 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
d19e45a1f5 [fontations] Support buildtype debugoptimized really 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
51c68eb29d [fontations] Cache charmap 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
f400d8b30c [fontations] Pass meson buildtype to cargo 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
1705723d7e [fontations] Cache static fontfuncs object 2025-03-06 04:23:24 +02:00
Khaled Hosny
7871ee5b6c [fontations/meson] Use link_whole instead of link_with
Instead of passing `--whole-archive` manually to the linker which has a
different name on macOS linker.
2025-03-06 04:23:24 +02:00
Khaled Hosny
c6d2e9e855 [fontations/doc] Add section 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
afe1af8fa9 [fontations] Implement get_nominal_glyphs()
Shapes now.
2025-03-06 04:23:24 +02:00
Behdad Esfahbod
e801e484f1 [fontations] Remove get_glyph_h_advance() 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
1390da5d12 [fontations] Implement get_glyph_h_advances() 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
94a6cfba89 [fontations] Working get_glyph_advance() 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
77b20cf7b9 Update src/hb-fontations.h
Co-authored-by: Khaled Hosny <khaled@aliftype.com>
2025-03-06 04:23:24 +02:00
Behdad Esfahbod
0113c86a2f [fontations] Hide internal symbols 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
71accd5e14 [fontations] Hide one symbol
How do I hide the other internal extern "C" symbols?
2025-03-06 04:23:24 +02:00
Behdad Esfahbod
9d754188c6 [meson] Fix unintended change to coretext 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
9439e1fdad [fontations] Links finally 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
6cac2a1ae0 [fontations] Ouch 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
395270e494 [fontations] Try folding into libharfbuzz 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
2a06b85d4e [fontations] Try using an intermediate library
Still doesn't link.
2025-03-06 04:23:24 +02:00
Behdad Esfahbod
f28daba53c [fontations] I don't know... 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
161b20f333 Try building with cargo 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
e806c9ae2a [fontations] Only require rust if building with fontations 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
e1c934421a [fontations] More experiments 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
db6431f140 [fontations] Fix a warning 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
bed809bc6b [fontations] Add to docs
Module itself undocumented so far.
2025-03-06 04:23:24 +02:00
Behdad Esfahbod
26da19f6ea Kinda builds now with bindgen
Requires nightly.
2025-03-06 04:23:24 +02:00
Behdad Esfahbod
3ba4266daa [fontations] bindgen hb.rs 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
f9b4706151 [fontations] Use as dependency, not library
Since it's optional.
2025-03-06 04:23:24 +02:00
Behdad Esfahbod
2abe54fc9c Almost works! 2025-03-06 04:23:24 +02:00
Behdad Esfahbod
ad8e4a29b9 [fontations] Start building a libharfbuzz-fontations 2025-03-06 04:23:24 +02:00
Patrik Weiskircher
ca3cd48fa3 Fix memory leak in hb_coretext_get_glyph_name 2025-03-04 16:59:21 +02:00
Behdad Esfahbod
718542ef7a [util] Space 2025-03-03 22:45:15 -07:00
Behdad Esfahbod
c544028700 [meson] Remove -Wno-non-virtual-dtor
No idea why it was there to begin with. We control warnings
from hb.hh.
2025-03-04 05:36:01 +02:00
Behdad Esfahbod
958e2c5331 Revert "[meson] Add buildtype=debugoptimize by default"
This reverts commit c4b572a24c.

This broke CI. Reverting till we figure it out.
2025-03-03 20:22:35 -07:00
Behdad Esfahbod
c4b572a24c [meson] Add buildtype=debugoptimize by default
Fixes https://github.com/harfbuzz/harfbuzz/issues/5103
2025-03-03 19:13:34 -07:00
Behdad Esfahbod
50fe45f43c [COLR] Fix memory leak 2025-03-03 16:31:41 -07:00
Alfred Wingate
628b868f44 meson: refactor freetype dependency logic
Simplify and respect -Dfreetype=disabled again.

Bug: https://bugs.gentoo.org/950274
Fixes: 1ad48fddd0
See-Also: 604fe80707
Signed-off-by: Alfred Wingate <parona@protonmail.com>
2025-03-04 01:12:05 +02:00
Behdad Esfahbod
9c6b6998ef [VARC] Fix sign of returned extents 2025-03-03 11:48:17 -07:00
dependabot[bot]
2a471ed125 Bump setuptools from 73.0.1 to 75.8.2 in /.ci
Bumps [setuptools](https://github.com/pypa/setuptools) from 73.0.1 to 75.8.2.
- [Release notes](https://github.com/pypa/setuptools/releases)
- [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/setuptools/compare/v73.0.1...v75.8.2)

---
updated-dependencies:
- dependency-name: setuptools
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-03 11:33:11 -07:00
Behdad Esfahbod
e9134c8ce3 [COLR] Reduce malloc pressure
By caching paint-extents.
2025-03-03 02:18:49 -07:00
Behdad Esfahbod
9efd17e225 [COLR] Switch to using (existing) accelerator 2025-03-03 02:17:13 -07:00
Behdad Esfahbod
17ddc84406 [VARC] Fix scratch caching 2025-03-03 01:27:32 -07:00
Behdad Esfahbod
a62058eee8 [VARC] Separate varc scratch from glyf scratch 2025-03-03 01:19:52 -07:00
Behdad Esfahbod
3199d1c1f5 [VARC] Use a context object to pass arguments around 2025-03-02 18:35:46 -07:00
Behdad Esfahbod
e0c6c98025 [VARC] Implement get_extents()
Fixes https://github.com/harfbuzz/harfbuzz/issues/5007
2025-03-02 16:56:20 -07:00
Behdad Esfahbod
d1826ca626 [TupleValues] Fix regression
Introduced in 043980a60e
2025-03-02 15:45:35 -07:00
Behdad Esfahbod
d9628a5643 [MultiVarData] Micro-optimize 2025-03-02 13:00:55 -07:00
Behdad Esfahbod
c81b1c43b1 [MultiVarData] Remove a likely 2025-03-02 12:43:28 -07:00
Behdad Esfahbod
ad0a5c93b5 [vector] Add fast path in extend() for length-known iterators 2025-03-01 16:02:10 -07:00
Behdad Esfahbod
7e3c96582f [VARC] Reuse parent MultiVarStore cache if coords didn't change
Minor optimization; applicable to the test hangul font mostly.
2025-03-01 15:09:58 -07:00
Khaled Hosny
3ef8709829 10.4.0 2025-03-01 00:59:49 +02:00
Behdad Esfahbod
75ce774bc3 [gvar] Use a method for add_delta 2025-02-28 15:25:23 -07:00
Khaled Hosny
532ed228e7 [docs] Move all deprecated APIs to the deprecated section 2025-02-28 23:56:03 +02:00
Khaled Hosny
69e1c3c352 [ft] Add hb_ft_font_get_ft_face()
A new name for hb_ft_font_get_face(), which is now deprecated.

Fixes  https://github.com/harfbuzz/harfbuzz/issues/5084
2025-02-28 23:56:03 +02:00
Khaled Hosny
484e8d4997 [directwrite] Add hb_directwrite_face_get_dw_font_face()
A new name for hb_directwrite_face_get_font_face(), which is now
deprecated.

Part of https://github.com/harfbuzz/harfbuzz/issues/5084
2025-02-28 23:56:03 +02:00
Behdad Esfahbod
8226f597ac [decycler] Add a couple more tests 2025-02-28 13:49:44 -07:00
Behdad Esfahbod
64dbeaf0f4 [glyf] Mover decycler to the scratch pad 2025-02-28 01:13:25 -07:00
Behdad Esfahbod
d59d435ec6 [decycler] Comments 2025-02-27 22:41:03 -07:00
Behdad Esfahbod
cb781f53aa [BASE] Fix a TODO item 2025-02-27 10:15:22 -07:00
Khaled Hosny
1a759886d9 Improve GitHub Actions badges [ci skip] 2025-02-27 15:45:28 +02:00
Khaled Hosny
527a209674 Remove Codacy badge [ci skip]
It takes long time on PRs and no one actually looks into its reports.
The service has just been disabled and the badge is a dead link now.
2025-02-27 15:31:56 +02:00
Behdad Esfahbod
4be765c083 Fix config build 2025-02-27 02:26:08 -07:00
Behdad Esfahbod
4a43373aec [MultiVarData] Unroll another loop 2025-02-26 17:24:28 -07:00
Behdad Esfahbod
00541f1952
Merge pull request #4970 from harfbuzz/GVAR
Add `GVAR` table
2025-02-26 16:22:48 -07:00
Behdad Esfahbod
a0543453de [CBDT] Change has_data() to be more accurate
get_length() was returning the Null table length if table
was not present.
2025-02-26 15:36:03 -07:00
Behdad Esfahbod
7504c67fb7 [CBDT] Return immediately if no data 2025-02-26 15:24:40 -07:00
Behdad Esfahbod
9d149c5284 [test-paint] Redirect generated output to stderr 2025-02-26 15:07:46 -07:00
Behdad Esfahbod
753093d60e [test-colrv1] Add test files from https://roettsch.es/var_colrv1.html
These are not currently used for any testing. To be used later.
2025-02-26 14:41:04 -07:00
Behdad Esfahbod
6fe1441782 [test-paint] Update comment 2025-02-26 14:40:08 -07:00
Behdad Esfahbod
17a83b748e [COLRv1] Optimize PaintColrLayers instead of PaintComposite
See https://github.com/googlefonts/colr-gradients-spec/issues/369#issuecomment-1816913943
and onwards.
2025-02-26 14:40:02 -07:00
Behdad Esfahbod
44b7ba51a3 [GVAR] Hide behind HB_NO_BEYOND_64K 2025-02-26 14:21:15 -07:00
Behdad Esfahbod
13900ce40d [GVAR] Hook up to face and glyf table 2025-02-26 14:21:15 -07:00
Behdad Esfahbod
ffe955b9f9 [GVAR] Change offsetToData size to 24bit
As per https://github.com/harfbuzz/boring-expansion-spec/issues/162
2025-02-26 14:21:15 -07:00
Behdad Esfahbod
894fee6db3 [GVAR] Implement table
Unused. It's just like `gvar` but with 24bit glyphCount.
2025-02-26 14:21:15 -07:00
Behdad Esfahbod
4d3642c188 [face] Fix a malloc fail infinite-loop error 2025-02-26 14:20:45 -07:00
Behdad Esfahbod
6fbd6bb34e [face] Avoid infinite-loop in building a face blob 2025-02-26 14:06:35 -07:00
Behdad Esfahbod
6a7b4dcae6 [VARC] Reduce stack usage on 32bit systems 2025-02-26 13:25:50 -07:00
Behdad Esfahbod
84ffb7e477 [SimpleGlyph] Minor use an intermediate variable 2025-02-26 12:53:58 -07:00
Behdad Esfahbod
54db2b2ed6 [SimpleGlyph] Remove a conditional from hot path
5% speedup in Roboto-Regular draw benchmark
2025-02-26 12:53:52 -07:00
Behdad Esfahbod
bb4d37b052 [VARC/coord-setter] Reduce stack allocation on 32bit systems 2025-02-26 12:17:27 -07:00
Behdad Esfahbod
51d3489ca1 [Composite] Fix memory-free rendering 2025-02-26 12:09:31 -07:00
Behdad Esfahbod
a037d3815f [vector] Fix operator = 2025-02-26 12:05:12 -07:00
Behdad Esfahbod
59e6a1c477 [glyf/Composite] Malloc-free 2025-02-26 11:34:04 -07:00
Behdad Esfahbod
3c4cb472d1 [VARC] Fix uninitialized value
Fixes https://oss-fuzz.com/testcase-detail/6089638800588800
2025-02-26 10:48:36 -07:00
Behdad Esfahbod
fcbf14a0e5 [CompositeGlyph] Adjust pre-allocation 2025-02-25 20:16:18 -07:00
Behdad Esfahbod
6ca8852eff [glyf] Return earlier if table is empty 2025-02-25 19:57:43 -07:00
Behdad Esfahbod
0cd98ebbf7 [vector] Add a missing fast-path 2025-02-25 18:53:04 -07:00
Behdad Esfahbod
41626401b0 [vector] Add faster extend() for array types 2025-02-25 18:48:34 -07:00
Behdad Esfahbod
aaf5c06d62 [vector] Rewrite copy_array() to extend vector 2025-02-25 18:45:38 -07:00
Behdad Esfahbod
40c77a1c5a Remove a redundant method 2025-02-25 18:37:20 -07:00
Behdad Esfahbod
81339256da [gvar] Rename two variables 2025-02-25 18:02:26 -07:00
Behdad Esfahbod
87830b62c6 [gvar] Remove unused method 2025-02-25 18:02:26 -07:00
Behdad Esfahbod
7614320a13 [glyf] Reduce malloc pressure
Benchmark 15% faster for draw.
2025-02-25 16:59:37 -07:00
Behdad Esfahbod
882d328839 [glyf] Port to decycler for composite glyphs
5% speed up drawing Roboto-Regular.ttf.
2025-02-25 16:35:32 -07:00
Behdad Esfahbod
ffee85d67f [VARC] Minor simplify pointer math 2025-02-25 16:20:42 -07:00
Behdad Esfahbod
dcb80ecbd9 [gvar] Use a method 2025-02-25 15:58:37 -07:00
Behdad Esfahbod
23937e8cd5 [gvar] Combine two loops 2025-02-25 15:48:23 -07:00
Behdad Esfahbod
9b451f2055 [gvar] Minor remove a variable 2025-02-25 15:16:09 -07:00
Behdad Esfahbod
7222c1e50f [path-builder] Add a constexpr 2025-02-25 15:13:20 -07:00
Behdad Esfahbod
e450552d07 [coord-setter] Fix memory access in case of malloc failure
Fixes https://oss-fuzz.com/testcase-detail/5383702943432704
2025-02-25 14:54:37 -07:00
Behdad Esfahbod
b12612f525 Fix compiler warnings 2025-02-25 13:47:06 -07:00
Behdad Esfahbod
8280ef7d93
Merge pull request #5089 from harfbuzz/vector-explicit
[vector] Disallow accidental creation of transient vectors
2025-02-25 12:18:43 -07:00
Garret Rieger
ea1434b897 Split iup glyf partial instance tests into a separate set which ignores due to IUP rounding differences fonttools. 2025-02-25 19:02:11 +00:00
Behdad Esfahbod
aaecaa4c0e [vector] Disallow accidental creation of transient vectors
Fix sites that were doing this under our feet.

This lowers precision of some instancing operations from double
to float, which modifies a few results by rounding error.

TODO: Update tests.
2025-02-25 19:02:11 +00:00
Behdad Esfahbod
f71faf5fec [VARC] Fix buffer scratch borrowing 2025-02-25 11:35:21 -07:00
Behdad Esfahbod
e76b689fe1 [VARC] Fix resource leak 2025-02-25 11:23:48 -07:00
Behdad Esfahbod
827be1b23c Revert "[MultiVarStore] Micro-optimize"
This reverts commit 13d98f1ded.

This broke bots. I don't fully understand why tests pass locally.
2025-02-25 10:23:10 -07:00
Behdad Esfahbod
13d98f1ded [MultiVarStore] Micro-optimize 2025-02-25 01:40:19 -07:00
Behdad Esfahbod
9a0cf8d641 [test/subset/cff-japanese] Shrink test
Was taking too long.
2025-02-25 00:19:25 -07:00
Behdad Esfahbod
084fb3ab4f [test/subset/cmap] Shrink test
Was taking more than the rest of the test suite combined.
2025-02-25 00:16:27 -07:00
Behdad Esfahbod
51d8ef48d9 [gvar] Cache shared_indices as well 2025-02-25 00:09:28 -07:00
Behdad Esfahbod
47124e6337 [VARC] Avoid creating cache if there's no VARC table 2025-02-24 23:25:50 -07:00
Behdad Esfahbod
d5d199fbc7 [VARC] Reduce malloc pressure
By caching one hb_glyf_scratch_t on the VARC accelerator.
2025-02-24 23:20:12 -07:00
Behdad Esfahbod
2c5ab14aaa [coord-setter] Increase static array size 2025-02-24 22:50:42 -07:00
Behdad Esfahbod
a058a1f223 [TupleValues] Unroll a loop 2025-02-24 21:53:17 -07:00
Behdad Esfahbod
13ee8edf06 [vector] Speed up extend() 2025-02-24 21:17:58 -07:00
Behdad Esfahbod
46485124ea [vector] Simplify a method 2025-02-24 21:04:34 -07:00
Behdad Esfahbod
6fe550306c [TupleValues] Don't overshadow end() method 2025-02-24 20:57:30 -07:00
Behdad Esfahbod
97a5c52af4 [VARC/MultiVarStore] Reduce malloc pressure more 2025-02-24 20:53:19 -07:00
Behdad Esfahbod
6938ee0342 [VARC] More nuanced caching 2025-02-24 20:44:15 -07:00
Behdad Esfahbod
74bb7c52f3 Fix a compiler warning 2025-02-24 20:21:38 -07:00
Behdad Esfahbod
081fcbdf5a [VARC] Minor move variable closer to use 2025-02-24 20:15:24 -07:00
Behdad Esfahbod
0a1b26b862 [coord-setter] Reduce malloc pressure
~15% speedup benchmark-font draw of varc-hanzi.ttf
2025-02-24 20:07:59 -07:00
Behdad Esfahbod
76c3beaf36 [VARC] Reduce malloc overhead 2025-02-24 19:50:51 -07:00
Behdad Esfahbod
2099db378a [TupleValues] Optimize decoding 2025-02-24 15:13:08 -07:00
Behdad Esfahbod
043980a60e [TupleValues] Micro-optimize 2025-02-24 11:23:11 -07:00
dependabot[bot]
474c6e43a6 Bump github/codeql-action from 3.28.9 to 3.28.10
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.9 to 3.28.10.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](9e8d0789d4...b56ba49b26)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-24 13:23:08 +02:00
dependabot[bot]
22e5469cec Bump ossf/scorecard-action from 2.4.0 to 2.4.1
Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.4.0 to 2.4.1.
- [Release notes](https://github.com/ossf/scorecard-action/releases)
- [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md)
- [Commits](62b2cac7ed...f49aabe0b5)

---
updated-dependencies:
- dependency-name: ossf/scorecard-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-24 13:22:54 +02:00
dependabot[bot]
5f23b9767a Bump actions/upload-artifact from 4.6.0 to 4.6.1
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.0 to 4.6.1.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](65c4c4a1dd...4cec3d8aa0)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-24 13:22:43 +02:00
Behdad Esfahbod
1ba907209f [VARC] Speed up MultiVarData::get_delta 2025-02-23 21:52:30 -07:00
Khaled Hosny
e41dc20c1c [directwrite] Fix -Wcast-align warning
https://github.com/harfbuzz/harfbuzz/pull/5079#issuecomment-2673805310
2025-02-21 10:38:52 +02:00
Khaled Hosny
694ffa8747 10.3.0 2025-02-20 23:56:59 +02:00
Khaled Hosny
03cf1565f5 [directwrite] Rename font_get_font to font_get_dw_font
https://github.com/harfbuzz/harfbuzz/pull/5079#pullrequestreview-2627407692
2025-02-20 22:16:22 +02:00
Khaled Hosny
f012442f98 Annotate printf functions with gnu_printf format under MingW
Fixes https://github.com/harfbuzz/harfbuzz/issues/5080
2025-02-20 21:53:14 +02:00
Khaled Hosny
a8fd29718a [directwrite] Add hb_directwrite_font_create()/font_get_font()
Uses hb_directwrite_face_create() under the hood, but copies variations
from directwrite to hb-font.
2025-02-20 21:40:27 +02:00
Behdad Esfahbod
7cf634290f [ot-layout] Use a variable
Doesn't make a diff in the generated code I believe,
but is nice.
2025-02-20 12:23:57 -07:00
Khaled Hosny
e28bcf58b1 Typo [ci skip] 2025-02-20 20:58:50 +02:00
Behdad Esfahbod
a2ea5d28cb [benchmark-font] Report draw times in ms, not us 2025-02-18 21:43:39 -07:00
Behdad Esfahbod
2032da0117 [ot-font] Centralize painting an outline glyph 2025-02-18 20:54:56 -07:00
Behdad Esfahbod
01f02f55a1 [COLR] Optimize NoVariation codepath 2025-02-18 20:28:48 -07:00
Behdad Esfahbod
4c263ecd00
Merge pull request #5074 from harfbuzz/tortoise-hare
[decycler] Implement an efficient graph cycle detector
2025-02-18 20:08:19 -07:00
Behdad Esfahbod
f26d9514b1 [COLR] Fix HB_LEAN build 2025-02-18 20:07:25 -07:00
Behdad Esfahbod
0bb72eeed0 [decycler] Turn off compiler warning
../src/OT/Var/VARC/../../../hb-decycler.hh:108:25: warning: storing the address of local variable ‘node’ in ‘*&c_15(D)->layers_decycler.hb_decycler_t::tortoise’ [-Wdangling-pointer=]
2025-02-18 20:02:56 -07:00
Behdad Esfahbod
c84e9b95be [decycler] Change value type from unsigned to uintptr_t
Since the node struct is gonna be 3*sizeof(void*) bytes anyway,
change value type to use the full space available.
2025-02-18 20:02:56 -07:00
Behdad Esfahbod
1c18646dd6 [decycler] Reduce stack use, kinda
Move the bool to the decycler from the node. The value can now become
a full pointer size (next commit).
2025-02-18 20:02:56 -07:00
Behdad Esfahbod
fb0e181a3e [decycler] Reduce stack use further
Down to three pointers. Exercise for the reader to prove this is
optimal.
2025-02-18 20:02:56 -07:00
Behdad Esfahbod
646da80c41 [decycler] Reduce stack use
Down from 5 pointers to 4.
2025-02-18 20:02:56 -07:00
Behdad Esfahbod
5aea89b5c4 [decycler] Don't leave a dangling pointer around
Even if it was never accessed.
2025-02-18 20:02:56 -07:00
Behdad Esfahbod
c7fc03a33a [ft-colr] Use hb_decycler_t 2025-02-18 20:02:56 -07:00
Behdad Esfahbod
bedc8d9373 [decycler] Document algorithm 2025-02-18 20:02:56 -07:00
Behdad Esfahbod
2bdf985022 [decycler] Add alternative way of using it to tests 2025-02-18 20:02:56 -07:00
Behdad Esfahbod
3cb4971729 [decycler] Add some documentation 2025-02-18 20:02:56 -07:00
Behdad Esfahbod
0667ceae87 [VARC] Reduce stack use 2025-02-18 20:02:56 -07:00
Behdad Esfahbod
4335e49a02 [VARC] Port to hb-decycler-t
5% faster on varc-hanzi test case.
2025-02-18 20:02:56 -07:00
Behdad Esfahbod
a0f83e783f [decycler] Reduce stack use
48bytes -> 40bytes per node.
2025-02-18 20:02:56 -07:00
Behdad Esfahbod
d5faabe7ea [decycler] Add test 2025-02-18 20:02:56 -07:00
Behdad Esfahbod
0aa400b1d8 [decycler] Implement an efficient graph cycle detector
This is an algorithm I came up with, based on the Floyd's
Tortoise-Hare constant-memory linear-time linked-list cycle-detection
algorithm.

https://en.wikipedia.org/wiki/Cycle_detection#Floyd's_tortoise_and_hare

It is linear-time and malloc-free. It *eventually* detects cycles,
not immediately.

The main different with Floyd's algorithm is that this algorithm
detects cycles when one is traversing down a graph, not just a
linked list.

Our existing cycle-detection algorithms use a set-of-integers,
either hb_set_t, or more efficient in this case, hb_map_t. Those
include at least one malloc, and as such show up on profiles.

Port hb-ot-font COLRv1 to use the decycler instead of previous
hb_map_t usage for cycle detection.

benchmark-font paint_glyph on NotoColorEmoji-Regular.ttf:
Before: 8ms; After: 5.5ms. No cycle detection: 5.5ms.

FT COLRv1 API is so slow (174ms) it's not worth porting to this.
Other graphs (VARC, etc) to be ported.

Test and documentation to be added.
2025-02-18 20:02:56 -07:00
Behdad Esfahbod
ed76c8559e [COLR] Optimize palette access 2025-02-18 20:01:36 -07:00
Behdad Esfahbod
016e78b683 [COLR] Micro-optimize 2025-02-18 19:49:48 -07:00
Behdad Esfahbod
e6eec3cc14 [test] Silence compiler warning 2025-02-18 00:48:49 -07:00
Jim-Wang
b97ef6c702 add dep 2025-02-16 09:29:28 +02:00
Behdad Esfahbod
215c8de3cd [ft-colr] Fix cycle-detection accounting
Fixes https://github.com/harfbuzz/harfbuzz/issues/5073
2025-02-15 21:08:14 -07:00
Khaled Hosny
ff3aaece6d [test/shape-plan] Add another test and some comments 2025-02-14 21:54:30 +02:00
Khaled Hosny
cf336f17b2 [shape-plan] Rename hb_ot_shape_plan_get_features to get_feature_tags
Simplify the API by returning only feature tags. The users of this API
would be interested only in feature enabled by default and whether the
feature is globally or partially enabled wouldn’t be of much interest in
that case. For user features, the user of the API already have full
access to them.
2025-02-14 21:54:30 +02:00
Khaled Hosny
a7d7715f10 [shape-plan] Add hb_ot_shape_plan_get_features
This should get the features on a shape plan after executing it.

Initially I wanted to return an array of tags, but then there can be
user features that are not enabled globally, so I thought returning
hb_feature_t with value and range would be better. There is a TODO since
I couldn’t figure out how to get the value and range from the feature
mask. But also it may be overkill and a simple boolean indicating wither
it is a global feature or not would be enough.

I wounder also what should happen to non-user features that are applied
selectively, like init or medi, does ot make sense to indicate whether
they are global or not?

This is inspired by the discussion in:
https://github.com/fontforge/fontforge/pull/5522#pullrequestreview-2574321449,
but it might be useful to other HarfBuzz users.
2025-02-14 21:54:30 +02:00
Khaled Hosny
bcd5aa368d [docs/coretext] Fix hb_coretext_font_set_funcs() documentation
Remove the note that fonts created with hb_coretext_font_create() have
these font functions configured for them, which is not true.

hb_coretext_font_create() documents this correctly.
2025-02-13 17:39:50 -07:00
Behdad Esfahbod
d2a88fbd7b [vector] Add alloc_exact() 2025-02-12 21:52:01 -05:00
Khaled Hosny
94584d14d3 [coretext] Use vector instead of malloc/free a C-array 2025-02-12 14:21:09 +02:00
Khaled Hosny
1bc87dfed2 [coretext] Handle allocation failures 2025-02-12 14:21:09 +02:00
Khaled Hosny
8c561733b6 [test/coretext] Add a test for copying variations 2025-02-12 14:21:09 +02:00
Khaled Hosny
c07b22335f [coretext] Fix copying of variations when creating hb-font 2025-02-12 14:21:09 +02:00
Behdad Esfahbod
778acfc606 [coretext] Don't assume that a normalized-coord 0 mins design-coords at default 2025-02-12 14:21:09 +02:00
Behdad Esfahbod
27a25f2d3d [coretext] Copy variations when creating hb-font
https://github.com/harfbuzz/harfbuzz/issues/3159#issuecomment-2652262262
2025-02-12 14:21:09 +02:00
Khaled Hosny
33b3177157 [ci] Stop generating test coverage data
It is failing on Linux CI after upgrading to Ubuntu 24.04, and macOS
upload to codecov was also silently failing for a while now. We don’t do
much with the coverage data anyway.
2025-02-12 13:52:39 +02:00
Khaled Hosny
d46c0ca223 [ci] Don’t use system Python on Linux
We are already installing one using actions/setup-python.
2025-02-12 13:52:39 +02:00
Khaled Hosny
467b08ba36 [ci] Update Ubuntu 20.04 images to 24.04
GitHub actions will start failing jobs using Ubuntu 20.04 images, so
switch to 24.04. Switch also on CircleCI while at it.
2025-02-12 13:52:39 +02:00
Behdad Esfahbod
a69842a839 [shape-plan] Minor check for invalid direction 2025-02-12 11:23:28 +00:00
Behdad Esfahbod
e9c2d78dae [buffer] Clean up some small mess 2025-02-12 11:12:51 +00:00
Behdad Esfahbod
6d95c12871 [buffer] Remove unused includes 2025-02-12 11:12:40 +00:00
Behdad Esfahbod
3446465750 [set] Tweak allocation
Allocation 2-page sets as exact count as well.
Don't do the same for the page_map.
2025-02-10 18:52:23 +00:00
dependabot[bot]
8f1c31c09c Bump hendrikmuhs/ccache-action from 1.2.16 to 1.2.17
Bumps [hendrikmuhs/ccache-action](https://github.com/hendrikmuhs/ccache-action) from 1.2.16 to 1.2.17.
- [Release notes](https://github.com/hendrikmuhs/ccache-action/releases)
- [Commits](5391144220...a1209f81af)

---
updated-dependencies:
- dependency-name: hendrikmuhs/ccache-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-10 11:17:25 +00:00
dependabot[bot]
11b714187b Bump github/codeql-action from 3.28.8 to 3.28.9
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.8 to 3.28.9.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](dd746615b3...9e8d0789d4)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-10 11:16:21 +00:00
dependabot[bot]
63cee529c2 Bump fonttools from 4.55.8 to 4.56.0 in /.ci
Bumps [fonttools](https://github.com/fonttools/fonttools) from 4.55.8 to 4.56.0.
- [Release notes](https://github.com/fonttools/fonttools/releases)
- [Changelog](https://github.com/fonttools/fonttools/blob/main/NEWS.rst)
- [Commits](https://github.com/fonttools/fonttools/compare/4.55.8...4.56.0)

---
updated-dependencies:
- dependency-name: fonttools
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-10 10:29:02 +00:00
Behdad Esfahbod
39fec7b11d
Merge pull request #5062 from harfbuzz/test-fuzzer-one-go
[test/fuzzing] Run each fuzzer on all fonts in one process
2025-02-09 17:54:46 +00:00
Behdad Esfahbod
abdd60acef
Merge pull request #5063 from harfbuzz/disable-google-benchmark-tests
[test] Exclude google-benchmark tests by default if meson "recent" an…
2025-02-09 17:54:07 +00:00
Behdad Esfahbod
b540c37c89
Update meson.build
Co-authored-by: خالد حسني (Khaled Hosny) <khaled@aliftype.com>
2025-02-09 09:47:18 -07:00
Khaled Hosny
7ba3efa5c6 [tests/fuzzing] Use the correct dirs for subset and repacker fuzzers 2025-02-09 18:42:45 +02:00
Behdad Esfahbod
57c9bdd0bd [test] Exclude google-benchmark tests by default if meson "recent" and...
...glib not built internally.

Second try.

See https://github.com/harfbuzz/harfbuzz/issues/4153#issuecomment-2646347531
2025-02-09 16:29:13 +00:00
Khaled Hosny
c404d8fc70 [test/fuzzing] Merge hb_fuzzer_tools.py back and simplify 2025-02-09 18:11:38 +02:00
Khaled Hosny
4c43fdcd07 [test/fuzzing] Simplify Python scripts further
We always path the fuzzer path in meson, so we don’t need to search for
fuzzer path in the scripts, and then we can use one script for all the
fuzzers.
2025-02-09 18:11:34 +02:00
Behdad Esfahbod
c29b1de39f [test/fuzzing] Remove old cruft 2025-02-09 15:38:18 +00:00
Behdad Esfahbod
1e3f59a79f [ci] Give sanitizers more time 2025-02-09 15:21:18 +00:00
Behdad Esfahbod
86329643fd [test/fuzzing] Call binaries with 64 fonts at a time
Second try... Previous attempt caused a too-many-command-line-args
on Windows.

https://github.com/harfbuzz/harfbuzz/issues/5061
2025-02-09 15:12:03 +00:00
Behdad Esfahbod
be22e43d7d [test/fuzzing] Run each fuzzer on all fonts in one process
Much much faster, specially under valgrind, than spawning one process per font.

Fixes https://github.com/harfbuzz/harfbuzz/issues/5061
2025-02-09 14:55:44 +00:00
Behdad Esfahbod
b5e07e7546
Merge pull request #5060 from harfbuzz/glyf-contour-start-match-ft-ct
[glyf] Change drawing algorithm to match FreeType / CoreText
2025-02-09 14:04:20 +00:00
Behdad Esfahbod
6738ee3d1b [ci/fedora-valgrind] Add time multiplier of 10 and run slow tests 2025-02-09 13:50:27 +00:00
Behdad Esfahbod
fc4d507770 [hb-draw-fuzzer] Increase test time
I'm getting timeouts. Might be an infinite loop. But let's see.
2025-02-09 13:28:45 +00:00
Behdad Esfahbod
4b54ee1148 [glyf] Change drawing algorithm to match FreeType / CoreText 2025-02-09 13:07:57 +00:00
Behdad Esfahbod
f858def14b Revert "[test] Exclude google-benchmark tests by default if meson "recent""
This reverts commit 3c975a857f.

See https://github.com/harfbuzz/harfbuzz/issues/4153#issuecomment-2646149763
2025-02-09 13:07:20 +00:00
Behdad Esfahbod
f68193a00a [glyf] Use direct access to points array
Not necessary faster. Prep'ing for next change.
2025-02-09 12:38:38 +00:00
Behdad Esfahbod
19a152b47e [perf] Don't depend on libharfbuzz-subset for most benchmarks 2025-02-09 12:37:28 +00:00
Behdad Esfahbod
3c975a857f [test] Exclude google-benchmark tests by default if meson "recent"
https://github.com/harfbuzz/harfbuzz/issues/4153#issuecomment-2646131694
2025-02-09 08:58:55 +00:00
Behdad Esfahbod
cb6779f9e5 [test] Try running slow tests early
Probably already happens, but this wouldn't hurt.

https://github.com/harfbuzz/harfbuzz/issues/4153#issuecomment-2646125367
2025-02-09 08:39:03 +00:00
Behdad Esfahbod
134eef550d [test] Reorder test suites
Makes it a bit faster.

https://github.com/harfbuzz/harfbuzz/issues/4153#issuecomment-2646120679
2025-02-09 08:26:11 +00:00
Behdad Esfahbod
c55738fa77 [test] Set MALLOC_CHECK_ to 1 instead of 2; kill G_SLICE=always-malloc
MALLOC_CHECK_=2 makes running tests twice slower on macOS. Value 1
is as fast as not checking at all. It's not like this ever caught
a bug for us or anything. We have so many sanitizers and fuzzers
funning on CI, which catch all kinds of memory problems.

G_SLICE is long gone in glib.

The slowest part of running the test suite now is the google-benchmark
tests, that get run by us... I'll see if I can disable. I had reported
it before at https://github.com/harfbuzz/harfbuzz/issues/4153
2025-02-09 08:11:01 +00:00
Behdad Esfahbod
b13017e651 Use HB_ALWAYS_INLINE instead of bare __attribute__
The former works on MSVC too.
2025-02-09 08:00:18 +00:00
Behdad Esfahbod
ee19666c39 [hb-shape/view] Allow --unicodes and --text if at least one is empty
Useful for scripting.
2025-02-09 05:14:36 +00:00
Behdad Esfahbod
5cab741929
Merge pull request #5058 from harfbuzz/ot-font-trak
[ot-font/trak] Move trak application to ot-font instead of ot-shape
2025-02-09 04:56:12 +00:00
Behdad Esfahbod
922a56f43a [trak] Fix configs build 2025-02-09 04:50:17 +00:00
Behdad Esfahbod
17c11ec523 [ft/trak] Apply trak in ft-font-funcs as well
Part of https://github.com/harfbuzz/harfbuzz/issues/5049
2025-02-09 04:46:29 +00:00
Behdad Esfahbod
ffae5b040d [ot-font/trak] Move trak application to ot-font instead of ot-shape
This is what CoreText does.

Fixes https://github.com/harfbuzz/harfbuzz/issues/5049
2025-02-09 04:39:32 +00:00
Behdad Esfahbod
f840480fde [trak] Remove leftover 2025-02-09 04:27:20 +00:00
Behdad Esfahbod
be287eab02 [trak] Don't shift glyphs
That's what CoreText does and fonts are designed for. Who are we to improve on...
2025-02-09 04:19:02 +00:00
Behdad Esfahbod
1150d4bf12 [trak] Remove support for disabling using pseudo-font-feature
Fixes https://github.com/harfbuzz/harfbuzz/issues/5052
2025-02-09 04:16:57 +00:00
Behdad Esfahbod
4c06c3d606
Merge pull request #5057 from harfbuzz/coretext-font-nonbmp
[coretext-font] Support non-BMP characters
2025-02-09 04:01:59 +00:00
Behdad Esfahbod
fb22295311 [coretext-font] Support non-BMP in variation-selector callback
Fixes https://github.com/harfbuzz/harfbuzz/issues/5056
2025-02-09 03:57:47 +00:00
Behdad Esfahbod
f6bf9f697e [coretext-font] Do early-return in get_nominal_glyphs()
Related to https://github.com/harfbuzz/harfbuzz/issues/5056
2025-02-09 03:57:47 +00:00
Behdad Esfahbod
c5e6c885c1 [coretext-font] Support non-BMP chars in get_nominal_glyph(s)
Part of https://github.com/harfbuzz/harfbuzz/issues/5056
2025-02-09 03:57:47 +00:00
Behdad Esfahbod
b9675d6d40
Merge pull request #5055 from harfbuzz/trak-interpolate
[trak] Interpolate between tracks
2025-02-09 03:01:21 +00:00
Behdad Esfahbod
a70a30ddfd [trak] Interpolate between tracks
Fixes https://github.com/harfbuzz/harfbuzz/issues/5054

According to Ned, this is what CoreText does.

Should add tests some time...
2025-02-09 02:56:20 +00:00
Behdad Esfahbod
1bf0a5bc17 [trak] Streamline a bit
Also use float math.
2025-02-09 02:43:09 +00:00
Behdad Esfahbod
b1677e76aa [trak] Handle "out-of-range" values better
If requested size < min-size, use the value for min-size.
If requested size > max-size, use the value for max-size.

This is the only way that makes sense. Extrapolating as we were
doing, is just wrong...

This also seems to match what CoreText does.

Adjacent to fixing https://github.com/harfbuzz/harfbuzz/issues/5054
2025-02-09 02:05:36 +00:00
Behdad Esfahbod
691cc93976 [trak] Fix build without STAT 2025-02-06 20:08:16 +00:00
Behdad Esfahbod
b8327fe605 Fix compiler errors 2025-02-06 20:01:12 +00:00
Behdad Esfahbod
f394206b7c [ot-shape] Only apply trak'ing if STAT table present 2025-02-06 19:56:33 +00:00
Behdad Esfahbod
6e0dd8110e [trak] Default ptem to 12
That's what CoreText does.
https://developer.apple.com/documentation/coretext/ctfontcreatewithgraphicsfont(_:_:_:_:)

Fixes https://github.com/harfbuzz/harfbuzz/issues/5048
2025-02-06 19:56:30 +00:00
Behdad Esfahbod
ef00ac8c84
Merge pull request #5051 from harfbuzz/trak-choose
[trak] Choose closest trak track to 0.0
2025-02-06 17:44:55 +00:00
Behdad Esfahbod
6a37a65276 [trak] Choose closest trak track to 0.0
Seems to be what CT does. Needs more testing to adjust better, but
for now it's better than before.
2025-02-06 17:41:36 +00:00
Behdad Esfahbod
8efd2d85c7 [coretext] Fix CGFont leak 2025-02-06 14:38:09 +00:00
Behdad Esfahbod
b5327faf99 Fix leak
From recent work.
2025-02-06 14:26:37 +00:00
Behdad Esfahbod
24fe2be9c1 [subset] Fix undefined-behavior 2025-02-06 11:55:23 +00:00
Behdad Esfahbod
97db7bb2a0 [set-digest] Cosmetic 2025-02-06 11:01:59 +00:00
Behdad Esfahbod
f0d6a36612 [face] Use a macro 2025-02-06 02:51:50 +00:00
Behdad Esfahbod
7bdc6c9a5a Whitespace 2025-02-06 02:47:13 +00:00
Behdad Esfahbod
6091abcc9b [buffer] Avoid a copy in collect_codepoints() 2025-02-06 02:40:24 +00:00
Behdad Esfahbod
e5e3bc4080 [buffer] Merge two functions into a template 2025-02-06 02:37:10 +00:00
Behdad Esfahbod
403f12f766 [buffer] A few always-inline's 2025-02-06 02:33:41 +00:00
Behdad Esfahbod
4818ba9ece [set-digest] Yet another tuning
Saves 5% on SF Pro while regressing 2% on Roboto.
2025-02-06 01:50:12 +00:00
Behdad Esfahbod
c737829449 [OT] Remove likely() from coverage check
Not that it matters, but because of the set-digest, this path
is not very likely() anymore.
2025-02-06 01:42:25 +00:00
Behdad Esfahbod
3577992a5b [gsubgpos] Simplify a destruction 2025-02-06 01:30:59 +00:00
Behdad Esfahbod
d0d256bb66 [bit-page] Move a couple methods around 2025-02-06 01:26:33 +00:00
Behdad Esfahbod
a4cd11dea9 [bit-page] Micro-optimize 2025-02-06 01:13:58 +00:00
Behdad Esfahbod
0a678a9233 Fix leak 2025-02-06 01:02:44 +00:00
Behdad Esfahbod
cad264b2c9 Indent 2025-02-06 00:56:16 +00:00
Behdad Esfahbod
63c92d5a0d [set-digest] always-inline 2025-02-06 00:52:41 +00:00
Behdad Esfahbod
d712a02845 [set-digest] Back to a 3-entry, with different parameters now
We used to use 4,0,9 for years. Now 3,0,6. It is slightly faster
and shouldn't regress common fonts.  The rationale is that OT
GSUB/GPOS are split by script, so any particular script is not
likely to use more than a few thousands of (consecutive mostly)
glyphs. The exception is CJK of course, but those have less
GSUB/GPOS work.
2025-02-06 00:45:49 +00:00
Behdad Esfahbod
f5fe66cf5f [set-digest] Minor sanity 2025-02-06 00:36:58 +00:00
Behdad Esfahbod
4e75dfae84 Hide unused member 2025-02-06 00:14:29 +00:00
Behdad Esfahbod
99043f204d [gsubgpos] Tweak cache again 2025-02-05 20:11:27 +00:00
Behdad Esfahbod
69057e6ec0 [Ligature] Cache coverage the same way as PairPos1
Another 7% down on Roboto-Regular.
2025-02-05 19:50:51 +00:00
Behdad Esfahbod
3975e220ce Merge branch 'pairpos-cache' 2025-02-05 19:44:08 +00:00
Behdad Esfahbod
e535c6835b [Context] Simplify cache costing 2025-02-05 19:43:43 +00:00
Behdad Esfahbod
7a746c3295 [Coverage] Fix cache cost reporting 2025-02-05 19:38:25 +00:00
Behdad Esfahbod
9a15e0e69a
Merge pull request #5043 from harfbuzz/pairpos-cache
[OT] PairPos cache
2025-02-05 19:37:27 +00:00
Behdad Esfahbod
5be62a9f66 [PairPosFormat1] Use a coverage cache as well
Speeds up Arial shaping by 3%.
2025-02-05 19:30:01 +00:00
Behdad Esfahbod
f22943a2a2 [PairPos] Cache coverage as well
Another 3% down in Roboto-Regular.
2025-02-05 19:18:25 +00:00
Behdad Esfahbod
726af2e4e5 [PairPos] Use a class cache
10% speedup on Roboto-Regular. 5% on SF Pro.
2025-02-05 19:18:25 +00:00
Behdad Esfahbod
acd122d030 [gsubgpos] Prepare for per-lookup allocated caches 2025-02-05 19:18:25 +00:00
Behdad Esfahbod
3f40edbfa0 [ClassDef] Add ability to use a cache 2025-02-05 19:18:25 +00:00
Behdad Esfahbod
7392f32e47 [face] Tweak stack again
Let's go with one loop iteration. It's cheap.
2025-02-05 19:16:08 +00:00
Behdad Esfahbod
515b6a58d9 [face] Minor stack var size change 2025-02-05 19:13:19 +00:00
Behdad Esfahbod
601dd1a748 [face-builder] Fix an OOM issue
Fixes https://oss-fuzz.com/testcase-detail/5721476158521344
2025-02-05 19:10:41 +00:00
Behdad Esfahbod
c05002afb8 [set] Add may_have() as alias for get() 2025-02-05 16:46:13 +00:00
Behdad Esfahbod
ad7f428be4 [set-digest] Comment 2025-02-05 16:44:04 +00:00
Behdad Esfahbod
900db7b1bd [bit-set] Add a couple of alias methods 2025-02-05 16:41:49 +00:00
Behdad Esfahbod
942a30b7df [aat] Remove now-unused code 2025-02-05 14:21:49 +00:00
Behdad Esfahbod
44281b2856 [aat] Back to simplified heuristic
Performs overall better.
2025-02-05 14:19:01 +00:00
Behdad Esfahbod
dc8da6129f
Merge pull request #5042 from harfbuzz/aat-regression
[aat] Fix performance regression
2025-02-05 14:12:55 +00:00
Behdad Esfahbod
b857b21a45 [morx] Try using buffer-glyph-set adaptive to number of chains 2025-02-05 13:50:09 +00:00
Behdad Esfahbod
491c8c4e10 Revert "[aat] Change threshold from 4 to 16"
This reverts commit 624d6edfe4.

Some other benchmarks see better results for 4. Let's leave at that.
2025-02-05 13:00:09 +00:00
Behdad Esfahbod
624d6edfe4 [aat] Change threshold from 4 to 16
Still worth it it seems.
2025-02-05 12:46:25 +00:00
Behdad Esfahbod
a26cf0f409 [aat] Fix regression in performance of shaping tiny strings 2025-02-05 12:41:40 +00:00
Behdad Esfahbod
cec5c57130 [aat] Refactor a method 2025-02-05 12:39:22 +00:00
Behdad Esfahbod
cd5dfc6dbe [kerx] Use hb_bit_set_t instead of hb_set_t 2025-02-05 12:33:00 +00:00
Behdad Esfahbod
d40c079fed [morx] Use hb_bit_set_t instead of hb_set_t directly 2025-02-05 12:30:56 +00:00
Behdad Esfahbod
7b9277486f [bit-set] Rename a method 2025-02-05 12:25:54 +00:00
Behdad Esfahbod
b44f6ff5fe [perf/texts] Add a list of just 2letter strings 2025-02-05 12:19:48 +00:00
Behdad Esfahbod
f738534042
Merge pull request #5041 from harfbuzz/aat-machine-initial
[morx] Only collect glyphs that can initiate action in the machine
2025-02-05 12:19:30 +00:00
Behdad Esfahbod
fc825168d0 [aat] Remove idempotent check
Not necessary after the recent filtering.

Another 10% speedup with LucidaGrande.
2025-02-05 11:17:34 +00:00
Behdad Esfahbod
849b17351e [aat] Divide the logic of is_actionable() into two
The two different uses require different logic. I had combined
the two logic into one in 37bfdf79c6
2025-02-05 11:15:36 +00:00
Behdad Esfahbod
b4787838e4 [aat] Speed up per-machine initial-glyph-set calculation
Use a bit-page instead of a full hb-set.
2025-02-05 10:52:26 +00:00
Behdad Esfahbod
7d14eb5eb3 [aat] Minor rename 2025-02-05 10:46:28 +00:00
Behdad Esfahbod
6215d68b69 [aat] Minor tweak to logic
DELETED_GLYPH can also initiate action.
2025-02-05 10:43:24 +00:00
Behdad Esfahbod
dc4ff7012c [bit-page] Add a couple of operators 2025-02-05 10:42:33 +00:00
Behdad Esfahbod
37bfdf79c6 [morx] Only collect glyphs that can initiate action in the machine
And match them against the buffer glyph_set.

4% speedup in LucidaGrande.
2025-02-05 10:38:24 +00:00
Behdad Esfahbod
d9e99baa9a [aat] Move is_actionable outside of the driver_context 2025-02-05 02:06:59 +00:00
Behdad Esfahbod
5ade5bab01 [aat] Move Flags out of driver_context_t 2025-02-05 01:53:09 +00:00
Behdad Esfahbod
9f38690e8e [aat] Remove another unused parameter
One logic change, but should be fine.
2025-02-05 01:39:28 +00:00
Behdad Esfahbod
d9058c64e0 [aat] Remove an unused parameter 2025-02-05 01:38:06 +00:00
Behdad Esfahbod
1a2780735c [array] Micro-optimize 2025-02-05 00:35:40 +00:00
Behdad Esfahbod
c87bfe410b [morx] Reuse a variable 2025-02-05 00:22:27 +00:00
Behdad Esfahbod
e99e6538d9 [aat-map] Micro-optimize a malloc 2025-02-05 00:08:29 +00:00
Behdad Esfahbod
3e27038fca [aat-map] Micro-optimize 2025-02-04 23:39:42 +00:00
Behdad Esfahbod
7f5fac7c87 [test-buffer] Fix unintionally merged change 2025-02-04 23:35:34 +00:00
Behdad Esfahbod
f0ead85283 [aat] Implement set filtering for Noncontextual chains as well 2025-02-04 23:30:30 +00:00
Behdad Esfahbod
e5bdba0b3c [aat] Rename a variable 2025-02-04 23:03:23 +00:00
Behdad Esfahbod
cb09fe7995 [bit-set] Remove a likely() 2025-02-04 22:54:10 +00:00
Behdad Esfahbod
749dc1eee0 [bit-set] Fix may_intersect() logic 2025-02-04 22:53:17 +00:00
Behdad Esfahbod
b30c65e271
Merge pull request #5040 from harfbuzz/aat-set
[aat] Speed up subchain skipping using exact sets
2025-02-04 22:48:58 +00:00
Behdad Esfahbod
22a21e81a0 [aat] Fix a crash 2025-02-04 22:30:42 +00:00
Behdad Esfahbod
275fb565bb [morx] Clean up memory 2025-02-04 22:30:42 +00:00
Behdad Esfahbod
255dadc152 [set] Speed up may_intersect() 2025-02-04 22:30:42 +00:00
Behdad Esfahbod
a617328005 [bit-set] Sprinkle a few .arrayZ around
All accesses are valid.
2025-02-04 22:30:42 +00:00
Behdad Esfahbod
7862c7c5e1 Rename a method again 2025-02-04 22:30:42 +00:00
Behdad Esfahbod
474bef1cfd [aat] Use exact set for buffer intersection versus subchains 2025-02-04 22:30:42 +00:00
Behdad Esfahbod
95eefa38f6 [set] Add a brute-force intersects(other_set) 2025-02-04 22:30:42 +00:00
Behdad Esfahbod
80bbb0b2e9 [set-digest] Rename a method 2025-02-04 22:30:32 +00:00
Behdad Esfahbod
7d17ea4996
Merge pull request #5037 from harfbuzz/face-blob
[face] Add fallback implementation to hb_face_reference_blob
2025-02-04 18:43:33 +00:00
Khaled Hosny
a315d43b04 [doc] Update hb_face_reference_blob() and hb_reference_table_func_t 2025-02-04 20:41:01 +02:00
Behdad Esfahbod
5b49ac21fe
Merge pull request #5039 from harfbuzz/lucida
[aat] Speed up Lucida Grande among others
2025-02-04 18:40:27 +00:00
Behdad Esfahbod
722ab54868 [kerx] Don't compute buffer digest
We don't use it in kerx
2025-02-04 17:59:39 +00:00
Behdad Esfahbod
449c7f2a0d [aat] Add some tracing 2025-02-04 17:56:22 +00:00
Behdad Esfahbod
3a1d7ee7e8 [aat] Remove the buffer-digest threshold
This can help us skip entire subchains, eg. when they are for
different scripts.

Speeds up LucidaGrande with ASCII text by 20%.
2025-02-04 17:33:42 +00:00
Behdad Esfahbod
e1cb3b155a Revert "[aat] Remove set-digest"
This reverts commit 832f199607.
2025-02-04 17:29:23 +00:00
Behdad Esfahbod
359d163d25 Revert "[aat] Remove buffer-digest stuff"
This reverts commit 7642366593.
2025-02-04 17:12:30 +00:00
Behdad Esfahbod
7d23e642a2 Revert "[aat] Remove dead code"
This reverts commit bf36f5c3a4.
2025-02-04 17:12:30 +00:00
Behdad Esfahbod
d109947672 Revert "[aat] Remove unused macro"
This reverts commit 2ddcccd26e.
2025-02-04 17:12:30 +00:00
Behdad Esfahbod
2ddcccd26e [aat] Remove unused macro 2025-02-04 17:05:45 +00:00
Behdad Esfahbod
1ff462354b [morx] Micro-optimize 2025-02-04 16:46:25 +00:00
Khaled Hosny
4825e5e2b4 [face] Add fallback implementation to hb_face_reference_blob
If referencing the face blob is not possible (e.g. not implemented by
the font functions), use face builder to create a blob out of
individual table blobs.

Fixes https://github.com/harfbuzz/harfbuzz/issues/5036
2025-02-04 15:45:22 +02:00
Behdad Esfahbod
9cf2ea3e8f Merge branch 'kern-set' 2025-02-04 13:34:31 +00:00
Behdad Esfahbod
bf36f5c3a4 [aat] Remove dead code 2025-02-04 13:32:31 +00:00
Behdad Esfahbod
7642366593 [aat] Remove buffer-digest stuff
With both morx & kerx sped up now using cache / set, this is not
beneficial anymore. Remove it.
2025-02-04 13:19:43 +00:00
Behdad Esfahbod
9a4601b06b [kern/kerx] Use hb-set-t for left/right, to guard bsearch
Use a set of all left glyphs participating in kerning, and all
right glyphs participating in kerning, and use these two to weed
out non-kerning pairs before bsearching into the kerns.

Speeds up shaping of HelveticaNeue by ~10%.
2025-02-04 13:16:54 +00:00
Behdad Esfahbod
3e50a8dfec [buffer] Use UINT_MAX instead of wrong macro 2025-02-04 13:06:23 +00:00
Behdad Esfahbod
cafbdf4217
Merge pull request #5031 from harfbuzz/aat-speedup
[aat] Add a class-cache to the machine & fix speed regression from 2023!
2025-02-04 11:22:15 +00:00
Behdad Esfahbod
267ebeeccd [perf/text] Add a long piece of JS code for benchmarking 2025-02-04 11:10:31 +00:00
Behdad Esfahbod
ee4ca63b6d [aat] Micro-optimize 2025-02-03 13:23:08 +00:00
Behdad Esfahbod
ed37725e00 [aat] Micro-optimize get_class 2025-02-03 12:59:58 +00:00
dependabot[bot]
be022b3550 Bump actions/setup-python from 5.3.0 to 5.4.0
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.3.0 to 5.4.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](0b93645e9f...42375524e2)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-03 04:47:45 -07:00
dependabot[bot]
4291114246 Bump github/codeql-action from 3.28.5 to 3.28.8
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.5 to 3.28.8.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](f6091c0113...dd746615b3)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-03 04:47:37 -07:00
Behdad Esfahbod
91572945bb [aat] More delambda
Again, this was costly.
2025-02-03 11:28:50 +00:00
Behdad Esfahbod
556eb02977 [aat] Remove a lambda
This lambda was added to "simplify" the logic. But has a lot of overhead.
2025-02-03 11:28:50 +00:00
Behdad Esfahbod
d9a25bc4ee [aat] Allocate caches together
No separate malloc.
2025-02-03 11:28:50 +00:00
Behdad Esfahbod
7b44a94a55 [aat] Shrink cache to 256 bytes per subtable 2025-02-03 11:28:50 +00:00
Behdad Esfahbod
b89ab7d0fb [aat] Shrink the class cache to be 512 bytes instead of 1kb 2025-02-03 11:28:50 +00:00
Behdad Esfahbod
4fb0ac7728 [aat] Minor simplify 2025-02-03 11:28:50 +00:00
Behdad Esfahbod
832f199607 [aat] Remove set-digest
Now that we have a class cache, this was just speeding things down.
2025-02-03 11:28:50 +00:00
Behdad Esfahbod
0e13e78153 [aat] Add a class-cache to the machine
Speeds up Times.ttc benchmark by 20%.
2025-02-03 11:28:50 +00:00
dependabot[bot]
3839e5fd59 Bump fonttools from 4.55.6 to 4.55.8 in /.ci
Bumps [fonttools](https://github.com/fonttools/fonttools) from 4.55.6 to 4.55.8.
- [Release notes](https://github.com/fonttools/fonttools/releases)
- [Changelog](https://github.com/fonttools/fonttools/blob/main/NEWS.rst)
- [Commits](https://github.com/fonttools/fonttools/compare/4.55.6...4.55.8)

---
updated-dependencies:
- dependency-name: fonttools
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-03 04:28:16 -07:00
Tor Arne Vestbø
04b2006fc9 Remove outdated documentation note about CT operating in 96 DPI
As extensively discussed and documented in #1484, Core Text does
not operate in 96 DPI. Core Text doesn't actually have a concept of
DPI internally, as it doesn't rasterize anything by itself, it just
generates vector paths that get passed along to Core Graphics.

In practice this means Core Text operates in the classical macOS
logical DPI of 72, with one typographic point corresponding to one
point in the Core Graphics coordinate system, which for a normal
bitmap context then corresponds to one pixel -- or two pixels for
a "retina" context with a 2x scale transform.

As of f401f85a5a, we no longer apply
any assumptions in HB about the target DPI being different than the
72 DPI used by CT, for example to account for the Web's standard of
96 DPI, so let's remove the documentation that still indicated this
was necessary.
2025-02-03 04:28:02 -07:00
Khaled Hosny
bbb9e56365 [ci] Pin GitHub workflows to Python 3.12 for now
Some dependencies seem to fail to install on Python 3.13.
2025-02-02 23:14:03 +02:00
Behdad Esfahbod
d8d0987feb [benchmark-shape] Remove variable-font test set
It doesn't really affect shaping much. Kill it.
2025-02-02 18:08:09 +00:00
Behdad Esfahbod
138448487e [aat] Typo 2025-02-02 11:56:01 +00:00
Behdad Esfahbod
f5e50890d0 [open-type] Another tweak to cmp()
Again, unlikely that compiler cares.
2025-02-02 11:40:27 +00:00
Behdad Esfahbod
c68df817a6 [open-type] Minor tweak to cmp()
Remove codepath that was never taken.
2025-02-02 11:39:01 +00:00
Behdad Esfahbod
9bd75952e5 [benchmark-shape] Compare diff shapers, not font funcs 2025-02-02 11:14:49 +00:00
Behdad Esfahbod
66bb94fe46 [set-digest] Tune back to starting with 4
Make Amiri slightly slower again, but works better for AAT fonts
I tested.
2025-02-02 08:40:30 +00:00
Behdad Esfahbod
9fd855ed55 [set-digest] Tune a bit more
Saves another 2% on Amiri benchmark.
2025-02-02 07:57:50 +00:00
Behdad Esfahbod
880b92ed6e [set-digest] Fix build on Linux 2025-02-02 07:43:33 +00:00
Behdad Esfahbod
92f13bbdd7 [set-digest] Inline combiner
Instead of defining one digest and then combining three of them at
different shifts, inline the code The compiler can optimize it better.

3% speedup with Amiri benchmark.
2025-02-01 19:11:20 +00:00
Behdad Esfahbod
c4c8eb4f8c [algs] Rename a macro
Clashes with Apple simd/simd.h
2025-02-01 15:58:47 +00:00
Behdad Esfahbod
b394ab39e9 [test-buffer] Add code for testing end_ptr 2025-02-01 14:26:32 +00:00
Behdad Esfahbod
9ba286de08 [ot-shape] Micro-optimize ::equal
For two integers, it's faster to compare them directly.
2025-02-01 14:25:13 +00:00
dependabot[bot]
6d8035a99c Bump meson from 1.6.1 to 1.7.0 in /.ci
Bumps [meson](https://github.com/mesonbuild/meson) from 1.6.1 to 1.7.0.
- [Release notes](https://github.com/mesonbuild/meson/releases)
- [Commits](https://github.com/mesonbuild/meson/compare/1.6.1...1.7.0)

---
updated-dependencies:
- dependency-name: meson
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-27 14:18:50 +02:00
dependabot[bot]
adc5ef1e09 Bump codecov/codecov-action from 5.1.2 to 5.3.1
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.1.2 to 5.3.1.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](1e68e06f1d...13ce06bfc6)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-27 14:18:08 +02:00
dependabot[bot]
c2fa380391 Bump github/codeql-action from 3.28.1 to 3.28.5
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.1 to 3.28.5.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](b6a472f63d...f6091c0113)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-27 14:16:59 +02:00
dependabot[bot]
721470f564 Bump fonttools from 4.55.3 to 4.55.6 in /.ci
Bumps [fonttools](https://github.com/fonttools/fonttools) from 4.55.3 to 4.55.6.
- [Release notes](https://github.com/fonttools/fonttools/releases)
- [Changelog](https://github.com/fonttools/fonttools/blob/main/NEWS.rst)
- [Commits](https://github.com/fonttools/fonttools/compare/4.55.3...4.55.6)

---
updated-dependencies:
- dependency-name: fonttools
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-27 14:16:22 +02:00
Behdad Esfahbod
9ef009f597 [test] Fix test
Broken by previous commit.
https://github.com/harfbuzz/harfbuzz/issues/5020#issuecomment-2613597379
2025-01-24 16:37:12 -07:00
Behdad Esfahbod
6be66b0ef2 [ft/coretext] Fail setting font-funcs gracefully
Fixes https://github.com/harfbuzz/harfbuzz/issues/5020
2025-01-24 16:26:54 -07:00
Behdad Esfahbod
4df11621ce [VARC] Fix variable binding
Ouch.
2025-01-24 05:00:05 -07:00
Behdad Esfahbod
2fa9ccee61 [VARC] Simplify 2025-01-23 23:14:53 -07:00
Behdad Esfahbod
2d2418ebac [VARC] Avoid float div-by-zero 2025-01-23 23:14:45 -07:00
Behdad Esfahbod
fe9398e9a9 [VARC] Chain transforms
Previous code was actually wrong even, for non-uniform x/y font scale.

Fixes https://github.com/harfbuzz/harfbuzz/issues/5017
2025-01-23 22:59:12 -07:00
David Corbett
22fbc75688 [ot-tags] Update IANA and OT language registries 2025-01-22 11:03:02 -07:00
Khaled Hosny
a888761a78 [hb-ft] Hopefully clarify hb_ft_font_create() life cycle even more
Add “only” to one more place.
2025-01-21 15:57:10 +02:00
dependabot[bot]
a40d6921dc Bump github/codeql-action from 3.27.6 to 3.28.1
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.27.6 to 3.28.1.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](aa57810251...b6a472f63d)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-20 21:04:40 +02:00
dependabot[bot]
3414b2dc6a Bump codecov/codecov-action from 5.1.1 to 5.1.2
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.1.1 to 5.1.2.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](7f8b4b4bde...1e68e06f1d)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-20 21:04:28 +02:00
dependabot[bot]
6e518c3f55 Bump actions/upload-artifact from 4.4.3 to 4.6.0
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.4.3 to 4.6.0.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](b4b15b8c7c...65c4c4a1dd)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-20 21:03:54 +02:00
dependabot[bot]
66cc1e7da9 Bump hendrikmuhs/ccache-action from 1.2.14 to 1.2.16
Bumps [hendrikmuhs/ccache-action](https://github.com/hendrikmuhs/ccache-action) from 1.2.14 to 1.2.16.
- [Release notes](https://github.com/hendrikmuhs/ccache-action/releases)
- [Commits](ed74d11c0b...5391144220)

---
updated-dependencies:
- dependency-name: hendrikmuhs/ccache-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-20 21:03:35 +02:00
Behdad Esfahbod
3a7ebc320d [config] Fix build with HB_LEAN
Fixes https://github.com/harfbuzz/harfbuzz/issues/4997
2025-01-13 14:53:31 -07:00
Khaled Hosny
1e629c3511 [morx] Blocklist dysfunctional morx table of AALMAGHRIBI.ttf font
Fixes #4108
2025-01-13 11:30:00 -07:00
Khaled Hosny
7b27c8edd4 10.2.0 2025-01-11 18:13:18 +02:00
Thrita
ba31fc95a9
Add support for Apple framework builds (#4993)
* Build: Update Apple Framework properties

Signed-off-by: Treata11 <treata11@yahoo.com>

* Build: Fix issues related to Framework properties

Signed-off-by: Treata11 <treata11@yahoo.com>

* Build: Fix framework properties of SHARED_LIBS

Signed-off-by: Treata11 <treata11@yahoo.com>

* Fix typos

---------

Signed-off-by: Treata11 <treata11@yahoo.com>
2025-01-11 11:51:57 +02:00
Behdad Esfahbod
021b443886 Garay script is RTL
Fixes https://github.com/harfbuzz/harfbuzz/issues/4996
2025-01-10 13:57:16 -07:00
Khaled Hosny
fc42cdd68d [docs] Reduce warnings 2025-01-08 22:17:03 +02:00
Khaled Hosny
1ce8191289 [subset-serialize] Formatting 2025-01-08 15:56:10 +02:00
Khaled Hosny
e943a0098b [subset-serialize] Try to fix MSVC build 2025-01-08 15:56:10 +02:00
Khaled Hosny
9d5beeafa1 [subset-serialize] Fix doc generation
gtk-doc is rather sensitive to white space, and it does not seem to be
able to parse bare `unsigned` without `int`.
2025-01-08 15:12:40 +02:00
Garret Rieger
bdb50f1c6e [repacker] Also rename api method from hb_subset_repack_or_fail -> hb_subset_serialize_or_fail. 2025-01-07 13:39:51 -07:00
Garret Rieger
056504168c [repacker] rename hb-subset-repacker -> hb-subset-serialize.
Also hb_link_t and hb_object_t to hb_subset_serialize_link_t and hb_subset_serialize_object_t.
2025-01-07 13:39:51 -07:00
dependabot[bot]
3a63e174d8 Bump jinja2 from 3.1.4 to 3.1.5 in /.ci
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.4 to 3.1.5.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.1.4...3.1.5)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-07 13:02:43 -07:00
Behdad Esfahbod
503553c3d2 [docs] Fix build for real this time 2025-01-07 11:50:12 -07:00
Behdad Esfahbod
fca062eb4c [docs] Fix build fail 2025-01-07 11:38:25 -07:00
Behdad Esfahbod
c1f5b780f3 Fix docs 2025-01-07 11:31:05 -07:00
Behdad Esfahbod
379e3c989a [shape] Wrap justify API in EXPERIMENTAL
Fixes https://github.com/harfbuzz/harfbuzz/issues/4984
2025-01-07 11:29:35 -07:00
Garret Rieger
5a6f5922dd [repacker] Promote repacking API to stable.
For #227.
2025-01-07 11:28:38 -07:00
Behdad Esfahbod
1abc8d2f37 Revert "Bump setuptools from 73.0.1 to 75.7.0 in /.ci"
This reverts commit 23358ec279.

Bots failing.
2025-01-07 11:27:46 -07:00
dependabot[bot]
23358ec279 Bump setuptools from 73.0.1 to 75.7.0 in /.ci
Bumps [setuptools](https://github.com/pypa/setuptools) from 73.0.1 to 75.7.0.
- [Release notes](https://github.com/pypa/setuptools/releases)
- [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/setuptools/compare/v73.0.1...v75.7.0)

---
updated-dependencies:
- dependency-name: setuptools
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-06 14:20:52 -07:00
David Corbett
57569baa65 Don’t insert U+25CC before super/subscript digits 2025-01-03 05:19:13 -07:00
dependabot[bot]
b5a65e0f20 Bump meson from 1.5.2 to 1.6.1 in /.ci
Bumps [meson](https://github.com/mesonbuild/meson) from 1.5.2 to 1.6.1.
- [Release notes](https://github.com/mesonbuild/meson/releases)
- [Commits](https://github.com/mesonbuild/meson/compare/1.5.2...1.6.1)

---
updated-dependencies:
- dependency-name: meson
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-23 05:18:18 -07:00
wang-bin
3258b1f248 [coretext]: fix tvOS build
define kCTFont* when unavailable, i.e. ios < 6.0, macOS < 10.8 or tvOS < 9.0.
MAC_OS_X_VERSION_MIN_REQUIRED is always defined in AvailabilityMacros.h for all targets,
while __ENVIRONMENT_*_VERSION_MIN_REQUIRED__ is defined by compiler when building a specific target
2024-12-20 00:25:45 -07:00
Khaled Hosny
524e0f0ad5 [doc] Improve hb_face_reference_table() docs 2024-12-19 11:54:10 +02:00
dependabot[bot]
e451e91ec3 Bump ninja from 1.11.1.2 to 1.11.1.3 in /.ci
Bumps [ninja](https://github.com/scikit-build/ninja-python-distributions) from 1.11.1.2 to 1.11.1.3.
- [Release notes](https://github.com/scikit-build/ninja-python-distributions/releases)
- [Changelog](https://github.com/scikit-build/ninja-python-distributions/blob/master/HISTORY.rst)
- [Commits](https://github.com/scikit-build/ninja-python-distributions/compare/1.11.1.2...1.11.1.3)

---
updated-dependencies:
- dependency-name: ninja
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-16 04:22:16 -07:00
dependabot[bot]
ce00135e37 Bump fonttools from 4.55.2 to 4.55.3 in /.ci
Bumps [fonttools](https://github.com/fonttools/fonttools) from 4.55.2 to 4.55.3.
- [Release notes](https://github.com/fonttools/fonttools/releases)
- [Changelog](https://github.com/fonttools/fonttools/blob/main/NEWS.rst)
- [Commits](https://github.com/fonttools/fonttools/compare/4.55.2...4.55.3)

---
updated-dependencies:
- dependency-name: fonttools
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-16 04:22:06 -07:00
David Corbett
edb3b20895 Make hb_test_tools.py work in Python 3.13 2024-12-15 12:34:48 -07:00
David Corbett
f887096ab1 [myanmar] Allow all tones (& visarga) in any order 2024-12-15 12:32:08 -07:00
Behdad Esfahbod
c8050b3872 [coretext] Fix build on old Mac
Fixes https://github.com/harfbuzz/harfbuzz/issues/4968
2024-12-10 11:22:15 -07:00
dependabot[bot]
c6609bed68 Bump codecov/codecov-action from 5.0.7 to 5.1.1
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.0.7 to 5.1.1.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](015f24e681...7f8b4b4bde)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-09 15:58:37 +02:00
dependabot[bot]
8364839f5c Bump github/codeql-action from 3.27.5 to 3.27.6
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.27.5 to 3.27.6.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](f09c1c0a94...aa57810251)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-09 15:41:46 +02:00
dependabot[bot]
30099ee188 Bump fonttools from 4.55.0 to 4.55.2 in /.ci
Bumps [fonttools](https://github.com/fonttools/fonttools) from 4.55.0 to 4.55.2.
- [Release notes](https://github.com/fonttools/fonttools/releases)
- [Changelog](https://github.com/fonttools/fonttools/blob/main/NEWS.rst)
- [Commits](https://github.com/fonttools/fonttools/compare/4.55.0...4.55.2)

---
updated-dependencies:
- dependency-name: fonttools
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-09 15:41:27 +02:00
David Corbett
40ef6c0577 [ot-tags] Update OpenType language system registry 2024-12-05 15:59:39 -07:00
Kesavan Yogeswaran
1c249be96e Sidestep nontrivial-memaccess warning in Crap()
With -Wnontrivial-memaccess, recent versions of clang flag the usage of
memcpy in hb-null.hh with pointers to nontrivially-copyable types.
Sidestep this warning by casting the problematic pointer to void*.
2024-12-02 14:55:50 -07:00
Caleb Maclennan
10cf348a67 [gsubgpos] Guard integer arithmetic against wrapping below zero
When either casting a signed integer to an unsigned one or subtracting
a value from an unsigned one, add assertions to verify we will not end
up below expected bounds.
2024-11-28 16:22:33 -07:00
Luca Ebach
780aaca89b set harfbuzz version in cmake config file 2024-11-28 02:31:46 +02:00
Qunxin Liu
3bb89eebd6 [instancer] use hb_parse_double() for parsing axis positions
Added hb_subset_axis_range_from/to_string()
2024-11-25 09:38:13 -07:00
dependabot[bot]
26a737ac15 Bump ninja from 1.11.1.1 to 1.11.1.2 in /.ci
Bumps [ninja](https://github.com/scikit-build/ninja-python-distributions) from 1.11.1.1 to 1.11.1.2.
- [Release notes](https://github.com/scikit-build/ninja-python-distributions/releases)
- [Changelog](https://github.com/scikit-build/ninja-python-distributions/blob/master/HISTORY.rst)
- [Commits](https://github.com/scikit-build/ninja-python-distributions/compare/1.11.1.1...1.11.1.2)

---
updated-dependencies:
- dependency-name: ninja
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-25 04:33:37 -07:00
dependabot[bot]
1dc8ff050f Bump codecov/codecov-action from 5.0.2 to 5.0.7
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.0.2 to 5.0.7.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](5c47607acb...015f24e681)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-25 04:07:53 -07:00
dependabot[bot]
7d6729de29 Bump github/codeql-action from 3.27.4 to 3.27.5
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.27.4 to 3.27.5.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](ea9e4e3799...f09c1c0a94)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-25 04:07:44 -07:00
Khaled Hosny
056cc56044 [config] Improve language handling with HB_LEAN
Remove HB_NO_LANGUAGE_LONG and HB_NO_LANGUAGE_PRIVATE_SUBTAG defines to
support language tags longer than 2 letters and private language tags
(needed to set language using OpenType language tags) respectively.

HB_LEAN is used when smaller binary size is desired, but in general it
should not produce different shaping output.

Fixes https://github.com/harfbuzz/harfbuzzjs/issues/108
2024-11-24 17:42:43 -07:00
Khaled Hosny
5e584ee7d9 [ci] Try to fix homebrew pkg-config/pkgconf mess
The packages are in conflict again, try to remove pkg-config this time
and use pkgconf.
2024-11-24 09:43:12 +02:00
Garret Rieger
0b7beefd0b Raise table growth limit during subsetting. Real case encountered that exceeded the current limit. Fixes #4943. 2024-11-21 18:10:21 -07:00
Khaled Hosny
773fe85018 [layout] Blocklist the GDEF table of various Courier New versions
These files have incorrectly give several base glyphs GDEF mark glyph
class leading in zeroing there advance widths.

Fixes https://github.com/harfbuzz/harfbuzz/issues/4936
2024-11-21 14:40:57 -07:00
Khaled Hosny
5002153e3a [ci] Try to fix macOS build
It seems that Homebrew now packages an alternative implementation of
pkg-config called pkgconf and some of the packages we install depend on
it, and installing both pkgconf and pkg-config is not supported.

Looks like pkgconf can’t find dependencies for us, so we do some
brew unlink/link dance to get both installed, and hope for the best.
2024-11-20 17:51:37 +02:00
dependabot[bot]
b14def8bb3 Bump fonttools from 4.54.1 to 4.55.0 in /.ci
Bumps [fonttools](https://github.com/fonttools/fonttools) from 4.54.1 to 4.55.0.
- [Release notes](https://github.com/fonttools/fonttools/releases)
- [Changelog](https://github.com/fonttools/fonttools/blob/main/NEWS.rst)
- [Commits](https://github.com/fonttools/fonttools/compare/4.54.1...4.55.0)

---
updated-dependencies:
- dependency-name: fonttools
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-18 08:30:48 -07:00
dependabot[bot]
baf374e378 Bump codecov/codecov-action from 4.6.0 to 5.0.2
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.6.0 to 5.0.2.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](b9fd7d16f6...5c47607acb)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-18 08:30:34 -07:00
dependabot[bot]
b608892658 Bump github/codeql-action from 3.27.0 to 3.27.4
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.27.0 to 3.27.4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](662472033e...ea9e4e3799)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-18 08:30:19 -07:00
Behdad Esfahbod
2ddae77179 [util/cairo] Handle all null matrices 2024-11-17 00:02:03 -07:00
Behdad Esfahbod
392463267f [cairo] Protect against some invalid matrices
hb-view --font-size 0,10 still fails with cairo error.
To be debugged separately.
2024-11-16 12:20:24 -07:00
Behdad Esfahbod
d759ee5a8d [ft] Guard FT_LOAD_NO_SVG
Also pass FT_LOAD_NO_BITMAP.
2024-11-15 16:18:34 -07:00
Behdad Esfahbod
965790764a [ft-colr] Don't load SVG table since we don't support it
Part of https://github.com/harfbuzz/harfbuzz/issues/4938
2024-11-15 15:33:11 -07:00
Behdad Esfahbod
21cba9e5bc [cairo] Fix scaling in paint_color_glyph
Fixes https://github.com/harfbuzz/harfbuzz/issues/4938
2024-11-15 15:21:21 -07:00
Behdad Esfahbod
de7f97b7f7 [COLR] Add comment 2024-11-15 15:14:37 -07:00
Garret Rieger
b0d52abe97 [subset] consider variation selectors subsetting cmap14
cmap14 subsetting code was not considering variation selectors in the input unicode set when deciding which variant glyphs to keep. This updates subsetting to only keeps variant glyphs if their variation selector code point is in the input unicodes set.

For https://github.com/harfbuzz/harfbuzz/issues/4911
2024-11-11 13:45:08 -07:00
Behdad Esfahbod
1767f99e2e [cairo] Guard hb_cairo_glyphs_from_buffer() against bad UTF-8
Previously it was assuming valid UTF-8.
2024-11-10 22:43:28 -07:00
Khaled Hosny
6898a6048c [meson] Update wrap files
This also updates the meson version on Windows cross-build jobs as wraps
now requires newer versions of meson. We still require only meson 0.55.0
for building HarfBuzz, but building with fallback wraps is allowed
to require newer meson.
2024-11-09 13:17:58 +02:00
Qunxin Liu
b5ed7846d6 [subset-serialize] release discarded objects 2024-11-08 18:06:35 -07:00
Qunxin Liu
622e9c33c3 [instancer] fix for incorrect offset calculation when we have gvar padding 2024-11-06 12:38:00 -07:00
Khaled Hosny
9ef44a2d67 10.1.0 2024-11-05 08:04:49 +02:00
Khaled Hosny
a9b76edca6 [ci] Pin Python version to 3.12 on macOS
It seems that lxml does not have 3.13 binary wheels (for macOS at
least), and building it from source is failing.
2024-11-05 02:13:11 +02:00
Behdad Esfahbod
c85a6c2a22 [cairo] Respect HB_NO_VAR
Fixes https://github.com/harfbuzz/harfbuzz/issues/4924
2024-11-04 17:34:02 -05:00
dependabot[bot]
5e32b5ca8f Bump actions/setup-python from 5.2.0 to 5.3.0
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.2.0 to 5.3.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](f677139bbe...0b93645e9f)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-28 08:48:18 -06:00
dependabot[bot]
4148c8d4e1 Bump actions/checkout from 4.2.1 to 4.2.2
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.1 to 4.2.2.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](eef61447b9...11bd71901b)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-28 08:48:05 -06:00
dependabot[bot]
f8e0ba5eff Bump github/codeql-action from 3.26.12 to 3.27.0
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.26.12 to 3.27.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](c36620d31a...662472033e)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-28 08:47:53 -06:00
Behdad Esfahbod
9974a66169 [icu] Make it build with ICU 76
Fixes https://github.com/harfbuzz/harfbuzz/issues/4915
2024-10-27 16:14:53 -07:00
Garret Rieger
392581be01 [subest] get benchmark subset working again. 2024-10-24 15:42:31 -06:00
Qunxin Liu
e5139c51aa bug fix in hashmap get_with_hash() 2024-10-21 15:46:06 -06:00
Behdad Esfahbod
825bc19643 [perf] Simplify meson.build
Fixes https://github.com/harfbuzz/harfbuzz/issues/4896
2024-10-16 01:56:17 -06:00
Behdad Esfahbod
35f67618e8
Merge pull request #4895 from harfbuzz/coretext-font
Coretext font
2024-10-15 15:27:25 -06:00
Behdad Esfahbod
de1a1e27d4 [coretext-font] Implement get_glyph_v_origin()
For a font without vertical metrics, I'm getting different
values from ot/ft. But that's expected, since in ot we just
implemented the same heuristics as ft.
2024-10-15 14:58:13 -06:00
Behdad Esfahbod
786097029e [coretext-font] Implement get_glyph_v_advances 2024-10-15 14:58:13 -06:00
Behdad Esfahbod
e1026a2252 [coretext-font] Implement get_variation_glyph()
Not sure if I got it right, but *seems* to work.
2024-10-15 14:58:13 -06:00
Behdad Esfahbod
d44cc8a1fc [coretext-font] Implement get_glyph_name() 2024-10-15 14:58:13 -06:00
Behdad Esfahbod
0ce67f56dd [coretext-font] Implement font_get_h_metrics 2024-10-15 14:58:13 -06:00
Behdad Esfahbod
e31ea830c8 [ft] Try using a ref-counted ft_library
https://github.com/harfbuzz/harfbuzz/pull/4895#issuecomment-2412348792
2024-10-15 14:58:13 -06:00
Behdad Esfahbod
52becf1c6d [test] Fix a leak 2024-10-15 14:58:13 -06:00
Behdad Esfahbod
a8360b7e95 [perf] Respect new envvar HB_FACE_LOADER 2024-10-15 14:58:13 -06:00
Behdad Esfahbod
c224178a09 [perf] Add hb-benchmark.hh 2024-10-15 14:58:13 -06:00
Behdad Esfahbod
2dc6334133 [tests] Remove invalid tests from collections.tests
Previously we silently returned the empty face if face_index
was out of range. With util/ now using the new API
hb_font_face_create_from_file_or_fail(), that returns a nullptr
face now. So, adjust tests.
2024-10-15 14:58:13 -06:00
Behdad Esfahbod
734ba5ab48 [hb-info] Fix font face number recording for .dfont 2024-10-15 14:58:13 -06:00
Behdad Esfahbod
67591f8511 [util] Add --face-loader
Currently crashes with ft. Investigating.
2024-10-15 14:58:13 -06:00
Behdad Esfahbod
75d168cbf4 [util] Rename a variable 2024-10-15 14:58:13 -06:00
Behdad Esfahbod
aa933abb76 [util] Use hb_face_create_from_file_or_fail() 2024-10-15 14:58:13 -06:00
Behdad Esfahbod
12fc715dd6 [ft] Add hb_ft_face_create_from_file_or_fail()
New API:
+hb_ft_face_create_from_file_or_fail()
2024-10-15 14:58:13 -06:00
Behdad Esfahbod
89c83b5b08 [coretext] Add hb_coretext_face_create_from_file_or_fail()
New API hb_coretext_face_create_from_file_or_fail()
2024-10-15 13:06:51 -06:00
dependabot[bot]
5f8b77d195 Bump github/codeql-action from 3.26.11 to 3.26.12
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.26.11 to 3.26.12.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](6db8d6351f...c36620d31a)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-14 16:08:28 -06:00
dependabot[bot]
bb5a8284e0 Bump actions/upload-artifact from 4.4.0 to 4.4.3
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.4.0 to 4.4.3.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](50769540e7...b4b15b8c7c)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-14 16:08:18 -06:00
dependabot[bot]
ea3b6c60ba Bump actions/checkout from 4.2.0 to 4.2.1
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.0 to 4.2.1.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](d632683dd7...eef61447b9)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-14 16:08:07 -06:00
Behdad Esfahbod
b12acba494 [face] Add hb_face_create_from_file_or_fail()
New API:
+ hb_face_create_from_file_or_fail()
2024-10-13 13:04:29 -06:00
Behdad Esfahbod
2437fd883a [face] Add hb_face_create_or_fail()
New API:
+ hb_face_create_or_fail()
2024-10-13 13:04:29 -06:00
Behdad Esfahbod
2166a46ad3 [coretext] Don't set CoreText funcs on new CoreText fonts 2024-10-13 13:04:29 -06:00
Behdad Esfahbod
62ae9fbd6a [coretext-font] Implement get_glyph_from_name 2024-10-13 13:04:29 -06:00
Behdad Esfahbod
b5e9f2cb2b [coretext-font] Implement get_glyph_extents 2024-10-13 13:04:29 -06:00
Behdad Esfahbod
8db2997e4e [coretext] Configure hb_coretext_font_create() with CT font funcs
Not sure if this is a good idea...
2024-10-13 13:04:29 -06:00
Behdad Esfahbod
8a805271a1 [coretext] Start implementing CoreText font-funcs
Does nominal glyph mapping, horiz advances, and draw so far.
2024-10-13 13:04:29 -06:00
Behdad Esfahbod
064b24177b [coretext] Rename hb-coretext.cc to hb-coretext-shape.cc 2024-10-13 13:04:29 -06:00
Behdad Esfahbod
e1269215f9 Revert "Fix a compiler warning"
This reverts commit 377e3c67a4.

377e3c67a4 (commitcomment-147888850)
2024-10-13 13:01:09 -06:00
Behdad Esfahbod
755929c48d Fix more compiler warnings
In case FreeType is not available.
2024-10-12 20:08:32 -06:00
Behdad Esfahbod
377e3c67a4 Fix a compiler warning 2024-10-12 20:06:54 -06:00
Behdad Esfahbod
ab36089924 [CFF] Increase max op num limit
This actually counts operands too, not just operators.
In a big variable-font design-space, each blend can easily take
a dozen ops or more. I was sent a font for which this limit
was hit. Increase by 20x for now.
2024-10-10 14:47:57 -06:00
Behdad Esfahbod
1a4bdd699a [font] Change fallback y_advance sign
Ouch.
2024-10-10 14:16:14 -06:00
Khaled Hosny
9c00255b4a [ci] Fix Codecov upload
Setup a repository token and use it, this seems to be required now.
2024-10-10 14:20:26 +03:00
Khaled Hosny
6a25df24b0 [COLR] Add and use get_clip_list () 2024-10-09 10:23:12 -06:00
Khaled Hosny
5462978c90 [COLR] Lets see if this makes CIFUZZ any happier 2024-10-09 10:23:12 -06:00
Behdad Esfahbod
008505e1c4 [COLR] Pepper some hb_barrier()'s around
The version is a minor version (because uint16), as such
version > 1 should be considered as supporting version 1
data.
2024-10-08 09:31:29 -06:00
Khaled Hosny
cec95a2d26 Try to fix heap-buffer-overflow 2024-10-07 13:24:14 -06:00
Khaled Hosny
4d1f6e049c [COLR] Enable COLRv0 support in get_extents()
paint_glyph() supports COLRv0 but this code is never reached because of
the early return if version is not 1. This early return seems to be from
before COLRv0 extents were supported.
2024-10-07 13:24:14 -06:00
Behdad Esfahbod
4587e08a46 [VarStoreInstancer] Fix null deref
Should fix this hopefully:
https://github.com/harfbuzz/harfbuzz/actions/runs/11203732283/job/31141330056?pr=4885
2024-10-07 08:41:23 -06:00
Behdad Esfahbod
e8de8d88df [CONFIG] Remove unused HB_NDEBUG 2024-10-07 06:11:25 -06:00
dependabot[bot]
50d67b202a Bump codecov/codecov-action from 4.5.0 to 4.6.0
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.5.0 to 4.6.0.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](e28ff129e5...b9fd7d16f6)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-07 05:47:42 -06:00
dependabot[bot]
d9c029755c Bump github/codeql-action from 3.26.9 to 3.26.11
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.26.9 to 3.26.11.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](461ef6c76d...6db8d6351f)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-07 05:47:29 -06:00
Julien Nabet
e157205499 unused-parameter in test/fuzzing/hb-draw-fuzzer.cc
../test/fuzzing/hb-draw-fuzzer.cc:19:28: error: unused parameter 'dfuncs' [-Werror,-Wunused-parameter]
_move_to (hb_draw_funcs_t *dfuncs, void *draw_data_,
                           ^
../test/fuzzing/hb-draw-fuzzer.cc:22:10: error: unused parameter 'user_data' [-Werror,-Wunused-parameter]
          void *user_data)
                ^
../test/fuzzing/hb-draw-fuzzer.cc:31:28: error: unused parameter 'dfuncs' [-Werror,-Wunused-parameter]
_line_to (hb_draw_funcs_t *dfuncs, void *draw_data_,
                           ^
../test/fuzzing/hb-draw-fuzzer.cc:34:10: error: unused parameter 'user_data' [-Werror,-Wunused-parameter]
          void *user_data)
                ^
../test/fuzzing/hb-draw-fuzzer.cc:44:33: error: unused parameter 'dfuncs' [-Werror,-Wunused-parameter]
_quadratic_to (hb_draw_funcs_t *dfuncs, void *draw_data_,
                                ^
../test/fuzzing/hb-draw-fuzzer.cc:46:15: error: unused parameter 'control_x' [-Werror,-Wunused-parameter]
               float control_x, float control_y,
                     ^
../test/fuzzing/hb-draw-fuzzer.cc:46:32: error: unused parameter 'control_y' [-Werror,-Wunused-parameter]
               float control_x, float control_y,
                                      ^
../test/fuzzing/hb-draw-fuzzer.cc:48:15: error: unused parameter 'user_data' [-Werror,-Wunused-parameter]
               void *user_data)
                     ^
../test/fuzzing/hb-draw-fuzzer.cc:58:29: error: unused parameter 'dfuncs' [-Werror,-Wunused-parameter]
_cubic_to (hb_draw_funcs_t *dfuncs, void *draw_data_,
                            ^
../test/fuzzing/hb-draw-fuzzer.cc:60:11: error: unused parameter 'control1_x' [-Werror,-Wunused-parameter]
           float control1_x, float control1_y,
                 ^
../test/fuzzing/hb-draw-fuzzer.cc:60:29: error: unused parameter 'control1_y' [-Werror,-Wunused-parameter]
           float control1_x, float control1_y,
                                   ^
../test/fuzzing/hb-draw-fuzzer.cc:61:11: error: unused parameter 'control2_x' [-Werror,-Wunused-parameter]
           float control2_x, float control2_y,
                 ^
../test/fuzzing/hb-draw-fuzzer.cc:61:29: error: unused parameter 'control2_y' [-Werror,-Wunused-parameter]
           float control2_x, float control2_y,
                                   ^
../test/fuzzing/hb-draw-fuzzer.cc:63:11: error: unused parameter 'user_data' [-Werror,-Wunused-parameter]
           void *user_data)
                 ^
../test/fuzzing/hb-draw-fuzzer.cc:73:31: error: unused parameter 'dfuncs' [-Werror,-Wunused-parameter]
_close_path (hb_draw_funcs_t *dfuncs, void *draw_data_,
                              ^
../test/fuzzing/hb-draw-fuzzer.cc:75:13: error: unused parameter 'user_data' [-Werror,-Wunused-parameter]
             void *user_data)
                   ^
16 errors generated.
2024-10-06 22:48:37 +03:00
Julien Nabet
8de0d91166 missing-field-initializers in test/api/test-ot-face.c
FAILED: test/fuzzing/hb-shape-fuzzer.p/hb-shape-fuzzer.cc.o clang++ -Itest/fuzzing/hb-shape-fuzzer.p -Itest/fuzzing -I../test/fuzzing -I. -I.. -Isrc -I../src -fdiagnostics-color=always -D_GLIBCXX_ASSERTIONS=1 -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -std=c++11 -fno-exceptions -O3 -fno-exceptions -fno-rtti -fno-threadsafe-statics -fvisibility-inlines-hidden -DHAVE_CONFIG_H -Wall -Wextra -Werror -MD -MQ test/fuzzing/hb-shape-fuzzer.p/hb-shape-fuzzer.cc.o -MF test/fuzzing/hb-shape-fuzzer.p/hb-shape-fuzzer.cc.o.d -o test/fuzzing/hb-shape-fuzzer.p/hb-shape-fuzzer.cc.o -c ../test/fuzzing/hb-shape-fuzzer.cc In file included from ../test/fuzzing/hb-shape-fuzzer.cc:9: ../test/fuzzing/../api/test-ot-face.c:47:34: error: missing field 'y_bearing' initializer [-Werror,-Wmissing-field-initializers]
hb_glyph_extents_t extents = {0};
^
../test/fuzzing/../api/test-ot-face.c:85:55: error: missing field 'enable' initializer [-Werror,-Wmissing-field-initializers]
hb_aat_layout_feature_selector_info_t setting = {0};
^
2 errors generated.
2024-10-06 12:47:27 -06:00
David Corbett
b6196986d7 [USE] Update the data files
This uses the data files from
<e00698c07a/USE>.
2024-10-03 19:54:54 -06:00
David Corbett
31b22016a2 [ot-tags] Update IANA and OT language registries 2024-10-03 19:54:54 -06:00
Julien Nabet
5772f4ffce missing-field-initializers in main.cc
FAILED: src/main.p/main.cc.o
clang++ -Isrc/main.p -Isrc -I../src -I. -I.. -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/sysprof-6 -fdiagnostics-color=always -D_GLIBCXX_ASSERTIONS=1 -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -std=c++11 -fno-exceptions -O3 -fno-exceptions -fno-rtti -fno-threadsafe-statics -fvisibility-inlines-hidden -DHAVE_CONFIG_H -Wall -Wextra -Werror -pthread -Wno-non-virtual-dtor -UNDEBUG -MD -MQ src/main.p/main.cc.o -MF src/main.p/main.cc.o.d -o src/main.p/main.cc.o -c ../src/main.cc
../src/main.cc:220:33: error: missing field 'y_bearing' initializer [-Werror,-Wmissing-field-initializers]
        hb_glyph_extents_t extents = {0};
                                       ^
../src/main.cc:270:36: error: missing field 'y_bearing' initializer [-Werror,-Wmissing-field-initializers]
    hb_glyph_extents_t extents = {0};
                                   ^
2 errors generated.
2024-10-01 11:33:20 -06:00
Julien Nabet
18f1d9121e missing-field-initializers in hb-draw.h
With clang build, I got:
FAILED: test/api/test-draw.p/test-draw.c.o
clang -Itest/api/test-draw.p -Itest/api -I../test/api -I. -I.. -Isrc -I../src -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/sysprof-6 -I/usr/include/freetype2 -I/usr/include/libpng16 -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -O3 -DHAVE_CONFIG_H -Wall -Wextra -Werror -pthread -MD -MQ test/api/test-draw.p/test-draw.c.o -MF test/api/test-draw.p/test-draw.c.o.d -o test/api/test-draw.p/test-draw.c.o -c ../test/api/test-draw.c
../test/api/test-draw.c:920:26: error: missing field 'reserved4' initializer [-Werror,-Wmissing-field-initializers]
    hb_draw_state_t st = HB_DRAW_STATE_DEFAULT;
                         ^
../src/hb-draw.h:73:71: note: expanded from macro 'HB_DRAW_STATE_DEFAULT'
define HB_DRAW_STATE_DEFAULT {0, 0.f, 0.f, 0.f, 0.f, {0.}, {0.}, {0.}}
2024-10-01 11:11:10 -06:00
Behdad Esfahbod
c1c0e82e3f Revert "Bump setuptools from 73.0.1 to 75.1.0 in /.ci"
This reverts commit a87fa89b4e.

Build was failing in linux-ci.
2024-09-30 09:46:27 -06:00
dependabot[bot]
4aad43c826 Bump github/codeql-action from 3.26.8 to 3.26.9
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.26.8 to 3.26.9.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](294a9d9291...461ef6c76d)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-30 09:43:53 -06:00
dependabot[bot]
a891445449 Bump actions/checkout from 4.1.7 to 4.2.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.7 to 4.2.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](692973e3d9...d632683dd7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-30 09:43:40 -06:00
dependabot[bot]
a87fa89b4e Bump setuptools from 73.0.1 to 75.1.0 in /.ci
Bumps [setuptools](https://github.com/pypa/setuptools) from 73.0.1 to 75.1.0.
- [Release notes](https://github.com/pypa/setuptools/releases)
- [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/setuptools/compare/v73.0.1...v75.1.0)

---
updated-dependencies:
- dependency-name: setuptools
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-30 09:43:24 -06:00
dependabot[bot]
fa79b51d13 Bump fonttools from 4.53.1 to 4.54.1 in /.ci
Bumps [fonttools](https://github.com/fonttools/fonttools) from 4.53.1 to 4.54.1.
- [Release notes](https://github.com/fonttools/fonttools/releases)
- [Changelog](https://github.com/fonttools/fonttools/blob/main/NEWS.rst)
- [Commits](https://github.com/fonttools/fonttools/compare/4.53.1...4.54.1)

---
updated-dependencies:
- dependency-name: fonttools
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-30 09:43:11 -06:00
Behdad Esfahbod
c7ef6a2ed5 Remove the hack re variation-selectors
Instead of abusing an unused Gen_Cat value, use existing facilities
to remember variation selectors.

Addresses
https://github.com/RazrFalcon/rustybuzz/pull/134#issuecomment-2374894164
2024-09-25 19:42:40 -06:00
1138 changed files with 64495 additions and 13206 deletions

48
.ci/build-win.sh Executable file
View file

@ -0,0 +1,48 @@
#!/bin/bash
set -ex
if [ "$#" -lt 1 ]
then
echo "Usage $0 ARCH (ARCH can be 32 or 64)"
exit 1
fi
ARCH=$1
shift
BUILD=build-win${ARCH}
INSTALL=install-win${ARCH}
DIST=harfbuzz-win${ARCH}
meson setup \
--buildtype=release \
--prefix="${PWD}/${BUILD}/${INSTALL}" \
--cross-file=.ci/win${ARCH}-cross-file.txt \
--wrap-mode=default \
--strip \
-Dtests=enabled \
-Dcairo=enabled \
-Dcairo:fontconfig=disabled \
-Dcairo:freetype=disabled \
-Dcairo:dwrite=disabled \
-Dcairo:tests=disabled \
-Dglib=enabled \
-Dlibffi:tests=false \
-Dfreetype=disabled \
-Dicu=disabled \
-Dchafa=disabled \
-Dgdi=enabled \
-Ddirectwrite=enabled \
${BUILD} \
"$@"
# building with all the cores won't work fine with CricleCI for some reason
meson compile -C ${BUILD} -j3
meson install -C ${BUILD}
mkdir ${BUILD}/${DIST}
cp ${BUILD}/${INSTALL}/bin/hb-*.exe ${BUILD}/${DIST}
cp ${BUILD}/${INSTALL}/bin/*.dll ${BUILD}/${DIST}
rm -f ${DIST}.zip
(cd ${BUILD} && zip -r ../${DIST}.zip ${DIST})
echo "${DIST}.zip is ready."

View file

@ -1,28 +0,0 @@
#!/bin/bash
set -e
meson --cross-file=.ci/win32-cross-file.txt \
--wrap-mode=default \
-Dtests=disabled \
-Dcairo=enabled \
-Dcairo:fontconfig=disabled \
-Dcairo:freetype=disabled \
-Dcairo:dwrite=disabled \
-Dcairo:tests=disabled \
-Dglib=enabled \
-Dfreetype=disabled \
-Dgdi=enabled \
-Ddirectwrite=enabled \
win32build \
$@
ninja -Cwin32build -j3 # building with all the cores won't work fine with CricleCI for some reason
rm -rf win32build/harfbuzz-win32
mkdir win32build/harfbuzz-win32
cp win32build/util/hb-*.exe win32build/harfbuzz-win32
find win32build -name '*.dll' -exec cp {} win32build/harfbuzz-win32 \;
i686-w64-mingw32-strip win32build/harfbuzz-win32/*.{dll,exe}
rm -f harfbuzz-win32.zip
(cd win32build && zip -r ../harfbuzz-win32.zip harfbuzz-win32)
echo "harfbuzz-win32.zip is ready."

View file

@ -1,28 +0,0 @@
#!/bin/bash
set -e
meson --cross-file=.ci/win64-cross-file.txt \
--wrap-mode=default \
-Dtests=disabled \
-Dcairo=enabled \
-Dcairo:fontconfig=disabled \
-Dcairo:freetype=disabled \
-Dcairo:dwrite=disabled \
-Dcairo:tests=disabled \
-Dglib=enabled \
-Dfreetype=disabled \
-Dgdi=enabled \
-Ddirectwrite=enabled \
win64build \
$@
ninja -Cwin64build -j3 # building with all the cores won't work fine with CricleCI for some reason
rm -rf win64build/harfbuzz-win64
mkdir win64build/harfbuzz-win64
cp win64build/util/hb-*.exe win64build/harfbuzz-win64
find win64build -name '*.dll' -exec cp {} win64build/harfbuzz-win64 \;
x86_64-w64-mingw32-strip win64build/harfbuzz-win64/*.{dll,exe}
rm -f harfbuzz-win64.zip
(cd win64build && zip -r ../harfbuzz-win64.zip harfbuzz-win64)
echo "harfbuzz-win64.zip is ready."

View file

@ -11,12 +11,11 @@ fi
if ! hash ghr 2> /dev/null; then
_GHR_VER=v0.14.0
_GHR=ghr_${_GHR_VER}_linux_amd64
mkdir -p $HOME/.local/bin
curl -sfL https://github.com/tcnksm/ghr/releases/download/$_GHR_VER/$_GHR.tar.gz |
tar xz -C $HOME/.local/bin --strip-components=1 $_GHR/ghr
tar xz -C . --strip-components=1 $_GHR/ghr
fi
ghr -replace \
./ghr -replace \
-u $CIRCLE_PROJECT_USERNAME \
-r $CIRCLE_PROJECT_REPONAME \
$CIRCLE_TAG \

View file

@ -4,47 +4,55 @@
#
# pip-compile --generate-hashes .ci/requirements-fonttools.in
#
fonttools==4.53.1 \
--hash=sha256:02569e9a810f9d11f4ae82c391ebc6fb5730d95a0657d24d754ed7763fb2d122 \
--hash=sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397 \
--hash=sha256:10f5e6c3510b79ea27bb1ebfcc67048cde9ec67afa87c7dd7efa5c700491ac7f \
--hash=sha256:2af40ae9cdcb204fc1d8f26b190aa16534fcd4f0df756268df674a270eab575d \
--hash=sha256:32f029c095ad66c425b0ee85553d0dc326d45d7059dbc227330fc29b43e8ba60 \
--hash=sha256:35250099b0cfb32d799fb5d6c651220a642fe2e3c7d2560490e6f1d3f9ae9169 \
--hash=sha256:3b3c8ebafbee8d9002bd8f1195d09ed2bd9ff134ddec37ee8f6a6375e6a4f0e8 \
--hash=sha256:4824c198f714ab5559c5be10fd1adf876712aa7989882a4ec887bf1ef3e00e31 \
--hash=sha256:5ff7e5e9bad94e3a70c5cd2fa27f20b9bb9385e10cddab567b85ce5d306ea923 \
--hash=sha256:651390c3b26b0c7d1f4407cad281ee7a5a85a31a110cbac5269de72a51551ba2 \
--hash=sha256:6e08f572625a1ee682115223eabebc4c6a2035a6917eac6f60350aba297ccadb \
--hash=sha256:6ed170b5e17da0264b9f6fae86073be3db15fa1bd74061c8331022bca6d09bab \
--hash=sha256:73379d3ffdeecb376640cd8ed03e9d2d0e568c9d1a4e9b16504a834ebadc2dfb \
--hash=sha256:75a157d8d26c06e64ace9df037ee93a4938a4606a38cb7ffaf6635e60e253b7a \
--hash=sha256:791b31ebbc05197d7aa096bbc7bd76d591f05905d2fd908bf103af4488e60670 \
--hash=sha256:7b6b35e52ddc8fb0db562133894e6ef5b4e54e1283dff606fda3eed938c36fc8 \
--hash=sha256:84ec3fb43befb54be490147b4a922b5314e16372a643004f182babee9f9c3407 \
--hash=sha256:8959a59de5af6d2bec27489e98ef25a397cfa1774b375d5787509c06659b3671 \
--hash=sha256:9dfdae43b7996af46ff9da520998a32b105c7f098aeea06b2226b30e74fbba88 \
--hash=sha256:9e6ceba2a01b448e36754983d376064730690401da1dd104ddb543519470a15f \
--hash=sha256:9efd176f874cb6402e607e4cc9b4a9cd584d82fc34a4b0c811970b32ba62501f \
--hash=sha256:a1c7c5aa18dd3b17995898b4a9b5929d69ef6ae2af5b96d585ff4005033d82f0 \
--hash=sha256:aae7bd54187e8bf7fd69f8ab87b2885253d3575163ad4d669a262fe97f0136cb \
--hash=sha256:b21952c092ffd827504de7e66b62aba26fdb5f9d1e435c52477e6486e9d128b2 \
--hash=sha256:b96cd370a61f4d083c9c0053bf634279b094308d52fdc2dd9a22d8372fdd590d \
--hash=sha256:becc5d7cb89c7b7afa8321b6bb3dbee0eec2b57855c90b3e9bf5fb816671fa7c \
--hash=sha256:bee32ea8765e859670c4447b0817514ca79054463b6b79784b08a8df3a4d78e3 \
--hash=sha256:c6e7170d675d12eac12ad1a981d90f118c06cf680b42a2d74c6c931e54b50719 \
--hash=sha256:c818c058404eb2bba05e728d38049438afd649e3c409796723dfc17cd3f08749 \
--hash=sha256:c8696544c964500aa9439efb6761947393b70b17ef4e82d73277413f291260a4 \
--hash=sha256:c9cd19cf4fe0595ebdd1d4915882b9440c3a6d30b008f3cc7587c1da7b95be5f \
--hash=sha256:d4d0096cb1ac7a77b3b41cd78c9b6bc4a400550e21dc7a92f2b5ab53ed74eb02 \
--hash=sha256:d92d3c2a1b39631a6131c2fa25b5406855f97969b068e7e08413325bc0afba58 \
--hash=sha256:da33440b1413bad53a8674393c5d29ce64d8c1a15ef8a77c642ffd900d07bfe1 \
--hash=sha256:e013aae589c1c12505da64a7d8d023e584987e51e62006e1bb30d72f26522c41 \
--hash=sha256:e128778a8e9bc11159ce5447f76766cefbd876f44bd79aff030287254e4752c4 \
--hash=sha256:e54f1bba2f655924c1138bbc7fa91abd61f45c68bd65ab5ed985942712864bbb \
--hash=sha256:e5b708073ea3d684235648786f5f6153a48dc8762cdfe5563c57e80787c29fbb \
--hash=sha256:e8bf06b94694251861ba7fdeea15c8ec0967f84c3d4143ae9daf42bbc7717fe3 \
--hash=sha256:f08df60fbd8d289152079a65da4e66a447efc1d5d5a4d3f299cdd39e3b2e4a7d \
--hash=sha256:f1f8758a2ad110bd6432203a344269f445a2907dc24ef6bccfd0ac4e14e0d71d \
--hash=sha256:f677ce218976496a587ab17140da141557beb91d2a5c1a14212c994093f2eae2
fonttools==4.57.0 \
--hash=sha256:03290e818782e7edb159474144fca11e36a8ed6663d1fcbd5268eb550594fd8e \
--hash=sha256:0425c2e052a5f1516c94e5855dbda706ae5a768631e9fcc34e57d074d1b65b92 \
--hash=sha256:05efceb2cb5f6ec92a4180fcb7a64aa8d3385fd49cfbbe459350229d1974f0b1 \
--hash=sha256:17168a4670bbe3775f3f3f72d23ee786bd965395381dfbb70111e25e81505b9d \
--hash=sha256:3122c604a675513c68bd24c6a8f9091f1c2376d18e8f5fe5a101746c81b3e98f \
--hash=sha256:34687a5d21f1d688d7d8d416cb4c5b9c87fca8a1797ec0d74b9fdebfa55c09ab \
--hash=sha256:3871349303bdec958360eedb619169a779956503ffb4543bb3e6211e09b647c4 \
--hash=sha256:39acf68abdfc74e19de7485f8f7396fa4d2418efea239b7061d6ed6a2510c746 \
--hash=sha256:3cf97236b192a50a4bf200dc5ba405aa78d4f537a2c6e4c624bb60466d5b03bd \
--hash=sha256:408ce299696012d503b714778d89aa476f032414ae57e57b42e4b92363e0b8ef \
--hash=sha256:44c26a311be2ac130f40a96769264809d3b0cb297518669db437d1cc82974888 \
--hash=sha256:46370ac47a1e91895d40e9ad48effbe8e9d9db1a4b80888095bc00e7beaa042f \
--hash=sha256:4dea5893b58d4637ffa925536462ba626f8a1b9ffbe2f5c272cdf2c6ebadb817 \
--hash=sha256:51d8482e96b28fb28aa8e50b5706f3cee06de85cbe2dce80dbd1917ae22ec5a6 \
--hash=sha256:541cb48191a19ceb1a2a4b90c1fcebd22a1ff7491010d3cf840dd3a68aebd654 \
--hash=sha256:579ba873d7f2a96f78b2e11028f7472146ae181cae0e4d814a37a09e93d5c5cc \
--hash=sha256:57e30241524879ea10cdf79c737037221f77cc126a8cdc8ff2c94d4a522504b9 \
--hash=sha256:69ab81b66ebaa8d430ba56c7a5f9abe0183afefd3a2d6e483060343398b13fb1 \
--hash=sha256:6e3e1ec10c29bae0ea826b61f265ec5c858c5ba2ce2e69a71a62f285cf8e4595 \
--hash=sha256:727ece10e065be2f9dd239d15dd5d60a66e17eac11aea47d447f9f03fdbc42de \
--hash=sha256:7339e6a3283e4b0ade99cade51e97cde3d54cd6d1c3744459e886b66d630c8b3 \
--hash=sha256:767604f244dc17c68d3e2dbf98e038d11a18abc078f2d0f84b6c24571d9c0b13 \
--hash=sha256:7a64edd3ff6a7f711a15bd70b4458611fb240176ec11ad8845ccbab4fe6745db \
--hash=sha256:81aa97669cd726349eb7bd43ca540cf418b279ee3caba5e2e295fb4e8f841c02 \
--hash=sha256:84c41ba992df5b8d680b89fd84c6a1f2aca2b9f1ae8a67400c8930cd4ea115f6 \
--hash=sha256:84fd56c78d431606332a0627c16e2a63d243d0d8b05521257d77c6529abe14d8 \
--hash=sha256:889e45e976c74abc7256d3064aa7c1295aa283c6bb19810b9f8b604dfe5c7f31 \
--hash=sha256:8e2e12d0d862f43d51e5afb8b9751c77e6bec7d2dc00aad80641364e9df5b199 \
--hash=sha256:967b65232e104f4b0f6370a62eb33089e00024f2ce143aecbf9755649421c683 \
--hash=sha256:9d077f909f2343daf4495ba22bb0e23b62886e8ec7c109ee8234bdbd678cf344 \
--hash=sha256:9d57b4e23ebbe985125d3f0cabbf286efa191ab60bbadb9326091050d88e8213 \
--hash=sha256:a1968f2a2003c97c4ce6308dc2498d5fd4364ad309900930aa5a503c9851aec8 \
--hash=sha256:a2a722c0e4bfd9966a11ff55c895c817158fcce1b2b6700205a376403b546ad9 \
--hash=sha256:a97bb05eb24637714a04dee85bdf0ad1941df64fe3b802ee4ac1c284a5f97b7c \
--hash=sha256:aff40f8ac6763d05c2c8f6d240c6dac4bb92640a86d9b0c3f3fff4404f34095c \
--hash=sha256:babe8d1eb059a53e560e7bf29f8e8f4accc8b6cfb9b5fd10e485bde77e71ef41 \
--hash=sha256:bbceffc80aa02d9e8b99f2a7491ed8c4a783b2fc4020119dc405ca14fb5c758c \
--hash=sha256:c59375e85126b15a90fcba3443eaac58f3073ba091f02410eaa286da9ad80ed8 \
--hash=sha256:ca2aed95855506b7ae94e8f1f6217b7673c929e4f4f1217bcaa236253055cb36 \
--hash=sha256:cc066cb98b912f525ae901a24cd381a656f024f76203bc85f78fcc9e66ae5aec \
--hash=sha256:cdef9a056c222d0479a1fdb721430f9efd68268014c54e8166133d2643cb05d9 \
--hash=sha256:d07f1b64008e39fceae7aa99e38df8385d7d24a474a8c9872645c4397b674481 \
--hash=sha256:d639397de852f2ccfb3134b152c741406752640a266d9c1365b0f23d7b88077f \
--hash=sha256:dff02c5c8423a657c550b48231d0a48d7e2b2e131088e55983cfe74ccc2c7cc9 \
--hash=sha256:e952c684274a7714b3160f57ec1d78309f955c6335c04433f07d36c5eb27b1f9 \
--hash=sha256:ea1e9e43ca56b0c12440a7c689b1350066595bebcaa83baad05b8b2675129d98 \
--hash=sha256:f022601f3ee9e1f6658ed6d184ce27fa5216cee5b82d279e0f0bde5deebece72 \
--hash=sha256:f0e9618630edd1910ad4f07f60d77c184b2f572c8ee43305ea3265675cbbfe7e \
--hash=sha256:f1d6bc9c23356908db712d282acb3eebd4ae5ec6d8b696aa40342b1d84f8e9e3 \
--hash=sha256:f4376819c1c778d59e0a31db5dc6ede854e9edf28bbfa5b756604727f7f800ac
# via -r requirements-fonttools.in

View file

@ -1,5 +1,4 @@
-r requirements-fonttools.in
meson==1.5.2
gcovr==5.0
meson==1.7.0
ninja
setuptools # https://github.com/harfbuzz/harfbuzz/issues/4475

View file

@ -4,242 +4,84 @@
#
# pip-compile --allow-unsafe --generate-hashes --output-file=.ci/requirements.txt .ci/requirements.in
#
fonttools==4.53.1 \
--hash=sha256:02569e9a810f9d11f4ae82c391ebc6fb5730d95a0657d24d754ed7763fb2d122 \
--hash=sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397 \
--hash=sha256:10f5e6c3510b79ea27bb1ebfcc67048cde9ec67afa87c7dd7efa5c700491ac7f \
--hash=sha256:2af40ae9cdcb204fc1d8f26b190aa16534fcd4f0df756268df674a270eab575d \
--hash=sha256:32f029c095ad66c425b0ee85553d0dc326d45d7059dbc227330fc29b43e8ba60 \
--hash=sha256:35250099b0cfb32d799fb5d6c651220a642fe2e3c7d2560490e6f1d3f9ae9169 \
--hash=sha256:3b3c8ebafbee8d9002bd8f1195d09ed2bd9ff134ddec37ee8f6a6375e6a4f0e8 \
--hash=sha256:4824c198f714ab5559c5be10fd1adf876712aa7989882a4ec887bf1ef3e00e31 \
--hash=sha256:5ff7e5e9bad94e3a70c5cd2fa27f20b9bb9385e10cddab567b85ce5d306ea923 \
--hash=sha256:651390c3b26b0c7d1f4407cad281ee7a5a85a31a110cbac5269de72a51551ba2 \
--hash=sha256:6e08f572625a1ee682115223eabebc4c6a2035a6917eac6f60350aba297ccadb \
--hash=sha256:6ed170b5e17da0264b9f6fae86073be3db15fa1bd74061c8331022bca6d09bab \
--hash=sha256:73379d3ffdeecb376640cd8ed03e9d2d0e568c9d1a4e9b16504a834ebadc2dfb \
--hash=sha256:75a157d8d26c06e64ace9df037ee93a4938a4606a38cb7ffaf6635e60e253b7a \
--hash=sha256:791b31ebbc05197d7aa096bbc7bd76d591f05905d2fd908bf103af4488e60670 \
--hash=sha256:7b6b35e52ddc8fb0db562133894e6ef5b4e54e1283dff606fda3eed938c36fc8 \
--hash=sha256:84ec3fb43befb54be490147b4a922b5314e16372a643004f182babee9f9c3407 \
--hash=sha256:8959a59de5af6d2bec27489e98ef25a397cfa1774b375d5787509c06659b3671 \
--hash=sha256:9dfdae43b7996af46ff9da520998a32b105c7f098aeea06b2226b30e74fbba88 \
--hash=sha256:9e6ceba2a01b448e36754983d376064730690401da1dd104ddb543519470a15f \
--hash=sha256:9efd176f874cb6402e607e4cc9b4a9cd584d82fc34a4b0c811970b32ba62501f \
--hash=sha256:a1c7c5aa18dd3b17995898b4a9b5929d69ef6ae2af5b96d585ff4005033d82f0 \
--hash=sha256:aae7bd54187e8bf7fd69f8ab87b2885253d3575163ad4d669a262fe97f0136cb \
--hash=sha256:b21952c092ffd827504de7e66b62aba26fdb5f9d1e435c52477e6486e9d128b2 \
--hash=sha256:b96cd370a61f4d083c9c0053bf634279b094308d52fdc2dd9a22d8372fdd590d \
--hash=sha256:becc5d7cb89c7b7afa8321b6bb3dbee0eec2b57855c90b3e9bf5fb816671fa7c \
--hash=sha256:bee32ea8765e859670c4447b0817514ca79054463b6b79784b08a8df3a4d78e3 \
--hash=sha256:c6e7170d675d12eac12ad1a981d90f118c06cf680b42a2d74c6c931e54b50719 \
--hash=sha256:c818c058404eb2bba05e728d38049438afd649e3c409796723dfc17cd3f08749 \
--hash=sha256:c8696544c964500aa9439efb6761947393b70b17ef4e82d73277413f291260a4 \
--hash=sha256:c9cd19cf4fe0595ebdd1d4915882b9440c3a6d30b008f3cc7587c1da7b95be5f \
--hash=sha256:d4d0096cb1ac7a77b3b41cd78c9b6bc4a400550e21dc7a92f2b5ab53ed74eb02 \
--hash=sha256:d92d3c2a1b39631a6131c2fa25b5406855f97969b068e7e08413325bc0afba58 \
--hash=sha256:da33440b1413bad53a8674393c5d29ce64d8c1a15ef8a77c642ffd900d07bfe1 \
--hash=sha256:e013aae589c1c12505da64a7d8d023e584987e51e62006e1bb30d72f26522c41 \
--hash=sha256:e128778a8e9bc11159ce5447f76766cefbd876f44bd79aff030287254e4752c4 \
--hash=sha256:e54f1bba2f655924c1138bbc7fa91abd61f45c68bd65ab5ed985942712864bbb \
--hash=sha256:e5b708073ea3d684235648786f5f6153a48dc8762cdfe5563c57e80787c29fbb \
--hash=sha256:e8bf06b94694251861ba7fdeea15c8ec0967f84c3d4143ae9daf42bbc7717fe3 \
--hash=sha256:f08df60fbd8d289152079a65da4e66a447efc1d5d5a4d3f299cdd39e3b2e4a7d \
--hash=sha256:f1f8758a2ad110bd6432203a344269f445a2907dc24ef6bccfd0ac4e14e0d71d \
--hash=sha256:f677ce218976496a587ab17140da141557beb91d2a5c1a14212c994093f2eae2
fonttools==4.57.0 \
--hash=sha256:03290e818782e7edb159474144fca11e36a8ed6663d1fcbd5268eb550594fd8e \
--hash=sha256:0425c2e052a5f1516c94e5855dbda706ae5a768631e9fcc34e57d074d1b65b92 \
--hash=sha256:05efceb2cb5f6ec92a4180fcb7a64aa8d3385fd49cfbbe459350229d1974f0b1 \
--hash=sha256:17168a4670bbe3775f3f3f72d23ee786bd965395381dfbb70111e25e81505b9d \
--hash=sha256:3122c604a675513c68bd24c6a8f9091f1c2376d18e8f5fe5a101746c81b3e98f \
--hash=sha256:34687a5d21f1d688d7d8d416cb4c5b9c87fca8a1797ec0d74b9fdebfa55c09ab \
--hash=sha256:3871349303bdec958360eedb619169a779956503ffb4543bb3e6211e09b647c4 \
--hash=sha256:39acf68abdfc74e19de7485f8f7396fa4d2418efea239b7061d6ed6a2510c746 \
--hash=sha256:3cf97236b192a50a4bf200dc5ba405aa78d4f537a2c6e4c624bb60466d5b03bd \
--hash=sha256:408ce299696012d503b714778d89aa476f032414ae57e57b42e4b92363e0b8ef \
--hash=sha256:44c26a311be2ac130f40a96769264809d3b0cb297518669db437d1cc82974888 \
--hash=sha256:46370ac47a1e91895d40e9ad48effbe8e9d9db1a4b80888095bc00e7beaa042f \
--hash=sha256:4dea5893b58d4637ffa925536462ba626f8a1b9ffbe2f5c272cdf2c6ebadb817 \
--hash=sha256:51d8482e96b28fb28aa8e50b5706f3cee06de85cbe2dce80dbd1917ae22ec5a6 \
--hash=sha256:541cb48191a19ceb1a2a4b90c1fcebd22a1ff7491010d3cf840dd3a68aebd654 \
--hash=sha256:579ba873d7f2a96f78b2e11028f7472146ae181cae0e4d814a37a09e93d5c5cc \
--hash=sha256:57e30241524879ea10cdf79c737037221f77cc126a8cdc8ff2c94d4a522504b9 \
--hash=sha256:69ab81b66ebaa8d430ba56c7a5f9abe0183afefd3a2d6e483060343398b13fb1 \
--hash=sha256:6e3e1ec10c29bae0ea826b61f265ec5c858c5ba2ce2e69a71a62f285cf8e4595 \
--hash=sha256:727ece10e065be2f9dd239d15dd5d60a66e17eac11aea47d447f9f03fdbc42de \
--hash=sha256:7339e6a3283e4b0ade99cade51e97cde3d54cd6d1c3744459e886b66d630c8b3 \
--hash=sha256:767604f244dc17c68d3e2dbf98e038d11a18abc078f2d0f84b6c24571d9c0b13 \
--hash=sha256:7a64edd3ff6a7f711a15bd70b4458611fb240176ec11ad8845ccbab4fe6745db \
--hash=sha256:81aa97669cd726349eb7bd43ca540cf418b279ee3caba5e2e295fb4e8f841c02 \
--hash=sha256:84c41ba992df5b8d680b89fd84c6a1f2aca2b9f1ae8a67400c8930cd4ea115f6 \
--hash=sha256:84fd56c78d431606332a0627c16e2a63d243d0d8b05521257d77c6529abe14d8 \
--hash=sha256:889e45e976c74abc7256d3064aa7c1295aa283c6bb19810b9f8b604dfe5c7f31 \
--hash=sha256:8e2e12d0d862f43d51e5afb8b9751c77e6bec7d2dc00aad80641364e9df5b199 \
--hash=sha256:967b65232e104f4b0f6370a62eb33089e00024f2ce143aecbf9755649421c683 \
--hash=sha256:9d077f909f2343daf4495ba22bb0e23b62886e8ec7c109ee8234bdbd678cf344 \
--hash=sha256:9d57b4e23ebbe985125d3f0cabbf286efa191ab60bbadb9326091050d88e8213 \
--hash=sha256:a1968f2a2003c97c4ce6308dc2498d5fd4364ad309900930aa5a503c9851aec8 \
--hash=sha256:a2a722c0e4bfd9966a11ff55c895c817158fcce1b2b6700205a376403b546ad9 \
--hash=sha256:a97bb05eb24637714a04dee85bdf0ad1941df64fe3b802ee4ac1c284a5f97b7c \
--hash=sha256:aff40f8ac6763d05c2c8f6d240c6dac4bb92640a86d9b0c3f3fff4404f34095c \
--hash=sha256:babe8d1eb059a53e560e7bf29f8e8f4accc8b6cfb9b5fd10e485bde77e71ef41 \
--hash=sha256:bbceffc80aa02d9e8b99f2a7491ed8c4a783b2fc4020119dc405ca14fb5c758c \
--hash=sha256:c59375e85126b15a90fcba3443eaac58f3073ba091f02410eaa286da9ad80ed8 \
--hash=sha256:ca2aed95855506b7ae94e8f1f6217b7673c929e4f4f1217bcaa236253055cb36 \
--hash=sha256:cc066cb98b912f525ae901a24cd381a656f024f76203bc85f78fcc9e66ae5aec \
--hash=sha256:cdef9a056c222d0479a1fdb721430f9efd68268014c54e8166133d2643cb05d9 \
--hash=sha256:d07f1b64008e39fceae7aa99e38df8385d7d24a474a8c9872645c4397b674481 \
--hash=sha256:d639397de852f2ccfb3134b152c741406752640a266d9c1365b0f23d7b88077f \
--hash=sha256:dff02c5c8423a657c550b48231d0a48d7e2b2e131088e55983cfe74ccc2c7cc9 \
--hash=sha256:e952c684274a7714b3160f57ec1d78309f955c6335c04433f07d36c5eb27b1f9 \
--hash=sha256:ea1e9e43ca56b0c12440a7c689b1350066595bebcaa83baad05b8b2675129d98 \
--hash=sha256:f022601f3ee9e1f6658ed6d184ce27fa5216cee5b82d279e0f0bde5deebece72 \
--hash=sha256:f0e9618630edd1910ad4f07f60d77c184b2f572c8ee43305ea3265675cbbfe7e \
--hash=sha256:f1d6bc9c23356908db712d282acb3eebd4ae5ec6d8b696aa40342b1d84f8e9e3 \
--hash=sha256:f4376819c1c778d59e0a31db5dc6ede854e9edf28bbfa5b756604727f7f800ac
# via -r requirements-fonttools.in
gcovr==5.0 \
--hash=sha256:1d80264cbaadff356b3dda71b8c62b3aa803e5b3eb6d526a24932cd6660a2576 \
--hash=sha256:8c49ebcfc5a98b56dd900c687aad0258ac86093d2f81a1417905193ab45fe69f
meson==1.7.0 \
--hash=sha256:08efbe84803eed07f863b05092d653a9d348f7038761d900412fddf56deb0284 \
--hash=sha256:ae3f12953045f3c7c60e27f2af1ad862f14dee125b4ed9bcb8a842a5080dbf85
# via -r requirements.in
jinja2==3.1.4 \
--hash=sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369 \
--hash=sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d
# via gcovr
lxml==4.9.3 \
--hash=sha256:05186a0f1346ae12553d66df1cfce6f251589fea3ad3da4f3ef4e34b2d58c6a3 \
--hash=sha256:075b731ddd9e7f68ad24c635374211376aa05a281673ede86cbe1d1b3455279d \
--hash=sha256:081d32421db5df44c41b7f08a334a090a545c54ba977e47fd7cc2deece78809a \
--hash=sha256:0a3d3487f07c1d7f150894c238299934a2a074ef590b583103a45002035be120 \
--hash=sha256:0bfd0767c5c1de2551a120673b72e5d4b628737cb05414f03c3277bf9bed3305 \
--hash=sha256:0c0850c8b02c298d3c7006b23e98249515ac57430e16a166873fc47a5d549287 \
--hash=sha256:0e2cb47860da1f7e9a5256254b74ae331687b9672dfa780eed355c4c9c3dbd23 \
--hash=sha256:120fa9349a24c7043854c53cae8cec227e1f79195a7493e09e0c12e29f918e52 \
--hash=sha256:1247694b26342a7bf47c02e513d32225ededd18045264d40758abeb3c838a51f \
--hash=sha256:141f1d1a9b663c679dc524af3ea1773e618907e96075262726c7612c02b149a4 \
--hash=sha256:14e019fd83b831b2e61baed40cab76222139926b1fb5ed0e79225bc0cae14584 \
--hash=sha256:1509dd12b773c02acd154582088820893109f6ca27ef7291b003d0e81666109f \
--hash=sha256:17a753023436a18e27dd7769e798ce302963c236bc4114ceee5b25c18c52c693 \
--hash=sha256:1e224d5755dba2f4a9498e150c43792392ac9b5380aa1b845f98a1618c94eeef \
--hash=sha256:1f447ea5429b54f9582d4b955f5f1985f278ce5cf169f72eea8afd9502973dd5 \
--hash=sha256:23eed6d7b1a3336ad92d8e39d4bfe09073c31bfe502f20ca5116b2a334f8ec02 \
--hash=sha256:25f32acefac14ef7bd53e4218fe93b804ef6f6b92ffdb4322bb6d49d94cad2bc \
--hash=sha256:2c74524e179f2ad6d2a4f7caf70e2d96639c0954c943ad601a9e146c76408ed7 \
--hash=sha256:303bf1edce6ced16bf67a18a1cf8339d0db79577eec5d9a6d4a80f0fb10aa2da \
--hash=sha256:3331bece23c9ee066e0fb3f96c61322b9e0f54d775fccefff4c38ca488de283a \
--hash=sha256:3e9bdd30efde2b9ccfa9cb5768ba04fe71b018a25ea093379c857c9dad262c40 \
--hash=sha256:411007c0d88188d9f621b11d252cce90c4a2d1a49db6c068e3c16422f306eab8 \
--hash=sha256:42871176e7896d5d45138f6d28751053c711ed4d48d8e30b498da155af39aebd \
--hash=sha256:46f409a2d60f634fe550f7133ed30ad5321ae2e6630f13657fb9479506b00601 \
--hash=sha256:48628bd53a426c9eb9bc066a923acaa0878d1e86129fd5359aee99285f4eed9c \
--hash=sha256:48d6ed886b343d11493129e019da91d4039826794a3e3027321c56d9e71505be \
--hash=sha256:4930be26af26ac545c3dffb662521d4e6268352866956672231887d18f0eaab2 \
--hash=sha256:4aec80cde9197340bc353d2768e2a75f5f60bacda2bab72ab1dc499589b3878c \
--hash=sha256:4c28a9144688aef80d6ea666c809b4b0e50010a2aca784c97f5e6bf143d9f129 \
--hash=sha256:4d2d1edbca80b510443f51afd8496be95529db04a509bc8faee49c7b0fb6d2cc \
--hash=sha256:4dd9a263e845a72eacb60d12401e37c616438ea2e5442885f65082c276dfb2b2 \
--hash=sha256:4f1026bc732b6a7f96369f7bfe1a4f2290fb34dce00d8644bc3036fb351a4ca1 \
--hash=sha256:4fb960a632a49f2f089d522f70496640fdf1218f1243889da3822e0a9f5f3ba7 \
--hash=sha256:50670615eaf97227d5dc60de2dc99fb134a7130d310d783314e7724bf163f75d \
--hash=sha256:50baa9c1c47efcaef189f31e3d00d697c6d4afda5c3cde0302d063492ff9b477 \
--hash=sha256:53ace1c1fd5a74ef662f844a0413446c0629d151055340e9893da958a374f70d \
--hash=sha256:5515edd2a6d1a5a70bfcdee23b42ec33425e405c5b351478ab7dc9347228f96e \
--hash=sha256:56dc1f1ebccc656d1b3ed288f11e27172a01503fc016bcabdcbc0978b19352b7 \
--hash=sha256:578695735c5a3f51569810dfebd05dd6f888147a34f0f98d4bb27e92b76e05c2 \
--hash=sha256:57aba1bbdf450b726d58b2aea5fe47c7875f5afb2c4a23784ed78f19a0462574 \
--hash=sha256:57d6ba0ca2b0c462f339640d22882acc711de224d769edf29962b09f77129cbf \
--hash=sha256:5c245b783db29c4e4fbbbfc9c5a78be496c9fea25517f90606aa1f6b2b3d5f7b \
--hash=sha256:5c31c7462abdf8f2ac0577d9f05279727e698f97ecbb02f17939ea99ae8daa98 \
--hash=sha256:64f479d719dc9f4c813ad9bb6b28f8390360660b73b2e4beb4cb0ae7104f1c12 \
--hash=sha256:65299ea57d82fb91c7f019300d24050c4ddeb7c5a190e076b5f48a2b43d19c42 \
--hash=sha256:6689a3d7fd13dc687e9102a27e98ef33730ac4fe37795d5036d18b4d527abd35 \
--hash=sha256:690dafd0b187ed38583a648076865d8c229661ed20e48f2335d68e2cf7dc829d \
--hash=sha256:6fc3c450eaa0b56f815c7b62f2b7fba7266c4779adcf1cece9e6deb1de7305ce \
--hash=sha256:704f61ba8c1283c71b16135caf697557f5ecf3e74d9e453233e4771d68a1f42d \
--hash=sha256:71c52db65e4b56b8ddc5bb89fb2e66c558ed9d1a74a45ceb7dcb20c191c3df2f \
--hash=sha256:71d66ee82e7417828af6ecd7db817913cb0cf9d4e61aa0ac1fde0583d84358db \
--hash=sha256:7d298a1bd60c067ea75d9f684f5f3992c9d6766fadbc0bcedd39750bf344c2f4 \
--hash=sha256:8b77946fd508cbf0fccd8e400a7f71d4ac0e1595812e66025bac475a8e811694 \
--hash=sha256:8d7e43bd40f65f7d97ad8ef5c9b1778943d02f04febef12def25f7583d19baac \
--hash=sha256:8df133a2ea5e74eef5e8fc6f19b9e085f758768a16e9877a60aec455ed2609b2 \
--hash=sha256:8ed74706b26ad100433da4b9d807eae371efaa266ffc3e9191ea436087a9d6a7 \
--hash=sha256:92af161ecbdb2883c4593d5ed4815ea71b31fafd7fd05789b23100d081ecac96 \
--hash=sha256:97047f0d25cd4bcae81f9ec9dc290ca3e15927c192df17331b53bebe0e3ff96d \
--hash=sha256:9719fe17307a9e814580af1f5c6e05ca593b12fb7e44fe62450a5384dbf61b4b \
--hash=sha256:9767e79108424fb6c3edf8f81e6730666a50feb01a328f4a016464a5893f835a \
--hash=sha256:9a92d3faef50658dd2c5470af249985782bf754c4e18e15afb67d3ab06233f13 \
--hash=sha256:9bb6ad405121241e99a86efff22d3ef469024ce22875a7ae045896ad23ba2340 \
--hash=sha256:9e28c51fa0ce5674be9f560c6761c1b441631901993f76700b1b30ca6c8378d6 \
--hash=sha256:aca086dc5f9ef98c512bac8efea4483eb84abbf926eaeedf7b91479feb092458 \
--hash=sha256:ae8b9c6deb1e634ba4f1930eb67ef6e6bf6a44b6eb5ad605642b2d6d5ed9ce3c \
--hash=sha256:b0a545b46b526d418eb91754565ba5b63b1c0b12f9bd2f808c852d9b4b2f9b5c \
--hash=sha256:b4e4bc18382088514ebde9328da057775055940a1f2e18f6ad2d78aa0f3ec5b9 \
--hash=sha256:b6420a005548ad52154c8ceab4a1290ff78d757f9e5cbc68f8c77089acd3c432 \
--hash=sha256:b86164d2cff4d3aaa1f04a14685cbc072efd0b4f99ca5708b2ad1b9b5988a991 \
--hash=sha256:bb3bb49c7a6ad9d981d734ef7c7193bc349ac338776a0360cc671eaee89bcf69 \
--hash=sha256:bef4e656f7d98aaa3486d2627e7d2df1157d7e88e7efd43a65aa5dd4714916cf \
--hash=sha256:c0781a98ff5e6586926293e59480b64ddd46282953203c76ae15dbbbf302e8bb \
--hash=sha256:c2006f5c8d28dee289f7020f721354362fa304acbaaf9745751ac4006650254b \
--hash=sha256:c41bfca0bd3532d53d16fd34d20806d5c2b1ace22a2f2e4c0008570bf2c58833 \
--hash=sha256:cd47b4a0d41d2afa3e58e5bf1f62069255aa2fd6ff5ee41604418ca925911d76 \
--hash=sha256:cdb650fc86227eba20de1a29d4b2c1bfe139dc75a0669270033cb2ea3d391b85 \
--hash=sha256:cef2502e7e8a96fe5ad686d60b49e1ab03e438bd9123987994528febd569868e \
--hash=sha256:d27be7405547d1f958b60837dc4c1007da90b8b23f54ba1f8b728c78fdb19d50 \
--hash=sha256:d37017287a7adb6ab77e1c5bee9bcf9660f90ff445042b790402a654d2ad81d8 \
--hash=sha256:d3ff32724f98fbbbfa9f49d82852b159e9784d6094983d9a8b7f2ddaebb063d4 \
--hash=sha256:d73d8ecf8ecf10a3bd007f2192725a34bd62898e8da27eb9d32a58084f93962b \
--hash=sha256:dd708cf4ee4408cf46a48b108fb9427bfa00b9b85812a9262b5c668af2533ea5 \
--hash=sha256:e3cd95e10c2610c360154afdc2f1480aea394f4a4f1ea0a5eacce49640c9b190 \
--hash=sha256:e4da8ca0c0c0aea88fd46be8e44bd49716772358d648cce45fe387f7b92374a7 \
--hash=sha256:eadfbbbfb41b44034a4c757fd5d70baccd43296fb894dba0295606a7cf3124aa \
--hash=sha256:ed667f49b11360951e201453fc3967344d0d0263aa415e1619e85ae7fd17b4e0 \
--hash=sha256:f3df3db1d336b9356dd3112eae5f5c2b8b377f3bc826848567f10bfddfee77e9 \
--hash=sha256:f6bdac493b949141b733c5345b6ba8f87a226029cbabc7e9e121a413e49441e0 \
--hash=sha256:fbf521479bcac1e25a663df882c46a641a9bff6b56dc8b0fafaebd2f66fb231b \
--hash=sha256:fc9b106a1bf918db68619fdcd6d5ad4f972fdd19c01d19bdb6bf63f3589a9ec5 \
--hash=sha256:fcdd00edfd0a3001e0181eab3e63bd5c74ad3e67152c84f93f13769a40e073a7 \
--hash=sha256:fe4bda6bd4340caa6e5cf95e73f8fea5c4bfc55763dd42f1b50a94c1b4a2fbd4
# via gcovr
markupsafe==2.1.3 \
--hash=sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e \
--hash=sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e \
--hash=sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431 \
--hash=sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686 \
--hash=sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c \
--hash=sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559 \
--hash=sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc \
--hash=sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb \
--hash=sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939 \
--hash=sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c \
--hash=sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0 \
--hash=sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4 \
--hash=sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9 \
--hash=sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575 \
--hash=sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba \
--hash=sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d \
--hash=sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd \
--hash=sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3 \
--hash=sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00 \
--hash=sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155 \
--hash=sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac \
--hash=sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52 \
--hash=sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f \
--hash=sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8 \
--hash=sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b \
--hash=sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007 \
--hash=sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24 \
--hash=sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea \
--hash=sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198 \
--hash=sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0 \
--hash=sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee \
--hash=sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be \
--hash=sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2 \
--hash=sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1 \
--hash=sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707 \
--hash=sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6 \
--hash=sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c \
--hash=sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58 \
--hash=sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823 \
--hash=sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779 \
--hash=sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636 \
--hash=sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c \
--hash=sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad \
--hash=sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee \
--hash=sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc \
--hash=sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2 \
--hash=sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48 \
--hash=sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7 \
--hash=sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e \
--hash=sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b \
--hash=sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa \
--hash=sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5 \
--hash=sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e \
--hash=sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb \
--hash=sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9 \
--hash=sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57 \
--hash=sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc \
--hash=sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc \
--hash=sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2 \
--hash=sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11
# via jinja2
meson==1.5.2 \
--hash=sha256:77706e2368a00d789c097632ccf4fc39251fba56d03e1e1b262559a3c7a08f5b \
--hash=sha256:f955e09ab0d71ef180ae85df65991d58ed8430323de7d77a37e11c9ea630910b
ninja==1.11.1.4 \
--hash=sha256:055f386fb550c2c9d6157e45e20a84d29c47968876b9c5794ae2aec46f952306 \
--hash=sha256:096487995473320de7f65d622c3f1d16c3ad174797602218ca8c967f51ec38a0 \
--hash=sha256:2ab67a41c90bea5ec4b795bab084bc0b3b3bb69d3cd21ca0294fc0fc15a111eb \
--hash=sha256:4617b3c12ff64b611a7d93fd9e378275512bb36eff8babff7c83f5116b4f8d66 \
--hash=sha256:5713cf50c5be50084a8693308a63ecf9e55c3132a78a41ab1363a28b6caaaee1 \
--hash=sha256:6aa39f6e894e0452e5b297327db00019383ae55d5d9c57c73b04f13bf79d438a \
--hash=sha256:9c29bb66d2aa46a2409ab369ea804c730faec7652e8c22c1e428cc09216543e5 \
--hash=sha256:b33923c8da88e8da20b6053e38deb433f53656441614207e01d283ad02c5e8e7 \
--hash=sha256:c3b96bd875f3ef1db782470e9e41d7508905a0986571f219d20ffed238befa15 \
--hash=sha256:cede0af00b58e27b31f2482ba83292a8e9171cdb9acc2c867a3b6e40b3353e43 \
--hash=sha256:cf4453679d15babc04ba023d68d091bb613091b67101c88f85d2171c6621c6eb \
--hash=sha256:cf554e73f72c04deb04d0cf51f5fdb1903d9c9ca3d2344249c8ce3bd616ebc02 \
--hash=sha256:cfdd09776436a1ff3c4a2558d3fc50a689fb9d7f1bdbc3e6f7b8c2991341ddb3 \
--hash=sha256:d3090d4488fadf6047d0d7a1db0c9643a8d391f0d94729554dbb89b5bdc769d7 \
--hash=sha256:d4a6f159b08b0ac4aca5ee1572e3e402f969139e71d85d37c0e2872129098749 \
--hash=sha256:ecce44a00325a93631792974659cf253a815cc6da4ec96f89742925dfc295a0d \
--hash=sha256:f6186d7607bb090c3be1e10c8a56b690be238f953616626f5032238c66e56867
# via -r requirements.in
ninja==1.11.1.1 \
--hash=sha256:18302d96a5467ea98b68e1cae1ae4b4fb2b2a56a82b955193c637557c7273dbd \
--hash=sha256:185e0641bde601e53841525c4196278e9aaf4463758da6dd1e752c0a0f54136a \
--hash=sha256:376889c76d87b95b5719fdd61dd7db193aa7fd4432e5d52d2e44e4c497bdbbee \
--hash=sha256:3e0f9be5bb20d74d58c66cc1c414c3e6aeb45c35b0d0e41e8d739c2c0d57784f \
--hash=sha256:73b93c14046447c7c5cc892433d4fae65d6364bec6685411cb97a8bcf815f93a \
--hash=sha256:7563ce1d9fe6ed5af0b8dd9ab4a214bf4ff1f2f6fd6dc29f480981f0f8b8b249 \
--hash=sha256:76482ba746a2618eecf89d5253c0d1e4f1da1270d41e9f54dfbd91831b0f6885 \
--hash=sha256:84502ec98f02a037a169c4b0d5d86075eaf6afc55e1879003d6cab51ced2ea4b \
--hash=sha256:95da904130bfa02ea74ff9c0116b4ad266174fafb1c707aa50212bc7859aebf1 \
--hash=sha256:9d793b08dd857e38d0b6ffe9e6b7145d7c485a42dcfea04905ca0cdb6017cc3c \
--hash=sha256:9df724344202b83018abb45cb1efc22efd337a1496514e7e6b3b59655be85205 \
--hash=sha256:aad34a70ef15b12519946c5633344bc775a7656d789d9ed5fdb0d456383716ef \
--hash=sha256:d491fc8d89cdcb416107c349ad1e3a735d4c4af5e1cb8f5f727baca6350fdaea \
--hash=sha256:ecf80cf5afd09f14dcceff28cb3f11dc90fb97c999c89307aea435889cb66877 \
--hash=sha256:fa2ba9d74acfdfbfbcf06fad1b8282de8a7a8c481d9dee45c859a8c93fcc1082
# via -r requirements.in
pygments==2.16.1 \
--hash=sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692 \
--hash=sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29
# via gcovr
# The following packages are considered to be unsafe in a requirements file:
setuptools==73.0.1 \
--hash=sha256:b208925fcb9f7af924ed2dc04708ea89791e24bde0d3020b27df0e116088b34e \
--hash=sha256:d59a3e788ab7e012ab2c4baed1b376da6366883ee20d7a5fc426816e3d7b1193
setuptools==78.1.0 \
--hash=sha256:18fd474d4a82a5f83dac888df697af65afa82dec7323d09c3e37d1f14288da54 \
--hash=sha256:3e386e96793c8702ae83d17b853fb93d3e09ef82ec62722e61da5cd22376dcd8
# via -r requirements.in

View file

@ -4,7 +4,7 @@ cpu_family = 'x86'
cpu = 'i686'
endian = 'little'
[properties]
[built-in options]
c_args = []
c_link_args = ['-static-libgcc', '-Wl,-Bstatic', '-lpthread']
cpp_args = []
@ -18,3 +18,5 @@ ld = 'i686-w64-mingw32-ld'
objcopy = 'i686-w64-mingw32-objcopy'
strip = 'i686-w64-mingw32-strip'
windres = 'i686-w64-mingw32-windres'
pkg-config = 'i686-w64-mingw32-pkg-config'
exe_wrapper = 'wine'

View file

@ -4,7 +4,7 @@ cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'
[properties]
[built-in options]
c_args = []
c_link_args = ['-static-libgcc', '-Wl,-Bstatic', '-lpthread']
cpp_args = []
@ -18,3 +18,5 @@ ld = 'x86_64-w64-mingw32-ld'
objcopy = 'x86_64-w64-mingw32-objcopy'
strip = 'x86_64-w64-mingw32-strip'
windres = 'x86_64-w64-mingw32-windres'
pkg-config = 'x86_64-w64-mingw32-pkg-config'
exe_wrapper = 'wine'

View file

@ -3,10 +3,10 @@ version: 2.1
executors:
win32-executor:
docker:
- image: cimg/base:2023.10
- image: ubuntu:24.04
win64-executor:
docker:
- image: cimg/base:2023.10
- image: ubuntu:24.04
dist-executor:
docker:
- image: cimg/base:2023.10
@ -37,7 +37,7 @@ jobs:
- run: meson dist --no-tests -Cbuild
- persist_to_workspace:
root: .
paths: build/meson-dist/harfbuzz-*.tar.xz
paths: [build/meson-dist/harfbuzz-*.tar.xz]
publish-dist:
executor: dist-executor
@ -56,22 +56,7 @@ jobs:
- run: dnf install -y pkg-config ragel valgrind gcc gcc-c++ meson git glib2-devel freetype-devel cairo-devel libicu-devel gobject-introspection-devel graphite2-devel redhat-rpm-config python python-pip || true
- run: meson setup build --buildtype=debugoptimized
- run: meson compile -Cbuild -j9
# TOOD: increase timeouts and remove --no-suite=slow
- run: RUN_VALGRIND=1 meson test -Cbuild --no-suite=slow --wrap='valgrind --leak-check=full --error-exitcode=1' --print-errorlogs --num-processes=$(($(nproc)/2 + 1))
alpine:
docker:
- image: alpine
steps:
- checkout
- run: apk update && apk add ragel gcc g++ glib-dev freetype-dev cairo-dev git py3-pip ninja
- run: |
python3 -m venv venv
source venv/bin/activate
pip3 install meson==0.56.0
meson setup build --buildtype=minsize
meson compile -Cbuild -j9
meson test -Cbuild --print-errorlogs
- run: RUN_VALGRIND=1 meson test -Cbuild -t 10 --no-suite=slow --wrap='valgrind --leak-check=full --error-exitcode=1' --print-errorlogs --num-processes=$(($(nproc)/2 + 1))
asan-ubsan:
docker:
@ -81,43 +66,47 @@ jobs:
- run: apt update || true
- run: DEBIAN_FRONTEND=noninteractive apt install -y python3 python3-pip python3-venv ninja-build clang lld git binutils pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev
- run: |
export ASAN_OPTIONS=log_path=stderr:halt_on_error=1:abort_on_error=1
export UBSAN_OPTIONS=log_path=stderr:halt_on_error=1:abort_on_error=1:print_stacktrace=1
python3 -m venv venv
source venv/bin/activate
pip3 install meson==0.56.0
pip3 install meson==0.60.0
CC=clang CXX=clang++ meson setup build --default-library=static -Db_sanitize=address,undefined --buildtype=debugoptimized --wrap-mode=nodownload -Dexperimental_api=true
meson compile -Cbuild -j9
meson test -Cbuild --print-errorlogs | asan_symbolize | c++filt
meson test -Cbuild -t 10 --print-errorlogs | asan_symbolize | c++filt
tsan:
docker:
- image: ubuntu:20.04
- image: ubuntu:24.04
steps:
- checkout
- run: apt update || true
- run: DEBIAN_FRONTEND=noninteractive apt install -y python3 python3-pip python3-venv ninja-build clang lld git binutils pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev
- run: |
export TSAN_OPTIONS=log_path=stderr:halt_on_error=1:abort_on_error=1
python3 -m venv venv
source venv/bin/activate
pip3 install meson==0.56.0
pip3 install meson==0.60.0
CC=clang CXX=clang++ meson setup build --default-library=static -Db_sanitize=thread --buildtype=debugoptimized --wrap-mode=nodownload -Dexperimental_api=true
meson compile -Cbuild -j9
meson test -Cbuild --print-errorlogs | asan_symbolize | c++filt
meson test -Cbuild -t 10 --print-errorlogs | asan_symbolize | c++filt
msan:
docker:
- image: ubuntu:20.04
- image: ubuntu:24.04
steps:
- checkout
- run: apt update || true
- run: DEBIAN_FRONTEND=noninteractive apt install -y python3 python3-pip python3-venv ninja-build clang lld git binutils pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev
- run: |
export MSAN_OPTIONS=log_path=stderr:halt_on_error=1:abort_on_error=1:print_stacktrace=1
python3 -m venv venv
source venv/bin/activate
pip3 install meson==0.56.0
pip3 install meson==0.60.0
# msan, needs --force-fallback-for=glib,freetype2 also which doesn't work yet but runs fuzzer cases at least
CC=clang CXX=clang++ meson setup build --default-library=static -Db_sanitize=memory --buildtype=debugoptimized --wrap-mode=nodownload -Dauto_features=disabled -Dtests=enabled -Dexperimental_api=true
meson compile -Cbuild -j9
meson test -Cbuild --print-errorlogs | asan_symbolize | c++filt
meson test -Cbuild -t 10 --print-errorlogs | asan_symbolize | c++filt
clang-cxx2a:
docker:
@ -132,17 +121,21 @@ jobs:
executor: win32-executor
steps:
- checkout
- run: sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y ninja-build python3 python3-pip python3-venv git g++-mingw-w64-i686 zip
- run: dpkg --add-architecture i386
- run: apt update
- run: DEBIAN_FRONTEND=noninteractive apt install -y ninja-build python3 python3-pip python3-venv git g++-mingw-w64-i686 zip wine wine32
- run: |
export LANG=en_US.UTF-8
python3 -m venv venv
source venv/bin/activate
pip3 install meson==0.60.0
bash .ci/build-win32.sh
pip3 install meson==1.6.0
bash .ci/build-win.sh 32
meson devenv -Cbuild-win32 meson test -t 10 --print-errorlogs --suite=harfbuzz
- store_artifacts:
path: harfbuzz-win32.zip
- persist_to_workspace:
root: .
paths: harfbuzz-win32.zip
paths: [harfbuzz-win32.zip]
publish-win32:
executor: win32-executor
@ -150,6 +143,8 @@ jobs:
- checkout
- attach_workspace:
at: .
- run: apt update
- run: DEBIAN_FRONTEND=noninteractive apt install -y curl
- run: |
mv harfbuzz-win32{,-$CIRCLE_TAG}.zip
.ci/publish_release_artifact.sh harfbuzz-win32-$CIRCLE_TAG.zip
@ -158,17 +153,21 @@ jobs:
executor: win64-executor
steps:
- checkout
- run: sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y ninja-build python3 python3-pip python3-venv git g++-mingw-w64-x86-64 zip
- run: dpkg --add-architecture i386
- run: apt update
- run: DEBIAN_FRONTEND=noninteractive apt install -y ninja-build python3 python3-pip python3-venv git g++-mingw-w64-x86-64 zip wine wine64 wine32:i386
- run: |
export LANG=en_US.UTF-8
python3 -m venv venv
source venv/bin/activate
pip3 install meson==0.60.0
bash .ci/build-win64.sh
pip3 install meson==1.6.0
bash .ci/build-win.sh 64
meson devenv -Cbuild-win64 meson test -t 10 --print-errorlogs --suite=harfbuzz
- store_artifacts:
path: harfbuzz-win64.zip
- persist_to_workspace:
root: .
paths: harfbuzz-win64.zip
paths: [harfbuzz-win64.zip]
publish-win64:
executor: win64-executor
@ -176,6 +175,8 @@ jobs:
- checkout
- attach_workspace:
at: .
- run: apt update
- run: DEBIAN_FRONTEND=noninteractive apt install -y curl
- run: |
mv harfbuzz-win64{,-$CIRCLE_TAG}.zip
.ci/publish_release_artifact.sh harfbuzz-win64-$CIRCLE_TAG.zip
@ -200,7 +201,6 @@ workflows:
branches:
ignore: /.*/
- fedora-valgrind
- alpine
- asan-ubsan
- tsan
- msan

View file

@ -15,7 +15,7 @@ jobs:
container:
image: devkitpro/devkitarm:latest
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Configure CMake
run: |
cmake -S . -B build \

View file

@ -21,7 +21,7 @@ jobs:
fuzz-seconds: 600
dry-run: false
- name: Upload Crash
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts

View file

@ -11,10 +11,10 @@ permissions:
jobs:
build:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: install dependencies
run: sudo apt-get install gcc
- name: HB_DISABLE_DEPRECATED

View file

@ -11,7 +11,7 @@ jobs:
latest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- run: sudo apt-get install gcc clang wget git curl pkg-config libfreetype6-dev libglib2.0-dev libicu-dev libgraphite2-dev

63
.github/workflows/fontations.yml vendored Normal file
View file

@ -0,0 +1,63 @@
name: fontations
on:
push:
branches: [ main ]
tags: ["*.*.*"]
pull_request:
branches: [ main ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Ccache
uses: hendrikmuhs/ccache-action@a1209f81afb8c005c13b4296c32e363431bffea5 # v1.2.17
with:
key: ${{ github.job }}-${{ runner.os }}-${{ runner.arch }}
- uses: dtolnay/rust-toolchain@nightly
- name: Install Dependencies
run: |
rustup component add \
rust-src \
rustfmt \
clippy \
--toolchain nightly-x86_64-unknown-linux-gnu
sudo apt-get update
sudo apt-get install \
gcc \
gobject-introspection \
gtk-doc-tools \
libcairo2-dev \
libfreetype6-dev \
libgirepository1.0-dev \
libglib2.0-dev \
libgraphite2-dev \
libicu-dev \
pkg-config \
bindgen
- name: Setup Python
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
with:
python-version: '3.12'
- name: Install Python Dependencies
run: pip3 install -r .ci/requirements.txt --require-hashes
- name: Setup Meson
run: |
ccache --version
meson setup build \
-Dauto_features=enabled \
-Dchafa=disabled \
-Dgraphite=enabled \
-Doptimization=2 \
-Dfontations=enabled
- name: Build
run: meson compile -Cbuild
- name: Test
run: RUST_BACKTRACE=1 meson test --print-errorlogs -Cbuild

View file

@ -12,13 +12,13 @@ permissions:
jobs:
build:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Ccache
uses: hendrikmuhs/ccache-action@ed74d11c0b343532753ecead8a951bb09bb34bc9 # v1.2.14
uses: hendrikmuhs/ccache-action@a1209f81afb8c005c13b4296c32e363431bffea5 # v1.2.17
with:
key: ${{ github.job }}-${{ runner.os }}-${{ runner.arch }}
- name: Install Dependencies
@ -34,16 +34,14 @@ jobs:
libglib2.0-dev \
libgraphite2-dev \
libicu-dev \
ninja-build \
pkg-config \
python3 \
python3-setuptools
help2man
- name: Setup Python
uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
with:
python-version: '3.x'
python-version: '3.12'
- name: Install Python Dependencies
run: sudo pip3 install -r .ci/requirements.txt --require-hashes
run: pip3 install -r .ci/requirements.txt --require-hashes
- name: Setup Meson
run: |
ccache --version
@ -52,7 +50,6 @@ jobs:
-Dchafa=disabled \
-Dgraphite=enabled \
-Doptimization=2 \
-Db_coverage=true \
-Ddoc_tests=true \
-Dragel_subproject=true
- name: Build
@ -67,9 +64,3 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
REVISION: ${{ github.sha }}
- name: Generate Coverage
run: ninja -Cbuild coverage-xml
- name: Upload Coverage
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0
with:
file: build/meson-logs/coverage.xml

View file

@ -15,15 +15,16 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Ccache
uses: hendrikmuhs/ccache-action@ed74d11c0b343532753ecead8a951bb09bb34bc9 # v1.2.14
uses: hendrikmuhs/ccache-action@a1209f81afb8c005c13b4296c32e363431bffea5 # v1.2.17
with:
key: ${{ github.job }}-${{ runner.os }}-${{ runner.arch }}
- name: Install Dependencies
run: |
export HOMEBREW_NO_AUTO_UPDATE=1
export HOMEBREW_NO_INSTALL_CLEANUP=1
brew rm -f pkg-config@0.29.2
brew install \
cairo \
freetype \
@ -33,11 +34,11 @@ jobs:
icu4c \
meson \
ninja \
pkg-config
pkgconf
- name: Setup Python
uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
with:
python-version: '3.x'
python-version: '3.12'
- name: Install Python Dependencies
run: pip3 install -r .ci/requirements.txt --require-hashes
- name: Setup Meson
@ -53,14 +54,7 @@ jobs:
-Dcoretext=enabled \
-Dgraphite=enabled \
-Doptimization=2 \
-Db_coverage=true \
- name: Build
run: meson compile -Cbuild
- name: Test
run: meson test --print-errorlogs -Cbuild
- name: Generate Coverage
run: ninja -Cbuild coverage-xml
- name: Upload Coverage
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0
with:
file: build/meson-logs/coverage.xml

View file

@ -28,16 +28,16 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Ccache
uses: hendrikmuhs/ccache-action@ed74d11c0b343532753ecead8a951bb09bb34bc9 # v1.2.14
uses: hendrikmuhs/ccache-action@a1209f81afb8c005c13b4296c32e363431bffea5 # v1.2.17
with:
variant: sccache
key: ${{ github.job }}-${{ matrix.os }}-${{ matrix.ARCH }}
- name: Setup Python
uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
with:
python-version: '3.x'
python-version: '3.12'
- name: Setup MSVC
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
with:

View file

@ -21,19 +21,16 @@ jobs:
MSYS2_ARCH: i686
- MSYSTEM: MINGW64
MSYS2_ARCH: x86_64
- MSYSTEM: CLANG64
MSYS2_ARCH: clang-x86_64
name: ${{ matrix.MSYSTEM }}
env:
# XXX: For some reason enabling jit debugging "fixes" random python crashes
# see https://github.com/msys2/MINGW-packages/issues/11864
MSYS: "winjitdebug"
defaults:
run:
shell: msys2 {0}
steps:
- name: Checkout
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup MSYS2
uses: msys2/setup-msys2@cf96e00c0aab3788743aaf63b64146f0d383cee9 # v2
with:
@ -42,8 +39,7 @@ jobs:
install: >-
mingw-w64-${{ matrix.MSYS2_ARCH }}-cairo
mingw-w64-${{ matrix.MSYS2_ARCH }}-freetype
mingw-w64-${{ matrix.MSYS2_ARCH }}-gcc
mingw-w64-${{ matrix.MSYS2_ARCH }}-gcc-libs
mingw-w64-${{ matrix.MSYS2_ARCH }}-cc
mingw-w64-${{ matrix.MSYS2_ARCH }}-gettext
mingw-w64-${{ matrix.MSYS2_ARCH }}-glib2
mingw-w64-${{ matrix.MSYS2_ARCH }}-gobject-introspection
@ -51,12 +47,9 @@ jobs:
mingw-w64-${{ matrix.MSYS2_ARCH }}-icu
mingw-w64-${{ matrix.MSYS2_ARCH }}-meson
mingw-w64-${{ matrix.MSYS2_ARCH }}-ninja
mingw-w64-${{ matrix.MSYS2_ARCH }}-pkg-config
mingw-w64-${{ matrix.MSYS2_ARCH }}-pkgconf
mingw-w64-${{ matrix.MSYS2_ARCH }}-python
mingw-w64-${{ matrix.MSYS2_ARCH }}-python-pip
- name: Remove installed HarfBuzz DLLs
run: |
rm -f -v /ming*/bin/libharfbuzz-*.dll
- name: Install Python Dependencies
run: |
pip3 install -r .ci/requirements-fonttools.txt --require-hashes
@ -76,7 +69,7 @@ jobs:
run: meson test --print-errorlogs --suite=harfbuzz -Cbuild
- name: Upload DLLs
if: always()
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: libharfbuzz-${{ matrix.MSYS2_ARCH }}
path: ./build/src/libharfbuzz-*.dll

View file

@ -29,12 +29,12 @@ jobs:
steps:
- name: "Checkout code"
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
with:
results_file: results.sarif
results_format: sarif
@ -51,7 +51,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: SARIF file
path: results.sarif
@ -59,6 +59,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@294a9d92911152fe08befb9ec03e240add280cb3 # v3.26.8
uses: github/codeql-action/upload-sarif@45775bd8235c68ba998cffa5171334d58593da47 # v3.28.15
with:
sarif_file: results.sarif

View file

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.12)
cmake_minimum_required(VERSION 3.14)
project(harfbuzz)
message(WARN "HarfBuzz has a Meson port and tries to migrate all the other build systems to it, please consider using it as we might remove our cmake port soon.")
@ -6,20 +6,6 @@ message(WARN "HarfBuzz has a Meson port and tries to migrate all the other build
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
## Limit framework build to Xcode generator
if (BUILD_FRAMEWORK)
# for a framework build on macOS, use:
# cmake -DBUILD_FRAMEWORK=ON -Bbuild -H. -GXcode && cmake --build build
if (NOT "${CMAKE_GENERATOR}" STREQUAL "Xcode")
message(FATAL_ERROR
"You should use Xcode generator with BUILD_FRAMEWORK enabled")
endif ()
set (CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_64_BIT)")
set (CMAKE_MACOSX_RPATH ON)
set (BUILD_SHARED_LIBS ON)
endif ()
## Disallow in-source builds, as CMake generated make files can collide with autotools ones
if (NOT MSVC AND "${PROJECT_BINARY_DIR}" STREQUAL "${PROJECT_SOURCE_DIR}")
message(FATAL_ERROR
@ -73,6 +59,14 @@ if (HB_HAVE_INTROSPECTION)
set (HB_HAVE_GLIB ON)
endif ()
if (APPLE)
option(BUILD_FRAMEWORK "Build as Apple Frameworks" OFF)
endif ()
if (BUILD_FRAMEWORK)
set (CMAKE_MACOSX_RPATH ON)
set (BUILD_SHARED_LIBS OFF)
endif ()
include_directories(AFTER
${PROJECT_SOURCE_DIR}/src
${PROJECT_BINARY_DIR}/src
@ -168,7 +162,7 @@ set (subset_project_sources
${PROJECT_SOURCE_DIR}/src/hb-subset-plan.cc
${PROJECT_SOURCE_DIR}/src/hb-subset-plan.hh
${PROJECT_SOURCE_DIR}/src/hb-subset-plan-member-list.hh
${PROJECT_SOURCE_DIR}/src/hb-subset-repacker.cc
${PROJECT_SOURCE_DIR}/src/hb-subset-serialize.cc
${PROJECT_SOURCE_DIR}/src/hb-subset.cc
${PROJECT_SOURCE_DIR}/src/hb-subset.hh
${PROJECT_SOURCE_DIR}/src/hb-repacker.hh
@ -210,6 +204,7 @@ set (project_headers
${PROJECT_SOURCE_DIR}/src/hb-ot.h
${PROJECT_SOURCE_DIR}/src/hb-paint.h
${PROJECT_SOURCE_DIR}/src/hb-set.h
${PROJECT_SOURCE_DIR}/src/hb-script-list.h
${PROJECT_SOURCE_DIR}/src/hb-shape-plan.h
${PROJECT_SOURCE_DIR}/src/hb-shape.h
${PROJECT_SOURCE_DIR}/src/hb-style.h
@ -219,7 +214,7 @@ set (project_headers
)
set (subset_project_headers
${PROJECT_SOURCE_DIR}/src/hb-subset.h
${PROJECT_SOURCE_DIR}/src/hb-subset-repacker.h
${PROJECT_SOURCE_DIR}/src/hb-subset-serialize.h
)
## Find and include needed header folders and libraries
@ -239,7 +234,7 @@ if (HB_HAVE_FREETYPE AND NOT TARGET freetype)
set (CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${FREETYPE_INCLUDE_DIRS})
set (CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${FREETYPE_LIBRARIES})
check_funcs(FT_Get_Var_Blend_Coordinates FT_Set_Var_Blend_Coordinates FT_Done_MM_Var)
check_funcs(FT_Get_Var_Blend_Coordinates FT_Set_Var_Blend_Coordinates FT_Done_MM_Var FT_Get_Transform)
endif ()
if (HB_HAVE_FREETYPE)
@ -340,15 +335,15 @@ endif ()
if (WIN32 AND HB_HAVE_GDI)
add_definitions(-DHAVE_GDI)
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-gdi.h)
list(APPEND THIRD_PARTY_LIBS gdi32)
list(APPEND PC_LIBS_PRIV -lgdi32)
list(APPEND THIRD_PARTY_LIBS gdi32 user32)
list(APPEND PC_LIBS_PRIV -lgdi32 -luser32)
endif ()
if (WIN32 AND HB_HAVE_UNISCRIBE)
add_definitions(-DHAVE_UNISCRIBE)
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.h)
list(APPEND THIRD_PARTY_LIBS usp10 gdi32 rpcrt4)
list(APPEND PC_LIBS_PRIV -lusp10 -lgdi32 -lrpcrt4)
list(APPEND THIRD_PARTY_LIBS usp10 gdi32 rpcrt4 user32)
list(APPEND PC_LIBS_PRIV -lusp10 -lgdi32 -lrpcrt4 -luser32)
endif ()
if (WIN32 AND HB_HAVE_DIRECTWRITE)
@ -506,6 +501,21 @@ if (HB_HAVE_ICU)
if (BUILD_SHARED_LIBS)
set_target_properties(harfbuzz harfbuzz-icu PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
if (BUILD_FRAMEWORK)
set_target_properties(harfbuzz harfbuzz-icu PROPERTIES
FRAMEWORK TRUE
FRAMEWORK_VERSION "${HB_VERSION}"
PUBLIC_HEADER "${project_headers}"
PRODUCT_BUNDLE_IDENTIFIER "harfbuzz.harfbuzz-icu"
XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
OUTPUT_NAME "harfbuzz-icu"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
MACOSX_FRAMEWORK_IDENTIFIER "harfbuzz-icu"
MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${HB_VERSION}"
MACOSX_FRAMEWORK_BUNDLE_VERSION "${HB_VERSION}"
)
endif ()
endif ()
endif ()
@ -513,12 +523,27 @@ endif ()
## Define harfbuzz-subset library
if (HB_BUILD_SUBSET)
add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers})
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-subset.h ${PROJECT_SOURCE_DIR}/src/hb-subset-repacker.h)
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-subset.h ${PROJECT_SOURCE_DIR}/src/hb-subset-serialize.h)
add_dependencies(harfbuzz-subset harfbuzz)
target_link_libraries(harfbuzz-subset harfbuzz ${THIRD_PARTY_LIBS})
if (BUILD_SHARED_LIBS)
set_target_properties(harfbuzz harfbuzz-subset PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
if (BUILD_FRAMEWORK)
set_target_properties(harfbuzz harfbuzz-subset PROPERTIES
FRAMEWORK TRUE
FRAMEWORK_VERSION "${HB_VERSION}"
PUBLIC_HEADER "${project_headers}"
PRODUCT_BUNDLE_IDENTIFIER "harfbuzz.harfbuzz-subset"
XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
OUTPUT_NAME "harfbuzz-subset"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
MACOSX_FRAMEWORK_IDENTIFIER "harfbuzz-subset"
MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${HB_VERSION}"
MACOSX_FRAMEWORK_BUNDLE_VERSION "${HB_VERSION}"
)
endif ()
endif ()
endif ()
@ -568,7 +593,22 @@ if (HB_HAVE_GOBJECT)
target_link_libraries(harfbuzz-gobject harfbuzz ${GOBJECT_LIBRARIES} ${THIRD_PARTY_LIBS})
if (BUILD_SHARED_LIBS)
set_target_properties(harfbuzz-gobject PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
set_target_properties(harfbuzz harfbuzz-gobject PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
if (BUILD_FRAMEWORK)
set_target_properties(harfbuzz-gobject PROPERTIES
FRAMEWORK TRUE
FRAMEWORK_VERSION "${HB_VERSION}"
PUBLIC_HEADER "${project_headers}"
PRODUCT_BUNDLE_IDENTIFIER "harfbuzz.harfbuzz-gobject"
XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
OUTPUT_NAME "harfbuzz-gobject"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
MACOSX_FRAMEWORK_IDENTIFIER "harfbuzz-gobject"
MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${HB_VERSION}"
MACOSX_FRAMEWORK_BUNDLE_VERSION "${HB_VERSION}"
)
endif ()
endif ()
endif ()
@ -581,6 +621,21 @@ if (HB_HAVE_CAIRO)
if (BUILD_SHARED_LIBS)
set_target_properties(harfbuzz-cairo PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
if (BUILD_FRAMEWORK)
set_target_properties(harfbuzz-cairo PROPERTIES
FRAMEWORK TRUE
FRAMEWORK_VERSION "${HB_VERSION}"
PUBLIC_HEADER "${project_headers}"
PRODUCT_BUNDLE_IDENTIFIER "harfbuzz.harbuzz-cairo"
XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
OUTPUT_NAME "harfbuzz-cairo"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
MACOSX_FRAMEWORK_IDENTIFIER "harfbuzz-cairo"
MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${HB_VERSION}"
MACOSX_FRAMEWORK_BUNDLE_VERSION "${HB_VERSION}"
)
endif ()
endif ()
endif()
@ -719,8 +774,12 @@ if (BUILD_FRAMEWORK)
set (CMAKE_MACOSX_RPATH ON)
set_target_properties(harfbuzz PROPERTIES
FRAMEWORK TRUE
FRAMEWORK_VERSION "${HB_VERSION}"
PUBLIC_HEADER "${project_headers}"
PRODUCT_BUNDLE_IDENTIFIER "harfbuzz"
XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
OUTPUT_NAME "harfbuzz"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
)
set (MACOSX_FRAMEWORK_IDENTIFIER "harfbuzz")
set (MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${HB_VERSION}")
@ -881,7 +940,8 @@ if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
FRAMEWORK DESTINATION Library/Frameworks
FRAMEWORK DESTINATION Library/Frameworks
COMPONENT runtime OPTIONAL
)
make_pkgconfig_pc_file("harfbuzz")
install(EXPORT harfbuzzConfig
@ -893,7 +953,8 @@ if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
FRAMEWORK DESTINATION Library/Frameworks
FRAMEWORK DESTINATION Library/Frameworks
COMPONENT runtime OPTIONAL
)
make_pkgconfig_pc_file("harfbuzz-icu")
endif ()
@ -902,13 +963,19 @@ if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
FRAMEWORK DESTINATION Library/Frameworks
FRAMEWORK DESTINATION Library/Frameworks
COMPONENT runtime OPTIONAL
)
make_pkgconfig_pc_file("harfbuzz-cairo")
endif ()
if (HB_BUILD_SUBSET)
install(TARGETS harfbuzz-subset
EXPORT harfbuzz-subset
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
FRAMEWORK DESTINATION Library/Frameworks
COMPONENT runtime OPTIONAL
)
make_pkgconfig_pc_file("harfbuzz-subset")
endif ()
@ -943,9 +1010,12 @@ if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
endif ()
if (HB_HAVE_GOBJECT)
install(TARGETS harfbuzz-gobject
EXPORT harfbuzz-gobject
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT runtime OPTIONAL
)
make_pkgconfig_pc_file("harfbuzz-gobject")
if (HB_HAVE_INTROSPECTION)

228
NEWS
View file

@ -1,12 +1,232 @@
Overview of changes leading to 11.1.0
Wednesdat, April 16, 2025
====================================
- Include bidi mirroring variants of the requested codepoints when subsetting.
The new HB_SUBSET_FLAGS_NO_BIDI_CLOSURE can be used to disable this
behaviour.
- Various bug fixes.
- Various build fixes and improvements.
- Various test suite improvements.
New API:
+HB_SUBSET_FLAGS_NO_BIDI_CLOSURE
Overview of changes leading to 11.0.1
Friday, April 4, 2025
====================================
- The change in version 10.3.0 to apply “trak” table tracking values to glyph
advances directly has been reverted as it required every font functions
implementation to handle it, which breaks existing custom font functions.
Tracking is instead back to being applied during shaping.
- When `directwrite` integration is enabled, we now link to `dwrite.dll`
instead of dynamically loading it.
- A new experimental APIs for getting raw “CFF” and “CFF2” CharStrings.
- We now provide manpages for the various command line utilities. Building
manpages requires “help2man” and will be skipped if it is not present.
- The command line utilities now set different return value for different kinds
of failures. Details are provided in the manpages.
- Various fixes and improvements to `fontations` font functions.
- All shaping operations using the `ot` shaper have become memory
allocation-free.
- Glyph extents returned by `hb-ot` and `hb-ft` font functions are now rounded
in stead of flooring/ceiling them, which also matches what other font
libraries do.
- Fix “AAT” deleted glyph marks interfering with fallback mark positioning.
- Glyph outlines emboldening have been moved out of `hb-ot` and `hb-ft` font
functions to the HarfBuzz font layer, so that it works with any font
functions implementation.
- Fix our fallback C++11 atomics integration, which seems to not be widely
used.
- Various testing fixes and improvements.
- Various subsetting fixes and improvements.
- Various other fixes and improvements.
Overview of changes leading to 11.0.0
Monday, March 24, 2025
====================================
- There are three new font-functions implementations (integrations) in this
release:
* `hb-coretext` has gained one, calling into the CoreText library,
* `hb-directwrite` has gained one, calling into the DirectWrite library.
* `hb-fontations` has gained one, calling into the Skrifa Rust library.
All three are mostly useful for performance and correctness testing, but some
clients might find them useful.
An API is added to use them from a single API by providing a backend name
string:
* `hb_font_set_funcs_using()`
- Several new APIs are added, to load a font-face using different
"face-loaders", and a single entry point to them all using a loader name
string:
* `hb_ft_face_create_from_file_or_fail()` and
`hb_ft_face_create_from_blob_or_fail()`
* `hb_coretext_face_create_from_file_or_fail()` and
`hb_coretext_face_create_from_blob_or_fail()`
* `hb_directwrite_face_create_from_file_or_fail()` and
`hb_directwrite_face_create_from_blob_or_fail()`
* `hb_face_create_from_file_or_fail_using()`
- All drawing and painting operations using the default, `hb-ot` functions have
become memory allocation-free.
- Several performance optimizations have been implemented.
- Application of the `trak` table during shaping has been improved.
- The `directwrite` shaper now supports font variations, and correctly applies
user features.
- The `hb-directwrite` API and shaper has graduated from experimental.
- Various bug fixes and other improvements.
- New API:
+hb_malloc
+hb_calloc
+hb_realloc
+hb_free
+hb_face_list_loaders
+hb_face_create_or_fail_using
+hb_face_create_from_file_or_fail_using
+hb_font_list_funcs
+hb_font_set_funcs_using
+hb_coretext_face_create_from_blob_or_fail
+hb_directwrite_face_create_from_file_or_fail
+hb_directwrite_face_create_from_blob_or_fail
+hb_directwrite_font_create
+hb_directwrite_font_get_dw_font_face
+hb_directwrite_font_set_funcs
+hb_fontations_font_set_funcs
+hb_ft_face_create_from_blob_or_fail
+hb_paint_push_font_transform
+hb_paint_push_inverse_font_transform
+HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES
+HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE
+HB_BUFFER_CLUSTER_LEVEL_IS_GRAPHEMES
+HB_BUFFER_CLUSTER_LEVEL_IS_CHARACTERS
- Deprecated API:
+hb_directwrite_font_get_dw_font
Overview of changes leading to 10.4.0
Saturday, March 1, 2025
====================================
- Drawing glyphs using hb-draw API now avoids any “malloc” calls, which
improves drawing performance by 10+%.
- Add support new “GVAR” table fonts with more than 65535 glyphs. Support is
currently behind a compilation flag and is disabled by default.
- Some hb-directwrite and hb-ft APIs got renamed with more clear names and the
old names are deprecated.
- Various build and fuzzing fixes.
- New API:
+hb_directwrite_face_get_dw_font_face()
+hb_ft_font_get_ft_face()
- Deprecated API:
+hb_directwrite_face_get_font_face()
+hb_ft_font_get_face()
Overview of changes leading to 10.3.0
Thursday, February 11, 2025
====================================
- Vastly improved “AAT” shaping performance. LucidaGrande benchmark-shape
before: 14.6ms after: 5.9ms.
- Improved OpenType shaping performance (kerning / ligature), at the expense of
~1kb per face allocated cache memory. Roboto-Regular benchmark-shape before:
10.3ms after: 9.4ms.
- Improved “COLRv1” benchmark-font paint performance. Before: 7.85ms after
4.85ms.
- Dont apply glyph substitutions in “morx” table of a font with known broken
“morx” table (AALMAGHRIBI.ttf font).
- Update IANA and OT language registries.
- Various documentation updates.
- Various build improvements, and test speed-ups.
- The “hb_face_reference_blob()” API now works for faces created with
“hb_face_create_for_tables()” if the face sets “get_table_tags” callback.
This constructs a new face blob from individual table blobs.
- Various fixes to how “trak” table is handled to bring it closer to Core Text
behaviour. Particularly, the tracking values for sizes not explicitly set in
the table are now properly interpolated, and the tracking is applied to glyph
advances when they are returned by ot-font functions, instead of applying
them during shaping. The “trak” pseudo OpenType feature that could be used to
disable “trak” table application have been dropped.
- Core Text font functions now support non-BMP code points.
- The drawing algorithm used by hb-draw for “glyf” table now match the
algorithm used by FreeType and Core Text.
- The “hb_coretext_font_create()” API now copy font variations from Core Text
font to the created HarfBuzz font.
- Add an API to get the feature tags enabled on a given shape-plan after
executing it, which can be used to applications to show in the UI what
features are applied by default (which can vary based on the font, the
script, the language, and the direction set on the buffer).
- Add APIs to created HarfBuzz font from DirectWrite font, and copy the font
variations.
- New API:
+hb_directwrite_font_create()
+hb_directwrite_font_get_dw_font()
+hb_ot_shape_plan_get_feature_tags()
Overview of changes leading to 10.2.0
Saturday, January 11, 2025
====================================
- Consider Unicode Variation Selectors when subsetting “cmap” table.
- Guard hb_cairo_glyphs_from_buffer() against malformed UTF-8 strings.
- Fix incorrect “COLR” v1 glyph scaling in hb-cairo.
- Use locale-independent parsing of double numbers is “hb-subset” command line
tool.
- Fix incorrect zeroing of advance width of base glyphs in various “Courier New”
font versions due to incorrect “GDEF” glyph classes.
- Fix handling of long language codes with “HB_LEAN” configuration.
- Update OpenType language system registry.
- Allow all Myanmar tone marks (including visarga) in any order
- Dont insert U+25CC DOTTED CIRCLE before superscript/subscript digits
- Handle Garay script as right to left script.
- New API for serializing font tables and potentially repacking them in optimal
way. This was a previously experimental-only API.
- New API for converting font variation setting from and to strings.
- Various build fixes
- Various subsetter and instancer fixes.
- New API:
+hb_subset_serialize_link_t
+hb_subset_serialize_object_t
+hb_subset_serialize_or_fail()
+hb_subset_axis_range_from_string()
+hb_subset_axis_range_to_string()
Overview of changes leading to 10.1.0
Tuesday, November 5, 2024
====================================
- Fix the sign of fallback vertical glyph advance (used when font has no
vertical advance data).
- Increase maximum “CFF” operands limit 20 times to support more complex fonts.
- Add “--face-loader” option to command line utilities.
- Support “COLR” v0 table in hb_font_get_glyph_extents().
- Add support for font functions that use Core Text APIs, similar to FreeType
font functions. This allows, for example, using drawing fonts that use the new
(and undocumented) “hvgl” table.
- Update IANA and OT language registries, as well ase USE data files.
- Fix build with ICU 76.
- Various compiler warnings and build fixes.
- Various subsetter fixes.
- New API:
+hb_face_create_or_fail()
+hb_face_create_from_file_or_fail()
+hb_coretext_face_create_from_file_or_fail()
+hb_coretext_font_set_funcs()
+hb_ft_face_create_from_file_or_fail()
Overview of changes leading to 10.0.1
Tuesday, Sep 24, 2024
Tuesday, September 24, 2024
====================================
- Relax sanitization checks for “morx” subtables to fix broken AAT shaping of
macOS 15.0 version of GeezaPro.
Overview of changes leading to 10.0.0
Monday, Sep 23, 2024
Monday, September 23, 2024
====================================
- Unicode 16.0.0 support.
- Various documentation fixes.
@ -131,10 +351,10 @@ Saturday, November 11, 2023
tools. Old option is kept as an alias.
- New API:
HB_AAT_LAYOUT_FEATURE_TYPE_CURSIVE_CONNECTION
+HB_AAT_LAYOUT_FEATURE_TYPE_CURSIVE_CONNECTION
- Deprecated API:
HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION
+HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION
Overview of changes leading to 8.2.2
Wednesday, October 18, 2023

View file

@ -1,9 +1,9 @@
[![Linux CI Status](https://github.com/harfbuzz/harfbuzz/workflows/linux-ci/badge.svg)](https://github.com/harfbuzz/harfbuzz/workflows/linux-ci/badge.svg)
[![Linux CI Status](https://github.com/harfbuzz/harfbuzz/actions/workflows/linux-ci.yml/badge.svg)](https://github.com/harfbuzz/harfbuzz/actions/workflows/linux-ci.yml)
[![macoOS CI Status](https://github.com/harfbuzz/harfbuzz/actions/workflows/macos-ci.yml/badge.svg)](https://github.com/harfbuzz/harfbuzz/actions/workflows/macos-ci.yml)
[![Windows CI Status](https://github.com/harfbuzz/harfbuzz/actions/workflows/msvc-ci.yml/badge.svg)](https://github.com/harfbuzz/harfbuzz/actions/workflows/msvc-ci.yml)
[![CircleCI Build Status](https://circleci.com/gh/harfbuzz/harfbuzz/tree/main.svg?style=svg)](https://circleci.com/gh/harfbuzz/harfbuzz/tree/main)
[![OSS-Fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/harfbuzz.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html)
[![OSS-Fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/harfbuzz.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html#harfbuzz)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/15166/badge.svg)](https://scan.coverity.com/projects/harfbuzz)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/89c872f5ce1c42af802602bfcd15d90a)](https://app.codacy.com/gh/harfbuzz/harfbuzz/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
[![Codecov Code Coverage](https://codecov.io/gh/harfbuzz/harfbuzz/branch/main/graph/badge.svg)](https://codecov.io/gh/harfbuzz/harfbuzz)
[![Packaging status](https://repology.org/badge/tiny-repos/harfbuzz.svg)](https://repology.org/project/harfbuzz/versions)
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/harfbuzz/harfbuzz/badge)](https://securityscorecards.dev/viewer/?uri=github.com/harfbuzz/harfbuzz)
@ -35,13 +35,20 @@ will also find Win32/Win64 binary bundles that include `libharfbuzz` DLL,
`hb-view.exe`, `hb-shape.exe`, and all dependencies.
The canonical source tree is available on [github][4].
Both development and user support discussion around HarfBuzz happens on
[github][4] as well.
The API that comes with `hb.h` will not change incompatibly. Other, peripheral,
headers are more likely to go through minor modifications, but again, we do our
best to never change API in an incompatible way. We will never break the ABI.
If you are not sure whether Pango or HarfBuzz is right for you, read [Pango vs
HarfBuzz][5].
The API and ABI are stable even across major version number jumps. In fact,
current HarfBuzz is API/ABI compatible all the way back to the 0.9.x series.
If one day we need to break the API/ABI, that would be called a new a library.
As such, we bump the major version number only when we add major new features,
the minor version when there is new API, and the micro version when there
are bug fixes.
## Development
@ -51,24 +58,38 @@ For custom configurations, see [CONFIG.md](CONFIG.md).
For testing and profiling, see [TESTING.md](TESTING.md).
For using with Python, see [README.python.md](README.python.md). There is also [uharfbuzz](https://github.com/harfbuzz/uharfbuzz).
For cross-compiling to Windows from Linux or macOS, see [README.mingw.md](README.mingw.md).
To report bugs or submit patches please use [github][4] issues and pull-requests.
### Developer documents
To get a better idea of where HarfBuzz stands in the text rendering stack you
may want to read [State of Text Rendering 2024][6].
Here are a few presentation slides about HarfBuzz at the
Internationalization and Unicode Conference over the years:
* November 2014, [Unicode, OpenType, and HarfBuzz: Closing the Circle][7],
* October 2012, [HarfBuzz, The Free and Open Text Shaping Engine][8],
* October 2009, [HarfBuzz: the Free and Open Shaping Engine][9].
- 2014 [Unicode, OpenType, and HarfBuzz: Closing the Circle][7]
- 2012 [HarfBuzz, The Free and Open Text Shaping Engine][8]
- 2016 [Ten Years of HarfBuzz][20]
- 2009 [HarfBuzz: the Free and Open Shaping Engine][9]
Both development and user support discussion around HarfBuzz happens on the
[github][4].
More presentations and papers are available on [behdad][11]'s website.
In particular, the following _studies_ are relevant to HarfBuzz development:
To report bugs or submit patches please use [github][4] issues and
pull-requests.
- 2025 [Subsetting][21]
- 2025 [Caching][12]
- 2025 [`hb-decycler`][13]
- 2022 [`hb-iter`][14]
- 2022 [A C library written in C++][15]
- 2022 [The case of the slow `hb-ft` `>h_advance` function][18]
- 2022 [PackTab: A static integer table packer][16]
- 2020 [HarfBuzz OT+AAT "Unishaper"][19]
- 2014 [Building the Indic Shaper][17]
- 2012 [Memory Consumption][10]
For a comparison of old vs new HarfBuzz memory consumption see [this][10].
<!--See past and upcoming [HarfBuzz Hackfests](https://freedesktop.org/wiki/Software/HarfBuzz/Hackfests/)!-->
## Name
@ -85,6 +106,8 @@ transliterated using the Latin script. It also means "talkative" or
> TrueType that adds support for complex script rendering, and HarfBuzz is an
> implementation of OpenType complex text shaping.
## Distribution
<details>
<summary>Packaging status of HarfBuzz</summary>
@ -96,9 +119,19 @@ transliterated using the Latin script. It also means "talkative" or
[2]: https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6AATIntro.html
[3]: https://github.com/harfbuzz/harfbuzz/releases
[4]: https://github.com/harfbuzz/harfbuzz
[5]: http://mces.blogspot.com/2009/11/pango-vs-harfbuzz.html
[6]: http://behdad.org/text2024
[7]: https://goo.gl/FSIQuC
[8]: https://goo.gl/2wSRu
[7]: https://docs.google.com/presentation/d/1x97pfbB1gbD53Yhz6-_yBUozQMVJ_5yMqqR_D-R7b7I/preview
[8]: https://docs.google.com/presentation/d/1ySTZaXP5XKFg0OpmHZM00v5b17GSr3ojnzJekl4U8qI/preview
[9]: http://behdad.org/download/Presentations/slippy/harfbuzz_slides.pdf
[10]: https://goo.gl/woyty
[10]: https://docs.google.com/document/d/12jfNpQJzeVIAxoUSpk7KziyINAa1msbGliyXqguS86M/preview
[11]: https://behdad.org/
[12]: https://docs.google.com/document/d/1_VgObf6Je0J8byMLsi7HCQHnKo2emGnx_ib_sHo-bt4/preview
[13]: https://docs.google.com/document/d/1Y-u08l9YhObRVObETZt1k8f_5lQdOix9TRH3zEXaoAw/preview
[14]: https://docs.google.com/document/d/1o-xvxCbgMe9JYFHLVnPjk01ZY_8Cj0vB9-KTI1d0nyk/preview
[15]: https://docs.google.com/document/d/18hI56KJpvXtwWbc9QSaz9zzhJwIMnrJ-zkAaKS-W-8k/preview
[16]: https://docs.google.com/document/d/1Xq3owVt61HVkJqbLFHl73il6pcTy6PdPJJ7bSouQiQw/preview
[17]: https://docs.google.com/document/d/1wMPwVNBvsIriamcyBO5aNs7Cdr8lmbwLJ8GmZBAswF4/preview
[18]: https://docs.google.com/document/d/1wskYbA-czBt57oH9gEuGf3sWbTx7bfOiEIcDs36-heo/preview
[19]: https://prezi.com/view/THNPJGFVDUCWoM20syev/
[20]: https://behdad.org/doc/harfbuzz10years-slides.pdf
[21]: https://docs.google.com/document/d/1_vZrt97OorJ0jA1YzJ29LRcGr3YGrNJANdOABjVZGEs/preview

216
README.mingw.md Normal file
View file

@ -0,0 +1,216 @@
Most HarfBuzz developers do so on Linux or macOS. However, HarfBuzz is a
cross-platform library and it is important to ensure that it works on Windows
as well. In particular, we use this workflow to develop and test the HarfBuzz
Uniscribe shaper and DirectWrite shaper and font backend, all from Linux or
macOS.
This document provides instructions for cross-compiling HarfBuzz on Linux or
macOS, for Windows, using the MinGW toolchain, and running tests and utilties
under Wine.
We then discuss using native Windows Uniscribe or DirectWrite DLLs, which
allows you to test HarfBuzz's shaping against the Microsoft shaping engines
instead of those provided by Wine.
This document assumes that you are familiar with building HarfBuzz on Linux or
macOS.
You can build for 32bit or 64bit Windows. If your intention is to use a native
Uniscribe usp10.dll from Windows 7 or before, you would need to build for 32bit.
If you want to use a native DirectWrite DLL from Windows 10 or later, you would
need to build for 64bit.
We suggest you read to the end of this document before starting, as it provides
a few different ways to build and test HarfBuzz for Windows.
1. Install Wine.
- Fedora: `dnf install wine`.
- Ubuntu, 32bit: `apt install wine wine32`.
- Ubuntu, 64bit: `apt install wine wine64`.
- Mac: `brew install wine-stable`.
Note that to run Wine on Apple silicon systems, you need the Apple Rosetta translator.
Follow the instructions you got from brew. This should do it:
- `softwareupdate --install-rosetta --agree-to-license`
2. Install the `mingw-w64` cross-compiler.
- Fedora, 32bit: `dnf install mingw32-gcc-c++`
- Fedora, 64bit: `dnf install mingw64-gcc-c++`
- Ubuntu, 32bit: `apt install g++-mingw-w64-i686`
- Ubuntu, 64bit: `apt install g++-mingw-w64-x86-64`
- Mac: `brew install mingw-w64`
3. Install dependencies.
First, make sure you do not have the mingw32 harfbuzz package, as that will
override our own build with older `meson`:
- Fedora, 32bit: `dnf remove mingw32-harfbuzz`
- Fedora, 64bit: `dnf remove mingw64-harfbuzz`
Then install the actual dependencies:
- Fedora, 32bit: `dnf install mingw32-glib2 mingw32-cairo mingw32-freetype`
- Fedora, 64bit: `dnf install mingw64-glib2 mingw64-cairo mingw64-freetype`
If you cannot find these packages for your distribution, or you are on macOS,
you can skip to the next step, as meson will automatically download and build
the dependencies for you.
4. If you are familiar with `meson`, you can use the cross-compile files we
provide to find your way around. But we do not recommend this way. Read until
the end of this section before deciding which one to use.
- 32bit: `meson --cross-file=.ci/win32-cross-file.txt build-win -Dglib-enabled -Dcairo=enabled -Dgdi=enabled -Ddirectwrite=enabled`
- 64bit: `meson --cross-file=.ci/win64-cross-file.txt build-win -Dglib-enabled -Dcairo=enabled -Dgdi=enabled -Ddirectwrite=enabled`
In which case, you will proceed to run `ninja` as usual to build:
- `ninja -C build-win`
Or you can simply invoke the scripts we provide for our Continuous Integration
system, to configure and build HarfBuzz for you. This is the easiest way to
build HarfBuzz for Windows and how we build our Windows binaries:
- 32bit: `./.ci/build-win.sh 32 && ln -s build-win32 build-win`
- 64bit: `./.ci/build-win.sh 64 && ln -s build-win64 build-win`
This might take a while, since, if you do not have the dependencies installed,
meson will download and build them for you.
5. If everything succeeds, you should have the `hb-shape.exe`, `hb-view.exe`,
`hb-subset.exe`, and `hb-info.exe` executables in `build-win/util`.
6. Configure your wine to find system mingw libraries. While there, set it also
to find the built HarfBuzz DLLs:
- Fedora, 32bit: `export WINEPATH="$HOME/harfbuzz/build-win/src;/usr/i686-w64-mingw32/sys-root/mingw/bin"`
- Fedora, 64bit: `export WINEPATH="$HOME/harfbuzz/build-win/src;/usr/x86_64-w64-mingw32/sys-root/mingw/bin"`
- Other systems: `export WINEPATH="$HOME/harfbuzz/build-win/src"`
Adjust for the path where you have built HarfBuzz. You might want to add this
to your `.bashrc` or `.zshrc` file.
Alternatively, can skip this step if commands are run through the `meson devenv`
command, which we will introduce in the next step. I personally find it more
convenient to set the `WINEPATH` variable, as it allows me to run the executables
directly from the shell.
7. Run the `hb-shape` executable under Wine:
- `wine build-win/util/hb-shape.exe perf/fonts/Roboto-Regular.ttf Test`
Or using `meson devenv to do the same:
- `meson devenv -C build-win util/hb-shape.exe $PWD/perf/fonts/Roboto-Regular.ttf Test`
You probably will get lots of Wine warnings, but if all works fine, you
should see:
```
[gid57=0+1123|gid74=1+1086|gid88=2+1057|gid89=3+670]
```
You can make Wine less verbose, without hiding all errors, by setting:
- `export WINEDEBUG=fixme-all,warn-all,err-plugplay,err-seh,err-rpc,err-ntoskrnl,err-winediag,err-systray,err-hid`
Add this to your `.bashrc` or `.zshrc` file as well.
Next, let's try some non-Latin text. Unfortunately, the command-line parsing of
our cross-compiled glib is not quite Unicode-aware, at least when run under
Wine. So you will need to find some other way to feed Unicode text to the
shaper. There are three different ways you can try:
- `echo حرف | wine build-win/util/hb-shape.exe perf/fonts/Amiri-Regular.ttf`
- `wine build-win/util/hb-shape.exe perf/fonts/Amiri-Regular.ttf -u 062D,0631,0641`
- `wine build-win/util/hb-shape.exe perf/fonts/Amiri-Regular.ttf --text-file harf.txt`
To get the Unicode codepoints for a string, you can use the `hb-unicode-decode`
utility:
```
$ test/shape/hb-unicode-decode حرف
U+062D,U+0631,U+0641
```
8. Next, let's try the `hb-view` utility. By default, `hb-view` outputs ANSI text,
which Wine will not display correctly. You can use the `-o` option to redirect the
output to a file, or just redirect the output using the shell, which will produce
a PNG file.
- `wine build-win/util/hb-view.exe perf/fonts/Roboto-Regular.ttf Test > test.png`
7. As noted, if your Linux has `binfmt_misc` enabled, you can run the executables
directly. If not, you can modify the cross-file to use the `exe_wrapper` option as
specified before.
- `build-win/util/hb-shape.exe perf/fonts/Roboto-Regular.ttf Test`
If that does not work, you can use the `wine` command as shown above.
10. You can try running the test suite. If on Linux with `binfmt_misc` enabled, you
can run the tests directly:
- `ninja -C build-win test`
For other situations, use `meson devenv`:
- `meson devenv -C build-win ninja test`
This might take a couple of minutes to run. Running under Wine is expensive, so
be patient.
If all goes well, tests should run. If all is well, you should probably see about
400 tests pass, some skipped, but none failing.
11. In the above testing situation, the `directwrite` test will be disabled
automatically upon detection of running under Wine. The reason the `directwrite`
test would otherwise fails is that we are running against the Wine-provided
DirectWrite DLL, which is an incomplete reimplementation of the DirectWrite API
by Wine, and not the real thing.
If you want to test the Uniscribe or DirectWrite shapers against the real
Uniscribe / DirectWrite, you can follow the instructions below.
11. Old Uniscribe: Assuming a 32bit build for now.
Bring a 32bit version of `usp10.dll` for yourself from
`C:\Windows\SysWOW64\usp10.dll` of your 64bit Windows installation,
or `C:\Windows\System32\usp10.dll` for 32bit Windows installation.
You want one from Windows 7 or earlier. One that is not just a proxy for
`TextShaping.dll`. Rule of thumb, your `usp10.dll` should have a size more
than 500kb.
Put the file in `~/.wine/drive_c/windows/syswow64/` so wine can find it.
You can now tell wine to use the native `usp10.dll`:
- `export WINEDLLOVERRIDES="usp10=n"`
- `wine build-win/util/hb-shape.exe perf/fonts/Roboto-Regular.ttf Test --shaper=uniscribe`
12. DirectWrite and new Uniscribe: You can use the same method to test the
DirectWrite shaper against the native DirectWrite DLL. Try with a 64bit build
this time.
Bring `TextShaping.dll`, `DWrite.dll`, and `usp10.dll` from your 64bit Windows
installation (`C:\Windows\System32`) to `~/.wine/drive_c/windows/system32/`.
You want the ones from Windows 10 or later. You might have some luck downloading
them from the internet, but be careful with the source. I had success with the
DLLs from [https://dllme.com](dllme.com), but I cannot vouch for the site.
You can now tell wine to use the native DirectWrite:
- `export WINEDLLOVERRIDES="textshaping,dwrite,usp10=n"`
- `wine build-win/util/hb-shape.exe perf/fonts/Roboto-Regular.ttf Test --shaper=directwrite`
If all works well, you should be able to rerun the tests and see all pass this time.
13. For some old instructions on how to test HarfBuzz's native Indic shaper against
Uniscribe, see: https://github.com/harfbuzz/harfbuzz/issues/3671
14. That's it! If you made it this far, you are now able to develop and test
HarfBuzz on Windows, from Linux or macOS. Enjoy!

View file

@ -3,21 +3,21 @@
- [ ] Open gitk and review changes since last release.
- [ ] Print all public API changes:
`git diff $(git describe | sed 's/-.*//').. src/*.h`
`git diff $(git describe | sed 's/-.*//').. src/*.h`
- [ ] Document them in NEWS.
All API and API semantic changes should be clearly marked as API additions, API changes, or API deletions.
All API and API semantic changes should be clearly marked as API additions, API changes, or API deletions.
- [ ] Document deprecations.
Ensure all new API / deprecations are in listed correctly in docs/harfbuzz-sections.txt.
If release added new API, add entry for new API index at the end of docs/harfbuzz-docs.xml.
Ensure all new API / deprecations are listed correctly in docs/harfbuzz-sections.txt.
If release added new API, add entry for new API index at the end of docs/harfbuzz-docs.xml.
If there's a backward-incompatible API change (including deletions for API used anywhere), that's a release blocker.
Do NOT release.
If there's a backward-incompatible API change (including deletions for API used anywhere), that's a release blocker.
Do NOT release.
- [ ] Based on severity of changes, decide whether it's a minor or micro release number bump.
- [ ] Search for 'XSince: REPLACEME' on the repository and replace it with the chosen version for the release, e.g. 'Since: 1.4.7'.
- [ ] Search for 'REPLACEME' on the repository and replace it with the chosen version for the release, e.g. 'Since: 1.4.7'.
- [ ] Make sure you have correct date and new version at the top of NEWS file.
@ -26,12 +26,16 @@
- [ ] Do a `meson test -Cbuild` so it both checks the tests and updates hb-version.h (use `git diff` to see if is really updated).
- [ ] Commit NEWS, meson.build, and src/hb-version.h, as well as any REPLACEME changes you made.
The commit message is simply the release number, e. g. "1.4.7"
The commit message is simply the release number, e. g. "1.4.7"
- [ ] Do a `meson dist -Cbuild` that runs the tests against the latest committed changes.
If doesn't pass, something fishy is going on, reset the repo and start over.
If it does not pass, something fishy is going on, reset the repo and start over.
- [ ] Tag the release and sign it: e.g. `git tag -s 1.4.7 -m 1.4.7`.
Enter your GPG password.
- [ ] Push the commit and tag out: `git push --follow-tags`.
- [ ] There should be a GitHub release automatically created.
When it does, go to that release page and add description.
The description should be the NEWS file additions.

View file

@ -90,15 +90,16 @@
<chapter id="integration-api">
<title>Integration API</title>
<xi:include href="xml/hb-cairo.xml"/>
<xi:include href="xml/hb-coretext.xml"/>
<xi:include href="xml/hb-directwrite.xml"/>
<xi:include href="xml/hb-ft.xml"/>
<xi:include href="xml/hb-fontations.xml"/>
<xi:include href="xml/hb-gdi.xml"/>
<xi:include href="xml/hb-glib.xml"/>
<xi:include href="xml/hb-graphite2.xml"/>
<xi:include href="xml/hb-icu.xml"/>
<xi:include href="xml/hb-uniscribe.xml"/>
<xi:include href="xml/hb-gdi.xml"/>
<xi:include href="xml/hb-directwrite.xml"/>
<xi:include href="xml/hb-cairo.xml"/>
</chapter>
<chapter id="style-api">
@ -120,6 +121,11 @@
<index id="api-index-full"><title>API Index</title><xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include></index>
<index id="deprecated-api-index"><title>Index of deprecated API</title><xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include></index>
<index id="api-index-11-0-0"><title>Index of new symbols in 11.0.0</title><xi:include href="xml/api-index-11.0.0.xml"><xi:fallback /></xi:include></index>
<index id="api-index-10-4-0"><title>Index of new symbols in 10.4.0</title><xi:include href="xml/api-index-10.4.0.xml"><xi:fallback /></xi:include></index>
<index id="api-index-10-3-0"><title>Index of new symbols in 10.3.0</title><xi:include href="xml/api-index-10.3.0.xml"><xi:fallback /></xi:include></index>
<index id="api-index-10-2-0"><title>Index of new symbols in 10.2.0</title><xi:include href="xml/api-index-10.2.0.xml"><xi:fallback /></xi:include></index>
<index id="api-index-10-1-0"><title>Index of new symbols in 10.1.0</title><xi:include href="xml/api-index-10.1.0.xml"><xi:fallback /></xi:include></index>
<index id="api-index-10-0-0"><title>Index of new symbols in 10.0.0</title><xi:include href="xml/api-index-10.0.0.xml"><xi:fallback /></xi:include></index>
<index id="api-index-8-5-0"><title>Index of new symbols in 8.5.0</title><xi:include href="xml/api-index-8.5.0.xml"><xi:fallback /></xi:include></index>
<index id="api-index-8-4-0"><title>Index of new symbols in 8.4.0</title><xi:include href="xml/api-index-8.4.0.xml"><xi:fallback /></xi:include></index>

View file

@ -114,6 +114,9 @@ hb_glyph_position_t
hb_buffer_content_type_t
hb_buffer_flags_t
hb_buffer_cluster_level_t
HB_BUFFER_CLUSTER_LEVEL_IS_CHARACTERS
HB_BUFFER_CLUSTER_LEVEL_IS_GRAPHEMES
HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE
hb_segment_properties_t
hb_buffer_serialize_format_t
hb_buffer_serialize_flags_t
@ -181,6 +184,10 @@ uint8_t
HB_EXTERN
HB_DEPRECATED
HB_DEPRECATED_FOR
hb_malloc
hb_calloc
hb_realloc
hb_free
<SUBSECTION Private>
HB_H_IN
HB_OT_H_IN
@ -285,6 +292,8 @@ hb_paint_custom_palette_color_func_t
hb_paint_funcs_set_custom_palette_color_func
hb_paint_push_transform
hb_paint_push_font_transform
hb_paint_push_inverse_font_transform
hb_paint_pop_transform
hb_paint_color_glyph
hb_paint_push_clip_glyph
@ -332,6 +341,10 @@ hb_font_funcs_set_glyph_shape_func
hb_font_get_glyph_v_kerning
hb_font_get_glyph_v_kerning_func_t
HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION
hb_directwrite_face_get_font_face
hb_directwrite_font_get_dw_font
hb_ft_font_get_face
hb_graphite2_font_get_gr_font
</SECTION>
<SECTION>
@ -340,15 +353,23 @@ HB_CORETEXT_TAG_KERX
HB_CORETEXT_TAG_MORT
HB_CORETEXT_TAG_MORX
hb_coretext_face_create
hb_coretext_face_create_from_file_or_fail
hb_coretext_face_create_from_blob_or_fail
hb_coretext_font_create
hb_coretext_face_get_cg_font
hb_coretext_font_get_ct_font
hb_coretext_font_set_funcs
</SECTION>
<SECTION>
<FILE>hb-directwrite</FILE>
hb_directwrite_face_create
hb_directwrite_face_get_font_face
hb_directwrite_face_create_from_file_or_fail
hb_directwrite_face_create_from_blob_or_fail
hb_directwrite_face_get_dw_font_face
hb_directwrite_font_create
hb_directwrite_font_get_dw_font_face
hb_directwrite_font_set_funcs
</SECTION>
<SECTION>
@ -356,6 +377,11 @@ hb_directwrite_face_get_font_face
hb_face_count
hb_face_t
hb_face_create
hb_face_create_or_fail
hb_face_create_or_fail_using
hb_face_create_from_file_or_fail
hb_face_create_from_file_or_fail_using
hb_face_list_loaders
hb_reference_table_func_t
hb_face_create_for_tables
hb_face_get_empty
@ -449,6 +475,8 @@ hb_font_get_serial
hb_font_changed
hb_font_set_funcs
hb_font_set_funcs_data
hb_font_set_funcs_using
hb_font_list_funcs
hb_font_subtract_glyph_origin_for_direction
hb_font_funcs_create
hb_font_funcs_get_empty
@ -508,15 +536,23 @@ hb_font_extents_t
hb_glyph_extents_t
</SECTION>
<SECTION>
<FILE>hb-fontations</FILE>
hb_fontations_font_set_funcs
</SECTION>
<SECTION>
<FILE>hb-ft</FILE>
hb_ft_face_create
hb_ft_face_create_cached
hb_ft_face_create_referenced
hb_ft_face_create_from_file_or_fail
hb_ft_face_create_from_blob_or_fail
hb_ft_font_create
hb_ft_font_create_referenced
hb_ft_font_changed
hb_ft_font_get_face
hb_ft_font_get_ft_face
hb_ft_font_lock_face
hb_ft_font_unlock_face
hb_ft_font_set_load_flags
@ -542,7 +578,6 @@ hb_glib_blob_create
<FILE>hb-graphite2</FILE>
HB_GRAPHITE2_TAG_SILF
hb_graphite2_face_get_gr_face
hb_graphite2_font_get_gr_font
</SECTION>
<SECTION>
@ -669,6 +704,7 @@ hb_ot_layout_table_get_script_tags
hb_ot_layout_table_get_lookup_count
hb_ot_layout_table_select_script
hb_ot_shape_plan_collect_lookups
hb_ot_shape_plan_get_feature_tags
hb_ot_layout_language_get_required_feature_index
HB_OT_MAX_TAGS_PER_LANGUAGE
HB_OT_MAX_TAGS_PER_SCRIPT
@ -796,8 +832,10 @@ hb_set_t
<FILE>hb-shape</FILE>
hb_shape
hb_shape_full
hb_shape_justify
hb_shape_list_shapers
<SUBSECTION Private>
hb_shape_justify
</SUBSECTION>
</SECTION>
<SECTION>
@ -895,6 +933,8 @@ hb_subset_input_pin_axis_location
hb_subset_input_pin_axis_to_default
hb_subset_input_get_axis_range
hb_subset_input_set_axis_range
hb_subset_axis_range_from_string
hb_subset_axis_range_to_string
hb_subset_or_fail
hb_subset_plan_create_or_fail
hb_subset_plan_reference
@ -910,11 +950,15 @@ hb_subset_flags_t
hb_subset_input_t
hb_subset_sets_t
hb_subset_plan_t
hb_subset_serialize_link_t
hb_subset_serialize_object_t
hb_subset_serialize_or_fail
<SUBSECTION Private>
hb_link_t
hb_object_t
hb_subset_repack_or_fail
hb_subset_input_override_name_table
hb_subset_cff_get_charstring_data
hb_subset_cff_get_charstrings_index
hb_subset_cff2_get_charstring_data
hb_subset_cff2_get_charstrings_index
</SECTION>
<SECTION>

View file

@ -518,18 +518,6 @@
<type>hb_font_t</type> font object. Core Text uses this value to
implement optical scaling.
</para>
<para>
When integrating your client code with Core Text, it is
important to recognize that Core Text <literal>points</literal>
are not typographic points (standardized at 72 per inch) as the
term is used elsewhere in OpenType. Instead, Core Text points
are CSS points, which are standardized at 96 per inch.
</para>
<para>
HarfBuzz's font functions take this distinction into account,
but it can be an easy detail to miss in cross-platform
code.
</para>
<para>
As a final note, you may notice a reference to an optional
<literal>coretext</literal> shaper back-end in the <xref

View file

@ -1,11 +1,12 @@
project('harfbuzz', 'c', 'cpp',
meson_version: '>= 0.55.0',
version: '10.0.1',
project('harfbuzz', ['c', 'cpp'],
meson_version: '>= 0.60.0',
version: '11.1.0',
default_options: [
'cpp_eh=none', # Just to support msvc, we are passing -fno-exceptions also anyway
# 'cpp_rtti=false', # Do NOT enable, wraps inherit it and ICU needs RTTI
'cpp_std=c++11',
'wrap_mode=nofallback', # Use --wrap-mode=default to revert, https://github.com/harfbuzz/harfbuzz/pull/2548
'buildtype=debugoptimized',
],
)
@ -31,11 +32,16 @@ pkgmod = import('pkgconfig')
cpp = meson.get_compiler('cpp')
null_dep = dependency('', required: false)
# Includes Microsoft Clang compiler with GNU arguments, see
# https://github.com/harfbuzz/harfbuzz/pull/4394
cpp_is_microsoft_compiler = host_machine.system() == 'windows' and cpp.get_define('_MSC_FULL_VER') != ''
# Only perform these checks if cpp_std is c++11 as setting -std directly
# produces a warning from meson.
if get_option('cpp_std') == 'c++11'
# Enforce C++14 requirement for MSVC STL
if cpp.get_id() == 'clang' and cpp.get_define('_MSC_FULL_VER') != ''
if cpp.get_id() == 'clang' and cpp_is_microsoft_compiler
add_project_arguments('-std=c++14', language: 'cpp')
elif cpp.get_id() == 'clang-cl'
# Clang-cl produces a warning when using -std=c++14, but not when using /std:c++14
@ -102,44 +108,36 @@ check_funcs = [
m_dep = cpp.find_library('m', required: false)
if meson.version().version_compare('>=0.60.0')
# Painful hack to handle multiple dependencies but also respect options
if get_option('freetype').disabled()
freetype_dep = dependency('', required: false)
else
# Sadly, FreeType's versioning schemes are different between pkg-config and CMake
# pkg-config: freetype2, cmake: Freetype
# Try pkg-config name
freetype_dep = dependency('freetype2',
version: freetype_min_version,
method: 'pkg-config',
required: false,
allow_fallback: false)
if not freetype_dep.found()
freetype_dep = dependency('FreeType',
# Try cmake name
freetype_dep = dependency('Freetype',
version: freetype_min_version_actual,
method: 'cmake',
required: get_option('freetype'),
default_options: ['harfbuzz=disabled'],
allow_fallback: true)
endif
else
# painful hack to handle multiple dependencies but also respect options
freetype_opt = get_option('freetype')
# we want to handle enabled manually after fallbacks, but also handle disabled normally
if freetype_opt.enabled()
freetype_opt = false
endif
# try pkg-config name
freetype_dep = dependency('freetype2', version: freetype_min_version, method: 'pkg-config', required: freetype_opt)
# when disabled, leave it not-found
if not freetype_dep.found() and not get_option('freetype').disabled()
# Try cmake name
freetype_dep = dependency('Freetype', version: freetype_min_version_actual, method: 'cmake', required: false)
# Subproject fallback, `allow_fallback: true` means the fallback will be
# tried even if the freetype option is set to `auto`.
required: false,
allow_fallback: false)
# Subproject fallback
if not freetype_dep.found()
freetype_dep = dependency('freetype2',
version: freetype_min_version,
method: 'pkg-config',
freetype_proj = subproject('freetype2',
version: freetype_min_version_actual,
required: get_option('freetype'),
default_options: ['harfbuzz=disabled'],
allow_fallback: true)
default_options: ['harfbuzz=disabled'])
if freetype_proj.found()
freetype_dep = freetype_proj.get_variable('freetype_dep')
else
freetype_dep = dependency('', required: false)
endif
endif
endif
endif
@ -152,38 +150,12 @@ wasm_dep = cpp.find_library('iwasm', required: get_option('wasm'))
# How to check whether iwasm was built, and hence requires, LLVM?
#llvm_dep = cpp.find_library('LLVM-15', required: get_option('wasm'))
if meson.version().version_compare('>=0.60.0')
# pkg-config: icu-uc, cmake: ICU but with components
icu_dep = dependency('icu-uc', 'ICU',
version: icu_min_version,
components: 'uc',
required: get_option('icu'),
allow_fallback: true)
else
# painful hack to handle multiple dependencies but also respect options
icu_opt = get_option('icu')
# we want to handle enabled manually after fallbacks, but also handle disabled normally
if icu_opt.enabled()
icu_opt = false
endif
# try pkg-config name
icu_dep = dependency('icu-uc', version: icu_min_version, method: 'pkg-config', required: icu_opt)
# when disabled, leave it not-found
if not icu_dep.found() and not get_option('icu').disabled()
# Try cmake name
icu_dep = dependency('ICU', version: icu_min_version, method: 'cmake', components: 'uc', required: false)
# Try again with subproject fallback. `allow_fallback: true` means the
# fallback will be tried even if the icu option is set to `auto`, but
# we cannot pass this option until Meson 0.59.0, because no wrap file
# is checked into git.
if not icu_dep.found()
icu_dep = dependency('icu-uc',
version: icu_min_version,
method: 'pkg-config',
required: get_option('icu'))
endif
endif
endif
# pkg-config: icu-uc, cmake: ICU but with components
icu_dep = dependency('icu-uc', 'ICU',
version: icu_min_version,
components: 'uc',
required: get_option('icu'),
allow_fallback: true)
if icu_dep.found() and icu_dep.version().version_compare('>=75.1') and (get_option('cpp_std') == 'c++11' or get_option('cpp_std') == 'c++14')
cpp17_arg = cpp.get_argument_syntax() == 'msvc' ? '/std:c++17' : '-std=c++17'
@ -227,16 +199,18 @@ endif
chafa_dep = dependency('chafa', version: chafa_min_version, required: get_option('chafa'))
fontations_dep_found = false
if get_option('fontations').enabled()
add_languages(['rust'], native: false, required : true)
fontations_dep_found = true
endif
conf = configuration_data()
incconfig = include_directories('.')
add_project_arguments('-DHAVE_CONFIG_H', language: ['c', 'cpp'])
warn_cflags = [
'-Wno-non-virtual-dtor',
]
cpp_args = cpp.get_supported_arguments(warn_cflags)
cpp_args = []
if glib_dep.found()
conf.set('HAVE_GLIB', 1)
@ -272,6 +246,10 @@ if chafa_dep.found()
conf.set('HAVE_CHAFA', 1)
endif
if fontations_dep_found
conf.set('HAVE_FONTATIONS', 1)
endif
if wasm_dep.found()
conf.set('HAVE_WASM', 1)
conf.set('HB_WASM_MODULE_DIR', '"'+get_option('prefix')+'/'+get_option('libdir')+'/harfbuzz/wasm"')
@ -315,13 +293,13 @@ endif
gdi_uniscribe_deps = []
# GDI (Uniscribe) (Windows)
if host_machine.system() == 'windows' and not get_option('gdi').disabled()
if (get_option('directwrite').enabled() and
if (get_option('gdi').enabled() and
not (cpp.has_header('usp10.h') and cpp.has_header('windows.h')))
error('GDI/Uniscribe was enabled explicitly, but required headers are missing.')
endif
gdi_deps_found = true
foreach usplib : ['usp10', 'gdi32', 'rpcrt4']
foreach usplib : ['usp10', 'gdi32', 'rpcrt4', 'user32']
dep = cpp.find_library(usplib, required: get_option('gdi'))
gdi_deps_found = gdi_deps_found and dep.found()
gdi_uniscribe_deps += dep
@ -333,13 +311,16 @@ if host_machine.system() == 'windows' and not get_option('gdi').disabled()
endif
endif
directwrite_dep = []
# DirectWrite (Windows)
if host_machine.system() == 'windows' and not get_option('directwrite').disabled()
if get_option('directwrite').enabled() and not cpp.has_header('dwrite_1.h')
if get_option('directwrite').enabled() and not cpp.has_header('dwrite_3.h')
error('DirectWrite was enabled explicitly, but required header is missing.')
endif
conf.set('HAVE_DIRECTWRITE', 1)
directwrite_dep = cpp.find_library('dwrite', required: get_option('directwrite'))
if directwrite_dep.found()
conf.set('HAVE_DIRECTWRITE', 1)
endif
endif
# CoreText (macOS)
@ -464,6 +445,11 @@ configure_file(output: 'config.h', configuration: conf)
alias_target('lib', libharfbuzz)
alias_target('libs', libharfbuzz, libharfbuzz_subset)
# Re glib, see https://github.com/harfbuzz/harfbuzz/issues/4153#issuecomment-2646347531
add_test_setup('default',
exclude_suites: ['google-benchmark'],
is_default: glib_dep.type_name() != 'internal' and not meson.is_subproject())
build_summary = {
'Directories':
{'prefix': get_option('prefix'),

View file

@ -15,10 +15,12 @@ option('graphite2', type: 'feature', value: 'disabled',
description: 'Enable Graphite2 complementary shaper')
option('freetype', type: 'feature', value: 'auto',
description: 'Enable freetype interop helpers')
option('fontations', type: 'feature', value: 'disabled',
description: 'Enabled fontations font functions')
option('gdi', type: 'feature', value: 'disabled',
description: 'Enable GDI helpers and Uniscribe shaper backend (Windows only)')
option('directwrite', type: 'feature', value: 'disabled',
description: 'Enable DirectWrite shaper backend on Windows (experimental)')
description: 'Enable DirectWrite shaper backend on Windows')
option('coretext', type: 'feature', value: 'disabled',
description: 'Enable CoreText shaper backend on macOS')
option('wasm', type: 'feature', value: 'disabled',

View file

@ -4,17 +4,21 @@ Benchmarks are implemented using [Google Benchmark](https://github.com/google/be
To build the benchmarks in this directory you need to set the benchmark
option while configuring the build with meson:
```
meson build -Dbenchmark=enabled --buildtype=release
```
or:
```
meson build -Dbenchmark=enabled --buildtype=debugoptimized
```
The default build type is `debugoptimized`, which is good enough for
benchmarking, but you can also get the fastest mode with `release`
build type:
```
meson build -Dbenchmark=enabled --buildtype=release
```
Then build a specific benchmark binaries with ninja:
You should, of course, enable features you want to benchmark, like
`-Dfreetype`, `-Dfontations`, `-Dcoretext`, etc.
Then build a specific benchmark binaries with ninja, eg.:
```
ninja -Cbuild perf/benchmark-set
```
@ -33,22 +37,47 @@ It's possible to filter the benchmarks being run and customize the output
via flags to the benchmark binary. See the
[Google Benchmark User Guide](https://github.com/google/benchmark/blob/main/docs/user_guide.md#user-guide) for more details.
The most useful benchmark is `benchmark-font`. You can provide custom fonts to it too.
For example, to run only the "paint" benchmarks, against a given font, you can do:
```
./build/perf/benchmark-font NotoColorEmoji-Regular.ttf --benchmark_filter="paint"
```
Some useful options are: `--benchmark_repetitions=5` to run the benchmark 5 times,
`--benchmark_min_time=.1s` to run the benchmark for at least .1 seconds (defaults
to .5s), and `--benchmark_filter=...` to filter the benchmarks by regular expression.
To compare before/after benchmarks, you need to save the benchmark results in files
for both runs. Use `--benchmark_out=results.json` to output the results in JSON format.
Then you can use:
```
./subprojects/benchmark-1.8.4/tools/compare.py benchmarks before.json after.json
```
Substitute your version of benchmark instead of 1.8.4.
# Profiling
Configure the build to include debug information for profiling:
If you like to disable optimizations and enable frame pointers for better profiling output,
you can do so with the following meson command:
```
CXXFLAGS="-fno-omit-frame-pointer" meson --reconfigure build -Dbenchmark=enabled --buildtype=debug
ninja -Cbuild
```
However, this will slow down the benchmarks significantly and might give you inaccurate
information as to where to optimize. It's better to profile the `debugoptimized` build (the default).
Then run the benchmark with perf:
```
perf record -g build/perf/benchmark-subset --benchmark_filter="BM_subset_codepoints/subset_notocjk/100000" --benchmark_repetitions=5
```
You probably want to filter to a specific benchmark of interest and set the number of repititions high enough to get a good sampling of profile data.
You probably want to filter to a specific benchmark of interest and set the number of
repititions high enough to get a good sampling of profile data.
Finally view the profile with:
```
perf report
```
Another useful `perf` tool is the `perf stat` command, which can give you a quick overview
of the performance of a benchmark, as well as stalled cycles, cache misses, and mispredicted branches.

View file

@ -1,17 +1,4 @@
#include "benchmark/benchmark.h"
#include <cassert>
#include <cstring>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "hb.h"
#include "hb-ot.h"
#ifdef HAVE_FREETYPE
#include "hb-ft.h"
#endif
#include "hb-benchmark.hh"
#define SUBSET_FONT_BASE_PATH "test/subset/data/fonts/"
@ -34,8 +21,6 @@ struct test_input_t
static test_input_t *tests = default_tests;
static unsigned num_tests = sizeof (default_tests) / sizeof (default_tests[0]);
enum backend_t { HARFBUZZ, FREETYPE };
enum operation_t
{
nominal_glyphs,
@ -94,16 +79,15 @@ _draw_funcs_create (void)
}
static void BM_Font (benchmark::State &state,
bool is_var, backend_t backend, operation_t operation,
bool is_var, const char * backend,
operation_t operation,
const test_input_t &test_input)
{
hb_font_t *font;
unsigned num_glyphs;
{
hb_blob_t *blob = hb_blob_create_from_file_or_fail (test_input.font_path);
assert (blob);
hb_face_t *face = hb_face_create (blob, 0);
hb_blob_destroy (blob);
hb_face_t *face = hb_benchmark_face_create_from_file_or_fail (test_input.font_path, 0);
assert (face);
num_glyphs = hb_face_get_glyph_count (face);
font = hb_font_create (face);
hb_face_destroy (face);
@ -115,17 +99,12 @@ static void BM_Font (benchmark::State &state,
hb_font_set_variations (font, &wght, 1);
}
switch (backend)
bool ret = hb_font_set_funcs_using (font, backend);
if (!ret)
{
case HARFBUZZ:
hb_ot_font_set_funcs (font);
break;
case FREETYPE:
#ifdef HAVE_FREETYPE
hb_ft_font_set_funcs (font);
#endif
break;
state.SkipWithError("Backend failed to initialize for font.");
hb_font_destroy (font);
return;
}
switch (operation)
@ -208,24 +187,17 @@ static void BM_Font (benchmark::State &state,
{
for (auto _ : state)
{
hb_blob_t *blob = hb_blob_create_from_file_or_fail (test_input.font_path);
assert (blob);
hb_face_t *face = hb_face_create (blob, 0);
hb_blob_destroy (blob);
hb_face_t *face = hb_benchmark_face_create_from_file_or_fail (test_input.font_path, 0);
assert (face);
hb_font_t *font = hb_font_create (face);
hb_face_destroy (face);
switch (backend)
bool ret = hb_font_set_funcs_using (font, backend);
if (!ret)
{
case HARFBUZZ:
hb_ot_font_set_funcs (font);
break;
case FREETYPE:
#ifdef HAVE_FREETYPE
hb_ft_font_set_funcs (font);
#endif
break;
state.SkipWithError("Backend failed to initialize for font.");
hb_font_destroy (font);
return;
}
hb_buffer_t *buffer = hb_buffer_create ();
@ -245,8 +217,7 @@ static void BM_Font (benchmark::State &state,
hb_font_destroy (font);
}
static void test_backend (backend_t backend,
const char *backend_name,
static void test_backend (const char *backend,
bool variable,
operation_t op,
const char *op_name,
@ -260,7 +231,7 @@ static void test_backend (backend_t backend,
strcat (name, p ? p + 1 : test_input.font_path);
strcat (name, variable ? "/var" : "");
strcat (name, "/");
strcat (name, backend_name);
strcat (name, backend);
benchmark::RegisterBenchmark (name, BM_Font, variable, backend, op, test_input)
->Unit(time_unit);
@ -270,6 +241,7 @@ static void test_operation (operation_t op,
const char *op_name,
benchmark::TimeUnit time_unit)
{
const char **supported_backends = hb_font_list_funcs ();
for (unsigned i = 0; i < num_tests; i++)
{
auto& test_input = tests[i];
@ -277,10 +249,8 @@ static void test_operation (operation_t op,
{
bool is_var = (bool) variable;
test_backend (HARFBUZZ, "hb", is_var, op, op_name, time_unit, test_input);
#ifdef HAVE_FREETYPE
test_backend (FREETYPE, "ft", is_var, op, op_name, time_unit, test_input);
#endif
for (const char **backend = supported_backends; *backend; backend++)
test_backend (*backend, is_var, op, op_name, time_unit, test_input);
}
}
}
@ -305,7 +275,7 @@ int main(int argc, char** argv)
TEST_OPERATION (nominal_glyphs, benchmark::kMicrosecond);
TEST_OPERATION (glyph_h_advances, benchmark::kMicrosecond);
TEST_OPERATION (glyph_extents, benchmark::kMicrosecond);
TEST_OPERATION (draw_glyph, benchmark::kMicrosecond);
TEST_OPERATION (draw_glyph, benchmark::kMillisecond);
TEST_OPERATION (paint_glyph, benchmark::kMillisecond);
TEST_OPERATION (load_face_and_shape, benchmark::kMicrosecond);

View file

@ -1,11 +1,4 @@
/*
* Benchmarks for hb_map_t operations.
*/
#include "benchmark/benchmark.h"
#include <cassert>
#include <cstdlib>
#include "hb.h"
#include "hb-benchmark.hh"
void RandomMap(unsigned size, hb_map_t* out, hb_set_t* key_sample) {
hb_map_clear(out);

View file

@ -1,9 +1,4 @@
/*
* Benchmarks for hb_set_t operations.
*/
#include "benchmark/benchmark.h"
#include "hb-ot.h"
#include "hb-benchmark.hh"
static void BM_hb_ot_tags_from_script_and_language (benchmark::State& state,
hb_script_t script,

View file

@ -1,11 +1,4 @@
/*
* Benchmarks for hb_set_t operations.
*/
#include "benchmark/benchmark.h"
#include <cassert>
#include <cstdlib>
#include "hb.h"
#include "hb-benchmark.hh"
void RandomSet(unsigned size, unsigned max_value, hb_set_t* out) {
hb_set_clear(out);

View file

@ -1,17 +1,4 @@
#include "benchmark/benchmark.h"
#include <cstring>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <cassert>
#include "hb.h"
#include "hb-ot.h"
#ifdef HAVE_FREETYPE
#include "hb-ft.h"
#endif
#include "hb-benchmark.hh"
#define SUBSET_FONT_BASE_PATH "test/subset/data/fonts/"
@ -19,76 +6,52 @@ struct test_input_t
{
const char *font_path;
const char *text_path;
bool is_variable;
} default_tests[] =
{
{"perf/fonts/NotoNastaliqUrdu-Regular.ttf",
"perf/texts/fa-thelittleprince.txt",
false},
"perf/texts/fa-thelittleprince.txt"},
{"perf/fonts/NotoNastaliqUrdu-Regular.ttf",
"perf/texts/fa-words.txt",
false},
"perf/texts/fa-words.txt"},
{"perf/fonts/Amiri-Regular.ttf",
"perf/texts/fa-thelittleprince.txt",
false},
"perf/texts/fa-thelittleprince.txt"},
{SUBSET_FONT_BASE_PATH "NotoSansDevanagari-Regular.ttf",
"perf/texts/hi-words.txt",
false},
"perf/texts/hi-words.txt"},
{"perf/fonts/Roboto-Regular.ttf",
"perf/texts/en-thelittleprince.txt",
false},
"perf/texts/en-thelittleprince.txt"},
{"perf/fonts/Roboto-Regular.ttf",
"perf/texts/en-words.txt",
false},
"perf/texts/en-words.txt"},
{SUBSET_FONT_BASE_PATH "SourceSerifVariable-Roman.ttf",
"perf/texts/en-thelittleprince.txt",
true},
"perf/texts/react-dom.txt"},
};
static test_input_t *tests = default_tests;
static unsigned num_tests = sizeof (default_tests) / sizeof (default_tests[0]);
enum backend_t { HARFBUZZ, FREETYPE };
const char *variation = nullptr;
static void BM_Shape (benchmark::State &state,
bool is_var,
backend_t backend,
const char *shaper,
const test_input_t &input)
{
hb_font_t *font;
{
hb_blob_t *blob = hb_blob_create_from_file_or_fail (input.font_path);
assert (blob);
hb_face_t *face = hb_face_create (blob, 0);
hb_blob_destroy (blob);
hb_face_t *face = hb_benchmark_face_create_from_file_or_fail (input.font_path, 0);
assert (face);
font = hb_font_create (face);
hb_face_destroy (face);
}
if (is_var)
if (variation)
{
hb_variation_t wght = {HB_TAG ('w','g','h','t'), 500};
hb_font_set_variations (font, &wght, 1);
}
switch (backend)
{
case HARFBUZZ:
hb_ot_font_set_funcs (font);
break;
case FREETYPE:
#ifdef HAVE_FREETYPE
hb_ft_font_set_funcs (font);
#endif
break;
hb_variation_t var;
hb_variation_from_string (variation, -1, &var);
hb_font_set_variations (font, &var, 1);
}
hb_blob_t *text_blob = hb_blob_create_from_file_or_fail (input.text_path);
@ -108,7 +71,8 @@ static void BM_Shape (benchmark::State &state,
hb_buffer_clear_contents (buf);
hb_buffer_add_utf8 (buf, text, text_length, 0, end - text);
hb_buffer_guess_segment_properties (buf);
hb_shape (font, buf, nullptr, 0);
const char *shaper_list[] = {shaper, nullptr};
hb_shape_full (font, buf, nullptr, 0, shaper_list);
unsigned skip = end - text + 1;
text_length -= skip;
@ -121,10 +85,8 @@ static void BM_Shape (benchmark::State &state,
hb_font_destroy (font);
}
static void test_backend (backend_t backend,
const char *backend_name,
bool variable,
const test_input_t &test_input)
static void test_shaper (const char *shaper,
const test_input_t &test_input)
{
char name[1024] = "BM_Shape";
const char *p;
@ -134,11 +96,10 @@ static void test_backend (backend_t backend,
strcat (name, "/");
p = strrchr (test_input.text_path, '/');
strcat (name, p ? p + 1 : test_input.text_path);
strcat (name, variable ? "/var" : "");
strcat (name, "/");
strcat (name, backend_name);
strcat (name, shaper);
benchmark::RegisterBenchmark (name, BM_Shape, variable, backend, test_input)
benchmark::RegisterBenchmark (name, BM_Shape, shaper, test_input)
->Unit(benchmark::kMillisecond);
}
@ -146,35 +107,25 @@ int main(int argc, char** argv)
{
benchmark::Initialize(&argc, argv);
test_input_t static_test = {};
if (argc > 2)
{
num_tests = (argc - 1) / 2;
tests = (test_input_t *) calloc (num_tests, sizeof (test_input_t));
for (unsigned i = 0; i < num_tests; i++)
{
tests[i].is_variable = true;
tests[i].font_path = argv[1 + i * 2];
tests[i].text_path = argv[2 + i * 2];
}
static_test.font_path = argv[1];
static_test.text_path = argv[2];
tests = &static_test;
num_tests = 1;
}
if (argc > 3)
variation = argv[3];
for (unsigned i = 0; i < num_tests; i++)
{
auto& test_input = tests[i];
for (int variable = 0; variable < int (test_input.is_variable) + 1; variable++)
{
bool is_var = (bool) variable;
test_backend (HARFBUZZ, "hb", is_var, test_input);
#ifdef HAVE_FREETYPE
test_backend (FREETYPE, "ft", is_var, test_input);
#endif
}
const char **shapers = hb_shape_list_shapers ();
for (const char **shaper = shapers; *shaper; shaper++)
test_shaper (*shaper, test_input);
}
benchmark::RunSpecifiedBenchmarks();
benchmark::Shutdown();
if (tests != default_tests)
free (tests);
}

View file

@ -1,13 +1,4 @@
#include "benchmark/benchmark.h"
#include <cassert>
#include <cstring>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "hb-subset.h"
#include "hb-benchmark.hh"
enum operation_t
{
@ -148,10 +139,8 @@ static void BM_subset (benchmark::State &state,
if (!cached_font_path || strcmp (cached_font_path, test_input.font_path))
{
hb_blob_t *blob = hb_blob_create_from_file_or_fail (test_input.font_path);
assert (blob);
face = hb_face_create (blob, 0);
hb_blob_destroy (blob);
face = hb_benchmark_face_create_from_file_or_fail (test_input.font_path, 0);
assert (face);
face = preprocess_face (face);

64
perf/hb-benchmark.hh Normal file
View file

@ -0,0 +1,64 @@
/*
* Copyright © 2024 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.
*
* Author(s): Behdad Esfahbod
*/
#ifndef HB_BENCHMARK_HH
#define HB_BENCHMARK_HH
#include <hb-config.hh>
#include <hb.h>
#include <hb-subset.h>
#include <hb-ot.h>
#ifdef HAVE_FREETYPE
#include <hb-ft.h>
#endif
#ifdef HAVE_FONTATIONS
#include <hb-fontations.h>
#endif
#ifdef HAVE_CORETEXT
#include <hb-coretext.h>
#endif
#include <benchmark/benchmark.h>
#include <cassert>
#include <cstdlib>
#include <cstring>
HB_BEGIN_DECLS
static inline hb_face_t *
hb_benchmark_face_create_from_file_or_fail (const char *font_path,
unsigned face_index)
{
return hb_face_create_from_file_or_fail_using (font_path, face_index, nullptr);
}
HB_END_DECLS
#endif /* HB_BENCHMARK_HH */

45
perf/hb-draw-all.c Normal file
View file

@ -0,0 +1,45 @@
#include <hb.h>
#include <stdlib.h>
#include <stdio.h>
int main (int argc, char **argv)
{
if (argc < 2)
{
fprintf (stderr, "Usage: %s font-file [font-funcs] [wght]\n", argv[0]);
return 1;
}
hb_face_t *face = hb_face_create_from_file_or_fail (argv[1], 0);
if (!face)
{
fprintf (stderr, "Failed to create face\n");
return 1;
}
hb_font_t *font = hb_font_create (face);
if (argc > 2)
hb_font_set_funcs_using (font, argv[2]);
if (argc > 3)
{
hb_variation_t variations[] = {
{ HB_TAG ('w', 'g', 'h', 't'), atoi (argv[3]) },
};
hb_font_set_variations (font, variations, 1);
}
hb_draw_funcs_t *funcs = hb_draw_funcs_create ();
unsigned glyph_count = hb_face_get_glyph_count (face);
for (unsigned gid = 0; gid < glyph_count; gid++)
hb_font_draw_glyph (font, gid, funcs, NULL);
hb_draw_funcs_destroy (funcs);
hb_font_destroy (font);
hb_face_destroy (face);
return 0;
}

45
perf/hb-paint-all.c Normal file
View file

@ -0,0 +1,45 @@
#include <hb.h>
#include <stdlib.h>
#include <stdio.h>
int main (int argc, char **argv)
{
if (argc < 2)
{
fprintf (stderr, "Usage: %s font-file [font-funcs] [wght]\n", argv[0]);
return 1;
}
hb_face_t *face = hb_face_create_from_file_or_fail (argv[1], 0);
if (!face)
{
fprintf (stderr, "Failed to create face\n");
return 1;
}
hb_font_t *font = hb_font_create (face);
if (argc > 2)
hb_font_set_funcs_using (font, argv[2]);
if (argc > 3)
{
hb_variation_t variations[] = {
{ HB_TAG ('w', 'g', 'h', 't'), atoi (argv[3]) },
};
hb_font_set_variations (font, variations, 1);
}
hb_paint_funcs_t *funcs = hb_paint_funcs_create ();
unsigned glyph_count = hb_face_get_glyph_count (face);
for (unsigned gid = 0; gid < glyph_count; gid++)
hb_font_paint_glyph (font, gid, funcs, NULL, 0, 0);
hb_paint_funcs_destroy (funcs);
hb_font_destroy (font);
hb_face_destroy (face);
return 0;
}

View file

@ -1,62 +1,54 @@
google_benchmark = subproject('google-benchmark')
google_benchmark_dep = google_benchmark.get_variable('google_benchmark_dep')
benchmark('benchmark-font', executable('benchmark-font', 'benchmark-font.cc',
dependencies: [
google_benchmark_dep, freetype_dep,
],
cpp_args: [],
benchmarks = [
'benchmark-font.cc',
'benchmark-map.cc',
'benchmark-ot.cc',
'benchmark-set.cc',
'benchmark-shape.cc',
]
foreach source : benchmarks
benchmark_name = source.split('.')[0]
benchmark(benchmark_name, executable(benchmark_name, source,
dependencies: [
google_benchmark_dep, freetype_dep, coretext_deps,
],
cpp_args: [],
include_directories: [incconfig, incsrc],
link_with: [libharfbuzz],
install: false,
), workdir: meson.current_source_dir() / '..', timeout: 100)
endforeach
benchmarks_subset = [
'benchmark-subset.cc',
]
foreach source : benchmarks_subset
benchmark_name = source.split('.')[0]
benchmark(benchmark_name, executable(benchmark_name, source,
dependencies: [
google_benchmark_dep, freetype_dep, coretext_deps,
],
cpp_args: [],
include_directories: [incconfig, incsrc],
link_with: [libharfbuzz, libharfbuzz_subset],
install: false,
), workdir: meson.current_source_dir() / '..', timeout: 100)
endforeach
hb_draw_all = executable('hb-draw-all', ['hb-draw-all.c'],
cpp_args: cpp_args,
include_directories: [incconfig, incsrc],
link_with: [libharfbuzz],
install: false,
), workdir: meson.current_source_dir() / '..', timeout: 100)
)
meson.override_find_program('hb-draw-all', hb_draw_all)
benchmark('benchmark-map', executable('benchmark-map', 'benchmark-map.cc',
dependencies: [
google_benchmark_dep,
],
cpp_args: [],
hb_paint_all = executable('hb-paint-all', ['hb-paint-all.c'],
cpp_args: cpp_args,
include_directories: [incconfig, incsrc],
link_with: [libharfbuzz],
install: false,
), workdir: meson.current_source_dir() / '..', timeout: 100)
benchmark('benchmark-ot', executable('benchmark-ot', 'benchmark-ot.cc',
dependencies: [
google_benchmark_dep,
],
cpp_args: [],
include_directories: [incconfig, incsrc],
link_with: [libharfbuzz],
install: false,
), workdir: meson.current_source_dir() / '..', timeout: 100)
benchmark('benchmark-set', executable('benchmark-set', 'benchmark-set.cc',
dependencies: [
google_benchmark_dep,
],
cpp_args: [],
include_directories: [incconfig, incsrc],
link_with: [libharfbuzz],
install: false,
), workdir: meson.current_source_dir() / '..', timeout: 100)
benchmark('benchmark-shape', executable('benchmark-shape', 'benchmark-shape.cc',
dependencies: [
google_benchmark_dep, freetype_dep,
],
cpp_args: [],
include_directories: [incconfig, incsrc],
link_with: [libharfbuzz],
install: false,
), workdir: meson.current_source_dir() / '..', timeout: 100)
benchmark('benchmark-subset', executable('benchmark-subset', 'benchmark-subset.cc',
dependencies: [
google_benchmark_dep,
],
cpp_args: [],
include_directories: [incconfig, incsrc],
link_with: [libharfbuzz, libharfbuzz_subset],
install: false,
), workdir: meson.current_source_dir() / '..', timeout: 100)
)
meson.override_find_program('hb-paint-all', hb_paint_all)

12391
perf/texts/en-2letters.txt Normal file

File diff suppressed because it is too large Load diff

29869
perf/texts/react-dom.txt Normal file

File diff suppressed because it is too large Load diff

View file

@ -941,10 +941,12 @@ struct CBDT
}
}
bool has_data () const { return cbdt.get_length (); }
bool has_data () const { return cbdt->version.major; }
bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const
{
if (!has_data ()) return false;
hb_glyph_extents_t extents;
hb_glyph_extents_t pixel_extents;
hb_blob_t *blob = reference_png (font, glyph);

View file

@ -29,11 +29,14 @@
#define OT_COLOR_COLR_COLR_HH
#include "../../../hb.hh"
#include "../../../hb-decycler.hh"
#include "../../../hb-open-type.hh"
#include "../../../hb-ot-var-common.hh"
#include "../../../hb-paint.hh"
#include "../../../hb-paint-extents.hh"
#include "../CPAL/CPAL.hh"
/*
* COLR -- Color
* https://docs.microsoft.com/en-us/typography/opentype/spec/colr
@ -44,6 +47,11 @@ namespace OT {
struct hb_paint_context_t;
}
struct hb_colr_scratch_t
{
hb_paint_extents_context_t paint_extents;
};
namespace OT {
struct COLR;
@ -66,11 +74,11 @@ public:
hb_paint_funcs_t *funcs;
void *data;
hb_font_t *font;
unsigned int palette_index;
hb_array_t<const BGRAColor> palette;
hb_color_t foreground;
ItemVarStoreInstancer &instancer;
hb_map_t current_glyphs;
hb_map_t current_layers;
hb_decycler_t glyphs_decycler;
hb_decycler_t layers_decycler;
int depth_left = HB_MAX_NESTING_LEVEL;
int edge_count = HB_MAX_GRAPH_EDGE_COUNT;
@ -85,7 +93,12 @@ public:
funcs (funcs_),
data (data_),
font (font_),
palette_index (palette_),
palette (
#ifndef HB_NO_COLOR
// https://github.com/harfbuzz/harfbuzz/issues/5116
font->face->table.CPAL->get_palette_colors (palette_ < font->face->table.CPAL->get_palette_count () ? palette_ : 0)
#endif
),
foreground (foreground_),
instancer (instancer_)
{ }
@ -99,12 +112,7 @@ public:
if (color_index != 0xffff)
{
if (!funcs->custom_palette_color (data, color_index, &color))
{
unsigned int clen = 1;
hb_face_t *face = hb_font_get_face (font);
hb_ot_color_palette_get_colors (face, palette_index, color_index, &clen, &color);
}
color = palette[color_index];
*is_foreground = false;
}
@ -930,9 +938,9 @@ struct PaintGlyph
void paint_glyph (hb_paint_context_t *c) const
{
TRACE_PAINT (this);
c->funcs->push_inverse_root_transform (c->data, c->font);
c->funcs->push_inverse_font_transform (c->data, c->font);
c->funcs->push_clip_glyph (c->data, gid, c->font);
c->funcs->push_root_transform (c->data, c->font);
c->funcs->push_font_transform (c->data, c->font);
c->recurse (this+paint);
c->funcs->pop_transform (c->data);
c->funcs->pop_clip (c->data);
@ -1003,7 +1011,7 @@ struct PaintTransform
void paint_glyph (hb_paint_context_t *c) const
{
TRACE_PAINT (this);
(this+transform).paint_glyph (c);
(this+transform).paint_glyph (c); // This does a push_transform()
c->recurse (this+src);
c->funcs->pop_transform (c->data);
}
@ -1509,10 +1517,12 @@ struct PaintComposite
void paint_glyph (hb_paint_context_t *c) const
{
TRACE_PAINT (this);
c->funcs->push_group (c->data);
c->recurse (this+backdrop);
c->funcs->push_group (c->data);
c->recurse (this+src);
c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int) mode);
c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER);
}
HBUINT8 format; /* format = 32 */
@ -1610,7 +1620,7 @@ struct ClipBox
void closurev1 (hb_colrv1_closure_context_t* c) const
{
switch (u.format) {
case 2: u.format2.closurev1 (c);
case 2: u.format2.closurev1 (c); return;
default:return;
}
}
@ -2058,7 +2068,7 @@ struct delta_set_index_map_subset_plan_t
unsigned outer = (*var_idx) >> 16;
unsigned bit_count = (outer == 0) ? 1 : hb_bit_storage (outer);
outer_bit_count = hb_max (bit_count, outer_bit_count);
unsigned inner = (*var_idx) & 0xFFFF;
bit_count = (inner == 0) ? 1 : hb_bit_storage (inner);
inner_bit_count = hb_max (bit_count, inner_bit_count);
@ -2077,10 +2087,12 @@ struct COLR
{
static constexpr hb_tag_t tableTag = HB_OT_TAG_COLR;
bool has_data () const { return has_v0_data () || version; }
bool has_v0_data () const { return numBaseGlyphs; }
bool has_v1_data () const
{
if (version != 1)
if (version < 1)
return false;
hb_barrier ();
@ -2110,7 +2122,53 @@ struct COLR
{
accelerator_t (hb_face_t *face)
{ colr = hb_sanitize_context_t ().reference_table<COLR> (face); }
~accelerator_t () { this->colr.destroy (); }
~accelerator_t ()
{
auto *scratch = cached_scratch.get_relaxed ();
if (scratch)
{
scratch->~hb_colr_scratch_t ();
hb_free (scratch);
}
colr.destroy ();
}
bool has_data () const { return colr->has_data (); }
#ifndef HB_NO_PAINT
bool
get_extents (hb_font_t *font,
hb_codepoint_t glyph,
hb_glyph_extents_t *extents) const
{
if (unlikely (!has_data ())) return false;
hb_colr_scratch_t *scratch = acquire_scratch ();
if (unlikely (!scratch)) return true;
bool ret = colr->get_extents (font, glyph, extents, *scratch);
release_scratch (scratch);
return ret;
}
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
{
if (unlikely (!has_data ())) return false;
hb_colr_scratch_t *scratch = acquire_scratch ();
if (unlikely (!scratch)) return true;
bool ret = colr->paint_glyph (font, glyph, funcs, data, palette_index, foreground, clip, *scratch);
release_scratch (scratch);
return ret;
}
#endif
bool is_valid () { return colr.get_blob ()->length; }
@ -2134,15 +2192,45 @@ struct COLR
const ItemVariationStore &get_var_store () const
{ return colr->get_var_store (); }
const ItemVariationStore *get_var_store_ptr () const
{ return colr->get_var_store_ptr (); }
bool has_delta_set_index_map () const
{ return colr->has_delta_set_index_map (); }
const DeltaSetIndexMap &get_delta_set_index_map () const
{ return colr->get_delta_set_index_map (); }
const DeltaSetIndexMap *get_delta_set_index_map_ptr () const
{ return colr->get_delta_set_index_map_ptr (); }
private:
hb_colr_scratch_t *acquire_scratch () const
{
hb_colr_scratch_t *scratch = cached_scratch.get_acquire ();
if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr)))
{
scratch = (hb_colr_scratch_t *) hb_calloc (1, sizeof (hb_colr_scratch_t));
if (unlikely (!scratch))
return nullptr;
}
return scratch;
}
void release_scratch (hb_colr_scratch_t *scratch) const
{
if (!cached_scratch.cmpexch (nullptr, scratch))
{
scratch->~hb_colr_scratch_t ();
hb_free (scratch);
}
}
public:
hb_blob_ptr_t<COLR> colr;
private:
hb_atomic_t<hb_colr_scratch_t *> cached_scratch;
};
void closure_glyphs (hb_codepoint_t glyph,
@ -2180,7 +2268,7 @@ struct COLR
hb_set_t *variation_indices,
hb_set_t *delta_set_indices) const
{
if (version != 1) return;
if (version < 1) return;
hb_barrier ();
hb_set_t visited_glyphs;
@ -2222,16 +2310,26 @@ struct COLR
{ return (this+baseGlyphList); }
bool has_var_store () const
{ return version >= 1 && varStore != 0; }
{ return version >= 1 && hb_barrier () && varStore != 0; }
bool has_delta_set_index_map () const
{ return version >= 1 && varIdxMap != 0; }
{ return version >= 1 && hb_barrier () && varIdxMap != 0; }
bool has_clip_list () const
{ return version >= 1 && hb_barrier () && clipList != 0; }
const DeltaSetIndexMap &get_delta_set_index_map () const
{ return (version == 0 || varIdxMap == 0) ? Null (DeltaSetIndexMap) : this+varIdxMap; }
{ return has_delta_set_index_map () && hb_barrier () ? this+varIdxMap : Null (DeltaSetIndexMap); }
const DeltaSetIndexMap *get_delta_set_index_map_ptr () const
{ return has_delta_set_index_map () && hb_barrier () ? &(this+varIdxMap) : nullptr; }
const ItemVariationStore &get_var_store () const
{ return (version == 0 || varStore == 0) ? Null (ItemVariationStore) : this+varStore; }
{ return has_var_store () && hb_barrier () ? this+varStore : Null (ItemVariationStore); }
const ItemVariationStore *get_var_store_ptr () const
{ return has_var_store () && hb_barrier () ? &(this+varStore) : nullptr; }
const ClipList &get_clip_list () const
{ return has_clip_list () && hb_barrier () ? this+clipList : Null (ClipList); }
bool sanitize (hb_sanitize_context_t *c) const
{
@ -2242,7 +2340,6 @@ struct COLR
(this+layersZ).sanitize (c, numLayers) &&
(version == 0 ||
(hb_barrier () &&
version == 1 &&
baseGlyphList.sanitize (c, this) &&
layerList.sanitize (c, this) &&
clipList.sanitize (c, this) &&
@ -2465,7 +2562,9 @@ struct COLR
if (unlikely (!c->serializer->extend_min (colr_prime))) return_trace (false);
if (version == 0 || downgrade_to_V0 (glyphset))
return_trace (colr_prime->serialize_V0 (c->serializer, 0, base_it, layer_it));
return_trace (colr_prime->serialize_V0 (c->serializer, 0, base_it, layer_it));
hb_barrier ();
//start version 1
if (!c->serializer->allocate_size<void> (5 * HBUINT32::static_size)) return_trace (false);
@ -2475,9 +2574,9 @@ struct COLR
* after instancing */
if (!subset_varstore (c, colr_prime)) return_trace (false);
ItemVarStoreInstancer instancer (varStore ? &(this+varStore) : nullptr,
varIdxMap ? &(this+varIdxMap) : nullptr,
c->plan->normalized_coords.as_array ());
ItemVarStoreInstancer instancer (get_var_store_ptr (),
get_delta_set_index_map_ptr (),
c->plan->normalized_coords.as_array ());
if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this, instancer))
return_trace (false);
@ -2503,14 +2602,15 @@ struct COLR
#ifndef HB_NO_PAINT
bool
get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
get_extents (hb_font_t *font,
hb_codepoint_t glyph,
hb_glyph_extents_t *extents,
hb_colr_scratch_t &scratch) const
{
if (version != 1)
return false;
ItemVarStoreInstancer instancer (&(this+varStore),
&(this+varIdxMap),
hb_array (font->coords, font->num_coords));
ItemVarStoreInstancer instancer (get_var_store_ptr (),
get_delta_set_index_map_ptr (),
hb_array (font->coords, font->num_coords));
if (get_clip (glyph, extents, instancer))
{
@ -2519,10 +2619,10 @@ struct COLR
}
auto *extents_funcs = hb_paint_extents_get_funcs ();
hb_paint_extents_context_t extents_data;
bool ret = paint_glyph (font, glyph, extents_funcs, &extents_data, 0, HB_COLOR(0,0,0,0));
scratch.paint_extents.clear ();
bool ret = paint_glyph (font, glyph, extents_funcs, &scratch.paint_extents, 0, HB_COLOR(0,0,0,0), true, scratch);
hb_extents_t e = extents_data.get_extents ();
auto e = scratch.paint_extents.get_extents ();
if (e.is_void ())
{
extents->x_bearing = 0;
@ -2532,6 +2632,7 @@ struct COLR
}
else
{
// Ugh. We need to undo the synthetic slant here. Leave it for now. :-(.
extents->x_bearing = e.xmin;
extents->y_bearing = e.ymax;
extents->width = e.xmax - e.xmin;
@ -2545,7 +2646,7 @@ struct COLR
bool
has_paint_for_glyph (hb_codepoint_t glyph) const
{
if (version == 1)
if (version >= 1)
{
hb_barrier ();
@ -2561,22 +2662,29 @@ struct COLR
hb_glyph_extents_t *extents,
const ItemVarStoreInstancer instancer) const
{
return (this+clipList).get_extents (glyph,
return get_clip_list ().get_extents (glyph,
extents,
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
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,
hb_colr_scratch_t &scratch) const
{
ItemVarStoreInstancer instancer (&(this+varStore),
&(this+varIdxMap),
hb_array (font->coords, font->num_coords));
ItemVarStoreInstancer instancer (get_var_store_ptr (),
get_delta_set_index_map_ptr (),
hb_array (font->coords, font->num_coords));
hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer);
c.current_glyphs.add (glyph);
if (version == 1)
hb_decycler_node_t node (c.glyphs_decycler);
node.visit (glyph);
if (version >= 1)
{
hb_barrier ();
@ -2592,6 +2700,7 @@ struct COLR
if (get_clip (glyph, &extents, instancer))
{
font->scale_glyph_extents (&extents);
font->synthetic_glyph_extents (&extents);
c.funcs->push_clip_rectangle (c.data,
extents.x_bearing,
extents.y_bearing + extents.height,
@ -2601,15 +2710,16 @@ struct COLR
else
{
auto *extents_funcs = hb_paint_extents_get_funcs ();
hb_paint_extents_context_t extents_data;
scratch.paint_extents.clear ();
paint_glyph (font, glyph,
extents_funcs, &extents_data,
extents_funcs, &scratch.paint_extents,
palette_index, foreground,
false);
false,
scratch);
hb_extents_t extents = extents_data.get_extents ();
is_bounded = extents_data.is_bounded ();
auto extents = scratch.paint_extents.get_extents ();
is_bounded = scratch.paint_extents.is_bounded ();
c.funcs->push_clip_rectangle (c.data,
extents.xmin,
@ -2619,7 +2729,7 @@ struct COLR
}
}
c.funcs->push_root_transform (c.data, font);
c.funcs->push_font_transform (c.data, font);
if (is_bounded)
c.recurse (*paint);
@ -2690,19 +2800,14 @@ void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const
{
TRACE_PAINT (this);
const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
hb_decycler_node_t node (c->layers_decycler);
for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
{
if (unlikely (c->current_layers.has (i)))
continue;
c->current_layers.add (i);
if (unlikely (!node.visit (i)))
return;
const Paint &paint = paint_offset_lists.get_paint (i);
c->funcs->push_group (c->data);
c->recurse (paint);
c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER);
c->current_layers.del (i);
}
}
@ -2710,16 +2815,14 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const
{
TRACE_PAINT (this);
if (unlikely (c->current_glyphs.has (gid)))
hb_decycler_node_t node (c->glyphs_decycler);
if (unlikely (!node.visit (gid)))
return;
c->current_glyphs.add (gid);
c->funcs->push_inverse_root_transform (c->data, c->font);
c->funcs->push_inverse_font_transform (c->data, c->font);
if (c->funcs->color_glyph (c->data, gid, c->font))
{
c->funcs->pop_transform (c->data);
c->current_glyphs.del (gid);
return;
}
c->funcs->pop_transform (c->data);
@ -2742,8 +2845,6 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const
if (has_clip_box)
c->funcs->pop_clip (c->data);
c->current_glyphs.del (gid);
}
} /* namespace OT */

View file

@ -187,6 +187,14 @@ struct CPAL
hb_ot_name_id_t get_color_name_id (unsigned int color_index) const
{ return v1 ().get_color_name_id (this, color_index, numColors); }
hb_array_t<const BGRAColor> get_palette_colors (unsigned int palette_index) const
{
if (unlikely (palette_index >= numPalettes))
return hb_array_t<const BGRAColor> ();
unsigned int start_index = colorRecordIndicesZ[palette_index];
hb_array_t<const BGRAColor> all_colors ((this+colorRecordsZ).arrayZ, numColorRecords);
return all_colors.sub_array (start_index, numColors);
}
unsigned int get_palette_colors (unsigned int palette_index,
unsigned int start_offset,
unsigned int *color_count, /* IN/OUT. May be NULL. */

View file

@ -96,6 +96,15 @@ struct Coverage
default:return NOT_COVERED;
}
}
unsigned int get_coverage (hb_codepoint_t glyph_id,
hb_ot_lookup_cache_t *cache) const
{
unsigned coverage;
if (cache && cache->get (glyph_id, &coverage)) return coverage;
coverage = get_coverage (glyph_id);
if (cache) cache->set (glyph_id, coverage);
return coverage;
}
unsigned get_population () const
{
@ -201,6 +210,19 @@ struct Coverage
}
}
unsigned cost () const
{
switch (u.format) {
case 1: hb_barrier (); return u.format1.cost ();
case 2: hb_barrier (); return u.format2.cost ();
#ifndef HB_NO_BEYOND_64K
case 3: hb_barrier (); return u.format3.cost ();
case 4: hb_barrier (); return u.format4.cost ();
#endif
default:return 0u;
}
}
/* Might return false if array looks unsorted.
* Used for faster rejection of corrupt data. */
template <typename set_t>

View file

@ -77,7 +77,7 @@ struct CoverageFormat1_3
bool intersects (const hb_set_t *glyphs) const
{
if (glyphArray.len > glyphs->get_population () * hb_bit_storage ((unsigned) glyphArray.len) / 2)
if (glyphArray.len > glyphs->get_population () * hb_bit_storage ((unsigned) glyphArray.len))
{
for (auto g : *glyphs)
if (get_coverage (g) != NOT_COVERED)
@ -103,6 +103,8 @@ struct CoverageFormat1_3
intersect_glyphs << glyphArray[i];
}
unsigned cost () const { return hb_bit_storage ((unsigned) glyphArray.len); /* bsearch cost */ }
template <typename set_t>
bool collect_coverage (set_t *glyphs) const
{ return glyphs->add_sorted_array (glyphArray.as_array ()); }

View file

@ -120,7 +120,7 @@ struct CoverageFormat2_4
bool intersects (const hb_set_t *glyphs) const
{
if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2)
if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len))
{
for (auto g : *glyphs)
if (get_coverage (g) != NOT_COVERED)
@ -157,6 +157,8 @@ struct CoverageFormat2_4
}
}
unsigned cost () const { return hb_bit_storage ((unsigned) rangeRecord.len); /* bsearch cost */ }
template <typename set_t>
bool collect_coverage (set_t *glyphs) const
{

View file

@ -205,20 +205,19 @@ struct CaretValueFormat3
unsigned varidx = (this+deviceTable).get_variation_index ();
hb_pair_t<unsigned, int> *new_varidx_delta;
if (!c->plan->layout_variation_idx_delta_map.has (varidx, &new_varidx_delta))
return_trace (false);
if (c->plan->layout_variation_idx_delta_map.has (varidx, &new_varidx_delta)) {
uint32_t new_varidx = hb_first (*new_varidx_delta);
int delta = hb_second (*new_varidx_delta);
if (delta != 0)
{
if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW))
return_trace (false);
}
uint32_t new_varidx = hb_first (*new_varidx_delta);
int delta = hb_second (*new_varidx_delta);
if (delta != 0)
{
if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW))
return_trace (false);
if (new_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW));
}
if (new_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW));
if (!c->serializer->embed (deviceTable))
return_trace (false);
@ -1015,7 +1014,8 @@ struct GDEF
hb_blob_ptr_t<GDEF> table;
#ifndef HB_NO_GDEF_CACHE
hb_vector_t<hb_set_digest_t> mark_glyph_set_digests;
mutable hb_cache_t<21, 3, 8> glyph_props_cache;
mutable hb_cache_t<21, 3> glyph_props_cache;
static_assert (sizeof (glyph_props_cache) == 512, "");
#endif
};

View file

@ -54,7 +54,7 @@ struct PairPosFormat1_3
{
auto &cov = this+coverage;
if (pairSet.len > glyphs->get_population () * hb_bit_storage ((unsigned) pairSet.len) / 4)
if (pairSet.len > glyphs->get_population () * hb_bit_storage ((unsigned) pairSet.len))
{
for (hb_codepoint_t g : glyphs->iter())
{
@ -103,12 +103,50 @@ struct PairPosFormat1_3
const Coverage &get_coverage () const { return this+coverage; }
bool apply (hb_ot_apply_context_t *c) const
unsigned cache_cost () const
{
return (this+coverage).cost ();
}
static void * cache_func (void *p, hb_ot_lookup_cache_op_t op)
{
switch (op)
{
case hb_ot_lookup_cache_op_t::CREATE:
{
hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) hb_malloc (sizeof (hb_ot_lookup_cache_t));
if (likely (cache))
cache->clear ();
return cache;
}
case hb_ot_lookup_cache_op_t::ENTER:
return (void *) true;
case hb_ot_lookup_cache_op_t::LEAVE:
return nullptr;
case hb_ot_lookup_cache_op_t::DESTROY:
{
hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) p;
hb_free (cache);
return nullptr;
}
}
return nullptr;
}
bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); }
bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); }
bool _apply (hb_ot_apply_context_t *c, bool cached) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
hb_ot_lookup_cache_t *cache = cached ? (hb_ot_lookup_cache_t *) c->lookup_accel->cache : nullptr;
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache);
#else
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return_trace (false);
#endif
if (index == NOT_COVERED) return_trace (false);
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
skippy_iter.reset_fast (buffer->idx);
@ -156,7 +194,7 @@ struct PairPosFormat1_3
strip = true;
newFormats = compute_effective_value_formats (glyphset, strip, true);
}
out->valueFormat[0] = newFormats.first;
out->valueFormat[1] = newFormats.second;

View file

@ -123,12 +123,61 @@ struct PairPosFormat2_4 : ValueBase
const Coverage &get_coverage () const { return this+coverage; }
bool apply (hb_ot_apply_context_t *c) const
struct pair_pos_cache_t
{
hb_ot_lookup_cache_t coverage;
hb_ot_lookup_cache_t first;
hb_ot_lookup_cache_t second;
};
unsigned cache_cost () const
{
return (this+coverage).cost () + (this+classDef1).cost () + (this+classDef2).cost ();
}
static void * cache_func (void *p, hb_ot_lookup_cache_op_t op)
{
switch (op)
{
case hb_ot_lookup_cache_op_t::CREATE:
{
pair_pos_cache_t *cache = (pair_pos_cache_t *) hb_malloc (sizeof (pair_pos_cache_t));
if (likely (cache))
{
cache->coverage.clear ();
cache->first.clear ();
cache->second.clear ();
}
return cache;
}
case hb_ot_lookup_cache_op_t::ENTER:
return (void *) true;
case hb_ot_lookup_cache_op_t::LEAVE:
return nullptr;
case hb_ot_lookup_cache_op_t::DESTROY:
{
pair_pos_cache_t *cache = (pair_pos_cache_t *) p;
hb_free (cache);
return nullptr;
}
}
return nullptr;
}
bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); }
bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); }
bool _apply (hb_ot_apply_context_t *c, bool cached) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
pair_pos_cache_t *cache = cached ? (pair_pos_cache_t *) c->lookup_accel->cache : nullptr;
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache ? &cache->coverage : nullptr);
#else
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return_trace (false);
#endif
if (index == NOT_COVERED) return_trace (false);
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
skippy_iter.reset_fast (buffer->idx);
@ -139,8 +188,13 @@ struct PairPosFormat2_4 : ValueBase
return_trace (false);
}
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint, cache ? &cache->first : nullptr);
unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint, cache ? &cache->second : nullptr);
#else
unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint);
unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint);
#endif
if (unlikely (klass1 >= class1Count || klass2 >= class2Count))
{
buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);

View file

@ -67,7 +67,7 @@ struct SinglePosFormat1 : ValueBase
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return_trace (false);
if (index == NOT_COVERED) return_trace (false);
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
{

View file

@ -66,7 +66,7 @@ struct SinglePosFormat2 : ValueBase
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return_trace (false);
if (index == NOT_COVERED) return_trace (false);
if (unlikely (index >= valueCount)) return_trace (false);

View file

@ -74,7 +74,7 @@ struct AlternateSubstFormat1_2
TRACE_APPLY (this);
unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return_trace (false);
if (index == NOT_COVERED) return_trace (false);
return_trace ((this+alternateSet[index]).apply (c));
}

View file

@ -78,12 +78,49 @@ struct LigatureSubstFormat1_2
return lig_set.would_apply (c);
}
bool apply (hb_ot_apply_context_t *c) const
unsigned cache_cost () const
{
return (this+coverage).cost ();
}
static void * cache_func (void *p, hb_ot_lookup_cache_op_t op)
{
switch (op)
{
case hb_ot_lookup_cache_op_t::CREATE:
{
hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) hb_malloc (sizeof (hb_ot_lookup_cache_t));
if (likely (cache))
cache->clear ();
return cache;
}
case hb_ot_lookup_cache_op_t::ENTER:
return (void *) true;
case hb_ot_lookup_cache_op_t::LEAVE:
return nullptr;
case hb_ot_lookup_cache_op_t::DESTROY:
{
hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) p;
hb_free (cache);
return nullptr;
}
}
return nullptr;
}
bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); }
bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); }
bool _apply (hb_ot_apply_context_t *c, bool cached) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint);
if (likely (index == NOT_COVERED)) return_trace (false);
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
hb_ot_lookup_cache_t *cache = cached ? (hb_ot_lookup_cache_t *) c->lookup_accel->cache : nullptr;
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache);
#else
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
#endif
if (index == NOT_COVERED) return_trace (false);
const auto &lig_set = this+ligatureSet[index];
return_trace (lig_set.apply (c));

View file

@ -66,7 +66,7 @@ struct MultipleSubstFormat1_2
TRACE_APPLY (this);
unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return_trace (false);
if (index == NOT_COVERED) return_trace (false);
return_trace ((this+sequence[index]).apply (c));
}

View file

@ -112,7 +112,7 @@ struct ReverseChainSingleSubstFormat1
{
TRACE_APPLY (this);
unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint);
if (likely (index == NOT_COVERED)) return_trace (false);
if (index == NOT_COVERED) return_trace (false);
if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL))
return_trace (false); /* No chaining to this type */

View file

@ -128,7 +128,7 @@ struct SingleSubstFormat1_3
TRACE_APPLY (this);
hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
unsigned int index = (this+coverage).get_coverage (glyph_id);
if (likely (index == NOT_COVERED)) return_trace (false);
if (index == NOT_COVERED) return_trace (false);
hb_codepoint_t d = deltaGlyphID;
hb_codepoint_t mask = get_mask ();

View file

@ -104,7 +104,7 @@ struct SingleSubstFormat2_4
{
TRACE_APPLY (this);
unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return_trace (false);
if (index == NOT_COVERED) return_trace (false);
if (unlikely (index >= substitute.len)) return_trace (false);

View file

@ -29,6 +29,9 @@
#ifndef OT_LAYOUT_TYPES_HH
#define OT_LAYOUT_TYPES_HH
using hb_ot_lookup_cache_t = hb_cache_t<15, 8, 7>;
static_assert (sizeof (hb_ot_lookup_cache_t) == 256, "");
namespace OT {
namespace Layout {

View file

@ -3,7 +3,6 @@
#ifndef HB_NO_VAR_COMPOSITES
#include "../../../hb-draw.hh"
#include "../../../hb-geometry.hh"
#include "../../../hb-ot-layout-common.hh"
#include "../../../hb-ot-layout-gdef-table.hh"
@ -127,24 +126,19 @@ hb_transforming_pen_get_funcs ()
return static_transforming_pen_funcs.get_unconst ();
}
hb_ubytes_t
VarComponent::get_path_at (hb_font_t *font,
VarComponent::get_path_at (const hb_varc_context_t &c,
hb_codepoint_t parent_gid,
hb_draw_session_t &draw_session,
hb_array_t<const int> coords,
hb_transform_t total_transform,
hb_ubytes_t total_record,
hb_set_t *visited,
signed *edges_left,
signed depth_left,
VarRegionList::cache_t *cache) const
{
const unsigned char *end = total_record.arrayZ + total_record.length;
const unsigned char *record = total_record.arrayZ;
auto &VARC = *font->face->table.VARC;
auto &VARC = *c.font->face->table.VARC->table;
auto &varStore = &VARC+VARC.varStore;
auto instancer = MultiItemVarStoreInstancer(&varStore, nullptr, coords, cache);
#define READ_UINT32VAR(name) \
HB_STMT_START { \
@ -187,22 +181,25 @@ VarComponent::get_path_at (hb_font_t *font,
unsigned conditionIndex;
READ_UINT32VAR (conditionIndex);
const auto &condition = (&VARC+VARC.conditionList)[conditionIndex];
auto instancer = MultiItemVarStoreInstancer(&varStore, nullptr, coords, cache);
show = condition.evaluate (coords.arrayZ, coords.length, &instancer);
}
// Axis values
hb_vector_t<unsigned> axisIndices;
hb_vector_t<float> axisValues;
auto &axisIndices = c.scratch.axisIndices;
axisIndices.clear ();
auto &axisValues = c.scratch.axisValues;
axisValues.clear ();
if (flags & (unsigned) flags_t::HAVE_AXES)
{
unsigned axisIndicesIndex;
READ_UINT32VAR (axisIndicesIndex);
axisIndices = (&VARC+VARC.axisIndicesList)[axisIndicesIndex];
axisIndices.extend ((&VARC+VARC.axisIndicesList)[axisIndicesIndex]);
axisValues.resize (axisIndices.length);
const HBUINT8 *p = (const HBUINT8 *) record;
TupleValues::decompile (p, axisValues, (const HBUINT8 *) end);
record += (const unsigned char *) p - record;
record = (const unsigned char *) p;
}
// Apply variations if any
@ -219,7 +216,7 @@ VarComponent::get_path_at (hb_font_t *font,
* limit on the max number of coords for now. */
if ((flags & (unsigned) flags_t::RESET_UNSPECIFIED_AXES) ||
coords.length > HB_VAR_COMPOSITE_MAX_AXES)
component_coords = hb_array<int> (font->coords, font->num_coords);
component_coords = hb_array<int> (c.font->coords, c.font->num_coords);
// Transform
@ -312,26 +309,19 @@ VarComponent::get_path_at (hb_font_t *font,
if (!(flags & (unsigned) flags_t::HAVE_SCALE_Y))
transform.scaleY = transform.scaleX;
// Scale the transform by the font's scale
float x_scale = font->x_multf;
float y_scale = font->y_multf;
transform.translateX *= x_scale;
transform.translateY *= y_scale;
transform.tCenterX *= x_scale;
transform.tCenterY *= y_scale;
total_transform.transform (transform.to_transform ());
total_transform.scale (c.font->x_mult ? 1.f / c.font->x_multf : 0.f,
c.font->y_mult ? 1.f / c.font->y_multf : 0.f);
// Build a transforming pen to apply the transform.
hb_draw_funcs_t *transformer_funcs = hb_transforming_pen_get_funcs ();
hb_transforming_pen_context_t context {transform.to_transform (),
draw_session.funcs,
draw_session.draw_data,
&draw_session.st};
hb_draw_session_t transformer_session {transformer_funcs, &context};
bool same_coords = component_coords.length == coords.length &&
component_coords.arrayZ == coords.arrayZ;
VARC.get_path_at (font, gid,
transformer_session, component_coords,
c.depth_left--;
VARC.get_path_at (c, gid,
component_coords, total_transform,
parent_gid,
visited, edges_left, depth_left - 1);
same_coords ? cache : nullptr);
c.depth_left++;
}
#undef PROCESS_TRANSFORM_COMPONENTS
@ -340,6 +330,87 @@ VarComponent::get_path_at (hb_font_t *font,
return hb_ubytes_t (record, end - record);
}
bool
VARC::get_path_at (const hb_varc_context_t &c,
hb_codepoint_t glyph,
hb_array_t<const int> coords,
hb_transform_t transform,
hb_codepoint_t parent_glyph,
VarRegionList::cache_t *parent_cache) const
{
// Don't recurse on the same glyph.
unsigned idx = glyph == parent_glyph ?
NOT_COVERED :
(this+coverage).get_coverage (glyph);
if (idx == NOT_COVERED)
{
if (c.draw_session)
{
// Build a transforming pen to apply the transform.
hb_draw_funcs_t *transformer_funcs = hb_transforming_pen_get_funcs ();
hb_transforming_pen_context_t context {transform,
c.draw_session->funcs,
c.draw_session->draw_data,
&c.draw_session->st};
hb_draw_session_t transformer_session {transformer_funcs, &context};
hb_draw_session_t &shape_draw_session = transform.is_identity () ? *c.draw_session : transformer_session;
if (!c.font->face->table.glyf->get_path_at (c.font, glyph, shape_draw_session, coords, c.scratch.glyf_scratch))
#ifndef HB_NO_CFF
if (!c.font->face->table.cff2->get_path_at (c.font, glyph, shape_draw_session, coords))
if (!c.font->face->table.cff1->get_path (c.font, glyph, shape_draw_session)) // Doesn't have variations
#endif
return false;
}
else if (c.extents)
{
hb_glyph_extents_t glyph_extents;
if (!c.font->face->table.glyf->get_extents_at (c.font, glyph, &glyph_extents, coords))
#ifndef HB_NO_CFF
if (!c.font->face->table.cff2->get_extents_at (c.font, glyph, &glyph_extents, coords))
if (!c.font->face->table.cff1->get_extents (c.font, glyph, &glyph_extents)) // Doesn't have variations
#endif
return false;
hb_extents_t comp_extents (glyph_extents);
transform.transform_extents (comp_extents);
c.extents->union_ (comp_extents);
}
return true;
}
if (c.depth_left <= 0)
return true;
if (c.edges_left <= 0)
return true;
(c.edges_left)--;
hb_decycler_node_t node (c.decycler);
if (unlikely (!node.visit (glyph)))
return true;
hb_ubytes_t record = (this+glyphRecords)[idx];
VarRegionList::cache_t static_cache[sizeof (void *) * 16];
VarRegionList::cache_t *cache = parent_cache ?
parent_cache :
(this+varStore).create_cache (hb_array (static_cache));
transform.scale (c.font->x_multf, c.font->y_multf);
VarCompositeGlyph::get_path_at (c,
glyph,
coords, transform,
record,
cache);
if (cache != parent_cache)
(this+varStore).destroy_cache (cache, hb_array (static_cache));
return true;
}
//} // namespace Var
} // namespace OT

View file

@ -1,6 +1,8 @@
#ifndef OT_VAR_VARC_VARC_HH
#define OT_VAR_VARC_VARC_HH
#include "../../../hb-decycler.hh"
#include "../../../hb-geometry.hh"
#include "../../../hb-ot-layout-common.hh"
#include "../../../hb-ot-glyf-table.hh"
#include "../../../hb-ot-cff2-table.hh"
@ -19,6 +21,24 @@ namespace OT {
#ifndef HB_NO_VAR_COMPOSITES
struct hb_varc_scratch_t
{
hb_vector_t<unsigned> axisIndices;
hb_vector_t<float> axisValues;
hb_glyf_scratch_t glyf_scratch;
};
struct hb_varc_context_t
{
hb_font_t *font;
hb_draw_session_t *draw_session;
hb_extents_t *extents;
mutable hb_decycler_t decycler;
mutable signed edges_left;
mutable signed depth_left;
hb_varc_scratch_t &scratch;
};
struct VarComponent
{
enum class flags_t : uint32_t
@ -42,37 +62,32 @@ struct VarComponent
};
HB_INTERNAL hb_ubytes_t
get_path_at (hb_font_t *font,
get_path_at (const hb_varc_context_t &c,
hb_codepoint_t parent_gid,
hb_draw_session_t &draw_session,
hb_array_t<const int> coords,
hb_transform_t transform,
hb_ubytes_t record,
hb_set_t *visited,
signed *edges_left,
signed depth_left,
VarRegionList::cache_t *cache = nullptr) const;
};
struct VarCompositeGlyph
{
static void
get_path_at (hb_font_t *font,
hb_codepoint_t glyph,
hb_draw_session_t &draw_session,
get_path_at (const hb_varc_context_t &c,
hb_codepoint_t gid,
hb_array_t<const int> coords,
hb_transform_t transform,
hb_ubytes_t record,
hb_set_t *visited,
signed *edges_left,
signed depth_left,
VarRegionList::cache_t *cache = nullptr)
VarRegionList::cache_t *cache)
{
while (record)
{
const VarComponent &comp = * (const VarComponent *) (record.arrayZ);
record = comp.get_path_at (font, glyph,
draw_session, coords,
record = comp.get_path_at (c,
gid,
coords, transform,
record,
visited, edges_left, depth_left, cache);
cache);
}
}
};
@ -85,79 +100,48 @@ struct VARC
static constexpr hb_tag_t tableTag = HB_TAG ('V', 'A', 'R', 'C');
bool
get_path_at (hb_font_t *font,
hb_codepoint_t glyph,
hb_draw_session_t &draw_session,
HB_INTERNAL bool
get_path_at (const hb_varc_context_t &c,
hb_codepoint_t gid,
hb_array_t<const int> coords,
hb_codepoint_t parent_glyph = HB_CODEPOINT_INVALID,
hb_set_t *visited = nullptr,
signed *edges_left = nullptr,
signed depth_left = HB_MAX_NESTING_LEVEL) const
hb_transform_t transform = HB_TRANSFORM_IDENTITY,
hb_codepoint_t parent_gid = HB_CODEPOINT_INVALID,
VarRegionList::cache_t *parent_cache = nullptr) const;
bool
get_path (hb_font_t *font,
hb_codepoint_t gid,
hb_draw_session_t &draw_session,
hb_varc_scratch_t &scratch) const
{
hb_set_t stack_set;
if (visited == nullptr)
visited = &stack_set;
signed stack_edges = HB_MAX_GRAPH_EDGE_COUNT;
if (edges_left == nullptr)
edges_left = &stack_edges;
hb_varc_context_t c {font,
&draw_session,
nullptr,
hb_decycler_t {},
HB_MAX_GRAPH_EDGE_COUNT,
HB_MAX_NESTING_LEVEL,
scratch};
// Don't recurse on the same glyph.
unsigned idx = glyph == parent_glyph ?
NOT_COVERED :
(this+coverage).get_coverage (glyph);
if (idx == NOT_COVERED)
{
if (!font->face->table.glyf->get_path_at (font, glyph, draw_session, coords))
#ifndef HB_NO_CFF
if (!font->face->table.cff2->get_path_at (font, glyph, draw_session, coords))
if (!font->face->table.cff1->get_path (font, glyph, draw_session)) // Doesn't have variations
#endif
return false;
return true;
}
if (depth_left <= 0)
return true;
if (*edges_left <= 0)
return true;
(*edges_left)--;
if (visited->has (glyph) || visited->in_error ())
return true;
visited->add (glyph);
hb_ubytes_t record = (this+glyphRecords)[idx];
VarRegionList::cache_t *cache = record.length >= 64 ? // Heuristic
(this+varStore).create_cache ()
: nullptr;
VarCompositeGlyph::get_path_at (font, glyph,
draw_session, coords,
record,
visited, edges_left, depth_left,
cache);
(this+varStore).destroy_cache (cache);
visited->del (glyph);
return true;
return get_path_at (c, gid,
hb_array (font->coords, font->num_coords));
}
bool
get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const
{ return get_path_at (font, gid, draw_session, hb_array (font->coords, font->num_coords)); }
bool paint_glyph (hb_font_t *font, hb_codepoint_t gid, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const
get_extents (hb_font_t *font,
hb_codepoint_t gid,
hb_extents_t *extents,
hb_varc_scratch_t &scratch) const
{
funcs->push_clip_glyph (data, gid, font);
funcs->color (data, true, foreground);
funcs->pop_clip (data);
hb_varc_context_t c {font,
nullptr,
extents,
hb_decycler_t {},
HB_MAX_GRAPH_EDGE_COUNT,
HB_MAX_NESTING_LEVEL,
scratch};
return true;
return get_path_at (c, gid,
hb_array (font->coords, font->num_coords));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -173,6 +157,89 @@ struct VARC
glyphRecords.sanitize (c, this));
}
struct accelerator_t
{
friend struct VarComponent;
accelerator_t (hb_face_t *face)
{
table = hb_sanitize_context_t ().reference_table<VARC> (face);
}
~accelerator_t ()
{
auto *scratch = cached_scratch.get_relaxed ();
if (scratch)
{
scratch->~hb_varc_scratch_t ();
hb_free (scratch);
}
table.destroy ();
}
bool
get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const
{
if (!table->has_data ()) return false;
auto *scratch = acquire_scratch ();
if (unlikely (!scratch)) return true;
bool ret = table->get_path (font, gid, draw_session, *scratch);
release_scratch (scratch);
return ret;
}
bool
get_extents (hb_font_t *font,
hb_codepoint_t gid,
hb_glyph_extents_t *extents) const
{
if (!table->has_data ()) return false;
hb_extents_t f_extents;
auto *scratch = acquire_scratch ();
if (unlikely (!scratch)) return true;
bool ret = table->get_extents (font, gid, &f_extents, *scratch);
release_scratch (scratch);
if (ret)
*extents = f_extents.to_glyph_extents (font->x_scale < 0, font->y_scale < 0);
return ret;
}
private:
hb_varc_scratch_t *acquire_scratch () const
{
hb_varc_scratch_t *scratch = cached_scratch.get_acquire ();
if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr)))
{
scratch = (hb_varc_scratch_t *) hb_calloc (1, sizeof (hb_varc_scratch_t));
if (unlikely (!scratch))
return nullptr;
}
return scratch;
}
void release_scratch (hb_varc_scratch_t *scratch) const
{
if (!cached_scratch.cmpexch (nullptr, scratch))
{
scratch->~hb_varc_scratch_t ();
hb_free (scratch);
}
}
private:
hb_blob_ptr_t<VARC> table;
hb_atomic_t<hb_varc_scratch_t *> cached_scratch;
};
bool has_data () const { return version.major != 0; }
protected:
FixedVersion<> version; /* Version identifier */
Offset32To<Coverage> coverage;
@ -184,6 +251,10 @@ struct VARC
DEFINE_SIZE_STATIC (24);
};
struct VARC_accelerator_t : VARC::accelerator_t {
VARC_accelerator_t (hb_face_t *face) : VARC::accelerator_t (face) {}
};
#endif
//}

View file

@ -11,22 +11,48 @@ namespace OT {
struct coord_setter_t
{
coord_setter_t (hb_array_t<const int> coords) :
coords (coords) {}
coord_setter_t (hb_array_t<const int> coords_)
{
length = coords_.length;
if (length <= ARRAY_LENGTH (static_coords))
hb_memcpy (static_coords, coords_.arrayZ, length * sizeof (int));
else
dynamic_coords.extend (coords_);
}
int& operator [] (unsigned idx)
{
if (unlikely (idx >= HB_VAR_COMPOSITE_MAX_AXES))
return Crap(int);
if (coords.length < idx + 1)
coords.resize (idx + 1);
return coords[idx];
if (length <= ARRAY_LENGTH (static_coords))
{
if (idx < ARRAY_LENGTH (static_coords))
{
while (length <= idx)
static_coords[length++] = 0;
return static_coords[idx];
}
else
dynamic_coords.extend (hb_array (static_coords, length));
}
if (dynamic_coords.length <= idx)
{
if (unlikely (!dynamic_coords.resize (idx + 1)))
return Crap(int);
length = idx + 1;
}
return dynamic_coords.arrayZ[idx];
}
hb_array_t<int> get_coords ()
{ return coords.as_array (); }
{ return length <= ARRAY_LENGTH (static_coords) ? hb_array (static_coords, length) : dynamic_coords.as_array (); }
hb_vector_t<int> coords;
private:
hb_vector_t<int> dynamic_coords;
unsigned length;
int static_coords[sizeof (void *) * 8];
};

View file

@ -143,7 +143,7 @@ struct CompositeGlyphRecord
float matrix[4];
contour_point_t trans;
get_transformation (matrix, trans);
if (unlikely (!points.alloc (points.length + 4))) return false; // For phantom points
if (unlikely (!points.alloc (points.length + 1 + 4))) return false; // For phantom points
points.push (trans);
return true;
}

View file

@ -251,7 +251,8 @@ struct Glyph
composite_contours_p = nullptr;
}
if (!get_points (font, glyf, all_points, &points_with_deltas, head_maxp_info_p, composite_contours_p, false, false))
hb_glyf_scratch_t scratch;
if (!get_points (font, glyf, all_points, scratch, &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
@ -305,6 +306,7 @@ struct Glyph
template <typename accelerator_t>
bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator,
contour_point_vector_t &all_points /* OUT */,
hb_glyf_scratch_t &scratch,
contour_point_vector_t *points_with_deltas = nullptr, /* OUT */
head_maxp_info_t * head_maxp_info = nullptr, /* OUT */
unsigned *composite_contours = nullptr, /* OUT */
@ -312,7 +314,6 @@ struct Glyph
bool use_my_metrics = true,
bool phantom_only = false,
hb_array_t<const int> coords = hb_array_t<const int> (),
hb_map_t *current_glyphs = nullptr,
unsigned int depth = 0,
unsigned *edge_count = nullptr) const
{
@ -322,10 +323,6 @@ struct Glyph
if (unlikely (*edge_count > HB_MAX_GRAPH_EDGE_COUNT)) return false;
(*edge_count)++;
hb_map_t current_glyphs_stack;
if (current_glyphs == nullptr)
current_glyphs = &current_glyphs_stack;
if (head_maxp_info)
{
head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth);
@ -334,8 +331,7 @@ struct Glyph
if (!coords)
coords = hb_array (font->coords, font->num_coords);
contour_point_vector_t stack_points;
contour_point_vector_t &points = type == SIMPLE ? all_points : stack_points;
contour_point_vector_t &points = type == SIMPLE ? all_points : scratch.comp_points;
unsigned old_length = points.length;
switch (type) {
@ -388,36 +384,53 @@ struct Glyph
#ifndef HB_NO_VAR
if (coords)
glyf_accelerator.gvar->apply_deltas_to_points (gid,
coords,
points.as_array ().sub_array (old_length),
phantom_only && type == SIMPLE);
{
#ifndef HB_NO_BEYOND_64K
if (glyf_accelerator.GVAR->has_data ())
glyf_accelerator.GVAR->apply_deltas_to_points (gid,
coords,
points.as_array ().sub_array (old_length),
scratch,
phantom_only && type == SIMPLE);
else
#endif
glyf_accelerator.gvar->apply_deltas_to_points (gid,
coords,
points.as_array ().sub_array (old_length),
scratch,
phantom_only && type == SIMPLE);
}
#endif
// mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it
// with child glyphs' points
if (points_with_deltas != nullptr && depth == 0 && type == COMPOSITE)
{
if (unlikely (!points_with_deltas->resize (points.length))) return false;
assert (old_length == 0);
*points_with_deltas = points;
}
float shift = 0;
switch (type) {
case SIMPLE:
if (depth == 0 && head_maxp_info)
head_maxp_info->maxPoints = hb_max (head_maxp_info->maxPoints, all_points.length - old_length - 4);
shift = phantoms[PHANTOM_LEFT].x;
break;
case COMPOSITE:
{
hb_decycler_node_t decycler_node (scratch.decycler);
unsigned int comp_index = 0;
for (auto &item : get_composite_iterator ())
{
hb_codepoint_t item_gid = item.get_gid ();
if (unlikely (current_glyphs->has (item_gid)))
if (unlikely (!decycler_node.visit (item_gid)))
{
comp_index++;
continue;
current_glyphs->add (item_gid);
}
unsigned old_count = all_points.length;
@ -426,6 +439,7 @@ struct Glyph
.get_points (font,
glyf_accelerator,
all_points,
scratch,
points_with_deltas,
head_maxp_info,
composite_contours,
@ -433,14 +447,16 @@ struct Glyph
use_my_metrics,
phantom_only,
coords,
current_glyphs,
depth + 1,
edge_count)))
{
current_glyphs->del (item_gid);
points.resize (old_length);
return false;
}
// points might have been reallocated. Relocate phantoms.
phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
auto comp_points = all_points.as_array ().sub_array (old_count);
/* Copy phantom points from component if USE_MY_METRICS flag set */
@ -455,7 +471,7 @@ struct Glyph
item.get_transformation (matrix, default_trans);
/* Apply component transformation & translation (with deltas applied) */
item.transform_points (comp_points, matrix, points[comp_index]);
item.transform_points (comp_points, matrix, points[old_length + comp_index]);
}
if (item.is_anchored () && !phantom_only)
@ -476,12 +492,11 @@ struct Glyph
if (all_points.length > HB_GLYF_MAX_POINTS)
{
current_glyphs->del (item_gid);
points.resize (old_length);
return false;
}
comp_index++;
current_glyphs->del (item_gid);
}
if (head_maxp_info && depth == 0)
@ -492,9 +507,13 @@ struct Glyph
head_maxp_info->maxComponentElements = hb_max (head_maxp_info->maxComponentElements, comp_index);
}
all_points.extend (phantoms);
shift = phantoms[PHANTOM_LEFT].x;
points.resize (old_length);
} break;
case EMPTY:
all_points.extend (phantoms);
shift = phantoms[PHANTOM_LEFT].x;
points.resize (old_length);
break;
}
@ -503,10 +522,9 @@ struct Glyph
/* Undocumented rasterizer behavior:
* Shift points horizontally by the updated left side bearing
*/
float v = -phantoms[PHANTOM_LEFT].x;
if (v)
if (shift)
for (auto &point : all_points)
point.x += v;
point.x -= shift;
}
return !all_points.in_error ();

View file

@ -127,19 +127,20 @@ struct SimpleGlyph
hb_array_t<contour_point_t> points_ /* IN/OUT */,
const HBUINT8 *end)
{
auto *points = points_.arrayZ;
unsigned count = points_.length;
for (unsigned int i = 0; i < count;)
{
if (unlikely (p + 1 > end)) return false;
uint8_t flag = *p++;
points_.arrayZ[i++].flag = flag;
points[i++].flag = flag;
if (flag & FLAG_REPEAT)
{
if (unlikely (p + 1 > end)) return false;
unsigned int repeat_count = *p++;
unsigned stop = hb_min (i + repeat_count, count);
for (; i < stop; i++)
points_.arrayZ[i].flag = flag;
points[i].flag = flag;
}
}
return true;
@ -160,10 +161,7 @@ struct SimpleGlyph
if (flag & short_flag)
{
if (unlikely (p + 1 > end)) return false;
if (flag & same_flag)
v += *p++;
else
v -= *p++;
v += (bool(flag & same_flag) * 2 - 1) * *p++;
}
else
{
@ -190,7 +188,7 @@ struct SimpleGlyph
unsigned int num_points = endPtsOfContours[num_contours - 1] + 1;
unsigned old_length = points.length;
points.alloc (points.length + num_points + 4, true); // Allocate for phantom points, to avoid a possible copy
points.alloc (points.length + num_points + 4); // Allocate for phantom points, to avoid a possible copy
if (unlikely (!points.resize (points.length + num_points, false))) return false;
auto points_ = points.as_array ().sub_array (old_length);
if (!phantom_only)
@ -281,9 +279,9 @@ struct SimpleGlyph
unsigned num_points = all_points.length - 4;
hb_vector_t<uint8_t> flags, x_coords, y_coords;
if (unlikely (!flags.alloc (num_points, true))) return false;
if (unlikely (!x_coords.alloc (2*num_points, true))) return false;
if (unlikely (!y_coords.alloc (2*num_points, true))) return false;
if (unlikely (!flags.alloc_exact (num_points))) return false;
if (unlikely (!x_coords.alloc_exact (2*num_points))) return false;
if (unlikely (!y_coords.alloc_exact (2*num_points))) return false;
unsigned lastflag = 255, repeat = 0;
int prev_x = 0, prev_y = 0;

View file

@ -94,7 +94,7 @@ struct glyf
}
hb_vector_t<unsigned> padded_offsets;
if (unlikely (!padded_offsets.alloc (c->plan->new_to_old_gid_list.length, true)))
if (unlikely (!padded_offsets.alloc_exact (c->plan->new_to_old_gid_list.length)))
return_trace (false);
hb_vector_t<glyf_impl::SubsetGlyph> glyphs;
@ -172,6 +172,9 @@ struct glyf_accelerator_t
glyf_table = nullptr;
#ifndef HB_NO_VAR
gvar = nullptr;
#ifndef HB_NO_BEYOND_64K
GVAR = nullptr;
#endif
#endif
hmtx = nullptr;
#ifndef HB_NO_VERTICAL
@ -187,6 +190,9 @@ struct glyf_accelerator_t
glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face);
#ifndef HB_NO_VAR
gvar = face->table.gvar;
#ifndef HB_NO_BEYOND_64K
GVAR = face->table.GVAR;
#endif
#endif
hmtx = face->table.hmtx;
#ifndef HB_NO_VERTICAL
@ -198,6 +204,13 @@ struct glyf_accelerator_t
}
~glyf_accelerator_t ()
{
auto *scratch = cached_scratch.get_relaxed ();
if (scratch)
{
scratch->~hb_glyf_scratch_t ();
hb_free (scratch);
}
glyf_table.destroy ();
}
@ -206,21 +219,16 @@ struct glyf_accelerator_t
protected:
template<typename T>
bool get_points (hb_font_t *font, hb_codepoint_t gid, T consumer,
hb_array_t<const int> coords = hb_array_t<const int> ()) const
hb_array_t<const int> coords,
hb_glyf_scratch_t &scratch) const
{
if (!coords)
coords = hb_array (font->coords, font->num_coords);
if (gid >= num_glyphs) return false;
/* Making this allocfree is not that easy
https://github.com/harfbuzz/harfbuzz/issues/2095
mostly because of gvar handling in VF fonts,
perhaps a separate path for non-VF fonts can be considered */
contour_point_vector_t all_points;
auto &all_points = scratch.all_points;
all_points.resize (0);
bool phantom_only = !consumer.is_consuming_contour_points ();
if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, nullptr, nullptr, nullptr, true, true, phantom_only, coords)))
if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, scratch, nullptr, nullptr, nullptr, true, true, phantom_only, coords)))
return false;
unsigned count = all_points.length;
@ -229,8 +237,61 @@ struct glyf_accelerator_t
if (consumer.is_consuming_contour_points ())
{
for (auto &point : all_points.as_array ().sub_array (0, count))
consumer.consume_point (point);
auto *points = all_points.arrayZ;
if (false)
{
/* Our path-builder was designed to work with this simple loop.
* But FreeType and CoreText do it differently, so we match those
* with the other, more complicated, code branch below. */
for (unsigned i = 0; i < count; i++)
{
consumer.consume_point (points[i]);
if (points[i].is_end_point)
consumer.contour_end ();
}
}
else
{
for (unsigned i = 0; i < count; i++)
{
// Start of a contour.
if (points[i].flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE)
{
// First point is on-curve. Draw the contour.
for (; i < count; i++)
{
consumer.consume_point (points[i]);
if (points[i].is_end_point)
{
consumer.contour_end ();
break;
}
}
}
else
{
unsigned start = i;
// Find end of the contour.
for (; i < count; i++)
if (points[i].is_end_point)
break;
unsigned end = i;
// Enough to start from the end. Our path-builder takes care of the rest.
if (likely (end < count)) // Can only fail in case of alloc failure *maybe*.
consumer.consume_point (points[end]);
for (i = start; i < end; i++)
consumer.consume_point (points[i]);
consumer.contour_end ();
}
}
}
consumer.points_end ();
}
@ -303,6 +364,7 @@ struct glyf_accelerator_t
HB_ALWAYS_INLINE
void consume_point (const contour_point_t &point) { bounds.add (point); }
void contour_end () {}
void points_end () { bounds.get_extents (font, extents, scaled); }
bool is_consuming_contour_points () { return extents; }
@ -318,7 +380,12 @@ struct glyf_accelerator_t
contour_point_t phantoms[glyf_impl::PHANTOM_COUNT];
if (font->num_coords)
success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false));
{
hb_glyf_scratch_t scratch;
success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false),
hb_array (font->coords, font->num_coords),
scratch);
}
if (unlikely (!success))
return
@ -338,9 +405,11 @@ struct glyf_accelerator_t
if (unlikely (gid >= num_glyphs)) return false;
hb_glyph_extents_t extents;
hb_glyf_scratch_t scratch;
contour_point_t phantoms[glyf_impl::PHANTOM_COUNT];
if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms, false))))
if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms, false),
hb_array (font->coords, font->num_coords),
scratch)))
return false;
*lsb = is_vertical
@ -360,26 +429,33 @@ struct glyf_accelerator_t
}
public:
bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const
bool get_extents (hb_font_t *font,
hb_codepoint_t gid,
hb_glyph_extents_t *extents) const
{ return get_extents_at (font, gid, extents, hb_array (font->coords, font->num_coords)); }
bool get_extents_at (hb_font_t *font,
hb_codepoint_t gid,
hb_glyph_extents_t *extents,
hb_array_t<const int> coords) const
{
if (unlikely (gid >= num_glyphs)) return false;
#ifndef HB_NO_VAR
if (font->num_coords)
return get_points (font, gid, points_aggregator_t (font, extents, nullptr, true));
if (coords)
{
hb_glyf_scratch_t scratch;
return get_points (font,
gid,
points_aggregator_t (font, extents, nullptr, true),
coords,
scratch);
}
#endif
return glyph_for_gid (gid).get_extents_without_var_scaled (font, *this, extents);
}
bool paint_glyph (hb_font_t *font, hb_codepoint_t gid, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const
{
funcs->push_clip_glyph (data, gid, font);
funcs->color (data, true, foreground);
funcs->pop_clip (data);
return true;
}
const glyf_impl::Glyph
glyph_for_gid (hb_codepoint_t gid, bool needs_padding_removal = false) const
{
@ -410,15 +486,52 @@ struct glyf_accelerator_t
bool
get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const
{ return get_points (font, gid, glyf_impl::path_builder_t (font, draw_session)); }
{
if (!has_data ()) return false;
hb_glyf_scratch_t *scratch;
// Borrow the cached strach buffer.
{
scratch = cached_scratch.get_acquire ();
if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr)))
{
scratch = (hb_glyf_scratch_t *) hb_calloc (1, sizeof (hb_glyf_scratch_t));
if (unlikely (!scratch))
return true;
}
}
bool ret = get_points (font, gid, glyf_impl::path_builder_t (font, draw_session),
hb_array (font->coords, font->num_coords),
*scratch);
// Put it back.
if (!cached_scratch.cmpexch (nullptr, scratch))
{
scratch->~hb_glyf_scratch_t ();
hb_free (scratch);
}
return ret;
}
bool
get_path_at (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session,
hb_array_t<const int> coords) const
{ return get_points (font, gid, glyf_impl::path_builder_t (font, draw_session), coords); }
hb_array_t<const int> coords,
hb_glyf_scratch_t &scratch) const
{
if (!has_data ()) return false;
return get_points (font, gid, glyf_impl::path_builder_t (font, draw_session),
coords,
scratch);
}
#ifndef HB_NO_VAR
const gvar_accelerator_t *gvar;
#ifndef HB_NO_BEYOND_64K
const GVAR_accelerator_t *GVAR;
#endif
#endif
const hmtx_accelerator_t *hmtx;
#ifndef HB_NO_VERTICAL
@ -430,6 +543,7 @@ struct glyf_accelerator_t
unsigned int num_glyphs;
hb_blob_ptr_t<loca> loca_table;
hb_blob_ptr_t<glyf> glyf_table;
hb_atomic_t<hb_glyf_scratch_t *> cached_scratch;
};
@ -439,7 +553,7 @@ glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan,
hb_vector_t<glyf_impl::SubsetGlyph>& glyphs /* OUT */) const
{
OT::glyf_accelerator_t glyf (plan->source);
if (!glyphs.alloc (plan->new_to_old_gid_list.length, true)) return false;
if (!glyphs.alloc_exact (plan->new_to_old_gid_list.length)) return false;
for (const auto &pair : plan->new_to_old_gid_list)
{

View file

@ -42,7 +42,7 @@ struct path_builder_t
{
bool is_on_curve = point.flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE;
#ifdef HB_NO_CUBIC_GLYF
bool is_cubic = false;
constexpr bool is_cubic = false;
#else
bool is_cubic = !is_on_curve && (point.flag & glyf_impl::SimpleGlyph::FLAG_CUBIC);
#endif
@ -124,58 +124,60 @@ struct path_builder_t
}
}
if (unlikely (point.is_end_point))
{
if (first_offcurve && last_offcurve)
{
optional_point_t mid = last_offcurve.mid (first_offcurve2 ?
first_offcurve2 :
first_offcurve);
if (last_offcurve2)
draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
last_offcurve.x, last_offcurve.y,
mid.x, mid.y);
else
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
mid.x, mid.y);
last_offcurve = optional_point_t ();
}
/* now check the rest */
if (first_offcurve && first_oncurve)
{
if (first_offcurve2)
draw_session->cubic_to (first_offcurve2.x, first_offcurve2.y,
first_offcurve.x, first_offcurve.y,
first_oncurve.x, first_oncurve.y);
else
draw_session->quadratic_to (first_offcurve.x, first_offcurve.y,
first_oncurve.x, first_oncurve.y);
}
else if (last_offcurve && first_oncurve)
{
if (last_offcurve2)
draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
last_offcurve.x, last_offcurve.y,
first_oncurve.x, first_oncurve.y);
else
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
first_oncurve.x, first_oncurve.y);
}
else if (first_oncurve)
draw_session->line_to (first_oncurve.x, first_oncurve.y);
else if (first_offcurve)
{
float x = first_offcurve.x, y = first_offcurve.y;
draw_session->move_to (x, y);
draw_session->quadratic_to (x, y, x, y);
}
/* Getting ready for the next contour */
first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t ();
draw_session->close_path ();
}
}
void contour_end ()
{
if (first_offcurve && last_offcurve)
{
optional_point_t mid = last_offcurve.mid (first_offcurve2 ?
first_offcurve2 :
first_offcurve);
if (last_offcurve2)
draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
last_offcurve.x, last_offcurve.y,
mid.x, mid.y);
else
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
mid.x, mid.y);
last_offcurve = optional_point_t ();
}
/* now check the rest */
if (first_offcurve && first_oncurve)
{
if (first_offcurve2)
draw_session->cubic_to (first_offcurve2.x, first_offcurve2.y,
first_offcurve.x, first_offcurve.y,
first_oncurve.x, first_oncurve.y);
else
draw_session->quadratic_to (first_offcurve.x, first_offcurve.y,
first_oncurve.x, first_oncurve.y);
}
else if (last_offcurve && first_oncurve)
{
if (last_offcurve2)
draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
last_offcurve.x, last_offcurve.y,
first_oncurve.x, first_oncurve.y);
else
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
first_oncurve.x, first_oncurve.y);
}
else if (first_oncurve)
draw_session->line_to (first_oncurve.x, first_oncurve.y);
else if (first_offcurve)
{
float x = first_offcurve.x, y = first_offcurve.y;
draw_session->move_to (x, y);
draw_session->quadratic_to (x, y, x, y);
}
/* Getting ready for the next contour */
first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t ();
draw_session->close_path ();
}
void points_end () {}
bool is_consuming_contour_points () { return true; }

View file

@ -163,7 +163,7 @@ struct NameRecord
if (platformID != 1)
{
unsigned text_size = hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (*name_bytes, nullptr, nullptr);
text_size++; // needs to consider NULL terminator for use in hb_ot_name_convert_utf()
unsigned byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size;
name_str_utf16_be = (char *) hb_calloc (byte_len, 1);
@ -174,14 +174,14 @@ struct NameRecord
}
hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (*name_bytes, &text_size,
(hb_utf16_be_t::codepoint_t *) name_str_utf16_be);
unsigned encoded_byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size;
if (!encoded_byte_len || !c->check_assign (out->length, encoded_byte_len, HB_SERIALIZE_ERROR_INT_OVERFLOW)) {
c->revert (snap);
hb_free (name_str_utf16_be);
return_trace (nullptr);
}
encoded_bytes = hb_bytes_t (name_str_utf16_be, encoded_byte_len);
}
else
@ -392,7 +392,7 @@ struct name
const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides =
&c->plan->name_table_overrides;
#endif
auto it =
+ nameRecordZ.as_array (count)
| hb_filter (c->plan->name_ids, &NameRecord::nameID)
@ -485,7 +485,7 @@ struct name
const hb_array_t<const NameRecord> all_names (this->table->nameRecordZ.arrayZ,
this->table->count);
this->names.alloc (all_names.length, true);
this->names.alloc_exact (all_names.length);
for (unsigned int i = 0; i < all_names.length; i++)
{

2
src/addTable.py Normal file → Executable file
View file

@ -1,3 +1,5 @@
#!/usr/bin/env python3
import sys
from fontTools.ttLib import TTFont
from fontTools.ttLib.tables.DefaultTable import DefaultTable

View file

@ -22,30 +22,30 @@ if not OBJS:
stat = 0
tested = 0
for obj in OBJS:
result = subprocess.run(objdump.split () + ['-t', obj], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
result = subprocess.run(objdump.split () + ['-t'] + OBJS, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.returncode:
if result.stderr.find (b'not recognized') != -1:
# https://github.com/harfbuzz/harfbuzz/issues/3019
print ('objdump %s returned "not recognized", skipping' % obj)
continue
print ('objdump %s returned error:\n%s' % (obj, result.stderr.decode ('utf-8')))
stat = 2
if result.returncode:
if result.stderr.find (b'not recognized') != -1:
# https://github.com/harfbuzz/harfbuzz/issues/3019
print ('objdump %s returned "not recognized", skipping')
else:
print ('objdump returned error:\n%s' % (result.stderr.decode ('utf-8')))
stat = 2
else:
tested = 1
result = result.stdout.decode ('utf-8')
result = result.stdout.decode ('utf-8')
# Checking that no object file has static initializers
for l in re.findall (r'^.*\.[cd]tors.*$', result, re.MULTILINE):
if not re.match (r'.*\b0+\b', l):
print ('Ouch, %s has static initializers/finalizers' % obj)
stat = 1
# Checking that no object file has static initializers
for l in re.findall (r'^.*\.[cd]tors.*$', result, re.MULTILINE):
if not re.match (r'.*\b0+\b', l):
print ('Ouch, library has static initializers/finalizers')
stat = 1
# Checking that no object file has lazy static C++ constructors/destructors or other such stuff
if ('__cxa_' in result) and ('__ubsan_handle' not in result):
print ('Ouch, %s has lazy static C++ constructors/destructors or other such stuff' % obj)
stat = 1
# Checking that no object file has lazy static C++ constructors/destructors or other such stuff
if ('__cxa_' in result) and ('__ubsan_handle' not in result):
print ('Ouch, library has lazy static C++ constructors/destructors or other such stuff')
stat = 1
tested += 1
sys.exit (stat if tested else 77)

View file

@ -7,18 +7,27 @@ os.environ['LC_ALL'] = 'C' # otherwise 'nm' prints in wrong order
builddir = os.getenv ('builddir', os.path.dirname (__file__))
libs = os.getenv ('libs', '.libs')
IGNORED_SYMBOLS = '|'.join(['_fini', '_init', '_fdata', '_ftext', '_fbss',
IGNORED_SYMBOLS = ['_fini', '_init', '_fdata', '_ftext', '_fbss',
'__bss_start', '__bss_start__', '__bss_end__', '_edata', '_end', '_bss_end__',
'__end__', '__gcov_.*', 'llvm_.*', 'flush_fn_list', 'writeout_fn_list', 'mangle_path',
'lprofDirMode', 'reset_fn_list'])
'lprofDirMode', 'reset_fn_list']
# Rust
IGNORED_SYMBOLS += [
'rust_eh_personality',
'_ZN3std9panicking11EMPTY_PANIC.*', # 'std::panicking::EMPTY_PANIC::.*'
'_ZN3std3sys3pal4unix4args3imp15ARGV_INIT_ARRAY.*', # 'std::sys::pal::unix::args::imp::ARGV_INIT_ARRAY::.*'
'_ZN3std3sys4args4unix3imp15ARGV_INIT_ARRAY.*', # std::sys::args::unix::imp::ARGV_INIT_ARRAY::.*
'_ZN17compiler_builtins4math4libm7generic4sqrt9RSQRT_TAB.*', # 'compiler_builtins::math::libm::generic::sqrt::RSQRT_TAB::.*'
]
IGNORED_SYMBOLS = '|'.join (IGNORED_SYMBOLS)
nm = os.getenv ('NM', shutil.which ('nm'))
if not nm:
print ('check-symbols.py: \'nm\' not found; skipping test')
sys.exit (77)
cxxfilt = shutil.which ('c++filt')
tested = False
stat = 0
@ -34,12 +43,6 @@ for soname in ['harfbuzz', 'harfbuzz-subset', 'harfbuzz-icu', 'harfbuzz-gobject'
for s in re.findall (r'^.+ [BCDGIRSTu] .+$', subprocess.check_output (nm.split() + [so]).decode ('utf-8'), re.MULTILINE)
if not re.match (r'.* %s(%s)\b' % (symprefix, IGNORED_SYMBOLS), s)]
# run again c++filt also if is available
if cxxfilt:
EXPORTED_SYMBOLS = subprocess.check_output (
[cxxfilt], input='\n'.join (EXPORTED_SYMBOLS).encode ()
).decode ('utf-8').splitlines ()
prefix = (symprefix + os.path.basename (so)).replace ('libharfbuzz', 'hb').replace ('-', '_').split ('.')[0]
print ('Checking that %s does not expose internal symbols' % so)

95
src/fontations/Cargo.lock generated Normal file
View file

@ -0,0 +1,95 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "bytemuck"
version = "1.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540"
dependencies = [
"bytemuck_derive",
]
[[package]]
name = "bytemuck_derive"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "font-types"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d868ec188a98bb014c606072edd47e52e7ab7297db943b0b28503121e1d037bd"
dependencies = [
"bytemuck",
]
[[package]]
name = "harfbuzz_fontations"
version = "0.0.0"
dependencies = [
"read-fonts",
"skrifa",
]
[[package]]
name = "proc-macro2"
version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801"
dependencies = [
"proc-macro2",
]
[[package]]
name = "read-fonts"
version = "0.27.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f14974c88fb4fd0a7203719f98020209248c9dbebaf9d10d860337797a905097"
dependencies = [
"bytemuck",
"font-types",
]
[[package]]
name = "skrifa"
version = "0.29.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c0ca53de9bb9bee1720c727606275148463cd938eb6bde249dcedeec4967747"
dependencies = [
"bytemuck",
"read-fonts",
]
[[package]]
name = "syn"
version = "2.0.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e02e925281e18ffd9d640e234264753c43edc62d64b2d4cf898f1bc5e75f3fc2"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"

28
src/fontations/Cargo.toml Normal file
View file

@ -0,0 +1,28 @@
[package]
name = "harfbuzz_fontations"
edition = "2021"
[dependencies]
read-fonts = "0.27"
skrifa = "0.29.2"
[lib]
name = "harfbuzz_fontations"
path = "lib.rs"
crate-type = ["staticlib"]
[profile.release]
strip = true
lto = "fat"
panic = "abort"
overflow-checks = false
codegen-units = 1
[profile.debugoptimized]
inherits = "release"
debug = true
codegen-units = 16
strip = false
[profile.dev]
lto = "fat"

1132
src/fontations/lib.rs Normal file

File diff suppressed because it is too large Load diff

105
src/fontations/meson.build Normal file
View file

@ -0,0 +1,105 @@
rust = import('unstable-rust')
hb_rs = rust.bindgen(
input : '../hb.h',
output : 'hb.rs',
include_directories: incsrc,
args : ['--allowlist-function=hb_.*',
'--allowlist-type=hb_.*',
'--no-copy=hb_.*',
],
)
cargo = find_program('cargo')
rustfmt = find_program('rustfmt')
rust_flags = ''
cargo_args = [
'--package', 'harfbuzz_fontations',
'--lib',
'--target-dir', meson.current_build_dir(),
'--manifest-path', meson.current_source_dir() / 'Cargo.toml',
'-Z', 'build-std=std,panic_abort',
'-Z', 'build-std-features=panic_immediate_abort',
]
buildtype = get_option('buildtype')
if buildtype == 'release' or buildtype == 'debugoptimized'
cargo_args += ['--profile', buildtype]
endif
opt_level = get_option('optimization')
rust_flags += ' -C opt-level=' + opt_level
harfbuzz_fontations = custom_target(
'harfbuzz_fontations',
input: ['lib.rs', 'Cargo.toml', 'Cargo.lock'],
output: ['libharfbuzz_fontations.a'],
depends: [hb_rs],
env: ['OUT_DIR=' + meson.current_build_dir(),
'RUSTFLAGS=' + rust_flags,
],
command: [
cargo, 'build',
] + cargo_args + [
'-Z', 'unstable-options',
'--artifact-dir', meson.current_build_dir(),
],
install: true,
install_dir: join_paths(get_option('prefix'), 'lib'),
)
harfbuzz_fontations_dep = declare_dependency(
link_with: harfbuzz_fontations,
)
clippy_fix = run_target(
'clippy-fix',
env: ['OUT_DIR=' + meson.current_build_dir()],
depends: [hb_rs, harfbuzz_fontations],
command: [
cargo, 'clippy',
] + cargo_args + [
'--allow-dirty', '--fix',
],
)
if get_option('tests').enabled() and cargo.found()
test(
'clippy',
cargo,
env: ['OUT_DIR=' + meson.current_build_dir()],
depends: [hb_rs, harfbuzz_fontations],
args: [
'clippy',
] + cargo_args + [
'--', '-D', 'warnings',
],
timeout: 120,
)
endif
rustfmt_fix = run_target(
'rustfmt-fix',
env: ['OUT_DIR=' + meson.current_build_dir()],
depends: [hb_rs],
command: [
rustfmt,
'--edition', '2021',
'--',
meson.current_source_dir() / 'lib.rs',
],
)
if get_option('tests').enabled() and rustfmt.found()
test(
'rustfmt',
rustfmt,
env: ['OUT_DIR=' + meson.current_build_dir()],
depends: [hb_rs],
args: [
'--check',
'--edition', '2021',
'--',
meson.current_source_dir() / 'lib.rs',
],
)
endif

View file

@ -20,8 +20,11 @@ if '--experimental-api' not in sys.argv:
# Move these to harfbuzz-sections.txt when got stable
experimental_symbols = \
"""hb_shape_justify
hb_subset_repack_or_fail
hb_subset_input_override_name_table
hb_subset_cff_get_charstring_data
hb_subset_cff_get_charstrings_index
hb_subset_cff2_get_charstring_data
hb_subset_cff2_get_charstrings_index
""".splitlines ()
symbols = [x for x in symbols if x not in experimental_symbols]
symbols = "\n".join (symbols)

View file

@ -102,6 +102,7 @@ categories = {
'CM',
'Symbol',
'CS',
'SMPst',
],
'khmer' : [
'VAbv',
@ -435,6 +436,8 @@ defaults = (category_map[defaults[0]], position_map[defaults[1]], defaults[2])
indic_data = {}
for k, (cat, pos, block) in combined.items():
cat = category_map[cat]
if cat == 'SM' and pos == 'Not_Applicable':
cat = 'SMPst'
pos = position_map[pos]
indic_data[k] = (cat, pos, block)
@ -454,7 +457,7 @@ for k, (cat, pos, block) in indic_data.items():
# Keep in sync with CONSONANT_FLAGS in the shaper
consonant_categories = ('C', 'CS', 'Ra','CM', 'V', 'PLACEHOLDER', 'DOTTEDCIRCLE')
matra_categories = ('M', 'MPst')
smvd_categories = ('SM', 'VD', 'A', 'Symbol')
smvd_categories = ('SM', 'SMPst', 'VD', 'A', 'Symbol')
for k, (cat, pos, block) in indic_data.items():
if cat in consonant_categories:
pos = 'BASE_C'
@ -530,6 +533,7 @@ short = [{
"Repha": 'Rf',
"PLACEHOLDER": 'GB',
"DOTTEDCIRCLE": 'DC',
"SMPst": 'SP',
"VPst": 'VR',
"VPre": 'VL',
"Robatic": 'Rt',

View file

@ -19,7 +19,9 @@ outdir = os.path.dirname (OUTPUT)
shutil.copy (INPUT, outdir)
rl = os.path.basename (INPUT)
hh = rl.replace ('.rl', '.hh')
subprocess.Popen (ragel.split() + ['-e', '-F1', '-o', hh, rl], cwd=outdir).wait ()
ret = subprocess.Popen (ragel.split() + ['-e', '-F1', '-o', hh, rl], cwd=outdir).wait ()
if ret:
sys.exit (ret)
# copy it also to src/
shutil.copyfile (os.path.join (outdir, hh), os.path.join (CURRENT_SOURCE_DIR, hh))

View file

@ -345,14 +345,18 @@ class OpenTypeRegistryParser (HTMLParser):
self.from_bcp_47_uninherited = None
# Whether the parser is in a <td> element
self._td = False
# Whether the parser is after a <br> element within the current <tr> element
self._br = False
# Whether the parser ignores the rest of the current <td> element
self._disengaged = False
# The text of the <td> elements of the current <tr> element.
self._current_tr = []
def handle_starttag (self, tag, attrs):
if tag == 'br':
self._br = True
if tag == 'a':
if self._current_tr and not self._disengaged:
self._current_tr[-1] = ''
self._disengaged = True
elif tag == 'br':
self._disengaged = True
elif tag == 'meta':
for attr, value in attrs:
if attr == 'name' and value == 'updated_at':
@ -362,12 +366,13 @@ class OpenTypeRegistryParser (HTMLParser):
self._td = True
self._current_tr.append ('')
elif tag == 'tr':
self._br = False
self._disengaged = False
self._current_tr = []
def handle_endtag (self, tag):
if tag == 'td':
self._td = False
self._disengaged = False
elif tag == 'tr' and self._current_tr:
expect (2 <= len (self._current_tr) <= 3)
name = self._current_tr[0].strip ()
@ -387,7 +392,7 @@ class OpenTypeRegistryParser (HTMLParser):
self.ranks[tag] = rank
def handle_data (self, data):
if self._td and not self._br:
if self._td and not self._disengaged:
self._current_tr[-1] += data
def handle_charref (self, name):

View file

@ -109,6 +109,7 @@ property_names = [
'Nukta',
'Virama',
'Pure_Killer',
'Reordering_Killer',
'Invisible_Stacker',
'Vowel_Independent',
'Vowel_Dependent',
@ -263,6 +264,8 @@ def is_OTHER(U, UISC, UDI, UGC, AJT):
and not is_SYM_MOD(U, UISC, UDI, UGC, AJT)
and not is_Word_Joiner(U, UISC, UDI, UGC, AJT)
)
def is_REORDERING_KILLER(U, UISC, UDI, UGC, AJT):
return UISC == Reordering_Killer
def is_REPHA(U, UISC, UDI, UGC, AJT):
return UISC in [Consonant_Preceding_Repha, Consonant_Prefixed]
def is_SAKOT(U, UISC, UDI, UGC, AJT):
@ -306,6 +309,7 @@ use_mapping = {
'SE': is_HIEROGLYPH_SEGMENT_END,
'ZWNJ': is_ZWNJ,
'O': is_OTHER,
'RK': is_REORDERING_KILLER,
'R': is_REPHA,
'Sk': is_SAKOT,
'SM': is_SYM_MOD,
@ -358,6 +362,7 @@ use_positions = {
'Pst': [Not_Applicable],
},
'R': None,
'RK': None,
'SUB': None,
}

View file

@ -172,7 +172,7 @@ print ('static void')
print ('_output_dotted_circle (hb_buffer_t *buffer)')
print ('{')
print (' (void) buffer->output_glyph (0x25CCu);')
print (' _hb_glyph_info_reset_continuation (&buffer->prev());')
print (' _hb_glyph_info_clear_continuation (&buffer->prev());')
print ('}')
print ()
print ('static void')

View file

@ -2,6 +2,8 @@
set_and_check(HARFBUZZ_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
set(HARFBUZZ_VERSION "@HARFBUZZ_VERSION@")
# Add the libraries.
add_library(harfbuzz::harfbuzz @HB_LIBRARY_TYPE@ IMPORTED)
set_target_properties(harfbuzz::harfbuzz PROPERTIES

View file

@ -57,8 +57,10 @@
#include "hb-subset-input.cc"
#include "hb-subset-instancer-iup.cc"
#include "hb-subset-instancer-solver.cc"
#include "hb-subset-plan-layout.cc"
#include "hb-subset-plan-var.cc"
#include "hb-subset-plan.cc"
#include "hb-subset-repacker.cc"
#include "hb-subset-serialize.cc"
#include "hb-subset.cc"
#include "hb-ucd.cc"
#include "hb-unicode.cc"

View file

@ -6,7 +6,11 @@
#include "hb-buffer-verify.cc"
#include "hb-buffer.cc"
#include "hb-common.cc"
#include "hb-coretext-font.cc"
#include "hb-coretext-shape.cc"
#include "hb-coretext.cc"
#include "hb-directwrite-font.cc"
#include "hb-directwrite-shape.cc"
#include "hb-directwrite.cc"
#include "hb-draw.cc"
#include "hb-face-builder.cc"

View file

@ -29,7 +29,13 @@
#include "hb-aat-layout.hh"
#include "hb-aat-map.hh"
#include "hb-ot-layout-common.hh"
#include "hb-ot-layout-gdef-table.hh"
#include "hb-open-type.hh"
#include "hb-cache.hh"
#include "hb-bit-set.hh"
#include "hb-bit-page.hh"
namespace OT {
struct GDEF;
@ -39,10 +45,66 @@ namespace AAT {
using namespace OT;
#define HB_AAT_BUFFER_DIGEST_THRESHOLD 32
struct ankr;
using hb_aat_class_cache_t = hb_cache_t<15, 8, 7>;
static_assert (sizeof (hb_aat_class_cache_t) == 256, "");
struct hb_aat_scratch_t
{
hb_aat_scratch_t () = default;
hb_aat_scratch_t (const hb_aat_scratch_t &) = delete;
hb_aat_scratch_t (hb_aat_scratch_t &&o)
{
buffer_glyph_set.set_relaxed (o.buffer_glyph_set.get_relaxed ());
o.buffer_glyph_set.set_relaxed (nullptr);
}
hb_aat_scratch_t & operator = (hb_aat_scratch_t &&o)
{
buffer_glyph_set.set_relaxed (o.buffer_glyph_set.get_relaxed ());
o.buffer_glyph_set.set_relaxed (nullptr);
return *this;
}
~hb_aat_scratch_t ()
{
auto *s = buffer_glyph_set.get_relaxed ();
if (unlikely (!s))
return;
s->fini ();
hb_free (s);
}
hb_bit_set_t *create_buffer_glyph_set () const
{
hb_bit_set_t *s = buffer_glyph_set.get_acquire ();
if (s && buffer_glyph_set.cmpexch (s, nullptr))
return s;
s = (hb_bit_set_t *) hb_calloc (1, sizeof (hb_bit_set_t));
if (unlikely (!s))
return nullptr;
s->init ();
return s;
}
void destroy_buffer_glyph_set (hb_bit_set_t *s) const
{
if (unlikely (!s))
return;
if (buffer_glyph_set.cmpexch (nullptr, s))
return;
s->fini ();
hb_free (s);
}
mutable hb_atomic_t<hb_bit_set_t *> buffer_glyph_set;
};
enum { DELETED_GLYPH = 0xFFFF };
#define HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED HB_BUFFER_SCRATCH_FLAG_SHAPER0
struct hb_aat_apply_context_t :
hb_dispatch_context_t<hb_aat_apply_context_t, bool, HB_DEBUG_APPLY>
{
@ -59,12 +121,15 @@ struct hb_aat_apply_context_t :
hb_buffer_t *buffer;
hb_sanitize_context_t sanitizer;
const ankr *ankr_table;
const OT::GDEF *gdef_table;
const OT::GDEF &gdef;
bool has_glyph_classes;
const hb_sorted_vector_t<hb_aat_map_t::range_flags_t> *range_flags = nullptr;
hb_set_digest_t buffer_digest = hb_set_digest_t::full ();
hb_set_digest_t machine_glyph_set = hb_set_digest_t::full ();
hb_set_digest_t left_set = hb_set_digest_t::full ();
hb_set_digest_t right_set = hb_set_digest_t::full ();
bool using_buffer_glyph_set = false;
hb_bit_set_t *buffer_glyph_set = nullptr;
const hb_bit_set_t *left_set = nullptr;
const hb_bit_set_t *right_set = nullptr;
const hb_bit_set_t *machine_glyph_set = nullptr;
hb_aat_class_cache_t *machine_class_cache = nullptr;
hb_mask_t subtable_flags = 0;
/* Unused. For debug tracing only. */
@ -80,6 +145,88 @@ struct hb_aat_apply_context_t :
HB_INTERNAL void set_ankr_table (const AAT::ankr *ankr_table_);
void set_lookup_index (unsigned int i) { lookup_index = i; }
void setup_buffer_glyph_set ()
{
using_buffer_glyph_set = buffer->len >= 4 && buffer_glyph_set;
if (likely (using_buffer_glyph_set))
buffer->collect_codepoints (*buffer_glyph_set);
}
bool buffer_intersects_machine () const
{
if (likely (using_buffer_glyph_set))
return buffer_glyph_set->intersects (*machine_glyph_set);
// Faster for shorter buffers.
for (unsigned i = 0; i < buffer->len; i++)
if (machine_glyph_set->has (buffer->info[i].codepoint))
return true;
return false;
}
template <typename T>
HB_NODISCARD bool output_glyphs (unsigned int count,
const T *glyphs)
{
if (likely (using_buffer_glyph_set))
buffer_glyph_set->add_array (glyphs, count);
for (unsigned int i = 0; i < count; i++)
{
if (glyphs[i] == DELETED_GLYPH)
{
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED;
_hb_glyph_info_set_aat_deleted (&buffer->cur());
}
else
{
#ifndef HB_NO_OT_LAYOUT
if (has_glyph_classes)
_hb_glyph_info_set_glyph_props (&buffer->cur(),
gdef.get_glyph_props (glyphs[i]));
#endif
}
if (unlikely (!buffer->output_glyph (glyphs[i]))) return false;
}
return true;
}
HB_NODISCARD bool replace_glyph (hb_codepoint_t glyph)
{
if (glyph == DELETED_GLYPH)
{
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED;
_hb_glyph_info_set_aat_deleted (&buffer->cur());
}
if (likely (using_buffer_glyph_set))
buffer_glyph_set->add (glyph);
#ifndef HB_NO_OT_LAYOUT
if (has_glyph_classes)
_hb_glyph_info_set_glyph_props (&buffer->cur(),
gdef.get_glyph_props (glyph));
#endif
return buffer->replace_glyph (glyph);
}
HB_NODISCARD bool delete_glyph ()
{
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED;
_hb_glyph_info_set_aat_deleted (&buffer->cur());
return buffer->replace_glyph (DELETED_GLYPH);
}
void replace_glyph_inplace (unsigned i, hb_codepoint_t glyph)
{
buffer->info[i].codepoint = glyph;
if (likely (using_buffer_glyph_set))
buffer_glyph_set->add (glyph);
#ifndef HB_NO_OT_LAYOUT
if (has_glyph_classes)
_hb_glyph_info_set_glyph_props (&buffer->info[i],
gdef.get_glyph_props (glyph));
#endif
}
};
@ -87,8 +234,6 @@ struct hb_aat_apply_context_t :
* Lookup Table
*/
enum { DELETED_GLYPH = 0xFFFF };
template <typename T> struct Lookup;
template <typename T>
@ -108,6 +253,13 @@ struct LookupFormat0
{
glyphs.add_range (0, num_glyphs - 1);
}
template <typename set_t, typename filter_t>
void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const
{
for (unsigned i = 0; i < num_glyphs; i++)
if (filter (arrayZ[i]))
glyphs.add (i);
}
bool sanitize (hb_sanitize_context_t *c) const
{
@ -140,8 +292,14 @@ struct LookupSegmentSingle
template <typename set_t>
void collect_glyphs (set_t &glyphs) const
{
if (first == DELETED_GLYPH)
return;
if (first == DELETED_GLYPH) return;
glyphs.add_range (first, last);
}
template <typename set_t, typename filter_t>
void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const
{
if (first == DELETED_GLYPH) return;
if (!filter (value)) return;
glyphs.add_range (first, last);
}
@ -182,6 +340,13 @@ struct LookupFormat2
for (unsigned int i = 0; i < count; i++)
segments[i].collect_glyphs (glyphs);
}
template <typename set_t, typename filter_t>
void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const
{
unsigned count = segments.get_length ();
for (unsigned int i = 0; i < count; i++)
segments[i].collect_glyphs_filtered (glyphs, filter);
}
bool sanitize (hb_sanitize_context_t *c) const
{
@ -217,10 +382,18 @@ struct LookupSegmentArray
template <typename set_t>
void collect_glyphs (set_t &glyphs) const
{
if (first == DELETED_GLYPH)
return;
if (first == DELETED_GLYPH) return;
glyphs.add_range (first, last);
}
template <typename set_t, typename filter_t>
void collect_glyphs_filtered (set_t &glyphs, const void *base, const filter_t &filter) const
{
if (first == DELETED_GLYPH) return;
const auto &values = base+valuesZ;
for (hb_codepoint_t i = first; i <= last; i++)
if (filter (values[i - first]))
glyphs.add (i);
}
int cmp (hb_codepoint_t g) const
{ return g < first ? -1 : g <= last ? 0 : +1; }
@ -271,6 +444,13 @@ struct LookupFormat4
for (unsigned i = 0; i < count; i++)
segments[i].collect_glyphs (glyphs);
}
template <typename set_t, typename filter_t>
void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const
{
unsigned count = segments.get_length ();
for (unsigned i = 0; i < count; i++)
segments[i].collect_glyphs_filtered (glyphs, this, filter);
}
bool sanitize (hb_sanitize_context_t *c) const
{
@ -303,8 +483,14 @@ struct LookupSingle
template <typename set_t>
void collect_glyphs (set_t &glyphs) const
{
if (glyph == DELETED_GLYPH)
return;
if (glyph == DELETED_GLYPH) return;
glyphs.add (glyph);
}
template <typename set_t, typename filter_t>
void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const
{
if (glyph == DELETED_GLYPH) return;
if (!filter (value)) return;
glyphs.add (glyph);
}
@ -344,6 +530,13 @@ struct LookupFormat6
for (unsigned i = 0; i < count; i++)
entries[i].collect_glyphs (glyphs);
}
template <typename set_t, typename filter_t>
void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const
{
unsigned count = entries.get_length ();
for (unsigned i = 0; i < count; i++)
entries[i].collect_glyphs_filtered (glyphs, filter);
}
bool sanitize (hb_sanitize_context_t *c) const
{
@ -379,12 +572,20 @@ struct LookupFormat8
template <typename set_t>
void collect_glyphs (set_t &glyphs) const
{
if (unlikely (!glyphCount))
return;
if (firstGlyph == DELETED_GLYPH)
return;
if (unlikely (!glyphCount)) return;
if (firstGlyph == DELETED_GLYPH) return;
glyphs.add_range (firstGlyph, firstGlyph + glyphCount - 1);
}
template <typename set_t, typename filter_t>
void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const
{
if (unlikely (!glyphCount)) return;
if (firstGlyph == DELETED_GLYPH) return;
const T *p = valueArrayZ.arrayZ;
for (unsigned i = 0; i < glyphCount; i++)
if (filter (p[i]))
glyphs.add (firstGlyph + i);
}
bool sanitize (hb_sanitize_context_t *c) const
{
@ -433,10 +634,8 @@ struct LookupFormat10
template <typename set_t>
void collect_glyphs (set_t &glyphs) const
{
if (unlikely (!glyphCount))
return;
if (firstGlyph == DELETED_GLYPH)
return;
if (unlikely (!glyphCount)) return;
if (firstGlyph == DELETED_GLYPH) return;
glyphs.add_range (firstGlyph, firstGlyph + glyphCount - 1);
}
@ -501,6 +700,18 @@ struct Lookup
default:return;
}
}
template <typename set_t, typename filter_t>
void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const
{
switch (u.format) {
case 0: hb_barrier (); u.format0.collect_glyphs_filtered (glyphs, num_glyphs, filter); return;
case 2: hb_barrier (); u.format2.collect_glyphs_filtered (glyphs, filter); return;
case 4: hb_barrier (); u.format4.collect_glyphs_filtered (glyphs, filter); return;
case 6: hb_barrier (); u.format6.collect_glyphs_filtered (glyphs, filter); return;
case 8: hb_barrier (); u.format8.collect_glyphs_filtered (glyphs, filter); return;
default:return;
}
}
typename T::type get_class (hb_codepoint_t glyph_id,
unsigned int num_glyphs,
@ -563,7 +774,7 @@ DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (AAT, Lookup, 2);
template <typename T>
struct Entry
{
// This does seem like it's ever called.
// This doesn't seem like it's ever called.
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@ -632,18 +843,51 @@ struct StateTable
{
(this+classTable).collect_glyphs (glyphs, num_glyphs);
}
template <typename set_t, typename table_t>
void collect_initial_glyphs (set_t &glyphs, unsigned num_glyphs, const table_t &table) const
{
unsigned num_classes = nClasses;
if (unlikely (num_classes > hb_bit_page_t::BITS))
{
(this+classTable).collect_glyphs (glyphs, num_glyphs);
return;
}
// Collect all classes going out from the start state.
hb_bit_page_t filter;
for (unsigned i = 0; i < num_classes; i++)
{
const auto &entry = get_entry (STATE_START_OF_TEXT, i);
if (new_state (entry.newState) == STATE_START_OF_TEXT &&
!table.is_action_initiable (entry) && !table.is_actionable (entry))
continue;
filter.add (i);
}
// And glyphs in those classes.
if (filter (CLASS_DELETED_GLYPH))
glyphs.add (DELETED_GLYPH);
(this+classTable).collect_glyphs_filtered (glyphs, num_glyphs, filter);
}
int new_state (unsigned int newState) const
{ return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / (int) nClasses; }
template <typename set_t>
unsigned int get_class (hb_codepoint_t glyph_id,
unsigned int num_glyphs,
const set_t &glyphs) const
hb_aat_class_cache_t *cache = nullptr) const
{
unsigned klass;
if (cache && cache->get (glyph_id, &klass)) return klass;
if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
if (!glyphs[glyph_id]) return CLASS_OUT_OF_BOUNDS;
return (this+classTable).get_class (glyph_id, num_glyphs, CLASS_OUT_OF_BOUNDS);
klass = (this+classTable).get_class (glyph_id, num_glyphs, CLASS_OUT_OF_BOUNDS);
if (cache) cache->set (glyph_id, klass);
return klass;
}
const Entry<Extra> *get_entries () const
@ -651,13 +895,14 @@ struct StateTable
const Entry<Extra> &get_entry (int state, unsigned int klass) const
{
if (unlikely (klass >= nClasses))
unsigned n_classes = nClasses;
if (unlikely (klass >= n_classes))
klass = CLASS_OUT_OF_BOUNDS;
const HBUSHORT *states = (this+stateArrayTable).arrayZ;
const Entry<Extra> *entries = (this+entryTable).arrayZ;
unsigned int entry = states[state * nClasses + klass];
unsigned int entry = states[state * n_classes + klass];
DEBUG_MSG (APPLY, nullptr, "e%u", entry);
return entries[entry];
@ -803,6 +1048,13 @@ struct ClassTable
if (classArray.arrayZ[i] != CLASS_OUT_OF_BOUNDS)
glyphs.add (firstGlyph + i);
}
template <typename set_t, typename filter_t>
void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const
{
for (unsigned i = 0; i < classArray.len; i++)
if (filter (classArray.arrayZ[i]))
glyphs.add (firstGlyph + i);
}
bool sanitize (hb_sanitize_context_t *c) const
{
@ -918,7 +1170,7 @@ struct ExtendedTypes
}
};
template <typename Types, typename EntryData>
template <typename Types, typename EntryData, typename Flags>
struct StateTableDriver
{
using StateTableT = StateTable<Types, EntryData>;
@ -929,14 +1181,6 @@ struct StateTableDriver
machine (machine_),
num_glyphs (face_->get_num_glyphs ()) {}
template <typename context_t>
bool is_idempotent_on_all_out_of_bounds (context_t *c, hb_aat_apply_context_t *ac)
{
const auto entry = machine.get_entry (StateTableT::STATE_START_OF_TEXT, CLASS_OUT_OF_BOUNDS);
return !c->is_actionable (ac->buffer, this, entry) &&
machine.new_state (entry.newState) == StateTableT::STATE_START_OF_TEXT;
}
template <typename context_t>
void drive (context_t *c, hb_aat_apply_context_t *ac)
{
@ -977,7 +1221,7 @@ struct StateTableDriver
}
unsigned int klass = likely (buffer->idx < buffer->len) ?
machine.get_class (buffer->cur().codepoint, num_glyphs, ac->machine_glyph_set) :
machine.get_class (buffer->cur().codepoint, num_glyphs, ac->machine_class_cache) :
(unsigned) CLASS_END_OF_TEXT;
DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
const EntryT &entry = machine.get_entry (state, klass);
@ -1011,41 +1255,36 @@ struct StateTableDriver
*
* https://github.com/harfbuzz/harfbuzz/issues/2860
*/
const auto is_safe_to_break_extra = [&]()
{
/* 2c. */
const auto &wouldbe_entry = machine.get_entry(StateTableT::STATE_START_OF_TEXT, klass);
/* 2c'. */
if (c->is_actionable (buffer, this, wouldbe_entry))
return false;
/* 2c". */
return next_state == machine.new_state(wouldbe_entry.newState)
&& (entry.flags & context_t::DontAdvance) == (wouldbe_entry.flags & context_t::DontAdvance);
};
const auto is_safe_to_break = [&]()
{
const EntryT *wouldbe_entry;
bool is_safe_to_break =
(
/* 1. */
if (c->is_actionable (buffer, this, entry))
return false;
!c->table->is_actionable (entry) &&
/* 2. */
// This one is meh, I know...
const auto ok =
(
state == StateTableT::STATE_START_OF_TEXT
|| ((entry.flags & context_t::DontAdvance) && next_state == StateTableT::STATE_START_OF_TEXT)
|| is_safe_to_break_extra();
if (!ok)
return false;
|| ((entry.flags & Flags::DontAdvance) && next_state == StateTableT::STATE_START_OF_TEXT)
|| (
/* 2c. */
wouldbe_entry = &machine.get_entry(StateTableT::STATE_START_OF_TEXT, klass)
,
/* 2c'. */
!c->table->is_actionable (*wouldbe_entry) &&
/* 2c". */
(
next_state == machine.new_state(wouldbe_entry->newState) &&
(entry.flags & Flags::DontAdvance) == (wouldbe_entry->flags & Flags::DontAdvance)
)
)
) &&
/* 3. */
return !c->is_actionable (buffer, this, machine.get_entry (state, CLASS_END_OF_TEXT));
};
!c->table->is_actionable (machine.get_entry (state, CLASS_END_OF_TEXT))
);
if (!is_safe_to_break () && buffer->backtrack_len () && buffer->idx < buffer->len)
if (!is_safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
c->transition (buffer, this, entry);
@ -1056,7 +1295,7 @@ struct StateTableDriver
if (buffer->idx == buffer->len || unlikely (!buffer->successful))
break;
if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
if (!(entry.flags & Flags::DontAdvance) || buffer->max_ops-- <= 0)
(void) buffer->next_glyph ();
}

View file

@ -112,10 +112,6 @@ struct KerxSubTableFormat0
if (header.coverage & header.Backwards)
return_trace (false);
if (!(c->buffer_digest.may_have (c->left_set) &&
c->buffer_digest.may_have (c->right_set)))
return_trace (false);
accelerator_t accel (*this, c);
hb_kern_machine_t<accelerator_t> machine (accel, header.coverage & header.CrossStream);
machine.kern (c->font, c->buffer, c->plan->kern_mask);
@ -144,7 +140,7 @@ struct KerxSubTableFormat0
int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
{
if (!c->left_set[left] || !c->right_set[right]) return 0;
if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0;
return table.get_kerning (left, right, c);
}
};
@ -189,6 +185,9 @@ struct Format1Entry<true>
DEFINE_SIZE_STATIC (2);
};
static bool initiateAction (const Entry<EntryData> &entry)
{ return entry.flags & Push; }
static bool performAction (const Entry<EntryData> &entry)
{ return entry.data.kernActionIndex != 0xFFFF; }
@ -211,6 +210,9 @@ struct Format1Entry<false>
typedef void EntryData;
static bool initiateAction (const Entry<EntryData> &entry)
{ return entry.flags & Push; }
static bool performAction (const Entry<EntryData> &entry)
{ return entry.flags & Offset; }
@ -227,13 +229,23 @@ struct KerxSubTableFormat1
typedef Format1Entry<Types::extended> Format1EntryT;
typedef typename Format1EntryT::EntryData EntryData;
enum Flags
{
DontAdvance = Format1EntryT::DontAdvance,
};
bool is_action_initiable (const Entry<EntryData> &entry) const
{
return Format1EntryT::initiateAction (entry);
}
bool is_actionable (const Entry<EntryData> &entry) const
{
return Format1EntryT::performAction (entry);
}
struct driver_context_t
{
static constexpr bool in_place = true;
enum
{
DontAdvance = Format1EntryT::DontAdvance,
};
driver_context_t (const KerxSubTableFormat1 *table_,
hb_aat_apply_context_t *c_) :
@ -246,12 +258,8 @@ struct KerxSubTableFormat1
depth (0),
crossStream (table->header.coverage & table->header.CrossStream) {}
bool is_actionable (hb_buffer_t *buffer HB_UNUSED,
StateTableDriver<Types, EntryData> *driver HB_UNUSED,
const Entry<EntryData> &entry)
{ return Format1EntryT::performAction (entry); }
void transition (hb_buffer_t *buffer,
StateTableDriver<Types, EntryData> *driver,
StateTableDriver<Types, EntryData, Flags> *driver,
const Entry<EntryData> &entry)
{
unsigned int flags = entry.flags;
@ -320,8 +328,9 @@ struct KerxSubTableFormat1
}
else if (buffer->info[idx].mask & kern_mask)
{
o.x_advance += c->font->em_scale_x (v);
o.x_offset += c->font->em_scale_x (v);
auto scaled = c->font->em_scale_x (v);
o.x_advance += scaled;
o.x_offset += scaled;
}
}
else
@ -351,9 +360,10 @@ struct KerxSubTableFormat1
}
}
private:
public:
hb_aat_apply_context_t *c;
const KerxSubTableFormat1 *table;
private:
const UnsizedArrayOf<FWORD> &kernAction;
unsigned int stack[8];
unsigned int depth;
@ -370,12 +380,7 @@ struct KerxSubTableFormat1
driver_context_t dc (this, c);
StateTableDriver<Types, EntryData> driver (machine, c->font->face);
if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) &&
!(c->buffer_digest.may_have (c->left_set) &&
c->buffer_digest.may_have (c->right_set)))
return_trace (false);
StateTableDriver<Types, EntryData, Flags> driver (machine, c->font->face);
driver.drive (&dc, c);
@ -393,10 +398,8 @@ struct KerxSubTableFormat1
template <typename set_t>
void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const
{
set_t set;
machine.collect_glyphs (set, num_glyphs);
left_set.union_ (set);
right_set.union_ (set);
machine.collect_initial_glyphs (left_set, num_glyphs, *this);
//machine.collect_glyphs (right_set, num_glyphs); // right_set is unused for machine kerning
}
protected:
@ -440,10 +443,6 @@ struct KerxSubTableFormat2
if (header.coverage & header.Backwards)
return_trace (false);
if (!(c->buffer_digest.may_have (c->left_set) &&
c->buffer_digest.may_have (c->right_set)))
return_trace (false);
accelerator_t accel (*this, c);
hb_kern_machine_t<accelerator_t> machine (accel, header.coverage & header.CrossStream);
machine.kern (c->font, c->buffer, c->plan->kern_mask);
@ -469,7 +468,7 @@ struct KerxSubTableFormat2
int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
{
if (!c->left_set[left] || !c->right_set[right]) return 0;
if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0;
return table.get_kerning (left, right, c);
}
};
@ -513,17 +512,26 @@ struct KerxSubTableFormat4
DEFINE_SIZE_STATIC (2);
};
enum Flags
{
Mark = 0x8000, /* If set, remember this glyph as the marked glyph. */
DontAdvance = 0x4000, /* If set, don't advance to the next glyph before
* going to the new state. */
Reserved = 0x3FFF, /* Not used; set to 0. */
};
bool is_action_initiable (const Entry<EntryData> &entry) const
{
return (entry.flags & Mark);
}
bool is_actionable (const Entry<EntryData> &entry) const
{
return entry.data.ankrActionIndex != 0xFFFF;
}
struct driver_context_t
{
static constexpr bool in_place = true;
enum Flags
{
Mark = 0x8000, /* If set, remember this glyph as the marked glyph. */
DontAdvance = 0x4000, /* If set, don't advance to the next glyph before
* going to the new state. */
Reserved = 0x3FFF, /* Not used; set to 0. */
};
enum SubTableFlags
{
ActionType = 0xC0000000, /* A two-bit field containing the action type. */
@ -533,20 +541,17 @@ struct KerxSubTableFormat4
* point table. */
};
driver_context_t (const KerxSubTableFormat4 *table,
driver_context_t (const KerxSubTableFormat4 *table_,
hb_aat_apply_context_t *c_) :
c (c_),
table (table_),
action_type ((table->flags & ActionType) >> 30),
ankrData ((HBUINT16 *) ((const char *) &table->machine + (table->flags & Offset))),
mark_set (false),
mark (0) {}
bool is_actionable (hb_buffer_t *buffer HB_UNUSED,
StateTableDriver<Types, EntryData> *driver HB_UNUSED,
const Entry<EntryData> &entry)
{ return entry.data.ankrActionIndex != 0xFFFF; }
void transition (hb_buffer_t *buffer,
StateTableDriver<Types, EntryData> *driver,
StateTableDriver<Types, EntryData, Flags> *driver,
const Entry<EntryData> &entry)
{
if (mark_set && entry.data.ankrActionIndex != 0xFFFF && buffer->idx < buffer->len)
@ -634,8 +639,10 @@ struct KerxSubTableFormat4
}
}
private:
public:
hb_aat_apply_context_t *c;
const KerxSubTableFormat4 *table;
private:
unsigned int action_type;
const HBUINT16 *ankrData;
bool mark_set;
@ -648,12 +655,7 @@ struct KerxSubTableFormat4
driver_context_t dc (this, c);
StateTableDriver<Types, EntryData> driver (machine, c->font->face);
if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) &&
!(c->buffer_digest.may_have (c->left_set) &&
c->buffer_digest.may_have (c->right_set)))
return_trace (false);
StateTableDriver<Types, EntryData, Flags> driver (machine, c->font->face);
driver.drive (&dc, c);
@ -671,10 +673,8 @@ struct KerxSubTableFormat4
template <typename set_t>
void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const
{
set_t set;
machine.collect_glyphs (set, num_glyphs);
left_set.union_ (set);
right_set.union_ (set);
machine.collect_initial_glyphs (left_set, num_glyphs, *this);
//machine.collect_glyphs (right_set, num_glyphs); // right_set is unused for machine kerning
}
protected:
@ -735,10 +735,6 @@ struct KerxSubTableFormat6
if (header.coverage & header.Backwards)
return_trace (false);
if (!(c->buffer_digest.may_have (c->left_set) &&
c->buffer_digest.may_have (c->right_set)))
return_trace (false);
accelerator_t accel (*this, c);
hb_kern_machine_t<accelerator_t> machine (accel, header.coverage & header.CrossStream);
machine.kern (c->font, c->buffer, c->plan->kern_mask);
@ -793,7 +789,7 @@ struct KerxSubTableFormat6
int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
{
if (!c->left_set[left] || !c->right_set[right]) return 0;
if (!(*c->left_set)[left] || !(*c->right_set)[right]) return 0;
return table.get_kerning (left, right, c);
}
};
@ -925,7 +921,18 @@ struct KerxSubTable
* The 'kerx' Table
*/
using kern_accelerator_data_t = hb_vector_t<hb_pair_t<hb_set_digest_t, hb_set_digest_t>>;
struct kern_subtable_accelerator_data_t
{
hb_bit_set_t left_set;
hb_bit_set_t right_set;
mutable hb_aat_class_cache_t class_cache;
};
struct kern_accelerator_data_t
{
hb_vector_t<kern_subtable_accelerator_data_t> subtable_accels;
hb_aat_scratch_t scratch;
};
template <typename T>
struct KerxTable
@ -985,14 +992,11 @@ struct KerxTable
}
bool apply (AAT::hb_aat_apply_context_t *c,
const kern_accelerator_data_t *accel_data = nullptr) const
const kern_accelerator_data_t &accel_data) const
{
c->buffer->unsafe_to_concat ();
if (c->buffer->len < HB_AAT_BUFFER_DIGEST_THRESHOLD)
c->buffer_digest = c->buffer->digest ();
else
c->buffer_digest = hb_set_digest_t::full ();
c->setup_buffer_glyph_set ();
typedef typename T::SubTable SubTable;
@ -1005,12 +1009,25 @@ struct KerxTable
{
bool reverse;
auto &subtable_accel = accel_data.subtable_accels[i];
if (!T::Types::extended && (st->u.header.coverage & st->u.header.Variation))
goto skip;
if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->u.header.is_horizontal ())
goto skip;
c->left_set = &subtable_accel.left_set;
c->right_set = &subtable_accel.right_set;
c->machine_glyph_set = &subtable_accel.left_set;
c->machine_class_cache = &subtable_accel.class_cache;
if (!c->buffer_intersects_machine ())
{
(void) c->buffer->message (c->font, "skipped subtable %u because no glyph matches", c->lookup_index);
goto skip;
}
reverse = bool (st->u.header.coverage & st->u.header.Backwards) !=
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
@ -1037,16 +1054,6 @@ struct KerxTable
if (reverse)
c->buffer->reverse ();
if (accel_data)
{
c->left_set = (*accel_data)[i].first;
c->right_set = (*accel_data)[i].second;
}
else
{
c->left_set = c->right_set = hb_set_digest_t::full ();
}
{
/* See comment in sanitize() for conditional here. */
hb_sanitize_with_object_t with (&c->sanitizer, i < count - 1 ? st : (const SubTable *) nullptr);
@ -1122,9 +1129,13 @@ struct KerxTable
unsigned int count = thiz()->tableCount;
for (unsigned int i = 0; i < count; i++)
{
hb_set_digest_t left_set, right_set;
st->collect_glyphs (left_set, right_set, num_glyphs);
accel_data.push (hb_pair (left_set, right_set));
auto &subtable_accel = *accel_data.subtable_accels.push ();
if (unlikely (accel_data.subtable_accels.in_error ()))
return accel_data;
st->collect_glyphs (subtable_accel.left_set, subtable_accel.right_set, num_glyphs);
subtable_accel.class_cache.clear ();
st = &StructAfter<SubTable> (*st);
}
@ -1148,11 +1159,12 @@ struct KerxTable
bool apply (AAT::hb_aat_apply_context_t *c) const
{
return table->apply (c, &accel_data);
return table->apply (c, accel_data);
}
hb_blob_ptr_t<T> table;
kern_accelerator_data_t accel_data;
hb_aat_scratch_t scratch;
};
};

View file

@ -29,8 +29,7 @@
#include "hb-open-type.hh"
#include "hb-aat-layout-common.hh"
#include "hb-ot-layout-common.hh"
#include "hb-ot-layout-gdef-table.hh"
#include "hb-ot-layout.hh"
#include "hb-aat-map.hh"
/*
@ -53,35 +52,40 @@ struct RearrangementSubtable
typedef void EntryData;
struct driver_context_t
enum Flags
{
static constexpr bool in_place = true;
enum Flags
{
MarkFirst = 0x8000, /* If set, make the current glyph the first
MarkFirst = 0x8000, /* If set, make the current glyph the first
* glyph to be rearranged. */
DontAdvance = 0x4000, /* If set, don't advance to the next glyph
DontAdvance = 0x4000, /* If set, don't advance to the next glyph
* before going to the new state. This means
* that the glyph index doesn't change, even
* if the glyph at that index has changed. */
MarkLast = 0x2000, /* If set, make the current glyph the last
MarkLast = 0x2000, /* If set, make the current glyph the last
* glyph to be rearranged. */
Reserved = 0x1FF0, /* These bits are reserved and should be set to 0. */
Verb = 0x000F, /* The type of rearrangement specified. */
};
Reserved = 0x1FF0, /* These bits are reserved and should be set to 0. */
Verb = 0x000F, /* The type of rearrangement specified. */
};
driver_context_t (const RearrangementSubtable *table HB_UNUSED) :
bool is_action_initiable (const Entry<EntryData> &entry) const
{
return (entry.flags & MarkFirst);
}
bool is_actionable (const Entry<EntryData> &entry) const
{
return (entry.flags & Verb);
}
struct driver_context_t
{
static constexpr bool in_place = true;
driver_context_t (const RearrangementSubtable *table_) :
ret (false),
table (table_),
start (0), end (0) {}
bool is_actionable (hb_buffer_t *buffer HB_UNUSED,
StateTableDriver<Types, EntryData> *driver HB_UNUSED,
const Entry<EntryData> &entry) const
{
return (entry.flags & Verb) && start < end;
}
void transition (hb_buffer_t *buffer,
StateTableDriver<Types, EntryData> *driver,
StateTableDriver<Types, EntryData, Flags> *driver,
const Entry<EntryData> &entry)
{
unsigned int flags = entry.flags;
@ -158,6 +162,7 @@ struct RearrangementSubtable
public:
bool ret;
const RearrangementSubtable *table;
private:
unsigned int start;
unsigned int end;
@ -169,11 +174,7 @@ struct RearrangementSubtable
driver_context_t dc (this);
StateTableDriver<Types, EntryData> driver (machine, c->face);
if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) &&
!c->buffer_digest.may_have (c->machine_glyph_set))
return_trace (false);
StateTableDriver<Types, EntryData, Flags> driver (machine, c->face);
driver.drive (&dc, c);
@ -207,39 +208,38 @@ struct ContextualSubtable
DEFINE_SIZE_STATIC (4);
};
enum Flags
{
SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */
DontAdvance = 0x4000, /* If set, don't advance to the next glyph before
* going to the new state. */
Reserved = 0x3FFF, /* These bits are reserved and should be set to 0. */
};
bool is_action_initiable (const Entry<EntryData> &entry) const
{
return (entry.flags & SetMark);
}
bool is_actionable (const Entry<EntryData> &entry) const
{
return entry.data.markIndex != 0xFFFF || entry.data.currentIndex != 0xFFFF;
}
struct driver_context_t
{
static constexpr bool in_place = true;
enum Flags
{
SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */
DontAdvance = 0x4000, /* If set, don't advance to the next glyph before
* going to the new state. */
Reserved = 0x3FFF, /* These bits are reserved and should be set to 0. */
};
driver_context_t (const ContextualSubtable *table_,
hb_aat_apply_context_t *c_) :
ret (false),
c (c_),
gdef (*c->gdef_table),
mark_set (false),
has_glyph_classes (gdef.has_glyph_classes ()),
mark (0),
table (table_),
mark_set (false),
mark (0),
subs (table+table->substitutionTables) {}
bool is_actionable (hb_buffer_t *buffer,
StateTableDriver<Types, EntryData> *driver,
const Entry<EntryData> &entry) const
{
if (buffer->idx == buffer->len && !mark_set)
return false;
return entry.data.markIndex != 0xFFFF || entry.data.currentIndex != 0xFFFF;
}
void transition (hb_buffer_t *buffer,
StateTableDriver<Types, EntryData> *driver,
StateTableDriver<Types, EntryData, Flags> *driver,
const Entry<EntryData> &entry)
{
/* Looks like CoreText applies neither mark nor current substitution for
@ -271,11 +271,7 @@ struct ContextualSubtable
if (replacement)
{
buffer->unsafe_to_break (mark, hb_min (buffer->idx + 1, buffer->len));
buffer->info[mark].codepoint = *replacement;
c->buffer_digest.add (*replacement);
if (has_glyph_classes)
_hb_glyph_info_set_glyph_props (&buffer->info[mark],
gdef.get_glyph_props (*replacement));
c->replace_glyph_inplace (mark, *replacement);
ret = true;
}
@ -301,11 +297,7 @@ struct ContextualSubtable
}
if (replacement)
{
buffer->info[idx].codepoint = *replacement;
c->buffer_digest.add (*replacement);
if (has_glyph_classes)
_hb_glyph_info_set_glyph_props (&buffer->info[idx],
gdef.get_glyph_props (*replacement));
c->replace_glyph_inplace (idx, *replacement);
ret = true;
}
@ -318,13 +310,11 @@ struct ContextualSubtable
public:
bool ret;
private:
hb_aat_apply_context_t *c;
const OT::GDEF &gdef;
bool mark_set;
bool has_glyph_classes;
unsigned int mark;
const ContextualSubtable *table;
private:
bool mark_set;
unsigned int mark;
const UnsizedListOfOffset16To<Lookup<HBGlyphID16>, HBUINT, void, false> &subs;
};
@ -334,11 +324,7 @@ struct ContextualSubtable
driver_context_t dc (this, c);
StateTableDriver<Types, EntryData> driver (machine, c->face);
if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) &&
!c->buffer_digest.may_have (c->machine_glyph_set))
return_trace (false);
StateTableDriver<Types, EntryData, Flags> driver (machine, c->face);
driver.drive (&dc, c);
@ -389,6 +375,16 @@ struct LigatureEntry;
template <>
struct LigatureEntry<true>
{
struct EntryData
{
HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry
* for processing this group, if indicated
* by the flags. */
public:
DEFINE_SIZE_STATIC (2);
};
enum Flags
{
SetComponent = 0x8000, /* Push this glyph onto the component stack for
@ -400,14 +396,8 @@ struct LigatureEntry<true>
Reserved = 0x1FFF, /* These bits are reserved and should be set to 0. */
};
struct EntryData
{
HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry
* for processing this group, if indicated
* by the flags. */
public:
DEFINE_SIZE_STATIC (2);
};
static bool initiateAction (const Entry<EntryData> &entry)
{ return entry.flags & SetComponent; }
static bool performAction (const Entry<EntryData> &entry)
{ return entry.flags & PerformAction; }
@ -418,6 +408,8 @@ struct LigatureEntry<true>
template <>
struct LigatureEntry<false>
{
typedef void EntryData;
enum Flags
{
SetComponent = 0x8000, /* Push this glyph onto the component stack for
@ -429,7 +421,8 @@ struct LigatureEntry<false>
* multiple of 4. */
};
typedef void EntryData;
static bool initiateAction (const Entry<EntryData> &entry)
{ return entry.flags & SetComponent; }
static bool performAction (const Entry<EntryData> &entry)
{ return entry.flags & Offset; }
@ -447,13 +440,23 @@ struct LigatureSubtable
typedef LigatureEntry<Types::extended> LigatureEntryT;
typedef typename LigatureEntryT::EntryData EntryData;
enum Flags
{
DontAdvance = LigatureEntryT::DontAdvance,
};
bool is_action_initiable (const Entry<EntryData> &entry) const
{
return LigatureEntryT::initiateAction (entry);
}
bool is_actionable (const Entry<EntryData> &entry) const
{
return LigatureEntryT::performAction (entry);
}
struct driver_context_t
{
static constexpr bool in_place = false;
enum
{
DontAdvance = LigatureEntryT::DontAdvance,
};
enum LigActionFlags
{
LigActionLast = 0x80000000, /* This is the last action in the list. This also
@ -476,14 +479,8 @@ struct LigatureSubtable
ligature (table+table->ligature),
match_length (0) {}
bool is_actionable (hb_buffer_t *buffer HB_UNUSED,
StateTableDriver<Types, EntryData> *driver HB_UNUSED,
const Entry<EntryData> &entry) const
{
return LigatureEntryT::performAction (entry);
}
void transition (hb_buffer_t *buffer,
StateTableDriver<Types, EntryData> *driver,
StateTableDriver<Types, EntryData, Flags> *driver,
const Entry<EntryData> &entry)
{
DEBUG_MSG (APPLY, nullptr, "Ligature transition at %u", buffer->idx);
@ -556,7 +553,7 @@ struct LigatureSubtable
hb_codepoint_t lig = ligatureData;
DEBUG_MSG (APPLY, nullptr, "Produced ligature %u", lig);
if (unlikely (!buffer->replace_glyph (lig))) return;
if (unlikely (!c->replace_glyph (lig))) return;
unsigned int lig_end = match_positions[(match_length - 1u) % ARRAY_LENGTH (match_positions)] + 1u;
/* Now go and delete all subsequent components. */
@ -564,8 +561,7 @@ struct LigatureSubtable
{
DEBUG_MSG (APPLY, nullptr, "Skipping ligature component");
if (unlikely (!buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]))) return;
buffer->cur().unicode_props() |= UPROPS_MASK_IGNORABLE;
if (unlikely (!buffer->replace_glyph (DELETED_GLYPH))) return;
if (!c->delete_glyph ()) return;
}
if (unlikely (!buffer->move_to (lig_end))) return;
@ -581,9 +577,9 @@ struct LigatureSubtable
public:
bool ret;
private:
hb_aat_apply_context_t *c;
const LigatureSubtable *table;
private:
const UnsizedArrayOf<HBUINT32> &ligAction;
const UnsizedArrayOf<HBUINT16> &component;
const UnsizedArrayOf<HBGlyphID16> &ligature;
@ -597,11 +593,7 @@ struct LigatureSubtable
driver_context_t dc (this, c);
StateTableDriver<Types, EntryData> driver (machine, c->face);
if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) &&
!c->buffer_digest.may_have (c->machine_glyph_set))
return_trace (false);
StateTableDriver<Types, EntryData, Flags> driver (machine, c->face);
driver.drive (&dc, c);
@ -638,9 +630,6 @@ struct NoncontextualSubtable
{
TRACE_APPLY (this);
const OT::GDEF &gdef (*c->gdef_table);
bool has_glyph_classes = gdef.has_glyph_classes ();
bool ret = false;
unsigned int num_glyphs = c->face->get_num_glyphs ();
@ -670,11 +659,7 @@ struct NoncontextualSubtable
const HBGlyphID16 *replacement = substitute.get_value (info[i].codepoint, num_glyphs);
if (replacement)
{
info[i].codepoint = *replacement;
c->buffer_digest.add (*replacement);
if (has_glyph_classes)
_hb_glyph_info_set_glyph_props (&info[i],
gdef.get_glyph_props (*replacement));
c->replace_glyph_inplace (i, *replacement);
ret = true;
}
}
@ -682,6 +667,12 @@ struct NoncontextualSubtable
return_trace (ret);
}
template <typename set_t>
void collect_initial_glyphs (set_t &glyphs, unsigned num_glyphs) const
{
substitute.collect_glyphs (glyphs, num_glyphs);
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@ -715,73 +706,78 @@ struct InsertionSubtable
DEFINE_SIZE_STATIC (4);
};
enum Flags
{
SetMark = 0x8000, /* If set, mark the current glyph. */
DontAdvance = 0x4000, /* If set, don't advance to the next glyph before
* going to the new state. This does not mean
* that the glyph pointed to is the same one as
* before. If you've made insertions immediately
* downstream of the current glyph, the next glyph
* processed would in fact be the first one
* inserted. */
CurrentIsKashidaLike= 0x2000, /* If set, and the currentInsertList is nonzero,
* then the specified glyph list will be inserted
* as a kashida-like insertion, either before or
* after the current glyph (depending on the state
* of the currentInsertBefore flag). If clear, and
* the currentInsertList is nonzero, then the
* specified glyph list will be inserted as a
* split-vowel-like insertion, either before or
* after the current glyph (depending on the state
* of the currentInsertBefore flag). */
MarkedIsKashidaLike= 0x1000, /* If set, and the markedInsertList is nonzero,
* then the specified glyph list will be inserted
* as a kashida-like insertion, either before or
* after the marked glyph (depending on the state
* of the markedInsertBefore flag). If clear, and
* the markedInsertList is nonzero, then the
* specified glyph list will be inserted as a
* split-vowel-like insertion, either before or
* after the marked glyph (depending on the state
* of the markedInsertBefore flag). */
CurrentInsertBefore= 0x0800, /* If set, specifies that insertions are to be made
* to the left of the current glyph. If clear,
* they're made to the right of the current glyph. */
MarkedInsertBefore= 0x0400, /* If set, specifies that insertions are to be
* made to the left of the marked glyph. If clear,
* they're made to the right of the marked glyph. */
CurrentInsertCount= 0x3E0, /* This 5-bit field is treated as a count of the
* number of glyphs to insert at the current
* position. Since zero means no insertions, the
* largest number of insertions at any given
* current location is 31 glyphs. */
MarkedInsertCount= 0x001F, /* This 5-bit field is treated as a count of the
* number of glyphs to insert at the marked
* position. Since zero means no insertions, the
* largest number of insertions at any given
* marked location is 31 glyphs. */
};
bool is_action_initiable (const Entry<EntryData> &entry) const
{
return (entry.flags & SetMark);
}
bool is_actionable (const Entry<EntryData> &entry) const
{
return (entry.flags & (CurrentInsertCount | MarkedInsertCount)) &&
(entry.data.currentInsertIndex != 0xFFFF ||entry.data.markedInsertIndex != 0xFFFF);
}
struct driver_context_t
{
static constexpr bool in_place = false;
enum Flags
{
SetMark = 0x8000, /* If set, mark the current glyph. */
DontAdvance = 0x4000, /* If set, don't advance to the next glyph before
* going to the new state. This does not mean
* that the glyph pointed to is the same one as
* before. If you've made insertions immediately
* downstream of the current glyph, the next glyph
* processed would in fact be the first one
* inserted. */
CurrentIsKashidaLike= 0x2000, /* If set, and the currentInsertList is nonzero,
* then the specified glyph list will be inserted
* as a kashida-like insertion, either before or
* after the current glyph (depending on the state
* of the currentInsertBefore flag). If clear, and
* the currentInsertList is nonzero, then the
* specified glyph list will be inserted as a
* split-vowel-like insertion, either before or
* after the current glyph (depending on the state
* of the currentInsertBefore flag). */
MarkedIsKashidaLike= 0x1000, /* If set, and the markedInsertList is nonzero,
* then the specified glyph list will be inserted
* as a kashida-like insertion, either before or
* after the marked glyph (depending on the state
* of the markedInsertBefore flag). If clear, and
* the markedInsertList is nonzero, then the
* specified glyph list will be inserted as a
* split-vowel-like insertion, either before or
* after the marked glyph (depending on the state
* of the markedInsertBefore flag). */
CurrentInsertBefore= 0x0800, /* If set, specifies that insertions are to be made
* to the left of the current glyph. If clear,
* they're made to the right of the current glyph. */
MarkedInsertBefore= 0x0400, /* If set, specifies that insertions are to be
* made to the left of the marked glyph. If clear,
* they're made to the right of the marked glyph. */
CurrentInsertCount= 0x3E0, /* This 5-bit field is treated as a count of the
* number of glyphs to insert at the current
* position. Since zero means no insertions, the
* largest number of insertions at any given
* current location is 31 glyphs. */
MarkedInsertCount= 0x001F, /* This 5-bit field is treated as a count of the
* number of glyphs to insert at the marked
* position. Since zero means no insertions, the
* largest number of insertions at any given
* marked location is 31 glyphs. */
};
driver_context_t (const InsertionSubtable *table,
driver_context_t (const InsertionSubtable *table_,
hb_aat_apply_context_t *c_) :
ret (false),
c (c_),
table (table_),
mark (0),
insertionAction (table+table->insertionAction) {}
bool is_actionable (hb_buffer_t *buffer HB_UNUSED,
StateTableDriver<Types, EntryData> *driver HB_UNUSED,
const Entry<EntryData> &entry) const
{
return (entry.flags & (CurrentInsertCount | MarkedInsertCount)) &&
(entry.data.currentInsertIndex != 0xFFFF ||entry.data.markedInsertIndex != 0xFFFF);
}
void transition (hb_buffer_t *buffer,
StateTableDriver<Types, EntryData> *driver,
StateTableDriver<Types, EntryData, Flags> *driver,
const Entry<EntryData> &entry)
{
unsigned int flags = entry.flags;
@ -805,9 +801,7 @@ struct InsertionSubtable
if (buffer->idx < buffer->len && !before)
if (unlikely (!buffer->copy_glyph ())) return;
/* TODO We ignore KashidaLike setting. */
if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return;
for (unsigned int i = 0; i < count; i++)
c->buffer_digest.add (glyphs[i]);
if (unlikely (!c->output_glyphs (count, glyphs))) return;
ret = true;
if (buffer->idx < buffer->len && !before)
buffer->skip_glyph ();
@ -836,7 +830,8 @@ struct InsertionSubtable
if (buffer->idx < buffer->len && !before)
if (unlikely (!buffer->copy_glyph ())) return;
/* TODO We ignore KashidaLike setting. */
if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return;
if (unlikely (!c->output_glyphs (count, glyphs))) return;
ret = true;
if (buffer->idx < buffer->len && !before)
buffer->skip_glyph ();
@ -861,8 +856,9 @@ struct InsertionSubtable
public:
bool ret;
private:
hb_aat_apply_context_t *c;
const InsertionSubtable *table;
private:
unsigned int mark;
const UnsizedArrayOf<HBGlyphID16> &insertionAction;
};
@ -873,11 +869,7 @@ struct InsertionSubtable
driver_context_t dc (this, c);
StateTableDriver<Types, EntryData> driver (machine, c->face);
if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) &&
!c->buffer_digest.may_have (c->machine_glyph_set))
return_trace (false);
StateTableDriver<Types, EntryData, Flags> driver (machine, c->face);
driver.drive (&dc, c);
@ -935,24 +927,33 @@ struct hb_accelerate_subtables_context_t :
friend struct hb_aat_layout_lookup_accelerator_t;
public:
hb_set_digest_t digest;
hb_bit_set_t glyph_set;
mutable hb_aat_class_cache_t class_cache;
template <typename T>
auto init_ (const T &obj_, unsigned num_glyphs, hb_priority<1>) HB_AUTO_RETURN
(
obj_.machine.collect_glyphs (this->digest, num_glyphs)
obj_.machine.collect_initial_glyphs (glyph_set, num_glyphs, obj_)
)
template <typename T>
void init_ (const T &obj_, unsigned num_glyphs, hb_priority<0>)
{
digest = digest.full ();
obj_.collect_initial_glyphs (glyph_set, num_glyphs);
}
template <typename T>
void init (const T &obj_, unsigned num_glyphs)
{
glyph_set.init ();
init_ (obj_, num_glyphs, hb_prioritize);
class_cache.clear ();
}
void
fini ()
{
glyph_set.fini ();
}
};
@ -999,12 +1000,21 @@ struct hb_aat_layout_chain_accelerator_t
if (unlikely (!thiz))
return nullptr;
thiz->count = count;
hb_accelerate_subtables_context_t c_accelerate_subtables (thiz->subtables, num_glyphs);
chain.dispatch (&c_accelerate_subtables);
return thiz;
}
void destroy ()
{
for (unsigned i = 0; i < count; i++)
subtables[i].fini ();
}
unsigned count;
hb_accelerate_subtables_context_t::hb_applicable_t subtables[HB_VAR_ARRAY];
};
@ -1152,17 +1162,28 @@ struct Chain
{
bool reverse;
if (hb_none (hb_iter (c->range_flags) |
hb_map ([&subtable] (const hb_aat_map_t::range_flags_t _) -> bool { return subtable->subFeatureFlags & (_.flags); })))
goto skip;
c->subtable_flags = subtable->subFeatureFlags;
c->machine_glyph_set = accel ? accel->subtables[i].digest : hb_set_digest_t::full ();
auto coverage = subtable->get_coverage ();
if (!(subtable->get_coverage() & ChainSubtable<Types>::AllDirections) &&
HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) !=
bool (subtable->get_coverage() & ChainSubtable<Types>::Vertical))
hb_mask_t subtable_flags = subtable->subFeatureFlags;
if (hb_none (hb_iter (c->range_flags) |
hb_map ([subtable_flags] (const hb_aat_map_t::range_flags_t _) -> bool { return subtable_flags & (_.flags); })))
goto skip;
c->subtable_flags = subtable_flags;
c->machine_glyph_set = accel ? &accel->subtables[i].glyph_set : &Null(hb_bit_set_t);
c->machine_class_cache = accel ? &accel->subtables[i].class_cache : nullptr;
if (!(coverage & ChainSubtable<Types>::AllDirections) &&
HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) !=
bool (coverage & ChainSubtable<Types>::Vertical))
goto skip;
if (!c->buffer_intersects_machine ())
{
(void) c->buffer->message (c->font, "skipped chainsubtable %u because no glyph matches", c->lookup_index);
goto skip;
}
/* Buffer contents is always in logical direction. Determine if
* we need to reverse before applying this subtable. We reverse
* back after if we did reverse indeed.
@ -1190,9 +1211,9 @@ struct Chain
(the order opposite that of the characters, which
may be right-to-left or left-to-right).
*/
reverse = subtable->get_coverage () & ChainSubtable<Types>::Logical ?
bool (subtable->get_coverage () & ChainSubtable<Types>::Backwards) :
bool (subtable->get_coverage () & ChainSubtable<Types>::Backwards) !=
reverse = coverage & ChainSubtable<Types>::Logical ?
bool (coverage & ChainSubtable<Types>::Backwards) :
bool (coverage & ChainSubtable<Types>::Backwards) !=
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
if (!c->buffer->message (c->font, "start chainsubtable %u", c->lookup_index))
@ -1298,9 +1319,15 @@ struct mortmorx
hb_sanitize_context_t sc;
this->table = sc.reference_table<T> (face);
if (unlikely (this->table->is_blocklisted (this->table.get_blob (), face)))
{
hb_blob_destroy (this->table.get_blob ());
this->table = hb_blob_get_empty ();
}
this->chain_count = table->get_chain_count ();
this->accels = (hb_atomic_ptr_t<hb_aat_layout_chain_accelerator_t> *) hb_calloc (this->chain_count, sizeof (*accels));
this->accels = (hb_atomic_t<hb_aat_layout_chain_accelerator_t *> *) hb_calloc (this->chain_count, sizeof (*accels));
if (unlikely (!this->accels))
{
this->chain_count = 0;
@ -1311,7 +1338,11 @@ struct mortmorx
~accelerator_t ()
{
for (unsigned int i = 0; i < this->chain_count; i++)
{
if (this->accels[i])
this->accels[i]->destroy ();
hb_free (this->accels[i]);
}
hb_free (this->accels);
this->table.destroy ();
}
@ -1343,7 +1374,8 @@ struct mortmorx
hb_blob_ptr_t<T> table;
unsigned int chain_count;
hb_atomic_ptr_t<hb_aat_layout_chain_accelerator_t> *accels;
hb_atomic_t<hb_aat_layout_chain_accelerator_t *> *accels;
hb_aat_scratch_t scratch;
};
@ -1365,9 +1397,8 @@ struct mortmorx
unsigned get_chain_count () const
{
return chainCount;
return chainCount;
}
void apply (hb_aat_apply_context_t *c,
const hb_aat_map_t &map,
const accelerator_t &accel) const
@ -1376,10 +1407,7 @@ struct mortmorx
c->buffer->unsafe_to_concat ();
if (c->buffer->len < HB_AAT_BUFFER_DIGEST_THRESHOLD)
c->buffer_digest = c->buffer->digest ();
else
c->buffer_digest = hb_set_digest_t::full ();
c->setup_buffer_glyph_set ();
c->set_lookup_index (0);
const Chain<Types> *chain = &firstChain;
@ -1428,8 +1456,17 @@ struct mortmorx
DEFINE_SIZE_MIN (8);
};
struct morx : mortmorx<morx, ExtendedTypes, HB_AAT_TAG_morx> {};
struct mort : mortmorx<mort, ObsoleteTypes, HB_AAT_TAG_mort> {};
struct morx : mortmorx<morx, ExtendedTypes, HB_AAT_TAG_morx>
{
HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
hb_face_t *face) const;
};
struct mort : mortmorx<mort, ObsoleteTypes, HB_AAT_TAG_mort>
{
HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
hb_face_t *face) const;
};
struct morx_accelerator_t : morx::accelerator_t {
morx_accelerator_t (hb_face_t *face) : morx::accelerator_t (face) {}

View file

@ -31,6 +31,7 @@
#include "hb-aat-layout-common.hh"
#include "hb-ot-layout.hh"
#include "hb-open-type.hh"
#include "hb-ot-stat-table.hh"
/*
* trak -- Tracking
@ -48,22 +49,74 @@ struct TrackTableEntry
float get_track_value () const { return track.to_float (); }
int get_value (const void *base, unsigned int index,
unsigned int table_size) const
{ return (base+valuesZ).as_array (table_size)[index]; }
float interpolate_at (unsigned int idx,
float ptem,
const void *base,
hb_array_t<const F16DOT16> size_table) const
{
const FWORD *values = (base+valuesZ).arrayZ;
float s0 = size_table[idx].to_float ();
float s1 = size_table[idx + 1].to_float ();
int v0 = values[idx];
int v1 = values[idx + 1];
// Deal with font bugs.
if (unlikely (s1 < s0))
{ hb_swap (s0, s1); hb_swap (v0, v1); }
if (unlikely (ptem < s0)) return v0;
if (unlikely (ptem > s1)) return v1;
if (unlikely (s0 == s1)) return (v0 + v1) * 0.5f;
float t = (ptem - s0) / (s1 - s0);
return v0 + t * (v1 - v0);
}
float get_value (float ptem,
const void *base,
hb_array_t<const F16DOT16> size_table) const
{
const FWORD *values = (base+valuesZ).arrayZ;
unsigned int n_sizes = size_table.length;
/*
* Choose size.
*/
if (!n_sizes) return 0.f;
if (n_sizes == 1) return values[0];
// At least two entries.
unsigned i;
for (i = 0; i < n_sizes; i++)
if (size_table[i].to_float () >= ptem)
break;
// Boundary conditions.
if (i == 0) return values[0];
if (i == n_sizes) return values[n_sizes - 1];
// Exact match.
if (size_table[i].to_float () == ptem) return values[i];
// Interpolate.
return interpolate_at (i - 1, ptem, base, size_table);
}
public:
bool sanitize (hb_sanitize_context_t *c, const void *base,
unsigned int table_size) const
bool sanitize (hb_sanitize_context_t *c,
const void *base,
unsigned int n_sizes) const
{
TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this) &&
(valuesZ.sanitize (c, base, table_size))));
(valuesZ.sanitize (c, base, n_sizes))));
}
protected:
F16DOT16 track; /* Track value for this record. */
NameID trackNameID; /* The 'name' table index for this track.
OT::NameID trackNameID; /* The 'name' table index for this track.
* (a short word or phrase like "loose"
* or "very tight") */
NNOffset16To<UnsizedArrayOf<FWORD>>
@ -76,58 +129,38 @@ struct TrackTableEntry
struct TrackData
{
float interpolate_at (unsigned int idx,
float target_size,
const TrackTableEntry &trackTableEntry,
const void *base) const
float get_tracking (const void *base, float ptem, float track = 0.f) const
{
unsigned int sizes = nSizes;
hb_array_t<const F16DOT16> size_table ((base+sizeTable).arrayZ, sizes);
unsigned count = nTracks;
hb_array_t<const F16DOT16> size_table = (base+sizeTable).as_array (nSizes);
float s0 = size_table[idx].to_float ();
float s1 = size_table[idx + 1].to_float ();
float t = unlikely (s0 == s1) ? 0.f : (target_size - s0) / (s1 - s0);
return t * trackTableEntry.get_value (base, idx + 1, sizes) +
(1.f - t) * trackTableEntry.get_value (base, idx, sizes);
}
if (!count) return 0.f;
if (count == 1) return trackTable[0].get_value (ptem, base, size_table);
int get_tracking (const void *base, float ptem) const
{
/*
* Choose track.
*/
const TrackTableEntry *trackTableEntry = nullptr;
unsigned int count = nTracks;
for (unsigned int i = 0; i < count; i++)
{
/* Note: Seems like the track entries are sorted by values. But the
* spec doesn't explicitly say that. It just mentions it in the example. */
// At least two entries.
/* For now we only seek for track entries with zero tracking value */
unsigned i = 0;
unsigned j = count - 1;
if (trackTable[i].get_track_value () == 0.f)
{
trackTableEntry = &trackTable[i];
break;
}
}
if (!trackTableEntry) return 0;
// Find the two entries that track is between.
while (i + 1 < count && trackTable[i + 1].get_track_value () <= track)
i++;
while (j > 0 && trackTable[j - 1].get_track_value () >= track)
j--;
/*
* Choose size.
*/
unsigned int sizes = nSizes;
if (!sizes) return 0;
if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes);
// Exact match.
if (i == j) return trackTable[i].get_value (ptem, base, size_table);
hb_array_t<const F16DOT16> size_table ((base+sizeTable).arrayZ, sizes);
unsigned int size_index;
for (size_index = 0; size_index < sizes - 1; size_index++)
if (size_table[size_index].to_float () >= ptem)
break;
// Interpolate.
return roundf (interpolate_at (size_index ? size_index - 1 : 0, ptem,
*trackTableEntry, base));
float t0 = trackTable[i].get_track_value ();
float t1 = trackTable[j].get_track_value ();
float t = (track - t0) / (t1 - t0);
float a = trackTable[i].get_value (ptem, base, size_table);
float b = trackTable[j].get_value (ptem, base, size_table);
return a + t * (b - a);
}
bool sanitize (hb_sanitize_context_t *c, const void *base) const
@ -158,42 +191,52 @@ struct trak
bool has_data () const { return version.to_int (); }
bool apply (hb_aat_apply_context_t *c) const
hb_position_t get_h_tracking (hb_font_t *font, float track = 0.f) const
{
float ptem = font->ptem > 0.f ? font->ptem : HB_CORETEXT_DEFAULT_FONT_SIZE;
return font->em_scalef_x ((this+horizData).get_tracking (this, ptem, track));
}
hb_position_t get_v_tracking (hb_font_t *font, float track = 0.f) const
{
float ptem = font->ptem > 0.f ? font->ptem : HB_CORETEXT_DEFAULT_FONT_SIZE;
return font->em_scalef_y ((this+vertData).get_tracking (this, ptem, track));
}
hb_position_t get_tracking (hb_font_t *font, hb_direction_t dir, float track = 0.f) const
{
#ifndef HB_NO_STYLE
if (!font->face->table.STAT->has_data ())
return 0;
return HB_DIRECTION_IS_HORIZONTAL (dir) ?
get_h_tracking (font, track) :
get_v_tracking (font, track);
#else
return 0;
#endif
}
bool apply (hb_aat_apply_context_t *c, float track = 0.f) const
{
TRACE_APPLY (this);
hb_mask_t trak_mask = c->plan->trak_mask;
const float ptem = c->font->ptem;
float ptem = c->font->ptem;
if (unlikely (ptem <= 0.f))
return_trace (false);
{
/* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */
ptem = HB_CORETEXT_DEFAULT_FONT_SIZE;
}
hb_buffer_t *buffer = c->buffer;
if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
{
const TrackData &trackData = this+horizData;
int tracking = trackData.get_tracking (this, ptem);
hb_position_t offset_to_add = c->font->em_scalef_x (tracking / 2);
hb_position_t advance_to_add = c->font->em_scalef_x (tracking);
hb_position_t advance_to_add = get_h_tracking (c->font, track);
foreach_grapheme (buffer, start, end)
{
if (!(buffer->info[start].mask & trak_mask)) continue;
buffer->pos[start].x_advance += advance_to_add;
buffer->pos[start].x_offset += offset_to_add;
}
}
else
{
const TrackData &trackData = this+vertData;
int tracking = trackData.get_tracking (this, ptem);
hb_position_t offset_to_add = c->font->em_scalef_y (tracking / 2);
hb_position_t advance_to_add = c->font->em_scalef_y (tracking);
hb_position_t advance_to_add = get_v_tracking (c->font, track);
foreach_grapheme (buffer, start, end)
{
if (!(buffer->info[start].mask & trak_mask)) continue;
buffer->pos[start].y_advance += advance_to_add;
buffer->pos[start].y_offset += offset_to_add;
}
}
return_trace (true);

View file

@ -37,6 +37,9 @@
#include "hb-aat-layout-trak-table.hh"
#include "hb-aat-ltag-table.hh"
#include "hb-ot-layout-gsub-table.hh"
#include "hb-ot-layout-gdef-table.hh"
/*
* hb_aat_apply_context_t
@ -55,13 +58,14 @@ AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *p
buffer (buffer_),
sanitizer (),
ankr_table (&Null (AAT::ankr)),
gdef_table (
gdef (
#ifndef HB_NO_OT_LAYOUT
face->table.GDEF->table
*face->table.GDEF->table
#else
&Null (GDEF)
Null (GDEF)
#endif
),
has_glyph_classes (gdef.has_glyph_classes ()),
lookup_index (0)
{
sanitizer.init (blob);
@ -200,13 +204,43 @@ hb_aat_layout_find_feature_mapping (hb_tag_t tag)
#endif
#ifndef HB_NO_AAT
#ifndef HB_NO_AAT_SHAPE
/*
* mort/morx/kerx/trak
*/
bool
AAT::morx::is_blocklisted (hb_blob_t *blob,
hb_face_t *face) const
{
#ifdef HB_NO_AAT_LAYOUT_BLOCKLIST
return false;
#endif
switch HB_CODEPOINT_ENCODE3 (blob->length,
face->table.GSUB->table.get_length (),
face->table.GDEF->table.get_length ())
{
/* https://github.com/harfbuzz/harfbuzz/issues/4108
sha1sum:a71ca6813b7e56a772cffff7c24a5166b087197c AALMAGHRIBI.ttf */
case HB_CODEPOINT_ENCODE3 (19892, 2794, 340):
return true;
}
return false;
}
bool
AAT::mort::is_blocklisted (hb_blob_t *blob,
hb_face_t *face) const
{
#ifdef HB_NO_AAT_LAYOUT_BLOCKLIST
return false;
#endif
return false;
}
void
hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper,
hb_aat_map_t *map)
@ -254,11 +288,14 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan,
const hb_feature_t *features,
unsigned num_features)
{
hb_aat_map_builder_t builder (font->face, plan->props);
for (unsigned i = 0; i < num_features; i++)
builder.add_feature (features[i]);
hb_aat_map_t map;
builder.compile (map);
if (num_features)
{
hb_aat_map_builder_t builder (font->face, plan->props);
for (unsigned i = 0; i < num_features; i++)
builder.add_feature (features[i]);
builder.compile (map);
}
{
auto &accel = *font->face->table.morx;
@ -267,7 +304,10 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan,
{
AAT::hb_aat_apply_context_t c (plan, font, buffer, accel.get_blob ());
if (!buffer->message (font, "start table morx")) return;
morx.apply (&c, map, accel);
c.buffer_glyph_set = accel.scratch.create_buffer_glyph_set ();
morx.apply (&c, num_features ? map : plan->aat_map, accel);
accel.scratch.destroy_buffer_glyph_set (c.buffer_glyph_set);
c.buffer_glyph_set = nullptr;
(void) buffer->message (font, "end table morx");
return;
}
@ -280,34 +320,24 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan,
{
AAT::hb_aat_apply_context_t c (plan, font, buffer, accel.get_blob ());
if (!buffer->message (font, "start table mort")) return;
mort.apply (&c, map, accel);
mort.apply (&c, num_features ? map : plan->aat_map, accel);
(void) buffer->message (font, "end table mort");
return;
}
}
}
void
hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
hb_glyph_position_t *pos = buffer->pos;
for (unsigned int i = 0; i < count; i++)
if (unlikely (info[i].codepoint == AAT::DELETED_GLYPH))
pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0;
}
static bool
is_deleted_glyph (const hb_glyph_info_t *info)
{
return info->codepoint == AAT::DELETED_GLYPH;
return _hb_glyph_info_is_aat_deleted (info);
}
void
hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer)
{
buffer->delete_glyphs_inplace (is_deleted_glyph);
if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED)
buffer->delete_glyphs_inplace (is_deleted_glyph);
}
/**
@ -338,8 +368,11 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan,
AAT::hb_aat_apply_context_t c (plan, font, buffer, accel.get_blob ());
if (!buffer->message (font, "start table kerx")) return;
c.buffer_glyph_set = accel.scratch.create_buffer_glyph_set ();
c.set_ankr_table (font->face->table.ankr.get ());
accel.apply (&c);
accel.scratch.destroy_buffer_glyph_set (c.buffer_glyph_set);
c.buffer_glyph_set = nullptr;
(void) buffer->message (font, "end table kerx");
}

View file

@ -32,6 +32,9 @@
#include "hb-ot-shape.hh"
#include "hb-aat-ltag-table.hh"
/* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */
#define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f
struct hb_aat_feature_mapping_t
{
hb_tag_t otFeatureTag;
@ -57,9 +60,6 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan,
const hb_feature_t *features,
unsigned num_features);
HB_INTERNAL void
hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer);
HB_INTERNAL void
hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer);

View file

@ -85,25 +85,31 @@ void
hb_aat_map_builder_t::compile (hb_aat_map_t &m)
{
/* Compute active features per range, and compile each. */
if (!features.length)
{
hb_aat_layout_compile_map (this, &m);
return;
}
/* Sort features by start/end events. */
hb_vector_t<feature_event_t> feature_events;
feature_events.alloc_exact (features.length * 2 + 1);
for (unsigned int i = 0; i < features.length; i++)
{
auto &feature = features[i];
auto &feature = features.arrayZ[i];
if (features[i].start == features[i].end)
if (feature.start == feature.end)
continue;
feature_event_t *event;
event = feature_events.push ();
event->index = features[i].start;
event->index = feature.start;
event->start = true;
event->feature = feature.info;
event = feature_events.push ();
event->index = features[i].end;
event->index = feature.end;
event->start = false;
event->feature = feature.info;
}
@ -139,12 +145,12 @@ hb_aat_map_builder_t::compile (hb_aat_map_t &m)
current_features.qsort ();
unsigned int j = 0;
for (unsigned int i = 1; i < current_features.length; i++)
if (current_features[i].type != current_features[j].type ||
if (current_features.arrayZ[i].type != current_features.arrayZ[j].type ||
/* Nonexclusive feature selectors come in even/odd pairs to turn a setting on/off
* respectively, so we mask out the low-order bit when checking for "duplicates"
* (selectors referring to the same feature setting) here. */
(!current_features[i].is_exclusive && ((current_features[i].setting & ~1) != (current_features[j].setting & ~1))))
current_features[++j] = current_features[i];
(!current_features.arrayZ[i].is_exclusive && ((current_features.arrayZ[i].setting & ~1) != (current_features.arrayZ[j].setting & ~1))))
current_features.arrayZ[++j] = current_features.arrayZ[i];
current_features.shrink (j + 1);
}

View file

@ -286,7 +286,7 @@ HB_FUNCOBJ (hb_bool);
// Compression function for Merkle-Damgard construction.
// This function is generated using the framework provided.
#define mix(h) ( \
#define fasthash_mix(h) ( \
(void) ((h) ^= (h) >> 23), \
(void) ((h) *= 0x2127599bf4325c37ULL), \
(h) ^= (h) >> 47)
@ -310,7 +310,7 @@ static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed)
#pragma GCC diagnostic ignored "-Wcast-align"
v = * (const uint64_t *) (pos++);
#pragma GCC diagnostic pop
h ^= mix(v);
h ^= fasthash_mix(v);
h *= m;
}
}
@ -320,7 +320,7 @@ static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed)
while (pos != end)
{
v = pos++->v;
h ^= mix(v);
h ^= fasthash_mix(v);
h *= m;
}
}
@ -336,11 +336,11 @@ static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed)
case 3: v ^= (uint64_t)pos2[2] << 16; HB_FALLTHROUGH;
case 2: v ^= (uint64_t)pos2[1] << 8; HB_FALLTHROUGH;
case 1: v ^= (uint64_t)pos2[0];
h ^= mix(v);
h ^= fasthash_mix(v);
h *= m;
}
return mix(h);
return fasthash_mix(h);
}
static inline uint32_t fasthash32(const void *buf, size_t len, uint32_t seed)

View file

@ -251,7 +251,8 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
if (end < start + 2)
return;
for (unsigned lhs = start, rhs = end - 1; lhs < rhs; lhs++, rhs--)
unsigned stop = start + (end - start) / 2;
for (unsigned lhs = start, rhs = end - 1; lhs < stop; lhs++, rhs--)
hb_swap (arrayZ[rhs], arrayZ[lhs]);
}

View file

@ -80,15 +80,14 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
#include <atomic>
#define _hb_memory_barrier() std::atomic_thread_fence(std::memory_order_ack_rel)
#define _hb_memory_r_barrier() std::atomic_thread_fence(std::memory_order_acquire)
#define _hb_memory_w_barrier() std::atomic_thread_fence(std::memory_order_release)
#define hb_atomic_int_impl_add(AI, V) (reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> *> (AI)->fetch_add ((V), std::memory_order_acq_rel))
#define hb_atomic_int_impl_set_relaxed(AI, V) (reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> *> (AI)->store ((V), std::memory_order_relaxed))
#define hb_atomic_int_impl_set(AI, V) (reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> *> (AI)->store ((V), std::memory_order_release))
#define hb_atomic_int_impl_get_relaxed(AI) (reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> const *> (AI)->load (std::memory_order_relaxed))
#define hb_atomic_int_impl_get(AI) (reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> const *> (AI)->load (std::memory_order_acquire))
#define hb_atomic_int_impl_add(AI, V) (reinterpret_cast<std::atomic<typename std::decay<decltype (*(AI))>::type> *> (AI)->fetch_add ((V), std::memory_order_acq_rel))
#define hb_atomic_int_impl_set_relaxed(AI, V) (reinterpret_cast<std::atomic<typename std::decay<decltype (*(AI))>::type> *> (AI)->store ((V), std::memory_order_relaxed))
#define hb_atomic_int_impl_set(AI, V) (reinterpret_cast<std::atomic<typename std::decay<decltype (*(AI))>::type> *> (AI)->store ((V), std::memory_order_release))
#define hb_atomic_int_impl_get_relaxed(AI) (reinterpret_cast<std::atomic<typename std::decay<decltype (*(AI))>::type> const *> (AI)->load (std::memory_order_relaxed))
#define hb_atomic_int_impl_get(AI) (reinterpret_cast<std::atomic<typename std::decay<decltype (*(AI))>::type> const *> (AI)->load (std::memory_order_acquire))
#define hb_atomic_ptr_impl_set_relaxed(P, V) (reinterpret_cast<std::atomic<void*> *> (P)->store ((V), std::memory_order_relaxed))
#define hb_atomic_ptr_impl_get_relaxed(P) (reinterpret_cast<std::atomic<void*> const *> (P)->load (std::memory_order_relaxed))
@ -149,62 +148,47 @@ static inline void _hb_compiler_memory_r_barrier () {}
#define hb_atomic_ptr_impl_get_relaxed(P) (*(P))
#endif
#ifndef hb_atomic_int_impl_set
inline void hb_atomic_int_impl_set (int *AI, int v) { _hb_memory_w_barrier (); *AI = v; }
inline void hb_atomic_int_impl_set (short *AI, short v) { _hb_memory_w_barrier (); *AI = v; }
template <typename T>
inline void hb_atomic_int_impl_set (T *AI, T v) { _hb_memory_w_barrier (); *AI = v; }
#endif
#ifndef hb_atomic_int_impl_get
inline int hb_atomic_int_impl_get (const int *AI) { int v = *AI; _hb_memory_r_barrier (); return v; }
inline short hb_atomic_int_impl_get (const short *AI) { short v = *AI; _hb_memory_r_barrier (); return v; }
template <typename T>
inline T hb_atomic_int_impl_get (const T *AI) { T v = *AI; _hb_memory_r_barrier (); return v; }
#endif
#ifndef hb_atomic_ptr_impl_get
inline void *hb_atomic_ptr_impl_get (void ** const P) { void *v = *P; _hb_memory_r_barrier (); return v; }
#endif
struct hb_atomic_short_t
template <typename T>
struct hb_atomic_t
{
hb_atomic_short_t () = default;
constexpr hb_atomic_short_t (short v) : v (v) {}
hb_atomic_t () = default;
constexpr hb_atomic_t (T v) : v (v) {}
hb_atomic_short_t& operator = (short v_) { set_relaxed (v_); return *this; }
operator short () const { return get_relaxed (); }
hb_atomic_t& operator = (T v_) { set_relaxed (v_); return *this; }
operator T () const { return get_relaxed (); }
void set_relaxed (short v_) { hb_atomic_int_impl_set_relaxed (&v, v_); }
void set_release (short v_) { hb_atomic_int_impl_set (&v, v_); }
short get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); }
short get_acquire () const { return hb_atomic_int_impl_get (&v); }
short inc () { return hb_atomic_int_impl_add (&v, 1); }
short dec () { return hb_atomic_int_impl_add (&v, -1); }
void set_relaxed (T v_) { hb_atomic_int_impl_set_relaxed (&v, v_); }
void set_release (T v_) { hb_atomic_int_impl_set (&v, v_); }
T get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); }
T get_acquire () const { return hb_atomic_int_impl_get (&v); }
T inc () { return hb_atomic_int_impl_add (&v, 1); }
T dec () { return hb_atomic_int_impl_add (&v, -1); }
short v = 0;
int operator ++ (int) { return inc (); }
int operator -- (int) { return dec (); }
long operator |= (long v_) { set_relaxed (get_relaxed () | v_); return *this; }
T v = 0;
};
struct hb_atomic_int_t
template <typename T>
struct hb_atomic_t<T*>
{
hb_atomic_int_t () = default;
constexpr hb_atomic_int_t (int v) : v (v) {}
hb_atomic_int_t& operator = (int v_) { set_relaxed (v_); return *this; }
operator int () const { return get_relaxed (); }
void set_relaxed (int v_) { hb_atomic_int_impl_set_relaxed (&v, v_); }
void set_release (int v_) { hb_atomic_int_impl_set (&v, v_); }
int get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); }
int get_acquire () const { return hb_atomic_int_impl_get (&v); }
int inc () { return hb_atomic_int_impl_add (&v, 1); }
int dec () { return hb_atomic_int_impl_add (&v, -1); }
int v = 0;
};
template <typename P>
struct hb_atomic_ptr_t
{
typedef hb_remove_pointer<P> T;
hb_atomic_ptr_t () = default;
constexpr hb_atomic_ptr_t (T* v) : v (v) {}
hb_atomic_ptr_t (const hb_atomic_ptr_t &other) = delete;
hb_atomic_t () = default;
constexpr hb_atomic_t (T* v) : v (v) {}
hb_atomic_t (const hb_atomic_t &other) = delete;
void init (T* v_ = nullptr) { set_relaxed (v_); }
void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); }
@ -212,6 +196,7 @@ struct hb_atomic_ptr_t
T *get_acquire () const { return (T *) hb_atomic_ptr_impl_get ((void **) &v); }
bool cmpexch (const T *old, T *new_) const { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); }
operator bool () const { return get_acquire () != nullptr; }
T * operator -> () const { return get_acquire (); }
template <typename C> operator C * () const { return get_acquire (); }

View file

@ -78,6 +78,28 @@ struct hb_vector_size_t
hb_vector_size_t operator ~ () const
{ return process (hb_bitwise_neg); }
operator bool () const
{
for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
if (v[i])
return true;
return false;
}
operator unsigned int () const
{
unsigned int r = 0;
for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
r += hb_popcount (v[i]);
return r;
}
bool operator == (const hb_vector_size_t &o) const
{
for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
if (v[i] != o.v[i])
return false;
return true;
}
hb_array_t<const elt_t> iter () const
{ return hb_array (v); }
@ -89,6 +111,8 @@ struct hb_vector_size_t
struct hb_bit_page_t
{
hb_bit_page_t () { init0 (); }
void init0 () { v.init0 (); population = 0; }
void init1 () { v.init1 (); population = PAGE_BITS; }
@ -101,10 +125,9 @@ struct hb_bit_page_t
bool is_empty () const
{
if (has_population ()) return !population;
return
+ hb_iter (v)
| hb_none
;
bool empty = !v;
if (empty) population = 0;
return empty;
}
uint32_t hash () const
{
@ -115,6 +138,10 @@ struct hb_bit_page_t
void del (hb_codepoint_t g) { elt (g) &= ~mask (g); dirty (); }
void set (hb_codepoint_t g, bool value) { if (value) add (g); else del (g); }
bool get (hb_codepoint_t g) const { return elt (g) & mask (g); }
bool may_have (hb_codepoint_t g) const { return get (g); }
bool operator [] (hb_codepoint_t g) const { return get (g); }
bool operator () (hb_codepoint_t g) const { return get (g); }
void add_range (hb_codepoint_t a, hb_codepoint_t b)
{
@ -220,13 +247,17 @@ struct hb_bit_page_t
}
bool operator == (const hb_bit_page_t &other) const { return is_equal (other); }
bool is_equal (const hb_bit_page_t &other) const
bool is_equal (const hb_bit_page_t &other) const { return v == other.v; }
bool intersects (const hb_bit_page_t &other) const
{
for (unsigned i = 0; i < len (); i++)
if (v[i] != other.v[i])
return false;
return true;
if (v[i] & other.v[i])
return true;
return false;
}
bool may_intersect (const hb_bit_page_t &other) const
{ return intersects (other); }
bool operator <= (const hb_bit_page_t &larger_page) const { return is_subset (larger_page); }
bool is_subset (const hb_bit_page_t &larger_page) const
{
@ -241,14 +272,10 @@ struct hb_bit_page_t
}
bool has_population () const { return population != UINT_MAX; }
unsigned int get_population () const
unsigned get_population () const
{
if (has_population ()) return population;
population =
+ hb_iter (v)
| hb_reduce ([] (unsigned pop, const elt_t &_) { return pop + hb_popcount (_); }, 0u)
;
return population;
return population = v;
}
bool next (hb_codepoint_t *codepoint) const

View file

@ -126,6 +126,7 @@ struct hb_bit_set_invertible_t
{ unlikely (inverted) ? (void) s.add_range (a, b) : s.del_range (a, b); }
bool get (hb_codepoint_t g) const { return s.get (g) ^ inverted; }
bool may_have (hb_codepoint_t g) const { return get (g); }
/* Has interface. */
bool operator [] (hb_codepoint_t k) const { return get (k); }
@ -139,6 +140,9 @@ struct hb_bit_set_invertible_t
hb_bit_set_invertible_t& operator << (const hb_codepoint_pair_t& range)
{ add_range (range.first, range.second); return *this; }
bool may_intersect (const hb_bit_set_invertible_t &other) const
{ return inverted || other.inverted || s.intersects (other.s); }
bool intersects (hb_codepoint_t first, hb_codepoint_t last) const
{
hb_codepoint_t c = first - 1;

View file

@ -77,7 +77,7 @@ struct hb_bit_set_t
bool successful = true; /* Allocations successful */
mutable unsigned int population = 0;
mutable hb_atomic_int_t last_page_lookup = 0;
mutable hb_atomic_t<unsigned> last_page_lookup = 0;
hb_sorted_vector_t<page_map_t> page_map;
hb_vector_t<page_t> pages;
@ -88,10 +88,11 @@ struct hb_bit_set_t
{
if (unlikely (!successful)) return false;
if (pages.length == 0 && count == 1)
if (pages.length < count && (unsigned) pages.allocated < count && count <= 2)
exact_size = true; // Most sets are small and local
if (unlikely (!pages.resize (count, clear, exact_size) || !page_map.resize (count, clear, exact_size)))
if (unlikely (!pages.resize (count, clear, exact_size) ||
!page_map.resize (count, clear)))
{
pages.resize (page_map.length, clear, exact_size);
successful = false;
@ -297,9 +298,9 @@ struct hb_bit_set_t
unsigned int write_index = 0;
for (unsigned int i = 0; i < page_map.length; i++)
{
int m = (int) page_map[i].major;
int m = (int) page_map.arrayZ[i].major;
if (m < ds || de < m)
page_map[write_index++] = page_map[i];
page_map.arrayZ[write_index++] = page_map.arrayZ[i];
}
compact (compact_workspace, write_index);
resize (write_index);
@ -345,6 +346,7 @@ struct hb_bit_set_t
return false;
return page->get (g);
}
bool may_have (hb_codepoint_t g) const { return get (g); }
/* Has interface. */
bool operator [] (hb_codepoint_t k) const { return get (k); }
@ -358,6 +360,31 @@ struct hb_bit_set_t
hb_bit_set_t& operator << (const hb_codepoint_pair_t& range)
{ add_range (range.first, range.second); return *this; }
bool intersects (const hb_bit_set_t &other) const
{
unsigned int na = pages.length;
unsigned int nb = other.pages.length;
unsigned int a = 0, b = 0;
for (; a < na && b < nb; )
{
if (page_map.arrayZ[a].major == other.page_map.arrayZ[b].major)
{
if (page_at (a).intersects (other.page_at (b)))
return true;
a++;
b++;
}
else if (page_map.arrayZ[a].major < other.page_map.arrayZ[b].major)
a++;
else
b++;
}
return false;
}
bool may_intersect (const hb_bit_set_t &other) const
{ return intersects (other); }
bool intersects (hb_codepoint_t first, hb_codepoint_t last) const
{
hb_codepoint_t c = first - 1;
@ -389,7 +416,7 @@ struct hb_bit_set_t
{
if (page_at (a).is_empty ()) { a++; continue; }
if (other.page_at (b).is_empty ()) { b++; continue; }
if (page_map[a].major != other.page_map[b].major ||
if (page_map.arrayZ[a].major != other.page_map.arrayZ[b].major ||
!page_at (a).is_equal (other.page_at (b)))
return false;
a++;
@ -412,8 +439,8 @@ struct hb_bit_set_t
uint32_t spi = 0;
for (uint32_t lpi = 0; spi < page_map.length && lpi < larger_set.page_map.length; lpi++)
{
uint32_t spm = page_map[spi].major;
uint32_t lpm = larger_set.page_map[lpi].major;
uint32_t spm = page_map.arrayZ[spi].major;
uint32_t lpm = larger_set.page_map.arrayZ[lpi].major;
auto sp = page_at (spi);
if (spm < lpm && !sp.is_empty ())
@ -503,7 +530,7 @@ struct hb_bit_set_t
for (; a < na && b < nb; )
{
if (page_map[a].major == other.page_map[b].major)
if (page_map.arrayZ[a].major == other.page_map.arrayZ[b].major)
{
if (!passthru_left)
{
@ -512,7 +539,7 @@ struct hb_bit_set_t
// passthru_left is set since no left side pages will be removed
// in that case.
if (write_index < a)
page_map[write_index] = page_map[a];
page_map.arrayZ[write_index] = page_map.arrayZ[a];
write_index++;
}
@ -520,7 +547,7 @@ struct hb_bit_set_t
a++;
b++;
}
else if (page_map[a].major < other.page_map[b].major)
else if (page_map.arrayZ[a].major < other.page_map.arrayZ[b].major)
{
if (passthru_left)
count++;
@ -765,8 +792,8 @@ struct hb_bit_set_t
unsigned int initial_size = size;
for (unsigned int i = start_page; i < page_map.length && size; i++)
{
uint32_t base = major_start (page_map[i].major);
unsigned int n = pages[page_map[i].index].write (base, start_page_value, out, size);
uint32_t base = major_start (page_map.arrayZ[i].major);
unsigned int n = pages[page_map.arrayZ[i].index].write (base, start_page_value, out, size);
out += n;
size -= n;
start_page_value = 0;
@ -814,8 +841,8 @@ struct hb_bit_set_t
hb_codepoint_t next_value = codepoint + 1;
for (unsigned int i=start_page; i<page_map.length && size; i++)
{
uint32_t base = major_start (page_map[i].major);
unsigned int n = pages[page_map[i].index].write_inverted (base, start_page_value, out, size, &next_value);
uint32_t base = major_start (page_map.arrayZ[i].major);
unsigned int n = pages[page_map.arrayZ[i].index].write_inverted (base, start_page_value, out, size, &next_value);
out += n;
size -= n;
start_page_value = 0;
@ -846,8 +873,8 @@ struct hb_bit_set_t
unsigned count = pages.length;
for (unsigned i = 0; i < count; i++)
{
const auto& map = page_map[i];
const auto& page = pages[map.index];
const auto& map = page_map.arrayZ[i];
const auto& page = pages.arrayZ[map.index];
if (!page.is_empty ())
return map.major * page_t::PAGE_BITS + page.get_min ();
@ -859,8 +886,8 @@ struct hb_bit_set_t
unsigned count = pages.length;
for (signed i = count - 1; i >= 0; i--)
{
const auto& map = page_map[(unsigned) i];
const auto& page = pages[map.index];
const auto& map = page_map.arrayZ[(unsigned) i];
const auto& page = pages.arrayZ[map.index];
if (!page.is_empty ())
return map.major * page_t::PAGE_BITS + page.get_max ();
@ -961,7 +988,7 @@ struct hb_bit_set_t
return nullptr;
last_page_lookup = i;
return &pages.arrayZ[page_map[i].index];
return &pages.arrayZ[page_map.arrayZ[i].index];
}
page_t &page_at (unsigned int i)
{

195
src/hb-bit-vector.hh Normal file
View file

@ -0,0 +1,195 @@
/*
* 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.
*
* Author(s): Behdad Esfahbod
*/
#ifndef HB_BIT_VECTOR_HH
#define HB_BIT_VECTOR_HH
#include "hb.hh"
#include "hb-atomic.hh"
struct hb_min_max_t
{
void add (hb_codepoint_t v) { min_v = hb_min (min_v, v); max_v = hb_max (max_v, v); }
void add_range (hb_codepoint_t a, hb_codepoint_t b)
{
min_v = hb_min (min_v, a);
max_v = hb_max (max_v, b);
}
template <typename set_t>
void union_ (const set_t &set)
{
hb_codepoint_t set_min = set.get_min ();
if (unlikely (set_min == HB_CODEPOINT_INVALID))
return;
hb_codepoint_t set_max = set.get_max ();
min_v = hb_min (min_v, set_min);
max_v = hb_max (max_v, set_max);
}
hb_codepoint_t get_min () const { return min_v; }
hb_codepoint_t get_max () const { return max_v; }
private:
hb_codepoint_t min_v = HB_CODEPOINT_INVALID;
hb_codepoint_t max_v = 0;
};
template <bool atomic = false>
struct hb_bit_vector_t
{
using int_t = uint64_t;
using elt_t = typename std::conditional<atomic, hb_atomic_t<int_t>, int_t>::type;
hb_bit_vector_t () = delete;
hb_bit_vector_t (const hb_bit_vector_t &other) = delete;
hb_bit_vector_t &operator= (const hb_bit_vector_t &other) = delete;
// Move
hb_bit_vector_t (hb_bit_vector_t &&other)
: min_v (other.min_v), max_v (other.max_v), count (other.count), elts (other.elts)
{
other.min_v = other.max_v = other.count = 0;
other.elts = nullptr;
}
hb_bit_vector_t &operator= (hb_bit_vector_t &&other)
{
hb_swap (min_v, other.min_v);
hb_swap (max_v, other.max_v);
hb_swap (count, other.count);
hb_swap (elts, other.elts);
return *this;
}
hb_bit_vector_t (unsigned min_v, unsigned max_v)
: min_v (min_v), max_v (max_v)
{
if (unlikely (min_v >= max_v))
{
min_v = max_v = count = 0;
return;
}
unsigned num = (max_v - min_v + sizeof (int_t) * 8) / (sizeof (int_t) * 8);
elts = (elt_t *) hb_calloc (num, sizeof (int_t));
if (unlikely (!elts))
{
min_v = max_v = count = 0;
return;
}
count = max_v - min_v + 1;
}
~hb_bit_vector_t ()
{
hb_free (elts);
}
void add (hb_codepoint_t g) { elt (g) |= mask (g); }
void del (hb_codepoint_t g) { elt (g) &= ~mask (g); }
void set (hb_codepoint_t g, bool value) { if (value) add (g); else del (g); }
bool get (hb_codepoint_t g) const { return elt (g) & mask (g); }
bool has (hb_codepoint_t g) const { return get (g); }
bool may_have (hb_codepoint_t g) const { return get (g); }
bool operator [] (hb_codepoint_t g) const { return get (g); }
bool operator () (hb_codepoint_t g) const { return get (g); }
void add_range (hb_codepoint_t a, hb_codepoint_t b)
{
if (unlikely (!count || a > b || a < min_v || b > max_v))
return;
elt_t *la = &elt (a);
elt_t *lb = &elt (b);
if (la == lb)
*la |= (mask (b) << 1) - mask(a);
else
{
*la |= ~(mask (a) - 1llu);
la++;
hb_memset (la, 0xff, (char *) lb - (char *) la);
*lb |= ((mask (b) << 1) - 1llu);
}
}
void del_range (hb_codepoint_t a, hb_codepoint_t b)
{
if (unlikely (!count || a > b || a < min_v || b > max_v))
return;
elt_t *la = &elt (a);
elt_t *lb = &elt (b);
if (la == lb)
*la &= ~((mask (b) << 1llu) - mask(a));
else
{
*la &= mask (a) - 1;
la++;
hb_memset (la, 0, (char *) lb - (char *) la);
*lb &= ~((mask (b) << 1) - 1llu);
}
}
void set_range (hb_codepoint_t a, hb_codepoint_t b, bool v)
{ if (v) add_range (a, b); else del_range (a, b); }
template <typename set_t>
void union_ (const set_t &set)
{
for (hb_codepoint_t g : set)
add (g);
}
static const unsigned int ELT_BITS = sizeof (elt_t) * 8;
static constexpr unsigned ELT_MASK = ELT_BITS - 1;
static constexpr elt_t zero = 0;
elt_t &elt (hb_codepoint_t g)
{
g -= min_v;
if (unlikely (g >= count))
return Crap(elt_t);
return elts[g / ELT_BITS];
}
const elt_t& elt (hb_codepoint_t g) const
{
g -= min_v;
if (unlikely (g >= count))
return Null(elt_t);
return elts[g / ELT_BITS];
}
static constexpr int_t mask (hb_codepoint_t g) { return elt_t (1) << (g & ELT_MASK); }
hb_codepoint_t min_v = 0, max_v = 0, count = 0;
elt_t *elts = nullptr;
};
#endif /* HB_BIT_VECTOR_HH */

Some files were not shown because too many files have changed in this diff Show more