[4fGradient] Relax interval checks for SkGradientShaderBase also

Similar to https://skia-review.googlesource.com/8270, treat intervals
as closed at both extremities in the 4f gradient fallback impl also.

BUG=skia:6212

Change-Id: I7f164868202ae6a0f76cbcdbcbf8e62db12a1bd4
Reviewed-on: https://skia-review.googlesource.com/8277
Commit-Queue: Florin Malita <fmalita@chromium.org>
Reviewed-by: Mike Reed <reed@google.com>
diff --git a/fuzz/FuzzGradients.cpp b/fuzz/FuzzGradients.cpp
index 8539f5a..88f3429 100644
--- a/fuzz/FuzzGradients.cpp
+++ b/fuzz/FuzzGradients.cpp
@@ -75,7 +75,7 @@
     }
 
     SkDebugf("--- fuzzLinearGradient ---\n");
-    SkDebugf("  pts:\t\t[ (%f %f) (%f %f) ]\n",
+    SkDebugf("  pts:\t\t[ (%.9g %.9g) (%.9g %.9g) ]\n",
              pts[0].x(), pts[0].y(), pts[1].x(), pts[1].y());
     SkDebugf("  colors:\t[ ");
     for (auto color : colors) {
diff --git a/src/effects/gradients/Sk4fGradientBase.cpp b/src/effects/gradients/Sk4fGradientBase.cpp
index 91f4185..e234e9b 100644
--- a/src/effects/gradients/Sk4fGradientBase.cpp
+++ b/src/effects/gradients/Sk4fGradientBase.cpp
@@ -360,7 +360,7 @@
             // TODO: maybe do this in ctor to remove a branch?
             fInterval = this->findFirstInterval(tiled_t);
             this->loadIntervalData(fInterval);
-        } else if (tiled_t < fInterval->fP0 || tiled_t >= fInterval->fP1) {
+        } else if (!fInterval->contains(tiled_t)) {
             fInterval = this->findNextInterval(t, tiled_t);
             this->loadIntervalData(fInterval);
         }
@@ -391,7 +391,7 @@
     }
 
     Sk4f lerp(SkScalar t) {
-        SkASSERT(t >= fInterval->fP0 && t < fInterval->fP1);
+        SkASSERT(fInterval->contains(t));
         return fCc + fDc * (t - fInterval->fP0);
     }
 
@@ -402,24 +402,24 @@
 
         while (i0 != i1) {
             SkASSERT(i0 < i1);
-            SkASSERT(t >= i0->fP0 && t < i1->fP1);
+            SkASSERT(t >= i0->fP0 && t <= i1->fP1);
 
             const Interval* i = i0 + ((i1 - i0) >> 1);
 
-            if (t >= i->fP1) {
+            if (t > i->fP1) {
                 i0 = i + 1;
             } else {
                 i1 = i;
             }
         }
 
-        SkASSERT(t >= i0->fP0 && t <= i0->fP1);
+        SkASSERT(i0->contains(t));
         return i0;
     }
 
     const Interval* findNextInterval(SkScalar t, SkScalar tiled_t) const {
-        SkASSERT(tiled_t < fInterval->fP0 || tiled_t >= fInterval->fP1);
-        SkASSERT(tiled_t >= fFirstInterval->fP0 && tiled_t < fLastInterval->fP1);
+        SkASSERT(!fInterval->contains(tiled_t));
+        SkASSERT(tiled_t >= fFirstInterval->fP0 && tiled_t <= fLastInterval->fP1);
 
         const Interval* i = fInterval;
 
@@ -431,14 +431,14 @@
                 if (i > fLastInterval) {
                     i = fFirstInterval;
                 }
-            } while (tiled_t < i->fP0 || tiled_t >= i->fP1);
+            } while (!i->contains(tiled_t));
         } else {
             do {
                 i -= 1;
                 if (i < fFirstInterval) {
                     i = fLastInterval;
                 }
-            } while (tiled_t < i->fP0 || tiled_t >= i->fP1);
+            } while (!i->contains(tiled_t));
         }
 
         return i;
diff --git a/src/effects/gradients/Sk4fGradientBase.h b/src/effects/gradients/Sk4fGradientBase.h
index fa8412c..6d0c3b9 100644
--- a/src/effects/gradients/Sk4fGradientBase.h
+++ b/src/effects/gradients/Sk4fGradientBase.h
@@ -37,6 +37,13 @@
 
         bool isZeroRamp() const { return fZeroRamp; }
 
+        bool contains(SkScalar p) const {
+            // True if p is in [p0,p1].  Note: this helper assumes a
+            // natural/increasing interval - so it's not usable in Sk4fLinearGradient.
+            SkASSERT(fP0 < fP1);
+            return p >= fP0 && p <= fP1;
+        }
+
         SkPM4f   fC0, fDc;
         SkScalar fP0, fP1;
         bool     fZeroRamp;
diff --git a/tests/GradientTest.cpp b/tests/GradientTest.cpp
index dc8a2bd..4cdd0c9 100644
--- a/tests/GradientTest.cpp
+++ b/tests/GradientTest.cpp
@@ -370,8 +370,18 @@
 // "Interesting" fuzzer values.
 static void test_linear_fuzzer(skiatest::Reporter*) {
     static const SkColor gColors0[] = { 0x30303030, 0x30303030 };
+    static const SkColor gColors1[] = { 0x30303030, 0x30303030, 0x30303030 };
+
+    static const SkScalar gPos1[]   = { 0, 0, 1 };
+
     static const SkScalar gMatrix0[9] =
-        { 6.40969056e-10f, 0, 6.40969056e-10f, 0, 4.42539023e-39f, 6.40969056e-10f, 0, 0, 1 };
+        { 6.40969056e-10f, 0              , 6.40969056e-10f,
+          0              , 4.42539023e-39f, 6.40969056e-10f,
+          0              , 0              , 1 };
+    static const SkScalar gMatrix1[9] =
+        { -2.75294113f    , 6.40969056e-10f,  6.40969056e-10f,
+           6.40969056e-10f, 6.40969056e-10f, -3.32810161e+24f,
+           6.40969056e-10f, 6.40969056e-10f,  0 };
 
     static const struct {
         SkPoint            fPts[2];
@@ -384,14 +394,24 @@
         const SkScalar*    fGlobalMatrix;
     } gConfigs[] = {
         {
-          {{0, -2.752941f}, {0, 0}},
-          gColors0,
-          nullptr,
-          SK_ARRAY_COUNT(gColors0),
-          SkShader::kClamp_TileMode,
-          0,
-          gMatrix0,
-          nullptr
+            {{0, -2.752941f}, {0, 0}},
+            gColors0,
+            nullptr,
+            SK_ARRAY_COUNT(gColors0),
+            SkShader::kClamp_TileMode,
+            0,
+            gMatrix0,
+            nullptr
+        },
+        {
+            {{4.42539023e-39f, -4.42539023e-39f}, {9.78041162e-15f, 4.42539023e-39f}},
+            gColors1,
+            gPos1,
+            SK_ARRAY_COUNT(gColors1),
+            SkShader::kClamp_TileMode,
+            0,
+            nullptr,
+            gMatrix1
         },
     };
 
@@ -417,6 +437,13 @@
                                                          config.fTileMode,
                                                          config.fFlags | forceFlags,
                                                          localMatrix.getMaybeNull()));
+            if (config.fGlobalMatrix) {
+                SkMatrix m;
+                m.set9(config.fGlobalMatrix);
+                canvas->save();
+                canvas->concat(m);
+            }
+
             canvas->drawPaint(paint);
         }
     }