Index: src/core/SkGeometry.cpp |
diff --git a/src/core/SkGeometry.cpp b/src/core/SkGeometry.cpp |
index 027b65f0f1962e82e0bbfc38afb77184a23fdc12..cb515e1d14b1eb06de3c415e32cee7c5e62c6713 100644 |
--- a/src/core/SkGeometry.cpp |
+++ b/src/core/SkGeometry.cpp |
@@ -975,7 +975,8 @@ static void ratquad_mapTo3D(const SkPoint src[3], SkScalar w, SkP3D dst[]) { |
dst[2].set(src[2].fX * 1, src[2].fY * 1, 1); |
} |
-void SkConic::chopAt(SkScalar t, SkConic dst[2]) const { |
+// return false if infinity or NaN is generated; caller must check |
+bool SkConic::chopAt(SkScalar t, SkConic dst[2]) const { |
SkP3D tmp[3], tmp2[3]; |
ratquad_mapTo3D(fPts, fW, tmp); |
@@ -1001,18 +1002,23 @@ void SkConic::chopAt(SkScalar t, SkConic dst[2]) const { |
SkScalar root = SkScalarSqrt(tmp2[1].fZ); |
dst[0].fW = tmp2[0].fZ / root; |
dst[1].fW = tmp2[2].fZ / root; |
+ SkASSERT(sizeof(dst[0]) == sizeof(SkScalar) * 7); |
+ SkASSERT(0 == offsetof(SkConic, fPts[0].fX)); |
+ return SkScalarsAreFinite(&dst[0].fPts[0].fX, 7 * 2); |
} |
void SkConic::chopAt(SkScalar t1, SkScalar t2, SkConic* dst) const { |
if (0 == t1 || 1 == t2) { |
if (0 == t1 && 1 == t2) { |
*dst = *this; |
+ return; |
} else { |
SkConic pair[2]; |
- this->chopAt(t1 ? t1 : t2, pair); |
- *dst = pair[SkToBool(t1)]; |
+ if (this->chopAt(t1 ? t1 : t2, pair)) { |
+ *dst = pair[SkToBool(t1)]; |
+ return; |
+ } |
} |
- return; |
} |
SkConicCoeff coeff(*this); |
Sk2s tt1(t1); |
@@ -1243,7 +1249,10 @@ bool SkConic::findYExtrema(SkScalar* t) const { |
bool SkConic::chopAtXExtrema(SkConic dst[2]) const { |
SkScalar t; |
if (this->findXExtrema(&t)) { |
- this->chopAt(t, dst); |
+ if (!this->chopAt(t, dst)) { |
+ // if chop can't return finite values, don't chop |
+ return false; |
+ } |
// now clean-up the middle, since we know t was meant to be at |
// an X-extrema |
SkScalar value = dst[0].fPts[2].fX; |
@@ -1258,7 +1267,10 @@ bool SkConic::chopAtXExtrema(SkConic dst[2]) const { |
bool SkConic::chopAtYExtrema(SkConic dst[2]) const { |
SkScalar t; |
if (this->findYExtrema(&t)) { |
- this->chopAt(t, dst); |
+ if (!this->chopAt(t, dst)) { |
+ // if chop can't return finite values, don't chop |
+ return false; |
+ } |
// now clean-up the middle, since we know t was meant to be at |
// an Y-extrema |
SkScalar value = dst[0].fPts[2].fY; |