One Quickie


Rounded rect path (Graphics->General)
Returned path is refcounted, so you'll need to CFRelease when done.
- (CGPathRef) newPathForRoundRect: (CGRect) rect
                        radius: (CGFloat) radius
                   strokeWidth: (CGFloat) strokeWidth {

    // Fit the stroked path inside the rectangle.
    rect.size.height -= strokeWidth;
    rect.size.width -= strokeWidth;
    rect.origin.x += strokeWidth / 2.0;
    rect.origin.y += strokeWidth / 2.0;

    CGMutablePathRef path = CGPathCreateMutable();

    // The inner rect size gives us X/Y/W/H values for the parts of the rect
    // that aren't on the curve.
    CGRect innerRect = CGRectInset(rect, radius, radius);

    CGFloat insideRight = innerRect.origin.x + innerRect.size.width;
    CGFloat outsideRight = rect.origin.x + rect.size.width;
    CGFloat insideBottom = innerRect.origin.y + innerRect.size.height;
    CGFloat outsideBottom = rect.origin.y + rect.size.height;

    CGFloat insideTop = innerRect.origin.y;
    CGFloat outsideTop = rect.origin.y;
    CGFloat outsideLeft = rect.origin.x;

    CGPathMoveToPoint (path, NULL, innerRect.origin.x, outsideTop);

    CGPathAddLineToPoint (path, NULL, insideRight, outsideTop);
    CGPathAddArcToPoint (path, NULL, outsideRight, outsideTop,
                         outsideRight, insideTop, radius);

    CGPathAddLineToPoint (path, NULL, outsideRight, insideBottom);
    CGPathAddArcToPoint (path, NULL,  outsideRight, outsideBottom,
                         insideRight, outsideBottom, radius);

    CGPathAddLineToPoint (path, NULL, innerRect.origin.x, outsideBottom);
    CGPathAddArcToPoint (path, NULL,  outsideLeft, outsideBottom,
                         outsideLeft, insideBottom, radius);

    CGPathAddLineToPoint (path, NULL, outsideLeft, insideTop);
    CGPathAddArcToPoint (path, NULL,  outsideLeft, outsideTop,
                         innerRect.origin.x, outsideTop, radius);

    CGPathCloseSubpath (path);

    return path;

} // newPathForRoundRect
If you're not in CGLand (or not needing the same code to work on the desktop and device), there's also UIBezierPath's -bezierPathWithRoundedRect:cornerRadius: (for all corners), and -bezierPathWithRoundedRect:byRoundingCorners:cornerRadii: (for some arbitrary subset of corners), and NSBezierPath's -bezierPathWithRoundedRect:xRadius:yRadius:. Muchos Thankos to Paul Collins for the reminder.



borkware home | products | miniblog | rants | quickies | cocoaheads
Advanced Mac OS X Programming book

webmonster@borkware.com