From d4631986e6b3a668a4a86e54a0e0027b201188b9 Mon Sep 17 00:00:00 2001 From: Cary Clark Date: Thu, 5 Jan 2017 12:08:38 -0500 Subject: ignore max curvature at end point 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 Commit-Queue: Cary Clark --- gm/cubicpaths.cpp | 24 ++++++++++++++++++++++++ src/core/SkStroke.cpp | 12 ++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/gm/cubicpaths.cpp b/gm/cubicpaths.cpp index abac5b2177..023316b658 100644 --- a/gm/cubicpaths.cpp +++ b/gm/cubicpaths.cpp @@ -426,6 +426,30 @@ DEF_SIMPLE_GM(bug5099, canvas, 50, 50) { canvas->drawPath(path, p); } +DEF_SIMPLE_GM(bug6083, canvas, 100, 50) { + SkPaint p; + p.setColor(SK_ColorRED); + p.setAntiAlias(true); + p.setStyle(SkPaint::kStroke_Style); + p.setStrokeWidth(15); + canvas->translate(-500, -130); + SkPath path; + path.moveTo(500.988f, 155.200f); + path.lineTo(526.109f, 155.200f); + SkPoint p1 = { 526.109f, 155.200f }; + SkPoint p2 = { 525.968f, 212.968f }; + SkPoint p3 = { 526.109f, 241.840f }; + path.cubicTo(p1, p2, p3); + canvas->drawPath(path, p); + canvas->translate(50, 0); + path.reset(); + p2.set(525.968f, 213.172f); + path.moveTo(500.988f, 155.200f); + path.lineTo(526.109f, 155.200f); + path.cubicTo(p1, p2, p3); + canvas->drawPath(path, p); +} + ////////////////////////////////////////////////////////////////////////////// DEF_GM( return new CubicPathGM; ) diff --git a/src/core/SkStroke.cpp b/src/core/SkStroke.cpp index 8ff7910bdc..e384df1ef7 100644 --- a/src/core/SkStroke.cpp +++ b/src/core/SkStroke.cpp @@ -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, -- cgit v1.2.3