ignore max curvature at end point
authorCary Clark <caryclark@google.com>
Thu, 5 Jan 2017 17:08:38 +0000 (12:08 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Thu, 5 Jan 2017 18:44:25 +0000 (18:44 +0000)
When a stroked cubic folds back on itself, the
stroker draws a round join.
If the max curvature is at
the endpoint, skip the join.

R=reed@google.com
BUG=skia:6083

Change-Id: I45e429432fcec311fa1115058515639370fe9a16
Reviewed-on: https://skia-review.googlesource.com/6606
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Cary Clark <caryclark@google.com>

gm/cubicpaths.cpp
src/core/SkStroke.cpp

index abac5b2..023316b 100644 (file)
@@ -426,6 +426,30 @@ DEF_SIMPLE_GM(bug5099, canvas, 50, 50) {
     canvas->drawPath(path, p);
 }
 
+DEF_SIMPLE_GM(bug6083, canvas, 100, 50) {
+    SkPaint p;\r
+    p.setColor(SK_ColorRED);\r
+    p.setAntiAlias(true);\r
+    p.setStyle(SkPaint::kStroke_Style);\r
+    p.setStrokeWidth(15);\r
+    canvas->translate(-500, -130);\r
+    SkPath path;\r
+    path.moveTo(500.988f, 155.200f);\r
+    path.lineTo(526.109f, 155.200f);\r
+    SkPoint p1 = { 526.109f, 155.200f };\r
+    SkPoint p2 = { 525.968f, 212.968f };\r
+    SkPoint p3 = { 526.109f, 241.840f };\r
+    path.cubicTo(p1, p2, p3);\r
+    canvas->drawPath(path, p);\r
+    canvas->translate(50, 0);\r
+    path.reset();\r
+    p2.set(525.968f, 213.172f);\r
+    path.moveTo(500.988f, 155.200f);\r
+    path.lineTo(526.109f, 155.200f);\r
+    path.cubicTo(p1, p2, p3);\r
+    canvas->drawPath(path, p);\r
+}
+
 //////////////////////////////////////////////////////////////////////////////
 
 DEF_GM( return new CubicPathGM; )
index 8ff7910..e384df1 100644 (file)
@@ -606,15 +606,23 @@ SkPathStroker::ReductionType SkPathStroker::CheckCubicLinear(const SkPoint cubic
     if (count == 0) {
         return kLine_ReductionType;
     }
+    int rCount = 0;
+    // Now loop over the t-values, and reject any that evaluate to either end-point
     for (int index = 0; index < count; ++index) {
         SkScalar t = tValues[index];
-        SkEvalCubicAt(cubic, t, &reduction[index], nullptr, nullptr);
+        SkEvalCubicAt(cubic, t, &reduction[rCount], nullptr, nullptr);
+        if (reduction[rCount] != cubic[0] && reduction[rCount] != cubic[3]) {
+            ++rCount;
+        }
+    }
+    if (rCount == 0) {
+        return kLine_ReductionType;
     }
     static_assert(kQuad_ReductionType + 1 == kDegenerate_ReductionType, "enum_out_of_whack");
     static_assert(kQuad_ReductionType + 2 == kDegenerate2_ReductionType, "enum_out_of_whack");
     static_assert(kQuad_ReductionType + 3 == kDegenerate3_ReductionType, "enum_out_of_whack");
 
-    return (ReductionType) (kQuad_ReductionType + count);
+    return (ReductionType) (kQuad_ReductionType + rCount);
 }
 
 SkPathStroker::ReductionType SkPathStroker::CheckConicLinear(const SkConic& conic,