aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2009-03-16 14:30:25 +0000
committerGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2009-03-16 14:30:25 +0000
commit1c1c70beb8fcba6bbcb3f6ca58215e646dca7888 (patch)
treee1c780c73efa2e6b439adb039da774d4730eb91b
parentf14883b92b7df63f9b7c368d138a551c75c8c977 (diff)
[Author: avi]
Add ability to create rounded rects with different radii for different corners. R=dmaclach
-rw-r--r--AppKit/GTMNSBezierPath+RoundRect.h25
-rw-r--r--AppKit/GTMNSBezierPath+RoundRect.m85
-rw-r--r--AppKit/GTMNSBezierPath+RoundRectTest.m14
-rw-r--r--AppKit/TestData/GTMNSBezierPath+RoundRectTest.ppc64.tiffbin10728 -> 11788 bytes
-rw-r--r--AppKit/TestData/GTMNSBezierPath+RoundRectTest.tiffbin10724 -> 11788 bytes
-rw-r--r--AppKit/TestData/GTMNSBezierPath+RoundRectTest.x86_64.tiffbin10728 -> 11788 bytes
6 files changed, 96 insertions, 28 deletions
diff --git a/AppKit/GTMNSBezierPath+RoundRect.h b/AppKit/GTMNSBezierPath+RoundRect.h
index b0b48de..25f4605 100644
--- a/AppKit/GTMNSBezierPath+RoundRect.h
+++ b/AppKit/GTMNSBezierPath+RoundRect.h
@@ -37,6 +37,20 @@
+ (NSBezierPath *)gtm_bezierPathWithRoundRect:(NSRect)rect
cornerRadius:(CGFloat)radius;
+/// Inscribe a round rectangle inside of rectangle |rect| with corner radii specified
+//
+// Args:
+// rect: outer rectangle to inscribe into
+// radius*: radii of the corners
+//
+// Returns:
+// Auto released NSBezierPath
++ (NSBezierPath *)gtm_bezierPathWithRoundRect:(NSRect)rect
+ topLeftCornerRadius:(CGFloat)radiusTL
+ topRightCornerRadius:(CGFloat)radiusTR
+ bottomLeftCornerRadius:(CGFloat)radiusBL
+ bottomRightCornerRadius:(CGFloat)radiusBR;
+
/// Adds a path which is a round rectangle inscribed inside of rectangle |rect| with a corner radius of |radius|
//
// Args:
@@ -45,4 +59,15 @@
// to be no larger than the smaller of half |rect|'s width or height
- (void)gtm_appendBezierPathWithRoundRect:(NSRect)rect
cornerRadius:(CGFloat)radius;
+
+/// Adds a path which is a round rectangle inscribed inside of rectangle |rect| with a corner radii specified
+//
+// Args:
+// rect: outer rectangle to inscribe into
+// radius*: radii of the corners
+- (void)gtm_appendBezierPathWithRoundRect:(NSRect)rect
+ topLeftCornerRadius:(CGFloat)radiusTL
+ topRightCornerRadius:(CGFloat)radiusTR
+ bottomLeftCornerRadius:(CGFloat)radiusBL
+ bottomRightCornerRadius:(CGFloat)radiusBR;
@end
diff --git a/AppKit/GTMNSBezierPath+RoundRect.m b/AppKit/GTMNSBezierPath+RoundRect.m
index d4e5050..806bd94 100644
--- a/AppKit/GTMNSBezierPath+RoundRect.m
+++ b/AppKit/GTMNSBezierPath+RoundRect.m
@@ -31,36 +31,69 @@
return bezier;
}
++ (NSBezierPath *)gtm_bezierPathWithRoundRect:(NSRect)rect
+ topLeftCornerRadius:(CGFloat)radiusTL
+ topRightCornerRadius:(CGFloat)radiusTR
+ bottomLeftCornerRadius:(CGFloat)radiusBL
+ bottomRightCornerRadius:(CGFloat)radiusBR {
+ NSBezierPath *bezier = [NSBezierPath bezierPath];
+ [bezier gtm_appendBezierPathWithRoundRect:rect
+ topLeftCornerRadius:radiusTL
+ topRightCornerRadius:radiusTR
+ bottomLeftCornerRadius:radiusBL
+ bottomRightCornerRadius:radiusBR];
+ return bezier;
+}
- (void)gtm_appendBezierPathWithRoundRect:(NSRect)rect
cornerRadius:(CGFloat)radius {
+ if (radius > 0.0) {
+ // Clamp radius to be no larger than half the rect's width or height.
+ radius = MIN(radius, 0.5 * MIN(rect.size.width, rect.size.height));
+
+ [self gtm_appendBezierPathWithRoundRect:rect
+ topLeftCornerRadius:radius
+ topRightCornerRadius:radius
+ bottomLeftCornerRadius:radius
+ bottomRightCornerRadius:radius];
+ } else {
+ // When radius <= 0.0, use plain rectangle.
+ [self appendBezierPathWithRect:rect];
+ }
+}
+
+- (void)gtm_appendBezierPathWithRoundRect:(NSRect)rect
+ topLeftCornerRadius:(CGFloat)radiusTL
+ topRightCornerRadius:(CGFloat)radiusTR
+ bottomLeftCornerRadius:(CGFloat)radiusBL
+ bottomRightCornerRadius:(CGFloat)radiusBR {
+ // Clamp radii to be at least zero. I'd like to clamp both TL+TR and BL+BR to
+ // be less than the width and TL+BL and TR+BR to be less than the height, but
+ // what to do if they're not? Do we scale them both evenly?
+ radiusTL = MAX(0, radiusTL);
+ radiusTR = MAX(0, radiusTR);
+ radiusBL = MAX(0, radiusBL);
+ radiusBR = MAX(0, radiusBR);
+
if (!NSIsEmptyRect(rect)) {
- if (radius > 0.0) {
- // Clamp radius to be no larger than half the rect's width or height.
- radius = MIN(radius, 0.5 * MIN(rect.size.width, rect.size.height));
-
- NSPoint topLeft = NSMakePoint(NSMinX(rect), NSMaxY(rect));
- NSPoint topRight = NSMakePoint(NSMaxX(rect), NSMaxY(rect));
- NSPoint bottomRight = NSMakePoint(NSMaxX(rect), NSMinY(rect));
-
- [self moveToPoint:NSMakePoint(NSMidX(rect), NSMaxY(rect))];
- [self appendBezierPathWithArcFromPoint:topLeft
- toPoint:rect.origin
- radius:radius];
- [self appendBezierPathWithArcFromPoint:rect.origin
- toPoint:bottomRight
- radius:radius];
- [self appendBezierPathWithArcFromPoint:bottomRight
- toPoint:topRight
- radius:radius];
- [self appendBezierPathWithArcFromPoint:topRight
- toPoint:topLeft
- radius:radius];
- [self closePath];
- } else {
- // When radius <= 0.0, use plain rectangle.
- [self appendBezierPathWithRect:rect];
- }
+ NSPoint topLeft = NSMakePoint(NSMinX(rect), NSMaxY(rect));
+ NSPoint topRight = NSMakePoint(NSMaxX(rect), NSMaxY(rect));
+ NSPoint bottomRight = NSMakePoint(NSMaxX(rect), NSMinY(rect));
+
+ [self moveToPoint:NSMakePoint(NSMidX(rect), NSMaxY(rect))];
+ [self appendBezierPathWithArcFromPoint:topLeft
+ toPoint:rect.origin
+ radius:radiusTL];
+ [self appendBezierPathWithArcFromPoint:rect.origin
+ toPoint:bottomRight
+ radius:radiusBL];
+ [self appendBezierPathWithArcFromPoint:bottomRight
+ toPoint:topRight
+ radius:radiusBR];
+ [self appendBezierPathWithArcFromPoint:topRight
+ toPoint:topLeft
+ radius:radiusTR];
+ [self closePath];
}
}
diff --git a/AppKit/GTMNSBezierPath+RoundRectTest.m b/AppKit/GTMNSBezierPath+RoundRectTest.m
index 5bdf3a3..101460c 100644
--- a/AppKit/GTMNSBezierPath+RoundRectTest.m
+++ b/AppKit/GTMNSBezierPath+RoundRectTest.m
@@ -28,7 +28,7 @@
@implementation GTMNSBezierPath_RoundRectTest
- (void)testRoundRects {
- GTMAssertDrawingEqualToImageNamed(self, NSMakeSize(490, 430),
+ GTMAssertDrawingEqualToImageNamed(self, NSMakeSize(490, 500),
@"GTMNSBezierPath+RoundRectTest", nil, nil);
}
@@ -95,7 +95,17 @@
[roundRect stroke];
theRects[j].origin.y += 35.0;
}
- }
+ }
+
+ // Different radii
+ NSRect bigRect = NSMakeRect(50, 440, 200, 40);
+ NSBezierPath *roundRect = [NSBezierPath gtm_bezierPathWithRoundRect:bigRect
+ topLeftCornerRadius:0.0
+ topRightCornerRadius:5.0
+ bottomLeftCornerRadius:10.0
+ bottomRightCornerRadius:20.0];
+ [roundRect setLineWidth:5.0];
+ [roundRect stroke];
}
diff --git a/AppKit/TestData/GTMNSBezierPath+RoundRectTest.ppc64.tiff b/AppKit/TestData/GTMNSBezierPath+RoundRectTest.ppc64.tiff
index ef22b6b..6e89cc1 100644
--- a/AppKit/TestData/GTMNSBezierPath+RoundRectTest.ppc64.tiff
+++ b/AppKit/TestData/GTMNSBezierPath+RoundRectTest.ppc64.tiff
Binary files differ
diff --git a/AppKit/TestData/GTMNSBezierPath+RoundRectTest.tiff b/AppKit/TestData/GTMNSBezierPath+RoundRectTest.tiff
index b165acf..6e89cc1 100644
--- a/AppKit/TestData/GTMNSBezierPath+RoundRectTest.tiff
+++ b/AppKit/TestData/GTMNSBezierPath+RoundRectTest.tiff
Binary files differ
diff --git a/AppKit/TestData/GTMNSBezierPath+RoundRectTest.x86_64.tiff b/AppKit/TestData/GTMNSBezierPath+RoundRectTest.x86_64.tiff
index ef22b6b..6e89cc1 100644
--- a/AppKit/TestData/GTMNSBezierPath+RoundRectTest.x86_64.tiff
+++ b/AppKit/TestData/GTMNSBezierPath+RoundRectTest.x86_64.tiff
Binary files differ