From 7ddd818bc81c5b1df972adbe2d7f5cbd672c2449 Mon Sep 17 00:00:00 2001 From: cepetr Date: Mon, 19 Feb 2024 11:41:11 +0100 Subject: [PATCH] feat(core): introduce new point & rect functions [no changelog] --- core/embed/rust/src/ui/geometry.rs | 44 ++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/core/embed/rust/src/ui/geometry.rs b/core/embed/rust/src/ui/geometry.rs index 79ab72c64..87f7147a7 100644 --- a/core/embed/rust/src/ui/geometry.rs +++ b/core/embed/rust/src/ui/geometry.rs @@ -188,6 +188,17 @@ impl Sub for Point { } } +impl core::ops::Neg for Point { + type Output = Point; + + fn neg(self) -> Self::Output { + Point { + x: -self.x, + y: -self.y, + } + } +} + impl Lerp for Point { fn lerp(a: Self, b: Self, t: f32) -> Self { Point::new(i16::lerp(a.x, b.x, t), i16::lerp(a.y, b.y, t)) @@ -241,6 +252,10 @@ impl Rect { } } + pub fn from_size(size: Offset) -> Self { + Self::from_top_left_and_size(Point::zero(), size) + } + pub const fn from_top_right_and_size(p0: Point, size: Offset) -> Self { let top_left = Point::new(p0.x - size.x, p0.y); Self::from_top_left_and_size(top_left, size) @@ -329,11 +344,26 @@ impl Rect { self.bottom_right().center(self.top_right()) } + pub fn is_empty(&self) -> bool { + self.x0 >= self.x1 || self.y0 >= self.y1 + } + /// Whether a `Point` is inside the `Rect`. pub const fn contains(&self, point: Point) -> bool { point.x >= self.x0 && point.x < self.x1 && point.y >= self.y0 && point.y < self.y1 } + pub fn has_intersection(&self, r: Rect) -> bool { + self.x0 < r.x1 && self.x1 > r.x0 && self.y0 < r.y1 && self.y1 > r.y0 + } + + pub fn intersect(&self, r: Rect) -> Rect { + Rect::new( + Point::new(core::cmp::max(self.x0, r.x0), core::cmp::max(self.y0, r.y0)), + Point::new(core::cmp::min(self.x1, r.x1), core::cmp::min(self.y1, r.y1)), + ) + } + /// Create a bigger `Rect` that contains both `self` and `other`. pub const fn union(&self, other: Self) -> Self { Self { @@ -461,6 +491,20 @@ impl Rect { self.bottom_left() - Offset::y(1), ] } + + /// Normalizes the rectangle coordinates. + /// + /// Returns a new `Rect` with potentially swapped left/right, + /// top/bottom coordinates, ensuring that `x0`, `y0` represents + /// the top-left corner and `x1`, `y1` represents the bottom-right corner. + pub fn normalize(&self) -> Self { + Rect { + x0: core::cmp::min(self.x0, self.x1), + y0: core::cmp::min(self.y0, self.y1), + x1: core::cmp::max(self.x0, self.x1), + y1: core::cmp::max(self.y0, self.y1), + } + } } #[derive(Copy, Clone, PartialEq, Eq)]