pathops work in progress
BUG=
Review URL: https://codereview.chromium.org/52653002
git-svn-id: http://skia.googlecode.com/svn/trunk@12089 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/pathops/SkDCubicIntersection.cpp b/src/pathops/SkDCubicIntersection.cpp
index ce23448..27b1634 100644
--- a/src/pathops/SkDCubicIntersection.cpp
+++ b/src/pathops/SkDCubicIntersection.cpp
@@ -292,6 +292,7 @@
tmpLine[1].fX += cubic2[2 - start].fY - cubic2[t1Index].fY;
tmpLine[1].fY -= cubic2[2 - start].fX - cubic2[t1Index].fX;
SkIntersections impTs;
+ impTs.allowNear(false);
impTs.intersectRay(cubic1, tmpLine);
for (int index = 0; index < impTs.used(); ++index) {
SkDPoint realPt = impTs.pt(index);
@@ -446,6 +447,7 @@
return fUsed;
}
} else {
+ // OPTIMIZATION: set exact end bits here to avoid cubic exact end later
for (int i1 = 0; i1 < 4; i1 += 3) {
for (int i2 = 0; i2 < 4; i2 += 3) {
if (c1[i1].approximatelyEqual(c2[i2])) {
@@ -483,21 +485,22 @@
return fUsed;
}
// FIXME: pass in cached bounds from caller
- SkDRect c1Bounds, c2Bounds;
- c1Bounds.setBounds(c1); // OPTIMIZE use setRawBounds ?
+ SkDRect c2Bounds;
c2Bounds.setBounds(c2);
- if (!(exactEndBits & 1)) {
+ if (!(exactEndBits & 4)) {
cubicNearEnd(c1, false, c2, c2Bounds);
}
- if (!(exactEndBits & 2)) {
+ if (!(exactEndBits & 8)) {
cubicNearEnd(c1, true, c2, c2Bounds);
}
if (!selfIntersect) {
+ SkDRect c1Bounds;
+ c1Bounds.setBounds(c1); // OPTIMIZE use setRawBounds ?
swap();
- if (!(exactEndBits & 4)) {
+ if (!(exactEndBits & 1)) {
cubicNearEnd(c2, false, c1, c1Bounds);
}
- if (!(exactEndBits & 8)) {
+ if (!(exactEndBits & 2)) {
cubicNearEnd(c2, true, c1, c1Bounds);
}
swap();
@@ -506,7 +509,61 @@
SkASSERT(!selfIntersect);
return fUsed;
}
- ::intersect(c1, 0, 1, c2, 0, 1, 1, *this);
+ SkIntersections i;
+ i.fAllowNear = false;
+ i.fMax = 9;
+ ::intersect(c1, 0, 1, c2, 0, 1, 1, i);
+ int compCount = i.used();
+ if (compCount) {
+ int exactCount = used();
+ if (exactCount == 0) {
+ set(i);
+ } else {
+ // at least one is exact or near, and at least one was computed. Eliminate duplicates
+ for (int exIdx = 0; exIdx < exactCount; ++exIdx) {
+ for (int cpIdx = 0; cpIdx < compCount; ) {
+ if (fT[0][0] == i[0][0] && fT[1][0] == i[1][0]) {
+ i.removeOne(cpIdx);
+ --compCount;
+ continue;
+ }
+ double tAvg = (fT[0][exIdx] + i[0][cpIdx]) / 2;
+ SkDPoint pt = c1.ptAtT(tAvg);
+ if (!pt.approximatelyEqual(fPt[exIdx])) {
+ ++cpIdx;
+ continue;
+ }
+ tAvg = (fT[1][exIdx] + i[1][cpIdx]) / 2;
+ pt = c2.ptAtT(tAvg);
+ if (!pt.approximatelyEqual(fPt[exIdx])) {
+ ++cpIdx;
+ continue;
+ }
+ i.removeOne(cpIdx);
+ --compCount;
+ }
+ }
+ // if mid t evaluates to nearly the same point, skip the t
+ for (int cpIdx = 0; cpIdx < compCount - 1; ) {
+ double tAvg = (fT[0][cpIdx] + i[0][cpIdx + 1]) / 2;
+ SkDPoint pt = c1.ptAtT(tAvg);
+ if (!pt.approximatelyEqual(fPt[cpIdx])) {
+ ++cpIdx;
+ continue;
+ }
+ tAvg = (fT[1][cpIdx] + i[1][cpIdx + 1]) / 2;
+ pt = c2.ptAtT(tAvg);
+ if (!pt.approximatelyEqual(fPt[cpIdx])) {
+ ++cpIdx;
+ continue;
+ }
+ i.removeOne(cpIdx);
+ --compCount;
+ }
+ // in addition to adding below missing function, think about how to say
+ append(i);
+ }
+ }
// If an end point and a second point very close to the end is returned, the second
// point may have been detected because the approximate quads
// intersected at the end and close to it. Verify that the second point is valid.