add more conservative check for wayward divide
authorcaryclark <caryclark@google.com>
Mon, 30 Nov 2015 21:47:11 +0000 (13:47 -0800)
committerCommit bot <commit-bot@chromium.org>
Mon, 30 Nov 2015 21:47:11 +0000 (13:47 -0800)
When the parallel stroke to the curve can't be computed from
the intersection of the tangent lines, as straight line connects
the two points instead. Allow the intersection to succeed unless
the ratio isn't finite or the contribution of (1 - ratio) isn't
significant.

R=reed@google.com,fmalita@chromium.org
BUG=skia:4603

Review URL: https://codereview.chromium.org/1484873003

gm/strokes.cpp
src/core/SkStroke.cpp

index bd39382..aa2db9c 100644 (file)
@@ -193,6 +193,22 @@ private:
     typedef skiagm::GM INHERITED;
 };
 
+DEF_SIMPLE_GM(CubicStroke, canvas, 384, 384) {
+    SkPaint p;
+    p.setAntiAlias(true);
+    p.setStyle(SkPaint::kStroke_Style);
+    p.setStrokeWidth(1.0720f);
+       SkPath path;
+    path.moveTo(-6000,-6000);
+    path.cubicTo(-3500,5500,-500,5500,2500,-6500);
+    canvas->drawPath(path, p);
+    p.setStrokeWidth(1.0721f);
+    canvas->translate(10, 10);
+    canvas->drawPath(path, p);
+    p.setStrokeWidth(1.0722f);
+    canvas->translate(10, 10);
+    canvas->drawPath(path, p);
+}
 
 class Strokes2GM : public skiagm::GM {
     SkPath fPath;
index e04d14a..65267d1 100644 (file)
@@ -836,14 +836,12 @@ SkPathStroker::ResultType SkPathStroker::intersectRay(SkQuadConstruct* quadPts,
         return STROKER_RESULT(kSplit_ResultType, depth, quadPts,
                 "(numerA=%g >= 0) == (numerB=%g >= 0)", numerA, numerB);
     }
-    // check to see if the denomerator is teeny relative to the numerator
-    bool validDivide = SkScalarAbs(numerA) * SK_ScalarNearlyZero < SkScalarAbs(denom);
-// the divide check is the same as checking if the scaled denom is nearly zero
-// (commented out because on some platforms the two are not bit-identical)
-//  SkASSERT(!SkScalarNearlyZero(denom / numerA) == validDivide);
+    // check to see if the denominator is teeny relative to the numerator
+    // if the offset by one will be lost, the ratio is too large
+    numerA /= denom;
+    bool validDivide = numerA > numerA - 1;
     if (validDivide) {
         if (kCtrlPt_RayType == intersectRayType) {
-            numerA /= denom;
             SkPoint* ctrlPt = &quadPts->fQuad[1];
             // the intersection of the tangents need not be on the tangent segment
             // so 0 <= numerA <= 1 is not necessarily true