shape ops work in progress
git-svn-id: http://skia.googlecode.com/svn/trunk@4815 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
be8cefcc07
commit
27c449af06
@ -26,6 +26,7 @@ struct State4 {
|
|||||||
int b;
|
int b;
|
||||||
int c;
|
int c;
|
||||||
int d;
|
int d;
|
||||||
|
int testsRun;
|
||||||
char filename[256];
|
char filename[256];
|
||||||
pthread_t threadID;
|
pthread_t threadID;
|
||||||
SkCanvas* canvas;
|
SkCanvas* canvas;
|
||||||
|
@ -50,7 +50,7 @@ const bool gRunTestsInOneThread = true;
|
|||||||
#define DEBUG_ACTIVE_SPANS 1
|
#define DEBUG_ACTIVE_SPANS 1
|
||||||
#define DEBUG_ADD_INTERSECTING_TS 0
|
#define DEBUG_ADD_INTERSECTING_TS 0
|
||||||
#define DEBUG_ADD_T_PAIR 0
|
#define DEBUG_ADD_T_PAIR 0
|
||||||
#define DEBUG_CONCIDENT 01
|
#define DEBUG_CONCIDENT 0
|
||||||
#define DEBUG_CROSS 1
|
#define DEBUG_CROSS 1
|
||||||
#define DEBUG_DUMP 1
|
#define DEBUG_DUMP 1
|
||||||
#define DEBUG_MARK_DONE 1
|
#define DEBUG_MARK_DONE 1
|
||||||
@ -656,7 +656,7 @@ struct Bounds : public SkRect {
|
|||||||
|
|
||||||
struct Span {
|
struct Span {
|
||||||
Segment* fOther;
|
Segment* fOther;
|
||||||
mutable SkPoint const* fPt; // lazily computed as needed
|
mutable SkPoint fPt; // lazily computed as needed
|
||||||
double fT;
|
double fT;
|
||||||
double fOtherT; // value at fOther[fOtherIndex].fT
|
double fOtherT; // value at fOther[fOtherIndex].fT
|
||||||
int fOtherIndex; // can't be used during intersection
|
int fOtherIndex; // can't be used during intersection
|
||||||
@ -792,10 +792,10 @@ public:
|
|||||||
#if DEBUG_CONCIDENT
|
#if DEBUG_CONCIDENT
|
||||||
SkDebugf("%s 1 this=%d other=%d t [%d] %1.9g (%1.9g,%1.9g)\n",
|
SkDebugf("%s 1 this=%d other=%d t [%d] %1.9g (%1.9g,%1.9g)\n",
|
||||||
__FUNCTION__, fID, other.fID, tIndexStart - 1,
|
__FUNCTION__, fID, other.fID, tIndexStart - 1,
|
||||||
fTs[tIndexStart - 1].fT, xyAtT(tIndexStart - 1).fX,
|
fTs[tIndexStart].fT, xyAtT(tIndexStart).fX,
|
||||||
xyAtT(tIndexStart - 1).fY);
|
xyAtT(tIndexStart).fY);
|
||||||
#endif
|
#endif
|
||||||
SkASSERT(0); // incomplete
|
addTPair(fTs[tIndexStart].fT, other, other.fTs[oIndex].fT);
|
||||||
}
|
}
|
||||||
if (nextT < 1 && fTs[tIndex].fWindValue) {
|
if (nextT < 1 && fTs[tIndex].fWindValue) {
|
||||||
#if DEBUG_CONCIDENT
|
#if DEBUG_CONCIDENT
|
||||||
@ -812,10 +812,10 @@ public:
|
|||||||
#if DEBUG_CONCIDENT
|
#if DEBUG_CONCIDENT
|
||||||
SkDebugf("%s 3 this=%d other=%d t [%d] %1.9g (%1.9g,%1.9g)\n",
|
SkDebugf("%s 3 this=%d other=%d t [%d] %1.9g (%1.9g,%1.9g)\n",
|
||||||
__FUNCTION__, fID, other.fID, oIndexStart - 1,
|
__FUNCTION__, fID, other.fID, oIndexStart - 1,
|
||||||
other.fTs[oIndexStart - 1].fT, other.xyAtT(oIndexStart - 1).fX,
|
other.fTs[oIndexStart].fT, other.xyAtT(oIndexStart).fX,
|
||||||
other.xyAtT(oIndexStart - 1).fY);
|
other.xyAtT(oIndexStart).fY);
|
||||||
|
other.debugAddTPair(other.fTs[oIndexStart].fT, *this, fTs[tIndex].fT);
|
||||||
#endif
|
#endif
|
||||||
SkASSERT(0); // incomplete
|
|
||||||
}
|
}
|
||||||
if (oNextT < 1 && other.fTs[oIndex].fWindValue) {
|
if (oNextT < 1 && other.fTs[oIndex].fWindValue) {
|
||||||
#if DEBUG_CONCIDENT
|
#if DEBUG_CONCIDENT
|
||||||
@ -965,7 +965,7 @@ public:
|
|||||||
}
|
}
|
||||||
span->fT = newT;
|
span->fT = newT;
|
||||||
span->fOther = other;
|
span->fOther = other;
|
||||||
span->fPt = NULL;
|
span->fPt.fX = SK_ScalarNaN;
|
||||||
span->fWindSum = SK_MinS32;
|
span->fWindSum = SK_MinS32;
|
||||||
span->fWindValue = 1;
|
span->fWindValue = 1;
|
||||||
if ((span->fDone = newT == 1)) {
|
if ((span->fDone = newT == 1)) {
|
||||||
@ -1068,7 +1068,7 @@ public:
|
|||||||
do {
|
do {
|
||||||
if (transfer) {
|
if (transfer) {
|
||||||
if (decrementOther) {
|
if (decrementOther) {
|
||||||
SkASSERT(abs(end->fWindValue) < gDebugMaxWindValue);
|
SkASSERT(abs(end->fWindValue) <= gDebugMaxWindValue);
|
||||||
++(end->fWindValue);
|
++(end->fWindValue);
|
||||||
} else if (decrementSpan(end)) {
|
} else if (decrementSpan(end)) {
|
||||||
TrackOutside(outsideTs, end->fT, oStartT);
|
TrackOutside(outsideTs, end->fT, oStartT);
|
||||||
@ -1085,7 +1085,7 @@ public:
|
|||||||
do {
|
do {
|
||||||
if (transfer) {
|
if (transfer) {
|
||||||
if (!decrementOther) {
|
if (!decrementOther) {
|
||||||
SkASSERT(abs(oEnd->fWindValue) < gDebugMaxWindValue);
|
SkASSERT(abs(oEnd->fWindValue) <= gDebugMaxWindValue);
|
||||||
++(oEnd->fWindValue);
|
++(oEnd->fWindValue);
|
||||||
} else if (other.decrementSpan(oEnd)) {
|
} else if (other.decrementSpan(oEnd)) {
|
||||||
TrackOutside(oOutsideTs, oEnd->fT, startT);
|
TrackOutside(oOutsideTs, oEnd->fT, startT);
|
||||||
@ -1320,28 +1320,21 @@ public:
|
|||||||
// it is guaranteed to have an end which describes a non-zero length (?)
|
// it is guaranteed to have an end which describes a non-zero length (?)
|
||||||
// winding -1 means ccw, 1 means cw
|
// winding -1 means ccw, 1 means cw
|
||||||
// firstFind allows coincident edges to be treated differently
|
// firstFind allows coincident edges to be treated differently
|
||||||
Segment* findNext(SkTDArray<Span*>& chase, int winding,
|
Segment* findNext(SkTDArray<Span*>& chase, bool firstFind, bool active,
|
||||||
int contourWinding, bool firstFind, bool active,
|
|
||||||
const int startIndex, const int endIndex, int& nextStart,
|
const int startIndex, const int endIndex, int& nextStart,
|
||||||
int& nextEnd, int& spanWinding) {
|
int& nextEnd, int& winding, int& spanWinding) {
|
||||||
|
|
||||||
start here;
|
|
||||||
// winding is a mess
|
|
||||||
// try to simplify what we got
|
|
||||||
|
|
||||||
int flipped = 1;
|
|
||||||
int sumWinding = winding + spanWinding;
|
int sumWinding = winding + spanWinding;
|
||||||
if (sumWinding == 0 || (false && contourWinding && !firstFind)) {
|
if (sumWinding == 0) {
|
||||||
sumWinding = spanWinding;
|
sumWinding = spanWinding;
|
||||||
}
|
}
|
||||||
bool insideContour = contourWinding && contourWinding * sumWinding < 0;
|
bool insideContour = active && winding && winding * sumWinding < 0;
|
||||||
if (insideContour && (true || !firstFind)) {
|
if (insideContour) {
|
||||||
sumWinding = contourWinding;
|
sumWinding = winding;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG_WINDING
|
#if DEBUG_WINDING
|
||||||
SkDebugf("%s winding=%d contourWinding=%d spanWinding=%d sumWinding=%d\n",
|
SkDebugf("%s winding=%d spanWinding=%d sumWinding=%d\n",
|
||||||
__FUNCTION__, winding, contourWinding, spanWinding, sumWinding);
|
__FUNCTION__, winding, spanWinding, sumWinding);
|
||||||
#endif
|
#endif
|
||||||
SkASSERT(startIndex != endIndex);
|
SkASSERT(startIndex != endIndex);
|
||||||
int count = fTs.count();
|
int count = fTs.count();
|
||||||
@ -1378,7 +1371,7 @@ public:
|
|||||||
int firstIndex = findStartingEdge(sorted, startIndex, end);
|
int firstIndex = findStartingEdge(sorted, startIndex, end);
|
||||||
SkASSERT(firstIndex >= 0);
|
SkASSERT(firstIndex >= 0);
|
||||||
#if DEBUG_SORT
|
#if DEBUG_SORT
|
||||||
debugShowSort(sorted, firstIndex, contourWinding, sumWinding);
|
debugShowSort(sorted, firstIndex, winding, sumWinding);
|
||||||
#endif
|
#endif
|
||||||
bool doBump = sorted[firstIndex]->firstBump(sumWinding);
|
bool doBump = sorted[firstIndex]->firstBump(sumWinding);
|
||||||
#if DEBUG_WINDING
|
#if DEBUG_WINDING
|
||||||
@ -1396,8 +1389,9 @@ public:
|
|||||||
const Angle* foundAngle = NULL;
|
const Angle* foundAngle = NULL;
|
||||||
bool foundDone = false;
|
bool foundDone = false;
|
||||||
// iterate through the angle, and compute everyone's winding
|
// iterate through the angle, and compute everyone's winding
|
||||||
bool firstEdge = true;
|
bool toggleWinding = false;
|
||||||
bool flopped = false;
|
bool flipFound = false;
|
||||||
|
int flipped = 1;
|
||||||
Segment* nextSegment;
|
Segment* nextSegment;
|
||||||
do {
|
do {
|
||||||
if (nextIndex == angleCount) {
|
if (nextIndex == angleCount) {
|
||||||
@ -1413,13 +1407,12 @@ public:
|
|||||||
maxWinding, sumWinding, nextAngle->sign());
|
maxWinding, sumWinding, nextAngle->sign());
|
||||||
#endif
|
#endif
|
||||||
if (maxWinding * sumWinding < 0) {
|
if (maxWinding * sumWinding < 0) {
|
||||||
flipped = -flipped;
|
flipFound ^= true;
|
||||||
flopped = true;
|
|
||||||
#if DEBUG_WINDING
|
#if DEBUG_WINDING
|
||||||
SkDebugf("flipped sign %d %d\n", maxWinding, sumWinding);
|
SkDebugf("flipFound maxWinding=%d sumWinding=%d\n",
|
||||||
|
maxWinding, sumWinding);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
firstEdge = false;
|
|
||||||
if (!sumWinding) {
|
if (!sumWinding) {
|
||||||
if (!active) {
|
if (!active) {
|
||||||
markDone(SkMin32(startIndex, endIndex), startWinding);
|
markDone(SkMin32(startIndex, endIndex), startWinding);
|
||||||
@ -1433,10 +1426,11 @@ public:
|
|||||||
if (!foundAngle || foundDone) {
|
if (!foundAngle || foundDone) {
|
||||||
foundAngle = nextAngle;
|
foundAngle = nextAngle;
|
||||||
foundDone = nextSegment->done(*nextAngle);
|
foundDone = nextSegment->done(*nextAngle);
|
||||||
if (!flopped && maxWinding * startWinding < 0) {
|
if (flipFound || (maxWinding * startWinding < 0)) {
|
||||||
flipped = -flipped;
|
flipped = -flipped;
|
||||||
#if DEBUG_WINDING
|
#if DEBUG_WINDING
|
||||||
SkDebugf("flopped sign %d %d\n", maxWinding, startWinding);
|
SkDebugf("flipped flipFound=%d maxWinding=%d startWinding=%d\n",
|
||||||
|
flipFound, maxWinding, startWinding);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1444,10 +1438,20 @@ public:
|
|||||||
}
|
}
|
||||||
if (!maxWinding && innerSwap && !foundAngle) {
|
if (!maxWinding && innerSwap && !foundAngle) {
|
||||||
if (sumWinding * startWinding < 0 && flipped > 0) {
|
if (sumWinding * startWinding < 0 && flipped > 0) {
|
||||||
SkDebugf("%s flip?\n");
|
#if DEBUG_WINDING
|
||||||
// flipped = -flipped;
|
SkDebugf("%s toggleWinding\n");
|
||||||
|
#endif
|
||||||
|
toggleWinding = true;
|
||||||
|
} else if (startWinding != sumWinding) {
|
||||||
|
winding = sumWinding;
|
||||||
}
|
}
|
||||||
foundAngle = nextAngle;
|
foundAngle = nextAngle;
|
||||||
|
if (flipFound) {
|
||||||
|
flipped = -1;
|
||||||
|
#if DEBUG_WINDING
|
||||||
|
SkDebugf("flipped flipFound=%d\n", flipFound);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (nextSegment->done()) {
|
if (nextSegment->done()) {
|
||||||
continue;
|
continue;
|
||||||
@ -1481,6 +1485,20 @@ public:
|
|||||||
nextSegment = foundAngle->segment();
|
nextSegment = foundAngle->segment();
|
||||||
spanWinding = SkSign32(spanWinding) * flipped * nextSegment->windValue(
|
spanWinding = SkSign32(spanWinding) * flipped * nextSegment->windValue(
|
||||||
SkMin32(nextStart, nextEnd));
|
SkMin32(nextStart, nextEnd));
|
||||||
|
if (toggleWinding) {
|
||||||
|
if (winding) {
|
||||||
|
winding = 0;
|
||||||
|
} else {
|
||||||
|
winding = -startWinding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
int min = SkMin32(nextStart, nextEnd);
|
||||||
|
int sign = foundAngle->sign();
|
||||||
|
int windSum = nextSegment->windSum(min);
|
||||||
|
int windValue = nextSegment->windValue(min);
|
||||||
|
SkASSERT(winding + sign * windValue == windSum);
|
||||||
|
#endif
|
||||||
#if DEBUG_WINDING
|
#if DEBUG_WINDING
|
||||||
SkDebugf("%s spanWinding=%d\n", __FUNCTION__, spanWinding);
|
SkDebugf("%s spanWinding=%d\n", __FUNCTION__, spanWinding);
|
||||||
#endif
|
#endif
|
||||||
@ -2013,18 +2031,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
const SkPoint& xyAtT(const Span* span) const {
|
const SkPoint& xyAtT(const Span* span) const {
|
||||||
if (!span->fPt) {
|
if (SkScalarIsNaN(span->fPt.fX)) {
|
||||||
if (span->fT == 0) {
|
if (span->fT == 0) {
|
||||||
span->fPt = &fPts[0];
|
span->fPt = fPts[0];
|
||||||
} else if (span->fT == 1) {
|
} else if (span->fT == 1) {
|
||||||
span->fPt = &fPts[fVerb];
|
span->fPt = fPts[fVerb];
|
||||||
} else {
|
} else {
|
||||||
SkPoint* pt = fIntersections.append();
|
(*SegmentXYAtT[fVerb])(fPts, span->fT, &span->fPt);
|
||||||
(*SegmentXYAtT[fVerb])(fPts, span->fT, pt);
|
|
||||||
span->fPt = pt;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return *span->fPt;
|
return span->fPt;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkScalar yAtT(int index) const {
|
SkScalar yAtT(int index) const {
|
||||||
@ -2153,10 +2169,6 @@ private:
|
|||||||
SkPath::Verb fVerb;
|
SkPath::Verb fVerb;
|
||||||
Bounds fBounds;
|
Bounds fBounds;
|
||||||
SkTDArray<Span> fTs; // two or more (always includes t=0 t=1)
|
SkTDArray<Span> fTs; // two or more (always includes t=0 t=1)
|
||||||
// OPTIMIZATION:if intersections array is a pointer, the it could only
|
|
||||||
// be allocated as needed instead of always initialized -- though maybe
|
|
||||||
// the initialization is lightweight enough that it hardly matters
|
|
||||||
mutable SkTDArray<SkPoint> fIntersections;
|
|
||||||
int fDoneSpans; // used for quick check that segment is finished
|
int fDoneSpans; // used for quick check that segment is finished
|
||||||
#if DEBUG_DUMP
|
#if DEBUG_DUMP
|
||||||
int fID;
|
int fID;
|
||||||
@ -3250,6 +3262,11 @@ static void debugShowActiveSpans(SkTDArray<Contour*>& contourList) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static bool windingIsActive(int winding, int spanWinding) {
|
||||||
|
return winding * spanWinding <= 0 && abs(winding) <= abs(spanWinding)
|
||||||
|
&& (!winding || !spanWinding || winding == -spanWinding);
|
||||||
|
}
|
||||||
|
|
||||||
// Each segment may have an inside or an outside. Segments contained within
|
// Each segment may have an inside or an outside. Segments contained within
|
||||||
// winding may have insides on either side, and form a contour that should be
|
// winding may have insides on either side, and form a contour that should be
|
||||||
// ignored. Segments that are coincident with opposing direction segments may
|
// ignored. Segments that are coincident with opposing direction segments may
|
||||||
@ -3286,21 +3303,26 @@ static void bridge(SkTDArray<Contour*>& contourList, SkPath& simple) {
|
|||||||
bool firstTime = true;
|
bool firstTime = true;
|
||||||
int winding = contourWinding;
|
int winding = contourWinding;
|
||||||
int spanWinding = current->spanSign(index, endIndex);
|
int spanWinding = current->spanSign(index, endIndex);
|
||||||
// int firstWinding = contourWinding + spanWinding;
|
int spanWindSum = current->windSum(SkMin32(index, endIndex));
|
||||||
|
if (spanWindSum != SK_MinS32) {
|
||||||
|
int calcWinding = spanWindSum;
|
||||||
|
if (spanWinding > 0) {
|
||||||
|
// calcWinding -= spanWinding;
|
||||||
|
}
|
||||||
|
SkDebugf("%s *** winding=%d calcWinding=%d\n", __FUNCTION__,
|
||||||
|
winding, calcWinding);
|
||||||
|
winding = calcWinding;
|
||||||
|
}
|
||||||
// FIXME: needs work. While it works in limited situations, it does
|
// FIXME: needs work. While it works in limited situations, it does
|
||||||
// not always compute winding correctly. Active should be removed and instead
|
// not always compute winding correctly. Active should be removed and instead
|
||||||
// the initial winding should be correctly passed in so that if the
|
// the initial winding should be correctly passed in so that if the
|
||||||
// inner contour is wound the same way, it never finds an accumulated
|
// inner contour is wound the same way, it never finds an accumulated
|
||||||
// winding of zero. Inside 'find next', we need to look for transitions
|
// winding of zero. Inside 'find next', we need to look for transitions
|
||||||
// other than zero when resolving sorted angles.
|
// other than zero when resolving sorted angles.
|
||||||
|
bool active = windingIsActive(winding, spanWinding);
|
||||||
SkTDArray<Span*> chaseArray;
|
SkTDArray<Span*> chaseArray;
|
||||||
do {
|
do {
|
||||||
bool active = winding * spanWinding <= 0
|
|
||||||
&& abs(winding) <= abs(spanWinding);
|
|
||||||
#if DEBUG_WINDING
|
#if DEBUG_WINDING
|
||||||
if (abs(winding) > abs(spanWinding) && winding * spanWinding < 0) {
|
|
||||||
SkDebugf("%s *** unexpected active?\n", __FUNCTION__);
|
|
||||||
}
|
|
||||||
SkDebugf("%s active=%s winding=%d spanWinding=%d\n",
|
SkDebugf("%s active=%s winding=%d spanWinding=%d\n",
|
||||||
__FUNCTION__, active ? "true" : "false",
|
__FUNCTION__, active ? "true" : "false",
|
||||||
winding, spanWinding);
|
winding, spanWinding);
|
||||||
@ -3309,9 +3331,9 @@ static void bridge(SkTDArray<Contour*>& contourList, SkPath& simple) {
|
|||||||
do {
|
do {
|
||||||
SkASSERT(!current->done());
|
SkASSERT(!current->done());
|
||||||
int nextStart, nextEnd;
|
int nextStart, nextEnd;
|
||||||
Segment* next = current->findNext(chaseArray, winding,
|
Segment* next = current->findNext(chaseArray,
|
||||||
contourWinding, firstTime, active, index, endIndex,
|
firstTime, active, index, endIndex,
|
||||||
nextStart, nextEnd, spanWinding);
|
nextStart, nextEnd, winding, spanWinding);
|
||||||
if (!next) {
|
if (!next) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3341,30 +3363,27 @@ static void bridge(SkTDArray<Contour*>& contourList, SkPath& simple) {
|
|||||||
spanWinding = current->windSum(lesser);
|
spanWinding = current->windSum(lesser);
|
||||||
int spanValue = current->windValue(lesser);
|
int spanValue = current->windValue(lesser);
|
||||||
SkASSERT(spanWinding != SK_MinS32);
|
SkASSERT(spanWinding != SK_MinS32);
|
||||||
int spanSign = current->spanSign(index, endIndex);
|
|
||||||
#if DEBUG_WINDING
|
#if DEBUG_WINDING
|
||||||
SkDebugf("%s spanWinding=%d spanSign=%d winding=%d spanValue=%d\n",
|
SkDebugf("%s spanWinding=%d winding=%d spanValue=%d\n",
|
||||||
__FUNCTION__, spanWinding, spanSign, winding, spanValue);
|
__FUNCTION__, spanWinding, winding, spanValue);
|
||||||
#endif
|
#endif
|
||||||
if (spanWinding * spanSign < 0) {
|
if (abs(spanWinding) != spanValue) {
|
||||||
#if DEBUG_WINDING
|
|
||||||
SkDebugf("%s spanWinding * spanSign < 0\n", __FUNCTION__);
|
|
||||||
#endif
|
|
||||||
// SkTSwap<int>(index, endIndex);
|
|
||||||
}
|
|
||||||
if (abs(spanWinding) > spanValue) {
|
|
||||||
winding = spanWinding;
|
winding = spanWinding;
|
||||||
spanWinding = spanValue * SkSign32(spanWinding);
|
spanWinding = spanValue * SkSign32(spanWinding);
|
||||||
winding -= spanWinding;
|
winding -= spanWinding;
|
||||||
#if DEBUG_WINDING
|
#if DEBUG_WINDING
|
||||||
SkDebugf("%s spanWinding=%d winding=%d\n", __FUNCTION__,
|
SkDebugf("%s != spanWinding=%d winding=%d\n", __FUNCTION__,
|
||||||
spanWinding, winding);
|
spanWinding, winding);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
active = windingIsActive(winding, spanWinding);
|
||||||
|
} else if (winding) {
|
||||||
#if DEBUG_WINDING
|
#if DEBUG_WINDING
|
||||||
SkDebugf("%s ->0 contourWinding=%d winding=%d\n", __FUNCTION__,
|
SkDebugf("%s ->0 contourWinding=%d winding=%d\n", __FUNCTION__,
|
||||||
contourWinding, winding);
|
contourWinding, winding);
|
||||||
#endif
|
#endif
|
||||||
|
// start here;
|
||||||
|
// set active=false if it was false when chase was created
|
||||||
|
active = abs(winding) <= abs(spanWinding);
|
||||||
winding = 0;
|
winding = 0;
|
||||||
}
|
}
|
||||||
} while (true);
|
} while (true);
|
||||||
|
@ -18,7 +18,7 @@ namespace SimplifyFindNextTest {
|
|||||||
#include "Intersection_Tests.h"
|
#include "Intersection_Tests.h"
|
||||||
|
|
||||||
static const SimplifyFindNextTest::Segment* testCommon(
|
static const SimplifyFindNextTest::Segment* testCommon(
|
||||||
int winding, int startIndex, int endIndex,
|
int contourWinding, int spanWinding, int startIndex, int endIndex,
|
||||||
SkTArray<SimplifyFindNextTest::Contour>& contours) {
|
SkTArray<SimplifyFindNextTest::Contour>& contours) {
|
||||||
SkTDArray<SimplifyFindNextTest::Contour*> contourList;
|
SkTDArray<SimplifyFindNextTest::Contour*> contourList;
|
||||||
makeContourList(contours, contourList);
|
makeContourList(contours, contourList);
|
||||||
@ -34,8 +34,9 @@ static const SimplifyFindNextTest::Segment* testCommon(
|
|||||||
pts[0] = segment.xyAtT(&segment.span(endIndex));
|
pts[0] = segment.xyAtT(&segment.span(endIndex));
|
||||||
int nextStart, nextEnd;
|
int nextStart, nextEnd;
|
||||||
SkTDArray<SimplifyFindNextTest::Span*> chaseArray;
|
SkTDArray<SimplifyFindNextTest::Span*> chaseArray;
|
||||||
SimplifyFindNextTest::Segment* next = segment.findNext(chaseArray, winding,
|
SimplifyFindNextTest::Segment* next = segment.findNext(chaseArray,
|
||||||
0, true, true, startIndex, endIndex, nextStart, nextEnd, winding);
|
true, true, startIndex, endIndex, nextStart, nextEnd,
|
||||||
|
contourWinding, spanWinding);
|
||||||
pts[1] = next->xyAtT(&next->span(nextStart));
|
pts[1] = next->xyAtT(&next->span(nextStart));
|
||||||
SkASSERT(pts[0] == pts[1]);
|
SkASSERT(pts[0] == pts[1]);
|
||||||
return next;
|
return next;
|
||||||
@ -44,17 +45,19 @@ static const SimplifyFindNextTest::Segment* testCommon(
|
|||||||
static void test(const SkPath& path) {
|
static void test(const SkPath& path) {
|
||||||
SkTArray<SimplifyFindNextTest::Contour> contours;
|
SkTArray<SimplifyFindNextTest::Contour> contours;
|
||||||
SimplifyFindNextTest::EdgeBuilder builder(path, contours);
|
SimplifyFindNextTest::EdgeBuilder builder(path, contours);
|
||||||
int winding = 0;
|
int contourWinding = 0;
|
||||||
|
int spanWinding = 1;
|
||||||
int start = 0;
|
int start = 0;
|
||||||
int end = 1;
|
int end = 1;
|
||||||
testCommon(winding, start, end, contours);
|
testCommon(contourWinding, spanWinding, start, end, contours);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test(const SkPath& path, int start, int end) {
|
static void test(const SkPath& path, int start, int end) {
|
||||||
SkTArray<SimplifyFindNextTest::Contour> contours;
|
SkTArray<SimplifyFindNextTest::Contour> contours;
|
||||||
SimplifyFindNextTest::EdgeBuilder builder(path, contours);
|
SimplifyFindNextTest::EdgeBuilder builder(path, contours);
|
||||||
int winding = 0;
|
int contourWinding = 0;
|
||||||
testCommon(winding, start, end, contours);
|
int spanWinding = 1;
|
||||||
|
testCommon(contourWinding, spanWinding, start, end, contours);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void testLine1() {
|
static void testLine1() {
|
||||||
|
@ -582,12 +582,78 @@ static void testLine59() {
|
|||||||
testSimplifyx(path);
|
testSimplifyx(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void (*firstTest)() = 0;
|
static void testLine60() {
|
||||||
|
SkPath path, simple;
|
||||||
|
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
|
||||||
|
path.addRect(6, 12, 18, 18, (SkPath::Direction) 1);
|
||||||
|
path.addRect(4, 12, 13, 13, (SkPath::Direction) 1);
|
||||||
|
testSimplifyx(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void testLine61() {
|
||||||
|
SkPath path, simple;
|
||||||
|
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
|
||||||
|
path.addRect(12, 0, 24, 24, (SkPath::Direction) 1);
|
||||||
|
path.addRect(12, 0, 21, 21, (SkPath::Direction) 1);
|
||||||
|
testSimplifyx(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void testLine62() {
|
||||||
|
SkPath path, simple;
|
||||||
|
path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
|
||||||
|
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
|
||||||
|
path.addRect(0, 12, 12, 12, (SkPath::Direction) 0);
|
||||||
|
path.addRect(4, 12, 13, 13, (SkPath::Direction) 1);
|
||||||
|
testSimplifyx(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void testLine63() {
|
||||||
|
SkPath path, simple;
|
||||||
|
path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
|
||||||
|
path.addRect(0, 10, 20, 20, (SkPath::Direction) 0);
|
||||||
|
path.addRect(0, 6, 12, 12, (SkPath::Direction) 1);
|
||||||
|
path.addRect(0, 32, 9, 36, (SkPath::Direction) 1);
|
||||||
|
testSimplifyx(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void testLine64() {
|
||||||
|
SkPath path, simple;
|
||||||
|
path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
|
||||||
|
path.addRect(10, 40, 30, 30, (SkPath::Direction) 0);
|
||||||
|
path.addRect(18, 6, 30, 30, (SkPath::Direction) 0);
|
||||||
|
testSimplifyx(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void testLine65() {
|
||||||
|
SkPath path, simple;
|
||||||
|
path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
|
||||||
|
path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
|
||||||
|
path.addRect(24, 0, 36, 36, (SkPath::Direction) 0);
|
||||||
|
path.addRect(32, 6, 36, 41, (SkPath::Direction) 1);
|
||||||
|
testSimplifyx(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void testLine66() {
|
||||||
|
SkPath path, simple;
|
||||||
|
path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
|
||||||
|
path.addRect(0, 30, 20, 20, (SkPath::Direction) 0);
|
||||||
|
path.addRect(12, 20, 24, 30, (SkPath::Direction) 0);
|
||||||
|
testSimplifyx(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void (*firstTest)() = testLine66;
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
void (*fun)();
|
void (*fun)();
|
||||||
const char* str;
|
const char* str;
|
||||||
} tests[] = {
|
} tests[] = {
|
||||||
|
TEST(testLine66),
|
||||||
|
TEST(testLine65),
|
||||||
|
TEST(testLine64),
|
||||||
|
TEST(testLine63),
|
||||||
|
TEST(testLine62),
|
||||||
|
TEST(testLine61),
|
||||||
|
TEST(testLine60),
|
||||||
TEST(testLine59),
|
TEST(testLine59),
|
||||||
TEST(testLine58),
|
TEST(testLine58),
|
||||||
TEST(testLine57),
|
TEST(testLine57),
|
||||||
@ -661,8 +727,8 @@ void SimplifyNew_Test() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef SK_DEBUG
|
#ifdef SK_DEBUG
|
||||||
gDebugMaxWindSum = 3;
|
gDebugMaxWindSum = 4;
|
||||||
gDebugMaxWindValue = 3;
|
gDebugMaxWindValue = 4;
|
||||||
#endif
|
#endif
|
||||||
size_t index = testCount - 1;
|
size_t index = testCount - 1;
|
||||||
if (firstTest) {
|
if (firstTest) {
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "SkCanvas.h"
|
#include "SkCanvas.h"
|
||||||
#include "SkStream.h"
|
#include "SkStream.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -29,7 +30,11 @@ static const char marker[] =
|
|||||||
"\n"
|
"\n"
|
||||||
"var testDivs = [\n";
|
"var testDivs = [\n";
|
||||||
static const char testLineStr[] = " testLine";
|
static const char testLineStr[] = " testLine";
|
||||||
|
#if 0
|
||||||
static const char filename[] = "../../experimental/Intersection/debugXX.txt";
|
static const char filename[] = "../../experimental/Intersection/debugXX.txt";
|
||||||
|
#else
|
||||||
|
static const char filename[] = "/flash/debug/XX.txt";
|
||||||
|
#endif
|
||||||
static int testNumber;
|
static int testNumber;
|
||||||
|
|
||||||
static void* testSimplify4x4RectsMain(void* data)
|
static void* testSimplify4x4RectsMain(void* data)
|
||||||
@ -38,6 +43,7 @@ static void* testSimplify4x4RectsMain(void* data)
|
|||||||
bzero(pathStr, sizeof(pathStr));
|
bzero(pathStr, sizeof(pathStr));
|
||||||
SkASSERT(data);
|
SkASSERT(data);
|
||||||
State4& state = *(State4*) data;
|
State4& state = *(State4*) data;
|
||||||
|
state.testsRun = 0;
|
||||||
int aShape = state.a & 0x03;
|
int aShape = state.a & 0x03;
|
||||||
int aCW = state.a >> 2;
|
int aCW = state.a >> 2;
|
||||||
int bShape = state.b & 0x03;
|
int bShape = state.b & 0x03;
|
||||||
@ -179,6 +185,7 @@ static void* testSimplify4x4RectsMain(void* data)
|
|||||||
getcwd(pwd, sizeof(pwd));
|
getcwd(pwd, sizeof(pwd));
|
||||||
SkDebugf("%s\n", pwd);
|
SkDebugf("%s\n", pwd);
|
||||||
#endif
|
#endif
|
||||||
|
#if 1
|
||||||
SkFILEWStream outFile(state.filename);
|
SkFILEWStream outFile(state.filename);
|
||||||
if (!outFile.isValid()) {
|
if (!outFile.isValid()) {
|
||||||
continue;
|
continue;
|
||||||
@ -211,8 +218,10 @@ static void* testSimplify4x4RectsMain(void* data)
|
|||||||
outFile.writeDecAsText(testNumber);
|
outFile.writeDecAsText(testNumber);
|
||||||
outFile.writeText("),\n");
|
outFile.writeText("),\n");
|
||||||
outFile.flush();
|
outFile.flush();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
testSimplifyx(path, out, state.bitmap, state.canvas);
|
testSimplifyx(path, out, state.bitmap, state.canvas);
|
||||||
|
state.testsRun++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -229,15 +238,16 @@ const int maxThreadsAllocated = 32;
|
|||||||
void Simplify4x4RectsThreaded_Test()
|
void Simplify4x4RectsThreaded_Test()
|
||||||
{
|
{
|
||||||
#ifdef SK_DEBUG
|
#ifdef SK_DEBUG
|
||||||
gDebugMaxWindSum = 3;
|
gDebugMaxWindSum = 4;
|
||||||
gDebugMaxWindValue = 3;
|
gDebugMaxWindValue = 4;
|
||||||
#endif
|
#endif
|
||||||
int maxThreads = 1;
|
int maxThreads = 1;
|
||||||
if (!gRunTestsInOneThread) {
|
if (!gRunTestsInOneThread) {
|
||||||
size_t size;
|
|
||||||
int threads = -1;
|
int threads = -1;
|
||||||
|
size_t size = sizeof(threads);
|
||||||
sysctlbyname("hw.logicalcpu_max", &threads, &size, NULL, 0);
|
sysctlbyname("hw.logicalcpu_max", &threads, &size, NULL, 0);
|
||||||
SkDebugf("%s size=%d processors=%d\n", __FUNCTION__, size, threads);
|
SkDebugf("%s errno=%d size=%d processors=%d\n", __FUNCTION__,
|
||||||
|
errno, size, threads);
|
||||||
if (threads > 0) {
|
if (threads > 0) {
|
||||||
maxThreads = threads;
|
maxThreads = threads;
|
||||||
} else {
|
} else {
|
||||||
@ -272,6 +282,7 @@ void Simplify4x4RectsThreaded_Test()
|
|||||||
statePtr->filename[sizeof(filename) - 6] = '0' + threadIndex % 10;
|
statePtr->filename[sizeof(filename) - 6] = '0' + threadIndex % 10;
|
||||||
}
|
}
|
||||||
threadIndex = 0;
|
threadIndex = 0;
|
||||||
|
int testsRun = 0;
|
||||||
for (int a = 0; a < 8; ++a) { // outermost
|
for (int a = 0; a < 8; ++a) { // outermost
|
||||||
for (int b = a ; b < 8; ++b) {
|
for (int b = a ; b < 8; ++b) {
|
||||||
for (int c = b ; c < 8; ++c) {
|
for (int c = b ; c < 8; ++c) {
|
||||||
@ -285,6 +296,9 @@ void Simplify4x4RectsThreaded_Test()
|
|||||||
createThread(statePtr, testSimplify4x4RectsMain);
|
createThread(statePtr, testSimplify4x4RectsMain);
|
||||||
if (++threadIndex >= maxThreads) {
|
if (++threadIndex >= maxThreads) {
|
||||||
waitForCompletion(threadState, threadIndex);
|
waitForCompletion(threadState, threadIndex);
|
||||||
|
for (int index = 0; index < maxThreads; ++index) {
|
||||||
|
testsRun += threadState[index].testsRun;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
testSimplify4x4RectsMain(statePtr);
|
testSimplify4x4RectsMain(statePtr);
|
||||||
@ -298,6 +312,9 @@ void Simplify4x4RectsThreaded_Test()
|
|||||||
if (!gRunTestsInOneThread) SkDebugf("\n\n%d", a);
|
if (!gRunTestsInOneThread) SkDebugf("\n\n%d", a);
|
||||||
}
|
}
|
||||||
waitForCompletion(threadState, threadIndex);
|
waitForCompletion(threadState, threadIndex);
|
||||||
|
for (int index = 0; index < maxThreads; ++index) {
|
||||||
|
testsRun += threadState[index].testsRun;
|
||||||
|
}
|
||||||
#ifdef SK_DEBUG
|
#ifdef SK_DEBUG
|
||||||
gDebugMaxWindSum = SK_MaxS32;
|
gDebugMaxWindSum = SK_MaxS32;
|
||||||
gDebugMaxWindValue = SK_MaxS32;
|
gDebugMaxWindValue = SK_MaxS32;
|
||||||
|
@ -587,11 +587,63 @@ path.close();
|
|||||||
path.addRect(4, 4, 13, 13, (SkPath::Direction) 1);
|
path.addRect(4, 4, 13, 13, (SkPath::Direction) 1);
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="testLine60">
|
||||||
|
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
|
||||||
|
path.addRect(6, 12, 18, 18, (SkPath::Direction) 1);
|
||||||
|
path.addRect(4, 12, 13, 13, (SkPath::Direction) 1);
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="testLine61">
|
||||||
|
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
|
||||||
|
path.addRect(12, 0, 24, 24, (SkPath::Direction) 1);
|
||||||
|
path.addRect(12, 0, 21, 21, (SkPath::Direction) 1);
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="testLine62">
|
||||||
|
path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
|
||||||
|
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
|
||||||
|
path.addRect(0, 12, 12, 12, (SkPath::Direction) 0);
|
||||||
|
path.addRect(4, 12, 13, 13, (SkPath::Direction) 1);
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="testLine63">
|
||||||
|
path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
|
||||||
|
path.addRect(0, 10, 20, 20, (SkPath::Direction) 0);
|
||||||
|
path.addRect(0, 6, 12, 12, (SkPath::Direction) 1);
|
||||||
|
path.addRect(0, 32, 9, 36, (SkPath::Direction) 1);
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="testLine64">
|
||||||
|
path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
|
||||||
|
path.addRect(10, 40, 30, 30, (SkPath::Direction) 0);
|
||||||
|
path.addRect(18, 6, 30, 30, (SkPath::Direction) 0);
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="testLine65">
|
||||||
|
path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
|
||||||
|
path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
|
||||||
|
path.addRect(24, 0, 36, 36, (SkPath::Direction) 0);
|
||||||
|
path.addRect(32, 6, 36, 41, (SkPath::Direction) 1);
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="testLine66">
|
||||||
|
path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
|
||||||
|
path.addRect(0, 30, 20, 20, (SkPath::Direction) 0);
|
||||||
|
path.addRect(12, 20, 24, 30, (SkPath::Direction) 0);
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
var testDivs = [
|
var testDivs = [
|
||||||
|
testLine66,
|
||||||
|
testLine65,
|
||||||
|
testLine64,
|
||||||
|
testLine63,
|
||||||
|
testLine62,
|
||||||
|
testLine61,
|
||||||
|
testLine60,
|
||||||
testLine59,
|
testLine59,
|
||||||
testLine58,
|
testLine58,
|
||||||
testLine57,
|
testLine57,
|
||||||
|
Loading…
Reference in New Issue
Block a user