Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(807)

Unified Diff: src/pathops/SkPathOpsDebug.cpp

Issue 1029993002: Revert of pathops version two (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/pathops/SkPathOpsDebug.h ('k') | src/pathops/SkPathOpsLine.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pathops/SkPathOpsDebug.cpp
diff --git a/src/pathops/SkPathOpsDebug.cpp b/src/pathops/SkPathOpsDebug.cpp
index 0331f34e8a74d91ffb34f8b6d0b0d7f88f7cab25..7db93f5e969b5ba53689be47c5f9936f76601e20 100644
--- a/src/pathops/SkPathOpsDebug.cpp
+++ b/src/pathops/SkPathOpsDebug.cpp
@@ -7,13 +7,6 @@
#include "SkPathOpsDebug.h"
#include "SkPath.h"
-#if DEBUG_ANGLE
-#include "SkString.h"
-#endif
-
-#if DEBUG_VALIDATE
-extern bool FLAGS_runFail;
-#endif
#if defined SK_DEBUG || !FORCE_RELEASE
@@ -33,10 +26,10 @@
const char* SkPathOpsDebug::kPathOpStr[] = {"diff", "sect", "union", "xor"};
#endif
-bool SkPathOpsDebug::ChaseContains(const SkTDArray<SkOpSpanBase* >& chaseArray,
- const SkOpSpanBase* span) {
+bool SkPathOpsDebug::ChaseContains(const SkTDArray<SkOpSpan *>& chaseArray,
+ const SkOpSpan* span) {
for (int index = 0; index < chaseArray.count(); ++index) {
- const SkOpSpanBase* entry = chaseArray[index];
+ const SkOpSpan* entry = chaseArray[index];
if (entry == span) {
return true;
}
@@ -72,8 +65,6 @@
SkDebugf("%d", wind);
}
}
-#endif // defined SK_DEBUG || !FORCE_RELEASE
-
#if DEBUG_SHOW_TEST_NAME
void* SkPathOpsDebug::CreateNameStr() {
@@ -106,159 +97,10 @@
}
#endif
+#endif // defined SK_DEBUG || !FORCE_RELEASE
+
#include "SkOpAngle.h"
#include "SkOpSegment.h"
-
-#if DEBUG_SWAP_TOP
-int SkOpSegment::debugInflections(const SkOpSpanBase* start, const SkOpSpanBase* end) const {
- if (fVerb != SkPath::kCubic_Verb) {
- return false;
- }
- SkDCubic dst = SkDCubic::SubDivide(fPts, start->t(), end->t());
- double inflections[2];
- return dst.findInflections(inflections);
-}
-#endif
-
-SkOpAngle* SkOpSegment::debugLastAngle() {
- SkOpAngle* result = NULL;
- SkOpSpan* span = this->head();
- do {
- if (span->toAngle()) {
- SkASSERT(!result);
- result = span->toAngle();
- }
- } while ((span = span->next()->upCastable()));
- SkASSERT(result);
- return result;
-}
-
-void SkOpSegment::debugReset() {
- this->init(this->fPts, this->contour(), this->verb());
-}
-
-#if DEBUG_ACTIVE_SPANS
-void SkOpSegment::debugShowActiveSpans() const {
- debugValidate();
- if (done()) {
- return;
- }
- int lastId = -1;
- double lastT = -1;
- const SkOpSpan* span = &fHead;
- do {
- if (span->done()) {
- continue;
- }
- if (lastId == fID && lastT == span->t()) {
- continue;
- }
- lastId = fID;
- lastT = span->t();
- SkDebugf("%s id=%d", __FUNCTION__, fID);
- SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
- for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
- SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
- }
- const SkOpPtT* ptT = span->ptT();
- SkDebugf(") t=%1.9g (%1.9g,%1.9g)", ptT->fT, ptT->fPt.fX, ptT->fPt.fY);
- SkDebugf(" tEnd=%1.9g", span->next()->t());
- SkDebugf(" windSum=");
- if (span->windSum() == SK_MinS32) {
- SkDebugf("?");
- } else {
- SkDebugf("%d", span->windSum());
- }
- SkDebugf(" windValue=%d oppValue=%d", span->windValue(), span->oppValue());
- SkDebugf("\n");
- } while ((span = span->next()->upCastable()));
-}
-#endif
-
-#if DEBUG_MARK_DONE
-void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan* span, int winding) {
- const SkPoint& pt = span->ptT()->fPt;
- SkDebugf("%s id=%d", fun, fID);
- SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
- for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
- SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
- }
- SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=",
- span->t(), span->debugID(), pt.fX, pt.fY, span->next()->t());
- if (winding == SK_MinS32) {
- SkDebugf("?");
- } else {
- SkDebugf("%d", winding);
- }
- SkDebugf(" windSum=");
- if (span->windSum() == SK_MinS32) {
- SkDebugf("?");
- } else {
- SkDebugf("%d", span->windSum());
- }
- SkDebugf(" windValue=%d\n", span->windValue());
-}
-
-void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan* span, int winding,
- int oppWinding) {
- const SkPoint& pt = span->ptT()->fPt;
- SkDebugf("%s id=%d", fun, fID);
- SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
- for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
- SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
- }
- SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=",
- span->t(), span->debugID(), pt.fX, pt.fY, span->next()->t(), winding, oppWinding);
- if (winding == SK_MinS32) {
- SkDebugf("?");
- } else {
- SkDebugf("%d", winding);
- }
- SkDebugf(" newOppSum=");
- if (oppWinding == SK_MinS32) {
- SkDebugf("?");
- } else {
- SkDebugf("%d", oppWinding);
- }
- SkDebugf(" oppSum=");
- if (span->oppSum() == SK_MinS32) {
- SkDebugf("?");
- } else {
- SkDebugf("%d", span->oppSum());
- }
- SkDebugf(" windSum=");
- if (span->windSum() == SK_MinS32) {
- SkDebugf("?");
- } else {
- SkDebugf("%d", span->windSum());
- }
- SkDebugf(" windValue=%d oppValue=%d\n", span->windValue(), span->oppValue());
-}
-
-#endif
-
-#if DEBUG_ANGLE
-SkString SkOpAngle::debugPart() const {
- SkString result;
- switch (this->segment()->verb()) {
- case SkPath::kLine_Verb:
- result.printf(LINE_DEBUG_STR " id=%d", LINE_DEBUG_DATA(fCurvePart),
- this->segment()->debugID());
- break;
- case SkPath::kQuad_Verb:
- result.printf(QUAD_DEBUG_STR " id=%d", QUAD_DEBUG_DATA(fCurvePart),
- this->segment()->debugID());
- break;
- case SkPath::kCubic_Verb:
- result.printf(CUBIC_DEBUG_STR " id=%d", CUBIC_DEBUG_DATA(fCurvePart),
- this->segment()->debugID());
- break;
- default:
- SkASSERT(0);
- }
- return result;
-}
-#endif
#if DEBUG_SORT
void SkOpAngle::debugLoop() const {
@@ -269,59 +111,25 @@
SkDebugf("\n");
next = next->fNext;
} while (next && next != first);
- next = first;
- do {
- next->debugValidate();
- next = next->fNext;
- } while (next && next != first);
-}
-#endif
-
-void SkOpAngle::debugValidate() const {
+}
+#endif
+
+#if DEBUG_ANGLE
+void SkOpAngle::debugSameAs(const SkOpAngle* compare) const {
+ SK_ALWAYSBREAK(fSegment == compare->fSegment);
+ const SkOpSpan& startSpan = fSegment->span(fStart);
+ const SkOpSpan& oStartSpan = fSegment->span(compare->fStart);
+ SK_ALWAYSBREAK(startSpan.fToAngle == oStartSpan.fToAngle);
+ SK_ALWAYSBREAK(startSpan.fFromAngle == oStartSpan.fFromAngle);
+ const SkOpSpan& endSpan = fSegment->span(fEnd);
+ const SkOpSpan& oEndSpan = fSegment->span(compare->fEnd);
+ SK_ALWAYSBREAK(endSpan.fToAngle == oEndSpan.fToAngle);
+ SK_ALWAYSBREAK(endSpan.fFromAngle == oEndSpan.fFromAngle);
+}
+#endif
+
#if DEBUG_VALIDATE
- const SkOpAngle* first = this;
- const SkOpAngle* next = this;
- int wind = 0;
- int opp = 0;
- int lastXor = -1;
- int lastOppXor = -1;
- do {
- if (next->unorderable()) {
- return;
- }
- const SkOpSpan* minSpan = next->start()->starter(next->end());
- if (minSpan->windValue() == SK_MinS32) {
- return;
- }
- bool op = next->segment()->operand();
- bool isXor = next->segment()->isXor();
- bool oppXor = next->segment()->oppXor();
- SkASSERT(!DEBUG_LIMIT_WIND_SUM || between(0, minSpan->windValue(), DEBUG_LIMIT_WIND_SUM));
- SkASSERT(!DEBUG_LIMIT_WIND_SUM
- || between(-DEBUG_LIMIT_WIND_SUM, minSpan->oppValue(), DEBUG_LIMIT_WIND_SUM));
- bool useXor = op ? oppXor : isXor;
- SkASSERT(lastXor == -1 || lastXor == (int) useXor);
- lastXor = (int) useXor;
- wind += next->sign() * (op ? minSpan->oppValue() : minSpan->windValue());
- if (useXor) {
- wind &= 1;
- }
- useXor = op ? isXor : oppXor;
- SkASSERT(lastOppXor == -1 || lastOppXor == (int) useXor);
- lastOppXor = (int) useXor;
- opp += next->sign() * (op ? minSpan->windValue() : minSpan->oppValue());
- if (useXor) {
- opp &= 1;
- }
- next = next->fNext;
- } while (next && next != first);
- SkASSERT(wind == 0);
- SkASSERT(opp == 0 || !FLAGS_runFail);
-#endif
-}
-
void SkOpAngle::debugValidateNext() const {
-#if !FORCE_RELEASE
const SkOpAngle* first = this;
const SkOpAngle* next = first;
SkTDArray<const SkOpAngle*>(angles);
@@ -337,137 +145,422 @@
return;
}
} while (true);
-#endif
-}
+}
+
+void SkOpAngle::debugValidateLoop() const {
+ const SkOpAngle* first = this;
+ const SkOpAngle* next = first;
+ SK_ALWAYSBREAK(first->next() != first);
+ int signSum = 0;
+ int oppSum = 0;
+ bool firstOperand = fSegment->operand();
+ bool unorderable = false;
+ do {
+ unorderable |= next->fUnorderable;
+ const SkOpSegment* segment = next->fSegment;
+ bool operandsMatch = firstOperand == segment->operand();
+ signSum += operandsMatch ? segment->spanSign(next) : segment->oppSign(next);
+ oppSum += operandsMatch ? segment->oppSign(next) : segment->spanSign(next);
+ const SkOpSpan& span = segment->span(SkMin32(next->fStart, next->fEnd));
+ if (segment->_xor()) {
+// SK_ALWAYSBREAK(span.fWindValue == 1);
+// SK_ALWAYSBREAK(span.fWindSum == SK_MinS32 || span.fWindSum == 1);
+ }
+ if (segment->oppXor()) {
+ SK_ALWAYSBREAK(span.fOppValue == 0 || abs(span.fOppValue) == 1);
+// SK_ALWAYSBREAK(span.fOppSum == SK_MinS32 || span.fOppSum == 0 || abs(span.fOppSum) == 1);
+ }
+ next = next->next();
+ if (!next) {
+ return;
+ }
+ } while (next != first);
+ if (unorderable) {
+ return;
+ }
+ SK_ALWAYSBREAK(!signSum || fSegment->_xor());
+ SK_ALWAYSBREAK(!oppSum || fSegment->oppXor());
+ int lastWinding;
+ int lastOppWinding;
+ int winding;
+ int oppWinding;
+ do {
+ const SkOpSegment* segment = next->fSegment;
+ const SkOpSpan& span = segment->span(SkMin32(next->fStart, next->fEnd));
+ winding = span.fWindSum;
+ if (winding != SK_MinS32) {
+// SK_ALWAYSBREAK(winding != 0);
+ SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(winding));
+ lastWinding = winding;
+ int diffWinding = segment->spanSign(next);
+ if (!segment->_xor()) {
+ SK_ALWAYSBREAK(diffWinding != 0);
+ bool sameSign = (winding > 0) == (diffWinding > 0);
+ winding -= sameSign ? diffWinding : -diffWinding;
+ SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(winding));
+ SK_ALWAYSBREAK(abs(winding) <= abs(lastWinding));
+ if (!sameSign) {
+ SkTSwap(winding, lastWinding);
+ }
+ }
+ lastOppWinding = oppWinding = span.fOppSum;
+ if (oppWinding != SK_MinS32 && !segment->oppXor()) {
+ int oppDiffWinding = segment->oppSign(next);
+// SK_ALWAYSBREAK(abs(oppDiffWinding) <= abs(diffWinding) || segment->_xor());
+ if (oppDiffWinding) {
+ bool oppSameSign = (oppWinding > 0) == (oppDiffWinding > 0);
+ oppWinding -= oppSameSign ? oppDiffWinding : -oppDiffWinding;
+ SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(oppWinding));
+ SK_ALWAYSBREAK(abs(oppWinding) <= abs(lastOppWinding));
+ if (!oppSameSign) {
+ SkTSwap(oppWinding, lastOppWinding);
+ }
+ }
+ }
+ firstOperand = segment->operand();
+ break;
+ }
+ SK_ALWAYSBREAK(span.fOppSum == SK_MinS32);
+ next = next->next();
+ } while (next != first);
+ if (winding == SK_MinS32) {
+ return;
+ }
+ SK_ALWAYSBREAK(oppWinding == SK_MinS32 || SkPathOpsDebug::ValidWind(oppWinding));
+ first = next;
+ next = next->next();
+ do {
+ const SkOpSegment* segment = next->fSegment;
+ lastWinding = winding;
+ lastOppWinding = oppWinding;
+ bool operandsMatch = firstOperand == segment->operand();
+ if (operandsMatch) {
+ if (!segment->_xor()) {
+ winding -= segment->spanSign(next);
+ SK_ALWAYSBREAK(winding != lastWinding);
+ SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(winding));
+ }
+ if (!segment->oppXor()) {
+ int oppDiffWinding = segment->oppSign(next);
+ if (oppWinding != SK_MinS32) {
+ oppWinding -= oppDiffWinding;
+ SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(oppWinding));
+ } else {
+ SK_ALWAYSBREAK(oppDiffWinding == 0);
+ }
+ }
+ } else {
+ if (!segment->oppXor()) {
+ winding -= segment->oppSign(next);
+ SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(winding));
+ }
+ if (!segment->_xor()) {
+ oppWinding -= segment->spanSign(next);
+ SK_ALWAYSBREAK(oppWinding != lastOppWinding);
+ SK_ALWAYSBREAK(SkPathOpsDebug::ValidWind(oppWinding));
+ }
+ }
+ bool useInner = SkOpSegment::UseInnerWinding(lastWinding, winding);
+ int sumWinding = useInner ? winding : lastWinding;
+ bool oppUseInner = SkOpSegment::UseInnerWinding(lastOppWinding, oppWinding);
+ int oppSumWinding = oppUseInner ? oppWinding : lastOppWinding;
+ if (!operandsMatch) {
+ SkTSwap(useInner, oppUseInner);
+ SkTSwap(sumWinding, oppSumWinding);
+ }
+ const SkOpSpan& span = segment->span(SkMin32(next->fStart, next->fEnd));
+ if (winding == -lastWinding) {
+ if (span.fWindSum != SK_MinS32) {
+ SkDebugf("%s useInner=%d spanSign=%d lastWinding=%d winding=%d windSum=%d\n",
+ __FUNCTION__,
+ useInner, segment->spanSign(next), lastWinding, winding, span.fWindSum);
+ }
+ }
+ if (oppWinding != SK_MinS32) {
+ if (span.fOppSum != SK_MinS32) {
+ SK_ALWAYSBREAK(span.fOppSum == oppSumWinding || segment->oppXor() || segment->_xor());
+ }
+ } else {
+ SK_ALWAYSBREAK(!firstOperand);
+ SK_ALWAYSBREAK(!segment->operand());
+ SK_ALWAYSBREAK(!span.fOppValue);
+ }
+ next = next->next();
+ } while (next != first);
+}
+#endif
+
+#if DEBUG_SWAP_TOP
+bool SkOpSegment::controlsContainedByEnds(int tStart, int tEnd) const {
+ if (fVerb != SkPath::kCubic_Verb) {
+ return false;
+ }
+ SkDCubic dst = SkDCubic::SubDivide(fPts, fTs[tStart].fT, fTs[tEnd].fT);
+ return dst.controlsContainedByEnds();
+}
+#endif
+
+#if DEBUG_CONCIDENT
+// SK_ALWAYSBREAK if pair has not already been added
+void SkOpSegment::debugAddTPair(double t, const SkOpSegment& other, double otherT) const {
+ for (int i = 0; i < fTs.count(); ++i) {
+ if (fTs[i].fT == t && fTs[i].fOther == &other && fTs[i].fOtherT == otherT) {
+ return;
+ }
+ }
+ SK_ALWAYSBREAK(0);
+}
+#endif
+
+#if DEBUG_ANGLE
+void SkOpSegment::debugCheckPointsEqualish(int tStart, int tEnd) const {
+ const SkPoint& basePt = fTs[tStart].fPt;
+ while (++tStart < tEnd) {
+ const SkPoint& cmpPt = fTs[tStart].fPt;
+ SK_ALWAYSBREAK(SkDPoint::ApproximatelyEqual(basePt, cmpPt));
+ }
+}
+#endif
+
+#if DEBUG_SWAP_TOP
+int SkOpSegment::debugInflections(int tStart, int tEnd) const {
+ if (fVerb != SkPath::kCubic_Verb) {
+ return false;
+ }
+ SkDCubic dst = SkDCubic::SubDivide(fPts, fTs[tStart].fT, fTs[tEnd].fT);
+ double inflections[2];
+ return dst.findInflections(inflections);
+}
+#endif
+
+const SkOpAngle* SkOpSegment::debugLastAngle() const {
+ const SkOpAngle* result = NULL;
+ for (int index = 0; index < count(); ++index) {
+ const SkOpSpan& span = this->span(index);
+ if (span.fToAngle) {
+ SkASSERT(!result);
+ result = span.fToAngle;
+ }
+ }
+ SkASSERT(result);
+ return result;
+}
+
+void SkOpSegment::debugReset() {
+ fTs.reset();
+ fAngles.reset();
+}
+
+#if DEBUG_CONCIDENT
+void SkOpSegment::debugShowTs(const char* prefix) const {
+ SkDebugf("%s %s id=%d", __FUNCTION__, prefix, fID);
+ int lastWind = -1;
+ int lastOpp = -1;
+ double lastT = -1;
+ int i;
+ for (i = 0; i < fTs.count(); ++i) {
+ bool change = lastT != fTs[i].fT || lastWind != fTs[i].fWindValue
+ || lastOpp != fTs[i].fOppValue;
+ if (change && lastWind >= 0) {
+ SkDebugf(" t=%1.3g %1.9g,%1.9g w=%d o=%d]",
+ lastT, xyAtT(i - 1).fX, xyAtT(i - 1).fY, lastWind, lastOpp);
+ }
+ if (change) {
+ SkDebugf(" [o=%d", fTs[i].fOther->fID);
+ lastWind = fTs[i].fWindValue;
+ lastOpp = fTs[i].fOppValue;
+ lastT = fTs[i].fT;
+ } else {
+ SkDebugf(",%d", fTs[i].fOther->fID);
+ }
+ }
+ if (i <= 0) {
+ return;
+ }
+ SkDebugf(" t=%1.3g %1.9g,%1.9g w=%d o=%d]",
+ lastT, xyAtT(i - 1).fX, xyAtT(i - 1).fY, lastWind, lastOpp);
+ if (fOperand) {
+ SkDebugf(" operand");
+ }
+ if (done()) {
+ SkDebugf(" done");
+ }
+ SkDebugf("\n");
+}
+#endif
+
+#if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY
+void SkOpSegment::debugShowActiveSpans() const {
+ debugValidate();
+ if (done()) {
+ return;
+ }
+#if DEBUG_ACTIVE_SPANS_SHORT_FORM
+ int lastId = -1;
+ double lastT = -1;
+#endif
+ for (int i = 0; i < fTs.count(); ++i) {
+ if (fTs[i].fDone) {
+ continue;
+ }
+ SK_ALWAYSBREAK(i < fTs.count() - 1);
+#if DEBUG_ACTIVE_SPANS_SHORT_FORM
+ if (lastId == fID && lastT == fTs[i].fT) {
+ continue;
+ }
+ lastId = fID;
+ lastT = fTs[i].fT;
+#endif
+ SkDebugf("%s id=%d", __FUNCTION__, fID);
+ SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
+ for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
+ SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
+ }
+ const SkOpSpan* span = &fTs[i];
+ SkDebugf(") t=%1.9g (%1.9g,%1.9g)", span->fT, xAtT(span), yAtT(span));
+ int iEnd = i + 1;
+ while (fTs[iEnd].fT < 1 && approximately_equal(fTs[i].fT, fTs[iEnd].fT)) {
+ ++iEnd;
+ }
+ SkDebugf(" tEnd=%1.9g", fTs[iEnd].fT);
+ const SkOpSegment* other = fTs[i].fOther;
+ SkDebugf(" other=%d otherT=%1.9g otherIndex=%d windSum=",
+ other->fID, fTs[i].fOtherT, fTs[i].fOtherIndex);
+ if (fTs[i].fWindSum == SK_MinS32) {
+ SkDebugf("?");
+ } else {
+ SkDebugf("%d", fTs[i].fWindSum);
+ }
+ SkDebugf(" windValue=%d oppValue=%d\n", fTs[i].fWindValue, fTs[i].fOppValue);
+ }
+}
+#endif
+
+#if DEBUG_MARK_DONE || DEBUG_UNSORTABLE
+void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan& span, int winding) {
+ const SkPoint& pt = xyAtT(&span);
+ SkDebugf("%s id=%d", fun, fID);
+ SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
+ for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
+ SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
+ }
+ SK_ALWAYSBREAK(&span == &span.fOther->fTs[span.fOtherIndex].fOther->
+ fTs[span.fOther->fTs[span.fOtherIndex].fOtherIndex]);
+ SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=%d windSum=",
+ span.fT, span.fOther->fTs[span.fOtherIndex].fOtherIndex, pt.fX, pt.fY,
+ (&span)[1].fT, winding);
+ if (span.fWindSum == SK_MinS32) {
+ SkDebugf("?");
+ } else {
+ SkDebugf("%d", span.fWindSum);
+ }
+ SkDebugf(" windValue=%d\n", span.fWindValue);
+}
+
+void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan& span, int winding,
+ int oppWinding) {
+ const SkPoint& pt = xyAtT(&span);
+ SkDebugf("%s id=%d", fun, fID);
+ SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
+ for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
+ SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
+ }
+ SK_ALWAYSBREAK(&span == &span.fOther->fTs[span.fOtherIndex].fOther->
+ fTs[span.fOther->fTs[span.fOtherIndex].fOtherIndex]);
+ SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=%d newOppSum=%d oppSum=",
+ span.fT, span.fOther->fTs[span.fOtherIndex].fOtherIndex, pt.fX, pt.fY,
+ (&span)[1].fT, winding, oppWinding);
+ if (span.fOppSum == SK_MinS32) {
+ SkDebugf("?");
+ } else {
+ SkDebugf("%d", span.fOppSum);
+ }
+ SkDebugf(" windSum=");
+ if (span.fWindSum == SK_MinS32) {
+ SkDebugf("?");
+ } else {
+ SkDebugf("%d", span.fWindSum);
+ }
+ SkDebugf(" windValue=%d oppValue=%d\n", span.fWindValue, span.fOppValue);
+}
+#endif
+
+#if DEBUG_SHOW_WINDING
+int SkOpSegment::debugShowWindingValues(int slotCount, int ofInterest) const {
+ if (!(1 << fID & ofInterest)) {
+ return 0;
+ }
+ int sum = 0;
+ SkTArray<char, true> slots(slotCount * 2);
+ memset(slots.begin(), ' ', slotCount * 2);
+ for (int i = 0; i < fTs.count(); ++i) {
+ // if (!(1 << fTs[i].fOther->fID & ofInterest)) {
+ // continue;
+ // }
+ sum += fTs[i].fWindValue;
+ slots[fTs[i].fOther->fID - 1] = as_digit(fTs[i].fWindValue);
+ sum += fTs[i].fOppValue;
+ slots[slotCount + fTs[i].fOther->fID - 1] = as_digit(fTs[i].fOppValue);
+ }
+ SkDebugf("%s id=%2d %.*s | %.*s\n", __FUNCTION__, fID, slotCount, slots.begin(), slotCount,
+ slots.begin() + slotCount);
+ return sum;
+}
+#endif
void SkOpSegment::debugValidate() const {
#if DEBUG_VALIDATE
- const SkOpSpanBase* span = &fHead;
- double lastT = -1;
- const SkOpSpanBase* prev = NULL;
- int count = 0;
+ int count = fTs.count();
+ SK_ALWAYSBREAK(count >= 2);
+ SK_ALWAYSBREAK(fTs[0].fT == 0);
+ SK_ALWAYSBREAK(fTs[count - 1].fT == 1);
int done = 0;
- do {
- if (!span->final()) {
- ++count;
- done += span->upCast()->done() ? 1 : 0;
- }
- SkASSERT(span->segment() == this);
- SkASSERT(!prev || prev->upCast()->next() == span);
- SkASSERT(!prev || prev == span->prev());
- prev = span;
- double t = span->ptT()->fT;
- SkASSERT(lastT < t);
- lastT = t;
- span->debugValidate();
- } while (!span->final() && (span = span->upCast()->next()));
- SkASSERT(count == fCount);
- SkASSERT(done == fDoneCount);
- SkASSERT(span->final());
- span->debugValidate();
-#endif
-}
-
-bool SkOpSpanBase::debugCoinEndLoopCheck() const {
- int loop = 0;
- const SkOpSpanBase* next = this;
- SkOpSpanBase* nextCoin;
- do {
- nextCoin = next->fCoinEnd;
- SkASSERT(nextCoin == this || nextCoin->fCoinEnd != nextCoin);
- for (int check = 1; check < loop - 1; ++check) {
- const SkOpSpanBase* checkCoin = this->fCoinEnd;
- const SkOpSpanBase* innerCoin = checkCoin;
- for (int inner = check + 1; inner < loop; ++inner) {
- innerCoin = innerCoin->fCoinEnd;
- if (checkCoin == innerCoin) {
- SkDebugf("*** bad coincident end loop ***\n");
- return false;
- }
- }
- }
- ++loop;
- } while ((next = nextCoin) && next != this);
- return true;
-}
-
-void SkOpSpanBase::debugValidate() const {
-#if DEBUG_VALIDATE
- const SkOpPtT* ptT = &fPtT;
- SkASSERT(ptT->span() == this);
- do {
-// SkASSERT(SkDPoint::RoughlyEqual(fPtT.fPt, ptT->fPt));
- ptT->debugValidate();
- ptT = ptT->next();
- } while (ptT != &fPtT);
- SkASSERT(this->debugCoinEndLoopCheck());
- if (!this->final()) {
- SkASSERT(this->upCast()->debugCoinLoopCheck());
- }
- if (fFromAngle) {
- fFromAngle->debugValidate();
- }
- if (!this->final() && this->upCast()->toAngle()) {
- this->upCast()->toAngle()->debugValidate();
- }
-#endif
-}
-
-bool SkOpSpan::debugCoinLoopCheck() const {
- int loop = 0;
- const SkOpSpan* next = this;
- SkOpSpan* nextCoin;
- do {
- nextCoin = next->fCoincident;
- SkASSERT(nextCoin == this || nextCoin->fCoincident != nextCoin);
- for (int check = 1; check < loop - 1; ++check) {
- const SkOpSpan* checkCoin = this->fCoincident;
- const SkOpSpan* innerCoin = checkCoin;
- for (int inner = check + 1; inner < loop; ++inner) {
- innerCoin = innerCoin->fCoincident;
- if (checkCoin == innerCoin) {
- SkDebugf("*** bad coincident loop ***\n");
- return false;
- }
- }
- }
- ++loop;
- } while ((next = nextCoin) && next != this);
- return true;
-}
-
-#include "SkOpContour.h"
-
-int SkOpPtT::debugLoopLimit(bool report) const {
- int loop = 0;
- const SkOpPtT* next = this;
- do {
- for (int check = 1; check < loop - 1; ++check) {
- const SkOpPtT* checkPtT = this->fNext;
- const SkOpPtT* innerPtT = checkPtT;
- for (int inner = check + 1; inner < loop; ++inner) {
- innerPtT = innerPtT->fNext;
- if (checkPtT == innerPtT) {
- if (report) {
- SkDebugf("*** bad ptT loop ***\n");
- }
- return loop;
- }
- }
- }
- ++loop;
- } while ((next = next->fNext) && next != this);
- return 0;
-}
-
-void SkOpPtT::debugValidate() const {
-#if DEBUG_VALIDATE
- if (contour()->globalState()->phase() == SkOpGlobalState::kIntersecting) {
- return;
- }
- SkASSERT(fNext);
- SkASSERT(fNext != this);
- SkASSERT(fNext->fNext);
- SkASSERT(debugLoopLimit(false) == 0);
-#endif
-}
+ double t = -1;
+ const SkOpSpan* last = NULL;
+ bool tinyTFound = false;
+ bool hasLoop = false;
+ for (int i = 0; i < count; ++i) {
+ const SkOpSpan& span = fTs[i];
+ SK_ALWAYSBREAK(t <= span.fT);
+ t = span.fT;
+ int otherIndex = span.fOtherIndex;
+ const SkOpSegment* other = span.fOther;
+ SK_ALWAYSBREAK(other != this || fVerb == SkPath::kCubic_Verb);
+ const SkOpSpan& otherSpan = other->fTs[otherIndex];
+ SK_ALWAYSBREAK(otherSpan.fPt == span.fPt);
+ SK_ALWAYSBREAK(otherSpan.fOtherT == t);
+ SK_ALWAYSBREAK(&fTs[i] == &otherSpan.fOther->fTs[otherSpan.fOtherIndex]);
+ done += span.fDone;
+ if (last) {
+ SK_ALWAYSBREAK(last->fT != span.fT || last->fOther != span.fOther);
+ bool tsEqual = last->fT == span.fT;
+ bool tsPreciselyEqual = precisely_equal(last->fT, span.fT);
+ SK_ALWAYSBREAK(!tsEqual || tsPreciselyEqual);
+ bool pointsEqual = last->fPt == span.fPt;
+ bool pointsNearlyEqual = AlmostEqualUlps(last->fPt, span.fPt);
+#if 0 // bufferOverflow test triggers this
+ SK_ALWAYSBREAK(!tsPreciselyEqual || pointsNearlyEqual);
+#endif
+// SK_ALWAYSBREAK(!last->fTiny || !tsPreciselyEqual || span.fTiny || tinyTFound);
+ SK_ALWAYSBREAK(last->fTiny || tsPreciselyEqual || !pointsEqual || hasLoop);
+ SK_ALWAYSBREAK(!last->fTiny || pointsEqual);
+ SK_ALWAYSBREAK(!last->fTiny || last->fDone);
+ SK_ALWAYSBREAK(!last->fSmall || pointsNearlyEqual);
+ SK_ALWAYSBREAK(!last->fSmall || last->fDone);
+// SK_ALWAYSBREAK(!last->fSmall || last->fTiny);
+// SK_ALWAYSBREAK(last->fTiny || !pointsEqual || last->fDone == span.fDone);
+ if (last->fTiny) {
+ tinyTFound |= !tsPreciselyEqual;
+ } else {
+ tinyTFound = false;
+ }
+ }
+ last = &span;
+ hasLoop |= last->fLoop;
+ }
+ SK_ALWAYSBREAK(done == fDoneSpans);
+// if (fAngles.count() ) {
+// fAngles.begin()->debugValidateLoop();
+// }
+#endif
+}
« no previous file with comments | « src/pathops/SkPathOpsDebug.h ('k') | src/pathops/SkPathOpsLine.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698