diff options
Diffstat (limited to 'include/core')
-rw-r--r-- | include/core/SkPath.h | 36 | ||||
-rw-r--r-- | include/core/SkPathRef.h | 65 |
2 files changed, 86 insertions, 15 deletions
diff --git a/include/core/SkPath.h b/include/core/SkPath.h index 3ff0af15a2..3c68ff7d84 100644 --- a/include/core/SkPath.h +++ b/include/core/SkPath.h @@ -154,6 +154,17 @@ public: */ bool isOval(SkRect* rect) const { return fPathRef->isOval(rect); } + /** Returns true if the path is a round rect. + * + * @param rrect Returns the bounding rect and radii of this round rect. + * + * @return true if this path is a round rect. + * Tracking whether a path is a round rect is considered an + * optimization for performance and so some paths that are in + * fact round rects can report false. + */ + bool isRRect(SkRRect* rrect) const { return fPathRef->isRRect(rrect); } + /** Clear any lines and curves from the path, making it empty. This frees up internal storage associated with those segments. On Android, does not change fSourcePath. @@ -918,10 +929,14 @@ public: */ class SK_API RawIter { public: - RawIter(); - RawIter(const SkPath&); + RawIter() {} + RawIter(const SkPath& path) { + setPath(path); + } - void setPath(const SkPath&); + void setPath(const SkPath& path) { + fRawIter.setPathRef(*path.fPathRef.get()); + } /** Return the next verb in this iteration of the path. When all segments have been visited, return kDone_Verb. @@ -930,15 +945,17 @@ public: This must not be NULL. @return The verb for the current segment */ - Verb next(SkPoint pts[4]); + Verb next(SkPoint pts[4]) { + return (Verb) fRawIter.next(pts); + } - SkScalar conicWeight() const { return *fConicWeights; } + SkScalar conicWeight() const { + return fRawIter.conicWeight(); + } private: - const SkPoint* fPts; - const uint8_t* fVerbs; - const uint8_t* fVerbStop; - const SkScalar* fConicWeights; + SkPathRef::Iter fRawIter; + friend class SkPath; }; /** @@ -1066,6 +1083,7 @@ private: friend class SkAutoDisableDirectionCheck; friend class SkBench_AddPathTest; // perf test reversePathTo friend class PathTest_Private; // unit test reversePathTo + friend class ForceIsRRect_Private; // unit test isRRect }; #endif diff --git a/include/core/SkPathRef.h b/include/core/SkPathRef.h index c09f6e87e4..86f55c9bca 100644 --- a/include/core/SkPathRef.h +++ b/include/core/SkPathRef.h @@ -11,6 +11,7 @@ #include "SkMatrix.h" #include "SkPoint.h" +#include "SkRRect.h" #include "SkRect.h" #include "SkRefCnt.h" #include "SkTDArray.h" @@ -100,12 +101,39 @@ public: void setIsOval(bool isOval) { fPathRef->setIsOval(isOval); } + void setIsRRect(bool isRRect) { fPathRef->setIsRRect(isRRect); } + void setBounds(const SkRect& rect) { fPathRef->setBounds(rect); } private: SkPathRef* fPathRef; }; + class SK_API Iter { + public: + Iter(); + Iter(const SkPathRef&); + + void setPathRef(const SkPathRef&); + + /** Return the next verb in this iteration of the path. When all + segments have been visited, return kDone_Verb. + + @param pts The points representing the current verb and/or segment + This must not be NULL. + @return The verb for the current segment + */ + uint8_t next(SkPoint pts[4]); + + SkScalar conicWeight() const { return *fConicWeights; } + + private: + const SkPoint* fPts; + const uint8_t* fVerbs; + const uint8_t* fVerbStop; + const SkScalar* fConicWeights; + }; + public: /** * Gets a path ref with no verbs or points. @@ -142,12 +170,20 @@ public: */ bool isOval(SkRect* rect) const { if (fIsOval && rect) { - *rect = getBounds(); + *rect = this->getBounds(); } return SkToBool(fIsOval); } + bool isRRect(SkRRect* rrect) const { + if (fIsRRect && rrect) { + *rrect = this->getRRect(); + } + return SkToBool(fIsRRect); + } + + bool hasComputedBounds() const { return !fBoundsIsDirty; } @@ -164,6 +200,8 @@ public: return fBounds; } + SkRRect getRRect() const; + /** * Transforms a path ref by a matrix, allocating a new one only if necessary. */ @@ -250,6 +288,7 @@ public: private: enum SerializationOffsets { + kIsRRect_SerializationShift = 26, // requires 1 bit kIsFinite_SerializationShift = 25, // requires 1 bit kIsOval_SerializationShift = 24, // requires 1 bit kSegmentMask_SerializationShift = 0 // requires 4 bits @@ -265,6 +304,7 @@ private: fGenerationID = kEmptyGenID; fSegmentMask = 0; fIsOval = false; + fIsRRect = false; SkDEBUGCODE(fEditorsAttached = 0;) SkDEBUGCODE(this->validate();) } @@ -312,6 +352,7 @@ private: fSegmentMask = 0; fIsOval = false; + fIsRRect = false; size_t newSize = sizeof(uint8_t) * verbCount + sizeof(SkPoint) * pointCount; size_t newReserve = sizeof(uint8_t) * reserveVerbs + sizeof(SkPoint) * reservePoints; @@ -411,9 +452,18 @@ private: void setIsOval(bool isOval) { fIsOval = isOval; } + void setIsRRect(bool isRRect) { fIsRRect = isRRect; } + + // called only by the editor. Note that this is not a const function. SkPoint* getPoints() { SkDEBUGCODE(this->validate();) fIsOval = false; + fIsRRect = false; + return fPoints; + } + + const SkPoint* getPoints() const { + SkDEBUGCODE(this->validate();) return fPoints; } @@ -424,11 +474,6 @@ private: }; mutable SkRect fBounds; - mutable uint8_t fBoundsIsDirty; - mutable SkBool8 fIsFinite; // only meaningful if bounds are valid - - SkBool8 fIsOval; - uint8_t fSegmentMask; SkPoint* fPoints; // points to begining of the allocation uint8_t* fVerbs; // points just past the end of the allocation (verbs grow backwards) @@ -445,7 +490,15 @@ private: SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owned + mutable uint8_t fBoundsIsDirty; + mutable SkBool8 fIsFinite; // only meaningful if bounds are valid + + SkBool8 fIsOval; + SkBool8 fIsRRect; + uint8_t fSegmentMask; + friend class PathRefTest_Private; + friend class ForceIsRRect_Private; // unit test isRRect typedef SkRefCnt INHERITED; }; |