diff options
Diffstat (limited to 'tests/PathOpsDebug.cpp')
-rwxr-xr-x | tests/PathOpsDebug.cpp | 568 |
1 files changed, 568 insertions, 0 deletions
diff --git a/tests/PathOpsDebug.cpp b/tests/PathOpsDebug.cpp new file mode 100755 index 0000000000..5c3563ed0f --- /dev/null +++ b/tests/PathOpsDebug.cpp @@ -0,0 +1,568 @@ +#include "SkOpContour.h" +#include "SkIntersectionHelper.h" +#include "SkOpSegment.h" + +inline void DebugDumpDouble(double x) { + if (x == floor(x)) { + SkDebugf("%.0f", x); + } else { + SkDebugf("%1.19g", x); + } +} + +inline void DebugDumpFloat(float x) { + if (x == floorf(x)) { + SkDebugf("%.0f", x); + } else { + SkDebugf("%1.9gf", x); + } +} + +// if not defined by PathOpsDebug.cpp ... +#if !defined SK_DEBUG && FORCE_RELEASE +bool SkPathOpsDebug::ValidWind(int wind) { + return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF; +} + +void SkPathOpsDebug::WindingPrintf(int wind) { + if (wind == SK_MinS32) { + SkDebugf("?"); + } else { + SkDebugf("%d", wind); + } +} +#endif + +void SkOpAngle::dump() const { +#if DEBUG_SORT + debugOne(false); +#endif + SkDebugf("\n"); +} + +void SkOpAngle::dumpFromTo(const SkOpSegment* segment, int from, int to) const { +#if DEBUG_SORT && DEBUG_ANGLE + const SkOpAngle* first = this; + const SkOpAngle* next = this; + const char* indent = ""; + do { + SkDebugf("%s", indent); + next->debugOne(false); + if (segment == next->fSegment) { + if (fNext && from == fNext->debugID()) { + SkDebugf(" << from"); + } + if (fNext && to == fNext->debugID()) { + SkDebugf(" << to"); + } + } + SkDebugf("\n"); + indent = " "; + next = next->fNext; + } while (next && next != first); +#endif +} + +void SkOpAngle::dumpLoop() const { + const SkOpAngle* first = this; + const SkOpAngle* next = this; + do { + next->dump(); + next = next->fNext; + } while (next && next != first); +} + +void SkOpAngle::dumpPartials() const { + const SkOpAngle* first = this; + const SkOpAngle* next = this; + do { + next->fCurvePart.dumpNumber(); + next = next->fNext; + } while (next && next != first); +} + +void SkOpContour::dump() const { + int segmentCount = fSegments.count(); + SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID()); + for (int test = 0; test < segmentCount; ++test) { + SkDebugf(" [%d] ((SkOpSegment*) 0x%p) [%d]\n", test, &fSegments[test], + fSegments[test].debugID()); + } +} + +void SkOpContour::dumpAngles() const { + int segmentCount = fSegments.count(); + SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID()); + for (int test = 0; test < segmentCount; ++test) { + SkDebugf(" [%d] ", test); + fSegments[test].dumpAngles(); + } +} + +void SkOpContour::dumpPts() const { + int segmentCount = fSegments.count(); + SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID()); + for (int test = 0; test < segmentCount; ++test) { + SkDebugf(" [%d] ", test); + fSegments[test].dumpPts(); + } +} + +void SkOpContour::dumpSpans() const { + int segmentCount = fSegments.count(); + SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID()); + for (int test = 0; test < segmentCount; ++test) { + SkDebugf(" [%d] ", test); + fSegments[test].dumpSpans(); + } +} + +void SkDCubic::dump() const { + SkDebugf("{{"); + int index = 0; + do { + fPts[index].dump(); + SkDebugf(", "); + } while (++index < 3); + fPts[index].dump(); + SkDebugf("}}\n"); +} + +void SkDCubic::dumpNumber() const { + SkDebugf("{{"); + int index = 0; + bool dumpedOne = false; + do { + if (!(fPts[index].fX == fPts[index].fX && fPts[index].fY == fPts[index].fY)) { + continue; + } + if (dumpedOne) { + SkDebugf(", "); + } + fPts[index].dump(); + dumpedOne = true; + } while (++index < 3); + if (fPts[index].fX == fPts[index].fX && fPts[index].fY == fPts[index].fY) { + if (dumpedOne) { + SkDebugf(", "); + } + fPts[index].dump(); + } + SkDebugf("}}\n"); +} + +void SkDLine::dump() const { + SkDebugf("{{"); + fPts[0].dump(); + SkDebugf(", "); + fPts[1].dump(); + SkDebugf("}}\n"); +} + +void SkDPoint::dump() const { + SkDebugf("{"); + DebugDumpDouble(fX); + SkDebugf(", "); + DebugDumpDouble(fY); + SkDebugf("}"); +} + +void SkDPoint::Dump(const SkPoint& pt) { + SkDebugf("{"); + DebugDumpFloat(pt.fX); + SkDebugf(", "); + DebugDumpFloat(pt.fY); + SkDebugf("}"); +} + + +void SkDQuad::dumpComma(const char* comma) const { + SkDebugf("{{"); + int index = 0; + do { + fPts[index].dump(); + SkDebugf(", "); + } while (++index < 2); + fPts[index].dump(); + SkDebugf("}}%s\n", comma ? comma : ""); +} + +void SkDQuad::dump() const { + dumpComma(""); +} + +void SkIntersectionHelper::dump() const { + SkDPoint::Dump(pts()[0]); + SkDPoint::Dump(pts()[1]); + if (verb() >= SkPath::kQuad_Verb) { + SkDPoint::Dump(pts()[2]); + } + if (verb() >= SkPath::kCubic_Verb) { + SkDPoint::Dump(pts()[3]); + } +} + +void SkOpSegment::dumpAngles() const { + SkDebugf("((SkOpSegment*) 0x%p) [%d]\n", this, debugID()); + int fromIndex = -1, toIndex = -1; + for (int index = 0; index < count(); ++index) { + int fIndex = fTs[index].fFromAngleIndex; + int tIndex = fTs[index].fToAngleIndex; + if (fromIndex == fIndex && tIndex == toIndex) { + continue; + } + if (fIndex >= 0) { + SkDebugf(" [%d] from=%d ", index, fIndex); + const SkOpAngle& angle = this->angle(fIndex); + angle.dumpFromTo(this, fIndex, tIndex); + } + if (tIndex >= 0) { + SkDebugf(" [%d] to=%d ", index, tIndex); + const SkOpAngle& angle = this->angle(tIndex); + angle.dumpFromTo(this, fIndex, tIndex); + } + fromIndex = fIndex; + toIndex = tIndex; + } +} + +void SkOpSegment::dumpContour(int firstID, int lastID) const { + if (debugID() < 0) { + return; + } + const SkOpSegment* test = this - (debugID() - 1); + test += (firstID - 1); + const SkOpSegment* last = test + (lastID - firstID); + while (test <= last) { + test->dumpSpans(); + ++test; + } +} + +void SkOpSegment::dumpPts() const { + int last = SkPathOpsVerbToPoints(fVerb); + SkDebugf("((SkOpSegment*) 0x%p) [%d] {{", this, debugID()); + int index = 0; + do { + SkDPoint::Dump(fPts[index]); + SkDebugf(", "); + } while (++index < last); + SkDPoint::Dump(fPts[index]); + SkDebugf("}}\n"); +} + +void SkOpSegment::dumpDPts() const { + int count = SkPathOpsVerbToPoints(fVerb); + SkDebugf("((SkOpSegment*) 0x%p) [%d] {{", this, debugID()); + int index = 0; + do { + SkDPoint dPt = {fPts[index].fX, fPts[index].fY}; + dPt.dump(); + if (index != count) { + SkDebugf(", "); + } + } while (++index <= count); + SkDebugf("}}\n"); +} + +void SkOpSegment::dumpSpans() const { + int count = this->count(); + SkDebugf("((SkOpSegment*) 0x%p) [%d]\n", this, debugID()); + for (int index = 0; index < count; ++index) { + const SkOpSpan& span = this->span(index); + SkDebugf(" [%d] ", index); + span.dumpOne(); + } +} + +void SkPathOpsDebug::DumpAngles(const SkTArray<SkOpAngle, true>& angles) { + int count = angles.count(); + for (int index = 0; index < count; ++index) { + angles[index].dump(); + } +} + +void SkPathOpsDebug::DumpAngles(const SkTArray<SkOpAngle* , true>& angles) { + int count = angles.count(); + for (int index = 0; index < count; ++index) { + angles[index]->dump(); + } +} + +void SkPathOpsDebug::DumpContours(const SkTArray<SkOpContour, true>& contours) { + int count = contours.count(); + for (int index = 0; index < count; ++index) { + contours[index].dump(); + } +} + +void SkPathOpsDebug::DumpContours(const SkTArray<SkOpContour* , true>& contours) { + int count = contours.count(); + for (int index = 0; index < count; ++index) { + contours[index]->dump(); + } +} + +void SkPathOpsDebug::DumpContourAngles(const SkTArray<SkOpContour, true>& contours) { + int count = contours.count(); + for (int index = 0; index < count; ++index) { + contours[index].dumpAngles(); + } +} + +void SkPathOpsDebug::DumpContourAngles(const SkTArray<SkOpContour* , true>& contours) { + int count = contours.count(); + for (int index = 0; index < count; ++index) { + contours[index]->dumpAngles(); + } +} + +void SkPathOpsDebug::DumpContourPts(const SkTArray<SkOpContour, true>& contours) { + int count = contours.count(); + for (int index = 0; index < count; ++index) { + contours[index].dumpPts(); + } +} + +void SkPathOpsDebug::DumpContourPts(const SkTArray<SkOpContour* , true>& contours) { + int count = contours.count(); + for (int index = 0; index < count; ++index) { + contours[index]->dumpPts(); + } +} + +void SkPathOpsDebug::DumpContourSpans(const SkTArray<SkOpContour, true>& contours) { + int count = contours.count(); + for (int index = 0; index < count; ++index) { + contours[index].dumpSpans(); + } +} + +void SkPathOpsDebug::DumpContourSpans(const SkTArray<SkOpContour* , true>& contours) { + int count = contours.count(); + for (int index = 0; index < count; ++index) { + contours[index]->dumpSpans(); + } +} + +void SkPathOpsDebug::DumpSpans(const SkTDArray<SkOpSpan *>& spans) { + int count = spans.count(); + for (int index = 0; index < count; ++index) { + const SkOpSpan* span = spans[index]; + const SkOpSpan& oSpan = span->fOther->span(span->fOtherIndex); + const SkOpSegment* segment = oSpan.fOther; + SkDebugf("((SkOpSegment*) 0x%p) [%d] ", segment, segment->debugID()); + SkDebugf("spanIndex:%d ", oSpan.fOtherIndex); + span->dumpOne(); + } +} + +// this does not require that other T index is initialized or correct +const SkOpSegment* SkOpSpan::debugToSegment(ptrdiff_t* spanIndex) const { + if (!fOther) { + return NULL; + } + int oppCount = fOther->count(); + for (int index = 0; index < oppCount; ++index) { + const SkOpSpan& otherSpan = fOther->span(index); + double otherTestT = otherSpan.fT; + if (otherTestT < fOtherT) { + continue; + } + SkASSERT(otherTestT == fOtherT); + const SkOpSegment* candidate = otherSpan.fOther; + const SkOpSpan* first = candidate->spans().begin(); + const SkOpSpan* last = candidate->spans().end() - 1; + if (first <= this && this <= last) { + if (spanIndex) { + *spanIndex = this - first; + } + return candidate; + } + } + SkASSERT(0); + return NULL; +} + +void SkOpSpan::dumpOne() const { + SkDebugf("t="); + DebugDumpDouble(fT); + SkDebugf(" pt="); + SkDPoint::Dump(fPt); + if (fOther) { + SkDebugf(" other.fID=%d", fOther->debugID()); + SkDebugf(" [%d] otherT=", fOtherIndex); + DebugDumpDouble(fOtherT); + } else { + SkDebugf(" other.fID=? [?] otherT=?"); + } +#if DEBUG_WINDING + SkDebugf(" windSum="); + SkPathOpsDebug::WindingPrintf(fWindSum); +#endif + if (SkPathOpsDebug::ValidWind(fOppSum) || fOppValue != 0) { +#if DEBUG_WINDING + SkDebugf(" oppSum="); + SkPathOpsDebug::WindingPrintf(fOppSum); +#endif + } + SkDebugf(" windValue=%d", fWindValue); + if (SkPathOpsDebug::ValidWind(fOppSum) || fOppValue != 0) { + SkDebugf(" oppValue=%d", fOppValue); + } + SkDebugf(" from=%d", fFromAngleIndex); + SkDebugf(" to=%d", fToAngleIndex); + if (fDone) { + SkDebugf(" done"); + } + if (fUnsortableStart) { + SkDebugf(" unsortable-start"); + } + if (fUnsortableEnd) { + SkDebugf(" unsortable-end"); + } + if (fTiny) { + SkDebugf(" tiny"); + } + if (fSmall) { + SkDebugf(" small"); + } + if (fLoop) { + SkDebugf(" loop"); + } + SkDebugf("\n"); +} + +void SkOpSpan::dump() const { + ptrdiff_t spanIndex; + const SkOpSegment* segment = debugToSegment(&spanIndex); + if (segment) { + SkDebugf("((SkOpSegment*) 0x%p) [%d]\n", segment, segment->debugID()); + SkDebugf(" [%d] ", spanIndex); + } else { + SkDebugf("((SkOpSegment*) ?) [?]\n"); + SkDebugf(" [?] "); + } + dumpOne(); +} + +void Dump(const SkTArray<class SkOpAngle, true>& angles) { + SkPathOpsDebug::DumpAngles(angles); +} + +void Dump(const SkTArray<class SkOpAngle* , true>& angles) { + SkPathOpsDebug::DumpAngles(angles); +} + +void Dump(const SkTArray<class SkOpAngle, true>* angles) { + SkPathOpsDebug::DumpAngles(*angles); +} + +void Dump(const SkTArray<class SkOpAngle* , true>* angles) { + SkPathOpsDebug::DumpAngles(*angles); +} + +void Dump(const SkTArray<class SkOpContour, true>& contours) { + SkPathOpsDebug::DumpContours(contours); +} + +void Dump(const SkTArray<class SkOpContour* , true>& contours) { + SkPathOpsDebug::DumpContours(contours); +} + +void Dump(const SkTArray<class SkOpContour, true>* contours) { + SkPathOpsDebug::DumpContours(*contours); +} + +void Dump(const SkTArray<class SkOpContour* , true>* contours) { + SkPathOpsDebug::DumpContours(*contours); +} + +void Dump(const SkTDArray<SkOpSpan *>& chaseArray) { + SkPathOpsDebug::DumpSpans(chaseArray); +} + +void Dump(const SkTDArray<SkOpSpan *>* chaseArray) { + SkPathOpsDebug::DumpSpans(*chaseArray); +} + +void DumpAngles(const SkTArray<class SkOpContour, true>& contours) { + SkPathOpsDebug::DumpContourAngles(contours); +} + +void DumpAngles(const SkTArray<class SkOpContour* , true>& contours) { + SkPathOpsDebug::DumpContourAngles(contours); +} + +void DumpAngles(const SkTArray<class SkOpContour, true>* contours) { + SkPathOpsDebug::DumpContourAngles(*contours); +} + +void DumpAngles(const SkTArray<class SkOpContour* , true>* contours) { + SkPathOpsDebug::DumpContourAngles(*contours); +} + +void DumpSpans(const SkTArray<class SkOpContour, true>& contours) { + SkPathOpsDebug::DumpContourSpans(contours); +} + +void DumpSpans(const SkTArray<class SkOpContour* , true>& contours) { + SkPathOpsDebug::DumpContourSpans(contours); +} + +void DumpSpans(const SkTArray<class SkOpContour, true>* contours) { + SkPathOpsDebug::DumpContourSpans(*contours); +} + +void DumpSpans(const SkTArray<class SkOpContour* , true>* contours) { + SkPathOpsDebug::DumpContourSpans(*contours); +} + +void DumpPts(const SkTArray<class SkOpContour, true>& contours) { + SkPathOpsDebug::DumpContourPts(contours); +} + +void DumpPts(const SkTArray<class SkOpContour* , true>& contours) { + SkPathOpsDebug::DumpContourPts(contours); +} + +void DumpPts(const SkTArray<class SkOpContour, true>* contours) { + SkPathOpsDebug::DumpContourPts(*contours); +} + +void DumpPts(const SkTArray<class SkOpContour* , true>* contours) { + SkPathOpsDebug::DumpContourPts(*contours); +} + +static void dumpTestCase(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) { + SkDebugf("<div id=\"quad%d\">\n", testNo); + quad1.dumpComma(","); + quad2.dump(); + SkDebugf("</div>\n\n"); +} + +static void dumpTestTrailer() { + SkDebugf("</div>\n\n<script type=\"text/javascript\">\n\n"); + SkDebugf(" var testDivs = [\n"); +} + +static void dumpTestList(int testNo, double min) { + SkDebugf(" quad%d,", testNo); + if (min > 0) { + SkDebugf(" // %1.9g", min); + } + SkDebugf("\n"); +} + +void DumpQ(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) { + SkDebugf("\n"); + dumpTestCase(quad1, quad2, testNo); + dumpTestTrailer(); + dumpTestList(testNo, 0); + SkDebugf("\n"); +} + +void DumpT(const SkDQuad& quad, double t) { + SkDLine line = {{quad.ptAtT(t), quad[0]}}; + line.dump(); +} |