tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

angle.rs (2706B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
      4 
      5 //! Computed angles.
      6 
      7 use crate::derives::*;
      8 use crate::values::distance::{ComputeSquaredDistance, SquaredDistance};
      9 use crate::values::CSSFloat;
     10 use crate::Zero;
     11 use std::f64::consts::PI;
     12 use std::fmt::{self, Write};
     13 use std::ops::Neg;
     14 use std::{f32, f64};
     15 use style_traits::{CssWriter, ToCss};
     16 
     17 /// A computed angle in degrees.
     18 #[derive(
     19    Add,
     20    Animate,
     21    Clone,
     22    Copy,
     23    Debug,
     24    Deserialize,
     25    MallocSizeOf,
     26    PartialEq,
     27    PartialOrd,
     28    Serialize,
     29    ToAnimatedZero,
     30    ToResolvedValue,
     31 )]
     32 #[repr(C)]
     33 pub struct Angle(CSSFloat);
     34 
     35 impl ToCss for Angle {
     36    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
     37    where
     38        W: Write,
     39    {
     40        self.degrees().to_css(dest)?;
     41        dest.write_str("deg")
     42    }
     43 }
     44 
     45 const RAD_PER_DEG: f64 = PI / 180.0;
     46 
     47 impl Angle {
     48    /// Creates a computed `Angle` value from a radian amount.
     49    pub fn from_radians(radians: CSSFloat) -> Self {
     50        Angle(radians / RAD_PER_DEG as f32)
     51    }
     52 
     53    /// Creates a computed `Angle` value from a degrees amount.
     54    #[inline]
     55    pub fn from_degrees(degrees: CSSFloat) -> Self {
     56        Angle(degrees)
     57    }
     58 
     59    /// Returns the amount of radians this angle represents.
     60    #[inline]
     61    pub fn radians(&self) -> CSSFloat {
     62        self.radians64().min(f32::MAX as f64).max(f32::MIN as f64) as f32
     63    }
     64 
     65    /// Returns the amount of radians this angle represents as a `f64`.
     66    ///
     67    /// Gecko stores angles as singles, but does this computation using doubles.
     68    ///
     69    /// This is significant enough to mess up rounding to the nearest
     70    /// quarter-turn for 225 degrees, for example.
     71    #[inline]
     72    pub fn radians64(&self) -> f64 {
     73        self.0 as f64 * RAD_PER_DEG
     74    }
     75 
     76    /// Return the value in degrees.
     77    #[inline]
     78    pub fn degrees(&self) -> CSSFloat {
     79        self.0
     80    }
     81 }
     82 
     83 impl Zero for Angle {
     84    #[inline]
     85    fn zero() -> Self {
     86        Angle(0.0)
     87    }
     88 
     89    #[inline]
     90    fn is_zero(&self) -> bool {
     91        self.0 == 0.
     92    }
     93 }
     94 
     95 impl ComputeSquaredDistance for Angle {
     96    #[inline]
     97    fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
     98        // Use the formula for calculating the distance between angles defined in SVG:
     99        // https://www.w3.org/TR/SVG/animate.html#complexDistances
    100        self.radians64()
    101            .compute_squared_distance(&other.radians64())
    102    }
    103 }
    104 
    105 impl Neg for Angle {
    106    type Output = Angle;
    107 
    108    #[inline]
    109    fn neg(self) -> Angle {
    110        Angle(-self.0)
    111    }
    112 }