shape ops work in progress (get rid of some warnings)

git-svn-id: http://skia.googlecode.com/svn/trunk@4037 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
caryclark@google.com 2012-05-23 18:09:25 +00:00
parent 72176b2d38
commit 65f9f0a166
7 changed files with 81 additions and 51 deletions

View File

@ -2,6 +2,6 @@
void contourBounds(const SkPath& path, SkTDArray<SkRect>& boundsArray);
void simplify(const SkPath& path, bool asFill, SkPath& simple);
void simplifyx(const SkPath& path, bool asFill, SkPath& simple);
void simplifyx(const SkPath& path, SkPath& simple);
extern const bool gRunTestsInOneThread; // FIXME: remove once debugging is complete

View File

@ -26,20 +26,24 @@
#define DEBUG_ADD_INTERSECTING_TS 0
#define DEBUG_BRIDGE 0
#define DEBUG_DUMP 0
#define DEBUG_PATH_CONSTRUCTION 0
#define DEBUG_UNUSED 0 // set to expose unused functions
#else
//const bool gRunTestsInOneThread = true;
#define DEBUG_ADD_INTERSECTING_TS 1
#define DEBUG_ADD_INTERSECTING_TS 0
#define DEBUG_BRIDGE 1
#define DEBUG_DUMP 1
#define DEBUG_PATH_CONSTRUCTION 1
#define DEBUG_UNUSED 0 // set to expose unused functions
#endif
#if DEBUG_DUMP
static const char* kLVerbStr[] = {"", "line", "quad", "cubic"};
static const char* kUVerbStr[] = {"", "Line", "Quad", "Cubic"};
// static const char* kUVerbStr[] = {"", "Line", "Quad", "Cubic"};
static int gContourID;
static int gSegmentID;
#endif
@ -262,6 +266,7 @@ static void (* const SegmentSubDivide[])(const SkPoint [], double , double ,
CubicSubDivide
};
#if DEBUG_UNUSED
static void QuadSubBounds(const SkPoint a[3], double startT, double endT,
SkRect& bounds) {
SkPoint dst[3];
@ -283,6 +288,7 @@ static void CubicSubBounds(const SkPoint a[4], double startT, double endT,
bounds.growToInclude(dst[index].fX, dst[index].fY);
}
}
#endif
static SkPath::Verb QuadReduceOrder(const SkPoint a[3],
SkTDArray<SkPoint>& reducePts) {
@ -357,12 +363,14 @@ static SkScalar (* const SegmentLeftMost[])(const SkPoint [], double , double) =
CubicLeftMost
};
#if DEBUG_UNUSED
static bool IsCoincident(const SkPoint a[2], const SkPoint& above,
const SkPoint& below) {
const _Line aLine = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY}};
const _Line bLine = {{above.fX, above.fY}, {below.fX, below.fY}};
return implicit_matches_ulps(aLine, bLine, 32);
}
#endif
class Segment;
@ -563,10 +571,9 @@ struct Span {
double fOtherT; // value at fOther[fOtherIndex].fT
int fOtherIndex; // can't be used during intersection
int fWinding; // accumulated from contours surrounding this one
// OPTIMIZATION: done needs only 2 bits (values are -1, 0, 1)
int fDone; // set when this pointer to the other span is processed
// OPTIMIZATION: done needs only 2 bits (values are -1, 0, 1)
// OPTIMIZATION: coincident needs only 2 bits (values are -1, 0, 1)
int fCoincident; // -1 start of coincidence, 0 no coincidence, 1 end
bool fDone; // if set, this span to next higher T has been processed
};
class Segment {
@ -581,7 +588,7 @@ public:
bool coincident) {
SkASSERT(start != end);
int smaller = start < end ? start : end;
if (fTs[start].fDone) {
if (fTs[smaller].fDone) {
return;
}
SkPoint edge[4];
@ -598,6 +605,17 @@ public:
void addCurveTo(int start, int end, SkPath& path) {
SkPoint edge[4];
(*SegmentSubDivide[fVerb])(fPts, fTs[start].fT, fTs[end].fT, edge);
#if DEBUG_PATH_CONSTRUCTION
SkDebugf("%s %s (%1.9g,%1.9g)", __FUNCTION__,
kLVerbStr[fVerb], edge[1].fX, edge[1].fY);
if (fVerb > 1) {
SkDebugf(" (%1.9g,%1.9g)", edge[2].fX, edge[2].fY);
}
if (fVerb > 2) {
SkDebugf(" (%1.9g,%1.9g)", edge[3].fX, edge[3].fY);
}
SkDebugf("\n");
#endif
switch (fVerb) {
case SkPath::kLine_Verb:
path.lineTo(edge[1].fX, edge[1].fY);
@ -610,7 +628,6 @@ public:
edge[3].fX, edge[3].fY);
break;
}
int smaller = start < end ? start : end;
}
void addLine(const SkPoint pts[2]) {
@ -622,6 +639,9 @@ public:
SkPoint pt;
double firstT = t(tIndex);
xyAtT(firstT, &pt);
#if DEBUG_PATH_CONSTRUCTION
SkDebugf("%s (%1.9g,%1.9g)\n", __FUNCTION__, pt.fX, pt.fY);
#endif
path.moveTo(pt.fX, pt.fY);
}
@ -643,7 +663,6 @@ public:
int insertedAt = -1;
Span* span;
size_t tCount = fTs.count();
double delta;
for (size_t idx2 = 0; idx2 < tCount; ++idx2) {
// OPTIMIZATION: if there are three or more identical Ts, then
// the fourth and following could be further insertion-sorted so
@ -663,7 +682,9 @@ finish:
span->fT = newT;
span->fOther = &other;
span->fWinding = 1;
span->fDone = 0;
if (span->fDone = newT == 1) {
++fDoneSpans;
}
span->fCoincident = coincident;
fCoincident |= coincident;
return insertedAt;
@ -728,7 +749,7 @@ finish:
// sort them using buildAngleList
// find the first in the sort
// see if ascendingT goes to top
bool clockwise(int tIndex) const {
bool clockwise(int /* tIndex */) const {
SkASSERT(0); // incomplete
return false;
}
@ -856,8 +877,8 @@ finish:
} while (true);
markDone(startIndex < endIndex ? startIndex : endIndex);
other = nextAngle->segment();
startIndex = nextAngle->end();
endIndex = nextAngle->start();
startIndex = nextAngle->start();
endIndex = nextAngle->end();
return other;
}
@ -884,7 +905,7 @@ finish:
// mark found segments as done
// FIXME: this is tricky code; needs its own unit test
void findTooCloseToCall(int winding) {
void findTooCloseToCall(int /* winding */ ) { // FIXME: winding should be considered
int count = fTs.count();
if (count < 3) { // require t=0, x, 1 at minimum
return;
@ -1026,6 +1047,7 @@ finish:
int end = nextSpan(firstT, 1, startLoc, startSpan, &endLoc, nextCo);
if (end == -1) {
end = nextSpan(firstT, -1, startLoc, startSpan, &endLoc, nextCo);
SkASSERT(end != -1);
}
// if the topmost T is not on end, or is three-way or more, find left
// look for left-ness from tLeft to firstT (matching y of other)
@ -1098,6 +1120,7 @@ finish:
return fBounds.fLeft == fBounds.fRight;
}
// last does not check for done spans because done is only set for the start
int lastSpan(int end, int step, const SkPoint& startLoc,
double startT, bool& coincident, bool* manyPtr = NULL) const {
int last = end;
@ -1113,9 +1136,6 @@ finish:
break;
}
const Span& lastSpan = fTs[last];
if (lastSpan.fDone) {
continue;
}
if (lastSpan.fT == startT) {
++found;
continue;
@ -1137,27 +1157,26 @@ finish:
}
void markDone(int index) {
SkASSERT(!fTs[index].fDone);
SkASSERT(!done());
double referenceT = fTs[index].fT;
int lesser = index;
while (--lesser >= 0 && referenceT == fTs[lesser].fT) {
SkASSERT(!fTs[lesser].fDone);
fTs[lesser].fDone = true;
fDoneSpans++;
}
do {
SkASSERT(!fTs[index].fDone);
fTs[index].fDone = true;
fDoneSpans++;
} while (++index < fTs.count() && referenceT == fTs[index].fT);
SkASSERT(!done());
fDoneSpans++;
}
// note the assert logic looks for unexpected done of span start
int nextSpan(int from, int step, const SkPoint& fromLoc,
const Span* fromSpan, SkPoint* toLoc, bool& coincident) const {
coincident = false;
if (done()) {
return -1;
}
SkASSERT(!done());
int count = fTs.count();
int to = from;
while (step > 0 ? ++to < count : --to >= 0) {
@ -1173,9 +1192,8 @@ finish:
if (fromLoc == loc) {
continue;
}
if (span->fDone) {
return -1;
}
SkASSERT(step < 0 || !fTs[from].fDone);
SkASSERT(step > 0 || !span->fDone);
if (toLoc) {
*toLoc = loc;
}
@ -1676,9 +1694,9 @@ protected:
int fLast;
};
#if DEBUG_ADD_INTERSECTING_TS
static void debugShowLineIntersection(int pts, const Work& wt,
const Work& wn, const double wtTs[2], const double wnTs[2]) {
#if DEBUG_ADD_INTERSECTING_TS
if (!pts) {
SkDebugf("%s no intersect (%1.9g,%1.9g %1.9g,%1.9g) (%1.9g,%1.9g %1.9g,%1.9g)\n",
__FUNCTION__, wt.pts()[0].fX, wt.pts()[0].fY,
@ -1703,10 +1721,13 @@ static void debugShowLineIntersection(int pts, const Work& wt,
SkDebugf(" wnTs[1]=%g", wnTs[1]);
SkDebugf("\n");
}
#endif
#else
static void debugShowLineIntersection(int , const Work& ,
const Work& , const double [2], const double [2]) {
}
#endif
static bool addIntersectTs(Contour* test, Contour* next, int winding) {
static bool addIntersectTs(Contour* test, Contour* next) {
if (test != next) {
if (test->bounds().fBottom < next->bounds().fTop) {
@ -1962,6 +1983,9 @@ static void bridge(SkTDArray<Contour*>& contourList, SkPath& simple) {
next->addCurveTo(tIndex, endIndex, simple);
next = next->findNext(winding, tIndex, endIndex);
} while (next != topSegment);
#if DEBUG_PATH_CONSTRUCTION
SkDebugf("%s close\n", __FUNCTION__);
#endif
simple.close();
} while (true);
@ -1999,7 +2023,7 @@ static void makeContourList(SkTArray<Contour>& contours,
QSort<Contour>(list.begin(), list.end() - 1);
}
void simplifyx(const SkPath& path, bool asFill, SkPath& simple) {
void simplifyx(const SkPath& path, SkPath& simple) {
// returns 1 for evenodd, -1 for winding, regardless of inverse-ness
int winding = (path.getFillType() & 1) ? 1 : -1;
simple.reset();
@ -2023,7 +2047,7 @@ void simplifyx(const SkPath& path, bool asFill, SkPath& simple) {
Contour* next;
do {
next = *nextPtr++;
} while (addIntersectTs(current, next, winding) && nextPtr != listEnd);
} while (addIntersectTs(current, next) && nextPtr != listEnd);
} while (currentPtr != listEnd);
fixOtherTIndex(contourList);
// eat through coincident edges

View File

@ -86,9 +86,9 @@ static void testPath(const SkPath& path, const SkPoint* pts1, SkPath::Verb c1Typ
}
SimplifyAddIntersectingTsTest::Contour& c1 = contour[0];
SimplifyAddIntersectingTsTest::Contour& c2 = contour[1];
addIntersectTs(&c1, &c2, 1);
addIntersectTs(&c1, &c2);
bool c1Intersected = c1.fSegments[0].intersected();
bool c2Intersected = c2.fSegments[0].intersected();
// bool c2Intersected = c2.fSegments[0].intersected();
#if DEBUG_DUMP
SkDebugf("%s %s (%1.9g,%1.9g %1.9g,%1.9g) %s %s (%1.9g,%1.9g %1.9g,%1.9g)\n",
__FUNCTION__, SimplifyAddIntersectingTsTest::kLVerbStr[c1Type],

View File

@ -17,15 +17,14 @@ namespace SimplifyFindNextTest {
static const SimplifyFindNextTest::Segment* testCommon(
int winding, int startIndex, int endIndex,
SkTArray<SimplifyFindNextTest::Contour>& contours,
SimplifyFindNextTest::EdgeBuilder& builder, const SkPath& path) {
SkTArray<SimplifyFindNextTest::Contour>& contours) {
SkTDArray<SimplifyFindNextTest::Contour*> contourList;
makeContourList(contours, contourList);
addIntersectTs(contourList[0], contourList[0], -1);
addIntersectTs(contourList[0], contourList[0]);
if (contours.count() > 1) {
SkASSERT(contours.count() == 2);
addIntersectTs(contourList[0], contourList[1], -1);
addIntersectTs(contourList[1], contourList[1], -1);
addIntersectTs(contourList[0], contourList[1]);
addIntersectTs(contourList[1], contourList[1]);
}
fixOtherTIndex(contourList);
SimplifyFindNextTest::Segment& segment = contours[0].fSegments[0];
@ -46,14 +45,14 @@ static void test(const SkPath& path) {
int winding = 0;
int start = 0;
int end = 1;
testCommon(winding, start, end, contours, builder, path);
testCommon(winding, start, end, contours);
}
static void test(const SkPath& path, int start, int end) {
SkTArray<SimplifyFindNextTest::Contour> contours;
SimplifyFindNextTest::EdgeBuilder builder(path, contours);
int winding = 0;
testCommon(winding, start, end, contours, builder, path);
testCommon(winding, start, end, contours);
}
static void testLine1() {
@ -72,12 +71,14 @@ static void addInnerCWTriangle(SkPath& path) {
path.close();
}
#if DEBUG_UNUSED
static void addInnerCCWTriangle(SkPath& path) {
path.moveTo(3,0);
path.lineTo(2,1);
path.lineTo(4,1);
path.close();
}
#endif
static void addOuterCWTriangle(SkPath& path) {
path.moveTo(3,0);
@ -86,12 +87,14 @@ static void addOuterCWTriangle(SkPath& path) {
path.close();
}
#if DEBUG_UNUSED
static void addOuterCCWTriangle(SkPath& path) {
path.moveTo(3,0);
path.lineTo(0,2);
path.lineTo(6,2);
path.close();
}
#endif
static void testLine2() {
SkPath path;

View File

@ -17,15 +17,14 @@ namespace SimplifyFindTopTest {
static const SimplifyFindTopTest::Segment* testCommon(
SkTArray<SimplifyFindTopTest::Contour>& contours,
SimplifyFindTopTest::EdgeBuilder& builder, const SkPath& path,
int& index, int& end) {
SkTDArray<SimplifyFindTopTest::Contour*> contourList;
makeContourList(contours, contourList);
addIntersectTs(contourList[0], contourList[0], -1);
addIntersectTs(contourList[0], contourList[0]);
if (contours.count() > 1) {
SkASSERT(contours.count() == 2);
addIntersectTs(contourList[0], contourList[1], -1);
addIntersectTs(contourList[1], contourList[1], -1);
addIntersectTs(contourList[0], contourList[1]);
addIntersectTs(contourList[1], contourList[1]);
}
fixOtherTIndex(contourList);
SimplifyFindTopTest::Segment* topStart = findTopContour(contourList,
@ -39,7 +38,7 @@ static void test(const SkPath& path) {
SkTArray<SimplifyFindTopTest::Contour> contours;
SimplifyFindTopTest::EdgeBuilder builder(path, contours);
int index, end;
testCommon(contours, builder, path, index, end);
testCommon(contours, index, end);
SkASSERT(index + 1 == end);
}
@ -49,7 +48,7 @@ static void test(const SkPath& path, SkScalar x1, SkScalar y1,
SimplifyFindTopTest::EdgeBuilder builder(path, contours);
int index, end;
const SimplifyFindTopTest::Segment* topSegment =
testCommon(contours, builder, path, index, end);
testCommon(contours, index, end);
SkPoint pts[2];
double firstT = topSegment->t(index);
topSegment->xyAtT(firstT, &pts[0]);

View File

@ -18,12 +18,11 @@ namespace SimplifyNewTest {
static SkBitmap bitmap;
static bool testSimplifyx(const SkPath& path, bool fill, SkPath& out,
SkBitmap& bitmap) {
static bool testSimplifyx(const SkPath& path, SkPath& out, SkBitmap& bitmap) {
if (false) {
showPath(path);
}
simplifyx(path, fill, out);
simplifyx(path, out);
if (false) {
return true;
}
@ -36,7 +35,7 @@ static void testLine1() {
path.lineTo(1,1);
path.lineTo(0,0);
path.close();
testSimplifyx(path, true, simple, bitmap);
testSimplifyx(path, simple, bitmap);
}
static void addInnerCWTriangle(SkPath& path) {
@ -46,12 +45,14 @@ static void addInnerCWTriangle(SkPath& path) {
path.close();
}
#if DEBUG_UNUSED
static void addInnerCCWTriangle(SkPath& path) {
path.moveTo(3,0);
path.lineTo(2,1);
path.lineTo(4,1);
path.close();
}
#endif
static void addOuterCWTriangle(SkPath& path) {
path.moveTo(3,0);
@ -60,18 +61,20 @@ static void addOuterCWTriangle(SkPath& path) {
path.close();
}
#if DEBUG_UNUSED
static void addOuterCCWTriangle(SkPath& path) {
path.moveTo(3,0);
path.lineTo(0,2);
path.lineTo(6,2);
path.close();
}
#endif
static void testLine2() {
SkPath path, simple;
addInnerCWTriangle(path);
addOuterCWTriangle(path);
testSimplifyx(path, true, simple, bitmap);
testSimplifyx(path, simple, bitmap);
}

View File

@ -72,6 +72,7 @@
'../experimental/Intersection/SimplifyAngle_Test.cpp',
'../experimental/Intersection/SimplifyFindNext_Test.cpp',
'../experimental/Intersection/SimplifyFindTop_Test.cpp',
'../experimental/Intersection/SimplifyNew_Test.cpp',
'../experimental/Intersection/TestUtilities.cpp',
'../experimental/Intersection/CubicIntersection_TestData.h',
'../experimental/Intersection/CubicUtilities.h',