fonts: Implement CSS font-variation-settings property for FreeType platforms (#38642)

This change adds support for variable fonts via the
[`font-variation-settings`](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variation-settings)
property.

There are three areas where we need to set the variation values:
* Webrender (`compositor.rs`), for drawing the glyphs
* Harfbuzz (`shaper.rs`), for most shaping tasks
* PlatformFont (`fonts/platform/`), for horizontal advances and kerning

For now, freetype is the only platform shaper that supports variable
fonts. I can't easily test the fonts with non-freetype shapers. Thats
why variable fonts are behind the `layout_variable_fonts_enabled` pref,
which is disabled by default.

<img width="1250" height="710" alt="image"
src="https://github.com/user-attachments/assets/1aee1407-f3a2-42f6-a106-af0443fcd588"
/>

<details><summary>HTML test file</summary>

```html
<style>
@font-face {
  font-family: "Amstelvar VF";
  src: url("https://mdn.github.io/shared-assets/fonts/variable-fonts/AmstelvarAlpha-VF.woff2")
    format("woff2-variations");
  font-weight: 300 900;
  font-stretch: 35% 100%;
  font-style: normal;
  font-display: swap;
}

p {
  font:
    1.2em "Amstelvar VF",
    Georgia,
    serif;
  font-size: 4rem;
  margin: 1rem;
  display: inline-block;
}

.p1 {
  font-variation-settings: "wght" 300;
}

.p2 {
  font-variation-settings: "wght" 625;
}

.p3 {
  font-variation-settings: "wght" 900;
}

</style>
<div>
  <p class="p1">Weight</p>
  <span>(font-variation-settings: "wght" 300)</span>
</div>
<div>
  <p class="p2">Weight</p>
  <span>(font-variation-settings: "wght" 625)</span>
</div>
<div>
  <p class="p3">Weight</p>
  <span>(font-variation-settings: "wght" 900)</span>
</div>
</div>
```
</details>



https://github.com/user-attachments/assets/9e21101a-796a-49fe-b82c-8999d8fa9ee1


Testing: Needs decision on whether we want to enable the pref in CI
Works towards https://github.com/servo/servo/issues/37236

Depends on https://github.com/servo/stylo/pull/230

---------

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
Simon Wülker 2025-08-18 18:30:14 +02:00 committed by GitHub
parent ce16fbce75
commit 7471ad7730
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 274 additions and 79 deletions

40
Cargo.lock generated
View file

@ -2382,7 +2382,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
dependencies = [
"libc",
"windows-sys 0.59.0",
"windows-sys 0.52.0",
]
[[package]]
@ -3042,7 +3042,7 @@ dependencies = [
"gobject-sys",
"libc",
"system-deps",
"windows-sys 0.59.0",
"windows-sys 0.52.0",
]
[[package]]
@ -4535,7 +4535,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
dependencies = [
"hermit-abi",
"libc",
"windows-sys 0.59.0",
"windows-sys 0.52.0",
]
[[package]]
@ -4839,7 +4839,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
dependencies = [
"cfg-if",
"windows-targets 0.52.6",
"windows-targets 0.48.5",
]
[[package]]
@ -7004,7 +7004,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys 0.4.15",
"windows-sys 0.59.0",
"windows-sys 0.52.0",
]
[[package]]
@ -7017,7 +7017,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys 0.9.4",
"windows-sys 0.59.0",
"windows-sys 0.52.0",
]
[[package]]
@ -7354,7 +7354,7 @@ dependencies = [
[[package]]
name = "selectors"
version = "0.31.0"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#d2519c05c9d7db31c91552d3337578270645d797"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f"
dependencies = [
"bitflags 2.9.1",
"cssparser",
@ -7660,7 +7660,7 @@ dependencies = [
[[package]]
name = "servo_arc"
version = "0.4.1"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#d2519c05c9d7db31c91552d3337578270645d797"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f"
dependencies = [
"serde",
"stable_deref_trait",
@ -8123,7 +8123,7 @@ dependencies = [
[[package]]
name = "stylo"
version = "0.6.0"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#d2519c05c9d7db31c91552d3337578270645d797"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f"
dependencies = [
"app_units",
"arrayvec",
@ -8180,7 +8180,7 @@ dependencies = [
[[package]]
name = "stylo_atoms"
version = "0.6.0"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#d2519c05c9d7db31c91552d3337578270645d797"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f"
dependencies = [
"string_cache",
"string_cache_codegen",
@ -8189,12 +8189,12 @@ dependencies = [
[[package]]
name = "stylo_config"
version = "0.6.0"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#d2519c05c9d7db31c91552d3337578270645d797"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f"
[[package]]
name = "stylo_derive"
version = "0.6.0"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#d2519c05c9d7db31c91552d3337578270645d797"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f"
dependencies = [
"darling",
"proc-macro2",
@ -8206,7 +8206,7 @@ dependencies = [
[[package]]
name = "stylo_dom"
version = "0.6.0"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#d2519c05c9d7db31c91552d3337578270645d797"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f"
dependencies = [
"bitflags 2.9.1",
"stylo_malloc_size_of",
@ -8215,7 +8215,7 @@ dependencies = [
[[package]]
name = "stylo_malloc_size_of"
version = "0.6.0"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#d2519c05c9d7db31c91552d3337578270645d797"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f"
dependencies = [
"app_units",
"cssparser",
@ -8232,12 +8232,12 @@ dependencies = [
[[package]]
name = "stylo_static_prefs"
version = "0.6.0"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#d2519c05c9d7db31c91552d3337578270645d797"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f"
[[package]]
name = "stylo_traits"
version = "0.6.0"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#d2519c05c9d7db31c91552d3337578270645d797"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f"
dependencies = [
"app_units",
"bitflags 2.9.1",
@ -8411,7 +8411,7 @@ dependencies = [
"getrandom 0.3.3",
"once_cell",
"rustix 1.0.8",
"windows-sys 0.59.0",
"windows-sys 0.52.0",
]
[[package]]
@ -8643,7 +8643,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "to_shmem"
version = "0.2.0"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#d2519c05c9d7db31c91552d3337578270645d797"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f"
dependencies = [
"cssparser",
"servo_arc",
@ -8656,7 +8656,7 @@ dependencies = [
[[package]]
name = "to_shmem_derive"
version = "0.1.0"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#d2519c05c9d7db31c91552d3337578270645d797"
source = "git+https://github.com/servo/stylo?branch=2025-08-01#8a6763eb2a66d3c93860313fba37fc3f09c7f70f"
dependencies = [
"darling",
"proc-macro2",
@ -9946,7 +9946,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
"windows-sys 0.59.0",
"windows-sys 0.48.0",
]
[[package]]