LinearGradientContext::shade4_clamp: fix div by 0

getScaleX() may return 0; move division using it after a
SkScalarNearlyZero check and closer to its first use.

Change-Id: Ie209d46dc101213e20e90486651ee17570425bb8
Reviewed-on: https://skia-review.googlesource.com/4643
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp
index ea20595..66accd8 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -737,7 +737,6 @@
         }
     }
     const float dither[2] = { dither0, dither1 };
-    const float invDx = 1 / dx;
 
     if (SkScalarNearlyZero(dx * count)) { // gradient is vertical
         const float pinFx = SkTPin(fx, 0.0f, 1.0f);
@@ -750,6 +749,8 @@
         return;
     }
 
+    SkASSERT(0.f != dx);
+    const float invDx = 1 / dx;
     if (dx > 0) {
         if (fApplyAlphaAfterInterp) {
             this->shade4_dx_clamp<true, true>(dstC, count, fx, dx, invDx, dither);
diff --git a/tests/GradientTest.cpp b/tests/GradientTest.cpp
index ee776e3..50643f1 100644
--- a/tests/GradientTest.cpp
+++ b/tests/GradientTest.cpp
@@ -279,6 +279,18 @@
     surface->getCanvas()->drawPaint(paint);
 }
 
+static void test_vertical(skiatest::Reporter* reporter) {
+    auto surface(SkSurface::MakeRasterN32Premul(200, 200));
+
+    const SkPoint pts[] = {{ 100, 50 }, { 100, 50 }};
+    const SkColor colors[] = { SK_ColorBLACK, SK_ColorWHITE };
+    const SkScalar pos[] = { 0, 1 };
+    SkPaint paint;
+    paint.setShader(SkGradientShader::MakeLinear(pts, colors, pos, 2, SkShader::kClamp_TileMode));
+
+    surface->getCanvas()->drawPaint(paint);
+}
+
 // A linear gradient interval can, due to numerical imprecision (likely in the divide)
 // finish an interval with the final fx not landing outside of [p0...p1].
 // The old code had an assert which this test triggered.
@@ -359,6 +371,7 @@
     TestConstantGradient(reporter);
     test_big_grad(reporter);
     test_nearly_vertical(reporter);
+    test_vertical(reporter);
     test_linear_fuzz(reporter);
     test_two_point_conical_zero_radius(reporter);
     test_clamping_overflow(reporter);