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

Side by Side 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, 5 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 unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 //
2 // NSBezierPath+MCAdditions.m
3 //
4 // Created by Sean Patrick O'Brien on 4/1/08.
5 // Copyright 2008 MolokoCacao. All rights reserved.
6 //
7
8 #import "NSBezierPath+MCAdditions.h"
9
10 // remove/comment out this line of you don't want to use undocumented functions
11 #define MCBEZIER_USE_PRIVATE_FUNCTION
12
13 #ifdef MCBEZIER_USE_PRIVATE_FUNCTION
14 extern CGPathRef CGContextCopyPath(CGContextRef context);
15 #endif
16
17 static void CGPathCallback(void *info, const CGPathElement *element)
18 {
19 NSBezierPath *path = info;
20 CGPoint *points = element->points;
21
22 switch (element->type) {
23 case kCGPathElementMoveToPoint:
24 {
25 [path moveToPoint:NSMakePoint(points[0].x, points[0].y)] ;
26 break;
27 }
28 case kCGPathElementAddLineToPoint:
29 {
30 [path lineToPoint:NSMakePoint(points[0].x, points[0].y)] ;
31 break;
32 }
33 case kCGPathElementAddQuadCurveToPoint:
34 {
35 // NOTE: This is untested.
36 NSPoint currentPoint = [path currentPoint];
37 NSPoint interpolatedPoint = NSMakePoint((currentPoint.x + 2*points[0].x) / 3, (currentPoint.y + 2*points[0].y) / 3);
38 [path curveToPoint:NSMakePoint(points[1].x, points[1].y) controlPoint1:interpolatedPoint controlPoint2:interpolatedPoint];
39 break;
40 }
41 case kCGPathElementAddCurveToPoint:
42 {
43 [path curveToPoint:NSMakePoint(points[2].x, points[2].y) controlPoint1:NSMakePoint(points[0].x, points[0].y) controlPoint2:NSMakePoint(p oints[1].x, points[1].y)];
44 break;
45 }
46 case kCGPathElementCloseSubpath:
47 {
48 [path closePath];
49 break;
50 }
51 }
52 }
53
54 @implementation NSBezierPath (MCAdditions)
55
56 + (NSBezierPath *)bezierPathWithCGPath:(CGPathRef)pathRef
57 {
58 NSBezierPath *path = [NSBezierPath bezierPath];
59 CGPathApply(pathRef, path, CGPathCallback);
60
61 return path;
62 }
63
64 // Method borrowed from Google's Cocoa additions
65 - (CGPathRef)cgPath
66 {
67 CGMutablePathRef thePath = CGPathCreateMutable();
68 if (!thePath) return nil;
69
70 unsigned int elementCount = [self elementCount];
71
72 // The maximum number of points is 3 for a NSCurveToBezierPathElement.
73 // (controlPoint1, controlPoint2, and endPoint)
74 NSPoint controlPoints[3];
75
76 for (unsigned int i = 0; i < elementCount; i++) {
77 switch ([self elementAtIndex:i associatedPoints:controlPoints]) {
78 case NSMoveToBezierPathElement:
79 CGPathMoveToPoint(thePath, &CGAffineTransformIde ntity,
80 controlPoints[ 0].x, controlPoints[0].y);
81 break;
82 case NSLineToBezierPathElement:
83 CGPathAddLineToPoint(thePath, &CGAffineTransform Identity,
84 control Points[0].x, controlPoints[0].y);
85 break;
86 case NSCurveToBezierPathElement:
87 CGPathAddCurveToPoint(thePath, &CGAffineTransfor mIdentity,
88 contro lPoints[0].x, controlPoints[0].y,
89 contro lPoints[1].x, controlPoints[1].y,
90 contro lPoints[2].x, controlPoints[2].y);
91 break;
92 case NSClosePathBezierPathElement:
93 CGPathCloseSubpath(thePath);
94 break;
95 default:
96 NSLog(@"Unknown element at [NSBezierPath (GTMBez ierPathCGPathAdditions) cgPath]");
97 break;
98 };
99 }
100 return thePath;
101 }
102
103 - (NSBezierPath *)pathWithStrokeWidth:(CGFloat)strokeWidth
104 {
105 #ifdef MCBEZIER_USE_PRIVATE_FUNCTION
106 NSBezierPath *path = [self copy];
107 CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort] ;
108 CGPathRef pathRef = [path cgPath];
109 [path release];
110
111 CGContextSaveGState(context);
112
113 CGContextBeginPath(context);
114 CGContextAddPath(context, pathRef);
115 CGContextSetLineWidth(context, strokeWidth);
116 CGContextReplacePathWithStrokedPath(context);
117 CGPathRef strokedPathRef = CGContextCopyPath(context);
118 CGContextBeginPath(context);
119 NSBezierPath *strokedPath = [NSBezierPath bezierPathWithCGPath:strokedPa thRef];
120
121 CGContextRestoreGState(context);
122
123 CFRelease(pathRef);
124 CFRelease(strokedPathRef);
125
126 return strokedPath;
127 #else
128 return nil;
129 #endif//MCBEZIER_USE_PRIVATE_FUNCTION
130 }
131
132 - (void)fillWithInnerShadow:(NSShadow *)shadow
133 {
134 [NSGraphicsContext saveGraphicsState];
135
136 NSSize offset = shadow.shadowOffset;
137 NSSize originalOffset = offset;
138 CGFloat radius = shadow.shadowBlurRadius;
139 NSRect bounds = NSInsetRect(self.bounds, -(ABS(offset.width) + radius), -(ABS(offset.height) + radius));
140 offset.height += bounds.size.height;
141 shadow.shadowOffset = offset;
142 NSAffineTransform *transform = [NSAffineTransform transform];
143 if ([[NSGraphicsContext currentContext] isFlipped])
144 [transform translateXBy:0 yBy:bounds.size.height];
145 else
146 [transform translateXBy:0 yBy:-bounds.size.height];
147
148 NSBezierPath *drawingPath = [NSBezierPath bezierPathWithRect:bounds];
149 [drawingPath setWindingRule:NSEvenOddWindingRule];
150 [drawingPath appendBezierPath:self];
151 [drawingPath transformUsingAffineTransform:transform];
152
153 [self addClip];
154 [shadow set];
155 [[NSColor blackColor] set];
156 [drawingPath fill];
157
158 shadow.shadowOffset = originalOffset;
159
160 [NSGraphicsContext restoreGraphicsState];
161 }
162
163 - (void)drawBlurWithColor:(NSColor *)color radius:(CGFloat)radius
164 {
165 NSRect bounds = NSInsetRect(self.bounds, -radius, -radius);
166 NSShadow *shadow = [[NSShadow alloc] init];
167 shadow.shadowOffset = NSMakeSize(0, bounds.size.height);
168 shadow.shadowBlurRadius = radius;
169 shadow.shadowColor = color;
170 NSBezierPath *path = [self copy];
171 NSAffineTransform *transform = [NSAffineTransform transform];
172 if ([[NSGraphicsContext currentContext] isFlipped])
173 [transform translateXBy:0 yBy:bounds.size.height];
174 else
175 [transform translateXBy:0 yBy:-bounds.size.height];
176 [path transformUsingAffineTransform:transform];
177
178 [NSGraphicsContext saveGraphicsState];
179
180 [shadow set];
181 [[NSColor blackColor] set];
182 NSRectClip(bounds);
183 [path fill];
184
185 [NSGraphicsContext restoreGraphicsState];
186
187 [path release];
188 [shadow release];
189 }
190
191 // Credit for the next two methods goes to Matt Gemmell
192 - (void)strokeInside
193 {
194 /* Stroke within path using no additional clipping rectangle. */
195 [self strokeInsideWithinRect:NSZeroRect];
196 }
197
198 - (void)strokeInsideWithinRect:(NSRect)clipRect
199 {
200 NSGraphicsContext *thisContext = [NSGraphicsContext currentContext];
201 float lineWidth = [self lineWidth];
202
203 /* Save the current graphics context. */
204 [thisContext saveGraphicsState];
205
206 /* Double the stroke width, since -stroke centers strokes on paths. */
207 [self setLineWidth:(lineWidth * 2.0)];
208
209 /* Clip drawing to this path; draw nothing outwith the path. */
210 [self setClip];
211
212 /* Further clip drawing to clipRect, usually the view's frame. */
213 if (clipRect.size.width > 0.0 && clipRect.size.height > 0.0) {
214 [NSBezierPath clipRect:clipRect];
215 }
216
217 /* Stroke the path. */
218 [self stroke];
219
220 /* Restore the previous graphics context. */
221 [thisContext restoreGraphicsState];
222 [self setLineWidth:lineWidth];
223 }
224
225 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698