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