makepad_draw/text/
geom.rs

1use {
2    super::num::{One, Zero},
3    std::ops::{Add, Div, Mul, Sub},
4};
5
6#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
7pub struct Point<T> {
8    pub x: T,
9    pub y: T,
10}
11
12impl<T> Point<T> {
13    pub const fn new(x: T, y: T) -> Self {
14        Self { x, y }
15    }
16
17    pub fn apply_transform(self, t: Transform<T>) -> Self
18    where
19        T: Add<Output = T> + Copy + Mul<Output = T>,
20    {
21        Self::new(
22            self.x * t.xx + self.y * t.yx + t.tx,
23            self.x * t.xy + self.y * t.yy + t.ty,
24        )
25    }
26}
27
28impl<T> Add<Size<T>> for Point<T>
29where
30    T: Add<Output = T>,
31{
32    type Output = Self;
33
34    fn add(self, size: Size<T>) -> Self::Output {
35        Self::new(self.x + size.width, self.y + size.height)
36    }
37}
38
39impl<T> Div<T> for Point<T>
40where
41    T: Div<Output = T> + Copy,
42{
43    type Output = Self;
44
45    fn div(self, scalar: T) -> Self::Output {
46        Self::new(self.x / scalar, self.y / scalar)
47    }
48}
49
50impl<T> Mul<T> for Point<T>
51where
52    T: Mul<Output = T> + Copy,
53{
54    type Output = Self;
55
56    fn mul(self, scalar: T) -> Self::Output {
57        Self::new(self.x * scalar, self.y * scalar)
58    }
59}
60
61impl<T> Sub for Point<T>
62where
63    T: Sub<Output = T>,
64{
65    type Output = Size<T>;
66
67    fn sub(self, other: Self) -> Self::Output {
68        Size::new(self.x - other.x, self.y - other.y)
69    }
70}
71
72impl<T> Sub<Size<T>> for Point<T>
73where
74    T: Sub<Output = T>,
75{
76    type Output = Self;
77
78    fn sub(self, size: Size<T>) -> Self::Output {
79        Self::new(self.x - size.width, self.y - size.height)
80    }
81}
82
83impl<T> From<Size<T>> for Point<T> {
84    fn from(size: Size<T>) -> Self {
85        Self::new(size.width, size.height)
86    }
87}
88
89impl<T> Zero for Point<T>
90where
91    T: Zero,
92{
93    const ZERO: Self = Self::new(T::ZERO, T::ZERO);
94}
95
96#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
97pub struct Size<T> {
98    pub width: T,
99    pub height: T,
100}
101
102impl<T> Size<T> {
103    pub const fn new(width: T, height: T) -> Self {
104        Self { width, height }
105    }
106
107    pub fn apply_transform(self, t: Transform<T>) -> Self
108    where
109        T: Add<Output = T> + Copy + Mul<Output = T>,
110    {
111        Self::new(
112            self.width * t.xx + self.height * t.yx,
113            self.width * t.xy + self.height * t.yy,
114        )
115    }
116}
117
118impl<T> Add for Size<T>
119where
120    T: Add<Output = T>,
121{
122    type Output = Self;
123
124    fn add(self, other: Self) -> Self::Output {
125        Self::new(self.width + other.width, self.height + other.height)
126    }
127}
128
129impl<T> From<T> for Size<T>
130where
131    T: Copy,
132{
133    fn from(scalar: T) -> Self {
134        Self::new(scalar, scalar)
135    }
136}
137
138impl<T> From<Point<T>> for Size<T> {
139    fn from(point: Point<T>) -> Self {
140        Self::new(point.x, point.y)
141    }
142}
143
144impl<T> Div<T> for Size<T>
145where
146    T: Div<Output = T> + Copy,
147{
148    type Output = Self;
149
150    fn div(self, scalar: T) -> Self::Output {
151        Self::new(self.width / scalar, self.height / scalar)
152    }
153}
154
155impl<T> Mul<T> for Size<T>
156where
157    T: Mul<Output = T> + Copy,
158{
159    type Output = Self;
160
161    fn mul(self, scalar: T) -> Self::Output {
162        Self::new(self.width * scalar, self.height * scalar)
163    }
164}
165
166impl<T> Sub for Size<T>
167where
168    T: Sub<Output = T>,
169{
170    type Output = Self;
171
172    fn sub(self, other: Self) -> Self::Output {
173        Self::new(self.width - other.width, self.height - other.height)
174    }
175}
176
177impl<T> Zero for Size<T>
178where
179    T: Zero,
180{
181    const ZERO: Self = Self::new(T::ZERO, T::ZERO);
182}
183
184#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
185pub struct Rect<T> {
186    pub origin: Point<T>,
187    pub size: Size<T>,
188}
189
190impl<T> Rect<T> {
191    pub const fn new(origin: Point<T>, size: Size<T>) -> Self {
192        Self { origin, size }
193    }
194
195    pub fn is_empty(self) -> bool
196    where
197        T: Eq + PartialEq + Zero,
198    {
199        self.size == Size::ZERO
200    }
201
202    pub fn contains_point(self, point: Point<T>) -> bool
203    where
204        T: Add<Output = T> + Copy + Ord,
205    {
206        if !(self.min().x..self.max().x).contains(&point.x) {
207            return false;
208        }
209        if !(self.min().y..self.max().y).contains(&point.y) {
210            return false;
211        }
212        true
213    }
214
215    pub fn contains_point_inclusive(self, point: Point<T>) -> bool
216    where
217        T: Add<Output = T> + Copy + Ord,
218    {
219        if !(self.min().x..=self.max().x).contains(&point.x) {
220            return false;
221        }
222        if !(self.min().y..=self.max().y).contains(&point.y) {
223            return false;
224        }
225        true
226    }
227
228    pub fn contains_rect(self, other: Self) -> bool
229    where
230        T: Add<Output = T> + Copy + Ord,
231    {
232        if !self.contains_point(other.min()) {
233            return false;
234        }
235        if !self.contains_point_inclusive(other.max()) {
236            return false;
237        }
238        true
239    }
240
241    pub fn min(self) -> Point<T>
242    where
243        T: Copy,
244    {
245        self.origin
246    }
247
248    pub fn max(self) -> Point<T>
249    where
250        T: Add<Output = T> + Copy,
251    {
252        self.origin + self.size
253    }
254
255    pub fn pad(self, padding: impl Into<Size<T>>) -> Self
256    where
257        T: Add<Output = T> + Copy + Sub<Output = T>,
258    {
259        self._pad(padding.into())
260    }
261
262    fn _pad(self, padding: Size<T>) -> Self
263    where
264        T: Add<Output = T> + Copy + Sub<Output = T>,
265    {
266        Self::new(self.origin - padding, self.size + padding + padding)
267    }
268
269    pub fn unpad(self, padding: impl Into<Size<T>>) -> Self
270    where
271        T: Add<Output = T> + Copy + Sub<Output = T>,
272    {
273        self._unpad(padding.into())
274    }
275
276    fn _unpad(self, padding: Size<T>) -> Self
277    where
278        T: Add<Output = T> + Copy + Sub<Output = T>,
279    {
280        Self::new(self.origin + padding, self.size - padding - padding)
281    }
282
283    pub fn apply_transform(self, t: Transform<T>) -> Self
284    where
285        T: Add<Output = T> + Copy + Mul<Output = T>,
286    {
287        Self::new(self.origin.apply_transform(t), self.size.apply_transform(t))
288    }
289
290    pub fn union(self, other: impl Into<Self>) -> Self
291    where
292        T: Add<Output = T> + Copy + Ord + Sub<Output = T>,
293    {
294        self._union(other.into())
295    }
296
297    fn _union(self, other: Self) -> Self
298    where
299        T: Add<Output = T> + Copy + Ord + Sub<Output = T>,
300    {
301        let min = Point::new(
302            self.min().x.min(other.min().x),
303            self.min().y.min(other.min().y),
304        );
305        let max = Point::new(
306            self.max().x.max(other.max().x),
307            self.max().y.max(other.max().y),
308        );
309        Self::new(min, max - min)
310    }
311}
312
313impl<T> From<Size<T>> for Rect<T>
314where
315    T: Default + Zero,
316{
317    fn from(size: Size<T>) -> Self {
318        Self::new(Point::ZERO, size)
319    }
320}
321
322impl<T> Zero for Rect<T>
323where
324    T: Zero,
325{
326    const ZERO: Self = Self::new(Point::ZERO, Size::ZERO);
327}
328
329#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
330pub struct Transform<T> {
331    pub xx: T,
332    pub xy: T,
333    pub yx: T,
334    pub yy: T,
335    pub tx: T,
336    pub ty: T,
337}
338
339impl<T> Transform<T> {
340    pub fn identity() -> Self
341    where
342        T: One + Zero,
343    {
344        Self {
345            xx: T::ONE,
346            xy: T::ZERO,
347            yx: T::ZERO,
348            yy: T::ONE,
349            tx: T::ZERO,
350            ty: T::ZERO,
351        }
352    }
353
354    pub fn from_scale(sx: T, sy: T) -> Self
355    where
356        T: Zero,
357    {
358        Self {
359            xx: sx,
360            xy: T::ZERO,
361            yx: T::ZERO,
362            yy: sy,
363            tx: T::ZERO,
364            ty: T::ZERO,
365        }
366    }
367
368    pub fn from_scale_uniform(s: T) -> Self
369    where
370        T: Copy + Zero,
371    {
372        Self::from_scale(s, s)
373    }
374
375    pub fn from_translate(tx: T, ty: T) -> Self
376    where
377        T: One + Zero,
378    {
379        Self {
380            xx: T::ONE,
381            xy: T::ZERO,
382            yx: T::ZERO,
383            yy: T::ONE,
384            tx,
385            ty,
386        }
387    }
388
389    pub fn translate(self, tx: T, ty: T) -> Self
390    where
391        T: Add<Output = T> + Copy,
392    {
393        Self {
394            tx: self.tx + tx,
395            ty: self.ty + ty,
396            ..self
397        }
398    }
399
400    pub fn scale(self, sx: T, sy: T) -> Self
401    where
402        T: Add<Output = T> + Copy + Mul<Output = T> + Zero,
403    {
404        Self {
405            xx: self.xx * sx,
406            xy: self.xy * sy,
407            yx: self.yx * sx,
408            yy: self.yy * sy,
409            tx: self.tx * sx,
410            ty: self.ty * sy,
411        }
412    }
413
414    pub fn scale_uniform(self, s: T) -> Self
415    where
416        T: Add<Output = T> + Copy + Mul<Output = T> + Zero,
417    {
418        self.scale(s, s)
419    }
420
421    pub fn concat(self, other: Self) -> Self
422    where
423        T: Add<Output = T> + Copy + Mul<Output = T>,
424    {
425        Self {
426            xx: self.xx * other.xx + self.xy * other.yx,
427            xy: self.xx * other.xy + self.xy * other.yy,
428            yx: self.yx * other.xx + self.yy * other.yx,
429            yy: self.yx * other.xy + self.yy * other.yy,
430            tx: self.tx * other.xx + self.ty * other.yx + other.tx,
431            ty: self.tx * other.xy + self.ty * other.yy + other.ty,
432        }
433    }
434}
435
436impl<T> Default for Transform<T>
437where
438    T: One + Zero,
439{
440    fn default() -> Self {
441        Self::identity()
442    }
443}