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