Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4978)

Unified Diff: chrome/browser/cocoa/third_party/NSBezierPath+MCAdditions.m

Issue 2805055: [Mac] Use Core Graphics to draw the close button used within tabs, infobars, ... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/cocoa/third_party/NSBezierPath+MCAdditions.m
===================================================================
--- chrome/browser/cocoa/third_party/NSBezierPath+MCAdditions.m (revision 0)
+++ chrome/browser/cocoa/third_party/NSBezierPath+MCAdditions.m (revision 0)
@@ -0,0 +1,225 @@
+//
+// NSBezierPath+MCAdditions.m
+//
+// Created by Sean Patrick O'Brien on 4/1/08.
+// Copyright 2008 MolokoCacao. All rights reserved.
+//
+
+#import "NSBezierPath+MCAdditions.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;
+}
+
+// Method borrowed from Google's Cocoa additions
+- (CGPathRef)cgPath
+{
+ CGMutablePathRef thePath = CGPathCreateMutable();
+ if (!thePath) return nil;
+
+ unsigned int elementCount = [self elementCount];
+
+ // The maximum number of points is 3 for a NSCurveToBezierPathElement.
+ // (controlPoint1, controlPoint2, and endPoint)
+ NSPoint controlPoints[3];
+
+ for (unsigned int i = 0; i < elementCount; i++) {
+ switch ([self elementAtIndex:i associatedPoints:controlPoints]) {
+ case NSMoveToBezierPathElement:
+ CGPathMoveToPoint(thePath, &CGAffineTransformIdentity,
+ controlPoints[0].x, controlPoints[0].y);
+ break;
+ case NSLineToBezierPathElement:
+ CGPathAddLineToPoint(thePath, &CGAffineTransformIdentity,
+ controlPoints[0].x, controlPoints[0].y);
+ break;
+ case NSCurveToBezierPathElement:
+ CGPathAddCurveToPoint(thePath, &CGAffineTransformIdentity,
+ controlPoints[0].x, controlPoints[0].y,
+ controlPoints[1].x, controlPoints[1].y,
+ controlPoints[2].x, controlPoints[2].y);
+ break;
+ case NSClosePathBezierPathElement:
+ CGPathCloseSubpath(thePath);
+ break;
+ default:
+ NSLog(@"Unknown element at [NSBezierPath (GTMBezierPathCGPathAdditions) cgPath]");
+ break;
+ };
+ }
+ return thePath;
+}
+
+- (NSBezierPath *)pathWithStrokeWidth:(CGFloat)strokeWidth
+{
+#ifdef MCBEZIER_USE_PRIVATE_FUNCTION
+ NSBezierPath *path = [self copy];
+ CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
+ CGPathRef pathRef = [path 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
Property changes on: chrome/browser/cocoa/third_party/NSBezierPath+MCAdditions.m
___________________________________________________________________
Added: svn:eol-style
+ LF

Powered by Google App Engine
This is Rietveld 408576698