compare degenerates with tolerance
authorcaryclark <caryclark@google.com>
Tue, 6 Sep 2016 15:54:10 +0000 (08:54 -0700)
committerCary Clark <caryclark@google.com>
Wed, 14 Sep 2016 14:17:59 +0000 (10:17 -0400)
Conics with very large w values can
be approximated with two straight lines.

This avoids iterating endlessly in an
attempt to create quadratics with unstable
numerics.

Check to see if the first chop generated
a pair of lines within the default
point comparison tolerance.

R=reed@google.com
BUG=643933, 643665
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2312923002

Review-Url: https://codereview.chromium.org/2312923002

src/core/SkGeometry.cpp
tests/PathTest.cpp

index 03a63b2bdad93df6914210968284db92f061b4c9..6a25ef8dbc6c4d1ac7dddb189c574c7f6282c5a8 100644 (file)
@@ -1176,7 +1176,8 @@ int SkConic::chopIntoQuadsPOW2(SkPoint pts[], int pow2) const {
         SkConic dst[2];
         this->chop(dst);
         // check to see if the first chop generates a pair of lines
         SkConic dst[2];
         this->chop(dst);
         // check to see if the first chop generates a pair of lines
-        if (dst[0].fPts[1] == dst[0].fPts[2] && dst[1].fPts[0] == dst[1].fPts[1]) {
+        if (dst[0].fPts[1].equalsWithinTolerance(dst[0].fPts[2])
+                && dst[1].fPts[0].equalsWithinTolerance(dst[1].fPts[1])) {
             pts[1] = pts[2] = pts[3] = dst[0].fPts[1];  // set ctrl == end to make lines
             pts[4] = dst[1].fPts[2];
             pow2 = 1;
             pts[1] = pts[2] = pts[3] = dst[0].fPts[1];  // set ctrl == end to make lines
             pts[4] = dst[1].fPts[2];
             pow2 = 1;
index 429d9e980fa707b4fdfd05b20aa97799a6b8dd38..032b646d4e194314f61be4caf0e58c7b9b791401 100644 (file)
@@ -138,6 +138,25 @@ static void test_fuzz_crbug_638223() {
     canvas->drawPath(path, paint);
 }
 
     canvas->drawPath(path, paint);
 }
 
+static void test_fuzz_crbug_643933() {
+    auto surface(SkSurface::MakeRasterN32Premul(250, 250));
+    SkCanvas* canvas = surface->getCanvas();
+    SkPaint paint;
+    paint.setAntiAlias(true);
+    SkPath path;
+    path.moveTo(0, 0);
+    path.conicTo(SkBits2Float(0x002001f2), SkBits2Float(0x4161ffff),  // 2.93943e-39f, 14.125f
+            SkBits2Float(0x49f7224d), SkBits2Float(0x45eec8df), // 2.02452e+06f, 7641.11f
+            SkBits2Float(0x721aee0c));  // 3.0687e+30f
+    canvas->drawPath(path, paint);
+    path.reset();
+    path.moveTo(0, 0);
+    path.conicTo(SkBits2Float(0x00007ff2), SkBits2Float(0x4169ffff),  // 4.58981e-41f, 14.625f
+        SkBits2Float(0x43ff2261), SkBits2Float(0x41eeea04),  // 510.269f, 29.8643f
+        SkBits2Float(0x5d06eff8));  // 6.07704e+17f
+    canvas->drawPath(path, paint);
+}
+
 /**
  * In debug mode, this path was causing an assertion to fail in
  * SkPathStroker::preJoinTo() and, in Release, the use of an unitialized value.
 /**
  * In debug mode, this path was causing an assertion to fail in
  * SkPathStroker::preJoinTo() and, in Release, the use of an unitialized value.
@@ -4256,6 +4275,7 @@ DEF_TEST(PathContains, reporter) {
 }
 
 DEF_TEST(Paths, reporter) {
 }
 
 DEF_TEST(Paths, reporter) {
+    test_fuzz_crbug_643933();
     test_sect_with_horizontal_needs_pinning();
     test_crbug_629455(reporter);
     test_fuzz_crbug_627414(reporter);
     test_sect_with_horizontal_needs_pinning();
     test_crbug_629455(reporter);
     test_fuzz_crbug_627414(reporter);