add convexity logic and tests for scalar max, Inf, and NaN

PathOps relies on isConvex() only returning true for trivially
convex paths. The old logic also returns true if the paths that
contain NaNs and Infinities. Return kUnknown_Convexity instead
in those cases and in cases where the convexity logic computes
intermediaries that overflow.

Review URL: https://codereview.chromium.org/784593002
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 25fd058..a08abbd 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -2215,7 +2215,8 @@
     Convexicator()
     : fPtCount(0)
     , fConvexity(SkPath::kConvex_Convexity)
-    , fDirection(SkPath::kUnknown_Direction) {
+    , fDirection(SkPath::kUnknown_Direction)
+    , fIsFinite(true) {
         fExpectedDir = kInvalid_DirChange;
         // warnings
         fLastPt.set(0, 0);
@@ -2233,7 +2234,7 @@
     SkPath::Direction getDirection() const { return fDirection; }
 
     void addPt(const SkPoint& pt) {
-        if (SkPath::kConcave_Convexity == fConvexity) {
+        if (SkPath::kConcave_Convexity == fConvexity || !fIsFinite) {
             return;
         }
 
@@ -2242,7 +2243,10 @@
             ++fPtCount;
         } else {
             SkVector vec = pt - fCurrPt;
-            if (!SkScalarNearlyZero(vec.lengthSqd(), SK_ScalarNearlyZero*SK_ScalarNearlyZero)) {
+            SkScalar lengthSqd = vec.lengthSqd();
+            if (!SkScalarIsFinite(lengthSqd)) {
+                fIsFinite = false;
+            } else if (!SkScalarNearlyZero(lengthSqd, SK_ScalarNearlyZero*SK_ScalarNearlyZero)) {
                 fLastPt = fCurrPt;
                 fCurrPt = pt;
                 if (++fPtCount == 2) {
@@ -2272,6 +2276,10 @@
         }
     }
 
+    bool isFinite() const {
+        return fIsFinite;
+    }
+
 private:
     void addVec(const SkVector& vec) {
         SkASSERT(vec.fX || vec.fY);
@@ -2310,6 +2318,7 @@
     SkPath::Convexity   fConvexity;
     SkPath::Direction   fDirection;
     int                 fDx, fDy, fSx, fSy;
+    bool                fIsFinite;
 };
 
 SkPath::Convexity SkPath::internalGetConvexity() const {
@@ -2322,6 +2331,9 @@
     int             count;
     Convexicator    state;
 
+    if (!isFinite()) {
+        return kUnknown_Convexity;
+    }
     while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
         switch (verb) {
             case kMove_Verb:
@@ -2350,6 +2362,9 @@
             state.addPt(pts[i]);
         }
         // early exit
+        if (!state.isFinite()) {
+            return kUnknown_Convexity;
+        }
         if (kConcave_Convexity == state.getConvexity()) {
             fConvexity = kConcave_Convexity;
             return kConcave_Convexity;