1use crate::point::{Point, PointF};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub struct Rect {
8 pub x: i32,
9 pub y: i32,
10 pub width: u32,
11 pub height: u32,
12}
13
14impl Rect {
15 pub fn new(x: i32, y: i32, width: u32, height: u32) -> Self {
17 Self {
18 x,
19 y,
20 width,
21 height,
22 }
23 }
24
25 pub fn from_xywh(x: i32, y: i32, width: u32, height: u32) -> Self {
27 Self::new(x, y, width, height)
28 }
29
30 pub fn from_ltrb(left: i32, top: i32, right: i32, bottom: i32) -> Self {
32 let width = (right - left).max(0) as u32;
33 let height = (bottom - top).max(0) as u32;
34 Self::new(left, top, width, height)
35 }
36
37 pub fn from_point_size(point: Point, width: u32, height: u32) -> Self {
39 Self::new(point.x, point.y, width, height)
40 }
41
42 pub fn from_points(p1: Point, p2: Point) -> Self {
44 let x = p1.x.min(p2.x);
45 let y = p1.y.min(p2.y);
46 let width = (p1.x.max(p2.x) - x) as u32;
47 let height = (p1.y.max(p2.y) - y) as u32;
48 Self::new(x, y, width, height)
49 }
50
51 pub fn top_left(&self) -> Point {
53 Point::new(self.x, self.y)
54 }
55
56 pub fn bottom_right(&self) -> Point {
58 Point::new(self.x + self.width as i32, self.y + self.height as i32)
59 }
60
61 pub fn center(&self) -> Point {
63 Point::new(
64 self.x + (self.width / 2) as i32,
65 self.y + (self.height / 2) as i32,
66 )
67 }
68
69 pub fn contains(&self, point: Point) -> bool {
71 point.x >= self.x
72 && point.x < self.x + self.width as i32
73 && point.y >= self.y
74 && point.y < self.y + self.height as i32
75 }
76
77 pub fn intersects(&self, other: &Rect) -> bool {
79 self.x < other.x + other.width as i32
80 && self.x + self.width as i32 > other.x
81 && self.y < other.y + other.height as i32
82 && self.y + self.height as i32 > other.y
83 }
84}
85
86impl Default for Rect {
87 fn default() -> Self {
88 Self::new(0, 0, 0, 0)
89 }
90}
91
92#[derive(Debug, Clone, Copy, PartialEq)]
94pub struct RectF {
95 pub x: f32,
96 pub y: f32,
97 pub width: f32,
98 pub height: f32,
99}
100
101impl RectF {
102 pub fn new(x: f32, y: f32, width: f32, height: f32) -> Self {
104 Self {
105 x,
106 y,
107 width,
108 height,
109 }
110 }
111
112 pub fn from_xywh(x: f32, y: f32, width: f32, height: f32) -> Self {
114 Self::new(x, y, width, height)
115 }
116
117 pub fn from_ltrb(left: f32, top: f32, right: f32, bottom: f32) -> Self {
119 let width = (right - left).max(0.0);
120 let height = (bottom - top).max(0.0);
121 Self::new(left, top, width, height)
122 }
123
124 pub fn from_point_size(point: PointF, width: f32, height: f32) -> Self {
126 Self::new(point.x, point.y, width, height)
127 }
128
129 pub fn to_rect(&self) -> Rect {
131 Rect::new(
132 self.x.round() as i32,
133 self.y.round() as i32,
134 self.width.round() as u32,
135 self.height.round() as u32,
136 )
137 }
138
139 pub fn center(&self) -> PointF {
141 PointF::new(self.x + self.width / 2.0, self.y + self.height / 2.0)
142 }
143}
144
145impl Default for RectF {
146 fn default() -> Self {
147 Self::new(0.0, 0.0, 0.0, 0.0)
148 }
149}
150
151impl From<Rect> for RectF {
152 fn from(r: Rect) -> Self {
153 Self::new(r.x as f32, r.y as f32, r.width as f32, r.height as f32)
154 }
155}
156
157pub type IRect = Rect;