diff options
-rw-r--r-- | src/pathops/SkPathOpsConic.cpp | 40 | ||||
-rw-r--r-- | tests/PathOpsSimplifyTest.cpp | 18 |
2 files changed, 52 insertions, 6 deletions
diff --git a/src/pathops/SkPathOpsConic.cpp b/src/pathops/SkPathOpsConic.cpp index b9b0cda0d4..82353d67b5 100644 --- a/src/pathops/SkPathOpsConic.cpp +++ b/src/pathops/SkPathOpsConic.cpp @@ -74,6 +74,12 @@ bool SkDConic::hullIntersects(const SkDCubic& cubic, bool* isLinear) const { } SkDPoint SkDConic::ptAtT(double t) const { + if (t == 0) { + return fPts[0]; + } + if (t == 1) { + return fPts[2]; + } double denominator = conic_eval_denominator(fWeight, t); SkDPoint result = { conic_eval_numerator(&fPts[0].fX, fWeight, t) / denominator, @@ -84,16 +90,38 @@ SkDPoint SkDConic::ptAtT(double t) const { /* see quad subdivide for rationale */ SkDConic SkDConic::subDivide(double t1, double t2) const { - double ax = conic_eval_numerator(&fPts[0].fX, fWeight, t1); - double ay = conic_eval_numerator(&fPts[0].fY, fWeight, t1); - double az = conic_eval_denominator(fWeight, t1); + double ax, ay, az; + if (t1 == 0) { + ax = fPts[0].fX; + ay = fPts[0].fY; + az = 1; + } else if (t1 != 1) { + ax = conic_eval_numerator(&fPts[0].fX, fWeight, t1); + ay = conic_eval_numerator(&fPts[0].fY, fWeight, t1); + az = conic_eval_denominator(fWeight, t1); + } else { + ax = fPts[2].fX; + ay = fPts[2].fY; + az = 1; + } double midT = (t1 + t2) / 2; double dx = conic_eval_numerator(&fPts[0].fX, fWeight, midT); double dy = conic_eval_numerator(&fPts[0].fY, fWeight, midT); double dz = conic_eval_denominator(fWeight, midT); - double cx = conic_eval_numerator(&fPts[0].fX, fWeight, t2); - double cy = conic_eval_numerator(&fPts[0].fY, fWeight, t2); - double cz = conic_eval_denominator(fWeight, t2); + double cx, cy, cz; + if (t2 == 1) { + cx = fPts[2].fX; + cy = fPts[2].fY; + cz = 1; + } else if (t2 != 0) { + cx = conic_eval_numerator(&fPts[0].fX, fWeight, t2); + cy = conic_eval_numerator(&fPts[0].fY, fWeight, t2); + cz = conic_eval_denominator(fWeight, t2); + } else { + cx = fPts[0].fX; + cy = fPts[0].fY; + cz = 1; + } double bx = 2 * dx - (ax + cx) / 2; double by = 2 * dy - (ay + cy) / 2; double bz = 2 * dz - (az + cz) / 2; diff --git a/tests/PathOpsSimplifyTest.cpp b/tests/PathOpsSimplifyTest.cpp index 165ee8d11d..8f03ba0051 100644 --- a/tests/PathOpsSimplifyTest.cpp +++ b/tests/PathOpsSimplifyTest.cpp @@ -4874,11 +4874,29 @@ static void fuzz864a(skiatest::Reporter* reporter,const char* filename) { testSimplify(reporter, path, filename); } +static void cr514118(skiatest::Reporter* reporter,const char* filename) { + SkPath path; +path.moveTo(SkBits2Float(0x42c80000), SkBits2Float(0x42480000)); // 100, 50 +path.conicTo(SkBits2Float(0x42c80000), SkBits2Float(0x00000000), SkBits2Float(0x42480000), SkBits2Float(0x00000000), SkBits2Float(0x3f3504f3)); // 100, 0, 50, 0, 0.707107f +path.conicTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000), SkBits2Float(0x00000000), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 0, 0, 0, 50, 0.707107f +path.conicTo(SkBits2Float(0x00000000), SkBits2Float(0x42c80000), SkBits2Float(0x42480000), SkBits2Float(0x42c80000), SkBits2Float(0x3f3504f3)); // 0, 100, 50, 100, 0.707107f +path.conicTo(SkBits2Float(0x42c80000), SkBits2Float(0x42c80000), SkBits2Float(0x42c80000), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 100, 100, 100, 50, 0.707107f +path.close(); +path.moveTo(SkBits2Float(0x42c80133), SkBits2Float(0x42480000)); // 100.002f, 50 +path.conicTo(SkBits2Float(0x42c80133), SkBits2Float(0x00000000), SkBits2Float(0x42480267), SkBits2Float(0x00000000), SkBits2Float(0x3f3504f3)); // 100.002f, 0, 50.0023f, 0, 0.707107f +path.conicTo(SkBits2Float(0x3b19b530), SkBits2Float(0x00000000), SkBits2Float(0x3b19b530), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 0.00234539f, 0, 0.00234539f, 50, 0.707107f +path.conicTo(SkBits2Float(0x3b19b530), SkBits2Float(0x42c80000), SkBits2Float(0x42480267), SkBits2Float(0x42c80000), SkBits2Float(0x3f3504f3)); // 0.00234539f, 100, 50.0023f, 100, 0.707107f +path.conicTo(SkBits2Float(0x42c80133), SkBits2Float(0x42c80000), SkBits2Float(0x42c80133), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 100.002f, 100, 100.002f, 50, 0.707107f +path.close(); + testSimplify(reporter, path, filename); +} + static void (*skipTest)(skiatest::Reporter* , const char* filename) = 0; static void (*firstTest)(skiatest::Reporter* , const char* filename) = 0; static void (*stopTest)(skiatest::Reporter* , const char* filename) = 0; static TestDesc tests[] = { + TEST(cr514118), TEST(fuzz864a), TEST(testQuads65), TEST(testIssue3838_3), |