Skip to content

Commit f2c9c75

Browse files
author
bors-servo
authored
Auto merge of #260 - pyfisch:inner-outer-rect, r=nical
Add inner_rect and outer_rect methods to Rect Closes #258 cc @nical Note: The `outer_rect` method is similar to the existing `inflate` method but more powerful. If `SideOffsets2D` hat a constructor taking two offsets one for each direction the `inflate` method could be removed I guess. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/euclid/260) <!-- Reviewable:end -->
2 parents 22cdd6d + d2ff23e commit f2c9c75

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed

src/rect.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use scale::TypedScale;
1313
use num::*;
1414
use point::TypedPoint2D;
1515
use vector::TypedVector2D;
16+
use side_offsets::TypedSideOffsets2D;
1617
use size::TypedSize2D;
1718

1819
use num_traits::NumCast;
@@ -220,6 +221,42 @@ where T: Copy + Clone + Zero + PartialOrd + PartialEq + Add<T, Output=T> + Sub<T
220221
self.translate(&size.to_vector())
221222
}
222223

224+
/// Calculate the size and position of an inner rectangle.
225+
///
226+
/// Subtracts the side offsets from all sides. The horizontal and vertical
227+
/// offsets must not be larger than the original side length.
228+
pub fn inner_rect(&self, offsets: TypedSideOffsets2D<T, U>) -> Self {
229+
let rect = TypedRect::new(
230+
TypedPoint2D::new(
231+
self.origin.x + offsets.left,
232+
self.origin.y + offsets.top
233+
),
234+
TypedSize2D::new(
235+
self.size.width - offsets.horizontal(),
236+
self.size.height - offsets.vertical()
237+
)
238+
);
239+
debug_assert!(rect.size.width >= Zero::zero());
240+
debug_assert!(rect.size.height >= Zero::zero());
241+
rect
242+
}
243+
244+
/// Calculate the size and position of an outer rectangle.
245+
///
246+
/// Add the offsets to all sides. The expanded rectangle is returned.
247+
pub fn outer_rect(&self, offsets: TypedSideOffsets2D<T, U>) -> Self {
248+
TypedRect::new(
249+
TypedPoint2D::new(
250+
self.origin.x - offsets.left,
251+
self.origin.y - offsets.top
252+
),
253+
TypedSize2D::new(
254+
self.size.width + offsets.horizontal(),
255+
self.size.height + offsets.vertical()
256+
)
257+
)
258+
}
259+
223260
/// Returns the smallest rectangle defined by the top/bottom/left/right-most
224261
/// points provided as parameter.
225262
///
@@ -481,6 +518,7 @@ pub fn rect<T: Copy, U>(x: T, y: T, w: T, h: T) -> TypedRect<T, U> {
481518
mod tests {
482519
use point::Point2D;
483520
use vector::vec2;
521+
use side_offsets::SideOffsets2D;
484522
use size::Size2D;
485523
use super::*;
486524

@@ -657,6 +695,18 @@ mod tests {
657695
assert!(rr.origin.y == 5);
658696
}
659697

698+
#[test]
699+
fn test_inner_outer_rect() {
700+
let inner_rect: Rect<i32> = Rect::new(Point2D::new(20, 40), Size2D::new(80, 100));
701+
let offsets = SideOffsets2D::new(20, 10, 10, 10);
702+
let outer_rect = inner_rect.outer_rect(offsets);
703+
assert_eq!(outer_rect.origin.x, 10);
704+
assert_eq!(outer_rect.origin.y, 20);
705+
assert_eq!(outer_rect.size.width, 100);
706+
assert_eq!(outer_rect.size.height, 130);
707+
assert_eq!(outer_rect.inner_rect(offsets), inner_rect);
708+
}
709+
660710
#[test]
661711
fn test_min_max_x_y() {
662712
let p = Rect::new(Point2D::new(0u32, 0u32), Size2D::new(50u32, 40u32));

0 commit comments

Comments
 (0)