blob: 94664c1172d42cc6aa582ead337e6fa8e0fe24f6 [file] [log] [blame]
caryclark54359292015-03-26 07:52:43 -07001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/core/SkString.h"
9#include "include/private/SkMutex.h"
10#include "src/pathops/SkIntersectionHelper.h"
11#include "src/pathops/SkOpCoincidence.h"
12#include "src/pathops/SkOpContour.h"
13#include "src/pathops/SkOpSegment.h"
14#include "tests/PathOpsDebug.h"
15#include "tests/PathOpsTSectDebug.h"
commit-bot@chromium.org4431e772014-04-14 17:08:59 +000016
Cary Clarkf3949122018-08-07 16:38:21 -040017bool PathOpsDebug::gJson;
Cary Clarkda6289c2018-08-27 16:10:28 -040018bool PathOpsDebug::gMarkJsonFlaky;
Cary Clarkf3949122018-08-07 16:38:21 -040019bool PathOpsDebug::gOutFirst;
Cary Clark4533f3d2018-08-08 09:48:09 -040020bool PathOpsDebug::gCheckForDuplicateNames;
Cary Clark9c9611f2018-08-08 13:17:25 -040021bool PathOpsDebug::gOutputSVG;
Cary Clarkf3949122018-08-07 16:38:21 -040022FILE* PathOpsDebug::gOut;
23
commit-bot@chromium.org4431e772014-04-14 17:08:59 +000024inline void DebugDumpDouble(double x) {
25 if (x == floor(x)) {
26 SkDebugf("%.0f", x);
27 } else {
28 SkDebugf("%1.19g", x);
29 }
30}
31
32inline void DebugDumpFloat(float x) {
33 if (x == floorf(x)) {
34 SkDebugf("%.0f", x);
35 } else {
36 SkDebugf("%1.9gf", x);
37 }
38}
39
caryclark65f55312014-11-13 06:58:52 -080040inline void DebugDumpHexFloat(float x) {
41 SkDebugf("SkBits2Float(0x%08x)", SkFloat2Bits(x));
42}
caryclark19eb3b22014-07-18 05:08:14 -070043
commit-bot@chromium.org4431e772014-04-14 17:08:59 +000044// if not defined by PathOpsDebug.cpp ...
45#if !defined SK_DEBUG && FORCE_RELEASE
46bool SkPathOpsDebug::ValidWind(int wind) {
47 return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF;
48}
49
50void SkPathOpsDebug::WindingPrintf(int wind) {
51 if (wind == SK_MinS32) {
52 SkDebugf("?");
53 } else {
54 SkDebugf("%d", wind);
55 }
56}
57#endif
58
caryclark55888e42016-07-18 10:01:36 -070059static void DumpID(int id) {
60 SkDebugf("} ");
61 if (id >= 0) {
62 SkDebugf("id=%d", id);
63 }
64 SkDebugf("\n");
65}
66
caryclark1049f122015-04-20 08:31:59 -070067void SkDConic::dump() const {
caryclark54359292015-03-26 07:52:43 -070068 dumpInner();
caryclark1049f122015-04-20 08:31:59 -070069 SkDebugf("},\n");
70}
71
72void SkDConic::dumpID(int id) const {
73 dumpInner();
caryclark55888e42016-07-18 10:01:36 -070074 DumpID(id);
caryclark1049f122015-04-20 08:31:59 -070075}
76
77void SkDConic::dumpInner() const {
caryclark26ad22a2015-10-16 09:03:38 -070078 SkDebugf("{");
79 fPts.dumpInner();
80 SkDebugf("}}, %1.9gf", fWeight);
caryclark1049f122015-04-20 08:31:59 -070081}
82
83void SkDCubic::dump() const {
84 this->dumpInner();
caryclark54359292015-03-26 07:52:43 -070085 SkDebugf("}},\n");
reed0dc4dd62015-03-24 13:55:33 -070086}
87
caryclark54359292015-03-26 07:52:43 -070088void SkDCubic::dumpID(int id) const {
caryclark1049f122015-04-20 08:31:59 -070089 this->dumpInner();
caryclark55888e42016-07-18 10:01:36 -070090 SkDebugf("}");
91 DumpID(id);
reed0dc4dd62015-03-24 13:55:33 -070092}
93
caryclark54359292015-03-26 07:52:43 -070094static inline bool double_is_NaN(double x) { return x != x; }
95
96void SkDCubic::dumpInner() const {
97 SkDebugf("{{");
98 int index = 0;
reed0dc4dd62015-03-24 13:55:33 -070099 do {
caryclark54359292015-03-26 07:52:43 -0700100 if (index != 0) {
101 if (double_is_NaN(fPts[index].fX) && double_is_NaN(fPts[index].fY)) {
102 return;
reed0dc4dd62015-03-24 13:55:33 -0700103 }
caryclark54359292015-03-26 07:52:43 -0700104 SkDebugf(", ");
reed0dc4dd62015-03-24 13:55:33 -0700105 }
caryclark54359292015-03-26 07:52:43 -0700106 fPts[index].dump();
107 } while (++index < 3);
108 if (double_is_NaN(fPts[index].fX) && double_is_NaN(fPts[index].fY)) {
reed0dc4dd62015-03-24 13:55:33 -0700109 return;
110 }
caryclark54359292015-03-26 07:52:43 -0700111 SkDebugf(", ");
reed0dc4dd62015-03-24 13:55:33 -0700112 fPts[index].dump();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000113}
114
caryclark55888e42016-07-18 10:01:36 -0700115void SkDCurve::dump() const {
116 dumpID(-1);
117}
118
caryclark1049f122015-04-20 08:31:59 -0700119void SkDCurve::dumpID(int id) const {
120#ifndef SK_RELEASE
121 switch(fVerb) {
122 case SkPath::kLine_Verb:
123 fLine.dumpID(id);
124 break;
125 case SkPath::kQuad_Verb:
126 fQuad.dumpID(id);
127 break;
128 case SkPath::kConic_Verb:
129 fConic.dumpID(id);
130 break;
131 case SkPath::kCubic_Verb:
132 fCubic.dumpID(id);
133 break;
134 default:
135 SkASSERT(0);
136 }
137#else
138 fCubic.dumpID(id);
139#endif
140}
141
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000142void SkDLine::dump() const {
caryclark1049f122015-04-20 08:31:59 -0700143 this->dumpInner();
144 SkDebugf("}},\n");
145}
146
147void SkDLine::dumpID(int id) const {
148 this->dumpInner();
caryclark55888e42016-07-18 10:01:36 -0700149 SkDebugf("}");
150 DumpID(id);
caryclark1049f122015-04-20 08:31:59 -0700151}
152
153void SkDLine::dumpInner() const {
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000154 SkDebugf("{{");
155 fPts[0].dump();
156 SkDebugf(", ");
157 fPts[1].dump();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000158}
159
160void SkDPoint::dump() const {
161 SkDebugf("{");
162 DebugDumpDouble(fX);
163 SkDebugf(", ");
164 DebugDumpDouble(fY);
165 SkDebugf("}");
166}
167
168void SkDPoint::Dump(const SkPoint& pt) {
169 SkDebugf("{");
170 DebugDumpFloat(pt.fX);
171 SkDebugf(", ");
172 DebugDumpFloat(pt.fY);
173 SkDebugf("}");
174}
175
caryclark65f55312014-11-13 06:58:52 -0800176void SkDPoint::DumpHex(const SkPoint& pt) {
177 SkDebugf("{");
178 DebugDumpHexFloat(pt.fX);
179 SkDebugf(", ");
180 DebugDumpHexFloat(pt.fY);
181 SkDebugf("}");
182}
183
184void SkDQuad::dump() const {
caryclark54359292015-03-26 07:52:43 -0700185 dumpInner();
186 SkDebugf("}},\n");
caryclark65f55312014-11-13 06:58:52 -0800187}
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000188
caryclark54359292015-03-26 07:52:43 -0700189void SkDQuad::dumpID(int id) const {
190 dumpInner();
caryclark55888e42016-07-18 10:01:36 -0700191 SkDebugf("}");
192 DumpID(id);
caryclark54359292015-03-26 07:52:43 -0700193}
194
195void SkDQuad::dumpInner() const {
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000196 SkDebugf("{{");
197 int index = 0;
198 do {
199 fPts[index].dump();
200 SkDebugf(", ");
201 } while (++index < 2);
202 fPts[index].dump();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000203}
204
caryclark54359292015-03-26 07:52:43 -0700205void SkIntersections::dump() const {
206 SkDebugf("used=%d of %d", fUsed, fMax);
207 for (int index = 0; index < fUsed; ++index) {
208 SkDebugf(" t=(%s%1.9g,%s%1.9g) pt=(%1.9g,%1.9g)",
209 fIsCoincident[0] & (1 << index) ? "*" : "", fT[0][index],
210 fIsCoincident[1] & (1 << index) ? "*" : "", fT[1][index],
211 fPt[index].fX, fPt[index].fY);
212 if (index < 2 && fNearlySame[index]) {
213 SkDebugf(" pt2=(%1.9g,%1.9g)",fPt2[index].fX, fPt2[index].fY);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000214 }
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000215 }
216 SkDebugf("\n");
217}
218
Cary Clark8762fb62018-10-16 16:06:24 -0400219const SkOpAngle* AngleAngle(const SkOpAngle* angle, int id) {
caryclark54359292015-03-26 07:52:43 -0700220 return angle->debugAngle(id);
221}
222
Cary Clark8762fb62018-10-16 16:06:24 -0400223SkOpContour* AngleContour(SkOpAngle* angle, int id) {
caryclark54359292015-03-26 07:52:43 -0700224 return angle->debugContour(id);
225}
226
Cary Clark8762fb62018-10-16 16:06:24 -0400227const SkOpPtT* AnglePtT(const SkOpAngle* angle, int id) {
caryclark54359292015-03-26 07:52:43 -0700228 return angle->debugPtT(id);
229}
230
Cary Clark8762fb62018-10-16 16:06:24 -0400231const SkOpSegment* AngleSegment(const SkOpAngle* angle, int id) {
caryclark54359292015-03-26 07:52:43 -0700232 return angle->debugSegment(id);
233}
234
Cary Clark8762fb62018-10-16 16:06:24 -0400235const SkOpSpanBase* AngleSpan(const SkOpAngle* angle, int id) {
caryclark54359292015-03-26 07:52:43 -0700236 return angle->debugSpan(id);
237}
238
Cary Clark8762fb62018-10-16 16:06:24 -0400239const SkOpAngle* ContourAngle(SkOpContour* contour, int id) {
caryclark54359292015-03-26 07:52:43 -0700240 return contour->debugAngle(id);
241}
242
Cary Clark8762fb62018-10-16 16:06:24 -0400243SkOpContour* ContourContour(SkOpContour* contour, int id) {
caryclark54359292015-03-26 07:52:43 -0700244 return contour->debugContour(id);
245}
246
Cary Clark8762fb62018-10-16 16:06:24 -0400247const SkOpPtT* ContourPtT(SkOpContour* contour, int id) {
caryclark54359292015-03-26 07:52:43 -0700248 return contour->debugPtT(id);
249}
250
Cary Clark8762fb62018-10-16 16:06:24 -0400251const SkOpSegment* ContourSegment(SkOpContour* contour, int id) {
caryclark54359292015-03-26 07:52:43 -0700252 return contour->debugSegment(id);
253}
254
Cary Clark8762fb62018-10-16 16:06:24 -0400255const SkOpSpanBase* ContourSpan(SkOpContour* contour, int id) {
caryclark54359292015-03-26 07:52:43 -0700256 return contour->debugSpan(id);
257}
258
Cary Clark8762fb62018-10-16 16:06:24 -0400259const SkOpAngle* CoincidenceAngle(SkOpCoincidence* coin, int id) {
caryclark27c8eb82015-07-06 11:38:33 -0700260 return coin->debugAngle(id);
261}
262
Cary Clark8762fb62018-10-16 16:06:24 -0400263SkOpContour* CoincidenceContour(SkOpCoincidence* coin, int id) {
caryclark27c8eb82015-07-06 11:38:33 -0700264 return coin->debugContour(id);
265}
266
Cary Clark8762fb62018-10-16 16:06:24 -0400267const SkOpPtT* CoincidencePtT(SkOpCoincidence* coin, int id) {
caryclark27c8eb82015-07-06 11:38:33 -0700268 return coin->debugPtT(id);
269}
270
Cary Clark8762fb62018-10-16 16:06:24 -0400271const SkOpSegment* CoincidenceSegment(SkOpCoincidence* coin, int id) {
caryclark27c8eb82015-07-06 11:38:33 -0700272 return coin->debugSegment(id);
273}
274
Cary Clark8762fb62018-10-16 16:06:24 -0400275const SkOpSpanBase* CoincidenceSpan(SkOpCoincidence* coin, int id) {
caryclark27c8eb82015-07-06 11:38:33 -0700276 return coin->debugSpan(id);
277}
278
Cary Clark8762fb62018-10-16 16:06:24 -0400279const SkOpAngle* PtTAngle(const SkOpPtT* ptT, int id) {
caryclark54359292015-03-26 07:52:43 -0700280 return ptT->debugAngle(id);
281}
282
Cary Clark8762fb62018-10-16 16:06:24 -0400283SkOpContour* PtTContour(SkOpPtT* ptT, int id) {
caryclark54359292015-03-26 07:52:43 -0700284 return ptT->debugContour(id);
285}
286
Cary Clark8762fb62018-10-16 16:06:24 -0400287const SkOpPtT* PtTPtT(const SkOpPtT* ptT, int id) {
caryclark54359292015-03-26 07:52:43 -0700288 return ptT->debugPtT(id);
289}
290
Cary Clark8762fb62018-10-16 16:06:24 -0400291const SkOpSegment* PtTSegment(const SkOpPtT* ptT, int id) {
caryclark54359292015-03-26 07:52:43 -0700292 return ptT->debugSegment(id);
293}
294
Cary Clark8762fb62018-10-16 16:06:24 -0400295const SkOpSpanBase* PtTSpan(const SkOpPtT* ptT, int id) {
caryclark54359292015-03-26 07:52:43 -0700296 return ptT->debugSpan(id);
297}
298
Cary Clark8762fb62018-10-16 16:06:24 -0400299const SkOpAngle* SegmentAngle(const SkOpSegment* span, int id) {
caryclark54359292015-03-26 07:52:43 -0700300 return span->debugAngle(id);
301}
302
Cary Clark8762fb62018-10-16 16:06:24 -0400303SkOpContour* SegmentContour(SkOpSegment* span, int id) {
caryclark54359292015-03-26 07:52:43 -0700304 return span->debugContour(id);
305}
306
Cary Clark8762fb62018-10-16 16:06:24 -0400307const SkOpPtT* SegmentPtT(const SkOpSegment* span, int id) {
caryclark54359292015-03-26 07:52:43 -0700308 return span->debugPtT(id);
309}
310
Cary Clark8762fb62018-10-16 16:06:24 -0400311const SkOpSegment* SegmentSegment(const SkOpSegment* span, int id) {
caryclark54359292015-03-26 07:52:43 -0700312 return span->debugSegment(id);
313}
314
Cary Clark8762fb62018-10-16 16:06:24 -0400315const SkOpSpanBase* SegmentSpan(const SkOpSegment* span, int id) {
caryclark54359292015-03-26 07:52:43 -0700316 return span->debugSpan(id);
317}
318
Cary Clark8762fb62018-10-16 16:06:24 -0400319const SkOpAngle* SpanAngle(const SkOpSpanBase* span, int id) {
caryclark54359292015-03-26 07:52:43 -0700320 return span->debugAngle(id);
321}
322
Cary Clark8762fb62018-10-16 16:06:24 -0400323SkOpContour* SpanContour(SkOpSpanBase* span, int id) {
caryclark54359292015-03-26 07:52:43 -0700324 return span->debugContour(id);
325}
326
Cary Clark8762fb62018-10-16 16:06:24 -0400327const SkOpPtT* SpanPtT(const SkOpSpanBase* span, int id) {
caryclark54359292015-03-26 07:52:43 -0700328 return span->debugPtT(id);
329}
330
Cary Clark8762fb62018-10-16 16:06:24 -0400331const SkOpSegment* SpanSegment(const SkOpSpanBase* span, int id) {
caryclark54359292015-03-26 07:52:43 -0700332 return span->debugSegment(id);
333}
334
Cary Clark8762fb62018-10-16 16:06:24 -0400335const SkOpSpanBase* SpanSpan(const SkOpSpanBase* span, int id) {
caryclark54359292015-03-26 07:52:43 -0700336 return span->debugSpan(id);
337}
338
Cary Clarkab87d7a2016-10-04 10:01:04 -0400339#if DEBUG_COIN
340void SkPathOpsDebug::DumpCoinDict() {
Cary Clarkb8421ed2018-03-14 15:55:02 -0400341 SkPathOpsDebug::gCoinSumChangedDict.dump("unused coin algorithm", false);
342 SkPathOpsDebug::gCoinSumVisitedDict.dump("visited coin function", true);
Cary Clarkab87d7a2016-10-04 10:01:04 -0400343}
344
345void SkPathOpsDebug::CoinDict::dump(const char* str, bool visitCheck) const {
346 int count = fDict.count();
347 for (int index = 0; index < count; ++index) {
348 const auto& entry = fDict[index];
349 if (visitCheck || entry.fGlitchType == kUninitialized_Glitch) {
350 SkDebugf("%s %s : line %d iteration %d", str, entry.fFunctionName,
351 entry.fLineNumber, entry.fIteration);
352 DumpGlitchType(entry.fGlitchType);
353 SkDebugf("\n");
354 }
355 }
356}
357#endif
358
caryclark624637c2015-05-11 07:21:27 -0700359void SkOpContour::dumpContours() const {
360 SkOpContour* contour = this->globalState()->contourHead();
361 do {
362 contour->dump();
363 } while ((contour = contour->next()));
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000364}
365
caryclark624637c2015-05-11 07:21:27 -0700366void SkOpContour::dumpContoursAll() const {
367 SkOpContour* contour = this->globalState()->contourHead();
368 do {
369 contour->dumpAll();
370 } while ((contour = contour->next()));
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000371}
372
caryclark624637c2015-05-11 07:21:27 -0700373void SkOpContour::dumpContoursAngles() const {
374 SkOpContour* contour = this->globalState()->contourHead();
375 do {
376 contour->dumpAngles();
377 } while ((contour = contour->next()));
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000378}
379
caryclark624637c2015-05-11 07:21:27 -0700380void SkOpContour::dumpContoursPts() const {
381 SkOpContour* contour = this->globalState()->contourHead();
382 do {
383 contour->dumpPts();
384 } while ((contour = contour->next()));
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000385}
386
caryclark624637c2015-05-11 07:21:27 -0700387void SkOpContour::dumpContoursPt(int segmentID) const {
388 SkOpContour* contour = this->globalState()->contourHead();
389 do {
390 contour->dumpPt(segmentID);
391 } while ((contour = contour->next()));
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000392}
393
caryclark624637c2015-05-11 07:21:27 -0700394void SkOpContour::dumpContoursSegment(int segmentID) const {
395 SkOpContour* contour = this->globalState()->contourHead();
396 do {
397 contour->dumpSegment(segmentID);
398 } while ((contour = contour->next()));
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000399}
400
caryclark624637c2015-05-11 07:21:27 -0700401void SkOpContour::dumpContoursSpan(int spanID) const {
402 SkOpContour* contour = this->globalState()->contourHead();
403 do {
404 contour->dumpSpan(spanID);
405 } while ((contour = contour->next()));
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000406}
407
caryclark624637c2015-05-11 07:21:27 -0700408void SkOpContour::dumpContoursSpans() const {
409 SkOpContour* contour = this->globalState()->contourHead();
410 do {
411 contour->dumpSpans();
412 } while ((contour = contour->next()));
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000413}
414
Cary Clark8762fb62018-10-16 16:06:24 -0400415#ifdef SK_DEBUG
416const SkTSpan* DebugSpan(const SkTSect* sect, int id) {
caryclark54359292015-03-26 07:52:43 -0700417 return sect->debugSpan(id);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000418}
419
Cary Clark8762fb62018-10-16 16:06:24 -0400420const SkTSpan* DebugT(const SkTSect* sect, double t) {
caryclark54359292015-03-26 07:52:43 -0700421 return sect->debugT(t);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000422}
Cary Clarkb2c7d842018-10-16 18:16:59 +0000423#endif
Cary Clarkb2c7d842018-10-16 18:16:59 +0000424
Cary Clark8762fb62018-10-16 16:06:24 -0400425void Dump(const SkTSect* sect) {
caryclark54359292015-03-26 07:52:43 -0700426 sect->dump();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000427}
428
Cary Clark8762fb62018-10-16 16:06:24 -0400429void DumpBoth(SkTSect* sect1, SkTSect* sect2) {
caryclark54359292015-03-26 07:52:43 -0700430 sect1->dumpBoth(sect2);
caryclarkdac1d172014-06-17 05:15:38 -0700431}
432
Cary Clark8762fb62018-10-16 16:06:24 -0400433void DumpBounded(SkTSect* sect1, int id) {
caryclark1049f122015-04-20 08:31:59 -0700434 sect1->dumpBounded(id);
435}
436
Cary Clark8762fb62018-10-16 16:06:24 -0400437void DumpBounds(SkTSect* sect1) {
caryclark1049f122015-04-20 08:31:59 -0700438 sect1->dumpBounds();
439}
440
Cary Clark8762fb62018-10-16 16:06:24 -0400441void DumpCoin(SkTSect* sect1) {
caryclark54359292015-03-26 07:52:43 -0700442 sect1->dumpCoin();
caryclarkdac1d172014-06-17 05:15:38 -0700443}
444
Cary Clark8762fb62018-10-16 16:06:24 -0400445void DumpCoinCurves(SkTSect* sect1) {
caryclark54359292015-03-26 07:52:43 -0700446 sect1->dumpCoinCurves();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000447}
448
Cary Clark8762fb62018-10-16 16:06:24 -0400449void DumpCurves(const SkTSect* sect) {
caryclark54359292015-03-26 07:52:43 -0700450 sect->dumpCurves();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000451}
452
Cary Clark8762fb62018-10-16 16:06:24 -0400453void Dump(const SkTSpan* span) {
caryclark1049f122015-04-20 08:31:59 -0700454 span->dump();
455}
456
Cary Clark8762fb62018-10-16 16:06:24 -0400457void DumpAll(const SkTSpan* span) {
caryclark26ad22a2015-10-16 09:03:38 -0700458 span->dumpAll();
459}
460
Cary Clark8762fb62018-10-16 16:06:24 -0400461void DumpBounded(const SkTSpan* span) {
caryclark26ad22a2015-10-16 09:03:38 -0700462 span->dumpBounded(0);
463}
464
Cary Clark8762fb62018-10-16 16:06:24 -0400465void DumpCoin(const SkTSpan* span) {
caryclark1049f122015-04-20 08:31:59 -0700466 span->dumpCoin();
467}
468
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000469static void dumpTestCase(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) {
caryclark54359292015-03-26 07:52:43 -0700470 SkDebugf("\n<div id=\"quad%d\">\n", testNo);
471 quad1.dumpInner();
472 SkDebugf("}}, ");
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000473 quad2.dump();
474 SkDebugf("</div>\n\n");
475}
476
477static void dumpTestTrailer() {
478 SkDebugf("</div>\n\n<script type=\"text/javascript\">\n\n");
479 SkDebugf(" var testDivs = [\n");
480}
481
482static void dumpTestList(int testNo, double min) {
483 SkDebugf(" quad%d,", testNo);
484 if (min > 0) {
485 SkDebugf(" // %1.9g", min);
486 }
487 SkDebugf("\n");
488}
489
490void DumpQ(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) {
491 SkDebugf("\n");
492 dumpTestCase(quad1, quad2, testNo);
493 dumpTestTrailer();
494 dumpTestList(testNo, 0);
495 SkDebugf("\n");
496}
497
498void DumpT(const SkDQuad& quad, double t) {
499 SkDLine line = {{quad.ptAtT(t), quad[0]}};
500 line.dump();
501}
caryclark54359292015-03-26 07:52:43 -0700502
503const SkOpAngle* SkOpAngle::debugAngle(int id) const {
504 return this->segment()->debugAngle(id);
505}
506
caryclark55888e42016-07-18 10:01:36 -0700507const SkOpCoincidence* SkOpAngle::debugCoincidence() const {
508 return this->segment()->debugCoincidence();
509}
510
caryclark30b9fdd2016-08-31 14:36:29 -0700511SkOpContour* SkOpAngle::debugContour(int id) const {
caryclark54359292015-03-26 07:52:43 -0700512 return this->segment()->debugContour(id);
513}
514
515const SkOpPtT* SkOpAngle::debugPtT(int id) const {
516 return this->segment()->debugPtT(id);
517}
518
519const SkOpSegment* SkOpAngle::debugSegment(int id) const {
520 return this->segment()->debugSegment(id);
521}
522
caryclark624637c2015-05-11 07:21:27 -0700523int SkOpAngle::debugSign() const {
524 SkASSERT(fStart->t() != fEnd->t());
525 return fStart->t() < fEnd->t() ? -1 : 1;
526}
527
caryclark54359292015-03-26 07:52:43 -0700528const SkOpSpanBase* SkOpAngle::debugSpan(int id) const {
529 return this->segment()->debugSpan(id);
530}
531
532void SkOpAngle::dump() const {
533 dumpOne(true);
534 SkDebugf("\n");
535}
536
537void SkOpAngle::dumpOne(bool functionHeader) const {
538// fSegment->debugValidate();
539 const SkOpSegment* segment = this->segment();
540 const SkOpSpan& mSpan = *fStart->starter(fEnd);
541 if (functionHeader) {
542 SkDebugf("%s ", __FUNCTION__);
543 }
544 SkDebugf("[%d", segment->debugID());
545 SkDebugf("/%d", debugID());
546 SkDebugf("] next=");
547 if (fNext) {
548 SkDebugf("%d", fNext->fStart->segment()->debugID());
549 SkDebugf("/%d", fNext->debugID());
550 } else {
551 SkDebugf("?");
552 }
553 SkDebugf(" sect=%d/%d ", fSectorStart, fSectorEnd);
554 SkDebugf(" s=%1.9g [%d] e=%1.9g [%d]", fStart->t(), fStart->debugID(),
555 fEnd->t(), fEnd->debugID());
caryclark624637c2015-05-11 07:21:27 -0700556 SkDebugf(" sgn=%d windVal=%d", this->debugSign(), mSpan.windValue());
caryclark54359292015-03-26 07:52:43 -0700557
558 SkDebugf(" windSum=");
559 SkPathOpsDebug::WindingPrintf(mSpan.windSum());
560 if (mSpan.oppValue() != 0 || mSpan.oppSum() != SK_MinS32) {
561 SkDebugf(" oppVal=%d", mSpan.oppValue());
562 SkDebugf(" oppSum=");
563 SkPathOpsDebug::WindingPrintf(mSpan.oppSum());
564 }
565 if (mSpan.done()) {
566 SkDebugf(" done");
567 }
568 if (unorderable()) {
569 SkDebugf(" unorderable");
570 }
571 if (segment->operand()) {
572 SkDebugf(" operand");
573 }
caryclark54359292015-03-26 07:52:43 -0700574}
575
576void SkOpAngle::dumpTo(const SkOpSegment* segment, const SkOpAngle* to) const {
577 const SkOpAngle* first = this;
578 const SkOpAngle* next = this;
579 const char* indent = "";
580 do {
581 SkDebugf("%s", indent);
582 next->dumpOne(false);
583 if (segment == next->fStart->segment()) {
584 if (this == fNext) {
585 SkDebugf(" << from");
586 }
587 if (to == fNext) {
588 SkDebugf(" << to");
589 }
590 }
591 SkDebugf("\n");
592 indent = " ";
593 next = next->fNext;
594 } while (next && next != first);
595}
596
597void SkOpAngle::dumpCurves() const {
598 const SkOpAngle* first = this;
599 const SkOpAngle* next = this;
600 do {
caryclarkeed356d2016-09-14 07:18:20 -0700601 next->fPart.fCurve.dumpID(next->segment()->debugID());
caryclark54359292015-03-26 07:52:43 -0700602 next = next->fNext;
603 } while (next && next != first);
604}
605
606void SkOpAngle::dumpLoop() const {
607 const SkOpAngle* first = this;
608 const SkOpAngle* next = this;
609 do {
610 next->dumpOne(false);
611 SkDebugf("\n");
612 next = next->fNext;
613 } while (next && next != first);
614}
615
616void SkOpAngle::dumpTest() const {
617 const SkOpAngle* first = this;
618 const SkOpAngle* next = this;
619 do {
620 SkDebugf("{ ");
621 SkOpSegment* segment = next->segment();
622 segment->dumpPts();
623 SkDebugf(", %d, %1.9g, %1.9g, {} },\n", SkPathOpsVerbToPoints(segment->verb()) + 1,
624 next->start()->t(), next->end()->t());
625 next = next->fNext;
626 } while (next && next != first);
627}
628
629bool SkOpPtT::debugMatchID(int id) const {
630 int limit = this->debugLoopLimit(false);
631 int loop = 0;
632 const SkOpPtT* ptT = this;
633 do {
634 if (ptT->debugID() == id) {
635 return true;
636 }
637 } while ((!limit || ++loop <= limit) && (ptT = ptT->next()) && ptT != this);
638 return false;
639}
640
641const SkOpAngle* SkOpPtT::debugAngle(int id) const {
642 return this->span()->debugAngle(id);
643}
644
caryclark30b9fdd2016-08-31 14:36:29 -0700645SkOpContour* SkOpPtT::debugContour(int id) const {
caryclark54359292015-03-26 07:52:43 -0700646 return this->span()->debugContour(id);
647}
648
caryclark55888e42016-07-18 10:01:36 -0700649const SkOpCoincidence* SkOpPtT::debugCoincidence() const {
650 return this->span()->debugCoincidence();
651}
652
caryclark54359292015-03-26 07:52:43 -0700653const SkOpPtT* SkOpPtT::debugPtT(int id) const {
654 return this->span()->debugPtT(id);
655}
656
657const SkOpSegment* SkOpPtT::debugSegment(int id) const {
658 return this->span()->debugSegment(id);
659}
660
661const SkOpSpanBase* SkOpPtT::debugSpan(int id) const {
662 return this->span()->debugSpan(id);
663}
664
665void SkOpPtT::dump() const {
666 SkDebugf("seg=%d span=%d ptT=%d",
667 this->segment()->debugID(), this->span()->debugID(), this->debugID());
668 this->dumpBase();
669 SkDebugf("\n");
670}
671
672void SkOpPtT::dumpAll() const {
673 contour()->indentDump();
674 const SkOpPtT* next = this;
675 int limit = debugLoopLimit(true);
676 int loop = 0;
677 do {
678 SkDebugf("%.*s", contour()->debugIndent(), " ");
679 SkDebugf("seg=%d span=%d ptT=%d",
680 next->segment()->debugID(), next->span()->debugID(), next->debugID());
681 next->dumpBase();
682 SkDebugf("\n");
683 if (limit && ++loop >= limit) {
684 SkDebugf("*** abort loop ***\n");
685 break;
686 }
687 } while ((next = next->fNext) && next != this);
688 contour()->outdentDump();
689}
690
691void SkOpPtT::dumpBase() const {
caryclark55888e42016-07-18 10:01:36 -0700692 SkDebugf(" t=%1.9g pt=(%1.9g,%1.9g)%s%s%s", this->fT, this->fPt.fX, this->fPt.fY,
693 this->fCoincident ? " coin" : "",
caryclark54359292015-03-26 07:52:43 -0700694 this->fDuplicatePt ? " dup" : "", this->fDeleted ? " deleted" : "");
695}
696
697const SkOpAngle* SkOpSpanBase::debugAngle(int id) const {
698 return this->segment()->debugAngle(id);
699}
700
caryclark55888e42016-07-18 10:01:36 -0700701const SkOpCoincidence* SkOpSpanBase::debugCoincidence() const {
702 return this->segment()->debugCoincidence();
703}
704
caryclark30b9fdd2016-08-31 14:36:29 -0700705SkOpContour* SkOpSpanBase::debugContour(int id) const {
caryclark54359292015-03-26 07:52:43 -0700706 return this->segment()->debugContour(id);
707}
708
709const SkOpPtT* SkOpSpanBase::debugPtT(int id) const {
710 return this->segment()->debugPtT(id);
711}
712
713const SkOpSegment* SkOpSpanBase::debugSegment(int id) const {
714 return this->segment()->debugSegment(id);
715}
716
717const SkOpSpanBase* SkOpSpanBase::debugSpan(int id) const {
718 return this->segment()->debugSpan(id);
719}
720
721void SkOpSpanBase::dump() const {
caryclark55888e42016-07-18 10:01:36 -0700722 this->dumpHead();
723 this->fPtT.dump();
caryclark54359292015-03-26 07:52:43 -0700724}
725
caryclark55888e42016-07-18 10:01:36 -0700726void SkOpSpanBase::dumpHead() const {
caryclark54359292015-03-26 07:52:43 -0700727 SkDebugf("%.*s", contour()->debugIndent(), " ");
728 SkDebugf("seg=%d span=%d", this->segment()->debugID(), this->debugID());
729 this->dumpBase();
730 SkDebugf("\n");
caryclark55888e42016-07-18 10:01:36 -0700731}
732
733void SkOpSpanBase::dumpAll() const {
734 this->dumpHead();
caryclark54359292015-03-26 07:52:43 -0700735 this->fPtT.dumpAll();
736}
737
738void SkOpSpanBase::dumpBase() const {
739 if (this->fAligned) {
740 SkDebugf(" aligned");
741 }
742 if (this->fChased) {
743 SkDebugf(" chased");
744 }
caryclark55888e42016-07-18 10:01:36 -0700745#ifdef SK_DEBUG
caryclark30b9fdd2016-08-31 14:36:29 -0700746 if (this->fDebugDeleted) {
caryclark55888e42016-07-18 10:01:36 -0700747 SkDebugf(" deleted");
748 }
749#endif
caryclark54359292015-03-26 07:52:43 -0700750 if (!this->final()) {
751 this->upCast()->dumpSpan();
752 }
753 const SkOpSpanBase* coin = this->coinEnd();
754 if (this != coin) {
755 SkDebugf(" coinEnd seg/span=%d/%d", coin->segment()->debugID(), coin->debugID());
756 } else if (this->final() || !this->upCast()->isCoincident()) {
757 const SkOpPtT* oPt = this->ptT()->next();
758 SkDebugf(" seg/span=%d/%d", oPt->segment()->debugID(), oPt->span()->debugID());
759 }
caryclark08bc8482015-04-24 09:08:57 -0700760 SkDebugf(" adds=%d", fSpanAdds);
caryclark54359292015-03-26 07:52:43 -0700761}
762
763void SkOpSpanBase::dumpCoin() const {
764 const SkOpSpan* span = this->upCastable();
765 if (!span) {
766 return;
767 }
768 if (!span->isCoincident()) {
769 return;
770 }
771 span->dumpCoin();
772}
773
774void SkOpSpan::dumpCoin() const {
775 const SkOpSpan* coincident = fCoincident;
776 bool ok = debugCoinLoopCheck();
777 this->dump();
778 int loop = 0;
779 do {
780 coincident->dump();
781 if (!ok && ++loop > 10) {
782 SkDebugf("*** abort loop ***\n");
783 break;
784 }
785 } while ((coincident = coincident->fCoincident) != this);
786}
787
788bool SkOpSpan::dumpSpan() const {
789 SkOpSpan* coin = fCoincident;
790 if (this != coin) {
791 SkDebugf(" coinStart seg/span=%d/%d", coin->segment()->debugID(), coin->debugID());
792 }
793 SkDebugf(" windVal=%d", this->windValue());
794 SkDebugf(" windSum=");
795 SkPathOpsDebug::WindingPrintf(this->windSum());
796 if (this->oppValue() != 0 || this->oppSum() != SK_MinS32) {
797 SkDebugf(" oppVal=%d", this->oppValue());
798 SkDebugf(" oppSum=");
799 SkPathOpsDebug::WindingPrintf(this->oppSum());
800 }
801 if (this->done()) {
802 SkDebugf(" done");
803 }
804 return this != coin;
805}
806
807const SkOpAngle* SkOpSegment::debugAngle(int id) const {
808 return this->contour()->debugAngle(id);
809}
810
caryclark55888e42016-07-18 10:01:36 -0700811const SkOpCoincidence* SkOpSegment::debugCoincidence() const {
812 return this->contour()->debugCoincidence();
813}
814
caryclark30b9fdd2016-08-31 14:36:29 -0700815SkOpContour* SkOpSegment::debugContour(int id) const {
caryclark54359292015-03-26 07:52:43 -0700816 return this->contour()->debugContour(id);
817}
818
819const SkOpPtT* SkOpSegment::debugPtT(int id) const {
820 return this->contour()->debugPtT(id);
821}
822
823const SkOpSegment* SkOpSegment::debugSegment(int id) const {
824 return this->contour()->debugSegment(id);
825}
826
827const SkOpSpanBase* SkOpSegment::debugSpan(int id) const {
828 return this->contour()->debugSpan(id);
829}
830
831void SkOpSegment::dump() const {
832 SkDebugf("%.*s", contour()->debugIndent(), " ");
833 this->dumpPts();
834 const SkOpSpanBase* span = &fHead;
835 contour()->indentDump();
836 do {
837 SkDebugf("%.*s span=%d ", contour()->debugIndent(), " ", span->debugID());
838 span->ptT()->dumpBase();
839 span->dumpBase();
840 SkDebugf("\n");
841 } while (!span->final() && (span = span->upCast()->next()));
842 contour()->outdentDump();
843}
844
845void SkOpSegment::dumpAll() const {
846 SkDebugf("%.*s", contour()->debugIndent(), " ");
847 this->dumpPts();
848 const SkOpSpanBase* span = &fHead;
849 contour()->indentDump();
850 do {
851 span->dumpAll();
852 } while (!span->final() && (span = span->upCast()->next()));
853 contour()->outdentDump();
854}
855
856void SkOpSegment::dumpAngles() const {
857 SkDebugf("seg=%d\n", debugID());
858 const SkOpSpanBase* span = &fHead;
859 do {
860 const SkOpAngle* fAngle = span->fromAngle();
halcanary96fcdcc2015-08-27 07:41:13 -0700861 const SkOpAngle* tAngle = span->final() ? nullptr : span->upCast()->toAngle();
caryclark54359292015-03-26 07:52:43 -0700862 if (fAngle) {
863 SkDebugf(" span=%d from=%d ", span->debugID(), fAngle->debugID());
864 fAngle->dumpTo(this, tAngle);
865 }
866 if (tAngle) {
867 SkDebugf(" span=%d to=%d ", span->debugID(), tAngle->debugID());
868 tAngle->dumpTo(this, fAngle);
869 }
870 } while (!span->final() && (span = span->upCast()->next()));
871}
872
873void SkOpSegment::dumpCoin() const {
874 const SkOpSpan* span = &fHead;
875 do {
876 span->dumpCoin();
877 } while ((span = span->next()->upCastable()));
878}
879
caryclark26ad22a2015-10-16 09:03:38 -0700880void SkOpSegment::dumpPtsInner(const char* prefix) const {
caryclark54359292015-03-26 07:52:43 -0700881 int last = SkPathOpsVerbToPoints(fVerb);
caryclark26ad22a2015-10-16 09:03:38 -0700882 SkDebugf("%s=%d {{", prefix, this->debugID());
caryclark1049f122015-04-20 08:31:59 -0700883 if (fVerb == SkPath::kConic_Verb) {
884 SkDebugf("{");
885 }
caryclark54359292015-03-26 07:52:43 -0700886 int index = 0;
887 do {
888 SkDPoint::Dump(fPts[index]);
889 SkDebugf(", ");
890 } while (++index < last);
891 SkDPoint::Dump(fPts[index]);
caryclark1049f122015-04-20 08:31:59 -0700892 SkDebugf("}}");
893 if (fVerb == SkPath::kConic_Verb) {
894 SkDebugf(", %1.9gf}", fWeight);
895 }
caryclark624637c2015-05-11 07:21:27 -0700896}
897
caryclark26ad22a2015-10-16 09:03:38 -0700898void SkOpSegment::dumpPts(const char* prefix) const {
899 dumpPtsInner(prefix);
caryclark1049f122015-04-20 08:31:59 -0700900 SkDebugf("\n");
caryclark54359292015-03-26 07:52:43 -0700901}
902
903void SkCoincidentSpans::dump() const {
904 SkDebugf("- seg=%d span=%d ptT=%d ", fCoinPtTStart->segment()->debugID(),
905 fCoinPtTStart->span()->debugID(), fCoinPtTStart->debugID());
906 fCoinPtTStart->dumpBase();
907 SkDebugf(" span=%d ptT=%d ", fCoinPtTEnd->span()->debugID(), fCoinPtTEnd->debugID());
908 fCoinPtTEnd->dumpBase();
909 if (fCoinPtTStart->segment()->operand()) {
910 SkDebugf(" operand");
911 }
912 if (fCoinPtTStart->segment()->isXor()) {
913 SkDebugf(" xor");
914 }
915 SkDebugf("\n");
916 SkDebugf("+ seg=%d span=%d ptT=%d ", fOppPtTStart->segment()->debugID(),
917 fOppPtTStart->span()->debugID(), fOppPtTStart->debugID());
918 fOppPtTStart->dumpBase();
919 SkDebugf(" span=%d ptT=%d ", fOppPtTEnd->span()->debugID(), fOppPtTEnd->debugID());
920 fOppPtTEnd->dumpBase();
921 if (fOppPtTStart->segment()->operand()) {
922 SkDebugf(" operand");
923 }
924 if (fOppPtTStart->segment()->isXor()) {
925 SkDebugf(" xor");
926 }
927 SkDebugf("\n");
928}
929
930void SkOpCoincidence::dump() const {
931 SkCoincidentSpans* span = fHead;
932 while (span) {
933 span->dump();
caryclark55888e42016-07-18 10:01:36 -0700934 span = span->next();
caryclark54359292015-03-26 07:52:43 -0700935 }
caryclark26ad22a2015-10-16 09:03:38 -0700936 if (!fTop || fHead == fTop) {
caryclark27c8eb82015-07-06 11:38:33 -0700937 return;
938 }
939 SkDebugf("top:\n");
940 span = fTop;
caryclark55888e42016-07-18 10:01:36 -0700941 int count = 0;
caryclark27c8eb82015-07-06 11:38:33 -0700942 while (span) {
943 span->dump();
caryclark55888e42016-07-18 10:01:36 -0700944 span = span->next();
945 SkCoincidentSpans* check = fTop;
946 ++count;
947 for (int index = 0; index < count; ++index) {
948 if (span == check) {
949 SkDebugf("(loops to #%d)\n", index);
950 return;
951 }
952 check = check->next();
953 }
caryclark27c8eb82015-07-06 11:38:33 -0700954 }
caryclark54359292015-03-26 07:52:43 -0700955}
956
caryclark624637c2015-05-11 07:21:27 -0700957void SkOpContour::dump() const {
caryclark1049f122015-04-20 08:31:59 -0700958 SkDebugf("contour=%d count=%d op=%d xor=%d\n", this->debugID(), fCount, fOperand, fXor);
caryclark54359292015-03-26 07:52:43 -0700959 if (!fCount) {
960 return;
961 }
962 const SkOpSegment* segment = &fHead;
caryclark624637c2015-05-11 07:21:27 -0700963 SkDEBUGCODE(fDebugIndent = 0);
964 this->indentDump();
caryclark54359292015-03-26 07:52:43 -0700965 do {
966 segment->dump();
967 } while ((segment = segment->next()));
caryclark624637c2015-05-11 07:21:27 -0700968 this->outdentDump();
caryclark54359292015-03-26 07:52:43 -0700969}
970
caryclark624637c2015-05-11 07:21:27 -0700971void SkOpContour::dumpAll() const {
caryclark1049f122015-04-20 08:31:59 -0700972 SkDebugf("contour=%d count=%d op=%d xor=%d\n", this->debugID(), fCount, fOperand, fXor);
caryclark54359292015-03-26 07:52:43 -0700973 if (!fCount) {
974 return;
975 }
976 const SkOpSegment* segment = &fHead;
caryclark624637c2015-05-11 07:21:27 -0700977 SkDEBUGCODE(fDebugIndent = 0);
978 this->indentDump();
caryclark54359292015-03-26 07:52:43 -0700979 do {
980 segment->dumpAll();
981 } while ((segment = segment->next()));
caryclark624637c2015-05-11 07:21:27 -0700982 this->outdentDump();
caryclark54359292015-03-26 07:52:43 -0700983}
984
985
986void SkOpContour::dumpAngles() const {
987 SkDebugf("contour=%d\n", this->debugID());
988 const SkOpSegment* segment = &fHead;
989 do {
990 SkDebugf(" seg=%d ", segment->debugID());
991 segment->dumpAngles();
992 } while ((segment = segment->next()));
993}
994
995void SkOpContour::dumpPt(int index) const {
996 const SkOpSegment* segment = &fHead;
997 do {
998 if (segment->debugID() == index) {
999 segment->dumpPts();
1000 }
1001 } while ((segment = segment->next()));
1002}
1003
caryclark26ad22a2015-10-16 09:03:38 -07001004void SkOpContour::dumpPts(const char* prefix) const {
caryclark54359292015-03-26 07:52:43 -07001005 SkDebugf("contour=%d\n", this->debugID());
1006 const SkOpSegment* segment = &fHead;
1007 do {
caryclark26ad22a2015-10-16 09:03:38 -07001008 SkDebugf(" %s=%d ", prefix, segment->debugID());
1009 segment->dumpPts(prefix);
caryclark54359292015-03-26 07:52:43 -07001010 } while ((segment = segment->next()));
1011}
1012
caryclark26ad22a2015-10-16 09:03:38 -07001013void SkOpContour::dumpPtsX(const char* prefix) const {
caryclark54359292015-03-26 07:52:43 -07001014 if (!this->fCount) {
1015 SkDebugf("<empty>\n");
1016 return;
1017 }
1018 const SkOpSegment* segment = &fHead;
1019 do {
caryclark26ad22a2015-10-16 09:03:38 -07001020 segment->dumpPts(prefix);
caryclark54359292015-03-26 07:52:43 -07001021 } while ((segment = segment->next()));
1022}
1023
1024void SkOpContour::dumpSegment(int index) const {
1025 debugSegment(index)->dump();
1026}
1027
caryclark26ad22a2015-10-16 09:03:38 -07001028void SkOpContour::dumpSegments(const char* prefix, SkPathOp op) const {
caryclark54359292015-03-26 07:52:43 -07001029 bool firstOp = false;
1030 const SkOpContour* c = this;
1031 do {
Ben Wagner3f985522017-10-09 10:47:47 -04001032 if (!firstOp && c->operand()) {
caryclark54359292015-03-26 07:52:43 -07001033#if DEBUG_ACTIVE_OP
1034 SkDebugf("op %s\n", SkPathOpsDebug::kPathOpStr[op]);
1035#endif
1036 firstOp = true;
1037 }
caryclark26ad22a2015-10-16 09:03:38 -07001038 c->dumpPtsX(prefix);
caryclark54359292015-03-26 07:52:43 -07001039 } while ((c = c->next()));
1040}
1041
1042void SkOpContour::dumpSpan(int index) const {
1043 debugSpan(index)->dump();
1044}
1045
1046void SkOpContour::dumpSpans() const {
1047 SkDebugf("contour=%d\n", this->debugID());
1048 const SkOpSegment* segment = &fHead;
1049 do {
1050 SkDebugf(" seg=%d ", segment->debugID());
1051 segment->dump();
1052 } while ((segment = segment->next()));
1053}
1054
caryclark03b03ca2015-04-23 09:13:37 -07001055void SkOpCurve::dump() const {
1056 int count = SkPathOpsVerbToPoints(SkDEBUGRELEASE(fVerb, SkPath::kCubic_Verb));
1057 SkDebugf("{{");
1058 int index;
1059 for (index = 0; index <= count - 1; ++index) {
1060 SkDebugf("{%1.9gf,%1.9gf}, ", fPts[index].fX, fPts[index].fY);
1061 }
1062 SkDebugf("{%1.9gf,%1.9gf}}}\n", fPts[index].fX, fPts[index].fY);
1063}
1064
caryclark54359292015-03-26 07:52:43 -07001065#ifdef SK_DEBUG
1066const SkOpAngle* SkOpGlobalState::debugAngle(int id) const {
caryclark624637c2015-05-11 07:21:27 -07001067 const SkOpContour* contour = fContourHead;
caryclark54359292015-03-26 07:52:43 -07001068 do {
1069 const SkOpSegment* segment = contour->first();
1070 while (segment) {
1071 const SkOpSpan* span = segment->head();
1072 do {
1073 SkOpAngle* angle = span->fromAngle();
1074 if (angle && angle->debugID() == id) {
1075 return angle;
1076 }
1077 angle = span->toAngle();
1078 if (angle && angle->debugID() == id) {
1079 return angle;
1080 }
1081 } while ((span = span->next()->upCastable()));
1082 const SkOpSpanBase* tail = segment->tail();
1083 SkOpAngle* angle = tail->fromAngle();
1084 if (angle && angle->debugID() == id) {
1085 return angle;
1086 }
1087 segment = segment->next();
1088 }
1089 } while ((contour = contour->next()));
halcanary96fcdcc2015-08-27 07:41:13 -07001090 return nullptr;
caryclark54359292015-03-26 07:52:43 -07001091}
1092
caryclark30b9fdd2016-08-31 14:36:29 -07001093SkOpContour* SkOpGlobalState::debugContour(int id) const {
caryclark624637c2015-05-11 07:21:27 -07001094 SkOpContour* contour = fContourHead;
caryclark54359292015-03-26 07:52:43 -07001095 do {
1096 if (contour->debugID() == id) {
1097 return contour;
1098 }
1099 } while ((contour = contour->next()));
halcanary96fcdcc2015-08-27 07:41:13 -07001100 return nullptr;
caryclark54359292015-03-26 07:52:43 -07001101}
1102
1103const SkOpPtT* SkOpGlobalState::debugPtT(int id) const {
caryclark624637c2015-05-11 07:21:27 -07001104 const SkOpContour* contour = fContourHead;
caryclark54359292015-03-26 07:52:43 -07001105 do {
1106 const SkOpSegment* segment = contour->first();
1107 while (segment) {
1108 const SkOpSpan* span = segment->head();
1109 do {
1110 const SkOpPtT* ptT = span->ptT();
1111 if (ptT->debugMatchID(id)) {
1112 return ptT;
1113 }
1114 } while ((span = span->next()->upCastable()));
1115 const SkOpSpanBase* tail = segment->tail();
1116 const SkOpPtT* ptT = tail->ptT();
1117 if (ptT->debugMatchID(id)) {
1118 return ptT;
1119 }
1120 segment = segment->next();
1121 }
1122 } while ((contour = contour->next()));
halcanary96fcdcc2015-08-27 07:41:13 -07001123 return nullptr;
caryclark54359292015-03-26 07:52:43 -07001124}
1125
1126const SkOpSegment* SkOpGlobalState::debugSegment(int id) const {
caryclark624637c2015-05-11 07:21:27 -07001127 const SkOpContour* contour = fContourHead;
caryclark54359292015-03-26 07:52:43 -07001128 do {
1129 const SkOpSegment* segment = contour->first();
1130 while (segment) {
1131 if (segment->debugID() == id) {
1132 return segment;
1133 }
1134 segment = segment->next();
1135 }
1136 } while ((contour = contour->next()));
halcanary96fcdcc2015-08-27 07:41:13 -07001137 return nullptr;
caryclark54359292015-03-26 07:52:43 -07001138}
1139
1140const SkOpSpanBase* SkOpGlobalState::debugSpan(int id) const {
caryclark624637c2015-05-11 07:21:27 -07001141 const SkOpContour* contour = fContourHead;
caryclark54359292015-03-26 07:52:43 -07001142 do {
1143 const SkOpSegment* segment = contour->first();
1144 while (segment) {
1145 const SkOpSpan* span = segment->head();
1146 do {
1147 if (span->debugID() == id) {
1148 return span;
1149 }
1150 } while ((span = span->next()->upCastable()));
1151 const SkOpSpanBase* tail = segment->tail();
1152 if (tail->debugID() == id) {
1153 return tail;
1154 }
1155 segment = segment->next();
1156 }
1157 } while ((contour = contour->next()));
halcanary96fcdcc2015-08-27 07:41:13 -07001158 return nullptr;
caryclark54359292015-03-26 07:52:43 -07001159}
1160#endif
1161
Cary Clark8762fb62018-10-16 16:06:24 -04001162char SkTCoincident::dumpIsCoincidentStr() const {
1163 if (!!fMatch != fMatch) {
1164 return '?';
1165 }
1166 return fMatch ? '*' : 0;
1167}
1168
1169void SkTCoincident::dump() const {
1170 SkDebugf("t=%1.9g pt=(%1.9g,%1.9g)%s\n", fPerpT, fPerpPt.fX, fPerpPt.fY,
1171 fMatch ? " match" : "");
1172}
1173
1174#ifdef SK_DEBUG
1175
1176const SkTSpan* SkTSect::debugSpan(int id) const {
1177 const SkTSpan* test = fHead;
1178 do {
1179 if (test->debugID() == id) {
1180 return test;
1181 }
1182 } while ((test = test->next()));
1183 return nullptr;
1184}
1185
1186const SkTSpan* SkTSect::debugT(double t) const {
1187 const SkTSpan* test = fHead;
1188 const SkTSpan* closest = nullptr;
1189 double bestDist = DBL_MAX;
1190 do {
1191 if (between(test->fStartT, t, test->fEndT)) {
1192 return test;
1193 }
1194 double testDist = SkTMin(fabs(test->fStartT - t), fabs(test->fEndT - t));
1195 if (bestDist > testDist) {
1196 bestDist = testDist;
1197 closest = test;
1198 }
1199 } while ((test = test->next()));
1200 SkASSERT(closest);
1201 return closest;
1202}
1203
1204#endif
1205
1206void SkTSect::dump() const {
1207 dumpCommon(fHead);
1208}
1209
1210extern int gDumpTSectNum;
1211
1212void SkTSect::dumpBoth(SkTSect* opp) const {
1213#if DEBUG_T_SECT_DUMP <= 2
1214#if DEBUG_T_SECT_DUMP == 2
1215 SkDebugf("%d ", ++gDumpTSectNum);
1216#endif
1217 this->dump();
1218 SkDebugf("\n");
1219 opp->dump();
1220 SkDebugf("\n");
1221#elif DEBUG_T_SECT_DUMP == 3
1222 SkDebugf("<div id=\"sect%d\">\n", ++gDumpTSectNum);
1223 if (this->fHead) {
1224 this->dumpCurves();
1225 }
1226 if (opp->fHead) {
1227 opp->dumpCurves();
1228 }
1229 SkDebugf("</div>\n\n");
1230#endif
1231}
1232
1233void SkTSect::dumpBounded(int id) const {
1234#ifdef SK_DEBUG
1235 const SkTSpan* bounded = debugSpan(id);
1236 if (!bounded) {
1237 SkDebugf("no span matches %d\n", id);
1238 return;
1239 }
1240 const SkTSpan* test = bounded->debugOpp()->fHead;
1241 do {
1242 if (test->findOppSpan(bounded)) {
1243 test->dump();
1244 SkDebugf(" ");
1245 }
1246 } while ((test = test->next()));
1247 SkDebugf("\n");
1248#endif
1249}
1250
1251void SkTSect::dumpBounds() const {
1252 const SkTSpan* test = fHead;
1253 do {
1254 test->dumpBounds();
1255 } while ((test = test->next()));
1256}
1257
1258void SkTSect::dumpCoin() const {
1259 dumpCommon(fCoincident);
1260}
1261
1262void SkTSect::dumpCoinCurves() const {
1263 dumpCommonCurves(fCoincident);
1264}
1265
1266void SkTSect::dumpCommon(const SkTSpan* test) const {
1267 SkDebugf("id=%d", debugID());
1268 if (!test) {
1269 SkDebugf(" (empty)");
1270 return;
1271 }
1272 do {
1273 SkDebugf(" ");
1274 test->dump();
1275 } while ((test = test->next()));
1276}
1277
1278void SkTSect::dumpCommonCurves(const SkTSpan* test) const {
1279#if DEBUG_T_SECT
1280 do {
1281 test->fPart->dumpID(test->debugID());
1282 } while ((test = test->next()));
1283#endif
1284}
1285
1286void SkTSect::dumpCurves() const {
1287 dumpCommonCurves(fHead);
1288}
1289
1290#ifdef SK_DEBUG
1291
1292const SkTSpan* SkTSpan::debugSpan(int id) const {
1293 return fDebugSect->debugSpan(id);
1294}
1295
1296const SkTSpan* SkTSpan::debugT(double t) const {
1297 return fDebugSect->debugT(t);
1298}
1299
1300#endif
1301
1302void SkTSpan::dumpAll() const {
1303 dumpID();
1304 SkDebugf("=(%g,%g) [", fStartT, fEndT);
1305 const SkTSpanBounded* testBounded = fBounded;
1306 while (testBounded) {
1307 const SkTSpan* span = testBounded->fBounded;
1308 const SkTSpanBounded* next = testBounded->fNext;
1309 span->dumpID();
1310 SkDebugf("=(%g,%g)", span->fStartT, span->fEndT);
1311 if (next) {
1312 SkDebugf(" ");
1313 }
1314 testBounded = next;
1315 }
1316 SkDebugf("]\n");
1317}
1318
1319void SkTSpan::dump() const {
1320 dumpID();
1321 SkDebugf("=(%g,%g) [", fStartT, fEndT);
1322 const SkTSpanBounded* testBounded = fBounded;
1323 while (testBounded) {
1324 const SkTSpan* span = testBounded->fBounded;
1325 const SkTSpanBounded* next = testBounded->fNext;
1326 span->dumpID();
1327 if (next) {
1328 SkDebugf(",");
1329 }
1330 testBounded = next;
1331 }
1332 SkDebugf("]");
1333}
1334
1335void SkTSpan::dumpBounded(int id) const {
1336 SkDEBUGCODE(fDebugSect->dumpBounded(id));
1337}
1338
1339void SkTSpan::dumpBounds() const {
1340 dumpID();
1341 SkDebugf(" bounds=(%1.9g,%1.9g, %1.9g,%1.9g) boundsMax=%1.9g%s\n",
1342 fBounds.fLeft, fBounds.fTop, fBounds.fRight, fBounds.fBottom, fBoundsMax,
1343 fCollapsed ? " collapsed" : "");
1344}
1345
1346void SkTSpan::dumpCoin() const {
1347 dumpID();
1348 SkDebugf(" coinStart ");
1349 fCoinStart.dump();
1350 SkDebugf(" coinEnd ");
1351 fCoinEnd.dump();
1352}
1353
1354void SkTSpan::dumpID() const {
1355 char cS = fCoinStart.dumpIsCoincidentStr();
1356 if (cS) {
1357 SkDebugf("%c", cS);
1358 }
1359 SkDebugf("%d", debugID());
1360 char cE = fCoinEnd.dumpIsCoincidentStr();
1361 if (cE) {
1362 SkDebugf("%c", cE);
1363 }
1364}
1365
caryclark54359292015-03-26 07:52:43 -07001366#if DEBUG_T_SECT_DUMP > 1
1367int gDumpTSectNum;
1368#endif
Cary Clarkb8421ed2018-03-14 15:55:02 -04001369
1370// global path dumps for msvs Visual Studio 17 to use from Immediate Window
Cary Clark8762fb62018-10-16 16:06:24 -04001371void Dump(const SkOpContour& contour) {
1372 contour.dump();
1373}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001374
Cary Clark8762fb62018-10-16 16:06:24 -04001375void DumpAll(const SkOpContour& contour) {
1376 contour.dumpAll();
1377}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001378
Cary Clark8762fb62018-10-16 16:06:24 -04001379void DumpAngles(const SkOpContour& contour) {
1380 contour.dumpAngles();
1381}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001382
Cary Clark8762fb62018-10-16 16:06:24 -04001383void DumpContours(const SkOpContour& contour) {
1384 contour.dumpContours();
1385}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001386
Cary Clark8762fb62018-10-16 16:06:24 -04001387void DumpContoursAll(const SkOpContour& contour) {
1388 contour.dumpContoursAll();
1389}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001390
Cary Clark8762fb62018-10-16 16:06:24 -04001391void DumpContoursAngles(const SkOpContour& contour) {
1392 contour.dumpContoursAngles();
1393}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001394
Cary Clark8762fb62018-10-16 16:06:24 -04001395void DumpContoursPts(const SkOpContour& contour) {
1396 contour.dumpContoursPts();
1397}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001398
Cary Clark8762fb62018-10-16 16:06:24 -04001399void DumpContoursPt(const SkOpContour& contour, int segmentID) {
1400 contour.dumpContoursPt(segmentID);
1401}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001402
Cary Clark8762fb62018-10-16 16:06:24 -04001403void DumpContoursSegment(const SkOpContour& contour, int segmentID) {
1404 contour.dumpContoursSegment(segmentID);
1405}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001406
Cary Clark8762fb62018-10-16 16:06:24 -04001407void DumpContoursSpan(const SkOpContour& contour, int segmentID) {
1408 contour.dumpContoursSpan(segmentID);
1409}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001410
Cary Clark8762fb62018-10-16 16:06:24 -04001411void DumpContoursSpans(const SkOpContour& contour) {
1412 contour.dumpContoursSpans();
1413}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001414
Cary Clark8762fb62018-10-16 16:06:24 -04001415void DumpPt(const SkOpContour& contour, int pt) {
1416 contour.dumpPt(pt);
1417}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001418
Cary Clark8762fb62018-10-16 16:06:24 -04001419void DumpPts(const SkOpContour& contour, const char* prefix) {
1420 contour.dumpPts(prefix);
1421}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001422
Cary Clark8762fb62018-10-16 16:06:24 -04001423void DumpSegment(const SkOpContour& contour, int seg) {
1424 contour.dumpSegment(seg);
1425}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001426
Cary Clark8762fb62018-10-16 16:06:24 -04001427void DumpSegments(const SkOpContour& contour, const char* prefix, SkPathOp op) {
1428 contour.dumpSegments(prefix, op);
1429}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001430
Cary Clark8762fb62018-10-16 16:06:24 -04001431void DumpSpan(const SkOpContour& contour, int span) {
1432 contour.dumpSpan(span);
1433}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001434
Cary Clark8762fb62018-10-16 16:06:24 -04001435void DumpSpans(const SkOpContour& contour ) {
1436 contour.dumpSpans();
1437}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001438
Cary Clark8762fb62018-10-16 16:06:24 -04001439void Dump(const SkOpSegment& segment) {
1440 segment.dump();
1441}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001442
Cary Clark8762fb62018-10-16 16:06:24 -04001443void DumpAll(const SkOpSegment& segment) {
1444 segment.dumpAll();
1445}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001446
Cary Clark8762fb62018-10-16 16:06:24 -04001447void DumpAngles(const SkOpSegment& segment) {
1448 segment.dumpAngles();
1449}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001450
Cary Clark8762fb62018-10-16 16:06:24 -04001451void DumpCoin(const SkOpSegment& segment) {
1452 segment.dumpCoin();
1453}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001454
Cary Clark8762fb62018-10-16 16:06:24 -04001455void DumpPts(const SkOpSegment& segment, const char* prefix) {
1456 segment.dumpPts(prefix);
1457}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001458
Cary Clark8762fb62018-10-16 16:06:24 -04001459void Dump(const SkOpPtT& ptT) {
1460 ptT.dump();
1461}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001462
Cary Clark8762fb62018-10-16 16:06:24 -04001463void DumpAll(const SkOpPtT& ptT) {
1464 ptT.dumpAll();
1465}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001466
Cary Clark8762fb62018-10-16 16:06:24 -04001467void Dump(const SkOpSpanBase& spanBase) {
1468 spanBase.dump();
1469}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001470
Cary Clark8762fb62018-10-16 16:06:24 -04001471void DumpCoin(const SkOpSpanBase& spanBase) {
1472 spanBase.dumpCoin();
1473}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001474
Cary Clark8762fb62018-10-16 16:06:24 -04001475void DumpAll(const SkOpSpanBase& spanBase) {
1476 spanBase.dumpAll();
1477}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001478
Cary Clark8762fb62018-10-16 16:06:24 -04001479void DumpCoin(const SkOpSpan& span) {
1480 span.dumpCoin();
1481}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001482
Cary Clark8762fb62018-10-16 16:06:24 -04001483bool DumpSpan(const SkOpSpan& span) {
1484 return span.dumpSpan();
1485}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001486
Cary Clark8762fb62018-10-16 16:06:24 -04001487void Dump(const SkDConic& conic) {
1488 conic.dump();
1489}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001490
Cary Clark8762fb62018-10-16 16:06:24 -04001491void DumpID(const SkDConic& conic, int id) {
1492 conic.dumpID(id);
1493}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001494
Cary Clark8762fb62018-10-16 16:06:24 -04001495void Dump(const SkDCubic& cubic) {
1496 cubic.dump();
1497}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001498
Cary Clark8762fb62018-10-16 16:06:24 -04001499void DumpID(const SkDCubic& cubic, int id) {
1500 cubic.dumpID(id);
1501}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001502
Cary Clark8762fb62018-10-16 16:06:24 -04001503void Dump(const SkDLine& line) {
1504 line.dump();
1505}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001506
Cary Clark8762fb62018-10-16 16:06:24 -04001507void DumpID(const SkDLine& line, int id) {
1508 line.dumpID(id);
1509}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001510
Cary Clark8762fb62018-10-16 16:06:24 -04001511void Dump(const SkDQuad& quad) {
1512 quad.dump();
1513}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001514
Cary Clark8762fb62018-10-16 16:06:24 -04001515void DumpID(const SkDQuad& quad, int id) {
1516 quad.dumpID(id);
1517}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001518
Cary Clark8762fb62018-10-16 16:06:24 -04001519void Dump(const SkDPoint& point) {
1520 point.dump();
1521}
Cary Clarkb8421ed2018-03-14 15:55:02 -04001522
Cary Clark8762fb62018-10-16 16:06:24 -04001523void Dump(const SkOpAngle& angle) {
1524 angle.dump();
Cary Clarkb8421ed2018-03-14 15:55:02 -04001525}