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