Bug 1455358: Fix clamping on animations. r=xidorn
authorEmilio Cobos Álvarez <emilio@crisal.io>
Thu, 19 Apr 2018 21:40:25 +0200
changeset 468638 4e937037938d4add34f469efa2899f63927969f2
parent 468637 eb75243cba9830bbe86f22ad92abca867b947d0e
child 468639 e366b3efb7482a13a72e1d3e4f124bda870332cf
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersxidorn
bugs1455358
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1455358: Fix clamping on animations. r=xidorn MozReview-Commit-ID: Awyub0dMOmq
servo/components/style/properties/longhand/font.mako.rs
servo/components/style/values/computed/angle.rs
servo/components/style/values/computed/font.rs
servo/components/style/values/specified/angle.rs
servo/components/style/values/specified/font.rs
--- a/servo/components/style/properties/longhand/font.mako.rs
+++ b/servo/components/style/properties/longhand/font.mako.rs
@@ -15,18 +15,17 @@
                           spec="https://drafts.csswg.org/css-fonts/#propdef-font-family",
                           servo_restyle_damage="rebuild_and_reflow")}
 
 ${helpers.predefined_type(
     "font-style",
     "FontStyle",
     initial_value="computed::FontStyle::normal()",
     initial_specified_value="specified::FontStyle::normal()",
-    # FIXME(emilio): This won't handle clamping correctly.
-    animation_value_type="ComputedValue",
+    animation_value_type="FontStyle",
     flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
     spec="https://drafts.csswg.org/css-fonts/#propdef-font-style",
     servo_restyle_damage="rebuild_and_reflow",
 )}
 
 <% font_variant_caps_custom_consts= { "small-caps": "SMALLCAPS",
                                       "all-small-caps": "ALLSMALL",
                                       "petite-caps": "PETITECAPS",
--- a/servo/components/style/values/computed/angle.rs
+++ b/servo/components/style/values/computed/angle.rs
@@ -59,16 +59,22 @@ impl Angle {
             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::Rad(val) => val as f64,
         };
         radians.min(f64::MAX).max(f64::MIN)
     }
 
+    /// Return the value in degrees.
+    pub fn degrees(&self) -> f32 {
+        use std::f32::consts::PI;
+        self.radians() * 360. / (2. * PI)
+    }
+
     /// <https://drafts.csswg.org/css-transitions/#animtype-number>
     #[inline]
     fn animate_fallback(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
         Ok(Angle::from_radians(self.radians().animate(&other.radians(), procedure)?))
     }
 }
 
 impl AsRef<Angle> for Angle {
--- a/servo/components/style/values/computed/font.rs
+++ b/servo/components/style/values/computed/font.rs
@@ -824,35 +824,58 @@ impl ToComputedValue for specified::MozS
         cmp::min(int, i8::MAX as i32) as i8
     }
 
     fn from_computed_value(other: &i8) -> Self {
         specified::MozScriptLevel::MozAbsolute(*other as i32)
     }
 }
 
+/// A wrapper over an `Angle`, that handles clamping to the appropriate range
+/// for `font-style` animation.
+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
+pub struct FontStyleAngle(pub Angle);
+
+impl ToAnimatedValue for FontStyleAngle {
+    type AnimatedValue = Angle;
+
+    #[inline]
+    fn to_animated_value(self) -> Self::AnimatedValue {
+        self.0
+    }
+
+    #[inline]
+    fn from_animated_value(animated: Self::AnimatedValue) -> Self {
+        FontStyleAngle(Angle::Deg(
+            animated.degrees()
+                .min(specified::FONT_STYLE_OBLIQUE_MAX_ANGLE_DEGREES)
+                .max(specified::FONT_STYLE_OBLIQUE_MIN_ANGLE_DEGREES)
+        ))
+    }
+}
+
 /// The computed value of `font-style`.
 ///
 /// FIXME(emilio): Angle should be a custom type to handle clamping during
 /// animation.
