firefly_rust/graphics/
size.rs

1use super::Point;
2use core::ops::*;
3#[cfg(feature = "nalgebra")]
4use nalgebra::{base::Scalar, Vector2};
5
6/// The screen width in pixels.
7pub const WIDTH: i32 = 240;
8
9/// The screen height in pixels.
10pub const HEIGHT: i32 = 160;
11
12/// Size of a bounding box for a shape.
13///
14/// The width and height must be positive.
15#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
16pub struct Size {
17    /// Horizontal size in pixels.
18    pub width: i32,
19    /// Vertical size in pixels.
20    pub height: i32,
21}
22
23impl Size {
24    /// The screen size.
25    pub const MAX: Size = Size {
26        width: WIDTH,
27        height: HEIGHT,
28    };
29
30    /// Create a new size casting the argument types.
31    #[must_use]
32    pub fn new<I: Into<i32>>(width: I, height: I) -> Self {
33        Self {
34            width: width.into(),
35            height: height.into(),
36        }
37    }
38
39    /// Set both width and height to their absolute (non-negative) value.
40    #[must_use]
41    pub const fn abs(self) -> Self {
42        Self {
43            width: self.width.abs(),
44            height: self.height.abs(),
45        }
46    }
47
48    /// Set both width and height to their minimum in the two given points.
49    #[must_use]
50    pub fn component_min(self, other: Self) -> Self {
51        Self {
52            width: self.width.min(other.width),
53            height: self.height.min(other.height),
54        }
55    }
56
57    /// Set both width and height to their maximum in the two given points.
58    #[must_use]
59    pub fn component_max(self, other: Self) -> Self {
60        Self {
61            width: self.width.max(other.width),
62            height: self.height.max(other.height),
63        }
64    }
65}
66
67impl Add for Size {
68    type Output = Size;
69
70    fn add(self, other: Size) -> Self {
71        Size {
72            width: self.width + other.width,
73            height: self.height + other.height,
74        }
75    }
76}
77
78impl AddAssign for Size {
79    fn add_assign(&mut self, other: Size) {
80        self.width += other.width;
81        self.height += other.height;
82    }
83}
84
85impl Sub for Size {
86    type Output = Size;
87
88    fn sub(self, other: Size) -> Self {
89        Size {
90            width: self.width - other.width,
91            height: self.height - other.height,
92        }
93    }
94}
95
96impl Sub<Point> for Size {
97    type Output = Size;
98
99    fn sub(self, other: Point) -> Self {
100        Size {
101            width: self.width - other.x,
102            height: self.height - other.y,
103        }
104    }
105}
106
107impl SubAssign for Size {
108    fn sub_assign(&mut self, other: Size) {
109        self.width -= other.width;
110        self.height -= other.height;
111    }
112}
113
114impl Mul<i32> for Size {
115    type Output = Size;
116
117    fn mul(self, rhs: i32) -> Self {
118        Size {
119            width: self.width * rhs,
120            height: self.height * rhs,
121        }
122    }
123}
124
125impl MulAssign<i32> for Size {
126    fn mul_assign(&mut self, rhs: i32) {
127        self.width *= rhs;
128        self.height *= rhs;
129    }
130}
131
132impl Div<i32> for Size {
133    type Output = Size;
134
135    fn div(self, rhs: i32) -> Self {
136        Size {
137            width: self.width / rhs,
138            height: self.height / rhs,
139        }
140    }
141}
142
143impl DivAssign<i32> for Size {
144    fn div_assign(&mut self, rhs: i32) {
145        self.width /= rhs;
146        self.height /= rhs;
147    }
148}
149
150impl Index<usize> for Size {
151    type Output = i32;
152
153    fn index(&self, idx: usize) -> &i32 {
154        match idx {
155            0 => &self.width,
156            1 => &self.height,
157            _ => panic!("index out of bounds: the len is 2 but the index is {idx}"),
158        }
159    }
160}
161
162impl From<Point> for Size {
163    fn from(value: Point) -> Self {
164        Self {
165            width: value.x,
166            height: value.y,
167        }
168    }
169}
170impl From<(i32, i32)> for Size {
171    fn from(other: (i32, i32)) -> Self {
172        Size {
173            width: other.0,
174            height: other.1,
175        }
176    }
177}
178
179impl From<[i32; 2]> for Size {
180    fn from(other: [i32; 2]) -> Self {
181        Size {
182            width: other[0],
183            height: other[1],
184        }
185    }
186}
187
188impl From<&[i32; 2]> for Size {
189    fn from(other: &[i32; 2]) -> Self {
190        Size {
191            width: other[0],
192            height: other[1],
193        }
194    }
195}
196
197impl From<Size> for (i32, i32) {
198    fn from(other: Size) -> (i32, i32) {
199        (other.width, other.height)
200    }
201}
202
203impl From<Size> for [i32; 2] {
204    fn from(other: Size) -> [i32; 2] {
205        [other.width, other.height]
206    }
207}
208
209impl From<&Size> for (i32, i32) {
210    fn from(other: &Size) -> (i32, i32) {
211        (other.width, other.height)
212    }
213}
214
215#[cfg(feature = "nalgebra")]
216impl<N> From<Vector2<N>> for Size
217where
218    N: Into<i32> + Scalar + Copy,
219{
220    fn from(other: Vector2<N>) -> Self {
221        Self {
222            width: other[0].into(),
223            height: other[1].into(),
224        }
225    }
226}
227
228#[cfg(feature = "nalgebra")]
229impl<N> From<&Vector2<N>> for Size
230where
231    N: Into<i32> + Scalar + Copy,
232{
233    fn from(other: &Vector2<N>) -> Self {
234        Self {
235            width: other[0].into(),
236            height: other[1].into(),
237        }
238    }
239}