From 54359294a7c9dc54802d512a5d891a35c1663392 Mon Sep 17 00:00:00 2001 From: caryclark Date: Thu, 26 Mar 2015 07:52:43 -0700 Subject: cumulative pathops patch Replace the implicit curve intersection with a geometric curve intersection. The implicit intersection proved mathematically unstable and took a long time to zero in on an answer. Use pointers instead of indices to refer to parts of curves. Indices required awkward renumbering. Unify t and point values so that small intervals can be eliminated in one pass. Break cubics up front to eliminate loops and cusps. Make the Simplify and Op code more regular and eliminate arbitrary differences. Add a builder that takes an array of paths and operators. Delete unused code. BUG=skia:3588 R=reed@google.com Review URL: https://codereview.chromium.org/1037573004 --- tests/PathOpsDebug.cpp | 1372 +++++++++++++++++++++++++++++------------------- 1 file changed, 837 insertions(+), 535 deletions(-) (limited to 'tests/PathOpsDebug.cpp') diff --git a/tests/PathOpsDebug.cpp b/tests/PathOpsDebug.cpp index c4fbbfa695..93fe33d99a 100755 --- a/tests/PathOpsDebug.cpp +++ b/tests/PathOpsDebug.cpp @@ -1,3 +1,12 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "PathOpsTSectDebug.h" +#include "SkOpCoincidence.h" #include "SkOpContour.h" #include "SkIntersectionHelper.h" #include "SkOpSegment.h" @@ -50,7 +59,6 @@ static void output_points(const SkPoint* pts, int count) { SkDebugf(", "); } } - SkDebugf(");\n"); } static void showPathContours(SkPath::RawIter& iter, const char* pathName) { @@ -61,18 +69,27 @@ static void showPathContours(SkPath::RawIter& iter, const char* pathName) { case SkPath::kMove_Verb: SkDebugf(" %s.moveTo(", pathName); output_points(&pts[0], 1); + SkDebugf(");\n"); continue; case SkPath::kLine_Verb: SkDebugf(" %s.lineTo(", pathName); output_points(&pts[1], 1); + SkDebugf(");\n"); break; case SkPath::kQuad_Verb: SkDebugf(" %s.quadTo(", pathName); output_points(&pts[1], 2); + SkDebugf(");\n"); + break; + case SkPath::kConic_Verb: + SkDebugf(" %s.conicTo(", pathName); + output_points(&pts[1], 2); + SkDebugf(", %1.9gf);\n", iter.conicWeight()); break; case SkPath::kCubic_Verb: SkDebugf(" %s.cubicTo(", pathName); output_points(&pts[1], 3); + SkDebugf(");\n"); break; case SkPath::kClose_Verb: SkDebugf(" %s.close();\n", pathName); @@ -129,11 +146,11 @@ static void show_function_header(const char* functionName) { } static const char* gOpStrs[] = { - "kDifference_PathOp", - "kIntersect_PathOp", - "kUnion_PathOp", + "kDifference_SkPathOp", + "kIntersect_SkPathOp", + "kUnion_SkPathOp", "kXor_PathOp", - "kReverseDifference_PathOp", + "kReverseDifference_SkPathOp", }; static void show_op(SkPathOp op, const char* pathOne, const char* pathTwo) { @@ -168,228 +185,35 @@ void SkPathOpsDebug::WindingPrintf(int wind) { } #endif -void SkOpAngle::dump() const { - dumpOne(true); - SkDebugf("\n"); -} - -void SkOpAngle::dumpOne(bool functionHeader) const { -// fSegment->debugValidate(); - const SkOpSpan& mSpan = fSegment->span(SkMin32(fStart, fEnd)); - if (functionHeader) { - SkDebugf("%s ", __FUNCTION__); - } - SkDebugf("[%d", fSegment->debugID()); - SkDebugf("/%d", debugID()); - SkDebugf("] next="); - if (fNext) { - SkDebugf("%d", fNext->fSegment->debugID()); - SkDebugf("/%d", fNext->debugID()); - } else { - SkDebugf("?"); - } - SkDebugf(" sect=%d/%d ", fSectorStart, fSectorEnd); - SkDebugf(" s=%1.9g [%d] e=%1.9g [%d]", fSegment->span(fStart).fT, fStart, - fSegment->span(fEnd).fT, fEnd); - SkDebugf(" sgn=%d windVal=%d", sign(), mSpan.fWindValue); - - SkDebugf(" windSum="); - SkPathOpsDebug::WindingPrintf(mSpan.fWindSum); - if (mSpan.fOppValue != 0 || mSpan.fOppSum != SK_MinS32) { - SkDebugf(" oppVal=%d", mSpan.fOppValue); - SkDebugf(" oppSum="); - SkPathOpsDebug::WindingPrintf(mSpan.fOppSum); - } - if (mSpan.fDone) { - SkDebugf(" done"); - } - if (unorderable()) { - SkDebugf(" unorderable"); - } - if (small()) { - SkDebugf(" small"); - } - if (mSpan.fTiny) { - SkDebugf(" tiny"); - } - if (fSegment->operand()) { - SkDebugf(" operand"); - } - if (fStop) { - SkDebugf(" stop"); - } -} - -void SkOpAngle::dumpTo(const SkOpSegment* segment, const SkOpAngle* to) const { - const SkOpAngle* first = this; - const SkOpAngle* next = this; - const char* indent = ""; - do { - SkDebugf("%s", indent); - next->dumpOne(false); - if (segment == next->fSegment) { - if (this == fNext) { - SkDebugf(" << from"); - } - if (to == fNext) { - SkDebugf(" << to"); - } - } - SkDebugf("\n"); - indent = " "; - next = next->fNext; - } while (next && next != first); -} - -void SkOpAngle::dumpLoop() const { - const SkOpAngle* first = this; - const SkOpAngle* next = this; - do { - next->dumpOne(false); - SkDebugf("\n"); - 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 SkOpAngleSet::dump() const { - // FIXME: unimplemented -/* This requires access to the internal SkChunkAlloc data - Defer implementing this until it is needed for debugging -*/ - SkASSERT(0); -} - -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::dumpCoincidence(const SkCoincidence& coin) const { - int thisIndex = coin.fSegments[0]; - const SkOpSegment& s1 = fSegments[thisIndex]; - int otherIndex = coin.fSegments[1]; - const SkOpSegment& s2 = coin.fOther->fSegments[otherIndex]; - SkDebugf("((SkOpSegment*) 0x%p) [%d] ((SkOpSegment*) 0x%p) [%d]\n", &s1, s1.debugID(), - &s2, s2.debugID()); - for (int index = 0; index < 2; ++index) { - SkDebugf(" {%1.9gf, %1.9gf}", coin.fPts[0][index].fX, coin.fPts[0][index].fY); - if (coin.fNearly[index]) { - SkDebugf(" {%1.9gf, %1.9gf}", coin.fPts[1][index].fX, coin.fPts[1][index].fY); - } - SkDebugf(" seg1t=%1.9g seg2t=%1.9g\n", coin.fTs[0][index], coin.fTs[1][index]); - } -} - -void SkOpContour::dumpCoincidences() const { - int count = fCoincidences.count(); - if (count > 0) { - SkDebugf("fCoincidences count=%d\n", count); - for (int test = 0; test < count; ++test) { - dumpCoincidence(fCoincidences[test]); - } - } - count = fPartialCoincidences.count(); - if (count == 0) { - return; - } - SkDebugf("fPartialCoincidences count=%d\n", count); - for (int test = 0; test < count; ++test) { - dumpCoincidence(fPartialCoincidences[test]); - } -} - -void SkOpContour::dumpPt(int index) const { - int segmentCount = fSegments.count(); - for (int test = 0; test < segmentCount; ++test) { - const SkOpSegment& segment = fSegments[test]; - if (segment.debugID() == index) { - fSegments[test].dumpPts(); - } - } -} - -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::dumpSpan(int index) const { - int segmentCount = fSegments.count(); - for (int test = 0; test < segmentCount; ++test) { - const SkOpSegment& segment = fSegments[test]; - if (segment.debugID() == index) { - fSegments[test].dumpSpans(); - } - } +void SkDCubic::dump() const { + dumpInner(); + SkDebugf("}},\n"); } -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::dumpID(int id) const { + dumpInner(); + SkDebugf("}} id=%d\n", id); } -void SkDCubic::dump() const { - SkDebugf("{{"); - int index = 0; - do { - fPts[index].dump(); - SkDebugf(", "); - } while (++index < 3); - fPts[index].dump(); - SkDebugf("}}\n"); -} +static inline bool double_is_NaN(double x) { return x != x; } -void SkDCubic::dumpNumber() const { +void SkDCubic::dumpInner() 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) { + if (index != 0) { + if (double_is_NaN(fPts[index].fX) && double_is_NaN(fPts[index].fY)) { + return; + } 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(); + if (double_is_NaN(fPts[index].fX) && double_is_NaN(fPts[index].fY)) { + return; } - SkDebugf("}}\n"); + SkDebugf(", "); + fPts[index].dump(); } void SkDLine::dump() const { @@ -397,7 +221,7 @@ void SkDLine::dump() const { fPts[0].dump(); SkDebugf(", "); fPts[1].dump(); - SkDebugf("}}\n"); + SkDebugf("}},\n"); } void SkDPoint::dump() const { @@ -425,10 +249,16 @@ void SkDPoint::DumpHex(const SkPoint& pt) { } void SkDQuad::dump() const { - dumpComma(""); + dumpInner(); + SkDebugf("}},\n"); } -void SkDQuad::dumpComma(const char* comma) const { +void SkDQuad::dumpID(int id) const { + dumpInner(); + SkDebugf("}} id=%d\n", id); +} + +void SkDQuad::dumpInner() const { SkDebugf("{{"); int index = 0; do { @@ -436,436 +266,262 @@ void SkDQuad::dumpComma(const char* comma) const { SkDebugf(", "); } while (++index < 2); fPts[index].dump(); - SkDebugf("}}%s\n", comma ? comma : ""); } -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 SkIntersections::dump() const { + SkDebugf("used=%d of %d", fUsed, fMax); + for (int index = 0; index < fUsed; ++index) { + SkDebugf(" t=(%s%1.9g,%s%1.9g) pt=(%1.9g,%1.9g)", + fIsCoincident[0] & (1 << index) ? "*" : "", fT[0][index], + fIsCoincident[1] & (1 << index) ? "*" : "", fT[1][index], + fPt[index].fX, fPt[index].fY); + if (index < 2 && fNearlySame[index]) { + SkDebugf(" pt2=(%1.9g,%1.9g)",fPt2[index].fX, fPt2[index].fY); + } } + SkDebugf("\n"); } -const SkTDArray& SkOpSegment::debugSpans() const { - return fTs; -} - -void SkOpSegment::dumpAngles() const { - SkDebugf("((SkOpSegment*) 0x%p) [%d]\n", this, debugID()); - const SkOpAngle* fromAngle = NULL; - const SkOpAngle* toAngle = NULL; - for (int index = 0; index < count(); ++index) { - const SkOpAngle* fAngle = fTs[index].fFromAngle; - const SkOpAngle* tAngle = fTs[index].fToAngle; - if (fromAngle == fAngle && toAngle == tAngle) { - continue; - } - if (fAngle) { - SkDebugf(" [%d] from=%d ", index, fAngle->debugID()); - fAngle->dumpTo(this, tAngle); - } - if (tAngle) { - SkDebugf(" [%d] to=%d ", index, tAngle->debugID()); - tAngle->dumpTo(this, fAngle); - } - fromAngle = fAngle; - toAngle = tAngle; - } +const SkOpAngle* SkPathOpsDebug::DebugAngleAngle(const SkOpAngle* angle, int id) { + return angle->debugAngle(id); } -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; - } +SkOpContour* SkPathOpsDebug::DebugAngleContour(SkOpAngle* angle, int id) { + return angle->debugContour(id); } -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"); +const SkOpPtT* SkPathOpsDebug::DebugAnglePtT(const SkOpAngle* angle, int id) { + return angle->debugPtT(id); } -void SkOpSegment::dumpHexPts() const { - int last = SkPathOpsVerbToPoints(fVerb); - SkDebugf("((SkOpSegment*) 0x%p) [%d] {{", this, debugID()); - int index = 0; - do { - SkDPoint::DumpHex(fPts[index]); - SkDebugf(", "); - } while (++index < last); - SkDPoint::DumpHex(fPts[index]); - SkDebugf("}}\n"); +const SkOpSegment* SkPathOpsDebug::DebugAngleSegment(const SkOpAngle* angle, int id) { + return angle->debugSegment(id); } -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"); +const SkOpSpanBase* SkPathOpsDebug::DebugAngleSpan(const SkOpAngle* angle, int id) { + return angle->debugSpan(id); } -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(); - } +const SkOpAngle* SkPathOpsDebug::DebugContourAngle(SkOpContour* contour, int id) { + return contour->debugAngle(id); } -void SkPathOpsDebug::DumpCoincidence(const SkTArray& contours) { - int count = contours.count(); - for (int index = 0; index < count; ++index) { - contours[index].dumpCoincidences(); - } +SkOpContour* SkPathOpsDebug::DebugContourContour(SkOpContour* contour, int id) { + return contour->debugContour(id); } -void SkPathOpsDebug::DumpCoincidence(const SkTArray& contours) { - int count = contours.count(); - for (int index = 0; index < count; ++index) { - contours[index]->dumpCoincidences(); - } +const SkOpPtT* SkPathOpsDebug::DebugContourPtT(SkOpContour* contour, int id) { + return contour->debugPtT(id); } -void SkPathOpsDebug::DumpContours(const SkTArray& contours) { - int count = contours.count(); - for (int index = 0; index < count; ++index) { - contours[index].dump(); - } +const SkOpSegment* SkPathOpsDebug::DebugContourSegment(SkOpContour* contour, int id) { + return contour->debugSegment(id); } -void SkPathOpsDebug::DumpContours(const SkTArray& contours) { - int count = contours.count(); - for (int index = 0; index < count; ++index) { - contours[index]->dump(); - } +const SkOpSpanBase* SkPathOpsDebug::DebugContourSpan(SkOpContour* contour, int id) { + return contour->debugSpan(id); } -void SkPathOpsDebug::DumpContourAngles(const SkTArray& contours) { - int count = contours.count(); - for (int index = 0; index < count; ++index) { - contours[index].dumpAngles(); - } +const SkOpAngle* SkPathOpsDebug::DebugPtTAngle(const SkOpPtT* ptT, int id) { + return ptT->debugAngle(id); } -void SkPathOpsDebug::DumpContourAngles(const SkTArray& contours) { - int count = contours.count(); - for (int index = 0; index < count; ++index) { - contours[index]->dumpAngles(); - } +SkOpContour* SkPathOpsDebug::DebugPtTContour(SkOpPtT* ptT, int id) { + return ptT->debugContour(id); } -void SkPathOpsDebug::DumpContourPts(const SkTArray& contours) { - int count = contours.count(); - for (int index = 0; index < count; ++index) { - contours[index].dumpPts(); - } +const SkOpPtT* SkPathOpsDebug::DebugPtTPtT(const SkOpPtT* ptT, int id) { + return ptT->debugPtT(id); } -void SkPathOpsDebug::DumpContourPts(const SkTArray& contours) { - int count = contours.count(); - for (int index = 0; index < count; ++index) { - contours[index]->dumpPts(); - } +const SkOpSegment* SkPathOpsDebug::DebugPtTSegment(const SkOpPtT* ptT, int id) { + return ptT->debugSegment(id); } -void SkPathOpsDebug::DumpContourPt(const SkTArray& contours, int segmentID) { - int count = contours.count(); - for (int index = 0; index < count; ++index) { - contours[index].dumpPt(segmentID); - } +const SkOpSpanBase* SkPathOpsDebug::DebugPtTSpan(const SkOpPtT* ptT, int id) { + return ptT->debugSpan(id); } -void SkPathOpsDebug::DumpContourPt(const SkTArray& contours, int segmentID) { - int count = contours.count(); - for (int index = 0; index < count; ++index) { - contours[index]->dumpPt(segmentID); - } +const SkOpAngle* SkPathOpsDebug::DebugSegmentAngle(const SkOpSegment* span, int id) { + return span->debugAngle(id); } -void SkPathOpsDebug::DumpContourSpans(const SkTArray& contours) { - int count = contours.count(); - for (int index = 0; index < count; ++index) { - contours[index].dumpSpans(); - } +SkOpContour* SkPathOpsDebug::DebugSegmentContour(SkOpSegment* span, int id) { + return span->debugContour(id); } -void SkPathOpsDebug::DumpContourSpans(const SkTArray& contours) { - int count = contours.count(); - for (int index = 0; index < count; ++index) { - contours[index]->dumpSpans(); - } +const SkOpPtT* SkPathOpsDebug::DebugSegmentPtT(const SkOpSegment* span, int id) { + return span->debugPtT(id); } -void SkPathOpsDebug::DumpContourSpan(const SkTArray& contours, int segmentID) { - int count = contours.count(); - for (int index = 0; index < count; ++index) { - contours[index].dumpSpan(segmentID); - } +const SkOpSegment* SkPathOpsDebug::DebugSegmentSegment(const SkOpSegment* span, int id) { + return span->debugSegment(id); } -void SkPathOpsDebug::DumpContourSpan(const SkTArray& contours, int segmentID) { - int count = contours.count(); - for (int index = 0; index < count; ++index) { - contours[index]->dumpSpan(segmentID); - } +const SkOpSpanBase* SkPathOpsDebug::DebugSegmentSpan(const SkOpSegment* span, int id) { + return span->debugSpan(id); } -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->debugSpans().begin(); - const SkOpSpan* last = candidate->debugSpans().end() - 1; - if (first <= this && this <= last) { - if (spanIndex) { - *spanIndex = this - first; - } - return candidate; - } - } - SkASSERT(0); - return NULL; +const SkOpAngle* SkPathOpsDebug::DebugSpanAngle(const SkOpSpanBase* span, int id) { + return span->debugAngle(id); } -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 (fWindSum != SK_MinS32) { - SkDebugf(" windSum=%d", fWindSum); - } - if (fOppSum != SK_MinS32 && (SkPathOpsDebug::ValidWind(fOppSum) || fOppValue != 0)) { - SkDebugf(" oppSum=%d", fOppSum); - } - SkDebugf(" windValue=%d", fWindValue); - if (SkPathOpsDebug::ValidWind(fOppSum) || fOppValue != 0) { - SkDebugf(" oppValue=%d", fOppValue); - } - if (fFromAngle && fFromAngle->debugID()) { - SkDebugf(" from=%d", fFromAngle->debugID()); - } - if (fToAngle && fToAngle->debugID()) { - SkDebugf(" to=%d", fToAngle->debugID()); - } - if (fChased) { - SkDebugf(" chased"); - } - if (fCoincident) { - SkDebugf(" coincident"); - } - if (fDone) { - SkDebugf(" done"); - } - if (fLoop) { - SkDebugf(" loop"); - } - if (fMultiple) { - SkDebugf(" multiple"); - } - if (fNear) { - SkDebugf(" near"); - } - if (fSmall) { - SkDebugf(" small"); - } - if (fTiny) { - SkDebugf(" tiny"); - } - SkDebugf("\n"); +SkOpContour* SkPathOpsDebug::DebugSpanContour(SkOpSpanBase* span, int id) { + return span->debugContour(id); } -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(); +const SkOpPtT* SkPathOpsDebug::DebugSpanPtT(const SkOpSpanBase* span, int id) { + return span->debugPtT(id); } -void Dump(const SkTArray& contours) { - SkPathOpsDebug::DumpContours(contours); +const SkOpSegment* SkPathOpsDebug::DebugSpanSegment(const SkOpSpanBase* span, int id) { + return span->debugSegment(id); } -void Dump(const SkTArray& contours) { - SkPathOpsDebug::DumpContours(contours); +const SkOpSpanBase* SkPathOpsDebug::DebugSpanSpan(const SkOpSpanBase* span, int id) { + return span->debugSpan(id); } -void Dump(const SkTArray* contours) { - SkPathOpsDebug::DumpContours(*contours); +void SkPathOpsDebug::DumpContours(SkTDArray* contours) { + int count = contours->count(); + for (int index = 0; index < count; ++index) { + (*contours)[index]->dump(); + } } -void Dump(const SkTArray* contours) { - SkPathOpsDebug::DumpContours(*contours); +void SkPathOpsDebug::DumpContoursAll(SkTDArray* contours) { + int count = contours->count(); + for (int index = 0; index < count; ++index) { + (*contours)[index]->dumpAll(); + } } -void Dump(const SkTDArray& chase) { - SkPathOpsDebug::DumpSpans(chase); +void SkPathOpsDebug::DumpContoursAngles(const SkTDArray* contours) { + int count = contours->count(); + for (int index = 0; index < count; ++index) { + (*contours)[index]->dumpAngles(); + } } -void Dump(const SkTDArray* chase) { - SkPathOpsDebug::DumpSpans(*chase); +void SkPathOpsDebug::DumpContoursPts(const SkTDArray* contours) { + int count = contours->count(); + for (int index = 0; index < count; ++index) { + (*contours)[index]->dumpPts(); + } } -void DumpAngles(const SkTArray& contours) { - SkPathOpsDebug::DumpContourAngles(contours); +void SkPathOpsDebug::DumpContoursPt(const SkTDArray* contours, int segmentID) { + int count = contours->count(); + for (int index = 0; index < count; ++index) { + (*contours)[index]->dumpPt(segmentID); + } } -void DumpAngles(const SkTArray& contours) { - SkPathOpsDebug::DumpContourAngles(contours); +void SkPathOpsDebug::DumpContoursSegment(const SkTDArray* contours, + int segmentID) { + if (contours->count()) { + (*contours)[0]->dumpSegment(segmentID); + } } -void DumpAngles(const SkTArray* contours) { - SkPathOpsDebug::DumpContourAngles(*contours); +void SkPathOpsDebug::DumpContoursSpan(const SkTDArray* contours, + int spanID) { + if (contours->count()) { + (*contours)[0]->dumpSpan(spanID); + } } -void DumpAngles(const SkTArray* contours) { - SkPathOpsDebug::DumpContourAngles(*contours); +void SkPathOpsDebug::DumpContoursSpans(const SkTDArray* contours) { + int count = contours->count(); + for (int index = 0; index < count; ++index) { + (*contours)[index]->dumpSpans(); + } } -void DumpCoin(const SkTArray& contours) { - SkPathOpsDebug::DumpCoincidence(contours); +const SkTSpan* DebugSpan(const SkTSect* sect, int id) { + return sect->debugSpan(id); } -void DumpCoin(const SkTArray& contours) { - SkPathOpsDebug::DumpCoincidence(contours); +const SkTSpan* DebugSpan(const SkTSect* sect, int id) { + return sect->debugSpan(id); } -void DumpCoin(const SkTArray* contours) { - SkPathOpsDebug::DumpCoincidence(*contours); +const SkTSpan* DebugT(const SkTSect* sect, double t) { + return sect->debugT(t); } -void DumpCoin(const SkTArray* contours) { - SkPathOpsDebug::DumpCoincidence(*contours); +const SkTSpan* DebugT(const SkTSect* sect, double t) { + return sect->debugT(t); } -void DumpSpans(const SkTArray& contours) { - SkPathOpsDebug::DumpContourSpans(contours); +const SkTSpan* DebugSpan(const SkTSpan* span, int id) { + return span->debugSpan(id); } -void DumpSpans(const SkTArray& contours) { - SkPathOpsDebug::DumpContourSpans(contours); +const SkTSpan* DebugSpan(const SkTSpan* span, int id) { + return span->debugSpan(id); } -void DumpSpans(const SkTArray* contours) { - SkPathOpsDebug::DumpContourSpans(*contours); +const SkTSpan* DebugT(const SkTSpan* span, double t) { + return span->debugT(t); } -void DumpSpans(const SkTArray* contours) { - SkPathOpsDebug::DumpContourSpans(*contours); +const SkTSpan* DebugT(const SkTSpan* span, double t) { + return span->debugT(t); } -void DumpSpan(const SkTArray& contours, int segmentID) { - SkPathOpsDebug::DumpContourSpan(contours, segmentID); +void Dump(const SkTSect* sect) { + sect->dump(); } -void DumpSpan(const SkTArray& contours, int segmentID) { - SkPathOpsDebug::DumpContourSpan(contours, segmentID); +void Dump(const SkTSect* sect) { + sect->dump(); } -void DumpSpan(const SkTArray* contours, int segmentID) { - SkPathOpsDebug::DumpContourSpan(*contours, segmentID); +void Dump(const SkTSpan* span) { + span->dump(); } -void DumpSpan(const SkTArray* contours, int segmentID) { - SkPathOpsDebug::DumpContourSpan(*contours, segmentID); +void Dump(const SkTSpan* span) { + span->dump(); } -void DumpPts(const SkTArray& contours) { - SkPathOpsDebug::DumpContourPts(contours); +void DumpBoth(SkTSect* sect1, SkTSect* sect2) { + sect1->dumpBoth(sect2); } -void DumpPts(const SkTArray& contours) { - SkPathOpsDebug::DumpContourPts(contours); +void DumpBoth(SkTSect* sect1, SkTSect* sect2) { + sect1->dumpBoth(sect2); } -void DumpPts(const SkTArray* contours) { - SkPathOpsDebug::DumpContourPts(*contours); +void DumpCoin(SkTSect* sect1) { + sect1->dumpCoin(); } -void DumpPts(const SkTArray* contours) { - SkPathOpsDebug::DumpContourPts(*contours); +void DumpCoin(SkTSect* sect1) { + sect1->dumpCoin(); } -void DumpPt(const SkTArray& contours, int segmentID) { - SkPathOpsDebug::DumpContourPt(contours, segmentID); +void DumpCoinCurves(SkTSect* sect1) { + sect1->dumpCoinCurves(); } -void DumpPt(const SkTArray& contours, int segmentID) { - SkPathOpsDebug::DumpContourPt(contours, segmentID); +void DumpCoinCurves(SkTSect* sect1) { + sect1->dumpCoinCurves(); } -void DumpPt(const SkTArray* contours, int segmentID) { - SkPathOpsDebug::DumpContourPt(*contours, segmentID); +void DumpCurves(const SkTSect* sect) { + sect->dumpCurves(); } -void DumpPt(const SkTArray* contours, int segmentID) { - SkPathOpsDebug::DumpContourPt(*contours, segmentID); +void DumpCurves(const SkTSect* sect) { + sect->dumpCurves(); } static void dumpTestCase(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) { - SkDebugf("
\n", testNo); - quad1.dumpComma(","); + SkDebugf("\n
\n", testNo); + quad1.dumpInner(); + SkDebugf("}}, "); quad2.dump(); SkDebugf("
\n\n"); } @@ -895,3 +551,649 @@ void DumpT(const SkDQuad& quad, double t) { SkDLine line = {{quad.ptAtT(t), quad[0]}}; line.dump(); } + +const SkOpAngle* SkOpAngle::debugAngle(int id) const { + return this->segment()->debugAngle(id); +} + +SkOpContour* SkOpAngle::debugContour(int id) { + return this->segment()->debugContour(id); +} + +const SkOpPtT* SkOpAngle::debugPtT(int id) const { + return this->segment()->debugPtT(id); +} + +const SkOpSegment* SkOpAngle::debugSegment(int id) const { + return this->segment()->debugSegment(id); +} + +const SkOpSpanBase* SkOpAngle::debugSpan(int id) const { + return this->segment()->debugSpan(id); +} + +void SkOpAngle::dump() const { + dumpOne(true); + SkDebugf("\n"); +} + +void SkOpAngle::dumpOne(bool functionHeader) const { +// fSegment->debugValidate(); + const SkOpSegment* segment = this->segment(); + const SkOpSpan& mSpan = *fStart->starter(fEnd); + if (functionHeader) { + SkDebugf("%s ", __FUNCTION__); + } + SkDebugf("[%d", segment->debugID()); + SkDebugf("/%d", debugID()); + SkDebugf("] next="); + if (fNext) { + SkDebugf("%d", fNext->fStart->segment()->debugID()); + SkDebugf("/%d", fNext->debugID()); + } else { + SkDebugf("?"); + } + SkDebugf(" sect=%d/%d ", fSectorStart, fSectorEnd); + SkDebugf(" s=%1.9g [%d] e=%1.9g [%d]", fStart->t(), fStart->debugID(), + fEnd->t(), fEnd->debugID()); + SkDebugf(" sgn=%d windVal=%d", this->sign(), mSpan.windValue()); + + SkDebugf(" windSum="); + SkPathOpsDebug::WindingPrintf(mSpan.windSum()); + if (mSpan.oppValue() != 0 || mSpan.oppSum() != SK_MinS32) { + SkDebugf(" oppVal=%d", mSpan.oppValue()); + SkDebugf(" oppSum="); + SkPathOpsDebug::WindingPrintf(mSpan.oppSum()); + } + if (mSpan.done()) { + SkDebugf(" done"); + } + if (unorderable()) { + SkDebugf(" unorderable"); + } + if (segment->operand()) { + SkDebugf(" operand"); + } + if (fStop) { + SkDebugf(" stop"); + } +} + +void SkOpAngle::dumpTo(const SkOpSegment* segment, const SkOpAngle* to) const { + const SkOpAngle* first = this; + const SkOpAngle* next = this; + const char* indent = ""; + do { + SkDebugf("%s", indent); + next->dumpOne(false); + if (segment == next->fStart->segment()) { + if (this == fNext) { + SkDebugf(" << from"); + } + if (to == fNext) { + SkDebugf(" << to"); + } + } + SkDebugf("\n"); + indent = " "; + next = next->fNext; + } while (next && next != first); +} + +void SkOpAngle::dumpCurves() const { + const SkOpAngle* first = this; + const SkOpAngle* next = this; + do { + next->fCurvePart.dumpID(next->segment()->debugID()); + next = next->fNext; + } while (next && next != first); +} + +void SkOpAngle::dumpLoop() const { + const SkOpAngle* first = this; + const SkOpAngle* next = this; + do { + next->dumpOne(false); + SkDebugf("\n"); + next = next->fNext; + } while (next && next != first); +} + +void SkOpAngle::dumpTest() const { + const SkOpAngle* first = this; + const SkOpAngle* next = this; + do { + SkDebugf("{ "); + SkOpSegment* segment = next->segment(); + segment->dumpPts(); + SkDebugf(", %d, %1.9g, %1.9g, {} },\n", SkPathOpsVerbToPoints(segment->verb()) + 1, + next->start()->t(), next->end()->t()); + next = next->fNext; + } while (next && next != first); +} + +bool SkOpPtT::debugMatchID(int id) const { + int limit = this->debugLoopLimit(false); + int loop = 0; + const SkOpPtT* ptT = this; + do { + if (ptT->debugID() == id) { + return true; + } + } while ((!limit || ++loop <= limit) && (ptT = ptT->next()) && ptT != this); + return false; +} + +const SkOpAngle* SkOpPtT::debugAngle(int id) const { + return this->span()->debugAngle(id); +} + +SkOpContour* SkOpPtT::debugContour(int id) { + return this->span()->debugContour(id); +} + +const SkOpPtT* SkOpPtT::debugPtT(int id) const { + return this->span()->debugPtT(id); +} + +const SkOpSegment* SkOpPtT::debugSegment(int id) const { + return this->span()->debugSegment(id); +} + +const SkOpSpanBase* SkOpPtT::debugSpan(int id) const { + return this->span()->debugSpan(id); +} + +void SkOpPtT::dump() const { + SkDebugf("seg=%d span=%d ptT=%d", + this->segment()->debugID(), this->span()->debugID(), this->debugID()); + this->dumpBase(); + SkDebugf("\n"); +} + +void SkOpPtT::dumpAll() const { + contour()->indentDump(); + const SkOpPtT* next = this; + int limit = debugLoopLimit(true); + int loop = 0; + do { + SkDebugf("%.*s", contour()->debugIndent(), " "); + SkDebugf("seg=%d span=%d ptT=%d", + next->segment()->debugID(), next->span()->debugID(), next->debugID()); + next->dumpBase(); + SkDebugf("\n"); + if (limit && ++loop >= limit) { + SkDebugf("*** abort loop ***\n"); + break; + } + } while ((next = next->fNext) && next != this); + contour()->outdentDump(); +} + +void SkOpPtT::dumpBase() const { + SkDebugf(" t=%1.9g pt=(%1.9g,%1.9g)%s%s", this->fT, this->fPt.fX, this->fPt.fY, + this->fDuplicatePt ? " dup" : "", this->fDeleted ? " deleted" : ""); +} + +const SkOpAngle* SkOpSpanBase::debugAngle(int id) const { + return this->segment()->debugAngle(id); +} + +SkOpContour* SkOpSpanBase::debugContour(int id) { + return this->segment()->debugContour(id); +} + +const SkOpPtT* SkOpSpanBase::debugPtT(int id) const { + return this->segment()->debugPtT(id); +} + +const SkOpSegment* SkOpSpanBase::debugSegment(int id) const { + return this->segment()->debugSegment(id); +} + +const SkOpSpanBase* SkOpSpanBase::debugSpan(int id) const { + return this->segment()->debugSpan(id); +} + +void SkOpSpanBase::dump() const { + this->dumpAll(); + SkDebugf("\n"); +} + +void SkOpSpanBase::dumpAll() const { + SkDebugf("%.*s", contour()->debugIndent(), " "); + SkDebugf("seg=%d span=%d", this->segment()->debugID(), this->debugID()); + this->dumpBase(); + SkDebugf("\n"); + this->fPtT.dumpAll(); +} + +void SkOpSpanBase::dumpBase() const { + if (this->fAligned) { + SkDebugf(" aligned"); + } + if (this->fChased) { + SkDebugf(" chased"); + } + if (!this->final()) { + this->upCast()->dumpSpan(); + } + const SkOpSpanBase* coin = this->coinEnd(); + if (this != coin) { + SkDebugf(" coinEnd seg/span=%d/%d", coin->segment()->debugID(), coin->debugID()); + } else if (this->final() || !this->upCast()->isCoincident()) { + const SkOpPtT* oPt = this->ptT()->next(); + SkDebugf(" seg/span=%d/%d", oPt->segment()->debugID(), oPt->span()->debugID()); + } +} + +void SkOpSpanBase::dumpCoin() const { + const SkOpSpan* span = this->upCastable(); + if (!span) { + return; + } + if (!span->isCoincident()) { + return; + } + span->dumpCoin(); +} + +void SkOpSpan::dumpCoin() const { + const SkOpSpan* coincident = fCoincident; + bool ok = debugCoinLoopCheck(); + this->dump(); + int loop = 0; + do { + coincident->dump(); + if (!ok && ++loop > 10) { + SkDebugf("*** abort loop ***\n"); + break; + } + } while ((coincident = coincident->fCoincident) != this); +} + +bool SkOpSpan::dumpSpan() const { + SkOpSpan* coin = fCoincident; + if (this != coin) { + SkDebugf(" coinStart seg/span=%d/%d", coin->segment()->debugID(), coin->debugID()); + } + SkDebugf(" windVal=%d", this->windValue()); + SkDebugf(" windSum="); + SkPathOpsDebug::WindingPrintf(this->windSum()); + if (this->oppValue() != 0 || this->oppSum() != SK_MinS32) { + SkDebugf(" oppVal=%d", this->oppValue()); + SkDebugf(" oppSum="); + SkPathOpsDebug::WindingPrintf(this->oppSum()); + } + if (this->done()) { + SkDebugf(" done"); + } + return this != coin; +} + +const SkOpAngle* SkOpSegment::debugAngle(int id) const { + return this->contour()->debugAngle(id); +} + +SkOpContour* SkOpSegment::debugContour(int id) { + return this->contour()->debugContour(id); +} + +const SkOpPtT* SkOpSegment::debugPtT(int id) const { + return this->contour()->debugPtT(id); +} + +const SkOpSegment* SkOpSegment::debugSegment(int id) const { + return this->contour()->debugSegment(id); +} + +const SkOpSpanBase* SkOpSegment::debugSpan(int id) const { + return this->contour()->debugSpan(id); +} + +void SkOpSegment::dump() const { + SkDebugf("%.*s", contour()->debugIndent(), " "); + this->dumpPts(); + const SkOpSpanBase* span = &fHead; + contour()->indentDump(); + do { + SkDebugf("%.*s span=%d ", contour()->debugIndent(), " ", span->debugID()); + span->ptT()->dumpBase(); + span->dumpBase(); + SkDebugf("\n"); + } while (!span->final() && (span = span->upCast()->next())); + contour()->outdentDump(); +} + +void SkOpSegment::dumpAll() const { + SkDebugf("%.*s", contour()->debugIndent(), " "); + this->dumpPts(); + const SkOpSpanBase* span = &fHead; + contour()->indentDump(); + do { + span->dumpAll(); + } while (!span->final() && (span = span->upCast()->next())); + contour()->outdentDump(); +} + +void SkOpSegment::dumpAngles() const { + SkDebugf("seg=%d\n", debugID()); + const SkOpSpanBase* span = &fHead; + do { + const SkOpAngle* fAngle = span->fromAngle(); + const SkOpAngle* tAngle = span->final() ? NULL : span->upCast()->toAngle(); + if (fAngle) { + SkDebugf(" span=%d from=%d ", span->debugID(), fAngle->debugID()); + fAngle->dumpTo(this, tAngle); + } + if (tAngle) { + SkDebugf(" span=%d to=%d ", span->debugID(), tAngle->debugID()); + tAngle->dumpTo(this, fAngle); + } + } while (!span->final() && (span = span->upCast()->next())); +} + +void SkOpSegment::dumpCoin() const { + const SkOpSpan* span = &fHead; + do { + span->dumpCoin(); + } while ((span = span->next()->upCastable())); +} + +void SkOpSegment::dumpPts() const { + int last = SkPathOpsVerbToPoints(fVerb); + SkDebugf("seg=%d {{", this->debugID()); + int index = 0; + do { + SkDPoint::Dump(fPts[index]); + SkDebugf(", "); + } while (++index < last); + SkDPoint::Dump(fPts[index]); + SkDebugf("}}\n"); +} + +void SkCoincidentSpans::dump() const { + SkDebugf("- seg=%d span=%d ptT=%d ", fCoinPtTStart->segment()->debugID(), + fCoinPtTStart->span()->debugID(), fCoinPtTStart->debugID()); + fCoinPtTStart->dumpBase(); + SkDebugf(" span=%d ptT=%d ", fCoinPtTEnd->span()->debugID(), fCoinPtTEnd->debugID()); + fCoinPtTEnd->dumpBase(); + if (fCoinPtTStart->segment()->operand()) { + SkDebugf(" operand"); + } + if (fCoinPtTStart->segment()->isXor()) { + SkDebugf(" xor"); + } + SkDebugf("\n"); + SkDebugf("+ seg=%d span=%d ptT=%d ", fOppPtTStart->segment()->debugID(), + fOppPtTStart->span()->debugID(), fOppPtTStart->debugID()); + fOppPtTStart->dumpBase(); + SkDebugf(" span=%d ptT=%d ", fOppPtTEnd->span()->debugID(), fOppPtTEnd->debugID()); + fOppPtTEnd->dumpBase(); + if (fOppPtTStart->segment()->operand()) { + SkDebugf(" operand"); + } + if (fOppPtTStart->segment()->isXor()) { + SkDebugf(" xor"); + } + SkDebugf("\n"); +} + +void SkOpCoincidence::dump() const { + SkCoincidentSpans* span = fHead; + while (span) { + span->dump(); + span = span->fNext; + } +} + +void SkOpContour::dump() { + SkDebugf("contour=%d count=%d\n", this->debugID(), fCount); + if (!fCount) { + return; + } + const SkOpSegment* segment = &fHead; + PATH_OPS_DEBUG_CODE(fIndent = 0); + indentDump(); + do { + segment->dump(); + } while ((segment = segment->next())); + outdentDump(); +} + +void SkOpContour::dumpAll() { + SkDebugf("contour=%d count=%d\n", this->debugID(), fCount); + if (!fCount) { + return; + } + const SkOpSegment* segment = &fHead; + PATH_OPS_DEBUG_CODE(fIndent = 0); + indentDump(); + do { + segment->dumpAll(); + } while ((segment = segment->next())); + outdentDump(); +} + + +void SkOpContour::dumpAngles() const { + SkDebugf("contour=%d\n", this->debugID()); + const SkOpSegment* segment = &fHead; + do { + SkDebugf(" seg=%d ", segment->debugID()); + segment->dumpAngles(); + } while ((segment = segment->next())); +} + +void SkOpContour::dumpPt(int index) const { + const SkOpSegment* segment = &fHead; + do { + if (segment->debugID() == index) { + segment->dumpPts(); + } + } while ((segment = segment->next())); +} + +void SkOpContour::dumpPts() const { + SkDebugf("contour=%d\n", this->debugID()); + const SkOpSegment* segment = &fHead; + do { + SkDebugf(" seg=%d ", segment->debugID()); + segment->dumpPts(); + } while ((segment = segment->next())); +} + +void SkOpContour::dumpPtsX() const { + if (!this->fCount) { + SkDebugf("\n"); + return; + } + const SkOpSegment* segment = &fHead; + do { + segment->dumpPts(); + } while ((segment = segment->next())); +} + +void SkOpContour::dumpSegment(int index) const { + debugSegment(index)->dump(); +} + +void SkOpContour::dumpSegments(SkPathOp op) const { + bool firstOp = false; + const SkOpContour* c = this; + do { + if (!firstOp && c->operand()) { +#if DEBUG_ACTIVE_OP + SkDebugf("op %s\n", SkPathOpsDebug::kPathOpStr[op]); +#endif + firstOp = true; + } + c->dumpPtsX(); + } while ((c = c->next())); +} + +void SkOpContour::dumpSpan(int index) const { + debugSpan(index)->dump(); +} + +void SkOpContour::dumpSpans() const { + SkDebugf("contour=%d\n", this->debugID()); + const SkOpSegment* segment = &fHead; + do { + SkDebugf(" seg=%d ", segment->debugID()); + segment->dump(); + } while ((segment = segment->next())); +} + +#ifdef SK_DEBUG +const SkOpAngle* SkOpGlobalState::debugAngle(int id) const { + const SkOpContour* contour = fHead; + do { + const SkOpSegment* segment = contour->first(); + while (segment) { + const SkOpSpan* span = segment->head(); + do { + SkOpAngle* angle = span->fromAngle(); + if (angle && angle->debugID() == id) { + return angle; + } + angle = span->toAngle(); + if (angle && angle->debugID() == id) { + return angle; + } + } while ((span = span->next()->upCastable())); + const SkOpSpanBase* tail = segment->tail(); + SkOpAngle* angle = tail->fromAngle(); + if (angle && angle->debugID() == id) { + return angle; + } + segment = segment->next(); + } + } while ((contour = contour->next())); + return NULL; +} + +SkOpContour* SkOpGlobalState::debugContour(int id) { + SkOpContour* contour = fHead; + do { + if (contour->debugID() == id) { + return contour; + } + } while ((contour = contour->next())); + return NULL; +} + +const SkOpPtT* SkOpGlobalState::debugPtT(int id) const { + const SkOpContour* contour = fHead; + do { + const SkOpSegment* segment = contour->first(); + while (segment) { + const SkOpSpan* span = segment->head(); + do { + const SkOpPtT* ptT = span->ptT(); + if (ptT->debugMatchID(id)) { + return ptT; + } + } while ((span = span->next()->upCastable())); + const SkOpSpanBase* tail = segment->tail(); + const SkOpPtT* ptT = tail->ptT(); + if (ptT->debugMatchID(id)) { + return ptT; + } + segment = segment->next(); + } + } while ((contour = contour->next())); + return NULL; +} + +const SkOpSegment* SkOpGlobalState::debugSegment(int id) const { + const SkOpContour* contour = fHead; + do { + const SkOpSegment* segment = contour->first(); + while (segment) { + if (segment->debugID() == id) { + return segment; + } + segment = segment->next(); + } + } while ((contour = contour->next())); + return NULL; +} + +const SkOpSpanBase* SkOpGlobalState::debugSpan(int id) const { + const SkOpContour* contour = fHead; + do { + const SkOpSegment* segment = contour->first(); + while (segment) { + const SkOpSpan* span = segment->head(); + do { + if (span->debugID() == id) { + return span; + } + } while ((span = span->next()->upCastable())); + const SkOpSpanBase* tail = segment->tail(); + if (tail->debugID() == id) { + return tail; + } + segment = segment->next(); + } + } while ((contour = contour->next())); + return NULL; +} +#endif + +const SkOpAngle* DebugAngle(const SkTArray* contours, int id) { + return (*contours)[0]->debugAngle(id); +} + +SkOpContour* DumpContour(const SkTArray* contours, int id) { + return (*contours)[0]->debugContour(id); +} + +const SkOpPtT* DebugPtT(const SkTArray* contours, int id) { + return (*contours)[0]->debugPtT(id); +} + +const SkOpSegment* DebugSegment(const SkTArray* contours, int id) { + return (*contours)[0]->debugSegment(id); +} + +const SkOpSpanBase* DebugSpan(const SkTArray* contours, int id) { + return (*contours)[0]->debugSpan(id); +} + +void Dump(SkTDArray* contours) { + SkPathOpsDebug::DumpContours(contours); +} + +void DumpAll(SkTDArray* contours) { + SkPathOpsDebug::DumpContoursAll(contours); +} + +void DumpAngles(const SkTDArray* contours) { + SkPathOpsDebug::DumpContoursAngles(contours); +} + +void DumpSegment(const SkTDArray* contours, int segmentID) { + SkPathOpsDebug::DumpContoursSegment(contours, segmentID); +} + +void DumpSpan(const SkTDArray* contours, int spanID) { + SkPathOpsDebug::DumpContoursSpan(contours, spanID); +} + +void DumpSpans(const SkTDArray* contours) { + SkPathOpsDebug::DumpContoursSpans(contours); +} + +void DumpPt(const SkTDArray* contours, int segmentID) { + SkPathOpsDebug::DumpContoursPt(contours, segmentID); +} + +void DumpPts(const SkTDArray* contours) { + SkPathOpsDebug::DumpContoursPts(contours); +} + +#if DEBUG_T_SECT_DUMP > 1 +int gDumpTSectNum; +#endif -- cgit v1.2.3