shape ops work in progress
git-svn-id: http://skia.googlecode.com/svn/trunk@4713 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
a276975a62
commit
47580694fb
@ -13,7 +13,7 @@
|
||||
// FIXME: remove once debugging is complete
|
||||
#if 01 // set to 1 for no debugging whatsoever
|
||||
|
||||
const bool gRunTestsInOneThread = false;
|
||||
//const bool gRunTestsInOneThread = false;
|
||||
|
||||
#define DEBUG_ACTIVE_LESS_THAN 0
|
||||
#define DEBUG_ADD 0
|
||||
@ -33,7 +33,7 @@ const bool gRunTestsInOneThread = false;
|
||||
|
||||
#else
|
||||
|
||||
const bool gRunTestsInOneThread = true;
|
||||
//const bool gRunTestsInOneThread = true;
|
||||
|
||||
#define DEBUG_ACTIVE_LESS_THAN 0
|
||||
#define DEBUG_ADD 01
|
||||
|
@ -26,6 +26,7 @@ struct State4 {
|
||||
int b;
|
||||
int c;
|
||||
int d;
|
||||
char filename[256];
|
||||
pthread_t threadID;
|
||||
SkCanvas* canvas;
|
||||
SkBitmap bitmap;
|
||||
|
@ -4,4 +4,9 @@ void contourBounds(const SkPath& path, SkTDArray<SkRect>& boundsArray);
|
||||
void simplify(const SkPath& path, bool asFill, SkPath& simple);
|
||||
void simplifyx(const SkPath& path, SkPath& simple);
|
||||
|
||||
extern const bool gRunTestsInOneThread; // FIXME: remove once debugging is complete
|
||||
// FIXME: remove this section once debugging is complete
|
||||
extern const bool gRunTestsInOneThread;
|
||||
#ifdef SK_DEBUG
|
||||
extern int gDebugMaxWindSum;
|
||||
extern int gDebugMaxWindValue;
|
||||
#endif
|
||||
|
@ -17,39 +17,51 @@
|
||||
// A Segment contains a Span array
|
||||
// A Span is describes a portion of a Segment using starting and ending T
|
||||
// T values range from 0 to 1, where 0 is the first Point in the Segment
|
||||
// An Edge is a Segment generated from a Span
|
||||
|
||||
// FIXME: remove once debugging is complete
|
||||
#if 0 // set to 1 for no debugging whatsoever
|
||||
#ifdef SK_DEBUG
|
||||
int gDebugMaxWindSum = SK_MaxS32;
|
||||
int gDebugMaxWindValue = SK_MaxS32;
|
||||
#endif
|
||||
|
||||
//const bool gxRunTestsInOneThread = false;
|
||||
#define DEBUG_UNUSED 0 // set to expose unused functions
|
||||
|
||||
#if 0 // set to 1 for multiple thread -- no debugging
|
||||
|
||||
const bool gRunTestsInOneThread = false;
|
||||
|
||||
#define DEBUG_ACTIVE_SPANS 0
|
||||
#define DEBUG_ADD_INTERSECTING_TS 0
|
||||
#define DEBUG_ADD_T_PAIR 0
|
||||
#define DEBUG_BRIDGE 0
|
||||
#define DEBUG_CONCIDENT 0
|
||||
#define DEBUG_CROSS 0
|
||||
#define DEBUG_DUMP 0
|
||||
#define DEBUG_PATH_CONSTRUCTION 0
|
||||
#define DEBUG_ACTIVE_SPANS 0
|
||||
#define DEBUG_WINDING 0
|
||||
#define DEBUG_UNUSED 0 // set to expose unused functions
|
||||
#define DEBUG_MARK_DONE 0
|
||||
#define DEBUG_PATH_CONSTRUCTION 0
|
||||
#define DEBUG_SORT 0
|
||||
#define DEBUG_WINDING 0
|
||||
|
||||
#else
|
||||
|
||||
//const bool gRunTestsInOneThread = true;
|
||||
const bool gRunTestsInOneThread = true;
|
||||
|
||||
#define DEBUG_ACTIVE_SPANS 1
|
||||
#define DEBUG_ADD_INTERSECTING_TS 0
|
||||
#define DEBUG_BRIDGE 1
|
||||
#define DEBUG_CROSS 1
|
||||
#define DEBUG_ADD_T_PAIR 1
|
||||
#define DEBUG_BRIDGE 0
|
||||
#define DEBUG_CONCIDENT 1
|
||||
#define DEBUG_CROSS 0
|
||||
#define DEBUG_DUMP 1
|
||||
#define DEBUG_MARK_DONE 1
|
||||
#define DEBUG_PATH_CONSTRUCTION 1
|
||||
#define DEBUG_ACTIVE_SPANS 01
|
||||
#define DEBUG_WINDING 01
|
||||
#define DEBUG_UNUSED 0 // set to expose unused functions
|
||||
#define DEBUG_MARK_DONE 01
|
||||
#define DEBUG_SORT 1
|
||||
#define DEBUG_WINDING 1
|
||||
|
||||
#endif
|
||||
|
||||
#if DEBUG_ACTIVE_SPANS && !DEBUG_DUMP
|
||||
#if (DEBUG_ACTIVE_SPANS || DEBUG_CONCIDENT) && !DEBUG_DUMP
|
||||
#undef DEBUG_DUMP
|
||||
#define DEBUG_DUMP 1
|
||||
#endif
|
||||
@ -466,6 +478,10 @@ public:
|
||||
}
|
||||
return fDDDx * rh.fDDDy < rh.fDDDx * fDDDy;
|
||||
}
|
||||
|
||||
double dx() const {
|
||||
return fDx;
|
||||
}
|
||||
|
||||
int end() const {
|
||||
return fEnd;
|
||||
@ -925,6 +941,7 @@ public:
|
||||
do {
|
||||
if (transfer) {
|
||||
if (decrementOther) {
|
||||
SkASSERT(abs(end->fWindValue) < gDebugMaxWindValue);
|
||||
++(end->fWindValue);
|
||||
} else {
|
||||
SkASSERT(end->fWindValue > 0);
|
||||
@ -958,6 +975,7 @@ public:
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SkASSERT(abs(oEnd->fWindValue) < gDebugMaxWindValue);
|
||||
++(oEnd->fWindValue);
|
||||
}
|
||||
}
|
||||
@ -975,54 +993,93 @@ public:
|
||||
other.addTOutsides(oOutsideTs, *this, endT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void addTOutsides(const SkTDArray<double>& outsideTs, Segment& other,
|
||||
double otherEnd) {
|
||||
int count = outsideTs.count();
|
||||
double endT = 0;
|
||||
int endSpan = 0;
|
||||
for (int index = 0; index < count; index += 2) {
|
||||
double t = outsideTs[index];
|
||||
double otherT = outsideTs[index + 1];
|
||||
if (t > 1 - FLT_EPSILON) {
|
||||
return;
|
||||
double oEnd) {
|
||||
// walk this to outsideTs[0]
|
||||
// walk other to outsideTs[1]
|
||||
// if either is > 0, add a pointer to the other, copying adjacent winding
|
||||
int tIndex = -1;
|
||||
int tCount = fTs.count();
|
||||
int oIndex = -1;
|
||||
int oCount = other.fTs.count();
|
||||
double tStart = outsideTs[0];
|
||||
double oStart = outsideTs[1];
|
||||
Span* tSpan;
|
||||
Span* oSpan;
|
||||
do {
|
||||
tSpan = &fTs[++tIndex];
|
||||
if (tStart - tSpan->fT < FLT_EPSILON) {
|
||||
break;
|
||||
}
|
||||
if (t - endT > FLT_EPSILON) {
|
||||
endSpan = addTDonePair(t, other, otherT);
|
||||
}
|
||||
do {
|
||||
endT = fTs[++endSpan].fT;
|
||||
} while (endT - t < FLT_EPSILON);
|
||||
} while (tIndex < tCount);
|
||||
do {
|
||||
oSpan = &other.fTs[++oIndex];
|
||||
if (oStart - oSpan->fT < FLT_EPSILON) {
|
||||
break;
|
||||
}
|
||||
} while (oIndex < oCount);
|
||||
if (tIndex > 0 || oIndex > 0) {
|
||||
addTPair(tStart, other, oStart);
|
||||
// note: counts for fT, other.fT are one greater
|
||||
} else {
|
||||
--tCount;
|
||||
--oCount;
|
||||
}
|
||||
addTPair(endT, other, otherEnd);
|
||||
tStart = fTs[tIndex].fT;
|
||||
oStart = other.fTs[oIndex].fT;
|
||||
do {
|
||||
do {
|
||||
tSpan = &fTs[++tIndex];
|
||||
} while (tSpan->fT - tStart < FLT_EPSILON && tIndex < tCount);
|
||||
tStart = fTs[tIndex].fT;
|
||||
do {
|
||||
oSpan = &other.fTs[++oIndex];
|
||||
} while (oSpan->fT - oStart < FLT_EPSILON && oIndex < oCount);
|
||||
oStart = other.fTs[oIndex].fT;
|
||||
if (tStart == 1 && oStart == 1) {
|
||||
break;
|
||||
}
|
||||
addTPair(tStart, other, oStart);
|
||||
++tCount;
|
||||
++oCount;
|
||||
} while (tStart < 1 && oStart < 1 && oEnd - oSpan->fT >= FLT_EPSILON);
|
||||
}
|
||||
|
||||
// match the other.fWindValue to its mates
|
||||
int addTDonePair(double t, Segment& other, double otherT) {
|
||||
int insertedAt = addTPair(t, other, otherT);
|
||||
Span& end = fTs[insertedAt];
|
||||
SkASSERT(end.fWindValue == 1);
|
||||
end.fWindValue = 0;
|
||||
end.fDone = true;
|
||||
++fDoneSpans;
|
||||
Span& otherEnd = other.fTs[end.fOtherIndex];
|
||||
Span* match = NULL;
|
||||
if (end.fOtherIndex > 0) {
|
||||
match = &other.fTs[end.fOtherIndex - 1];
|
||||
}
|
||||
if (!match || match->fT < otherT) {
|
||||
match = &other.fTs[end.fOtherIndex + 1];
|
||||
}
|
||||
otherEnd.fWindValue = match->fWindValue;
|
||||
return insertedAt;
|
||||
}
|
||||
|
||||
int addTPair(double t, Segment& other, double otherT) {
|
||||
void addTPair(double t, Segment& other, double otherT) {
|
||||
#if DEBUG_ADD_T_PAIR
|
||||
SkDebugf("%s addTPair this=%d %1.9g other=%d %1.9g\n",
|
||||
__FUNCTION__, fID, t, other.fID, otherT);
|
||||
#endif
|
||||
int insertedAt = addT(t, &other);
|
||||
int otherInsertedAt = other.addT(otherT, this);
|
||||
addOtherT(insertedAt, otherT, otherInsertedAt);
|
||||
other.addOtherT(otherInsertedAt, t, insertedAt);
|
||||
return insertedAt;
|
||||
Span& newSpan = fTs[insertedAt];
|
||||
if (insertedAt > 0) {
|
||||
const Span& lastSpan = fTs[insertedAt - 1];
|
||||
if (t - lastSpan.fT < FLT_EPSILON) {
|
||||
int tWind = lastSpan.fWindValue;
|
||||
newSpan.fWindValue = tWind;
|
||||
if (!tWind) {
|
||||
newSpan.fDone = true;
|
||||
++fDoneSpans;
|
||||
}
|
||||
}
|
||||
}
|
||||
int oIndex = newSpan.fOtherIndex;
|
||||
if (oIndex > 0) {
|
||||
const Span& lastOther = other.fTs[oIndex - 1];
|
||||
if (otherT - lastOther.fT < FLT_EPSILON) {
|
||||
int oWind = lastOther.fWindValue;
|
||||
Span& otherSpan = other.fTs[oIndex];
|
||||
otherSpan.fWindValue = oWind;
|
||||
if (!oWind) {
|
||||
otherSpan.fDone = true;
|
||||
++(other.fDoneSpans);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addTwoAngles(int start, int end, SkTDArray<Angle>& angles) const {
|
||||
@ -1037,7 +1094,7 @@ public:
|
||||
addAngle(angles, end, tIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const Bounds& bounds() const {
|
||||
return fBounds;
|
||||
}
|
||||
@ -1099,6 +1156,9 @@ public:
|
||||
do {
|
||||
int start = end;
|
||||
end = nextSpan(start, 1);
|
||||
if (fTs[start].fWindValue == 0) {
|
||||
continue;
|
||||
}
|
||||
SkPoint edge[4];
|
||||
// OPTIMIZE: wrap this so that if start==0 end==fTCount-1 we can
|
||||
// work with the original data directly
|
||||
@ -1121,7 +1181,7 @@ public:
|
||||
if (bestY < pt.fY) {
|
||||
bestY = pt.fY;
|
||||
bestT = foundT < 1 ? start : end;
|
||||
hitT = foundT;
|
||||
hitT = fTs[start].fT + (fTs[end].fT - fTs[start].fT) * foundT;
|
||||
}
|
||||
} while (fTs[end].fT != 1);
|
||||
return bestT;
|
||||
@ -1132,6 +1192,13 @@ public:
|
||||
return fDoneSpans == fTs.count();
|
||||
}
|
||||
|
||||
bool done(const Angle& angle) const {
|
||||
int start = angle.start();
|
||||
int end = angle.end();
|
||||
const Span& mSpan = fTs[SkMin32(start, end)];
|
||||
return mSpan.fDone;
|
||||
}
|
||||
|
||||
// so the span needs to contain the pairing info found here
|
||||
// this should include the winding computed for the edge, and
|
||||
// what edge it connects to, and whether it is discarded
|
||||
@ -1190,20 +1257,25 @@ public:
|
||||
int angleCount = angles.count();
|
||||
int firstIndex = findStartingEdge(sorted, startIndex, end);
|
||||
SkASSERT(firstIndex >= 0);
|
||||
#if DEBUG_SORT
|
||||
debugShowSort(sorted, firstIndex, winding);
|
||||
#endif
|
||||
#if DEBUG_WINDING
|
||||
SkDebugf("%s (first) winding=%d sign=%d\n", __FUNCTION__,
|
||||
winding, sorted[firstIndex]->sign());
|
||||
#endif
|
||||
bool innerSwap = false;
|
||||
int startWinding = winding;
|
||||
if (winding * sorted[firstIndex]->sign() > 0 && active) {
|
||||
// FIXME: this means winding was computed wrong by caller ?
|
||||
winding = 0;
|
||||
innerSwap = true;
|
||||
if (sorted[firstIndex]->sign() * winding > 0) {
|
||||
winding -= rewind(sorted[firstIndex]);
|
||||
if (active) {
|
||||
innerSwap = true;
|
||||
}
|
||||
}
|
||||
int nextIndex = firstIndex + 1;
|
||||
int lastIndex = firstIndex != 0 ? firstIndex : angleCount;
|
||||
const Angle* foundAngle = NULL;
|
||||
bool foundDone = false;
|
||||
// iterate through the angle, and compute everyone's winding
|
||||
bool firstEdge = true;
|
||||
do {
|
||||
@ -1216,27 +1288,37 @@ public:
|
||||
int windValue = nextSegment->windValue(nextAngle);
|
||||
SkASSERT(windValue > 0);
|
||||
winding -= nextAngle->sign() * windValue;
|
||||
SkASSERT(abs(winding) <= gDebugMaxWindSum);
|
||||
#if DEBUG_WINDING
|
||||
SkDebugf("%s maxWinding=%d winding=%d sign=%d\n", __FUNCTION__,
|
||||
maxWinding, winding, nextAngle->sign());
|
||||
#endif
|
||||
if (maxWinding * winding < 0) {
|
||||
flipped = -flipped;
|
||||
#if DEBUG_WINDING
|
||||
SkDebugf("flipped sign %d %d\n", maxWinding, winding);
|
||||
#endif
|
||||
}
|
||||
firstEdge = false;
|
||||
if (!winding) {
|
||||
if (!active) {
|
||||
SkASSERT(nextAngle->segment() == this);
|
||||
markWinding(SkMin32(nextAngle->start(), nextAngle->end()),
|
||||
maxWinding);
|
||||
markDone(SkMin32(startIndex, endIndex), startWinding);
|
||||
nextSegment->markWinding(SkMin32(nextAngle->start(),
|
||||
nextAngle->end()), maxWinding);
|
||||
#if DEBUG_WINDING
|
||||
SkDebugf("%s inactive\n", __FUNCTION__);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
if (!foundAngle) {
|
||||
if (!foundAngle || foundDone) {
|
||||
foundAngle = nextAngle;
|
||||
foundDone = nextSegment->done(*nextAngle);
|
||||
if (flipped > 0 && maxWinding * startWinding < 0) {
|
||||
flipped = -flipped;
|
||||
#if DEBUG_WINDING
|
||||
SkDebugf("flopped sign %d %d\n", maxWinding, winding);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -1265,8 +1347,8 @@ public:
|
||||
}
|
||||
}
|
||||
} while (++nextIndex != lastIndex);
|
||||
sorted[firstIndex]->segment()->
|
||||
markDone(SkMin32(startIndex, endIndex), startWinding);
|
||||
SkASSERT(sorted[firstIndex]->segment() == this);
|
||||
markDone(SkMin32(startIndex, endIndex), startWinding);
|
||||
if (!foundAngle) {
|
||||
return NULL;
|
||||
}
|
||||
@ -1628,6 +1710,7 @@ public:
|
||||
#endif
|
||||
span.fDone = true;
|
||||
SkASSERT(span.fWindSum == SK_MinS32 || span.fWindSum == winding);
|
||||
SkASSERT(abs(winding) <= gDebugMaxWindSum);
|
||||
span.fWindSum = winding;
|
||||
fDoneSpans++;
|
||||
}
|
||||
@ -1644,6 +1727,7 @@ public:
|
||||
#endif
|
||||
span.fDone = true;
|
||||
SkASSERT(span.fWindSum == SK_MinS32 || span.fWindSum == winding);
|
||||
SkASSERT(abs(winding) <= gDebugMaxWindSum);
|
||||
span.fWindSum = winding;
|
||||
fDoneSpans++;
|
||||
} while (++index < fTs.count() && fTs[index].fT - referenceT < FLT_EPSILON);
|
||||
@ -1658,13 +1742,14 @@ public:
|
||||
if (span.fDone) {
|
||||
continue;
|
||||
}
|
||||
SkASSERT(span.fWindValue == 1 || winding == 0);
|
||||
// SkASSERT(span.fWindValue == 1 || winding == 0);
|
||||
SkASSERT(span.fWindSum == SK_MinS32 || span.fWindSum == winding);
|
||||
#if DEBUG_MARK_DONE
|
||||
const SkPoint& pt = xyAtT(&span);
|
||||
SkDebugf("%s segment=%d index=%d t=%1.9g pt=(%1.9g,%1.9g) wind=%d\n",
|
||||
__FUNCTION__, fID, lesser, span.fT, pt.fX, pt.fY, winding);
|
||||
#endif
|
||||
SkASSERT(abs(winding) <= gDebugMaxWindSum);
|
||||
span.fWindSum = winding;
|
||||
}
|
||||
do {
|
||||
@ -1673,13 +1758,14 @@ public:
|
||||
if (span.fDone) {
|
||||
continue;
|
||||
}
|
||||
SkASSERT(span.fWindValue == 1 || winding == 0);
|
||||
// SkASSERT(span.fWindValue == 1 || winding == 0);
|
||||
SkASSERT(span.fWindSum == SK_MinS32 || span.fWindSum == winding);
|
||||
#if DEBUG_MARK_DONE
|
||||
const SkPoint& pt = xyAtT(&span);
|
||||
SkDebugf("%s segment=%d index=%d t=%1.9g pt=(%1.9g,%1.9g) wind=%d\n",
|
||||
__FUNCTION__, fID, index, span.fT, pt.fX, pt.fY, winding);
|
||||
#endif
|
||||
SkASSERT(abs(winding) <= gDebugMaxWindSum);
|
||||
span.fWindSum = winding;
|
||||
} while (++index < fTs.count() && fTs[index].fT - referenceT < FLT_EPSILON);
|
||||
}
|
||||
@ -1724,6 +1810,15 @@ public:
|
||||
fTs.reset();
|
||||
}
|
||||
|
||||
int rewind(const Angle* angle) {
|
||||
SkASSERT(angle->segment() == this);
|
||||
const Span& span = fTs[SkMin32(angle->start(), angle->end())];
|
||||
#if DEBUG_SORT
|
||||
SkDebugf("%s offset=%d\n", __FUNCTION__, angle->sign() * span.fWindValue);
|
||||
#endif
|
||||
return angle->sign() * span.fWindValue;
|
||||
}
|
||||
|
||||
// OPTIMIZATION: mark as debugging only if used solely by tests
|
||||
const Span& span(int tIndex) const {
|
||||
return fTs[tIndex];
|
||||
@ -1819,6 +1914,17 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DEBUG_CONCIDENT
|
||||
void debugShowTs() {
|
||||
SkDebugf("%s %d", __FUNCTION__, fID);
|
||||
for (int i = 0; i < fTs.count(); ++i) {
|
||||
SkDebugf(" [o=%d %1.9g (%1.9g,%1.9g) w=%d]", fTs[i].fOther->fID,
|
||||
fTs[i].fT, xAtT(&fTs[i]), yAtT(&fTs[i]), fTs[i].fWindValue);
|
||||
}
|
||||
SkDebugf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DEBUG_ACTIVE_SPANS
|
||||
void debugShowActiveSpans(int contourID, int segmentIndex) {
|
||||
if (done()) {
|
||||
@ -1846,6 +1952,42 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DEBUG_SORT
|
||||
void debugShowSort(const SkTDArray<Angle*>& angles, int first, int winding) {
|
||||
int index = first;
|
||||
int windSum = winding;
|
||||
const Angle& fAngle = *angles[first];
|
||||
const Segment& fSegment = *fAngle.segment();
|
||||
SkASSERT(&fSegment == this);
|
||||
const Span& fSpan = fSegment.fTs[SkMin32(fAngle.start(), fAngle.end())];
|
||||
if (fAngle.sign() * winding < 0) {
|
||||
windSum += fAngle.sign() * fSpan.fWindValue;
|
||||
}
|
||||
do {
|
||||
const Angle& angle = *angles[index];
|
||||
const Segment& segment = *angle.segment();
|
||||
int start = angle.start();
|
||||
int end = angle.end();
|
||||
const Span& sSpan = segment.fTs[start];
|
||||
const Span& eSpan = segment.fTs[end];
|
||||
const Span& mSpan = segment.fTs[SkMin32(start, end)];
|
||||
int lastSum = windSum;
|
||||
windSum -= angle.sign() * mSpan.fWindValue;
|
||||
SkDebugf("%s [%d] id=%d start=%d (%1.9g,%,1.9g) end=%d (%1.9g,%,1.9g)"
|
||||
" sign=%d windValue=%d winding: %d->%d (max=%d) done=%d\n",
|
||||
__FUNCTION__, index, segment.fID, start, segment.xAtT(&sSpan),
|
||||
segment.yAtT(&sSpan), end, segment.xAtT(&eSpan),
|
||||
segment.yAtT(&eSpan), angle.sign(), mSpan.fWindValue,
|
||||
lastSum, windSum, abs(lastSum) > abs(windSum) ? lastSum :
|
||||
windSum, mSpan.fDone);
|
||||
++index;
|
||||
if (index == angles.count()) {
|
||||
index = 0;
|
||||
}
|
||||
} while (index != first);
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
const SkPoint* fPts;
|
||||
SkPath::Verb fVerb;
|
||||
@ -2017,6 +2159,10 @@ public:
|
||||
int otherIndex = coincidence.fSegments[1];
|
||||
Segment& thisOne = thisContour->fSegments[thisIndex];
|
||||
Segment& other = otherContour->fSegments[otherIndex];
|
||||
#if DEBUG_CONCIDENT
|
||||
thisOne.debugShowTs();
|
||||
other.debugShowTs();
|
||||
#endif
|
||||
double startT = coincidence.fTs[0][0];
|
||||
double endT = coincidence.fTs[0][1];
|
||||
if (startT > endT) {
|
||||
@ -2047,6 +2193,10 @@ public:
|
||||
}
|
||||
thisOne.addTCoincident(startT, endT, other, oStartT, oEndT);
|
||||
}
|
||||
#if DEBUG_CONCIDENT
|
||||
thisOne.debugShowTs();
|
||||
other.debugShowTs();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -2715,8 +2865,10 @@ static void coincidenceCheck(SkTDArray<Contour*>& contourList, int winding) {
|
||||
static int innerContourCheck(SkTDArray<Contour*>& contourList,
|
||||
Contour* baseContour, const SkPoint& basePt) {
|
||||
int contourCount = contourList.count();
|
||||
int winding = 0;
|
||||
SkScalar bestY = SK_ScalarMin;
|
||||
const Segment* test = NULL;
|
||||
int tIndex;
|
||||
double tHit;
|
||||
for (int cTest = 0; cTest < contourCount; ++cTest) {
|
||||
Contour* contour = contourList[cTest];
|
||||
if (basePt.fY < contour->bounds().fTop) {
|
||||
@ -2728,58 +2880,88 @@ static int innerContourCheck(SkTDArray<Contour*>& contourList,
|
||||
if (baseContour->crosses(contour)) {
|
||||
continue;
|
||||
}
|
||||
int tIndex;
|
||||
double tHit;
|
||||
const Segment* test = contour->crossedSegment(basePt, bestY, tIndex,
|
||||
tHit);
|
||||
if (!test) {
|
||||
continue;
|
||||
const Segment* next = contour->crossedSegment(basePt, bestY, tIndex, tHit);
|
||||
if (next) {
|
||||
test = next;
|
||||
}
|
||||
// If the ray hit the end of a span, we need to construct the wheel of
|
||||
// angles to find the span closest to the ray -- even if there are just
|
||||
// two spokes on the wheel.
|
||||
if (tHit == test->t(tIndex)) {
|
||||
SkTDArray<Angle> angles;
|
||||
int end = test->nextSpan(tIndex, 1);
|
||||
if (end < 0) {
|
||||
end = test->nextSpan(tIndex, -1);
|
||||
}
|
||||
if (!test) {
|
||||
baseContour->setWinding(0);
|
||||
return 0;
|
||||
}
|
||||
int winding, windValue;
|
||||
// If the ray hit the end of a span, we need to construct the wheel of
|
||||
// angles to find the span closest to the ray -- even if there are just
|
||||
// two spokes on the wheel.
|
||||
if (tHit == test->t(tIndex)) {
|
||||
SkTDArray<Angle> angles;
|
||||
int end = test->nextSpan(tIndex, 1);
|
||||
if (end < 0) {
|
||||
end = test->nextSpan(tIndex, -1);
|
||||
}
|
||||
test->addTwoAngles(end, tIndex, angles);
|
||||
test->buildAngles(tIndex, angles);
|
||||
SkTDArray<Angle*> sorted;
|
||||
// OPTIMIZATION: call a sort that, if base point is the leftmost,
|
||||
// returns the first counterclockwise hour before 6 o'clock,
|
||||
// or if the base point is rightmost, returns the first clockwise
|
||||
// hour after 6 o'clock
|
||||
sortAngles(angles, sorted);
|
||||
#if DEBUG_SORT
|
||||
sorted[0]->segment()->debugShowSort(sorted, 0, 0);
|
||||
#endif
|
||||
// walk the sorted angle fan to find the lowest angle
|
||||
// above the base point. Currently, the first angle in the sorted array
|
||||
// is 12 noon or an earlier hour (the next counterclockwise)
|
||||
int count = sorted.count();
|
||||
int left = -1;
|
||||
int right = -1;
|
||||
for (int index = 0; index < count; ++index) {
|
||||
double indexDx = sorted[index]->dx();
|
||||
if (indexDx < 0) {
|
||||
left = index;
|
||||
} else if (indexDx > 0) {
|
||||
right = index;
|
||||
break;
|
||||
}
|
||||
test->addTwoAngles(tIndex, end, angles);
|
||||
// test->buildAnglesInner(tIndex, angles);
|
||||
test->buildAngles(tIndex, angles);
|
||||
SkTDArray<Angle*> sorted;
|
||||
sortAngles(angles, sorted);
|
||||
const Angle* angle = sorted[0];
|
||||
test = angle->segment();
|
||||
SkScalar testDx = (*SegmentDXAtT[test->verb()])(test->pts(), tHit);
|
||||
if (testDx == 0) {
|
||||
angle = *(sorted.end() - 1);
|
||||
test = angle->segment();
|
||||
SkASSERT((*SegmentDXAtT[test->verb()])(test->pts(), tHit) != 0);
|
||||
}
|
||||
tIndex = angle->start(); // lesser Y
|
||||
winding = test->windSum(SkMin32(tIndex, angle->end()));
|
||||
#if DEBUG_WINDING
|
||||
SkDebugf("%s 1 winding=%d\n", __FUNCTION__, winding);
|
||||
#endif
|
||||
} else {
|
||||
winding = test->windSum(tIndex);
|
||||
#if DEBUG_WINDING
|
||||
SkDebugf("%s 2 winding=%d\n", __FUNCTION__, winding);
|
||||
#endif
|
||||
}
|
||||
// see if a + change in T results in a +/- change in X (compute x'(T))
|
||||
SkScalar dx = (*SegmentDXAtT[test->verb()])(test->pts(), tHit);
|
||||
#if DEBUG_WINDING
|
||||
SkDebugf("%s dx=%1.9g\n", __FUNCTION__, dx);
|
||||
#endif
|
||||
SkASSERT(dx != 0);
|
||||
if (winding * dx > 0) { // if same signs, result is negative
|
||||
winding += dx > 0 ? -1 : 1;
|
||||
#if DEBUG_WINDING
|
||||
SkDebugf("%s 3 winding=%d\n", __FUNCTION__, winding);
|
||||
#endif
|
||||
SkASSERT(left >= 0 || right >= 0);
|
||||
if (left < 0) {
|
||||
left = right;
|
||||
}
|
||||
const Angle* angle = sorted[left];
|
||||
test = angle->segment();
|
||||
winding = test->windSum(angle);
|
||||
windValue = test->windValue(angle);
|
||||
#if 0
|
||||
int firstSign = angle->sign();
|
||||
if (firstSign * winding > 0) {
|
||||
winding -= test->rewind(angle);
|
||||
}
|
||||
#endif
|
||||
#if DEBUG_WINDING
|
||||
SkDebugf("%s angle winding=%d windValue=%d\n", __FUNCTION__, winding,
|
||||
windValue);
|
||||
#endif
|
||||
} else {
|
||||
winding = test->windSum(tIndex);
|
||||
windValue = test->windValue(tIndex);
|
||||
#if DEBUG_WINDING
|
||||
SkDebugf("%s single winding=%d windValue=%d\n", __FUNCTION__, winding,
|
||||
windValue);
|
||||
#endif
|
||||
}
|
||||
// see if a + change in T results in a +/- change in X (compute x'(T))
|
||||
SkScalar dx = (*SegmentDXAtT[test->verb()])(test->pts(), tHit);
|
||||
#if DEBUG_WINDING
|
||||
SkDebugf("%s dx=%1.9g\n", __FUNCTION__, dx);
|
||||
#endif
|
||||
SkASSERT(dx != 0);
|
||||
if (winding * dx > 0) { // if same signs, result is negative
|
||||
winding += dx > 0 ? -windValue : windValue;
|
||||
#if DEBUG_WINDING
|
||||
SkDebugf("%s final winding=%d\n", __FUNCTION__, winding);
|
||||
#endif
|
||||
}
|
||||
baseContour->setWinding(winding);
|
||||
return winding;
|
||||
@ -2851,9 +3033,12 @@ static Segment* findChase(SkTDArray<Span*>& chase, int& tIndex, int& endIndex) {
|
||||
angle = sorted[++firstIndex];
|
||||
winding = angle->segment()->windSum(angle);
|
||||
} while (winding == SK_MinS32);
|
||||
#if DEBUG_SORT
|
||||
angle->segment()->debugShowSort(sorted, firstIndex, winding);
|
||||
#endif
|
||||
int firstSign = angle->sign();
|
||||
if (firstSign * winding > 0) {
|
||||
winding -= firstSign;
|
||||
winding -= angle->segment()->rewind(angle);
|
||||
}
|
||||
// SkDebugf("%s firstSign=%d\n", __FUNCTION__, firstSign);
|
||||
// we care about first sign and whether wind sum indicates this
|
||||
|
@ -87,9 +87,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);
|
||||
#if DEBUG_DUMP
|
||||
bool c1Intersected = c1.segments()[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],
|
||||
pts1[0].fX, pts1[0].fY,
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include "Intersection_Tests.h"
|
||||
#include "ShapeOps.h"
|
||||
|
||||
#define TEST(name) { name, #name }
|
||||
|
||||
static void testLine1() {
|
||||
SkPath path, simple;
|
||||
path.moveTo(2,0);
|
||||
@ -404,63 +406,192 @@ static void testLine36() {
|
||||
testSimplifyx(path);
|
||||
}
|
||||
|
||||
#define TEST(name) { name, #name }
|
||||
static void testLine37() {
|
||||
SkPath path, simple;
|
||||
path.addRect(0, 20, 20, 20, (SkPath::Direction) 0);
|
||||
path.addRect(18, 24, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(0, 0, 9, 9, (SkPath::Direction) 0);
|
||||
testSimplifyx(path);
|
||||
}
|
||||
|
||||
static void testLine38() {
|
||||
SkPath path, simple;
|
||||
path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(6, 12, 18, 18, (SkPath::Direction) 0);
|
||||
path.addRect(12, 12, 21, 21, (SkPath::Direction) 0);
|
||||
testSimplifyx(path);
|
||||
}
|
||||
|
||||
static void testLine40() {
|
||||
SkPath path, simple;
|
||||
path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(12, 18, 24, 24, (SkPath::Direction) 0);
|
||||
path.addRect(4, 16, 13, 13, (SkPath::Direction) 0);
|
||||
testSimplifyx(path);
|
||||
}
|
||||
|
||||
static void testLine41() {
|
||||
SkPath path, simple;
|
||||
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
|
||||
path.addRect(18, 24, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(12, 0, 21, 21, (SkPath::Direction) 0);
|
||||
testSimplifyx(path);
|
||||
}
|
||||
|
||||
static void testLine42() {
|
||||
SkPath path, simple;
|
||||
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
|
||||
path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
|
||||
path.addRect(8, 16, 17, 17, (SkPath::Direction) 0);
|
||||
testSimplifyx(path);
|
||||
}
|
||||
|
||||
static void testLine43() {
|
||||
SkPath path, simple;
|
||||
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
|
||||
path.addRect(6, 24, 18, 18, (SkPath::Direction) 0);
|
||||
path.addRect(0, 32, 9, 36, (SkPath::Direction) 1);
|
||||
testSimplifyx(path);
|
||||
}
|
||||
|
||||
static void testLine44() {
|
||||
SkPath path, simple;
|
||||
path.addRect(10, 40, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(18, 0, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(18, 32, 27, 36, (SkPath::Direction) 1);
|
||||
testSimplifyx(path);
|
||||
}
|
||||
|
||||
static void testLine45() {
|
||||
SkPath path, simple;
|
||||
path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(18, 0, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(24, 32, 33, 36, (SkPath::Direction) 0);
|
||||
testSimplifyx(path);
|
||||
}
|
||||
|
||||
static void testLine46() {
|
||||
SkPath path, simple;
|
||||
path.addRect(10, 40, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(24, 0, 36, 36, (SkPath::Direction) 0);
|
||||
path.addRect(24, 32, 33, 36, (SkPath::Direction) 0);
|
||||
testSimplifyx(path);
|
||||
}
|
||||
|
||||
static void testLine47() {
|
||||
SkPath path, simple;
|
||||
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
|
||||
path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
|
||||
path.addRect(0, 0, 9, 9, (SkPath::Direction) 1);
|
||||
testSimplifyx(path);
|
||||
}
|
||||
|
||||
static void testLine48() {
|
||||
SkPath path, simple;
|
||||
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
|
||||
path.addRect(0, 6, 12, 12, (SkPath::Direction) 0);
|
||||
path.addRect(0, 0, 9, 9, (SkPath::Direction) 1);
|
||||
testSimplifyx(path);
|
||||
}
|
||||
|
||||
static void testLine49() {
|
||||
SkPath path, simple;
|
||||
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
|
||||
path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
|
||||
path.addRect(0, 0, 9, 9, (SkPath::Direction) 0);
|
||||
testSimplifyx(path);
|
||||
}
|
||||
|
||||
static void testLine50() {
|
||||
SkPath path, simple;
|
||||
path.addRect(10, 30, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(24, 20, 36, 30, (SkPath::Direction) 0);
|
||||
testSimplifyx(path);
|
||||
}
|
||||
|
||||
|
||||
static void testLine51() {
|
||||
SkPath path, simple;
|
||||
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 (*firstTest)() = testLine51;
|
||||
|
||||
static struct {
|
||||
void (*fun)();
|
||||
const char* str;
|
||||
} tests[] = {
|
||||
TEST(testLine1),
|
||||
TEST(testLine2),
|
||||
TEST(testLine3),
|
||||
TEST(testLine4),
|
||||
TEST(testLine5),
|
||||
TEST(testLine6),
|
||||
TEST(testLine7a),
|
||||
TEST(testLine7b),
|
||||
TEST(testLine7),
|
||||
TEST(testLine8),
|
||||
TEST(testLine9),
|
||||
TEST(testLine10),
|
||||
TEST(testLine10a),
|
||||
TEST(testLine11),
|
||||
TEST(testLine12),
|
||||
TEST(testLine13),
|
||||
TEST(testLine14),
|
||||
TEST(testLine15),
|
||||
TEST(testLine16),
|
||||
TEST(testLine17),
|
||||
TEST(testLine18),
|
||||
TEST(testLine19),
|
||||
TEST(testLine20),
|
||||
TEST(testLine21),
|
||||
TEST(testLine22),
|
||||
TEST(testLine23),
|
||||
TEST(testLine51),
|
||||
TEST(testLine50),
|
||||
TEST(testLine49),
|
||||
TEST(testLine48),
|
||||
TEST(testLine47),
|
||||
TEST(testLine46),
|
||||
TEST(testLine45),
|
||||
TEST(testLine44),
|
||||
TEST(testLine43),
|
||||
TEST(testLine42),
|
||||
TEST(testLine41),
|
||||
TEST(testLine40),
|
||||
TEST(testLine38),
|
||||
TEST(testLine37),
|
||||
TEST(testLine36),
|
||||
TEST(testLine35),
|
||||
TEST(testLine34),
|
||||
TEST(testLine33),
|
||||
TEST(testLine32),
|
||||
TEST(testLine31),
|
||||
TEST(testLine30),
|
||||
TEST(testLine29),
|
||||
TEST(testLine28),
|
||||
TEST(testLine27),
|
||||
TEST(testLine26),
|
||||
TEST(testLine25),
|
||||
TEST(testLine24a),
|
||||
TEST(testLine24),
|
||||
TEST(testLine25),
|
||||
TEST(testLine26),
|
||||
TEST(testLine27),
|
||||
TEST(testLine28),
|
||||
TEST(testLine29),
|
||||
TEST(testLine30),
|
||||
TEST(testLine31),
|
||||
TEST(testLine32),
|
||||
TEST(testLine33),
|
||||
TEST(testLine34),
|
||||
TEST(testLine35),
|
||||
TEST(testLine36),
|
||||
TEST(testLine23),
|
||||
TEST(testLine22),
|
||||
TEST(testLine21),
|
||||
TEST(testLine20),
|
||||
TEST(testLine19),
|
||||
TEST(testLine18),
|
||||
TEST(testLine17),
|
||||
TEST(testLine16),
|
||||
TEST(testLine15),
|
||||
TEST(testLine14),
|
||||
TEST(testLine13),
|
||||
TEST(testLine12),
|
||||
TEST(testLine11),
|
||||
TEST(testLine10a),
|
||||
TEST(testLine10),
|
||||
TEST(testLine9),
|
||||
TEST(testLine8),
|
||||
TEST(testLine7b),
|
||||
TEST(testLine7a),
|
||||
TEST(testLine7),
|
||||
TEST(testLine6),
|
||||
TEST(testLine5),
|
||||
TEST(testLine4),
|
||||
TEST(testLine3),
|
||||
TEST(testLine2),
|
||||
TEST(testLine1),
|
||||
};
|
||||
|
||||
static const size_t testCount = sizeof(tests) / sizeof(tests[0]);
|
||||
|
||||
static void (*firstTest)() = 0;
|
||||
static bool skipAll = false;
|
||||
|
||||
void SimplifyNew_Test() {
|
||||
if (skipAll) {
|
||||
return;
|
||||
}
|
||||
#ifdef SK_DEBUG
|
||||
gDebugMaxWindSum = 3;
|
||||
gDebugMaxWindValue = 3;
|
||||
#endif
|
||||
size_t index = 0;
|
||||
if (firstTest) {
|
||||
while (index < testCount && tests[index].fun != firstTest) {
|
||||
@ -473,4 +604,8 @@ void SimplifyNew_Test() {
|
||||
(*tests[index].fun)();
|
||||
firstTestComplete = true;
|
||||
}
|
||||
#ifdef SK_DEBUG
|
||||
gDebugMaxWindSum = SK_MaxS32;
|
||||
gDebugMaxWindValue = SK_MaxS32;
|
||||
#endif
|
||||
}
|
||||
|
@ -19,6 +19,15 @@
|
||||
// same with x (3 bits, 5 values)
|
||||
// not included, square, tall, wide (2 bits)
|
||||
// cw or ccw (1 bit)
|
||||
static const char marker[] =
|
||||
"</div>\n"
|
||||
"\n"
|
||||
"<script type=\"text/javascript\">\n"
|
||||
"\n"
|
||||
"var testDivs = [\n";
|
||||
static const char testLineStr[] = " testLine";
|
||||
static const char filename[] = "../../experimental/Intersection/debugXX.txt";
|
||||
static int testNumber;
|
||||
|
||||
static void* testSimplify4x4RectsMain(void* data)
|
||||
{
|
||||
@ -27,13 +36,13 @@ static void* testSimplify4x4RectsMain(void* data)
|
||||
SkASSERT(data);
|
||||
State4& state = *(State4*) data;
|
||||
int aShape = state.a & 0x03;
|
||||
int aCW = state.a >> 1;
|
||||
int aCW = state.a >> 2;
|
||||
int bShape = state.b & 0x03;
|
||||
int bCW = state.b >> 1;
|
||||
int bCW = state.b >> 2;
|
||||
int cShape = state.c & 0x03;
|
||||
int cCW = state.c >> 1;
|
||||
int cCW = state.c >> 2;
|
||||
int dShape = state.d & 0x03;
|
||||
int dCW = state.d >> 1;
|
||||
int dCW = state.d >> 2;
|
||||
for (int aXAlign = 0 ; aXAlign < 5; ++aXAlign) {
|
||||
for (int aYAlign = 0 ; aYAlign < 5; ++aYAlign) {
|
||||
for (int bXAlign = 0 ; bXAlign < 5; ++bXAlign) {
|
||||
@ -159,54 +168,43 @@ static void* testSimplify4x4RectsMain(void* data)
|
||||
dYAlign = 5;
|
||||
}
|
||||
path.close();
|
||||
SkDebugf("%s", pathStr);
|
||||
if (!testSimplifyx(path, out, state.bitmap, state.canvas)) {
|
||||
SkDebugf("*/\n{ %s %d, %d, %d, %d, %d, %d, %d, %d,"
|
||||
" %d, %d, %d, %d },\n/*\n",
|
||||
__FUNCTION__, state.a, state.b, state.c, state.d,
|
||||
aXAlign, aYAlign, bXAlign, bYAlign,
|
||||
cXAlign, cYAlign, dXAlign, dYAlign);
|
||||
SkFILEStream inFile("../../experimental/Intersection/op.htm");
|
||||
if (!inFile.isValid()) {
|
||||
continue;
|
||||
}
|
||||
SkTDArray<char> inData;
|
||||
inData.setCount(inFile.getLength());
|
||||
size_t inLen = inData.count();
|
||||
inFile.read(inData.begin(), inLen);
|
||||
inFile.setPath(NULL);
|
||||
SkFILEWStream outFile("../../experimental/Intersection/xop.htm");
|
||||
if (gRunTestsInOneThread) {
|
||||
SkDebugf("%s\n", pathStr);
|
||||
} else {
|
||||
SkFILEWStream outFile(state.filename);
|
||||
if (!outFile.isValid()) {
|
||||
continue;
|
||||
}
|
||||
const char marker[] =
|
||||
"</div>\n"
|
||||
"\n"
|
||||
"<script type=\"text/javascript\">\n"
|
||||
"\n"
|
||||
"var testDivs = [\n";
|
||||
const char testLineStr[] = " testLine";
|
||||
char* insert = strstr(inData.begin(), marker);
|
||||
if (!insert) {
|
||||
continue;
|
||||
}
|
||||
size_t startLen = insert - inData.begin();
|
||||
insert += sizeof(marker);
|
||||
const char* numLoc = insert + sizeof(testLineStr);
|
||||
int testNumber = atoi(numLoc) + 1;
|
||||
outFile.write(inData.begin(), startLen);
|
||||
outFile.writeText("<div id=\"testLine");
|
||||
outFile.writeDecAsText(testNumber);
|
||||
outFile.writeText("\">\n");
|
||||
outFile.writeText(pathStr);
|
||||
outFile.writeText("</div>\n\n");
|
||||
|
||||
outFile.writeText(marker);
|
||||
outFile.writeText(testLineStr);
|
||||
outFile.writeDecAsText(testNumber);
|
||||
outFile.writeText(",\n");
|
||||
outFile.write(insert, inLen - startLen - sizeof(marker));
|
||||
outFile.writeText(",\n\n\n");
|
||||
|
||||
outFile.writeText("static void testLine");
|
||||
outFile.writeDecAsText(testNumber);
|
||||
outFile.writeText("() {\n SkPath path, simple;\n");
|
||||
outFile.writeText(pathStr);
|
||||
outFile.writeText(" testSimplifyx(path);\n}\n");
|
||||
outFile.writeText("static void (*firstTest)() = testLine");
|
||||
outFile.writeDecAsText(testNumber);
|
||||
outFile.writeText(";\n\n");
|
||||
|
||||
outFile.writeText("static struct {\n");
|
||||
outFile.writeText(" void (*fun)();\n");
|
||||
outFile.writeText(" const char* str;\n");
|
||||
outFile.writeText("} tests[] = {\n");
|
||||
outFile.writeText(" TEST(testLine");
|
||||
outFile.writeDecAsText(testNumber);
|
||||
outFile.writeText("),\n");
|
||||
outFile.flush();
|
||||
}
|
||||
}
|
||||
testSimplifyx(path, out, state.bitmap, state.canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -218,12 +216,41 @@ static void* testSimplify4x4RectsMain(void* data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const int maxThreads = 1; // gRunTestsInOneThread ? 1 : 24;
|
||||
const int maxThreads = gRunTestsInOneThread ? 1 : 8;
|
||||
|
||||
void Simplify4x4RectsThreaded_Test()
|
||||
{
|
||||
#ifdef SK_DEBUG
|
||||
gDebugMaxWindSum = 3;
|
||||
gDebugMaxWindValue = 3;
|
||||
#endif
|
||||
if (maxThreads > 1) {
|
||||
SkFILEStream inFile("../../experimental/Intersection/op.htm");
|
||||
if (inFile.isValid()) {
|
||||
SkTDArray<char> inData;
|
||||
inData.setCount(inFile.getLength());
|
||||
size_t inLen = inData.count();
|
||||
inFile.read(inData.begin(), inLen);
|
||||
inFile.setPath(NULL);
|
||||
char* insert = strstr(inData.begin(), marker);
|
||||
if (insert) {
|
||||
insert += sizeof(marker) - 1;
|
||||
const char* numLoc = insert + sizeof(testLineStr) - 1;
|
||||
testNumber = atoi(numLoc) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
State4 threadState[maxThreads];
|
||||
int threadIndex = 0;
|
||||
int threadIndex;
|
||||
for (threadIndex = 0; threadIndex < maxThreads; ++threadIndex) {
|
||||
State4* statePtr = &threadState[threadIndex];
|
||||
strcpy(statePtr->filename, filename);
|
||||
SkASSERT(statePtr->filename[sizeof(filename) - 7] == 'X');
|
||||
SkASSERT(statePtr->filename[sizeof(filename) - 6] == 'X');
|
||||
statePtr->filename[sizeof(filename) - 7] = '0' + threadIndex / 10;
|
||||
statePtr->filename[sizeof(filename) - 6] = '0' + threadIndex % 10;
|
||||
}
|
||||
threadIndex = 0;
|
||||
for (int a = 0; a < 8; ++a) { // outermost
|
||||
for (int b = a ; b < 8; ++b) {
|
||||
for (int c = b ; c < 8; ++c) {
|
||||
@ -241,10 +268,18 @@ void Simplify4x4RectsThreaded_Test()
|
||||
} else {
|
||||
testSimplify4x4RectsMain(statePtr);
|
||||
}
|
||||
if (maxThreads > 1) SkDebugf(".");
|
||||
}
|
||||
if (maxThreads > 1) SkDebugf("%d", c);
|
||||
}
|
||||
if (maxThreads > 1) SkDebugf("\n%d", b);
|
||||
}
|
||||
if (maxThreads > 1) SkDebugf("\n\n%d", a);
|
||||
}
|
||||
waitForCompletion(threadState, threadIndex);
|
||||
#ifdef SK_DEBUG
|
||||
gDebugMaxWindSum = SK_MaxS32;
|
||||
gDebugMaxWindValue = SK_MaxS32;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -345,6 +345,18 @@ path.close();
|
||||
testSimplifyx(path);
|
||||
</div>
|
||||
|
||||
<div id="testLine19">
|
||||
SkPath path, simple;
|
||||
path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
|
||||
path.addRect(12, 16, 21, 21, (SkPath::Direction) 0);
|
||||
testSimplifyx(path);
|
||||
</div>
|
||||
|
||||
<div id="testLine24">
|
||||
path.addRect(0, 18, 12, 12, (SkPath::Direction) 0);
|
||||
path.addRect(4, 12, 13, 13, (SkPath::Direction) 0);
|
||||
</div>
|
||||
|
||||
<div id="testLine28">
|
||||
SkPath path, simple;
|
||||
path.addRect(0, 6, 12, 12, (SkPath::Direction) 0);
|
||||
@ -401,23 +413,129 @@ path.close();
|
||||
path.addRect(4, 16, 13, 13, (SkPath::Direction) 0);
|
||||
</div>
|
||||
|
||||
<div id="testLine37">
|
||||
path.addRect(0, 20, 20, 20, (SkPath::Direction) 0);
|
||||
path.addRect(18, 24, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(0, 0, 9, 9, (SkPath::Direction) 0);
|
||||
</div>
|
||||
|
||||
<div id="testLine38">
|
||||
path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(6, 12, 18, 18, (SkPath::Direction) 0);
|
||||
path.addRect(12, 12, 21, 21, (SkPath::Direction) 0);
|
||||
</div>
|
||||
|
||||
<div id="testLine39">
|
||||
path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(12, 6, 24, 24, (SkPath::Direction) 0);
|
||||
path.addRect(12, 4, 21, 21, (SkPath::Direction) 0);
|
||||
</div>
|
||||
|
||||
<div id="testLine40">
|
||||
path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(12, 18, 24, 24, (SkPath::Direction) 0);
|
||||
path.addRect(4, 16, 13, 13, (SkPath::Direction) 0);
|
||||
</div>
|
||||
|
||||
<div id="testLine41">
|
||||
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
|
||||
path.addRect(18, 24, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(12, 0, 21, 21, (SkPath::Direction) 0);
|
||||
</div>
|
||||
|
||||
<div id="testLine42">
|
||||
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
|
||||
path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
|
||||
path.addRect(8, 16, 17, 17, (SkPath::Direction) 0);
|
||||
</div>
|
||||
|
||||
<div id="testLine43">
|
||||
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
|
||||
path.addRect(6, 24, 18, 18, (SkPath::Direction) 0);
|
||||
path.addRect(0, 32, 9, 36, (SkPath::Direction) 1);
|
||||
</div>
|
||||
|
||||
<div id="testLine44">
|
||||
path.addRect(10, 40, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(18, 0, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(18, 32, 27, 36, (SkPath::Direction) 1);
|
||||
</div>
|
||||
|
||||
<div id="testLine45">
|
||||
path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(18, 0, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(24, 32, 33, 36, (SkPath::Direction) 0);
|
||||
</div>
|
||||
|
||||
<div id="testLine46">
|
||||
path.addRect(10, 40, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(24, 0, 36, 36, (SkPath::Direction) 0);
|
||||
path.addRect(24, 32, 33, 36, (SkPath::Direction) 0);
|
||||
</div>
|
||||
|
||||
<div id="testLine47">
|
||||
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
|
||||
path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
|
||||
path.addRect(0, 0, 9, 9, (SkPath::Direction) 1);
|
||||
</div>
|
||||
|
||||
<div id="testLine48">
|
||||
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
|
||||
path.addRect(0, 6, 12, 12, (SkPath::Direction) 0);
|
||||
path.addRect(0, 0, 9, 9, (SkPath::Direction) 1);
|
||||
</div>
|
||||
|
||||
<div id="testLine49">
|
||||
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
|
||||
path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
|
||||
path.addRect(0, 0, 9, 9, (SkPath::Direction) 0);
|
||||
</div>
|
||||
|
||||
<div id="testLine50">
|
||||
path.addRect(10, 30, 30, 30, (SkPath::Direction) 0);
|
||||
path.addRect(24, 20, 36, 30, (SkPath::Direction) 0);
|
||||
</div>
|
||||
|
||||
<div id="testLine51">
|
||||
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>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var testDivs = [
|
||||
testLine51,
|
||||
testLine50,
|
||||
testLine49,
|
||||
testLine48,
|
||||
testLine47,
|
||||
testLine46,
|
||||
testLine45,
|
||||
testLine44,
|
||||
testLine43,
|
||||
testLine42,
|
||||
testLine41,
|
||||
testLine40,
|
||||
testLine39,
|
||||
testLine38,
|
||||
testLine37,
|
||||
testLine36,
|
||||
testLine35,
|
||||
testLine34,
|
||||
testLine33,
|
||||
testLine9,
|
||||
testLine7,
|
||||
testLine30,
|
||||
testLine32,
|
||||
testLine31,
|
||||
testLine29,
|
||||
testLine28,
|
||||
testLine24,
|
||||
testLine19,
|
||||
testLine17,
|
||||
testLine9,
|
||||
testLine7,
|
||||
testSimplifyQuadratic21,
|
||||
testSimplifyQuadratic20,
|
||||
testSimplifyQuadratic19,
|
||||
|
Loading…
Reference in New Issue
Block a user