style: Implement css(dimension) and derive ToCss for a bunch of stuff.

For css(dimension), it'd be nice to derive(Parse) too, I think...
This commit is contained in:
Emilio Cobos Álvarez 2017-11-11 14:57:12 +01:00
parent 1b533f9bdc
commit 4927786d90
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
10 changed files with 98 additions and 153 deletions

View file

@ -1315,14 +1315,14 @@ impl FragmentDisplayListBuilding for Fragment {
LineDirection::Angle(angle) => angle.radians(), LineDirection::Angle(angle) => angle.radians(),
LineDirection::Horizontal(x) => { LineDirection::Horizontal(x) => {
match x { match x {
X::Left => Angle::Degree(270.).radians(), X::Left => Angle::Deg(270.).radians(),
X::Right => Angle::Degree(90.).radians(), X::Right => Angle::Deg(90.).radians(),
} }
}, },
LineDirection::Vertical(y) => { LineDirection::Vertical(y) => {
match y { match y {
Y::Top => Angle::Degree(0.).radians(), Y::Top => Angle::Deg(0.).radians(),
Y::Bottom => Angle::Degree(180.).radians(), Y::Bottom => Angle::Deg(180.).radians(),
} }
}, },
LineDirection::Corner(horizontal, vertical) => { LineDirection::Corner(horizontal, vertical) => {

View file

@ -116,9 +116,9 @@ impl From<nsStyleCoord_CalcValue> for LengthOrPercentageOrAuto {
impl From<Angle> for CoordDataValue { impl From<Angle> for CoordDataValue {
fn from(reference: Angle) -> Self { fn from(reference: Angle) -> Self {
match reference { match reference {
Angle::Degree(val) => CoordDataValue::Degree(val), Angle::Deg(val) => CoordDataValue::Degree(val),
Angle::Gradian(val) => CoordDataValue::Grad(val), Angle::Grad(val) => CoordDataValue::Grad(val),
Angle::Radian(val) => CoordDataValue::Radian(val), Angle::Rad(val) => CoordDataValue::Radian(val),
Angle::Turn(val) => CoordDataValue::Turn(val), Angle::Turn(val) => CoordDataValue::Turn(val),
} }
} }
@ -128,9 +128,9 @@ impl Angle {
/// Converts Angle struct into (value, unit) pair. /// Converts Angle struct into (value, unit) pair.
pub fn to_gecko_values(&self) -> (f32, nsCSSUnit) { pub fn to_gecko_values(&self) -> (f32, nsCSSUnit) {
match *self { match *self {
Angle::Degree(val) => (val, nsCSSUnit::eCSSUnit_Degree), Angle::Deg(val) => (val, nsCSSUnit::eCSSUnit_Degree),
Angle::Gradian(val) => (val, nsCSSUnit::eCSSUnit_Grad), Angle::Grad(val) => (val, nsCSSUnit::eCSSUnit_Grad),
Angle::Radian(val) => (val, nsCSSUnit::eCSSUnit_Radian), Angle::Rad(val) => (val, nsCSSUnit::eCSSUnit_Radian),
Angle::Turn(val) => (val, nsCSSUnit::eCSSUnit_Turn), Angle::Turn(val) => (val, nsCSSUnit::eCSSUnit_Turn),
} }
} }
@ -138,9 +138,9 @@ impl Angle {
/// Converts gecko (value, unit) pair into Angle struct /// Converts gecko (value, unit) pair into Angle struct
pub fn from_gecko_values(value: f32, unit: nsCSSUnit) -> Angle { pub fn from_gecko_values(value: f32, unit: nsCSSUnit) -> Angle {
match unit { match unit {
nsCSSUnit::eCSSUnit_Degree => Angle::Degree(value), nsCSSUnit::eCSSUnit_Degree => Angle::Deg(value),
nsCSSUnit::eCSSUnit_Grad => Angle::Gradian(value), nsCSSUnit::eCSSUnit_Grad => Angle::Grad(value),
nsCSSUnit::eCSSUnit_Radian => Angle::Radian(value), nsCSSUnit::eCSSUnit_Radian => Angle::Rad(value),
nsCSSUnit::eCSSUnit_Turn => Angle::Turn(value), nsCSSUnit::eCSSUnit_Turn => Angle::Turn(value),
_ => panic!("Unexpected unit {:?} for angle", unit), _ => panic!("Unexpected unit {:?} for angle", unit),
} }

View file

@ -29,7 +29,7 @@ use style_traits::{CSSPixel, DevicePixel};
use style_traits::{ToCss, ParseError, StyleParseErrorKind}; use style_traits::{ToCss, ParseError, StyleParseErrorKind};
use style_traits::viewport::ViewportConstraints; use style_traits::viewport::ViewportConstraints;
use stylesheets::Origin; use stylesheets::Origin;
use values::{CSSFloat, CustomIdent, serialize_dimension}; use values::{CSSFloat, CustomIdent};
use values::computed::{self, ToComputedValue}; use values::computed::{self, ToComputedValue};
use values::computed::font::FontSize; use values::computed::font::FontSize;
use values::specified::Length; use values::specified::Length;
@ -262,7 +262,8 @@ impl PartialEq for Expression {
} }
/// A resolution. /// A resolution.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq, ToCss)]
#[css(dimension)]
pub enum Resolution { pub enum Resolution {
/// Dots per inch. /// Dots per inch.
Dpi(CSSFloat), Dpi(CSSFloat),
@ -303,18 +304,6 @@ impl Resolution {
} }
} }
impl ToCss for Resolution {
fn to_css<W>(&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. /// A value found or expected in a media expression.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum MediaExpressionValue { pub enum MediaExpressionValue {

View file

@ -291,9 +291,9 @@ impl GeckoStyleCoordConvertible for Angle {
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> { fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
match coord.as_value() { match coord.as_value() {
CoordDataValue::Degree(val) => Some(Angle::Degree(val)), CoordDataValue::Degree(val) => Some(Angle::Deg(val)),
CoordDataValue::Grad(val) => Some(Angle::Gradian(val)), CoordDataValue::Grad(val) => Some(Angle::Grad(val)),
CoordDataValue::Radian(val) => Some(Angle::Radian(val)), CoordDataValue::Radian(val) => Some(Angle::Rad(val)),
CoordDataValue::Turn(val) => Some(Angle::Turn(val)), CoordDataValue::Turn(val) => Some(Angle::Turn(val)),
_ => None, _ => None,
} }

View file

@ -5,9 +5,8 @@
//! Computed angles. //! Computed angles.
use euclid::Radians; use euclid::Radians;
use std::{f32, f64, fmt}; use std::{f32, f64};
use std::f64::consts::PI; use std::f64::consts::PI;
use style_traits::ToCss;
use values::CSSFloat; use values::CSSFloat;
use values::animated::{Animate, Procedure}; use values::animated::{Animate, Procedure};
use values::distance::{ComputeSquaredDistance, SquaredDistance}; use values::distance::{ComputeSquaredDistance, SquaredDistance};
@ -15,15 +14,16 @@ use values::distance::{ComputeSquaredDistance, SquaredDistance};
/// A computed angle. /// A computed angle.
#[animate(fallback = "Self::animate_fallback")] #[animate(fallback = "Self::animate_fallback")]
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[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)] #[derive(PartialOrd, ToAnimatedZero)]
#[css(dimension)]
pub enum Angle { pub enum Angle {
/// An angle with degree unit. /// An angle with degree unit.
Degree(CSSFloat), Deg(CSSFloat),
/// An angle with gradian unit. /// An angle with gradian unit.
Gradian(CSSFloat), Grad(CSSFloat),
/// An angle with radian unit. /// An angle with radian unit.
Radian(CSSFloat), Rad(CSSFloat),
/// An angle with turn unit. /// An angle with turn unit.
Turn(CSSFloat), Turn(CSSFloat),
} }
@ -31,7 +31,7 @@ pub enum Angle {
impl Angle { impl Angle {
/// Creates a computed `Angle` value from a radian amount. /// Creates a computed `Angle` value from a radian amount.
pub fn from_radians(radians: CSSFloat) -> Self { pub fn from_radians(radians: CSSFloat) -> Self {
Angle::Radian(radians) Angle::Rad(radians)
} }
/// Returns the amount of radians this angle represents. /// Returns the amount of radians this angle represents.
@ -53,17 +53,17 @@ impl Angle {
const RAD_PER_TURN: f64 = PI * 2.0; const RAD_PER_TURN: f64 = PI * 2.0;
let radians = match *self { let radians = match *self {
Angle::Degree(val) => val as f64 * RAD_PER_DEG, Angle::Deg(val) => val as f64 * RAD_PER_DEG,
Angle::Gradian(val) => val as f64 * RAD_PER_GRAD, Angle::Grad(val) => val as f64 * RAD_PER_GRAD,
Angle::Turn(val) => val as f64 * RAD_PER_TURN, 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) radians.min(f64::MAX).max(f64::MIN)
} }
/// Returns an angle that represents a rotation of zero radians. /// Returns an angle that represents a rotation of zero radians.
pub fn zero() -> Self { pub fn zero() -> Self {
Angle::Radian(0.0) Self::from_radians(0.0)
} }
/// <https://drafts.csswg.org/css-transitions/#animtype-number> /// <https://drafts.csswg.org/css-transitions/#animtype-number>
@ -82,25 +82,6 @@ impl ComputeSquaredDistance for Angle {
} }
} }
impl ToCss for Angle {
fn to_css<W>(&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<Angle> for Radians<CSSFloat> { impl From<Angle> for Radians<CSSFloat> {
#[inline] #[inline]
fn from(a: Angle) -> Self { fn from(a: Angle) -> Self {

View file

@ -57,12 +57,12 @@ impl ToComputedValue for Angle {
impl Angle { impl Angle {
/// Creates an angle with the given value in degrees. /// Creates an angle with the given value in degrees.
pub fn from_degrees(value: CSSFloat, was_calc: bool) -> Self { 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. /// Creates an angle with the given value in gradians.
pub fn from_gradians(value: CSSFloat, was_calc: bool) -> Self { 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. /// Creates an angle with the given value in turns.
@ -72,7 +72,7 @@ impl Angle {
/// Creates an angle with the given value in radians. /// Creates an angle with the given value in radians.
pub fn from_radians(value: CSSFloat, was_calc: bool) -> Self { 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. /// Returns the amount of radians this angle represents.
@ -89,7 +89,7 @@ impl Angle {
/// Returns an `Angle` parsed from a `calc()` expression. /// Returns an `Angle` parsed from a `calc()` expression.
pub fn from_calc(radians: CSSFloat) -> Self { pub fn from_calc(radians: CSSFloat) -> Self {
Angle { Angle {
value: ComputedAngle::Radian(radians), value: ComputedAngle::Rad(radians),
was_calc: true, was_calc: true,
} }
} }

View file

@ -400,7 +400,13 @@ impl CalcNode {
NoCalcLength::ServoCharacterWidth(..) => unreachable!(), NoCalcLength::ServoCharacterWidth(..) => unreachable!(),
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
NoCalcLength::Physical(physical) => { 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);
}
}
} }
} }
} }

View file

@ -11,15 +11,14 @@ use cssparser::{Parser, Token};
use euclid::Size2D; use euclid::Size2D;
use font_metrics::FontMetricsQueryResult; use font_metrics::FontMetricsQueryResult;
use parser::{Parse, ParserContext}; use parser::{Parse, ParserContext};
use std::{cmp, fmt, mem}; use std::{cmp, mem};
#[allow(unused_imports)] use std::ascii::AsciiExt; #[allow(unused_imports)] use std::ascii::AsciiExt;
use std::ops::{Add, Mul}; use std::ops::{Add, Mul};
use style_traits::{ToCss, ParseError, StyleParseErrorKind}; use style_traits::{ParseError, StyleParseErrorKind};
use style_traits::values::specified::AllowedNumericType; use style_traits::values::specified::AllowedNumericType;
use stylesheets::CssRuleType; use stylesheets::CssRuleType;
use super::{AllowQuirks, Number, ToComputedValue, Percentage}; use super::{AllowQuirks, Number, ToComputedValue, Percentage};
use values::{Auto, CSSFloat, Either, None_, Normal}; use values::{Auto, CSSFloat, Either, ExtremumLength, None_, Normal};
use values::{ExtremumLength, serialize_dimension};
use values::computed::{self, CSSPixelLength, Context}; use values::computed::{self, CSSPixelLength, Context};
use values::generics::NonNegative; use values::generics::NonNegative;
use values::specified::NonNegativeNumber; use values::specified::NonNegativeNumber;
@ -52,8 +51,9 @@ pub fn au_to_int_px(au: f32) -> i32 {
(au / AU_PER_PX).round() as i32 (au / AU_PER_PX).round() as i32
} }
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
/// A font relative length. /// A font relative length.
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
#[css(dimension)]
pub enum FontRelativeLength { pub enum FontRelativeLength {
/// A "em" value: https://drafts.csswg.org/css-values/#em /// A "em" value: https://drafts.csswg.org/css-values/#em
Em(CSSFloat), Em(CSSFloat),
@ -65,19 +65,6 @@ pub enum FontRelativeLength {
Rem(CSSFloat) Rem(CSSFloat)
} }
impl ToCss for FontRelativeLength {
fn to_css<W>(&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 /// A source to resolve font-relative units against
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
pub enum FontBaseSize { pub enum FontBaseSize {
@ -206,10 +193,11 @@ impl FontRelativeLength {
} }
} }
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
/// A viewport-relative length. /// A viewport-relative length.
/// ///
/// <https://drafts.csswg.org/css-values/#viewport-relative-lengths> /// <https://drafts.csswg.org/css-values/#viewport-relative-lengths>
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
#[css(dimension)]
pub enum ViewportPercentageLength { pub enum ViewportPercentageLength {
/// A vw unit: https://drafts.csswg.org/css-values/#vw /// A vw unit: https://drafts.csswg.org/css-values/#vw
Vw(CSSFloat), Vw(CSSFloat),
@ -221,17 +209,6 @@ pub enum ViewportPercentageLength {
Vmax(CSSFloat) Vmax(CSSFloat)
} }
impl ToCss for ViewportPercentageLength {
fn to_css<W>(&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 { impl ViewportPercentageLength {
/// Computes the given viewport-relative length for the given viewport size. /// Computes the given viewport-relative length for the given viewport size.
pub fn to_computed_value(&self, viewport_size: Size2D<Au>) -> CSSPixelLength { pub fn to_computed_value(&self, viewport_size: Size2D<Au>) -> CSSPixelLength {
@ -255,7 +232,7 @@ impl ViewportPercentageLength {
} }
/// HTML5 "character width", as defined in HTML5 § 14.5.4. /// 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); pub struct CharacterWidth(pub i32);
impl CharacterWidth { impl CharacterWidth {
@ -273,7 +250,8 @@ impl CharacterWidth {
} }
/// Represents an absolute length with its unit /// Represents an absolute length with its unit
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)] #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
#[css(dimension)]
pub enum AbsoluteLength { pub enum AbsoluteLength {
/// An absolute length in pixels (px) /// An absolute length in pixels (px)
Px(CSSFloat), Px(CSSFloat),
@ -334,20 +312,6 @@ impl ToComputedValue for AbsoluteLength {
} }
} }
impl ToCss for AbsoluteLength {
fn to_css<W>(&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<CSSFloat> for AbsoluteLength { impl Mul<CSSFloat> for AbsoluteLength {
type Output = AbsoluteLength; type Output = AbsoluteLength;
@ -383,19 +347,25 @@ impl Add<AbsoluteLength> for AbsoluteLength {
} }
} }
/// Represents a physical length (mozmm) based on DPI /// Represents a physical length based on DPI.
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq, ToCss)]
#[cfg(feature = "gecko")]
#[derive(MallocSizeOf)] #[derive(MallocSizeOf)]
pub struct PhysicalLength(pub CSSFloat); #[css(dimension)]
pub enum PhysicalLength {
/// A physical length in millimetres.
Mozmm(CSSFloat),
}
#[cfg(feature = "gecko")]
impl PhysicalLength { impl PhysicalLength {
fn is_zero(&self) -> bool { /// Checks whether the length value is zero.
self.0 == 0. pub fn is_zero(&self) -> bool {
match *self {
PhysicalLength::Mozmm(v) => v == 0.,
}
} }
/// Computes the given character width. /// Computes the given character width.
#[cfg(feature = "gecko")]
pub fn to_computed_value(&self, context: &Context) -> CSSPixelLength { pub fn to_computed_value(&self, context: &Context) -> CSSPixelLength {
use gecko_bindings::bindings; use gecko_bindings::bindings;
use std::f32; use std::f32;
@ -408,32 +378,31 @@ impl PhysicalLength {
}; };
let px_per_physical_inch = au_per_physical_inch / AU_PER_PX; 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)) CSSPixelLength::new(pixel.min(f32::MAX).max(f32::MIN))
} }
} }
#[cfg(feature = "gecko")]
impl ToCss for PhysicalLength {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
serialize_dimension(self.0, "mozmm", dest)
}
}
#[cfg(feature = "gecko")]
impl Mul<CSSFloat> for PhysicalLength { impl Mul<CSSFloat> for PhysicalLength {
type Output = PhysicalLength; type Output = Self ;
#[inline] #[inline]
fn mul(self, scalar: CSSFloat) -> PhysicalLength { fn mul(self, scalar: CSSFloat) -> Self {
PhysicalLength(self.0 * scalar) match self {
PhysicalLength::Mozmm(v) => PhysicalLength::Mozmm(v * scalar),
}
} }
} }
/// A `<length>` without taking `calc` expressions into account /// A `<length>` without taking `calc` expressions into account
/// ///
/// <https://drafts.csswg.org/css-values/#lengths> /// <https://drafts.csswg.org/css-values/#lengths>
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)] #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
pub enum NoCalcLength { pub enum NoCalcLength {
/// An absolute length /// An absolute length
/// ///
@ -454,6 +423,7 @@ pub enum NoCalcLength {
/// ///
/// This cannot be specified by the user directly and is only generated by /// This cannot be specified by the user directly and is only generated by
/// `Stylist::synthesize_rules_for_legacy_attributes()`. /// `Stylist::synthesize_rules_for_legacy_attributes()`.
#[css(function)]
ServoCharacterWidth(CharacterWidth), ServoCharacterWidth(CharacterWidth),
/// A physical length (mozmm) based on DPI /// A physical length (mozmm) based on DPI
@ -461,24 +431,6 @@ pub enum NoCalcLength {
Physical(PhysicalLength), Physical(PhysicalLength),
} }
impl ToCss for NoCalcLength {
fn to_css<W>(&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<CSSFloat> for NoCalcLength { impl Mul<CSSFloat> for NoCalcLength {
type Output = NoCalcLength; type Output = NoCalcLength;
@ -539,7 +491,7 @@ impl NoCalcLength {
Ok(NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vmax(value))) Ok(NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vmax(value)))
}, },
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
"mozmm" => Ok(NoCalcLength::Physical(PhysicalLength(value))), "mozmm" => Ok(NoCalcLength::Physical(PhysicalLength::Mozmm(value))),
_ => Err(()) _ => Err(())
} }
} }

View file

@ -19,9 +19,14 @@ pub fn derive(input: DeriveInput) -> Tokens {
let mut identifier = to_css_identifier(variant.ident.as_ref()); let mut identifier = to_css_identifier(variant.ident.as_ref());
let variant_attrs = cg::parse_variant_attrs::<CssVariantAttrs>(variant); let variant_attrs = cg::parse_variant_attrs::<CssVariantAttrs>(variant);
let separator = if variant_attrs.comma { ", " } else { " " }; let separator = if variant_attrs.comma { ", " } else { " " };
if input_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 = if !bindings.is_empty() {
let mut expr = quote! {}; let mut expr = quote! {};
if variant_attrs.function && variant_attrs.iterable { if variant_attrs.function && variant_attrs.iterable {
assert_eq!(bindings.len(), 1); assert_eq!(bindings.len(), 1);
let binding = &bindings[0]; let binding = &bindings[0];
@ -52,7 +57,18 @@ pub fn derive(input: DeriveInput) -> Tokens {
::std::fmt::Write::write_str(dest, #identifier) ::std::fmt::Write::write_str(dest, #identifier)
} }
}; };
if variant_attrs.function {
if input_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("("); identifier.push_str("(");
expr = quote! { expr = quote! {
::std::fmt::Write::write_str(dest, #identifier)?; ::std::fmt::Write::write_str(dest, #identifier)?;
@ -96,6 +112,7 @@ pub fn derive(input: DeriveInput) -> Tokens {
struct CssInputAttrs { struct CssInputAttrs {
derive_debug: bool, derive_debug: bool,
function: bool, function: bool,
dimension: bool,
comma: bool, comma: bool,
} }

View file

@ -3171,7 +3171,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetLengthValue(
structs::nsCSSUnit::eCSSUnit_Inch => NoCalcLength::Absolute(AbsoluteLength::In(value)), structs::nsCSSUnit::eCSSUnit_Inch => NoCalcLength::Absolute(AbsoluteLength::In(value)),
structs::nsCSSUnit::eCSSUnit_Centimeter => NoCalcLength::Absolute(AbsoluteLength::Cm(value)), structs::nsCSSUnit::eCSSUnit_Centimeter => NoCalcLength::Absolute(AbsoluteLength::Cm(value)),
structs::nsCSSUnit::eCSSUnit_Millimeter => NoCalcLength::Absolute(AbsoluteLength::Mm(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_Point => NoCalcLength::Absolute(AbsoluteLength::Pt(value)),
structs::nsCSSUnit::eCSSUnit_Pica => NoCalcLength::Absolute(AbsoluteLength::Pc(value)), structs::nsCSSUnit::eCSSUnit_Pica => NoCalcLength::Absolute(AbsoluteLength::Pc(value)),
structs::nsCSSUnit::eCSSUnit_Quarter => NoCalcLength::Absolute(AbsoluteLength::Q(value)), structs::nsCSSUnit::eCSSUnit_Quarter => NoCalcLength::Absolute(AbsoluteLength::Q(value)),