diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 7a864c06d27..a88aec3b684 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -1008,26 +1008,7 @@ fn static_assert() { ${impl_simple("font_variant_alternates", "mFont.variantAlternates")} - pub fn set_font_size_adjust(&mut self, v: longhands::font_size_adjust::computed_value::T) { - use crate::properties::longhands::font_size_adjust::computed_value::T; - match v { - T::None => self.gecko.mFont.sizeAdjust = -1.0 as f32, - T::Number(n) => self.gecko.mFont.sizeAdjust = n, - } - } - - pub fn copy_font_size_adjust_from(&mut self, other: &Self) { - self.gecko.mFont.sizeAdjust = other.gecko.mFont.sizeAdjust; - } - - pub fn reset_font_size_adjust(&mut self, other: &Self) { - self.copy_font_size_adjust_from(other) - } - - pub fn clone_font_size_adjust(&self) -> longhands::font_size_adjust::computed_value::T { - use crate::properties::longhands::font_size_adjust::computed_value::T; - T::from_gecko_adjust(self.gecko.mFont.sizeAdjust) - } + ${impl_simple("font_size_adjust", "mFont.sizeAdjust")} #[allow(non_snake_case)] pub fn set__x_lang(&mut self, v: longhands::_x_lang::computed_value::T) { diff --git a/components/style/properties/longhands/font.mako.rs b/components/style/properties/longhands/font.mako.rs index f5304355e03..cf75bb59123 100644 --- a/components/style/properties/longhands/font.mako.rs +++ b/components/style/properties/longhands/font.mako.rs @@ -388,8 +388,7 @@ pub mod system_font { font_weight, font_stretch, font_style, - font_size_adjust: longhands::font_size_adjust::computed_value - ::T::from_gecko_adjust(system.sizeAdjust), + font_size_adjust: system.sizeAdjust, % for kwprop in kw_font_props: ${kwprop}: longhands::${kwprop}::computed_value::T::from_gecko_keyword( system.${to_camel_case_lower(kwprop.replace('font_', ''))} diff --git a/components/style/values/computed/font.rs b/components/style/values/computed/font.rs index 0bd177bcc85..d5906d0e89f 100644 --- a/components/style/values/computed/font.rs +++ b/components/style/values/computed/font.rs @@ -8,9 +8,9 @@ use crate::gecko_bindings::sugar::refptr::RefPtr; #[cfg(feature = "gecko")] use crate::gecko_bindings::{bindings, structs}; -use crate::values::animated::{ToAnimatedValue, ToAnimatedZero}; +use crate::values::animated::ToAnimatedValue; use crate::values::computed::{ - Angle, Context, Integer, Length, NonNegativeLength, NonNegativePercentage, + Angle, Context, Integer, Length, NonNegativeLength, NonNegativeNumber, NonNegativePercentage, }; use crate::values::computed::{Number, Percentage, ToComputedValue}; use crate::values::generics::font::{FeatureTagValue, FontSettings, VariationValue}; @@ -623,24 +623,7 @@ impl<'a> Iterator for FontFamilyNameIter<'a> { } /// Preserve the readability of text when font fallback occurs -#[derive( - Animate, - Clone, - ComputeSquaredDistance, - Copy, - Debug, - MallocSizeOf, - PartialEq, - ToCss, - ToResolvedValue, -)] -pub enum FontSizeAdjust { - #[animation(error)] - /// None variant - None, - /// Number variant - Number(CSSFloat), -} +pub type FontSizeAdjust = generics::GenericFontSizeAdjust; impl FontSizeAdjust { #[inline] @@ -648,40 +631,6 @@ impl FontSizeAdjust { pub fn none() -> Self { FontSizeAdjust::None } - - /// Get font-size-adjust with float number - pub fn from_gecko_adjust(gecko: f32) -> Self { - if gecko == -1.0 { - FontSizeAdjust::None - } else { - FontSizeAdjust::Number(gecko) - } - } -} - -impl ToAnimatedZero for FontSizeAdjust { - #[inline] - // FIXME(emilio): why? - fn to_animated_zero(&self) -> Result { - Err(()) - } -} - -impl ToAnimatedValue for FontSizeAdjust { - type AnimatedValue = Self; - - #[inline] - fn to_animated_value(self) -> Self { - self - } - - #[inline] - fn from_animated_value(animated: Self::AnimatedValue) -> Self { - match animated { - FontSizeAdjust::Number(number) => FontSizeAdjust::Number(number.max(0.)), - _ => animated, - } - } } /// Use VariantAlternatesList as computed type of FontVariantAlternates diff --git a/components/style/values/generics/font.rs b/components/style/values/generics/font.rs index 226613d4545..02f91068d38 100644 --- a/components/style/values/generics/font.rs +++ b/components/style/values/generics/font.rs @@ -202,3 +202,56 @@ pub enum FontStyle { #[value_info(starts_with_keyword)] Oblique(Angle), } + +/// A generic value for the `font-size-adjust` property. +/// +/// https://www.w3.org/TR/css-fonts-4/#font-size-adjust-prop +/// https://github.com/w3c/csswg-drafts/issues/6160 +#[allow(missing_docs)] +#[repr(u8)] +#[derive( + Animate, + Clone, + ComputeSquaredDistance, + Copy, + Debug, + Hash, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToAnimatedZero, + ToComputedValue, + ToResolvedValue, + ToShmem, +)] +pub enum GenericFontSizeAdjust { + #[animation(error)] + None, + // 'ex' is the implied basis, so the keyword can be omitted + Ex(Number), + #[value_info(starts_with_keyword)] + Cap(Number), + #[value_info(starts_with_keyword)] + Ch(Number), + #[value_info(starts_with_keyword)] + Ic(Number), +} + +impl ToCss for GenericFontSizeAdjust { + fn to_css(&self, dest: &mut CssWriter) -> fmt::Result + where + W: Write, + { + let (prefix, value) = match self { + Self::None => return dest.write_str("none"), + Self::Ex(v) => ("", v), + Self::Cap(v) => ("cap ", v), + Self::Ch(v) => ("ch ", v), + Self::Ic(v) => ("ic ", v), + }; + + dest.write_str(prefix)?; + value.to_css(dest) + } +} diff --git a/components/style/values/specified/font.rs b/components/style/values/specified/font.rs index b007bc3f5a4..52e0585b3b2 100644 --- a/components/style/values/specified/font.rs +++ b/components/style/values/specified/font.rs @@ -13,8 +13,9 @@ use crate::values::computed::font::{FamilyName, FontFamilyList, FontStyleAngle, use crate::values::computed::{font as computed, Length, NonNegativeLength}; use crate::values::computed::{Angle as ComputedAngle, Percentage as ComputedPercentage}; use crate::values::computed::{CSSPixelLength, Context, ToComputedValue}; +use crate::values::computed::FontSizeAdjust as ComputedFontSizeAdjust; use crate::values::generics::font::VariationValue; -use crate::values::generics::font::{self as generics, FeatureTagValue, FontSettings, FontTag}; +use crate::values::generics::font::{self as generics, FeatureTagValue, FontSettings, FontTag, GenericFontSizeAdjust}; use crate::values::generics::NonNegative; use crate::values::specified::length::{FontBaseSize, PX_PER_PT}; use crate::values::specified::{AllowQuirks, Angle, Integer, LengthPercentage}; @@ -761,16 +762,13 @@ impl Parse for FamilyName { } } -#[derive( - Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss, ToShmem, -)] /// Preserve the readability of text when font fallback occurs +#[derive( + Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem, +)] +#[allow(missing_docs)] pub enum FontSizeAdjust { - /// None variant - None, - /// Number variant - Number(NonNegativeNumber), - /// system font + Value(GenericFontSizeAdjust), #[css(skip)] System(SystemFont), } @@ -779,34 +777,53 @@ impl FontSizeAdjust { #[inline] /// Default value of font-size-adjust pub fn none() -> Self { - FontSizeAdjust::None + FontSizeAdjust::Value(GenericFontSizeAdjust::None) } system_font_methods!(FontSizeAdjust, font_size_adjust); } +impl Parse for FontSizeAdjust { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + let location = input.current_source_location(); + if let Ok(ident) = input.try_parse(|i| i.expect_ident_cloned()) { + let basis_enabled = static_prefs::pref!("layout.css.font-size-adjust.basis.enabled"); + let basis = match_ignore_ascii_case! { &ident, + "none" => return Ok(FontSizeAdjust::none()), + // Check for size adjustment basis keywords if enabled. + "ex" if basis_enabled => GenericFontSizeAdjust::Ex, + "cap" if basis_enabled => GenericFontSizeAdjust::Cap, + "ch" if basis_enabled => GenericFontSizeAdjust::Ch, + "ic" if basis_enabled => GenericFontSizeAdjust::Ic, + // Unknown (or disabled) keyword. + _ => return Err(location.new_custom_error( + ::selectors::parser::SelectorParseErrorKind::UnexpectedIdent(ident) + )), + }; + let value = NonNegativeNumber::parse(context, input)?; + return Ok(FontSizeAdjust::Value(basis(value))); + } + // Without a basis keyword, the number refers to the 'ex' metric. + let value = NonNegativeNumber::parse(context, input)?; + Ok(FontSizeAdjust::Value(GenericFontSizeAdjust::Ex(value))) + } +} + impl ToComputedValue for FontSizeAdjust { - type ComputedValue = computed::FontSizeAdjust; + type ComputedValue = ComputedFontSizeAdjust; fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { match *self { - FontSizeAdjust::None => computed::FontSizeAdjust::None, - FontSizeAdjust::Number(ref n) => { - // The computed version handles clamping of animated values - // itself. - computed::FontSizeAdjust::Number(n.to_computed_value(context).0) - }, + FontSizeAdjust::Value(v) => v.to_computed_value(context), FontSizeAdjust::System(_) => self.compute_system(context), } } - fn from_computed_value(computed: &computed::FontSizeAdjust) -> Self { - match *computed { - computed::FontSizeAdjust::None => FontSizeAdjust::None, - computed::FontSizeAdjust::Number(v) => { - FontSizeAdjust::Number(NonNegativeNumber::from_computed_value(&v.into())) - }, - } + fn from_computed_value(computed: &ComputedFontSizeAdjust) -> Self { + Self::Value(ToComputedValue::from_computed_value(computed)) } }