API  0.9.7
 All Classes Files Functions Variables Macros Groups Pages
CPBezierPath.j
Go to the documentation of this file.
1 /*
2  * CPBezierPath.j
3  *
4  * Created by Ross Boucher.
5  * Copyright 2009, 280 North, Inc.
6  *
7  * Adapted from Kevin Wojniak, portions Copyright 2009 Kevin Wojniak.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  * Copyright 2009 280 North, Inc.
23  */
24 
25 
26 
27 
28 // Class defaults
29 
30 var DefaultLineWidth = 1.0;
31 
32 
45 @implementation CPBezierPath : CPObject
46 {
47  CGPath _path;
48  float _lineWidth;
49  CPArray _lineDashes;
50  float _lineDashesPhase;
51 }
52 
56 + (CPBezierPath)bezierPath
57 {
58  return [[self alloc] init];
59 }
60 
64 + (CPBezierPath)bezierPathWithOvalInRect:(CGRect)aRect
65 {
66  var path = [self bezierPath];
67 
68  [path appendBezierPathWithOvalInRect:aRect];
69 
70  return path;
71 }
72 
76 + (CPBezierPath)bezierPathWithRect:(CGRect)aRect
77 {
78  var path = [self bezierPath];
79 
80  [path appendBezierPathWithRect:aRect];
81 
82  return path;
83 }
84 
85 + (CPBezierPath)bezierPathWithRoundedRect:(CGRect)aRect xRadius:(float)xRadius yRadius:(float)yRadius
86 {
87  var path = [self bezierPath];
88 
89  [path appendBezierPathWithRoundedRect:aRect xRadius:xRadius yRadius:yRadius];
90 
91  return path;
92 }
93 
97 + (float)defaultLineWidth
98 {
99  return DefaultLineWidth;
100 }
101 
105 + (void)setDefaultLineWidth:(float)width
106 {
108 }
109 
113 + (void)fillRect:(CGRect)aRect
114 {
115  [[self bezierPathWithRect:aRect] fill];
116 }
117 
121 + (void)strokeRect:(CGRect)aRect
122 {
123  [[self bezierPathWithRect:aRect] stroke];
124 }
125 
129 + (void)strokeLineFromPoint:(CGPoint)point1 toPoint:(CGPoint)point2
130 {
131  var path = [self bezierPath];
132 
133  [path moveToPoint:point1];
134  [path lineToPoint:point2];
135 
136  [path stroke];
137 }
138 
142 - (id)init
143 {
144  if (self = [super init])
145  {
146  _path = CGPathCreateMutable();
147  _lineWidth = [[self class] defaultLineWidth];
148  _lineDashesPhase = 0;
149  _lineDashes = [];
150  }
151 
152  return self;
153 }
154 
158 - (void)moveToPoint:(CGPoint)point
159 {
160  CGPathMoveToPoint(_path, nil, point.x, point.y);
161 }
162 
166 - (void)lineToPoint:(CGPoint)point
167 {
168  CGPathAddLineToPoint(_path, nil, point.x, point.y);
169 }
170 
174 - (void)curveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2
175 {
176  CGPathAddCurveToPoint(_path, nil, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, endPoint.x, endPoint.y);
177 }
178 
179 - (CGRect)bounds
180 {
181  // TODO: this should return this. The controlPointBounds is not a tight fit.
182  // return CGPathGetBoundingBox(_path);
183 
184  return [self controlPointBounds];
185 }
186 
187 - (CGRect)controlPointBounds
188 {
189  return CGPathGetBoundingBox(_path);
190 }
191 
195 - (void)closePath
196 {
197  CGPathCloseSubpath(_path);
198 }
199 
203 - (void)stroke
204 {
206 
207  CGContextBeginPath(ctx);
208  CGContextAddPath(ctx, _path);
209  CGContextSetLineWidth(ctx, [self lineWidth]);
210  CGContextSetLineDash(ctx, _lineDashesPhase, _lineDashes);
211  CGContextStrokePath(ctx);
212 }
213 
217 - (void)fill
218 {
220 
221  CGContextBeginPath(ctx);
222  CGContextAddPath(ctx, _path);
223  CGContextSetLineWidth(ctx, [self lineWidth]);
224  CGContextSetLineDash(ctx, _lineDashesPhase, _lineDashes);
225  CGContextClosePath(ctx);
226  CGContextFillPath(ctx);
227 }
228 
232 - (void)getLineDash:(CPArrayRef)patternRef count:(NSInteger)count phase:(CGFloatRef)phaseRef
233 {
234  return [self getLineDash:patternRef phase:phaseRef];
235 }
236 
240 - (void)getLineDash:(CPArrayRef)patternRef phase:(CGFloatRef)phaseRef
241 {
242  if (patternRef)
243  @deref(patternRef) = [_lineDashes copy];
244  if (phaseRef)
245  @deref(phaseRef) = _lineDashesPhase;
246 }
247 
251 - (void)setLineDash:(CPArray)aPattern count:(NSInteger)count phase:(CGFloat)aPhase
252 {
253  [self setLineDash:aPattern phase:aPhase];
254 }
255 
262 - (void)setLineDash:(CPArray)aPattern phase:(CGFloat)aPhase
263 {
264  _lineDashes = aPattern;
265  _lineDashesPhase = aPhase;
266 }
267 
271 - (float)lineWidth
272 {
273  return _lineWidth;
274 }
275 
279 - (void)setLineWidth:(float)lineWidth
280 {
281  _lineWidth = lineWidth;
282 }
283 
287 - (unsigned)elementCount
288 {
289  return _path.count;
290 }
291 
295 - (BOOL)isEmpty
296 {
297  return CGPathIsEmpty(_path);
298 }
299 
303 - (CGPoint)currentPoint
304 {
305  return CGPathGetCurrentPoint(_path);
306 }
307 
311 - (void)appendBezierPathWithPoints:(CPArray)points count:(unsigned)count
312 {
313  CGPathAddLines(_path, nil, points, count);
314 }
315 
319 - (void)appendBezierPathWithRect:(CGRect)rect
320 {
321  CGPathAddRect(_path, nil, rect);
322 }
323 
327 - (void)appendBezierPathWithOvalInRect:(CGRect)rect
328 {
329  CGPathAddPath(_path, nil, CGPathWithEllipseInRect(rect));
330 }
331 
335 - (void)appendBezierPathWithRoundedRect:(CGRect)rect xRadius:(float)xRadius yRadius:(float)yRadius
336 {
337  CGPathAddPath(_path, nil, CGPathWithRoundedRectangleInRect(rect, xRadius, yRadius, YES, YES, YES, YES));
338 }
339 
340 - (void)appendBezierPathWithArcFromPoint:(CGPoint)fromPoint toPoint:(CGPoint)toPoint radius:(float)radius
341 {
342  CGPathAddArcToPoint(_path, null, fromPoint.x, fromPoint.y, toPoint.x, toPoint.y, radius);
343 }
344 
348 - (void)appendBezierPath:(CPBezierPath)other
349 {
350  CGPathAddPath(_path, nil, other._path);
351 }
352 
356 - (void)removeAllPoints
357 {
358  _path = CGPathCreateMutable();
359 }
360 
361 - (void)addClip
362 {
364 
365  CGContextAddPath(ctx, _path);
366  CGContextClip(ctx);
367 }
368 
369 - (void)setClip
370 {
372 
373  CGContextBeginPath(ctx);
374  CGContextAddPath(ctx, _path);
375  CGContextClip(ctx);
376 }
377 
378 @end