From 285d8bb58bfc129ee3f6ec549ab6a60afe7dd4a7 Mon Sep 17 00:00:00 2001 From: Connor Brewster Date: Wed, 1 Nov 2017 11:06:40 -0500 Subject: [PATCH] style: Move font-weight outside of mako --- .../style/properties/longhand/font.mako.rs | 171 +----------------- components/style/values/computed/font.rs | 76 +++++++- components/style/values/computed/mod.rs | 2 +- components/style/values/specified/font.rs | 84 +++++++++ components/style/values/specified/mod.rs | 2 +- 5 files changed, 168 insertions(+), 167 deletions(-) diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index 290df5d49aac..aaa51dac3f3e 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -616,170 +616,13 @@ ${helpers.single_keyword_system("font-variant-caps", flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER", animation_value_type="discrete")} -<%helpers:longhand name="font-weight" animation_value_type="ComputedValue" - flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER" - spec="https://drafts.csswg.org/css-fonts/#propdef-font-weight"> - use properties::longhands::system_font::SystemFont; - - - #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToCss)] - pub enum SpecifiedValue { - Normal, - Bold, - Bolder, - Lighter, - Weight(computed_value::T), - System(SystemFont), - } - - /// normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 - pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) - -> Result> { - let result = input.try(|input| { - let ident = input.expect_ident().map_err(|_| ())?; - match_ignore_ascii_case! { &ident, - "normal" => Ok(SpecifiedValue::Normal), - "bold" => Ok(SpecifiedValue::Bold), - "bolder" => Ok(SpecifiedValue::Bolder), - "lighter" => Ok(SpecifiedValue::Lighter), - _ => Err(()) - } - }); - result.or_else(|_| computed_value::T::parse(context, input).map(SpecifiedValue::Weight)) - } - - impl SpecifiedValue { - pub fn from_gecko_keyword(kw: u32) -> Self { - computed_value::T::from_int(kw as i32).map(SpecifiedValue::Weight) - .expect("Found unexpected value in style struct for font-weight property") - } - } - - impl SpecifiedValue { - pub fn system_font(f: SystemFont) -> Self { - SpecifiedValue::System(f) - } - pub fn get_system(&self) -> Option { - if let SpecifiedValue::System(s) = *self { - Some(s) - } else { - None - } - } - } - - pub mod computed_value { - /// As of CSS Fonts Module Level 3, only the following values are - /// valid: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 - /// - /// However, system fonts may provide other values. Pango - /// may provide 350, 380, and 1000 (on top of the existing values), for example. - #[derive(Clone, ComputeSquaredDistance, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, - ToCss)] - #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] - pub struct T(pub u16); - - impl T { - /// Value for normal - pub fn normal() -> Self { - T(400) - } - - /// Value for bold - pub fn bold() -> Self { - T(700) - } - - /// Convert from an integer to Weight - pub fn from_int(n: i32) -> Result { - if n >= 100 && n <= 900 && n % 100 == 0 { - Ok(T(n as u16)) - } else { - Err(()) - } - } - - /// Convert from an Gecko weight - pub fn from_gecko_weight(weight: u16) -> Self { - // we allow a wider range of weights than is parseable - // because system fonts may provide custom values - T(weight) - } - - /// Weither this weight is bold - pub fn is_bold(&self) -> bool { - self.0 > 500 - } - - /// Return the bolder weight - pub fn bolder(self) -> Self { - if self.0 < 400 { - T(400) - } else if self.0 < 600 { - T(700) - } else { - T(900) - } - } - - /// Returns the lighter weight - pub fn lighter(self) -> Self { - if self.0 < 600 { - T(100) - } else if self.0 < 800 { - T(400) - } else { - T(700) - } - } - } - } - - impl Parse for computed_value::T { - fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) - -> Result> { - Self::from_int(input.expect_integer()?) - .map_err(|_| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) - } - } - - #[inline] - pub fn get_initial_value() -> computed_value::T { - computed_value::T::normal() - } - - #[inline] - pub fn get_initial_specified_value() -> SpecifiedValue { - SpecifiedValue::Normal - } - - impl ToComputedValue for SpecifiedValue { - type ComputedValue = computed_value::T; - - #[inline] - fn to_computed_value(&self, context: &Context) -> computed_value::T { - match *self { - SpecifiedValue::Weight(weight) => weight, - SpecifiedValue::Normal => computed_value::T::normal(), - SpecifiedValue::Bold => computed_value::T::bold(), - SpecifiedValue::Bolder => - context.builder.get_parent_font().clone_font_weight().bolder(), - SpecifiedValue::Lighter => - context.builder.get_parent_font().clone_font_weight().lighter(), - SpecifiedValue::System(_) => { - <%self:nongecko_unreachable> - context.cached_system_font.as_ref().unwrap().font_weight.clone() - - } - } - } - - #[inline] - fn from_computed_value(computed: &computed_value::T) -> Self { - SpecifiedValue::Weight(*computed) - } - } - +${helpers.predefined_type("font-weight", + "FontWeight", + initial_value="computed::FontWeight::normal()", + initial_specified_value="specified::FontWeight::Normal", + animation_value_type="ComputedValue", + flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER", + spec="https://drafts.csswg.org/css-fonts/#propdef-font-weight")} <%helpers:longhand name="font-size" animation_value_type="NonNegativeLength" flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER" diff --git a/components/style/values/computed/font.rs b/components/style/values/computed/font.rs index 906affb46662..13cd36173662 100644 --- a/components/style/values/computed/font.rs +++ b/components/style/values/computed/font.rs @@ -5,8 +5,10 @@ //! Computed values for font properties use app_units::Au; +use cssparser::Parser; +use parser::{Parse, ParserContext}; use std::fmt; -use style_traits::ToCss; +use style_traits::{ParseError, StyleParseErrorKind, ToCss}; use values::animated::ToAnimatedValue; use values::computed::{Context, NonNegativeLength, ToComputedValue}; use values::specified::font as specified; @@ -15,6 +17,15 @@ use values::specified::length::{FontBaseSize, NoCalcLength}; pub use values::computed::Length as MozScriptMinSize; pub use values::specified::font::XTextZoom; +/// As of CSS Fonts Module Level 3, only the following values are +/// valid: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 +/// +/// However, system fonts may provide other values. Pango +/// may provide 350, 380, and 1000 (on top of the existing values), for example. +#[derive(Clone, ComputeSquaredDistance, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToCss)] +#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] +pub struct FontWeight(pub u16); + #[derive(Animate, ComputeSquaredDistance, MallocSizeOf, ToAnimatedZero)] #[derive(Clone, Copy, Debug, PartialEq)] /// The computed value of font-size @@ -70,6 +81,69 @@ impl From for KeywordInfo { } } +impl FontWeight { + /// Value for normal + pub fn normal() -> Self { + FontWeight(400) + } + + /// Value for bold + pub fn bold() -> Self { + FontWeight(700) + } + + /// Convert from an integer to Weight + pub fn from_int(n: i32) -> Result { + if n >= 100 && n <= 900 && n % 100 == 0 { + Ok(FontWeight(n as u16)) + } else { + Err(()) + } + } + + /// Convert from an Gecko weight + pub fn from_gecko_weight(weight: u16) -> Self { + // we allow a wider range of weights than is parseable + // because system fonts may provide custom values + FontWeight(weight) + } + + /// Weither this weight is bold + pub fn is_bold(&self) -> bool { + self.0 > 500 + } + + /// Return the bolder weight + pub fn bolder(self) -> Self { + if self.0 < 400 { + FontWeight(400) + } else if self.0 < 600 { + FontWeight(700) + } else { + FontWeight(900) + } + } + + /// Returns the lighter weight + pub fn lighter(self) -> Self { + if self.0 < 600 { + FontWeight(100) + } else if self.0 < 800 { + FontWeight(400) + } else { + FontWeight(700) + } + } +} + +impl Parse for FontWeight { + fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) + -> Result> { + FontWeight::from_int(input.expect_integer()?) + .map_err(|_| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) + } +} + impl FontSize { /// The actual computed font size. pub fn size(self) -> Au { diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 558c084b64f3..1975e0e68d12 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -36,7 +36,7 @@ pub use self::angle::Angle; pub use self::background::{BackgroundSize, BackgroundRepeat}; pub use self::border::{BorderImageSlice, BorderImageWidth, BorderImageSideWidth}; pub use self::border::{BorderRadius, BorderCornerRadius, BorderSpacing}; -pub use self::font::{XTextZoom, MozScriptMinSize}; +pub use self::font::{FontWeight, MozScriptMinSize, XTextZoom}; pub use self::box_::{AnimationIterationCount, AnimationName, ScrollSnapType, VerticalAlign}; pub use self::color::{Color, ColorPropertyValue, RGBAColor}; pub use self::effects::{BoxShadow, Filter, SimpleShadow}; diff --git a/components/style/values/specified/font.rs b/components/style/values/specified/font.rs index e20d429b810a..7cc21ddcfc6c 100644 --- a/components/style/values/specified/font.rs +++ b/components/style/values/specified/font.rs @@ -18,6 +18,90 @@ use values::specified::length::{AU_PER_PT, AU_PER_PX, FontBaseSize}; const DEFAULT_SCRIPT_MIN_SIZE_PT: u32 = 8; +#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToCss)] +/// A specified font-weight value +pub enum FontWeight { + /// Normal variant + Normal, + /// Bold variant + Bold, + /// Bolder variant + Bolder, + /// Lighter variant + Lighter, + /// Computed weight variant + Weight(computed::FontWeight), + /// System font varaint + System(SystemFont), +} + +impl FontWeight { + /// Get a specified FontWeight from a gecko keyword + pub fn from_gecko_keyword(kw: u32) -> Self { + computed::FontWeight::from_int(kw as i32).map(FontWeight::Weight) + .expect("Found unexpected value in style struct for font-weight property") + } + + /// Get a specified FontWeight from a SystemFont + pub fn system_font(f: SystemFont) -> Self { + FontWeight::System(f) + } + + /// Retreive a SystemFont from FontWeight + pub fn get_system(&self) -> Option { + if let FontWeight::System(s) = *self { + Some(s) + } else { + None + } + } +} + +impl Parse for FontWeight { + fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) + -> Result> { + let result = input.try(|input| { + let ident = input.expect_ident().map_err(|_| ())?; + match_ignore_ascii_case! { &ident, + "normal" => Ok(FontWeight::Normal), + "bold" => Ok(FontWeight::Bold), + "bolder" => Ok(FontWeight::Bolder), + "lighter" => Ok(FontWeight::Lighter), + _ => Err(()) + } + }); + result.or_else(|_| computed::FontWeight::parse(context, input).map(FontWeight::Weight)) + } +} + +impl ToComputedValue for FontWeight { + type ComputedValue = computed::FontWeight; + + #[inline] + fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { + match *self { + FontWeight::Weight(weight) => weight, + FontWeight::Normal => computed::FontWeight::normal(), + FontWeight::Bold => computed::FontWeight::bold(), + FontWeight::Bolder => + context.builder.get_parent_font().clone_font_weight().bolder(), + FontWeight::Lighter => + context.builder.get_parent_font().clone_font_weight().lighter(), + #[cfg(feature = "gecko")] + FontWeight::System(_) => + context.cached_system_font.as_ref().unwrap().font_weight.clone(), + #[cfg(not(feature = "gecko"))] + FontWeight::System(_) => + unreachable!(), + } + } + + #[inline] + fn from_computed_value(computed: &computed::FontWeight) -> Self { + FontWeight::Weight(*computed) + } +} + #[derive(Clone, Debug, MallocSizeOf, PartialEq)] /// A specified font-size value pub enum FontSize { diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 1c9bc6122a68..85fa42c8906c 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -30,7 +30,7 @@ pub use self::align::{AlignItems, AlignJustifyContent, AlignJustifySelf, Justify pub use self::background::{BackgroundRepeat, BackgroundSize}; pub use self::border::{BorderCornerRadius, BorderImageSlice, BorderImageWidth}; pub use self::border::{BorderImageSideWidth, BorderRadius, BorderSideWidth, BorderSpacing}; -pub use self::font::{XTextZoom, MozScriptMinSize}; +pub use self::font::{FontWeight, MozScriptMinSize, XTextZoom}; pub use self::box_::{AnimationIterationCount, AnimationName, ScrollSnapType, VerticalAlign}; pub use self::color::{Color, ColorPropertyValue, RGBAColor}; pub use self::effects::{BoxShadow, Filter, SimpleShadow};