style/values/computed/
percentage.rs

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 percentages.
6
7use crate::values::animated::ToAnimatedValue;
8use crate::values::generics::NonNegative;
9use crate::values::specified::percentage::ToPercentage;
10use crate::values::{serialize_normalized_percentage, CSSFloat};
11use crate::Zero;
12use std::fmt;
13use style_traits::{CssWriter, ToCss};
14
15/// A computed percentage.
16#[derive(
17    Animate,
18    Clone,
19    ComputeSquaredDistance,
20    Copy,
21    Debug,
22    Default,
23    Deserialize,
24    MallocSizeOf,
25    PartialEq,
26    PartialOrd,
27    Serialize,
28    SpecifiedValueInfo,
29    ToAnimatedValue,
30    ToAnimatedZero,
31    ToComputedValue,
32    ToResolvedValue,
33    ToShmem,
34)]
35#[repr(C)]
36pub struct Percentage(pub CSSFloat);
37
38impl Percentage {
39    /// 100%
40    #[inline]
41    pub fn hundred() -> Self {
42        Percentage(1.)
43    }
44
45    /// Returns the absolute value for this percentage.
46    #[inline]
47    pub fn abs(&self) -> Self {
48        Percentage(self.0.abs())
49    }
50
51    /// Clamps this percentage to a non-negative percentage.
52    #[inline]
53    pub fn clamp_to_non_negative(self) -> Self {
54        Percentage(self.0.max(0.))
55    }
56}
57
58impl Zero for Percentage {
59    fn zero() -> Self {
60        Percentage(0.)
61    }
62
63    fn is_zero(&self) -> bool {
64        self.0 == 0.
65    }
66}
67
68impl ToPercentage for Percentage {
69    fn to_percentage(&self) -> CSSFloat {
70        self.0
71    }
72}
73
74impl std::ops::AddAssign for Percentage {
75    fn add_assign(&mut self, other: Self) {
76        self.0 += other.0
77    }
78}
79
80impl std::ops::Add for Percentage {
81    type Output = Self;
82
83    fn add(self, other: Self) -> Self {
84        Percentage(self.0 + other.0)
85    }
86}
87
88impl std::ops::Sub for Percentage {
89    type Output = Self;
90
91    fn sub(self, other: Self) -> Self {
92        Percentage(self.0 - other.0)
93    }
94}
95
96impl std::ops::Rem for Percentage {
97    type Output = Self;
98
99    fn rem(self, other: Self) -> Self {
100        Percentage(self.0 % other.0)
101    }
102}
103
104impl ToCss for Percentage {
105    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
106    where
107        W: fmt::Write,
108    {
109        serialize_normalized_percentage(self.0, dest)
110    }
111}
112
113/// A wrapper over a `Percentage`, whose value should be clamped to 0.
114pub type NonNegativePercentage = NonNegative<Percentage>;
115
116impl NonNegativePercentage {
117    /// 100%
118    #[inline]
119    pub fn hundred() -> Self {
120        NonNegative(Percentage::hundred())
121    }
122}
123
124impl ToAnimatedValue for NonNegativePercentage {
125    type AnimatedValue = Percentage;
126
127    #[inline]
128    fn to_animated_value(self, _: &crate::values::animated::Context) -> Self::AnimatedValue {
129        self.0
130    }
131
132    #[inline]
133    fn from_animated_value(animated: Self::AnimatedValue) -> Self {
134        NonNegative(animated.clamp_to_non_negative())
135    }
136}