aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkPath.h5
-rw-r--r--src/core/SkPath.cpp6
-rw-r--r--src/core/SkStroke.cpp12
3 files changed, 12 insertions, 11 deletions
diff --git a/include/core/SkPath.h b/include/core/SkPath.h
index b8c921f3ee..b36fa65a6d 100644
--- a/include/core/SkPath.h
+++ b/include/core/SkPath.h
@@ -1177,9 +1177,8 @@ private:
bool isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts,
bool* isClosed, Direction* direction) const;
- // called by stroker to see if all points are equal and worthy of a cap
- // equivalent to a short-circuit version of getBounds().isEmpty()
- bool isZeroLength() const;
+ // called by stroker to see if all points (in the last contour) are equal and worthy of a cap
+ bool isZeroLengthSincePoint(int startPtIndex) const;
/** Returns if the path can return a bound at no cost (true) or will have to
perform some computation (false).
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index f4c8e8b7c4..2be3251401 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -1192,12 +1192,12 @@ bool SkPath::hasOnlyMoveTos() const {
return true;
}
-bool SkPath::isZeroLength() const {
- int count = fPathRef->countPoints();
+bool SkPath::isZeroLengthSincePoint(int startPtIndex) const {
+ int count = fPathRef->countPoints() - startPtIndex;
if (count < 2) {
return true;
}
- const SkPoint* pts = fPathRef.get()->points();
+ const SkPoint* pts = fPathRef.get()->points() + startPtIndex;
const SkPoint& first = *pts;
for (int index = 1; index < count; ++index) {
if (first != pts[index]) {
diff --git a/src/core/SkStroke.cpp b/src/core/SkStroke.cpp
index e384df1ef7..61bd730e67 100644
--- a/src/core/SkStroke.cpp
+++ b/src/core/SkStroke.cpp
@@ -136,14 +136,14 @@ public:
void done(SkPath* dst, bool isLine) {
this->finishContour(false, isLine);
- fOuter.addPath(fExtra);
dst->swap(fOuter);
}
SkScalar getResScale() const { return fResScale; }
- bool isZeroLength() const {
- return fInner.isZeroLength() && fOuter.isZeroLength();
+ bool isCurrentContourEmpty() const {
+ return fInner.isZeroLengthSincePoint(0) &&
+ fOuter.isZeroLengthSincePoint(fFirstOuterPtIndexInContour);
}
private:
@@ -156,6 +156,7 @@ private:
SkVector fFirstNormal, fPrevNormal, fFirstUnitNormal, fPrevUnitNormal;
SkPoint fFirstPt, fPrevPt; // on original path
SkPoint fFirstOuterPt;
+ int fFirstOuterPtIndexInContour;
int fSegmentCount;
bool fPrevIsLine;
bool fCanIgnoreCenter;
@@ -164,7 +165,6 @@ private:
SkStrokerPriv::JoinProc fJoiner;
SkPath fInner, fOuter; // outer is our working answer, inner is temp
- SkPath fExtra; // added as extra complete contours
enum StrokeType {
kOuter_StrokeType = 1, // use sign-opposite values later to flip perpendicular axis
@@ -325,6 +325,7 @@ void SkPathStroker::finishContour(bool close, bool currIsLine) {
// reallocating its internal storage.
fInner.rewind();
fSegmentCount = -1;
+ fFirstOuterPtIndexInContour = fOuter.countPoints();
}
///////////////////////////////////////////////////////////////////////////////
@@ -352,6 +353,7 @@ SkPathStroker::SkPathStroker(const SkPath& src,
fCapper = SkStrokerPriv::CapFactory(cap);
fJoiner = SkStrokerPriv::JoinFactory(join);
fSegmentCount = -1;
+ fFirstOuterPtIndexInContour = 0;
fPrevIsLine = false;
// Need some estimate of how large our final result (fOuter)
@@ -1431,7 +1433,7 @@ void SkStroke::strokePath(const SkPath& src, SkPath* dst) const {
/* If the stroke consists of a moveTo followed by one or more zero-length
verbs, then followed by a close, treat is as if it were followed by a
zero-length line. Lines without length can have square & round end caps. */
- if (stroker.isZeroLength()) {
+ if (stroker.isCurrentContourEmpty()) {
ZERO_LENGTH:
lastSegment = SkPath::kLine_Verb;
break;