aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-07-11 11:22:26 -0700
committerGitHub <noreply@github.com>2017-07-11 11:22:26 -0700
commitde331c6bc8f987521d600043285d32f42be07048 (patch)
tree3346d6a5d8fa416fcf66c5db6a20d6a8dd56fe17
parentbc1ac6e64cd9735d87e4057f4bbe61023ffc22f5 (diff)
parente554146e2a6d1b4ecf409ab8980574e0dd007e8e (diff)
downloadservo-de331c6bc8f987521d600043285d32f42be07048.tar.gz
servo-de331c6bc8f987521d600043285d32f42be07048.zip
Auto merge of #17654 - jyc:image-orientation, r=Manishearth
Make Servo's rounding of image-orientation values agree with Gecko's, and pass orientations directly as an enum instead of as angles. Has been reviewed: https://reviewboard.mozilla.org/r/155336/ <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [ ] `./mach build -d` does not report any errors - [ ] `./mach test-tidy` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [X] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Bugzilla issue: https://bugzilla.mozilla.org/show_bug.cgi?id=1355380 <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17654) <!-- Reviewable:end -->
-rw-r--r--components/style/gecko/generated/bindings.rs2
-rw-r--r--components/style/properties/gecko.mako.rs4
-rw-r--r--components/style/properties/longhand/inherited_box.mako.rs79
-rw-r--r--components/style/values/computed/mod.rs29
4 files changed, 85 insertions, 29 deletions
diff --git a/components/style/gecko/generated/bindings.rs b/components/style/gecko/generated/bindings.rs
index 427992d8939..f5c64216008 100644
--- a/components/style/gecko/generated/bindings.rs
+++ b/components/style/gecko/generated/bindings.rs
@@ -897,7 +897,7 @@ extern "C" {
}
extern "C" {
pub fn Gecko_SetImageOrientation(aVisibility: *mut nsStyleVisibility,
- aRadians: f64, aFlip: bool);
+ aOrientation: u8, aFlip: bool);
}
extern "C" {
pub fn Gecko_SetImageOrientationAsFromImage(aVisibility:
diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs
index 13f7b130841..240139c33cb 100644
--- a/components/style/properties/gecko.mako.rs
+++ b/components/style/properties/gecko.mako.rs
@@ -3846,9 +3846,9 @@ fn static_assert() {
bindings::Gecko_SetImageOrientationAsFromImage(&mut self.gecko);
}
},
- T::AngleWithFlipped(ref angle, flipped) => {
+ T::AngleWithFlipped(ref orientation, flipped) => {
unsafe {
- bindings::Gecko_SetImageOrientation(&mut self.gecko, angle.radians() as f64, flipped);
+ bindings::Gecko_SetImageOrientation(&mut self.gecko, *orientation as u8, flipped);
}
}
}
diff --git a/components/style/properties/longhand/inherited_box.mako.rs b/components/style/properties/longhand/inherited_box.mako.rs
index 772847df0ba..b6830761abf 100644
--- a/components/style/properties/longhand/inherited_box.mako.rs
+++ b/components/style/properties/longhand/inherited_box.mako.rs
@@ -68,9 +68,8 @@ ${helpers.single_keyword("image-rendering",
no_viewport_percentage!(SpecifiedValue);
- use std::f32::consts::PI;
- use values::CSSFloat;
- const TWO_PI: CSSFloat = 2.0 * PI;
+ use std::f64::consts::PI;
+ const TWO_PI: f64 = 2.0 * PI;
#[derive(Clone, PartialEq, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
@@ -99,31 +98,77 @@ ${helpers.single_keyword("image-rendering",
}
pub mod computed_value {
- use values::computed::Angle;
+ use std::fmt;
+ use style_traits::ToCss;
+ use values::specified::Angle;
+
+ #[derive(Copy, Clone, Debug, Eq, PartialEq)]
+ #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+ 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, PartialEq, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum T {
FromImage,
- AngleWithFlipped(Angle, bool),
+ AngleWithFlipped(Orientation, bool),
}
}
+ use self::computed_value::Orientation;
+
#[inline]
pub fn get_initial_value() -> computed_value::T {
- computed_value::T::AngleWithFlipped(computed::Angle::zero(), false)
+ 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 normalize_angle(angle: &computed::Angle) -> computed::Angle {
- let radians = angle.radians();
- let rounded_quarter_turns = (4.0 * radians / TWO_PI).round();
- let normalized_quarter_turns = (rounded_quarter_turns % 4.0 + 4.0) % 4.0;
- let normalized_radians = normalized_quarter_turns/4.0 * TWO_PI;
- computed::Angle::from_radians(normalized_radians)
+ 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 { Orientation::Angle0 }
+ else if rounded_angle < 0.75 * PI { Orientation::Angle90 }
+ else if rounded_angle < 1.25 * PI { Orientation::Angle180 }
+ else if rounded_angle < 1.75 * PI { Orientation::Angle270 }
+ else { Orientation::Angle0 }
}
impl ToComputedValue for SpecifiedValue {
@@ -133,11 +178,11 @@ ${helpers.single_keyword("image-rendering",
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 normalized_angle = normalize_angle(&angle);
- computed_value::T::AngleWithFlipped(normalized_angle, self.flipped)
+ let orientation = orientation_of_angle(&angle);
+ computed_value::T::AngleWithFlipped(orientation, self.flipped)
} else {
if self.flipped {
- computed_value::T::AngleWithFlipped(computed::Angle::zero(), true)
+ computed_value::T::AngleWithFlipped(Orientation::Angle0, true)
} else {
computed_value::T::FromImage
}
@@ -148,9 +193,9 @@ ${helpers.single_keyword("image-rendering",
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 angle, flipped) => {
+ computed_value::T::AngleWithFlipped(ref orientation, flipped) => {
SpecifiedValue {
- angle: Some(Angle::from_computed_value(angle)),
+ angle: Some(orientation.angle()),
flipped: flipped,
}
}
diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs
index 9b08cd6e2bb..1183cbd3044 100644
--- a/components/style/values/computed/mod.rs
+++ b/components/style/values/computed/mod.rs
@@ -13,7 +13,8 @@ use media_queries::Device;
use properties;
use properties::{ComputedValues, StyleBuilder};
use std::f32;
-use std::f32::consts::PI;
+use std::f64;
+use std::f64::consts::PI;
use std::fmt;
use style_traits::ToCss;
use super::{CSSFloat, CSSInteger, RGBA};
@@ -313,17 +314,27 @@ impl Angle {
/// Return the amount of radians this angle represents.
#[inline]
pub fn radians(&self) -> CSSFloat {
- const RAD_PER_DEG: CSSFloat = PI / 180.0;
- const RAD_PER_GRAD: CSSFloat = PI / 200.0;
- const RAD_PER_TURN: CSSFloat = PI * 2.0;
+ self.radians64().min(f32::MAX as f64).max(f32::MIN as f64) as f32
+ }
+
+ /// Return the amount of radians this angle represents as a 64-bit float.
+ /// Gecko stores angles as singles, but does this computation using doubles.
+ /// See nsCSSValue::GetAngleValueInRadians.
+ /// This is significant enough to mess up rounding to the nearest
+ /// quarter-turn for 225 degrees, for example.
+ #[inline]
+ pub fn radians64(&self) -> f64 {
+ const RAD_PER_DEG: f64 = PI / 180.0;
+ const RAD_PER_GRAD: f64 = PI / 200.0;
+ const RAD_PER_TURN: f64 = PI * 2.0;
let radians = match *self {
- Angle::Degree(val) => val * RAD_PER_DEG,
- Angle::Gradian(val) => val * RAD_PER_GRAD,
- Angle::Turn(val) => val * RAD_PER_TURN,
- Angle::Radian(val) => val,
+ Angle::Degree(val) => val as f64 * RAD_PER_DEG,
+ Angle::Gradian(val) => val as f64 * RAD_PER_GRAD,
+ Angle::Turn(val) => val as f64 * RAD_PER_TURN,
+ Angle::Radian(val) => val as f64,
};
- radians.min(f32::MAX).max(f32::MIN)
+ radians.min(f64::MAX).max(f64::MIN)
}
/// Returns an angle that represents a rotation of zero radians.