skia2/tests/PathOpsDebug.cpp
Cary Clark da6289c5f3 mark tests flaky for pathkit
retain flaky state to avoid manual edits

R=kjlubick@google.com

Bug: skia:
Change-Id: I2f30a90aed46c52a0b30af1ccb7d6235b6db6945
Reviewed-on: https://skia-review.googlesource.com/149800
Commit-Queue: Cary Clark <caryclark@skia.org>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
2018-08-27 20:35:15 +00:00

1718 lines
54 KiB
C++

/*
* 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 "PathOpsDebug.h"
#include "PathOpsTSectDebug.h"
#include "SkOpCoincidence.h"
#include "SkOpContour.h"
#include "SkIntersectionHelper.h"
#include "SkMutex.h"
#include "SkOpSegment.h"
#include "SkString.h"
bool PathOpsDebug::gJson;
bool PathOpsDebug::gMarkJsonFlaky;
bool PathOpsDebug::gOutFirst;
bool PathOpsDebug::gCheckForDuplicateNames;
bool PathOpsDebug::gOutputSVG;
FILE* PathOpsDebug::gOut;
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);
}
}
inline void DebugDumpHexFloat(float x) {
SkDebugf("SkBits2Float(0x%08x)", SkFloat2Bits(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
static void DumpID(int id) {
SkDebugf("} ");
if (id >= 0) {
SkDebugf("id=%d", id);
}
SkDebugf("\n");
}
void SkDConic::dump() const {
dumpInner();
SkDebugf("},\n");
}
void SkDConic::dumpID(int id) const {
dumpInner();
DumpID(id);
}
void SkDConic::dumpInner() const {
SkDebugf("{");
fPts.dumpInner();
SkDebugf("}}, %1.9gf", fWeight);
}
void SkDCubic::dump() const {
this->dumpInner();
SkDebugf("}},\n");
}
void SkDCubic::dumpID(int id) const {
this->dumpInner();
SkDebugf("}");
DumpID(id);
}
static inline bool double_is_NaN(double x) { return x != x; }
void SkDCubic::dumpInner() const {
SkDebugf("{{");
int index = 0;
do {
if (index != 0) {
if (double_is_NaN(fPts[index].fX) && double_is_NaN(fPts[index].fY)) {
return;
}
SkDebugf(", ");
}
fPts[index].dump();
} while (++index < 3);
if (double_is_NaN(fPts[index].fX) && double_is_NaN(fPts[index].fY)) {
return;
}
SkDebugf(", ");
fPts[index].dump();
}
void SkDCurve::dump() const {
dumpID(-1);
}
void SkDCurve::dumpID(int id) const {
#ifndef SK_RELEASE
switch(fVerb) {
case SkPath::kLine_Verb:
fLine.dumpID(id);
break;
case SkPath::kQuad_Verb:
fQuad.dumpID(id);
break;
case SkPath::kConic_Verb:
fConic.dumpID(id);
break;
case SkPath::kCubic_Verb:
fCubic.dumpID(id);
break;
default:
SkASSERT(0);
}
#else
fCubic.dumpID(id);
#endif
}
void SkDLine::dump() const {
this->dumpInner();
SkDebugf("}},\n");
}
void SkDLine::dumpID(int id) const {
this->dumpInner();
SkDebugf("}");
DumpID(id);
}
void SkDLine::dumpInner() const {
SkDebugf("{{");
fPts[0].dump();
SkDebugf(", ");
fPts[1].dump();
}
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 SkDPoint::DumpHex(const SkPoint& pt) {
SkDebugf("{");
DebugDumpHexFloat(pt.fX);
SkDebugf(", ");
DebugDumpHexFloat(pt.fY);
SkDebugf("}");
}
void SkDQuad::dump() const {
dumpInner();
SkDebugf("}},\n");
}
void SkDQuad::dumpID(int id) const {
dumpInner();
SkDebugf("}");
DumpID(id);
}
void SkDQuad::dumpInner() const {
SkDebugf("{{");
int index = 0;
do {
fPts[index].dump();
SkDebugf(", ");
} while (++index < 2);
fPts[index].dump();
}
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");
}
namespace SkOpDebug {
const ::SkOpAngle* AngleAngle(const ::SkOpAngle* angle, int id) {
return angle->debugAngle(id);
}
::SkOpContour* AngleContour(::SkOpAngle* angle, int id) {
return angle->debugContour(id);
}
const ::SkOpPtT* AnglePtT(const ::SkOpAngle* angle, int id) {
return angle->debugPtT(id);
}
const ::SkOpSegment* AngleSegment(const ::SkOpAngle* angle, int id) {
return angle->debugSegment(id);
}
const ::SkOpSpanBase* AngleSpan(const ::SkOpAngle* angle, int id) {
return angle->debugSpan(id);
}
const ::SkOpAngle* ContourAngle(::SkOpContour* contour, int id) {
return contour->debugAngle(id);
}
::SkOpContour* ContourContour(::SkOpContour* contour, int id) {
return contour->debugContour(id);
}
const ::SkOpPtT* ContourPtT(::SkOpContour* contour, int id) {
return contour->debugPtT(id);
}
const ::SkOpSegment* ContourSegment(::SkOpContour* contour, int id) {
return contour->debugSegment(id);
}
const ::SkOpSpanBase* ContourSpan(::SkOpContour* contour, int id) {
return contour->debugSpan(id);
}
const ::SkOpAngle* CoincidenceAngle(::SkOpCoincidence* coin, int id) {
return coin->debugAngle(id);
}
::SkOpContour* CoincidenceContour(::SkOpCoincidence* coin, int id) {
return coin->debugContour(id);
}
const ::SkOpPtT* CoincidencePtT(::SkOpCoincidence* coin, int id) {
return coin->debugPtT(id);
}
const ::SkOpSegment* CoincidenceSegment(::SkOpCoincidence* coin, int id) {
return coin->debugSegment(id);
}
const ::SkOpSpanBase* CoincidenceSpan(::SkOpCoincidence* coin, int id) {
return coin->debugSpan(id);
}
const ::SkOpAngle* PtTAngle(const ::SkOpPtT* ptT, int id) {
return ptT->debugAngle(id);
}
::SkOpContour* PtTContour(::SkOpPtT* ptT, int id) {
return ptT->debugContour(id);
}
const ::SkOpPtT* PtTPtT(const ::SkOpPtT* ptT, int id) {
return ptT->debugPtT(id);
}
const ::SkOpSegment* PtTSegment(const ::SkOpPtT* ptT, int id) {
return ptT->debugSegment(id);
}
const ::SkOpSpanBase* PtTSpan(const ::SkOpPtT* ptT, int id) {
return ptT->debugSpan(id);
}
const ::SkOpAngle* SegmentAngle(const ::SkOpSegment* span, int id) {
return span->debugAngle(id);
}
::SkOpContour* SegmentContour(::SkOpSegment* span, int id) {
return span->debugContour(id);
}
const ::SkOpPtT* SegmentPtT(const ::SkOpSegment* span, int id) {
return span->debugPtT(id);
}
const ::SkOpSegment* SegmentSegment(const ::SkOpSegment* span, int id) {
return span->debugSegment(id);
}
const ::SkOpSpanBase* SegmentSpan(const ::SkOpSegment* span, int id) {
return span->debugSpan(id);
}
const ::SkOpAngle* SpanAngle(const ::SkOpSpanBase* span, int id) {
return span->debugAngle(id);
}
::SkOpContour* SpanContour(::SkOpSpanBase* span, int id) {
return span->debugContour(id);
}
const ::SkOpPtT* SpanPtT(const ::SkOpSpanBase* span, int id) {
return span->debugPtT(id);
}
const ::SkOpSegment* SpanSegment(const ::SkOpSpanBase* span, int id) {
return span->debugSegment(id);
}
const ::SkOpSpanBase* SpanSpan(const ::SkOpSpanBase* span, int id) {
return span->debugSpan(id);
}
} // namespace SkPathOpsDebug
#if DEBUG_COIN
void SkPathOpsDebug::DumpCoinDict() {
SkPathOpsDebug::gCoinSumChangedDict.dump("unused coin algorithm", false);
SkPathOpsDebug::gCoinSumVisitedDict.dump("visited coin function", true);
}
void SkPathOpsDebug::CoinDict::dump(const char* str, bool visitCheck) const {
int count = fDict.count();
for (int index = 0; index < count; ++index) {
const auto& entry = fDict[index];
if (visitCheck || entry.fGlitchType == kUninitialized_Glitch) {
SkDebugf("%s %s : line %d iteration %d", str, entry.fFunctionName,
entry.fLineNumber, entry.fIteration);
DumpGlitchType(entry.fGlitchType);
SkDebugf("\n");
}
}
}
#endif
void SkOpContour::dumpContours() const {
SkOpContour* contour = this->globalState()->contourHead();
do {
contour->dump();
} while ((contour = contour->next()));
}
void SkOpContour::dumpContoursAll() const {
SkOpContour* contour = this->globalState()->contourHead();
do {
contour->dumpAll();
} while ((contour = contour->next()));
}
void SkOpContour::dumpContoursAngles() const {
SkOpContour* contour = this->globalState()->contourHead();
do {
contour->dumpAngles();
} while ((contour = contour->next()));
}
void SkOpContour::dumpContoursPts() const {
SkOpContour* contour = this->globalState()->contourHead();
do {
contour->dumpPts();
} while ((contour = contour->next()));
}
void SkOpContour::dumpContoursPt(int segmentID) const {
SkOpContour* contour = this->globalState()->contourHead();
do {
contour->dumpPt(segmentID);
} while ((contour = contour->next()));
}
void SkOpContour::dumpContoursSegment(int segmentID) const {
SkOpContour* contour = this->globalState()->contourHead();
do {
contour->dumpSegment(segmentID);
} while ((contour = contour->next()));
}
void SkOpContour::dumpContoursSpan(int spanID) const {
SkOpContour* contour = this->globalState()->contourHead();
do {
contour->dumpSpan(spanID);
} while ((contour = contour->next()));
}
void SkOpContour::dumpContoursSpans() const {
SkOpContour* contour = this->globalState()->contourHead();
do {
contour->dumpSpans();
} while ((contour = contour->next()));
}
template <typename TCurve, typename OppCurve>
const SkTSpan<TCurve, OppCurve>* DebugSpan(const SkTSect<TCurve, OppCurve>* sect, int id) {
return sect->debugSpan(id);
}
void DontCallDebugSpan(int id);
void DontCallDebugSpan(int id) { // exists to instantiate the templates
SkDQuad quad;
SkDConic conic;
SkDCubic cubic;
SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
DebugSpan(&q1q2, id);
DebugSpan(&q1k2, id);
DebugSpan(&q1c2, id);
DebugSpan(&k1q2, id);
DebugSpan(&k1k2, id);
DebugSpan(&k1c2, id);
DebugSpan(&c1q2, id);
DebugSpan(&c1k2, id);
DebugSpan(&c1c2, id);
}
template <typename TCurve, typename OppCurve>
const SkTSpan<TCurve, OppCurve>* DebugT(const SkTSect<TCurve, OppCurve>* sect, double t) {
return sect->debugT(t);
}
void DontCallDebugT(double t);
void DontCallDebugT(double t) { // exists to instantiate the templates
SkDQuad quad;
SkDConic conic;
SkDCubic cubic;
SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
DebugT(&q1q2, t);
DebugT(&q1k2, t);
DebugT(&q1c2, t);
DebugT(&k1q2, t);
DebugT(&k1k2, t);
DebugT(&k1c2, t);
DebugT(&c1q2, t);
DebugT(&c1k2, t);
DebugT(&c1c2, t);
}
template <typename TCurve, typename OppCurve>
void Dump(const SkTSect<TCurve, OppCurve>* sect) {
sect->dump();
}
void DontCallDumpTSect();
void DontCallDumpTSect() { // exists to instantiate the templates
SkDQuad quad;
SkDConic conic;
SkDCubic cubic;
SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
Dump(&q1q2);
Dump(&q1k2);
Dump(&q1c2);
Dump(&k1q2);
Dump(&k1k2);
Dump(&k1c2);
Dump(&c1q2);
Dump(&c1k2);
Dump(&c1c2);
}
template <typename TCurve, typename OppCurve>
void DumpBoth(SkTSect<TCurve, OppCurve>* sect1, SkTSect<OppCurve, TCurve>* sect2) {
sect1->dumpBoth(sect2);
}
void DontCallDumpBoth();
void DontCallDumpBoth() { // exists to instantiate the templates
SkDQuad quad;
SkDConic conic;
SkDCubic cubic;
SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
DumpBoth(&q1q2, &q1q2);
DumpBoth(&q1k2, &k1q2);
DumpBoth(&q1c2, &c1q2);
DumpBoth(&k1q2, &q1k2);
DumpBoth(&k1k2, &k1k2);
DumpBoth(&k1c2, &c1k2);
DumpBoth(&c1q2, &q1c2);
DumpBoth(&c1k2, &k1c2);
DumpBoth(&c1c2, &c1c2);
}
template <typename TCurve, typename OppCurve>
void DumpBounded(SkTSect<TCurve, OppCurve>* sect1, int id) {
sect1->dumpBounded(id);
}
void DontCallDumpBounded();
void DontCallDumpBounded() {
SkDQuad quad;
SkDConic conic;
SkDCubic cubic;
SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
DumpBounded(&q1q2, 0);
DumpBounded(&q1k2, 0);
DumpBounded(&q1c2, 0);
DumpBounded(&k1q2, 0);
DumpBounded(&k1k2, 0);
DumpBounded(&k1c2, 0);
DumpBounded(&c1q2, 0);
DumpBounded(&c1k2, 0);
DumpBounded(&c1c2, 0);
}
template <typename TCurve, typename OppCurve>
void DumpBounds(SkTSect<TCurve, OppCurve>* sect1) {
sect1->dumpBounds();
}
void DontCallDumpBounds();
void DontCallDumpBounds() {
SkDQuad quad;
SkDConic conic;
SkDCubic cubic;
SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
DumpBounds(&q1q2);
DumpBounds(&q1k2);
DumpBounds(&q1c2);
DumpBounds(&k1q2);
DumpBounds(&k1k2);
DumpBounds(&k1c2);
DumpBounds(&c1q2);
DumpBounds(&c1k2);
DumpBounds(&c1c2);
}
template <typename TCurve, typename OppCurve>
void DumpCoin(SkTSect<TCurve, OppCurve>* sect1) {
sect1->dumpCoin();
}
void DontCallDumpCoin();
void DontCallDumpCoin() { // exists to instantiate the templates
SkDQuad quad;
SkDConic conic;
SkDCubic cubic;
SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
DumpCoin(&q1q2);
DumpCoin(&q1k2);
DumpCoin(&q1c2);
DumpCoin(&k1q2);
DumpCoin(&k1k2);
DumpCoin(&k1c2);
DumpCoin(&c1q2);
DumpCoin(&c1k2);
DumpCoin(&c1c2);
}
template <typename TCurve, typename OppCurve>
void DumpCoinCurves(SkTSect<TCurve, OppCurve>* sect1) {
sect1->dumpCoinCurves();
}
void DontCallDumpCoinCurves();
void DontCallDumpCoinCurves() { // exists to instantiate the templates
SkDQuad quad;
SkDConic conic;
SkDCubic cubic;
SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
DumpCoinCurves(&q1q2);
DumpCoinCurves(&q1k2);
DumpCoinCurves(&q1c2);
DumpCoinCurves(&k1q2);
DumpCoinCurves(&k1k2);
DumpCoinCurves(&k1c2);
DumpCoinCurves(&c1q2);
DumpCoinCurves(&c1k2);
DumpCoinCurves(&c1c2);
}
template <typename TCurve, typename OppCurve>
void DumpCurves(const SkTSect<TCurve, OppCurve>* sect) {
sect->dumpCurves();
}
void DontCallDumpCurves();
void DontCallDumpCurves() { // exists to instantiate the templates
SkDQuad quad;
SkDConic conic;
SkDCubic cubic;
SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
DumpCurves(&q1q2);
DumpCurves(&q1k2);
DumpCurves(&q1c2);
DumpCurves(&k1q2);
DumpCurves(&k1k2);
DumpCurves(&k1c2);
DumpCurves(&c1q2);
DumpCurves(&c1k2);
DumpCurves(&c1c2);
}
template <typename TCurve, typename OppCurve>
void Dump(const SkTSpan<TCurve, OppCurve>* span) {
span->dump();
}
void DontCallDumpTSpan();
void DontCallDumpTSpan() { // exists to instantiate the templates
SkTSpan<SkDQuad, SkDQuad> q1q2; q1q2.debugInit();
SkTSpan<SkDQuad, SkDConic> q1k2; q1k2.debugInit();
SkTSpan<SkDQuad, SkDCubic> q1c2; q1c2.debugInit();
SkTSpan<SkDConic, SkDQuad> k1q2; k1q2.debugInit();
SkTSpan<SkDConic, SkDConic> k1k2; k1k2.debugInit();
SkTSpan<SkDConic, SkDCubic> k1c2; k1c2.debugInit();
SkTSpan<SkDCubic, SkDQuad> c1q2; c1q2.debugInit();
SkTSpan<SkDCubic, SkDConic> c1k2; c1k2.debugInit();
SkTSpan<SkDCubic, SkDCubic> c1c2; c1c2.debugInit();
Dump(&q1q2);
Dump(&q1k2);
Dump(&q1c2);
Dump(&k1q2);
Dump(&k1k2);
Dump(&k1c2);
Dump(&c1q2);
Dump(&c1k2);
Dump(&c1c2);
}
template <typename TCurve, typename OppCurve>
void DumpAll(const SkTSpan<TCurve, OppCurve>* span) {
span->dumpAll();
}
void DontCallDumpSpanAll();
void DontCallDumpSpanAll() { // exists to instantiate the templates
SkTSpan<SkDQuad, SkDQuad> q1q2; q1q2.debugInit();
SkTSpan<SkDQuad, SkDConic> q1k2; q1k2.debugInit();
SkTSpan<SkDQuad, SkDCubic> q1c2; q1c2.debugInit();
SkTSpan<SkDConic, SkDQuad> k1q2; k1q2.debugInit();
SkTSpan<SkDConic, SkDConic> k1k2; k1k2.debugInit();
SkTSpan<SkDConic, SkDCubic> k1c2; k1c2.debugInit();
SkTSpan<SkDCubic, SkDQuad> c1q2; c1q2.debugInit();
SkTSpan<SkDCubic, SkDConic> c1k2; c1k2.debugInit();
SkTSpan<SkDCubic, SkDCubic> c1c2; c1c2.debugInit();
DumpAll(&q1q2);
DumpAll(&q1k2);
DumpAll(&q1c2);
DumpAll(&k1q2);
DumpAll(&k1k2);
DumpAll(&k1c2);
DumpAll(&c1q2);
DumpAll(&c1k2);
DumpAll(&c1c2);
}
template <typename TCurve, typename OppCurve>
void DumpBounded(const SkTSpan<TCurve, OppCurve>* span) {
span->dumpBounded(0);
}
void DontCallDumpSpanBounded();
void DontCallDumpSpanBounded() { // exists to instantiate the templates
SkTSpan<SkDQuad, SkDQuad> q1q2; q1q2.debugInit();
SkTSpan<SkDQuad, SkDConic> q1k2; q1k2.debugInit();
SkTSpan<SkDQuad, SkDCubic> q1c2; q1c2.debugInit();
SkTSpan<SkDConic, SkDQuad> k1q2; k1q2.debugInit();
SkTSpan<SkDConic, SkDConic> k1k2; k1k2.debugInit();
SkTSpan<SkDConic, SkDCubic> k1c2; k1c2.debugInit();
SkTSpan<SkDCubic, SkDQuad> c1q2; c1q2.debugInit();
SkTSpan<SkDCubic, SkDConic> c1k2; c1k2.debugInit();
SkTSpan<SkDCubic, SkDCubic> c1c2; c1c2.debugInit();
DumpBounded(&q1q2);
DumpBounded(&q1k2);
DumpBounded(&q1c2);
DumpBounded(&k1q2);
DumpBounded(&k1k2);
DumpBounded(&k1c2);
DumpBounded(&c1q2);
DumpBounded(&c1k2);
DumpBounded(&c1c2);
}
template <typename TCurve, typename OppCurve>
void DumpCoin(const SkTSpan<TCurve, OppCurve>* span) {
span->dumpCoin();
}
void DontCallDumpSpanCoin();
void DontCallDumpSpanCoin() { // exists to instantiate the templates
SkTSpan<SkDQuad, SkDQuad> q1q2; q1q2.debugInit();
SkTSpan<SkDQuad, SkDConic> q1k2; q1k2.debugInit();
SkTSpan<SkDQuad, SkDCubic> q1c2; q1c2.debugInit();
SkTSpan<SkDConic, SkDQuad> k1q2; k1q2.debugInit();
SkTSpan<SkDConic, SkDConic> k1k2; k1k2.debugInit();
SkTSpan<SkDConic, SkDCubic> k1c2; k1c2.debugInit();
SkTSpan<SkDCubic, SkDQuad> c1q2; c1q2.debugInit();
SkTSpan<SkDCubic, SkDConic> c1k2; c1k2.debugInit();
SkTSpan<SkDCubic, SkDCubic> c1c2; c1c2.debugInit();
DumpCoin(&q1q2);
DumpCoin(&q1k2);
DumpCoin(&q1c2);
DumpCoin(&k1q2);
DumpCoin(&k1k2);
DumpCoin(&k1c2);
DumpCoin(&c1q2);
DumpCoin(&c1k2);
DumpCoin(&c1c2);
}
static void dumpTestCase(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) {
SkDebugf("\n<div id=\"quad%d\">\n", testNo);
quad1.dumpInner();
SkDebugf("}}, ");
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();
}
const SkOpAngle* SkOpAngle::debugAngle(int id) const {
return this->segment()->debugAngle(id);
}
const SkOpCoincidence* SkOpAngle::debugCoincidence() const {
return this->segment()->debugCoincidence();
}
SkOpContour* SkOpAngle::debugContour(int id) const {
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);
}
int SkOpAngle::debugSign() const {
SkASSERT(fStart->t() != fEnd->t());
return fStart->t() < fEnd->t() ? -1 : 1;
}
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->debugSign(), 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");
}
}
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->fPart.fCurve.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) const {
return this->span()->debugContour(id);
}
const SkOpCoincidence* SkOpPtT::debugCoincidence() const {
return this->span()->debugCoincidence();
}
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%s", this->fT, this->fPt.fX, this->fPt.fY,
this->fCoincident ? " coin" : "",
this->fDuplicatePt ? " dup" : "", this->fDeleted ? " deleted" : "");
}
const SkOpAngle* SkOpSpanBase::debugAngle(int id) const {
return this->segment()->debugAngle(id);
}
const SkOpCoincidence* SkOpSpanBase::debugCoincidence() const {
return this->segment()->debugCoincidence();
}
SkOpContour* SkOpSpanBase::debugContour(int id) const {
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->dumpHead();
this->fPtT.dump();
}
void SkOpSpanBase::dumpHead() const {
SkDebugf("%.*s", contour()->debugIndent(), " ");
SkDebugf("seg=%d span=%d", this->segment()->debugID(), this->debugID());
this->dumpBase();
SkDebugf("\n");
}
void SkOpSpanBase::dumpAll() const {
this->dumpHead();
this->fPtT.dumpAll();
}
void SkOpSpanBase::dumpBase() const {
if (this->fAligned) {
SkDebugf(" aligned");
}
if (this->fChased) {
SkDebugf(" chased");
}
#ifdef SK_DEBUG
if (this->fDebugDeleted) {
SkDebugf(" deleted");
}
#endif
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());
}
SkDebugf(" adds=%d", fSpanAdds);
}
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);
}
const SkOpCoincidence* SkOpSegment::debugCoincidence() const {
return this->contour()->debugCoincidence();
}
SkOpContour* SkOpSegment::debugContour(int id) const {
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() ? nullptr : 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::dumpPtsInner(const char* prefix) const {
int last = SkPathOpsVerbToPoints(fVerb);
SkDebugf("%s=%d {{", prefix, this->debugID());
if (fVerb == SkPath::kConic_Verb) {
SkDebugf("{");
}
int index = 0;
do {
SkDPoint::Dump(fPts[index]);
SkDebugf(", ");
} while (++index < last);
SkDPoint::Dump(fPts[index]);
SkDebugf("}}");
if (fVerb == SkPath::kConic_Verb) {
SkDebugf(", %1.9gf}", fWeight);
}
}
void SkOpSegment::dumpPts(const char* prefix) const {
dumpPtsInner(prefix);
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->next();
}
if (!fTop || fHead == fTop) {
return;
}
SkDebugf("top:\n");
span = fTop;
int count = 0;
while (span) {
span->dump();
span = span->next();
SkCoincidentSpans* check = fTop;
++count;
for (int index = 0; index < count; ++index) {
if (span == check) {
SkDebugf("(loops to #%d)\n", index);
return;
}
check = check->next();
}
}
}
void SkOpContour::dump() const {
SkDebugf("contour=%d count=%d op=%d xor=%d\n", this->debugID(), fCount, fOperand, fXor);
if (!fCount) {
return;
}
const SkOpSegment* segment = &fHead;
SkDEBUGCODE(fDebugIndent = 0);
this->indentDump();
do {
segment->dump();
} while ((segment = segment->next()));
this->outdentDump();
}
void SkOpContour::dumpAll() const {
SkDebugf("contour=%d count=%d op=%d xor=%d\n", this->debugID(), fCount, fOperand, fXor);
if (!fCount) {
return;
}
const SkOpSegment* segment = &fHead;
SkDEBUGCODE(fDebugIndent = 0);
this->indentDump();
do {
segment->dumpAll();
} while ((segment = segment->next()));
this->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 char* prefix) const {
SkDebugf("contour=%d\n", this->debugID());
const SkOpSegment* segment = &fHead;
do {
SkDebugf(" %s=%d ", prefix, segment->debugID());
segment->dumpPts(prefix);
} while ((segment = segment->next()));
}
void SkOpContour::dumpPtsX(const char* prefix) const {
if (!this->fCount) {
SkDebugf("<empty>\n");
return;
}
const SkOpSegment* segment = &fHead;
do {
segment->dumpPts(prefix);
} while ((segment = segment->next()));
}
void SkOpContour::dumpSegment(int index) const {
debugSegment(index)->dump();
}
void SkOpContour::dumpSegments(const char* prefix, 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(prefix);
} 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()));
}
void SkOpCurve::dump() const {
int count = SkPathOpsVerbToPoints(SkDEBUGRELEASE(fVerb, SkPath::kCubic_Verb));
SkDebugf("{{");
int index;
for (index = 0; index <= count - 1; ++index) {
SkDebugf("{%1.9gf,%1.9gf}, ", fPts[index].fX, fPts[index].fY);
}
SkDebugf("{%1.9gf,%1.9gf}}}\n", fPts[index].fX, fPts[index].fY);
}
#ifdef SK_DEBUG
const SkOpAngle* SkOpGlobalState::debugAngle(int id) const {
const SkOpContour* contour = fContourHead;
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 nullptr;
}
SkOpContour* SkOpGlobalState::debugContour(int id) const {
SkOpContour* contour = fContourHead;
do {
if (contour->debugID() == id) {
return contour;
}
} while ((contour = contour->next()));
return nullptr;
}
const SkOpPtT* SkOpGlobalState::debugPtT(int id) const {
const SkOpContour* contour = fContourHead;
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 nullptr;
}
const SkOpSegment* SkOpGlobalState::debugSegment(int id) const {
const SkOpContour* contour = fContourHead;
do {
const SkOpSegment* segment = contour->first();
while (segment) {
if (segment->debugID() == id) {
return segment;
}
segment = segment->next();
}
} while ((contour = contour->next()));
return nullptr;
}
const SkOpSpanBase* SkOpGlobalState::debugSpan(int id) const {
const SkOpContour* contour = fContourHead;
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 nullptr;
}
#endif
#if DEBUG_T_SECT_DUMP > 1
int gDumpTSectNum;
#endif
// global path dumps for msvs Visual Studio 17 to use from Immediate Window
namespace SkOpDebug {
void Dump(const SkOpContour& contour) {
contour.dump();
}
void DumpAll(const SkOpContour& contour) {
contour.dumpAll();
}
void DumpAngles(const SkOpContour& contour) {
contour.dumpAngles();
}
void DumpContours(const SkOpContour& contour) {
contour.dumpContours();
}
void DumpContoursAll(const SkOpContour& contour) {
contour.dumpContoursAll();
}
void DumpContoursAngles(const SkOpContour& contour) {
contour.dumpContoursAngles();
}
void DumpContoursPts(const SkOpContour& contour) {
contour.dumpContoursPts();
}
void DumpContoursPt(const SkOpContour& contour, int segmentID) {
contour.dumpContoursPt(segmentID);
}
void DumpContoursSegment(const SkOpContour& contour, int segmentID) {
contour.dumpContoursSegment(segmentID);
}
void DumpContoursSpan(const SkOpContour& contour, int segmentID) {
contour.dumpContoursSpan(segmentID);
}
void DumpContoursSpans(const SkOpContour& contour) {
contour.dumpContoursSpans();
}
void DumpPt(const SkOpContour& contour, int pt) {
contour.dumpPt(pt);
}
void DumpPts(const SkOpContour& contour, const char* prefix) {
contour.dumpPts(prefix);
}
void DumpSegment(const SkOpContour& contour, int seg) {
contour.dumpSegment(seg);
}
void DumpSegments(const SkOpContour& contour, const char* prefix, SkPathOp op) {
contour.dumpSegments(prefix, op);
}
void DumpSpan(const SkOpContour& contour, int span) {
contour.dumpSpan(span);
}
void DumpSpans(const SkOpContour& contour ) {
contour.dumpSpans();
}
void Dump(const SkOpSegment& segment) {
segment.dump();
}
void DumpAll(const SkOpSegment& segment) {
segment.dumpAll();
}
void DumpAngles(const SkOpSegment& segment) {
segment.dumpAngles();
}
void DumpCoin(const SkOpSegment& segment) {
segment.dumpCoin();
}
void DumpPts(const SkOpSegment& segment, const char* prefix) {
segment.dumpPts(prefix);
}
void Dump(const SkOpPtT& ptT) {
ptT.dump();
}
void DumpAll(const SkOpPtT& ptT) {
ptT.dumpAll();
}
void Dump(const SkOpSpanBase& spanBase) {
spanBase.dump();
}
void DumpCoin(const SkOpSpanBase& spanBase) {
spanBase.dumpCoin();
}
void DumpAll(const SkOpSpanBase& spanBase) {
spanBase.dumpAll();
}
void DumpCoin(const SkOpSpan& span) {
span.dumpCoin();
}
bool DumpSpan(const SkOpSpan& span) {
return span.dumpSpan();
}
void Dump(const SkDConic& conic) {
conic.dump();
}
void DumpID(const SkDConic& conic, int id) {
conic.dumpID(id);
}
void Dump(const SkDCubic& cubic) {
cubic.dump();
}
void DumpID(const SkDCubic& cubic, int id) {
cubic.dumpID(id);
}
void Dump(const SkDLine& line) {
line.dump();
}
void DumpID(const SkDLine& line, int id) {
line.dumpID(id);
}
void Dump(const SkDQuad& quad) {
quad.dump();
}
void DumpID(const SkDQuad& quad, int id) {
quad.dumpID(id);
}
void Dump(const SkDPoint& point) {
point.dump();
}
void Dump(const SkOpAngle& angle) {
angle.dump();
}
// dummy definitions to fool msvs Visual Studio 2018 Immediate Window
#define DummyDefinitions(a, b) \
\
void Dump(const SkDebugTCoincident##a##b& curve) { \
((const SkTCoincident<SkD##a, SkD##b>& ) curve).dump(); \
} \
\
void Dump(const SkDebugTSect##a##b& curve) { \
((const SkTSect<SkD##a, SkD##b>& ) curve).dump(); \
} \
\
void DumpBoth(const SkDebugTSect##a##b& curve, SkDebugTSect##a##b* opp) { \
((const SkTSect<SkD##a, SkD##b>& ) curve).dumpBoth((SkTSect<SkD##b, SkD##a>* ) opp); \
} \
\
void DumpBounded(const SkDebugTSect##a##b& curve, int id) { \
((const SkTSect<SkD##a, SkD##b>& ) curve).dumpBounded(id); \
} \
\
void DumpBounds(const SkDebugTSect##a##b& curve) { \
((const SkTSect<SkD##a, SkD##b>& ) curve).dumpBounds(); \
} \
\
void DumpCoin(const SkDebugTSect##a##b& curve) { \
((const SkTSect<SkD##a, SkD##b>& ) curve).dumpCoin(); \
} \
\
void DumpCoinCurves(const SkDebugTSect##a##b& curve) { \
((const SkTSect<SkD##a, SkD##b>& ) curve).dumpCoinCurves(); \
} \
\
void DumpCurves(const SkDebugTSect##a##b& curve) { \
((const SkTSect<SkD##a, SkD##b>& ) curve).dumpCurves(); \
} \
\
void Dump(const SkDebugTSpan##a##b& curve) { \
((const SkTSpan<SkD##a, SkD##b>& ) curve).dump(); \
} \
\
void DumpAll(const SkDebugTSpan##a##b& curve) { \
((const SkTSpan<SkD##a, SkD##b>& ) curve).dumpAll(); \
} \
\
void DumpBounded(const SkDebugTSpan##a##b& curve, int id) { \
((const SkTSpan<SkD##a, SkD##b>& ) curve).dumpBounded(id); \
} \
\
void DumpBounds(const SkDebugTSpan##a##b& curve) { \
((const SkTSpan<SkD##a, SkD##b>& ) curve).dumpBounds(); \
} \
\
void DumpCoin(const SkDebugTSpan##a##b& curve) { \
((const SkTSpan<SkD##a, SkD##b>& ) curve).dumpCoin(); \
}
DummyDefinitions(Quad, Quad);
DummyDefinitions(Conic, Quad);
DummyDefinitions(Conic, Conic);
DummyDefinitions(Cubic, Quad);
DummyDefinitions(Cubic, Conic);
DummyDefinitions(Cubic, Cubic);
#undef DummyDefinitions
}