aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/PathOpsDebug.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/PathOpsDebug.cpp')
-rwxr-xr-xtests/PathOpsDebug.cpp568
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();
+}