0

Roll Skrifa, Read-fonts to address autohinting hang

Addresses urgent issue in Skrifa GSUB processing during autohinting.
Requires read-fonts update for reasons of internal dependency due to
previous changes in read-fonts.

Updated crates:

* read-fonts: 0.27.1 => 0.27.2
* skrifa: 0.28.0 => 0.28.1

Vetted for:
* read-fonts@0.27.2, skrifa@0.28.1: does-not-implement-crypto, safe-to-deploy,
  ub-risk-0

Bug: chromium:396173460
Change-Id: I478ea79e1be9d78f6376dd3d56d23b68adb1f130
Cq-Include-Trybots: chromium/try:android-rust-arm32-rel
Cq-Include-Trybots: chromium/try:android-rust-arm64-dbg
Cq-Include-Trybots: chromium/try:android-rust-arm64-rel
Cq-Include-Trybots: chromium/try:linux-rust-x64-dbg
Cq-Include-Trybots: chromium/try:linux-rust-x64-rel
Cq-Include-Trybots: chromium/try:win-rust-x64-dbg
Cq-Include-Trybots: chromium/try:win-rust-x64-rel
Disable-Rts: True
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6298807
Commit-Queue: Dominik Röttsches <drott@chromium.org>
Reviewed-by: Łukasz Anforowicz <lukasza@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1424063}
This commit is contained in:
Dominik Röttsches
2025-02-24 11:56:12 -08:00
committed by Chromium LUCI CQ
parent 35bc5ec5a2
commit 12a1d01b8e
255 changed files with 1408 additions and 1343 deletions
infra
third_party/rust
chromium_crates_io
Cargo.lockCargo.toml
supply-chain
vendor
read-fonts-0.27.1
read-fonts-0.27.2
.cargo-checksum.json.cargo_vcs_info.jsonCargo.tomlCargo.toml.origLICENSE-APACHELICENSE-MITREADME.md
benches
generated
src
skrifa-0.28.0
skrifa-0.28.1
read_fonts
skrifa

@ -46,7 +46,6 @@ chrome/browser/autofill/android/junit/src/org/chromium/chrome/browser/autofill/e
chrome/browser/chromeos/extensions/telemetry 2 1
chrome/browser/download 1 1
chrome/browser/extensions 2 1
chrome/browser/extensions/api/identity 1 1
chrome/browser/extensions/commands 3 1
chrome/browser/feed/android 1 1
chrome/browser/first_run 1 1
@ -458,7 +457,6 @@ third_party/blink/web_tests/external/wpt/resource-timing 1 1
third_party/blink/web_tests/external/wpt/sanitizer-api/support 3 1
third_party/blink/web_tests/external/wpt/wai-aria/scripts 1 1
third_party/blink/web_tests/external/wpt/webaudio/js 1 1
third_party/blink/web_tests/external/wpt/webcodecs 1 1
third_party/blink/web_tests/external/wpt/webrtc 1 1
third_party/blink/web_tests/external/wpt/webrtc/third_party/sdp 2 1
third_party/blink/web_tests/external/wpt/websockets/stream/tentative 1 1
@ -700,7 +698,7 @@ third_party/rust/chromium_crates_io/vendor/rand_chacha-0.3.1 4 1
third_party/rust/chromium_crates_io/vendor/rand_core-0.6.4 4 1
third_party/rust/chromium_crates_io/vendor/rand_core-0.6.4/src 3 1
third_party/rust/chromium_crates_io/vendor/rand_pcg-0.3.1 4 1
third_party/rust/chromium_crates_io/vendor/read-fonts-0.27.1/src/tables 3 2
third_party/rust/chromium_crates_io/vendor/read-fonts-0.27.2/src/tables 3 2
third_party/rust/chromium_crates_io/vendor/regex-1.11.1 1 1
third_party/rust/chromium_crates_io/vendor/regex-1.11.1/src 1 1
third_party/rust/chromium_crates_io/vendor/regex-1.11.1/tests 7 6
@ -750,7 +748,7 @@ third_party/rust/chromium_crates_io/vendor/windows-sys-0.52.0/src/Windows/Wdk/Sy
third_party/rust/chromium_crates_io/vendor/windows-sys-0.52.0/src/Windows/Win32/Networking/Clustering 2 1
third_party/rust/chromium_crates_io/vendor/write16-1.0.0 1 1
third_party/rust/chromium_crates_io/vendor/zerocopy-0.7.35 1 1
third_party/screen-ai 3 1
third_party/screen-ai 2 1
third_party/sentencepiece/src 2 2
third_party/sentencepiece/src/doc 3 1
third_party/sentencepiece/src/src 1 1

