Skip to content

Commit

Permalink
Move image-orientation property outside of mako
Browse files Browse the repository at this point in the history
Fixes #19765
  • Loading branch information
jonleighton committed Jan 14, 2018
1 parent 7b92eb9 commit bd55639
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 189 deletions.
3 changes: 2 additions & 1 deletion components/style/properties/gecko.mako.rs
Expand Up @@ -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 {
Expand Down
196 changes: 8 additions & 188 deletions components/style/properties/longhand/inherited_box.mako.rs
Expand Up @@ -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")}
75 changes: 75 additions & 0 deletions 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(())
},
}
}
}
2 changes: 2 additions & 0 deletions components/style/values/computed/mod.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit bd55639

Please sign in to comment.