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