mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Auto merge of #16674 - canaltinova:angle-unit, r=emilio
Preserve units in computed Angle <!-- Please describe your changes on the following line: --> It was converting all angles to radians before. But other browsers preserves the angle units. Fixed that behavior. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #16594 and [Bug 1360659](https://bugzilla.mozilla.org/show_bug.cgi?id=1360659) <!-- 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. --> <!-- 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/16674) <!-- Reviewable:end -->
This commit is contained in:
commit
0abd5bbabd
8 changed files with 120 additions and 82 deletions
|
@ -11,6 +11,8 @@ use media_queries::Device;
|
|||
#[cfg(feature = "gecko")]
|
||||
use properties;
|
||||
use properties::{ComputedValues, StyleBuilder};
|
||||
use std::f32;
|
||||
use std::f32::consts::PI;
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use super::{CSSFloat, CSSInteger, RGBA};
|
||||
|
@ -139,27 +141,42 @@ impl<T> ToComputedValue for T
|
|||
/// A computed `<angle>` value.
|
||||
#[derive(Clone, PartialEq, PartialOrd, Copy, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
|
||||
pub struct Angle {
|
||||
radians: CSSFloat,
|
||||
pub enum Angle {
|
||||
/// An angle with degree unit
|
||||
Degree(CSSFloat),
|
||||
/// An angle with gradian unit
|
||||
Gradian(CSSFloat),
|
||||
/// An angle with radian unit
|
||||
Radian(CSSFloat),
|
||||
/// An angle with turn unit
|
||||
Turn(CSSFloat),
|
||||
}
|
||||
|
||||
impl Angle {
|
||||
/// Construct a computed `Angle` value from a radian amount.
|
||||
pub fn from_radians(radians: CSSFloat) -> Self {
|
||||
Angle {
|
||||
radians: radians,
|
||||
}
|
||||
Angle::Radian(radians)
|
||||
}
|
||||
|
||||
/// Return the amount of radians this angle represents.
|
||||
#[inline]
|
||||
pub fn radians(&self) -> CSSFloat {
|
||||
self.radians
|
||||
const RAD_PER_DEG: CSSFloat = PI / 180.0;
|
||||
const RAD_PER_GRAD: CSSFloat = PI / 200.0;
|
||||
const RAD_PER_TURN: CSSFloat = 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,
|
||||
};
|
||||
radians.min(f32::MAX).max(f32::MIN)
|
||||
}
|
||||
|
||||
/// Returns an angle that represents a rotation of zero radians.
|
||||
pub fn zero() -> Self {
|
||||
Self::from_radians(0.0)
|
||||
Angle::Radian(0.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,7 +184,12 @@ impl ToCss for Angle {
|
|||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write,
|
||||
{
|
||||
write!(dest, "{}rad", self.radians())
|
||||
match *self {
|
||||
Angle::Degree(val) => write!(dest, "{}deg", val),
|
||||
Angle::Gradian(val) => write!(dest, "{}grad", val),
|
||||
Angle::Radian(val) => write!(dest, "{}rad", val),
|
||||
Angle::Turn(val) => write!(dest, "{}turn", val),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ use self::grid::{TrackBreadth as GenericTrackBreadth, TrackSize as GenericTrackS
|
|||
use self::url::SpecifiedUrl;
|
||||
use std::ascii::AsciiExt;
|
||||
use std::f32;
|
||||
use std::f32::consts::PI;
|
||||
use std::fmt;
|
||||
use std::ops::Mul;
|
||||
use style_traits::ToCss;
|
||||
|
@ -300,45 +299,21 @@ impl Parse for BorderRadiusSize {
|
|||
#[derive(Clone, PartialEq, Copy, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
|
||||
/// An angle consisting of a value and a unit.
|
||||
///
|
||||
/// Computed Angle is essentially same as specified angle except calc
|
||||
/// value serialization. Therefore we are using computed Angle enum
|
||||
/// to hold the value and unit type.
|
||||
pub struct Angle {
|
||||
value: CSSFloat,
|
||||
unit: AngleUnit,
|
||||
value: computed::Angle,
|
||||
was_calc: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
|
||||
/// A unit used together with an angle.
|
||||
pub enum AngleUnit {
|
||||
/// Degrees, short name "deg".
|
||||
Degree,
|
||||
/// Gradians, short name "grad".
|
||||
Gradian,
|
||||
/// Radians, short name "rad".
|
||||
Radian,
|
||||
/// Turns, short name "turn".
|
||||
Turn,
|
||||
}
|
||||
|
||||
impl ToCss for AngleUnit {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
use self::AngleUnit::*;
|
||||
dest.write_str(match *self {
|
||||
Degree => "deg",
|
||||
Gradian => "grad",
|
||||
Radian => "rad",
|
||||
Turn => "turn",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for Angle {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
if self.was_calc {
|
||||
dest.write_str("calc(")?;
|
||||
}
|
||||
self.value.to_css(dest)?;
|
||||
self.unit.to_css(dest)?;
|
||||
if self.was_calc {
|
||||
dest.write_str(")")?;
|
||||
}
|
||||
|
@ -350,48 +325,39 @@ impl ToComputedValue for Angle {
|
|||
type ComputedValue = computed::Angle;
|
||||
|
||||
fn to_computed_value(&self, _context: &Context) -> Self::ComputedValue {
|
||||
computed::Angle::from_radians(self.radians())
|
||||
self.value
|
||||
}
|
||||
|
||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||
Angle::from_radians(computed.radians())
|
||||
Angle {
|
||||
value: *computed,
|
||||
was_calc: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Angle {
|
||||
/// Returns an angle with the given value in degrees.
|
||||
pub fn from_degrees(value: CSSFloat) -> Self {
|
||||
Angle { value: value, unit: AngleUnit::Degree, was_calc: false }
|
||||
Angle { value: computed::Angle::Degree(value), was_calc: false }
|
||||
}
|
||||
/// Returns an angle with the given value in gradians.
|
||||
pub fn from_gradians(value: CSSFloat) -> Self {
|
||||
Angle { value: value, unit: AngleUnit::Gradian, was_calc: false }
|
||||
Angle { value: computed::Angle::Gradian(value), was_calc: false }
|
||||
}
|
||||
/// Returns an angle with the given value in turns.
|
||||
pub fn from_turns(value: CSSFloat) -> Self {
|
||||
Angle { value: value, unit: AngleUnit::Turn, was_calc: false }
|
||||
Angle { value: computed::Angle::Turn(value), was_calc: false }
|
||||
}
|
||||
/// Returns an angle with the given value in radians.
|
||||
pub fn from_radians(value: CSSFloat) -> Self {
|
||||
Angle { value: value, unit: AngleUnit::Radian, was_calc: false }
|
||||
Angle { value: computed::Angle::Radian(value), was_calc: false }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(missing_docs)]
|
||||
pub fn radians(self) -> f32 {
|
||||
use self::AngleUnit::*;
|
||||
|
||||
const RAD_PER_DEG: CSSFloat = PI / 180.0;
|
||||
const RAD_PER_GRAD: CSSFloat = PI / 200.0;
|
||||
const RAD_PER_TURN: CSSFloat = PI * 2.0;
|
||||
|
||||
let radians = match self.unit {
|
||||
Degree => self.value * RAD_PER_DEG,
|
||||
Gradian => self.value * RAD_PER_GRAD,
|
||||
Turn => self.value * RAD_PER_TURN,
|
||||
Radian => self.value,
|
||||
};
|
||||
radians.min(f32::MAX).max(f32::MIN)
|
||||
self.value.radians()
|
||||
}
|
||||
|
||||
/// Returns an angle value that represents zero.
|
||||
|
@ -402,8 +368,7 @@ impl Angle {
|
|||
/// Returns an `Angle` parsed from a `calc()` expression.
|
||||
pub fn from_calc(radians: CSSFloat) -> Self {
|
||||
Angle {
|
||||
value: radians,
|
||||
unit: AngleUnit::Radian,
|
||||
value: computed::Angle::Radian(radians),
|
||||
was_calc: true,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue