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