From f7af5a1c79ba3ef7042f40f0d20233c4f6ff0466 Mon Sep 17 00:00:00 2001 From: valadaptive Date: Fri, 22 Aug 2025 12:46:02 -0400 Subject: [PATCH 1/2] Fix `Rect::round(_out)` --- path/src/rect.rs | 24 ++++++++++++++++-------- tests/images/fill/float-rect.png | Bin 115 -> 1690 bytes 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/path/src/rect.rs b/path/src/rect.rs index d9c2799..c1db1b4 100644 --- a/path/src/rect.rs +++ b/path/src/rect.rs @@ -311,11 +311,15 @@ impl Rect { /// /// Width and height are guarantee to be >= 1. pub fn round(&self) -> Option { + let left = i32::saturate_round(self.left()); + let top = i32::saturate_round(self.top()); + let right = i32::saturate_round(self.right()); + let bottom = i32::saturate_round(self.bottom()); IntRect::from_xywh( - i32::saturate_round(self.x()), - i32::saturate_round(self.y()), - core::cmp::max(1, i32::saturate_round(self.width()) as u32), - core::cmp::max(1, i32::saturate_round(self.height()) as u32), + left, + top, + core::cmp::max(1, right.saturating_sub(left)) as u32, + core::cmp::max(1, bottom.saturating_sub(top)) as u32, ) } @@ -323,11 +327,15 @@ impl Rect { /// /// Width and height are guarantee to be >= 1. pub fn round_out(&self) -> Option { + let left = i32::saturate_floor(self.left()); + let top = i32::saturate_floor(self.top()); + let right = i32::saturate_ceil(self.right()); + let bottom = i32::saturate_ceil(self.bottom()); IntRect::from_xywh( - i32::saturate_floor(self.x()), - i32::saturate_floor(self.y()), - core::cmp::max(1, i32::saturate_ceil(self.width()) as u32), - core::cmp::max(1, i32::saturate_ceil(self.height()) as u32), + left, + top, + core::cmp::max(1, right.saturating_sub(left)) as u32, + core::cmp::max(1, bottom.saturating_sub(top)) as u32, ) } diff --git a/tests/images/fill/float-rect.png b/tests/images/fill/float-rect.png index ef0d55118ad3ce7359cbba4d5174170f48f7f360..a39fc8505efd2281d0120e201942ad4ae95d0764 100644 GIT binary patch literal 1690 zcmeAS@N?(olHy`uVBq!ia0vp^DImtASp)_3015%+EL z{*V1TU)_JBZ~xmlerCPoBiApR=Kt-jKNI>tt^Vgt`Cq60oEFeuH2v?J{6ER-ewqJ1 zeg5Bt@MrOD6@q);q}M-|FTT3}W_;bZ_I*bGjgEA`NVWeh{eQ;le`o)F+HC)2>d)zl zaW4A5Z{GiLJmzcux9Ri$E?j?RKhH;{s+;Hk9kYM7s($nSKX3SJQ~#xQj5={N6i3tI mXm%OFg$}W$Io1OIpJ47JnUaDapX9$D< delta 97 zcmbQmTRcG`nvt1-fx%0MT^vZU1^9%x0%@a$X$#WTxPdIDk|4ieh7*r<+IInYQl2i3 wAr-fhCE5=Bv*(eK__QbRo<{x@^FIs>Q9E`f&yqj#6sU^9)78&qol`;+0L9=PdjJ3c From 279489c6863cfb63dada3634b7ccdf81134bb8e2 Mon Sep 17 00:00:00 2001 From: valadaptive Date: Fri, 22 Aug 2025 13:29:25 -0400 Subject: [PATCH 2/2] Remove round_overflow tests entirely These tests seem to be...kinda broken? I mean, we explicitly use saturating casts to *avoid* failure. Because we now saturate every absolute coordinate, I think these methods are infallible for now. --- path/src/rect.rs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/path/src/rect.rs b/path/src/rect.rs index c1db1b4..f8d6d8c 100644 --- a/path/src/rect.rs +++ b/path/src/rect.rs @@ -535,19 +535,6 @@ mod rect_tests { assert_eq!(rect.height(), 20.0); } - #[test] - fn round_overflow() { - // minimum value that cause overflow - // because i32::MAX has no exact conversion to f32 - let x = 128.0; - // maximum width - let width = i32::MAX as f32; - - let rect = Rect::from_xywh(x, 0.0, width, 1.0).unwrap(); - assert_eq!(rect.round(), None); - assert_eq!(rect.round_out(), None); - } - #[test] fn transform() { // Tests based on 2x2 rectangle