Skip to content

Commit

Permalink
style: Move font-weight outside of mako
Browse files Browse the repository at this point in the history
  • Loading branch information
cbrewster committed Nov 1, 2017
1 parent b23131a commit 285d8bb
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 167 deletions.
171 changes: 7 additions & 164 deletions components/style/properties/longhand/font.mako.rs
Expand Up @@ -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<SpecifiedValue, ParseError<'i>> {
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<SystemFont> {
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<Self, ()> {
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, ParseError<'i>> {
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()
</%self:nongecko_unreachable>
}
}
}

#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue::Weight(*computed)
}
}
</%helpers:longhand>
${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"
Expand Down
76 changes: 75 additions & 1 deletion components/style/values/computed/font.rs
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -70,6 +81,69 @@ impl From<specified::KeywordSize> 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<Self, ()> {
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, ParseError<'i>> {
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 {
Expand Down
2 changes: 1 addition & 1 deletion components/style/values/computed/mod.rs
Expand Up @@ -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};
Expand Down
84 changes: 84 additions & 0 deletions components/style/values/specified/font.rs
Expand Up @@ -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<SystemFont> {
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<FontWeight, ParseError<'i>> {
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 {
Expand Down
2 changes: 1 addition & 1 deletion components/style/values/specified/mod.rs
Expand Up @@ -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};
Expand Down

0 comments on commit 285d8bb

Please sign in to comment.