1use std::fmt;
7
8#[repr(C)]
23#[derive(Debug, Clone, Copy, PartialEq)]
24pub struct CGRect {
25 pub x: f64,
26 pub y: f64,
27 pub width: f64,
28 pub height: f64,
29}
30
31impl std::hash::Hash for CGRect {
32 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
33 self.x.to_bits().hash(state);
34 self.y.to_bits().hash(state);
35 self.width.to_bits().hash(state);
36 self.height.to_bits().hash(state);
37 }
38}
39
40impl Eq for CGRect {}
41
42impl CGRect {
43 pub const fn new(x: f64, y: f64, width: f64, height: f64) -> Self {
54 Self {
55 x,
56 y,
57 width,
58 height,
59 }
60 }
61
62 pub const fn zero() -> Self {
73 Self::new(0.0, 0.0, 0.0, 0.0)
74 }
75
76 pub const fn with_origin_and_size(origin: CGPoint, size: CGSize) -> Self {
78 Self {
79 x: origin.x,
80 y: origin.y,
81 width: size.width,
82 height: size.height,
83 }
84 }
85
86 pub const fn origin(&self) -> CGPoint {
88 CGPoint::new(self.x, self.y)
89 }
90
91 pub const fn size(&self) -> CGSize {
93 CGSize::new(self.width, self.height)
94 }
95
96 pub const fn center(&self) -> CGPoint {
98 CGPoint::new(self.x + self.width / 2.0, self.y + self.height / 2.0)
99 }
100
101 pub const fn min_x(&self) -> f64 {
103 self.x
104 }
105
106 pub const fn min_y(&self) -> f64 {
108 self.y
109 }
110
111 pub const fn max_x(&self) -> f64 {
113 self.x + self.width
114 }
115
116 pub const fn max_y(&self) -> f64 {
118 self.y + self.height
119 }
120
121 pub const fn mid_x(&self) -> f64 {
123 self.x + self.width / 2.0
124 }
125
126 pub const fn mid_y(&self) -> f64 {
128 self.y + self.height / 2.0
129 }
130
131 pub fn is_empty(&self) -> bool {
132 self.width <= 0.0 || self.height <= 0.0
133 }
134
135 pub const fn is_null(&self) -> bool {
137 self.x == 0.0 && self.y == 0.0 && self.width == 0.0 && self.height == 0.0
138 }
139}
140
141impl Default for CGRect {
142 fn default() -> Self {
143 Self::zero()
144 }
145}
146
147impl fmt::Display for CGRect {
148 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
149 write!(
150 f,
151 "({}, {}, {}, {})",
152 self.x, self.y, self.width, self.height
153 )
154 }
155}
156
157#[repr(C)]
171#[derive(Debug, Clone, Copy, PartialEq)]
172pub struct CGSize {
173 pub width: f64,
174 pub height: f64,
175}
176
177impl std::hash::Hash for CGSize {
178 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
179 self.width.to_bits().hash(state);
180 self.height.to_bits().hash(state);
181 }
182}
183
184impl Eq for CGSize {}
185
186impl CGSize {
187 pub const fn new(width: f64, height: f64) -> Self {
198 Self { width, height }
199 }
200
201 pub const fn zero() -> Self {
212 Self::new(0.0, 0.0)
213 }
214
215 pub const fn area(&self) -> f64 {
217 self.width * self.height
218 }
219
220 pub fn aspect_ratio(&self) -> f64 {
222 if self.height == 0.0 {
223 0.0
224 } else {
225 self.width / self.height
226 }
227 }
228
229 #[allow(clippy::float_cmp)]
232 pub const fn is_square(&self) -> bool {
233 self.width == self.height
234 }
235
236 pub fn is_empty(&self) -> bool {
237 self.width <= 0.0 || self.height <= 0.0
238 }
239
240 pub const fn is_null(&self) -> bool {
242 self.width == 0.0 && self.height == 0.0
243 }
244}
245
246impl Default for CGSize {
247 fn default() -> Self {
248 Self::zero()
249 }
250}
251
252impl fmt::Display for CGSize {
253 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
254 write!(f, "{}x{}", self.width, self.height)
255 }
256}
257
258#[repr(C)]
272#[derive(Debug, Clone, Copy, PartialEq)]
273pub struct CGPoint {
274 pub x: f64,
275 pub y: f64,
276}
277
278impl std::hash::Hash for CGPoint {
279 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
280 self.x.to_bits().hash(state);
281 self.y.to_bits().hash(state);
282 }
283}
284
285impl Eq for CGPoint {}
286
287impl CGPoint {
288 pub const fn new(x: f64, y: f64) -> Self {
299 Self { x, y }
300 }
301
302 pub const fn zero() -> Self {
313 Self::new(0.0, 0.0)
314 }
315
316 pub const fn is_zero(&self) -> bool {
318 self.x == 0.0 && self.y == 0.0
319 }
320
321 pub fn distance_to(&self, other: &Self) -> f64 {
323 let dx = self.x - other.x;
324 let dy = self.y - other.y;
325 dx.hypot(dy)
326 }
327
328 pub const fn distance_squared_to(&self, other: &Self) -> f64 {
330 let dx = self.x - other.x;
331 let dy = self.y - other.y;
332 dx * dx + dy * dy
333 }
334}
335
336impl Default for CGPoint {
337 fn default() -> Self {
338 Self::zero()
339 }
340}
341
342impl fmt::Display for CGPoint {
343 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
344 write!(f, "({}, {})", self.x, self.y)
345 }
346}
347
348pub type CGDisplayID = u32;