@ -1061,7 +1061,7 @@ dependencies = [
[[package]]
name = "read-fonts"
version = "0.27.1"
version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytemuck",
@ -1241,7 +1241,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "skrifa"
version = "0.28.0"
version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytemuck",

@ -37,13 +37,13 @@ qr_code = "2"
quote = "1"
rand = "0.8"
rand_pcg = "0.3"
read-fonts = "0.27"
read-fonts = "0.27.2"
regex = "1"
rustc-demangle-capi = "0.1"
serde = "1"
serde_json = "1"
sfv = "0.10.4"
skrifa = "0.28"
skrifa = "0.28.1"
small_ctor = "0.1"
static_assertions = "1"
strum = "0.25.0"

@ -2479,6 +2479,12 @@ criteria = ["safe-to-deploy", "does-not-implement-crypto", "ub-risk-0"]
delta = "0.26.0 -> 0.27.1"
notes = "IFT impl behind feature flag."
[[audits.read-fonts]]
who = "Dominik Röttsches <drott@chromium.org>"
criteria = ["safe-to-deploy", "does-not-implement-crypto", "ub-risk-0"]
delta = "0.27.1 -> 0.27.2"
notes = "CFF charsets support, font_builder related changes, clippy fixes."
[[audits.regex]]
who = "danakj@chromium.org"
criteria = ["safe-to-run", "does-not-implement-crypto"]
@ -3258,6 +3264,12 @@ criteria = ["safe-to-deploy", "does-not-implement-crypto", "ub-risk-0"]
delta = "0.27.0 -> 0.28.0"
notes = "Minor clippy fix."
[[audits.skrifa]]
who = "Dominik Röttsches <drott@chromium.org>"
criteria = ["safe-to-deploy", "does-not-implement-crypto", "ub-risk-0"]
delta = "0.28.0 -> 0.28.1"
notes = "Fix for gsub hang, limits to cmap 12 iterator."
[[audits.small_ctor]]
who = "danakj@chromium.org"
criteria = ["safe-to-run", "does-not-implement-crypto"]

@ -368,7 +368,7 @@ criteria = ["crypto-safe", "safe-to-run"]
[policy."rand_pcg:0.3.1"]
criteria = ["crypto-safe", "safe-to-run"]
[policy."read-fonts:0.27.1"]
[policy."read-fonts:0.27.2"]
criteria = ["crypto-safe", "safe-to-deploy", "ub-risk-2"]
[policy."regex-automata:0.4.9"]
@ -434,7 +434,7 @@ criteria = []
[policy."simd-adler32:0.3.7"]
criteria = ["crypto-safe", "safe-to-deploy", "ub-risk-2"]
[policy."skrifa:0.28.0"]
[policy."skrifa:0.28.1"]
criteria = ["crypto-safe", "safe-to-deploy", "ub-risk-2"]
[policy."small_ctor:0.1.2"]
@ -763,9 +763,10 @@ https://crbug.com/366411886
Bumped up the exemption to 1.14.0 in February 2025.
WARNING: The `malloc_size_of` feature has **not** been audited because
this feature does not explicitly document its safetly requirements.
this feature does not explicitly document its safety requirements.
See also https://chromium-review.googlesource.com/c/chromium/src/+/6275133/comment/ea0d7a93_98051a2e/
and https://github.com/servo/malloc_size_of/issues/8.
This feature is banned in gnrt_config.toml.
"""
[[exemptions.syn]]

@ -1,6 +0,0 @@
{
"git": {
"sha1": "7da01ca7044f00b92baf47f4b6d561dd365de407"
},
"path_in_vcs": "read-fonts"
}

@ -1,738 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "anes"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
[[package]]
name = "anstyle"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "bumpalo"
version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "bytemuck"
version = "1.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a"
dependencies = [
"bytemuck_derive",
]
[[package]]
name = "bytemuck_derive"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cast"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "ciborium"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e"
dependencies = [
"ciborium-io",
"ciborium-ll",
"serde",
]
[[package]]
name = "ciborium-io"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757"
[[package]]
name = "ciborium-ll"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9"
dependencies = [
"ciborium-io",
"half",
]
[[package]]
name = "clap"
version = "4.5.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
version = "4.5.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec"
dependencies = [
"anstyle",
"clap_lex",
]
[[package]]
name = "clap_lex"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7"
[[package]]
name = "core_maths"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3b02505ccb8c50b0aa21ace0fc08c3e53adebd4e58caa18a36152803c7709a3"
dependencies = [
"libm",
]
[[package]]
name = "criterion"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f"
dependencies = [
"anes",
"cast",
"ciborium",
"clap",
"criterion-plot",
"is-terminal",
"itertools",
"num-traits",
"once_cell",
"oorandom",
"plotters",
"rayon",
"regex",
"serde",
"serde_derive",
"serde_json",
"tinytemplate",
"walkdir",
]
[[package]]
name = "criterion-plot"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
dependencies = [
"cast",
"itertools",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
dependencies = [
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "either"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
[[package]]
name = "font-types"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d868ec188a98bb014c606072edd47e52e7ab7297db943b0b28503121e1d037bd"
dependencies = [
"bytemuck",
"serde",
]
[[package]]
name = "getrandom"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "half"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888"
dependencies = [
"cfg-if",
"crunchy",
]
[[package]]
name = "hermit-abi"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
[[package]]
name = "is-terminal"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b"
dependencies = [
"hermit-abi",
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2"
[[package]]
name = "js-sys"
version = "0.3.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.164"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f"
[[package]]
name = "libm"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa"
[[package]]
name = "log"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
[[package]]
name = "oorandom"
version = "11.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9"
[[package]]
name = "plotters"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747"
dependencies = [
"num-traits",
"plotters-backend",
"plotters-svg",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "plotters-backend"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a"
[[package]]
name = "plotters-svg"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670"
dependencies = [
"plotters-backend",
]
[[package]]
name = "ppv-lite86"
version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
dependencies = [
"zerocopy",
]
[[package]]
name = "proc-macro2"
version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "rayon"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
dependencies = [
"crossbeam-deque",
"crossbeam-utils",
]
[[package]]
name = "read-fonts"
version = "0.27.1"
dependencies = [
"bytemuck",
"core_maths",
"criterion",
"font-types",
"rand",
"serde",
]
[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "ryu"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "serde"
version = "1.0.215"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.215"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.133"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]
[[package]]
name = "syn"
version = "2.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tinytemplate"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
dependencies = [
"serde",
"serde_json",
]
[[package]]
name = "unicode-ident"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e"
dependencies = [
"cfg-if",
"once_cell",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d"
[[package]]
name = "web-sys"
version = "0.3.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "winapi-util"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "zerocopy"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
"byteorder",
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

@ -0,0 +1,6 @@
{
"git": {
"sha1": "d7b4a99bd0fb0c433ce4ef620fa3c1afda6b831b"
},
"path_in_vcs": "read-fonts"
}

@ -12,13 +12,7 @@
[package]
edition = "2021"
name = "read-fonts"
version = "0.27.1"
build = false
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
version = "0.27.2"
description = "Reading OpenType font files."
readme = "README.md"
categories = [
@ -36,22 +30,12 @@ features = [
"std",
]
[lib]
name = "read_fonts"
path = "src/lib.rs"
[[bench]]
name = "bench_helper"
path = "benches/bench_helper.rs"
[[bench]]
name = "int_set_benchmark"
path = "benches/int_set_benchmark.rs"
harness = false
[[bench]]
name = "sparse_bit_set_benchmark"
path = "benches/sparse_bit_set_benchmark.rs"
harness = false
[dependencies.bytemuck]

@ -1,6 +1,6 @@
[package]
name = "read-fonts"
version = "0.27.1"
version = "0.27.2"
description = "Reading OpenType font files."
readme = "README.md"
categories = ["text-processing", "parsing", "graphics"]

@ -689,3 +689,418 @@ impl<'a> SomeRecord<'a> for FdSelectRange4 {
}
}
}
/// Charset with custom glyph id to string id mappings.
#[derive(Clone)]
pub enum CustomCharset<'a> {
Format0(CharsetFormat0<'a>),
Format1(CharsetFormat1<'a>),
Format2(CharsetFormat2<'a>),
}
impl<'a> CustomCharset<'a> {
///Return the `FontData` used to resolve offsets for this table.
pub fn offset_data(&self) -> FontData<'a> {
match self {
Self::Format0(item) => item.offset_data(),
Self::Format1(item) => item.offset_data(),
Self::Format2(item) => item.offset_data(),
}
}
/// Format; =0
pub fn format(&self) -> u8 {
match self {
Self::Format0(item) => item.format(),
Self::Format1(item) => item.format(),
Self::Format2(item) => item.format(),
}
}
}
impl<'a> FontRead<'a> for CustomCharset<'a> {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
let format: u8 = data.read_at(0usize)?;
match format {
CharsetFormat0Marker::FORMAT => Ok(Self::Format0(FontRead::read(data)?)),
CharsetFormat1Marker::FORMAT => Ok(Self::Format1(FontRead::read(data)?)),
CharsetFormat2Marker::FORMAT => Ok(Self::Format2(FontRead::read(data)?)),
other => Err(ReadError::InvalidFormat(other.into())),
}
}
}
impl MinByteRange for CustomCharset<'_> {
fn min_byte_range(&self) -> Range<usize> {
match self {
Self::Format0(item) => item.min_byte_range(),
Self::Format1(item) => item.min_byte_range(),
Self::Format2(item) => item.min_byte_range(),
}
}
}
#[cfg(feature = "experimental_traverse")]
impl<'a> CustomCharset<'a> {
fn dyn_inner<'b>(&'b self) -> &'b dyn SomeTable<'a> {
match self {
Self::Format0(table) => table,
Self::Format1(table) => table,
Self::Format2(table) => table,
}
}
}
#[cfg(feature = "experimental_traverse")]
impl std::fmt::Debug for CustomCharset<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.dyn_inner().fmt(f)
}
}
#[cfg(feature = "experimental_traverse")]
impl<'a> SomeTable<'a> for CustomCharset<'a> {
fn type_name(&self) -> &str {
self.dyn_inner().type_name()
}
fn get_field(&self, idx: usize) -> Option<Field<'a>> {
self.dyn_inner().get_field(idx)
}
}
impl Format<u8> for CharsetFormat0Marker {
const FORMAT: u8 = 0;
}
/// Charset format 0.
#[derive(Debug, Clone, Copy)]
#[doc(hidden)]
pub struct CharsetFormat0Marker {
glyph_byte_len: usize,
}
impl CharsetFormat0Marker {
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
start..start + u8::RAW_BYTE_LEN
}
pub fn glyph_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
start..start + self.glyph_byte_len
}
}
impl MinByteRange for CharsetFormat0Marker {
fn min_byte_range(&self) -> Range<usize> {
0..self.glyph_byte_range().end
}
}
impl<'a> FontRead<'a> for CharsetFormat0<'a> {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
let mut cursor = data.cursor();
cursor.advance::<u8>();
let glyph_byte_len = cursor.remaining_bytes() / u16::RAW_BYTE_LEN * u16::RAW_BYTE_LEN;
cursor.advance_by(glyph_byte_len);
cursor.finish(CharsetFormat0Marker { glyph_byte_len })
}
}
/// Charset format 0.
pub type CharsetFormat0<'a> = TableRef<'a, CharsetFormat0Marker>;
#[allow(clippy::needless_lifetimes)]
impl<'a> CharsetFormat0<'a> {
/// Format; =0
pub fn format(&self) -> u8 {
let range = self.shape.format_byte_range();
self.data.read_at(range.start).unwrap()
}
/// Glyph name array.
pub fn glyph(&self) -> &'a [BigEndian<u16>] {
let range = self.shape.glyph_byte_range();
self.data.read_array(range).unwrap()
}
}
#[cfg(feature = "experimental_traverse")]
impl<'a> SomeTable<'a> for CharsetFormat0<'a> {
fn type_name(&self) -> &str {
"CharsetFormat0"
}
fn get_field(&self, idx: usize) -> Option<Field<'a>> {
match idx {
0usize => Some(Field::new("format", self.format())),
1usize => Some(Field::new("glyph", self.glyph())),
_ => None,
}
}
}
#[cfg(feature = "experimental_traverse")]
#[allow(clippy::needless_lifetimes)]
impl<'a> std::fmt::Debug for CharsetFormat0<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
(self as &dyn SomeTable<'a>).fmt(f)
}
}
impl Format<u8> for CharsetFormat1Marker {
const FORMAT: u8 = 1;
}
/// Charset format 1.
#[derive(Debug, Clone, Copy)]
#[doc(hidden)]
pub struct CharsetFormat1Marker {
ranges_byte_len: usize,
}
impl CharsetFormat1Marker {
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
start..start + u8::RAW_BYTE_LEN
}
pub fn ranges_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
start..start + self.ranges_byte_len
}
}
impl MinByteRange for CharsetFormat1Marker {
fn min_byte_range(&self) -> Range<usize> {
0..self.ranges_byte_range().end
}
}
impl<'a> FontRead<'a> for CharsetFormat1<'a> {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
let mut cursor = data.cursor();
cursor.advance::<u8>();
let ranges_byte_len =
cursor.remaining_bytes() / CharsetRange1::RAW_BYTE_LEN * CharsetRange1::RAW_BYTE_LEN;
cursor.advance_by(ranges_byte_len);
cursor.finish(CharsetFormat1Marker { ranges_byte_len })
}
}
/// Charset format 1.
pub type CharsetFormat1<'a> = TableRef<'a, CharsetFormat1Marker>;
#[allow(clippy::needless_lifetimes)]
impl<'a> CharsetFormat1<'a> {
/// Format; =1
pub fn format(&self) -> u8 {
let range = self.shape.format_byte_range();
self.data.read_at(range.start).unwrap()
}
/// Range1 array.
pub fn ranges(&self) -> &'a [CharsetRange1] {
let range = self.shape.ranges_byte_range();
self.data.read_array(range).unwrap()
}
}
#[cfg(feature = "experimental_traverse")]
impl<'a> SomeTable<'a> for CharsetFormat1<'a> {
fn type_name(&self) -> &str {
"CharsetFormat1"
}
fn get_field(&self, idx: usize) -> Option<Field<'a>> {
match idx {
0usize => Some(Field::new("format", self.format())),
1usize => Some(Field::new(
"ranges",
traversal::FieldType::array_of_records(
stringify!(CharsetRange1),
self.ranges(),
self.offset_data(),
),
)),
_ => None,
}
}
}
#[cfg(feature = "experimental_traverse")]
#[allow(clippy::needless_lifetimes)]
impl<'a> std::fmt::Debug for CharsetFormat1<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
(self as &dyn SomeTable<'a>).fmt(f)
}
}
/// Range struct for Charset format 1.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct CharsetRange1 {
/// First glyph in range.
pub first: BigEndian<u16>,
/// Glyphs left in range (excluding first).
pub n_left: u8,
}
impl CharsetRange1 {
/// First glyph in range.
pub fn first(&self) -> u16 {
self.first.get()
}
/// Glyphs left in range (excluding first).
pub fn n_left(&self) -> u8 {
self.n_left
}
}
impl FixedSize for CharsetRange1 {
const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u8::RAW_BYTE_LEN;
}
#[cfg(feature = "experimental_traverse")]
impl<'a> SomeRecord<'a> for CharsetRange1 {
fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
RecordResolver {
name: "CharsetRange1",
get_field: Box::new(move |idx, _data| match idx {
0usize => Some(Field::new("first", self.first())),
1usize => Some(Field::new("n_left", self.n_left())),
_ => None,
}),
data,
}
}
}
impl Format<u8> for CharsetFormat2Marker {
const FORMAT: u8 = 2;
}
/// Charset format 2.
#[derive(Debug, Clone, Copy)]
#[doc(hidden)]
pub struct CharsetFormat2Marker {
ranges_byte_len: usize,
}
impl CharsetFormat2Marker {
pub fn format_byte_range(&self) -> Range<usize> {
let start = 0;
start..start + u8::RAW_BYTE_LEN
}
pub fn ranges_byte_range(&self) -> Range<usize> {
let start = self.format_byte_range().end;
start..start + self.ranges_byte_len
}
}
impl MinByteRange for CharsetFormat2Marker {
fn min_byte_range(&self) -> Range<usize> {
0..self.ranges_byte_range().end
}
}
impl<'a> FontRead<'a> for CharsetFormat2<'a> {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
let mut cursor = data.cursor();
cursor.advance::<u8>();
let ranges_byte_len =
cursor.remaining_bytes() / CharsetRange2::RAW_BYTE_LEN * CharsetRange2::RAW_BYTE_LEN;
cursor.advance_by(ranges_byte_len);
cursor.finish(CharsetFormat2Marker { ranges_byte_len })
}
}
/// Charset format 2.
pub type CharsetFormat2<'a> = TableRef<'a, CharsetFormat2Marker>;
#[allow(clippy::needless_lifetimes)]
impl<'a> CharsetFormat2<'a> {
/// Format; =2
pub fn format(&self) -> u8 {
let range = self.shape.format_byte_range();
self.data.read_at(range.start).unwrap()
}
/// Range2 array.
pub fn ranges(&self) -> &'a [CharsetRange2] {
let range = self.shape.ranges_byte_range();
self.data.read_array(range).unwrap()
}
}
#[cfg(feature = "experimental_traverse")]
impl<'a> SomeTable<'a> for CharsetFormat2<'a> {
fn type_name(&self) -> &str {
"CharsetFormat2"
}
fn get_field(&self, idx: usize) -> Option<Field<'a>> {
match idx {
0usize => Some(Field::new("format", self.format())),
1usize => Some(Field::new(
"ranges",
traversal::FieldType::array_of_records(
stringify!(CharsetRange2),
self.ranges(),
self.offset_data(),
),
)),
_ => None,
}
}
}
#[cfg(feature = "experimental_traverse")]
#[allow(clippy::needless_lifetimes)]
impl<'a> std::fmt::Debug for CharsetFormat2<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
(self as &dyn SomeTable<'a>).fmt(f)
}
}
/// Range struct for Charset format 2.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct CharsetRange2 {
/// First glyph in range.
pub first: BigEndian<u16>,
/// Glyphs left in range (excluding first).
pub n_left: BigEndian<u16>,
}
impl CharsetRange2 {
/// First glyph in range.
pub fn first(&self) -> u16 {
self.first.get()
}
/// Glyphs left in range (excluding first).
pub fn n_left(&self) -> u16 {
self.n_left.get()
}
}
impl FixedSize for CharsetRange2 {
const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN;
}
#[cfg(feature = "experimental_traverse")]
impl<'a> SomeRecord<'a> for CharsetRange2 {
fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
RecordResolver {
name: "CharsetRange2",
get_field: Box::new(move |idx, _data| match idx {
0usize => Some(Field::new("first", self.first())),
1usize => Some(Field::new("n_left", self.n_left())),
_ => None,
}),
data,
}
}
}

@ -30,7 +30,7 @@ impl Lookup0<'_> {
/// Lookup segment for format 2.
#[derive(Copy, Clone, bytemuck::AnyBitPattern)]
#[repr(packed)]
#[repr(C, packed)]
pub struct LookupSegment2<T>
where
T: LookupValue,
@ -93,7 +93,7 @@ impl Lookup4<'_> {
/// Lookup single record for format 6.
#[derive(Copy, Clone, bytemuck::AnyBitPattern)]
#[repr(packed)]
#[repr(C, packed)]
pub struct LookupSingle<T>
where
T: LookupValue,
@ -661,7 +661,7 @@ mod tests {
}
#[derive(Copy, Clone, Debug, bytemuck::AnyBitPattern)]
#[repr(packed)]
#[repr(C, packed)]
struct ContextualData {
_mark_index: BigEndian<u16>,
current_index: BigEndian<u16>,

@ -2,7 +2,7 @@
include!("../../generated/generated_cff.rs");
use super::postscript::{Index1, Latin1String, StringId};
use super::postscript::{dict, Charset, Error, Index1, Latin1String, StringId};
/// The [Compact Font Format](https://learn.microsoft.com/en-us/typography/opentype/spec/cff) table.
#[derive(Clone)]
@ -79,6 +79,40 @@ impl<'a> Cff<'a> {
pub fn global_subrs(&self) -> Index1<'a> {
self.global_subrs.clone()
}
/// Returns the character set associated with the top dict at the given
/// index.
///
/// See "Charsets" at <https://adobe-type-tools.github.io/font-tech-notes/pdfs/5176.CFF.pdf#page=21>
pub fn charset(&self, top_dict_index: usize) -> Result<Option<Charset<'a>>, Error> {
let top_dict = self.top_dicts().get(top_dict_index)?;
let offset_data = self.offset_data();
let mut charset_offset: Option<usize> = None;
let mut num_glyphs: Option<u32> = None;
for entry in dict::entries(top_dict, None) {
match entry {
Ok(dict::Entry::Charset(offset)) => {
charset_offset = Some(offset);
}
Ok(dict::Entry::CharstringsOffset(offset)) => {
num_glyphs = Some(
Index1::read(
offset_data
.split_off(offset)
.ok_or(ReadError::OutOfBounds)?,
)?
.count() as u32,
);
}
_ => {}
}
}
if let Some((charset_offset, num_glyphs)) = charset_offset.zip(num_glyphs) {
Ok(Some(Charset::new(offset_data, charset_offset, num_glyphs)?))
} else {
Ok(None)
}
}
}
impl TopLevelTable for Cff<'_> {
@ -152,4 +186,33 @@ mod tests {
"Noto Serif Display"
);
}
#[test]
fn glyph_names() {
test_glyph_names(
font_test_data::NOTO_SERIF_DISPLAY_TRIMMED,
&[".notdef", "i", "j", "k", "l"],
);
}
#[test]
fn icons_glyph_names() {
test_glyph_names(font_test_data::MATERIAL_ICONS_SUBSET, &[".notdef", "_10k"]);
}
fn test_glyph_names(font_data: &[u8], expected_names: &[&str]) {
let font = FontRef::new(font_data).unwrap();
let cff = font.cff().unwrap();
let charset = cff.charset(0).unwrap().unwrap();
let sid_to_string = |sid| std::str::from_utf8(cff.string(sid).unwrap().bytes()).unwrap();
let names_by_lookup = (0..charset.num_glyphs())
.map(|gid| sid_to_string(charset.string_id(GlyphId::new(gid)).unwrap()))
.collect::<Vec<_>>();
assert_eq!(names_by_lookup, expected_names);
let names_by_iter = charset
.iter()
.map(|(_gid, sid)| sid_to_string(sid))
.collect::<Vec<_>>();
assert_eq!(names_by_iter, expected_names);
}
}

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