diff --git a/components/style/font_face.rs b/components/style/font_face.rs index 27d8d4f1efc..38de34a3705 100644 --- a/components/style/font_face.rs +++ b/components/style/font_face.rs @@ -26,7 +26,7 @@ use style_traits::{Comma, CssWriter, OneOrMoreSeparated, ParseError}; use style_traits::{StyleParseErrorKind, ToCss}; use values::computed::font::FamilyName; #[cfg(feature = "gecko")] -use values::specified::font::{SpecifiedFontFeatureSettings, FontVariationSettings}; +use values::specified::font::{SpecifiedFontFeatureSettings, SpecifiedFontVariationSettings}; use values::specified::url::SpecifiedUrl; /// A source for a font-face rule. @@ -397,7 +397,7 @@ font_face_descriptors! { "font-feature-settings" feature_settings / mFontFeatureSettings: SpecifiedFontFeatureSettings, /// The variation settings of this font face. - "font-variation-settings" variation_settings / mFontVariationSettings: FontVariationSettings, + "font-variation-settings" variation_settings / mFontVariationSettings: SpecifiedFontVariationSettings, /// The language override of this font face. "font-language-override" language_override / mFontLanguageOverride: font_language_override::SpecifiedValue, diff --git a/components/style/gecko/rules.rs b/components/style/gecko/rules.rs index f231f2a7dfe..9460ab2e74b 100644 --- a/components/style/gecko/rules.rs +++ b/components/style/gecko/rules.rs @@ -22,7 +22,7 @@ use std::str; use str::CssStringWriter; use values::computed::font::FamilyName; use values::generics::font::FontTag; -use values::specified::font::{FontVariationSettings, SpecifiedFontFeatureSettings}; +use values::specified::font::{SpecifiedFontVariationSettings, SpecifiedFontFeatureSettings}; /// A @font-face rule pub type FontFaceRule = RefPtr; @@ -74,7 +74,7 @@ impl ToNsCssValue for SpecifiedFontFeatureSettings { } } -impl ToNsCssValue for FontVariationSettings { +impl ToNsCssValue for SpecifiedFontVariationSettings { fn convert(self, nscssvalue: &mut nsCSSValue) { if self.0.is_empty() { nscssvalue.set_normal(); diff --git a/components/style/properties/data.py b/components/style/properties/data.py index 3b4c45029cb..4e257a5ea40 100644 --- a/components/style/properties/data.py +++ b/components/style/properties/data.py @@ -19,7 +19,8 @@ SYSTEM_FONT_LONGHANDS = """font_family font_size font_style font_size_adjust font_variant_alternates font_variant_ligatures font_variant_east_asian font_variant_numeric font_language_override - font_feature_settings font_optical_sizing""".split() + font_feature_settings font_variation_settings + font_optical_sizing""".split() def maybe_moz_logical_alias(product, side, prop): diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index 1e24ca45741..50a12c9efdd 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -167,6 +167,7 @@ ${helpers.predefined_type("font-variation-settings", products="gecko", gecko_pref="layout.css.font-variations.enabled", initial_value="computed::FontVariationSettings::normal()", + initial_specified_value="specified::FontVariationSettings::normal()", animation_value_type="ComputedValue", flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER", spec="${variation_spec}")} @@ -371,6 +372,7 @@ ${helpers.predefined_type("-x-text-zoom", font_language_override: longhands::font_language_override::computed_value ::T(system.languageOverride), font_feature_settings: longhands::font_feature_settings::get_initial_value(), + font_variation_settings: longhands::font_variation_settings::get_initial_value(), font_variant_alternates: longhands::font_variant_alternates::get_initial_value(), system_font: *self, default_font_type: system.fontlist.mDefaultFontType, diff --git a/components/style/properties/shorthand/font.mako.rs b/components/style/properties/shorthand/font.mako.rs index 1a4c0d04118..c2f8a09a6b0 100644 --- a/components/style/properties/shorthand/font.mako.rs +++ b/components/style/properties/shorthand/font.mako.rs @@ -17,7 +17,8 @@ ${'font-variant-numeric' if product == 'gecko' else ''} ${'font-variant-position' if product == 'gecko' else ''} ${'font-language-override' if product == 'gecko' else ''} - ${'font-feature-settings' if product == 'gecko' else ''}" + ${'font-feature-settings' if product == 'gecko' else ''} + ${'font-variation-settings' if product == 'gecko' else ''}" spec="https://drafts.csswg.org/css-fonts-3/#propdef-font"> use parser::Parse; use properties::longhands::{font_family, font_style, font_weight, font_stretch}; @@ -32,7 +33,7 @@ variant_alternates variant_east_asian \ variant_ligatures variant_numeric \ variant_position feature_settings \ - optical_sizing".split() + variation_settings optical_sizing".split() %> % if product == "gecko": % for prop in gecko_sub_properties: @@ -162,9 +163,14 @@ return Ok(()); } } + if let Some(v) = self.font_variation_settings { + if v != &font_variation_settings::get_initial_specified_value() { + return Ok(()); + } + } % for name in gecko_sub_properties: - % if name != "optical_sizing": + % if name != "optical_sizing" and name != "variation_settings": if self.font_${name} != &font_${name}::get_initial_specified_value() { return Ok(()); } @@ -203,7 +209,7 @@ let mut all = true; % for prop in SYSTEM_FONT_LONGHANDS: - % if prop == "font_optical_sizing": + % if prop == "font_optical_sizing" or prop == "font_variation_settings": if let Some(value) = self.${prop} { % else: { diff --git a/components/style/values/specified/font.rs b/components/style/values/specified/font.rs index 36d0ae7c698..ce634e510ae 100644 --- a/components/style/values/specified/font.rs +++ b/components/style/values/specified/font.rs @@ -1653,7 +1653,7 @@ impl Parse for FontVariantNumeric { } } -/// This property provides low-level control over OpenType or TrueType font variations. +/// This property provides low-level control over OpenType or TrueType font features. pub type SpecifiedFontFeatureSettings = FontSettings>; /// Define initial settings that apply when the font defined by an @font-face @@ -1910,7 +1910,71 @@ impl Parse for FontLanguageOverride { /// This property provides low-level control over OpenType or TrueType font /// variations. -pub type FontVariationSettings = FontSettings>; +pub type SpecifiedFontVariationSettings = FontSettings>; + +/// Define initial settings that apply when the font defined by an @font-face +/// rule is rendered. +#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)] +pub enum FontVariationSettings { + /// Value of `FontSettings` + Value(SpecifiedFontVariationSettings), + /// System font + System(SystemFont) +} + +impl FontVariationSettings { + #[inline] + /// Get default value of `font-variation-settings` as normal + pub fn normal() -> FontVariationSettings { + FontVariationSettings::Value(FontSettings::normal()) + } + + /// Get `font-variation-settings` with system font + pub fn system_font(f: SystemFont) -> Self { + FontVariationSettings::System(f) + } + + /// Get system font + pub fn get_system(&self) -> Option { + if let FontVariationSettings::System(s) = *self { + Some(s) + } else { + None + } + } +} + +impl ToComputedValue for FontVariationSettings { + type ComputedValue = computed::FontVariationSettings; + + fn to_computed_value(&self, context: &Context) -> computed::FontVariationSettings { + match *self { + FontVariationSettings::Value(ref v) => v.to_computed_value(context), + FontVariationSettings::System(_) => { + #[cfg(feature = "gecko")] { + context.cached_system_font.as_ref().unwrap().font_variation_settings.clone() + } + #[cfg(feature = "servo")] { + unreachable!() + } + } + } + } + + fn from_computed_value(other: &computed::FontVariationSettings) -> Self { + FontVariationSettings::Value(ToComputedValue::from_computed_value(other)) + } +} + +impl Parse for FontVariationSettings { + /// normal | # + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't> + ) -> Result> { + SpecifiedFontVariationSettings::parse(context, input).map(FontVariationSettings::Value) + } +} fn parse_one_feature_value<'i, 't>( context: &ParserContext, diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 093e558488d..40f5bae66eb 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -4857,7 +4857,7 @@ pub extern "C" fn Servo_ParseFontDescriptor( use style::font_face::{FontDisplay, FontWeight, Source}; use style::properties::longhands::font_language_override; use style::values::computed::font::FamilyName; - use style::values::specified::font::{SpecifiedFontFeatureSettings, FontVariationSettings}; + use style::values::specified::font::{SpecifiedFontFeatureSettings, SpecifiedFontVariationSettings}; let string = unsafe { (*value).to_string() }; let mut input = ParserInput::new(&string); @@ -4907,7 +4907,7 @@ pub extern "C" fn Servo_ParseFontDescriptor( eCSSFontDesc_Src / Vec, eCSSFontDesc_UnicodeRange / Vec, eCSSFontDesc_FontFeatureSettings / SpecifiedFontFeatureSettings, - eCSSFontDesc_FontVariationSettings / FontVariationSettings, + eCSSFontDesc_FontVariationSettings / SpecifiedFontVariationSettings, eCSSFontDesc_FontLanguageOverride / font_language_override::SpecifiedValue, eCSSFontDesc_Display / FontDisplay, ] diff --git a/ports/geckolib/tests/size_of.rs b/ports/geckolib/tests/size_of.rs index 054dee754ec..0f24603fb4e 100644 --- a/ports/geckolib/tests/size_of.rs +++ b/ports/geckolib/tests/size_of.rs @@ -40,7 +40,7 @@ size_of_test!(test_size_of_rule_node, RuleNode, 80); // This is huge, but we allocate it on the stack and then never move it, // we only pass `&mut SourcePropertyDeclaration` references around. -size_of_test!(test_size_of_parsed_declaration, style::properties::SourcePropertyDeclaration, 576); +size_of_test!(test_size_of_parsed_declaration, style::properties::SourcePropertyDeclaration, 608); size_of_test!(test_size_of_computed_image, computed::image::Image, 40); size_of_test!(test_size_of_specified_image, specified::image::Image, 40);