#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& angles) { int count = angles.count(); for (int index = 0; index < count; ++index) { angles[index].dump(); } } void SkPathOpsDebug::DumpAngles(const SkTArray& angles) { int count = angles.count(); for (int index = 0; index < count; ++index) { angles[index]->dump(); } } void SkPathOpsDebug::DumpContours(const SkTArray& contours) { int count = contours.count(); for (int index = 0; index < count; ++index) { contours[index].dump(); } } void SkPathOpsDebug::DumpContours(const SkTArray& contours) { int count = contours.count(); for (int index = 0; index < count; ++index) { contours[index]->dump(); } } void SkPathOpsDebug::DumpContourAngles(const SkTArray& contours) { int count = contours.count(); for (int index = 0; index < count; ++index) { contours[index].dumpAngles(); } } void SkPathOpsDebug::DumpContourAngles(const SkTArray& contours) { int count = contours.count(); for (int index = 0; index < count; ++index) { contours[index]->dumpAngles(); } } void SkPathOpsDebug::DumpContourPts(const SkTArray& contours) { int count = contours.count(); for (int index = 0; index < count; ++index) { contours[index].dumpPts(); } } void SkPathOpsDebug::DumpContourPts(const SkTArray& contours) { int count = contours.count(); for (int index = 0; index < count; ++index) { contours[index]->dumpPts(); } } void SkPathOpsDebug::DumpContourSpans(const SkTArray& contours) { int count = contours.count(); for (int index = 0; index < count; ++index) { contours[index].dumpSpans(); } } void SkPathOpsDebug::DumpContourSpans(const SkTArray& contours) { int count = contours.count(); for (int index = 0; index < count; ++index) { contours[index]->dumpSpans(); } } void SkPathOpsDebug::DumpSpans(const SkTDArray& 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& angles) { SkPathOpsDebug::DumpAngles(angles); } void Dump(const SkTArray& angles) { SkPathOpsDebug::DumpAngles(angles); } void Dump(const SkTArray* angles) { SkPathOpsDebug::DumpAngles(*angles); } void Dump(const SkTArray* angles) { SkPathOpsDebug::DumpAngles(*angles); } void Dump(const SkTArray& contours) { SkPathOpsDebug::DumpContours(contours); } void Dump(const SkTArray& contours) { SkPathOpsDebug::DumpContours(contours); } void Dump(const SkTArray* contours) { SkPathOpsDebug::DumpContours(*contours); } void Dump(const SkTArray* contours) { SkPathOpsDebug::DumpContours(*contours); } void Dump(const SkTDArray& chaseArray) { SkPathOpsDebug::DumpSpans(chaseArray); } void Dump(const SkTDArray* chaseArray) { SkPathOpsDebug::DumpSpans(*chaseArray); } void DumpAngles(const SkTArray& contours) { SkPathOpsDebug::DumpContourAngles(contours); } void DumpAngles(const SkTArray& contours) { SkPathOpsDebug::DumpContourAngles(contours); } void DumpAngles(const SkTArray* contours) { SkPathOpsDebug::DumpContourAngles(*contours); } void DumpAngles(const SkTArray* contours) { SkPathOpsDebug::DumpContourAngles(*contours); } void DumpSpans(const SkTArray& contours) { SkPathOpsDebug::DumpContourSpans(contours); } void DumpSpans(const SkTArray& contours) { SkPathOpsDebug::DumpContourSpans(contours); } void DumpSpans(const SkTArray* contours) { SkPathOpsDebug::DumpContourSpans(*contours); } void DumpSpans(const SkTArray* contours) { SkPathOpsDebug::DumpContourSpans(*contours); } void DumpPts(const SkTArray& contours) { SkPathOpsDebug::DumpContourPts(contours); } void DumpPts(const SkTArray& contours) { SkPathOpsDebug::DumpContourPts(contours); } void DumpPts(const SkTArray* contours) { SkPathOpsDebug::DumpContourPts(*contours); } void DumpPts(const SkTArray* contours) { SkPathOpsDebug::DumpContourPts(*contours); } static void dumpTestCase(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) { SkDebugf("
\n", testNo); quad1.dumpComma(","); quad2.dump(); SkDebugf("
\n\n"); } static void dumpTestTrailer() { SkDebugf("\n\n