diff --git a/Cargo.lock b/Cargo.lock index e40ebd0722e..0edef019254 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2174,9 +2174,9 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "dwrote" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe1f192fcce01590bd8d839aca53ce0d11d803bf291b2a6c4ad925a8f0024be" +checksum = "20c93d234bac0cdd0e2ac08bc8a5133f8df2169e95b262dfcea5e5cb7855672f" dependencies = [ "lazy_static", "libc", @@ -4903,7 +4903,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -10079,7 +10079,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/components/fonts/Cargo.toml b/components/fonts/Cargo.toml index e4c27ca6c6f..7cb96dab891 100644 --- a/components/fonts/Cargo.toml +++ b/components/fonts/Cargo.toml @@ -73,7 +73,7 @@ fontconfig_sys = { package = "yeslogic-fontconfig-sys", version = "6" } xml-rs = "0.8" [target.'cfg(target_os = "windows")'.dependencies] -dwrote = "0.11.2" +dwrote = "0.11.4" truetype = { version = "0.47.3", features = ["ignore-invalid-language-ids"] } [lints.rust] diff --git a/components/fonts/platform/windows/font.rs b/components/fonts/platform/windows/font.rs index 55d90886225..09e0e8f1642 100644 --- a/components/fonts/platform/windows/font.rs +++ b/components/fonts/platform/windows/font.rs @@ -12,7 +12,9 @@ use std::ops::Deref; use std::sync::Arc; use app_units::Au; -use dwrote::{FontCollection, FontFace, FontFile}; +use dwrote::{ + DWRITE_FONT_AXIS_VALUE, DWRITE_FONT_SIMULATIONS_NONE, FontCollection, FontFace, FontFile, +}; use euclid::default::{Point2D, Rect, Size2D}; use log::{debug, warn}; use style::Zero; @@ -67,6 +69,7 @@ pub struct PlatformFont { em_size: f32, du_to_px: f32, scaled_du_to_px: f32, + variations: Vec, } // Based on information from the Skia codebase, it seems that DirectWrite APIs from @@ -92,7 +95,11 @@ impl Deref for Nondebug { } impl PlatformFont { - fn new(font_face: FontFace, pt_size: Option) -> Result { + fn new( + font_face: FontFace, + pt_size: Option, + variations: Vec, + ) -> Result { let pt_size = pt_size.unwrap_or(au_from_pt(12.)); let du_per_em = font_face.metrics().metrics0().designUnitsPerEm as f32; @@ -107,8 +114,51 @@ impl PlatformFont { em_size, du_to_px: design_units_to_pixels, scaled_du_to_px: scaled_design_units_to_pixels, + variations, }) } + + fn new_with_variations( + font_face: FontFace, + pt_size: Option, + variations: &[FontVariation], + ) -> Result { + if variations.is_empty() { + return Self::new(font_face, pt_size, vec![]); + } + + // On FreeType and CoreText platforms, the platform layer is able to read the minimum, maxmimum, + // and default values of each axis. This doesn't seem possible here and it seems that Gecko + // also just sets the value of the axis based on the values from the style as well. + // + // dwrote (and presumably the Windows APIs) accept a reversed version of the table + // tag bytes, which means that `u32::swap_bytes` must be called here in order to + // use a byte order compatible with the rest of Servo. + let variations: Vec<_> = variations + .into_iter() + .map(|variation| DWRITE_FONT_AXIS_VALUE { + axisTag: variation.tag.swap_bytes(), + value: variation.value, + }) + .collect(); + + let Some(font_face) = + font_face.create_font_face_with_variations(DWRITE_FONT_SIMULATIONS_NONE, &variations) + else { + return Err("Could not adapt FontFace to given variations"); + }; + + let variations = font_face.variations().unwrap_or_default(); + let variations = variations + .iter() + .map(|dwrote_variation| FontVariation { + tag: dwrote_variation.axisTag.swap_bytes(), + value: dwrote_variation.value, + }) + .collect(); + + Self::new(font_face, pt_size, variations) + } } impl PlatformFontMethods for PlatformFont { @@ -116,22 +166,19 @@ impl PlatformFontMethods for PlatformFont { _font_identifier: FontIdentifier, data: &FontData, pt_size: Option, - _variations: &[FontVariation], + variations: &[FontVariation], ) -> Result { let font_face = FontFile::new_from_buffer(Arc::new(data.clone())) .ok_or("Could not create FontFile")? - .create_face( - 0, /* face_index */ - dwrote::DWRITE_FONT_SIMULATIONS_NONE, - ) + .create_face(0 /* face_index */, DWRITE_FONT_SIMULATIONS_NONE) .map_err(|_| "Could not create FontFace")?; - Self::new(font_face, pt_size) + Self::new_with_variations(font_face, pt_size, variations) } fn new_from_local_font_identifier( font_identifier: LocalFontIdentifier, pt_size: Option, - _variations: &[FontVariation], + variations: &[FontVariation], ) -> Result { let font_face = FontCollection::system() .font_from_descriptor(&font_identifier.font_descriptor) @@ -139,7 +186,7 @@ impl PlatformFontMethods for PlatformFont { .flatten() .ok_or("Could not create Font from descriptor")? .create_font_face(); - Self::new(font_face, pt_size) + Self::new_with_variations(font_face, pt_size, variations) } fn descriptor(&self) -> FontTemplateDescriptor { @@ -324,7 +371,6 @@ impl PlatformFontMethods for PlatformFont { } fn variations(&self) -> &[FontVariation] { - // FIXME: implement this for windows - &[] + &self.variations } }