| /* | 
 |  * Copyright 2014 Google Inc. | 
 |  * | 
 |  * Use of this source code is governed by a BSD-style license that can be | 
 |  * found in the LICENSE file. | 
 |  */ | 
 |  | 
 | #include "PathOpsTSectDebug.h" | 
 | #include "SkOpCoincidence.h" | 
 | #include "SkOpContour.h" | 
 | #include "SkIntersectionHelper.h" | 
 | #include "SkMutex.h" | 
 | #include "SkOpSegment.h" | 
 | #include "SkString.h" | 
 |  | 
 | inline void DebugDumpDouble(double x) { | 
 |     if (x == floor(x)) { | 
 |         SkDebugf("%.0f", x); | 
 |     } else { | 
 |         SkDebugf("%1.19g", x); | 
 |     } | 
 | } | 
 |  | 
 | inline void DebugDumpFloat(float x) { | 
 |     if (x == floorf(x)) { | 
 |         SkDebugf("%.0f", x); | 
 |     } else { | 
 |         SkDebugf("%1.9gf", x); | 
 |     } | 
 | } | 
 |  | 
 | 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 | 
 |  | 
 | void SkDConic::dump() const { | 
 |     dumpInner(); | 
 |     SkDebugf("},\n"); | 
 | } | 
 |  | 
 | void SkDConic::dumpID(int id) const { | 
 |     dumpInner(); | 
 |     SkDebugf("} id=%d\n", id); | 
 | } | 
 |  | 
 | void SkDConic::dumpInner() const { | 
 |     SkDebugf("{{"); | 
 |     int index = 0; | 
 |     do { | 
 |         fPts[index].dump(); | 
 |         SkDebugf(", "); | 
 |     } while (++index < 2); | 
 |     fPts[index].dump(); | 
 |     SkDebugf("}, %1.9g", fWeight); | 
 | } | 
 |  | 
 | void SkDCubic::dump() const { | 
 |     this->dumpInner(); | 
 |     SkDebugf("}},\n"); | 
 | } | 
 |  | 
 | void SkDCubic::dumpID(int id) const { | 
 |     this->dumpInner(); | 
 |     SkDebugf("}} id=%d\n", 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::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("}} id=%d\n", 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("}} id=%d\n", 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"); | 
 | } | 
 |  | 
 | const SkOpAngle* SkPathOpsDebug::DebugAngleAngle(const SkOpAngle* angle, int id) { | 
 |     return angle->debugAngle(id); | 
 | } | 
 |  | 
 | SkOpContour* SkPathOpsDebug::DebugAngleContour(SkOpAngle* angle, int id) { | 
 |     return angle->debugContour(id); | 
 | } | 
 |  | 
 | const SkOpPtT* SkPathOpsDebug::DebugAnglePtT(const SkOpAngle* angle, int id) { | 
 |     return angle->debugPtT(id); | 
 | } | 
 |  | 
 | const SkOpSegment* SkPathOpsDebug::DebugAngleSegment(const SkOpAngle* angle, int id) { | 
 |     return angle->debugSegment(id); | 
 | } | 
 |  | 
 | const SkOpSpanBase* SkPathOpsDebug::DebugAngleSpan(const SkOpAngle* angle, int id) { | 
 |     return angle->debugSpan(id); | 
 | } | 
 |  | 
 | const SkOpAngle* SkPathOpsDebug::DebugContourAngle(SkOpContour* contour, int id) { | 
 |     return contour->debugAngle(id); | 
 | } | 
 |  | 
 | SkOpContour* SkPathOpsDebug::DebugContourContour(SkOpContour* contour, int id) { | 
 |     return contour->debugContour(id); | 
 | } | 
 |  | 
 | const SkOpPtT* SkPathOpsDebug::DebugContourPtT(SkOpContour* contour, int id) { | 
 |     return contour->debugPtT(id); | 
 | } | 
 |  | 
 | const SkOpSegment* SkPathOpsDebug::DebugContourSegment(SkOpContour* contour, int id) { | 
 |     return contour->debugSegment(id); | 
 | } | 
 |  | 
 | const SkOpSpanBase* SkPathOpsDebug::DebugContourSpan(SkOpContour* contour, int id) { | 
 |     return contour->debugSpan(id); | 
 | } | 
 |  | 
 | const SkOpAngle* SkPathOpsDebug::DebugPtTAngle(const SkOpPtT* ptT, int id) { | 
 |     return ptT->debugAngle(id); | 
 | } | 
 |  | 
 | SkOpContour* SkPathOpsDebug::DebugPtTContour(SkOpPtT* ptT, int id) { | 
 |     return ptT->debugContour(id); | 
 | } | 
 |  | 
 | const SkOpPtT* SkPathOpsDebug::DebugPtTPtT(const SkOpPtT* ptT, int id) { | 
 |     return ptT->debugPtT(id); | 
 | } | 
 |  | 
 | const SkOpSegment* SkPathOpsDebug::DebugPtTSegment(const SkOpPtT* ptT, int id) { | 
 |     return ptT->debugSegment(id); | 
 | } | 
 |  | 
 | const SkOpSpanBase* SkPathOpsDebug::DebugPtTSpan(const SkOpPtT* ptT, int id) { | 
 |     return ptT->debugSpan(id); | 
 | } | 
 |  | 
 | const SkOpAngle* SkPathOpsDebug::DebugSegmentAngle(const SkOpSegment* span, int id) { | 
 |     return span->debugAngle(id); | 
 | } | 
 |  | 
 | SkOpContour* SkPathOpsDebug::DebugSegmentContour(SkOpSegment* span, int id) { | 
 |     return span->debugContour(id); | 
 | } | 
 |  | 
 | const SkOpPtT* SkPathOpsDebug::DebugSegmentPtT(const SkOpSegment* span, int id) { | 
 |     return span->debugPtT(id); | 
 | } | 
 |  | 
 | const SkOpSegment* SkPathOpsDebug::DebugSegmentSegment(const SkOpSegment* span, int id) { | 
 |     return span->debugSegment(id); | 
 | } | 
 |  | 
 | const SkOpSpanBase* SkPathOpsDebug::DebugSegmentSpan(const SkOpSegment* span, int id) { | 
 |     return span->debugSpan(id); | 
 | } | 
 |  | 
 | const SkOpAngle* SkPathOpsDebug::DebugSpanAngle(const SkOpSpanBase* span, int id) { | 
 |     return span->debugAngle(id); | 
 | } | 
 |  | 
 | SkOpContour* SkPathOpsDebug::DebugSpanContour(SkOpSpanBase* span, int id) { | 
 |     return span->debugContour(id); | 
 | } | 
 |  | 
 | const SkOpPtT* SkPathOpsDebug::DebugSpanPtT(const SkOpSpanBase* span, int id) { | 
 |     return span->debugPtT(id); | 
 | } | 
 |  | 
 | const SkOpSegment* SkPathOpsDebug::DebugSpanSegment(const SkOpSpanBase* span, int id) { | 
 |     return span->debugSegment(id); | 
 | } | 
 |  | 
 | const SkOpSpanBase* SkPathOpsDebug::DebugSpanSpan(const SkOpSpanBase* span, int id) { | 
 |     return span->debugSpan(id); | 
 | } | 
 |  | 
 | 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 PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDQuad, SkDConic> q1k2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDQuad, SkDCubic> q1c2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDQuad> k1q2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDConic> k1k2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDCubic> k1c2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDQuad> c1q2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDConic> c1k2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDCubic> c1c2(cubic 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 PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDQuad, SkDConic> q1k2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDQuad, SkDCubic> q1c2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDQuad> k1q2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDConic> k1k2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDCubic> k1c2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDQuad> c1q2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDConic> c1k2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDCubic> c1c2(cubic 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 PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDQuad, SkDConic> q1k2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDQuad, SkDCubic> q1c2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDQuad> k1q2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDConic> k1k2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDCubic> k1c2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDQuad> c1q2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDConic> c1k2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDCubic> c1c2(cubic 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 PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDQuad, SkDConic> q1k2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDQuad, SkDCubic> q1c2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDQuad> k1q2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDConic> k1k2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDCubic> k1c2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDQuad> c1q2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDConic> c1k2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDCubic> c1c2(cubic 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 PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDQuad, SkDConic> q1k2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDQuad, SkDCubic> q1c2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDQuad> k1q2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDConic> k1k2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDCubic> k1c2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDQuad> c1q2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDConic> c1k2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDCubic> c1c2(cubic 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 PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDQuad, SkDConic> q1k2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDQuad, SkDCubic> q1c2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDQuad> k1q2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDConic> k1k2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDCubic> k1c2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDQuad> c1q2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDConic> c1k2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDCubic> c1c2(cubic 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 PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDQuad, SkDConic> q1k2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDQuad, SkDCubic> q1c2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDQuad> k1q2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDConic> k1k2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDCubic> k1c2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDQuad> c1q2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDConic> c1k2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDCubic> c1c2(cubic 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 PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDQuad, SkDConic> q1k2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDQuad, SkDCubic> q1c2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDQuad> k1q2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDConic> k1k2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDCubic> k1c2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDQuad> c1q2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDConic> c1k2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDCubic> c1c2(cubic 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 PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDQuad, SkDConic> q1k2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDQuad, SkDCubic> q1c2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDQuad> k1q2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDConic> k1k2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDConic, SkDCubic> k1c2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDQuad> c1q2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDConic> c1k2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1)); | 
 |     SkTSect<SkDCubic, SkDCubic> c1c2(cubic 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 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); | 
 | } | 
 |  | 
 | SkOpContour* SkOpAngle::debugContour(int id) { | 
 |     return this->segment()->debugContour(id); | 
 | } | 
 |  | 
 | const SkOpPtT* SkOpAngle::debugPtT(int id) const { | 
 |     return this->segment()->debugPtT(id); | 
 | } | 
 |  | 
 | const SkOpSegment* SkOpAngle::debugSegment(int id) const { | 
 |     return this->segment()->debugSegment(id); | 
 | } | 
 |  | 
 | 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->fCurvePart.dumpID(next->segment()->debugID()); | 
 |         next = next->fNext; | 
 |     } while (next && next != first); | 
 | } | 
 |  | 
 | void SkOpAngle::dumpLoop() const { | 
 |     const SkOpAngle* first = this; | 
 |     const SkOpAngle* next = this; | 
 |     do { | 
 |         next->dumpOne(false); | 
 |         SkDebugf("\n"); | 
 |         next = next->fNext; | 
 |     } while (next && next != first); | 
 | } | 
 |  | 
 | void SkOpAngle::dumpTest() const { | 
 |     const SkOpAngle* first = this; | 
 |     const SkOpAngle* next = this; | 
 |     do { | 
 |         SkDebugf("{ "); | 
 |         SkOpSegment* segment = next->segment(); | 
 |         segment->dumpPts(); | 
 |         SkDebugf(", %d, %1.9g, %1.9g, {} },\n", SkPathOpsVerbToPoints(segment->verb()) + 1, | 
 |                 next->start()->t(), next->end()->t()); | 
 |         next = next->fNext; | 
 |     } while (next && next != first); | 
 | } | 
 |  | 
 | bool SkOpPtT::debugMatchID(int id) const { | 
 |     int limit = this->debugLoopLimit(false); | 
 |     int loop = 0; | 
 |     const SkOpPtT* ptT = this; | 
 |     do { | 
 |         if (ptT->debugID() == id) { | 
 |             return true; | 
 |         } | 
 |     } while ((!limit || ++loop <= limit) && (ptT = ptT->next()) && ptT != this); | 
 |     return false; | 
 | } | 
 |  | 
 | const SkOpAngle* SkOpPtT::debugAngle(int id) const { | 
 |     return this->span()->debugAngle(id); | 
 | } | 
 |  | 
 | SkOpContour* SkOpPtT::debugContour(int id) { | 
 |     return this->span()->debugContour(id); | 
 | } | 
 |  | 
 | const SkOpPtT* SkOpPtT::debugPtT(int id) const { | 
 |     return this->span()->debugPtT(id); | 
 | } | 
 |  | 
 | const SkOpSegment* SkOpPtT::debugSegment(int id) const { | 
 |     return this->span()->debugSegment(id); | 
 | } | 
 |  | 
 | const SkOpSpanBase* SkOpPtT::debugSpan(int id) const { | 
 |     return this->span()->debugSpan(id); | 
 | } | 
 |  | 
 | void SkOpPtT::dump() const { | 
 |     SkDebugf("seg=%d span=%d ptT=%d", | 
 |             this->segment()->debugID(), this->span()->debugID(), this->debugID()); | 
 |     this->dumpBase(); | 
 |     SkDebugf("\n"); | 
 | } | 
 |  | 
 | void SkOpPtT::dumpAll() const { | 
 |     contour()->indentDump(); | 
 |     const SkOpPtT* next = this; | 
 |     int limit = debugLoopLimit(true); | 
 |     int loop = 0; | 
 |     do { | 
 |         SkDebugf("%.*s", contour()->debugIndent(), "        "); | 
 |         SkDebugf("seg=%d span=%d ptT=%d", | 
 |                 next->segment()->debugID(), next->span()->debugID(), next->debugID()); | 
 |         next->dumpBase(); | 
 |         SkDebugf("\n"); | 
 |         if (limit && ++loop >= limit) { | 
 |             SkDebugf("*** abort loop ***\n"); | 
 |             break; | 
 |         } | 
 |     } while ((next = next->fNext) && next != this); | 
 |     contour()->outdentDump(); | 
 | } | 
 |  | 
 | void SkOpPtT::dumpBase() const { | 
 |     SkDebugf(" t=%1.9g pt=(%1.9g,%1.9g)%s%s", this->fT, this->fPt.fX, this->fPt.fY, | 
 |             this->fDuplicatePt ? " dup" : "", this->fDeleted ? " deleted" : ""); | 
 | } | 
 |  | 
 | const SkOpAngle* SkOpSpanBase::debugAngle(int id) const { | 
 |     return this->segment()->debugAngle(id); | 
 | } | 
 |  | 
 | SkOpContour* SkOpSpanBase::debugContour(int id) { | 
 |     return this->segment()->debugContour(id); | 
 | } | 
 |  | 
 | const SkOpPtT* SkOpSpanBase::debugPtT(int id) const { | 
 |     return this->segment()->debugPtT(id); | 
 | } | 
 |  | 
 | const SkOpSegment* SkOpSpanBase::debugSegment(int id) const { | 
 |     return this->segment()->debugSegment(id); | 
 | } | 
 |  | 
 | const SkOpSpanBase* SkOpSpanBase::debugSpan(int id) const { | 
 |     return this->segment()->debugSpan(id); | 
 | } | 
 |  | 
 | void SkOpSpanBase::dump() const { | 
 |     this->dumpAll(); | 
 |     SkDebugf("\n"); | 
 | } | 
 |  | 
 | void SkOpSpanBase::dumpAll() const { | 
 |     SkDebugf("%.*s", contour()->debugIndent(), "        "); | 
 |     SkDebugf("seg=%d span=%d", this->segment()->debugID(), this->debugID()); | 
 |     this->dumpBase(); | 
 |     SkDebugf("\n"); | 
 |     this->fPtT.dumpAll(); | 
 | } | 
 |  | 
 | void SkOpSpanBase::dumpBase() const { | 
 |     if (this->fAligned) { | 
 |         SkDebugf(" aligned"); | 
 |     } | 
 |     if (this->fChased) { | 
 |         SkDebugf(" chased"); | 
 |     } | 
 |     if (!this->final()) { | 
 |         this->upCast()->dumpSpan(); | 
 |     } | 
 |     const SkOpSpanBase* coin = this->coinEnd(); | 
 |     if (this != coin) { | 
 |         SkDebugf(" coinEnd seg/span=%d/%d", coin->segment()->debugID(), coin->debugID()); | 
 |     } else if (this->final() || !this->upCast()->isCoincident()) { | 
 |         const SkOpPtT* oPt = this->ptT()->next(); | 
 |         SkDebugf(" seg/span=%d/%d", oPt->segment()->debugID(), oPt->span()->debugID()); | 
 |     } | 
 |     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); | 
 | } | 
 |  | 
 | SkOpContour* SkOpSegment::debugContour(int id) { | 
 |     return this->contour()->debugContour(id); | 
 | } | 
 |  | 
 | const SkOpPtT* SkOpSegment::debugPtT(int id) const { | 
 |     return this->contour()->debugPtT(id); | 
 | } | 
 |  | 
 | const SkOpSegment* SkOpSegment::debugSegment(int id) const { | 
 |     return this->contour()->debugSegment(id); | 
 | } | 
 |  | 
 | const SkOpSpanBase* SkOpSegment::debugSpan(int id) const { | 
 |     return this->contour()->debugSpan(id); | 
 | } | 
 |  | 
 | void SkOpSegment::dump() const { | 
 |     SkDebugf("%.*s", contour()->debugIndent(), "        "); | 
 |     this->dumpPts(); | 
 |     const SkOpSpanBase* span = &fHead; | 
 |     contour()->indentDump(); | 
 |     do { | 
 |         SkDebugf("%.*s span=%d ", contour()->debugIndent(), "        ", span->debugID()); | 
 |         span->ptT()->dumpBase(); | 
 |         span->dumpBase(); | 
 |         SkDebugf("\n"); | 
 |     } while (!span->final() && (span = span->upCast()->next())); | 
 |     contour()->outdentDump(); | 
 | } | 
 |  | 
 | void SkOpSegment::dumpAll() const { | 
 |     SkDebugf("%.*s", contour()->debugIndent(), "        "); | 
 |     this->dumpPts(); | 
 |     const SkOpSpanBase* span = &fHead; | 
 |     contour()->indentDump(); | 
 |     do { | 
 |         span->dumpAll(); | 
 |     } while (!span->final() && (span = span->upCast()->next())); | 
 |     contour()->outdentDump(); | 
 | } | 
 |  | 
 | void SkOpSegment::dumpAngles() const { | 
 |     SkDebugf("seg=%d\n", debugID()); | 
 |     const SkOpSpanBase* span = &fHead; | 
 |     do { | 
 |         const SkOpAngle* fAngle = span->fromAngle(); | 
 |         const SkOpAngle* tAngle = span->final() ? NULL : span->upCast()->toAngle(); | 
 |         if (fAngle) { | 
 |             SkDebugf("  span=%d from=%d ", span->debugID(), fAngle->debugID()); | 
 |             fAngle->dumpTo(this, tAngle); | 
 |         } | 
 |         if (tAngle) { | 
 |             SkDebugf("  span=%d to=%d   ", span->debugID(), tAngle->debugID()); | 
 |             tAngle->dumpTo(this, fAngle); | 
 |         } | 
 |     } while (!span->final() && (span = span->upCast()->next())); | 
 | } | 
 |  | 
 | void SkOpSegment::dumpCoin() const { | 
 |     const SkOpSpan* span = &fHead; | 
 |     do { | 
 |         span->dumpCoin(); | 
 |     } while ((span = span->next()->upCastable())); | 
 | } | 
 |  | 
 | void SkOpSegment::dumpPtsInner() const { | 
 |     int last = SkPathOpsVerbToPoints(fVerb); | 
 |     SkDebugf("seg=%d {{", 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 { | 
 |     dumpPtsInner(); | 
 |     SkDebugf("\n"); | 
 | } | 
 |  | 
 | void SkCoincidentSpans::dump() const { | 
 |     SkDebugf("- seg=%d span=%d ptT=%d ", fCoinPtTStart->segment()->debugID(), | 
 |         fCoinPtTStart->span()->debugID(), fCoinPtTStart->debugID()); | 
 |     fCoinPtTStart->dumpBase(); | 
 |     SkDebugf(" span=%d ptT=%d ", fCoinPtTEnd->span()->debugID(), fCoinPtTEnd->debugID()); | 
 |     fCoinPtTEnd->dumpBase(); | 
 |     if (fCoinPtTStart->segment()->operand()) { | 
 |         SkDebugf(" operand"); | 
 |     } | 
 |     if (fCoinPtTStart->segment()->isXor()) { | 
 |         SkDebugf(" xor"); | 
 |     } | 
 |     SkDebugf("\n"); | 
 |     SkDebugf("+ seg=%d span=%d ptT=%d ", fOppPtTStart->segment()->debugID(), | 
 |         fOppPtTStart->span()->debugID(), fOppPtTStart->debugID()); | 
 |     fOppPtTStart->dumpBase(); | 
 |     SkDebugf(" span=%d ptT=%d ", fOppPtTEnd->span()->debugID(), fOppPtTEnd->debugID()); | 
 |     fOppPtTEnd->dumpBase(); | 
 |     if (fOppPtTStart->segment()->operand()) { | 
 |         SkDebugf(" operand"); | 
 |     } | 
 |     if (fOppPtTStart->segment()->isXor()) { | 
 |         SkDebugf(" xor"); | 
 |     } | 
 |     SkDebugf("\n"); | 
 | } | 
 |  | 
 | void SkOpCoincidence::dump() const { | 
 |     SkCoincidentSpans* span = fHead; | 
 |     while (span) { | 
 |         span->dump(); | 
 |         span = span->fNext; | 
 |     } | 
 | } | 
 |  | 
 | void SkOpContour::dump() 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 { | 
 |     SkDebugf("contour=%d\n", this->debugID()); | 
 |     const SkOpSegment* segment = &fHead; | 
 |     do { | 
 |         SkDebugf("  seg=%d ", segment->debugID()); | 
 |         segment->dumpPts(); | 
 |     } while ((segment = segment->next())); | 
 | } | 
 |  | 
 | void SkOpContour::dumpPtsX() const { | 
 |     if (!this->fCount) { | 
 |         SkDebugf("<empty>\n"); | 
 |         return; | 
 |     } | 
 |     const SkOpSegment* segment = &fHead; | 
 |     do { | 
 |         segment->dumpPts(); | 
 |     } while ((segment = segment->next())); | 
 | } | 
 |  | 
 | void SkOpContour::dumpSegment(int index) const { | 
 |     debugSegment(index)->dump(); | 
 | } | 
 |  | 
 | void SkOpContour::dumpSegments(SkPathOp op) const { | 
 |     bool firstOp = false; | 
 |     const SkOpContour* c = this; | 
 |     do { | 
 |         if (!firstOp && c->operand()) { | 
 | #if DEBUG_ACTIVE_OP | 
 |             SkDebugf("op %s\n", SkPathOpsDebug::kPathOpStr[op]); | 
 | #endif | 
 |             firstOp = true; | 
 |         } | 
 |         c->dumpPtsX(); | 
 |     } while ((c = c->next())); | 
 | } | 
 |  | 
 | void SkOpContour::dumpSpan(int index) const { | 
 |     debugSpan(index)->dump(); | 
 | } | 
 |  | 
 | void SkOpContour::dumpSpans() const { | 
 |     SkDebugf("contour=%d\n", this->debugID()); | 
 |     const SkOpSegment* segment = &fHead; | 
 |     do { | 
 |         SkDebugf("  seg=%d ", segment->debugID()); | 
 |         segment->dump(); | 
 |     } while ((segment = segment->next())); | 
 | } | 
 |  | 
 | 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 NULL; | 
 | } | 
 |  | 
 | SkOpContour* SkOpGlobalState::debugContour(int id) { | 
 |     SkOpContour* contour = fContourHead; | 
 |     do { | 
 |         if (contour->debugID() == id) { | 
 |             return contour; | 
 |         } | 
 |     } while ((contour = contour->next())); | 
 |     return NULL; | 
 | } | 
 |  | 
 | 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 NULL; | 
 | } | 
 |  | 
 | 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 NULL; | 
 | } | 
 |  | 
 | 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 NULL; | 
 | } | 
 | #endif | 
 |  | 
 | #if DEBUG_T_SECT_DUMP > 1 | 
 | int gDumpTSectNum; | 
 | #endif |