Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(807)

Unified Diff: src/pathops/SkDLineIntersection.cpp

Issue 23542056: path ops work in progress (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: verbose + mutex around file number access Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/pathops/SkDCubicLineIntersection.cpp ('k') | src/pathops/SkDQuadImplicit.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
}
« no previous file with comments | « src/pathops/SkDCubicLineIntersection.cpp ('k') | src/pathops/SkDQuadImplicit.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698