Skip to content

Commit cb5515e

Browse files
committed
Merge branch 'pr/105'
2 parents 765f544 + 1b1b0ee commit cb5515e

File tree

2 files changed

+164
-8
lines changed

2 files changed

+164
-8
lines changed

Foundation/NSGeometry.swift

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ prefix public func -(x: CGFloat) -> CGFloat {
6363
return CGFloat(-x.native)
6464
}
6565

66+
public func +=(inout lhs: CGFloat, rhs: CGFloat) {
67+
lhs.native = lhs.native + rhs.native
68+
}
69+
6670
extension Double {
6771
public init(_ value: CGFloat) {
6872
self = Double(value.native)
@@ -446,14 +450,63 @@ public func NSIntegralRectWithOptions(aRect: NSRect, _ opts: NSAlignmentOptions)
446450
return result
447451
}
448452

449-
public func NSUnionRect(aRect: NSRect, _ bRect: NSRect) -> NSRect { NSUnimplemented() }
450-
public func NSIntersectionRect(aRect: NSRect, _ bRect: NSRect) -> NSRect { NSUnimplemented() }
451-
public func NSOffsetRect(aRect: NSRect, _ dX: CGFloat, _ dY: CGFloat) -> NSRect { NSUnimplemented() }
453+
public func NSUnionRect(aRect: NSRect, _ bRect: NSRect) -> NSRect {
454+
let isEmptyFirstRect = NSIsEmptyRect(aRect)
455+
let isEmptySecondRect = NSIsEmptyRect(bRect)
456+
if isEmptyFirstRect && isEmptySecondRect {
457+
return NSZeroRect
458+
} else if isEmptyFirstRect {
459+
return bRect
460+
} else if isEmptySecondRect {
461+
return aRect
462+
}
463+
let x = min(NSMinX(aRect), NSMinX(bRect))
464+
let y = min(NSMinY(aRect), NSMinY(bRect))
465+
let width = max(NSMaxX(aRect), NSMaxX(bRect)) - x
466+
let height = max(NSMaxY(aRect), NSMaxY(bRect)) - y
467+
return NSMakeRect(x, y, width, height)
468+
}
469+
470+
public func NSIntersectionRect(aRect: NSRect, _ bRect: NSRect) -> NSRect {
471+
if NSMaxX(aRect) <= NSMinX(bRect) || NSMaxX(bRect) <= NSMinX(aRect) || NSMaxY(aRect) <= NSMinY(bRect) || NSMaxY(bRect) <= NSMinY(aRect) {
472+
return NSZeroRect
473+
}
474+
let x = max(NSMinX(aRect), NSMinX(bRect))
475+
let y = max(NSMinY(aRect), NSMinY(bRect))
476+
let width = min(NSMaxX(aRect), NSMaxX(bRect)) - x
477+
let height = min(NSMaxY(aRect), NSMaxY(bRect)) - y
478+
return NSMakeRect(x, y, width, height)
479+
}
480+
481+
public func NSOffsetRect(aRect: NSRect, _ dX: CGFloat, _ dY: CGFloat) -> NSRect {
482+
var result = aRect
483+
result.origin.x += dX
484+
result.origin.y += dY
485+
return result
486+
}
487+
452488
public func NSDivideRect(inRect: NSRect, _ slice: UnsafeMutablePointer<NSRect>, _ rem: UnsafeMutablePointer<NSRect>, _ amount: CGFloat, _ edge: NSRectEdge) { NSUnimplemented() }
453-
public func NSPointInRect(aPoint: NSPoint, _ aRect: NSRect) -> Bool { NSUnimplemented() }
454-
public func NSMouseInRect(aPoint: NSPoint, _ aRect: NSRect, _ flipped: Bool) -> Bool { NSUnimplemented() }
455-
public func NSContainsRect(aRect: NSRect, _ bRect: NSRect) -> Bool { NSUnimplemented() }
456-
public func NSIntersectsRect(aRect: NSRect, _ bRect: NSRect) -> Bool { NSUnimplemented() }
489+
490+
public func NSPointInRect(aPoint: NSPoint, _ aRect: NSRect) -> Bool {
491+
return NSMouseInRect(aPoint, aRect, true)
492+
}
493+
494+
public func NSMouseInRect(aPoint: NSPoint, _ aRect: NSRect, _ flipped: Bool) -> Bool {
495+
if flipped {
496+
return aPoint.x >= NSMinX(aRect) && aPoint.y >= NSMinX(aRect) && aPoint.x < NSMaxX(aRect) && aPoint.y < NSMaxY(aRect)
497+
}
498+
return aPoint.x >= NSMinX(aRect) && aPoint.y > NSMinY(aRect) && aPoint.x < NSMaxX(aRect) && aPoint.y <= NSMaxY(aRect)
499+
}
500+
501+
public func NSContainsRect(aRect: NSRect, _ bRect: NSRect) -> Bool {
502+
return !NSIsEmptyRect(bRect) && NSMaxX(bRect) <= NSMaxX(aRect) && NSMinX(bRect) >= NSMinX(aRect) &&
503+
NSMaxY(bRect) <= NSMaxY(aRect) && NSMinY(bRect) >= NSMinY(aRect)
504+
}
505+
506+
public func NSIntersectsRect(aRect: NSRect, _ bRect: NSRect) -> Bool {
507+
return !(NSIsEmptyRect(aRect) || NSIsEmptyRect(bRect) ||
508+
NSMaxX(aRect) <= NSMinX(bRect) || NSMaxX(bRect) <= NSMinX(aRect) || NSMaxY(aRect) <= NSMinY(bRect) || NSMaxY(bRect) <= NSMinY(aRect))
509+
}
457510

458511
public func NSStringFromPoint(aPoint: NSPoint) -> String { NSUnimplemented() }
459512
public func NSStringFromSize(aSize: NSSize) -> String { NSUnimplemented() }

TestFoundation/TestNSGeometry.swift

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ class TestNSGeometry : XCTestCase {
3131
("test_NSMakePoint", test_NSMakePoint),
3232
("test_NSMakeSize", test_NSMakeSize),
3333
("test_NSMakeRect", test_NSMakeRect),
34+
("test_NSUnionRect", test_NSUnionRect),
35+
("test_NSIntersectionRect", test_NSIntersectionRect),
36+
("test_NSOffsetRect", test_NSOffsetRect),
37+
("test_NSPointInRect", test_NSPointInRect),
38+
("test_NSMouseInRect", test_NSMouseInRect),
39+
("test_NSContainsRect", test_NSContainsRect),
40+
("test_NSIntersectsRect", test_NSIntersectsRect),
3441
("test_NSIntegralRect", test_NSIntegralRect),
3542
("test_NSIntegralRectWithOptions", test_NSIntegralRectWithOptions),
3643
]
@@ -141,6 +148,102 @@ class TestNSGeometry : XCTestCase {
141148
XCTAssertEqual(r2.size.height, CGFloat(5.0))
142149
}
143150

151+
func test_NSUnionRect() {
152+
let r1 = NSMakeRect(CGFloat(1.2), CGFloat(3.1), CGFloat(10.0), CGFloat(10.0))
153+
let r2 = NSMakeRect(CGFloat(10.2), CGFloat(2.5), CGFloat(5.0), CGFloat(5.0))
154+
155+
XCTAssertTrue(NSIsEmptyRect(NSUnionRect(NSZeroRect, NSZeroRect)))
156+
XCTAssertTrue(NSEqualRects(r1, NSUnionRect(r1, NSZeroRect)))
157+
XCTAssertTrue(NSEqualRects(r2, NSUnionRect(NSZeroRect, r2)))
158+
159+
let r3 = NSUnionRect(r1, r2)
160+
XCTAssertEqual(r3.origin.x, CGFloat(1.2))
161+
XCTAssertEqual(r3.origin.y, CGFloat(2.5))
162+
XCTAssertEqual(r3.size.width, CGFloat(14.0))
163+
XCTAssertEqual(r3.size.height, CGFloat(10.6))
164+
}
165+
166+
func test_NSIntersectionRect() {
167+
let r1 = NSMakeRect(CGFloat(1.2), CGFloat(3.1), CGFloat(10.0), CGFloat(10.0))
168+
let r2 = NSMakeRect(CGFloat(-2.3), CGFloat(-1.5), CGFloat(1.0), CGFloat(1.0))
169+
let r3 = NSMakeRect(CGFloat(10.2), CGFloat(2.5), CGFloat(5.0), CGFloat(5.0))
170+
171+
XCTAssertTrue(NSIsEmptyRect(NSIntersectionRect(r1, r2)))
172+
173+
let r4 = NSIntersectionRect(r1, r3)
174+
XCTAssertEqual(r4.origin.x, CGFloat(10.2))
175+
XCTAssertEqual(r4.origin.y, CGFloat(3.1))
176+
XCTAssertEqual(r4.size.width, CGFloat(1.0))
177+
XCTAssertEqual(r4.size.height, CGFloat(4.4))
178+
}
179+
180+
func test_NSOffsetRect() {
181+
let r1 = NSMakeRect(CGFloat(1.2), CGFloat(3.1), CGFloat(10.0), CGFloat(10.0))
182+
let r2 = NSOffsetRect(r1, CGFloat(2.0), CGFloat(-5.0))
183+
let expectedRect = NSMakeRect(CGFloat(3.2), CGFloat(-1.9), CGFloat(10.0), CGFloat(10.0))
184+
185+
XCTAssertTrue(NSEqualRects(r2, expectedRect))
186+
}
187+
188+
func test_NSPointInRect() {
189+
let p1 = NSMakePoint(CGFloat(2.2), CGFloat(5.3))
190+
let p2 = NSMakePoint(CGFloat(1.2), CGFloat(3.1))
191+
let p3 = NSMakePoint(CGFloat(1.2), CGFloat(5.3))
192+
let p4 = NSMakePoint(CGFloat(5.2), CGFloat(3.1))
193+
let p5 = NSMakePoint(CGFloat(11.2), CGFloat(13.1))
194+
let r1 = NSMakeRect(CGFloat(1.2), CGFloat(3.1), CGFloat(10.0), CGFloat(10.0))
195+
let r2 = NSMakeRect(CGFloat(-2.3), CGFloat(-1.5), CGFloat(1.0), CGFloat(1.0))
196+
197+
XCTAssertFalse(NSPointInRect(NSZeroPoint, NSZeroRect))
198+
XCTAssertFalse(NSPointInRect(p1, r2))
199+
XCTAssertTrue(NSPointInRect(p1, r1))
200+
XCTAssertTrue(NSPointInRect(p2, r1))
201+
XCTAssertTrue(NSPointInRect(p3, r1))
202+
XCTAssertTrue(NSPointInRect(p4, r1))
203+
XCTAssertFalse(NSPointInRect(p5, r1))
204+
}
205+
206+
func test_NSMouseInRect() {
207+
let p1 = NSMakePoint(CGFloat(2.2), CGFloat(5.3))
208+
let r1 = NSMakeRect(CGFloat(1.2), CGFloat(3.1), CGFloat(10.0), CGFloat(10.0))
209+
let r2 = NSMakeRect(CGFloat(-2.3), CGFloat(-1.5), CGFloat(1.0), CGFloat(1.0))
210+
211+
XCTAssertFalse(NSMouseInRect(NSZeroPoint, NSZeroRect, true))
212+
XCTAssertFalse(NSMouseInRect(p1, r2, true))
213+
XCTAssertTrue(NSMouseInRect(p1, r1, true))
214+
215+
let p2 = NSMakePoint(NSMinX(r1), NSMaxY(r1))
216+
XCTAssertFalse(NSMouseInRect(p2, r1, true))
217+
XCTAssertTrue(NSMouseInRect(p2, r1, false))
218+
219+
let p3 = NSMakePoint(NSMinX(r1), NSMinY(r1))
220+
XCTAssertFalse(NSMouseInRect(p3, r1, false))
221+
XCTAssertTrue(NSMouseInRect(p3, r1, true))
222+
}
223+
224+
func test_NSContainsRect() {
225+
let r1 = NSMakeRect(CGFloat(1.2), CGFloat(3.1), CGFloat(10.0), CGFloat(10.0))
226+
let r2 = NSMakeRect(CGFloat(-2.3), CGFloat(-1.5), CGFloat(1.0), CGFloat(1.0))
227+
let r3 = NSMakeRect(CGFloat(10.2), CGFloat(5.5), CGFloat(0.5), CGFloat(5.0))
228+
229+
XCTAssertFalse(NSContainsRect(r1, NSZeroRect))
230+
XCTAssertFalse(NSContainsRect(r1, r2))
231+
XCTAssertFalse(NSContainsRect(r2, r1))
232+
XCTAssertTrue(NSContainsRect(r1, r3))
233+
}
234+
235+
func test_NSIntersectsRect() {
236+
let r1 = NSMakeRect(CGFloat(1.2), CGFloat(3.1), CGFloat(10.0), CGFloat(10.0))
237+
let r2 = NSMakeRect(CGFloat(-2.3), CGFloat(-1.5), CGFloat(1.0), CGFloat(1.0))
238+
let r3 = NSMakeRect(CGFloat(10.2), CGFloat(2.5), CGFloat(5.0), CGFloat(5.0))
239+
240+
XCTAssertFalse(NSIntersectsRect(NSZeroRect, NSZeroRect))
241+
XCTAssertFalse(NSIntersectsRect(r1, NSZeroRect))
242+
XCTAssertFalse(NSIntersectsRect(NSZeroRect, r2))
243+
XCTAssertFalse(NSIntersectsRect(r1, r2))
244+
XCTAssertTrue(NSIntersectsRect(r1, r3))
245+
}
246+
144247
func test_NSIntegralRect() {
145248
let referenceNegativeRect = NSMakeRect(CGFloat(-0.6), CGFloat(-5.4), CGFloat(-105.7), CGFloat(-24.3))
146249
XCTAssertEqual(NSIntegralRect(referenceNegativeRect), NSZeroRect)
@@ -250,4 +353,4 @@ class TestNSGeometry : XCTestCase {
250353
XCTAssertEqual(result, expectedResult)
251354

252355
}
253-
}
356+
}

0 commit comments

Comments
 (0)