Improve accuracy of cubic classification

- Updates the logic to reflect the Loop-Blinn paper instead of the GPU
  gems website.
- Removes the threshold for detecting local cusps. The serpentine
  codepath works for these cusps anyway, so what we really want to know
  is whether the discriminant is negative.
- Makes sure to not scale the inflection function by 1/0.
- Shifts the inflection function coefficients in d[] so they match the
  paper.
- Stores the cubic discriminant in d[0].

Bug: skia:
Change-Id: I909a522a0fd27c9c8dfbc27d968bc43eeb7a416f
Reviewed-on: https://skia-review.googlesource.com/13304
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/src/pathops/SkPathOpsCubic.cpp b/src/pathops/SkPathOpsCubic.cpp
index d842e2c..1e74eb0 100644
--- a/src/pathops/SkPathOpsCubic.cpp
+++ b/src/pathops/SkPathOpsCubic.cpp
@@ -248,17 +248,18 @@
     if (cubic.monotonicInX() && cubic.monotonicInY()) {
         return 0;
     }
-    SkScalar d[3];
+    SkScalar d[4];
     SkCubicType cubicType = SkClassifyCubic(pointsPtr, d);
     switch (cubicType) {
-        case kLoop_SkCubicType: {
+        case SkCubicType::kLoop: {
             // crib code from gpu path utils that finds t values where loop self-intersects
             // use it to find mid of t values which should be a friendly place to chop
-            SkScalar tempSqrt = SkScalarSqrt(4.f * d[0] * d[2] - 3.f * d[1] * d[1]);
-            SkScalar ls = d[1] - tempSqrt;
-            SkScalar lt = 2.f * d[0];
-            SkScalar ms = d[1] + tempSqrt;
-            SkScalar mt = 2.f * d[0];
+            SkASSERT(d[0] < 0);
+            SkScalar tempSqrt = SkScalarSqrt(-d[0]);
+            SkScalar ls = d[2] - tempSqrt;
+            SkScalar lt = 2.f * d[1];
+            SkScalar ms = d[2] + tempSqrt;
+            SkScalar mt = 2.f * d[1];
             if (roughly_between(0, ls, lt) && roughly_between(0, ms, mt)) {
                 ls = ls / lt;
                 ms = ms / mt;
@@ -269,8 +270,9 @@
             }
         }
         // fall through if no t value found
-        case kSerpentine_SkCubicType:
-        case kCusp_SkCubicType: {
+        case SkCubicType::kSerpentine:
+        case SkCubicType::kLocalCusp:
+        case SkCubicType::kInfiniteCusp: {
             double inflectionTs[2];
             int infTCount = cubic.findInflections(inflectionTs);
             double maxCurvature[3];