Fixed3232 overflow in LinearGradientContext::shadeSpan()

Speculative fix for TAP ubsan failures.

Change-Id: Id3a78adbfab04ba3404a23059cbd8c162d812c2e
Reviewed-on: https://skia-review.googlesource.com/8315
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/include/private/SkFixed.h b/include/private/SkFixed.h
index 2ef8fff..b2eea5f 100644
--- a/include/private/SkFixed.h
+++ b/include/private/SkFixed.h
@@ -145,11 +145,15 @@
 
 typedef int64_t SkFixed3232;   // 32.32
 
+#define SkFixed3232Max            (0x7FFFFFFFFFFFFFFFLL)
+#define SkFixed3232Min            (-SkFixed3232Max)
+
 #define SkIntToFixed3232(x)       (SkLeftShift((SkFixed3232)(x), 32))
 #define SkFixed3232ToInt(x)       ((int)((x) >> 32))
 #define SkFixedToFixed3232(x)     (SkLeftShift((SkFixed3232)(x), 16))
 #define SkFixed3232ToFixed(x)     ((SkFixed)((x) >> 16))
 #define SkFloatToFixed3232(x)     ((SkFixed3232)((x) * (65536.0f * 65536.0f)))
+#define SkFixed3232ToFloat(x)     (x * (1 / (65536.0f * 65536.0f)))
 
 #define SkScalarToFixed3232(x)    SkFloatToFixed3232(x)
 
diff --git a/src/effects/gradients/SkClampRange.h b/src/effects/gradients/SkClampRange.h
index d3d2d08..91c259a 100644
--- a/src/effects/gradients/SkClampRange.h
+++ b/src/effects/gradients/SkClampRange.h
@@ -11,11 +11,13 @@
 #include "SkFixed.h"
 #include "SkScalar.h"
 
-#define SkGradFixed             SkFixed3232
-#define SkScalarToGradFixed(x)  SkScalarToFixed3232(x)
-#define SkFixedToGradFixed(x)   SkFixedToFixed3232(x)
-#define SkGradFixedToFixed(x)   (SkFixed)((x) >> 16)
-#define kFracMax_SkGradFixed    0xFFFFFFFFLL
+#define SkGradFixed               SkFixed3232
+#define SkScalarPinToGradFixed(x) SkScalarToFixed3232(SkTPin(x,                                 \
+                                                             SkFixed3232ToFloat(SkFixed3232Min),\
+                                                             SkFixed3232ToFloat(SkFixed3232Max)))
+#define SkFixedToGradFixed(x)     SkFixedToFixed3232(x)
+#define SkGradFixedToFixed(x)     (SkFixed)((x) >> 16)
+#define kFracMax_SkGradFixed      0xFFFFFFFFLL
 
 /**
  *  Iteration fixed fx by dx, clamping as you go to [0..kFracMax_SkGradFixed], this class
diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp
index 73247cb..1dbe2e7 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -359,15 +359,15 @@
     if (fDstToIndexClass != kPerspective_MatrixClass) {
         dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
                              SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
-        SkGradFixed dx, fx = SkScalarToGradFixed(srcPt.fX);
+        SkGradFixed dx, fx = SkScalarPinToGradFixed(srcPt.fX);
 
         if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
             const auto step = fDstToIndex.fixedStepInX(SkIntToScalar(y));
             // todo: do we need a real/high-precision value for dx here?
-            dx = SkScalarToGradFixed(step.fX);
+            dx = SkScalarPinToGradFixed(step.fX);
         } else {
             SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
-            dx = SkScalarToGradFixed(fDstToIndex.getScaleX());
+            dx = SkScalarPinToGradFixed(fDstToIndex.getScaleX());
         }
 
         LinearShadeProc shadeProc = shadeSpan_linear_repeat;