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    ToTyped,
35)]
36#[repr(C)]
37pub struct Percentage(pub CSSFloat);
38
39impl Percentage {
40    /// 100%
41    #[inline]
42    pub fn hundred() -> Self {
43        Percentage(1.)
44    }
45
46    /// Returns the absolute value for this percentage.
47    #[inline]
48    pub fn abs(&self) -> Self {
49        Percentage(self.0.abs())
50    }
51
52    /// Clamps this percentage to a non-negative percentage.
53    #[inline]
54    pub fn clamp_to_non_negative(self) -> Self {
55        Percentage(self.0.max(0.))
56    }
57}
58
59impl Zero for Percentage {
60    fn zero() -> Self {
61        Percentage(0.)
62    }
63
64    fn is_zero(&self) -> bool {
65        self.0 == 0.
66    }
67}
68
69impl ToPercentage for Percentage {
70    fn to_percentage(&self) -> CSSFloat {
71        self.0
72    }
73}
74
75impl std::ops::AddAssign for Percentage {
76    fn add_assign(&mut self, other: Self) {
77        self.0 += other.0
78    }
79}
80
81impl std::ops::Add for Percentage {
82    type Output = Self;
83
84    fn add(self, other: Self) -> Self {
85        Percentage(self.0 + other.0)
86    }
87}
88
89impl std::ops::Sub for Percentage {
90    type Output = Self;
91
92    fn sub(self, other: Self) -> Self {
93        Percentage(self.0 - other.0)
94    }
95}
96
97impl std::ops::Rem for Percentage {
98    type Output = Self;
99
100    fn rem(self, other: Self) -> Self {
101        Percentage(self.0 % other.0)
102    }
103}
104
105impl ToCss for Percentage {
106    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
107    where
108        W: fmt::Write,
109    {
110        serialize_normalized_percentage(self.0, dest)
111    }
112}
113
114/// A wrapper over a `Percentage`, whose value should be clamped to 0.
115pub type NonNegativePercentage = NonNegative<Percentage>;
116
117impl NonNegativePercentage {
118    /// 100%
119    #[inline]
120    pub fn hundred() -> Self {
121        NonNegative(Percentage::hundred())
122    }
123}
124
125impl ToAnimatedValue for NonNegativePercentage {
126    type AnimatedValue = Percentage;
127
128    #[inline]
129    fn to_animated_value(self, _: &crate::values::animated::Context) -> Self::AnimatedValue {
130        self.0
131    }
132
133    #[inline]
134    fn from_animated_value(animated: Self::AnimatedValue) -> Self {
135        NonNegative(animated.clamp_to_non_negative())
136    }
137}