From: caryclark Date: Mon, 22 Feb 2016 20:44:54 +0000 (-0800) Subject: allow move/zero-line/close to draw caps X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~129^2~1892 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d49a86ade0bab1fc3048d6ba5d8536abf25ed77c;p=platform%2Fupstream%2FlibSkiaSharp.git allow move/zero-line/close to draw caps R=fmalita@chromium.org BUG=skia:4784 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1720953002 Review URL: https://codereview.chromium.org/1720953002 --- diff --git a/include/core/SkPath.h b/include/core/SkPath.h index e1bc5e4..8df7633 100644 --- a/include/core/SkPath.h +++ b/include/core/SkPath.h @@ -1143,6 +1143,10 @@ 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; + /** 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 06bbeef..320448a 100644 --- a/src/core/SkPath.cpp +++ b/src/core/SkPath.cpp @@ -1184,6 +1184,21 @@ bool SkPath::hasOnlyMoveTos() const { return true; } +bool SkPath::isZeroLength() const { + int count = fPathRef->countPoints(); + if (count < 2) { + return true; + } + const SkPoint* pts = fPathRef.get()->points(); + const SkPoint& first = *pts; + for (int index = 1; index < count; ++index) { + if (first != pts[index]) { + return false; + } + } + return true; +} + void SkPath::addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, Direction dir) { assert_known_direction(dir); diff --git a/src/core/SkStroke.cpp b/src/core/SkStroke.cpp index 5a43075..370cbdc 100644 --- a/src/core/SkStroke.cpp +++ b/src/core/SkStroke.cpp @@ -140,6 +140,10 @@ public: SkScalar getResScale() const { return fResScale; } + bool isZeroLength() const { + return fInner.isZeroLength() && fOuter.isZeroLength(); + } + private: SkScalar fRadius; SkScalar fInvMiterLimit; @@ -1394,13 +1398,22 @@ void SkStroke::strokePath(const SkPath& src, SkPath* dst) const { lastSegment = SkPath::kCubic_Verb; break; case SkPath::kClose_Verb: - if (stroker.hasOnlyMoveTo() && SkPaint::kButt_Cap != this->getCap()) { + if (SkPaint::kButt_Cap != this->getCap()) { /* If the stroke consists of a moveTo followed by a close, treat it as if it were followed by a zero-length line. Lines without length can have square and round end caps. */ - stroker.lineTo(stroker.moveToPt()); - lastSegment = SkPath::kLine_Verb; - break; + if (stroker.hasOnlyMoveTo()) { + stroker.lineTo(stroker.moveToPt()); + goto ZERO_LENGTH; + } + /* 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()) { + ZERO_LENGTH: + lastSegment = SkPath::kLine_Verb; + break; + } } stroker.close(lastSegment == SkPath::kLine_Verb); break;