From 277351da3589ba6497635f12dc9793d032e469e1 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Sun, 13 Aug 2017 00:50:36 +0200 Subject: [PATCH] Derive ComputeSquaredDistance --- components/style/macros.rs | 12 +- components/style/properties/helpers.mako.rs | 13 +- .../style/properties/longhand/font.mako.rs | 11 +- .../longhand/inherited_table.mako.rs | 13 +- components/style/values/animated/effects.rs | 12 -- .../style/values/computed/background.rs | 19 --- components/style/values/computed/mod.rs | 25 +--- components/style/values/computed/text.rs | 23 ---- components/style/values/computed/transform.rs | 12 -- .../style/values/generics/background.rs | 2 +- .../style/values/generics/basic_shape.rs | 92 +------------- components/style/values/generics/border.rs | 31 +---- components/style/values/generics/effects.rs | 2 +- components/style/values/generics/mod.rs | 31 +---- components/style/values/generics/position.rs | 20 +-- components/style/values/generics/rect.rs | 18 +-- components/style/values/generics/svg.rs | 66 +--------- components/style/values/generics/text.rs | 2 +- components/style/values/generics/transform.rs | 2 +- components/style/values/mod.rs | 23 +--- .../style_derive/compute_squared_distance.rs | 117 ++++++++++++++++++ components/style_derive/lib.rs | 7 ++ 22 files changed, 162 insertions(+), 391 deletions(-) create mode 100644 components/style_derive/compute_squared_distance.rs diff --git a/components/style/macros.rs b/components/style/macros.rs index 3251b7e2d37..8af642f80da 100644 --- a/components/style/macros.rs +++ b/components/style/macros.rs @@ -84,7 +84,7 @@ macro_rules! define_keyword_type { ($name: ident, $css: expr) => { #[allow(missing_docs)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - #[derive(Clone, Copy, PartialEq, ToCss)] + #[derive(Clone, ComputeSquaredDistance, Copy, PartialEq, ToCss)] pub struct $name; impl $crate::properties::animated_properties::Animatable for $name { @@ -117,15 +117,5 @@ macro_rules! define_keyword_type { #[inline] fn to_animated_zero(&self) -> Result { Ok($name) } } - - impl $crate::values::distance::ComputeSquaredDistance for $name { - #[inline] - fn compute_squared_distance( - &self, - _other: &Self - ) -> Result<$crate::values::distance::SquaredDistance, ()> { - Ok($crate::values::distance::SquaredDistance::Value(0.)) - } - } }; } diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index d428cc20cdb..e82ee073c87 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -119,8 +119,11 @@ use values::computed::ComputedVecIter; /// The computed value, effectively a list of single values. - #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + #[derive(Clone, Debug, PartialEq)] + % if need_animatable or animation_value_type == "ComputedValue": + #[derive(ComputeSquaredDistance)] + % endif pub struct T( % if allow_empty and allow_empty != "NotInitial": pub Vec, @@ -132,7 +135,6 @@ % if need_animatable or animation_value_type == "ComputedValue": use properties::animated_properties::Animatable; use values::animated::ToAnimatedZero; - use values::distance::{ComputeSquaredDistance, SquaredDistance}; impl Animatable for T { fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) @@ -145,13 +147,6 @@ } } - impl ComputeSquaredDistance for T { - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - self.0.compute_squared_distance(&other.0) - } - } - impl ToAnimatedZero for T { #[inline] fn to_animated_zero(&self) -> Result { Err(()) } diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index 1eae098655e..0ebcf2db9a7 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -480,24 +480,15 @@ ${helpers.single_keyword_system("font-variant-caps", } pub mod computed_value { - use values::distance::{ComputeSquaredDistance, SquaredDistance}; - /// 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, Copy, Debug, PartialEq, Eq, Hash, ToCss)] + #[derive(Clone, ComputeSquaredDistance, Copy, Debug, PartialEq, Eq, Hash, ToCss)] #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))] pub struct T(pub u16); - impl ComputeSquaredDistance for T { - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - self.0.compute_squared_distance(&other.0) - } - } - impl T { /// Value for normal pub fn normal() -> Self { diff --git a/components/style/properties/longhand/inherited_table.mako.rs b/components/style/properties/longhand/inherited_table.mako.rs index d6aa1369bb3..1d646cc9410 100644 --- a/components/style/properties/longhand/inherited_table.mako.rs +++ b/components/style/properties/longhand/inherited_table.mako.rs @@ -28,11 +28,10 @@ ${helpers.single_keyword("caption-side", "top bottom", pub mod computed_value { use properties::animated_properties::Animatable; use values::animated::{ToAnimatedValue, ToAnimatedZero}; - use values::distance::{ComputeSquaredDistance, SquaredDistance}; use values::computed::NonNegativeAu; #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - #[derive(Clone, Copy, Debug, PartialEq, ToCss)] + #[derive(Clone, ComputeSquaredDistance, Copy, Debug, PartialEq, ToCss)] pub struct T { pub horizontal: NonNegativeAu, pub vertical: NonNegativeAu, @@ -52,16 +51,6 @@ ${helpers.single_keyword("caption-side", "top bottom", } } - impl ComputeSquaredDistance for T { - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - Ok( - self.horizontal.compute_squared_distance(&other.horizontal)? + - self.vertical.compute_squared_distance(&other.vertical)?, - ) - } - } - impl ToAnimatedZero for T { #[inline] fn to_animated_zero(&self) -> Result { Err(()) } diff --git a/components/style/values/animated/effects.rs b/components/style/values/animated/effects.rs index 5c4a02b519a..37cf926a1d7 100644 --- a/components/style/values/animated/effects.rs +++ b/components/style/values/animated/effects.rs @@ -227,18 +227,6 @@ impl Animatable for SimpleShadow { } } -impl ComputeSquaredDistance for SimpleShadow { - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - Ok( - self.color.compute_squared_distance(&other.color)? + - self.horizontal.compute_squared_distance(&other.horizontal)? + - self.vertical.compute_squared_distance(&other.vertical)? + - self.blur.compute_squared_distance(&other.blur)? - ) - } -} - impl ToAnimatedZero for SimpleShadow { #[inline] fn to_animated_zero(&self) -> Result { diff --git a/components/style/values/computed/background.rs b/components/style/values/computed/background.rs index 9bfb77c1523..a2111a046e4 100644 --- a/components/style/values/computed/background.rs +++ b/components/style/values/computed/background.rs @@ -8,7 +8,6 @@ use properties::animated_properties::{Animatable, RepeatableListAnimatable}; use properties::longhands::background_size::computed_value::T as BackgroundSizeList; use values::animated::{ToAnimatedValue, ToAnimatedZero}; use values::computed::length::LengthOrPercentageOrAuto; -use values::distance::{ComputeSquaredDistance, SquaredDistance}; use values::generics::background::BackgroundSize as GenericBackgroundSize; /// A computed value for the `background-size` property. @@ -33,24 +32,6 @@ impl Animatable for BackgroundSize { } } -impl ComputeSquaredDistance for BackgroundSize { - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - match (self, other) { - ( - &GenericBackgroundSize::Explicit { width: self_width, height: self_height }, - &GenericBackgroundSize::Explicit { width: other_width, height: other_height }, - ) => { - Ok( - self_width.compute_squared_distance(&other_width)? + - self_height.compute_squared_distance(&other_height)? - ) - } - _ => Err(()), - } - } -} - impl ToAnimatedZero for BackgroundSize { #[inline] fn to_animated_zero(&self) -> Result { Err(()) } diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 42f37b4ab22..b963d37fab6 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -543,9 +543,9 @@ pub type LengthOrPercentageOrNumber = Either; /// NonNegativeLengthOrPercentage | NonNegativeNumber pub type NonNegativeLengthOrPercentageOrNumber = Either; -#[derive(Clone, PartialEq, Eq, Copy, Debug)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Clone, ComputeSquaredDistance, Copy, Debug, Eq, PartialEq)] /// A computed cliprect for clip and image-region pub struct ClipRect { pub top: Option, @@ -554,18 +554,6 @@ pub struct ClipRect { pub left: Option, } -impl ComputeSquaredDistance for ClipRect { - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - Ok( - self.top.compute_squared_distance(&other.top)? + - self.right.compute_squared_distance(&other.right)? + - self.bottom.compute_squared_distance(&other.bottom)? + - self.left.compute_squared_distance(&other.left)?, - ) - } -} - impl ToCss for ClipRect { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { dest.write_str("rect(")?; @@ -671,17 +659,10 @@ impl From for NonNegativeAu { } /// A computed `` value. -#[derive(Clone, Copy, Debug, Default, PartialEq, HasViewportPercentage)] +#[derive(Clone, ComputeSquaredDistance, Copy, Debug, Default, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(Deserialize, HeapSizeOf, Serialize))] pub struct Percentage(pub CSSFloat); -impl ComputeSquaredDistance for Percentage { - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - self.0.compute_squared_distance(&other.0) - } -} - impl Percentage { /// 0% #[inline] diff --git a/components/style/values/computed/text.rs b/components/style/values/computed/text.rs index 7db57907391..fd39b4dd647 100644 --- a/components/style/values/computed/text.rs +++ b/components/style/values/computed/text.rs @@ -9,7 +9,6 @@ use values::{CSSInteger, CSSFloat}; use values::animated::ToAnimatedZero; use values::computed::{NonNegativeAu, NonNegativeNumber}; use values::computed::length::{Length, LengthOrPercentage}; -use values::distance::{ComputeSquaredDistance, SquaredDistance}; use values::generics::text::InitialLetter as GenericInitialLetter; use values::generics::text::LineHeight as GenericLineHeight; use values::generics::text::Spacing; @@ -48,28 +47,6 @@ impl Animatable for LineHeight { } } -impl ComputeSquaredDistance for LineHeight { - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - match (self, other) { - (&GenericLineHeight::Length(ref this), &GenericLineHeight::Length(ref other)) => { - this.compute_squared_distance(other) - }, - (&GenericLineHeight::Number(ref this), &GenericLineHeight::Number(ref other)) => { - this.compute_squared_distance(other) - }, - (&GenericLineHeight::Normal, &GenericLineHeight::Normal) => { - Ok(SquaredDistance::Value(0.)) - }, - #[cfg(feature = "gecko")] - (&GenericLineHeight::MozBlockHeight, &GenericLineHeight::MozBlockHeight) => { - Ok(SquaredDistance::Value(0.)) - }, - _ => Err(()), - } - } -} - impl ToAnimatedZero for LineHeight { #[inline] fn to_animated_zero(&self) -> Result { Err(()) } diff --git a/components/style/values/computed/transform.rs b/components/style/values/computed/transform.rs index c57bef639df..70c543b9a7f 100644 --- a/components/style/values/computed/transform.rs +++ b/components/style/values/computed/transform.rs @@ -7,7 +7,6 @@ use properties::animated_properties::Animatable; use values::animated::ToAnimatedZero; use values::computed::{Length, LengthOrPercentage, Number, Percentage}; -use values::distance::{ComputeSquaredDistance, SquaredDistance}; use values::generics::transform::TimingFunction as GenericTimingFunction; use values::generics::transform::TransformOrigin as GenericTransformOrigin; @@ -40,17 +39,6 @@ impl Animatable for TransformOrigin { } } -impl ComputeSquaredDistance for TransformOrigin { - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - Ok( - self.horizontal.compute_squared_distance(&other.horizontal)? + - self.vertical.compute_squared_distance(&other.vertical)? + - self.depth.compute_squared_distance(&other.depth)? - ) - } -} - impl ToAnimatedZero for TransformOrigin { #[inline] fn to_animated_zero(&self) -> Result { diff --git a/components/style/values/generics/background.rs b/components/style/values/generics/background.rs index aa24454ef6d..8a79691f3b9 100644 --- a/components/style/values/generics/background.rs +++ b/components/style/values/generics/background.rs @@ -5,7 +5,7 @@ //! Generic types for CSS values related to backgrounds. /// A generic value for the `background-size` property. -#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue, ToCss)] +#[derive(Clone, ComputeSquaredDistance, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue, ToCss)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum BackgroundSize { /// ` ` diff --git a/components/style/values/generics/basic_shape.rs b/components/style/values/generics/basic_shape.rs index cf1437ce8d0..cad038df0f1 100644 --- a/components/style/values/generics/basic_shape.rs +++ b/components/style/values/generics/basic_shape.rs @@ -55,7 +55,7 @@ pub enum ShapeSource { #[allow(missing_docs)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[derive(Clone, Debug, PartialEq, ToComputedValue, ToCss)] +#[derive(Clone, ComputeSquaredDistance, Debug, PartialEq, ToComputedValue, ToCss)] pub enum BasicShape { Inset(InsetRect), Circle(Circle), @@ -66,7 +66,7 @@ pub enum BasicShape { /// https://drafts.csswg.org/css-shapes/#funcdef-inset #[allow(missing_docs)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[derive(Clone, Debug, PartialEq, ToComputedValue)] +#[derive(Clone, ComputeSquaredDistance, Debug, PartialEq, ToComputedValue)] pub struct InsetRect { pub rect: Rect, pub round: Option>, @@ -75,7 +75,7 @@ pub struct InsetRect { /// https://drafts.csswg.org/css-shapes/#funcdef-circle #[allow(missing_docs)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[derive(Clone, Copy, Debug, PartialEq, ToComputedValue)] +#[derive(Clone, ComputeSquaredDistance, Copy, Debug, PartialEq, ToComputedValue)] pub struct Circle { pub position: Position, pub radius: ShapeRadius, @@ -84,7 +84,7 @@ pub struct Circle { /// https://drafts.csswg.org/css-shapes/#funcdef-ellipse #[allow(missing_docs)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[derive(Clone, Copy, Debug, PartialEq, ToComputedValue)] +#[derive(Clone, ComputeSquaredDistance, Copy, Debug, PartialEq, ToComputedValue)] pub struct Ellipse { pub position: Position, pub semiaxis_x: ShapeRadius, @@ -94,7 +94,7 @@ pub struct Ellipse { /// https://drafts.csswg.org/css-shapes/#typedef-shape-radius #[allow(missing_docs)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[derive(Clone, Copy, Debug, PartialEq, ToComputedValue, ToCss)] +#[derive(Clone, ComputeSquaredDistance, Copy, Debug, PartialEq, ToComputedValue, ToCss)] pub enum ShapeRadius { Length(LengthOrPercentage), ClosestSide, @@ -148,7 +148,7 @@ where } // FIXME(nox): Implement ComputeSquaredDistance for T types and stop -// using PartialEq here. +// using PartialEq here, this will let us derive this impl. impl ComputeSquaredDistance for ShapeSource where B: ComputeSquaredDistance, @@ -208,31 +208,6 @@ where } } -impl ComputeSquaredDistance for BasicShape -where - H: ComputeSquaredDistance, - V: ComputeSquaredDistance, - L: ComputeSquaredDistance + Copy, -{ - fn compute_squared_distance(&self, other: &Self) -> Result { - match (self, other) { - (&BasicShape::Circle(ref this), &BasicShape::Circle(ref other)) => { - this.compute_squared_distance(other) - }, - (&BasicShape::Ellipse(ref this), &BasicShape::Ellipse(ref other)) => { - this.compute_squared_distance(other) - }, - (&BasicShape::Inset(ref this), &BasicShape::Inset(ref other)) => { - this.compute_squared_distance(other) - }, - (&BasicShape::Polygon(ref this), &BasicShape::Polygon(ref other)) => { - this.compute_squared_distance(other) - }, - _ => Err(()), - } - } -} - impl Animatable for InsetRect where L: Animatable + Copy, @@ -249,18 +224,6 @@ where } } -impl ComputeSquaredDistance for InsetRect -where - L: ComputeSquaredDistance + Copy, -{ - fn compute_squared_distance(&self, other: &Self) -> Result { - Ok( - self.rect.compute_squared_distance(&other.rect)? + - self.round.compute_squared_distance(&other.round)?, - ) - } -} - impl ToCss for InsetRect where L: ToCss + PartialEq { @@ -293,20 +256,6 @@ where } } -impl ComputeSquaredDistance for Circle -where - H: ComputeSquaredDistance, - V: ComputeSquaredDistance, - L: ComputeSquaredDistance, -{ - fn compute_squared_distance(&self, other: &Self) -> Result { - Ok( - self.position.compute_squared_distance(&other.position)? + - self.radius.compute_squared_distance(&other.radius)?, - ) - } -} - impl Animatable for Ellipse where H: Animatable, @@ -326,21 +275,6 @@ where } } -impl ComputeSquaredDistance for Ellipse -where - H: ComputeSquaredDistance, - V: ComputeSquaredDistance, - L: ComputeSquaredDistance, -{ - fn compute_squared_distance(&self, other: &Self) -> Result { - Ok( - self.position.compute_squared_distance(&other.position)? + - self.semiaxis_x.compute_squared_distance(&other.semiaxis_x)? + - self.semiaxis_y.compute_squared_distance(&other.semiaxis_y)?, - ) - } -} - impl Animatable for ShapeRadius where L: Animatable, @@ -360,20 +294,6 @@ where } } -impl ComputeSquaredDistance for ShapeRadius -where - L: ComputeSquaredDistance, -{ - fn compute_squared_distance(&self, other: &Self) -> Result { - match (self, other) { - (&ShapeRadius::Length(ref this), &ShapeRadius::Length(ref other)) => { - this.compute_squared_distance(other) - }, - _ => Err(()), - } - } -} - impl Default for ShapeRadius { #[inline] fn default() -> Self { ShapeRadius::ClosestSide } diff --git a/components/style/values/generics/border.rs b/components/style/values/generics/border.rs index 9b66ce23dc2..78faf1de050 100644 --- a/components/style/values/generics/border.rs +++ b/components/style/values/generics/border.rs @@ -8,7 +8,6 @@ use euclid::Size2D; use properties::animated_properties::Animatable; use std::fmt; use style_traits::ToCss; -use values::distance::{ComputeSquaredDistance, SquaredDistance}; use values::generics::rect::Rect; /// A generic value for a single side of a `border-image-width` property. @@ -37,7 +36,7 @@ pub struct BorderImageSlice { /// /// https://drafts.csswg.org/css-backgrounds-3/#border-radius #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)] +#[derive(Clone, ComputeSquaredDistance, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)] pub struct BorderRadius { /// The top left radius. pub top_left: BorderCornerRadius, @@ -49,9 +48,9 @@ pub struct BorderRadius { pub bottom_left: BorderCornerRadius, } -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)] /// A generic value for `border-*-radius` longhand properties. +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Clone, ComputeSquaredDistance, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)] pub struct BorderCornerRadius(pub Size2D); impl From for BorderImageSlice @@ -132,20 +131,6 @@ where } } -impl ComputeSquaredDistance for BorderRadius -where - L: ComputeSquaredDistance + Copy, -{ - fn compute_squared_distance(&self, other: &Self) -> Result { - Ok( - self.top_left.compute_squared_distance(&other.top_left)? + - self.top_right.compute_squared_distance(&other.top_right)? + - self.bottom_right.compute_squared_distance(&other.bottom_right)? + - self.bottom_left.compute_squared_distance(&other.bottom_left)?, - ) - } -} - impl ToCss for BorderRadius where L: PartialEq + ToCss { @@ -193,16 +178,6 @@ where } } -impl ComputeSquaredDistance for BorderCornerRadius -where - L: ComputeSquaredDistance + Copy, -{ - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - self.0.compute_squared_distance(&other.0) - } -} - impl ToCss for BorderCornerRadius where L: ToCss, { diff --git a/components/style/values/generics/effects.rs b/components/style/values/generics/effects.rs index 9105123f5ab..cff8d87c078 100644 --- a/components/style/values/generics/effects.rs +++ b/components/style/values/generics/effects.rs @@ -65,7 +65,7 @@ pub enum Filter { /// Contrary to the canonical order from the spec, the color is serialised /// first, like in Gecko and Webkit. #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToAnimatedValue, ToCss)] +#[derive(Clone, ComputeSquaredDistance, Debug, HasViewportPercentage, PartialEq, ToAnimatedValue, ToCss)] pub struct SimpleShadow { /// Color. pub color: Color, diff --git a/components/style/values/generics/mod.rs b/components/style/values/generics/mod.rs index 689dd95f1d1..b097b0f85de 100644 --- a/components/style/values/generics/mod.rs +++ b/components/style/values/generics/mod.rs @@ -11,7 +11,6 @@ use parser::{Parse, ParserContext}; use std::fmt; use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseError, ToCss}; use super::CustomIdent; -use values::distance::{ComputeSquaredDistance, SquaredDistance}; pub mod background; pub mod basic_shape; @@ -268,31 +267,13 @@ impl ToCss for FontSettingTagFloat { } /// A wrapper of Non-negative values. -#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, PartialOrd, ToComputedValue, ToCss)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))] +#[cfg_attr(feature = "servo", derive(Deserialize, HeapSizeOf, Serialize))] +#[derive(Clone, ComputeSquaredDistance, Copy, Debug, HasViewportPercentage)] +#[derive(PartialEq, PartialOrd, ToComputedValue, ToCss)] pub struct NonNegative(pub T); -impl ComputeSquaredDistance for NonNegative -where - T: ComputeSquaredDistance, -{ - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - self.0.compute_squared_distance(&other.0) - } -} - /// A wrapper of greater-than-or-equal-to-one values. -#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, PartialOrd, ToComputedValue, ToCss)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))] +#[cfg_attr(feature = "servo", derive(Deserialize, HeapSizeOf, Serialize))] +#[derive(Clone, ComputeSquaredDistance, Copy, Debug, HasViewportPercentage)] +#[derive(PartialEq, PartialOrd, ToComputedValue, ToCss)] pub struct GreaterThanOrEqualToOne(pub T); - -impl ComputeSquaredDistance for GreaterThanOrEqualToOne -where - T: ComputeSquaredDistance, -{ - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - self.0.compute_squared_distance(&other.0) - } -} diff --git a/components/style/values/generics/position.rs b/components/style/values/generics/position.rs index 0c641a62daa..503cb9a1563 100644 --- a/components/style/values/generics/position.rs +++ b/components/style/values/generics/position.rs @@ -5,11 +5,9 @@ //! Generic types for CSS handling of specified and computed values of //! [`position`](https://drafts.csswg.org/css-backgrounds-3/#position) -use values::distance::{ComputeSquaredDistance, SquaredDistance}; - -#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] /// A generic type for representing a CSS [position](https://drafts.csswg.org/css-values/#position). +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Clone, ComputeSquaredDistance, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)] pub struct Position { /// The horizontal component of position. pub horizontal: H, @@ -26,17 +24,3 @@ impl Position { } } } - -impl ComputeSquaredDistance for Position -where - H: ComputeSquaredDistance, - V: ComputeSquaredDistance, -{ - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - Ok( - self.horizontal.compute_squared_distance(&other.horizontal)? + - self.vertical.compute_squared_distance(&other.vertical)?, - ) - } -} diff --git a/components/style/values/generics/rect.rs b/components/style/values/generics/rect.rs index b948cf88f82..89ce196267a 100644 --- a/components/style/values/generics/rect.rs +++ b/components/style/values/generics/rect.rs @@ -9,11 +9,10 @@ use parser::{Parse, ParserContext}; use properties::animated_properties::Animatable; use std::fmt; use style_traits::{ToCss, ParseError}; -use values::distance::{ComputeSquaredDistance, SquaredDistance}; /// A CSS value made of four components, where its `ToCss` impl will try to /// serialize as few components as possible, like for example in `border-width`. -#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)] +#[derive(Clone, ComputeSquaredDistance, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct Rect(pub T, pub T, pub T, pub T); @@ -71,21 +70,6 @@ where } } -impl ComputeSquaredDistance for Rect -where - L: ComputeSquaredDistance, -{ - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - Ok( - self.0.compute_squared_distance(&other.0)? + - self.1.compute_squared_distance(&other.1)? + - self.2.compute_squared_distance(&other.2)? + - self.3.compute_squared_distance(&other.3)?, - ) - } -} - impl From for Rect where T: Clone { diff --git a/components/style/values/generics/svg.rs b/components/style/values/generics/svg.rs index 079bce1f1c1..60f76950aee 100644 --- a/components/style/values/generics/svg.rs +++ b/components/style/values/generics/svg.rs @@ -6,10 +6,8 @@ use cssparser::Parser; use parser::{Parse, ParserContext}; -use properties::animated_properties::RepeatableListAnimatable; use std::fmt; use style_traits::{ParseError, StyleParseError, ToCss}; -use values::distance::{ComputeSquaredDistance, SquaredDistance}; /// An SVG paint value /// @@ -99,7 +97,8 @@ impl Parse for SVGPaint { /// ` | | ` Length(LengthType), @@ -107,28 +106,9 @@ pub enum SVGLength { ContextValue, } -impl ComputeSquaredDistance for SVGLength -where - L: ComputeSquaredDistance, -{ - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - match (self, other) { - (&SVGLength::Length(ref this), &SVGLength::Length(ref other)) => { - this.compute_squared_distance(other) - }, - _ => { - // FIXME(nox): Should this return `Ok(SquaredDistance::Value(0.))` - // if `self` and `other` are the same keyword value? - Err(()) - }, - } - } -} - /// Generic value for stroke-dasharray. #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[derive(Clone, Debug, PartialEq, HasViewportPercentage, ToAnimatedValue, ToComputedValue)] +#[derive(Clone, ComputeSquaredDistance, Debug, PartialEq, HasViewportPercentage, ToAnimatedValue, ToComputedValue)] pub enum SVGStrokeDashArray { /// `[ | | ]#` Values(Vec), @@ -136,25 +116,6 @@ pub enum SVGStrokeDashArray { ContextValue, } -impl ComputeSquaredDistance for SVGStrokeDashArray -where - L: ComputeSquaredDistance + RepeatableListAnimatable, -{ - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - match (self, other) { - (&SVGStrokeDashArray::Values(ref this), &SVGStrokeDashArray::Values(ref other)) => { - this.compute_squared_distance(other) - }, - _ => { - // FIXME(nox): Should this return `Ok(SquaredDistance::Value(0.))` - // if `self` and `other` are the same keyword value? - Err(()) - }, - } - } -} - impl ToCss for SVGStrokeDashArray where LengthType: ToCss { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match self { @@ -181,7 +142,7 @@ impl ToCss for SVGStrokeDashArray where LengthType: ToCs /// An SVG opacity value accepts `context-{fill,stroke}-opacity` in /// addition to opacity value. #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[derive(Clone, Copy, Debug, PartialEq, HasViewportPercentage, ToComputedValue, ToCss)] +#[derive(Clone, ComputeSquaredDistance, Copy, Debug, PartialEq, HasViewportPercentage, ToComputedValue, ToCss)] pub enum SVGOpacity { /// `` Opacity(OpacityType), @@ -190,22 +151,3 @@ pub enum SVGOpacity { /// `context-stroke-opacity` ContextStrokeOpacity, } - -impl ComputeSquaredDistance for SVGOpacity -where - L: ComputeSquaredDistance, -{ - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - match (self, other) { - (&SVGOpacity::Opacity(ref this), &SVGOpacity::Opacity(ref other)) => { - this.compute_squared_distance(other) - } - _ => { - // FIXME(nox): Should this return `Ok(SquaredDistance::Value(0.))` - // if `self` and `other` are the same keyword value? - Err(()) - }, - } - } -} diff --git a/components/style/values/generics/text.rs b/components/style/values/generics/text.rs index 3330d0dbceb..a3879602bdc 100644 --- a/components/style/values/generics/text.rs +++ b/components/style/values/generics/text.rs @@ -110,7 +110,7 @@ where /// A generic value for the `line-height` property. #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToAnimatedValue, ToCss)] +#[derive(Clone, ComputeSquaredDistance, Copy, Debug, HasViewportPercentage, PartialEq, ToAnimatedValue, ToCss)] pub enum LineHeight { /// `normal` Normal, diff --git a/components/style/values/generics/transform.rs b/components/style/values/generics/transform.rs index e00104f0c43..32f37caec12 100644 --- a/components/style/values/generics/transform.rs +++ b/components/style/values/generics/transform.rs @@ -24,7 +24,7 @@ pub struct Matrix { /// A generic transform origin. #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue, ToCss)] +#[derive(Clone, ComputeSquaredDistance, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue, ToCss)] pub struct TransformOrigin { /// The horizontal origin. pub horizontal: H, diff --git a/components/style/values/mod.rs b/components/style/values/mod.rs index 4a2c20b3b18..f03ab188a7a 100644 --- a/components/style/values/mod.rs +++ b/components/style/values/mod.rs @@ -16,7 +16,6 @@ use std::ascii::AsciiExt; use std::fmt::{self, Debug}; use std::hash; use style_traits::{ToCss, ParseError, StyleParseError}; -use values::distance::{ComputeSquaredDistance, SquaredDistance}; pub mod animated; pub mod computed; @@ -53,7 +52,8 @@ impl Parse for Impossible { /// A struct representing one of two kinds of values. #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[derive(Clone, Copy, HasViewportPercentage, PartialEq, ToAnimatedValue, ToComputedValue, ToCss)] +#[derive(Clone, ComputeSquaredDistance, Copy, HasViewportPercentage, PartialEq)] +#[derive(ToAnimatedValue, ToComputedValue, ToCss)] pub enum Either { /// The first value. First(A), @@ -61,25 +61,6 @@ pub enum Either { Second(B), } -impl ComputeSquaredDistance for Either -where - A: ComputeSquaredDistance, - B: ComputeSquaredDistance, -{ - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - match (self, other) { - (&Either::First(ref this), &Either::First(ref other)) => { - this.compute_squared_distance(other) - }, - (&Either::Second(ref this), &Either::Second(ref other)) => { - this.compute_squared_distance(other) - }, - _ => Err(()) - } - } -} - impl Debug for Either { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { diff --git a/components/style_derive/compute_squared_distance.rs b/components/style_derive/compute_squared_distance.rs new file mode 100644 index 00000000000..46aa376319d --- /dev/null +++ b/components/style_derive/compute_squared_distance.rs @@ -0,0 +1,117 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use quote; +use std::borrow::Cow; +use syn; +use synstructure; + +pub fn derive(input: syn::DeriveInput) -> quote::Tokens { + let name = &input.ident; + let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + let mut where_clause = where_clause.clone(); + for param in &input.generics.ty_params { + where_clause.predicates.push(where_predicate(syn::Ty::Path(None, param.ident.clone().into()))) + } + + let variants = variants(&input); + let mut match_body = quote!(); + match_body.append_all(variants.iter().map(|variant| { + let name = match input.body { + syn::Body::Struct(_) => Cow::Borrowed(&input.ident), + syn::Body::Enum(_) => { + Cow::Owned(syn::Ident::from(format!("{}::{}", input.ident, variant.ident))) + }, + }; + let (this_pattern, this_info) = synstructure::match_pattern( + &name, + &variant.data, + &synstructure::BindOpts::with_prefix( + synstructure::BindStyle::Ref, + "this".to_owned(), + ), + ); + let (other_pattern, other_info) = synstructure::match_pattern( + &name, + &variant.data, + &synstructure::BindOpts::with_prefix( + synstructure::BindStyle::Ref, + "other".to_owned(), + ), + ); + let sum = if this_info.is_empty() { + quote! { ::values::distance::SquaredDistance::Value(0.) } + } else { + let mut sum = quote!(); + sum.append_separated(this_info.iter().zip(&other_info).map(|(this, other)| { + where_clause.predicates.push(where_predicate(this.field.ty.clone())); + quote! { + ::values::distance::ComputeSquaredDistance::compute_squared_distance(#this, #other)? + } + }), "+"); + sum + }; + quote! { + (&#this_pattern, &#other_pattern) => { + Ok(#sum) + } + } + })); + + if variants.len() > 1 { + match_body = quote! { #match_body, _ => Err(()), }; + } + + quote! { + impl #impl_generics ::values::distance::ComputeSquaredDistance for #name #ty_generics #where_clause { + #[allow(unused_variables, unused_imports)] + #[inline] + fn compute_squared_distance( + &self, + other: &Self, + ) -> Result<::values::distance::SquaredDistance, ()> { + match (self, other) { + #match_body + } + } + } + } +} + +fn variants(input: &syn::DeriveInput) -> Cow<[syn::Variant]> { + match input.body { + syn::Body::Enum(ref variants) => (&**variants).into(), + syn::Body::Struct(ref data) => { + vec![syn::Variant { + ident: input.ident.clone(), + attrs: input.attrs.clone(), + data: data.clone(), + discriminant: None, + }].into() + }, + } +} + +fn where_predicate(ty: syn::Ty) -> syn::WherePredicate { + syn::WherePredicate::BoundPredicate( + syn::WhereBoundPredicate { + bound_lifetimes: vec![], + bounded_ty: ty, + bounds: vec![syn::TyParamBound::Trait( + syn::PolyTraitRef { + bound_lifetimes: vec![], + trait_ref: syn::Path { + global: true, + segments: vec![ + "values".into(), + "distance".into(), + "ComputeSquaredDistance".into(), + ], + }, + }, + syn::TraitBoundModifier::None, + )], + }, + ) +} diff --git a/components/style_derive/lib.rs b/components/style_derive/lib.rs index 683d6c2c563..13a855eb6ba 100644 --- a/components/style_derive/lib.rs +++ b/components/style_derive/lib.rs @@ -9,11 +9,18 @@ extern crate synstructure; use proc_macro::TokenStream; +mod compute_squared_distance; mod has_viewport_percentage; mod to_animated_value; mod to_computed_value; mod to_css; +#[proc_macro_derive(ComputeSquaredDistance)] +pub fn derive_compute_squared_distance(stream: TokenStream) -> TokenStream { + let input = syn::parse_derive_input(&stream.to_string()).unwrap(); + compute_squared_distance::derive(input).to_string().parse().unwrap() +} + #[proc_macro_derive(HasViewportPercentage)] pub fn derive_has_viewport_percentage(stream: TokenStream) -> TokenStream { let input = syn::parse_derive_input(&stream.to_string()).unwrap();