Skia
2DGraphicsLibrary
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SkPath.h
1 /*
2  * Copyright 2006 The Android Open Source Project
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkPath_DEFINED
9 #define SkPath_DEFINED
10 
11 #include "SkMatrix.h"
12 #include "SkPathRef.h"
13 #include "SkRefCnt.h"
14 
15 class SkReader32;
16 class SkWriter32;
17 class SkAutoPathBoundsUpdate;
18 class SkString;
19 class SkRRect;
20 class SkWStream;
21 
27 class SK_API SkPath {
28 public:
29  enum Direction {
34  };
35 
36  SkPath();
37  SkPath(const SkPath&);
38  ~SkPath();
39 
40  SkPath& operator=(const SkPath&);
41  friend SK_API bool operator==(const SkPath&, const SkPath&);
42  friend bool operator!=(const SkPath& a, const SkPath& b) {
43  return !(a == b);
44  }
45 
54  bool isInterpolatable(const SkPath& compare) const;
55 
65  bool interpolate(const SkPath& ending, SkScalar weight, SkPath* out) const;
66 
67 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
68 
69  bool unique() const { return fPathRef->unique(); }
70 #endif
71 
72  enum FillType {
86  kInverseEvenOdd_FillType
87  };
88 
94  FillType getFillType() const { return (FillType)fFillType; }
95 
102  fFillType = SkToU8(ft);
103  }
104 
106  bool isInverseFillType() const { return IsInverseFillType((FillType)fFillType); }
107 
113  fFillType ^= 2;
114  }
115 
116  enum Convexity {
117  kUnknown_Convexity,
118  kConvex_Convexity,
119  kConcave_Convexity
120  };
121 
126  Convexity getConvexity() const {
127  if (kUnknown_Convexity != fConvexity) {
128  return static_cast<Convexity>(fConvexity);
129  } else {
130  return this->internalGetConvexity();
131  }
132  }
133 
140  Convexity getConvexityOrUnknown() const { return (Convexity)fConvexity; }
141 
151  void setConvexity(Convexity);
152 
157  bool isConvex() const {
158  return kConvex_Convexity == this->getConvexity();
159  }
160 
167  SK_ATTR_DEPRECATED("use setConvexity")
168  void setIsConvex(bool isConvex) {
169  this->setConvexity(isConvex ? kConvex_Convexity : kConcave_Convexity);
170  }
171 
184  bool isOval(SkRect* rect, Direction* dir = nullptr,
185  unsigned* start = nullptr) const {
186  bool isCCW = false;
187  bool result = fPathRef->isOval(rect, &isCCW, start);
188  if (dir && result) {
189  *dir = isCCW ? kCCW_Direction : kCW_Direction;
190  }
191  return result;
192  }
193 
206  bool isRRect(SkRRect* rrect, Direction* dir = nullptr,
207  unsigned* start = nullptr) const {
208  bool isCCW = false;
209  bool result = fPathRef->isRRect(rrect, &isCCW, start);
210  if (dir && result) {
211  *dir = isCCW ? kCCW_Direction : kCW_Direction;
212  }
213  return result;
214  }
215 
220  void reset();
221 
227  void rewind();
228 
233  bool isEmpty() const {
234  SkDEBUGCODE(this->validate();)
235  return 0 == fPathRef->countVerbs();
236  }
237 
240  bool isLastContourClosed() const;
241 
246  bool isFinite() const {
247  SkDEBUGCODE(this->validate();)
248  return fPathRef->isFinite();
249  }
250 
253  bool isVolatile() const {
254  return SkToBool(fIsVolatile);
255  }
256 
264  void setIsVolatile(bool isVolatile) {
265  fIsVolatile = isVolatile;
266  }
267 
272  static bool IsLineDegenerate(const SkPoint& p1, const SkPoint& p2, bool exact) {
273  return exact ? p1 == p2 : p1.equalsWithinTolerance(p2);
274  }
275 
280  static bool IsQuadDegenerate(const SkPoint& p1, const SkPoint& p2,
281  const SkPoint& p3, bool exact) {
282  return exact ? p1 == p2 && p2 == p3 : p1.equalsWithinTolerance(p2) &&
283  p2.equalsWithinTolerance(p3);
284  }
285 
290  static bool IsCubicDegenerate(const SkPoint& p1, const SkPoint& p2,
291  const SkPoint& p3, const SkPoint& p4, bool exact) {
292  return exact ? p1 == p2 && p2 == p3 && p3 == p4 : p1.equalsWithinTolerance(p2) &&
293  p2.equalsWithinTolerance(p3) &&
294  p3.equalsWithinTolerance(p4);
295  }
296 
303  bool isLine(SkPoint line[2]) const;
304 
307  int countPoints() const;
308 
313  SkPoint getPoint(int index) const;
314 
321  int getPoints(SkPoint points[], int max) const;
322 
325  int countVerbs() const;
326 
334  int getVerbs(uint8_t verbs[], int max) const;
335 
337  void swap(SkPath& other);
338 
346  const SkRect& getBounds() const {
347  return fPathRef->getBounds();
348  }
349 
355  void updateBoundsCache() const {
356  // for now, just calling getBounds() is sufficient
357  this->getBounds();
358  }
359 
366  bool conservativelyContainsRect(const SkRect& rect) const;
367 
368  // Construction methods
369 
376  void incReserve(unsigned extraPtCount);
377 
383  void moveTo(SkScalar x, SkScalar y);
384 
389  void moveTo(const SkPoint& p) {
390  this->moveTo(p.fX, p.fY);
391  }
392 
402  void rMoveTo(SkScalar dx, SkScalar dy);
403 
411  void lineTo(SkScalar x, SkScalar y);
412 
419  void lineTo(const SkPoint& p) {
420  this->lineTo(p.fX, p.fY);
421  }
422 
432  void rLineTo(SkScalar dx, SkScalar dy);
433 
443  void quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2);
444 
452  void quadTo(const SkPoint& p1, const SkPoint& p2) {
453  this->quadTo(p1.fX, p1.fY, p2.fX, p2.fY);
454  }
455 
469  void rQuadTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2);
470 
471  void conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
472  SkScalar w);
473  void conicTo(const SkPoint& p1, const SkPoint& p2, SkScalar w) {
474  this->conicTo(p1.fX, p1.fY, p2.fX, p2.fY, w);
475  }
476  void rConicTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2,
477  SkScalar w);
478 
490  void cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
491  SkScalar x3, SkScalar y3);
492 
501  void cubicTo(const SkPoint& p1, const SkPoint& p2, const SkPoint& p3) {
502  this->cubicTo(p1.fX, p1.fY, p2.fX, p2.fY, p3.fX, p3.fY);
503  }
504 
522  void rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
523  SkScalar x3, SkScalar y3);
524 
536  void arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool forceMoveTo);
537 
541  void arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar radius);
542 
546  void arcTo(const SkPoint p1, const SkPoint p2, SkScalar radius) {
547  this->arcTo(p1.fX, p1.fY, p2.fX, p2.fY, radius);
548  }
549 
550  enum ArcSize {
555  };
556 
570  void arcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, ArcSize largeArc,
571  Direction sweep, SkScalar x, SkScalar y);
572 
573  void arcTo(const SkPoint r, SkScalar xAxisRotate, ArcSize largeArc, Direction sweep,
574  const SkPoint xy) {
575  this->arcTo(r.fX, r.fY, xAxisRotate, largeArc, sweep, xy.fX, xy.fY);
576  }
577 
591  void rArcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, ArcSize largeArc,
592  Direction sweep, SkScalar dx, SkScalar dy);
593 
597  void close();
598 
607  static bool IsInverseFillType(FillType fill) {
608  static_assert(0 == kWinding_FillType, "fill_type_mismatch");
609  static_assert(1 == kEvenOdd_FillType, "fill_type_mismatch");
610  static_assert(2 == kInverseWinding_FillType, "fill_type_mismatch");
611  static_assert(3 == kInverseEvenOdd_FillType, "fill_type_mismatch");
612  return (fill & 2) != 0;
613  }
614 
624  static_assert(0 == kWinding_FillType, "fill_type_mismatch");
625  static_assert(1 == kEvenOdd_FillType, "fill_type_mismatch");
626  static_assert(2 == kInverseWinding_FillType, "fill_type_mismatch");
627  static_assert(3 == kInverseEvenOdd_FillType, "fill_type_mismatch");
628  return (FillType)(fill & 1);
629  }
630 
635  static int ConvertConicToQuads(const SkPoint& p0, const SkPoint& p1, const SkPoint& p2,
636  SkScalar w, SkPoint pts[], int pow2);
637 
653  bool isRect(SkRect* rect, bool* isClosed = NULL, Direction* direction = NULL) const;
654 
667  bool isNestedFillRects(SkRect rect[2], Direction dirs[2] = NULL) const;
668 
676  void addRect(const SkRect& rect, Direction dir = kCW_Direction);
677 
691  void addRect(const SkRect& rect, Direction dir, unsigned start);
692 
708  void addRect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom,
709  Direction dir = kCW_Direction);
710 
719  void addOval(const SkRect& oval, Direction dir = kCW_Direction);
720 
738  void addOval(const SkRect& oval, Direction dir, unsigned start);
739 
752  void addCircle(SkScalar x, SkScalar y, SkScalar radius,
753  Direction dir = kCW_Direction);
754 
761  void addArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle);
762 
770  void addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
771  Direction dir = kCW_Direction);
772 
784  void addRoundRect(const SkRect& rect, const SkScalar radii[],
785  Direction dir = kCW_Direction);
786 
796  void addRRect(const SkRRect& rrect, Direction dir = kCW_Direction);
797 
813  void addRRect(const SkRRect& rrect, Direction dir, unsigned start);
814 
826  void addPoly(const SkPoint pts[], int count, bool close);
827 
828  enum AddPathMode {
838  kExtend_AddPathMode
839  };
840 
846  void addPath(const SkPath& src, SkScalar dx, SkScalar dy,
847  AddPathMode mode = kAppend_AddPathMode);
848 
851  void addPath(const SkPath& src, AddPathMode mode = kAppend_AddPathMode) {
852  SkMatrix m;
853  m.reset();
854  this->addPath(src, m, mode);
855  }
856 
862  void addPath(const SkPath& src, const SkMatrix& matrix, AddPathMode mode = kAppend_AddPathMode);
863 
867  void reverseAddPath(const SkPath& src);
868 
875  void offset(SkScalar dx, SkScalar dy, SkPath* dst) const;
876 
882  void offset(SkScalar dx, SkScalar dy) {
883  this->offset(dx, dy, this);
884  }
885 
892  void transform(const SkMatrix& matrix, SkPath* dst) const;
893 
898  void transform(const SkMatrix& matrix) {
899  this->transform(matrix, this);
900  }
901 
908  bool getLastPt(SkPoint* lastPt) const;
909 
916  void setLastPt(SkScalar x, SkScalar y);
917 
923  void setLastPt(const SkPoint& p) {
924  this->setLastPt(p.fX, p.fY);
925  }
926 
927  enum SegmentMask {
928  kLine_SegmentMask = 1 << 0,
929  kQuad_SegmentMask = 1 << 1,
930  kConic_SegmentMask = 1 << 2,
931  kCubic_SegmentMask = 1 << 3,
932  };
933 
939  uint32_t getSegmentMasks() const { return fPathRef->getSegmentMasks(); }
940 
941  enum Verb {
949  };
950 
960  class SK_API Iter {
961  public:
962  Iter();
963  Iter(const SkPath&, bool forceClose);
964 
965  void setPath(const SkPath&, bool forceClose);
966 
979  Verb next(SkPoint pts[4], bool doConsumeDegerates = true, bool exact = false) {
980  if (doConsumeDegerates) {
981  this->consumeDegenerateSegments(exact);
982  }
983  return this->doNext(pts);
984  }
985 
990  SkScalar conicWeight() const { return *fConicWeights; }
991 
1000  bool isCloseLine() const { return SkToBool(fCloseLine); }
1001 
1005  bool isClosedContour() const;
1006 
1007  private:
1008  const SkPoint* fPts;
1009  const uint8_t* fVerbs;
1010  const uint8_t* fVerbStop;
1011  const SkScalar* fConicWeights;
1012  SkPoint fMoveTo;
1013  SkPoint fLastPt;
1014  SkBool8 fForceClose;
1015  SkBool8 fNeedClose;
1016  SkBool8 fCloseLine;
1017  SkBool8 fSegmentState;
1018 
1019  inline const SkPoint& cons_moveTo();
1020  Verb autoClose(SkPoint pts[2]);
1021  void consumeDegenerateSegments(bool exact);
1022  Verb doNext(SkPoint pts[4]);
1023  };
1024 
1027  class SK_API RawIter {
1028  public:
1029  RawIter() {}
1030  RawIter(const SkPath& path) {
1031  setPath(path);
1032  }
1033 
1034  void setPath(const SkPath& path) {
1035  fRawIter.setPathRef(*path.fPathRef.get());
1036  }
1037 
1045  Verb next(SkPoint pts[4]) {
1046  return (Verb) fRawIter.next(pts);
1047  }
1048 
1053  Verb peek() const {
1054  return (Verb) fRawIter.peek();
1055  }
1056 
1057  SkScalar conicWeight() const {
1058  return fRawIter.conicWeight();
1059  }
1060 
1061  private:
1062  SkPathRef::Iter fRawIter;
1063  friend class SkPath;
1064  };
1065 
1070  bool contains(SkScalar x, SkScalar y) const;
1071 
1072  void dump(SkWStream* , bool forceClose, bool dumpAsHex) const;
1073  void dump() const;
1074  void dumpHex() const;
1075 
1080  size_t writeToMemory(void* buffer) const;
1089  size_t readFromMemory(const void* buffer, size_t length);
1090 
1095  uint32_t getGenerationID() const;
1096 
1097 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
1098  static const int kPathRefGenIDBitCnt = 30; // leave room for the fill type (skbug.com/1762)
1099 #else
1100  static const int kPathRefGenIDBitCnt = 32;
1101 #endif
1102 
1103  SkDEBUGCODE(void validate() const;)
1104  SkDEBUGCODE(void experimentalValidateRef() const { fPathRef->validate(); } )
1105 
1106 private:
1107  enum SerializationOffsets {
1108  // 1 free bit at 29
1109  kUnused1_SerializationShift = 28, // 1 free bit
1110  kDirection_SerializationShift = 26, // requires 2 bits
1111  kIsVolatile_SerializationShift = 25, // requires 1 bit
1112  // 1 free bit at 24
1113  kConvexity_SerializationShift = 16, // requires 8 bits
1114  kFillType_SerializationShift = 8, // requires 8 bits
1115  // low-8-bits are version
1116  };
1117 
1118  enum SerializationVersions {
1119  kPathPrivFirstDirection_Version = 1,
1120  kPathPrivLastMoveToIndex_Version = 2,
1121  kCurrent_Version = 2
1122  };
1123 
1124  SkAutoTUnref<SkPathRef> fPathRef;
1125  int fLastMoveToIndex;
1126  uint8_t fFillType;
1127  mutable uint8_t fConvexity;
1128  mutable SkAtomic<uint8_t, sk_memory_order_relaxed> fFirstDirection;// SkPathPriv::FirstDirection
1129  mutable SkBool8 fIsVolatile;
1130 
1135  void resetFields();
1136 
1141  void copyFields(const SkPath& that);
1142 
1143  friend class Iter;
1144  friend class SkPathPriv;
1145  friend class SkPathStroker;
1146 
1147  /* Append, in reverse order, the first contour of path, ignoring path's
1148  last point. If no moveTo() call has been made for this contour, the
1149  first point is automatically set to (0,0).
1150  */
1151  void reversePathTo(const SkPath&);
1152 
1153  // called before we add points for lineTo, quadTo, cubicTo, checking to see
1154  // if we need to inject a leading moveTo first
1155  //
1156  // SkPath path; path.lineTo(...); <--- need a leading moveTo(0, 0)
1157  // SkPath path; ... path.close(); path.lineTo(...) <-- need a moveTo(previous moveTo)
1158  //
1159  inline void injectMoveToIfNeeded();
1160 
1161  inline bool hasOnlyMoveTos() const;
1162 
1163  Convexity internalGetConvexity() const;
1164 
1165  bool isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts,
1166  bool* isClosed, Direction* direction) const;
1167 
1168  // called by stroker to see if all points are equal and worthy of a cap
1169  // equivalent to a short-circuit version of getBounds().isEmpty()
1170  bool isZeroLength() const;
1171 
1175  bool hasComputedBounds() const {
1176  SkDEBUGCODE(this->validate();)
1177  return fPathRef->hasComputedBounds();
1178  }
1179 
1180 
1181  // 'rect' needs to be sorted
1182  void setBounds(const SkRect& rect) {
1183  SkPathRef::Editor ed(&fPathRef);
1184 
1185  ed.setBounds(rect);
1186  }
1187 
1188  void setPt(int index, SkScalar x, SkScalar y);
1189 
1190  friend class SkAutoPathBoundsUpdate;
1191  friend class SkAutoDisableOvalCheck;
1192  friend class SkAutoDisableDirectionCheck;
1193  friend class SkBench_AddPathTest; // perf test reversePathTo
1194  friend class PathTest_Private; // unit test reversePathTo
1195  friend class ForceIsRRect_Private; // unit test isRRect
1196 };
1197 
1198 #endif
iter.next returns 3 points + iter.conicWeight()
Definition: SkPath.h:945
static bool IsQuadDegenerate(const SkPoint &p1, const SkPoint &p2, const SkPoint &p3, bool exact)
Test a quad for zero length.
Definition: SkPath.h:280
Verb next(SkPoint pts[4])
Return the next verb in this iteration of the path.
Definition: SkPath.h:1045
void setFillType(FillType ft)
Set the path's fill type.
Definition: SkPath.h:101
bool contains(SkScalar x, SkScalar y) const
Returns true if the point { x, y } is contained by the path, taking into account the FillType...
static bool IsCubicDegenerate(const SkPoint &p1, const SkPoint &p2, const SkPoint &p3, const SkPoint &p4, bool exact)
Test a cubic curve for zero length.
Definition: SkPath.h:290
Specifies that "inside" is computed by an odd number of edge crossings.
Definition: SkPath.h:80
The SkRRect class represents a rounded rect with a potentially different radii for each corner...
Definition: SkRRect.h:48
The SkPath class encapsulates compound (multiple contour) geometric paths consisting of straight line...
Definition: SkPath.h:27
Definition: SkPathRef.h:41
void arcTo(const SkPoint p1, const SkPoint p2, SkScalar radius)
Append a line and arc to the current path.
Definition: SkPath.h:546
Convexity getConvexity() const
Return the path's convexity, as stored in the path.
Definition: SkPath.h:126
bool hasComputedBounds() const
Returns if the path can return a bound at no cost (true) or will have to perform some computation (fa...
Definition: SkPath.h:1175
static FillType ConvertToNonInverseFillType(FillType fill)
Returns the equivalent non-inverted fill type to the given fill type.
Definition: SkPath.h:623
const SkRect & getBounds() const
Returns the bounds of the path's points.
Definition: SkPath.h:346
void cubicTo(const SkPoint &p1, const SkPoint &p2, const SkPoint &p3)
Add a cubic bezier from the last point, approaching control points p1 and p2, and ending at p3...
Definition: SkPath.h:501
void offset(SkScalar dx, SkScalar dy)
Offset the path by (dx,dy), returning true on success.
Definition: SkPath.h:882
Definition: SkPoint.h:156
bool isOval(SkRect *rect, Direction *dir=nullptr, unsigned *start=nullptr) const
Returns true if the path is an oval.
Definition: SkPath.h:184
Convexity getConvexityOrUnknown() const
Return the currently cached value for convexity, even if that is set to kUnknown_Convexity.
Definition: SkPath.h:140
iter.next returns 3 points
Definition: SkPath.h:944
SkScalar conicWeight() const
Return the weight for the current conic.
Definition: SkPath.h:990
FillType getFillType() const
Return the path's fill type.
Definition: SkPath.h:94
The SkMatrix class holds a 3x3 matrix for transforming coordinates.
Definition: SkMatrix.h:26
Verb peek() const
Return what the next verb will be, but do not visit the next segment.
Definition: SkPath.h:1053
uint32_t getGenerationID() const
Returns a non-zero, globally unique value corresponding to the set of verbs and points in the path (b...
bool isCloseLine() const
If next() returns kLine_Verb, then this query returns true if the line was the result of a close() co...
Definition: SkPath.h:1000
Definition: SkWriter32.h:25
ArcSize
Definition: SkPath.h:550
iter.next returns 0 points
Definition: SkPath.h:947
void setIsVolatile(bool isVolatile)
Specify whether this path is volatile.
Definition: SkPath.h:264
uint8_t SkBool8
Meant to be a small version of bool, for storage purposes.
Definition: SkTypes.h:268
void transform(const SkMatrix &matrix)
Transform the points in this path by matrix.
Definition: SkPath.h:898
void setLastPt(const SkPoint &p)
Set the last point on the path.
Definition: SkPath.h:923
Direction
Definition: SkPath.h:29
void toggleInverseFillType()
Toggle between inverse and normal filltypes.
Definition: SkPath.h:112
void updateBoundsCache() const
Calling this will, if the internal cache of the bounds is out of date, update it so that subsequent c...
Definition: SkPath.h:355
iter.next returns 2 points
Definition: SkPath.h:943
#define SkToBool(cond)
Returns 0 or 1 based on the condition.
Definition: SkTypes.h:287
iter.next returns 1 point
Definition: SkPath.h:942
static bool IsInverseFillType(FillType fill)
Returns whether or not a fill type is inverted.
Definition: SkPath.h:607
size_t writeToMemory(void *buffer) const
Write the path to the buffer, and return the number of bytes written.
Specifies that "inside" is computed by a non-zero sum of signed edge crossings.
Definition: SkPath.h:76
the larger of the two possible SVG arcs.
Definition: SkPath.h:554
uint32_t getSegmentMasks() const
Returns a mask, where each bit corresponding to a SegmentMask is set if the path contains 1 or more s...
Definition: SkPath.h:939
the smaller of the two possible SVG arcs.
Definition: SkPath.h:552
size_t readFromMemory(const void *buffer, size_t length)
Initializes the path from the buffer.
void quadTo(const SkPoint &p1, const SkPoint &p2)
Add a quadratic bezier from the last point, approaching control point p1, and ending at p2...
Definition: SkPath.h:452
void addPath(const SkPath &src, AddPathMode mode=kAppend_AddPathMode)
Add a copy of src to the path.
Definition: SkPath.h:851
iter.next returns 4 points
Definition: SkPath.h:946
bool isEmpty() const
Returns true if the path is empty (contains no lines or curves)
Definition: SkPath.h:233
Source path contours are added as new contours.
Definition: SkPath.h:831
void copyFields(const SkPath &that)
Sets all fields other than fPathRef to the values in 'that'.
void reset()
Set the matrix to identity.
bool isRRect(SkRRect *rrect, Direction *dir=nullptr, unsigned *start=nullptr) const
Returns true if the path is a round rect.
Definition: SkPath.h:206
bool isFinite() const
Returns true if all of the points in this path are finite, meaning there are no infinities and no NaN...
Definition: SkPath.h:246
FillType
Definition: SkPath.h:72
Iterate through the verbs in the path, providing the associated points.
Definition: SkPath.h:1027
bool isVolatile() const
Returns true if the path is volatile (i.e.
Definition: SkPath.h:253
Definition: SkPathRef.h:117
Definition: SkStream.h:182
Definition: SkRect.h:390
Verb next(SkPoint pts[4], bool doConsumeDegerates=true, bool exact=false)
Return the next verb in this iteration of the path.
Definition: SkPath.h:979
counter-clockwise direction for adding closed contours
Definition: SkPath.h:33
bool isConvex() const
Returns true if the path is flagged as being convex.
Definition: SkPath.h:157
void lineTo(const SkPoint &p)
Add a line from the last point to the specified point.
Definition: SkPath.h:419
AddPathMode
Definition: SkPath.h:828
clockwise direction for adding closed contours
Definition: SkPath.h:31
iter.next returns 0 points
Definition: SkPath.h:948
bool equalsWithinTolerance(const SkPoint &p) const
Return true if this point and the given point are far enough apart such that a vector between them wo...
Definition: SkPoint.h:401
void resetFields()
Resets all fields other than fPathRef to their initial 'empty' values.
Iterate through all of the segments (lines, quadratics, cubics) of each contours in a path...
Definition: SkPath.h:960
bool isInverseFillType() const
Returns true if the filltype is one of the Inverse variants.
Definition: SkPath.h:106
Verb
Definition: SkPath.h:941
Light weight class for managing strings.
Definition: SkString.h:121
void moveTo(const SkPoint &p)
Set the beginning of the next contour to the point.
Definition: SkPath.h:389
static bool IsLineDegenerate(const SkPoint &p1, const SkPoint &p2, bool exact)
Test a line for zero length.
Definition: SkPath.h:272
Same as Winding, but draws outside of the path, rather than inside.
Definition: SkPath.h:83