From 406e44949c3c766a74e18b49f2f1f4e29f862ba8 Mon Sep 17 00:00:00 2001 From: caryclark Date: Tue, 6 Sep 2016 08:54:10 -0700 Subject: [PATCH] compare degenerates with tolerance 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 | 3 ++- tests/PathTest.cpp | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/core/SkGeometry.cpp b/src/core/SkGeometry.cpp index 03a63b2..6a25ef8 100644 --- a/src/core/SkGeometry.cpp +++ b/src/core/SkGeometry.cpp @@ -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 - 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; diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp index 429d9e9..032b646 100644 --- a/tests/PathTest.cpp +++ b/tests/PathTest.cpp @@ -138,6 +138,25 @@ static void test_fuzz_crbug_638223() { 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. @@ -4256,6 +4275,7 @@ DEF_TEST(PathContains, reporter) { } DEF_TEST(Paths, reporter) { + test_fuzz_crbug_643933(); test_sect_with_horizontal_needs_pinning(); test_crbug_629455(reporter); test_fuzz_crbug_627414(reporter); -- 2.7.4