diff options
author | 2017-07-10 15:09:26 -0400 | |
---|---|---|
committer | 2017-07-10 19:39:28 +0000 | |
commit | a2318576d6510dc63513ce335ed0027666bd55bf (patch) | |
tree | 3e20ab17671506af3e966a2929530934a17cf488 /src | |
parent | 6d70274ccf6e7a3729af53e401d2d9e6726035a3 (diff) |
Correctly stroke zero length segments in multi-contour paths
Bug: skia:
Change-Id: I959287780ef94a258a6746132f3acb9f90e6c6cc
Reviewed-on: https://skia-review.googlesource.com/21863
Reviewed-by: Cary Clark <caryclark@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkPath.cpp | 6 | ||||
-rw-r--r-- | src/core/SkStroke.cpp | 12 |
2 files changed, 10 insertions, 8 deletions
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; |