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 "include/core/SkString.h"
9 #include "include/private/SkMutex.h"
10 #include "src/pathops/SkIntersectionHelper.h"
11 #include "src/pathops/SkOpCoincidence.h"
12 #include "src/pathops/SkOpContour.h"
13 #include "src/pathops/SkOpSegment.h"
14 #include "tests/PathOpsDebug.h"
15 #include "tests/PathOpsTSectDebug.h"
16 
17 bool PathOpsDebug::gJson;
18 bool PathOpsDebug::gMarkJsonFlaky;
19 bool PathOpsDebug::gOutFirst;
20 bool PathOpsDebug::gCheckForDuplicateNames;
21 bool PathOpsDebug::gOutputSVG;
22 FILE* PathOpsDebug::gOut;
23 
DebugDumpDouble(double x)24 inline void DebugDumpDouble(double x) {
25     if (x == floor(x)) {
26         SkDebugf("%.0f", x);
27     } else {
28         SkDebugf("%1.19g", x);
29     }
30 }
31 
DebugDumpFloat(float x)32 inline void DebugDumpFloat(float x) {
33     if (x == floorf(x)) {
34         SkDebugf("%.0f", x);
35     } else {
36         SkDebugf("%1.9gf", x);
37     }
38 }
39 
DebugDumpHexFloat(float x)40 inline void DebugDumpHexFloat(float x) {
41     SkDebugf("SkBits2Float(0x%08x)", SkFloat2Bits(x));
42 }
43 
44 // if not defined by PathOpsDebug.cpp ...
45 #if !defined SK_DEBUG && FORCE_RELEASE
ValidWind(int wind)46 bool SkPathOpsDebug::ValidWind(int wind) {
47     return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF;
48 }
49 
WindingPrintf(int wind)50 void SkPathOpsDebug::WindingPrintf(int wind) {
51     if (wind == SK_MinS32) {
52         SkDebugf("?");
53     } else {
54         SkDebugf("%d", wind);
55     }
56 }
57 #endif
58 
DumpID(int id)59 static void DumpID(int id) {
60     SkDebugf("} ");
61     if (id >= 0) {
62         SkDebugf("id=%d", id);
63     }
64     SkDebugf("\n");
65 }
66 
dump() const67 void SkDConic::dump() const {
68     dumpInner();
69     SkDebugf("},\n");
70 }
71 
dumpID(int id) const72 void SkDConic::dumpID(int id) const {
73     dumpInner();
74     DumpID(id);
75 }
76 
dumpInner() const77 void SkDConic::dumpInner() const {
78     SkDebugf("{");
79     fPts.dumpInner();
80     SkDebugf("}}, %1.9gf", fWeight);
81 }
82 
dump() const83 void SkDCubic::dump() const {
84     this->dumpInner();
85     SkDebugf("}},\n");
86 }
87 
dumpID(int id) const88 void SkDCubic::dumpID(int id) const {
89     this->dumpInner();
90     SkDebugf("}");
91     DumpID(id);
92 }
93 
double_is_NaN(double x)94 static inline bool double_is_NaN(double x) { return x != x; }
95 
dumpInner() const96 void SkDCubic::dumpInner() const {
97     SkDebugf("{{");
98     int index = 0;
99     do {
100         if (index != 0) {
101             if (double_is_NaN(fPts[index].fX) && double_is_NaN(fPts[index].fY)) {
102                 return;
103             }
104             SkDebugf(", ");
105         }
106         fPts[index].dump();
107     } while (++index < 3);
108     if (double_is_NaN(fPts[index].fX) && double_is_NaN(fPts[index].fY)) {
109         return;
110     }
111     SkDebugf(", ");
112     fPts[index].dump();
113 }
114 
dump() const115 void SkDCurve::dump() const {
116     dumpID(-1);
117 }
118 
dumpID(int id) const119 void SkDCurve::dumpID(int id) const {
120 #ifndef SK_RELEASE
121     switch(fVerb) {
122         case SkPath::kLine_Verb:
123             fLine.dumpID(id);
124             break;
125         case SkPath::kQuad_Verb:
126             fQuad.dumpID(id);
127             break;
128         case SkPath::kConic_Verb:
129             fConic.dumpID(id);
130             break;
131         case SkPath::kCubic_Verb:
132             fCubic.dumpID(id);
133             break;
134         default:
135             SkASSERT(0);
136     }
137 #else
138     fCubic.dumpID(id);
139 #endif
140 }
141 
dump() const142 void SkDLine::dump() const {
143     this->dumpInner();
144     SkDebugf("}},\n");
145 }
146 
dumpID(int id) const147 void SkDLine::dumpID(int id) const {
148     this->dumpInner();
149     SkDebugf("}");
150     DumpID(id);
151 }
152 
dumpInner() const153 void SkDLine::dumpInner() const {
154     SkDebugf("{{");
155     fPts[0].dump();
156     SkDebugf(", ");
157     fPts[1].dump();
158 }
159 
dump() const160 void SkDPoint::dump() const {
161     SkDebugf("{");
162     DebugDumpDouble(fX);
163     SkDebugf(", ");
164     DebugDumpDouble(fY);
165     SkDebugf("}");
166 }
167 
Dump(const SkPoint & pt)168 void SkDPoint::Dump(const SkPoint& pt) {
169     SkDebugf("{");
170     DebugDumpFloat(pt.fX);
171     SkDebugf(", ");
172     DebugDumpFloat(pt.fY);
173     SkDebugf("}");
174 }
175 
DumpHex(const SkPoint & pt)176 void SkDPoint::DumpHex(const SkPoint& pt) {
177     SkDebugf("{");
178     DebugDumpHexFloat(pt.fX);
179     SkDebugf(", ");
180     DebugDumpHexFloat(pt.fY);
181     SkDebugf("}");
182 }
183 
dump() const184 void SkDQuad::dump() const {
185     dumpInner();
186     SkDebugf("}},\n");
187 }
188 
dumpID(int id) const189 void SkDQuad::dumpID(int id) const {
190     dumpInner();
191     SkDebugf("}");
192     DumpID(id);
193 }
194 
dumpInner() const195 void SkDQuad::dumpInner() const {
196     SkDebugf("{{");
197     int index = 0;
198     do {
199         fPts[index].dump();
200         SkDebugf(", ");
201     } while (++index < 2);
202     fPts[index].dump();
203 }
204 
dump() const205 void SkIntersections::dump() const {
206     SkDebugf("used=%d of %d", fUsed, fMax);
207     for (int index = 0; index < fUsed; ++index) {
208         SkDebugf(" t=(%s%1.9g,%s%1.9g) pt=(%1.9g,%1.9g)",
209                 fIsCoincident[0] & (1 << index) ? "*" : "", fT[0][index],
210                 fIsCoincident[1] & (1 << index) ? "*" : "", fT[1][index],
211                 fPt[index].fX, fPt[index].fY);
212         if (index < 2 && fNearlySame[index]) {
213             SkDebugf(" pt2=(%1.9g,%1.9g)",fPt2[index].fX, fPt2[index].fY);
214         }
215     }
216     SkDebugf("\n");
217 }
218 
AngleAngle(const SkOpAngle * angle,int id)219 const SkOpAngle* AngleAngle(const SkOpAngle* angle, int id) {
220     return angle->debugAngle(id);
221 }
222 
AngleContour(SkOpAngle * angle,int id)223 SkOpContour* AngleContour(SkOpAngle* angle, int id) {
224     return angle->debugContour(id);
225 }
226 
AnglePtT(const SkOpAngle * angle,int id)227 const SkOpPtT* AnglePtT(const SkOpAngle* angle, int id) {
228     return angle->debugPtT(id);
229 }
230 
AngleSegment(const SkOpAngle * angle,int id)231 const SkOpSegment* AngleSegment(const SkOpAngle* angle, int id) {
232     return angle->debugSegment(id);
233 }
234 
AngleSpan(const SkOpAngle * angle,int id)235 const SkOpSpanBase* AngleSpan(const SkOpAngle* angle, int id) {
236     return angle->debugSpan(id);
237 }
238 
ContourAngle(SkOpContour * contour,int id)239 const SkOpAngle* ContourAngle(SkOpContour* contour, int id) {
240     return contour->debugAngle(id);
241 }
242 
ContourContour(SkOpContour * contour,int id)243 SkOpContour* ContourContour(SkOpContour* contour, int id) {
244     return contour->debugContour(id);
245 }
246 
ContourPtT(SkOpContour * contour,int id)247 const SkOpPtT* ContourPtT(SkOpContour* contour, int id) {
248     return contour->debugPtT(id);
249 }
250 
ContourSegment(SkOpContour * contour,int id)251 const SkOpSegment* ContourSegment(SkOpContour* contour, int id) {
252     return contour->debugSegment(id);
253 }
254 
ContourSpan(SkOpContour * contour,int id)255 const SkOpSpanBase* ContourSpan(SkOpContour* contour, int id) {
256     return contour->debugSpan(id);
257 }
258 
CoincidenceAngle(SkOpCoincidence * coin,int id)259 const SkOpAngle* CoincidenceAngle(SkOpCoincidence* coin, int id) {
260     return coin->debugAngle(id);
261 }
262 
CoincidenceContour(SkOpCoincidence * coin,int id)263 SkOpContour* CoincidenceContour(SkOpCoincidence* coin, int id) {
264     return coin->debugContour(id);
265 }
266 
CoincidencePtT(SkOpCoincidence * coin,int id)267 const SkOpPtT* CoincidencePtT(SkOpCoincidence* coin, int id) {
268     return coin->debugPtT(id);
269 }
270 
CoincidenceSegment(SkOpCoincidence * coin,int id)271 const SkOpSegment* CoincidenceSegment(SkOpCoincidence* coin, int id) {
272     return coin->debugSegment(id);
273 }
274 
CoincidenceSpan(SkOpCoincidence * coin,int id)275 const SkOpSpanBase* CoincidenceSpan(SkOpCoincidence* coin, int id) {
276     return coin->debugSpan(id);
277 }
278 
PtTAngle(const SkOpPtT * ptT,int id)279 const SkOpAngle* PtTAngle(const SkOpPtT* ptT, int id) {
280     return ptT->debugAngle(id);
281 }
282 
PtTContour(SkOpPtT * ptT,int id)283 SkOpContour* PtTContour(SkOpPtT* ptT, int id) {
284     return ptT->debugContour(id);
285 }
286 
PtTPtT(const SkOpPtT * ptT,int id)287 const SkOpPtT* PtTPtT(const SkOpPtT* ptT, int id) {
288     return ptT->debugPtT(id);
289 }
290 
PtTSegment(const SkOpPtT * ptT,int id)291 const SkOpSegment* PtTSegment(const SkOpPtT* ptT, int id) {
292     return ptT->debugSegment(id);
293 }
294 
PtTSpan(const SkOpPtT * ptT,int id)295 const SkOpSpanBase* PtTSpan(const SkOpPtT* ptT, int id) {
296     return ptT->debugSpan(id);
297 }
298 
SegmentAngle(const SkOpSegment * span,int id)299 const SkOpAngle* SegmentAngle(const SkOpSegment* span, int id) {
300     return span->debugAngle(id);
301 }
302 
SegmentContour(SkOpSegment * span,int id)303 SkOpContour* SegmentContour(SkOpSegment* span, int id) {
304     return span->debugContour(id);
305 }
306 
SegmentPtT(const SkOpSegment * span,int id)307 const SkOpPtT* SegmentPtT(const SkOpSegment* span, int id) {
308     return span->debugPtT(id);
309 }
310 
SegmentSegment(const SkOpSegment * span,int id)311 const SkOpSegment* SegmentSegment(const SkOpSegment* span, int id) {
312     return span->debugSegment(id);
313 }
314 
SegmentSpan(const SkOpSegment * span,int id)315 const SkOpSpanBase* SegmentSpan(const SkOpSegment* span, int id) {
316     return span->debugSpan(id);
317 }
318 
SpanAngle(const SkOpSpanBase * span,int id)319 const SkOpAngle* SpanAngle(const SkOpSpanBase* span, int id) {
320     return span->debugAngle(id);
321 }
322 
SpanContour(SkOpSpanBase * span,int id)323 SkOpContour* SpanContour(SkOpSpanBase* span, int id) {
324     return span->debugContour(id);
325 }
326 
SpanPtT(const SkOpSpanBase * span,int id)327 const SkOpPtT* SpanPtT(const SkOpSpanBase* span, int id) {
328     return span->debugPtT(id);
329 }
330 
SpanSegment(const SkOpSpanBase * span,int id)331 const SkOpSegment* SpanSegment(const SkOpSpanBase* span, int id) {
332     return span->debugSegment(id);
333 }
334 
SpanSpan(const SkOpSpanBase * span,int id)335 const SkOpSpanBase* SpanSpan(const SkOpSpanBase* span, int id) {
336     return span->debugSpan(id);
337 }
338 
339 #if DEBUG_COIN
DumpCoinDict()340 void SkPathOpsDebug::DumpCoinDict() {
341     SkPathOpsDebug::gCoinSumChangedDict.dump("unused coin algorithm", false);
342     SkPathOpsDebug::gCoinSumVisitedDict.dump("visited coin function", true);
343 }
344 
dump(const char * str,bool visitCheck) const345 void SkPathOpsDebug::CoinDict::dump(const char* str, bool visitCheck) const {
346     int count = fDict.count();
347     for (int index = 0; index < count; ++index) {
348         const auto& entry = fDict[index];
349         if (visitCheck || entry.fGlitchType == kUninitialized_Glitch) {
350             SkDebugf("%s %s : line %d iteration %d", str, entry.fFunctionName,
351                     entry.fLineNumber, entry.fIteration);
352             DumpGlitchType(entry.fGlitchType);
353             SkDebugf("\n");
354         }
355     }
356 }
357 #endif
358 
dumpContours() const359 void SkOpContour::dumpContours() const {
360     SkOpContour* contour = this->globalState()->contourHead();
361     do {
362         contour->dump();
363     } while ((contour = contour->next()));
364 }
365 
dumpContoursAll() const366 void SkOpContour::dumpContoursAll() const {
367     SkOpContour* contour = this->globalState()->contourHead();
368     do {
369         contour->dumpAll();
370     } while ((contour = contour->next()));
371 }
372 
dumpContoursAngles() const373 void SkOpContour::dumpContoursAngles() const {
374     SkOpContour* contour = this->globalState()->contourHead();
375     do {
376         contour->dumpAngles();
377     } while ((contour = contour->next()));
378 }
379 
dumpContoursPts() const380 void SkOpContour::dumpContoursPts() const {
381     SkOpContour* contour = this->globalState()->contourHead();
382     do {
383         contour->dumpPts();
384     } while ((contour = contour->next()));
385 }
386 
dumpContoursPt(int segmentID) const387 void SkOpContour::dumpContoursPt(int segmentID) const {
388     SkOpContour* contour = this->globalState()->contourHead();
389     do {
390         contour->dumpPt(segmentID);
391     } while ((contour = contour->next()));
392 }
393 
dumpContoursSegment(int segmentID) const394 void SkOpContour::dumpContoursSegment(int segmentID) const {
395     SkOpContour* contour = this->globalState()->contourHead();
396     do {
397         contour->dumpSegment(segmentID);
398     } while ((contour = contour->next()));
399 }
400 
dumpContoursSpan(int spanID) const401 void SkOpContour::dumpContoursSpan(int spanID) const {
402     SkOpContour* contour = this->globalState()->contourHead();
403     do {
404         contour->dumpSpan(spanID);
405     } while ((contour = contour->next()));
406 }
407 
dumpContoursSpans() const408 void SkOpContour::dumpContoursSpans() const {
409     SkOpContour* contour = this->globalState()->contourHead();
410     do {
411         contour->dumpSpans();
412     } while ((contour = contour->next()));
413 }
414 
415 #ifdef SK_DEBUG
DebugSpan(const SkTSect * sect,int id)416 const SkTSpan* DebugSpan(const SkTSect* sect, int id) {
417     return sect->debugSpan(id);
418 }
419 
DebugT(const SkTSect * sect,double t)420 const SkTSpan* DebugT(const SkTSect* sect, double t) {
421     return sect->debugT(t);
422 }
423 #endif
424 
Dump(const SkTSect * sect)425 void Dump(const SkTSect* sect) {
426     sect->dump();
427 }
428 
DumpBoth(SkTSect * sect1,SkTSect * sect2)429 void DumpBoth(SkTSect* sect1, SkTSect* sect2) {
430     sect1->dumpBoth(sect2);
431 }
432 
DumpBounded(SkTSect * sect1,int id)433 void DumpBounded(SkTSect* sect1, int id) {
434     sect1->dumpBounded(id);
435 }
436 
DumpBounds(SkTSect * sect1)437 void DumpBounds(SkTSect* sect1) {
438     sect1->dumpBounds();
439 }
440 
DumpCoin(SkTSect * sect1)441 void DumpCoin(SkTSect* sect1) {
442     sect1->dumpCoin();
443 }
444 
DumpCoinCurves(SkTSect * sect1)445 void DumpCoinCurves(SkTSect* sect1) {
446     sect1->dumpCoinCurves();
447 }
448 
DumpCurves(const SkTSect * sect)449 void DumpCurves(const SkTSect* sect) {
450     sect->dumpCurves();
451 }
452 
Dump(const SkTSpan * span)453 void Dump(const SkTSpan* span) {
454     span->dump();
455 }
456 
DumpAll(const SkTSpan * span)457 void DumpAll(const SkTSpan* span) {
458     span->dumpAll();
459 }
460 
DumpBounded(const SkTSpan * span)461 void DumpBounded(const SkTSpan* span) {
462     span->dumpBounded(0);
463 }
464 
DumpCoin(const SkTSpan * span)465 void DumpCoin(const SkTSpan* span) {
466     span->dumpCoin();
467 }
468 
dumpTestCase(const SkDQuad & quad1,const SkDQuad & quad2,int testNo)469 static void dumpTestCase(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) {
470     SkDebugf("\n<div id=\"quad%d\">\n", testNo);
471     quad1.dumpInner();
472     SkDebugf("}}, ");
473     quad2.dump();
474     SkDebugf("</div>\n\n");
475 }
476 
dumpTestTrailer()477 static void dumpTestTrailer() {
478     SkDebugf("</div>\n\n<script type=\"text/javascript\">\n\n");
479     SkDebugf("    var testDivs = [\n");
480 }
481 
dumpTestList(int testNo,double min)482 static void dumpTestList(int testNo, double min) {
483     SkDebugf("        quad%d,", testNo);
484     if (min > 0) {
485         SkDebugf("  // %1.9g", min);
486     }
487     SkDebugf("\n");
488 }
489 
DumpQ(const SkDQuad & quad1,const SkDQuad & quad2,int testNo)490 void DumpQ(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) {
491     SkDebugf("\n");
492     dumpTestCase(quad1, quad2, testNo);
493     dumpTestTrailer();
494     dumpTestList(testNo, 0);
495     SkDebugf("\n");
496 }
497 
DumpT(const SkDQuad & quad,double t)498 void DumpT(const SkDQuad& quad, double t) {
499     SkDLine line = {{quad.ptAtT(t), quad[0]}};
500     line.dump();
501 }
502 
debugAngle(int id) const503 const SkOpAngle* SkOpAngle::debugAngle(int id) const {
504     return this->segment()->debugAngle(id);
505 }
506 
debugCoincidence() const507 const SkOpCoincidence* SkOpAngle::debugCoincidence() const {
508     return this->segment()->debugCoincidence();
509 }
510 
debugContour(int id) const511 SkOpContour* SkOpAngle::debugContour(int id) const {
512     return this->segment()->debugContour(id);
513 }
514 
debugPtT(int id) const515 const SkOpPtT* SkOpAngle::debugPtT(int id) const {
516     return this->segment()->debugPtT(id);
517 }
518 
debugSegment(int id) const519 const SkOpSegment* SkOpAngle::debugSegment(int id) const {
520     return this->segment()->debugSegment(id);
521 }
522 
debugSign() const523 int SkOpAngle::debugSign() const {
524     SkASSERT(fStart->t() != fEnd->t());
525     return fStart->t() < fEnd->t() ? -1 : 1;
526 }
527 
debugSpan(int id) const528 const SkOpSpanBase* SkOpAngle::debugSpan(int id) const {
529     return this->segment()->debugSpan(id);
530 }
531 
dump() const532 void SkOpAngle::dump() const {
533     dumpOne(true);
534     SkDebugf("\n");
535 }
536 
dumpOne(bool functionHeader) const537 void SkOpAngle::dumpOne(bool functionHeader) const {
538 //    fSegment->debugValidate();
539     const SkOpSegment* segment = this->segment();
540     const SkOpSpan& mSpan = *fStart->starter(fEnd);
541     if (functionHeader) {
542         SkDebugf("%s ", __FUNCTION__);
543     }
544     SkDebugf("[%d", segment->debugID());
545     SkDebugf("/%d", debugID());
546     SkDebugf("] next=");
547     if (fNext) {
548         SkDebugf("%d", fNext->fStart->segment()->debugID());
549         SkDebugf("/%d", fNext->debugID());
550     } else {
551         SkDebugf("?");
552     }
553     SkDebugf(" sect=%d/%d ", fSectorStart, fSectorEnd);
554     SkDebugf(" s=%1.9g [%d] e=%1.9g [%d]", fStart->t(), fStart->debugID(),
555                 fEnd->t(), fEnd->debugID());
556     SkDebugf(" sgn=%d windVal=%d", this->debugSign(), mSpan.windValue());
557 
558     SkDebugf(" windSum=");
559     SkPathOpsDebug::WindingPrintf(mSpan.windSum());
560     if (mSpan.oppValue() != 0 || mSpan.oppSum() != SK_MinS32) {
561         SkDebugf(" oppVal=%d", mSpan.oppValue());
562         SkDebugf(" oppSum=");
563         SkPathOpsDebug::WindingPrintf(mSpan.oppSum());
564     }
565     if (mSpan.done()) {
566         SkDebugf(" done");
567     }
568     if (unorderable()) {
569         SkDebugf(" unorderable");
570     }
571     if (segment->operand()) {
572         SkDebugf(" operand");
573     }
574 }
575 
dumpTo(const SkOpSegment * segment,const SkOpAngle * to) const576 void SkOpAngle::dumpTo(const SkOpSegment* segment, const SkOpAngle* to) const {
577     const SkOpAngle* first = this;
578     const SkOpAngle* next = this;
579     const char* indent = "";
580     do {
581         SkDebugf("%s", indent);
582         next->dumpOne(false);
583         if (segment == next->fStart->segment()) {
584             if (this == fNext) {
585                 SkDebugf(" << from");
586             }
587             if (to == fNext) {
588                 SkDebugf(" << to");
589             }
590         }
591         SkDebugf("\n");
592         indent = "           ";
593         next = next->fNext;
594     } while (next && next != first);
595 }
596 
dumpCurves() const597 void SkOpAngle::dumpCurves() const {
598     const SkOpAngle* first = this;
599     const SkOpAngle* next = this;
600     do {
601         next->fPart.fCurve.dumpID(next->segment()->debugID());
602         next = next->fNext;
603     } while (next && next != first);
604 }
605 
dumpLoop() const606 void SkOpAngle::dumpLoop() const {
607     const SkOpAngle* first = this;
608     const SkOpAngle* next = this;
609     do {
610         next->dumpOne(false);
611         SkDebugf("\n");
612         next = next->fNext;
613     } while (next && next != first);
614 }
615 
dumpTest() const616 void SkOpAngle::dumpTest() const {
617     const SkOpAngle* first = this;
618     const SkOpAngle* next = this;
619     do {
620         SkDebugf("{ ");
621         SkOpSegment* segment = next->segment();
622         segment->dumpPts();
623         SkDebugf(", %d, %1.9g, %1.9g, {} },\n", SkPathOpsVerbToPoints(segment->verb()) + 1,
624                 next->start()->t(), next->end()->t());
625         next = next->fNext;
626     } while (next && next != first);
627 }
628 
debugMatchID(int id) const629 bool SkOpPtT::debugMatchID(int id) const {
630     int limit = this->debugLoopLimit(false);
631     int loop = 0;
632     const SkOpPtT* ptT = this;
633     do {
634         if (ptT->debugID() == id) {
635             return true;
636         }
637     } while ((!limit || ++loop <= limit) && (ptT = ptT->next()) && ptT != this);
638     return false;
639 }
640 
debugAngle(int id) const641 const SkOpAngle* SkOpPtT::debugAngle(int id) const {
642     return this->span()->debugAngle(id);
643 }
644 
debugContour(int id) const645 SkOpContour* SkOpPtT::debugContour(int id) const {
646     return this->span()->debugContour(id);
647 }
648 
debugCoincidence() const649 const SkOpCoincidence* SkOpPtT::debugCoincidence() const {
650     return this->span()->debugCoincidence();
651 }
652 
debugPtT(int id) const653 const SkOpPtT* SkOpPtT::debugPtT(int id) const {
654     return this->span()->debugPtT(id);
655 }
656 
debugSegment(int id) const657 const SkOpSegment* SkOpPtT::debugSegment(int id) const {
658     return this->span()->debugSegment(id);
659 }
660 
debugSpan(int id) const661 const SkOpSpanBase* SkOpPtT::debugSpan(int id) const {
662     return this->span()->debugSpan(id);
663 }
664 
dump() const665 void SkOpPtT::dump() const {
666     SkDebugf("seg=%d span=%d ptT=%d",
667             this->segment()->debugID(), this->span()->debugID(), this->debugID());
668     this->dumpBase();
669     SkDebugf("\n");
670 }
671 
dumpAll() const672 void SkOpPtT::dumpAll() const {
673     contour()->indentDump();
674     const SkOpPtT* next = this;
675     int limit = debugLoopLimit(true);
676     int loop = 0;
677     do {
678         SkDebugf("%.*s", contour()->debugIndent(), "        ");
679         SkDebugf("seg=%d span=%d ptT=%d",
680                 next->segment()->debugID(), next->span()->debugID(), next->debugID());
681         next->dumpBase();
682         SkDebugf("\n");
683         if (limit && ++loop >= limit) {
684             SkDebugf("*** abort loop ***\n");
685             break;
686         }
687     } while ((next = next->fNext) && next != this);
688     contour()->outdentDump();
689 }
690 
dumpBase() const691 void SkOpPtT::dumpBase() const {
692     SkDebugf(" t=%1.9g pt=(%1.9g,%1.9g)%s%s%s", this->fT, this->fPt.fX, this->fPt.fY,
693             this->fCoincident ? " coin" : "",
694             this->fDuplicatePt ? " dup" : "", this->fDeleted ? " deleted" : "");
695 }
696 
debugAngle(int id) const697 const SkOpAngle* SkOpSpanBase::debugAngle(int id) const {
698     return this->segment()->debugAngle(id);
699 }
700 
debugCoincidence() const701 const SkOpCoincidence* SkOpSpanBase::debugCoincidence() const {
702     return this->segment()->debugCoincidence();
703 }
704 
debugContour(int id) const705 SkOpContour* SkOpSpanBase::debugContour(int id) const {
706     return this->segment()->debugContour(id);
707 }
708 
debugPtT(int id) const709 const SkOpPtT* SkOpSpanBase::debugPtT(int id) const {
710     return this->segment()->debugPtT(id);
711 }
712 
debugSegment(int id) const713 const SkOpSegment* SkOpSpanBase::debugSegment(int id) const {
714     return this->segment()->debugSegment(id);
715 }
716 
debugSpan(int id) const717 const SkOpSpanBase* SkOpSpanBase::debugSpan(int id) const {
718     return this->segment()->debugSpan(id);
719 }
720 
dump() const721 void SkOpSpanBase::dump() const {
722     this->dumpHead();
723     this->fPtT.dump();
724 }
725 
dumpHead() const726 void SkOpSpanBase::dumpHead() const {
727     SkDebugf("%.*s", contour()->debugIndent(), "        ");
728     SkDebugf("seg=%d span=%d", this->segment()->debugID(), this->debugID());
729     this->dumpBase();
730     SkDebugf("\n");
731 }
732 
dumpAll() const733 void SkOpSpanBase::dumpAll() const {
734     this->dumpHead();
735     this->fPtT.dumpAll();
736 }
737 
dumpBase() const738 void SkOpSpanBase::dumpBase() const {
739     if (this->fAligned) {
740         SkDebugf(" aligned");
741     }
742     if (this->fChased) {
743         SkDebugf(" chased");
744     }
745 #ifdef SK_DEBUG
746     if (this->fDebugDeleted) {
747         SkDebugf(" deleted");
748     }
749 #endif
750     if (!this->final()) {
751         this->upCast()->dumpSpan();
752     }
753     const SkOpSpanBase* coin = this->coinEnd();
754     if (this != coin) {
755         SkDebugf(" coinEnd seg/span=%d/%d", coin->segment()->debugID(), coin->debugID());
756     } else if (this->final() || !this->upCast()->isCoincident()) {
757         const SkOpPtT* oPt = this->ptT()->next();
758         SkDebugf(" seg/span=%d/%d", oPt->segment()->debugID(), oPt->span()->debugID());
759     }
760     SkDebugf(" adds=%d", fSpanAdds);
761 }
762 
dumpCoin() const763 void SkOpSpanBase::dumpCoin() const {
764     const SkOpSpan* span = this->upCastable();
765     if (!span) {
766         return;
767     }
768     if (!span->isCoincident()) {
769         return;
770     }
771     span->dumpCoin();
772 }
773 
dumpCoin() const774 void SkOpSpan::dumpCoin() const {
775     const SkOpSpan* coincident = fCoincident;
776     bool ok = debugCoinLoopCheck();
777     this->dump();
778     int loop = 0;
779     do {
780         coincident->dump();
781         if (!ok && ++loop > 10) {
782             SkDebugf("*** abort loop ***\n");
783             break;
784         }
785     } while ((coincident = coincident->fCoincident) != this);
786 }
787 
dumpSpan() const788 bool SkOpSpan::dumpSpan() const {
789     SkOpSpan* coin = fCoincident;
790     if (this != coin) {
791         SkDebugf(" coinStart seg/span=%d/%d", coin->segment()->debugID(), coin->debugID());
792     }
793     SkDebugf(" windVal=%d", this->windValue());
794     SkDebugf(" windSum=");
795     SkPathOpsDebug::WindingPrintf(this->windSum());
796     if (this->oppValue() != 0 || this->oppSum() != SK_MinS32) {
797         SkDebugf(" oppVal=%d", this->oppValue());
798         SkDebugf(" oppSum=");
799         SkPathOpsDebug::WindingPrintf(this->oppSum());
800     }
801     if (this->done()) {
802         SkDebugf(" done");
803     }
804     return this != coin;
805 }
806 
debugAngle(int id) const807 const SkOpAngle* SkOpSegment::debugAngle(int id) const {
808     return this->contour()->debugAngle(id);
809 }
810 
debugCoincidence() const811 const SkOpCoincidence* SkOpSegment::debugCoincidence() const {
812     return this->contour()->debugCoincidence();
813 }
814 
debugContour(int id) const815 SkOpContour* SkOpSegment::debugContour(int id) const {
816     return this->contour()->debugContour(id);
817 }
818 
debugPtT(int id) const819 const SkOpPtT* SkOpSegment::debugPtT(int id) const {
820     return this->contour()->debugPtT(id);
821 }
822 
debugSegment(int id) const823 const SkOpSegment* SkOpSegment::debugSegment(int id) const {
824     return this->contour()->debugSegment(id);
825 }
826 
debugSpan(int id) const827 const SkOpSpanBase* SkOpSegment::debugSpan(int id) const {
828     return this->contour()->debugSpan(id);
829 }
830 
dump() const831 void SkOpSegment::dump() const {
832     SkDebugf("%.*s", contour()->debugIndent(), "        ");
833     this->dumpPts();
834     const SkOpSpanBase* span = &fHead;
835     contour()->indentDump();
836     do {
837         SkDebugf("%.*s span=%d ", contour()->debugIndent(), "        ", span->debugID());
838         span->ptT()->dumpBase();
839         span->dumpBase();
840         SkDebugf("\n");
841     } while (!span->final() && (span = span->upCast()->next()));
842     contour()->outdentDump();
843 }
844 
dumpAll() const845 void SkOpSegment::dumpAll() const {
846     SkDebugf("%.*s", contour()->debugIndent(), "        ");
847     this->dumpPts();
848     const SkOpSpanBase* span = &fHead;
849     contour()->indentDump();
850     do {
851         span->dumpAll();
852     } while (!span->final() && (span = span->upCast()->next()));
853     contour()->outdentDump();
854 }
855 
dumpAngles() const856 void SkOpSegment::dumpAngles() const {
857     SkDebugf("seg=%d\n", debugID());
858     const SkOpSpanBase* span = &fHead;
859     do {
860         const SkOpAngle* fAngle = span->fromAngle();
861         const SkOpAngle* tAngle = span->final() ? nullptr : span->upCast()->toAngle();
862         if (fAngle) {
863             SkDebugf("  span=%d from=%d ", span->debugID(), fAngle->debugID());
864             fAngle->dumpTo(this, tAngle);
865         }
866         if (tAngle) {
867             SkDebugf("  span=%d to=%d   ", span->debugID(), tAngle->debugID());
868             tAngle->dumpTo(this, fAngle);
869         }
870     } while (!span->final() && (span = span->upCast()->next()));
871 }
872 
dumpCoin() const873 void SkOpSegment::dumpCoin() const {
874     const SkOpSpan* span = &fHead;
875     do {
876         span->dumpCoin();
877     } while ((span = span->next()->upCastable()));
878 }
879 
dumpPtsInner(const char * prefix) const880 void SkOpSegment::dumpPtsInner(const char* prefix) const {
881     int last = SkPathOpsVerbToPoints(fVerb);
882     SkDebugf("%s=%d {{", prefix, this->debugID());
883     if (fVerb == SkPath::kConic_Verb) {
884         SkDebugf("{");
885     }
886     int index = 0;
887     do {
888         SkDPoint::Dump(fPts[index]);
889         SkDebugf(", ");
890     } while (++index < last);
891     SkDPoint::Dump(fPts[index]);
892     SkDebugf("}}");
893     if (fVerb == SkPath::kConic_Verb) {
894         SkDebugf(", %1.9gf}", fWeight);
895     }
896 }
897 
dumpPts(const char * prefix) const898 void SkOpSegment::dumpPts(const char* prefix) const {
899     dumpPtsInner(prefix);
900     SkDebugf("\n");
901 }
902 
dump() const903 void SkCoincidentSpans::dump() const {
904     SkDebugf("- seg=%d span=%d ptT=%d ", fCoinPtTStart->segment()->debugID(),
905         fCoinPtTStart->span()->debugID(), fCoinPtTStart->debugID());
906     fCoinPtTStart->dumpBase();
907     SkDebugf(" span=%d ptT=%d ", fCoinPtTEnd->span()->debugID(), fCoinPtTEnd->debugID());
908     fCoinPtTEnd->dumpBase();
909     if (fCoinPtTStart->segment()->operand()) {
910         SkDebugf(" operand");
911     }
912     if (fCoinPtTStart->segment()->isXor()) {
913         SkDebugf(" xor");
914     }
915     SkDebugf("\n");
916     SkDebugf("+ seg=%d span=%d ptT=%d ", fOppPtTStart->segment()->debugID(),
917         fOppPtTStart->span()->debugID(), fOppPtTStart->debugID());
918     fOppPtTStart->dumpBase();
919     SkDebugf(" span=%d ptT=%d ", fOppPtTEnd->span()->debugID(), fOppPtTEnd->debugID());
920     fOppPtTEnd->dumpBase();
921     if (fOppPtTStart->segment()->operand()) {
922         SkDebugf(" operand");
923     }
924     if (fOppPtTStart->segment()->isXor()) {
925         SkDebugf(" xor");
926     }
927     SkDebugf("\n");
928 }
929 
dump() const930 void SkOpCoincidence::dump() const {
931     SkCoincidentSpans* span = fHead;
932     while (span) {
933         span->dump();
934         span = span->next();
935     }
936     if (!fTop || fHead == fTop) {
937         return;
938     }
939     SkDebugf("top:\n");
940     span = fTop;
941     int count = 0;
942     while (span) {
943         span->dump();
944         span = span->next();
945         SkCoincidentSpans* check = fTop;
946         ++count;
947         for (int index = 0; index < count; ++index) {
948             if (span == check) {
949                 SkDebugf("(loops to #%d)\n", index);
950                 return;
951             }
952             check = check->next();
953         }
954     }
955 }
956 
dump() const957 void SkOpContour::dump() const {
958     SkDebugf("contour=%d count=%d op=%d xor=%d\n", this->debugID(), fCount, fOperand, fXor);
959     if (!fCount) {
960         return;
961     }
962     const SkOpSegment* segment = &fHead;
963     SkDEBUGCODE(fDebugIndent = 0);
964     this->indentDump();
965     do {
966         segment->dump();
967     } while ((segment = segment->next()));
968     this->outdentDump();
969 }
970 
dumpAll() const971 void SkOpContour::dumpAll() const {
972     SkDebugf("contour=%d count=%d op=%d xor=%d\n", this->debugID(), fCount, fOperand, fXor);
973     if (!fCount) {
974         return;
975     }
976     const SkOpSegment* segment = &fHead;
977     SkDEBUGCODE(fDebugIndent = 0);
978     this->indentDump();
979     do {
980         segment->dumpAll();
981     } while ((segment = segment->next()));
982     this->outdentDump();
983 }
984 
985 
dumpAngles() const986 void SkOpContour::dumpAngles() const {
987     SkDebugf("contour=%d\n", this->debugID());
988     const SkOpSegment* segment = &fHead;
989     do {
990         SkDebugf("  seg=%d ", segment->debugID());
991         segment->dumpAngles();
992     } while ((segment = segment->next()));
993 }
994 
dumpPt(int index) const995 void SkOpContour::dumpPt(int index) const {
996     const SkOpSegment* segment = &fHead;
997     do {
998         if (segment->debugID() == index) {
999             segment->dumpPts();
1000         }
1001     } while ((segment = segment->next()));
1002 }
1003 
dumpPts(const char * prefix) const1004 void SkOpContour::dumpPts(const char* prefix) const {
1005     SkDebugf("contour=%d\n", this->debugID());
1006     const SkOpSegment* segment = &fHead;
1007     do {
1008         SkDebugf("  %s=%d ", prefix, segment->debugID());
1009         segment->dumpPts(prefix);
1010     } while ((segment = segment->next()));
1011 }
1012 
dumpPtsX(const char * prefix) const1013 void SkOpContour::dumpPtsX(const char* prefix) const {
1014     if (!this->fCount) {
1015         SkDebugf("<empty>\n");
1016         return;
1017     }
1018     const SkOpSegment* segment = &fHead;
1019     do {
1020         segment->dumpPts(prefix);
1021     } while ((segment = segment->next()));
1022 }
1023 
dumpSegment(int index) const1024 void SkOpContour::dumpSegment(int index) const {
1025     debugSegment(index)->dump();
1026 }
1027 
dumpSegments(const char * prefix,SkPathOp op) const1028 void SkOpContour::dumpSegments(const char* prefix, SkPathOp op) const {
1029     bool firstOp = false;
1030     const SkOpContour* c = this;
1031     do {
1032         if (!firstOp && c->operand()) {
1033 #if DEBUG_ACTIVE_OP
1034             SkDebugf("op %s\n", SkPathOpsDebug::kPathOpStr[op]);
1035 #endif
1036             firstOp = true;
1037         }
1038         c->dumpPtsX(prefix);
1039     } while ((c = c->next()));
1040 }
1041 
dumpSpan(int index) const1042 void SkOpContour::dumpSpan(int index) const {
1043     debugSpan(index)->dump();
1044 }
1045 
dumpSpans() const1046 void SkOpContour::dumpSpans() const {
1047     SkDebugf("contour=%d\n", this->debugID());
1048     const SkOpSegment* segment = &fHead;
1049     do {
1050         SkDebugf("  seg=%d ", segment->debugID());
1051         segment->dump();
1052     } while ((segment = segment->next()));
1053 }
1054 
dump() const1055 void SkOpCurve::dump() const {
1056     int count = SkPathOpsVerbToPoints(SkDEBUGRELEASE(fVerb, SkPath::kCubic_Verb));
1057     SkDebugf("{{");
1058     int index;
1059     for (index = 0; index <= count - 1; ++index) {
1060         SkDebugf("{%1.9gf,%1.9gf}, ", fPts[index].fX, fPts[index].fY);
1061     }
1062     SkDebugf("{%1.9gf,%1.9gf}}}\n", fPts[index].fX, fPts[index].fY);
1063 }
1064 
1065 #ifdef SK_DEBUG
debugAngle(int id) const1066 const SkOpAngle* SkOpGlobalState::debugAngle(int id) const {
1067     const SkOpContour* contour = fContourHead;
1068     do {
1069         const SkOpSegment* segment = contour->first();
1070         while (segment) {
1071             const SkOpSpan* span = segment->head();
1072             do {
1073                 SkOpAngle* angle = span->fromAngle();
1074                 if (angle && angle->debugID() == id) {
1075                     return angle;
1076                 }
1077                 angle = span->toAngle();
1078                 if (angle && angle->debugID() == id) {
1079                     return angle;
1080                 }
1081             } while ((span = span->next()->upCastable()));
1082             const SkOpSpanBase* tail = segment->tail();
1083             SkOpAngle* angle = tail->fromAngle();
1084             if (angle && angle->debugID() == id) {
1085                 return angle;
1086             }
1087             segment = segment->next();
1088         }
1089     } while ((contour = contour->next()));
1090     return nullptr;
1091 }
1092 
debugContour(int id) const1093 SkOpContour* SkOpGlobalState::debugContour(int id) const {
1094     SkOpContour* contour = fContourHead;
1095     do {
1096         if (contour->debugID() == id) {
1097             return contour;
1098         }
1099     } while ((contour = contour->next()));
1100     return nullptr;
1101 }
1102 
debugPtT(int id) const1103 const SkOpPtT* SkOpGlobalState::debugPtT(int id) const {
1104     const SkOpContour* contour = fContourHead;
1105     do {
1106         const SkOpSegment* segment = contour->first();
1107         while (segment) {
1108             const SkOpSpan* span = segment->head();
1109             do {
1110                 const SkOpPtT* ptT = span->ptT();
1111                 if (ptT->debugMatchID(id)) {
1112                     return ptT;
1113                 }
1114             } while ((span = span->next()->upCastable()));
1115             const SkOpSpanBase* tail = segment->tail();
1116             const SkOpPtT* ptT = tail->ptT();
1117             if (ptT->debugMatchID(id)) {
1118                 return ptT;
1119             }
1120             segment = segment->next();
1121         }
1122     } while ((contour = contour->next()));
1123     return nullptr;
1124 }
1125 
debugSegment(int id) const1126 const SkOpSegment* SkOpGlobalState::debugSegment(int id) const {
1127     const SkOpContour* contour = fContourHead;
1128     do {
1129         const SkOpSegment* segment = contour->first();
1130         while (segment) {
1131             if (segment->debugID() == id) {
1132                 return segment;
1133             }
1134             segment = segment->next();
1135         }
1136     } while ((contour = contour->next()));
1137     return nullptr;
1138 }
1139 
debugSpan(int id) const1140 const SkOpSpanBase* SkOpGlobalState::debugSpan(int id) const {
1141     const SkOpContour* contour = fContourHead;
1142     do {
1143         const SkOpSegment* segment = contour->first();
1144         while (segment) {
1145             const SkOpSpan* span = segment->head();
1146             do {
1147                 if (span->debugID() == id) {
1148                     return span;
1149                 }
1150             } while ((span = span->next()->upCastable()));
1151             const SkOpSpanBase* tail = segment->tail();
1152             if (tail->debugID() == id) {
1153                 return tail;
1154             }
1155             segment = segment->next();
1156         }
1157     } while ((contour = contour->next()));
1158     return nullptr;
1159 }
1160 #endif
1161 
dumpIsCoincidentStr() const1162 char SkTCoincident::dumpIsCoincidentStr() const {
1163     if (!!fMatch != fMatch) {
1164         return '?';
1165     }
1166     return fMatch ? '*' : 0;
1167 }
1168 
dump() const1169 void SkTCoincident::dump() const {
1170     SkDebugf("t=%1.9g pt=(%1.9g,%1.9g)%s\n", fPerpT, fPerpPt.fX, fPerpPt.fY,
1171             fMatch ? " match" : "");
1172 }
1173 
1174 #ifdef SK_DEBUG
1175 
debugSpan(int id) const1176 const SkTSpan* SkTSect::debugSpan(int id) const {
1177     const SkTSpan* test = fHead;
1178     do {
1179         if (test->debugID() == id) {
1180             return test;
1181         }
1182     } while ((test = test->next()));
1183     return nullptr;
1184 }
1185 
debugT(double t) const1186 const SkTSpan* SkTSect::debugT(double t) const {
1187     const SkTSpan* test = fHead;
1188     const SkTSpan* closest = nullptr;
1189     double bestDist = DBL_MAX;
1190     do {
1191         if (between(test->fStartT, t, test->fEndT)) {
1192             return test;
1193         }
1194         double testDist = std::min(fabs(test->fStartT - t), fabs(test->fEndT - t));
1195         if (bestDist > testDist) {
1196             bestDist = testDist;
1197             closest = test;
1198         }
1199     } while ((test = test->next()));
1200     SkASSERT(closest);
1201     return closest;
1202 }
1203 
1204 #endif
1205 
dump() const1206 void SkTSect::dump() const {
1207     dumpCommon(fHead);
1208 }
1209 
1210 extern int gDumpTSectNum;
1211 
dumpBoth(SkTSect * opp) const1212 void SkTSect::dumpBoth(SkTSect* opp) const {
1213 #if DEBUG_T_SECT_DUMP <= 2
1214 #if DEBUG_T_SECT_DUMP == 2
1215     SkDebugf("%d ", ++gDumpTSectNum);
1216 #endif
1217     this->dump();
1218     SkDebugf("\n");
1219     opp->dump();
1220     SkDebugf("\n");
1221 #elif DEBUG_T_SECT_DUMP == 3
1222     SkDebugf("<div id=\"sect%d\">\n", ++gDumpTSectNum);
1223     if (this->fHead) {
1224         this->dumpCurves();
1225     }
1226     if (opp->fHead) {
1227         opp->dumpCurves();
1228     }
1229     SkDebugf("</div>\n\n");
1230 #endif
1231 }
1232 
dumpBounded(int id) const1233 void SkTSect::dumpBounded(int id) const {
1234 #ifdef SK_DEBUG
1235     const SkTSpan* bounded = debugSpan(id);
1236     if (!bounded) {
1237         SkDebugf("no span matches %d\n", id);
1238         return;
1239     }
1240     const SkTSpan* test = bounded->debugOpp()->fHead;
1241     do {
1242         if (test->findOppSpan(bounded)) {
1243             test->dump();
1244             SkDebugf(" ");
1245         }
1246     } while ((test = test->next()));
1247     SkDebugf("\n");
1248 #endif
1249 }
1250 
dumpBounds() const1251 void SkTSect::dumpBounds() const {
1252     const SkTSpan* test = fHead;
1253     do {
1254         test->dumpBounds();
1255     } while ((test = test->next()));
1256 }
1257 
dumpCoin() const1258 void SkTSect::dumpCoin() const {
1259     dumpCommon(fCoincident);
1260 }
1261 
dumpCoinCurves() const1262 void SkTSect::dumpCoinCurves() const {
1263     dumpCommonCurves(fCoincident);
1264 }
1265 
dumpCommon(const SkTSpan * test) const1266 void SkTSect::dumpCommon(const SkTSpan* test) const {
1267     SkDebugf("id=%d", debugID());
1268     if (!test) {
1269         SkDebugf(" (empty)");
1270         return;
1271     }
1272     do {
1273         SkDebugf(" ");
1274         test->dump();
1275     } while ((test = test->next()));
1276 }
1277 
dumpCommonCurves(const SkTSpan * test) const1278 void SkTSect::dumpCommonCurves(const SkTSpan* test) const {
1279 #if DEBUG_T_SECT
1280     do {
1281         test->fPart->dumpID(test->debugID());
1282     } while ((test = test->next()));
1283 #endif
1284 }
1285 
dumpCurves() const1286 void SkTSect::dumpCurves() const {
1287     dumpCommonCurves(fHead);
1288 }
1289 
1290 #ifdef SK_DEBUG
1291 
debugSpan(int id) const1292 const SkTSpan* SkTSpan::debugSpan(int id) const {
1293     return fDebugSect->debugSpan(id);
1294 }
1295 
debugT(double t) const1296 const SkTSpan* SkTSpan::debugT(double t) const {
1297     return fDebugSect->debugT(t);
1298 }
1299 
1300 #endif
1301 
dumpAll() const1302 void SkTSpan::dumpAll() const {
1303     dumpID();
1304     SkDebugf("=(%g,%g) [", fStartT, fEndT);
1305     const SkTSpanBounded* testBounded = fBounded;
1306     while (testBounded) {
1307         const SkTSpan* span = testBounded->fBounded;
1308         const SkTSpanBounded* next = testBounded->fNext;
1309         span->dumpID();
1310         SkDebugf("=(%g,%g)", span->fStartT, span->fEndT);
1311         if (next) {
1312             SkDebugf(" ");
1313         }
1314         testBounded = next;
1315     }
1316     SkDebugf("]\n");
1317 }
1318 
dump() const1319 void SkTSpan::dump() const {
1320     dumpID();
1321     SkDebugf("=(%g,%g) [", fStartT, fEndT);
1322     const SkTSpanBounded* testBounded = fBounded;
1323     while (testBounded) {
1324         const SkTSpan* span = testBounded->fBounded;
1325         const SkTSpanBounded* next = testBounded->fNext;
1326         span->dumpID();
1327         if (next) {
1328             SkDebugf(",");
1329         }
1330         testBounded = next;
1331     }
1332     SkDebugf("]");
1333 }
1334 
dumpBounded(int id) const1335 void SkTSpan::dumpBounded(int id) const {
1336     SkDEBUGCODE(fDebugSect->dumpBounded(id));
1337 }
1338 
dumpBounds() const1339 void SkTSpan::dumpBounds() const {
1340     dumpID();
1341     SkDebugf(" bounds=(%1.9g,%1.9g, %1.9g,%1.9g) boundsMax=%1.9g%s\n",
1342             fBounds.fLeft, fBounds.fTop, fBounds.fRight, fBounds.fBottom, fBoundsMax,
1343             fCollapsed ? " collapsed" : "");
1344 }
1345 
dumpCoin() const1346 void SkTSpan::dumpCoin() const {
1347     dumpID();
1348     SkDebugf(" coinStart ");
1349     fCoinStart.dump();
1350     SkDebugf(" coinEnd ");
1351     fCoinEnd.dump();
1352 }
1353 
dumpID() const1354 void SkTSpan::dumpID() const {
1355     char cS = fCoinStart.dumpIsCoincidentStr();
1356     if (cS) {
1357         SkDebugf("%c", cS);
1358     }
1359     SkDebugf("%d", debugID());
1360     char cE = fCoinEnd.dumpIsCoincidentStr();
1361     if (cE) {
1362         SkDebugf("%c", cE);
1363     }
1364 }
1365 
1366 #if DEBUG_T_SECT_DUMP > 1
1367 int gDumpTSectNum;
1368 #endif
1369 
1370 // global path dumps for msvs Visual Studio 17 to use from Immediate Window
Dump(const SkOpContour & contour)1371 void Dump(const SkOpContour& contour) {
1372     contour.dump();
1373 }
1374 
DumpAll(const SkOpContour & contour)1375 void DumpAll(const SkOpContour& contour) {
1376     contour.dumpAll();
1377 }
1378 
DumpAngles(const SkOpContour & contour)1379 void DumpAngles(const SkOpContour& contour) {
1380     contour.dumpAngles();
1381 }
1382 
DumpContours(const SkOpContour & contour)1383 void DumpContours(const SkOpContour& contour) {
1384     contour.dumpContours();
1385 }
1386 
DumpContoursAll(const SkOpContour & contour)1387 void DumpContoursAll(const SkOpContour& contour) {
1388     contour.dumpContoursAll();
1389 }
1390 
DumpContoursAngles(const SkOpContour & contour)1391 void DumpContoursAngles(const SkOpContour& contour) {
1392     contour.dumpContoursAngles();
1393 }
1394 
DumpContoursPts(const SkOpContour & contour)1395 void DumpContoursPts(const SkOpContour& contour) {
1396     contour.dumpContoursPts();
1397 }
1398 
DumpContoursPt(const SkOpContour & contour,int segmentID)1399 void DumpContoursPt(const SkOpContour& contour, int segmentID) {
1400     contour.dumpContoursPt(segmentID);
1401 }
1402 
DumpContoursSegment(const SkOpContour & contour,int segmentID)1403 void DumpContoursSegment(const SkOpContour& contour, int segmentID) {
1404     contour.dumpContoursSegment(segmentID);
1405 }
1406 
DumpContoursSpan(const SkOpContour & contour,int segmentID)1407 void DumpContoursSpan(const SkOpContour& contour, int segmentID) {
1408     contour.dumpContoursSpan(segmentID);
1409 }
1410 
DumpContoursSpans(const SkOpContour & contour)1411 void DumpContoursSpans(const SkOpContour& contour) {
1412     contour.dumpContoursSpans();
1413 }
1414 
DumpPt(const SkOpContour & contour,int pt)1415 void DumpPt(const SkOpContour& contour, int pt) {
1416     contour.dumpPt(pt);
1417 }
1418 
DumpPts(const SkOpContour & contour,const char * prefix)1419 void DumpPts(const SkOpContour& contour, const char* prefix) {
1420     contour.dumpPts(prefix);
1421 }
1422 
DumpSegment(const SkOpContour & contour,int seg)1423 void DumpSegment(const SkOpContour& contour, int seg) {
1424     contour.dumpSegment(seg);
1425 }
1426 
DumpSegments(const SkOpContour & contour,const char * prefix,SkPathOp op)1427 void DumpSegments(const SkOpContour& contour, const char* prefix, SkPathOp op) {
1428     contour.dumpSegments(prefix, op);
1429 }
1430 
DumpSpan(const SkOpContour & contour,int span)1431 void DumpSpan(const SkOpContour& contour, int span) {
1432     contour.dumpSpan(span);
1433 }
1434 
DumpSpans(const SkOpContour & contour)1435 void DumpSpans(const SkOpContour& contour ) {
1436     contour.dumpSpans();
1437 }
1438 
Dump(const SkOpSegment & segment)1439 void Dump(const SkOpSegment& segment) {
1440     segment.dump();
1441 }
1442 
DumpAll(const SkOpSegment & segment)1443 void DumpAll(const SkOpSegment& segment) {
1444     segment.dumpAll();
1445 }
1446 
DumpAngles(const SkOpSegment & segment)1447 void DumpAngles(const SkOpSegment& segment) {
1448     segment.dumpAngles();
1449 }
1450 
DumpCoin(const SkOpSegment & segment)1451 void DumpCoin(const SkOpSegment& segment) {
1452     segment.dumpCoin();
1453 }
1454 
DumpPts(const SkOpSegment & segment,const char * prefix)1455 void DumpPts(const SkOpSegment& segment, const char* prefix) {
1456     segment.dumpPts(prefix);
1457 }
1458 
Dump(const SkOpPtT & ptT)1459 void Dump(const SkOpPtT& ptT) {
1460     ptT.dump();
1461 }
1462 
DumpAll(const SkOpPtT & ptT)1463 void DumpAll(const SkOpPtT& ptT) {
1464     ptT.dumpAll();
1465 }
1466 
Dump(const SkOpSpanBase & spanBase)1467 void Dump(const SkOpSpanBase& spanBase) {
1468     spanBase.dump();
1469 }
1470 
DumpCoin(const SkOpSpanBase & spanBase)1471 void DumpCoin(const SkOpSpanBase& spanBase) {
1472     spanBase.dumpCoin();
1473 }
1474 
DumpAll(const SkOpSpanBase & spanBase)1475 void DumpAll(const SkOpSpanBase& spanBase) {
1476     spanBase.dumpAll();
1477 }
1478 
DumpCoin(const SkOpSpan & span)1479 void DumpCoin(const SkOpSpan& span) {
1480     span.dumpCoin();
1481 }
1482 
DumpSpan(const SkOpSpan & span)1483 bool DumpSpan(const SkOpSpan& span) {
1484     return span.dumpSpan();
1485 }
1486 
Dump(const SkDConic & conic)1487 void Dump(const SkDConic& conic) {
1488     conic.dump();
1489 }
1490 
DumpID(const SkDConic & conic,int id)1491 void DumpID(const SkDConic& conic, int id) {
1492     conic.dumpID(id);
1493 }
1494 
Dump(const SkDCubic & cubic)1495 void Dump(const SkDCubic& cubic) {
1496     cubic.dump();
1497 }
1498 
DumpID(const SkDCubic & cubic,int id)1499 void DumpID(const SkDCubic& cubic, int id) {
1500     cubic.dumpID(id);
1501 }
1502 
Dump(const SkDLine & line)1503 void Dump(const SkDLine& line) {
1504     line.dump();
1505 }
1506 
DumpID(const SkDLine & line,int id)1507 void DumpID(const SkDLine& line, int id) {
1508     line.dumpID(id);
1509 }
1510 
Dump(const SkDQuad & quad)1511 void Dump(const SkDQuad& quad) {
1512     quad.dump();
1513 }
1514 
DumpID(const SkDQuad & quad,int id)1515 void DumpID(const SkDQuad& quad, int id) {
1516     quad.dumpID(id);
1517 }
1518 
Dump(const SkDPoint & point)1519 void Dump(const SkDPoint& point) {
1520     point.dump();
1521 }
1522 
Dump(const SkOpAngle & angle)1523 void Dump(const SkOpAngle& angle) {
1524     angle.dump();
1525 }
1526