Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Unified Diff: include/core/SkPathRef.h

Issue 25787002: Move more of SkPath into SkPathRef (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: cleaned up Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/core/SkPath.h ('k') | src/core/SkPath.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: include/core/SkPathRef.h
===================================================================
--- include/core/SkPathRef.h (revision 11888)
+++ include/core/SkPathRef.h (working copy)
@@ -23,7 +23,7 @@
* Holds the path verbs and points. It is versioned by a generation ID. None of its public methods
* modify the contents. To modify or append to the verbs/points wrap the SkPathRef in an
* SkPathRef::Editor object. Installing the editor resets the generation ID. It also performs
- * copy-on-write if the SkPathRef is shared by multipls SkPaths. The caller passes the Editor's
+ * copy-on-write if the SkPathRef is shared by multiple SkPaths. The caller passes the Editor's
* constructor a SkAutoTUnref, which may be updated to point to a new SkPathRef after the editor's
* constructor returns.
*
@@ -71,21 +71,12 @@
SkPoint* growForConic(SkScalar w);
/**
- * Allocates space for additional verbs and points and returns pointers to the new verbs and
- * points. verbs will point one beyond the first new verb (index it using [~<i>]). pts points
- * at the first new point (indexed normally [<i>]).
+ * Allocates space for additional lines and returns a pointer to the new
+ * points. The return pointer points at the first new point (indexed normally [<i>]).
*/
- void grow(int newVerbs, int newPts, uint8_t** verbs, SkPoint** pts) {
- SkASSERT(NULL != verbs);
- SkASSERT(NULL != pts);
+ SkPoint* growForLines(int numLines) {
SkDEBUGCODE(fPathRef->validate();)
- int oldVerbCnt = fPathRef->fVerbCnt;
- int oldPointCnt = fPathRef->fPointCnt;
- SkASSERT(verbs && pts);
- fPathRef->grow(newVerbs, newPts);
- *verbs = fPathRef->fVerbs - oldVerbCnt;
- *pts = fPathRef->fPoints + oldPointCnt;
- SkDEBUGCODE(fPathRef->validate();)
+ return fPathRef->growForLines(numLines);
}
/**
@@ -95,11 +86,23 @@
void resetToSize(int newVerbCnt, int newPointCnt, int newConicCount) {
fPathRef->resetToSize(newVerbCnt, newPointCnt, newConicCount);
}
+
/**
* Gets the path ref that is wrapped in the Editor.
*/
SkPathRef* pathRef() { return fPathRef; }
+ void setDirection(int /* SkPath::Direction */ dir) { fPathRef->setDirection(dir); }
+
+ void setIsOval(bool isOval) { fPathRef->setIsOval(isOval); }
+
+ void setConvexity(int /*SkPath::Convexity*/ convexity) {
+ fPathRef->setConvexity(convexity);
+ }
+
+ // 'rect' needs to be sorted
+ void setBounds(const SkRect& rect) { fPathRef->setBounds(rect); }
+
private:
SkPathRef* fPathRef;
};
@@ -117,7 +120,51 @@
return SkRef(gEmptyPathRef);
}
+ uint8_t /*SkPath::Direction*/ getDirection() const { return fDirection; }
+
/**
+ * Tries to quickly compute the direction of the first non-degenerate
+ * contour. If it can be computed, return true and set dir to that
+ * direction. If it cannot be (quickly) determined, return false and ignore
+ * the dir parameter. If the direction was determined, it is cached to make
+ * subsequent calls return quickly.
+ */
+ bool cheapComputeDirection(int* dir) const;
+
+ /**
+ * Return the path's convexity, as stored in the path. If it is currently unknown,
+ * then this function will attempt to compute the convexity (and cache the result).
+ */
+ int /*SkPath::Convexity*/ getConvexity() const;
+
+ /**
+ * Return the currently cached value for convexity, even if that is set to
+ * kUnknown_Convexity. Note: getConvexity() will automatically call
+ * ComputeConvexity and cache its return value if the current setting is
+ * kUnknown.
+ */
+ int /*SkPath::Convexity*/ getConvexityOrUnknown() const {
+ return fConvexity;
+ }
+
+ /** Returns true if the path is an oval.
+ *
+ * @param rect returns the bounding rect of this oval. It's a circle
+ * if the height and width are the same.
+ *
+ * @return true if this path is an oval.
+ * Tracking whether a path is an oval is considered an
+ * optimization for performance and so some paths that are in
+ * fact ovals can report false.
+ */
+ bool isOval(SkRect* rect) const {
+ if (fIsOval && NULL != rect) {
+ *rect = this->getBounds();
+ }
+ return SkToBool(fIsOval);
+ }
+
+ /**
* Returns true if all of the points in this path are finite, meaning there
* are no infinities and no NaNs.
*/
@@ -128,6 +175,13 @@
return SkToBool(fIsFinite);
}
+ /**
+ * Returns a mask, where each bit corresponding to a SegmentMask is
+ * set if the path contains 1 or more segments of that type.
+ * Returns 0 for an empty path (no segments).
+ */
+ uint32_t getSegmentMasks() const { return fSegmentMask; }
+
bool hasComputedBounds() const {
return !fBoundsIsDirty;
}
@@ -144,13 +198,6 @@
return fBounds;
}
- void setBounds(const SkRect& rect) {
- SkASSERT(rect.fLeft <= rect.fRight && rect.fTop <= rect.fBottom);
- fBounds = rect;
- fBoundsIsDirty = false;
- fIsFinite = fBounds.isFinite();
- }
-
/**
* Transforms a path ref by a matrix, allocating a new one only if necessary.
*/
@@ -213,7 +260,7 @@
/**
* Convenience methods for getting to a verb or point by index.
*/
- uint8_t atVerb(int index) {
+ uint8_t atVerb(int index) const {
SkASSERT((unsigned) index < (unsigned) fVerbCnt);
return this->verbs()[~index];
}
@@ -227,40 +274,58 @@
/**
* Writes the path points and verbs to a buffer.
*/
- void writeToBuffer(SkWBuffer* buffer);
+ void writeToBuffer(SkWBuffer* buffer) const;
/**
* Gets the number of bytes that would be written in writeBuffer()
*/
- uint32_t writeSize();
+ uint32_t writeSize() const;
private:
enum SerializationOffsets {
+ kDirection_SerializationShift = 26, // requires 2 bits
kIsFinite_SerializationShift = 25, // requires 1 bit
+ kIsOval_SerializationShift = 24, // requires 1 bit
+ kConvexity_SerializationShift = 16, // requires 8 bits
+ // FillType (in SkPath) takes up 8
+ kSegmentMask_SerializationShift = 0 // requires 4 bits
};
- SkPathRef() {
- fBoundsIsDirty = true; // this also invalidates fIsFinite
- fPointCnt = 0;
- fVerbCnt = 0;
- fVerbs = NULL;
- fPoints = NULL;
- fFreeSpace = 0;
- fGenerationID = kEmptyGenID;
- SkDEBUGCODE(fEditorsAttached = 0;)
- SkDEBUGCODE(this->validate();)
+ // flag to require a moveTo if we begin with something else, like lineTo etc.
+ static const int kINITIAL_LASTMOVETOINDEX_VALUE = ~0;
+
+ SkPathRef();
+
+ /**
+ * Store a convexity setting in the path. There is no automatic check to
+ * see if this value actually agrees with the return value that would be
+ * computed by getConvexity().
+ *
+ * Note: even if this is set to a "known" value, if the path is later
+ * changed (e.g. lineTo(), addRect(), etc.) then the cached value will be
+ * reset to kUnknown_Convexity.
+ */
+ void setConvexity(int /*SkPath::Convexity*/ convexity) {
+ fConvexity = convexity;
}
+ // 'rect' needs to be sorted
+ void setBounds(const SkRect& rect) {
+ SkASSERT(rect.fLeft <= rect.fRight && rect.fTop <= rect.fBottom);
+ fBounds = rect;
+ fBoundsIsDirty = false;
+ fIsFinite = fBounds.isFinite();
+ }
+
void copy(const SkPathRef& ref, int additionalReserveVerbs, int additionalReservePoints);
// Return true if the computed bounds are finite.
- static bool ComputePtBounds(SkRect* bounds, const SkPathRef& ref) {
- int count = ref.countPoints();
+ static bool ComputePtBounds(SkRect* bounds, const SkPoint* points, int count) {
if (count <= 1) { // we ignore just 1 point (moveto)
bounds->setEmpty();
- return count ? ref.points()->isFinite() : true;
+ return count ? points->isFinite() : true;
} else {
- return bounds->setBoundsCheck(ref.points(), count);
+ return bounds->setBoundsCheck(points, count);
}
}
@@ -269,7 +334,7 @@
SkDEBUGCODE(this->validate();)
SkASSERT(fBoundsIsDirty);
- fIsFinite = ComputePtBounds(&fBounds, *this);
+ fIsFinite = ComputePtBounds(&fBounds, this->points(), this->countPoints());
fBoundsIsDirty = false;
}
@@ -284,58 +349,24 @@
/** Resets the path ref with verbCount verbs and pointCount points, all uninitialized. Also
* allocates space for reserveVerb additional verbs and reservePoints additional points.*/
void resetToSize(int verbCount, int pointCount, int conicCount,
- int reserveVerbs = 0, int reservePoints = 0) {
- SkDEBUGCODE(this->validate();)
- fBoundsIsDirty = true; // this also invalidates fIsFinite
- fGenerationID = 0;
+ int reserveVerbs = 0, int reservePoints = 0);
- size_t newSize = sizeof(uint8_t) * verbCount + sizeof(SkPoint) * pointCount;
- size_t newReserve = sizeof(uint8_t) * reserveVerbs + sizeof(SkPoint) * reservePoints;
- size_t minSize = newSize + newReserve;
+ // This method assumes space has already been allocated for the new
+ // verb and point.
+ void injectMove();
- ptrdiff_t sizeDelta = this->currSize() - minSize;
-
- if (sizeDelta < 0 || static_cast<size_t>(sizeDelta) >= 3 * minSize) {
- sk_free(fPoints);
- fPoints = NULL;
- fVerbs = NULL;
- fFreeSpace = 0;
- fVerbCnt = 0;
- fPointCnt = 0;
- this->makeSpace(minSize);
- fVerbCnt = verbCount;
- fPointCnt = pointCount;
- fFreeSpace -= newSize;
- } else {
- fPointCnt = pointCount;
- fVerbCnt = verbCount;
- fFreeSpace = this->currSize() - minSize;
- }
- fConicWeights.setCount(conicCount);
- SkDEBUGCODE(this->validate();)
- }
-
/**
- * Increases the verb count by newVerbs and the point count be newPoints. New verbs and points
- * are uninitialized.
+ * Increases the verb and point count by numLines. The new points
+ * are uninitialized. All the new verbs are set to kLine_SegmentMask.
*/
- void grow(int newVerbs, int newPoints) {
- SkDEBUGCODE(this->validate();)
- size_t space = newVerbs * sizeof(uint8_t) + newPoints * sizeof (SkPoint);
- this->makeSpace(space);
- fVerbCnt += newVerbs;
- fPointCnt += newPoints;
- fFreeSpace -= space;
- fBoundsIsDirty = true; // this also invalidates fIsFinite
- SkDEBUGCODE(this->validate();)
- }
+ SkPoint* growForLines(int numLines);
/**
* Increases the verb count 1, records the new verb, and creates room for the requisite number
* of additional points. A pointer to the first point is returned. Any new points are
* uninitialized.
*/
- SkPoint* growForVerb(int /*SkPath::Verb*/ verb);
+ SkPoint* growForVerb(int /* SkPath::Verb */ verb);
/**
* Ensures that the free space available in the path ref is >= size. The verb and point counts
@@ -397,13 +428,24 @@
SkDEBUGCODE(void validate() const;)
+ int internalGetConvexity() const;
+
+ void setIsOval(bool isOval) { fIsOval = isOval; }
+ void setDirection(int direction) { fDirection = direction; }
+
enum {
kMinSize = 256,
};
mutable SkRect fBounds;
+ int fLastMoveToIndex;
+
+ uint8_t fSegmentMask;
mutable uint8_t fBoundsIsDirty;
+ mutable uint8_t fConvexity;
+ mutable uint8_t fDirection;
mutable SkBool8 fIsFinite; // only meaningful if bounds are valid
+ mutable SkBool8 fIsOval;
SkPoint* fPoints; // points to begining of the allocation
uint8_t* fVerbs; // points just past the end of the allocation (verbs grow backwards)
« no previous file with comments | « include/core/SkPath.h ('k') | src/core/SkPath.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698