blob: d9a7093a8145f1f02f33a01b14282513575a5f08 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SkPath_DEFINED
18#define SkPath_DEFINED
19
20#include "SkMatrix.h"
21#include "SkTDArray.h"
22
djsollen@google.comf5dbe2f2011-04-15 13:41:26 +000023#ifdef ANDROID
24#define GEN_ID_INC fGenerationID++
25#define GEN_ID_PTR_INC(ptr) ptr->fGenerationID++
26#else
27#define GEN_ID_INC
28#define GEN_ID_PTR_INC(ptr)
29#endif
30
reed@android.com8a1c16f2008-12-17 15:59:43 +000031class SkFlattenableReadBuffer;
32class SkFlattenableWriteBuffer;
33class SkAutoPathBoundsUpdate;
34class SkString;
35
36/** \class SkPath
37
38 The SkPath class encapsulates compound (multiple contour) geometric paths
39 consisting of straight line segments, quadratic curves, and cubic curves.
40*/
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +000041class SK_API SkPath {
reed@android.com8a1c16f2008-12-17 15:59:43 +000042public:
43 SkPath();
44 SkPath(const SkPath&);
45 ~SkPath();
46
47 SkPath& operator=(const SkPath&);
reed@android.com3abec1d2009-03-02 05:36:20 +000048
49 friend bool operator==(const SkPath&, const SkPath&);
50 friend bool operator!=(const SkPath& a, const SkPath& b) {
51 return !(a == b);
52 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000053
54 enum FillType {
55 /** Specifies that "inside" is computed by a non-zero sum of signed
56 edge crossings
57 */
58 kWinding_FillType,
59 /** Specifies that "inside" is computed by an odd number of edge
60 crossings
61 */
62 kEvenOdd_FillType,
63 /** Same as Winding, but draws outside of the path, rather than inside
64 */
65 kInverseWinding_FillType,
66 /** Same as EvenOdd, but draws outside of the path, rather than inside
67 */
68 kInverseEvenOdd_FillType
69 };
70
71 /** Return the path's fill type. This is used to define how "inside" is
72 computed. The default value is kWinding_FillType.
73
74 @return the path's fill type
75 */
76 FillType getFillType() const { return (FillType)fFillType; }
77
78 /** Set the path's fill type. This is used to define how "inside" is
79 computed. The default value is kWinding_FillType.
80
81 @param ft The new fill type for this path
82 */
djsollen@google.comf5dbe2f2011-04-15 13:41:26 +000083 void setFillType(FillType ft) {
84 fFillType = SkToU8(ft);
85 GEN_ID_INC;
86 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000087
88 /** Returns true if the filltype is one of the Inverse variants */
89 bool isInverseFillType() const { return (fFillType & 2) != 0; }
90
91 /** Toggle between inverse and normal filltypes. This reverse the return
92 value of isInverseFillType()
93 */
djsollen@google.comf5dbe2f2011-04-15 13:41:26 +000094 void toggleInverseFillType() {
95 fFillType ^= 2;
96 GEN_ID_INC;
97 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000098
reed@android.com6b82d1a2009-06-03 02:35:01 +000099 /** Returns true if the path is flagged as being convex. This is not a
100 confirmed by any analysis, it is just the value set earlier.
101 */
deanm@chromium.org81aaa9d2009-06-18 14:46:03 +0000102 bool isConvex() const { return fIsConvex != 0; }
reed@android.com6b82d1a2009-06-03 02:35:01 +0000103
104 /** Set the isConvex flag to true or false. Convex paths may draw faster if
105 this flag is set, though setting this to true on a path that is in fact
106 not convex can give undefined results when drawn. Paths default to
107 isConvex == false
108 */
djsollen@google.comf5dbe2f2011-04-15 13:41:26 +0000109 void setIsConvex(bool isConvex) {
110 fIsConvex = (isConvex != 0);
111 GEN_ID_INC;
112 }
reed@android.com6b82d1a2009-06-03 02:35:01 +0000113
reed@android.com8a1c16f2008-12-17 15:59:43 +0000114 /** Clear any lines and curves from the path, making it empty. This frees up
115 internal storage associated with those segments.
reed@android.com6b82d1a2009-06-03 02:35:01 +0000116 This does NOT change the fill-type setting nor isConvex
reed@android.com8a1c16f2008-12-17 15:59:43 +0000117 */
118 void reset();
119
120 /** Similar to reset(), in that all lines and curves are removed from the
121 path. However, any internal storage for those lines/curves is retained,
122 making reuse of the path potentially faster.
reed@android.com6b82d1a2009-06-03 02:35:01 +0000123 This does NOT change the fill-type setting nor isConvex
reed@android.com8a1c16f2008-12-17 15:59:43 +0000124 */
125 void rewind();
126
127 /** Returns true if the path is empty (contains no lines or curves)
128
129 @return true if the path is empty (contains no lines or curves)
130 */
131 bool isEmpty() const;
132
133 /** Returns true if the path specifies a rectangle. If so, and if rect is
134 not null, set rect to the bounds of the path. If the path does not
135 specify a rectangle, return false and ignore rect.
136
137 @param rect If not null, returns the bounds of the path if it specifies
138 a rectangle
139 @return true if the path specifies a rectangle
140 */
141 bool isRect(SkRect* rect) const;
142
reed@android.comd3aa4ff2010-02-09 16:38:45 +0000143 /** Return the number of points in the path
144 */
145 int countPoints() const {
146 return this->getPoints(NULL, 0);
147 }
148
149 /** Return the point at the specified index. If the index is out of range
150 (i.e. is not 0 <= index < countPoints()) then the returned coordinates
151 will be (0,0)
152 */
153 SkPoint getPoint(int index) const;
154
reed@android.com8a1c16f2008-12-17 15:59:43 +0000155 /** Returns the number of points in the path. Up to max points are copied.
156
157 @param points If not null, receives up to max points
158 @param max The maximum number of points to copy into points
159 @return the actual number of points in the path
160 */
161 int getPoints(SkPoint points[], int max) const;
162
163 //! Swap contents of this and other. Guaranteed not to throw
164 void swap(SkPath& other);
165
reed@android.comd252db02009-04-01 18:31:44 +0000166 /** Returns the bounds of the path's points. If the path contains 0 or 1
167 points, the bounds is set to (0,0,0,0), and isEmpty() will return true.
168 Note: this bounds may be larger than the actual shape, since curves
169 do not extend as far as their control points.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000170 */
reed@android.comd252db02009-04-01 18:31:44 +0000171 const SkRect& getBounds() const {
172 if (fBoundsIsDirty) {
173 this->computeBounds();
174 }
175 return fBounds;
176 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000177
178 /** Calling this will, if the internal cache of the bounds is out of date,
reed@android.comd252db02009-04-01 18:31:44 +0000179 update it so that subsequent calls to getBounds will be instanteous.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000180 This also means that any copies or simple transformations of the path
181 will inherit the cached bounds.
reed@android.comd252db02009-04-01 18:31:44 +0000182 */
183 void updateBoundsCache() const {
184 // for now, just calling getBounds() is sufficient
185 this->getBounds();
186 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000187
188 // Construction methods
189
190 /** Hint to the path to prepare for adding more points. This can allow the
191 path to more efficiently grow its storage.
192
193 @param extraPtCount The number of extra points the path should
194 preallocate for.
195 */
196 void incReserve(unsigned extraPtCount);
197
198 /** Set the beginning of the next contour to the point (x,y).
199
200 @param x The x-coordinate of the start of a new contour
201 @param y The y-coordinate of the start of a new contour
202 */
203 void moveTo(SkScalar x, SkScalar y);
204
205 /** Set the beginning of the next contour to the point
206
207 @param p The start of a new contour
208 */
209 void moveTo(const SkPoint& p) {
210 this->moveTo(p.fX, p.fY);
211 }
212
213 /** Set the beginning of the next contour relative to the last point on the
214 previous contour. If there is no previous contour, this is treated the
215 same as moveTo().
216
217 @param dx The amount to add to the x-coordinate of the end of the
218 previous contour, to specify the start of a new contour
219 @param dy The amount to add to the y-coordinate of the end of the
220 previous contour, to specify the start of a new contour
221 */
222 void rMoveTo(SkScalar dx, SkScalar dy);
223
224 /** Add a line from the last point to the specified point (x,y). If no
225 moveTo() call has been made for this contour, the first point is
226 automatically set to (0,0).
227
228 @param x The x-coordinate of the end of a line
229 @param y The y-coordinate of the end of a line
230 */
231 void lineTo(SkScalar x, SkScalar y);
232
233 /** Add a line from the last point to the specified point. If no moveTo()
234 call has been made for this contour, the first point is automatically
235 set to (0,0).
236
237 @param p The end of a line
238 */
239 void lineTo(const SkPoint& p) {
240 this->lineTo(p.fX, p.fY);
241 }
242
243 /** Same as lineTo, but the coordinates are considered relative to the last
244 point on this contour. If there is no previous point, then a moveTo(0,0)
245 is inserted automatically.
246
247 @param dx The amount to add to the x-coordinate of the previous point
248 on this contour, to specify a line
249 @param dy The amount to add to the y-coordinate of the previous point
250 on this contour, to specify a line
251 */
252 void rLineTo(SkScalar dx, SkScalar dy);
253
254 /** Add a quadratic bezier from the last point, approaching control point
255 (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for
256 this contour, the first point is automatically set to (0,0).
257
258 @param x1 The x-coordinate of the control point on a quadratic curve
259 @param y1 The y-coordinate of the control point on a quadratic curve
260 @param x2 The x-coordinate of the end point on a quadratic curve
261 @param y2 The y-coordinate of the end point on a quadratic curve
262 */
263 void quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2);
264
265 /** Add a quadratic bezier from the last point, approaching control point
266 p1, and ending at p2. If no moveTo() call has been made for this
267 contour, the first point is automatically set to (0,0).
268
269 @param p1 The control point on a quadratic curve
270 @param p2 The end point on a quadratic curve
271 */
272 void quadTo(const SkPoint& p1, const SkPoint& p2) {
273 this->quadTo(p1.fX, p1.fY, p2.fX, p2.fY);
274 }
275
276 /** Same as quadTo, but the coordinates are considered relative to the last
277 point on this contour. If there is no previous point, then a moveTo(0,0)
278 is inserted automatically.
279
280 @param dx1 The amount to add to the x-coordinate of the last point on
281 this contour, to specify the control point of a quadratic curve
282 @param dy1 The amount to add to the y-coordinate of the last point on
283 this contour, to specify the control point of a quadratic curve
284 @param dx2 The amount to add to the x-coordinate of the last point on
285 this contour, to specify the end point of a quadratic curve
286 @param dy2 The amount to add to the y-coordinate of the last point on
287 this contour, to specify the end point of a quadratic curve
288 */
289 void rQuadTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2);
290
291 /** Add a cubic bezier from the last point, approaching control points
292 (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been
293 made for this contour, the first point is automatically set to (0,0).
294
295 @param x1 The x-coordinate of the 1st control point on a cubic curve
296 @param y1 The y-coordinate of the 1st control point on a cubic curve
297 @param x2 The x-coordinate of the 2nd control point on a cubic curve
298 @param y2 The y-coordinate of the 2nd control point on a cubic curve
299 @param x3 The x-coordinate of the end point on a cubic curve
300 @param y3 The y-coordinate of the end point on a cubic curve
301 */
302 void cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
303 SkScalar x3, SkScalar y3);
304
305 /** Add a cubic bezier from the last point, approaching control points p1
306 and p2, and ending at p3. If no moveTo() call has been made for this
307 contour, the first point is automatically set to (0,0).
308
309 @param p1 The 1st control point on a cubic curve
310 @param p2 The 2nd control point on a cubic curve
311 @param p3 The end point on a cubic curve
312 */
313 void cubicTo(const SkPoint& p1, const SkPoint& p2, const SkPoint& p3) {
314 this->cubicTo(p1.fX, p1.fY, p2.fX, p2.fY, p3.fX, p3.fY);
315 }
316
317 /** Same as cubicTo, but the coordinates are considered relative to the
318 current point on this contour. If there is no previous point, then a
319 moveTo(0,0) is inserted automatically.
320
321 @param dx1 The amount to add to the x-coordinate of the last point on
322 this contour, to specify the 1st control point of a cubic curve
323 @param dy1 The amount to add to the y-coordinate of the last point on
324 this contour, to specify the 1st control point of a cubic curve
325 @param dx2 The amount to add to the x-coordinate of the last point on
326 this contour, to specify the 2nd control point of a cubic curve
327 @param dy2 The amount to add to the y-coordinate of the last point on
328 this contour, to specify the 2nd control point of a cubic curve
329 @param dx3 The amount to add to the x-coordinate of the last point on
330 this contour, to specify the end point of a cubic curve
331 @param dy3 The amount to add to the y-coordinate of the last point on
332 this contour, to specify the end point of a cubic curve
333 */
334 void rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
335 SkScalar x3, SkScalar y3);
336
337 /** Append the specified arc to the path as a new contour. If the start of
338 the path is different from the path's current last point, then an
339 automatic lineTo() is added to connect the current contour to the start
340 of the arc. However, if the path is empty, then we call moveTo() with
341 the first point of the arc. The sweep angle is treated mod 360.
342
343 @param oval The bounding oval defining the shape and size of the arc
344 @param startAngle Starting angle (in degrees) where the arc begins
345 @param sweepAngle Sweep angle (in degrees) measured clockwise. This is
346 treated mod 360.
347 @param forceMoveTo If true, always begin a new contour with the arc
348 */
349 void arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
350 bool forceMoveTo);
351
352 /** Append a line and arc to the current path. This is the same as the
353 PostScript call "arct".
354 */
355 void arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
356 SkScalar radius);
357
358 /** Append a line and arc to the current path. This is the same as the
359 PostScript call "arct".
360 */
361 void arcTo(const SkPoint p1, const SkPoint p2, SkScalar radius) {
362 this->arcTo(p1.fX, p1.fY, p2.fX, p2.fY, radius);
363 }
364
365 /** Close the current contour. If the current point is not equal to the
366 first point of the contour, a line segment is automatically added.
367 */
368 void close();
369
370 enum Direction {
371 /** clockwise direction for adding closed contours */
372 kCW_Direction,
373 /** counter-clockwise direction for adding closed contours */
374 kCCW_Direction
375 };
376
377 /** Add a closed rectangle contour to the path
378 @param rect The rectangle to add as a closed contour to the path
379 @param dir The direction to wind the rectangle's contour
380 */
381 void addRect(const SkRect& rect, Direction dir = kCW_Direction);
382
383 /** Add a closed rectangle contour to the path
384
385 @param left The left side of a rectangle to add as a closed contour
386 to the path
387 @param top The top of a rectangle to add as a closed contour to the
388 path
389 @param right The right side of a rectangle to add as a closed contour
390 to the path
391 @param bottom The bottom of a rectangle to add as a closed contour to
392 the path
393 @param dir The direction to wind the rectangle's contour
394 */
395 void addRect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom,
396 Direction dir = kCW_Direction);
397
398 /** Add a closed oval contour to the path
399
400 @param oval The bounding oval to add as a closed contour to the path
401 @param dir The direction to wind the oval's contour
402 */
403 void addOval(const SkRect& oval, Direction dir = kCW_Direction);
404
405 /** Add a closed circle contour to the path
406
407 @param x The x-coordinate of the center of a circle to add as a
408 closed contour to the path
409 @param y The y-coordinate of the center of a circle to add as a
410 closed contour to the path
411 @param radius The radius of a circle to add as a closed contour to the
412 path
413 @param dir The direction to wind the circle's contour
414 */
415 void addCircle(SkScalar x, SkScalar y, SkScalar radius,
416 Direction dir = kCW_Direction);
417
418 /** Add the specified arc to the path as a new contour.
419
420 @param oval The bounds of oval used to define the size of the arc
421 @param startAngle Starting angle (in degrees) where the arc begins
422 @param sweepAngle Sweep angle (in degrees) measured clockwise
423 */
424 void addArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle);
425
426 /** Add a closed round-rectangle contour to the path
427 @param rect The bounds of a round-rectangle to add as a closed contour
428 @param rx The x-radius of the rounded corners on the round-rectangle
429 @param ry The y-radius of the rounded corners on the round-rectangle
430 @param dir The direction to wind the round-rectangle's contour
431 */
432 void addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
433 Direction dir = kCW_Direction);
434
435 /** Add a closed round-rectangle contour to the path. Each corner receives
436 two radius values [X, Y]. The corners are ordered top-left, top-right,
437 bottom-right, bottom-left.
438 @param rect The bounds of a round-rectangle to add as a closed contour
439 @param radii Array of 8 scalars, 4 [X,Y] pairs for each corner
440 @param dir The direction to wind the round-rectangle's contour
441 */
442 void addRoundRect(const SkRect& rect, const SkScalar radii[],
443 Direction dir = kCW_Direction);
444
445 /** Add a copy of src to the path, offset by (dx,dy)
446 @param src The path to add as a new contour
447 @param dx The amount to translate the path in X as it is added
448 @param dx The amount to translate the path in Y as it is added
449 */
450 void addPath(const SkPath& src, SkScalar dx, SkScalar dy);
451
452 /** Add a copy of src to the path
453 */
454 void addPath(const SkPath& src) {
455 SkMatrix m;
456 m.reset();
457 this->addPath(src, m);
458 }
459
460 /** Add a copy of src to the path, transformed by matrix
461 @param src The path to add as a new contour
462 */
463 void addPath(const SkPath& src, const SkMatrix& matrix);
464
465 /** Offset the path by (dx,dy), returning true on success
466
467 @param dx The amount in the X direction to offset the entire path
468 @param dy The amount in the Y direction to offset the entire path
469 @param dst The translated path is written here
470 */
471 void offset(SkScalar dx, SkScalar dy, SkPath* dst) const;
472
473 /** Offset the path by (dx,dy), returning true on success
474
475 @param dx The amount in the X direction to offset the entire path
476 @param dy The amount in the Y direction to offset the entire path
477 */
478 void offset(SkScalar dx, SkScalar dy) {
479 this->offset(dx, dy, this);
480 }
481
482 /** Transform the points in this path by matrix, and write the answer into
483 dst.
484
485 @param matrix The matrix to apply to the path
486 @param dst The transformed path is written here
487 */
488 void transform(const SkMatrix& matrix, SkPath* dst) const;
489
490 /** Transform the points in this path by matrix
491
492 @param matrix The matrix to apply to the path
493 */
494 void transform(const SkMatrix& matrix) {
495 this->transform(matrix, this);
496 }
497
498 /** Return the last point on the path. If no points have been added, (0,0)
499 is returned.
500
501 @param lastPt The last point on the path is returned here
502 */
503 void getLastPt(SkPoint* lastPt) const;
504
505 /** Set the last point on the path. If no points have been added,
506 moveTo(x,y) is automatically called.
507
508 @param x The new x-coordinate for the last point
509 @param y The new y-coordinate for the last point
510 */
511 void setLastPt(SkScalar x, SkScalar y);
512
513 /** Set the last point on the path. If no points have been added, moveTo(p)
514 is automatically called.
515
516 @param p The new location for the last point
517 */
518 void setLastPt(const SkPoint& p) {
519 this->setLastPt(p.fX, p.fY);
520 }
521
522 enum Verb {
523 kMove_Verb, //!< iter.next returns 1 point
524 kLine_Verb, //!< iter.next returns 2 points
525 kQuad_Verb, //!< iter.next returns 3 points
526 kCubic_Verb, //!< iter.next returns 4 points
527 kClose_Verb, //!< iter.next returns 1 point (the last point)
528 kDone_Verb //!< iter.next returns 0 points
529 };
530
531 /** Iterate through all of the segments (lines, quadratics, cubics) of
532 each contours in a path.
533 */
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +0000534 class SK_API Iter {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000535 public:
536 Iter();
537 Iter(const SkPath&, bool forceClose);
538
539 void setPath(const SkPath&, bool forceClose);
540
541 /** Return the next verb in this iteration of the path. When all
542 segments have been visited, return kDone_Verb.
543
544 @param pts The points representing the current verb and/or segment
545 @return The verb for the current segment
546 */
547 Verb next(SkPoint pts[4]);
548
549 /** If next() returns kLine_Verb, then this query returns true if the
550 line was the result of a close() command (i.e. the end point is the
551 initial moveto for this contour). If next() returned a different
552 verb, this returns an undefined value.
553
554 @return If the last call to next() returned kLine_Verb, return true
555 if it was the result of an explicit close command.
556 */
557 bool isCloseLine() const { return SkToBool(fCloseLine); }
558
559 /** Returns true if the current contour is closed (has a kClose_Verb)
560 @return true if the current contour is closed (has a kClose_Verb)
561 */
562 bool isClosedContour() const;
563
564 private:
565 const SkPoint* fPts;
566 const uint8_t* fVerbs;
567 const uint8_t* fVerbStop;
568 SkPoint fMoveTo;
569 SkPoint fLastPt;
570 SkBool8 fForceClose;
571 SkBool8 fNeedClose;
572 SkBool8 fNeedMoveTo;
573 SkBool8 fCloseLine;
574
575 bool cons_moveTo(SkPoint pts[1]);
576 Verb autoClose(SkPoint pts[2]);
577 };
578
reed@android.com8a1c16f2008-12-17 15:59:43 +0000579 void dump(bool forceClose, const char title[] = NULL) const;
reed@android.come522ca52009-11-23 20:10:41 +0000580 void dump() const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000581
582 void flatten(SkFlattenableWriteBuffer&) const;
583 void unflatten(SkFlattenableReadBuffer&);
584
585 /** Subdivide the path so that no segment is longer that dist.
586 If bendLines is true, then turn all line segments into curves.
587 If dst == null, then the original path itself is modified (not const!)
588 */
589 void subdivide(SkScalar dist, bool bendLines, SkPath* dst = NULL) const;
590
djsollen@google.comf5dbe2f2011-04-15 13:41:26 +0000591#ifdef ANDROID
592 uint32_t getGenerationID() const;
593#endif
594
reed@android.com8a1c16f2008-12-17 15:59:43 +0000595 SkDEBUGCODE(void validate() const;)
596
597private:
598 SkTDArray<SkPoint> fPts;
599 SkTDArray<uint8_t> fVerbs;
reed@android.comd252db02009-04-01 18:31:44 +0000600 mutable SkRect fBounds;
601 mutable uint8_t fBoundsIsDirty;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000602 uint8_t fFillType;
reed@android.com6b82d1a2009-06-03 02:35:01 +0000603 uint8_t fIsConvex;
djsollen@google.comf5dbe2f2011-04-15 13:41:26 +0000604#ifdef ANDROID
605 uint32_t fGenerationID;
606#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000607
reed@android.comd252db02009-04-01 18:31:44 +0000608 // called, if dirty, by getBounds()
609 void computeBounds() const;
610
reed@android.com8a1c16f2008-12-17 15:59:43 +0000611 friend class Iter;
612 void cons_moveto();
613
614 friend class SkPathStroker;
615 /* Append the first contour of path, ignoring path's initial point. If no
616 moveTo() call has been made for this contour, the first point is
617 automatically set to (0,0).
618 */
619 void pathTo(const SkPath& path);
620
621 /* Append, in reverse order, the first contour of path, ignoring path's
622 last point. If no moveTo() call has been made for this contour, the
623 first point is automatically set to (0,0).
624 */
625 void reversePathTo(const SkPath&);
626
627 friend const SkPoint* sk_get_path_points(const SkPath&, int index);
628 friend class SkAutoPathBoundsUpdate;
629};
630
631#endif
632