handle NaN in curve choppers and edgeclipper
authorreed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 8 Mar 2010 17:44:42 +0000 (17:44 +0000)
committerreed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 8 Mar 2010 17:44:42 +0000 (17:44 +0000)
git-svn-id: http://skia.googlecode.com/svn/trunk@522 2bbb7eff-a529-9590-31e7-b0007b416f81

src/core/SkEdgeClipper.cpp
src/core/SkGeometry.cpp

index d41291d..a265d9f 100644 (file)
@@ -280,7 +280,11 @@ static void chop_cubic_in_Y(SkPoint pts[4], const SkRect& clip) {
     if (pts[0].fY < clip.fTop) {
         if (chopMonoCubicAtY(pts, clip.fTop, &t)) {
             SkChopCubicAt(pts, tmp, t);
-            clamp_ge(tmp[3].fY, clip.fTop);
+            // given the imprecision of computing t, we just slam our Y coord
+            // to the top of the clip. This also saves us in the bad case where
+            // the t was soooo bad that the entire segment could have been
+            // below fBottom
+            tmp[3].fY = clip.fTop;
             clamp_ge(tmp[4].fY, clip.fTop);
             clamp_ge(tmp[5].fY, clip.fTop);
             pts[0] = tmp[3];
@@ -324,10 +328,10 @@ void SkEdgeClipper::clipMonoCubic(const SkPoint src[4], const SkRect& clip) {
     if (pts[3].fY <= clip.fTop || pts[0].fY >= clip.fBottom) {
         return;
     }
-    
+
     // Now chop so that pts is contained within clip in Y
     chop_cubic_in_Y(pts, clip);
-    
+
     if (pts[0].fX > pts[3].fX) {
         SkTSwap<SkPoint>(pts[0], pts[3]);
         SkTSwap<SkPoint>(pts[1], pts[2]);
index c0ef4a5..34a0fe0 100644 (file)
@@ -100,6 +100,9 @@ static int valid_unit_divide(SkScalar numer, SkScalar denom, SkScalar* ratio)
         return 0;
 
     SkScalar r = SkScalarDiv(numer, denom);
+    if (SkScalarIsNaN(r)) {
+        return 0;
+    }
     SkASSERT(r >= 0 && r < SK_Scalar1);
     if (r == 0) // catch underflow if numer <<<< denom
         return 0;
@@ -124,8 +127,9 @@ int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2])
 
 #ifdef SK_SCALAR_IS_FLOAT
     float R = B*B - 4*A*C;
-    if (R < 0)  // complex roots
+    if (R < 0 || SkScalarIsNaN(R)) {  // complex roots
         return 0;
+    }
     R = sk_float_sqrt(R);
 #else
     Sk64    RR, tmp;