aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/pathops/SkPathOpsConic.cpp40
-rw-r--r--tests/PathOpsSimplifyTest.cpp18
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),