| Index: src/pathops/SkDLineIntersection.cpp
|
| diff --git a/src/pathops/SkDLineIntersection.cpp b/src/pathops/SkDLineIntersection.cpp
|
| index 4b818dcb97f70be50b2a9c229be3a64bea25c43b..fca0a04d1f0f4b0953876541ed4cc46ec256eeab 100644
|
| --- a/src/pathops/SkDLineIntersection.cpp
|
| +++ b/src/pathops/SkDLineIntersection.cpp
|
| @@ -26,15 +26,44 @@ SkDPoint SkIntersections::Line(const SkDLine& a, const SkDLine& b) {
|
| return p;
|
| }
|
|
|
| -int SkIntersections::computePoints(const SkDLine& line, int used) {
|
| +void SkIntersections::cleanUpCoincidence() {
|
| + SkASSERT(fUsed == 2);
|
| + // both t values are good
|
| + bool startMatch = fT[0][0] == 0 && (fT[1][0] == 0 || fT[1][0] == 1);
|
| + bool endMatch = fT[0][1] == 1 && (fT[1][1] == 0 || fT[1][1] == 1);
|
| + if (startMatch || endMatch) {
|
| + removeOne(startMatch);
|
| + return;
|
| + }
|
| + // either t value is good
|
| + bool pStartMatch = fT[0][0] == 0 || fT[1][0] == 0 || fT[1][0] == 1;
|
| + bool pEndMatch = fT[0][1] == 1 || fT[1][1] == 0 || fT[1][1] == 1;
|
| + removeOne(pStartMatch || !pEndMatch);
|
| +}
|
| +
|
| +void SkIntersections::cleanUpParallelLines(bool parallel) {
|
| + while (fUsed > 2) {
|
| + removeOne(1);
|
| + }
|
| + if (fUsed == 2 && !parallel) {
|
| + bool startMatch = fT[0][0] == 0 || fT[1][0] == 0 || fT[1][0] == 1;
|
| + bool endMatch = fT[0][1] == 1 || fT[1][1] == 0 || fT[1][1] == 1;
|
| + if ((!startMatch && !endMatch) || approximately_equal(fT[0][0], fT[0][1])) {
|
| + SkASSERT(startMatch || endMatch);
|
| + removeOne(endMatch);
|
| + }
|
| + }
|
| +}
|
| +
|
| +void SkIntersections::computePoints(const SkDLine& line, int used) {
|
| fPt[0] = line.ptAtT(fT[0][0]);
|
| if ((fUsed = used) == 2) {
|
| fPt[1] = line.ptAtT(fT[0][1]);
|
| }
|
| - return fUsed;
|
| }
|
|
|
| int SkIntersections::intersectRay(const SkDLine& a, const SkDLine& b) {
|
| + fMax = 2;
|
| SkDVector aLen = a[1] - a[0];
|
| SkDVector bLen = b[1] - b[0];
|
| /* Slopes match when denom goes to zero:
|
| @@ -69,11 +98,13 @@ int SkIntersections::intersectRay(const SkDLine& a, const SkDLine& b) {
|
| fT[1][0] = fT[1][1] = 1;
|
| used = 2;
|
| }
|
| - return computePoints(a, used);
|
| + computePoints(a, used);
|
| + return fUsed;
|
| }
|
|
|
| // note that this only works if both lines are neither horizontal nor vertical
|
| int SkIntersections::intersect(const SkDLine& a, const SkDLine& b) {
|
| + fMax = 3; // note that we clean up so that there is no more than two in the end
|
| // see if end points intersect the opposite line
|
| double t;
|
| for (int iA = 0; iA < 2; ++iA) {
|
| @@ -103,8 +134,9 @@ int SkIntersections::intersect(const SkDLine& a, const SkDLine& b) {
|
| double ayBxLen = ayLen * bxLen;
|
| // detect parallel lines the same way here and in SkOpAngle operator <
|
| // so that non-parallel means they are also sortable
|
| - bool unparallel = NotAlmostEqualUlps(axByLen, ayBxLen);
|
| - if (unparallel) {
|
| + bool unparallel = fAllowNear ? NotAlmostEqualUlps(axByLen, ayBxLen)
|
| + : NotAlmostDequalUlps(axByLen, ayBxLen);
|
| + if (unparallel && fUsed == 0) {
|
| double ab0y = a[0].fY - b[0].fY;
|
| double ab0x = a[0].fX - b[0].fX;
|
| double numerA = ab0y * bxLen - byLen * ab0x;
|
| @@ -128,17 +160,8 @@ int SkIntersections::intersect(const SkDLine& a, const SkDLine& b) {
|
| }
|
| }
|
| }
|
| - while (fUsed > 2) {
|
| - removeOne(1);
|
| - }
|
| - if (fUsed == 2 && unparallel) {
|
| - bool startMatch = fT[0][0] == 0 || fT[1][0] == 0 || fT[1][0] == 1;
|
| - bool endMatch = fT[0][1] == 1 || fT[1][1] == 0 || fT[1][1] == 1;
|
| - if (!startMatch && !endMatch) {
|
| - SkASSERT(startMatch || endMatch);
|
| - removeOne(endMatch);
|
| - }
|
| - }
|
| + cleanUpParallelLines(!unparallel);
|
| + SkASSERT(fUsed <= 2);
|
| return fUsed;
|
| }
|
|
|
| @@ -162,6 +185,7 @@ static double horizontal_intercept(const SkDLine& line, double y) {
|
| }
|
|
|
| int SkIntersections::horizontal(const SkDLine& line, double y) {
|
| + fMax = 2;
|
| int horizontalType = horizontal_coincident(line, y);
|
| if (horizontalType == 1) {
|
| fT[0][0] = horizontal_intercept(line, y);
|
| @@ -174,6 +198,7 @@ int SkIntersections::horizontal(const SkDLine& line, double y) {
|
|
|
| int SkIntersections::horizontal(const SkDLine& line, double left, double right,
|
| double y, bool flipped) {
|
| + fMax = 2;
|
| // see if end points intersect the opposite line
|
| double t;
|
| const SkDPoint leftPt = { left, y };
|
| @@ -203,26 +228,26 @@ int SkIntersections::horizontal(const SkDLine& line, double left, double right,
|
| fT[1][index] = 1 - fT[1][index];
|
| }
|
| }
|
| - return computePoints(line, result);
|
| + computePoints(line, result);
|
| }
|
| }
|
| - if (!fAllowNear && result != 2) {
|
| - return fUsed;
|
| - }
|
| - if ((t = line.nearPoint(leftPt)) >= 0) {
|
| - insert(t, (double) flipped, leftPt);
|
| - }
|
| - if (left != right) {
|
| - const SkDPoint rightPt = { right, y };
|
| - if ((t = line.nearPoint(rightPt)) >= 0) {
|
| - insert(t, (double) !flipped, rightPt);
|
| + if (fAllowNear || result == 2) {
|
| + if ((t = line.nearPoint(leftPt)) >= 0) {
|
| + insert(t, (double) flipped, leftPt);
|
| }
|
| - for (int index = 0; index < 2; ++index) {
|
| - if ((t = SkDLine::NearPointH(line[index], left, right, y)) >= 0) {
|
| - insert((double) index, flipped ? 1 - t : t, line[index]);
|
| + if (left != right) {
|
| + const SkDPoint rightPt = { right, y };
|
| + if ((t = line.nearPoint(rightPt)) >= 0) {
|
| + insert(t, (double) !flipped, rightPt);
|
| + }
|
| + for (int index = 0; index < 2; ++index) {
|
| + if ((t = SkDLine::NearPointH(line[index], left, right, y)) >= 0) {
|
| + insert((double) index, flipped ? 1 - t : t, line[index]);
|
| + }
|
| }
|
| }
|
| }
|
| + cleanUpParallelLines(result == 2);
|
| return fUsed;
|
| }
|
|
|
| @@ -246,6 +271,7 @@ static double vertical_intercept(const SkDLine& line, double x) {
|
| }
|
|
|
| int SkIntersections::vertical(const SkDLine& line, double x) {
|
| + fMax = 2;
|
| int verticalType = vertical_coincident(line, x);
|
| if (verticalType == 1) {
|
| fT[0][0] = vertical_intercept(line, x);
|
| @@ -258,6 +284,7 @@ int SkIntersections::vertical(const SkDLine& line, double x) {
|
|
|
| int SkIntersections::vertical(const SkDLine& line, double top, double bottom,
|
| double x, bool flipped) {
|
| + fMax = 2;
|
| // see if end points intersect the opposite line
|
| double t;
|
| SkDPoint topPt = { x, top };
|
| @@ -287,26 +314,26 @@ int SkIntersections::vertical(const SkDLine& line, double top, double bottom,
|
| fT[1][index] = 1 - fT[1][index];
|
| }
|
| }
|
| - return computePoints(line, result);
|
| + computePoints(line, result);
|
| }
|
| }
|
| - if (!fAllowNear && result != 2) {
|
| - return fUsed;
|
| - }
|
| - if ((t = line.nearPoint(topPt)) >= 0) {
|
| - insert(t, (double) flipped, topPt);
|
| - }
|
| - if (top != bottom) {
|
| - SkDPoint bottomPt = { x, bottom };
|
| - if ((t = line.nearPoint(bottomPt)) >= 0) {
|
| - insert(t, (double) !flipped, bottomPt);
|
| + if (fAllowNear || result == 2) {
|
| + if ((t = line.nearPoint(topPt)) >= 0) {
|
| + insert(t, (double) flipped, topPt);
|
| }
|
| - for (int index = 0; index < 2; ++index) {
|
| - if ((t = SkDLine::NearPointV(line[index], top, bottom, x)) >= 0) {
|
| - insert((double) index, flipped ? 1 - t : t, line[index]);
|
| + if (top != bottom) {
|
| + SkDPoint bottomPt = { x, bottom };
|
| + if ((t = line.nearPoint(bottomPt)) >= 0) {
|
| + insert(t, (double) !flipped, bottomPt);
|
| + }
|
| + for (int index = 0; index < 2; ++index) {
|
| + if ((t = SkDLine::NearPointV(line[index], top, bottom, x)) >= 0) {
|
| + insert((double) index, flipped ? 1 - t : t, line[index]);
|
| + }
|
| }
|
| }
|
| }
|
| + cleanUpParallelLines(result == 2);
|
| return fUsed;
|
| }
|
|
|
|
|