-pub type FontStyle = generics::FontStyle<Angle>;
+pub type FontStyle = generics::FontStyle<FontStyleAngle>;
 
 impl FontStyle {
     /// The `normal` value.
     #[inline]
     pub fn normal() -> Self {
         generics::FontStyle::Normal
     }
 
     /// The default angle for font-style: oblique. This is 20deg per spec:
     ///
     /// https://drafts.csswg.org/css-fonts-4/#valdef-font-style-oblique-angle
     #[inline]
-    pub fn default_angle() -> Angle {
-        Angle::Deg(specified::DEFAULT_FONT_STYLE_OBLIQUE_ANGLE_DEGREES)
+    fn default_angle() -> FontStyleAngle {
+        FontStyleAngle(Angle::Deg(specified::DEFAULT_FONT_STYLE_OBLIQUE_ANGLE_DEGREES))
     }
 
 
     /// Get the font style from Gecko's nsFont struct.
     #[cfg(feature = "gecko")]
     pub fn from_gecko(kw: u8) -> Self {
         use gecko_bindings::structs;
 
--- a/servo/components/style/values/specified/angle.rs
+++ b/servo/components/style/values/specified/angle.rs
@@ -105,18 +105,17 @@ impl Angle {
     #[inline]
     pub fn radians(self) -> f32 {
         self.value.radians()
     }
 
     /// Returns the amount of degrees this angle represents.
     #[inline]
     pub fn degrees(self) -> f32 {
-        use std::f32::consts::PI;
-        self.radians() * 360. / (2. * PI)
+        self.value.degrees()
     }
 
     /// Returns `0deg`.
     pub fn zero() -> Self {
         Self::from_degrees(0.0, false)
     }
 
     /// Returns an `Angle` parsed from a `calc()` expression.
--- a/servo/components/style/values/specified/font.rs
+++ b/servo/components/style/values/specified/font.rs
@@ -14,17 +14,17 @@ use gecko_bindings::bindings;
 use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
 use parser::{Parse, ParserContext};
 use properties::longhands::system_font::SystemFont;
 use std::fmt::{self, Write};
 use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
 use values::CustomIdent;
 use values::computed::{Angle as ComputedAngle, Percentage as ComputedPercentage};
 use values::computed::{font as computed, Context, Length, NonNegativeLength, ToComputedValue};
-use values::computed::font::{FamilyName, FontFamilyList, SingleFontFamily};
+use values::computed::font::{FamilyName, FontFamilyList, FontStyleAngle, SingleFontFamily};
 use values::generics::NonNegative;
 use values::generics::font::{self as generics, FeatureTagValue, FontSettings, FontTag};
 use values::generics::font::{KeywordInfo as GenericKeywordInfo, KeywordSize, VariationValue};
 use values::specified::{AllowQuirks, Angle, Integer, LengthOrPercentage, NoCalcLength, Number, Percentage};
 use values::specified::length::{FontBaseSize, AU_PER_PT, AU_PER_PX};
 
 const DEFAULT_SCRIPT_MIN_SIZE_PT: u32 = 8;
 const DEFAULT_SCRIPT_SIZE_MULTIPLIER: f64 = 0.71;
@@ -236,27 +236,27 @@ impl Parse for SpecifiedFontStyle {
 impl ToComputedValue for SpecifiedFontStyle {
     type ComputedValue = computed::FontStyle;
 
     fn to_computed_value(&self, _: &Context) -> Self::ComputedValue {
         match *self {
             generics::FontStyle::Normal => generics::FontStyle::Normal,
             generics::FontStyle::Italic => generics::FontStyle::Italic,
             generics::FontStyle::Oblique(ref angle) => {
-                generics::FontStyle::Oblique(Self::compute_angle(angle))
+                generics::FontStyle::Oblique(FontStyleAngle(Self::compute_angle(angle)))
             }
         }
     }
 
     fn from_computed_value(computed: &Self::ComputedValue) -> Self {
         match *computed {
             generics::FontStyle::Normal => generics::FontStyle::Normal,
             generics::FontStyle::Italic => generics::FontStyle::Italic,
             generics::FontStyle::Oblique(ref angle) => {
-                generics::FontStyle::Oblique(Angle::from_computed_value(angle))
+                generics::FontStyle::Oblique(Angle::from_computed_value(&angle.0))
             }
         }
     }
 }
 
 
 /// The default angle for `font-style: oblique`.
 ///