Merge pull request #4368 from googlefonts/support_gvar
Initial implementation for gvar partial instancing
diff --git a/.ci/requirements-fonttools.txt b/.ci/requirements-fonttools.txt
index 345c41b..754a2c8 100644
--- a/.ci/requirements-fonttools.txt
+++ b/.ci/requirements-fonttools.txt
@@ -4,39 +4,39 @@
#
# pip-compile --generate-hashes .ci/requirements-fonttools.in
#
-fonttools==4.41.1 \
- --hash=sha256:1df1b6f4c7c4bc8201eb47f3b268adbf2539943aa43c400f84556557e3e109c0 \
- --hash=sha256:2a22b2c425c698dcd5d6b0ff0b566e8e9663172118db6fd5f1941f9b8063da9b \
- --hash=sha256:33191f062549e6bb1a4782c22a04ebd37009c09360e2d6686ac5083774d06d95 \
- --hash=sha256:38cdecd8f1fd4bf4daae7fed1b3170dfc1b523388d6664b2204b351820aa78a7 \
- --hash=sha256:3ae64303ba670f8959fdaaa30ba0c2dabe75364fdec1caeee596c45d51ca3425 \
- --hash=sha256:3d1f9471134affc1e3b1b806db6e3e2ad3fa99439e332f1881a474c825101096 \
- --hash=sha256:4e3334d51f0e37e2c6056e67141b2adabc92613a968797e2571ca8a03bd64773 \
- --hash=sha256:4edc795533421e98f60acee7d28fc8d941ff5ac10f44668c9c3635ad72ae9045 \
- --hash=sha256:547ab36a799dded58a46fa647266c24d0ed43a66028cd1cd4370b246ad426cac \
- --hash=sha256:59eba8b2e749a1de85760da22333f3d17c42b66e03758855a12a2a542723c6e7 \
- --hash=sha256:704bccd69b0abb6fab9f5e4d2b75896afa48b427caa2c7988792a2ffce35b441 \
- --hash=sha256:73ef0bb5d60eb02ba4d3a7d23ada32184bd86007cb2de3657cfcb1175325fc83 \
- --hash=sha256:7763316111df7b5165529f4183a334aa24c13cdb5375ffa1dc8ce309c8bf4e5c \
- --hash=sha256:849ec722bbf7d3501a0e879e57dec1fc54919d31bff3f690af30bb87970f9784 \
- --hash=sha256:891cfc5a83b0307688f78b9bb446f03a7a1ad981690ac8362f50518bc6153975 \
- --hash=sha256:952cb405f78734cf6466252fec42e206450d1a6715746013f64df9cbd4f896fa \
- --hash=sha256:a7bbb290d13c6dd718ec2c3db46fe6c5f6811e7ea1e07f145fd8468176398224 \
- --hash=sha256:a9b3cc10dc9e0834b6665fd63ae0c6964c6bc3d7166e9bc84772e0edd09f9fa2 \
- --hash=sha256:aaaef294d8e411f0ecb778a0aefd11bb5884c9b8333cc1011bdaf3b58ca4bd75 \
- --hash=sha256:afce2aeb80be72b4da7dd114f10f04873ff512793d13ce0b19d12b2a4c44c0f0 \
- --hash=sha256:b0938ebbeccf7c80bb9a15e31645cf831572c3a33d5cc69abe436e7000c61b14 \
- --hash=sha256:b2d1ee95be42b80d1f002d1ee0a51d7a435ea90d36f1a5ae331be9962ee5a3f1 \
- --hash=sha256:b927e5f466d99c03e6e20961946314b81d6e3490d95865ef88061144d9f62e38 \
- --hash=sha256:bdd729744ae7ecd7f7311ad25d99da4999003dcfe43b436cf3c333d4e68de73d \
- --hash=sha256:c2071267deaa6d93cb16288613419679c77220543551cbe61da02c93d92df72f \
- --hash=sha256:cac73bbef7734e78c60949da11c4903ee5837168e58772371bd42a75872f4f82 \
- --hash=sha256:da2c2964bdc827ba6b8a91dc6de792620be4da3922c4cf0599f36a488c07e2b2 \
- --hash=sha256:e16a9449f21a93909c5be2f5ed5246420f2316e94195dbfccb5238aaa38f9751 \
- --hash=sha256:e5c2b0a95a221838991e2f0e455dec1ca3a8cc9cd54febd68cc64d40fdb83669 \
- --hash=sha256:ec453a45778524f925a8f20fd26a3326f398bfc55d534e37bab470c5e415caa1 \
- --hash=sha256:edee0900cf0eedb29d17c7876102d6e5a91ee333882b1f5abc83e85b934cadb5 \
- --hash=sha256:f14f3ccea4cc7dd1b277385adf3c3bf18f9860f87eab9c2fb650b0af16800f55 \
- --hash=sha256:f240d9adf0583ac8fc1646afe7f4ac039022b6f8fa4f1575a2cfa53675360b69 \
- --hash=sha256:f48602c0b3fd79cd83a34c40af565fe6db7ac9085c8823b552e6e751e3a5b8be
+fonttools==4.42.1 \
+ --hash=sha256:0eb79a2da5eb6457a6f8ab904838454accc7d4cccdaff1fd2bd3a0679ea33d64 \
+ --hash=sha256:113337c2d29665839b7d90b39f99b3cac731f72a0eda9306165a305c7c31d341 \
+ --hash=sha256:12a7c247d1b946829bfa2f331107a629ea77dc5391dfd34fdcd78efa61f354ca \
+ --hash=sha256:179737095eb98332a2744e8f12037b2977f22948cf23ff96656928923ddf560a \
+ --hash=sha256:19b7db825c8adee96fac0692e6e1ecd858cae9affb3b4812cdb9d934a898b29e \
+ --hash=sha256:37983b6bdab42c501202500a2be3a572f50d4efe3237e0686ee9d5f794d76b35 \
+ --hash=sha256:3a35981d90feebeaef05e46e33e6b9e5b5e618504672ca9cd0ff96b171e4bfff \
+ --hash=sha256:46a0ec8adbc6ff13494eb0c9c2e643b6f009ce7320cf640de106fb614e4d4360 \
+ --hash=sha256:4aa79366e442dbca6e2c8595645a3a605d9eeabdb7a094d745ed6106816bef5d \
+ --hash=sha256:515607ec756d7865f23070682622c49d922901943697871fc292277cf1e71967 \
+ --hash=sha256:53eb5091ddc8b1199330bb7b4a8a2e7995ad5d43376cadce84523d8223ef3136 \
+ --hash=sha256:5d18fc642fd0ac29236ff88ecfccff229ec0386090a839dd3f1162e9a7944a40 \
+ --hash=sha256:5fb289b7a815638a7613d46bcf324c9106804725b2bb8ad913c12b6958ffc4ec \
+ --hash=sha256:62f481ac772fd68901573956231aea3e4b1ad87b9b1089a61613a91e2b50bb9b \
+ --hash=sha256:689508b918332fb40ce117131633647731d098b1b10d092234aa959b4251add5 \
+ --hash=sha256:68a02bbe020dc22ee0540e040117535f06df9358106d3775e8817d826047f3fd \
+ --hash=sha256:6ed2662a3d9c832afa36405f8748c250be94ae5dfc5283d668308391f2102861 \
+ --hash=sha256:7286aed4ea271df9eab8d7a9b29e507094b51397812f7ce051ecd77915a6e26b \
+ --hash=sha256:7cc7d685b8eeca7ae69dc6416833fbfea61660684b7089bca666067cb2937dcf \
+ --hash=sha256:8708b98c278012ad267ee8a7433baeb809948855e81922878118464b274c909d \
+ --hash=sha256:9398f244e28e0596e2ee6024f808b06060109e33ed38dcc9bded452fd9bbb853 \
+ --hash=sha256:9e36344e48af3e3bde867a1ca54f97c308735dd8697005c2d24a86054a114a71 \
+ --hash=sha256:a398bdadb055f8de69f62b0fc70625f7cbdab436bbb31eef5816e28cab083ee8 \
+ --hash=sha256:acb47f6f8680de24c1ab65ebde39dd035768e2a9b571a07c7b8da95f6c8815fd \
+ --hash=sha256:be24fcb80493b2c94eae21df70017351851652a37de514de553435b256b2f249 \
+ --hash=sha256:c391cd5af88aacaf41dd7cfb96eeedfad297b5899a39e12f4c2c3706d0a3329d \
+ --hash=sha256:c95b0724a6deea2c8c5d3222191783ced0a2f09bd6d33f93e563f6f1a4b3b3a4 \
+ --hash=sha256:c9b1ce7a45978b821a06d375b83763b27a3a5e8a2e4570b3065abad240a18760 \
+ --hash=sha256:db372213d39fa33af667c2aa586a0c1235e88e9c850f5dd5c8e1f17515861868 \
+ --hash=sha256:db55cbaea02a20b49fefbd8e9d62bd481aaabe1f2301dabc575acc6b358874fa \
+ --hash=sha256:ed1a13a27f59d1fc1920394a7f596792e9d546c9ca5a044419dca70c37815d7c \
+ --hash=sha256:f2b82f46917d8722e6b5eafeefb4fb585d23babd15d8246c664cd88a5bddd19c \
+ --hash=sha256:f2f806990160d1ce42d287aa419df3ffc42dfefe60d473695fb048355fe0c6a0 \
+ --hash=sha256:f720fa82a11c0f9042376fd509b5ed88dab7e3cd602eee63a1af08883b37342b
# via -r requirements-fonttools.in
diff --git a/.ci/requirements.in b/.ci/requirements.in
index 6288c6b..72fe697 100644
--- a/.ci/requirements.in
+++ b/.ci/requirements.in
@@ -1,4 +1,4 @@
-r requirements-fonttools.in
-meson==1.2.0
+meson==1.2.1
gcovr==5.0
ninja
diff --git a/.ci/requirements.txt b/.ci/requirements.txt
index 00c4437..173508e 100644
--- a/.ci/requirements.txt
+++ b/.ci/requirements.txt
@@ -4,41 +4,41 @@
#
# pip-compile --generate-hashes .ci/requirements.in
#
-fonttools==4.41.1 \
- --hash=sha256:1df1b6f4c7c4bc8201eb47f3b268adbf2539943aa43c400f84556557e3e109c0 \
- --hash=sha256:2a22b2c425c698dcd5d6b0ff0b566e8e9663172118db6fd5f1941f9b8063da9b \
- --hash=sha256:33191f062549e6bb1a4782c22a04ebd37009c09360e2d6686ac5083774d06d95 \
- --hash=sha256:38cdecd8f1fd4bf4daae7fed1b3170dfc1b523388d6664b2204b351820aa78a7 \
- --hash=sha256:3ae64303ba670f8959fdaaa30ba0c2dabe75364fdec1caeee596c45d51ca3425 \
- --hash=sha256:3d1f9471134affc1e3b1b806db6e3e2ad3fa99439e332f1881a474c825101096 \
- --hash=sha256:4e3334d51f0e37e2c6056e67141b2adabc92613a968797e2571ca8a03bd64773 \
- --hash=sha256:4edc795533421e98f60acee7d28fc8d941ff5ac10f44668c9c3635ad72ae9045 \
- --hash=sha256:547ab36a799dded58a46fa647266c24d0ed43a66028cd1cd4370b246ad426cac \
- --hash=sha256:59eba8b2e749a1de85760da22333f3d17c42b66e03758855a12a2a542723c6e7 \
- --hash=sha256:704bccd69b0abb6fab9f5e4d2b75896afa48b427caa2c7988792a2ffce35b441 \
- --hash=sha256:73ef0bb5d60eb02ba4d3a7d23ada32184bd86007cb2de3657cfcb1175325fc83 \
- --hash=sha256:7763316111df7b5165529f4183a334aa24c13cdb5375ffa1dc8ce309c8bf4e5c \
- --hash=sha256:849ec722bbf7d3501a0e879e57dec1fc54919d31bff3f690af30bb87970f9784 \
- --hash=sha256:891cfc5a83b0307688f78b9bb446f03a7a1ad981690ac8362f50518bc6153975 \
- --hash=sha256:952cb405f78734cf6466252fec42e206450d1a6715746013f64df9cbd4f896fa \
- --hash=sha256:a7bbb290d13c6dd718ec2c3db46fe6c5f6811e7ea1e07f145fd8468176398224 \
- --hash=sha256:a9b3cc10dc9e0834b6665fd63ae0c6964c6bc3d7166e9bc84772e0edd09f9fa2 \
- --hash=sha256:aaaef294d8e411f0ecb778a0aefd11bb5884c9b8333cc1011bdaf3b58ca4bd75 \
- --hash=sha256:afce2aeb80be72b4da7dd114f10f04873ff512793d13ce0b19d12b2a4c44c0f0 \
- --hash=sha256:b0938ebbeccf7c80bb9a15e31645cf831572c3a33d5cc69abe436e7000c61b14 \
- --hash=sha256:b2d1ee95be42b80d1f002d1ee0a51d7a435ea90d36f1a5ae331be9962ee5a3f1 \
- --hash=sha256:b927e5f466d99c03e6e20961946314b81d6e3490d95865ef88061144d9f62e38 \
- --hash=sha256:bdd729744ae7ecd7f7311ad25d99da4999003dcfe43b436cf3c333d4e68de73d \
- --hash=sha256:c2071267deaa6d93cb16288613419679c77220543551cbe61da02c93d92df72f \
- --hash=sha256:cac73bbef7734e78c60949da11c4903ee5837168e58772371bd42a75872f4f82 \
- --hash=sha256:da2c2964bdc827ba6b8a91dc6de792620be4da3922c4cf0599f36a488c07e2b2 \
- --hash=sha256:e16a9449f21a93909c5be2f5ed5246420f2316e94195dbfccb5238aaa38f9751 \
- --hash=sha256:e5c2b0a95a221838991e2f0e455dec1ca3a8cc9cd54febd68cc64d40fdb83669 \
- --hash=sha256:ec453a45778524f925a8f20fd26a3326f398bfc55d534e37bab470c5e415caa1 \
- --hash=sha256:edee0900cf0eedb29d17c7876102d6e5a91ee333882b1f5abc83e85b934cadb5 \
- --hash=sha256:f14f3ccea4cc7dd1b277385adf3c3bf18f9860f87eab9c2fb650b0af16800f55 \
- --hash=sha256:f240d9adf0583ac8fc1646afe7f4ac039022b6f8fa4f1575a2cfa53675360b69 \
- --hash=sha256:f48602c0b3fd79cd83a34c40af565fe6db7ac9085c8823b552e6e751e3a5b8be
+fonttools==4.42.1 \
+ --hash=sha256:0eb79a2da5eb6457a6f8ab904838454accc7d4cccdaff1fd2bd3a0679ea33d64 \
+ --hash=sha256:113337c2d29665839b7d90b39f99b3cac731f72a0eda9306165a305c7c31d341 \
+ --hash=sha256:12a7c247d1b946829bfa2f331107a629ea77dc5391dfd34fdcd78efa61f354ca \
+ --hash=sha256:179737095eb98332a2744e8f12037b2977f22948cf23ff96656928923ddf560a \
+ --hash=sha256:19b7db825c8adee96fac0692e6e1ecd858cae9affb3b4812cdb9d934a898b29e \
+ --hash=sha256:37983b6bdab42c501202500a2be3a572f50d4efe3237e0686ee9d5f794d76b35 \
+ --hash=sha256:3a35981d90feebeaef05e46e33e6b9e5b5e618504672ca9cd0ff96b171e4bfff \
+ --hash=sha256:46a0ec8adbc6ff13494eb0c9c2e643b6f009ce7320cf640de106fb614e4d4360 \
+ --hash=sha256:4aa79366e442dbca6e2c8595645a3a605d9eeabdb7a094d745ed6106816bef5d \
+ --hash=sha256:515607ec756d7865f23070682622c49d922901943697871fc292277cf1e71967 \
+ --hash=sha256:53eb5091ddc8b1199330bb7b4a8a2e7995ad5d43376cadce84523d8223ef3136 \
+ --hash=sha256:5d18fc642fd0ac29236ff88ecfccff229ec0386090a839dd3f1162e9a7944a40 \
+ --hash=sha256:5fb289b7a815638a7613d46bcf324c9106804725b2bb8ad913c12b6958ffc4ec \
+ --hash=sha256:62f481ac772fd68901573956231aea3e4b1ad87b9b1089a61613a91e2b50bb9b \
+ --hash=sha256:689508b918332fb40ce117131633647731d098b1b10d092234aa959b4251add5 \
+ --hash=sha256:68a02bbe020dc22ee0540e040117535f06df9358106d3775e8817d826047f3fd \
+ --hash=sha256:6ed2662a3d9c832afa36405f8748c250be94ae5dfc5283d668308391f2102861 \
+ --hash=sha256:7286aed4ea271df9eab8d7a9b29e507094b51397812f7ce051ecd77915a6e26b \
+ --hash=sha256:7cc7d685b8eeca7ae69dc6416833fbfea61660684b7089bca666067cb2937dcf \
+ --hash=sha256:8708b98c278012ad267ee8a7433baeb809948855e81922878118464b274c909d \
+ --hash=sha256:9398f244e28e0596e2ee6024f808b06060109e33ed38dcc9bded452fd9bbb853 \
+ --hash=sha256:9e36344e48af3e3bde867a1ca54f97c308735dd8697005c2d24a86054a114a71 \
+ --hash=sha256:a398bdadb055f8de69f62b0fc70625f7cbdab436bbb31eef5816e28cab083ee8 \
+ --hash=sha256:acb47f6f8680de24c1ab65ebde39dd035768e2a9b571a07c7b8da95f6c8815fd \
+ --hash=sha256:be24fcb80493b2c94eae21df70017351851652a37de514de553435b256b2f249 \
+ --hash=sha256:c391cd5af88aacaf41dd7cfb96eeedfad297b5899a39e12f4c2c3706d0a3329d \
+ --hash=sha256:c95b0724a6deea2c8c5d3222191783ced0a2f09bd6d33f93e563f6f1a4b3b3a4 \
+ --hash=sha256:c9b1ce7a45978b821a06d375b83763b27a3a5e8a2e4570b3065abad240a18760 \
+ --hash=sha256:db372213d39fa33af667c2aa586a0c1235e88e9c850f5dd5c8e1f17515861868 \
+ --hash=sha256:db55cbaea02a20b49fefbd8e9d62bd481aaabe1f2301dabc575acc6b358874fa \
+ --hash=sha256:ed1a13a27f59d1fc1920394a7f596792e9d546c9ca5a044419dca70c37815d7c \
+ --hash=sha256:f2b82f46917d8722e6b5eafeefb4fb585d23babd15d8246c664cd88a5bddd19c \
+ --hash=sha256:f2f806990160d1ce42d287aa419df3ffc42dfefe60d473695fb048355fe0c6a0 \
+ --hash=sha256:f720fa82a11c0f9042376fd509b5ed88dab7e3cd602eee63a1af08883b37342b
# via -r requirements-fonttools.in
gcovr==5.0 \
--hash=sha256:1d80264cbaadff356b3dda71b8c62b3aa803e5b3eb6d526a24932cd6660a2576 \
@@ -179,9 +179,9 @@
--hash=sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc \
--hash=sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2
# via jinja2
-meson==1.2.0 \
- --hash=sha256:10c0364edc67a1b3146f405800b300f0535f42b8736e79c744a8029a855b7c6b \
- --hash=sha256:1c0b634fe6b6a7072e398647f1bf392048577068a5c92ae44d04085dab0ded6f
+meson==1.2.1 \
+ --hash=sha256:08f83fc17513e99cd6e82c7554c1f58af70425211887f8f9c7363b2a90209462 \
+ --hash=sha256:b1db3a153087549497ee52b1c938d2134e0338214fe14f7efd16fecd57b639f5
# via -r requirements.in
ninja==1.11.1 \
--hash=sha256:1c474326e11fba3f8c2582715d79216292e327d3335367c0e87e9647a002cc4a \
diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml
index 950e4ed..05ec95f 100644
--- a/.github/workflows/linux-ci.yml
+++ b/.github/workflows/linux-ci.yml
@@ -18,7 +18,7 @@
- name: Checkout
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Setup Ccache
- uses: hendrikmuhs/ccache-action@ca3acd2731eef11f1572ccb126356c2f9298d35e # v1.2.9
+ uses: hendrikmuhs/ccache-action@6d1841ec156c39a52b1b23a810da917ab98da1f4 # v1.2.10
with:
key: ${{ github.job }}-${{ runner.os }}-${{ runner.arch }}
- name: Install Dependencies
diff --git a/.github/workflows/macos-ci.yml b/.github/workflows/macos-ci.yml
index abf2864..c57a5f3 100644
--- a/.github/workflows/macos-ci.yml
+++ b/.github/workflows/macos-ci.yml
@@ -17,7 +17,7 @@
- name: Checkout
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Setup Ccache
- uses: hendrikmuhs/ccache-action@ca3acd2731eef11f1572ccb126356c2f9298d35e # v1.2.9
+ uses: hendrikmuhs/ccache-action@6d1841ec156c39a52b1b23a810da917ab98da1f4 # v1.2.10
with:
key: ${{ github.job }}-${{ runner.os }}-${{ runner.arch }}
- name: Install Dependencies
diff --git a/.github/workflows/msvc-ci.yml b/.github/workflows/msvc-ci.yml
index 7ef0679..518b0ae 100644
--- a/.github/workflows/msvc-ci.yml
+++ b/.github/workflows/msvc-ci.yml
@@ -30,7 +30,7 @@
- name: Checkout
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Setup Ccache
- uses: hendrikmuhs/ccache-action@ca3acd2731eef11f1572ccb126356c2f9298d35e # v1.2.9
+ uses: hendrikmuhs/ccache-action@6d1841ec156c39a52b1b23a810da917ab98da1f4 # v1.2.10
with:
variant: sccache
key: ${{ github.job }}-${{ matrix.os }}-${{ matrix.ARCH }}
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
index 3432dbe..3f25667 100644
--- a/.github/workflows/scorecard.yml
+++ b/.github/workflows/scorecard.yml
@@ -59,6 +59,6 @@
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
- uses: github/codeql-action/upload-sarif@0ba4244466797eb048eb91a6cd43d5c03ca8bd05 # v2.21.2
+ uses: github/codeql-action/upload-sarif@a09933a12a80f87b87005513f0abb1494c27a716 # v2.21.4
with:
sarif_file: results.sarif
diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt
index 46d0a16..a9307f2 100644
--- a/docs/harfbuzz-sections.txt
+++ b/docs/harfbuzz-sections.txt
@@ -244,6 +244,8 @@
hb_paint_funcs_set_push_transform_func
hb_paint_pop_transform_func_t
hb_paint_funcs_set_pop_transform_func
+hb_paint_color_glyph_func_t
+hb_paint_funcs_set_color_glyph_func
hb_paint_push_clip_glyph_func_t
hb_paint_funcs_set_push_clip_glyph_func
hb_paint_push_clip_rectangle_func_t
@@ -280,6 +282,7 @@
hb_paint_push_transform
hb_paint_pop_transform
+hb_paint_color_glyph
hb_paint_push_clip_glyph
hb_paint_push_clip_rectangle
hb_paint_pop_clip
diff --git a/perf/benchmark-font.cc b/perf/benchmark-font.cc
index 244e06a..67e0517 100644
--- a/perf/benchmark-font.cc
+++ b/perf/benchmark-font.cc
@@ -42,6 +42,7 @@
glyph_h_advances,
glyph_extents,
draw_glyph,
+ paint_glyph,
load_face_and_shape,
};
@@ -192,6 +193,17 @@
hb_draw_funcs_destroy (draw_funcs);
break;
}
+ case paint_glyph:
+ {
+ hb_paint_funcs_t *paint_funcs = hb_paint_funcs_create ();
+ for (auto _ : state)
+ {
+ for (unsigned gid = 0; gid < num_glyphs; ++gid)
+ hb_font_paint_glyph (font, gid, paint_funcs, nullptr, 0, 0);
+ }
+ hb_paint_funcs_destroy (paint_funcs);
+ break;
+ }
case load_face_and_shape:
{
for (auto _ : state)
@@ -294,6 +306,7 @@
TEST_OPERATION (glyph_h_advances, benchmark::kMicrosecond);
TEST_OPERATION (glyph_extents, benchmark::kMicrosecond);
TEST_OPERATION (draw_glyph, benchmark::kMicrosecond);
+ TEST_OPERATION (paint_glyph, benchmark::kMillisecond);
TEST_OPERATION (load_face_and_shape, benchmark::kMicrosecond);
#undef TEST_OPERATION
diff --git a/src/OT/Color/COLR/COLR.hh b/src/OT/Color/COLR/COLR.hh
index 76f4c08..012c381 100644
--- a/src/OT/Color/COLR/COLR.hh
+++ b/src/OT/Color/COLR/COLR.hh
@@ -53,6 +53,7 @@
struct hb_paint_context_t :
hb_dispatch_context_t<hb_paint_context_t>
{
+ const char *get_name () { return "PAINT"; }
template <typename T>
return_t dispatch (const T &obj) { obj.paint_glyph (this); return hb_empty_t (); }
static return_t default_return_value () { return hb_empty_t (); }
@@ -68,6 +69,8 @@
unsigned int palette_index;
hb_color_t foreground;
VarStoreInstancer &instancer;
+ hb_map_t current_glyphs;
+ hb_map_t current_layers;
int depth_left = HB_MAX_NESTING_LEVEL;
int edge_count = HB_COLRV1_MAX_EDGE_COUNT;
@@ -261,6 +264,7 @@
void paint_glyph (hb_paint_context_t *c) const
{
+ TRACE_PAINT (this);
value.paint_glyph (c, varIdxBase);
}
@@ -315,6 +319,7 @@
void paint_glyph (hb_paint_context_t *c) const
{
+ TRACE_PAINT (this);
value.paint_glyph (c, varIdxBase);
}
@@ -558,6 +563,7 @@
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
+ TRACE_PAINT (this);
c->funcs->push_transform (c->data,
xx.to_float (c->instancer (varIdxBase, 0)),
yx.to_float (c->instancer (varIdxBase, 1)),
@@ -639,6 +645,7 @@
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
+ TRACE_PAINT (this);
hb_bool_t is_foreground;
hb_color_t color;
@@ -693,6 +700,7 @@
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
+ TRACE_PAINT (this);
hb_color_line_t cl = {
(void *) &(this+colorLine),
(this+colorLine).static_get_color_stops, c,
@@ -759,6 +767,7 @@
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
+ TRACE_PAINT (this);
hb_color_line_t cl = {
(void *) &(this+colorLine),
(this+colorLine).static_get_color_stops, c,
@@ -823,6 +832,7 @@
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
+ TRACE_PAINT (this);
hb_color_line_t cl = {
(void *) &(this+colorLine),
(this+colorLine).static_get_color_stops, c,
@@ -874,6 +884,7 @@
void paint_glyph (hb_paint_context_t *c) const
{
+ TRACE_PAINT (this);
c->funcs->push_inverse_root_transform (c->data, c->font);
c->funcs->push_clip_glyph (c->data, gid, c->font);
c->funcs->push_root_transform (c->data, c->font);
@@ -946,6 +957,7 @@
void paint_glyph (hb_paint_context_t *c) const
{
+ TRACE_PAINT (this);
(this+transform).paint_glyph (c);
c->recurse (this+src);
c->funcs->pop_transform (c->data);
@@ -990,6 +1002,7 @@
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
+ TRACE_PAINT (this);
float ddx = dx + c->instancer (varIdxBase, 0);
float ddy = dy + c->instancer (varIdxBase, 1);
@@ -1038,6 +1051,7 @@
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
+ TRACE_PAINT (this);
float sx = scaleX.to_float (c->instancer (varIdxBase, 0));
float sy = scaleY.to_float (c->instancer (varIdxBase, 1));
@@ -1088,6 +1102,7 @@
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
+ TRACE_PAINT (this);
float sx = scaleX.to_float (c->instancer (varIdxBase, 0));
float sy = scaleY.to_float (c->instancer (varIdxBase, 1));
float tCenterX = centerX + c->instancer (varIdxBase, 2);
@@ -1141,6 +1156,7 @@
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
+ TRACE_PAINT (this);
float s = scale.to_float (c->instancer (varIdxBase, 0));
bool p1 = c->funcs->push_scale (c->data, s, s);
@@ -1188,6 +1204,7 @@
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
+ TRACE_PAINT (this);
float s = scale.to_float (c->instancer (varIdxBase, 0));
float tCenterX = centerX + c->instancer (varIdxBase, 1);
float tCenterY = centerY + c->instancer (varIdxBase, 2);
@@ -1239,6 +1256,7 @@
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
+ TRACE_PAINT (this);
float a = angle.to_float (c->instancer (varIdxBase, 0));
bool p1 = c->funcs->push_rotate (c->data, a);
@@ -1286,6 +1304,7 @@
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
+ TRACE_PAINT (this);
float a = angle.to_float (c->instancer (varIdxBase, 0));
float tCenterX = centerX + c->instancer (varIdxBase, 1);
float tCenterY = centerY + c->instancer (varIdxBase, 2);
@@ -1340,6 +1359,7 @@
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
+ TRACE_PAINT (this);
float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0));
float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1));
@@ -1390,6 +1410,7 @@
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
+ TRACE_PAINT (this);
float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0));
float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1));
float tCenterX = centerX + c->instancer (varIdxBase, 2);
@@ -1442,6 +1463,7 @@
void paint_glyph (hb_paint_context_t *c) const
{
+ TRACE_PAINT (this);
c->recurse (this+backdrop);
c->funcs->push_group (c->data);
c->recurse (this+src);
@@ -2287,6 +2309,7 @@
&(this+varIdxMap),
hb_array (font->coords, font->num_coords));
hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer);
+ c.current_glyphs.add (glyph);
if (version == 1)
{
@@ -2402,18 +2425,42 @@
void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const
{
+ TRACE_PAINT (this);
const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
{
+ if (unlikely (c->current_layers.has (i)))
+ continue;
+
+ c->current_layers.add (i);
+
const Paint &paint = paint_offset_lists.get_paint (i);
c->funcs->push_group (c->data);
c->recurse (paint);
c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER);
+
+ c->current_layers.del (i);
}
}
void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const
{
+ TRACE_PAINT (this);
+
+ if (unlikely (c->current_glyphs.has (gid)))
+ return;
+
+ c->current_glyphs.add (gid);
+
+ c->funcs->push_inverse_root_transform (c->data, c->font);
+ if (c->funcs->color_glyph (c->data, gid, c->font))
+ {
+ c->funcs->pop_transform (c->data);
+ c->current_glyphs.del (gid);
+ return;
+ }
+ c->funcs->pop_transform (c->data);
+
const COLR *colr_table = c->get_colr_table ();
const Paint *paint = colr_table->get_base_glyph_paint (gid);
@@ -2432,6 +2479,8 @@
if (has_clip_box)
c->funcs->pop_clip (c->data);
+
+ c->current_glyphs.del (gid);
}
} /* namespace OT */
diff --git a/src/OT/glyf/Glyph.hh b/src/OT/glyf/Glyph.hh
index 2b2184f..5ea6119 100644
--- a/src/OT/glyf/Glyph.hh
+++ b/src/OT/glyf/Glyph.hh
@@ -350,6 +350,7 @@
bool use_my_metrics = true,
bool phantom_only = false,
hb_array_t<int> coords = hb_array_t<int> (),
+ hb_map_t *current_glyphs = nullptr,
unsigned int depth = 0,
unsigned *edge_count = nullptr) const
{
@@ -359,6 +360,10 @@
if (unlikely (*edge_count > HB_GLYF_MAX_EDGE_COUNT)) return false;
(*edge_count)++;
+ hb_map_t current_glyphs_stack;
+ if (current_glyphs == nullptr)
+ current_glyphs = ¤t_glyphs_stack;
+
if (head_maxp_info)
{
head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth);
@@ -453,10 +458,17 @@
unsigned int comp_index = 0;
for (auto &item : get_composite_iterator ())
{
+ hb_codepoint_t item_gid = item.get_gid ();
+
+ if (unlikely (current_glyphs->has (item_gid)))
+ continue;
+
+ current_glyphs->add (item_gid);
+
unsigned old_count = all_points.length;
if (unlikely ((!phantom_only || (use_my_metrics && item.is_use_my_metrics ())) &&
- !glyf_accelerator.glyph_for_gid (item.get_gid ())
+ !glyf_accelerator.glyph_for_gid (item_gid)
.get_points (font,
glyf_accelerator,
all_points,
@@ -467,9 +479,13 @@
use_my_metrics,
phantom_only,
coords,
+ current_glyphs,
depth + 1,
edge_count)))
+ {
+ current_glyphs->del (item_gid);
return false;
+ }
auto comp_points = all_points.as_array ().sub_array (old_count);
@@ -505,9 +521,13 @@
all_points.resize (all_points.length - PHANTOM_COUNT);
if (all_points.length > HB_GLYF_MAX_POINTS)
+ {
+ current_glyphs->del (item_gid);
return false;
+ }
comp_index++;
+ current_glyphs->del (item_gid);
}
if (head_maxp_info && depth == 0)
@@ -525,6 +545,13 @@
hb_array_t<contour_point_t> points_left = points.as_array ();
for (auto &item : get_var_composite_iterator ())
{
+ hb_codepoint_t item_gid = item.get_gid ();
+
+ if (unlikely (current_glyphs->has (item_gid)))
+ continue;
+
+ current_glyphs->add (item_gid);
+
unsigned item_num_points = item.get_num_points ();
hb_array_t<contour_point_t> record_points = points_left.sub_array (0, item_num_points);
assert (record_points.length == item_num_points);
@@ -542,7 +569,7 @@
unsigned old_count = all_points.length;
if (unlikely ((!phantom_only || (use_my_metrics && item.is_use_my_metrics ())) &&
- !glyf_accelerator.glyph_for_gid (item.get_gid ())
+ !glyf_accelerator.glyph_for_gid (item_gid)
.get_points (font,
glyf_accelerator,
all_points,
@@ -553,9 +580,13 @@
use_my_metrics,
phantom_only,
coord_setter.get_coords (),
+ current_glyphs,
depth + 1,
edge_count)))
+ {
+ current_glyphs->del (item_gid);
return false;
+ }
auto comp_points = all_points.as_array ().sub_array (old_count);
@@ -571,9 +602,14 @@
all_points.resize (all_points.length - PHANTOM_COUNT);
if (all_points.length > HB_GLYF_MAX_POINTS)
+ {
+ current_glyphs->del (item_gid);
return false;
+ }
points_left += item_num_points;
+
+ current_glyphs->del (item_gid);
}
all_points.extend (phantoms);
} break;
diff --git a/src/graph/graph.hh b/src/graph/graph.hh
index 0680958..f81bed8 100644
--- a/src/graph/graph.hh
+++ b/src/graph/graph.hh
@@ -290,7 +290,7 @@
new_parents.set (id_map[_.first], _.second);
}
- if (new_parents.in_error ())
+ if (parents.in_error() || new_parents.in_error ())
return false;
parents = std::move (new_parents);
@@ -310,8 +310,15 @@
if (parents.has (old_index, &pv))
{
unsigned v = *pv;
- parents.set (new_index, v);
+ if (!parents.set (new_index, v))
+ incoming_edges_ -= v;
parents.del (old_index);
+
+ if (incoming_edges_ == 1)
+ {
+ single_parent = *parents.keys ();
+ parents.reset ();
+ }
}
}
diff --git a/src/hb-cairo.cc b/src/hb-cairo.cc
index 68c7bc0..f4f9f54 100644
--- a/src/hb-cairo.cc
+++ b/src/hb-cairo.cc
@@ -166,6 +166,32 @@
cairo_restore (cr);
}
+static hb_bool_t
+hb_cairo_paint_color_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED,
+ void *paint_data,
+ hb_codepoint_t glyph,
+ hb_font_t *font,
+ void *user_data HB_UNUSED)
+{
+ hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
+ cairo_t *cr = c->cr;
+
+ cairo_save (cr);
+
+ hb_position_t x_scale, y_scale;
+ hb_font_get_scale (font, &x_scale, &y_scale);
+ cairo_scale (cr, x_scale, y_scale);
+
+ cairo_glyph_t cairo_glyph = { glyph, 0, 0 };
+ cairo_set_scaled_font (cr, c->scaled_font);
+ cairo_set_font_size (cr, 1);
+ cairo_show_glyphs (cr, &cairo_glyph, 1);
+
+ cairo_restore (cr);
+
+ return true;
+}
+
static void
hb_cairo_push_clip_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED,
void *paint_data,
@@ -397,6 +423,7 @@
hb_paint_funcs_set_push_transform_func (funcs, hb_cairo_push_transform, nullptr, nullptr);
hb_paint_funcs_set_pop_transform_func (funcs, hb_cairo_pop_transform, nullptr, nullptr);
+ hb_paint_funcs_set_color_glyph_func (funcs, hb_cairo_paint_color_glyph, nullptr, nullptr);
hb_paint_funcs_set_push_clip_glyph_func (funcs, hb_cairo_push_clip_glyph, nullptr, nullptr);
hb_paint_funcs_set_push_clip_rectangle_func (funcs, hb_cairo_push_clip_rectangle, nullptr, nullptr);
hb_paint_funcs_set_pop_clip_func (funcs, hb_cairo_pop_clip, nullptr, nullptr);
diff --git a/src/hb-common.cc b/src/hb-common.cc
index 282a8e4..bd4cd88 100644
--- a/src/hb-common.cc
+++ b/src/hb-common.cc
@@ -815,7 +815,7 @@
}
const char *p = *pp;
- while (*pp < end && (ISALNUM(**pp) || **pp == '_'))
+ while (*pp < end && (**pp != ' ' && **pp != '=' && **pp != '['))
(*pp)++;
if (p == *pp || *pp - p > 4)
diff --git a/src/hb-debug.hh b/src/hb-debug.hh
index 6055fce..559db40 100644
--- a/src/hb-debug.hh
+++ b/src/hb-debug.hh
@@ -265,8 +265,9 @@
}
}
template <>
-/*static*/ inline void _hb_warn_no_return<hb_empty_t> (bool returned HB_UNUSED)
-{}
+/*static*/ inline void _hb_warn_no_return<hb_empty_t> (bool returned HB_UNUSED) {}
+template <>
+/*static*/ inline void _hb_warn_no_return<void> (bool returned HB_UNUSED) {}
template <int max_level, typename ret_t>
struct hb_auto_trace_t
@@ -450,12 +451,26 @@
#define HB_DEBUG_SUBSET_REPACK (HB_DEBUG+0)
#endif
+#ifndef HB_DEBUG_PAINT
+#define HB_DEBUG_PAINT (HB_DEBUG+0)
+#endif
+#if HB_DEBUG_PAINT
+#define TRACE_PAINT(this) \
+ HB_UNUSED hb_auto_trace_t<HB_DEBUG_PAINT, void> trace \
+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+ " ")
+#else
+#define TRACE_PAINT(this) HB_UNUSED hb_no_trace_t<void> trace
+#endif
+
+
#ifndef HB_DEBUG_DISPATCH
#define HB_DEBUG_DISPATCH ( \
HB_DEBUG_APPLY + \
HB_DEBUG_SANITIZE + \
HB_DEBUG_SERIALIZE + \
HB_DEBUG_SUBSET + \
+ HB_DEBUG_PAINT + \
0)
#endif
#if HB_DEBUG_DISPATCH
diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh
index fa5712f..1afbbbb 100644
--- a/src/hb-ft-colr.hh
+++ b/src/hb-ft-colr.hh
@@ -105,6 +105,8 @@
FT_Color *palette;
unsigned palette_index;
hb_color_t foreground;
+ hb_map_t current_glyphs;
+ hb_map_t current_layers;
int depth_left = HB_MAX_NESTING_LEVEL;
int edge_count = HB_COLRV1_MAX_EDGE_COUNT;
};
@@ -220,9 +222,18 @@
&paint.u.colr_layers.layer_iterator,
&other_paint))
{
+ unsigned i = paint.u.colr_layers.layer_iterator.layer;
+
+ if (unlikely (c->current_layers.has (i)))
+ continue;
+
+ c->current_layers.add (i);
+
c->funcs->push_group (c->data);
c->recurse (other_paint);
c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER);
+
+ c->current_layers.del (i);
}
}
break;
@@ -320,8 +331,27 @@
break;
case FT_COLR_PAINTFORMAT_COLR_GLYPH:
{
+ hb_codepoint_t gid = paint.u.colr_glyph.glyphID;
+
+ if (unlikely (c->current_glyphs.has (gid)))
+ return;
+
+ c->current_glyphs.add (gid);
+
+ c->funcs->push_inverse_root_transform (c->data, c->font);
+ c->ft_font->lock.unlock ();
+ if (c->funcs->color_glyph (c->data, gid, c->font))
+ {
+ c->ft_font->lock.lock ();
+ c->funcs->pop_transform (c->data);
+ c->current_glyphs.del (gid);
+ return;
+ }
+ c->ft_font->lock.lock ();
+ c->funcs->pop_transform (c->data);
+
FT_OpaquePaint other_paint = {0};
- if (FT_Get_Color_Glyph_Paint (ft_face, paint.u.colr_glyph.glyphID,
+ if (FT_Get_Color_Glyph_Paint (ft_face, gid,
FT_COLOR_NO_ROOT_TRANSFORM,
&other_paint))
{
@@ -350,6 +380,8 @@
if (has_clip_box)
c->funcs->pop_clip (c->data);
+
+ c->current_glyphs.del (gid);
}
}
break;
@@ -474,6 +506,7 @@
hb_ft_paint_context_t c (ft_font, font,
paint_funcs, paint_data,
palette, palette_index, foreground);
+ c.current_glyphs.add (gid);
bool is_bounded = true;
FT_ClipBox clip_box;
@@ -497,6 +530,7 @@
hb_ft_paint_context_t ce (ft_font, font,
extents_funcs, &extents_data,
palette, palette_index, foreground);
+ ce.current_glyphs.add (gid);
ce.funcs->push_root_transform (ce.data, font);
ce.recurse (paint);
ce.funcs->pop_transform (ce.data);
diff --git a/src/hb-limits.hh b/src/hb-limits.hh
index c503b30..25c1e71 100644
--- a/src/hb-limits.hh
+++ b/src/hb-limits.hh
@@ -106,7 +106,7 @@
#endif
#ifndef HB_COLRV1_MAX_EDGE_COUNT
-#define HB_COLRV1_MAX_EDGE_COUNT 1024
+#define HB_COLRV1_MAX_EDGE_COUNT 65536
#endif
diff --git a/src/hb-map.hh b/src/hb-map.hh
index 42604ef..6ea4166 100644
--- a/src/hb-map.hh
+++ b/src/hb-map.hh
@@ -276,6 +276,11 @@
uint32_t hash = hb_hash (key);
return set_with_hash (std::move (key), hash, std::forward<VV> (value), overwrite);
}
+ bool add (const K &key)
+ {
+ uint32_t hash = hb_hash (key);
+ return set_with_hash (key, hash, item_t::default_value ());
+ }
const V& get_with_hash (const K &key, uint32_t hash) const
{
diff --git a/src/hb-ot-shaper-arabic.cc b/src/hb-ot-shaper-arabic.cc
index 256f8f1..72dcc84 100644
--- a/src/hb-ot-shaper-arabic.cc
+++ b/src/hb-ot-shaper-arabic.cc
@@ -486,8 +486,10 @@
if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH)))
return;
- /* The Arabic shaper currently always processes in RTL mode, so we should
- * stretch / position the stretched pieces to the left / preceding glyphs. */
+ bool rtl = buffer->props.direction == HB_DIRECTION_RTL;
+
+ if (!rtl)
+ buffer->reverse ();
/* We do a two pass implementation:
* First pass calculates the exact number of extra glyphs we need,
@@ -577,7 +579,10 @@
++n_copies;
hb_position_t excess = (n_copies + 1) * sign * w_repeating - sign * w_remaining;
if (excess > 0)
+ {
extra_repeat_overlap = excess / (n_copies * n_repeating);
+ w_remaining = 0;
+ }
}
if (step == MEASURE)
@@ -588,7 +593,7 @@
else
{
buffer->unsafe_to_break (context, end);
- hb_position_t x_offset = 0;
+ hb_position_t x_offset = w_remaining / 2;
for (unsigned int k = end; k > start; k--)
{
hb_position_t width = font->get_glyph_h_advance (info[k - 1].codepoint);
@@ -599,16 +604,27 @@
DEBUG_MSG (ARABIC, nullptr, "appending %u copies of glyph %u; j=%u",
repeat, info[k - 1].codepoint, j);
+ pos[k - 1].x_advance = 0;
for (unsigned int n = 0; n < repeat; n++)
{
- x_offset -= width;
- if (n > 0)
- x_offset += extra_repeat_overlap;
+ if (rtl)
+ {
+ x_offset -= width;
+ if (n > 0)
+ x_offset += extra_repeat_overlap;
+ }
pos[k - 1].x_offset = x_offset;
/* Append copy. */
--j;
info[j] = info[k - 1];
pos[j] = pos[k - 1];
+
+ if (!rtl)
+ {
+ x_offset += width;
+ if (n > 0)
+ x_offset -= extra_repeat_overlap;
+ }
}
}
}
@@ -625,6 +641,9 @@
buffer->len = new_len;
}
}
+
+ if (!rtl)
+ buffer->reverse ();
}
diff --git a/src/hb-ot-var-common.hh b/src/hb-ot-var-common.hh
index 1d8be05..d1c617e 100644
--- a/src/hb-ot-var-common.hh
+++ b/src/hb-ot-var-common.hh
@@ -230,7 +230,7 @@
/* according to the spec, if colr table has varStore but does not have
* varIdxMap, then an implicit identity mapping is used */
float operator() (uint32_t varIdx, unsigned short offset = 0) const
- { return varStore->get_delta (varIdxMap ? varIdxMap->map (VarIdx::add (varIdx, offset)) : varIdx + offset, coords); }
+ { return coords ? varStore->get_delta (varIdxMap ? varIdxMap->map (VarIdx::add (varIdx, offset)) : varIdx + offset, coords) : 0; }
const VariationStore *varStore;
const DeltaSetIndexMap *varIdxMap;
diff --git a/src/hb-paint.cc b/src/hb-paint.cc
index 28150f1..0a53845 100644
--- a/src/hb-paint.cc
+++ b/src/hb-paint.cc
@@ -54,6 +54,12 @@
hb_paint_pop_transform_nil (hb_paint_funcs_t *funcs, void *paint_data,
void *user_data) {}
+static hb_bool_t
+hb_paint_color_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data,
+ hb_codepoint_t glyph,
+ hb_font_t *font,
+ void *user_data) { return false; }
+
static void
hb_paint_push_clip_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data,
hb_codepoint_t glyph,
@@ -474,6 +480,25 @@
}
/**
+ * hb_paint_color_glyph:
+ * @funcs: paint functions
+ * @paint_data: associated data passed by the caller
+ * @glyph: the glyph ID
+ * @font: the font
+ *
+ * Perform a "color-glyph" paint operation.
+ *
+ * XSince: REPLACEME
+ */
+hb_bool_t
+hb_paint_color_glyph (hb_paint_funcs_t *funcs, void *paint_data,
+ hb_codepoint_t glyph,
+ hb_font_t *font)
+{
+ return funcs->color_glyph (paint_data, glyph, font);
+}
+
+/**
* hb_paint_push_clip_glyph:
* @funcs: paint functions
* @paint_data: associated data passed by the caller
diff --git a/src/hb-paint.h b/src/hb-paint.h
index 5433827..74f49f0 100644
--- a/src/hb-paint.h
+++ b/src/hb-paint.h
@@ -137,6 +137,26 @@
void *user_data);
/**
+ * hb_paint_color_glyph_func_t:
+ * @funcs: paint functions object
+ * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
+ * @glyph: the glyph ID
+ * @font: the font
+ * @user_data: User data pointer passed to hb_paint_funcs_set_color_glyph_func()
+ *
+ * A virtual method for the #hb_paint_funcs_t to render a color glyph by glyph index.
+ *
+ * Return value: %true if the glyph was painted, %false otherwise.
+ *
+ * XSince: REPLACEME
+ */
+typedef hb_bool_t (*hb_paint_color_glyph_func_t) (hb_paint_funcs_t *funcs,
+ void *paint_data,
+ hb_codepoint_t glyph,
+ hb_font_t *font,
+ void *user_data);
+
+/**
* hb_paint_push_clip_glyph_func_t:
* @funcs: paint functions object
* @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
@@ -724,6 +744,23 @@
hb_destroy_func_t destroy);
/**
+ * hb_paint_funcs_set_color_glyph_func:
+ * @funcs: A paint functions struct
+ * @func: (closure user_data) (destroy destroy) (scope notified): The color-glyph callback
+ * @user_data: Data to pass to @func
+ * @destroy: (nullable): Function to call when @user_data is no longer needed
+ *
+ * Sets the color-glyph callback on the paint functions struct.
+ *
+ * Since: 7.0.0
+ */
+HB_EXTERN void
+hb_paint_funcs_set_color_glyph_func (hb_paint_funcs_t *funcs,
+ hb_paint_color_glyph_func_t func,
+ void *user_data,
+ hb_destroy_func_t destroy);
+
+/**
* hb_paint_funcs_set_push_clip_glyph_func:
* @funcs: A paint functions struct
* @func: (closure user_data) (destroy destroy) (scope notified): The push-clip-glyph callback
@@ -922,6 +959,11 @@
HB_EXTERN void
hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data);
+HB_EXTERN hb_bool_t
+hb_paint_color_glyph (hb_paint_funcs_t *funcs, void *paint_data,
+ hb_codepoint_t glyph,
+ hb_font_t *font);
+
HB_EXTERN void
hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data,
hb_codepoint_t glyph,
diff --git a/src/hb-paint.hh b/src/hb-paint.hh
index d291a4b..56b790d 100644
--- a/src/hb-paint.hh
+++ b/src/hb-paint.hh
@@ -32,6 +32,7 @@
#define HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS \
HB_PAINT_FUNC_IMPLEMENT (push_transform) \
HB_PAINT_FUNC_IMPLEMENT (pop_transform) \
+ HB_PAINT_FUNC_IMPLEMENT (color_glyph) \
HB_PAINT_FUNC_IMPLEMENT (push_clip_glyph) \
HB_PAINT_FUNC_IMPLEMENT (push_clip_rectangle) \
HB_PAINT_FUNC_IMPLEMENT (pop_clip) \
@@ -77,6 +78,13 @@
void pop_transform (void *paint_data)
{ func.pop_transform (this, paint_data,
!user_data ? nullptr : user_data->pop_transform); }
+ bool color_glyph (void *paint_data,
+ hb_codepoint_t glyph,
+ hb_font_t *font)
+ { return func.color_glyph (this, paint_data,
+ glyph,
+ font,
+ !user_data ? nullptr : user_data->push_clip_glyph); }
void push_clip_glyph (void *paint_data,
hb_codepoint_t glyph,
hb_font_t *font)
diff --git a/test/api/results/bad-154 b/test/api/results/bad-154
index 2f4bdfc..5f88e03 100644
--- a/test/api/results/bad-154
+++ b/test/api/results/bad-154
@@ -1,351 +1,9 @@
-# random seed: R02S345aec86e0be01a834deb6fc61057f9c
+# random seed: R02S13f44c97ec7b03f792b3b9650a81b62a
# Start of hb tests
# Start of paint tests
# Start of ot tests
start clip rectangle 0 500 500 1e+03
start transform 1 0 0 1 0 0
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- start clip rectangle 0 500 500 1e+03
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
- push group
- start transform 1 0 -0 1 0 0
- start clip glyph 159
- start transform 1 0 0 1 0 0
- solid 128 128 128 102
- end transform
- end clip
- end transform
- pop group mode 3
- end clip
push group
start transform 1 0 -0 1 0 0
start clip glyph 159
diff --git a/test/api/results/test-154 b/test/api/results/test-154
index 8b329cf..f108da8 100644
--- a/test/api/results/test-154
+++ b/test/api/results/test-154
@@ -1,10 +1,16 @@
-# random seed: R02S9ffd1e4fb7cd9c50371f61b259bb32b5
+# random seed: R02S46170a7a8abc3ad07d2b70fd08efc176
# Start of hb tests
# Start of paint tests
# Start of ot tests
start clip rectangle 0 500 500 1e+03
start transform 1 0 0 1 0 0
+ start transform 1 0 -0 1 0 0
+ paint color glyph 164; acting as failed
+ end transform
start clip rectangle 100 100 900 900
+ start transform 1 0 -0 1 0 0
+ paint color glyph 93; acting as failed
+ end transform
start clip rectangle 0 0 1e+03 1e+03
start transform 1 0 -0 1 0 0
start clip glyph 2
diff --git a/test/api/results/testvf-154 b/test/api/results/testvf-154
index 6da136f..cd6e9b9 100644
--- a/test/api/results/testvf-154
+++ b/test/api/results/testvf-154
@@ -1,10 +1,16 @@
-# random seed: R02S2212d33e4705ca20b6475a83d116b9ab
+# random seed: R02Sd6c6e6b574cffce42448b4c7ec9ed3b1
# Start of hb tests
# Start of paint tests
# Start of ot tests
start clip rectangle 0 500 500 1e+03
start transform 1 0 0 1 0 0
+ start transform 1 0 -0 1 0 0
+ paint color glyph 164; acting as failed
+ end transform
start clip rectangle 100 100 900 900
+ start transform 1 0 -0 1 0 0
+ paint color glyph 93; acting as failed
+ end transform
start clip rectangle 0 0 1e+03 1e+03
start transform 1 0 -0 1 0 0
start clip glyph 2
diff --git a/test/api/test-paint.c b/test/api/test-paint.c
index 13b71c5..810b7ac 100644
--- a/test/api/test-paint.c
+++ b/test/api/test-paint.c
@@ -97,6 +97,20 @@
print (data, "end transform");
}
+static hb_bool_t
+paint_color_glyph (hb_paint_funcs_t *funcs,
+ void *paint_data,
+ hb_codepoint_t glyph,
+ hb_font_t *font,
+ void *user_data)
+{
+ paint_data_t *data = paint_data;
+
+ print (data, "paint color glyph %u; acting as failed", glyph);
+
+ return FALSE;
+}
+
static void
push_clip_glyph (hb_paint_funcs_t *funcs,
void *paint_data,
@@ -286,6 +300,7 @@
hb_paint_funcs_set_push_transform_func (funcs, push_transform, NULL, NULL);
hb_paint_funcs_set_pop_transform_func (funcs, pop_transform, NULL, NULL);
+ hb_paint_funcs_set_color_glyph_func (funcs, paint_color_glyph, NULL, NULL);
hb_paint_funcs_set_push_clip_glyph_func (funcs, push_clip_glyph, NULL, NULL);
hb_paint_funcs_set_push_clip_rectangle_func (funcs, push_clip_rectangle, NULL, NULL);
hb_paint_funcs_set_pop_clip_func (funcs, pop_clip, NULL, NULL);
@@ -389,7 +404,7 @@
/* Run
*
- * GENERATE_DATA=1 G_TEST_SRCDIR=./test/api ./build/test/api/test-ot-color -p TESTCASE > test/api/results/OUTPUT
+ * GENERATE_DATA=1 G_TEST_SRCDIR=./test/api ./build/test/api/test-paint -p TESTCASE > test/api/results/OUTPUT
*
* to produce the expected results file.
*/
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-repacker-fuzzer-6697168080338944 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-repacker-fuzzer-6697168080338944
new file mode 100644
index 0000000..1859841
--- /dev/null
+++ b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-repacker-fuzzer-6697168080338944
Binary files differ
diff --git a/test/shape/data/in-house/fonts/507637795ce4f2975593da54d12b46f76c7cc4cc.ttf b/test/shape/data/in-house/fonts/507637795ce4f2975593da54d12b46f76c7cc4cc.ttf
new file mode 100644
index 0000000..e25dcca
--- /dev/null
+++ b/test/shape/data/in-house/fonts/507637795ce4f2975593da54d12b46f76c7cc4cc.ttf
Binary files differ
diff --git a/test/shape/data/in-house/tests/arabic-stch.tests b/test/shape/data/in-house/tests/arabic-stch.tests
index 491b242..890d8bf 100644
--- a/test/shape/data/in-house/tests/arabic-stch.tests
+++ b/test/shape/data/in-house/tests/arabic-stch.tests
@@ -1 +1,3 @@
../fonts/d9b8bc10985f24796826c29f7ccba3d0ae11ec02.ttf;--no-glyph-names;U+0718,U+070F,U+0718,U+0718,U+002E;[1=4+168|3=3+502|3=2+502|4=1@-1004,0+0|5=1@-876,0+0|5=1@-799,0+0|5=1@-722,0+0|5=1@-645,0+0|4=1@-566,0+0|5=1@-438,0+0|5=1@-361,0+0|5=1@-284,0+0|5=1@-207,0+0|4=1@-128,0+0|3=0+502]
+../fonts/507637795ce4f2975593da54d12b46f76c7cc4cc.ttf;--direction=l;U+0891,U+0661,U+0662,U+0663,U+0664,U+066B;[piastre-ar.head=0+0|piastre-ar.repeat=0@644,0+0|piastre-ar.repeat=0@778,0+0|piastre-ar.repeat=0@897,0+0|piastre-ar.repeat=0@1016,0+0|piastre-ar.repeat=0@1135,0+0|piastre-ar.repeat=0@1254,0+0|piastre-ar.repeat=0@1373,0+0|piastre-ar.repeat=0@1492,0+0|piastre-ar.tail=0@1611,0+0|one-ar=1+449|two-ar=2+449|three-ar=3+449|four-ar=4+449|decimalseparator-ar=5+222]
+../fonts/507637795ce4f2975593da54d12b46f76c7cc4cc.ttf;--direction=l;U+0661,U+0662,U+0663,U+0891,U+0664,U+066B;[one-ar=0+449|two-ar=1+449|three-ar=2+449|piastre-ar.head=3@-192,0+0|piastre-ar.repeat=3@452,0+0|piastre-ar.tail=3@586,0+0|four-ar=4+449|decimalseparator-ar=5+222]
diff --git a/util/view-cairo.hh b/util/view-cairo.hh
index d737b85..c96003c 100644
--- a/util/view-cairo.hh
+++ b/util/view-cairo.hh
@@ -202,6 +202,8 @@
cairo_restore (cr);
}
+ // https://github.com/harfbuzz/harfbuzz/issues/4378
+#if CAIRO_VERSION >= 11705
if (l.num_clusters)
cairo_show_text_glyphs (cr,
l.utf8, l.utf8_len,
@@ -209,6 +211,7 @@
l.clusters, l.num_clusters,
l.cluster_flags);
else
+#endif
cairo_show_glyphs (cr, l.glyphs, l.num_glyphs);
}