diff options
-rw-r--r-- | components/style/properties/gecko.mako.rs | 3 | ||||
-rw-r--r-- | components/style/properties/longhand/inherited_box.mako.rs | 196 | ||||
-rw-r--r-- | components/style/values/computed/inherited_box.rs | 75 | ||||
-rw-r--r-- | components/style/values/computed/mod.rs | 2 | ||||
-rw-r--r-- | components/style/values/specified/inherited_box.rs | 139 | ||||
-rw-r--r-- | components/style/values/specified/mod.rs | 2 |
6 files changed, 228 insertions, 189 deletions
diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index bb67759a554..94d51177246 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -4611,7 +4611,8 @@ fn static_assert() { 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 { diff --git a/components/style/properties/longhand/inherited_box.mako.rs b/components/style/properties/longhand/inherited_box.mako.rs index 2002f868d89..dabbe14d859 100644 --- a/components/style/properties/longhand/inherited_box.mako.rs +++ b/components/style/properties/longhand/inherited_box.mako.rs @@ -57,191 +57,11 @@ ${helpers.single_keyword("image-rendering", 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")} diff --git a/components/style/values/computed/inherited_box.rs b/components/style/values/computed/inherited_box.rs new file mode 100644 index 00000000000..2fa4dd819a5 --- /dev/null +++ b/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(()) + }, + } + } +} diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index a127b8e58b0..96bd928d352 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -46,6 +46,7 @@ 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; @@ -81,6 +82,7 @@ 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; diff --git a/components/style/values/specified/inherited_box.rs b/components/style/values/specified/inherited_box.rs new file mode 100644 index 00000000000..6d483c35fb2 --- /dev/null +++ b/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 }) + } + } +} diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index e2b16607957..b8b648dcbcd 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -43,6 +43,7 @@ pub use self::flex::FlexBasis; 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}; @@ -83,6 +84,7 @@ pub mod font; pub mod gecko; pub mod grid; pub mod image; +pub mod inherited_box; pub mod length; pub mod list; pub mod outline; |