fix clamping when we chop a cubic
authorreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 16 Apr 2012 16:27:09 +0000 (16:27 +0000)
committerreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 16 Apr 2012 16:27:09 +0000 (16:27 +0000)
Review URL: https://codereview.appspot.com/6039048

git-svn-id: http://skia.googlecode.com/svn/trunk@3691 2bbb7eff-a529-9590-31e7-b0007b416f81

src/core/SkEdgeClipper.cpp
tests/DrawPathTest.cpp

index 70da7e64057e55c9a92c5a7da78a2232922e317a..14afce5786f31021f1c60a977b20bc0dab60ad51 100644 (file)
@@ -286,8 +286,8 @@ static void chop_cubic_in_Y(SkPoint pts[4], const SkRect& clip) {
             // still be monotonic in Y. Since we can't trust the numerics of
             // the chopper, we force those conditions now
             tmp[3].fY = clip.fTop;
-            tmp[4].fY = SkMaxScalar(tmp[4].fY, clip.fTop);
-            tmp[5].fY = SkMaxScalar(tmp[5].fY, tmp[4].fY);
+            clamp_ge(tmp[4].fY, clip.fTop);
+            clamp_ge(tmp[5].fY, tmp[4].fY);
 
             pts[0] = tmp[3];
             pts[1] = tmp[4];
@@ -307,9 +307,10 @@ static void chop_cubic_in_Y(SkPoint pts[4], const SkRect& clip) {
         if (chopMonoCubicAtY(pts, clip.fBottom, &t)) {
             SkPoint tmp[7];
             SkChopCubicAt(pts, tmp, t);
-            clamp_le(tmp[1].fY, clip.fBottom);
+            tmp[3].fY = clip.fBottom;
             clamp_le(tmp[2].fY, clip.fBottom);
-            clamp_le(tmp[3].fY, clip.fBottom);
+            clamp_le(tmp[1].fY, tmp[2].fY);
+
             pts[1] = tmp[1];
             pts[2] = tmp[2];
             pts[3] = tmp[3];
@@ -365,8 +366,8 @@ void SkEdgeClipper::clipMonoCubic(const SkPoint src[4], const SkRect& clip) {
             // still be monotonic in X. Since we can't trust the numerics of
             // the chopper, we force those conditions now
             tmp[3].fX = clip.fLeft;
-            tmp[4].fX = SkMaxScalar(tmp[4].fX, clip.fLeft);
-            tmp[5].fX = SkMaxScalar(tmp[5].fX, tmp[4].fX);
+            clamp_ge(tmp[4].fX, clip.fLeft);
+            clamp_ge(tmp[5].fX, tmp[4].fX);
 
             pts[0] = tmp[3];
             pts[1] = tmp[4];
@@ -385,9 +386,10 @@ void SkEdgeClipper::clipMonoCubic(const SkPoint src[4], const SkRect& clip) {
         if (chopMonoCubicAtX(pts, clip.fRight, &t)) {
             SkPoint tmp[7];
             SkChopCubicAt(pts, tmp, t);
-            clamp_le(tmp[1].fX, clip.fRight);
+            tmp[3].fX = clip.fRight;
             clamp_le(tmp[2].fX, clip.fRight);
-            clamp_le(tmp[3].fX, clip.fRight);
+            clamp_le(tmp[1].fX, tmp[2].fX);
+
             this->appendCubic(tmp, reverse);
             this->appendVLine(clip.fRight, tmp[3].fY, tmp[6].fY, reverse);
         } else {
index f0556c278fc45f70733a60a98e7bedf918f81a74..9bbb88f7e8c6b67d3fce166a3dd6e9df55aa0b1b 100644 (file)
@@ -25,6 +25,8 @@ static SkCanvas* new_canvas(int w, int h) {
     return create(SkBitmap::kARGB_8888_Config, w, h, 0, NULL);
 }
 
+///////////////////////////////////////////////////////////////////////////////
+
 static void test_bug533(skiatest::Reporter* reporter) {
 #ifdef SK_SCALAR_IS_FLOAT
     /*
@@ -44,6 +46,20 @@ static void test_bug533(skiatest::Reporter* reporter) {
 #endif
 }
 
+static void test_bigcubic(skiatest::Reporter* reporter) {
+#ifdef SK_SCALAR_IS_FLOAT
+    SkPath path;
+    path.moveTo(64, 3);
+    path.cubicTo(-329936, -100000000, -329936, 100000000, 1153, 330003);
+    
+    SkPaint paint;
+    paint.setAntiAlias(true);
+    
+    SkAutoTUnref<SkCanvas> canvas(new_canvas(640, 480));
+    canvas.get()->drawPath(path, paint);
+#endif
+}
+
 // we used to assert if the bounds of the device (clip) was larger than 32K
 // even when the path itself was smaller. We just draw and hope in the debug
 // version to not assert.
@@ -63,6 +79,7 @@ static void test_giantaa(skiatest::Reporter* reporter) {
 static void TestDrawPath(skiatest::Reporter* reporter) {
     test_giantaa(reporter);
     test_bug533(reporter);
+    test_bigcubic(reporter);
 }
 
 #include "TestClassDef.h"