epaint/
corner_radius_f32.rs

1use crate::CornerRadius;
2
3/// How rounded the corners of things should be, in `f32`.
4///
5/// This is used for calculations, but storage is usually done with the more compact [`CornerRadius`].
6#[derive(Copy, Clone, Debug, PartialEq)]
7#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
8pub struct CornerRadiusF32 {
9    /// Radius of the rounding of the North-West (left top) corner.
10    pub nw: f32,
11
12    /// Radius of the rounding of the North-East (right top) corner.
13    pub ne: f32,
14
15    /// Radius of the rounding of the South-West (left bottom) corner.
16    pub sw: f32,
17
18    /// Radius of the rounding of the South-East (right bottom) corner.
19    pub se: f32,
20}
21
22impl From<CornerRadius> for CornerRadiusF32 {
23    #[inline]
24    fn from(cr: CornerRadius) -> Self {
25        Self {
26            nw: cr.nw as f32,
27            ne: cr.ne as f32,
28            sw: cr.sw as f32,
29            se: cr.se as f32,
30        }
31    }
32}
33
34impl From<CornerRadiusF32> for CornerRadius {
35    #[inline]
36    fn from(cr: CornerRadiusF32) -> Self {
37        Self {
38            nw: cr.nw.round() as u8,
39            ne: cr.ne.round() as u8,
40            sw: cr.sw.round() as u8,
41            se: cr.se.round() as u8,
42        }
43    }
44}
45
46impl Default for CornerRadiusF32 {
47    #[inline]
48    fn default() -> Self {
49        Self::ZERO
50    }
51}
52
53impl From<f32> for CornerRadiusF32 {
54    #[inline]
55    fn from(radius: f32) -> Self {
56        Self {
57            nw: radius,
58            ne: radius,
59            sw: radius,
60            se: radius,
61        }
62    }
63}
64
65impl CornerRadiusF32 {
66    /// No rounding on any corner.
67    pub const ZERO: Self = Self {
68        nw: 0.0,
69        ne: 0.0,
70        sw: 0.0,
71        se: 0.0,
72    };
73
74    /// Same rounding on all four corners.
75    #[inline]
76    pub const fn same(radius: f32) -> Self {
77        Self {
78            nw: radius,
79            ne: radius,
80            sw: radius,
81            se: radius,
82        }
83    }
84
85    /// Do all corners have the same rounding?
86    #[inline]
87    pub fn is_same(&self) -> bool {
88        self.nw == self.ne && self.nw == self.sw && self.nw == self.se
89    }
90
91    /// Make sure each corner has a rounding of at least this.
92    #[inline]
93    pub fn at_least(&self, min: f32) -> Self {
94        Self {
95            nw: self.nw.max(min),
96            ne: self.ne.max(min),
97            sw: self.sw.max(min),
98            se: self.se.max(min),
99        }
100    }
101
102    /// Make sure each corner has a rounding of at most this.
103    #[inline]
104    pub fn at_most(&self, max: f32) -> Self {
105        Self {
106            nw: self.nw.min(max),
107            ne: self.ne.min(max),
108            sw: self.sw.min(max),
109            se: self.se.min(max),
110        }
111    }
112}
113
114impl std::ops::Add for CornerRadiusF32 {
115    type Output = Self;
116    #[inline]
117    fn add(self, rhs: Self) -> Self {
118        Self {
119            nw: self.nw + rhs.nw,
120            ne: self.ne + rhs.ne,
121            sw: self.sw + rhs.sw,
122            se: self.se + rhs.se,
123        }
124    }
125}
126
127impl std::ops::AddAssign for CornerRadiusF32 {
128    #[inline]
129    fn add_assign(&mut self, rhs: Self) {
130        *self = Self {
131            nw: self.nw + rhs.nw,
132            ne: self.ne + rhs.ne,
133            sw: self.sw + rhs.sw,
134            se: self.se + rhs.se,
135        };
136    }
137}
138
139impl std::ops::AddAssign<f32> for CornerRadiusF32 {
140    #[inline]
141    fn add_assign(&mut self, rhs: f32) {
142        *self = Self {
143            nw: self.nw + rhs,
144            ne: self.ne + rhs,
145            sw: self.sw + rhs,
146            se: self.se + rhs,
147        };
148    }
149}
150
151impl std::ops::Sub for CornerRadiusF32 {
152    type Output = Self;
153    #[inline]
154    fn sub(self, rhs: Self) -> Self {
155        Self {
156            nw: self.nw - rhs.nw,
157            ne: self.ne - rhs.ne,
158            sw: self.sw - rhs.sw,
159            se: self.se - rhs.se,
160        }
161    }
162}
163
164impl std::ops::SubAssign for CornerRadiusF32 {
165    #[inline]
166    fn sub_assign(&mut self, rhs: Self) {
167        *self = Self {
168            nw: self.nw - rhs.nw,
169            ne: self.ne - rhs.ne,
170            sw: self.sw - rhs.sw,
171            se: self.se - rhs.se,
172        };
173    }
174}
175
176impl std::ops::SubAssign<f32> for CornerRadiusF32 {
177    #[inline]
178    fn sub_assign(&mut self, rhs: f32) {
179        *self = Self {
180            nw: self.nw - rhs,
181            ne: self.ne - rhs,
182            sw: self.sw - rhs,
183            se: self.se - rhs,
184        };
185    }
186}
187
188impl std::ops::Div<f32> for CornerRadiusF32 {
189    type Output = Self;
190    #[inline]
191    fn div(self, rhs: f32) -> Self {
192        Self {
193            nw: self.nw / rhs,
194            ne: self.ne / rhs,
195            sw: self.sw / rhs,
196            se: self.se / rhs,
197        }
198    }
199}
200
201impl std::ops::DivAssign<f32> for CornerRadiusF32 {
202    #[inline]
203    fn div_assign(&mut self, rhs: f32) {
204        *self = Self {
205            nw: self.nw / rhs,
206            ne: self.ne / rhs,
207            sw: self.sw / rhs,
208            se: self.se / rhs,
209        };
210    }
211}
212
213impl std::ops::Mul<f32> for CornerRadiusF32 {
214    type Output = Self;
215    #[inline]
216    fn mul(self, rhs: f32) -> Self {
217        Self {
218            nw: self.nw * rhs,
219            ne: self.ne * rhs,
220            sw: self.sw * rhs,
221            se: self.se * rhs,
222        }
223    }
224}
225
226impl std::ops::MulAssign<f32> for CornerRadiusF32 {
227    #[inline]
228    fn mul_assign(&mut self, rhs: f32) {
229        *self = Self {
230            nw: self.nw * rhs,
231            ne: self.ne * rhs,
232            sw: self.sw * rhs,
233            se: self.se * rhs,
234        };
235    }
236}