Harden LinearGradient4fContext

Three distinct issues exposed by Fuzzer:

1) truncating the flags to 8 bits may trip the assert in SkToU8

Since clients can pass in any garbage, we cannot assume it fits in 8
bits.  Just static_cast<> instead.

2) vertical gradients with dx == -0.0 don't trigger interval inversion.

For dx < 0 we want reversed intervals.  But, alas, -0.0 < 0 == false
(thanks, Ob^WIEEE 754!).  Use signbit() instead.

3) half closed range checking needs to be inverted for reversed
intervals.

Normally we check for [p0, p1), but for reversed intervals (p1 < p0) we
want to check for [p1, p0), and not (p1, p0].  Adjust the logic
accordingly.

BUG=skia:5647
R=reed@google.com,kjlubick@google.com
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2349153004

Review-Url: https://codereview.chromium.org/2349153004
diff --git a/src/effects/gradients/Sk4fLinearGradient.cpp b/src/effects/gradients/Sk4fLinearGradient.cpp
index dc6e530..cd1f770 100644
--- a/src/effects/gradients/Sk4fLinearGradient.cpp
+++ b/src/effects/gradients/Sk4fLinearGradient.cpp
@@ -100,12 +100,13 @@
     return f < 0 ? f + 2 : f;
 }
 
-// true when x is in [k1,k2)
+// true when x is in [k1,k2), or [k2, k1) when the interval is reversed.
+// TODO(fmalita): hoist the reversed interval check out of this helper.
 bool in_range(SkScalar x, SkScalar k1, SkScalar k2) {
     SkASSERT(k1 != k2);
     return (k1 < k2)
-        ? (x >= k1 && x < k2)
-        : (x >= k2 && x < k1);
+        ? (x >= k1 && x <  k2)
+        : (x >  k2 && x <= k1);
 }
 
 } // anonymous namespace
@@ -116,7 +117,7 @@
     : INHERITED(shader, rec) {
 
     // Our fast path expects interval points to be monotonically increasing in x.
-    const bool reverseIntervals = this->isFast() && fDstToPos.getScaleX() < 0;
+    const bool reverseIntervals = this->isFast() && signbit(fDstToPos.getScaleX());
     this->buildIntervals(shader, rec, reverseIntervals);
 
     SkASSERT(fIntervals.count() > 0);
@@ -290,6 +291,7 @@
         , fDx(dx)
         , fIsVertical(is_vertical)
     {
+        SkASSERT(fAdvX >= 0);
         SkASSERT(firstInterval <= lastInterval);
         SkASSERT(in_range(fx, i->fP0, i->fP1));
         this->compute_interval_props(fx - i->fP0);