Skia
2DGraphicsLibrary
 All Classes Namespaces 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 "../private/SkPathRef.h"
13 
14 class SkAutoPathBoundsUpdate;
15 class SkRRect;
16 class SkWStream;
17 
25 class SK_API SkPath {
26 public:
27  enum Direction {
32  };
33 
34  SkPath();
35  SkPath(const SkPath& path);
36  ~SkPath();
37 
38  SkPath& operator=(const SkPath& path);
39  // mac chromium dbg requires SK_API to make operator== visible
40  friend SK_API bool operator==(const SkPath& a, const SkPath& b);
41  friend bool operator!=(const SkPath& a, const SkPath& b) {
42  return !(a == b);
43  }
44 
53  bool isInterpolatable(const SkPath& compare) const;
54 
64  bool interpolate(const SkPath& ending, SkScalar weight, SkPath* out) const;
65 
66 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
67 
68  bool unique() const { return fPathRef->unique(); }
69 #endif
70 
71  enum FillType {
85  kInverseEvenOdd_FillType
86  };
87 
93  FillType getFillType() const { return (FillType)fFillType; }
94 
101  fFillType = SkToU8(ft);
102  }
103 
105  bool isInverseFillType() const { return IsInverseFillType((FillType)fFillType); }
106 
112  fFillType ^= 2;
113  }
114 
115  enum Convexity {
116  kUnknown_Convexity,
117  kConvex_Convexity,
118  kConcave_Convexity
119  };
120 
125  Convexity getConvexity() const {
126  if (kUnknown_Convexity != fConvexity) {
127  return static_cast<Convexity>(fConvexity);
128  } else {
129  return this->internalGetConvexity();
130  }
131  }
132 
139  Convexity getConvexityOrUnknown() const { return (Convexity)fConvexity; }
140 
150  void setConvexity(Convexity convexity);
151 
156  bool isConvex() const {
157  return kConvex_Convexity == this->getConvexity();
158  }
159 
166  SK_ATTR_DEPRECATED("use setConvexity")
167  void setIsConvex(bool isConvex) {
168  this->setConvexity(isConvex ? kConvex_Convexity : kConcave_Convexity);
169  }
170 
183  bool isOval(SkRect* rect, Direction* dir = nullptr,
184  unsigned* start = nullptr) const {
185  bool isCCW = false;
186  bool result = fPathRef->isOval(rect, &isCCW, start);
187  if (dir && result) {
188  *dir = isCCW ? kCCW_Direction : kCW_Direction;
189  }
190  return result;
191  }
192 
205  bool isRRect(SkRRect* rrect, Direction* dir = nullptr,
206  unsigned* start = nullptr) const {
207  bool isCCW = false;
208  bool result = fPathRef->isRRect(rrect, &isCCW, start);
209  if (dir && result) {
210  *dir = isCCW ? kCCW_Direction : kCW_Direction;
211  }
212  return result;
213  }
214 
219  void reset();
220 
226  void rewind();
227 
232  bool isEmpty() const {
233  SkDEBUGCODE(this->validate();)
234  return 0 == fPathRef->countVerbs();
235  }
236 
239  bool isLastContourClosed() const;
240 
245  bool isFinite() const {
246  SkDEBUGCODE(this->validate();)
247  return fPathRef->isFinite();
248  }
249 
252  bool isVolatile() const {
253  return SkToBool(fIsVolatile);
254  }
255 
263  void setIsVolatile(bool isVolatile) {
264  fIsVolatile = isVolatile;
265  }
266 
271  static bool IsLineDegenerate(const SkPoint& p1, const SkPoint& p2, bool exact) {
272  return exact ? p1 == p2 : p1.equalsWithinTolerance(p2);
273  }
274 
279  static bool IsQuadDegenerate(const SkPoint& p1, const SkPoint& p2,
280  const SkPoint& p3, bool exact) {
281  return exact ? p1 == p2 && p2 == p3 : p1.equalsWithinTolerance(p2) &&
282  p2.equalsWithinTolerance(p3);
283  }
284 
289  static bool IsCubicDegenerate(const SkPoint& p1, const SkPoint& p2,
290  const SkPoint& p3, const SkPoint& p4, bool exact) {
291  return exact ? p1 == p2 && p2 == p3 && p3 == p4 : p1.equalsWithinTolerance(p2) &&
292  p2.equalsWithinTolerance(p3) &&
293  p3.equalsWithinTolerance(p4);
294  }
295 
302  bool isLine(SkPoint line[2]) const;
303 
306  int countPoints() const;
307 
312  SkPoint getPoint(int index) const;
313 
320  int getPoints(SkPoint points[], int max) const;
321 
324  int countVerbs() const;
325 
333  int getVerbs(uint8_t verbs[], int max) const;
334 
336  void swap(SkPath& other);
337 
345  const SkRect& getBounds() const {
346  return fPathRef->getBounds();
347  }
348 
354  void updateBoundsCache() const {
355  // for now, just calling getBounds() is sufficient
356  this->getBounds();
357  }
358 
370  SkRect computeTightBounds() const;
371 
378  bool conservativelyContainsRect(const SkRect& rect) const;
379 
380  // Construction methods
381 
388  void incReserve(unsigned extraPtCount);
389 
395  void moveTo(SkScalar x, SkScalar y);
396 
401  void moveTo(const SkPoint& p) {
402  this->moveTo(p.fX, p.fY);
403  }
404 
414  void rMoveTo(SkScalar dx, SkScalar dy);
415 
423  void lineTo(SkScalar x, SkScalar y);
424 
431  void lineTo(const SkPoint& p) {
432  this->lineTo(p.fX, p.fY);
433  }
434 
444  void rLineTo(SkScalar dx, SkScalar dy);
445 
455  void quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2);
456 
464  void quadTo(const SkPoint& p1, const SkPoint& p2) {
465  this->quadTo(p1.fX, p1.fY, p2.fX, p2.fY);
466  }
467 
481  void rQuadTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2);
482 
483  void conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
484  SkScalar w);
485  void conicTo(const SkPoint& p1, const SkPoint& p2, SkScalar w) {
486  this->conicTo(p1.fX, p1.fY, p2.fX, p2.fY, w);
487  }
488  void rConicTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2,
489  SkScalar w);
490 
502  void cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
503  SkScalar x3, SkScalar y3);
504 
513  void cubicTo(const SkPoint& p1, const SkPoint& p2, const SkPoint& p3) {
514  this->cubicTo(p1.fX, p1.fY, p2.fX, p2.fY, p3.fX, p3.fY);
515  }
516 
534  void rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
535  SkScalar x3, SkScalar y3);
536 
548  void arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool forceMoveTo);
549 
553  void arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar radius);
554 
558  void arcTo(const SkPoint p1, const SkPoint p2, SkScalar radius) {
559  this->arcTo(p1.fX, p1.fY, p2.fX, p2.fY, radius);
560  }
561 
562  enum ArcSize {
567  };
568 
582  void arcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, ArcSize largeArc,
583  Direction sweep, SkScalar x, SkScalar y);
584 
585  void arcTo(const SkPoint r, SkScalar xAxisRotate, ArcSize largeArc, Direction sweep,
586  const SkPoint xy) {
587  this->arcTo(r.fX, r.fY, xAxisRotate, largeArc, sweep, xy.fX, xy.fY);
588  }
589 
603  void rArcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, ArcSize largeArc,
604  Direction sweep, SkScalar dx, SkScalar dy);
605 
609  void close();
610 
619  static bool IsInverseFillType(FillType fill) {
620  static_assert(0 == kWinding_FillType, "fill_type_mismatch");
621  static_assert(1 == kEvenOdd_FillType, "fill_type_mismatch");
622  static_assert(2 == kInverseWinding_FillType, "fill_type_mismatch");
623  static_assert(3 == kInverseEvenOdd_FillType, "fill_type_mismatch");
624  return (fill & 2) != 0;
625  }
626 
636  static_assert(0 == kWinding_FillType, "fill_type_mismatch");
637  static_assert(1 == kEvenOdd_FillType, "fill_type_mismatch");
638  static_assert(2 == kInverseWinding_FillType, "fill_type_mismatch");
639  static_assert(3 == kInverseEvenOdd_FillType, "fill_type_mismatch");
640  return (FillType)(fill & 1);
641  }
642 
647  static int ConvertConicToQuads(const SkPoint& p0, const SkPoint& p1, const SkPoint& p2,
648  SkScalar w, SkPoint pts[], int pow2);
649 
665  bool isRect(SkRect* rect, bool* isClosed = NULL, Direction* direction = NULL) const;
666 
679  bool isNestedFillRects(SkRect rect[2], Direction dirs[2] = NULL) const;
680 
688  void addRect(const SkRect& rect, Direction dir = kCW_Direction);
689 
703  void addRect(const SkRect& rect, Direction dir, unsigned start);
704 
720  void addRect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom,
721  Direction dir = kCW_Direction);
722 
731  void addOval(const SkRect& oval, Direction dir = kCW_Direction);
732 
750  void addOval(const SkRect& oval, Direction dir, unsigned start);
751 
764  void addCircle(SkScalar x, SkScalar y, SkScalar radius,
765  Direction dir = kCW_Direction);
766 
773  void addArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle);
774 
782  void addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
783  Direction dir = kCW_Direction);
784 
796  void addRoundRect(const SkRect& rect, const SkScalar radii[],
797  Direction dir = kCW_Direction);
798 
808  void addRRect(const SkRRect& rrect, Direction dir = kCW_Direction);
809 
825  void addRRect(const SkRRect& rrect, Direction dir, unsigned start);
826 
838  void addPoly(const SkPoint pts[], int count, bool close);
839 
840  enum AddPathMode {
850  kExtend_AddPathMode
851  };
852 
858  void addPath(const SkPath& src, SkScalar dx, SkScalar dy,
859  AddPathMode mode = kAppend_AddPathMode);
860 
863  void addPath(const SkPath& src, AddPathMode mode = kAppend_AddPathMode) {
864  SkMatrix m;
865  m.reset();
866  this->addPath(src, m, mode);
867  }
868 
874  void addPath(const SkPath& src, const SkMatrix& matrix, AddPathMode mode = kAppend_AddPathMode);
875 
879  void reverseAddPath(const SkPath& src);
880 
887  void offset(SkScalar dx, SkScalar dy, SkPath* dst) const;
888 
894  void offset(SkScalar dx, SkScalar dy) {
895  this->offset(dx, dy, this);
896  }
897 
904  void transform(const SkMatrix& matrix, SkPath* dst) const;
905 
910  void transform(const SkMatrix& matrix) {
911  this->transform(matrix, this);
912  }
913 
920  bool getLastPt(SkPoint* lastPt) const;
921 
928  void setLastPt(SkScalar x, SkScalar y);
929 
935  void setLastPt(const SkPoint& p) {
936  this->setLastPt(p.fX, p.fY);
937  }
938 
939  enum SegmentMask {
940  kLine_SegmentMask = 1 << 0,
941  kQuad_SegmentMask = 1 << 1,
942  kConic_SegmentMask = 1 << 2,
943  kCubic_SegmentMask = 1 << 3,
944  };
945 
951  uint32_t getSegmentMasks() const { return fPathRef->getSegmentMasks(); }
952 
953  enum Verb {
961  };
962 
972  class SK_API Iter {
973  public:
974  Iter();
975  Iter(const SkPath&, bool forceClose);
976 
977  void setPath(const SkPath&, bool forceClose);
978 
991  Verb next(SkPoint pts[4], bool doConsumeDegerates = true, bool exact = false) {
992  if (doConsumeDegerates) {
993  this->consumeDegenerateSegments(exact);
994  }
995  return this->doNext(pts);
996  }
997 
1002  SkScalar conicWeight() const { return *fConicWeights; }
1003 
1012  bool isCloseLine() const { return SkToBool(fCloseLine); }
1013 
1017  bool isClosedContour() const;
1018 
1019  private:
1020  const SkPoint* fPts;
1021  const uint8_t* fVerbs;
1022  const uint8_t* fVerbStop;
1023  const SkScalar* fConicWeights;
1024  SkPoint fMoveTo;
1025  SkPoint fLastPt;
1026  SkBool8 fForceClose;
1027  SkBool8 fNeedClose;
1028  SkBool8 fCloseLine;
1029  SkBool8 fSegmentState;
1030 
1031  inline const SkPoint& cons_moveTo();
1032  Verb autoClose(SkPoint pts[2]);
1033  void consumeDegenerateSegments(bool exact);
1034  Verb doNext(SkPoint pts[4]);
1035  };
1036 
1039  class SK_API RawIter {
1040  public:
1041  RawIter() {}
1042  RawIter(const SkPath& path) {
1043  setPath(path);
1044  }
1045 
1046  void setPath(const SkPath& path) {
1047  fRawIter.setPathRef(*path.fPathRef.get());
1048  }
1049 
1057  Verb next(SkPoint pts[4]) {
1058  return (Verb) fRawIter.next(pts);
1059  }
1060 
1065  Verb peek() const {
1066  return (Verb) fRawIter.peek();
1067  }
1068 
1069  SkScalar conicWeight() const {
1070  return fRawIter.conicWeight();
1071  }
1072 
1073  private:
1074  SkPathRef::Iter fRawIter;
1075  friend class SkPath;
1076  };
1077 
1082  bool contains(SkScalar x, SkScalar y) const;
1083 
1084  void dump(SkWStream* stream, bool forceClose, bool dumpAsHex) const;
1085  void dump() const;
1086  void dumpHex() const;
1087 
1092  size_t writeToMemory(void* buffer) const;
1101  size_t readFromMemory(const void* buffer, size_t length);
1102 
1107  uint32_t getGenerationID() const;
1108 
1109 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
1110  static const int kPathRefGenIDBitCnt = 30; // leave room for the fill type (skbug.com/1762)
1111 #else
1112  static const int kPathRefGenIDBitCnt = 32;
1113 #endif
1114 
1115  SkDEBUGCODE(void validate() const;)
1116  SkDEBUGCODE(void experimentalValidateRef() const { fPathRef->validate(); } )
1117 
1118 private:
1119  enum SerializationOffsets {
1120  // 1 free bit at 29
1121  kUnused1_SerializationShift = 28, // 1 free bit
1122  kDirection_SerializationShift = 26, // requires 2 bits
1123  kIsVolatile_SerializationShift = 25, // requires 1 bit
1124  // 1 free bit at 24
1125  kConvexity_SerializationShift = 16, // requires 8 bits
1126  kFillType_SerializationShift = 8, // requires 8 bits
1127  // low-8-bits are version
1128  };
1129 
1130  enum SerializationVersions {
1131  kPathPrivFirstDirection_Version = 1,
1132  kPathPrivLastMoveToIndex_Version = 2,
1133  kCurrent_Version = 2
1134  };
1135 
1136  sk_sp<SkPathRef> fPathRef;
1137  int fLastMoveToIndex;
1138  uint8_t fFillType;
1139  mutable uint8_t fConvexity;
1140  mutable SkAtomic<uint8_t, sk_memory_order_relaxed> fFirstDirection;// SkPathPriv::FirstDirection
1141  SkBool8 fIsVolatile;
1142 
1147  void resetFields();
1148 
1153  void copyFields(const SkPath& that);
1154 
1155  friend class Iter;
1156  friend class SkPathPriv;
1157  friend class SkPathStroker;
1158 
1159  /* Append, in reverse order, the first contour of path, ignoring path's
1160  last point. If no moveTo() call has been made for this contour, the
1161  first point is automatically set to (0,0).
1162  */
1163  void reversePathTo(const SkPath&);
1164 
1165  // called before we add points for lineTo, quadTo, cubicTo, checking to see
1166  // if we need to inject a leading moveTo first
1167  //
1168  // SkPath path; path.lineTo(...); <--- need a leading moveTo(0, 0)
1169  // SkPath path; ... path.close(); path.lineTo(...) <-- need a moveTo(previous moveTo)
1170  //
1171  inline void injectMoveToIfNeeded();
1172 
1173  inline bool hasOnlyMoveTos() const;
1174 
1175  Convexity internalGetConvexity() const;
1176 
1177  bool isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts,
1178  bool* isClosed, Direction* direction) const;
1179 
1180  // called by stroker to see if all points are equal and worthy of a cap
1181  // equivalent to a short-circuit version of getBounds().isEmpty()
1182  bool isZeroLength() const;
1183 
1187  bool hasComputedBounds() const {
1188  SkDEBUGCODE(this->validate();)
1189  return fPathRef->hasComputedBounds();
1190  }
1191 
1192 
1193  // 'rect' needs to be sorted
1194  void setBounds(const SkRect& rect) {
1195  SkPathRef::Editor ed(&fPathRef);
1196 
1197  ed.setBounds(rect);
1198  }
1199 
1200  void setPt(int index, SkScalar x, SkScalar y);
1201 
1202  friend class SkAutoPathBoundsUpdate;
1203  friend class SkAutoDisableOvalCheck;
1204  friend class SkAutoDisableDirectionCheck;
1205  friend class SkPathWriter;
1206  friend class SkOpBuilder;
1207  friend class SkBench_AddPathTest; // perf test reversePathTo
1208  friend class PathTest_Private; // unit test reversePathTo
1209  friend class ForceIsRRect_Private; // unit test isRRect
1210 };
1211 
1212 #endif
iter.next returns 3 points + iter.conicWeight()
Definition: SkPath.h:957
static bool IsQuadDegenerate(const SkPoint &p1, const SkPoint &p2, const SkPoint &p3, bool exact)
Test a quad for zero length.
Definition: SkPath.h:279
Verb next(SkPoint pts[4])
Return the next verb in this iteration of the path.
Definition: SkPath.h:1057
void setFillType(FillType ft)
Set the path's fill type.
Definition: SkPath.h:100
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:289
Specifies that "inside" is computed by an odd number of edge crossings.
Definition: SkPath.h:79
The SkRRect class represents a rounded rect with a potentially different radii for each corner...
Definition: SkRRect.h:47
The SkPath class encapsulates compound (multiple contour) geometric paths consisting of straight line...
Definition: SkPath.h:25
void arcTo(const SkPoint p1, const SkPoint p2, SkScalar radius)
Append a line and arc to the current path.
Definition: SkPath.h:558
Convexity getConvexity() const
Return the path's convexity, as stored in the path.
Definition: SkPath.h:125
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:1187
static FillType ConvertToNonInverseFillType(FillType fill)
Returns the equivalent non-inverted fill type to the given fill type.
Definition: SkPath.h:635
const SkRect & getBounds() const
Returns the bounds of the path's points.
Definition: SkPath.h:345
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:513
void offset(SkScalar dx, SkScalar dy)
Offset the path by (dx,dy), returning true on success.
Definition: SkPath.h:894
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:183
Convexity getConvexityOrUnknown() const
Return the currently cached value for convexity, even if that is set to kUnknown_Convexity.
Definition: SkPath.h:139
iter.next returns 3 points
Definition: SkPath.h:956
SkScalar conicWeight() const
Return the weight for the current conic.
Definition: SkPath.h:1002
FillType getFillType() const
Return the path's fill type.
Definition: SkPath.h:93
The SkMatrix class holds a 3x3 matrix for transforming coordinates.
Definition: SkMatrix.h:28
Verb peek() const
Return what the next verb will be, but do not visit the next segment.
Definition: SkPath.h:1065
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:1012
ArcSize
Definition: SkPath.h:562
iter.next returns 0 points
Definition: SkPath.h:959
void setIsVolatile(bool isVolatile)
Specify whether this path is volatile.
Definition: SkPath.h:263
uint8_t SkBool8
Meant to be a small version of bool, for storage purposes.
Definition: SkTypes.h:208
void transform(const SkMatrix &matrix)
Transform the points in this path by matrix.
Definition: SkPath.h:910
void setLastPt(const SkPoint &p)
Set the last point on the path.
Definition: SkPath.h:935
Direction
Definition: SkPath.h:27
void toggleInverseFillType()
Toggle between inverse and normal filltypes.
Definition: SkPath.h:111
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:354
iter.next returns 2 points
Definition: SkPath.h:955
#define SkToBool(cond)
Returns 0 or 1 based on the condition.
Definition: SkTypes.h:227
iter.next returns 1 point
Definition: SkPath.h:954
static bool IsInverseFillType(FillType fill)
Returns whether or not a fill type is inverted.
Definition: SkPath.h:619
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:75
the larger of the two possible SVG arcs.
Definition: SkPath.h:566
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:951
the smaller of the two possible SVG arcs.
Definition: SkPath.h:564
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:464
void addPath(const SkPath &src, AddPathMode mode=kAppend_AddPathMode)
Add a copy of src to the path.
Definition: SkPath.h:863
iter.next returns 4 points
Definition: SkPath.h:958
bool isEmpty() const
Returns true if the path is empty (contains no lines or curves)
Definition: SkPath.h:232
Source path contours are added as new contours.
Definition: SkPath.h:843
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:205
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:245
FillType
Definition: SkPath.h:71
Iterate through the verbs in the path, providing the associated points.
Definition: SkPath.h:1039
bool isVolatile() const
Returns true if the path is volatile (i.e.
Definition: SkPath.h:252
Definition: SkStream.h:182
Definition: SkRect.h:404
Verb next(SkPoint pts[4], bool doConsumeDegerates=true, bool exact=false)
Return the next verb in this iteration of the path.
Definition: SkPath.h:991
counter-clockwise direction for adding closed contours
Definition: SkPath.h:31
bool isConvex() const
Returns true if the path is flagged as being convex.
Definition: SkPath.h:156
void lineTo(const SkPoint &p)
Add a line from the last point to the specified point.
Definition: SkPath.h:431
AddPathMode
Definition: SkPath.h:840
clockwise direction for adding closed contours
Definition: SkPath.h:29
iter.next returns 0 points
Definition: SkPath.h:960
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:972
bool isInverseFillType() const
Returns true if the filltype is one of the Inverse variants.
Definition: SkPath.h:105
Verb
Definition: SkPath.h:953
void moveTo(const SkPoint &p)
Set the beginning of the next contour to the point.
Definition: SkPath.h:401
static bool IsLineDegenerate(const SkPoint &p1, const SkPoint &p2, bool exact)
Test a line for zero length.
Definition: SkPath.h:271
Same as Winding, but draws outside of the path, rather than inside.
Definition: SkPath.h:82