Index: src/core/SkStroke.cpp |
diff --git a/src/core/SkStroke.cpp b/src/core/SkStroke.cpp |
index 1689f9730b008716e2217fb756953d2b48ede1b4..f1b0cae5dedf7d06dabda66df1b2152918ba1efa 100644 |
--- a/src/core/SkStroke.cpp |
+++ b/src/core/SkStroke.cpp |
@@ -119,7 +119,7 @@ class SkPathStroker { |
public: |
SkPathStroker(const SkPath& src, |
SkScalar radius, SkScalar miterLimit, SkPaint::Cap, |
- SkPaint::Join, SkScalar resScale); |
+ SkPaint::Join, SkScalar resScale, bool autoClose, bool reverseInner); |
bool hasOnlyMoveTo() const { return 0 == fSegmentCount; } |
SkPoint moveToPt() const { return fFirstPt; } |
@@ -132,7 +132,7 @@ public: |
void close(bool isLine) { this->finishContour(true, isLine); } |
void done(SkPath* dst, bool isLine) { |
- this->finishContour(false, isLine); |
+ this->finishContour(fAutoClose, isLine); |
fOuter.addPath(fExtra); |
dst->swap(fOuter); |
} |
@@ -151,6 +151,8 @@ private: |
SkPoint fFirstOuterPt; |
int fSegmentCount; |
bool fPrevIsLine; |
+ bool fAutoClose; |
+ bool fReverseInner; |
SkStrokerPriv::CapProc fCapper; |
SkStrokerPriv::JoinProc fJoiner; |
@@ -287,21 +289,29 @@ void SkPathStroker::finishContour(bool close, bool currIsLine) { |
fFirstUnitNormal, fRadius, fInvMiterLimit, |
fPrevIsLine, currIsLine); |
fOuter.close(); |
- // now add fInner as its own contour |
- fInner.getLastPt(&pt); |
- fOuter.moveTo(pt.fX, pt.fY); |
- fOuter.reversePathTo(fInner); |
+ if (fReverseInner) { |
+ // now add fInner as its own contour |
+ fInner.getLastPt(&pt); |
+ fOuter.moveTo(pt.fX, pt.fY); |
+ fOuter.reversePathTo(fInner); |
+ } else { |
+ fOuter.addPath(fInner); |
+ } |
fOuter.close(); |
} else { // add caps to start and end |
- // cap the end |
- fInner.getLastPt(&pt); |
- fCapper(&fOuter, fPrevPt, fPrevNormal, pt, |
- currIsLine ? &fInner : nullptr); |
- fOuter.reversePathTo(fInner); |
- // cap the start |
- fCapper(&fOuter, fFirstPt, -fFirstNormal, fFirstOuterPt, |
- fPrevIsLine ? &fInner : nullptr); |
- fOuter.close(); |
+ if (fReverseInner) { |
+ // cap the end |
+ fInner.getLastPt(&pt); |
+ fCapper(&fOuter, fPrevPt, fPrevNormal, pt, |
+ currIsLine ? &fInner : nullptr); |
+ fOuter.reversePathTo(fInner); |
+ // cap the start |
+ fCapper(&fOuter, fFirstPt, -fFirstNormal, fFirstOuterPt, |
+ fPrevIsLine ? &fInner : nullptr); |
+ fOuter.close(); |
+ } else { |
+ fOuter.addPath(fInner); |
+ } |
} |
} |
// since we may re-use fInner, we rewind instead of reset, to save on |
@@ -314,9 +324,12 @@ void SkPathStroker::finishContour(bool close, bool currIsLine) { |
SkPathStroker::SkPathStroker(const SkPath& src, |
SkScalar radius, SkScalar miterLimit, |
- SkPaint::Cap cap, SkPaint::Join join, SkScalar resScale) |
+ SkPaint::Cap cap, SkPaint::Join join, SkScalar resScale, |
+ bool autoClose, bool reverseInner) |
: fRadius(radius) |
- , fResScale(resScale) { |
+ , fResScale(resScale) |
+ , fAutoClose(autoClose) |
+ , fReverseInner(reverseInner) { |
/* This is only used when join is miter_join, but we initialize it here |
so that it is always defined, to fis valgrind warnings. |
@@ -354,7 +367,7 @@ SkPathStroker::SkPathStroker(const SkPath& src, |
void SkPathStroker::moveTo(const SkPoint& pt) { |
if (fSegmentCount > 0) { |
- this->finishContour(false, false); |
+ this->finishContour(fAutoClose, false); |
} |
fSegmentCount = 0; |
fFirstPt = fPrevPt = pt; |
@@ -1224,6 +1237,8 @@ SkStroke::SkStroke() { |
fCap = SkPaint::kDefault_Cap; |
fJoin = SkPaint::kDefault_Join; |
fDoFill = false; |
+ fAutoClose = false; |
+ fReverseInner = true; |
} |
SkStroke::SkStroke(const SkPaint& p) { |
@@ -1232,6 +1247,8 @@ SkStroke::SkStroke(const SkPaint& p) { |
fCap = (uint8_t)p.getStrokeCap(); |
fJoin = (uint8_t)p.getStrokeJoin(); |
fDoFill = SkToU8(p.getStyle() == SkPaint::kStrokeAndFill_Style); |
+ fAutoClose = false; |
+ fReverseInner = true; |
} |
SkStroke::SkStroke(const SkPaint& p, SkScalar width) { |
@@ -1240,6 +1257,8 @@ SkStroke::SkStroke(const SkPaint& p, SkScalar width) { |
fCap = (uint8_t)p.getStrokeCap(); |
fJoin = (uint8_t)p.getStrokeJoin(); |
fDoFill = SkToU8(p.getStyle() == SkPaint::kStrokeAndFill_Style); |
+ fAutoClose = false; |
+ fReverseInner = true; |
} |
void SkStroke::setWidth(SkScalar width) { |
@@ -1317,7 +1336,7 @@ void SkStroke::strokePath(const SkPath& src, SkPath* dst) const { |
} |
} |
- SkPathStroker stroker(src, radius, fMiterLimit, this->getCap(), this->getJoin(), fResScale); |
+ SkPathStroker stroker(src, radius, fMiterLimit, this->getCap(), this->getJoin(), fResScale, this->getAutoClose(), this->getReverseInner()); |
SkPath::Iter iter(src, false); |
SkPath::Verb lastSegment = SkPath::kMove_Verb; |
@@ -1473,6 +1492,6 @@ void SkStroke::strokeRect(const SkRect& origRect, SkPath* dst, |
if (fWidth < SkMinScalar(rw, rh) && !fDoFill) { |
r = rect; |
r.inset(radius, radius); |
- dst->addRect(r, reverse_direction(dir)); |
+ dst->addRect(r, this->getReverseInner() ? reverse_direction(dir) : dir); |
} |
} |