mirror of
https://github.com/servo/servo.git
synced 2025-08-26 23:58:20 +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
40
Cargo.lock
generated
40
Cargo.lock
generated
|
@ -2382,7 +2382,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
|
checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3042,7 +3042,7 @@ dependencies = [
|
||||||
"gobject-sys",
|
"gobject-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"system-deps",
|
"system-deps",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -4535,7 +4535,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi",
|
"hermit-abi",
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -4839,7 +4839,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
|
checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"windows-targets 0.52.6",
|
"windows-targets 0.48.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -7004,7 +7004,7 @@ dependencies = [
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys 0.4.15",
|
"linux-raw-sys 0.4.15",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -7017,7 +7017,7 @@ dependencies = [
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys 0.9.4",
|
"linux-raw-sys 0.9.4",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -7354,7 +7354,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "selectors"
|
name = "selectors"
|
||||||
version = "0.31.0"
|
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 = [
|
dependencies = [
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
"cssparser",
|
"cssparser",
|
||||||
|
@ -7660,7 +7660,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "servo_arc"
|
name = "servo_arc"
|
||||||
version = "0.4.1"
|
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 = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"stable_deref_trait",
|
"stable_deref_trait",
|
||||||
|
@ -8123,7 +8123,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo"
|
name = "stylo"
|
||||||
version = "0.6.0"
|
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 = [
|
dependencies = [
|
||||||
"app_units",
|
"app_units",
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
|
@ -8180,7 +8180,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo_atoms"
|
name = "stylo_atoms"
|
||||||
version = "0.6.0"
|
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 = [
|
dependencies = [
|
||||||
"string_cache",
|
"string_cache",
|
||||||
"string_cache_codegen",
|
"string_cache_codegen",
|
||||||
|
@ -8189,12 +8189,12 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo_config"
|
name = "stylo_config"
|
||||||
version = "0.6.0"
|
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]]
|
[[package]]
|
||||||
name = "stylo_derive"
|
name = "stylo_derive"
|
||||||
version = "0.6.0"
|
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 = [
|
dependencies = [
|
||||||
"darling",
|
"darling",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
@ -8206,7 +8206,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo_dom"
|
name = "stylo_dom"
|
||||||
version = "0.6.0"
|
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 = [
|
dependencies = [
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
"stylo_malloc_size_of",
|
"stylo_malloc_size_of",
|
||||||
|
@ -8215,7 +8215,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo_malloc_size_of"
|
name = "stylo_malloc_size_of"
|
||||||
version = "0.6.0"
|
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 = [
|
dependencies = [
|
||||||
"app_units",
|
"app_units",
|
||||||
"cssparser",
|
"cssparser",
|
||||||
|
@ -8232,12 +8232,12 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo_static_prefs"
|
name = "stylo_static_prefs"
|
||||||
version = "0.6.0"
|
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]]
|
[[package]]
|
||||||
name = "stylo_traits"
|
name = "stylo_traits"
|
||||||
version = "0.6.0"
|
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 = [
|
dependencies = [
|
||||||
"app_units",
|
"app_units",
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
|
@ -8411,7 +8411,7 @@ dependencies = [
|
||||||
"getrandom 0.3.3",
|
"getrandom 0.3.3",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix 1.0.8",
|
"rustix 1.0.8",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -8643,7 +8643,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "to_shmem"
|
name = "to_shmem"
|
||||||
version = "0.2.0"
|
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 = [
|
dependencies = [
|
||||||
"cssparser",
|
"cssparser",
|
||||||
"servo_arc",
|
"servo_arc",
|
||||||
|
@ -8656,7 +8656,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "to_shmem_derive"
|
name = "to_shmem_derive"
|
||||||
version = "0.1.0"
|
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 = [
|
dependencies = [
|
||||||
"darling",
|
"darling",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
@ -9946,7 +9946,7 @@ version = "0.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -43,9 +43,9 @@ use webrender_api::units::{
|
||||||
use webrender_api::{
|
use webrender_api::{
|
||||||
self, BuiltDisplayList, DirtyRect, DisplayListPayload, DocumentId, Epoch as WebRenderEpoch,
|
self, BuiltDisplayList, DirtyRect, DisplayListPayload, DocumentId, Epoch as WebRenderEpoch,
|
||||||
ExternalScrollId, FontInstanceFlags, FontInstanceKey, FontInstanceOptions, FontKey,
|
ExternalScrollId, FontInstanceFlags, FontInstanceKey, FontInstanceOptions, FontKey,
|
||||||
HitTestFlags, PipelineId as WebRenderPipelineId, PropertyBinding, ReferenceFrameKind,
|
FontVariation, HitTestFlags, PipelineId as WebRenderPipelineId, PropertyBinding,
|
||||||
RenderReasons, SampledScrollOffset, ScrollLocation, SpaceAndClipInfo, SpatialId,
|
ReferenceFrameKind, RenderReasons, SampledScrollOffset, ScrollLocation, SpaceAndClipInfo,
|
||||||
SpatialTreeItemKey, TransformStyle,
|
SpatialId, SpatialTreeItemKey, TransformStyle,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::InitialCompositorState;
|
use crate::InitialCompositorState;
|
||||||
|
@ -713,8 +713,14 @@ impl IOCompositor {
|
||||||
self.global.borrow_mut().send_transaction(transaction);
|
self.global.borrow_mut().send_transaction(transaction);
|
||||||
},
|
},
|
||||||
|
|
||||||
CompositorMsg::AddFontInstance(font_instance_key, font_key, size, flags) => {
|
CompositorMsg::AddFontInstance(
|
||||||
self.add_font_instance(font_instance_key, font_key, size, flags);
|
font_instance_key,
|
||||||
|
font_key,
|
||||||
|
size,
|
||||||
|
flags,
|
||||||
|
variations,
|
||||||
|
) => {
|
||||||
|
self.add_font_instance(font_instance_key, font_key, size, flags, variations);
|
||||||
},
|
},
|
||||||
|
|
||||||
CompositorMsg::RemoveFonts(keys, instance_keys) => {
|
CompositorMsg::RemoveFonts(keys, instance_keys) => {
|
||||||
|
@ -1506,7 +1512,14 @@ impl IOCompositor {
|
||||||
font_key: FontKey,
|
font_key: FontKey,
|
||||||
size: f32,
|
size: f32,
|
||||||
flags: FontInstanceFlags,
|
flags: FontInstanceFlags,
|
||||||
|
variations: Vec<FontVariation>,
|
||||||
) {
|
) {
|
||||||
|
let variations = if pref!(layout_variable_fonts_enabled) {
|
||||||
|
variations
|
||||||
|
} else {
|
||||||
|
vec![]
|
||||||
|
};
|
||||||
|
|
||||||
let mut transaction = Transaction::new();
|
let mut transaction = Transaction::new();
|
||||||
|
|
||||||
let font_instance_options = FontInstanceOptions {
|
let font_instance_options = FontInstanceOptions {
|
||||||
|
@ -1519,7 +1532,7 @@ impl IOCompositor {
|
||||||
size,
|
size,
|
||||||
Some(font_instance_options),
|
Some(font_instance_options),
|
||||||
None,
|
None,
|
||||||
Vec::new(),
|
variations,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.global.borrow_mut().send_transaction(transaction);
|
self.global.borrow_mut().send_transaction(transaction);
|
||||||
|
|
|
@ -48,6 +48,10 @@ pub fn set(preferences: Preferences) {
|
||||||
"layout.container-queries.enabled",
|
"layout.container-queries.enabled",
|
||||||
preferences.layout_container_queries_enabled,
|
preferences.layout_container_queries_enabled,
|
||||||
);
|
);
|
||||||
|
stylo_config::set_bool(
|
||||||
|
"layout.variable_fonts.enabled",
|
||||||
|
preferences.layout_variable_fonts_enabled,
|
||||||
|
);
|
||||||
|
|
||||||
let changed = preferences.diff(&PREFERENCES.read().unwrap());
|
let changed = preferences.diff(&PREFERENCES.read().unwrap());
|
||||||
|
|
||||||
|
@ -229,6 +233,7 @@ pub struct Preferences {
|
||||||
pub layout_flexbox_enabled: bool,
|
pub layout_flexbox_enabled: bool,
|
||||||
pub layout_threads: i64,
|
pub layout_threads: i64,
|
||||||
pub layout_unimplemented: bool,
|
pub layout_unimplemented: bool,
|
||||||
|
pub layout_variable_fonts_enabled: bool,
|
||||||
pub layout_writing_mode_enabled: bool,
|
pub layout_writing_mode_enabled: bool,
|
||||||
/// Enable hardware acceleration for video playback.
|
/// Enable hardware acceleration for video playback.
|
||||||
pub media_glvideo_enabled: bool,
|
pub media_glvideo_enabled: bool,
|
||||||
|
@ -407,6 +412,7 @@ impl Preferences {
|
||||||
// TODO(mrobinson): This should likely be based on the number of processors.
|
// TODO(mrobinson): This should likely be based on the number of processors.
|
||||||
layout_threads: 3,
|
layout_threads: 3,
|
||||||
layout_unimplemented: false,
|
layout_unimplemented: false,
|
||||||
|
layout_variable_fonts_enabled: false,
|
||||||
layout_writing_mode_enabled: false,
|
layout_writing_mode_enabled: false,
|
||||||
media_glvideo_enabled: false,
|
media_glvideo_enabled: false,
|
||||||
media_testing_enabled: false,
|
media_testing_enabled: false,
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::hash::Hash;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use std::sync::{Arc, OnceLock};
|
use std::sync::{Arc, OnceLock};
|
||||||
|
@ -26,7 +27,7 @@ use style::values::computed::font::{
|
||||||
};
|
};
|
||||||
use style::values::computed::{FontStretch, FontStyle, FontWeight};
|
use style::values::computed::{FontStretch, FontStyle, FontWeight};
|
||||||
use unicode_script::Script;
|
use unicode_script::Script;
|
||||||
use webrender_api::{FontInstanceFlags, FontInstanceKey};
|
use webrender_api::{FontInstanceFlags, FontInstanceKey, FontVariation};
|
||||||
|
|
||||||
use crate::platform::font::{FontTable, PlatformFont};
|
use crate::platform::font::{FontTable, PlatformFont};
|
||||||
pub use crate::platform::font_list::fallback_font_families;
|
pub use crate::platform::font_list::fallback_font_families;
|
||||||
|
@ -43,13 +44,14 @@ macro_rules! ot_tag {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const GPOS: u32 = ot_tag!('G', 'P', 'O', 'S');
|
pub type OpenTypeTableTag = u32;
|
||||||
pub const GSUB: u32 = ot_tag!('G', 'S', 'U', 'B');
|
pub const GPOS: OpenTypeTableTag = ot_tag!('G', 'P', 'O', 'S');
|
||||||
pub const KERN: u32 = ot_tag!('k', 'e', 'r', 'n');
|
pub const GSUB: OpenTypeTableTag = ot_tag!('G', 'S', 'U', 'B');
|
||||||
pub const SBIX: u32 = ot_tag!('s', 'b', 'i', 'x');
|
pub const KERN: OpenTypeTableTag = ot_tag!('k', 'e', 'r', 'n');
|
||||||
pub const CBDT: u32 = ot_tag!('C', 'B', 'D', 'T');
|
pub const SBIX: OpenTypeTableTag = ot_tag!('s', 'b', 'i', 'x');
|
||||||
pub const COLR: u32 = ot_tag!('C', 'O', 'L', 'R');
|
pub const CBDT: OpenTypeTableTag = ot_tag!('C', 'B', 'D', 'T');
|
||||||
pub const BASE: u32 = ot_tag!('B', 'A', 'S', 'E');
|
pub const COLR: OpenTypeTableTag = ot_tag!('C', 'O', 'L', 'R');
|
||||||
|
pub const BASE: OpenTypeTableTag = ot_tag!('B', 'A', 'S', 'E');
|
||||||
|
|
||||||
pub const LAST_RESORT_GLYPH_ADVANCE: FractionalPixel = 10.0;
|
pub const LAST_RESORT_GLYPH_ADVANCE: FractionalPixel = 10.0;
|
||||||
|
|
||||||
|
@ -66,6 +68,7 @@ pub trait PlatformFontMethods: Sized {
|
||||||
fn new_from_template(
|
fn new_from_template(
|
||||||
template: FontTemplateRef,
|
template: FontTemplateRef,
|
||||||
pt_size: Option<Au>,
|
pt_size: Option<Au>,
|
||||||
|
variations: &[FontVariation],
|
||||||
data: &Option<FontData>,
|
data: &Option<FontData>,
|
||||||
) -> Result<PlatformFont, &'static str> {
|
) -> Result<PlatformFont, &'static str> {
|
||||||
let template = template.borrow();
|
let template = template.borrow();
|
||||||
|
@ -73,13 +76,14 @@ pub trait PlatformFontMethods: Sized {
|
||||||
|
|
||||||
match font_identifier {
|
match font_identifier {
|
||||||
FontIdentifier::Local(font_identifier) => {
|
FontIdentifier::Local(font_identifier) => {
|
||||||
Self::new_from_local_font_identifier(font_identifier, pt_size)
|
Self::new_from_local_font_identifier(font_identifier, pt_size, variations)
|
||||||
},
|
},
|
||||||
FontIdentifier::Web(_) => Self::new_from_data(
|
FontIdentifier::Web(_) => Self::new_from_data(
|
||||||
font_identifier,
|
font_identifier,
|
||||||
data.as_ref()
|
data.as_ref()
|
||||||
.expect("Should never create a web font without data."),
|
.expect("Should never create a web font without data."),
|
||||||
pt_size,
|
pt_size,
|
||||||
|
variations,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,12 +91,14 @@ pub trait PlatformFontMethods: Sized {
|
||||||
fn new_from_local_font_identifier(
|
fn new_from_local_font_identifier(
|
||||||
font_identifier: LocalFontIdentifier,
|
font_identifier: LocalFontIdentifier,
|
||||||
pt_size: Option<Au>,
|
pt_size: Option<Au>,
|
||||||
|
variations: &[FontVariation],
|
||||||
) -> Result<PlatformFont, &'static str>;
|
) -> Result<PlatformFont, &'static str>;
|
||||||
|
|
||||||
fn new_from_data(
|
fn new_from_data(
|
||||||
font_identifier: FontIdentifier,
|
font_identifier: FontIdentifier,
|
||||||
data: &FontData,
|
data: &FontData,
|
||||||
pt_size: Option<Au>,
|
pt_size: Option<Au>,
|
||||||
|
variations: &[FontVariation],
|
||||||
) -> Result<PlatformFont, &'static str>;
|
) -> Result<PlatformFont, &'static str>;
|
||||||
|
|
||||||
/// Get a [`FontTemplateDescriptor`] from a [`PlatformFont`]. This is used to get
|
/// Get a [`FontTemplateDescriptor`] from a [`PlatformFont`]. This is used to get
|
||||||
|
@ -109,6 +115,9 @@ pub trait PlatformFontMethods: Sized {
|
||||||
|
|
||||||
/// Get the necessary [`FontInstanceFlags`]` for this font.
|
/// Get the necessary [`FontInstanceFlags`]` for this font.
|
||||||
fn webrender_font_instance_flags(&self) -> FontInstanceFlags;
|
fn webrender_font_instance_flags(&self) -> FontInstanceFlags;
|
||||||
|
|
||||||
|
/// Return all the variation values that the font was instantiated with.
|
||||||
|
fn variations(&self) -> &[FontVariation];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used to abstract over the shaper's choice of fixed int representation.
|
// Used to abstract over the shaper's choice of fixed int representation.
|
||||||
|
@ -192,18 +201,29 @@ pub struct FontDescriptor {
|
||||||
pub style: FontStyle,
|
pub style: FontStyle,
|
||||||
pub variant: font_variant_caps::T,
|
pub variant: font_variant_caps::T,
|
||||||
pub pt_size: Au,
|
pub pt_size: Au,
|
||||||
|
pub variation_settings: Vec<FontVariation>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eq for FontDescriptor {}
|
impl Eq for FontDescriptor {}
|
||||||
|
|
||||||
impl<'a> From<&'a FontStyleStruct> for FontDescriptor {
|
impl<'a> From<&'a FontStyleStruct> for FontDescriptor {
|
||||||
fn from(style: &'a FontStyleStruct) -> Self {
|
fn from(style: &'a FontStyleStruct) -> Self {
|
||||||
|
let variation_settings = style
|
||||||
|
.clone_font_variation_settings()
|
||||||
|
.0
|
||||||
|
.into_iter()
|
||||||
|
.map(|setting| FontVariation {
|
||||||
|
tag: setting.tag.0,
|
||||||
|
value: setting.value,
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
FontDescriptor {
|
FontDescriptor {
|
||||||
weight: style.font_weight,
|
weight: style.font_weight,
|
||||||
stretch: style.font_stretch,
|
stretch: style.font_stretch,
|
||||||
style: style.font_style,
|
style: style.font_style,
|
||||||
variant: style.font_variant_caps,
|
variant: style.font_variant_caps,
|
||||||
pt_size: Au::from_f32_px(style.font_size.computed_size().px()),
|
pt_size: Au::from_f32_px(style.font_size.computed_size().px()),
|
||||||
|
variation_settings,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,8 +300,12 @@ impl Font {
|
||||||
data: Option<FontData>,
|
data: Option<FontData>,
|
||||||
synthesized_small_caps: Option<FontRef>,
|
synthesized_small_caps: Option<FontRef>,
|
||||||
) -> Result<Font, &'static str> {
|
) -> Result<Font, &'static str> {
|
||||||
let handle =
|
let handle = PlatformFont::new_from_template(
|
||||||
PlatformFont::new_from_template(template.clone(), Some(descriptor.pt_size), &data)?;
|
template.clone(),
|
||||||
|
Some(descriptor.pt_size),
|
||||||
|
&descriptor.variation_settings,
|
||||||
|
&data,
|
||||||
|
)?;
|
||||||
let metrics = handle.metrics();
|
let metrics = handle.metrics();
|
||||||
|
|
||||||
Ok(Font {
|
Ok(Font {
|
||||||
|
@ -336,6 +360,10 @@ impl Font {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn variations(&self) -> &[FontVariation] {
|
||||||
|
self.handle.variations()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
|
@ -426,9 +454,8 @@ impl Font {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shape_text_harfbuzz(&self, text: &str, options: &ShapingOptions, glyphs: &mut GlyphStore) {
|
fn shape_text_harfbuzz(&self, text: &str, options: &ShapingOptions, glyphs: &mut GlyphStore) {
|
||||||
let this = self as *const Font;
|
|
||||||
self.shaper
|
self.shaper
|
||||||
.get_or_init(|| Shaper::new(this))
|
.get_or_init(|| Shaper::new(self))
|
||||||
.shape_text(text, options, glyphs);
|
.shape_text(text, options, glyphs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,8 +571,7 @@ impl Font {
|
||||||
|
|
||||||
/// Get the [`FontBaseline`] for this font.
|
/// Get the [`FontBaseline`] for this font.
|
||||||
pub fn baseline(&self) -> Option<FontBaseline> {
|
pub fn baseline(&self) -> Option<FontBaseline> {
|
||||||
let this = self as *const Font;
|
self.shaper.get_or_init(|| Shaper::new(self)).baseline()
|
||||||
self.shaper.get_or_init(|| Shaper::new(this)).baseline()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ use style::shared_lock::SharedRwLockReadGuard;
|
||||||
use style::stylesheets::{CssRule, DocumentStyleSheet, FontFaceRule, StylesheetInDocument};
|
use style::stylesheets::{CssRule, DocumentStyleSheet, FontFaceRule, StylesheetInDocument};
|
||||||
use style::values::computed::font::{FamilyName, FontFamilyNameSyntax, SingleFontFamily};
|
use style::values::computed::font::{FamilyName, FontFamilyNameSyntax, SingleFontFamily};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use webrender_api::{FontInstanceFlags, FontInstanceKey, FontKey};
|
use webrender_api::{FontInstanceFlags, FontInstanceKey, FontKey, FontVariation};
|
||||||
|
|
||||||
use crate::font::{
|
use crate::font::{
|
||||||
Font, FontDescriptor, FontFamilyDescriptor, FontGroup, FontRef, FontSearchScope,
|
Font, FontDescriptor, FontFamilyDescriptor, FontGroup, FontRef, FontSearchScope,
|
||||||
|
@ -45,6 +45,8 @@ use crate::{FontData, LowercaseFontFamilyName, PlatformFontMethods, SystemFontSe
|
||||||
|
|
||||||
static SMALL_CAPS_SCALE_FACTOR: f32 = 0.8; // Matches FireFox (see gfxFont.h)
|
static SMALL_CAPS_SCALE_FACTOR: f32 = 0.8; // Matches FireFox (see gfxFont.h)
|
||||||
|
|
||||||
|
pub type FontParameters = (FontKey, Au, Vec<FontVariation>);
|
||||||
|
|
||||||
#[derive(MallocSizeOf)]
|
#[derive(MallocSizeOf)]
|
||||||
struct FontGroupRef(#[conditional_malloc_size_of] Arc<RwLock<FontGroup>>);
|
struct FontGroupRef(#[conditional_malloc_size_of] Arc<RwLock<FontGroup>>);
|
||||||
|
|
||||||
|
@ -87,7 +89,7 @@ pub struct FontContext {
|
||||||
|
|
||||||
/// A collection of WebRender [`FontInstanceKey`]s generated for the web fonts that
|
/// A collection of WebRender [`FontInstanceKey`]s generated for the web fonts that
|
||||||
/// this [`FontContext`] controls.
|
/// this [`FontContext`] controls.
|
||||||
webrender_font_instance_keys: RwLock<HashMap<(FontKey, Au), FontInstanceKey>>,
|
webrender_font_instance_keys: RwLock<HashMap<FontParameters, FontInstanceKey>>,
|
||||||
|
|
||||||
/// The data for each web font [`FontIdentifier`]. This data might be used by more than one
|
/// The data for each web font [`FontIdentifier`]. This data might be used by more than one
|
||||||
/// [`FontTemplate`] as each identifier refers to a URL.
|
/// [`FontTemplate`] as each identifier refers to a URL.
|
||||||
|
@ -270,7 +272,7 @@ impl FontContext {
|
||||||
) -> Result<FontRef, &'static str> {
|
) -> Result<FontRef, &'static str> {
|
||||||
Ok(FontRef(Arc::new(Font::new(
|
Ok(FontRef(Arc::new(Font::new(
|
||||||
font_template.clone(),
|
font_template.clone(),
|
||||||
font_descriptor.clone(),
|
font_descriptor,
|
||||||
self.get_font_data(&font_template.identifier()),
|
self.get_font_data(&font_template.identifier()),
|
||||||
synthesized_small_caps,
|
synthesized_small_caps,
|
||||||
)?)))
|
)?)))
|
||||||
|
@ -282,11 +284,13 @@ impl FontContext {
|
||||||
font.template.identifier(),
|
font.template.identifier(),
|
||||||
font.descriptor.pt_size,
|
font.descriptor.pt_size,
|
||||||
font.webrender_font_instance_flags(),
|
font.webrender_font_instance_flags(),
|
||||||
|
font.variations().to_owned(),
|
||||||
),
|
),
|
||||||
FontIdentifier::Web(_) => self.create_web_font_instance(
|
FontIdentifier::Web(_) => self.create_web_font_instance(
|
||||||
font.template.clone(),
|
font.template.clone(),
|
||||||
font.descriptor.pt_size,
|
font.descriptor.pt_size,
|
||||||
font.webrender_font_instance_flags(),
|
font.webrender_font_instance_flags(),
|
||||||
|
font.variations().to_owned(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -296,6 +300,7 @@ impl FontContext {
|
||||||
font_template: FontTemplateRef,
|
font_template: FontTemplateRef,
|
||||||
pt_size: Au,
|
pt_size: Au,
|
||||||
flags: FontInstanceFlags,
|
flags: FontInstanceFlags,
|
||||||
|
variations: Vec<FontVariation>,
|
||||||
) -> FontInstanceKey {
|
) -> FontInstanceKey {
|
||||||
let identifier = font_template.identifier().clone();
|
let identifier = font_template.identifier().clone();
|
||||||
let font_data = self
|
let font_data = self
|
||||||
|
@ -318,7 +323,7 @@ impl FontContext {
|
||||||
let key = *self
|
let key = *self
|
||||||
.webrender_font_instance_keys
|
.webrender_font_instance_keys
|
||||||
.write()
|
.write()
|
||||||
.entry((font_key, pt_size))
|
.entry((font_key, pt_size, variations.clone()))
|
||||||
.or_insert_with(|| {
|
.or_insert_with(|| {
|
||||||
let font_instance_key = self.system_font_service_proxy.generate_font_instance_key();
|
let font_instance_key = self.system_font_service_proxy.generate_font_instance_key();
|
||||||
self.compositor_api.lock().add_font_instance(
|
self.compositor_api.lock().add_font_instance(
|
||||||
|
@ -326,6 +331,7 @@ impl FontContext {
|
||||||
font_key,
|
font_key,
|
||||||
pt_size.to_f32_px(),
|
pt_size.to_f32_px(),
|
||||||
flags,
|
flags,
|
||||||
|
variations,
|
||||||
);
|
);
|
||||||
font_instance_key
|
font_instance_key
|
||||||
});
|
});
|
||||||
|
@ -612,7 +618,7 @@ impl FontContextWebFontMethods for Arc<FontContext> {
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut removed_instance_keys: HashSet<FontInstanceKey> = HashSet::new();
|
let mut removed_instance_keys: HashSet<FontInstanceKey> = HashSet::new();
|
||||||
webrender_font_instance_keys.retain(|(font_key, _), instance_key| {
|
webrender_font_instance_keys.retain(|(font_key, _, _), instance_key| {
|
||||||
if removed_keys.contains(font_key) {
|
if removed_keys.contains(font_key) {
|
||||||
removed_instance_keys.insert(*instance_key);
|
removed_instance_keys.insert(*instance_key);
|
||||||
false
|
false
|
||||||
|
@ -857,11 +863,11 @@ impl RemoteWebFontDownloader {
|
||||||
|
|
||||||
let url: ServoUrl = self.url.clone().into();
|
let url: ServoUrl = self.url.clone().into();
|
||||||
let identifier = FontIdentifier::Web(url.clone());
|
let identifier = FontIdentifier::Web(url.clone());
|
||||||
let Ok(handle) = PlatformFont::new_from_data(identifier, &font_data, None) else {
|
let Ok(handle) = PlatformFont::new_from_data(identifier, &font_data, None, &[]) else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
let state = self.take_state();
|
let state = self.take_state();
|
||||||
|
|
||||||
let mut descriptor = handle.descriptor();
|
let mut descriptor = handle.descriptor();
|
||||||
descriptor
|
descriptor
|
||||||
.override_values_with_css_font_template_descriptors(&state.css_font_face_descriptors);
|
.override_values_with_css_font_template_descriptors(&state.css_font_face_descriptors);
|
||||||
|
|
|
@ -315,7 +315,7 @@ impl<'a> DetailedGlyphStore {
|
||||||
|
|
||||||
// This struct is used by GlyphStore clients to provide new glyph data.
|
// This struct is used by GlyphStore clients to provide new glyph data.
|
||||||
// It should be allocated on the stack and passed by reference to GlyphStore.
|
// It should be allocated on the stack and passed by reference to GlyphStore.
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct GlyphData {
|
pub struct GlyphData {
|
||||||
id: GlyphId,
|
id: GlyphId,
|
||||||
advance: Au,
|
advance: Au,
|
||||||
|
|
|
@ -23,7 +23,7 @@ use style::Zero;
|
||||||
use style::computed_values::font_stretch::T as FontStretch;
|
use style::computed_values::font_stretch::T as FontStretch;
|
||||||
use style::computed_values::font_weight::T as FontWeight;
|
use style::computed_values::font_weight::T as FontWeight;
|
||||||
use style::values::computed::font::FontStyle;
|
use style::values::computed::font::FontStyle;
|
||||||
use webrender_api::FontInstanceFlags;
|
use webrender_api::{FontInstanceFlags, FontVariation};
|
||||||
|
|
||||||
use super::LocalFontIdentifier;
|
use super::LocalFontIdentifier;
|
||||||
use super::library_handle::FreeTypeLibraryHandle;
|
use super::library_handle::FreeTypeLibraryHandle;
|
||||||
|
@ -63,6 +63,7 @@ pub struct PlatformFont {
|
||||||
face: ReentrantMutex<FreeTypeFace>,
|
face: ReentrantMutex<FreeTypeFace>,
|
||||||
requested_face_size: Au,
|
requested_face_size: Au,
|
||||||
actual_face_size: Au,
|
actual_face_size: Au,
|
||||||
|
variations: Vec<FontVariation>,
|
||||||
|
|
||||||
/// A member that allows using `skrifa` to read values from this font.
|
/// A member that allows using `skrifa` to read values from this font.
|
||||||
table_provider_data: FreeTypeFaceTableProviderData,
|
table_provider_data: FreeTypeFaceTableProviderData,
|
||||||
|
@ -73,11 +74,14 @@ impl PlatformFontMethods for PlatformFont {
|
||||||
_font_identifier: FontIdentifier,
|
_font_identifier: FontIdentifier,
|
||||||
font_data: &FontData,
|
font_data: &FontData,
|
||||||
requested_size: Option<Au>,
|
requested_size: Option<Au>,
|
||||||
|
variations: &[FontVariation],
|
||||||
) -> Result<PlatformFont, &'static str> {
|
) -> Result<PlatformFont, &'static str> {
|
||||||
let library = FreeTypeLibraryHandle::get().lock();
|
let library = FreeTypeLibraryHandle::get().lock();
|
||||||
let data: &[u8] = font_data.as_ref();
|
let data: &[u8] = font_data.as_ref();
|
||||||
let face = FreeTypeFace::new_from_memory(&library, data)?;
|
let face = FreeTypeFace::new_from_memory(&library, data)?;
|
||||||
|
|
||||||
|
let normalized_variations = face.set_variations_for_font(variations, &library)?;
|
||||||
|
|
||||||
let (requested_face_size, actual_face_size) = match requested_size {
|
let (requested_face_size, actual_face_size) = match requested_size {
|
||||||
Some(requested_size) => (requested_size, face.set_size(requested_size)?),
|
Some(requested_size) => (requested_size, face.set_size(requested_size)?),
|
||||||
None => (Au::zero(), Au::zero()),
|
None => (Au::zero(), Au::zero()),
|
||||||
|
@ -88,18 +92,22 @@ impl PlatformFontMethods for PlatformFont {
|
||||||
requested_face_size,
|
requested_face_size,
|
||||||
actual_face_size,
|
actual_face_size,
|
||||||
table_provider_data: FreeTypeFaceTableProviderData::Web(font_data.clone()),
|
table_provider_data: FreeTypeFaceTableProviderData::Web(font_data.clone()),
|
||||||
|
variations: normalized_variations,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_from_local_font_identifier(
|
fn new_from_local_font_identifier(
|
||||||
font_identifier: LocalFontIdentifier,
|
font_identifier: LocalFontIdentifier,
|
||||||
requested_size: Option<Au>,
|
requested_size: Option<Au>,
|
||||||
|
variations: &[FontVariation],
|
||||||
) -> Result<PlatformFont, &'static str> {
|
) -> Result<PlatformFont, &'static str> {
|
||||||
let library = FreeTypeLibraryHandle::get().lock();
|
let library = FreeTypeLibraryHandle::get().lock();
|
||||||
let filename = CString::new(&*font_identifier.path).expect("filename contains NUL byte!");
|
let filename = CString::new(&*font_identifier.path).expect("filename contains NUL byte!");
|
||||||
|
|
||||||
let face = FreeTypeFace::new_from_file(&library, &filename, font_identifier.index())?;
|
let face = FreeTypeFace::new_from_file(&library, &filename, font_identifier.index())?;
|
||||||
|
|
||||||
|
let normalized_variations = face.set_variations_for_font(variations, &library)?;
|
||||||
|
|
||||||
let (requested_face_size, actual_face_size) = match requested_size {
|
let (requested_face_size, actual_face_size) = match requested_size {
|
||||||
Some(requested_size) => (requested_size, face.set_size(requested_size)?),
|
Some(requested_size) => (requested_size, face.set_size(requested_size)?),
|
||||||
None => (Au::zero(), Au::zero()),
|
None => (Au::zero(), Au::zero()),
|
||||||
|
@ -119,6 +127,7 @@ impl PlatformFontMethods for PlatformFont {
|
||||||
Arc::new(memory_mapped_font_data),
|
Arc::new(memory_mapped_font_data),
|
||||||
font_identifier.index(),
|
font_identifier.index(),
|
||||||
),
|
),
|
||||||
|
variations: normalized_variations,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,6 +386,10 @@ impl PlatformFontMethods for PlatformFont {
|
||||||
// loading bitmaps. There's no harm to always passing it.
|
// loading bitmaps. There's no harm to always passing it.
|
||||||
FontInstanceFlags::EMBEDDED_BITMAPS
|
FontInstanceFlags::EMBEDDED_BITMAPS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn variations(&self) -> &[FontVariation] {
|
||||||
|
&self.variations
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PlatformFont {
|
impl PlatformFont {
|
||||||
|
|
|
@ -7,10 +7,13 @@ use std::ptr;
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use freetype_sys::{
|
use freetype_sys::{
|
||||||
FT_Done_Face, FT_F26Dot6, FT_FACE_FLAG_COLOR, FT_FACE_FLAG_FIXED_SIZES, FT_FACE_FLAG_SCALABLE,
|
FT_Done_Face, FT_Done_MM_Var, FT_F26Dot6, FT_FACE_FLAG_COLOR, FT_FACE_FLAG_FIXED_SIZES,
|
||||||
FT_Face, FT_FaceRec, FT_Int32, FT_LOAD_COLOR, FT_LOAD_DEFAULT, FT_Long, FT_New_Face,
|
FT_FACE_FLAG_SCALABLE, FT_Face, FT_FaceRec, FT_Fixed, FT_Get_MM_Var, FT_HAS_MULTIPLE_MASTERS,
|
||||||
FT_New_Memory_Face, FT_Pos, FT_Select_Size, FT_Set_Char_Size, FT_UInt,
|
FT_Int32, FT_LOAD_COLOR, FT_LOAD_DEFAULT, FT_Long, FT_MM_Var, FT_New_Face, FT_New_Memory_Face,
|
||||||
|
FT_Pos, FT_Select_Size, FT_Set_Char_Size, FT_Set_Var_Design_Coordinates, FT_UInt,
|
||||||
|
FTErrorMethods,
|
||||||
};
|
};
|
||||||
|
use webrender_api::FontVariation;
|
||||||
|
|
||||||
use crate::platform::freetype::library_handle::FreeTypeLibraryHandle;
|
use crate::platform::freetype::library_handle::FreeTypeLibraryHandle;
|
||||||
|
|
||||||
|
@ -164,6 +167,74 @@ impl FreeTypeFace {
|
||||||
|
|
||||||
load_flags as FT_Int32
|
load_flags as FT_Int32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Applies to provided variations to the font face.
|
||||||
|
///
|
||||||
|
/// Returns the normalized font variations, which are clamped
|
||||||
|
/// to fit within the range of their respective axis. Variation
|
||||||
|
/// values for nonexistent axes are not included.
|
||||||
|
pub(crate) fn set_variations_for_font(
|
||||||
|
&self,
|
||||||
|
variations: &[FontVariation],
|
||||||
|
library: &FreeTypeLibraryHandle,
|
||||||
|
) -> Result<Vec<FontVariation>, &'static str> {
|
||||||
|
if !FT_HAS_MULTIPLE_MASTERS(self.as_ptr()) ||
|
||||||
|
variations.is_empty() ||
|
||||||
|
!servo_config::pref!(layout_variable_fonts_enabled)
|
||||||
|
{
|
||||||
|
// Nothing to do
|
||||||
|
return Ok(vec![]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query variation axis of font
|
||||||
|
let mut mm_var: *mut FT_MM_Var = ptr::null_mut();
|
||||||
|
let result = unsafe { FT_Get_MM_Var(self.as_ptr(), &mut mm_var as *mut _) };
|
||||||
|
if !result.succeeded() {
|
||||||
|
return Err("Failed to query font variations");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare values for each axis. These are either the provided values (if any) or the default
|
||||||
|
// ones for the axis.
|
||||||
|
let num_axis = unsafe { (*mm_var).num_axis } as usize;
|
||||||
|
let mut normalized_axis_values = Vec::with_capacity(variations.len());
|
||||||
|
let mut coords = vec![0; num_axis];
|
||||||
|
for (index, coord) in coords.iter_mut().enumerate() {
|
||||||
|
let axis_data = unsafe { &*(*mm_var).axis.add(index) };
|
||||||
|
let Some(variation) = variations
|
||||||
|
.iter()
|
||||||
|
.find(|variation| variation.tag == axis_data.tag as u32)
|
||||||
|
else {
|
||||||
|
*coord = axis_data.def;
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Freetype uses a 16.16 fixed point format for variation values
|
||||||
|
let shift_factor = 16.0_f32.exp2();
|
||||||
|
let min_value = axis_data.minimum as f32 / shift_factor;
|
||||||
|
let max_value = axis_data.maximum as f32 / shift_factor;
|
||||||
|
normalized_axis_values.push(FontVariation {
|
||||||
|
tag: variation.tag,
|
||||||
|
value: variation.value.min(max_value).max(min_value),
|
||||||
|
});
|
||||||
|
|
||||||
|
*coord = (variation.value * shift_factor) as FT_Fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free the MM_Var structure
|
||||||
|
unsafe {
|
||||||
|
FT_Done_MM_Var(library.freetype_library, mm_var);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the values for each variation axis
|
||||||
|
let result = unsafe {
|
||||||
|
FT_Set_Var_Design_Coordinates(self.as_ptr(), coords.len() as u32, coords.as_ptr())
|
||||||
|
};
|
||||||
|
if !result.succeeded() {
|
||||||
|
return Err("Could not set variations for font face");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(normalized_axis_values)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// FT_Face can be used in multiple threads, but from only one thread at a time.
|
/// FT_Face can be used in multiple threads, but from only one thread at a time.
|
||||||
|
|
|
@ -19,7 +19,7 @@ use core_text::font_descriptor::{
|
||||||
use euclid::default::{Point2D, Rect, Size2D};
|
use euclid::default::{Point2D, Rect, Size2D};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use style::values::computed::font::{FontStretch, FontStyle, FontWeight};
|
use style::values::computed::font::{FontStretch, FontStyle, FontWeight};
|
||||||
use webrender_api::FontInstanceFlags;
|
use webrender_api::{FontInstanceFlags, FontVariation};
|
||||||
|
|
||||||
use super::core_text_font_cache::CoreTextFontCache;
|
use super::core_text_font_cache::CoreTextFontCache;
|
||||||
use super::font_list::LocalFontIdentifier;
|
use super::font_list::LocalFontIdentifier;
|
||||||
|
@ -201,6 +201,7 @@ impl PlatformFontMethods for PlatformFont {
|
||||||
font_identifier: FontIdentifier,
|
font_identifier: FontIdentifier,
|
||||||
data: &FontData,
|
data: &FontData,
|
||||||
requested_size: Option<Au>,
|
requested_size: Option<Au>,
|
||||||
|
_variations: &[FontVariation],
|
||||||
) -> Result<PlatformFont, &'static str> {
|
) -> Result<PlatformFont, &'static str> {
|
||||||
Self::new(font_identifier, Some(data), requested_size)
|
Self::new(font_identifier, Some(data), requested_size)
|
||||||
}
|
}
|
||||||
|
@ -208,6 +209,7 @@ impl PlatformFontMethods for PlatformFont {
|
||||||
fn new_from_local_font_identifier(
|
fn new_from_local_font_identifier(
|
||||||
font_identifier: LocalFontIdentifier,
|
font_identifier: LocalFontIdentifier,
|
||||||
requested_size: Option<Au>,
|
requested_size: Option<Au>,
|
||||||
|
_variations: &[FontVariation],
|
||||||
) -> Result<PlatformFont, &'static str> {
|
) -> Result<PlatformFont, &'static str> {
|
||||||
Self::new(FontIdentifier::Local(font_identifier), None, requested_size)
|
Self::new(FontIdentifier::Local(font_identifier), None, requested_size)
|
||||||
}
|
}
|
||||||
|
@ -353,6 +355,11 @@ impl PlatformFontMethods for PlatformFont {
|
||||||
Size2D::new(rect.size.width as f32, rect.size.height as f32),
|
Size2D::new(rect.size.width as f32, rect.size.height as f32),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn variations(&self) -> &[FontVariation] {
|
||||||
|
// FIXME: Implement this for macos
|
||||||
|
&[]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) trait CoreTextFontTraitsMapping {
|
pub(super) trait CoreTextFontTraitsMapping {
|
||||||
|
|
|
@ -21,7 +21,7 @@ use style::computed_values::font_weight::T as StyleFontWeight;
|
||||||
use style::values::computed::font::FontStyle as StyleFontStyle;
|
use style::values::computed::font::FontStyle as StyleFontStyle;
|
||||||
use truetype::tables::WindowsMetrics;
|
use truetype::tables::WindowsMetrics;
|
||||||
use truetype::value::Read;
|
use truetype::value::Read;
|
||||||
use webrender_api::FontInstanceFlags;
|
use webrender_api::{FontInstanceFlags, FontVariation};
|
||||||
|
|
||||||
use super::font_list::LocalFontIdentifier;
|
use super::font_list::LocalFontIdentifier;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -116,6 +116,7 @@ impl PlatformFontMethods for PlatformFont {
|
||||||
_font_identifier: FontIdentifier,
|
_font_identifier: FontIdentifier,
|
||||||
data: &FontData,
|
data: &FontData,
|
||||||
pt_size: Option<Au>,
|
pt_size: Option<Au>,
|
||||||
|
_variations: &[FontVariation],
|
||||||
) -> Result<Self, &'static str> {
|
) -> Result<Self, &'static str> {
|
||||||
let font_face = FontFile::new_from_buffer(Arc::new(data.clone()))
|
let font_face = FontFile::new_from_buffer(Arc::new(data.clone()))
|
||||||
.ok_or("Could not create FontFile")?
|
.ok_or("Could not create FontFile")?
|
||||||
|
@ -130,6 +131,7 @@ impl PlatformFontMethods for PlatformFont {
|
||||||
fn new_from_local_font_identifier(
|
fn new_from_local_font_identifier(
|
||||||
font_identifier: LocalFontIdentifier,
|
font_identifier: LocalFontIdentifier,
|
||||||
pt_size: Option<Au>,
|
pt_size: Option<Au>,
|
||||||
|
_variations: &[FontVariation],
|
||||||
) -> Result<PlatformFont, &'static str> {
|
) -> Result<PlatformFont, &'static str> {
|
||||||
let font_face = FontCollection::system()
|
let font_face = FontCollection::system()
|
||||||
.font_from_descriptor(&font_identifier.font_descriptor)
|
.font_from_descriptor(&font_identifier.font_descriptor)
|
||||||
|
@ -320,4 +322,9 @@ impl PlatformFontMethods for PlatformFont {
|
||||||
Size2D::new(width, height),
|
Size2D::new(width, height),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn variations(&self) -> &[FontVariation] {
|
||||||
|
// FIXME: implement this for windows
|
||||||
|
&[]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,9 @@ use harfbuzz_sys::{
|
||||||
hb_face_create_for_tables, hb_face_destroy, hb_face_t, hb_feature_t, hb_font_create,
|
hb_face_create_for_tables, hb_face_destroy, hb_face_t, hb_feature_t, hb_font_create,
|
||||||
hb_font_destroy, hb_font_funcs_create, hb_font_funcs_set_glyph_h_advance_func,
|
hb_font_destroy, hb_font_funcs_create, hb_font_funcs_set_glyph_h_advance_func,
|
||||||
hb_font_funcs_set_nominal_glyph_func, hb_font_funcs_t, hb_font_set_funcs, hb_font_set_ppem,
|
hb_font_funcs_set_nominal_glyph_func, hb_font_funcs_t, hb_font_set_funcs, hb_font_set_ppem,
|
||||||
hb_font_set_scale, hb_font_t, hb_glyph_info_t, hb_glyph_position_t, hb_ot_layout_get_baseline,
|
hb_font_set_scale, hb_font_set_variations, hb_font_t, hb_glyph_info_t, hb_glyph_position_t,
|
||||||
hb_position_t, hb_script_from_iso15924_tag, hb_shape, hb_tag_t,
|
hb_ot_layout_get_baseline, hb_position_t, hb_script_from_iso15924_tag, hb_shape, hb_tag_t,
|
||||||
|
hb_variation_t,
|
||||||
};
|
};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use num_traits::Zero;
|
use num_traits::Zero;
|
||||||
|
@ -32,13 +33,14 @@ use crate::font::advance_for_shaped_glyph;
|
||||||
use crate::platform::font::FontTable;
|
use crate::platform::font::FontTable;
|
||||||
use crate::{
|
use crate::{
|
||||||
BASE, ByteIndex, Font, FontBaseline, FontTableMethods, FontTableTag, GlyphData, GlyphId,
|
BASE, ByteIndex, Font, FontBaseline, FontTableMethods, FontTableTag, GlyphData, GlyphId,
|
||||||
GlyphStore, KERN, ShapingFlags, ShapingOptions, fixed_to_float, float_to_fixed, ot_tag,
|
GlyphStore, KERN, OpenTypeTableTag, ShapingFlags, ShapingOptions, fixed_to_float,
|
||||||
|
float_to_fixed, ot_tag,
|
||||||
};
|
};
|
||||||
|
|
||||||
const NO_GLYPH: i32 = -1;
|
const NO_GLYPH: i32 = -1;
|
||||||
const LIGA: u32 = ot_tag!('l', 'i', 'g', 'a');
|
const LIGA: OpenTypeTableTag = ot_tag!('l', 'i', 'g', 'a');
|
||||||
const HB_OT_TAG_DEFAULT_SCRIPT: u32 = ot_tag!('D', 'F', 'L', 'T');
|
const HB_OT_TAG_DEFAULT_SCRIPT: OpenTypeTableTag = ot_tag!('D', 'F', 'L', 'T');
|
||||||
const HB_OT_TAG_DEFAULT_LANGUAGE: u32 = ot_tag!('d', 'f', 'l', 't');
|
const HB_OT_TAG_DEFAULT_LANGUAGE: OpenTypeTableTag = ot_tag!('d', 'f', 'l', 't');
|
||||||
|
|
||||||
pub struct ShapedGlyphData {
|
pub struct ShapedGlyphData {
|
||||||
count: usize,
|
count: usize,
|
||||||
|
@ -155,18 +157,17 @@ impl Drop for Shaper {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Shaper {
|
impl Shaper {
|
||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)] // Has an unsafe block inside
|
pub fn new(font: &Font) -> Shaper {
|
||||||
pub fn new(font: *const Font) -> Shaper {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let hb_face: *mut hb_face_t = hb_face_create_for_tables(
|
let hb_face: *mut hb_face_t = hb_face_create_for_tables(
|
||||||
Some(font_table_func),
|
Some(font_table_func),
|
||||||
font as *const c_void as *mut c_void,
|
font as *const Font as *mut c_void,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
let hb_font: *mut hb_font_t = hb_font_create(hb_face);
|
let hb_font: *mut hb_font_t = hb_font_create(hb_face);
|
||||||
|
|
||||||
// Set points-per-em. if zero, performs no hinting in that direction.
|
// Set points-per-em. if zero, performs no hinting in that direction.
|
||||||
let pt_size = (*font).descriptor.pt_size.to_f64_px();
|
let pt_size = font.descriptor.pt_size.to_f64_px();
|
||||||
hb_font_set_ppem(hb_font, pt_size as c_uint, pt_size as c_uint);
|
hb_font_set_ppem(hb_font, pt_size as c_uint, pt_size as c_uint);
|
||||||
|
|
||||||
// Set scaling. Note that this takes 16.16 fixed point.
|
// Set scaling. Note that this takes 16.16 fixed point.
|
||||||
|
@ -180,10 +181,26 @@ impl Shaper {
|
||||||
hb_font_set_funcs(
|
hb_font_set_funcs(
|
||||||
hb_font,
|
hb_font,
|
||||||
HB_FONT_FUNCS.0,
|
HB_FONT_FUNCS.0,
|
||||||
font as *mut Font as *mut c_void,
|
font as *const Font as *mut c_void,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if servo_config::pref!(layout_variable_fonts_enabled) {
|
||||||
|
let variations = &font.variations();
|
||||||
|
if !variations.is_empty() {
|
||||||
|
let variations: Vec<_> = variations
|
||||||
|
.iter()
|
||||||
|
.map(|variation| hb_variation_t {
|
||||||
|
tag: variation.tag,
|
||||||
|
|
||||||
|
value: variation.value,
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
hb_font_set_variations(hb_font, variations.as_ptr(), variations.len() as u32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Shaper {
|
Shaper {
|
||||||
hb_face,
|
hb_face,
|
||||||
hb_font,
|
hb_font,
|
||||||
|
@ -270,6 +287,7 @@ impl Shaper {
|
||||||
features.as_mut_ptr(),
|
features.as_mut_ptr(),
|
||||||
features.len() as u32,
|
features.len() as u32,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.save_glyph_results(text, options, glyphs, hb_buffer);
|
self.save_glyph_results(text, options, glyphs, hb_buffer);
|
||||||
hb_buffer_destroy(hb_buffer);
|
hb_buffer_destroy(hb_buffer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ use style::values::computed::font::{
|
||||||
};
|
};
|
||||||
use style::values::computed::{FontStretch, FontWeight};
|
use style::values::computed::{FontStretch, FontWeight};
|
||||||
use style::values::specified::FontStretch as SpecifiedFontStretch;
|
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::FontDescriptor;
|
||||||
use crate::font_store::FontStore;
|
use crate::font_store::FontStore;
|
||||||
|
@ -65,6 +65,7 @@ pub enum SystemFontServiceMessage {
|
||||||
FontIdentifier,
|
FontIdentifier,
|
||||||
Au,
|
Au,
|
||||||
FontInstanceFlags,
|
FontInstanceFlags,
|
||||||
|
Vec<FontVariation>,
|
||||||
IpcSender<FontInstanceKey>,
|
IpcSender<FontInstanceKey>,
|
||||||
),
|
),
|
||||||
GetFontKey(IpcSender<FontKey>),
|
GetFontKey(IpcSender<FontKey>),
|
||||||
|
@ -94,7 +95,7 @@ pub struct SystemFontService {
|
||||||
local_families: FontStore,
|
local_families: FontStore,
|
||||||
compositor_api: CrossProcessCompositorApi,
|
compositor_api: CrossProcessCompositorApi,
|
||||||
webrender_fonts: HashMap<FontIdentifier, FontKey>,
|
webrender_fonts: HashMap<FontIdentifier, FontKey>,
|
||||||
font_instances: HashMap<(FontKey, Au), FontInstanceKey>,
|
font_instances: HashMap<(FontKey, Au, Vec<FontVariation>), FontInstanceKey>,
|
||||||
generic_fonts: ResolvedGenericFontFamilies,
|
generic_fonts: ResolvedGenericFontFamilies,
|
||||||
|
|
||||||
/// This is an optimization that allows the [`SystemFontService`] to send font data to
|
/// This is an optimization that allows the [`SystemFontService`] to send font data to
|
||||||
|
@ -176,8 +177,15 @@ impl SystemFontService {
|
||||||
let _ =
|
let _ =
|
||||||
result_sender.send(self.get_font_templates(font_descriptor, font_family));
|
result_sender.send(self.get_font_templates(font_descriptor, font_family));
|
||||||
},
|
},
|
||||||
SystemFontServiceMessage::GetFontInstance(identifier, pt_size, flags, result) => {
|
SystemFontServiceMessage::GetFontInstance(
|
||||||
let _ = result.send(self.get_font_instance(identifier, pt_size, flags));
|
identifier,
|
||||||
|
pt_size,
|
||||||
|
flags,
|
||||||
|
variations,
|
||||||
|
result,
|
||||||
|
) => {
|
||||||
|
let _ =
|
||||||
|
result.send(self.get_font_instance(identifier, pt_size, flags, variations));
|
||||||
},
|
},
|
||||||
SystemFontServiceMessage::GetFontKey(result_sender) => {
|
SystemFontServiceMessage::GetFontKey(result_sender) => {
|
||||||
self.fetch_new_keys();
|
self.fetch_new_keys();
|
||||||
|
@ -281,6 +289,7 @@ impl SystemFontService {
|
||||||
identifier: FontIdentifier,
|
identifier: FontIdentifier,
|
||||||
pt_size: Au,
|
pt_size: Au,
|
||||||
flags: FontInstanceFlags,
|
flags: FontInstanceFlags,
|
||||||
|
variations: Vec<FontVariation>,
|
||||||
) -> FontInstanceKey {
|
) -> FontInstanceKey {
|
||||||
self.fetch_new_keys();
|
self.fetch_new_keys();
|
||||||
|
|
||||||
|
@ -301,7 +310,7 @@ impl SystemFontService {
|
||||||
|
|
||||||
*self
|
*self
|
||||||
.font_instances
|
.font_instances
|
||||||
.entry((font_key, pt_size))
|
.entry((font_key, pt_size, variations.clone()))
|
||||||
.or_insert_with(|| {
|
.or_insert_with(|| {
|
||||||
let font_instance_key = self.free_font_instance_keys.pop().unwrap();
|
let font_instance_key = self.free_font_instance_keys.pop().unwrap();
|
||||||
compositor_api.add_font_instance(
|
compositor_api.add_font_instance(
|
||||||
|
@ -309,6 +318,7 @@ impl SystemFontService {
|
||||||
font_key,
|
font_key,
|
||||||
pt_size.to_f32_px(),
|
pt_size.to_f32_px(),
|
||||||
flags,
|
flags,
|
||||||
|
variations,
|
||||||
);
|
);
|
||||||
font_instance_key
|
font_instance_key
|
||||||
})
|
})
|
||||||
|
@ -473,6 +483,7 @@ impl SystemFontServiceProxy {
|
||||||
identifier: FontIdentifier,
|
identifier: FontIdentifier,
|
||||||
size: Au,
|
size: Au,
|
||||||
flags: FontInstanceFlags,
|
flags: FontInstanceFlags,
|
||||||
|
variations: Vec<FontVariation>,
|
||||||
) -> FontInstanceKey {
|
) -> FontInstanceKey {
|
||||||
let (response_chan, response_port) = ipc::channel().expect("failed to create IPC channel");
|
let (response_chan, response_port) = ipc::channel().expect("failed to create IPC channel");
|
||||||
self.sender
|
self.sender
|
||||||
|
@ -481,6 +492,7 @@ impl SystemFontServiceProxy {
|
||||||
identifier,
|
identifier,
|
||||||
size,
|
size,
|
||||||
flags,
|
flags,
|
||||||
|
variations,
|
||||||
response_chan,
|
response_chan,
|
||||||
))
|
))
|
||||||
.expect("failed to send message to system font service");
|
.expect("failed to send message to system font service");
|
||||||
|
|
|
@ -27,7 +27,7 @@ fn make_font(path: PathBuf) -> Font {
|
||||||
let data = FontData::from_bytes(&bytes);
|
let data = FontData::from_bytes(&bytes);
|
||||||
|
|
||||||
let identifier = FontIdentifier::Web(ServoUrl::from_file_path(path).unwrap());
|
let identifier = FontIdentifier::Web(ServoUrl::from_file_path(path).unwrap());
|
||||||
let platform_font = PlatformFont::new_from_data(identifier.clone(), &data, None).unwrap();
|
let platform_font = PlatformFont::new_from_data(identifier.clone(), &data, None, &[]).unwrap();
|
||||||
|
|
||||||
let template = FontTemplate {
|
let template = FontTemplate {
|
||||||
identifier,
|
identifier,
|
||||||
|
@ -40,6 +40,7 @@ fn make_font(path: PathBuf) -> Font {
|
||||||
style: FontStyle::normal(),
|
style: FontStyle::normal(),
|
||||||
variant: FontVariantCaps::Normal,
|
variant: FontVariantCaps::Normal,
|
||||||
pt_size: Au::from_px(24),
|
pt_size: Au::from_px(24),
|
||||||
|
variation_settings: vec![],
|
||||||
};
|
};
|
||||||
Font::new(FontTemplateRef::new(template), descriptor, Some(data), None).unwrap()
|
Font::new(FontTemplateRef::new(template), descriptor, Some(data), None).unwrap()
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,7 @@ mod font_context {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
SystemFontServiceMessage::GetFontInstanceKey(result_sender) |
|
SystemFontServiceMessage::GetFontInstanceKey(result_sender) |
|
||||||
SystemFontServiceMessage::GetFontInstance(_, _, _, result_sender) => {
|
SystemFontServiceMessage::GetFontInstance(_, _, _, _, result_sender) => {
|
||||||
let _ = result_sender.send(FontInstanceKey(IdNamespace(0), 0));
|
let _ = result_sender.send(FontInstanceKey(IdNamespace(0), 0));
|
||||||
},
|
},
|
||||||
SystemFontServiceMessage::GetFontKey(result_sender) => {
|
SystemFontServiceMessage::GetFontKey(result_sender) => {
|
||||||
|
@ -187,8 +187,11 @@ mod font_context {
|
||||||
path: path.to_str().expect("Could not load test font").into(),
|
path: path.to_str().expect("Could not load test font").into(),
|
||||||
variation_index: 0,
|
variation_index: 0,
|
||||||
};
|
};
|
||||||
let handle =
|
let handle = PlatformFont::new_from_local_font_identifier(
|
||||||
PlatformFont::new_from_local_font_identifier(local_font_identifier.clone(), None)
|
local_font_identifier.clone(),
|
||||||
|
None,
|
||||||
|
&[],
|
||||||
|
)
|
||||||
.expect("Could not load test font");
|
.expect("Could not load test font");
|
||||||
|
|
||||||
family.add_template(FontTemplate::new(
|
family.add_template(FontTemplate::new(
|
||||||
|
@ -352,6 +355,7 @@ mod font_context {
|
||||||
style: FontStyle::normal(),
|
style: FontStyle::normal(),
|
||||||
variant: FontVariantCaps::Normal,
|
variant: FontVariantCaps::Normal,
|
||||||
pt_size: Au(10),
|
pt_size: Au(10),
|
||||||
|
variation_settings: vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
let family = SingleFontFamily::FamilyName(FamilyName {
|
let family = SingleFontFamily::FamilyName(FamilyName {
|
||||||
|
|
|
@ -36,7 +36,7 @@ fn test_font_template_descriptor() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let data = FontData::from_bytes(&bytes);
|
let data = FontData::from_bytes(&bytes);
|
||||||
|
|
||||||
let handle = PlatformFont::new_from_data(identifier, &data, None).unwrap();
|
let handle = PlatformFont::new_from_data(identifier, &data, None, &[]).unwrap();
|
||||||
handle.descriptor()
|
handle.descriptor()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -432,6 +432,7 @@ impl TextRun {
|
||||||
&shaping_options,
|
&shaping_options,
|
||||||
font,
|
font,
|
||||||
);
|
);
|
||||||
|
|
||||||
segment
|
segment
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
|
@ -837,6 +837,7 @@ malloc_size_of_is_webrender_malloc_size_of!(webrender_api::LineStyle);
|
||||||
malloc_size_of_is_webrender_malloc_size_of!(webrender_api::MixBlendMode);
|
malloc_size_of_is_webrender_malloc_size_of!(webrender_api::MixBlendMode);
|
||||||
malloc_size_of_is_webrender_malloc_size_of!(webrender_api::NormalBorder);
|
malloc_size_of_is_webrender_malloc_size_of!(webrender_api::NormalBorder);
|
||||||
malloc_size_of_is_webrender_malloc_size_of!(webrender_api::RepeatMode);
|
malloc_size_of_is_webrender_malloc_size_of!(webrender_api::RepeatMode);
|
||||||
|
malloc_size_of_is_webrender_malloc_size_of!(webrender_api::FontVariation);
|
||||||
|
|
||||||
macro_rules! malloc_size_of_is_stylo_malloc_size_of(
|
macro_rules! malloc_size_of_is_stylo_malloc_size_of(
|
||||||
($($ty:ty),+) => (
|
($($ty:ty),+) => (
|
||||||
|
|
|
@ -122,6 +122,7 @@ def add_css_properties_attributes(css_properties_json: str, parser: Parser) -> N
|
||||||
["layout.css.transition-behavior.enabled", "layout_css_transition_behavior_enabled"],
|
["layout.css.transition-behavior.enabled", "layout_css_transition_behavior_enabled"],
|
||||||
["layout.writing-mode.enabled", "layout_writing_mode_enabled"],
|
["layout.writing-mode.enabled", "layout_writing_mode_enabled"],
|
||||||
["layout.container-queries.enabled", "layout_container_queries_enabled"],
|
["layout.container-queries.enabled", "layout_container_queries_enabled"],
|
||||||
|
["layout.variable_fonts.enabled", "layout_variable_fonts_enabled"]
|
||||||
]
|
]
|
||||||
for mapping in MAPPING:
|
for mapping in MAPPING:
|
||||||
if mapping[0] == preference_name:
|
if mapping[0] == preference_name:
|
||||||
|
|
|
@ -14,7 +14,7 @@ use log::warn;
|
||||||
use malloc_size_of_derive::MallocSizeOf;
|
use malloc_size_of_derive::MallocSizeOf;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use strum_macros::IntoStaticStr;
|
use strum_macros::IntoStaticStr;
|
||||||
use webrender_api::DocumentId;
|
use webrender_api::{DocumentId, FontVariation};
|
||||||
|
|
||||||
pub mod display_list;
|
pub mod display_list;
|
||||||
pub mod rendering_context;
|
pub mod rendering_context;
|
||||||
|
@ -132,7 +132,13 @@ pub enum CompositorMsg {
|
||||||
/// Add a system font with the given font key and handle.
|
/// Add a system font with the given font key and handle.
|
||||||
AddSystemFont(FontKey, NativeFontHandle),
|
AddSystemFont(FontKey, NativeFontHandle),
|
||||||
/// Add an instance of a font with the given instance key.
|
/// Add an instance of a font with the given instance key.
|
||||||
AddFontInstance(FontInstanceKey, FontKey, f32, FontInstanceFlags),
|
AddFontInstance(
|
||||||
|
FontInstanceKey,
|
||||||
|
FontKey,
|
||||||
|
f32,
|
||||||
|
FontInstanceFlags,
|
||||||
|
Vec<FontVariation>,
|
||||||
|
),
|
||||||
/// Remove the given font resources from our WebRender instance.
|
/// Remove the given font resources from our WebRender instance.
|
||||||
RemoveFonts(Vec<FontKey>, Vec<FontInstanceKey>),
|
RemoveFonts(Vec<FontKey>, Vec<FontInstanceKey>),
|
||||||
/// Measure the current memory usage associated with the compositor.
|
/// Measure the current memory usage associated with the compositor.
|
||||||
|
@ -303,12 +309,14 @@ impl CrossProcessCompositorApi {
|
||||||
font_key: FontKey,
|
font_key: FontKey,
|
||||||
size: f32,
|
size: f32,
|
||||||
flags: FontInstanceFlags,
|
flags: FontInstanceFlags,
|
||||||
|
variations: Vec<FontVariation>,
|
||||||
) {
|
) {
|
||||||
let _x = self.0.send(CompositorMsg::AddFontInstance(
|
let _x = self.0.send(CompositorMsg::AddFontInstance(
|
||||||
font_instance_key,
|
font_instance_key,
|
||||||
font_key,
|
font_key,
|
||||||
size,
|
size,
|
||||||
flags,
|
flags,
|
||||||
|
variations,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue