Skip to content

Commit f5ea337

Browse files
authored
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 #37236 Depends on servo/stylo#230 --------- Signed-off-by: Simon Wülker <[email protected]>
1 parent 520531d commit f5ea337

File tree

19 files changed

+274
-79
lines changed

19 files changed

+274
-79
lines changed

Cargo.lock

Lines changed: 20 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components/compositing/compositor.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ use webrender_api::units::{
4343
use webrender_api::{
4444
self, BuiltDisplayList, DirtyRect, DisplayListPayload, DocumentId, Epoch as WebRenderEpoch,
4545
ExternalScrollId, FontInstanceFlags, FontInstanceKey, FontInstanceOptions, FontKey,
46-
HitTestFlags, PipelineId as WebRenderPipelineId, PropertyBinding, ReferenceFrameKind,
47-
RenderReasons, SampledScrollOffset, ScrollLocation, SpaceAndClipInfo, SpatialId,
48-
SpatialTreeItemKey, TransformStyle,
46+
FontVariation, HitTestFlags, PipelineId as WebRenderPipelineId, PropertyBinding,
47+
ReferenceFrameKind, RenderReasons, SampledScrollOffset, ScrollLocation, SpaceAndClipInfo,
48+
SpatialId, SpatialTreeItemKey, TransformStyle,
4949
};
5050

5151
use crate::InitialCompositorState;
@@ -713,8 +713,14 @@ impl IOCompositor {
713713
self.global.borrow_mut().send_transaction(transaction);
714714
},
715715

716-
CompositorMsg::AddFontInstance(font_instance_key, font_key, size, flags) => {
717-
self.add_font_instance(font_instance_key, font_key, size, flags);
716+
CompositorMsg::AddFontInstance(
717+
font_instance_key,
718+
font_key,
719+
size,
720+
flags,
721+
variations,
722+
) => {
723+
self.add_font_instance(font_instance_key, font_key, size, flags, variations);
718724
},
719725

720726
CompositorMsg::RemoveFonts(keys, instance_keys) => {
@@ -1506,7 +1512,14 @@ impl IOCompositor {
15061512
font_key: FontKey,
15071513
size: f32,
15081514
flags: FontInstanceFlags,
1515+
variations: Vec<FontVariation>,
15091516
) {
1517+
let variations = if pref!(layout_variable_fonts_enabled) {
1518+
variations
1519+
} else {
1520+
vec![]
1521+
};
1522+
15101523
let mut transaction = Transaction::new();
15111524

15121525
let font_instance_options = FontInstanceOptions {
@@ -1519,7 +1532,7 @@ impl IOCompositor {
15191532
size,
15201533
Some(font_instance_options),
15211534
None,
1522-
Vec::new(),
1535+
variations,
15231536
);
15241537

15251538
self.global.borrow_mut().send_transaction(transaction);

components/config/prefs.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ pub fn set(preferences: Preferences) {
4848
"layout.container-queries.enabled",
4949
preferences.layout_container_queries_enabled,
5050
);
51+
stylo_config::set_bool(
52+
"layout.variable_fonts.enabled",
53+
preferences.layout_variable_fonts_enabled,
54+
);
5155

5256
let changed = preferences.diff(&PREFERENCES.read().unwrap());
5357

@@ -229,6 +233,7 @@ pub struct Preferences {
229233
pub layout_flexbox_enabled: bool,
230234
pub layout_threads: i64,
231235
pub layout_unimplemented: bool,
236+
pub layout_variable_fonts_enabled: bool,
232237
pub layout_writing_mode_enabled: bool,
233238
/// Enable hardware acceleration for video playback.
234239
pub media_glvideo_enabled: bool,
@@ -407,6 +412,7 @@ impl Preferences {
407412
// TODO(mrobinson): This should likely be based on the number of processors.
408413
layout_threads: 3,
409414
layout_unimplemented: false,
415+
layout_variable_fonts_enabled: false,
410416
layout_writing_mode_enabled: false,
411417
media_glvideo_enabled: false,
412418
media_testing_enabled: false,

0 commit comments

Comments
 (0)