screencapturekit/cg/
rect.rs

1//! `CGRect` type for 2D rectangles
2
3use std::fmt;
4
5use super::{CGPoint, CGSize};
6
7/// `CGRect` representation
8///
9/// Represents a rectangle with origin (x, y) and dimensions (width, height).
10///
11/// # Examples
12///
13/// ```
14/// use screencapturekit::cg::CGRect;
15///
16/// let rect = CGRect::new(10.0, 20.0, 100.0, 200.0);
17/// assert_eq!(rect.x, 10.0);
18/// assert_eq!(rect.width, 100.0);
19/// assert_eq!(rect.max_x(), 110.0);
20/// ```
21#[repr(C)]
22#[derive(Debug, Clone, Copy, PartialEq)]
23pub struct CGRect {
24    pub x: f64,
25    pub y: f64,
26    pub width: f64,
27    pub height: f64,
28}
29
30impl std::hash::Hash for CGRect {
31    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
32        self.x.to_bits().hash(state);
33        self.y.to_bits().hash(state);
34        self.width.to_bits().hash(state);
35        self.height.to_bits().hash(state);
36    }
37}
38
39impl Eq for CGRect {}
40
41impl CGRect {
42    /// Create a new rectangle
43    ///
44    /// # Examples
45    ///
46    /// ```
47    /// use screencapturekit::cg::CGRect;
48    ///
49    /// let rect = CGRect::new(0.0, 0.0, 1920.0, 1080.0);
50    /// assert_eq!(rect.width, 1920.0);
51    /// ```
52    pub const fn new(x: f64, y: f64, width: f64, height: f64) -> Self {
53        Self {
54            x,
55            y,
56            width,
57            height,
58        }
59    }
60
61    /// Create a zero-sized rectangle at origin
62    ///
63    /// # Examples
64    ///
65    /// ```
66    /// use screencapturekit::cg::CGRect;
67    ///
68    /// let rect = CGRect::zero();
69    /// assert!(rect.is_null());
70    /// ```
71    pub const fn zero() -> Self {
72        Self::new(0.0, 0.0, 0.0, 0.0)
73    }
74
75    /// Create a rect with origin and size
76    pub const fn with_origin_and_size(origin: CGPoint, size: CGSize) -> Self {
77        Self {
78            x: origin.x,
79            y: origin.y,
80            width: size.width,
81            height: size.height,
82        }
83    }
84
85    /// Get the origin point
86    pub const fn origin(&self) -> CGPoint {
87        CGPoint::new(self.x, self.y)
88    }
89
90    /// Get the size
91    pub const fn size(&self) -> CGSize {
92        CGSize::new(self.width, self.height)
93    }
94
95    /// Get the center point
96    pub const fn center(&self) -> CGPoint {
97        CGPoint::new(self.x + self.width / 2.0, self.y + self.height / 2.0)
98    }
99
100    /// Get the minimum X coordinate
101    pub const fn min_x(&self) -> f64 {
102        self.x
103    }
104
105    /// Get the minimum Y coordinate
106    pub const fn min_y(&self) -> f64 {
107        self.y
108    }
109
110    /// Get the maximum X coordinate
111    pub const fn max_x(&self) -> f64 {
112        self.x + self.width
113    }
114
115    /// Get the maximum Y coordinate
116    pub const fn max_y(&self) -> f64 {
117        self.y + self.height
118    }
119
120    /// Get the mid X coordinate
121    pub const fn mid_x(&self) -> f64 {
122        self.x + self.width / 2.0
123    }
124
125    /// Get the mid Y coordinate
126    pub const fn mid_y(&self) -> f64 {
127        self.y + self.height / 2.0
128    }
129
130    pub fn is_empty(&self) -> bool {
131        self.width <= 0.0 || self.height <= 0.0
132    }
133
134    /// Check if rect is null (both position and size are zero)
135    pub const fn is_null(&self) -> bool {
136        self.x == 0.0 && self.y == 0.0 && self.width == 0.0 && self.height == 0.0
137    }
138}
139
140impl Default for CGRect {
141    fn default() -> Self {
142        Self::zero()
143    }
144}
145
146impl fmt::Display for CGRect {
147    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
148        write!(
149            f,
150            "({}, {}, {}, {})",
151            self.x, self.y, self.width, self.height
152        )
153    }
154}