path ops -- use standard max, min, double-is-nan

fix a comment or two as well
Review URL: https://codereview.chromium.org/13934009

git-svn-id: http://skia.googlecode.com/svn/trunk@8822 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkFloatingPoint.h b/include/core/SkFloatingPoint.h
index 02880f3..44a3eef 100644
--- a/include/core/SkFloatingPoint.h
+++ b/include/core/SkFloatingPoint.h
@@ -77,6 +77,8 @@
     #define sk_float_isinf(x)       isinf(x)
 #endif
 
+#define sk_double_isnan(a)          sk_float_isnan(a)
+
 #ifdef SK_USE_FLOATBITS
     #define sk_float_floor2int(x)   SkFloatToIntFloor(x)
     #define sk_float_round2int(x)   SkFloatToIntRound(x)
diff --git a/include/core/SkTypes.h b/include/core/SkTypes.h
index ae27089..4f6788c 100644
--- a/include/core/SkTypes.h
+++ b/include/core/SkTypes.h
@@ -314,6 +314,14 @@
     return a;
 }
 
+template <typename T> const T& SkTMin(const T& a, const T& b) {
+    return (a < b) ? a : b;
+}
+
+template <typename T> const T& SkTMax(const T& a, const T& b) {
+    return (b < a) ? a : b;
+}
+
 static inline int32_t SkSign32(int32_t a) {
     return (a >> 31) | ((unsigned) -a >> 31);
 }
diff --git a/src/pathops/SkDCubicIntersection.cpp b/src/pathops/SkDCubicIntersection.cpp
index 2f1804d..10d4e71 100644
--- a/src/pathops/SkDCubicIntersection.cpp
+++ b/src/pathops/SkDCubicIntersection.cpp
@@ -141,12 +141,12 @@
 #if 1
                     double c1Bottom = tIdx == 0 ? 0 :
                             (t1Start + (t1 - t1Start) * locals[0][tIdx - 1] + to1) / 2;
-                    double c1Min = SkTMax<double>(c1Bottom, to1 - offset);
+                    double c1Min = SkTMax(c1Bottom, to1 - offset);
                     double c1Top = tIdx == tCount - 1 ? 1 :
                             (t1Start + (t1 - t1Start) * locals[0][tIdx + 1] + to1) / 2;
