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);