style/values/computed/
angle.rs1use crate::values::distance::{ComputeSquaredDistance, SquaredDistance};
8use crate::values::CSSFloat;
9use crate::Zero;
10use std::f64::consts::PI;
11use std::fmt::{self, Write};
12use std::{f32, f64};
13use std::ops::Neg;
14use style_traits::{CssWriter, ToCss};
15
16#[derive(
18 Add,
19 Animate,
20 Clone,
21 Copy,
22 Debug,
23 Deserialize,
24 MallocSizeOf,
25 PartialEq,
26 PartialOrd,
27 Serialize,
28 ToAnimatedZero,
29 ToResolvedValue,
30)]
31#[repr(C)]
32pub struct Angle(CSSFloat);
33
34impl ToCss for Angle {
35 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
36 where
37 W: Write,
38 {
39 self.degrees().to_css(dest)?;
40 dest.write_str("deg")
41 }
42}
43
44const RAD_PER_DEG: f64 = PI / 180.0;
45
46impl Angle {
47 pub fn from_radians(radians: CSSFloat) -> Self {
49 Angle(radians / RAD_PER_DEG as f32)
50 }
51
52 #[inline]
54 pub fn from_degrees(degrees: CSSFloat) -> Self {
55 Angle(degrees)
56 }
57
58 #[inline]
60 pub fn radians(&self) -> CSSFloat {
61 self.radians64().min(f32::MAX as f64).max(f32::MIN as f64) as f32
62 }
63
64 #[inline]
71 pub fn radians64(&self) -> f64 {
72 self.0 as f64 * RAD_PER_DEG
73 }
74
75 #[inline]
77 pub fn degrees(&self) -> CSSFloat {
78 self.0
79 }
80}
81
82impl Zero for Angle {
83 #[inline]
84 fn zero() -> Self {
85 Angle(0.0)
86 }
87
88 #[inline]
89 fn is_zero(&self) -> bool {
90 self.0 == 0.
91 }
92}
93
94impl ComputeSquaredDistance for Angle {
95 #[inline]
96 fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
97 self.radians64()
100 .compute_squared_distance(&other.radians64())
101 }
102}
103
104impl Neg for Angle {
105 type Output = Angle;
106
107 #[inline]
108 fn neg(self) -> Angle {
109 Angle(-self.0)
110 }
111}