servo: Merge #19766 - Move image-orientation property outside of mako (from jonleighton:issue-19765); r=emilio
authorJon Leighton <j@jonathanleighton.com>
Sun, 14 Jan 2018 16:55:15 -0600
changeset 453530 0969933b3908afef3035183c93f8fd67d2bcef31
parent 453529 1a3dd418e8e7f7ece934ad0ffb91109514de3cce
child 453531 516d427dcc01f9702a2819a6990d10a68977b272
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
milestone59.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
servo: Merge #19766 - Move image-orientation property outside of mako (from jonleighton:issue-19765); r=emilio Fixes https://github.com/servo/servo/issues/19765 r? emilio Source-Repo: https://github.com/servo/servo Source-Revision: ec34023d7a1ba5d7cc882fbb66b880960ce79c43
servo/components/style/properties/gecko.mako.rs
servo/components/style/properties/longhand/inherited_box.mako.rs
servo/components/style/values/computed/inherited_box.rs
servo/components/style/values/computed/mod.rs
servo/components/style/values/specified/inherited_box.rs
servo/components/style/values/specified/mod.rs
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -4604,17 +4604,18 @@ fn static_assert() {
     }
 
     pub fn reset_image_orientation(&mut self, other: &Self) {
         self.copy_image_orientation_from(other)
     }
 
     pub fn clone_image_orientation(&self) -> longhands::image_orientation::computed_value::T {
         use gecko_bindings::structs::nsStyleImageOrientation_Angles;
-        use properties::longhands::image_orientation::computed_value::{Orientation, T};
+        use properties::longhands::image_orientation::computed_value::T;
+        use values::computed::Orientation;
 
         let gecko_orientation = self.gecko.mImageOrientation.mOrientation;
         if gecko_orientation & structs::nsStyleImageOrientation_Bits_FROM_IMAGE_MASK as u8 != 0 {
             T::FromImage
         } else {
             const ANGLE0: u8 = nsStyleImageOrientation_Angles::ANGLE_0 as u8;
             const ANGLE90: u8 = nsStyleImageOrientation_Angles::ANGLE_90 as u8;
             const ANGLE180: u8 = nsStyleImageOrientation_Angles::ANGLE_180 as u8;
--- a/servo/components/style/properties/longhand/inherited_box.mako.rs
+++ b/servo/components/style/properties/longhand/inherited_box.mako.rs
@@ -52,196 +52,16 @@
 ${helpers.single_keyword("image-rendering",
                          "auto",
                          extra_gecko_values="optimizespeed optimizequality -moz-crisp-edges",
                          extra_servo_values="pixelated crisp-edges",
                          custom_consts=image_rendering_custom_consts,
                          animation_value_type="discrete",
                          spec="https://drafts.csswg.org/css-images/#propdef-image-rendering")}
 
-// Image Orientation
-<%helpers:longhand name="image-orientation"
-                   products="gecko"
-                   animation_value_type="discrete"
-                   gecko_pref="layout.css.image-orientation.enabled"
-    spec="https://drafts.csswg.org/css-images/#propdef-image-orientation, \
-      /// additional values in https://developer.mozilla.org/en-US/docs/Web/CSS/image-orientation">
-    use std::fmt;
-    use style_traits::ToCss;
-    use values::specified::Angle;
-
-
-    use std::f64::consts::PI;
-    const TWO_PI: f64 = 2.0 * PI;
-
-    #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
-    pub struct SpecifiedValue {
-        pub angle: Option<Angle>,
-        pub flipped: bool
-    }
-
-    impl ToCss for SpecifiedValue {
-        fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
-            if let Some(angle) = self.angle {
-                angle.to_css(dest)?;
-                if self.flipped {
-                    dest.write_str(" flip")
-                } else {
-                    Ok(())
-                }
-            } else {
-                if self.flipped {
-                    dest.write_str("flip")
-                } else {
-                    dest.write_str("from-image")
-                }
-            }
-        }
-    }
-
-    pub mod computed_value {
-        use std::fmt;
-        use style_traits::ToCss;
-        use values::specified::Angle;
-
-        #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq)]
-        pub enum Orientation {
-            Angle0 = 0,
-            Angle90,
-            Angle180,
-            Angle270,
-        }
-
-        impl Orientation {
-            pub fn angle(&self) -> Angle {
-                match *self {
-                    Orientation::Angle0 => Angle::from_degrees(0.0, false),
-                    Orientation::Angle90 => Angle::from_degrees(90.0, false),
-                    Orientation::Angle180 => Angle::from_degrees(180.0, false),
-                    Orientation::Angle270 => Angle::from_degrees(270.0, false),
-                }
-            }
-        }
-
-        impl ToCss for Orientation {
-            fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
-                // Should agree with Angle::to_css.
-                match *self {
-                    Orientation::Angle0 => dest.write_str("0deg"),
-                    Orientation::Angle90 => dest.write_str("90deg"),
-                    Orientation::Angle180 => dest.write_str("180deg"),
-                    Orientation::Angle270 => dest.write_str("270deg"),
-                }
-            }
-        }
-
-        #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
-        pub enum T {
-            FromImage,
-            AngleWithFlipped(Orientation, bool),
-        }
-    }
-
-    use self::computed_value::Orientation;
-
-    #[inline]
-    pub fn get_initial_value() -> computed_value::T {
-        computed_value::T::AngleWithFlipped(Orientation::Angle0, false)
-    }
-
-    // According to CSS Content Module Level 3:
-    // The computed value of the property is calculated by rounding the specified angle
-    // to the nearest quarter-turn, rounding away from 0, then moduloing the value by 1 turn.
-    // This mirrors the Gecko implementation in
-    // nsStyleImageOrientation::CreateAsAngleAndFlip.
-    #[inline]
-    fn orientation_of_angle(angle: &computed::Angle) -> Orientation {
-        // Note that `angle` can be negative.
-        let mut rounded_angle = angle.radians64() % TWO_PI;
-        if rounded_angle < 0.0 {
-            // This computation introduces rounding error. Gecko previously
-            // didn't handle the negative case correctly; by branching we can
-            // match Gecko's behavior when it was correct.
-            rounded_angle = rounded_angle + TWO_PI;
-        }
-        if rounded_angle < 0.25 * PI {
-            return Orientation::Angle0
-        }
-        if rounded_angle < 0.75 * PI {
-            return Orientation::Angle90
-        }
-        if rounded_angle < 1.25 * PI {
-            return Orientation::Angle180
-        }
-        if rounded_angle < 1.75 * PI {
-            return Orientation::Angle270
-        }
-        Orientation::Angle0
-    }
-
-    impl ToComputedValue for SpecifiedValue {
-        type ComputedValue = computed_value::T;
-
-        #[inline]
-        fn to_computed_value(&self, context: &Context) -> computed_value::T {
-            if let Some(ref angle) = self.angle {
-                let angle = angle.to_computed_value(context);
-                let orientation = orientation_of_angle(&angle);
-                computed_value::T::AngleWithFlipped(orientation, self.flipped)
-            } else {
-                if self.flipped {
-                    computed_value::T::AngleWithFlipped(Orientation::Angle0, true)
-                } else {
-                    computed_value::T::FromImage
-                }
-            }
-        }
-
-        #[inline]
-        fn from_computed_value(computed: &computed_value::T) -> Self {
-            match *computed {
-                computed_value::T::FromImage => SpecifiedValue { angle: None, flipped: false },
-                computed_value::T::AngleWithFlipped(ref orientation, flipped) => {
-                    SpecifiedValue {
-                        angle: Some(orientation.angle()),
-                        flipped: flipped,
-                    }
-                }
-            }
-        }
-    }
-
-    impl ToCss for computed_value::T {
-        fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
-            match *self {
-                computed_value::T::FromImage => dest.write_str("from-image"),
-                computed_value::T::AngleWithFlipped(angle, flipped) => {
-                    angle.to_css(dest)?;
-                    if flipped {
-                        dest.write_str(" flip")?;
-                    }
-                    Ok(())
-                },
-            }
-        }
-    }
-
-    // from-image | <angle> | [<angle>? flip]
-    pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                         -> Result<SpecifiedValue, ParseError<'i>> {
-        if input.try(|input| input.expect_ident_matching("from-image")).is_ok() {
-            // Handle from-image
-            Ok(SpecifiedValue { angle: None, flipped: false })
-        } else if input.try(|input| input.expect_ident_matching("flip")).is_ok() {
-            // Handle flip
-            Ok(SpecifiedValue { angle: Some(Angle::zero()), flipped: true })
-        } else {
-            // Handle <angle> | <angle> flip
-            let angle = input.try(|input| Angle::parse(context, input)).ok();
-            if angle.is_none() {
-                return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
-            }
-
-            let flipped = input.try(|input| input.expect_ident_matching("flip")).is_ok();
-            Ok(SpecifiedValue { angle: angle, flipped: flipped })
-        }
-    }
-</%helpers:longhand>
+${helpers.predefined_type("image-orientation",
+                          "ImageOrientation",
+                          "computed::ImageOrientation::zero()",
+                          products="gecko",
+                          animation_value_type="discrete",
+                          gecko_pref="layout.css.image-orientation.enabled",
+                          spec="https://drafts.csswg.org/css-images/#propdef-image-orientation, \
+                    /// additional values in https://developer.mozilla.org/en-US/docs/Web/CSS/image-orientation")}
new file mode 100644
--- /dev/null
+++ b/servo/components/style/values/computed/inherited_box.rs
@@ -0,0 +1,75 @@
+/* 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/. */
+
+//! Computed values for inherited box
+
+use std::fmt;
+use style_traits::ToCss;
+use values::specified::Angle;
+
+/// An angle rounded and normalized per https://drafts.csswg.org/css-images/#propdef-image-orientation
+#[allow(missing_docs)]
+#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq)]
+pub enum Orientation {
+    Angle0 = 0,
+    Angle90,
+    Angle180,
+    Angle270,
+}
+
+impl Orientation {
+    /// Get the actual angle that this orientation value represents.
+    pub fn angle(&self) -> Angle {
+        match *self {
+            Orientation::Angle0 => Angle::from_degrees(0.0, false),
+            Orientation::Angle90 => Angle::from_degrees(90.0, false),
+            Orientation::Angle180 => Angle::from_degrees(180.0, false),
+            Orientation::Angle270 => Angle::from_degrees(270.0, false),
+        }
+    }
+}
+
+impl ToCss for Orientation {
+    fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+        // Should agree with Angle::to_css.
+        match *self {
+            Orientation::Angle0 => dest.write_str("0deg"),
+            Orientation::Angle90 => dest.write_str("90deg"),
+            Orientation::Angle180 => dest.write_str("180deg"),
+            Orientation::Angle270 => dest.write_str("270deg"),
+        }
+    }
+}
+
+/// https://drafts.csswg.org/css-images/#propdef-image-orientation
+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
+pub enum ImageOrientation {
+    /// 'from-image'
+    FromImage,
+
+    /// '<angle>' | '<angle>? flip'
+    AngleWithFlipped(Orientation, bool),
+}
+
+impl ImageOrientation {
+    #[allow(missing_docs)]
+    pub fn zero() -> Self {
+        ImageOrientation::AngleWithFlipped(Orientation::Angle0, false)
+    }
+}
+
+impl ToCss for ImageOrientation {
+    fn to_css<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result {
+        match *self {
+            ImageOrientation::FromImage => dest.write_str("from-image"),
+            ImageOrientation::AngleWithFlipped(angle, flipped) => {
+                angle.to_css(dest)?;
+                if flipped {
+                    dest.write_str(" flip")?;
+                }
+                Ok(())
+            },
+        }
+    }
+}
--- a/servo/components/style/values/computed/mod.rs
+++ b/servo/components/style/values/computed/mod.rs
@@ -41,16 +41,17 @@ pub use self::font::{FontFamily, FontLan
 pub use self::font::{FontVariantLigatures, FontVariantNumeric, FontFeatureSettings};
 pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XTextZoom, XLang};
 pub use self::box_::{AnimationIterationCount, AnimationName, Display, OverscrollBehavior, Contain};
 pub use self::box_::{OverflowClipBox, ScrollSnapType, TouchAction, VerticalAlign, WillChange};
 pub use self::color::{Color, ColorPropertyValue, RGBAColor};
 pub use self::effects::{BoxShadow, Filter, SimpleShadow};
 pub use self::flex::FlexBasis;
 pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection, MozImageRect};
+pub use self::inherited_box::{Orientation, ImageOrientation};
 #[cfg(feature = "gecko")]
 pub use self::gecko::ScrollSnapPoint;
 pub use self::rect::LengthOrNumberRect;
 pub use super::{Auto, Either, None_};
 pub use super::specified::{BorderStyle, TextDecorationLine};
 pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNone, LengthOrNumber, LengthOrPercentage};
 pub use self::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, MaxLength, MozLength};
 pub use self::length::{CSSPixelLength, NonNegativeLength, NonNegativeLengthOrPercentage};
@@ -76,16 +77,17 @@ pub mod basic_shape;
 pub mod border;
 #[path = "box.rs"]
 pub mod box_;
 pub mod color;
 pub mod effects;
 pub mod flex;
 pub mod font;
 pub mod image;
+pub mod inherited_box;
 #[cfg(feature = "gecko")]
 pub mod gecko;
 pub mod length;
 pub mod list;
 pub mod outline;
 pub mod percentage;
 pub mod position;
 pub mod rect;
new file mode 100644
--- /dev/null
+++ b/servo/components/style/values/specified/inherited_box.rs
@@ -0,0 +1,139 @@
+/* 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/. */
+
+//! Specified values for inherited box
+
+use cssparser::Parser;
+use parser::{Parse, ParserContext};
+use std::f64::consts::PI;
+use std::fmt;
+use style_traits::{ParseError, StyleParseErrorKind, ToCss};
+use values::computed;
+use values::computed::{Context, Orientation, ToComputedValue};
+use values::specified::Angle;
+
+/// The specified value of the `image-orientation` property.
+/// https://drafts.csswg.org/css-images/#propdef-image-orientation
+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
+pub struct ImageOrientation {
+    /// The angle specified, if any
+    pub angle: Option<Angle>,
+
+    /// Whether or not "flip" was specified
+    pub flipped: bool
+}
+
+impl ToCss for ImageOrientation {
+    fn to_css<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result {
+        if let Some(angle) = self.angle {
+            angle.to_css(dest)?;
+            if self.flipped {
+                dest.write_str(" flip")
+            } else {
+                Ok(())
+            }
+        } else {
+            if self.flipped {
+                dest.write_str("flip")
+            } else {
+                dest.write_str("from-image")
+            }
+        }
+    }
+}
+
+const TWO_PI: f64 = 2.0 * PI;
+
+// According to CSS Content Module Level 3:
+// The computed value of the property is calculated by rounding the specified angle
+// to the nearest quarter-turn, rounding away from 0, then moduloing the value by 1 turn.
+// This mirrors the Gecko implementation in
+// nsStyleImageOrientation::CreateAsAngleAndFlip.
+#[inline]
+fn orientation_of_angle(angle: &computed::Angle) -> Orientation {
+    // Note that `angle` can be negative.
+    let mut rounded_angle = angle.radians64() % TWO_PI;
+    if rounded_angle < 0.0 {
+        // This computation introduces rounding error. Gecko previously
+        // didn't handle the negative case correctly; by branching we can
+        // match Gecko's behavior when it was correct.
+        rounded_angle += TWO_PI;
+    }
+    if rounded_angle < 0.25 * PI {
+        return Orientation::Angle0
+    }
+    if rounded_angle < 0.75 * PI {
+        return Orientation::Angle90
+    }
+    if rounded_angle < 1.25 * PI {
+        return Orientation::Angle180
+    }
+    if rounded_angle < 1.75 * PI {
+        return Orientation::Angle270
+    }
+    Orientation::Angle0
+}
+
+impl ToComputedValue for ImageOrientation {
+    type ComputedValue = computed::ImageOrientation;
+
+    #[inline]
+    fn to_computed_value(&self, context: &Context) -> computed::ImageOrientation {
+        if let Some(ref angle) = self.angle {
+            let angle = angle.to_computed_value(context);
+            let orientation = orientation_of_angle(&angle);
+            computed::ImageOrientation::AngleWithFlipped(orientation, self.flipped)
+        } else {
+            if self.flipped {
+                computed::ImageOrientation::zero()
+            } else {
+                computed::ImageOrientation::FromImage
+            }
+        }
+    }
+
+    #[inline]
+    fn from_computed_value(computed: &computed::ImageOrientation) -> Self {
+        match *computed {
+            computed::ImageOrientation::FromImage => {
+                ImageOrientation {
+                    angle: None,
+                    flipped: false
+                }
+            },
+
+            computed::ImageOrientation::AngleWithFlipped(ref orientation, flipped) => {
+                ImageOrientation {
+                    angle: Some(orientation.angle()),
+                    flipped: flipped,
+                }
+            }
+        }
+    }
+}
+
+impl Parse for ImageOrientation {
+    // from-image | <angle> | [<angle>? flip]
+    fn parse<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>
+    ) -> Result<Self, ParseError<'i>> {
+        if input.try(|input| input.expect_ident_matching("from-image")).is_ok() {
+            // Handle from-image
+            Ok(ImageOrientation { angle: None, flipped: false })
+        } else if input.try(|input| input.expect_ident_matching("flip")).is_ok() {
+            // Handle flip
+            Ok(ImageOrientation { angle: Some(Angle::zero()), flipped: true })
+        } else {
+            // Handle <angle> | <angle> flip
+            let angle = input.try(|input| Angle::parse(context, input)).ok();
+            if angle.is_none() {
+                return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
+            }
+
+            let flipped = input.try(|input| input.expect_ident_matching("flip")).is_ok();
+            Ok(ImageOrientation { angle: angle, flipped: flipped })
+        }
+    }
+}
--- a/servo/components/style/values/specified/mod.rs
+++ b/servo/components/style/values/specified/mod.rs
@@ -38,16 +38,17 @@ pub use self::box_::{AnimationIterationC
 pub use self::box_::{OverflowClipBox, ScrollSnapType, TouchAction, VerticalAlign, WillChange};
 pub use self::color::{Color, ColorPropertyValue, RGBAColor};
 pub use self::effects::{BoxShadow, Filter, SimpleShadow};
 pub use self::flex::FlexBasis;
 #[cfg(feature = "gecko")]
 pub use self::gecko::ScrollSnapPoint;
 pub use self::image::{ColorStop, EndingShape as GradientEndingShape, Gradient};
 pub use self::image::{GradientItem, GradientKind, Image, ImageLayer, MozImageRect};
+pub use self::inherited_box::ImageOrientation;
 pub use self::length::{AbsoluteLength, CalcLengthOrPercentage, CharacterWidth};
 pub use self::length::{FontRelativeLength, Length, LengthOrNone, LengthOrNumber};
 pub use self::length::{LengthOrPercentage, LengthOrPercentageOrAuto};
 pub use self::length::{LengthOrPercentageOrNone, MaxLength, MozLength};
 pub use self::length::{NoCalcLength, ViewportPercentageLength};
 pub use self::length::NonNegativeLengthOrPercentage;
 pub use self::list::{ListStyleImage, Quotes};
 #[cfg(feature = "gecko")]
@@ -78,16 +79,17 @@ pub mod calc;
 pub mod color;
 pub mod effects;
 pub mod flex;
 pub mod font;
 #[cfg(feature = "gecko")]
 pub mod gecko;
 pub mod grid;
 pub mod image;
+pub mod inherited_box;
 pub mod length;
 pub mod list;
 pub mod outline;
 pub mod percentage;
 pub mod position;
 pub mod rect;
 pub mod source_size_list;
 pub mod svg;