mirror of
https://github.com/servo/servo.git
synced 2025-09-30 00:29:14 +01:00
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:
parent
ce16fbce75
commit
7471ad7730
19 changed files with 274 additions and 79 deletions
|
@ -28,7 +28,7 @@ use style::values::computed::font::{
|
|||
};
|
||||
use style::values::computed::{FontStretch, FontWeight};
|
||||
use style::values::specified::FontStretch as SpecifiedFontStretch;
|
||||
use webrender_api::{FontInstanceFlags, FontInstanceKey, FontKey};
|
||||
use webrender_api::{FontInstanceFlags, FontInstanceKey, FontKey, FontVariation};
|
||||
|
||||
use crate::font::FontDescriptor;
|
||||
use crate::font_store::FontStore;
|
||||
|
@ -65,6 +65,7 @@ pub enum SystemFontServiceMessage {
|
|||
FontIdentifier,
|
||||
Au,
|
||||
FontInstanceFlags,
|
||||
Vec<FontVariation>,
|
||||
IpcSender<FontInstanceKey>,
|
||||
),
|
||||
GetFontKey(IpcSender<FontKey>),
|
||||
|
@ -94,7 +95,7 @@ pub struct SystemFontService {
|
|||
local_families: FontStore,
|
||||
compositor_api: CrossProcessCompositorApi,
|
||||
webrender_fonts: HashMap<FontIdentifier, FontKey>,
|
||||
font_instances: HashMap<(FontKey, Au), FontInstanceKey>,
|
||||
font_instances: HashMap<(FontKey, Au, Vec<FontVariation>), FontInstanceKey>,
|
||||
generic_fonts: ResolvedGenericFontFamilies,
|
||||
|
||||
/// This is an optimization that allows the [`SystemFontService`] to send font data to
|
||||
|
@ -176,8 +177,15 @@ impl SystemFontService {
|
|||
let _ =
|
||||
result_sender.send(self.get_font_templates(font_descriptor, font_family));
|
||||
},
|
||||
SystemFontServiceMessage::GetFontInstance(identifier, pt_size, flags, result) => {
|
||||
let _ = result.send(self.get_font_instance(identifier, pt_size, flags));
|
||||
SystemFontServiceMessage::GetFontInstance(
|
||||
identifier,
|
||||
pt_size,
|
||||
flags,
|
||||
variations,
|
||||
result,
|
||||
) => {
|
||||
let _ =
|
||||
result.send(self.get_font_instance(identifier, pt_size, flags, variations));
|
||||
},
|
||||
SystemFontServiceMessage::GetFontKey(result_sender) => {
|
||||
self.fetch_new_keys();
|
||||
|
@ -281,6 +289,7 @@ impl SystemFontService {
|
|||
identifier: FontIdentifier,
|
||||
pt_size: Au,
|
||||
flags: FontInstanceFlags,
|
||||
variations: Vec<FontVariation>,
|
||||
) -> FontInstanceKey {
|
||||
self.fetch_new_keys();
|
||||
|
||||
|
@ -301,7 +310,7 @@ impl SystemFontService {
|
|||
|
||||
*self
|
||||
.font_instances
|
||||
.entry((font_key, pt_size))
|
||||
.entry((font_key, pt_size, variations.clone()))
|
||||
.or_insert_with(|| {
|
||||
let font_instance_key = self.free_font_instance_keys.pop().unwrap();
|
||||
compositor_api.add_font_instance(
|
||||
|
@ -309,6 +318,7 @@ impl SystemFontService {
|
|||
font_key,
|
||||
pt_size.to_f32_px(),
|
||||
flags,
|
||||
variations,
|
||||
);
|
||||
font_instance_key
|
||||
})
|
||||
|
@ -473,6 +483,7 @@ impl SystemFontServiceProxy {
|
|||
identifier: FontIdentifier,
|
||||
size: Au,
|
||||
flags: FontInstanceFlags,
|
||||
variations: Vec<FontVariation>,
|
||||
) -> FontInstanceKey {
|
||||
let (response_chan, response_port) = ipc::channel().expect("failed to create IPC channel");
|
||||
self.sender
|
||||
|
@ -481,6 +492,7 @@ impl SystemFontServiceProxy {
|
|||
identifier,
|
||||
size,
|
||||
flags,
|
||||
variations,
|
||||
response_chan,
|
||||
))
|
||||
.expect("failed to send message to system font service");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue