Compute slope using fSnappedY

If we use the oldy and dy directly as we did previously, the slope could
be very different from (newSnappedX - fSnappedX) / (newSnappedY -
fSnappedY) in the updateLine when the edge made a lot of updates with
small dy but large dx. That will cause bug skia:5995

BUG=skia:5995

Change-Id: If521976ed87195dfea5961afd58bedb98447c568
Reviewed-on: https://skia-review.googlesource.com/5269
Reviewed-by: Cary Clark <caryclark@google.com>
Commit-Queue: Yuqian Li <liyuqian@google.com>
diff --git a/src/core/SkAnalyticEdge.cpp b/src/core/SkAnalyticEdge.cpp
index a9cbc50..4b7050f 100644
--- a/src/core/SkAnalyticEdge.cpp
+++ b/src/core/SkAnalyticEdge.cpp
@@ -105,10 +105,14 @@
         {
             newx    = oldx + (dx >> shift);
             newy    = oldy + (dy >> shift);
+            SkFDot6 diffY = (newy - fSnappedY) >> 10;
+            slope = diffY ? QuickSkFDot6Div((newx - fSnappedX) >> 10, diffY) : SK_MaxS32;
+            #ifdef SK_ANALYTIC_AA_GUARD
             slope = dy >> 10 > 0 ? QuickSkFDot6Div(dx >> 10, dy >> 10) : SK_MaxS32;
+            #endif
             if (SkAbs32(dy) >= SK_Fixed1 * 2) { // only snap when dy is large enough
                 newSnappedY = SkTMin<SkFixed>(fQEdge.fQLastY, SkFixedRoundToFixed(newy));
-                newSnappedX = newx + SkFixedMul(slope, newSnappedY - newy);
+                newSnappedX = newx - SkFixedMul(slope, newy - newSnappedY);
             } else {
                 newSnappedY = SkTMin(fQEdge.fQLastY, snapY(newy));
                 newSnappedX = newx;
@@ -122,9 +126,8 @@
             newy    = fQEdge.fQLastY;
             newSnappedY = newy;
             newSnappedX = newx;
-            slope = (newSnappedY - fSnappedY) >> 10
-                    ? QuickSkFDot6Div((newx - fSnappedX) >> 10, (newy - fSnappedY) >> 10)
-                    : SK_MaxS32;
+            SkFDot6 diffY = (newy - fSnappedY) >> 10;
+            slope = diffY ? QuickSkFDot6Div((newx - fSnappedX) >> 10, diffY) : SK_MaxS32;
         }
         if (slope < SK_MaxS32) {
             success = this->updateLine(fSnappedX, fSnappedY, newSnappedX, newSnappedY, slope);
diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp
index f064a16..9be3976 100644
--- a/tests/PathTest.cpp
+++ b/tests/PathTest.cpp
@@ -242,6 +242,19 @@
     stroke.applyToPath(&path, path);
 }
 
+static void test_path_crbugskia5995() {
+    auto surface(SkSurface::MakeRasterN32Premul(500, 500));
+    SkCanvas* canvas = surface->getCanvas();
+    SkPaint paint;
+    paint.setAntiAlias(true);
+    SkPath path;
+    path.moveTo(SkBits2Float(0x40303030), SkBits2Float(0x3e303030));  // 2.75294f, 0.172059f
+    path.quadTo(SkBits2Float(0x41d63030), SkBits2Float(0x30303030), SkBits2Float(0x41013030),
+            SkBits2Float(0x00000000));  // 26.7735f, 6.40969e-10f, 8.07426f, 0
+    path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000));  // 0, 0
+    canvas->drawPath(path, paint);
+}
+
 static void make_path0(SkPath* path) {
     // from  *  https://code.google.com/p/skia/issues/detail?id=1706
 
@@ -4528,6 +4541,7 @@
     test_dump(reporter);
     test_path_crbug389050(reporter);
     test_path_crbugskia2820(reporter);
+    test_path_crbugskia5995();
     test_skbug_3469(reporter);
     test_skbug_3239(reporter);
     test_bounds_crbug_513799(reporter);