Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2014 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "PathOpsTSectDebug.h"
      9 #include "SkOpCoincidence.h"
     10 #include "SkOpContour.h"
     11 #include "SkIntersectionHelper.h"
     12 #include "SkMutex.h"
     13 #include "SkOpSegment.h"
     14 #include "SkString.h"
     15 
     16 extern bool FLAGS_runFail;
     17 
     18 inline void DebugDumpDouble(double x) {
     19     if (x == floor(x)) {
     20         SkDebugf("%.0f", x);
     21     } else {
     22         SkDebugf("%1.19g", x);
     23     }
     24 }
     25 
     26 inline void DebugDumpFloat(float x) {
     27     if (x == floorf(x)) {
     28         SkDebugf("%.0f", x);
     29     } else {
     30         SkDebugf("%1.9gf", x);
     31     }
     32 }
     33 
     34 inline void DebugDumpHexFloat(float x) {
     35     SkDebugf("SkBits2Float(0x%08x)", SkFloat2Bits(x));
     36 }
     37 
     38 // if not defined by PathOpsDebug.cpp ...
     39 #if !defined SK_DEBUG && FORCE_RELEASE
     40 bool SkPathOpsDebug::ValidWind(int wind) {
     41     return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF;
     42 }
     43 
     44 void SkPathOpsDebug::WindingPrintf(int wind) {
     45     if (wind == SK_MinS32) {
     46         SkDebugf("?");
     47     } else {
     48         SkDebugf("%d", wind);
     49     }
     50 }
     51 #endif
     52 
     53 void SkDConic::dump() const {
     54     dumpInner();
     55     SkDebugf("},\n");
     56 }
     57 
     58 void SkDConic::dumpID(int id) const {
     59     dumpInner();
     60     SkDebugf("} id=%d\n", id);
     61 }
     62 
     63 void SkDConic::dumpInner() const {
     64     SkDebugf("{");
     65     fPts.dumpInner();
     66     SkDebugf("}}, %1.9gf", fWeight);
     67 }
     68 
     69 void SkDCubic::dump() const {
     70     this->dumpInner();
     71     SkDebugf("}},\n");
     72 }
     73 
     74 void SkDCubic::dumpID(int id) const {
     75     this->dumpInner();
     76     SkDebugf("}} id=%d\n", id);
     77 }
     78 
     79 static inline bool double_is_NaN(double x) { return x != x; }
     80 
     81 void SkDCubic::dumpInner() const {
     82     SkDebugf("{{");
     83     int index = 0;
     84     do {
     85         if (index != 0) {
     86             if (double_is_NaN(fPts[index].fX) && double_is_NaN(fPts[index].fY)) {
     87                 return;
     88             }
     89             SkDebugf(", ");
     90         }
     91         fPts[index].dump();
     92     } while (++index < 3);
     93     if (double_is_NaN(fPts[index].fX) && double_is_NaN(fPts[index].fY)) {
     94         return;
     95     }
     96     SkDebugf(", ");
     97     fPts[index].dump();
     98 }
     99 
    100 void SkDCurve::dumpID(int id) const {
    101 #ifndef SK_RELEASE
    102     switch(fVerb) {
    103         case SkPath::kLine_Verb:
    104             fLine.dumpID(id);
    105             break;
    106         case SkPath::kQuad_Verb:
    107             fQuad.dumpID(id);
    108             break;
    109         case SkPath::kConic_Verb:
    110             fConic.dumpID(id);
    111             break;
    112         case SkPath::kCubic_Verb:
    113             fCubic.dumpID(id);
    114             break;
    115         default:
    116             SkASSERT(0);
    117     }
    118 #else
    119     fCubic.dumpID(id);
    120 #endif
    121 }
    122 
    123 void SkDLine::dump() const {
    124     this->dumpInner();
    125     SkDebugf("}},\n");
    126 }
    127 
    128 void SkDLine::dumpID(int id) const {
    129     this->dumpInner();
    130     SkDebugf("}} id=%d\n", id);
    131 }
    132 
    133 void SkDLine::dumpInner() const {
    134     SkDebugf("{{");
    135     fPts[0].dump();
    136     SkDebugf(", ");
    137     fPts[1].dump();
    138 }
    139 
    140 void SkDPoint::dump() const {
    141     SkDebugf("{");
    142     DebugDumpDouble(fX);
    143     SkDebugf(", ");
    144     DebugDumpDouble(fY);
    145     SkDebugf("}");
    146 }
    147 
    148 void SkDPoint::Dump(const SkPoint& pt) {
    149     SkDebugf("{");
    150     DebugDumpFloat(pt.fX);
    151     SkDebugf(", ");
    152     DebugDumpFloat(pt.fY);
    153     SkDebugf("}");
    154 }
    155 
    156 void SkDPoint::DumpHex(const SkPoint& pt) {
    157     SkDebugf("{");
    158     DebugDumpHexFloat(pt.fX);
    159     SkDebugf(", ");
    160     DebugDumpHexFloat(pt.fY);
    161     SkDebugf("}");
    162 }
    163 
    164 void SkDQuad::dump() const {
    165     dumpInner();
    166     SkDebugf("}},\n");
    167 }
    168 
    169 void SkDQuad::dumpID(int id) const {
    170     dumpInner();
    171     SkDebugf("}} id=%d\n", id);
    172 }
    173 
    174 void SkDQuad::dumpInner() const {
    175     SkDebugf("{{");
    176     int index = 0;
    177     do {
    178         fPts[index].dump();
    179         SkDebugf(", ");
    180     } while (++index < 2);
    181     fPts[index].dump();
    182 }
    183 
    184 void SkIntersections::dump() const {
    185     SkDebugf("used=%d of %d", fUsed, fMax);
    186     for (int index = 0; index < fUsed; ++index) {
    187         SkDebugf(" t=(%s%1.9g,%s%1.9g) pt=(%1.9g,%1.9g)",
    188                 fIsCoincident[0] & (1 << index) ? "*" : "", fT[0][index],
    189                 fIsCoincident[1] & (1 << index) ? "*" : "", fT[1][index],
    190                 fPt[index].fX, fPt[index].fY);
    191         if (index < 2 && fNearlySame[index]) {
    192             SkDebugf(" pt2=(%1.9g,%1.9g)",fPt2[index].fX, fPt2[index].fY);
    193         }
    194     }
    195     SkDebugf("\n");
    196 }
    197 
    198 const SkOpAngle* SkPathOpsDebug::DebugAngleAngle(const SkOpAngle* angle, int id) {
    199     return angle->debugAngle(id);
    200 }
    201 
    202 SkOpContour* SkPathOpsDebug::DebugAngleContour(SkOpAngle* angle, int id) {
    203     return angle->debugContour(id);
    204 }
    205 
    206 const SkOpPtT* SkPathOpsDebug::DebugAnglePtT(const SkOpAngle* angle, int id) {
    207     return angle->debugPtT(id);
    208 }
    209 
    210 const SkOpSegment* SkPathOpsDebug::DebugAngleSegment(const SkOpAngle* angle, int id) {
    211     return angle->debugSegment(id);
    212 }
    213 
    214 const SkOpSpanBase* SkPathOpsDebug::DebugAngleSpan(const SkOpAngle* angle, int id) {
    215     return angle->debugSpan(id);
    216 }
    217 
    218 const SkOpAngle* SkPathOpsDebug::DebugContourAngle(SkOpContour* contour, int id) {
    219     return contour->debugAngle(id);
    220 }
    221 
    222 SkOpContour* SkPathOpsDebug::DebugContourContour(SkOpContour* contour, int id) {
    223     return contour->debugContour(id);
    224 }
    225 
    226 const SkOpPtT* SkPathOpsDebug::DebugContourPtT(SkOpContour* contour, int id) {
    227     return contour->debugPtT(id);
    228 }
    229 
    230 const SkOpSegment* SkPathOpsDebug::DebugContourSegment(SkOpContour* contour, int id) {
    231     return contour->debugSegment(id);
    232 }
    233 
    234 const SkOpSpanBase* SkPathOpsDebug::DebugContourSpan(SkOpContour* contour, int id) {
    235     return contour->debugSpan(id);
    236 }
    237 
    238 const SkOpAngle* SkPathOpsDebug::DebugCoincidenceAngle(SkOpCoincidence* coin, int id) {
    239     return coin->debugAngle(id);
    240 }
    241 
    242 SkOpContour* SkPathOpsDebug::DebugCoincidenceContour(SkOpCoincidence* coin, int id) {
    243     return coin->debugContour(id);
    244 }
    245 
    246 const SkOpPtT* SkPathOpsDebug::DebugCoincidencePtT(SkOpCoincidence* coin, int id) {
    247     return coin->debugPtT(id);
    248 }
    249 
    250 const SkOpSegment* SkPathOpsDebug::DebugCoincidenceSegment(SkOpCoincidence* coin, int id) {
    251     return coin->debugSegment(id);
    252 }
    253 
    254 const SkOpSpanBase* SkPathOpsDebug::DebugCoincidenceSpan(SkOpCoincidence* coin, int id) {
    255     return coin->debugSpan(id);
    256 }
    257 
    258 const SkOpAngle* SkPathOpsDebug::DebugPtTAngle(const SkOpPtT* ptT, int id) {
    259     return ptT->debugAngle(id);
    260 }
    261 
    262 SkOpContour* SkPathOpsDebug::DebugPtTContour(SkOpPtT* ptT, int id) {
    263     return ptT->debugContour(id);
    264 }
    265 
    266 const SkOpPtT* SkPathOpsDebug::DebugPtTPtT(const SkOpPtT* ptT, int id) {
    267     return ptT->debugPtT(id);
    268 }
    269 
    270 const SkOpSegment* SkPathOpsDebug::DebugPtTSegment(const SkOpPtT* ptT, int id) {
    271     return ptT->debugSegment(id);
    272 }
    273 
    274 const SkOpSpanBase* SkPathOpsDebug::DebugPtTSpan(const SkOpPtT* ptT, int id) {
    275     return ptT->debugSpan(id);
    276 }
    277 
    278 const SkOpAngle* SkPathOpsDebug::DebugSegmentAngle(const SkOpSegment* span, int id) {
    279     return span->debugAngle(id);
    280 }
    281 
    282 SkOpContour* SkPathOpsDebug::DebugSegmentContour(SkOpSegment* span, int id) {
    283     return span->debugContour(id);
    284 }
    285 
    286 const SkOpPtT* SkPathOpsDebug::DebugSegmentPtT(const SkOpSegment* span, int id) {
    287     return span->debugPtT(id);
    288 }
    289 
    290 const SkOpSegment* SkPathOpsDebug::DebugSegmentSegment(const SkOpSegment* span, int id) {
    291     return span->debugSegment(id);
    292 }
    293 
    294 const SkOpSpanBase* SkPathOpsDebug::DebugSegmentSpan(const SkOpSegment* span, int id) {
    295     return span->debugSpan(id);
    296 }
    297 
    298 const SkOpAngle* SkPathOpsDebug::DebugSpanAngle(const SkOpSpanBase* span, int id) {
    299     return span->debugAngle(id);
    300 }
    301 
    302 SkOpContour* SkPathOpsDebug::DebugSpanContour(SkOpSpanBase* span, int id) {
    303     return span->debugContour(id);
    304 }
    305 
    306 const SkOpPtT* SkPathOpsDebug::DebugSpanPtT(const SkOpSpanBase* span, int id) {
    307     return span->debugPtT(id);
    308 }
    309 
    310 const SkOpSegment* SkPathOpsDebug::DebugSpanSegment(const SkOpSpanBase* span, int id) {
    311     return span->debugSegment(id);
    312 }
    313 
    314 const SkOpSpanBase* SkPathOpsDebug::DebugSpanSpan(const SkOpSpanBase* span, int id) {
    315     return span->debugSpan(id);
    316 }
    317 
    318 void SkOpContour::dumpContours() const {
    319     SkOpContour* contour = this->globalState()->contourHead();
    320     do {
    321         contour->dump();
    322     } while ((contour = contour->next()));
    323 }
    324 
    325 void SkOpContour::dumpContoursAll() const {
    326     SkOpContour* contour = this->globalState()->contourHead();
    327     do {
    328         contour->dumpAll();
    329     } while ((contour = contour->next()));
    330 }
    331 
    332 void SkOpContour::dumpContoursAngles() const {
    333     SkOpContour* contour = this->globalState()->contourHead();
    334     do {
    335         contour->dumpAngles();
    336     } while ((contour = contour->next()));
    337 }
    338 
    339 void SkOpContour::dumpContoursPts() const {
    340     SkOpContour* contour = this->globalState()->contourHead();
    341     do {
    342         contour->dumpPts();
    343     } while ((contour = contour->next()));
    344 }
    345 
    346 void SkOpContour::dumpContoursPt(int segmentID) const {
    347     SkOpContour* contour = this->globalState()->contourHead();
    348     do {
    349         contour->dumpPt(segmentID);
    350     } while ((contour = contour->next()));
    351 }
    352 
    353 void SkOpContour::dumpContoursSegment(int segmentID) const {
    354     SkOpContour* contour = this->globalState()->contourHead();
    355     do {
    356         contour->dumpSegment(segmentID);
    357     } while ((contour = contour->next()));
    358 }
    359 
    360 void SkOpContour::dumpContoursSpan(int spanID) const {
    361     SkOpContour* contour = this->globalState()->contourHead();
    362     do {
    363         contour->dumpSpan(spanID);
    364     } while ((contour = contour->next()));
    365 }
    366 
    367 void SkOpContour::dumpContoursSpans() const {
    368     SkOpContour* contour = this->globalState()->contourHead();
    369     do {
    370         contour->dumpSpans();
    371     } while ((contour = contour->next()));
    372 }
    373 
    374 template <typename TCurve, typename OppCurve>
    375 const SkTSpan<TCurve, OppCurve>* DebugSpan(const SkTSect<TCurve, OppCurve>* sect, int id) {
    376     return sect->debugSpan(id);
    377 }
    378 
    379 void DontCallDebugSpan(int id);
    380 void DontCallDebugSpan(int id) {  // exists to instantiate the templates
    381     SkDQuad quad;
    382     SkDConic conic;
    383     SkDCubic cubic;
    384     SkTSect<SkDQuad, SkDQuad> q1q2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    385     SkTSect<SkDQuad, SkDConic> q1k2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    386     SkTSect<SkDQuad, SkDCubic> q1c2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    387     SkTSect<SkDConic, SkDQuad> k1q2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    388     SkTSect<SkDConic, SkDConic> k1k2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    389     SkTSect<SkDConic, SkDCubic> k1c2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    390     SkTSect<SkDCubic, SkDQuad> c1q2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    391     SkTSect<SkDCubic, SkDConic> c1k2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    392     SkTSect<SkDCubic, SkDCubic> c1c2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    393     DebugSpan(&q1q2, id);
    394     DebugSpan(&q1k2, id);
    395     DebugSpan(&q1c2, id);
    396     DebugSpan(&k1q2, id);
    397     DebugSpan(&k1k2, id);
    398     DebugSpan(&k1c2, id);
    399     DebugSpan(&c1q2, id);
    400     DebugSpan(&c1k2, id);
    401     DebugSpan(&c1c2, id);
    402 }
    403 
    404 template <typename TCurve, typename OppCurve>
    405 const SkTSpan<TCurve, OppCurve>* DebugT(const SkTSect<TCurve, OppCurve>* sect, double t) {
    406     return sect->debugT(t);
    407 }
    408 
    409 void DontCallDebugT(double t);
    410 void DontCallDebugT(double t) {  // exists to instantiate the templates
    411     SkDQuad quad;
    412     SkDConic conic;
    413     SkDCubic cubic;
    414     SkTSect<SkDQuad, SkDQuad> q1q2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    415     SkTSect<SkDQuad, SkDConic> q1k2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    416     SkTSect<SkDQuad, SkDCubic> q1c2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    417     SkTSect<SkDConic, SkDQuad> k1q2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    418     SkTSect<SkDConic, SkDConic> k1k2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    419     SkTSect<SkDConic, SkDCubic> k1c2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    420     SkTSect<SkDCubic, SkDQuad> c1q2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    421     SkTSect<SkDCubic, SkDConic> c1k2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    422     SkTSect<SkDCubic, SkDCubic> c1c2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    423     DebugT(&q1q2, t);
    424     DebugT(&q1k2, t);
    425     DebugT(&q1c2, t);
    426     DebugT(&k1q2, t);
    427     DebugT(&k1k2, t);
    428     DebugT(&k1c2, t);
    429     DebugT(&c1q2, t);
    430     DebugT(&c1k2, t);
    431     DebugT(&c1c2, t);
    432 }
    433 
    434 template <typename TCurve, typename OppCurve>
    435 void Dump(const SkTSect<TCurve, OppCurve>* sect) {
    436     sect->dump();
    437 }
    438 
    439 void DontCallDumpTSect();
    440 void DontCallDumpTSect() {  // exists to instantiate the templates
    441     SkDQuad quad;
    442     SkDConic conic;
    443     SkDCubic cubic;
    444     SkTSect<SkDQuad, SkDQuad> q1q2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    445     SkTSect<SkDQuad, SkDConic> q1k2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    446     SkTSect<SkDQuad, SkDCubic> q1c2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    447     SkTSect<SkDConic, SkDQuad> k1q2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    448     SkTSect<SkDConic, SkDConic> k1k2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    449     SkTSect<SkDConic, SkDCubic> k1c2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    450     SkTSect<SkDCubic, SkDQuad> c1q2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    451     SkTSect<SkDCubic, SkDConic> c1k2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    452     SkTSect<SkDCubic, SkDCubic> c1c2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    453     Dump(&q1q2);
    454     Dump(&q1k2);
    455     Dump(&q1c2);
    456     Dump(&k1q2);
    457     Dump(&k1k2);
    458     Dump(&k1c2);
    459     Dump(&c1q2);
    460     Dump(&c1k2);
    461     Dump(&c1c2);
    462 }
    463 
    464 template <typename TCurve, typename OppCurve>
    465 void DumpBoth(SkTSect<TCurve, OppCurve>* sect1, SkTSect<OppCurve, TCurve>* sect2) {
    466     sect1->dumpBoth(sect2);
    467 }
    468 
    469 void DontCallDumpBoth();
    470 void DontCallDumpBoth() {  // exists to instantiate the templates
    471     SkDQuad quad;
    472     SkDConic conic;
    473     SkDCubic cubic;
    474     SkTSect<SkDQuad, SkDQuad> q1q2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    475     SkTSect<SkDQuad, SkDConic> q1k2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    476     SkTSect<SkDQuad, SkDCubic> q1c2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    477     SkTSect<SkDConic, SkDQuad> k1q2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    478     SkTSect<SkDConic, SkDConic> k1k2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    479     SkTSect<SkDConic, SkDCubic> k1c2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    480     SkTSect<SkDCubic, SkDQuad> c1q2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    481     SkTSect<SkDCubic, SkDConic> c1k2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    482     SkTSect<SkDCubic, SkDCubic> c1c2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    483     DumpBoth(&q1q2, &q1q2);
    484     DumpBoth(&q1k2, &k1q2);
    485     DumpBoth(&q1c2, &c1q2);
    486     DumpBoth(&k1q2, &q1k2);
    487     DumpBoth(&k1k2, &k1k2);
    488     DumpBoth(&k1c2, &c1k2);
    489     DumpBoth(&c1q2, &q1c2);
    490     DumpBoth(&c1k2, &k1c2);
    491     DumpBoth(&c1c2, &c1c2);
    492 }
    493 
    494 template <typename TCurve, typename OppCurve>
    495 void DumpBounded(SkTSect<TCurve, OppCurve>* sect1, int id) {
    496     sect1->dumpBounded(id);
    497 }
    498 
    499 void DontCallDumpBounded();
    500 void DontCallDumpBounded() {
    501     SkDQuad quad;
    502     SkDConic conic;
    503     SkDCubic cubic;
    504     SkTSect<SkDQuad, SkDQuad> q1q2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    505     SkTSect<SkDQuad, SkDConic> q1k2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    506     SkTSect<SkDQuad, SkDCubic> q1c2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    507     SkTSect<SkDConic, SkDQuad> k1q2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    508     SkTSect<SkDConic, SkDConic> k1k2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    509     SkTSect<SkDConic, SkDCubic> k1c2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    510     SkTSect<SkDCubic, SkDQuad> c1q2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    511     SkTSect<SkDCubic, SkDConic> c1k2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    512     SkTSect<SkDCubic, SkDCubic> c1c2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    513     DumpBounded(&q1q2, 0);
    514     DumpBounded(&q1k2, 0);
    515     DumpBounded(&q1c2, 0);
    516     DumpBounded(&k1q2, 0);
    517     DumpBounded(&k1k2, 0);
    518     DumpBounded(&k1c2, 0);
    519     DumpBounded(&c1q2, 0);
    520     DumpBounded(&c1k2, 0);
    521     DumpBounded(&c1c2, 0);
    522 }
    523 
    524 template <typename TCurve, typename OppCurve>
    525 void DumpBounds(SkTSect<TCurve, OppCurve>* sect1) {
    526     sect1->dumpBounds();
    527 }
    528 
    529 void DontCallDumpBounds();
    530 void DontCallDumpBounds() {
    531     SkDQuad quad;
    532     SkDConic conic;
    533     SkDCubic cubic;
    534     SkTSect<SkDQuad, SkDQuad> q1q2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    535     SkTSect<SkDQuad, SkDConic> q1k2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    536     SkTSect<SkDQuad, SkDCubic> q1c2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    537     SkTSect<SkDConic, SkDQuad> k1q2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    538     SkTSect<SkDConic, SkDConic> k1k2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    539     SkTSect<SkDConic, SkDCubic> k1c2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    540     SkTSect<SkDCubic, SkDQuad> c1q2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    541     SkTSect<SkDCubic, SkDConic> c1k2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    542     SkTSect<SkDCubic, SkDCubic> c1c2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    543     DumpBounds(&q1q2);
    544     DumpBounds(&q1k2);
    545     DumpBounds(&q1c2);
    546     DumpBounds(&k1q2);
    547     DumpBounds(&k1k2);
    548     DumpBounds(&k1c2);
    549     DumpBounds(&c1q2);
    550     DumpBounds(&c1k2);
    551     DumpBounds(&c1c2);
    552 }
    553 
    554 template <typename TCurve, typename OppCurve>
    555 void DumpCoin(SkTSect<TCurve, OppCurve>* sect1) {
    556     sect1->dumpCoin();
    557 }
    558 
    559 void DontCallDumpCoin();
    560 void DontCallDumpCoin() {  // exists to instantiate the templates
    561     SkDQuad quad;
    562     SkDConic conic;
    563     SkDCubic cubic;
    564     SkTSect<SkDQuad, SkDQuad> q1q2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    565     SkTSect<SkDQuad, SkDConic> q1k2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    566     SkTSect<SkDQuad, SkDCubic> q1c2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    567     SkTSect<SkDConic, SkDQuad> k1q2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    568     SkTSect<SkDConic, SkDConic> k1k2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    569     SkTSect<SkDConic, SkDCubic> k1c2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    570     SkTSect<SkDCubic, SkDQuad> c1q2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    571     SkTSect<SkDCubic, SkDConic> c1k2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    572     SkTSect<SkDCubic, SkDCubic> c1c2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    573     DumpCoin(&q1q2);
    574     DumpCoin(&q1k2);
    575     DumpCoin(&q1c2);
    576     DumpCoin(&k1q2);
    577     DumpCoin(&k1k2);
    578     DumpCoin(&k1c2);
    579     DumpCoin(&c1q2);
    580     DumpCoin(&c1k2);
    581     DumpCoin(&c1c2);
    582 }
    583 
    584 template <typename TCurve, typename OppCurve>
    585 void DumpCoinCurves(SkTSect<TCurve, OppCurve>* sect1) {
    586     sect1->dumpCoinCurves();
    587 }
    588 
    589 void DontCallDumpCoinCurves();
    590 void DontCallDumpCoinCurves() {  // exists to instantiate the templates
    591     SkDQuad quad;
    592     SkDConic conic;
    593     SkDCubic cubic;
    594     SkTSect<SkDQuad, SkDQuad> q1q2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    595     SkTSect<SkDQuad, SkDConic> q1k2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    596     SkTSect<SkDQuad, SkDCubic> q1c2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    597     SkTSect<SkDConic, SkDQuad> k1q2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    598     SkTSect<SkDConic, SkDConic> k1k2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    599     SkTSect<SkDConic, SkDCubic> k1c2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    600     SkTSect<SkDCubic, SkDQuad> c1q2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    601     SkTSect<SkDCubic, SkDConic> c1k2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    602     SkTSect<SkDCubic, SkDCubic> c1c2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    603     DumpCoinCurves(&q1q2);
    604     DumpCoinCurves(&q1k2);
    605     DumpCoinCurves(&q1c2);
    606     DumpCoinCurves(&k1q2);
    607     DumpCoinCurves(&k1k2);
    608     DumpCoinCurves(&k1c2);
    609     DumpCoinCurves(&c1q2);
    610     DumpCoinCurves(&c1k2);
    611     DumpCoinCurves(&c1c2);
    612 }
    613 
    614 template <typename TCurve, typename OppCurve>
    615 void DumpCurves(const SkTSect<TCurve, OppCurve>* sect) {
    616     sect->dumpCurves();
    617 }
    618 
    619 void DontCallDumpCurves();
    620 void DontCallDumpCurves() {  // exists to instantiate the templates
    621     SkDQuad quad;
    622     SkDConic conic;
    623     SkDCubic cubic;
    624     SkTSect<SkDQuad, SkDQuad> q1q2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    625     SkTSect<SkDQuad, SkDConic> q1k2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    626     SkTSect<SkDQuad, SkDCubic> q1c2(quad PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    627     SkTSect<SkDConic, SkDQuad> k1q2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    628     SkTSect<SkDConic, SkDConic> k1k2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    629     SkTSect<SkDConic, SkDCubic> k1c2(conic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    630     SkTSect<SkDCubic, SkDQuad> c1q2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    631     SkTSect<SkDCubic, SkDConic> c1k2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    632     SkTSect<SkDCubic, SkDCubic> c1c2(cubic PATH_OPS_DEBUG_T_SECT_PARAMS(1));
    633     DumpCurves(&q1q2);
    634     DumpCurves(&q1k2);
    635     DumpCurves(&q1c2);
    636     DumpCurves(&k1q2);
    637     DumpCurves(&k1k2);
    638     DumpCurves(&k1c2);
    639     DumpCurves(&c1q2);
    640     DumpCurves(&c1k2);
    641     DumpCurves(&c1c2);
    642 }
    643 
    644 template <typename TCurve, typename OppCurve>
    645 void Dump(const SkTSpan<TCurve, OppCurve>* span) {
    646     span->dump();
    647 }
    648 
    649 void DontCallDumpTSpan();
    650 void DontCallDumpTSpan() {  // exists to instantiate the templates
    651     SkTSpan<SkDQuad, SkDQuad> q1q2; q1q2.debugInit();
    652     SkTSpan<SkDQuad, SkDConic> q1k2; q1k2.debugInit();
    653     SkTSpan<SkDQuad, SkDCubic> q1c2; q1c2.debugInit();
    654     SkTSpan<SkDConic, SkDQuad> k1q2; k1q2.debugInit();
    655     SkTSpan<SkDConic, SkDConic> k1k2; k1k2.debugInit();
    656     SkTSpan<SkDConic, SkDCubic> k1c2; k1c2.debugInit();
    657     SkTSpan<SkDCubic, SkDQuad> c1q2; c1q2.debugInit();
    658     SkTSpan<SkDCubic, SkDConic> c1k2; c1k2.debugInit();
    659     SkTSpan<SkDCubic, SkDCubic> c1c2; c1c2.debugInit();
    660     Dump(&q1q2);
    661     Dump(&q1k2);
    662     Dump(&q1c2);
    663     Dump(&k1q2);
    664     Dump(&k1k2);
    665     Dump(&k1c2);
    666     Dump(&c1q2);
    667     Dump(&c1k2);
    668     Dump(&c1c2);
    669 }
    670 
    671 template <typename TCurve, typename OppCurve>
    672 void DumpAll(const SkTSpan<TCurve, OppCurve>* span) {
    673     span->dumpAll();
    674 }
    675 
    676 void DontCallDumpSpanAll();
    677 void DontCallDumpSpanAll() {  // exists to instantiate the templates
    678     SkTSpan<SkDQuad, SkDQuad> q1q2; q1q2.debugInit();
    679     SkTSpan<SkDQuad, SkDConic> q1k2; q1k2.debugInit();
    680     SkTSpan<SkDQuad, SkDCubic> q1c2; q1c2.debugInit();
    681     SkTSpan<SkDConic, SkDQuad> k1q2; k1q2.debugInit();
    682     SkTSpan<SkDConic, SkDConic> k1k2; k1k2.debugInit();
    683     SkTSpan<SkDConic, SkDCubic> k1c2; k1c2.debugInit();
    684     SkTSpan<SkDCubic, SkDQuad> c1q2; c1q2.debugInit();
    685     SkTSpan<SkDCubic, SkDConic> c1k2; c1k2.debugInit();
    686     SkTSpan<SkDCubic, SkDCubic> c1c2; c1c2.debugInit();
    687     DumpAll(&q1q2);
    688     DumpAll(&q1k2);
    689     DumpAll(&q1c2);
    690     DumpAll(&k1q2);
    691     DumpAll(&k1k2);
    692     DumpAll(&k1c2);
    693     DumpAll(&c1q2);
    694     DumpAll(&c1k2);
    695     DumpAll(&c1c2);
    696 }
    697 
    698 template <typename TCurve, typename OppCurve>
    699 void DumpBounded(const SkTSpan<TCurve, OppCurve>* span) {
    700     span->dumpBounded(0);
    701 }
    702 
    703 void DontCallDumpSpanBounded();
    704 void DontCallDumpSpanBounded() {  // exists to instantiate the templates
    705     SkTSpan<SkDQuad, SkDQuad> q1q2; q1q2.debugInit();
    706     SkTSpan<SkDQuad, SkDConic> q1k2; q1k2.debugInit();
    707     SkTSpan<SkDQuad, SkDCubic> q1c2; q1c2.debugInit();
    708     SkTSpan<SkDConic, SkDQuad> k1q2; k1q2.debugInit();
    709     SkTSpan<SkDConic, SkDConic> k1k2; k1k2.debugInit();
    710     SkTSpan<SkDConic, SkDCubic> k1c2; k1c2.debugInit();
    711     SkTSpan<SkDCubic, SkDQuad> c1q2; c1q2.debugInit();
    712     SkTSpan<SkDCubic, SkDConic> c1k2; c1k2.debugInit();
    713     SkTSpan<SkDCubic, SkDCubic> c1c2; c1c2.debugInit();
    714     DumpBounded(&q1q2);
    715     DumpBounded(&q1k2);
    716     DumpBounded(&q1c2);
    717     DumpBounded(&k1q2);
    718     DumpBounded(&k1k2);
    719     DumpBounded(&k1c2);
    720     DumpBounded(&c1q2);
    721     DumpBounded(&c1k2);
    722     DumpBounded(&c1c2);
    723 }
    724 
    725 template <typename TCurve, typename OppCurve>
    726 void DumpCoin(const SkTSpan<TCurve, OppCurve>* span) {
    727     span->dumpCoin();
    728 }
    729 
    730 void DontCallDumpSpanCoin();
    731 void DontCallDumpSpanCoin() {  // exists to instantiate the templates
    732     SkTSpan<SkDQuad, SkDQuad> q1q2; q1q2.debugInit();
    733     SkTSpan<SkDQuad, SkDConic> q1k2; q1k2.debugInit();
    734     SkTSpan<SkDQuad, SkDCubic> q1c2; q1c2.debugInit();
    735     SkTSpan<SkDConic, SkDQuad> k1q2; k1q2.debugInit();
    736     SkTSpan<SkDConic, SkDConic> k1k2; k1k2.debugInit();
    737     SkTSpan<SkDConic, SkDCubic> k1c2; k1c2.debugInit();
    738     SkTSpan<SkDCubic, SkDQuad> c1q2; c1q2.debugInit();
    739     SkTSpan<SkDCubic, SkDConic> c1k2; c1k2.debugInit();
    740     SkTSpan<SkDCubic, SkDCubic> c1c2; c1c2.debugInit();
    741     DumpCoin(&q1q2);
    742     DumpCoin(&q1k2);
    743     DumpCoin(&q1c2);
    744     DumpCoin(&k1q2);
    745     DumpCoin(&k1k2);
    746     DumpCoin(&k1c2);
    747     DumpCoin(&c1q2);
    748     DumpCoin(&c1k2);
    749     DumpCoin(&c1c2);
    750 }
    751 
    752 static void dumpTestCase(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) {
    753     SkDebugf("\n<div id=\"quad%d\">\n", testNo);
    754     quad1.dumpInner();
    755     SkDebugf("}}, ");
    756     quad2.dump();
    757     SkDebugf("</div>\n\n");
    758 }
    759 
    760 static void dumpTestTrailer() {
    761     SkDebugf("</div>\n\n<script type=\"text/javascript\">\n\n");
    762     SkDebugf("    var testDivs = [\n");
    763 }
    764 
    765 static void dumpTestList(int testNo, double min) {
    766     SkDebugf("        quad%d,", testNo);
    767     if (min > 0) {
    768         SkDebugf("  // %1.9g", min);
    769     }
    770     SkDebugf("\n");
    771 }
    772 
    773 void DumpQ(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) {
    774     SkDebugf("\n");
    775     dumpTestCase(quad1, quad2, testNo);
    776     dumpTestTrailer();
    777     dumpTestList(testNo, 0);
    778     SkDebugf("\n");
    779 }
    780 
    781 void DumpT(const SkDQuad& quad, double t) {
    782     SkDLine line = {{quad.ptAtT(t), quad[0]}};
    783     line.dump();
    784 }
    785 
    786 const SkOpAngle* SkOpAngle::debugAngle(int id) const {
    787     return this->segment()->debugAngle(id);
    788 }
    789 
    790 SkOpContour* SkOpAngle::debugContour(int id) {
    791     return this->segment()->debugContour(id);
    792 }
    793 
    794 const SkOpPtT* SkOpAngle::debugPtT(int id) const {
    795     return this->segment()->debugPtT(id);
    796 }
    797 
    798 const SkOpSegment* SkOpAngle::debugSegment(int id) const {
    799     return this->segment()->debugSegment(id);
    800 }
    801 
    802 int SkOpAngle::debugSign() const {
    803     SkASSERT(fStart->t() != fEnd->t());
    804     return fStart->t() < fEnd->t() ? -1 : 1;
    805 }
    806 
    807 const SkOpSpanBase* SkOpAngle::debugSpan(int id) const {
    808     return this->segment()->debugSpan(id);
    809 }
    810 
    811 void SkOpAngle::dump() const {
    812     dumpOne(true);
    813     SkDebugf("\n");
    814 }
    815 
    816 void SkOpAngle::dumpOne(bool functionHeader) const {
    817 //    fSegment->debugValidate();
    818     const SkOpSegment* segment = this->segment();
    819     const SkOpSpan& mSpan = *fStart->starter(fEnd);
    820     if (functionHeader) {
    821         SkDebugf("%s ", __FUNCTION__);
    822     }
    823     SkDebugf("[%d", segment->debugID());
    824     SkDebugf("/%d", debugID());
    825     SkDebugf("] next=");
    826     if (fNext) {
    827         SkDebugf("%d", fNext->fStart->segment()->debugID());
    828         SkDebugf("/%d", fNext->debugID());
    829     } else {
    830         SkDebugf("?");
    831     }
    832     SkDebugf(" sect=%d/%d ", fSectorStart, fSectorEnd);
    833     SkDebugf(" s=%1.9g [%d] e=%1.9g [%d]", fStart->t(), fStart->debugID(),
    834                 fEnd->t(), fEnd->debugID());
    835     SkDebugf(" sgn=%d windVal=%d", this->debugSign(), mSpan.windValue());
    836 
    837     SkDebugf(" windSum=");
    838     SkPathOpsDebug::WindingPrintf(mSpan.windSum());
    839     if (mSpan.oppValue() != 0 || mSpan.oppSum() != SK_MinS32) {
    840         SkDebugf(" oppVal=%d", mSpan.oppValue());
    841         SkDebugf(" oppSum=");
    842         SkPathOpsDebug::WindingPrintf(mSpan.oppSum());
    843     }
    844     if (mSpan.done()) {
    845         SkDebugf(" done");
    846     }
    847     if (unorderable()) {
    848         SkDebugf(" unorderable");
    849     }
    850     if (segment->operand()) {
    851         SkDebugf(" operand");
    852     }
    853 }
    854 
    855 void SkOpAngle::dumpTo(const SkOpSegment* segment, const SkOpAngle* to) const {
    856     const SkOpAngle* first = this;
    857     const SkOpAngle* next = this;
    858     const char* indent = "";
    859     do {
    860         SkDebugf("%s", indent);
    861         next->dumpOne(false);
    862         if (segment == next->fStart->segment()) {
    863             if (this == fNext) {
    864                 SkDebugf(" << from");
    865             }
    866             if (to == fNext) {
    867                 SkDebugf(" << to");
    868             }
    869         }
    870         SkDebugf("\n");
    871         indent = "           ";
    872         next = next->fNext;
    873     } while (next && next != first);
    874 }
    875 
    876 void SkOpAngle::dumpCurves() const {
    877     const SkOpAngle* first = this;
    878     const SkOpAngle* next = this;
    879     do {
    880         next->fCurvePart.dumpID(next->segment()->debugID());
    881         next = next->fNext;
    882     } while (next && next != first);
    883 }
    884 
    885 void SkOpAngle::dumpLoop() const {
    886     const SkOpAngle* first = this;
    887     const SkOpAngle* next = this;
    888     do {
    889         next->dumpOne(false);
    890         SkDebugf("\n");
    891         next = next->fNext;
    892     } while (next && next != first);
    893 }
    894 
    895 void SkOpAngle::dumpTest() const {
    896     const SkOpAngle* first = this;
    897     const SkOpAngle* next = this;
    898     do {
    899         SkDebugf("{ ");
    900         SkOpSegment* segment = next->segment();
    901         segment->dumpPts();
    902         SkDebugf(", %d, %1.9g, %1.9g, {} },\n", SkPathOpsVerbToPoints(segment->verb()) + 1,
    903                 next->start()->t(), next->end()->t());
    904         next = next->fNext;
    905     } while (next && next != first);
    906 }
    907 
    908 bool SkOpPtT::debugMatchID(int id) const {
    909     int limit = this->debugLoopLimit(false);
    910     int loop = 0;
    911     const SkOpPtT* ptT = this;
    912     do {
    913         if (ptT->debugID() == id) {
    914             return true;
    915         }
    916     } while ((!limit || ++loop <= limit) && (ptT = ptT->next()) && ptT != this);
    917     return false;
    918 }
    919 
    920 const SkOpAngle* SkOpPtT::debugAngle(int id) const {
    921     return this->span()->debugAngle(id);
    922 }
    923 
    924 SkOpContour* SkOpPtT::debugContour(int id) {
    925     return this->span()->debugContour(id);
    926 }
    927 
    928 const SkOpPtT* SkOpPtT::debugPtT(int id) const {
    929     return this->span()->debugPtT(id);
    930 }
    931 
    932 const SkOpSegment* SkOpPtT::debugSegment(int id) const {
    933     return this->span()->debugSegment(id);
    934 }
    935 
    936 const SkOpSpanBase* SkOpPtT::debugSpan(int id) const {
    937     return this->span()->debugSpan(id);
    938 }
    939 
    940 void SkOpPtT::dump() const {
    941     SkDebugf("seg=%d span=%d ptT=%d",
    942             this->segment()->debugID(), this->span()->debugID(), this->debugID());
    943     this->dumpBase();
    944     SkDebugf("\n");
    945 }
    946 
    947 void SkOpPtT::dumpAll() const {
    948     contour()->indentDump();
    949     const SkOpPtT* next = this;
    950     int limit = debugLoopLimit(true);
    951     int loop = 0;
    952     do {
    953         SkDebugf("%.*s", contour()->debugIndent(), "        ");
    954         SkDebugf("seg=%d span=%d ptT=%d",
    955                 next->segment()->debugID(), next->span()->debugID(), next->debugID());
    956         next->dumpBase();
    957         SkDebugf("\n");
    958         if (limit && ++loop >= limit) {
    959             SkDebugf("*** abort loop ***\n");
    960             break;
    961         }
    962     } while ((next = next->fNext) && next != this);
    963     contour()->outdentDump();
    964 }
    965 
    966 void SkOpPtT::dumpBase() const {
    967     SkDebugf(" t=%1.9g pt=(%1.9g,%1.9g)%s%s", this->fT, this->fPt.fX, this->fPt.fY,
    968             this->fDuplicatePt ? " dup" : "", this->fDeleted ? " deleted" : "");
    969 }
    970 
    971 const SkOpAngle* SkOpSpanBase::debugAngle(int id) const {
    972     return this->segment()->debugAngle(id);
    973 }
    974 
    975 SkOpContour* SkOpSpanBase::debugContour(int id) {
    976     return this->segment()->debugContour(id);
    977 }
    978 
    979 const SkOpPtT* SkOpSpanBase::debugPtT(int id) const {
    980     return this->segment()->debugPtT(id);
    981 }
    982 
    983 const SkOpSegment* SkOpSpanBase::debugSegment(int id) const {
    984     return this->segment()->debugSegment(id);
    985 }
    986 
    987 const SkOpSpanBase* SkOpSpanBase::debugSpan(int id) const {
    988     return this->segment()->debugSpan(id);
    989 }
    990 
    991 void SkOpSpanBase::dump() const {
    992     this->dumpAll();
    993     SkDebugf("\n");
    994 }
    995 
    996 void SkOpSpanBase::dumpAll() const {
    997     SkDebugf("%.*s", contour()->debugIndent(), "        ");
    998     SkDebugf("seg=%d span=%d", this->segment()->debugID(), this->debugID());
    999     this->dumpBase();
   1000     SkDebugf("\n");
   1001     this->fPtT.dumpAll();
   1002 }
   1003 
   1004 void SkOpSpanBase::dumpBase() const {
   1005     if (this->fAligned) {
   1006         SkDebugf(" aligned");
   1007     }
   1008     if (this->fChased) {
   1009         SkDebugf(" chased");
   1010     }
   1011     if (!this->final()) {
   1012         this->upCast()->dumpSpan();
   1013     }
   1014     const SkOpSpanBase* coin = this->coinEnd();
   1015     if (this != coin) {
   1016         SkDebugf(" coinEnd seg/span=%d/%d", coin->segment()->debugID(), coin->debugID());
   1017     } else if (this->final() || !this->upCast()->isCoincident()) {
   1018         const SkOpPtT* oPt = this->ptT()->next();
   1019         SkDebugf(" seg/span=%d/%d", oPt->segment()->debugID(), oPt->span()->debugID());
   1020     }
   1021     SkDebugf(" adds=%d", fSpanAdds);
   1022 }
   1023 
   1024 void SkOpSpanBase::dumpCoin() const {
   1025     const SkOpSpan* span = this->upCastable();
   1026     if (!span) {
   1027         return;
   1028     }
   1029     if (!span->isCoincident()) {
   1030         return;
   1031     }
   1032     span->dumpCoin();
   1033 }
   1034 
   1035 void SkOpSpan::dumpCoin() const {
   1036     const SkOpSpan* coincident = fCoincident;
   1037     bool ok = debugCoinLoopCheck();
   1038     this->dump();
   1039     int loop = 0;
   1040     do {
   1041         coincident->dump();
   1042         if (!ok && ++loop > 10) {
   1043             SkDebugf("*** abort loop ***\n");
   1044             break;
   1045         }
   1046     } while ((coincident = coincident->fCoincident) != this);
   1047 }
   1048 
   1049 bool SkOpSpan::dumpSpan() const {
   1050     SkOpSpan* coin = fCoincident;
   1051     if (this != coin) {
   1052         SkDebugf(" coinStart seg/span=%d/%d", coin->segment()->debugID(), coin->debugID());
   1053     }
   1054     SkDebugf(" windVal=%d", this->windValue());
   1055     SkDebugf(" windSum=");
   1056     SkPathOpsDebug::WindingPrintf(this->windSum());
   1057     if (this->oppValue() != 0 || this->oppSum() != SK_MinS32) {
   1058         SkDebugf(" oppVal=%d", this->oppValue());
   1059         SkDebugf(" oppSum=");
   1060         SkPathOpsDebug::WindingPrintf(this->oppSum());
   1061     }
   1062     if (this->done()) {
   1063         SkDebugf(" done");
   1064     }
   1065     return this != coin;
   1066 }
   1067 
   1068 const SkOpAngle* SkOpSegment::debugAngle(int id) const {
   1069     return this->contour()->debugAngle(id);
   1070 }
   1071 
   1072 SkOpContour* SkOpSegment::debugContour(int id) {
   1073     return this->contour()->debugContour(id);
   1074 }
   1075 
   1076 const SkOpPtT* SkOpSegment::debugPtT(int id) const {
   1077     return this->contour()->debugPtT(id);
   1078 }
   1079 
   1080 const SkOpSegment* SkOpSegment::debugSegment(int id) const {
   1081     return this->contour()->debugSegment(id);
   1082 }
   1083 
   1084 const SkOpSpanBase* SkOpSegment::debugSpan(int id) const {
   1085     return this->contour()->debugSpan(id);
   1086 }
   1087 
   1088 void SkOpSegment::dump() const {
   1089     SkDebugf("%.*s", contour()->debugIndent(), "        ");
   1090     this->dumpPts();
   1091     const SkOpSpanBase* span = &fHead;
   1092     contour()->indentDump();
   1093     do {
   1094         SkDebugf("%.*s span=%d ", contour()->debugIndent(), "        ", span->debugID());
   1095         span->ptT()->dumpBase();
   1096         span->dumpBase();
   1097         SkDebugf("\n");
   1098     } while (!span->final() && (span = span->upCast()->next()));
   1099     contour()->outdentDump();
   1100 }
   1101 
   1102 void SkOpSegment::dumpAll() const {
   1103     SkDebugf("%.*s", contour()->debugIndent(), "        ");
   1104     this->dumpPts();
   1105     const SkOpSpanBase* span = &fHead;
   1106     contour()->indentDump();
   1107     do {
   1108         span->dumpAll();
   1109     } while (!span->final() && (span = span->upCast()->next()));
   1110     contour()->outdentDump();
   1111 }
   1112 
   1113 void SkOpSegment::dumpAngles() const {
   1114     SkDebugf("seg=%d\n", debugID());
   1115     const SkOpSpanBase* span = &fHead;
   1116     do {
   1117         const SkOpAngle* fAngle = span->fromAngle();
   1118         const SkOpAngle* tAngle = span->final() ? nullptr : span->upCast()->toAngle();
   1119         if (fAngle) {
   1120             SkDebugf("  span=%d from=%d ", span->debugID(), fAngle->debugID());
   1121             fAngle->dumpTo(this, tAngle);
   1122         }
   1123         if (tAngle) {
   1124             SkDebugf("  span=%d to=%d   ", span->debugID(), tAngle->debugID());
   1125             tAngle->dumpTo(this, fAngle);
   1126         }
   1127     } while (!span->final() && (span = span->upCast()->next()));
   1128 }
   1129 
   1130 void SkOpSegment::dumpCoin() const {
   1131     const SkOpSpan* span = &fHead;
   1132     do {
   1133         span->dumpCoin();
   1134     } while ((span = span->next()->upCastable()));
   1135 }
   1136 
   1137 void SkOpSegment::dumpPtsInner(const char* prefix) const {
   1138     int last = SkPathOpsVerbToPoints(fVerb);
   1139     SkDebugf("%s=%d {{", prefix, this->debugID());
   1140     if (fVerb == SkPath::kConic_Verb) {
   1141         SkDebugf("{");
   1142     }
   1143     int index = 0;
   1144     do {
   1145         SkDPoint::Dump(fPts[index]);
   1146         SkDebugf(", ");
   1147     } while (++index < last);
   1148     SkDPoint::Dump(fPts[index]);
   1149     SkDebugf("}}");
   1150     if (fVerb == SkPath::kConic_Verb) {
   1151         SkDebugf(", %1.9gf}", fWeight);
   1152     }
   1153 }
   1154 
   1155 void SkOpSegment::dumpPts(const char* prefix) const {
   1156     dumpPtsInner(prefix);
   1157     SkDebugf("\n");
   1158 }
   1159 
   1160 void SkCoincidentSpans::dump() const {
   1161     SkDebugf("- seg=%d span=%d ptT=%d ", fCoinPtTStart->segment()->debugID(),
   1162         fCoinPtTStart->span()->debugID(), fCoinPtTStart->debugID());
   1163     fCoinPtTStart->dumpBase();
   1164     SkDebugf(" span=%d ptT=%d ", fCoinPtTEnd->span()->debugID(), fCoinPtTEnd->debugID());
   1165     fCoinPtTEnd->dumpBase();
   1166     if (fCoinPtTStart->segment()->operand()) {
   1167         SkDebugf(" operand");
   1168     }
   1169     if (fCoinPtTStart->segment()->isXor()) {
   1170         SkDebugf(" xor");
   1171     }
   1172     SkDebugf("\n");
   1173     SkDebugf("+ seg=%d span=%d ptT=%d ", fOppPtTStart->segment()->debugID(),
   1174         fOppPtTStart->span()->debugID(), fOppPtTStart->debugID());
   1175     fOppPtTStart->dumpBase();
   1176     SkDebugf(" span=%d ptT=%d ", fOppPtTEnd->span()->debugID(), fOppPtTEnd->debugID());
   1177     fOppPtTEnd->dumpBase();
   1178     if (fOppPtTStart->segment()->operand()) {
   1179         SkDebugf(" operand");
   1180     }
   1181     if (fOppPtTStart->segment()->isXor()) {
   1182         SkDebugf(" xor");
   1183     }
   1184     SkDebugf("\n");
   1185 }
   1186 
   1187 void SkOpCoincidence::dump() const {
   1188     SkCoincidentSpans* span = fHead;
   1189     while (span) {
   1190         span->dump();
   1191         span = span->fNext;
   1192     }
   1193     if (!fTop || fHead == fTop) {
   1194         return;
   1195     }
   1196     SkDebugf("top:\n");
   1197     span = fTop;
   1198     if (fHead) {
   1199         span->dump();
   1200         return;
   1201     }
   1202     while (span) {
   1203         span->dump();
   1204         span = span->fNext;
   1205     }
   1206 }
   1207 
   1208 void SkOpContour::dump() const {
   1209     SkDebugf("contour=%d count=%d op=%d xor=%d\n", this->debugID(), fCount, fOperand, fXor);
   1210     if (!fCount) {
   1211         return;
   1212     }
   1213     const SkOpSegment* segment = &fHead;
   1214     SkDEBUGCODE(fDebugIndent = 0);
   1215     this->indentDump();
   1216     do {
   1217         segment->dump();
   1218     } while ((segment = segment->next()));
   1219     this->outdentDump();
   1220 }
   1221 
   1222 void SkOpContour::dumpAll() const {
   1223     SkDebugf("contour=%d count=%d op=%d xor=%d\n", this->debugID(), fCount, fOperand, fXor);
   1224     if (!fCount) {
   1225         return;
   1226     }
   1227     const SkOpSegment* segment = &fHead;
   1228     SkDEBUGCODE(fDebugIndent = 0);
   1229     this->indentDump();
   1230     do {
   1231         segment->dumpAll();
   1232     } while ((segment = segment->next()));
   1233     this->outdentDump();
   1234 }
   1235 
   1236 
   1237 void SkOpContour::dumpAngles() const {
   1238     SkDebugf("contour=%d\n", this->debugID());
   1239     const SkOpSegment* segment = &fHead;
   1240     do {
   1241         SkDebugf("  seg=%d ", segment->debugID());
   1242         segment->dumpAngles();
   1243     } while ((segment = segment->next()));
   1244 }
   1245 
   1246 void SkOpContour::dumpPt(int index) const {
   1247     const SkOpSegment* segment = &fHead;
   1248     do {
   1249         if (segment->debugID() == index) {
   1250             segment->dumpPts();
   1251         }
   1252     } while ((segment = segment->next()));
   1253 }
   1254 
   1255 void SkOpContour::dumpPts(const char* prefix) const {
   1256     SkDebugf("contour=%d\n", this->debugID());
   1257     const SkOpSegment* segment = &fHead;
   1258     do {
   1259         SkDebugf("  %s=%d ", prefix, segment->debugID());
   1260         segment->dumpPts(prefix);
   1261     } while ((segment = segment->next()));
   1262 }
   1263 
   1264 void SkOpContour::dumpPtsX(const char* prefix) const {
   1265     if (!this->fCount) {
   1266         SkDebugf("<empty>\n");
   1267         return;
   1268     }
   1269     const SkOpSegment* segment = &fHead;
   1270     do {
   1271         segment->dumpPts(prefix);
   1272     } while ((segment = segment->next()));
   1273 }
   1274 
   1275 void SkOpContour::dumpSegment(int index) const {
   1276     debugSegment(index)->dump();
   1277 }
   1278 
   1279 void SkOpContour::dumpSegments(const char* prefix, SkPathOp op) const {
   1280     bool firstOp = false;
   1281     const SkOpContour* c = this;
   1282     do {
   1283         if (!firstOp && c->operand() && op >= 0) {
   1284 #if DEBUG_ACTIVE_OP
   1285             SkDebugf("op %s\n", SkPathOpsDebug::kPathOpStr[op]);
   1286 #endif
   1287             firstOp = true;
   1288         }
   1289         c->dumpPtsX(prefix);
   1290     } while ((c = c->next()));
   1291 }
   1292 
   1293 void SkOpContour::dumpSpan(int index) const {
   1294     debugSpan(index)->dump();
   1295 }
   1296 
   1297 void SkOpContour::dumpSpans() const {
   1298     SkDebugf("contour=%d\n", this->debugID());
   1299     const SkOpSegment* segment = &fHead;
   1300     do {
   1301         SkDebugf("  seg=%d ", segment->debugID());
   1302         segment->dump();
   1303     } while ((segment = segment->next()));
   1304 }
   1305 
   1306 void SkOpCurve::dump() const {
   1307     int count = SkPathOpsVerbToPoints(SkDEBUGRELEASE(fVerb, SkPath::kCubic_Verb));
   1308     SkDebugf("{{");
   1309     int index;
   1310     for (index = 0; index <= count - 1; ++index) {
   1311         SkDebugf("{%1.9gf,%1.9gf}, ", fPts[index].fX, fPts[index].fY);
   1312     }
   1313     SkDebugf("{%1.9gf,%1.9gf}}}\n", fPts[index].fX, fPts[index].fY);
   1314 }
   1315 
   1316 #ifdef SK_DEBUG
   1317 const SkOpAngle* SkOpGlobalState::debugAngle(int id) const {
   1318     const SkOpContour* contour = fContourHead;
   1319     do {
   1320         const SkOpSegment* segment = contour->first();
   1321         while (segment) {
   1322             const SkOpSpan* span = segment->head();
   1323             do {
   1324                 SkOpAngle* angle = span->fromAngle();
   1325                 if (angle && angle->debugID() == id) {
   1326                     return angle;
   1327                 }
   1328                 angle = span->toAngle();
   1329                 if (angle && angle->debugID() == id) {
   1330                     return angle;
   1331                 }
   1332             } while ((span = span->next()->upCastable()));
   1333             const SkOpSpanBase* tail = segment->tail();
   1334             SkOpAngle* angle = tail->fromAngle();
   1335             if (angle && angle->debugID() == id) {
   1336                 return angle;
   1337             }
   1338             segment = segment->next();
   1339         }
   1340     } while ((contour = contour->next()));
   1341     return nullptr;
   1342 }
   1343 
   1344 SkOpContour* SkOpGlobalState::debugContour(int id) {
   1345     SkOpContour* contour = fContourHead;
   1346     do {
   1347         if (contour->debugID() == id) {
   1348             return contour;
   1349         }
   1350     } while ((contour = contour->next()));
   1351     return nullptr;
   1352 }
   1353 
   1354 const SkOpPtT* SkOpGlobalState::debugPtT(int id) const {
   1355     const SkOpContour* contour = fContourHead;
   1356     do {
   1357         const SkOpSegment* segment = contour->first();
   1358         while (segment) {
   1359             const SkOpSpan* span = segment->head();
   1360             do {
   1361                 const SkOpPtT* ptT = span->ptT();
   1362                 if (ptT->debugMatchID(id)) {
   1363                     return ptT;
   1364                 }
   1365             } while ((span = span->next()->upCastable()));
   1366             const SkOpSpanBase* tail = segment->tail();
   1367             const SkOpPtT* ptT = tail->ptT();
   1368             if (ptT->debugMatchID(id)) {
   1369                 return ptT;
   1370             }
   1371             segment = segment->next();
   1372         }
   1373     } while ((contour = contour->next()));
   1374     return nullptr;
   1375 }
   1376 
   1377 const SkOpSegment* SkOpGlobalState::debugSegment(int id) const {
   1378     const SkOpContour* contour = fContourHead;
   1379     do {
   1380         const SkOpSegment* segment = contour->first();
   1381         while (segment) {
   1382             if (segment->debugID() == id) {
   1383                 return segment;
   1384             }
   1385             segment = segment->next();
   1386         }
   1387     } while ((contour = contour->next()));
   1388     return nullptr;
   1389 }
   1390 
   1391 const SkOpSpanBase* SkOpGlobalState::debugSpan(int id) const {
   1392     const SkOpContour* contour = fContourHead;
   1393     do {
   1394         const SkOpSegment* segment = contour->first();
   1395         while (segment) {
   1396             const SkOpSpan* span = segment->head();
   1397             do {
   1398                 if (span->debugID() == id) {
   1399                     return span;
   1400                 }
   1401             } while ((span = span->next()->upCastable()));
   1402             const SkOpSpanBase* tail = segment->tail();
   1403             if (tail->debugID() == id) {
   1404                 return tail;
   1405             }
   1406             segment = segment->next();
   1407         }
   1408     } while ((contour = contour->next()));
   1409     return nullptr;
   1410 }
   1411 #endif
   1412 
   1413 #if DEBUG_T_SECT_DUMP > 1
   1414 int gDumpTSectNum;
   1415 #endif
   1416