1use crate::{Radians, Vector};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
5pub struct Size<T = f32> {
6 pub width: T,
8 pub height: T,
10}
11
12impl<T> Size<T> {
13 pub const fn new(width: T, height: T) -> Self {
15 Size { width, height }
16 }
17}
18
19impl Size {
20 pub const ZERO: Size = Size::new(0., 0.);
22
23 pub const UNIT: Size = Size::new(1., 1.);
25
26 pub const INFINITE: Size = Size::new(f32::INFINITY, f32::INFINITY);
28
29 pub fn min(self, other: Self) -> Self {
31 Size {
32 width: self.width.min(other.width),
33 height: self.height.min(other.height),
34 }
35 }
36
37 pub fn max(self, other: Self) -> Self {
39 Size {
40 width: self.width.max(other.width),
41 height: self.height.max(other.height),
42 }
43 }
44
45 pub fn expand(self, other: impl Into<Size>) -> Self {
47 let other = other.into();
48
49 Size {
50 width: self.width + other.width,
51 height: self.height + other.height,
52 }
53 }
54
55 pub fn rotate(self, rotation: Radians) -> Size {
58 let radians = f32::from(rotation);
59
60 Size {
61 width: (self.width * radians.cos()).abs() + (self.height * radians.sin()).abs(),
62 height: (self.width * radians.sin()).abs() + (self.height * radians.cos()).abs(),
63 }
64 }
65
66 pub const fn ratio(self, aspect_ratio: f32) -> Size {
69 Size {
70 width: (self.height * aspect_ratio).min(self.width),
71 height: (self.width / aspect_ratio).min(self.height),
72 }
73 }
74}
75
76impl<T> From<[T; 2]> for Size<T> {
77 fn from([width, height]: [T; 2]) -> Self {
78 Size { width, height }
79 }
80}
81
82impl<T> From<(T, T)> for Size<T> {
83 fn from((width, height): (T, T)) -> Self {
84 Self { width, height }
85 }
86}
87
88impl From<(u32, u32)> for Size {
89 fn from((width, height): (u32, u32)) -> Self {
90 Size::new(width as f32, height as f32)
91 }
92}
93
94impl<T> From<Vector<T>> for Size<T> {
95 fn from(vector: Vector<T>) -> Self {
96 Size {
97 width: vector.x,
98 height: vector.y,
99 }
100 }
101}
102
103impl<T> From<Size<T>> for [T; 2] {
104 fn from(size: Size<T>) -> Self {
105 [size.width, size.height]
106 }
107}
108
109impl<T> From<Size<T>> for Vector<T> {
110 fn from(size: Size<T>) -> Self {
111 Vector::new(size.width, size.height)
112 }
113}
114
115impl<T> std::ops::Add for Size<T>
116where
117 T: std::ops::Add<Output = T>,
118{
119 type Output = Size<T>;
120
121 fn add(self, rhs: Self) -> Self::Output {
122 Size {
123 width: self.width + rhs.width,
124 height: self.height + rhs.height,
125 }
126 }
127}
128
129impl<T> std::ops::Sub for Size<T>
130where
131 T: std::ops::Sub<Output = T>,
132{
133 type Output = Size<T>;
134
135 fn sub(self, rhs: Self) -> Self::Output {
136 Size {
137 width: self.width - rhs.width,
138 height: self.height - rhs.height,
139 }
140 }
141}
142
143impl<T> std::ops::Mul<T> for Size<T>
144where
145 T: std::ops::Mul<Output = T> + Copy,
146{
147 type Output = Size<T>;
148
149 fn mul(self, rhs: T) -> Self::Output {
150 Size {
151 width: self.width * rhs,
152 height: self.height * rhs,
153 }
154 }
155}
156
157impl<T> std::ops::Div<T> for Size<T>
158where
159 T: std::ops::Div<Output = T> + Copy,
160{
161 type Output = Size<T>;
162
163 fn div(self, rhs: T) -> Self::Output {
164 Size {
165 width: self.width / rhs,
166 height: self.height / rhs,
167 }
168 }
169}
170
171impl<T> std::ops::Mul<Vector<T>> for Size<T>
172where
173 T: std::ops::Mul<Output = T> + Copy,
174{
175 type Output = Size<T>;
176
177 fn mul(self, scale: Vector<T>) -> Self::Output {
178 Size {
179 width: self.width * scale.x,
180 height: self.height * scale.y,
181 }
182 }
183}