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 
DebugDumpDouble(double x)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 
DebugDumpFloat(float x)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 
DebugDumpHexFloat(float x)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
ValidWind(int wind)38 bool SkPathOpsDebug::ValidWind(int wind) {
39     return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF;
40 }
41 
WindingPrintf(int wind)42 void SkPathOpsDebug::WindingPrintf(int wind) {
43     if (wind == SK_MinS32) {
44         SkDebugf("?");
45     } else {
46         SkDebugf("%d", wind);
47     }
48 }
49 #endif
50 
dump() const51 void SkDConic::dump() const {
52     dumpInner();
53     SkDebugf("},\n");
54 }
55 
dumpID(int id) const56 void SkDConic::dumpID(int id) const {
57     dumpInner();
58     SkDebugf("} id=%d\n", id);
59 }
60 
dumpInner() const61 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 
dump() const72 void SkDCubic::dump() const {
73     this->dumpInner();
74     SkDebugf("}},\n");
75 }
76 
dumpID(int id) const77 void SkDCubic::dumpID(int id) const {
78     this->dumpInner();
79     SkDebugf("}} id=%d\n", id);
80 }
81 
double_is_NaN(double x)82 static inline bool double_is_NaN(double x) { return x != x; }
83 
dumpInner() const84 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 
dumpID(int id) const103 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 
dump() const126 void SkDLine::dump() const {
127     this->dumpInner();
128     SkDebugf("}},\n");
129 }
130 
dumpID(int id) const131 void SkDLine::dumpID(int id) const {
132     this->dumpInner();
133     SkDebugf("}} id=%d\n", id);
134 }
135 
dumpInner() const136 void SkDLine::dumpInner() const {
137     SkDebugf("{{");
138     fPts[0].dump();
139     SkDebugf(", ");
140     fPts[1].dump();
141 }
142 
dump() const143 void SkDPoint::dump() const {
144     SkDebugf("{");
145     DebugDumpDouble(fX);
146     SkDebugf(", ");
147     DebugDumpDouble(fY);
148     SkDebugf("}");
149 }
150 
Dump(const SkPoint & pt)151 void SkDPoint::Dump(const SkPoint& pt) {
152     SkDebugf("{");
153     DebugDumpFloat(pt.fX);
154     SkDebugf(", ");
155     DebugDumpFloat(pt.fY);
156     SkDebugf("}");
157 }
158 
DumpHex(const SkPoint & pt)159 void SkDPoint::DumpHex(const SkPoint& pt) {
160     SkDebugf("{");
161     DebugDumpHexFloat(pt.fX);
162     SkDebugf(", ");
163     DebugDumpHexFloat(pt.fY);
164     SkDebugf("}");
165 }
166 
dump() const167 void SkDQuad::dump() const {
168     dumpInner();
169     SkDebugf("}},\n");
170 }
171 
dumpID(int id) const172 void SkDQuad::dumpID(int id) const {
173     dumpInner();
174     SkDebugf("}} id=%d\n", id);
175 }
176 
dumpInner() const177 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 
dump() const187 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 
DebugAngleAngle(const SkOpAngle * angle,int id)201 const SkOpAngle* SkPathOpsDebug::DebugAngleAngle(const SkOpAngle* angle, int id) {
202     return angle->debugAngle(id);
203 }
204 
DebugAngleContour(SkOpAngle * angle,int id)205 SkOpContour* SkPathOpsDebug::DebugAngleContour(SkOpAngle* angle, int id) {
206     return angle->debugContour(id);
207 }
208 
DebugAnglePtT(const SkOpAngle * angle,int id)209 const SkOpPtT* SkPathOpsDebug::DebugAnglePtT(const SkOpAngle* angle, int id) {
210     return angle->debugPtT(id);
211 }
212 
DebugAngleSegment(const SkOpAngle * angle,int id)213 const SkOpSegment* SkPathOpsDebug::DebugAngleSegment(const SkOpAngle* angle, int id) {
214     return angle->debugSegment(id);
215 }
216 
DebugAngleSpan(const SkOpAngle * angle,int id)217 const SkOpSpanBase* SkPathOpsDebug::DebugAngleSpan(const SkOpAngle* angle, int id) {
218     return angle->debugSpan(id);
219 }
220 
DebugContourAngle(SkOpContour * contour,int id)221 const SkOpAngle* SkPathOpsDebug::DebugContourAngle(SkOpContour* contour, int id) {
222     return contour->debugAngle(id);
223 }
224 
DebugContourContour(SkOpContour * contour,int id)225 SkOpContour* SkPathOpsDebug::DebugContourContour(SkOpContour* contour, int id) {
226     return contour->debugContour(id);
227 }
228 
DebugContourPtT(SkOpContour * contour,int id)229 const SkOpPtT* SkPathOpsDebug::DebugContourPtT(SkOpContour* contour, int id) {
230     return contour->debugPtT(id);
231 }
232 
DebugContourSegment(SkOpContour * contour,int id)233 const SkOpSegment* SkPathOpsDebug::DebugContourSegment(SkOpContour* contour, int id) {
234     return contour->debugSegment(id);
235 }
236 
DebugContourSpan(SkOpContour * contour,int id)237 const SkOpSpanBase* SkPathOpsDebug::DebugContourSpan(SkOpContour* contour, int id) {
238     return contour->debugSpan(id);
239 }
240 
DebugPtTAngle(const SkOpPtT * ptT,int id)241 const SkOpAngle* SkPathOpsDebug::DebugPtTAngle(const SkOpPtT* ptT, int id) {
242     return ptT->debugAngle(id);
243 }
244 
DebugPtTContour(SkOpPtT * ptT,int id)245 SkOpContour* SkPathOpsDebug::DebugPtTContour(SkOpPtT* ptT, int id) {
246     return ptT->debugContour(id);
247 }
248 
DebugPtTPtT(const SkOpPtT * ptT,int id)249 const SkOpPtT* SkPathOpsDebug::DebugPtTPtT(const SkOpPtT* ptT, int id) {
250     return ptT->debugPtT(id);
251 }
252 
DebugPtTSegment(const SkOpPtT * ptT,int id)253 const SkOpSegment* SkPathOpsDebug::DebugPtTSegment(const SkOpPtT* ptT, int id) {
254     return ptT->debugSegment(id);
255 }
256 
DebugPtTSpan(const SkOpPtT * ptT,int id)257 const SkOpSpanBase* SkPathOpsDebug::DebugPtTSpan(const SkOpPtT* ptT, int id) {
258     return ptT->debugSpan(id);
259 }
260 
DebugSegmentAngle(const SkOpSegment * span,int id)261 const SkOpAngle* SkPathOpsDebug::DebugSegmentAngle(const SkOpSegment* span, int id) {
262     return span->debugAngle(id);
263 }
264 
DebugSegmentContour(SkOpSegment * span,int id)265 SkOpContour* SkPathOpsDebug::DebugSegmentContour(SkOpSegment* span, int id) {
266     return span->debugContour(id);
267 }
268 
DebugSegmentPtT(const SkOpSegment * span,int id)269 const SkOpPtT* SkPathOpsDebug::DebugSegmentPtT(const SkOpSegment* span, int id) {
270     return span->debugPtT(id);
271 }
272 
DebugSegmentSegment(const SkOpSegment * span,int id)273 const SkOpSegment* SkPathOpsDebug::DebugSegmentSegment(const SkOpSegment* span, int id) {
274     return span->debugSegment(id);
275 }
276 
DebugSegmentSpan(const SkOpSegment * span,int id)277 const SkOpSpanBase* SkPathOpsDebug::DebugSegmentSpan(const SkOpSegment* span, int id) {
278     return span->debugSpan(id);
279 }
280 
DebugSpanAngle(const SkOpSpanBase * span,int id)281 const SkOpAngle* SkPathOpsDebug::DebugSpanAngle(const SkOpSpanBase* span, int id) {
282     return span->debugAngle(id);
283 }
284 
DebugSpanContour(SkOpSpanBase * span,int id)285 SkOpContour* SkPathOpsDebug::DebugSpanContour(SkOpSpanBase* span, int id) {
286     return span->debugContour(id);
287 }
288 
DebugSpanPtT(const SkOpSpanBase * span,int id)289 const SkOpPtT* SkPathOpsDebug::DebugSpanPtT(const SkOpSpanBase* span, int id) {
290     return span->debugPtT(id);
291 }
292 
DebugSpanSegment(const SkOpSpanBase * span,int id)293 const SkOpSegment* SkPathOpsDebug::DebugSpanSegment(const SkOpSpanBase* span, int id) {
294     return span->debugSegment(id);
295 }
296 
DebugSpanSpan(const SkOpSpanBase * span,int id)297 const SkOpSpanBase* SkPathOpsDebug::DebugSpanSpan(const SkOpSpanBase* span, int id) {
298     return span->debugSpan(id);
299 }
300 
dumpContours() const301 void SkOpContour::dumpContours() const {
302     SkOpContour* contour = this->globalState()->contourHead();
303     do {
304         contour->dump();
305     } while ((contour = contour->next()));
306 }
307 
dumpContoursAll() const308 void SkOpContour::dumpContoursAll() const {
309     SkOpContour* contour = this->globalState()->contourHead();
310     do {
311         contour->dumpAll();
312     } while ((contour = contour->next()));
313 }
314 
dumpContoursAngles() const315 void SkOpContour::dumpContoursAngles() const {
316     SkOpContour* contour = this->globalState()->contourHead();
317     do {
318         contour->dumpAngles();
319     } while ((contour = contour->next()));
320 }
321 
dumpContoursPts() const322 void SkOpContour::dumpContoursPts() const {
323     SkOpContour* contour = this->globalState()->contourHead();
324     do {
325         contour->dumpPts();
326     } while ((contour = contour->next()));
327 }
328 
dumpContoursPt(int segmentID) const329 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 
dumpContoursSegment(int segmentID) const336 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 
dumpContoursSpan(int spanID) const343 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 
dumpContoursSpans() const350 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>
DebugSpan(const SkTSect<TCurve,OppCurve> * sect,int id)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);
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>
DebugT(const SkTSect<TCurve,OppCurve> * sect,double t)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);
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>
Dump(const SkTSect<TCurve,OppCurve> * sect)418 void Dump(const SkTSect<TCurve, OppCurve>* sect) {
419     sect->dump();
420 }
421 
422 void DontCallDumpTSect();
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>
DumpBoth(SkTSect<TCurve,OppCurve> * sect1,SkTSect<OppCurve,TCurve> * sect2)448 void DumpBoth(SkTSect<TCurve, OppCurve>* sect1, SkTSect<OppCurve, TCurve>* sect2) {
449     sect1->dumpBoth(sect2);
450 }
451 
452 void DontCallDumpBoth();
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>
DumpBounded(SkTSect<TCurve,OppCurve> * sect1,int id)478 void DumpBounded(SkTSect<TCurve, OppCurve>* sect1, int id) {
479     sect1->dumpBounded(id);
480 }
481 
482 void DontCallDumpBounded();
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>
DumpBounds(SkTSect<TCurve,OppCurve> * sect1)508 void DumpBounds(SkTSect<TCurve, OppCurve>* sect1) {
509     sect1->dumpBounds();
510 }
511 
512 void DontCallDumpBounds();
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>
DumpCoin(SkTSect<TCurve,OppCurve> * sect1)538 void DumpCoin(SkTSect<TCurve, OppCurve>* sect1) {
539     sect1->dumpCoin();
540 }
541 
542 void DontCallDumpCoin();
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>
DumpCoinCurves(SkTSect<TCurve,OppCurve> * sect1)568 void DumpCoinCurves(SkTSect<TCurve, OppCurve>* sect1) {
569     sect1->dumpCoinCurves();
570 }
571 
572 void DontCallDumpCoinCurves();
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>
DumpCurves(const SkTSect<TCurve,OppCurve> * sect)598 void DumpCurves(const SkTSect<TCurve, OppCurve>* sect) {
599     sect->dumpCurves();
600 }
601 
602 void DontCallDumpCurves();
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>
Dump(const SkTSpan<TCurve,OppCurve> * span)628 void Dump(const SkTSpan<TCurve, OppCurve>* span) {
629     span->dump();
630 }
631 
632 void DontCallDumpTSpan();
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>
DumpCoin(const SkTSpan<TCurve,OppCurve> * span)655 void DumpCoin(const SkTSpan<TCurve, OppCurve>* span) {
656     span->dumpCoin();
657 }
658 
659 void DontCallDumpSpanCoin();
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 
dumpTestCase(const SkDQuad & quad1,const SkDQuad & quad2,int testNo)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 
dumpTestTrailer()689 static void dumpTestTrailer() {
690     SkDebugf("</div>\n\n<script type=\"text/javascript\">\n\n");
691     SkDebugf("    var testDivs = [\n");
692 }
693 
dumpTestList(int testNo,double min)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 
DumpQ(const SkDQuad & quad1,const SkDQuad & quad2,int testNo)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 
DumpT(const SkDQuad & quad,double t)710 void DumpT(const SkDQuad& quad, double t) {
711     SkDLine line = {{quad.ptAtT(t), quad[0]}};
712     line.dump();
713 }
714 
debugAngle(int id) const715 const SkOpAngle* SkOpAngle::debugAngle(int id) const {
716     return this->segment()->debugAngle(id);
717 }
718 
debugContour(int id)719 SkOpContour* SkOpAngle::debugContour(int id) {
720     return this->segment()->debugContour(id);
721 }
722 
debugPtT(int id) const723 const SkOpPtT* SkOpAngle::debugPtT(int id) const {
724     return this->segment()->debugPtT(id);
725 }
726 
debugSegment(int id) const727 const SkOpSegment* SkOpAngle::debugSegment(int id) const {
728     return this->segment()->debugSegment(id);
729 }
730 
debugSign() const731 int SkOpAngle::debugSign() const {
732     SkASSERT(fStart->t() != fEnd->t());
733     return fStart->t() < fEnd->t() ? -1 : 1;
734 }
735 
debugSpan(int id) const736 const SkOpSpanBase* SkOpAngle::debugSpan(int id) const {
737     return this->segment()->debugSpan(id);
738 }
739 
dump() const740 void SkOpAngle::dump() const {
741     dumpOne(true);
742     SkDebugf("\n");
743 }
744 
dumpOne(bool functionHeader) const745 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 
dumpTo(const SkOpSegment * segment,const SkOpAngle * to) const784 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 
dumpCurves() const805 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 
dumpLoop() const814 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 
dumpTest() const824 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 
debugMatchID(int id) const837 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 
debugAngle(int id) const849 const SkOpAngle* SkOpPtT::debugAngle(int id) const {
850     return this->span()->debugAngle(id);
851 }
852 
debugContour(int id)853 SkOpContour* SkOpPtT::debugContour(int id) {
854     return this->span()->debugContour(id);
855 }
856 
debugPtT(int id) const857 const SkOpPtT* SkOpPtT::debugPtT(int id) const {
858     return this->span()->debugPtT(id);
859 }
860 
debugSegment(int id) const861 const SkOpSegment* SkOpPtT::debugSegment(int id) const {
862     return this->span()->debugSegment(id);
863 }
864 
debugSpan(int id) const865 const SkOpSpanBase* SkOpPtT::debugSpan(int id) const {
866     return this->span()->debugSpan(id);
867 }
868 
dump() const869 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 
dumpAll() const876 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 
dumpBase() const895 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 
debugAngle(int id) const900 const SkOpAngle* SkOpSpanBase::debugAngle(int id) const {
901     return this->segment()->debugAngle(id);
902 }
903 
debugContour(int id)904 SkOpContour* SkOpSpanBase::debugContour(int id) {
905     return this->segment()->debugContour(id);
906 }
907 
debugPtT(int id) const908 const SkOpPtT* SkOpSpanBase::debugPtT(int id) const {
909     return this->segment()->debugPtT(id);
910 }
911 
debugSegment(int id) const912 const SkOpSegment* SkOpSpanBase::debugSegment(int id) const {
913     return this->segment()->debugSegment(id);
914 }
915 
debugSpan(int id) const916 const SkOpSpanBase* SkOpSpanBase::debugSpan(int id) const {
917     return this->segment()->debugSpan(id);
918 }
919 
dump() const920 void SkOpSpanBase::dump() const {
921     this->dumpAll();
922     SkDebugf("\n");
923 }
924 
dumpAll() const925 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 
dumpBase() const933 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 
dumpCoin() const953 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 
dumpCoin() const964 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 
dumpSpan() const978 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 
debugAngle(int id) const997 const SkOpAngle* SkOpSegment::debugAngle(int id) const {
998     return this->contour()->debugAngle(id);
999 }
1000 
debugContour(int id)1001 SkOpContour* SkOpSegment::debugContour(int id) {
1002     return this->contour()->debugContour(id);
1003 }
1004 
debugPtT(int id) const1005 const SkOpPtT* SkOpSegment::debugPtT(int id) const {
1006     return this->contour()->debugPtT(id);
1007 }
1008 
debugSegment(int id) const1009 const SkOpSegment* SkOpSegment::debugSegment(int id) const {
1010     return this->contour()->debugSegment(id);
1011 }
1012 
debugSpan(int id) const1013 const SkOpSpanBase* SkOpSegment::debugSpan(int id) const {
1014     return this->contour()->debugSpan(id);
1015 }
1016 
dump() const1017 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 
dumpAll() const1031 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 
dumpAngles() const1042 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 
dumpCoin() const1059 void SkOpSegment::dumpCoin() const {
1060     const SkOpSpan* span = &fHead;
1061     do {
1062         span->dumpCoin();
1063     } while ((span = span->next()->upCastable()));
1064 }
1065 
dumpPtsInner() const1066 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 
dumpPts() const1084 void SkOpSegment::dumpPts() const {
1085     dumpPtsInner();
1086     SkDebugf("\n");
1087 }
1088 
dump() const1089 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 
dump() const1116 void SkOpCoincidence::dump() const {
1117     SkCoincidentSpans* span = fHead;
1118     while (span) {
1119         span->dump();
1120         span = span->fNext;
1121     }
1122 }
1123 
dump() const1124 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 
dumpAll() const1138 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 
dumpAngles() const1153 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 
dumpPt(int index) const1162 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 
dumpPts() const1171 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 
dumpPtsX() const1180 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 
dumpSegment(int index) const1191 void SkOpContour::dumpSegment(int index) const {
1192     debugSegment(index)->dump();
1193 }
1194 
dumpSegments(SkPathOp op) const1195 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 
dumpSpan(int index) const1209 void SkOpContour::dumpSpan(int index) const {
1210     debugSpan(index)->dump();
1211 }
1212 
dumpSpans() const1213 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 
dump() const1222 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
debugAngle(int id) const1233 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 
debugContour(int id)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 
debugPtT(int id) const1270 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 
debugSegment(int id) const1293 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 
debugSpan(int id) const1307 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