increase iteration count from 16 to 24, when computing cubic-line intersection.
authorreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 18 Jan 2013 17:49:28 +0000 (17:49 +0000)
committerreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 18 Jan 2013 17:49:28 +0000 (17:49 +0000)
This fixes crbug 170666. Before the fix, were were finishing the "clip" step
with a curve that was still partly negative, and so as assert would fire.

added unittest to confirm that the assert doesn't fire.

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

src/core/SkEdgeClipper.cpp
tests/PathTest.cpp

index 84d6e9b6c2ed14e620b659d6f04210c2bfc93085..11b919a9f58950f08f92146e5318b453982c0af5 100644 (file)
@@ -246,7 +246,7 @@ static bool chopMonoCubicAt(SkScalar c0, SkScalar c1, SkScalar c2, SkScalar c3,
     SkScalar maxT = SK_Scalar1;
     SkScalar mid;
     int i;
-    for (i = 0; i < 16; i++) {
+    for (i = 0; i < 24; i++) {
         mid = SkScalarAve(minT, maxT);
         SkScalar delta = eval_cubic_coeff(A, B, C, D, mid);
         if (delta < 0) {
index 0cdc58d831a7dfbe6f778e2837bbe7b898215d3e..ee101402df31a8eb3e23e3275f6352bdf6a9f3da 100644 (file)
@@ -31,6 +31,108 @@ static SkSurface* new_surface(int w, int h) {
     return SkSurface::NewRaster(info);
 }
 
+static void build_path_170666(SkPath& path) {
+    path.moveTo(17.9459f, 21.6344f);
+    path.lineTo(139.545f, -47.8105f);
+    path.lineTo(139.545f, -47.8105f);
+    path.lineTo(131.07f, -47.3888f);
+    path.lineTo(131.07f, -47.3888f);
+    path.lineTo(122.586f, -46.9532f);
+    path.lineTo(122.586f, -46.9532f);
+    path.lineTo(18076.6f, 31390.9f);
+    path.lineTo(18076.6f, 31390.9f);
+    path.lineTo(18085.1f, 31390.5f);
+    path.lineTo(18085.1f, 31390.5f);
+    path.lineTo(18076.6f, 31390.9f);
+    path.lineTo(18076.6f, 31390.9f);
+    path.lineTo(17955, 31460.3f);
+    path.lineTo(17955, 31460.3f);
+    path.lineTo(17963.5f, 31459.9f);
+    path.lineTo(17963.5f, 31459.9f);
+    path.lineTo(17971.9f, 31459.5f);
+    path.lineTo(17971.9f, 31459.5f);
+    path.lineTo(17.9551f, 21.6205f);
+    path.lineTo(17.9551f, 21.6205f);
+    path.lineTo(9.47091f, 22.0561f);
+    path.lineTo(9.47091f, 22.0561f);
+    path.lineTo(17.9459f, 21.6344f);
+    path.lineTo(17.9459f, 21.6344f);
+    path.close();path.moveTo(0.995934f, 22.4779f);
+    path.lineTo(0.986725f, 22.4918f);
+    path.lineTo(0.986725f, 22.4918f);
+    path.lineTo(17955, 31460.4f);
+    path.lineTo(17955, 31460.4f);
+    path.lineTo(17971.9f, 31459.5f);
+    path.lineTo(17971.9f, 31459.5f);
+    path.lineTo(18093.6f, 31390.1f);
+    path.lineTo(18093.6f, 31390.1f);
+    path.lineTo(18093.6f, 31390);
+    path.lineTo(18093.6f, 31390);
+    path.lineTo(139.555f, -47.8244f);
+    path.lineTo(139.555f, -47.8244f);
+    path.lineTo(122.595f, -46.9671f);
+    path.lineTo(122.595f, -46.9671f);
+    path.lineTo(0.995934f, 22.4779f);
+    path.lineTo(0.995934f, 22.4779f);
+    path.close();
+    path.moveTo(5.43941f, 25.5223f);
+    path.lineTo(798267, -28871.1f);
+    path.lineTo(798267, -28871.1f);
+    path.lineTo(3.12512e+06f, -113102);
+    path.lineTo(3.12512e+06f, -113102);
+    path.cubicTo(5.16324e+06f, -186882, 8.15247e+06f, -295092, 1.1957e+07f, -432813);
+    path.cubicTo(1.95659e+07f, -708257, 3.04359e+07f, -1.10175e+06f, 4.34798e+07f, -1.57394e+06f);
+    path.cubicTo(6.95677e+07f, -2.51831e+06f, 1.04352e+08f, -3.77748e+06f, 1.39135e+08f, -5.03666e+06f);
+    path.cubicTo(1.73919e+08f, -6.29583e+06f, 2.08703e+08f, -7.555e+06f, 2.34791e+08f, -8.49938e+06f);
+    path.cubicTo(2.47835e+08f, -8.97157e+06f, 2.58705e+08f, -9.36506e+06f, 2.66314e+08f, -9.6405e+06f);
+    path.cubicTo(2.70118e+08f, -9.77823e+06f, 2.73108e+08f, -9.88644e+06f, 2.75146e+08f, -9.96022e+06f);
+    path.cubicTo(2.76165e+08f, -9.99711e+06f, 2.76946e+08f, -1.00254e+07f, 2.77473e+08f, -1.00444e+07f);
+    path.lineTo(2.78271e+08f, -1.00733e+07f);
+    path.lineTo(2.78271e+08f, -1.00733e+07f);
+    path.cubicTo(2.78271e+08f, -1.00733e+07f, 2.08703e+08f, -7.555e+06f, 135.238f, 23.3517f);
+    path.cubicTo(131.191f, 23.4981f, 125.995f, 23.7976f, 123.631f, 24.0206f);
+    path.cubicTo(121.267f, 24.2436f, 122.631f, 24.3056f, 126.677f, 24.1591f);
+    path.cubicTo(2.08703e+08f, -7.555e+06f, 2.78271e+08f, -1.00733e+07f, 2.78271e+08f, -1.00733e+07f);
+    path.lineTo(2.77473e+08f, -1.00444e+07f);
+    path.lineTo(2.77473e+08f, -1.00444e+07f);
+    path.cubicTo(2.76946e+08f, -1.00254e+07f, 2.76165e+08f, -9.99711e+06f, 2.75146e+08f, -9.96022e+06f);
+    path.cubicTo(2.73108e+08f, -9.88644e+06f, 2.70118e+08f, -9.77823e+06f, 2.66314e+08f, -9.6405e+06f);
+    path.cubicTo(2.58705e+08f, -9.36506e+06f, 2.47835e+08f, -8.97157e+06f, 2.34791e+08f, -8.49938e+06f);
+    path.cubicTo(2.08703e+08f, -7.555e+06f, 1.73919e+08f, -6.29583e+06f, 1.39135e+08f, -5.03666e+06f);
+    path.cubicTo(1.04352e+08f, -3.77749e+06f, 6.95677e+07f, -2.51831e+06f, 4.34798e+07f, -1.57394e+06f);
+    path.cubicTo(3.04359e+07f, -1.10175e+06f, 1.95659e+07f, -708258, 1.1957e+07f, -432814);
+    path.cubicTo(8.15248e+06f, -295092, 5.16324e+06f, -186883, 3.12513e+06f, -113103);
+    path.lineTo(798284, -28872);
+    path.lineTo(798284, -28872);
+    path.lineTo(22.4044f, 24.6677f);
+    path.lineTo(22.4044f, 24.6677f);
+    path.cubicTo(22.5186f, 24.5432f, 18.8134f, 24.6337f, 14.1287f, 24.8697f);
+    path.cubicTo(9.4439f, 25.1057f, 5.55359f, 25.3978f, 5.43941f, 25.5223f);
+    path.close();
+}
+
+static void build_path_simple_170666(SkPath& path) {
+    path.moveTo(126.677f, 24.1591f);
+    path.cubicTo(2.08703e+08f, -7.555e+06f, 2.78271e+08f, -1.00733e+07f, 2.78271e+08f, -1.00733e+07f);
+}
+
+// This used to assert in the SK_DEBUG build, as the clip step would fail with
+// too-few interations in our cubic-line intersection code. That code now runs
+// 24 interations (instead of 16).
+static void test_crbug_170666(skiatest::Reporter* reporter) {
+    SkPath path;
+    SkPaint paint;
+    paint.setAntiAlias(true);
+
+    SkAutoTUnref<SkSurface> surface(new_surface(1000, 1000));
+    
+    build_path_simple_170666(path);
+    surface->getCanvas()->drawPath(path, paint);
+    
+    build_path_170666(path);
+    surface->getCanvas()->drawPath(path, paint);
+}
+
 // Make sure we stay non-finite once we get there (unless we reset or rewind).
 static void test_addrect_isfinite(skiatest::Reporter* reporter) {
     SkPath path;
@@ -2254,6 +2356,7 @@ static void TestPath(skiatest::Reporter* reporter) {
     test_arb_zero_rad_round_rect_is_rect(reporter);
     test_addrect_isfinite(reporter);
     test_clipped_cubic(reporter);
+    test_crbug_170666(reporter);
 }
 
 #include "TestClassDef.h"