SkPath::rewind needs to have same reset as SkPath::reset.
R=caryclark@google.com, reed@google.com
Review URL: https://codereview.chromium.org/17432003
git-svn-id: http://skia.googlecode.com/svn/trunk@9718 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkPath.h b/include/core/SkPath.h
index c5e50d7..85cd7b7 100644
--- a/include/core/SkPath.h
+++ b/include/core/SkPath.h
@@ -984,6 +984,19 @@
const SkPath* fSourcePath;
#endif
+ /** Resets all fields other than fPathRef to their initial 'empty' values.
+ * Assumes the caller has already emptied fPathRef.
+ * On Android increments fGenerationID without reseting it.
+ */
+ void resetFields();
+
+ /** Sets all fields other than fPathRef to the values in 'that'.
+ * Assumes the caller has already set fPathRef.
+ * On Android increments fGenerationID without copying it.
+ * On Android sets fSourcePath to NULL.
+ */
+ void copyFields(const SkPath& that);
+
// called, if dirty, by getBounds()
void computeBounds() const;
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 8e9be85..e997b80 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -219,68 +219,75 @@
#else
: fPathRef(SkPathRef::CreateEmpty())
#endif
- , fFillType(kWinding_FillType)
- , fBoundsIsDirty(true) {
+#ifdef SK_BUILD_FOR_ANDROID
+ , fGenerationID(0)
+#endif
+{
+ this->resetFields();
+}
+
+void SkPath::resetFields() {
+ //fPathRef is assumed to have been emptied by the caller.
+ fLastMoveToIndex = INITIAL_LASTMOVETOINDEX_VALUE;
+ fFillType = kWinding_FillType;
+ fSegmentMask = 0;
+ fBoundsIsDirty = true;
fConvexity = kUnknown_Convexity;
fDirection = kUnknown_Direction;
- fSegmentMask = 0;
- fLastMoveToIndex = INITIAL_LASTMOVETOINDEX_VALUE;
+ fIsFinite = false;
fIsOval = false;
- fIsFinite = false; // gets computed when we know our bounds
#ifdef SK_BUILD_FOR_ANDROID
- fGenerationID = 0;
+ GEN_ID_INC;
fSourcePath = NULL;
#endif
}
-SkPath::SkPath(const SkPath& src)
+SkPath::SkPath(const SkPath& that)
#if SK_DEBUG_PATH_REF
: fPathRef(this)
+#else
+ : fPathRef(SkRef(that.fPathRef.get()))
+#endif
+#ifdef SK_BUILD_FOR_ANDROID
+ , fGenerationID(0)
#endif
{
- SkDEBUGCODE(src.validate();)
- src.fPathRef.get()->ref();
- fPathRef.reset(src.fPathRef.get());
- fBounds = src.fBounds;
- fFillType = src.fFillType;
- fBoundsIsDirty = src.fBoundsIsDirty;
- fConvexity = src.fConvexity;
- fDirection = src.fDirection;
- fIsFinite = src.fIsFinite;
- fSegmentMask = src.fSegmentMask;
- fLastMoveToIndex = src.fLastMoveToIndex;
- fIsOval = src.fIsOval;
-#ifdef SK_BUILD_FOR_ANDROID
- fGenerationID = src.fGenerationID;
- fSourcePath = NULL;
-#endif
+ this->copyFields(that);
+ SkDEBUGCODE(that.validate();)
}
SkPath::~SkPath() {
SkDEBUGCODE(this->validate();)
}
-SkPath& SkPath::operator=(const SkPath& src) {
- SkDEBUGCODE(src.validate();)
+SkPath& SkPath::operator=(const SkPath& that) {
+ SkDEBUGCODE(that.validate();)
- if (this != &src) {
- src.fPathRef.get()->ref();
- fPathRef.reset(src.fPathRef.get());
- fBounds = src.fBounds;
- fFillType = src.fFillType;
- fBoundsIsDirty = src.fBoundsIsDirty;
- fConvexity = src.fConvexity;
- fDirection = src.fDirection;
- fIsFinite = src.fIsFinite;
- fSegmentMask = src.fSegmentMask;
- fLastMoveToIndex = src.fLastMoveToIndex;
- fIsOval = src.fIsOval;
- GEN_ID_INC;
+ if (this != &that) {
+ fPathRef.reset(SkRef(that.fPathRef.get()));
+ this->copyFields(that);
}
SkDEBUGCODE(this->validate();)
return *this;
}
+void SkPath::copyFields(const SkPath& that) {
+ //fPathRef is assumed to have been set by the caller.
+ fBounds = that.fBounds;
+ fLastMoveToIndex = that.fLastMoveToIndex;
+ fFillType = that.fFillType;
+ fSegmentMask = that.fSegmentMask;
+ fBoundsIsDirty = that.fBoundsIsDirty;
+ fConvexity = that.fConvexity;
+ fDirection = that.fDirection;
+ fIsFinite = that.fIsFinite;
+ fIsOval = that.fIsOval;
+#ifdef SK_BUILD_FOR_ANDROID
+ GEN_ID_INC;
+ fSourcePath = NULL;
+#endif
+}
+
SK_API bool operator==(const SkPath& a, const SkPath& b) {
// note: don't need to look at isConvex or bounds, since just comparing the
// raw data is sufficient.
@@ -294,21 +301,22 @@
*a.fPathRef.get() == *b.fPathRef.get());
}
-void SkPath::swap(SkPath& other) {
- SkASSERT(&other != NULL);
+void SkPath::swap(SkPath& that) {
+ SkASSERT(&that != NULL);
- if (this != &other) {
- SkTSwap<SkRect>(fBounds, other.fBounds);
- fPathRef.swap(&other.fPathRef);
- SkTSwap<uint8_t>(fFillType, other.fFillType);
- SkTSwap<uint8_t>(fBoundsIsDirty, other.fBoundsIsDirty);
- SkTSwap<uint8_t>(fConvexity, other.fConvexity);
- SkTSwap<uint8_t>(fDirection, other.fDirection);
- SkTSwap<uint8_t>(fSegmentMask, other.fSegmentMask);
- SkTSwap<int>(fLastMoveToIndex, other.fLastMoveToIndex);
- SkTSwap<SkBool8>(fIsOval, other.fIsOval);
- SkTSwap<SkBool8>(fIsFinite, other.fIsFinite);
+ if (this != &that) {
+ fPathRef.swap(&that.fPathRef);
+ SkTSwap<SkRect>(fBounds, that.fBounds);
+ SkTSwap<int>(fLastMoveToIndex, that.fLastMoveToIndex);
+ SkTSwap<uint8_t>(fFillType, that.fFillType);
+ SkTSwap<uint8_t>(fSegmentMask, that.fSegmentMask);
+ SkTSwap<uint8_t>(fBoundsIsDirty, that.fBoundsIsDirty);
+ SkTSwap<uint8_t>(fConvexity, that.fConvexity);
+ SkTSwap<uint8_t>(fDirection, that.fDirection);
+ SkTSwap<SkBool8>(fIsFinite, that.fIsFinite);
+ SkTSwap<SkBool8>(fIsOval, that.fIsOval);
GEN_ID_INC;
+ GEN_ID_PTR_INC(&that);
}
}
@@ -411,25 +419,14 @@
SkDEBUGCODE(this->validate();)
fPathRef.reset(SkPathRef::CreateEmpty());
- GEN_ID_INC;
- fBoundsIsDirty = true;
- fConvexity = kUnknown_Convexity;
- fDirection = kUnknown_Direction;
- fSegmentMask = 0;
- fLastMoveToIndex = INITIAL_LASTMOVETOINDEX_VALUE;
- fIsOval = false;
+ this->resetFields();
}
void SkPath::rewind() {
SkDEBUGCODE(this->validate();)
SkPathRef::Rewind(&fPathRef);
- GEN_ID_INC;
- fConvexity = kUnknown_Convexity;
- fBoundsIsDirty = true;
- fSegmentMask = 0;
- fLastMoveToIndex = INITIAL_LASTMOVETOINDEX_VALUE;
- fIsOval = false;
+ this->resetFields();
}
bool SkPath::isEmpty() const {
diff --git a/src/pathops/SkPathOpsSimplify.cpp b/src/pathops/SkPathOpsSimplify.cpp
index f89c4af..fd40c38 100644
--- a/src/pathops/SkPathOpsSimplify.cpp
+++ b/src/pathops/SkPathOpsSimplify.cpp
@@ -164,8 +164,8 @@
SkTArray<SkOpContour*, true> contourList;
MakeContourList(contours, contourList, false, false);
SkOpContour** currentPtr = contourList.begin();
- result->setFillType(fillType);
result->reset();
+ result->setFillType(fillType);
if (!currentPtr) {
return true;
}
diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp
index 0f59aeb..6c8f83e 100644
--- a/tests/PathTest.cpp
+++ b/tests/PathTest.cpp
@@ -2327,11 +2327,8 @@
REPORTER_ASSERT(reporter, path.isOval(NULL));
}
-static void TestPath(skiatest::Reporter* reporter) {
- SkTSize<SkScalar>::Make(3,4);
-
- SkPath p, p2;
- SkRect bounds, bounds2;
+static void test_empty(skiatest::Reporter* reporter, const SkPath& p) {
+ SkPath empty;
REPORTER_ASSERT(reporter, p.isEmpty());
REPORTER_ASSERT(reporter, 0 == p.countPoints());
@@ -2340,8 +2337,16 @@
REPORTER_ASSERT(reporter, p.isConvex());
REPORTER_ASSERT(reporter, p.getFillType() == SkPath::kWinding_FillType);
REPORTER_ASSERT(reporter, !p.isInverseFillType());
- REPORTER_ASSERT(reporter, p == p2);
- REPORTER_ASSERT(reporter, !(p != p2));
+ REPORTER_ASSERT(reporter, p == empty);
+ REPORTER_ASSERT(reporter, !(p != empty));
+}
+
+static void TestPath(skiatest::Reporter* reporter) {
+ SkTSize<SkScalar>::Make(3,4);
+
+ SkPath p, empty;
+ SkRect bounds, bounds2;
+ test_empty(reporter, p);
REPORTER_ASSERT(reporter, p.getBounds().isEmpty());
@@ -2354,22 +2359,23 @@
REPORTER_ASSERT(reporter, !p.isEmpty());
p.reset();
- REPORTER_ASSERT(reporter, 0 == p.getSegmentMasks());
- REPORTER_ASSERT(reporter, p.isEmpty());
+ test_empty(reporter, p);
p.addOval(bounds);
check_convex_bounds(reporter, p, bounds);
REPORTER_ASSERT(reporter, !p.isEmpty());
- p.reset();
+ p.rewind();
+ test_empty(reporter, p);
+
p.addRect(bounds);
check_convex_bounds(reporter, p, bounds);
// we have only lines
REPORTER_ASSERT(reporter, SkPath::kLine_SegmentMask == p.getSegmentMasks());
REPORTER_ASSERT(reporter, !p.isEmpty());
- REPORTER_ASSERT(reporter, p != p2);
- REPORTER_ASSERT(reporter, !(p == p2));
+ REPORTER_ASSERT(reporter, p != empty);
+ REPORTER_ASSERT(reporter, !(p == empty));
// do getPoints and getVerbs return the right result
REPORTER_ASSERT(reporter, p.getPoints(NULL, 0) == 4);