Skip to content

Commit 81a6f49

Browse files
authored
Rect: add union operation (#533)
Add `Rect.union` and associated tests.
1 parent 50d03ae commit 81a6f49

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

Sources/SwiftWin32/CG/Rect.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,19 @@ public struct Rect {
173173
height: standardized.size.height)
174174
}
175175

176+
/// Returns the smallest rectangle that contains the two source rectangles.
177+
public func union(_ rect: Rect) -> Rect {
178+
guard !self.isNull else { return rect }
179+
guard !rect.isNull else { return self }
180+
let lhs: Rect = self.standardized, rhs: Rect = rect.standardized
181+
182+
let origin: Point = Point(x: min(lhs.minX, rhs.minX),
183+
y: min(lhs.minY, rhs.minY))
184+
let size: Size = Size(width: max(lhs.maxX, rhs.maxX) - origin.x,
185+
height: max(lhs.maxY, rhs.maxY) - origin.y)
186+
return Rect(origin: origin, size: size)
187+
}
188+
176189
/// Returns the intersection of two rectangles.
177190
public func intersection(_ rect: Rect) -> Rect {
178191
guard !self.isNull, !rect.isNull else { return .null }

Tests/CoreGraphicsTests/CoreGraphicsTests.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,33 @@ final class CoreGraphicsTests: XCTestCase {
203203
XCTAssertFalse(r4.intersects(r1))
204204
}
205205

206+
func testRectUnion() {
207+
let r1: Rect = Rect(x: 0, y: 0, width: 50, height: 50)
208+
let r2: Rect = Rect(x: 25, y: 25, width: 50, height: 50)
209+
let r3: Rect = Rect(x: 100, y: 100, width: 50, height: 50)
210+
let r4: Rect = Rect(x: 75, y: 75, width: -50, height: -50)
211+
212+
XCTAssertEqual(r1.union(r2), Rect(x: 0, y: 0, width: 75, height: 75))
213+
XCTAssertEqual(r2.union(r1), Rect(x: 0, y: 0, width: 75, height: 75))
214+
215+
XCTAssertEqual(Rect.null.union(r1), Rect(x: 0, y: 0, width: 50, height: 50))
216+
XCTAssertEqual(r1.union(Rect.null), Rect(x: 0, y: 0, width: 50, height: 50))
217+
218+
XCTAssertEqual(r1.union(r3), Rect(x: 0, y: 0, width: 150, height: 150))
219+
XCTAssertEqual(r3.union(r1), Rect(x: 0, y: 0, width: 150, height: 150))
220+
221+
XCTAssertEqual(r1.union(r4), Rect(x: 0, y: 0, width: 75, height: 75))
222+
XCTAssertEqual(r4.union(r1), Rect(x: 0, y: 0, width: 75, height: 75))
223+
224+
XCTAssertEqual(Rect.zero.union(Rect.zero), Rect.zero)
225+
226+
XCTAssertEqual(Rect.infinite.union(Rect.zero), Rect.infinite)
227+
XCTAssertEqual(Rect.zero.union(Rect.infinite), Rect.infinite)
228+
229+
XCTAssertEqual(Rect.infinite.union(Rect.null), Rect.infinite)
230+
XCTAssertEqual(Rect.null.union(Rect.infinite), Rect.infinite)
231+
}
232+
206233
func testRectNonstandardEquality() {
207234
let r1: Rect = Rect(x: 0, y: 0, width: 10, height: 10)
208235
let r2: Rect = Rect(x: 10, y: 10, width: -10, height: -10)
@@ -229,6 +256,7 @@ final class CoreGraphicsTests: XCTestCase {
229256
("testRectInsetBy", testRectInsetBy),
230257
("testRectIntersection", testRectIntersection),
231258
("testRectIntersects", testRectIntersects),
259+
("testRectUnion", testRectUnion),
232260
("testRectNonstandardEquality", testRectNonstandardEquality),
233261
]
234262
}

0 commit comments

Comments
 (0)