diff options
author | andybons@chromium.org <andybons@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-01 20:25:38 +0000 |
---|---|---|
committer | andybons@chromium.org <andybons@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-01 20:25:38 +0000 |
commit | bcc18d3d4b89f4985b4bf542c319d6e94de452e0 (patch) | |
tree | 689fe92abe4b260a511e44d0415d625989c3e44c /third_party/molokocacao/NSBezierPath+MCAdditions.m | |
parent | 4cd2d520d95db38a157fd2f86161ea457eab7af2 (diff) | |
download | chromium_src-bcc18d3d4b89f4985b4bf542c319d6e94de452e0.zip chromium_src-bcc18d3d4b89f4985b4bf542c319d6e94de452e0.tar.gz chromium_src-bcc18d3d4b89f4985b4bf542c319d6e94de452e0.tar.bz2 |
[Mac] Moving some new third party code into its proper dir. Also tweak the radius of the close button hover state circle a bit.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/2833050
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@51417 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party/molokocacao/NSBezierPath+MCAdditions.m')
-rw-r--r-- | third_party/molokocacao/NSBezierPath+MCAdditions.m | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/third_party/molokocacao/NSBezierPath+MCAdditions.m b/third_party/molokocacao/NSBezierPath+MCAdditions.m new file mode 100644 index 0000000..e1771cc --- /dev/null +++ b/third_party/molokocacao/NSBezierPath+MCAdditions.m @@ -0,0 +1,188 @@ +// +// NSBezierPath+MCAdditions.m +// +// Created by Sean Patrick O'Brien on 4/1/08. +// Copyright 2008 MolokoCacao. All rights reserved. +// + +#import "NSBezierPath+MCAdditions.h" + +#import "third_party/GTM/AppKit/GTMNSBezierPath+CGPath.h" + +// remove/comment out this line of you don't want to use undocumented functions +#define MCBEZIER_USE_PRIVATE_FUNCTION + +#ifdef MCBEZIER_USE_PRIVATE_FUNCTION +extern CGPathRef CGContextCopyPath(CGContextRef context); +#endif + +static void CGPathCallback(void *info, const CGPathElement *element) +{ + NSBezierPath *path = info; + CGPoint *points = element->points; + + switch (element->type) { + case kCGPathElementMoveToPoint: + { + [path moveToPoint:NSMakePoint(points[0].x, points[0].y)]; + break; + } + case kCGPathElementAddLineToPoint: + { + [path lineToPoint:NSMakePoint(points[0].x, points[0].y)]; + break; + } + case kCGPathElementAddQuadCurveToPoint: + { + // NOTE: This is untested. + NSPoint currentPoint = [path currentPoint]; + NSPoint interpolatedPoint = NSMakePoint((currentPoint.x + 2*points[0].x) / 3, (currentPoint.y + 2*points[0].y) / 3); + [path curveToPoint:NSMakePoint(points[1].x, points[1].y) controlPoint1:interpolatedPoint controlPoint2:interpolatedPoint]; + break; + } + case kCGPathElementAddCurveToPoint: + { + [path curveToPoint:NSMakePoint(points[2].x, points[2].y) controlPoint1:NSMakePoint(points[0].x, points[0].y) controlPoint2:NSMakePoint(points[1].x, points[1].y)]; + break; + } + case kCGPathElementCloseSubpath: + { + [path closePath]; + break; + } + } +} + +@implementation NSBezierPath (MCAdditions) + ++ (NSBezierPath *)bezierPathWithCGPath:(CGPathRef)pathRef +{ + NSBezierPath *path = [NSBezierPath bezierPath]; + CGPathApply(pathRef, path, CGPathCallback); + + return path; +} + +- (NSBezierPath *)pathWithStrokeWidth:(CGFloat)strokeWidth +{ +#ifdef MCBEZIER_USE_PRIVATE_FUNCTION + NSBezierPath *path = [self copy]; + CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort]; + CGPathRef pathRef = [path gtm_CGPath]; + [path release]; + + CGContextSaveGState(context); + + CGContextBeginPath(context); + CGContextAddPath(context, pathRef); + CGContextSetLineWidth(context, strokeWidth); + CGContextReplacePathWithStrokedPath(context); + CGPathRef strokedPathRef = CGContextCopyPath(context); + CGContextBeginPath(context); + NSBezierPath *strokedPath = [NSBezierPath bezierPathWithCGPath:strokedPathRef]; + + CGContextRestoreGState(context); + + CFRelease(pathRef); + CFRelease(strokedPathRef); + + return strokedPath; +#else + return nil; +#endif // MCBEZIER_USE_PRIVATE_FUNCTION +} + +- (void)fillWithInnerShadow:(NSShadow *)shadow +{ + [NSGraphicsContext saveGraphicsState]; + + NSSize offset = shadow.shadowOffset; + NSSize originalOffset = offset; + CGFloat radius = shadow.shadowBlurRadius; + NSRect bounds = NSInsetRect(self.bounds, -(ABS(offset.width) + radius), -(ABS(offset.height) + radius)); + offset.height += bounds.size.height; + shadow.shadowOffset = offset; + NSAffineTransform *transform = [NSAffineTransform transform]; + if ([[NSGraphicsContext currentContext] isFlipped]) + [transform translateXBy:0 yBy:bounds.size.height]; + else + [transform translateXBy:0 yBy:-bounds.size.height]; + + NSBezierPath *drawingPath = [NSBezierPath bezierPathWithRect:bounds]; + [drawingPath setWindingRule:NSEvenOddWindingRule]; + [drawingPath appendBezierPath:self]; + [drawingPath transformUsingAffineTransform:transform]; + + [self addClip]; + [shadow set]; + [[NSColor blackColor] set]; + [drawingPath fill]; + + shadow.shadowOffset = originalOffset; + + [NSGraphicsContext restoreGraphicsState]; +} + +- (void)drawBlurWithColor:(NSColor *)color radius:(CGFloat)radius +{ + NSRect bounds = NSInsetRect(self.bounds, -radius, -radius); + NSShadow *shadow = [[NSShadow alloc] init]; + shadow.shadowOffset = NSMakeSize(0, bounds.size.height); + shadow.shadowBlurRadius = radius; + shadow.shadowColor = color; + NSBezierPath *path = [self copy]; + NSAffineTransform *transform = [NSAffineTransform transform]; + if ([[NSGraphicsContext currentContext] isFlipped]) + [transform translateXBy:0 yBy:bounds.size.height]; + else + [transform translateXBy:0 yBy:-bounds.size.height]; + [path transformUsingAffineTransform:transform]; + + [NSGraphicsContext saveGraphicsState]; + + [shadow set]; + [[NSColor blackColor] set]; + NSRectClip(bounds); + [path fill]; + + [NSGraphicsContext restoreGraphicsState]; + + [path release]; + [shadow release]; +} + +// Credit for the next two methods goes to Matt Gemmell +- (void)strokeInside +{ + /* Stroke within path using no additional clipping rectangle. */ + [self strokeInsideWithinRect:NSZeroRect]; +} + +- (void)strokeInsideWithinRect:(NSRect)clipRect +{ + NSGraphicsContext *thisContext = [NSGraphicsContext currentContext]; + float lineWidth = [self lineWidth]; + + /* Save the current graphics context. */ + [thisContext saveGraphicsState]; + + /* Double the stroke width, since -stroke centers strokes on paths. */ + [self setLineWidth:(lineWidth * 2.0)]; + + /* Clip drawing to this path; draw nothing outwith the path. */ + [self setClip]; + + /* Further clip drawing to clipRect, usually the view's frame. */ + if (clipRect.size.width > 0.0 && clipRect.size.height > 0.0) { + [NSBezierPath clipRect:clipRect]; + } + + /* Stroke the path. */ + [self stroke]; + + /* Restore the previous graphics context. */ + [thisContext restoreGraphicsState]; + [self setLineWidth:lineWidth]; +} + +@end |