aboutsummaryrefslogtreecommitdiffhomepage
path: root/experimental/Intersection
diff options
context:
space:
mode:
authorGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-03-05 22:01:21 +0000
committerGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-03-05 22:01:21 +0000
commit4917f17bf6bd8bff7f4b03717dcb02561cf227c9 (patch)
tree9ffe08f80aab2c515e30f271a1a8c4061b8bb64d /experimental/Intersection
parentceb441476e1712861e87a9bb428f119349ef6bb5 (diff)
work in progress
of note, all edge walker tests succeed at this point git-svn-id: http://skia.googlecode.com/svn/trunk@3330 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'experimental/Intersection')
-rw-r--r--experimental/Intersection/EdgeWalker.cpp123
-rw-r--r--experimental/Intersection/EdgeWalkerPolygons_Test.cpp153
-rw-r--r--experimental/Intersection/EdgeWalkerQuadralaterals_Test.cpp108
-rw-r--r--experimental/Intersection/Intersection_Tests.cpp3
-rw-r--r--experimental/Intersection/Intersection_Tests.h1
-rw-r--r--experimental/Intersection/LineIntersection.cpp2
-rw-r--r--experimental/Intersection/edge.xcodeproj/project.pbxproj4
7 files changed, 344 insertions, 50 deletions
diff --git a/experimental/Intersection/EdgeWalker.cpp b/experimental/Intersection/EdgeWalker.cpp
index 2c1e5f5f4a..771e63960f 100644
--- a/experimental/Intersection/EdgeWalker.cpp
+++ b/experimental/Intersection/EdgeWalker.cpp
@@ -14,9 +14,9 @@
#include "SkTDArray.h"
#include "TSearch.h"
-static bool gShowDebugf = true; // FIXME: remove once debugging is complete
+static bool gShowDebugf = false; // FIXME: remove once debugging is complete
static bool gShowPath = false;
-static bool gDebugLessThan = true;
+static bool gDebugLessThan = false;
static int LineIntersect(const SkPoint a[2], const SkPoint b[2],
double aRange[2], double bRange[2]) {
@@ -165,9 +165,9 @@ public:
if (listIndex >= listCount) {
break;
}
+ int closeEdgeIndex = -listIndex - 1;
SkPoint firstPt, lastLine[2];
bool doMove = true;
- bool closed = false;
int edgeIndex;
do {
SkPoint* ptArray = fEdges[listIndex].fPts;
@@ -193,7 +193,6 @@ public:
lastLine[0] = *start;
lastLine[1] = *end;
doMove = false;
- closed = false;
break;
}
gap = lastLine[1] != *start;
@@ -216,15 +215,6 @@ public:
lastLine[0] = *start;
}
lastLine[1] = *end;
- if (firstPt == *end) {
- simple.lineTo(end->fX, end->fY);
- simple.close();
- if (gShowDebugf) {
- SkDebugf("%s close 1 (%g, %g)\n", __FUNCTION__,
- end->fX, end->fY);
- }
- closed = true;
- }
break;
default:
// FIXME: add other curve types
@@ -237,26 +227,31 @@ public:
edgeIndex = fBottoms[listIndex];
fBottoms[listIndex] = 0;
}
- if (!edgeIndex) {
+ if (edgeIndex) {
+ listIndex = abs(edgeIndex) - 1;
+ if (edgeIndex < 0) {
+ fTops[listIndex] = 0;
+ } else {
+ fBottoms[listIndex] = 0;
+ }
+ }
+ if (edgeIndex == closeEdgeIndex || edgeIndex == 0) {
+ if (lastLine[1] != firstPt) {
+ simple.lineTo(lastLine[1].fX, lastLine[1].fY);
+ }
simple.lineTo(firstPt.fX, firstPt.fY);
simple.close();
if (gShowDebugf) {
- SkDebugf("%s close 2 (%g,%g)\n", __FUNCTION__,
- firstPt.fX, firstPt.fY);
+ SkDebugf("%s close (%g, %g)\n", __FUNCTION__,
+ firstPt.fX, firstPt.fY);
}
break;
}
- listIndex = abs(edgeIndex) - 1;
- if (edgeIndex < 0) {
- fTops[listIndex] = 0;
- } else {
- fBottoms[listIndex] = 0;
- }
// if this and next edge go different directions
if (advance > 0 ^ edgeIndex < 0) {
advance = -advance;
}
- } while (edgeIndex && !closed);
+ } while (edgeIndex);
} while (true);
}
@@ -396,8 +391,15 @@ struct Bounds : public SkRect {
}
};
-struct Intercepts {
+class Intercepts {
+public:
+ Intercepts()
+ : fTopIntercepts(0)
+ , fBottomIntercepts(0) {
+ }
SkTDArray<double> fTs;
+ int fTopIntercepts;
+ int fBottomIntercepts;
};
struct InEdge {
@@ -407,13 +409,18 @@ struct InEdge {
: fBounds.fTop < rh.fBounds.fTop;
}
- bool add(double* ts, size_t count, ptrdiff_t verbIndex) {
+ void add(double* ts, size_t count, ptrdiff_t verbIndex) {
// FIXME: in the pathological case where there is a ton of intercepts, binary search?
bool foundIntercept = false;
Intercepts& intercepts = fIntercepts[verbIndex];
for (size_t index = 0; index < count; ++index) {
double t = ts[index];
- if (t <= 0 || t >= 1) {
+ if (t <= 0) {
+ fContainsIntercepts |= ++intercepts.fTopIntercepts > 1;
+ continue;
+ }
+ if (t >= 1) {
+ fContainsIntercepts |= ++intercepts.fBottomIntercepts > 1;
continue;
}
foundIntercept = true;
@@ -424,14 +431,15 @@ struct InEdge {
if (delta > 0) {
*intercepts.fTs.insert(idx2) = t;
}
- return foundIntercept;
+ fContainsIntercepts = true;
+ return;
}
}
if (tCount == 0 || t > intercepts.fTs[tCount - 1]) {
*intercepts.fTs.append() = t;
}
}
- return foundIntercept;
+ fContainsIntercepts |= foundIntercept;
}
bool cached(const InEdge* edge) {
@@ -483,7 +491,7 @@ struct InEdge {
// temporary data : move this to a separate struct?
SkTDArray<const InEdge*> fCached; // list of edges already intercepted
SkTArray<Intercepts> fIntercepts; // one per verb
-
+
// persistent data
SkTDArray<SkPoint> fPts;
SkTDArray<uint8_t> fVerbs;
@@ -739,8 +747,9 @@ struct ActiveEdge {
void calcLeft(SkScalar y) {
// OPTIMIZE: put a kDone_Verb at the end of the verb list?
- if (done(y))
+ if (fDone || fBelow.fY > y) {
return; // nothing to do; use last
+ }
calcLeft();
}
@@ -772,6 +781,7 @@ struct ActiveEdge {
void init(const InEdge* edge) {
fWorkEdge.init(edge);
initT();
+ fBelow.fY = SK_ScalarMin;
fDone = false;
fYBottom = SK_ScalarMin;
}
@@ -792,7 +802,7 @@ struct ActiveEdge {
// t values, since the same t values could exist intersecting non-coincident
// edges.
bool isCoincidentWith(const ActiveEdge* edge, SkScalar y) const {
- if (fAbove.fX != edge->fAbove.fX || fBelow.fX != edge->fBelow.fX) {
+ if (fAbove != edge->fAbove || fBelow != edge->fBelow) {
return false;
}
uint8_t verb = fDone ? fWorkEdge.lastVerb() : fWorkEdge.verb();
@@ -803,14 +813,7 @@ struct ActiveEdge {
}
switch (verb) {
case SkPath::kLine_Verb: {
- int offset = fDone ? -1 : 1;
- int edgeOffset = edge->fDone ? -1 : 1;
- const SkPoint* pts = fWorkEdge.fPts;
- const SkPoint* edgePts = edge->fWorkEdge.fPts;
- return (pts->fX - pts[offset].fX)
- * (edgePts->fY - edgePts[edgeOffset].fY)
- == (pts->fY - pts[offset].fY)
- * (edgePts->fX - edgePts[edgeOffset].fX);
+ return true;
}
default:
// FIXME: add support for all curve types
@@ -886,7 +889,12 @@ static void addToActive(SkTDArray<ActiveEdge>& activeEdges, const InEdge* edge)
active->init(edge);
}
- // find any intersections in the range of active edges
+// Find any intersections in the range of active edges. A pair of edges, on
+// either side of another edge, may change the winding contribution for part of
+// the edge.
+// OPTIMIZATION: Another approach would be to keep horizontal edges just for
+// the purpose of computing when edges change their winding contribution, since
+// this is essentially computing the horizontal intersection.
static void addBottomT(InEdge** currentPtr, InEdge** lastPtr, SkScalar bottom) {
InEdge** testPtr = currentPtr;
InEdge* test = *testPtr;
@@ -901,8 +909,7 @@ static void addBottomT(InEdge** currentPtr, InEdge** lastPtr, SkScalar bottom) {
double wtTs[2];
int pts = LineIntersect(wt.fPts, bottom, wtTs);
if (pts) {
- test->fContainsIntercepts |= test->add(wtTs, pts,
- wt.verbIndex());
+ test->add(wtTs, pts, wt.verbIndex());
}
} else {
// FIXME: add all curve types
@@ -936,10 +943,8 @@ static void addIntersectingTs(InEdge** currentPtr, InEdge** lastPtr) {
double wtTs[2], wnTs[2];
int pts = LineIntersect(wt.fPts, wn.fPts, wtTs, wnTs);
if (pts) {
- test->fContainsIntercepts |= test->add(wtTs, pts,
- wt.verbIndex());
- next->fContainsIntercepts |= next->add(wnTs, pts,
- wn.verbIndex());
+ test->add(wtTs, pts, wt.verbIndex());
+ next->add(wnTs, pts, wn.verbIndex());
}
} else {
// FIXME: add all combinations of curve types
@@ -987,6 +992,18 @@ static void computeInterceptBottom(SkTDArray<ActiveEdge>& activeEdges,
wt.init(test);
do {
const Intercepts& intercepts = test->fIntercepts[wt.verbIndex()];
+ if (intercepts.fTopIntercepts > 1) {
+ SkScalar yTop = wt.fPts[0].fY;
+ if (yTop > y && bottom > yTop) {
+ bottom = yTop;
+ }
+ }
+ if (intercepts.fBottomIntercepts > 1) {
+ SkScalar yBottom = wt.fPts[wt.verb()].fY;
+ if (yBottom > y && bottom > yBottom) {
+ bottom = yBottom;
+ }
+ }
const SkTDArray<double>& fTs = intercepts.fTs;
size_t count = fTs.count();
for (size_t index = 0; index < count; ++index) {
@@ -1099,8 +1116,10 @@ static void sortHorizontal(SkTDArray<ActiveEdge>& activeEdges,
// and not all at once as is done here, fold this test into the
// current less than test.
if (activePtr->swapCoincident(nextPtr, bottom)) {
+ winding -= activePtr->fWorkEdge.winding();
SkTSwap<ActiveEdge*>(edgeList[index - 1], edgeList[index]);
SkTSwap<ActiveEdge*>(activePtr, nextPtr);
+ winding += activePtr->fWorkEdge.winding();
}
if (!firstCoincident) {
firstCoincident = activePtr;
@@ -1154,7 +1173,8 @@ static void stitchEdge(SkTDArray<ActiveEdge*>& edgeList, SkScalar y,
bool closer = (winding & windingMask) == 0;
SkASSERT(!opener | !closer);
bool inWinding = opener | closer;
- const SkPoint* clipped;
+ SkPoint clippedPts[2];
+ const SkPoint* clipped = NULL;
uint8_t verb = wt.verb();
bool moreToDo, aboveBottom;
do {
@@ -1165,7 +1185,6 @@ static void stitchEdge(SkTDArray<ActiveEdge*>& edgeList, SkScalar y,
do {
nextT = activePtr->nextT();
if (verb == SkPath::kLine_Verb) {
- SkPoint clippedPts[2];
// FIXME: obtuse: want efficient way to say
// !currentT && currentT != 1 || !nextT && nextT != 1
if (currentT * nextT != 0 || currentT + nextT != 1) {
@@ -1184,6 +1203,11 @@ static void stitchEdge(SkTDArray<ActiveEdge*>& edgeList, SkScalar y,
}
outBuilder.addLine(clipped);
}
+ if (clipped[1].fY > activePtr->fBelow.fY
+ && bottom >= activePtr->fBelow.fY ) {
+ activePtr->fAbove = activePtr->fBelow;
+ activePtr->fBelow = clipped[1];
+ }
activePtr->fSkip = false;
} else {
// FIXME: add all curve types
@@ -1214,6 +1238,9 @@ void simplify(const SkPath& path, bool asFill, SkPath& simple) {
InEdge edgeSentinel;
makeEdgeList(edges, edgeSentinel, edgeList);
InEdge** currentPtr = edgeList.begin();
+ if (!currentPtr) {
+ return;
+ }
// walk the sorted edges from top to bottom, computing accumulated winding
SkTDArray<ActiveEdge> activeEdges;
OutEdgeBuilder outBuilder(asFill);
diff --git a/experimental/Intersection/EdgeWalkerPolygons_Test.cpp b/experimental/Intersection/EdgeWalkerPolygons_Test.cpp
index 3ea0e0bae7..07ce6c8f8a 100644
--- a/experimental/Intersection/EdgeWalkerPolygons_Test.cpp
+++ b/experimental/Intersection/EdgeWalkerPolygons_Test.cpp
@@ -245,6 +245,91 @@ static void testSimplifyTriangle17() {
comparePaths(path, out);
}
+static void testSimplifyTriangle18() {
+ SkPath path, out;
+ path.moveTo(0, 0);
+ path.lineTo(0, 1);
+ path.lineTo(1, 2);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(0, 1);
+ path.lineTo(0, 3);
+ path.close();
+ simplify(path, true, out);
+ comparePaths(path, out);
+}
+
+static void testSimplifyTriangle19() {
+ SkPath path, out;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.lineTo(0, 1);
+ path.lineTo(3, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 1);
+ path.lineTo(2, 1);
+ path.close();
+ simplify(path, true, out);
+ comparePaths(path, out);
+}
+
+static void testSimplifyTriangle20() {
+ SkPath path, out;
+ path.moveTo(0, 0);
+ path.lineTo(2, 1);
+ path.lineTo(1, 3);
+ path.close();
+ path.moveTo(2, 0);
+ path.lineTo(3, 2);
+ path.lineTo(0, 3);
+ path.close();
+ simplify(path, true, out);
+ comparePaths(path, out);
+}
+
+static void testSimplifyTriangle21() {
+ SkPath path, out;
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(1, 2);
+ path.close();
+ path.moveTo(2, 0);
+ path.lineTo(2, 1);
+ path.lineTo(0, 3);
+ path.close();
+ simplify(path, true, out);
+ comparePaths(path, out);
+}
+
+static void testSimplifyDegenerateTriangle1() {
+ SkPath path, out;
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(0, 0);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(0, 0);
+ path.close();
+ simplify(path, true, out);
+ comparePaths(path, out);
+}
+
+static void testSimplifyDegenerateTriangle2() {
+ SkPath path, out;
+ path.moveTo(0, 0);
+ path.lineTo(1, 1);
+ path.lineTo(2, 2);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(2, 2);
+ path.lineTo(3, 3);
+ path.close();
+ simplify(path, true, out);
+ comparePaths(path, out);
+}
+
static void testSimplifyWindingParallelogram() {
SkPath path, out;
path.setFillType(SkPath::kWinding_FillType);
@@ -361,6 +446,67 @@ static void testSimplifyNondegenerate4x4Triangles() {
}
}
+static void testSimplifyDegenerate4x4Triangles() {
+ char pathStr[1024];
+ bzero(pathStr, sizeof(pathStr));
+ for (int a = 0; a < 16; ++a) {
+ int ax = a & 0x03;
+ int ay = a >> 2;
+ for (int b = a ; b < 16; ++b) {
+ int bx = b & 0x03;
+ int by = b >> 2;
+ for (int c = a ; c < 16; ++c) {
+ int cx = c & 0x03;
+ int cy = c >> 2;
+ bool abcIsATriangle = (bx - ax) * (cy - ay)
+ != (by - ay) * (cx - ax);
+ for (int d = 0; d < 16; ++d) {
+ int dx = d & 0x03;
+ int dy = d >> 2;
+ for (int e = d ; e < 16; ++e) {
+ int ex = e & 0x03;
+ int ey = e >> 2;
+ for (int f = d ; f < 16; ++f) {
+ int fx = f & 0x03;
+ int fy = f >> 2;
+ if (abcIsATriangle && (ex - dx) * (fy - dy)
+ != (ey - dy) * (fx - dx)) {
+ continue;
+ }
+ SkPath path, out;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(ax, ay);
+ path.lineTo(bx, by);
+ path.lineTo(cx, cy);
+ path.close();
+ path.moveTo(dx, dy);
+ path.lineTo(ex, ey);
+ path.lineTo(fx, fy);
+ path.close();
+ if (1) {
+ char* str = pathStr;
+ str += sprintf(str, " path.moveTo(%d, %d);\n", ax, ay);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", bx, by);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", cx, cy);
+ str += sprintf(str, " path.close();\n");
+ str += sprintf(str, " path.moveTo(%d, %d);\n", dx, dy);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", ex, ey);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", fx, fy);
+ str += sprintf(str, " path.close();");
+ }
+ simplify(path, true, out);
+ comparePaths(path, out);
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ simplify(path, true, out);
+ comparePaths(path, out);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
static void testPathTriangleRendering() {
SkPath one, two;
one.moveTo(0, 0);
@@ -382,6 +528,12 @@ static void testPathTriangleRendering() {
}
static void (*simplifyTests[])() = {
+ testSimplifyDegenerateTriangle2,
+ testSimplifyDegenerateTriangle1,
+ testSimplifyTriangle21,
+ testSimplifyTriangle20,
+ testSimplifyTriangle19,
+ testSimplifyTriangle18,
testSimplifyTriangle17,
testSimplifyTriangle16,
testSimplifyTriangle15,
@@ -401,6 +553,7 @@ static void (*simplifyTests[])() = {
testSimplifyTriangle2,
testSimplifyWindingParallelogram,
testSimplifyXorParallelogram,
+ testSimplifyDegenerate4x4Triangles,
testSimplifyNondegenerate4x4Triangles,
testPathTriangleRendering,
};
diff --git a/experimental/Intersection/EdgeWalkerQuadralaterals_Test.cpp b/experimental/Intersection/EdgeWalkerQuadralaterals_Test.cpp
new file mode 100644
index 0000000000..b22e1a392a
--- /dev/null
+++ b/experimental/Intersection/EdgeWalkerQuadralaterals_Test.cpp
@@ -0,0 +1,108 @@
+#include "EdgeWalker_Test.h"
+#include "Intersection_Tests.h"
+
+static void testSimplifyQuad1() {
+ SkPath path, out;
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(3, 2);
+ path.lineTo(3, 3);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(1, 3);
+ path.lineTo(1, 3);
+ path.lineTo(1, 3);
+ path.close();
+ simplify(path, true, out);
+ comparePaths(path, out);
+}
+
+static void testSimplify4x4Quadralaterals() {
+ char pathStr[1024];
+ bzero(pathStr, sizeof(pathStr));
+ for (int a = 0; a < 16; ++a) {
+ int ax = a & 0x03;
+ int ay = a >> 2;
+ for (int b = a ; b < 16; ++b) {
+ int bx = b & 0x03;
+ int by = b >> 2;
+ for (int c = b ; c < 16; ++c) {
+ int cx = c & 0x03;
+ int cy = c >> 2;
+ for (int d = c; d < 16; ++d) {
+ int dx = d & 0x03;
+ int dy = d >> 2;
+ for (int e = 0 ; e < 16; ++e) {
+ int ex = e & 0x03;
+ int ey = e >> 2;
+ for (int f = e ; f < 16; ++f) {
+ int fx = f & 0x03;
+ int fy = f >> 2;
+ for (int g = f ; g < 16; ++g) {
+ int gx = g & 0x03;
+ int gy = g >> 2;
+ for (int h = g ; g < 16; ++g) {
+ int hx = h & 0x03;
+ int hy = h >> 2;
+ SkPath path, out;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(ax, ay);
+ path.lineTo(bx, by);
+ path.lineTo(cx, cy);
+ path.lineTo(dx, dy);
+ path.close();
+ path.moveTo(ex, ey);
+ path.lineTo(fx, fy);
+ path.lineTo(gx, gy);
+ path.lineTo(hx, hy);
+ path.close();
+ if (1) {
+ char* str = pathStr;
+ str += sprintf(str, " path.moveTo(%d, %d);\n", ax, ay);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", bx, by);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", cx, cy);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", dx, dy);
+ str += sprintf(str, " path.close();\n");
+ str += sprintf(str, " path.moveTo(%d, %d);\n", ex, ey);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", fx, fy);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", gx, gy);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", hx, hy);
+ str += sprintf(str, " path.close();");
+ }
+ simplify(path, true, out);
+ comparePaths(path, out);
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ simplify(path, true, out);
+ comparePaths(path, out);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+static void (*simplifyTests[])() = {
+ testSimplifyQuad1,
+ testSimplify4x4Quadralaterals,
+};
+
+static size_t simplifyTestsCount = sizeof(simplifyTests) / sizeof(simplifyTests[0]);
+
+static void (*firstTest)() = 0;
+
+void SimplifyQuadralateralPaths_Test() {
+ size_t index = 0;
+ if (firstTest) {
+ while (index < simplifyTestsCount && simplifyTests[index] != firstTest) {
+ ++index;
+ }
+ }
+ for ( ; index < simplifyTestsCount; ++index) {
+ (*simplifyTests[index])();
+ }
+}
diff --git a/experimental/Intersection/Intersection_Tests.cpp b/experimental/Intersection/Intersection_Tests.cpp
index 42f4a26e2f..2a1620ee81 100644
--- a/experimental/Intersection/Intersection_Tests.cpp
+++ b/experimental/Intersection/Intersection_Tests.cpp
@@ -17,8 +17,9 @@ void Intersection_Tests() {
LineQuadraticIntersection_Test();
LineCubicIntersection_Test();
- SimplifyPolygonPaths_Test();
SimplifyRectangularPaths_Test();
+ SimplifyPolygonPaths_Test();
+ SimplifyQuadralateralPaths_Test();
QuadraticCoincidence_Test();
QuadraticReduceOrder_Test();
diff --git a/experimental/Intersection/Intersection_Tests.h b/experimental/Intersection/Intersection_Tests.h
index 9def8b551c..f007dda8de 100644
--- a/experimental/Intersection/Intersection_Tests.h
+++ b/experimental/Intersection/Intersection_Tests.h
@@ -12,6 +12,7 @@ void LineIntersection_Test();
void LineParameter_Test();
void LineQuadraticIntersection_Test();
void SimplifyPolygonPaths_Test();
+void SimplifyQuadralateralPaths_Test();
void SimplifyRectangularPaths_Test();
void QuadraticBezierClip_Test();
void QuadraticCoincidence_Test();
diff --git a/experimental/Intersection/LineIntersection.cpp b/experimental/Intersection/LineIntersection.cpp
index 99b9e82788..4d80606945 100644
--- a/experimental/Intersection/LineIntersection.cpp
+++ b/experimental/Intersection/LineIntersection.cpp
@@ -59,7 +59,7 @@ int intersect(const _Line& a, const _Line& b, double aRange[2], double bRange[2]
bRange[0] = aMin <= bMin ? 0 : (aMin - bMin) / (bMax - bMin);
bRange[1] = aMax >= bMax ? 1 : (aMax - bMin) / (bMax - bMin);
}
- return 2;
+ return 1 + ((aRange[0] != aRange[1]) || (bRange[0] != bRange[1]));
}
}
double ab0y = a[0].y - b[0].y;
diff --git a/experimental/Intersection/edge.xcodeproj/project.pbxproj b/experimental/Intersection/edge.xcodeproj/project.pbxproj
index 6180ae8876..cf433c686d 100644
--- a/experimental/Intersection/edge.xcodeproj/project.pbxproj
+++ b/experimental/Intersection/edge.xcodeproj/project.pbxproj
@@ -58,6 +58,7 @@
FECAA6C714BDCE9B00B35E2C /* QuadraticIntersection_Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECAA6C614BDCE9B00B35E2C /* QuadraticIntersection_Test.cpp */; };
FECAA6E114BDDF2D00B35E2C /* QuadraticReduceOrder_Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECAA6E014BDDF2D00B35E2C /* QuadraticReduceOrder_Test.cpp */; };
FED53C391483CB9400F6359E /* Inline_Tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FED53C381483CB9400F6359E /* Inline_Tests.cpp */; };
+ FED865F915056A79006F4508 /* EdgeWalkerQuadralaterals_Test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FED865F815056A79006F4508 /* EdgeWalkerQuadralaterals_Test.cpp */; };
FEED7245144DD2250059E97B /* SkEventNotifier.mm in Sources */ = {isa = PBXBuildFile; fileRef = FEED723E144DD2250059E97B /* SkEventNotifier.mm */; };
FEED7292144DD4610059E97B /* libexperimental.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FEED726E144DD4050059E97B /* libexperimental.a */; };
FEED7293144DD4620059E97B /* libskgr.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FEED7276144DD4140059E97B /* libskgr.a */; };
@@ -299,6 +300,7 @@
FECAAB7F14BDFAFD00B35E2C /* CubicParameterization_TestUtility.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CubicParameterization_TestUtility.cpp; sourceTree = "<group>"; };
FECAACA614BE1C6100B35E2C /* QuadraticParameterization_TestUtility.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuadraticParameterization_TestUtility.cpp; sourceTree = "<group>"; };
FED53C381483CB9400F6359E /* Inline_Tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Inline_Tests.cpp; sourceTree = "<group>"; };
+ FED865F815056A79006F4508 /* EdgeWalkerQuadralaterals_Test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EdgeWalkerQuadralaterals_Test.cpp; sourceTree = "<group>"; };
FEED723C144DD2250059E97B /* SampleApp.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = SampleApp.xib; path = ../../src/utils/mac/SampleApp.xib; sourceTree = SOURCE_ROOT; };
FEED723D144DD2250059E97B /* SampleAppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = SampleAppDelegate.mm; path = ../../src/utils/mac/SampleAppDelegate.mm; sourceTree = SOURCE_ROOT; };
FEED723E144DD2250059E97B /* SkEventNotifier.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = SkEventNotifier.mm; path = ../../src/utils/mac/SkEventNotifier.mm; sourceTree = SOURCE_ROOT; };
@@ -536,6 +538,7 @@
FEED7673144F2D770059E97B /* TestUtilities.h */,
FEED764B144F29BD0059E97B /* TestUtilities.cpp */,
FE7413DB14F6926D00056D7B /* EdgeWalker_Test.h */,
+ FED865F815056A79006F4508 /* EdgeWalkerQuadralaterals_Test.cpp */,
);
name = Tests;
sourceTree = "<group>";
@@ -948,6 +951,7 @@
FEA61B2C14F2AF6600B736CB /* EdgeWalkerRectangles_Test.cpp in Sources */,
FE7413D414F6915A00056D7B /* EdgeWalkerPolygons_Test.cpp in Sources */,
FE7413D814F691C200056D7B /* EdgeWalker_TestUtility.cpp in Sources */,
+ FED865F915056A79006F4508 /* EdgeWalkerQuadralaterals_Test.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};