/* * 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 const SkTSpan* DebugSpan(const SkTSect* 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 q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect 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 const SkTSpan* DebugT(const SkTSect* 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 q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect 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 void Dump(const SkTSect* sect) { sect->dump(); } void DontCallDumpTSect(); void DontCallDumpTSect() { // exists to instantiate the templates SkDQuad quad; SkDConic conic; SkDCubic cubic; SkTSect q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect 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 void DumpBoth(SkTSect* sect1, SkTSect* sect2) { sect1->dumpBoth(sect2); } void DontCallDumpBoth(); void DontCallDumpBoth() { // exists to instantiate the templates SkDQuad quad; SkDConic conic; SkDCubic cubic; SkTSect q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect 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 void DumpBounded(SkTSect* sect1, int id) { sect1->dumpBounded(id); } void DontCallDumpBounded(); void DontCallDumpBounded() { SkDQuad quad; SkDConic conic; SkDCubic cubic; SkTSect q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect 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 void DumpBounds(SkTSect* sect1) { sect1->dumpBounds(); } void DontCallDumpBounds(); void DontCallDumpBounds() { SkDQuad quad; SkDConic conic; SkDCubic cubic; SkTSect q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect 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 void DumpCoin(SkTSect* sect1) { sect1->dumpCoin(); } void DontCallDumpCoin(); void DontCallDumpCoin() { // exists to instantiate the templates SkDQuad quad; SkDConic conic; SkDCubic cubic; SkTSect q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect 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 void DumpCoinCurves(SkTSect* sect1) { sect1->dumpCoinCurves(); } void DontCallDumpCoinCurves(); void DontCallDumpCoinCurves() { // exists to instantiate the templates SkDQuad quad; SkDConic conic; SkDCubic cubic; SkTSect q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect 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 void DumpCurves(const SkTSect* sect) { sect->dumpCurves(); } void DontCallDumpCurves(); void DontCallDumpCurves() { // exists to instantiate the templates SkDQuad quad; SkDConic conic; SkDCubic cubic; SkTSect q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1)); SkTSect 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 void Dump(const SkTSpan* span) { span->dump(); } void DontCallDumpTSpan(); void DontCallDumpTSpan() { // exists to instantiate the templates SkTSpan q1q2; q1q2.debugInit(); SkTSpan q1k2; q1k2.debugInit(); SkTSpan q1c2; q1c2.debugInit(); SkTSpan k1q2; k1q2.debugInit(); SkTSpan k1k2; k1k2.debugInit(); SkTSpan k1c2; k1c2.debugInit(); SkTSpan c1q2; c1q2.debugInit(); SkTSpan c1k2; c1k2.debugInit(); SkTSpan c1c2; c1c2.debugInit(); Dump(&q1q2); Dump(&q1k2); Dump(&q1c2); Dump(&k1q2); Dump(&k1k2); Dump(&k1c2); Dump(&c1q2); Dump(&c1k2); Dump(&c1c2); } template void DumpAll(const SkTSpan* span) { span->dumpAll(); } void DontCallDumpSpanAll(); void DontCallDumpSpanAll() { // exists to instantiate the templates SkTSpan q1q2; q1q2.debugInit(); SkTSpan q1k2; q1k2.debugInit(); SkTSpan q1c2; q1c2.debugInit(); SkTSpan k1q2; k1q2.debugInit(); SkTSpan k1k2; k1k2.debugInit(); SkTSpan k1c2; k1c2.debugInit(); SkTSpan c1q2; c1q2.debugInit(); SkTSpan c1k2; c1k2.debugInit(); SkTSpan c1c2; c1c2.debugInit(); DumpAll(&q1q2); DumpAll(&q1k2); DumpAll(&q1c2); DumpAll(&k1q2); DumpAll(&k1k2); DumpAll(&k1c2); DumpAll(&c1q2); DumpAll(&c1k2); DumpAll(&c1c2); } template void DumpBounded(const SkTSpan* span) { span->dumpBounded(0); } void DontCallDumpSpanBounded(); void DontCallDumpSpanBounded() { // exists to instantiate the templates SkTSpan q1q2; q1q2.debugInit(); SkTSpan q1k2; q1k2.debugInit(); SkTSpan q1c2; q1c2.debugInit(); SkTSpan k1q2; k1q2.debugInit(); SkTSpan k1k2; k1k2.debugInit(); SkTSpan k1c2; k1c2.debugInit(); SkTSpan c1q2; c1q2.debugInit(); SkTSpan c1k2; c1k2.debugInit(); SkTSpan c1c2; c1c2.debugInit(); DumpBounded(&q1q2); DumpBounded(&q1k2); DumpBounded(&q1c2); DumpBounded(&k1q2); DumpBounded(&k1k2); DumpBounded(&k1c2); DumpBounded(&c1q2); DumpBounded(&c1k2); DumpBounded(&c1c2); } template void DumpCoin(const SkTSpan* span) { span->dumpCoin(); } void DontCallDumpSpanCoin(); void DontCallDumpSpanCoin() { // exists to instantiate the templates SkTSpan q1q2; q1q2.debugInit(); SkTSpan q1k2; q1k2.debugInit(); SkTSpan q1c2; q1c2.debugInit(); SkTSpan k1q2; k1q2.debugInit(); SkTSpan k1k2; k1k2.debugInit(); SkTSpan k1c2; k1c2.debugInit(); SkTSpan c1q2; c1q2.debugInit(); SkTSpan c1k2; c1k2.debugInit(); SkTSpan 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
\n", testNo); quad1.dumpInner(); SkDebugf("}}, "); quad2.dump(); SkDebugf("
\n\n"); } static void dumpTestTrailer() { SkDebugf("\n\n