1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright 2025 the Vello Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT
//! Geometry utilities.
/// An axis-aligned rectangle with `u16` coordinates, stored as two corners `(x0, y0)` and
/// `(x1, y1)`.
///
/// `(x0, y0)` is the top-left (minimum) corner and `(x1, y1)` is the bottom-right (maximum) corner.
/// The rectangle is considered to be empty when `x0 >= x1` or `y0 >= y1`.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct RectU16 {
/// The minimum x coordinate (left edge).
pub x0: u16,
/// The minimum y coordinate (top edge).
pub y0: u16,
/// The maximum x coordinate (right edge, exclusive).
pub x1: u16,
/// The maximum y coordinate (bottom edge, exclusive).
pub y1: u16,
}
impl RectU16 {
/// A rectangle with all coordinates set to zero.
pub const ZERO: Self = Self {
x0: 0,
y0: 0,
x1: 0,
y1: 0,
};
/// An empty, maximally inverted rectangle, useful as a starting value for incremental union
/// operations.
///
/// Has `(x0, y0) = (u16::MAX, u16::MAX)` and `(x1, y1) = (0, 0)`.
pub const INVERTED: Self = Self {
x0: u16::MAX,
y0: u16::MAX,
x1: 0,
y1: 0,
};
/// Create a new rectangle from its corner coordinates.
#[inline(always)]
pub const fn new(x0: u16, y0: u16, x1: u16, y1: u16) -> Self {
Self { x0, y0, x1, y1 }
}
/// The width of the rectangle (`x1 - x0`), saturating at zero.
#[inline(always)]
pub const fn width(self) -> u16 {
self.x1.saturating_sub(self.x0)
}
/// The height of the rectangle (`y1 - y0`), saturating at zero.
#[inline(always)]
pub const fn height(self) -> u16 {
self.y1.saturating_sub(self.y0)
}
/// Returns `true` if the rectangle has zero area (`x0 >= x1` or `y0 >= y1`).
#[inline(always)]
pub const fn is_empty(self) -> bool {
self.x0 >= self.x1 || self.y0 >= self.y1
}
/// Check if a point `(x, y)` is contained within this rectangle.
///
/// Returns `true` if `x0 <= x < x1` and `y0 <= y < y1`.
#[inline(always)]
pub const fn contains(self, x: u16, y: u16) -> bool {
(x >= self.x0) & (x < self.x1) & (y >= self.y0) & (y < self.y1)
}
/// Compute the intersection of two rectangles.
///
/// The result may be empty if the rectangles do not overlap.
#[inline(always)]
pub const fn intersect(self, other: Self) -> Self {
Self {
x0: const_max(self.x0, other.x0),
y0: const_max(self.y0, other.y0),
x1: const_min(self.x1, other.x1),
y1: const_min(self.y1, other.y1),
}
}
/// Expand this rectangle to also cover `other` (union in place).
///
/// The union of `self` with a [`Self::INVERTED`] returns `self`.
#[inline(always)]
pub const fn union(&mut self, other: Self) {
self.x0 = const_min(self.x0, other.x0);
self.y0 = const_min(self.y0, other.y0);
self.x1 = const_max(self.x1, other.x1);
self.y1 = const_max(self.y1, other.y1);
}
}
#[inline(always)]
const fn const_max(a: u16, b: u16) -> u16 {
if a > b { a } else { b }
}
#[inline(always)]
const fn const_min(a: u16, b: u16) -> u16 {
if a < b { a } else { b }
}