-                    double c1Max = SkTMin<double>(c1Top, to1 + offset);
-                    double c2Min = SkTMax<double>(0., to2 - offset);
-                    double c2Max = SkTMin<double>(1., to2 + offset);
+                    double c1Max = SkTMin(c1Top, to1 + offset);
+                    double c2Min = SkTMax(0., to2 - offset);
+                    double c2Max = SkTMin(1., to2 + offset);
                 #if ONE_OFF_DEBUG
                     SkDebugf("%.*s %s 1 contains1=%d/%d contains2=%d/%d\n", i.depth()*2, tab,
                             __FUNCTION__,
@@ -172,8 +172,8 @@
                             i.used(), i.used() > 0 ? i[0][i.used() - 1] : -1);
                 #endif
                     if (tCount > 1) {
-                        c1Min = SkTMax<double>(0., to1 - offset);
-                        c1Max = SkTMin<double>(1., to1 + offset);
+                        c1Min = SkTMax(0., to1 - offset);
+                        c1Max = SkTMin(1., to1 + offset);
                         double c2Bottom = tIdx == 0 ? to2 :
                                 (t2Start + (t2 - t2Start) * locals[1][tIdx - 1] + to2) / 2;
                         double c2Top = tIdx == tCount - 1 ? to2 :
@@ -187,8 +187,8 @@
                         if (c2Top == to2) {
                             c2Top = 1;
                         }
-                        c2Min = SkTMax<double>(c2Bottom, to2 - offset);
-                        c2Max = SkTMin<double>(c2Top, to2 + offset);
+                        c2Min = SkTMax(c2Bottom, to2 - offset);
+                        c2Max = SkTMin(c2Top, to2 + offset);
                     #if ONE_OFF_DEBUG
                         SkDebugf("%.*s %s 2 contains1=%d/%d contains2=%d/%d\n", i.depth()*2, tab,
                             __FUNCTION__,
@@ -213,8 +213,8 @@
                     SkDebugf("%.*s %s 2 i.used=%d t=%1.9g\n", i.depth()*2, tab, __FUNCTION__,
                             i.used(), i.used() > 0 ? i[0][i.used() - 1] : -1);
                 #endif
-                        c1Min = SkTMax<double>(c1Bottom, to1 - offset);
-                        c1Max = SkTMin<double>(c1Top, to1 + offset);
+                        c1Min = SkTMax(c1Bottom, to1 - offset);
+                        c1Max = SkTMin(c1Top, to1 + offset);
                     #if ONE_OFF_DEBUG
                         SkDebugf("%.*s %s 3 contains1=%d/%d contains2=%d/%d\n", i.depth()*2, tab,
                         __FUNCTION__,
@@ -243,10 +243,10 @@
 #else
                     double c1Bottom = tIdx == 0 ? 0 :
                             (t1Start + (t1 - t1Start) * locals.fT[0][tIdx - 1] + to1) / 2;
-                    double c1Min = SkTMax<double>(c1Bottom, to1 - offset);
+                    double c1Min = SkTMax(c1Bottom, to1 - offset);
                     double c1Top = tIdx == tCount - 1 ? 1 :
                             (t1Start + (t1 - t1Start) * locals.fT[0][tIdx + 1] + to1) / 2;
-                    double c1Max = SkTMin<double>(c1Top, to1 + offset);
+                    double c1Max = SkTMin(c1Top, to1 + offset);
                     double c2Bottom = tIdx == 0 ? to2 :
                             (t2Start + (t2 - t2Start) * locals.fT[1][tIdx - 1] + to2) / 2;
                     double c2Top = tIdx == tCount - 1 ? to2 :
@@ -260,8 +260,8 @@
                     if (c2Top == to2) {
                         c2Top = 1;
                     }
-                    double c2Min = SkTMax<double>(c2Bottom, to2 - offset);
-                    double c2Max = SkTMin<double>(c2Top, to2 + offset);
+                    double c2Min = SkTMax(c2Bottom, to2 - offset);
+                    double c2Max = SkTMin(c2Top, to2 + offset);
                 #if ONE_OFF_DEBUG
                     SkDebugf("%s contains1=%d/%d contains2=%d/%d\n", __FUNCTION__,
                             c1Min <= 0.210357794 && 0.210357794 <= c1Max
@@ -351,13 +351,13 @@
         while (tLast + 1 < tVals.count() && roughly_equal(tVals[tLast + 1], tVals[tIdx])) {
             ++tLast;
         }
-        double tMin2 = SkTMax<double>(tVals[tIdx] - LINE_FRACTION, 0.0);
-        double tMax2 = SkTMin<double>(tVals[tLast] + LINE_FRACTION, 1.0);
+        double tMin2 = SkTMax(tVals[tIdx] - LINE_FRACTION, 0.0);
+        double tMax2 = SkTMin(tVals[tLast] + LINE_FRACTION, 1.0);
         int lastUsed = i.used();
         intersect(cubic1, tMin1, tMax1, cubic2, tMin2, tMax2, 1, i);
         if (lastUsed == i.used()) {
-            tMin2 = SkTMax<double>(tVals[tIdx] - (1.0 / SkDCubic::gPrecisionUnit), 0.0);
-            tMax2 = SkTMin<double>(tVals[tLast] + (1.0 / SkDCubic::gPrecisionUnit), 1.0);
+            tMin2 = SkTMax(tVals[tIdx] - (1.0 / SkDCubic::gPrecisionUnit), 0.0);
+            tMax2 = SkTMin(tVals[tLast] + (1.0 / SkDCubic::gPrecisionUnit), 1.0);
             intersect(cubic1, tMin1, tMax1, cubic2, tMin2, tMax2, 1, i);
         }
         tIdx = tLast + 1;
diff --git a/src/pathops/SkDLineIntersection.cpp b/src/pathops/SkDLineIntersection.cpp
index 93f0353..68e1f9e 100644
--- a/src/pathops/SkDLineIntersection.cpp
+++ b/src/pathops/SkDLineIntersection.cpp
@@ -109,16 +109,16 @@
         if ((at0 < 0 && at1 < 0) || (at0 > 1 && at1 > 1)) {
             return fUsed = 0;
         }
-        fT[0][0] = SkTMax<double>(SkTMin<double>(at0, 1.0), 0.0);
-        fT[0][1] = SkTMax<double>(SkTMin<double>(at1, 1.0), 0.0);
+        fT[0][0] = SkTMax(SkTMin(at0, 1.0), 0.0);
+        fT[0][1] = SkTMax(SkTMin(at1, 1.0), 0.0);
     }
     double bDenom = b0 - b1;
     if (approximately_zero(bDenom)) {
         fT[1][0] = fT[1][1] = 0;
     } else {
         int bIn = aDenom * bDenom < 0;
-        fT[1][bIn] = SkTMax<double>(SkTMin<double>((b0 - a0) / bDenom, 1.0), 0.0);
-        fT[1][!bIn] = SkTMax<double>(SkTMin<double>((b0 - a1) / bDenom, 1.0), 0.0);
+        fT[1][bIn] = SkTMax(SkTMin((b0 - a0) / bDenom, 1.0), 0.0);
+        fT[1][!bIn] = SkTMax(SkTMin((b0 - a1) / bDenom, 1.0), 0.0);
     }
     bool second = fabs(fT[0][0] - fT[0][1]) > FLT_EPSILON;
     SkASSERT((fabs(fT[1][0] - fT[1][1]) <= FLT_EPSILON) ^ second);
@@ -189,11 +189,11 @@
             if ((at0 < 0 && at1 < 0) || (at0 > 1 && at1 > 1)) {
                 return fUsed = 0;
             }
-            fT[0][0] = SkTMax<double>(SkTMin<double>(at0, 1.0), 0.0);
-            fT[0][1] = SkTMax<double>(SkTMin<double>(at1, 1.0), 0.0);
+            fT[0][0] = SkTMax(SkTMin(at0, 1.0), 0.0);
+            fT[0][1] = SkTMax(SkTMin(at1, 1.0), 0.0);
             int bIn = (a0 - a1) * (b0 - b1) < 0;
-            fT[1][bIn] = SkTMax<double>(SkTMin<double>((b0 - a0) / (b0 - b1), 1.0), 0.0);
-            fT[1][!bIn] = SkTMax<double>(SkTMin<double>((b0 - a1) / (b0 - b1), 1.0), 0.0);
+            fT[1][bIn] = SkTMax(SkTMin((b0 - a0) / (b0 - b1), 1.0), 0.0);
+            fT[1][!bIn] = SkTMax(SkTMin((b0 - a1) / (b0 - b1), 1.0), 0.0);
             bool second = fabs(fT[0][0] - fT[0][1]) > FLT_EPSILON;
             SkASSERT((fabs(fT[1][0] - fT[1][1]) <= FLT_EPSILON) ^ second);
             return computePoints(line, 1 + second);
@@ -250,11 +250,11 @@
             if ((at0 < 0 && at1 < 0) || (at0 > 1 && at1 > 1)) {
                 return fUsed = 0;
             }
-            fT[0][0] = SkTMax<double>(SkTMin<double>(at0, 1.0), 0.0);
-            fT[0][1] = SkTMax<double>(SkTMin<double>(at1, 1.0), 0.0);
+            fT[0][0] = SkTMax(SkTMin(at0, 1.0), 0.0);
+            fT[0][1] = SkTMax(SkTMin(at1, 1.0), 0.0);
             int bIn = (a0 - a1) * (b0 - b1) < 0;
-            fT[1][bIn] = SkTMax<double>(SkTMin<double>((b0 - a0) / (b0 - b1), 1.0), 0.0);
-            fT[1][!bIn] = SkTMax<double>(SkTMin<double>((b0 - a1) / (b0 - b1), 1.0), 0.0);
+            fT[1][bIn] = SkTMax(SkTMin((b0 - a0) / (b0 - b1), 1.0), 0.0);
+            fT[1][!bIn] = SkTMax(SkTMin((b0 - a1) / (b0 - b1), 1.0), 0.0);
             bool second = fabs(fT[0][0] - fT[0][1]) > FLT_EPSILON;
             SkASSERT((fabs(fT[1][0] - fT[1][1]) <= FLT_EPSILON) ^ second);
             return computePoints(line, 1 + second);
diff --git a/src/pathops/SkDQuadIntersection.cpp b/src/pathops/SkDQuadIntersection.cpp
index 5abbbdc..5df08ac 100644
--- a/src/pathops/SkDQuadIntersection.cpp
+++ b/src/pathops/SkDQuadIntersection.cpp
@@ -243,7 +243,7 @@
     double m1 = flat_measure(q1);
     double m2 = flat_measure(q2);
 #if DEBUG_FLAT_QUADS
-    double min = SkTMin<double>(m1, m2);
+    double min = SkTMin(m1, m2);
     if (min > 5) {
         SkDebugf("%s maybe not flat enough.. %1.9g\n", __FUNCTION__, min);
     }
diff --git a/src/pathops/SkPathOpsBounds.h b/src/pathops/SkPathOpsBounds.h
index e4dd030..61ef7bb 100644
--- a/src/pathops/SkPathOpsBounds.h
+++ b/src/pathops/SkPathOpsBounds.h
@@ -17,7 +17,9 @@
                 a.fTop <= b.fBottom && b.fTop <= a.fBottom;
     }
 
-    // FIXME: add() is generically useful and could be added directly to SkRect
+   // Note that add(), unlike SkRect::join() or SkRect::growToInclude()
+   // does not treat the bounds of horizontal and vertical lines as
+   // empty rectangles.
     void add(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) {
         if (left < fLeft) fLeft = left;
         if (top < fTop) fTop = top;
diff --git a/src/pathops/SkPathOpsPoint.h b/src/pathops/SkPathOpsPoint.h
index 713b457..aca38d8 100644
--- a/src/pathops/SkPathOpsPoint.h
+++ b/src/pathops/SkPathOpsPoint.h
@@ -96,8 +96,8 @@
     // return approximately_equal(a.fY, fY) && approximately_equal(a.fX, fX);
     // because that will not take the magnitude of the values
     bool approximatelyEqual(const SkDPoint& a) const {
-        double denom = SkTMax<double>(fabs(fX), SkTMax<double>(fabs(fY),
-                SkTMax<double>(fabs(a.fX), fabs(a.fY))));
+        double denom = SkTMax(fabs(fX), SkTMax(fabs(fY),
+                SkTMax(fabs(a.fX), fabs(a.fY))));
         if (denom == 0) {
             return true;
         }
@@ -107,8 +107,8 @@
     }
 
     bool approximatelyEqual(const SkPoint& a) const {
-        double denom = SkTMax<double>(fabs(fX), SkTMax<double>(fabs(fY),
-                SkScalarToDouble(SkTMax<SkScalar>(fabsf(a.fX), fabsf(a.fY)))));
+        double denom = SkTMax(fabs(fX), SkTMax(fabs(fY),
+                SkScalarToDouble(SkTMax(fabsf(a.fX), fabsf(a.fY)))));
         if (denom == 0) {
             return true;
         }
@@ -118,8 +118,8 @@
     }
 
     bool approximatelyEqualHalf(const SkDPoint& a) const {
-        double denom = SkTMax<double>(fabs(fX), SkTMax<double>(fabs(fY),
-                SkTMax<double>(fabs(a.fX), fabs(a.fY))));
+        double denom = SkTMax(fabs(fX), SkTMax(fabs(fY),
+                SkTMax(fabs(a.fX), fabs(a.fY))));
         if (denom == 0) {
             return true;
         }
diff --git a/src/pathops/SkPathOpsQuad.cpp b/src/pathops/SkPathOpsQuad.cpp
index cbba2a3..685f49e 100644
--- a/src/pathops/SkPathOpsQuad.cpp
+++ b/src/pathops/SkPathOpsQuad.cpp
@@ -26,7 +26,7 @@
     int roots = SkDCubic::RootsValidT(a, b, c, d, ts);
     double d0 = pt.distanceSquared(fPts[0]);
     double d2 = pt.distanceSquared(fPts[2]);
-    double distMin = SkTMin<double>(d0, d2);
+    double distMin = SkTMin(d0, d2);
     int bestIndex = -1;
     for (int index = 0; index < roots; ++index) {
         SkDPoint onQuad = xyAtT(ts[index]);
diff --git a/src/pathops/SkPathOpsTypes.h b/src/pathops/SkPathOpsTypes.h
index c3c0cd5..4d81586 100644
--- a/src/pathops/SkPathOpsTypes.h
+++ b/src/pathops/SkPathOpsTypes.h
@@ -15,22 +15,6 @@
 #include "SkPathOpsDebug.h"
 #include "SkScalar.h"
 
-// FIXME: move these into SkTypes.h
-template <typename T> inline T SkTMax(T a, T b) {
-    if (a < b)
-        a = b;
-    return a;
-}
-
-template <typename T> inline T SkTMin(T a, T b) {
-    if (a > b)
-        a = b;
-    return a;
-}
-
-// FIXME: move this into SkFloatingPoint.h
-#define sk_double_isnan(a) sk_float_isnan(a)
-
 enum SkPathOpsMask {
     kWinding_PathOpsMask = -1,
     kNo_PathOpsMask = 0,
diff --git a/tests/PathOpsDRectTest.cpp b/tests/PathOpsDRectTest.cpp
index a053ac7..6eb1955 100644
--- a/tests/PathOpsDRectTest.cpp
+++ b/tests/PathOpsDRectTest.cpp
@@ -43,30 +43,30 @@
     for (index = 0; index < lineTests_count; ++index) {
         const SkDLine& line = lineTests[index];
         rect.setBounds(line);
-        REPORTER_ASSERT(reporter, rect.fLeft == SkTMin<double>(line[0].fX, line[1].fX));
-        REPORTER_ASSERT(reporter, rect.fTop == SkTMin<double>(line[0].fY, line[1].fY));
-        REPORTER_ASSERT(reporter, rect.fRight == SkTMax<double>(line[0].fX, line[1].fX));
-        REPORTER_ASSERT(reporter, rect.fBottom == SkTMax<double>(line[0].fY, line[1].fY));
+        REPORTER_ASSERT(reporter, rect.fLeft == SkTMin(line[0].fX, line[1].fX));
+        REPORTER_ASSERT(reporter, rect.fTop == SkTMin(line[0].fY, line[1].fY));
+        REPORTER_ASSERT(reporter, rect.fRight == SkTMax(line[0].fX, line[1].fX));
+        REPORTER_ASSERT(reporter, rect.fBottom == SkTMax(line[0].fY, line[1].fY));
         rect2.set(line[0]);
         rect2.add(line[1]);
-        REPORTER_ASSERT(reporter, rect2.fLeft == SkTMin<double>(line[0].fX, line[1].fX));
-        REPORTER_ASSERT(reporter, rect2.fTop == SkTMin<double>(line[0].fY, line[1].fY));
-        REPORTER_ASSERT(reporter, rect2.fRight == SkTMax<double>(line[0].fX, line[1].fX));
-        REPORTER_ASSERT(reporter, rect2.fBottom == SkTMax<double>(line[0].fY, line[1].fY));
+        REPORTER_ASSERT(reporter, rect2.fLeft == SkTMin(line[0].fX, line[1].fX));
+        REPORTER_ASSERT(reporter, rect2.fTop == SkTMin(line[0].fY, line[1].fY));
+        REPORTER_ASSERT(reporter, rect2.fRight == SkTMax(line[0].fX, line[1].fX));
+        REPORTER_ASSERT(reporter, rect2.fBottom == SkTMax(line[0].fY, line[1].fY));
         REPORTER_ASSERT(reporter, rect.contains(line[0]));
         REPORTER_ASSERT(reporter, rect.intersects(&rect2));
     }
     for (index = 0; index < quadTests_count; ++index) {
         const SkDQuad& quad = quadTests[index];
         rect.setRawBounds(quad);
-        REPORTER_ASSERT(reporter, rect.fLeft == SkTMin<double>(quad[0].fX,
-                SkTMin<double>(quad[1].fX, quad[2].fX)));
-        REPORTER_ASSERT(reporter, rect.fTop == SkTMin<double>(quad[0].fY,
-                SkTMin<double>(quad[1].fY, quad[2].fY)));
-        REPORTER_ASSERT(reporter, rect.fRight == SkTMax<double>(quad[0].fX,
-                SkTMax<double>(quad[1].fX, quad[2].fX)));
-        REPORTER_ASSERT(reporter, rect.fBottom == SkTMax<double>(quad[0].fY,
-                SkTMax<double>(quad[1].fY, quad[2].fY)));
+        REPORTER_ASSERT(reporter, rect.fLeft == SkTMin(quad[0].fX,
+                SkTMin(quad[1].fX, quad[2].fX)));
+        REPORTER_ASSERT(reporter, rect.fTop == SkTMin(quad[0].fY,
+                SkTMin(quad[1].fY, quad[2].fY)));
+        REPORTER_ASSERT(reporter, rect.fRight == SkTMax(quad[0].fX,
+                SkTMax(quad[1].fX, quad[2].fX)));
+        REPORTER_ASSERT(reporter, rect.fBottom == SkTMax(quad[0].fY,
+                SkTMax(quad[1].fY, quad[2].fY)));
         rect2.setBounds(quad);
         REPORTER_ASSERT(reporter, rect.intersects(&rect2));
         // FIXME: add a recursive box subdivision method to verify that tight bounds is correct
@@ -78,14 +78,14 @@
     for (index = 0; index < cubicTests_count; ++index) {
         const SkDCubic& cubic = cubicTests[index];
         rect.setRawBounds(cubic);
-        REPORTER_ASSERT(reporter, rect.fLeft == SkTMin<double>(cubic[0].fX,
-                SkTMin<double>(cubic[1].fX, SkTMin<double>(cubic[2].fX, cubic[3].fX))));
-        REPORTER_ASSERT(reporter, rect.fTop == SkTMin<double>(cubic[0].fY,
-                SkTMin<double>(cubic[1].fY, SkTMin<double>(cubic[2].fY, cubic[3].fY))));
-        REPORTER_ASSERT(reporter, rect.fRight == SkTMax<double>(cubic[0].fX,
-                SkTMax<double>(cubic[1].fX, SkTMax<double>(cubic[2].fX, cubic[3].fX))));
-        REPORTER_ASSERT(reporter, rect.fBottom == SkTMax<double>(cubic[0].fY,
-                SkTMax<double>(cubic[1].fY, SkTMax<double>(cubic[2].fY, cubic[3].fY))));
+        REPORTER_ASSERT(reporter, rect.fLeft == SkTMin(cubic[0].fX,
+                SkTMin(cubic[1].fX, SkTMin(cubic[2].fX, cubic[3].fX))));
+        REPORTER_ASSERT(reporter, rect.fTop == SkTMin(cubic[0].fY,
+                SkTMin(cubic[1].fY, SkTMin(cubic[2].fY, cubic[3].fY))));
+        REPORTER_ASSERT(reporter, rect.fRight == SkTMax(cubic[0].fX,
+                SkTMax(cubic[1].fX, SkTMax(cubic[2].fX, cubic[3].fX))));
+        REPORTER_ASSERT(reporter, rect.fBottom == SkTMax(cubic[0].fY,
+                SkTMax(cubic[1].fY, SkTMax(cubic[2].fY, cubic[3].fY))));
         rect2.setBounds(cubic);
         REPORTER_ASSERT(reporter, rect.intersects(&rect2));
         // FIXME: add a recursive box subdivision method to verify that tight bounds is correct