fix circle dash

Thin conic dashes are treated as lines both if the
curvature is detected as zero, and if the midpoint
is close enough to the control point.

To fix:
Halve the midpoint to control point magic number.
Use quad max curvature as a placeholder for conic
max curvature.

R=reed@google.com,fmalita@chromium.org
Bug:843966
Change-Id: Ide43bef8767c03670ffd19fdc38c191d6e2332f3
Reviewed-on: https://skia-review.googlesource.com/c/129243
Commit-Queue: Cary Clark <caryclark@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Reviewed-by: Mike Reed <reed@google.com>
Reviewed-by: Cary Clark <caryclark@skia.org>
diff --git a/gm/dashcircle.cpp b/gm/dashcircle.cpp
index 72e3d1c..3168a0e 100644
--- a/gm/dashcircle.cpp
+++ b/gm/dashcircle.cpp
@@ -225,3 +225,39 @@
 };
 
 DEF_GM(return new DashCircle2GM;)
+
+DEF_SIMPLE_GM(maddash, canvas, 1600, 1600) {
+    canvas->drawRect({0, 0, 1600, 1600}, SkPaint());
+    SkPaint p;
+    p.setColor(SK_ColorRED);
+    p.setAntiAlias(true);
+    p.setStyle(SkPaint::kStroke_Style);
+    p.setStrokeWidth(380);
+
+    SkScalar intvls[] = { 2.5, 10 /* 1200 */ };
+    p.setPathEffect(SkDashPathEffect::Make(intvls, 2, 0));
+
+    canvas->drawCircle(400, 400, 200, p);
+
+    SkPath path;
+    path.moveTo(800, 400);
+    path.quadTo(1000, 400, 1000, 600);
+    path.quadTo(1000, 800, 800, 800);
+    path.quadTo(600, 800, 600, 600);
+    path.quadTo(600, 400, 800, 400);
+    path.close();
+    canvas->translate(350, 150);
+    p.setStrokeWidth(320);
+    canvas->drawPath(path, p);
+
+    path.reset();
+    path.moveTo(800, 400);
+    path.cubicTo(900, 400, 1000, 500, 1000, 600);
+    path.cubicTo(1000, 700, 900, 800, 800, 800);
+    path.cubicTo(700, 800, 600, 700, 600, 600);
+    path.cubicTo(600, 500, 700, 400, 800, 400);
+    path.close();
+    canvas->translate(-550, 500);
+    p.setStrokeWidth(300);
+    canvas->drawPath(path, p);
+}
diff --git a/src/core/SkStroke.cpp b/src/core/SkStroke.cpp
index d31fba9..42a5dff 100644
--- a/src/core/SkStroke.cpp
+++ b/src/core/SkStroke.cpp
@@ -591,7 +591,12 @@
     SkASSERT(outer2 >= 1 && outer2 <= 2);
     SkASSERT(outer1 < outer2);
     int mid = outer1 ^ outer2 ^ 3;
-    SkScalar lineSlop =  ptMax * ptMax * 0.00001f;  // this multiplier is pulled out of the air
+#ifdef SK_USE_LEGACY_CONIC_CURVATURE_SLOP
+    const float kCurvatureSlop = 0.00001f;
+#else
+    const float kCurvatureSlop = 0.000005f;  // this multiplier is pulled out of the air
+#endif
+    SkScalar lineSlop =  ptMax * ptMax * kCurvatureSlop;
     return pt_to_line(quad[mid], quad[outer1], quad[outer2]) <= lineSlop;
 }
 
@@ -651,20 +656,19 @@
     if (!conic_in_line(conic)) {
         return kQuad_ReductionType;
     }
-#if 0   // once findMaxCurvature is implemented, this will be a better solution
-    SkScalar t;
-    if (!conic.findMaxCurvature(&t) || 0 == t) {
-        return kLine_ReductionType;
-    }
-#else  // but for now, use extrema instead
+#ifdef SK_USE_LEGACY_CONIC_CURVATURE_SLOP
     SkScalar xT = 0, yT = 0;
     (void) conic.findXExtrema(&xT);
     (void) conic.findYExtrema(&yT);
     SkScalar t = SkTMax(xT, yT);
+#else
+    // SkFindConicMaxCurvature would be a better solution, once we know how to
+    // implement it. Quad curvature is a reasonable substitute
+    SkScalar t = SkFindQuadMaxCurvature(conic.fPts);
+#endif
     if (0 == t) {
         return kLine_ReductionType;
     }
-#endif
     conic.evalAt(t, reduction, nullptr);
     return kDegenerate_ReductionType;
 }