Bug 1374233 - Part 8: Implement ToAnimatedValue for BorderCornerRadius. draft
authorBoris Chiou <boris.chiou@gmail.com>
Fri, 21 Jul 2017 13:01:56 +0800
changeset 614999 35a82792d901a9acaaf3a8da6287f113435ca071
parent 614998 6d0a21f50687384fc91b93f9a158338748e14376
child 615000 aa97c1697ad28ea7be9a9ac28dff40d987355c61
push id70205
push userbmo:boris.chiou@gmail.com
push dateTue, 25 Jul 2017 08:53:17 +0000
bugs1374233
milestone56.0a1
Bug 1374233 - Part 8: Implement ToAnimatedValue for BorderCornerRadius. BorderCornerRadius should always be non-negative, so we can implemennt ToAnimatedValue for it directly, for properties: 1. border-{*}-radius 2. -moz-outline-{*}-radius MozReview-Commit-ID: HEbeHz9Hfkd
servo/components/style/properties/longhand/border.mako.rs
servo/components/style/properties/longhand/outline.mako.rs
servo/components/style/values/animated/mod.rs
servo/components/style/values/computed/length.rs
--- a/servo/components/style/properties/longhand/border.mako.rs
+++ b/servo/components/style/properties/longhand/border.mako.rs
@@ -57,17 +57,17 @@
 // FIXME(#4126): when gfx supports painting it, make this Size2D<LengthOrPercentage>
 % for corner in ["top-left", "top-right", "bottom-right", "bottom-left"]:
     ${helpers.predefined_type("border-" + corner + "-radius", "BorderCornerRadius",
                               "computed::LengthOrPercentage::zero().into()",
                               "parse", extra_prefixes="webkit",
                               spec="https://drafts.csswg.org/css-backgrounds/#border-%s-radius" % corner,
                               boxed=True,
                               flags="APPLIES_TO_FIRST_LETTER",
-                              animation_value_type="ComputedValue")}
+                              animation_value_type="BorderCornerRadius")}
 % endfor
 
 /// -moz-border-*-colors: color, string, enum, none, inherit/initial
 /// These non-spec properties are just for Gecko (Stylo) internal use.
 % for side in PHYSICAL_SIDES:
     <%helpers:longhand name="-moz-border-${side}-colors" animation_value_type="discrete"
                        spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-border-*-colors)"
                        products="gecko"
--- a/servo/components/style/properties/longhand/outline.mako.rs
+++ b/servo/components/style/properties/longhand/outline.mako.rs
@@ -71,15 +71,15 @@
                           spec="https://drafts.csswg.org/css-ui/#propdef-outline-width")}
 
 // The -moz-outline-radius-* properties are non-standard and not on a standards track.
 % for corner in ["topleft", "topright", "bottomright", "bottomleft"]:
     ${helpers.predefined_type("-moz-outline-radius-" + corner, "BorderCornerRadius",
         "computed::LengthOrPercentage::zero().into()",
         products="gecko",
         boxed=True,
-        animation_value_type="ComputedValue",
+        animation_value_type="BorderCornerRadius",
         spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-outline-radius)")}
 % endfor
 
 ${helpers.predefined_type("outline-offset", "Length", "Au(0)", products="servo gecko",
                           animation_value_type="ComputedValue",
                           spec="https://drafts.csswg.org/css-ui/#propdef-outline-offset")}
--- a/servo/components/style/values/animated/mod.rs
+++ b/servo/components/style/values/animated/mod.rs
@@ -5,16 +5,17 @@
 //! Animated values.
 //!
 //! Some values, notably colors, cannot be interpolated directly with their
 //! computed values and need yet another intermediate representation. This
 //! module's raison d'ĂȘtre is to ultimately contain all these types.
 
 use app_units::Au;
 use values::computed::Angle as ComputedAngle;
+use values::computed::BorderCornerRadius as ComputedBorderCornerRadius;
 use values::computed::NonNegativeAu;
 use values::computed::NonNegativeNumber as ComputedNonNegativeNumber;
 use values::computed::GreaterThanOrEqualToOneNumber as ComputedGreaterThanOrEqualToOneNumber;
 use values::computed::PositiveInteger as ComputedPositiveInteger;
 use values::computed::NonNegativeLengthOrPercentage as ComputedNonNegativeLengthOrPercentage;
 use values::specified::url::SpecifiedUrl;
 
 pub mod effects;
@@ -154,28 +155,32 @@ impl ToAnimatedValue for ComputedNonNega
 
     #[inline]
     fn to_animated_value(self) -> Self {
         self
     }
 
     #[inline]
     fn from_animated_value(animated: Self::AnimatedValue) -> Self {
-        use values::computed::{LengthOrPercentage, Percentage};
-        match animated.0 {
-            LengthOrPercentage::Length(au) => {
-                ComputedNonNegativeLengthOrPercentage(
-                    LengthOrPercentage::Length(Au(::std::cmp::max(au.0, 0))))
-            },
-            LengthOrPercentage::Percentage(percentage) => {
-                ComputedNonNegativeLengthOrPercentage(
-                    LengthOrPercentage::Percentage(Percentage(percentage.0.max(0.))))
-            },
-            _ => animated
-        }
+        ComputedNonNegativeLengthOrPercentage(animated.0.clamp_to_non_negative())
+    }
+}
+
+impl ToAnimatedValue for ComputedBorderCornerRadius {
+    type AnimatedValue = Self;
+
+    #[inline]
+    fn to_animated_value(self) -> Self {
+        self
+    }
+
+    #[inline]
+    fn from_animated_value(animated: Self::AnimatedValue) -> Self {
+        ComputedBorderCornerRadius::new(animated.0.width.clamp_to_non_negative(),
+                                        animated.0.height.clamp_to_non_negative())
     }
 }
 
 /// Returns a value similar to `self` that represents zero.
 pub trait ToAnimatedZero: Sized {
     /// Returns a value that, when added with an underlying value, will produce the underlying
     /// value. This is used for SMIL animation's "by-animation" where SMIL first interpolates from
     /// the zero value to the 'by' value, and then adds the result to the underlying value.
--- a/servo/components/style/values/computed/length.rs
+++ b/servo/components/style/values/computed/length.rs
@@ -346,16 +346,30 @@ impl LengthOrPercentage {
         match *self {
             LengthOrPercentage::Length(length) => length,
             LengthOrPercentage::Percentage(p) => containing_length.scale_by(p.0),
             LengthOrPercentage::Calc(ref calc) => {
                 calc.to_used_value(Some(containing_length)).unwrap()
             },
         }
     }
+
+    /// Returns the clamped non-negative values.
+    #[inline]
+    pub fn clamp_to_non_negative(self) -> Self {
+        match self {
+            LengthOrPercentage::Length(length) => {
+                LengthOrPercentage::Length(Au(::std::cmp::max(length.0, 0)))
+            },
+            LengthOrPercentage::Percentage(percentage) => {
+                LengthOrPercentage::Percentage(Percentage(percentage.0.max(0.)))
+            },
+            _ => self
+        }
+    }
 }
 
 impl fmt::Debug for LengthOrPercentage {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             LengthOrPercentage::Length(length) => write!(f, "{:?}", length),
             LengthOrPercentage::Percentage(percentage) => write!(f, "{}%", percentage.0 * 100.),
             LengthOrPercentage::Calc(calc) => write!(f, "{:?}", calc),