From 1c1c70beb8fcba6bbcb3f6ca58215e646dca7888 Mon Sep 17 00:00:00 2001 From: "gtm.daemon" Date: Mon, 16 Mar 2009 14:30:25 +0000 Subject: [Author: avi] Add ability to create rounded rects with different radii for different corners. R=dmaclach --- AppKit/GTMNSBezierPath+RoundRect.m | 85 ++++++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 26 deletions(-) (limited to 'AppKit/GTMNSBezierPath+RoundRect.m') 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]; } } -- cgit v1.2.3