diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index c8c2f043b0f..cda9f31d878 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -1315,14 +1315,14 @@ impl FragmentDisplayListBuilding for Fragment { LineDirection::Angle(angle) => angle.radians(), LineDirection::Horizontal(x) => { match x { - X::Left => Angle::Degree(270.).radians(), - X::Right => Angle::Degree(90.).radians(), + X::Left => Angle::Deg(270.).radians(), + X::Right => Angle::Deg(90.).radians(), } }, LineDirection::Vertical(y) => { match y { - Y::Top => Angle::Degree(0.).radians(), - Y::Bottom => Angle::Degree(180.).radians(), + Y::Top => Angle::Deg(0.).radians(), + Y::Bottom => Angle::Deg(180.).radians(), } }, LineDirection::Corner(horizontal, vertical) => { diff --git a/components/style/gecko/conversions.rs b/components/style/gecko/conversions.rs index 4603de3b260..cc879dfd78c 100644 --- a/components/style/gecko/conversions.rs +++ b/components/style/gecko/conversions.rs @@ -116,9 +116,9 @@ impl From for LengthOrPercentageOrAuto { impl From for CoordDataValue { fn from(reference: Angle) -> Self { match reference { - Angle::Degree(val) => CoordDataValue::Degree(val), - Angle::Gradian(val) => CoordDataValue::Grad(val), - Angle::Radian(val) => CoordDataValue::Radian(val), + Angle::Deg(val) => CoordDataValue::Degree(val), + Angle::Grad(val) => CoordDataValue::Grad(val), + Angle::Rad(val) => CoordDataValue::Radian(val), Angle::Turn(val) => CoordDataValue::Turn(val), } } @@ -128,9 +128,9 @@ impl Angle { /// Converts Angle struct into (value, unit) pair. pub fn to_gecko_values(&self) -> (f32, nsCSSUnit) { match *self { - Angle::Degree(val) => (val, nsCSSUnit::eCSSUnit_Degree), - Angle::Gradian(val) => (val, nsCSSUnit::eCSSUnit_Grad), - Angle::Radian(val) => (val, nsCSSUnit::eCSSUnit_Radian), + Angle::Deg(val) => (val, nsCSSUnit::eCSSUnit_Degree), + Angle::Grad(val) => (val, nsCSSUnit::eCSSUnit_Grad), + Angle::Rad(val) => (val, nsCSSUnit::eCSSUnit_Radian), Angle::Turn(val) => (val, nsCSSUnit::eCSSUnit_Turn), } } @@ -138,9 +138,9 @@ impl Angle { /// Converts gecko (value, unit) pair into Angle struct pub fn from_gecko_values(value: f32, unit: nsCSSUnit) -> Angle { match unit { - nsCSSUnit::eCSSUnit_Degree => Angle::Degree(value), - nsCSSUnit::eCSSUnit_Grad => Angle::Gradian(value), - nsCSSUnit::eCSSUnit_Radian => Angle::Radian(value), + nsCSSUnit::eCSSUnit_Degree => Angle::Deg(value), + nsCSSUnit::eCSSUnit_Grad => Angle::Grad(value), + nsCSSUnit::eCSSUnit_Radian => Angle::Rad(value), nsCSSUnit::eCSSUnit_Turn => Angle::Turn(value), _ => panic!("Unexpected unit {:?} for angle", unit), } diff --git a/components/style/gecko/media_queries.rs b/components/style/gecko/media_queries.rs index 95a4ec2e42a..625802eecf6 100644 --- a/components/style/gecko/media_queries.rs +++ b/components/style/gecko/media_queries.rs @@ -29,7 +29,7 @@ use style_traits::{CSSPixel, DevicePixel}; use style_traits::{ToCss, ParseError, StyleParseErrorKind}; use style_traits::viewport::ViewportConstraints; use stylesheets::Origin; -use values::{CSSFloat, CustomIdent, serialize_dimension}; +use values::{CSSFloat, CustomIdent}; use values::computed::{self, ToComputedValue}; use values::computed::font::FontSize; use values::specified::Length; @@ -262,13 +262,16 @@ impl PartialEq for Expression { } /// A resolution. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, ToCss)] pub enum Resolution { /// Dots per inch. + #[css(dimension)] Dpi(CSSFloat), /// Dots per pixel. + #[css(dimension)] Dppx(CSSFloat), /// Dots per centimeter. + #[css(dimension)] Dpcm(CSSFloat), } @@ -303,18 +306,6 @@ impl Resolution { } } -impl ToCss for Resolution { - fn to_css(&self, dest: &mut W) -> fmt::Result - where W: fmt::Write, - { - match *self { - Resolution::Dpi(v) => serialize_dimension(v, "dpi", dest), - Resolution::Dppx(v) => serialize_dimension(v, "dppx", dest), - Resolution::Dpcm(v) => serialize_dimension(v, "dpcm", dest), - } - } -} - /// A value found or expected in a media expression. #[derive(Clone, Debug, PartialEq)] pub enum MediaExpressionValue { diff --git a/components/style/gecko/values.rs b/components/style/gecko/values.rs index 09a796c5980..fc5d75bbe4b 100644 --- a/components/style/gecko/values.rs +++ b/components/style/gecko/values.rs @@ -214,7 +214,7 @@ impl GeckoStyleCoordConvertible for TrackBreadth< fn to_gecko_style_coord(&self, coord: &mut T) { match *self { TrackBreadth::Breadth(ref lop) => lop.to_gecko_style_coord(coord), - TrackBreadth::Flex(fr) => coord.set_value(CoordDataValue::FlexFraction(fr)), + TrackBreadth::Fr(fr) => coord.set_value(CoordDataValue::FlexFraction(fr)), TrackBreadth::Keyword(TrackKeyword::Auto) => coord.set_value(CoordDataValue::Auto), TrackBreadth::Keyword(TrackKeyword::MinContent) => coord.set_value(CoordDataValue::Enumerated(StyleGridTrackBreadth::MinContent as u32)), @@ -235,7 +235,7 @@ impl GeckoStyleCoordConvertible for TrackBreadth< None } }, - CoordDataValue::FlexFraction(fr) => Some(TrackBreadth::Flex(fr)), + CoordDataValue::FlexFraction(fr) => Some(TrackBreadth::Fr(fr)), CoordDataValue::Auto => Some(TrackBreadth::Keyword(TrackKeyword::Auto)), _ => L::from_gecko_style_coord(coord).map(TrackBreadth::Breadth), } @@ -291,9 +291,9 @@ impl GeckoStyleCoordConvertible for Angle { fn from_gecko_style_coord(coord: &T) -> Option { match coord.as_value() { - CoordDataValue::Degree(val) => Some(Angle::Degree(val)), - CoordDataValue::Grad(val) => Some(Angle::Gradian(val)), - CoordDataValue::Radian(val) => Some(Angle::Radian(val)), + CoordDataValue::Degree(val) => Some(Angle::Deg(val)), + CoordDataValue::Grad(val) => Some(Angle::Grad(val)), + CoordDataValue::Radian(val) => Some(Angle::Rad(val)), CoordDataValue::Turn(val) => Some(Angle::Turn(val)), _ => None, } diff --git a/components/style/values/computed/angle.rs b/components/style/values/computed/angle.rs index fdaecf93ab1..7cc10e97c4d 100644 --- a/components/style/values/computed/angle.rs +++ b/components/style/values/computed/angle.rs @@ -5,9 +5,8 @@ //! Computed angles. use euclid::Radians; -use std::{f32, f64, fmt}; +use std::{f32, f64}; use std::f64::consts::PI; -use style_traits::ToCss; use values::CSSFloat; use values::animated::{Animate, Procedure}; use values::distance::{ComputeSquaredDistance, SquaredDistance}; @@ -15,23 +14,27 @@ use values::distance::{ComputeSquaredDistance, SquaredDistance}; /// A computed angle. #[animate(fallback = "Self::animate_fallback")] #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] -#[derive(Animate, Clone, Copy, Debug, MallocSizeOf, PartialEq)] +#[derive(Animate, Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)] #[derive(PartialOrd, ToAnimatedZero)] pub enum Angle { /// An angle with degree unit. - Degree(CSSFloat), + #[css(dimension)] + Deg(CSSFloat), /// An angle with gradian unit. - Gradian(CSSFloat), + #[css(dimension)] + Grad(CSSFloat), /// An angle with radian unit. - Radian(CSSFloat), + #[css(dimension)] + Rad(CSSFloat), /// An angle with turn unit. + #[css(dimension)] Turn(CSSFloat), } impl Angle { /// Creates a computed `Angle` value from a radian amount. pub fn from_radians(radians: CSSFloat) -> Self { - Angle::Radian(radians) + Angle::Rad(radians) } /// Returns the amount of radians this angle represents. @@ -53,17 +56,17 @@ impl Angle { const RAD_PER_TURN: f64 = PI * 2.0; let radians = match *self { - Angle::Degree(val) => val as f64 * RAD_PER_DEG, - Angle::Gradian(val) => val as f64 * RAD_PER_GRAD, + Angle::Deg(val) => val as f64 * RAD_PER_DEG, + Angle::Grad(val) => val as f64 * RAD_PER_GRAD, Angle::Turn(val) => val as f64 * RAD_PER_TURN, - Angle::Radian(val) => val as f64, + Angle::Rad(val) => val as f64, }; radians.min(f64::MAX).max(f64::MIN) } /// Returns an angle that represents a rotation of zero radians. pub fn zero() -> Self { - Angle::Radian(0.0) + Self::from_radians(0.0) } /// @@ -82,25 +85,6 @@ impl ComputeSquaredDistance for Angle { } } -impl ToCss for Angle { - fn to_css(&self, dest: &mut W) -> fmt::Result - where - W: fmt::Write, - { - let mut write = |value: CSSFloat, unit: &str| { - value.to_css(dest)?; - dest.write_str(unit) - }; - - match *self { - Angle::Degree(val) => write(val, "deg"), - Angle::Gradian(val) => write(val, "grad"), - Angle::Radian(val) => write(val, "rad"), - Angle::Turn(val) => write(val, "turn"), - } - } -} - impl From for Radians { #[inline] fn from(a: Angle) -> Self { diff --git a/components/style/values/computed/font.rs b/components/style/values/computed/font.rs index 98c3e014c4b..1613e64892b 100644 --- a/components/style/values/computed/font.rs +++ b/components/style/values/computed/font.rs @@ -326,12 +326,12 @@ impl ToComputedValue for specified::MozScriptLevel { let parent = cx.builder.get_parent_font().clone__moz_script_level(); parent as i32 + rel } - specified::MozScriptLevel::Absolute(abs) => abs, + specified::MozScriptLevel::MozAbsolute(abs) => abs, }; cmp::min(int, i8::MAX as i32) as i8 } fn from_computed_value(other: &i8) -> Self { - specified::MozScriptLevel::Absolute(*other as i32) + specified::MozScriptLevel::MozAbsolute(*other as i32) } } diff --git a/components/style/values/generics/grid.rs b/components/style/values/generics/grid.rs index db2e4721075..bd0dc82507f 100644 --- a/components/style/values/generics/grid.rs +++ b/components/style/values/generics/grid.rs @@ -9,7 +9,7 @@ use cssparser::Parser; use parser::{Parse, ParserContext}; use std::{fmt, mem, usize}; use style_traits::{ToCss, ParseError, StyleParseErrorKind}; -use values::{CSSFloat, CustomIdent, serialize_dimension}; +use values::{CSSFloat, CustomIdent}; use values::computed::{Context, ToComputedValue}; use values::specified; use values::specified::grid::parse_line_names; @@ -143,12 +143,13 @@ add_impls_for_keyword_enum!(TrackKeyword); /// avoid re-implementing it for the computed type. /// /// -#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue)] +#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss)] pub enum TrackBreadth { /// The generic type is almost always a non-negative `` Breadth(L), /// A flex fraction specified in `fr` units. - Flex(CSSFloat), + #[css(dimension)] + Fr(CSSFloat), /// One of the track-sizing keywords (`auto`, `min-content`, `max-content`) Keyword(TrackKeyword), } @@ -166,16 +167,6 @@ impl TrackBreadth { } } -impl ToCss for TrackBreadth { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - TrackBreadth::Breadth(ref lop) => lop.to_css(dest), - TrackBreadth::Flex(ref value) => serialize_dimension(*value, "fr", dest), - TrackBreadth::Keyword(ref k) => k.to_css(dest), - } - } -} - /// A `` type for explicit grid track sizing. Like ``, this is /// generic only to avoid code bloat. It only takes `` /// @@ -212,7 +203,7 @@ impl TrackSize { } match *breadth_1 { - TrackBreadth::Flex(_) => false, // should be at this point + TrackBreadth::Fr(_) => false, // should be at this point _ => breadth_2.is_fixed(), } }, @@ -242,7 +233,7 @@ impl ToCss for TrackSize { // According to gecko minmax(auto, ) is equivalent to , // and both are serialized as . if let TrackBreadth::Keyword(TrackKeyword::Auto) = *min { - if let TrackBreadth::Flex(_) = *max { + if let TrackBreadth::Fr(_) = *max { return max.to_css(dest); } } @@ -268,7 +259,7 @@ impl ToComputedValue for TrackSize { #[inline] fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { match *self { - TrackSize::Breadth(TrackBreadth::Flex(ref f)) => { + TrackSize::Breadth(TrackBreadth::Fr(ref f)) => { // outside `minmax()` expands to `mimmax(auto, )` // https://drafts.csswg.org/css-grid/#valdef-grid-template-columns-flex // FIXME(nox): This sounds false, the spec just says that @@ -276,7 +267,7 @@ impl ToComputedValue for TrackSize { // into `minmax` at computed value time. TrackSize::Minmax( TrackBreadth::Keyword(TrackKeyword::Auto), - TrackBreadth::Flex(f.to_computed_value(context)), + TrackBreadth::Fr(f.to_computed_value(context)), ) }, TrackSize::Breadth(ref b) => { diff --git a/components/style/values/mod.rs b/components/style/values/mod.rs index 7a690662acc..0aa1ae4ccf3 100644 --- a/components/style/values/mod.rs +++ b/components/style/values/mod.rs @@ -41,14 +41,6 @@ pub fn serialize_percentage(value: CSSFloat, dest: &mut W) dest.write_str("%") } -/// Serialize a value with given unit into dest. -pub fn serialize_dimension(value: CSSFloat, unit: &str, dest: &mut W) - -> fmt::Result where W: fmt::Write -{ - value.to_css(dest)?; - dest.write_str(unit) -} - /// Convenience void type to disable some properties and values through types. #[cfg_attr(feature = "servo", derive(Deserialize, MallocSizeOf, Serialize))] #[derive(Clone, Copy, Debug, PartialEq, ToComputedValue, ToCss)] diff --git a/components/style/values/specified/angle.rs b/components/style/values/specified/angle.rs index e3714a5babf..863a436ab4f 100644 --- a/components/style/values/specified/angle.rs +++ b/components/style/values/specified/angle.rs @@ -57,12 +57,12 @@ impl ToComputedValue for Angle { impl Angle { /// Creates an angle with the given value in degrees. pub fn from_degrees(value: CSSFloat, was_calc: bool) -> Self { - Angle { value: ComputedAngle::Degree(value), was_calc } + Angle { value: ComputedAngle::Deg(value), was_calc } } /// Creates an angle with the given value in gradians. pub fn from_gradians(value: CSSFloat, was_calc: bool) -> Self { - Angle { value: ComputedAngle::Gradian(value), was_calc } + Angle { value: ComputedAngle::Grad(value), was_calc } } /// Creates an angle with the given value in turns. @@ -72,7 +72,7 @@ impl Angle { /// Creates an angle with the given value in radians. pub fn from_radians(value: CSSFloat, was_calc: bool) -> Self { - Angle { value: ComputedAngle::Radian(value), was_calc } + Angle { value: ComputedAngle::Rad(value), was_calc } } /// Returns the amount of radians this angle represents. @@ -89,7 +89,7 @@ impl Angle { /// Returns an `Angle` parsed from a `calc()` expression. pub fn from_calc(radians: CSSFloat) -> Self { Angle { - value: ComputedAngle::Radian(radians), + value: ComputedAngle::Rad(radians), was_calc: true, } } diff --git a/components/style/values/specified/calc.rs b/components/style/values/specified/calc.rs index f88105fdb61..295e9488f61 100644 --- a/components/style/values/specified/calc.rs +++ b/components/style/values/specified/calc.rs @@ -400,7 +400,13 @@ impl CalcNode { NoCalcLength::ServoCharacterWidth(..) => unreachable!(), #[cfg(feature = "gecko")] NoCalcLength::Physical(physical) => { - ret.mozmm = Some(ret.mozmm.unwrap_or(0.) + physical.0 * factor); + use values::specified::length::PhysicalLength; + + match physical { + PhysicalLength::Mozmm(mozmm) => { + ret.mozmm = Some(ret.mozmm.unwrap_or(0.) + mozmm * factor); + } + } } } } diff --git a/components/style/values/specified/font.rs b/components/style/values/specified/font.rs index da2fa9432e8..f0f2c2e9be8 100644 --- a/components/style/values/specified/font.rs +++ b/components/style/values/specified/font.rs @@ -636,81 +636,31 @@ bitflags! { } } -#[derive(Clone, Debug, MallocSizeOf, PartialEq)] +#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)] /// Set of variant alternates pub enum VariantAlternates { /// Enables display of stylistic alternates + #[css(function)] Stylistic(CustomIdent), /// Enables display with stylistic sets + #[css(comma, function, iterable)] Styleset(Box<[CustomIdent]>), /// Enables display of specific character variants + #[css(comma, function, iterable)] CharacterVariant(Box<[CustomIdent]>), /// Enables display of swash glyphs + #[css(function)] Swash(CustomIdent), /// Enables replacement of default glyphs with ornaments + #[css(function)] Ornaments(CustomIdent), /// Enables display of alternate annotation forms + #[css(function)] Annotation(CustomIdent), /// Enables display of historical forms HistoricalForms, } -impl ToCss for VariantAlternates { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - VariantAlternates::Swash(ref atom) => { - dest.write_str("swash")?; - dest.write_str("(")?; - atom.to_css(dest)?; - dest.write_str(")") - }, - VariantAlternates::Stylistic(ref atom) => { - dest.write_str("stylistic")?; - dest.write_str("(")?; - atom.to_css(dest)?; - dest.write_str(")") - }, - VariantAlternates::Ornaments(ref atom) => { - dest.write_str("ornaments")?; - dest.write_str("(")?; - atom.to_css(dest)?; - dest.write_str(")") - }, - VariantAlternates::Annotation(ref atom) => { - dest.write_str("annotation")?; - dest.write_str("(")?; - atom.to_css(dest)?; - dest.write_str(")") - }, - VariantAlternates::Styleset(ref vec) => { - dest.write_str("styleset")?; - dest.write_str("(")?; - let mut iter = vec.iter(); - iter.next().unwrap().to_css(dest)?; - for c in iter { - dest.write_str(", ")?; - c.to_css(dest)?; - } - dest.write_str(")") - }, - VariantAlternates::CharacterVariant(ref vec) => { - dest.write_str("character-variant")?; - dest.write_str("(")?; - let mut iter = vec.iter(); - iter.next().unwrap().to_css(dest)?; - for c in iter { - dest.write_str(", ")?; - c.to_css(dest)?; - } - dest.write_str(")") - }, - VariantAlternates::HistoricalForms => { - dest.write_str("historical-forms") - }, - } - } -} - #[derive(Clone, Debug, MallocSizeOf, PartialEq)] /// List of Variant Alternates pub struct VariantAlternatesList(pub Box<[VariantAlternates]>); @@ -1027,33 +977,26 @@ impl Parse for MozScriptMinSize { } #[cfg_attr(feature = "gecko", derive(MallocSizeOf))] -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq, ToCss)] /// Changes the scriptlevel in effect for the children. /// Ref: https://wiki.mozilla.org/MathML:mstyle /// /// The main effect of scriptlevel is to control the font size. /// https://www.w3.org/TR/MathML3/chapter3.html#presm.scriptlevel pub enum MozScriptLevel { - /// Change `font-size` relatively + /// Change `font-size` relatively. Relative(i32), - /// Change `font-size` absolutely - Absolute(i32), - /// Change `font-size` automatically + /// Change `font-size` absolutely. + /// + /// Should only be serialized by presentation attributes, so even though + /// serialization for this would look the same as for the `Relative` + /// variant, it is unexposed, so no big deal. + #[css(function)] + MozAbsolute(i32), + /// Change `font-size` automatically. Auto } -impl ToCss for MozScriptLevel { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - MozScriptLevel::Auto => dest.write_str("auto"), - MozScriptLevel::Relative(rel) => rel.to_css(dest), - // can only be specified by pres attrs; should not - // serialize to anything else - MozScriptLevel::Absolute(_) => Ok(()), - } - } -} - impl Parse for MozScriptLevel { fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { if let Ok(i) = input.try(|i| i.expect_integer()) { diff --git a/components/style/values/specified/grid.rs b/components/style/values/specified/grid.rs index b951082aea9..f2b8453c46c 100644 --- a/components/style/values/specified/grid.rs +++ b/components/style/values/specified/grid.rs @@ -33,7 +33,7 @@ impl Parse for TrackBreadth { } if let Ok(f) = input.try(parse_flex) { - return Ok(TrackBreadth::Flex(f)) + return Ok(TrackBreadth::Fr(f)) } TrackKeyword::parse(input).map(TrackBreadth::Keyword) diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index f2e802d38cb..19eeb33bbcd 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -11,15 +11,14 @@ use cssparser::{Parser, Token}; use euclid::Size2D; use font_metrics::FontMetricsQueryResult; use parser::{Parse, ParserContext}; -use std::{cmp, fmt, mem}; +use std::{cmp, mem}; #[allow(unused_imports)] use std::ascii::AsciiExt; use std::ops::{Add, Mul}; -use style_traits::{ToCss, ParseError, StyleParseErrorKind}; +use style_traits::{ParseError, StyleParseErrorKind}; use style_traits::values::specified::AllowedNumericType; use stylesheets::CssRuleType; use super::{AllowQuirks, Number, ToComputedValue, Percentage}; -use values::{Auto, CSSFloat, Either, None_, Normal}; -use values::{ExtremumLength, serialize_dimension}; +use values::{Auto, CSSFloat, Either, ExtremumLength, None_, Normal}; use values::computed::{self, CSSPixelLength, Context}; use values::generics::NonNegative; use values::specified::NonNegativeNumber; @@ -52,32 +51,23 @@ pub fn au_to_int_px(au: f32) -> i32 { (au / AU_PER_PX).round() as i32 } -#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)] /// A font relative length. +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)] pub enum FontRelativeLength { /// A "em" value: https://drafts.csswg.org/css-values/#em + #[css(dimension)] Em(CSSFloat), /// A "ex" value: https://drafts.csswg.org/css-values/#ex + #[css(dimension)] Ex(CSSFloat), /// A "ch" value: https://drafts.csswg.org/css-values/#ch + #[css(dimension)] Ch(CSSFloat), /// A "rem" value: https://drafts.csswg.org/css-values/#rem + #[css(dimension)] Rem(CSSFloat) } -impl ToCss for FontRelativeLength { - fn to_css(&self, dest: &mut W) -> fmt::Result - where W: fmt::Write - { - match *self { - FontRelativeLength::Em(length) => serialize_dimension(length, "em", dest), - FontRelativeLength::Ex(length) => serialize_dimension(length, "ex", dest), - FontRelativeLength::Ch(length) => serialize_dimension(length, "ch", dest), - FontRelativeLength::Rem(length) => serialize_dimension(length, "rem", dest) - } - } -} - /// A source to resolve font-relative units against #[derive(Clone, Copy, Debug, PartialEq)] pub enum FontBaseSize { @@ -206,32 +196,25 @@ impl FontRelativeLength { } } -#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)] /// A viewport-relative length. /// /// +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)] pub enum ViewportPercentageLength { /// A vw unit: https://drafts.csswg.org/css-values/#vw + #[css(dimension)] Vw(CSSFloat), /// A vh unit: https://drafts.csswg.org/css-values/#vh + #[css(dimension)] Vh(CSSFloat), /// + #[css(dimension)] Vmin(CSSFloat), /// + #[css(dimension)] Vmax(CSSFloat) } -impl ToCss for ViewportPercentageLength { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - ViewportPercentageLength::Vw(length) => serialize_dimension(length, "vw", dest), - ViewportPercentageLength::Vh(length) => serialize_dimension(length, "vh", dest), - ViewportPercentageLength::Vmin(length) => serialize_dimension(length, "vmin", dest), - ViewportPercentageLength::Vmax(length) => serialize_dimension(length, "vmax", dest) - } - } -} - impl ViewportPercentageLength { /// Computes the given viewport-relative length for the given viewport size. pub fn to_computed_value(&self, viewport_size: Size2D) -> CSSPixelLength { @@ -255,7 +238,7 @@ impl ViewportPercentageLength { } /// HTML5 "character width", as defined in HTML5 ยง 14.5.4. -#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)] +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)] pub struct CharacterWidth(pub i32); impl CharacterWidth { @@ -273,21 +256,28 @@ impl CharacterWidth { } /// Represents an absolute length with its unit -#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)] +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)] pub enum AbsoluteLength { /// An absolute length in pixels (px) + #[css(dimension)] Px(CSSFloat), /// An absolute length in inches (in) + #[css(dimension)] In(CSSFloat), /// An absolute length in centimeters (cm) + #[css(dimension)] Cm(CSSFloat), /// An absolute length in millimeters (mm) + #[css(dimension)] Mm(CSSFloat), /// An absolute length in quarter-millimeters (q) + #[css(dimension)] Q(CSSFloat), /// An absolute length in points (pt) + #[css(dimension)] Pt(CSSFloat), /// An absolute length in pica (pc) + #[css(dimension)] Pc(CSSFloat), } @@ -334,20 +324,6 @@ impl ToComputedValue for AbsoluteLength { } } -impl ToCss for AbsoluteLength { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - AbsoluteLength::Px(length) => serialize_dimension(length, "px", dest), - AbsoluteLength::In(length) => serialize_dimension(length, "in", dest), - AbsoluteLength::Cm(length) => serialize_dimension(length, "cm", dest), - AbsoluteLength::Mm(length) => serialize_dimension(length, "mm", dest), - AbsoluteLength::Q(length) => serialize_dimension(length, "q", dest), - AbsoluteLength::Pt(length) => serialize_dimension(length, "pt", dest), - AbsoluteLength::Pc(length) => serialize_dimension(length, "pc", dest), - } - } -} - impl Mul for AbsoluteLength { type Output = AbsoluteLength; @@ -383,19 +359,27 @@ impl Add for AbsoluteLength { } } -/// Represents a physical length (mozmm) based on DPI -#[derive(Clone, Copy, Debug, PartialEq)] -#[cfg(feature = "gecko")] +/// Represents a physical length based on DPI. +/// +/// FIXME(emilio): Unship (https://bugzilla.mozilla.org/show_bug.cgi?id=1416564) +#[derive(Clone, Copy, Debug, PartialEq, ToCss)] #[derive(MallocSizeOf)] -pub struct PhysicalLength(pub CSSFloat); +pub enum PhysicalLength { + /// A physical length in millimetres. + #[css(dimension)] + Mozmm(CSSFloat), +} -#[cfg(feature = "gecko")] impl PhysicalLength { - fn is_zero(&self) -> bool { - self.0 == 0. + /// Checks whether the length value is zero. + pub fn is_zero(&self) -> bool { + match *self { + PhysicalLength::Mozmm(v) => v == 0., + } } /// Computes the given character width. + #[cfg(feature = "gecko")] pub fn to_computed_value(&self, context: &Context) -> CSSPixelLength { use gecko_bindings::bindings; use std::f32; @@ -408,32 +392,31 @@ impl PhysicalLength { }; let px_per_physical_inch = au_per_physical_inch / AU_PER_PX; - let pixel = self.0 * px_per_physical_inch * INCH_PER_MM; + + let mm = match *self { + PhysicalLength::Mozmm(v) => v, + }; + + let pixel = mm * px_per_physical_inch * INCH_PER_MM; CSSPixelLength::new(pixel.min(f32::MAX).max(f32::MIN)) } } -#[cfg(feature = "gecko")] -impl ToCss for PhysicalLength { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - serialize_dimension(self.0, "mozmm", dest) - } -} - -#[cfg(feature = "gecko")] impl Mul for PhysicalLength { - type Output = PhysicalLength; + type Output = Self ; #[inline] - fn mul(self, scalar: CSSFloat) -> PhysicalLength { - PhysicalLength(self.0 * scalar) + fn mul(self, scalar: CSSFloat) -> Self { + match self { + PhysicalLength::Mozmm(v) => PhysicalLength::Mozmm(v * scalar), + } } } /// A `` without taking `calc` expressions into account /// /// -#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)] +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)] pub enum NoCalcLength { /// An absolute length /// @@ -454,6 +437,7 @@ pub enum NoCalcLength { /// /// This cannot be specified by the user directly and is only generated by /// `Stylist::synthesize_rules_for_legacy_attributes()`. + #[css(function)] ServoCharacterWidth(CharacterWidth), /// A physical length (mozmm) based on DPI @@ -461,24 +445,6 @@ pub enum NoCalcLength { Physical(PhysicalLength), } -impl ToCss for NoCalcLength { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - NoCalcLength::Absolute(length) => length.to_css(dest), - NoCalcLength::FontRelative(length) => length.to_css(dest), - NoCalcLength::ViewportPercentage(length) => length.to_css(dest), - /* This should only be reached from style dumping code */ - NoCalcLength::ServoCharacterWidth(CharacterWidth(i)) => { - dest.write_str("CharWidth(")?; - i.to_css(dest)?; - dest.write_char(')') - } - #[cfg(feature = "gecko")] - NoCalcLength::Physical(length) => length.to_css(dest), - } - } -} - impl Mul for NoCalcLength { type Output = NoCalcLength; @@ -539,7 +505,7 @@ impl NoCalcLength { Ok(NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vmax(value))) }, #[cfg(feature = "gecko")] - "mozmm" => Ok(NoCalcLength::Physical(PhysicalLength(value))), + "mozmm" => Ok(NoCalcLength::Physical(PhysicalLength::Mozmm(value))), _ => Err(()) } } diff --git a/components/style_derive/to_css.rs b/components/style_derive/to_css.rs index 6ae438ccbd2..59cc4f4236b 100644 --- a/components/style_derive/to_css.rs +++ b/components/style_derive/to_css.rs @@ -19,15 +19,34 @@ pub fn derive(input: DeriveInput) -> Tokens { let mut identifier = to_css_identifier(variant.ident.as_ref()); let variant_attrs = cg::parse_variant_attrs::(variant); let separator = if variant_attrs.comma { ", " } else { " " }; + + if variant_attrs.dimension { + assert_eq!(bindings.len(), 1); + assert!(!variant_attrs.function, "That makes no sense"); + } + let mut expr = if !bindings.is_empty() { let mut expr = quote! {}; - for binding in bindings { - where_clause.add_trait_bound(&binding.field.ty); + if variant_attrs.function && variant_attrs.iterable { + assert_eq!(bindings.len(), 1); + let binding = &bindings[0]; expr = quote! { #expr - writer.item(#binding)?; + + for item in #binding.iter() { + writer.item(item)?; + } }; + } else { + for binding in bindings { + where_clause.add_trait_bound(&binding.field.ty); + expr = quote! { + #expr + writer.item(#binding)?; + }; + } } + quote! {{ let mut writer = ::style_traits::values::SequenceWriter::new(&mut *dest, #separator); #expr @@ -38,7 +57,18 @@ pub fn derive(input: DeriveInput) -> Tokens { ::std::fmt::Write::write_str(dest, #identifier) } }; - if variant_attrs.function { + + if variant_attrs.dimension { + // FIXME(emilio): Remove when bug 1416564 lands. + if identifier == "-mozmm" { + identifier = "mozmm".into(); + } + + expr = quote! { + #expr?; + ::std::fmt::Write::write_str(dest, #identifier) + } + } else if variant_attrs.function { identifier.push_str("("); expr = quote! { ::std::fmt::Write::write_str(dest, #identifier)?; @@ -89,7 +119,9 @@ struct CssInputAttrs { #[derive(Default, FromVariant)] struct CssVariantAttrs { function: bool, + iterable: bool, comma: bool, + dimension: bool, } /// Transforms "FooBar" to "foo-bar". diff --git a/components/style_traits/values.rs b/components/style_traits/values.rs index 9b2b308d5d1..3e951548e6c 100644 --- a/components/style_traits/values.rs +++ b/components/style_traits/values.rs @@ -24,6 +24,12 @@ use std::fmt::{self, Write}; /// commas, otherwise, by spaces; /// * if `#[css(function)]` is found on a variant, the variant name gets /// serialised like unit variants and its fields are surrounded by parentheses; +/// * if `#[css(iterable)]` is found on a function variant, that variant needs +/// to have a single member, and that member needs to be iterable. The +/// iterable will be serialized as the arguments for the function. +/// * if `#[css(dimension)]` is found on a variant, that variant needs +/// to have a single member. The variant would be serialized as a CSS +/// dimension token, like: . /// * finally, one can put `#[css(derive_debug)]` on the whole type, to /// implement `Debug` by a single call to `ToCss::to_css`. pub trait ToCss { diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index bb443057b6d..07d05379628 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -3171,7 +3171,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetLengthValue( structs::nsCSSUnit::eCSSUnit_Inch => NoCalcLength::Absolute(AbsoluteLength::In(value)), structs::nsCSSUnit::eCSSUnit_Centimeter => NoCalcLength::Absolute(AbsoluteLength::Cm(value)), structs::nsCSSUnit::eCSSUnit_Millimeter => NoCalcLength::Absolute(AbsoluteLength::Mm(value)), - structs::nsCSSUnit::eCSSUnit_PhysicalMillimeter => NoCalcLength::Physical(PhysicalLength(value)), + structs::nsCSSUnit::eCSSUnit_PhysicalMillimeter => NoCalcLength::Physical(PhysicalLength::Mozmm(value)), structs::nsCSSUnit::eCSSUnit_Point => NoCalcLength::Absolute(AbsoluteLength::Pt(value)), structs::nsCSSUnit::eCSSUnit_Pica => NoCalcLength::Absolute(AbsoluteLength::Pc(value)), structs::nsCSSUnit::eCSSUnit_Quarter => NoCalcLength::Absolute(AbsoluteLength::Q(value)), @@ -3202,7 +3202,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetNumberValue( let prop = match_wrap_declared! { long, MozScriptSizeMultiplier => value, // Gecko uses Number values to signal that it is absolute - MozScriptLevel => MozScriptLevel::Absolute(value as i32), + MozScriptLevel => MozScriptLevel::MozAbsolute(value as i32), }; write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| { decls.push(prop, Importance::Normal, DeclarationSource::CssOm);