Index: src/core/SkPath.cpp |
=================================================================== |
--- src/core/SkPath.cpp (revision 13420) |
+++ src/core/SkPath.cpp (working copy) |
@@ -122,6 +122,9 @@ |
//////////////////////////////////////////////////////////////////////////// |
+// flag to require a moveTo if we begin with something else, like lineTo etc. |
+#define INITIAL_LASTMOVETOINDEX_VALUE ~0 |
+ |
SkPath::SkPath() |
: fPathRef(SkPathRef::CreateEmpty()) |
#ifdef SK_BUILD_FOR_ANDROID |
@@ -133,6 +136,7 @@ |
void SkPath::resetFields() { |
//fPathRef is assumed to have been emptied by the caller. |
+ fLastMoveToIndex = INITIAL_LASTMOVETOINDEX_VALUE; |
fFillType = kWinding_FillType; |
fConvexity = kUnknown_Convexity; |
fDirection = kUnknown_Direction; |
@@ -170,6 +174,7 @@ |
void SkPath::copyFields(const SkPath& that) { |
//fPathRef is assumed to have been set by the caller. |
+ fLastMoveToIndex = that.fLastMoveToIndex; |
fFillType = that.fFillType; |
fConvexity = that.fConvexity; |
fDirection = that.fDirection; |
@@ -187,6 +192,7 @@ |
if (this != &that) { |
fPathRef.swap(&that.fPathRef); |
+ SkTSwap<int>(fLastMoveToIndex, that.fLastMoveToIndex); |
SkTSwap<uint8_t>(fFillType, that.fFillType); |
SkTSwap<uint8_t>(fConvexity, that.fConvexity); |
SkTSwap<uint8_t>(fDirection, that.fDirection); |
@@ -661,6 +667,9 @@ |
SkPathRef::Editor ed(&fPathRef); |
+ // remember our index |
+ fLastMoveToIndex = fPathRef->countPoints(); |
+ |
ed.growForVerb(kMove_Verb)->set(x, y); |
} |
@@ -670,11 +679,26 @@ |
this->moveTo(pt.fX + x, pt.fY + y); |
} |
+void SkPath::injectMoveToIfNeeded() { |
+ if (fLastMoveToIndex < 0) { |
+ SkScalar x, y; |
+ if (fPathRef->countVerbs() == 0) { |
+ x = y = 0; |
+ } else { |
+ const SkPoint& pt = fPathRef->atPoint(~fLastMoveToIndex); |
+ x = pt.fX; |
+ y = pt.fY; |
+ } |
+ this->moveTo(x, y); |
+ } |
+} |
+ |
void SkPath::lineTo(SkScalar x, SkScalar y) { |
SkDEBUGCODE(this->validate();) |
+ this->injectMoveToIfNeeded(); |
+ |
SkPathRef::Editor ed(&fPathRef); |
- ed.injectMoveToIfNeeded(); |
ed.growForVerb(kLine_Verb)->set(x, y); |
DIRTY_AFTER_EDIT; |
@@ -690,8 +714,9 @@ |
void SkPath::quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) { |
SkDEBUGCODE(this->validate();) |
+ this->injectMoveToIfNeeded(); |
+ |
SkPathRef::Editor ed(&fPathRef); |
- ed.injectMoveToIfNeeded(); |
SkPoint* pts = ed.growForVerb(kQuad_Verb); |
pts[0].set(x1, y1); |
pts[1].set(x2, y2); |
@@ -719,8 +744,9 @@ |
} else { |
SkDEBUGCODE(this->validate();) |
+ this->injectMoveToIfNeeded(); |
+ |
SkPathRef::Editor ed(&fPathRef); |
- ed.injectMoveToIfNeeded(); |
SkPoint* pts = ed.growForVerb(kConic_Verb, w); |
pts[0].set(x1, y1); |
pts[1].set(x2, y2); |
@@ -741,8 +767,9 @@ |
SkScalar x3, SkScalar y3) { |
SkDEBUGCODE(this->validate();) |
+ this->injectMoveToIfNeeded(); |
+ |
SkPathRef::Editor ed(&fPathRef); |
- ed.injectMoveToIfNeeded(); |
SkPoint* pts = ed.growForVerb(kCubic_Verb); |
pts[0].set(x1, y1); |
pts[1].set(x2, y2); |
@@ -783,6 +810,15 @@ |
break; |
} |
} |
+ |
+ // signal that we need a moveTo to follow us (unless we're done) |
+#if 0 |
+ if (fLastMoveToIndex >= 0) { |
+ fLastMoveToIndex = ~fLastMoveToIndex; |
+ } |
+#else |
+ fLastMoveToIndex ^= ~fLastMoveToIndex >> (8 * sizeof(fLastMoveToIndex) - 1); |
+#endif |
} |
/////////////////////////////////////////////////////////////////////////////// |
@@ -824,6 +860,8 @@ |
return; |
} |
+ fLastMoveToIndex = fPathRef->countPoints(); |
+ |
// +close makes room for the extra kClose_Verb |
SkPathRef::Editor ed(&fPathRef, count+close, count); |
@@ -1320,6 +1358,8 @@ |
SkDEBUGCODE(this->validate();) |
SkASSERT(count & 1); |
+ fLastMoveToIndex = fPathRef->countPoints(); |
+ |
SkPathRef::Editor ed(&fPathRef, 1+(count-1)/2, count); |
ed.growForVerb(kMove_Verb)->set(pts[0].fX, pts[0].fY); |