From 254de49a6260737c44fc0764ee2d89ec544775ac 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 | 32 ++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/core/embed/rust/src/ui/geometry.rs b/core/embed/rust/src/ui/geometry.rs index 79ab72c640..d73702340a 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 const 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,6 +344,14 @@ impl Rect { self.bottom_right().center(self.top_right()) } + /// Checks if the rectangle is empty. + /// + /// It is possible to custruct a rectangle with negative width or height. + /// All such rectangles are considered as empty. + pub const 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 @@ -425,6 +448,15 @@ impl Rect { (left, center, right) } + /// Calculates the intersection of two rectangles. + /// + /// If the rectangles do not intersect, an "empty" rectangle is returned. + /// + /// The implementation may yield rectangles with negative width or height + /// if there's no intersection. Such rectangles are considered empty, + /// and subsequent operations like clamp, union, and translation + /// work correctly with them. However, it's important to be aware of this + /// behavior. pub const fn clamp(self, limit: Rect) -> Self { Self { x0: max(self.x0, limit.x0),