blob: 8ac38aaf6dc8998c0ca15c23bfe31b8a3e20351c [file] [log] [blame]
commit-bot@chromium.org4431e772014-04-14 17:08:59 +00001#include "SkOpContour.h"
2#include "SkIntersectionHelper.h"
3#include "SkOpSegment.h"
caryclark19eb3b22014-07-18 05:08:14 -07004#include "SkString.h"
commit-bot@chromium.org4431e772014-04-14 17:08:59 +00005
6inline void DebugDumpDouble(double x) {
7 if (x == floor(x)) {
8 SkDebugf("%.0f", x);
9 } else {
10 SkDebugf("%1.19g", x);
11 }
12}
13
14inline void DebugDumpFloat(float x) {
15 if (x == floorf(x)) {
16 SkDebugf("%.0f", x);
17 } else {
18 SkDebugf("%1.9gf", x);
19 }
20}
21
caryclark19eb3b22014-07-18 05:08:14 -070022
23#if DEBUG_SHOW_TEST_NAME
24
25static void output_scalar(SkScalar num) {
26 if (num == (int) num) {
27 SkDebugf("%d", (int) num);
28 } else {
29 SkString str;
30 str.printf("%1.9g", num);
31 int width = (int) str.size();
32 const char* cStr = str.c_str();
33 while (cStr[width - 1] == '0') {
34 --width;
35 }
36 str.resize(width);
37 SkDebugf("%sf", str.c_str());
38 }
39}
40
41static void output_points(const SkPoint* pts, int count) {
42 for (int index = 0; index < count; ++index) {
43 output_scalar(pts[index].fX);
44 SkDebugf(", ");
45 output_scalar(pts[index].fY);
46 if (index + 1 < count) {
47 SkDebugf(", ");
48 }
49 }
50 SkDebugf(");\n");
51}
52
53static void showPathContours(SkPath::RawIter& iter, const char* pathName) {
54 uint8_t verb;
55 SkPoint pts[4];
56 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
57 switch (verb) {
58 case SkPath::kMove_Verb:
59 SkDebugf(" %s.moveTo(", pathName);
60 output_points(&pts[0], 1);
61 continue;
62 case SkPath::kLine_Verb:
63 SkDebugf(" %s.lineTo(", pathName);
64 output_points(&pts[1], 1);
65 break;
66 case SkPath::kQuad_Verb:
67 SkDebugf(" %s.quadTo(", pathName);
68 output_points(&pts[1], 2);
69 break;
70 case SkPath::kCubic_Verb:
71 SkDebugf(" %s.cubicTo(", pathName);
72 output_points(&pts[1], 3);
73 break;
74 case SkPath::kClose_Verb:
75 SkDebugf(" %s.close();\n", pathName);
76 break;
77 default:
78 SkDEBUGFAIL("bad verb");
79 return;
80 }
81 }
82}
83
84static const char* gFillTypeStr[] = {
85 "kWinding_FillType",
86 "kEvenOdd_FillType",
87 "kInverseWinding_FillType",
88 "kInverseEvenOdd_FillType"
89};
90
91void SkPathOpsDebug::ShowOnePath(const SkPath& path, const char* name, bool includeDeclaration) {
92 SkPath::RawIter iter(path);
93#define SUPPORT_RECT_CONTOUR_DETECTION 0
94#if SUPPORT_RECT_CONTOUR_DETECTION
95 int rectCount = path.isRectContours() ? path.rectContours(NULL, NULL) : 0;
96 if (rectCount > 0) {
97 SkTDArray<SkRect> rects;
98 SkTDArray<SkPath::Direction> directions;
99 rects.setCount(rectCount);
100 directions.setCount(rectCount);
101 path.rectContours(rects.begin(), directions.begin());
102 for (int contour = 0; contour < rectCount; ++contour) {
103 const SkRect& rect = rects[contour];
104 SkDebugf("path.addRect(%1.9g, %1.9g, %1.9g, %1.9g, %s);\n", rect.fLeft, rect.fTop,
105 rect.fRight, rect.fBottom, directions[contour] == SkPath::kCCW_Direction
106 ? "SkPath::kCCW_Direction" : "SkPath::kCW_Direction");
107 }
108 return;
109 }
110#endif
111 SkPath::FillType fillType = path.getFillType();
112 SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInverseEvenOdd_FillType);
113 if (includeDeclaration) {
114 SkDebugf(" SkPath %s;\n", name);
115 }
116 SkDebugf(" %s.setFillType(SkPath::%s);\n", name, gFillTypeStr[fillType]);
117 iter.setPath(path);
118 showPathContours(iter, name);
119}
120
121static void show_function_header(const char* functionName) {
122 SkDebugf("\nstatic void %s(skiatest::Reporter* reporter, const char* filename) {\n", functionName);
123 if (strcmp("skphealth_com76", functionName) == 0) {
124 SkDebugf("found it\n");
125 }
126}
127
128static const char* gOpStrs[] = {
129 "kDifference_PathOp",
130 "kIntersect_PathOp",
131 "kUnion_PathOp",
132 "kXor_PathOp",
133 "kReverseDifference_PathOp",
134};
135
136static void show_op(SkPathOp op, const char* pathOne, const char* pathTwo) {
137 SkDebugf(" testPathOp(reporter, %s, %s, %s, filename);\n", pathOne, pathTwo, gOpStrs[op]);
138 SkDebugf("}\n");
139}
140
141SK_DECLARE_STATIC_MUTEX(gTestMutex);
142
143void SkPathOpsDebug::ShowPath(const SkPath& a, const SkPath& b, SkPathOp shapeOp,
144 const char* testName) {
145 SkAutoMutexAcquire ac(gTestMutex);
146 show_function_header(testName);
147 ShowOnePath(a, "path", true);
148 ShowOnePath(b, "pathB", true);
149 show_op(shapeOp, "path", "pathB");
150}
151#endif
152
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000153// if not defined by PathOpsDebug.cpp ...
154#if !defined SK_DEBUG && FORCE_RELEASE
155bool SkPathOpsDebug::ValidWind(int wind) {
156 return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF;
157}
158
159void SkPathOpsDebug::WindingPrintf(int wind) {
160 if (wind == SK_MinS32) {
161 SkDebugf("?");
162 } else {
163 SkDebugf("%d", wind);
164 }
165}
166#endif
167
168void SkOpAngle::dump() const {
caryclarkdac1d172014-06-17 05:15:38 -0700169 dumpOne(true);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000170 SkDebugf("\n");
171}
172
caryclarkdac1d172014-06-17 05:15:38 -0700173void SkOpAngle::dumpOne(bool functionHeader) const {
174// fSegment->debugValidate();
175 const SkOpSpan& mSpan = fSegment->span(SkMin32(fStart, fEnd));
176 if (functionHeader) {
177 SkDebugf("%s ", __FUNCTION__);
178 }
179 SkDebugf("[%d", fSegment->debugID());
180 SkDebugf("/%d", debugID());
181 SkDebugf("] next=");
182 if (fNext) {
183 SkDebugf("%d", fNext->fSegment->debugID());
184 SkDebugf("/%d", fNext->debugID());
185 } else {
186 SkDebugf("?");
187 }
188 SkDebugf(" sect=%d/%d ", fSectorStart, fSectorEnd);
189 SkDebugf(" s=%1.9g [%d] e=%1.9g [%d]", fSegment->span(fStart).fT, fStart,
190 fSegment->span(fEnd).fT, fEnd);
191 SkDebugf(" sgn=%d windVal=%d", sign(), mSpan.fWindValue);
192
193 SkDebugf(" windSum=");
194 SkPathOpsDebug::WindingPrintf(mSpan.fWindSum);
195 if (mSpan.fOppValue != 0 || mSpan.fOppSum != SK_MinS32) {
196 SkDebugf(" oppVal=%d", mSpan.fOppValue);
197 SkDebugf(" oppSum=");
198 SkPathOpsDebug::WindingPrintf(mSpan.fOppSum);
199 }
200 if (mSpan.fDone) {
201 SkDebugf(" done");
202 }
203 if (unorderable()) {
204 SkDebugf(" unorderable");
205 }
206 if (small()) {
207 SkDebugf(" small");
208 }
209 if (mSpan.fTiny) {
210 SkDebugf(" tiny");
211 }
212 if (fSegment->operand()) {
213 SkDebugf(" operand");
214 }
215 if (fStop) {
216 SkDebugf(" stop");
217 }
218}
219
220void SkOpAngle::dumpTo(const SkOpSegment* segment, const SkOpAngle* to) const {
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000221 const SkOpAngle* first = this;
222 const SkOpAngle* next = this;
223 const char* indent = "";
224 do {
225 SkDebugf("%s", indent);
caryclarkdac1d172014-06-17 05:15:38 -0700226 next->dumpOne(false);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000227 if (segment == next->fSegment) {
caryclarkdac1d172014-06-17 05:15:38 -0700228 if (this == fNext) {
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000229 SkDebugf(" << from");
230 }
caryclarkdac1d172014-06-17 05:15:38 -0700231 if (to == fNext) {
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000232 SkDebugf(" << to");
233 }
234 }
235 SkDebugf("\n");
236 indent = " ";
237 next = next->fNext;
238 } while (next && next != first);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000239}
240
241void SkOpAngle::dumpLoop() const {
242 const SkOpAngle* first = this;
243 const SkOpAngle* next = this;
244 do {
caryclarke4097e32014-06-18 07:24:19 -0700245 next->dumpOne(false);
246 SkDebugf("\n");
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000247 next = next->fNext;
248 } while (next && next != first);
249}
250
251void SkOpAngle::dumpPartials() const {
252 const SkOpAngle* first = this;
253 const SkOpAngle* next = this;
254 do {
255 next->fCurvePart.dumpNumber();
256 next = next->fNext;
257 } while (next && next != first);
258}
259
caryclarkdac1d172014-06-17 05:15:38 -0700260void SkOpAngleSet::dump() const {
261 // FIXME: unimplemented
262/* This requires access to the internal SkChunkAlloc data
263 Defer implementing this until it is needed for debugging
264*/
265 SkASSERT(0);
266}
267
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000268void SkOpContour::dump() const {
269 int segmentCount = fSegments.count();
270 SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID());
271 for (int test = 0; test < segmentCount; ++test) {
272 SkDebugf(" [%d] ((SkOpSegment*) 0x%p) [%d]\n", test, &fSegments[test],
273 fSegments[test].debugID());
274 }
275}
276
277void SkOpContour::dumpAngles() const {
278 int segmentCount = fSegments.count();
279 SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID());
280 for (int test = 0; test < segmentCount; ++test) {
281 SkDebugf(" [%d] ", test);
282 fSegments[test].dumpAngles();
283 }
284}
285
caryclarkdac1d172014-06-17 05:15:38 -0700286void SkOpContour::dumpCoincidence(const SkCoincidence& coin) const {
287 int thisIndex = coin.fSegments[0];
288 const SkOpSegment& s1 = fSegments[thisIndex];
289 int otherIndex = coin.fSegments[1];
290 const SkOpSegment& s2 = coin.fOther->fSegments[otherIndex];
291 SkDebugf("((SkOpSegment*) 0x%p) [%d] ((SkOpSegment*) 0x%p) [%d]\n", &s1, s1.debugID(),
292 &s2, s2.debugID());
293 for (int index = 0; index < 2; ++index) {
294 SkDebugf(" {%1.9gf, %1.9gf}", coin.fPts[0][index].fX, coin.fPts[0][index].fY);
295 if (coin.fNearly[index]) {
296 SkDebugf(" {%1.9gf, %1.9gf}", coin.fPts[1][index].fX, coin.fPts[1][index].fY);
297 }
298 SkDebugf(" seg1t=%1.9g seg2t=%1.9g\n", coin.fTs[0][index], coin.fTs[1][index]);
299 }
300}
301
302void SkOpContour::dumpCoincidences() const {
303 int count = fCoincidences.count();
304 if (count > 0) {
305 SkDebugf("fCoincidences count=%d\n", count);
306 for (int test = 0; test < count; ++test) {
307 dumpCoincidence(fCoincidences[test]);
308 }
309 }
310 count = fPartialCoincidences.count();
311 if (count == 0) {
312 return;
313 }
314 SkDebugf("fPartialCoincidences count=%d\n", count);
315 for (int test = 0; test < count; ++test) {
316 dumpCoincidence(fPartialCoincidences[test]);
317 }
318}
319
320void SkOpContour::dumpPt(int index) const {
321 int segmentCount = fSegments.count();
322 for (int test = 0; test < segmentCount; ++test) {
323 const SkOpSegment& segment = fSegments[test];
324 if (segment.debugID() == index) {
325 fSegments[test].dumpPts();
326 }
327 }
328}
329
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000330void SkOpContour::dumpPts() const {
331 int segmentCount = fSegments.count();
332 SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID());
333 for (int test = 0; test < segmentCount; ++test) {
334 SkDebugf(" [%d] ", test);
335 fSegments[test].dumpPts();
336 }
337}
338
caryclarkdac1d172014-06-17 05:15:38 -0700339void SkOpContour::dumpSpan(int index) const {
340 int segmentCount = fSegments.count();
341 for (int test = 0; test < segmentCount; ++test) {
342 const SkOpSegment& segment = fSegments[test];
343 if (segment.debugID() == index) {
344 fSegments[test].dumpSpans();
345 }
346 }
347}
348
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000349void SkOpContour::dumpSpans() const {
350 int segmentCount = fSegments.count();
351 SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID());
352 for (int test = 0; test < segmentCount; ++test) {
353 SkDebugf(" [%d] ", test);
354 fSegments[test].dumpSpans();
355 }
356}
357
358void SkDCubic::dump() const {
359 SkDebugf("{{");
360 int index = 0;
361 do {
362 fPts[index].dump();
363 SkDebugf(", ");
364 } while (++index < 3);
365 fPts[index].dump();
366 SkDebugf("}}\n");
367}
368
369void SkDCubic::dumpNumber() const {
370 SkDebugf("{{");
371 int index = 0;
372 bool dumpedOne = false;
373 do {
374 if (!(fPts[index].fX == fPts[index].fX && fPts[index].fY == fPts[index].fY)) {
375 continue;
376 }
377 if (dumpedOne) {
378 SkDebugf(", ");
379 }
380 fPts[index].dump();
381 dumpedOne = true;
382 } while (++index < 3);
383 if (fPts[index].fX == fPts[index].fX && fPts[index].fY == fPts[index].fY) {
384 if (dumpedOne) {
385 SkDebugf(", ");
386 }
387 fPts[index].dump();
388 }
389 SkDebugf("}}\n");
390}
391
392void SkDLine::dump() const {
393 SkDebugf("{{");
394 fPts[0].dump();
395 SkDebugf(", ");
396 fPts[1].dump();
397 SkDebugf("}}\n");
398}
399
400void SkDPoint::dump() const {
401 SkDebugf("{");
402 DebugDumpDouble(fX);
403 SkDebugf(", ");
404 DebugDumpDouble(fY);
405 SkDebugf("}");
406}
407
408void SkDPoint::Dump(const SkPoint& pt) {
409 SkDebugf("{");
410 DebugDumpFloat(pt.fX);
411 SkDebugf(", ");
412 DebugDumpFloat(pt.fY);
413 SkDebugf("}");
414}
415
416
417void SkDQuad::dumpComma(const char* comma) const {
418 SkDebugf("{{");
419 int index = 0;
420 do {
421 fPts[index].dump();
422 SkDebugf(", ");
423 } while (++index < 2);
424 fPts[index].dump();
425 SkDebugf("}}%s\n", comma ? comma : "");
426}
427
428void SkDQuad::dump() const {
429 dumpComma("");
430}
431
432void SkIntersectionHelper::dump() const {
433 SkDPoint::Dump(pts()[0]);
434 SkDPoint::Dump(pts()[1]);
435 if (verb() >= SkPath::kQuad_Verb) {
436 SkDPoint::Dump(pts()[2]);
437 }
438 if (verb() >= SkPath::kCubic_Verb) {
439 SkDPoint::Dump(pts()[3]);
440 }
441}
442
commit-bot@chromium.org8cb1daa2014-04-25 12:59:11 +0000443const SkTDArray<SkOpSpan>& SkOpSegment::debugSpans() const {
444 return fTs;
445}
446
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000447void SkOpSegment::dumpAngles() const {
448 SkDebugf("((SkOpSegment*) 0x%p) [%d]\n", this, debugID());
caryclarkdac1d172014-06-17 05:15:38 -0700449 const SkOpAngle* fromAngle = NULL;
450 const SkOpAngle* toAngle = NULL;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000451 for (int index = 0; index < count(); ++index) {
caryclarkdac1d172014-06-17 05:15:38 -0700452 const SkOpAngle* fAngle = fTs[index].fFromAngle;
453 const SkOpAngle* tAngle = fTs[index].fToAngle;
454 if (fromAngle == fAngle && toAngle == tAngle) {
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000455 continue;
456 }
caryclarkdac1d172014-06-17 05:15:38 -0700457 if (fAngle) {
458 SkDebugf(" [%d] from=%d ", index, fAngle->debugID());
459 fAngle->dumpTo(this, tAngle);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000460 }
caryclarkdac1d172014-06-17 05:15:38 -0700461 if (tAngle) {
462 SkDebugf(" [%d] to=%d ", index, tAngle->debugID());
463 tAngle->dumpTo(this, fAngle);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000464 }
caryclarkdac1d172014-06-17 05:15:38 -0700465 fromAngle = fAngle;
466 toAngle = tAngle;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000467 }
468}
469
470void SkOpSegment::dumpContour(int firstID, int lastID) const {
471 if (debugID() < 0) {
472 return;
473 }
474 const SkOpSegment* test = this - (debugID() - 1);
475 test += (firstID - 1);
476 const SkOpSegment* last = test + (lastID - firstID);
477 while (test <= last) {
478 test->dumpSpans();
479 ++test;
480 }
481}
482
483void SkOpSegment::dumpPts() const {
484 int last = SkPathOpsVerbToPoints(fVerb);
485 SkDebugf("((SkOpSegment*) 0x%p) [%d] {{", this, debugID());
486 int index = 0;
487 do {
488 SkDPoint::Dump(fPts[index]);
489 SkDebugf(", ");
490 } while (++index < last);
491 SkDPoint::Dump(fPts[index]);
492 SkDebugf("}}\n");
493}
494
495void SkOpSegment::dumpDPts() const {
496 int count = SkPathOpsVerbToPoints(fVerb);
497 SkDebugf("((SkOpSegment*) 0x%p) [%d] {{", this, debugID());
498 int index = 0;
499 do {
500 SkDPoint dPt = {fPts[index].fX, fPts[index].fY};
501 dPt.dump();
502 if (index != count) {
503 SkDebugf(", ");
504 }
505 } while (++index <= count);
506 SkDebugf("}}\n");
507}
508
509void SkOpSegment::dumpSpans() const {
510 int count = this->count();
511 SkDebugf("((SkOpSegment*) 0x%p) [%d]\n", this, debugID());
512 for (int index = 0; index < count; ++index) {
513 const SkOpSpan& span = this->span(index);
514 SkDebugf(" [%d] ", index);
515 span.dumpOne();
516 }
517}
518
caryclarkdac1d172014-06-17 05:15:38 -0700519void SkPathOpsDebug::DumpCoincidence(const SkTArray<SkOpContour, true>& contours) {
520 int count = contours.count();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000521 for (int index = 0; index < count; ++index) {
caryclarkdac1d172014-06-17 05:15:38 -0700522 contours[index].dumpCoincidences();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000523 }
524}
525
caryclarkdac1d172014-06-17 05:15:38 -0700526void SkPathOpsDebug::DumpCoincidence(const SkTArray<SkOpContour* , true>& contours) {
527 int count = contours.count();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000528 for (int index = 0; index < count; ++index) {
caryclarkdac1d172014-06-17 05:15:38 -0700529 contours[index]->dumpCoincidences();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000530 }
531}
532
533void SkPathOpsDebug::DumpContours(const SkTArray<SkOpContour, true>& contours) {
534 int count = contours.count();
535 for (int index = 0; index < count; ++index) {
536 contours[index].dump();
537 }
538}
539
540void SkPathOpsDebug::DumpContours(const SkTArray<SkOpContour* , true>& contours) {
541 int count = contours.count();
542 for (int index = 0; index < count; ++index) {
543 contours[index]->dump();
544 }
545}
546
547void SkPathOpsDebug::DumpContourAngles(const SkTArray<SkOpContour, true>& contours) {
548 int count = contours.count();
549 for (int index = 0; index < count; ++index) {
550 contours[index].dumpAngles();
551 }
552}
553
554void SkPathOpsDebug::DumpContourAngles(const SkTArray<SkOpContour* , true>& contours) {
555 int count = contours.count();
556 for (int index = 0; index < count; ++index) {
557 contours[index]->dumpAngles();
558 }
559}
560
561void SkPathOpsDebug::DumpContourPts(const SkTArray<SkOpContour, true>& contours) {
562 int count = contours.count();
563 for (int index = 0; index < count; ++index) {
564 contours[index].dumpPts();
565 }
566}
567
568void SkPathOpsDebug::DumpContourPts(const SkTArray<SkOpContour* , true>& contours) {
569 int count = contours.count();
570 for (int index = 0; index < count; ++index) {
571 contours[index]->dumpPts();
572 }
573}
574
caryclarkdac1d172014-06-17 05:15:38 -0700575void SkPathOpsDebug::DumpContourPt(const SkTArray<SkOpContour, true>& contours, int segmentID) {
576 int count = contours.count();
577 for (int index = 0; index < count; ++index) {
578 contours[index].dumpPt(segmentID);
579 }
580}
581
582void SkPathOpsDebug::DumpContourPt(const SkTArray<SkOpContour* , true>& contours, int segmentID) {
583 int count = contours.count();
584 for (int index = 0; index < count; ++index) {
585 contours[index]->dumpPt(segmentID);
586 }
587}
588
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000589void SkPathOpsDebug::DumpContourSpans(const SkTArray<SkOpContour, true>& contours) {
590 int count = contours.count();
591 for (int index = 0; index < count; ++index) {
592 contours[index].dumpSpans();
593 }
594}
595
596void SkPathOpsDebug::DumpContourSpans(const SkTArray<SkOpContour* , true>& contours) {
597 int count = contours.count();
598 for (int index = 0; index < count; ++index) {
599 contours[index]->dumpSpans();
600 }
601}
602
caryclarkdac1d172014-06-17 05:15:38 -0700603void SkPathOpsDebug::DumpContourSpan(const SkTArray<SkOpContour, true>& contours, int segmentID) {
604 int count = contours.count();
605 for (int index = 0; index < count; ++index) {
606 contours[index].dumpSpan(segmentID);
607 }
608}
609
610void SkPathOpsDebug::DumpContourSpan(const SkTArray<SkOpContour* , true>& contours, int segmentID) {
611 int count = contours.count();
612 for (int index = 0; index < count; ++index) {
613 contours[index]->dumpSpan(segmentID);
614 }
615}
616
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000617void SkPathOpsDebug::DumpSpans(const SkTDArray<SkOpSpan *>& spans) {
618 int count = spans.count();
619 for (int index = 0; index < count; ++index) {
620 const SkOpSpan* span = spans[index];
621 const SkOpSpan& oSpan = span->fOther->span(span->fOtherIndex);
622 const SkOpSegment* segment = oSpan.fOther;
623 SkDebugf("((SkOpSegment*) 0x%p) [%d] ", segment, segment->debugID());
624 SkDebugf("spanIndex:%d ", oSpan.fOtherIndex);
625 span->dumpOne();
626 }
627}
628
629// this does not require that other T index is initialized or correct
630const SkOpSegment* SkOpSpan::debugToSegment(ptrdiff_t* spanIndex) const {
631 if (!fOther) {
632 return NULL;
633 }
634 int oppCount = fOther->count();
635 for (int index = 0; index < oppCount; ++index) {
636 const SkOpSpan& otherSpan = fOther->span(index);
637 double otherTestT = otherSpan.fT;
638 if (otherTestT < fOtherT) {
639 continue;
640 }
641 SkASSERT(otherTestT == fOtherT);
642 const SkOpSegment* candidate = otherSpan.fOther;
commit-bot@chromium.org8cb1daa2014-04-25 12:59:11 +0000643 const SkOpSpan* first = candidate->debugSpans().begin();
644 const SkOpSpan* last = candidate->debugSpans().end() - 1;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000645 if (first <= this && this <= last) {
646 if (spanIndex) {
647 *spanIndex = this - first;
648 }
649 return candidate;
650 }
651 }
652 SkASSERT(0);
653 return NULL;
654}
655
656void SkOpSpan::dumpOne() const {
657 SkDebugf("t=");
658 DebugDumpDouble(fT);
659 SkDebugf(" pt=");
660 SkDPoint::Dump(fPt);
661 if (fOther) {
662 SkDebugf(" other.fID=%d", fOther->debugID());
663 SkDebugf(" [%d] otherT=", fOtherIndex);
664 DebugDumpDouble(fOtherT);
665 } else {
666 SkDebugf(" other.fID=? [?] otherT=?");
667 }
caryclarkdac1d172014-06-17 05:15:38 -0700668 if (fWindSum != SK_MinS32) {
669 SkDebugf(" windSum=%d", fWindSum);
670 }
671 if (fOppSum != SK_MinS32 && (SkPathOpsDebug::ValidWind(fOppSum) || fOppValue != 0)) {
672 SkDebugf(" oppSum=%d", fOppSum);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000673 }
674 SkDebugf(" windValue=%d", fWindValue);
675 if (SkPathOpsDebug::ValidWind(fOppSum) || fOppValue != 0) {
676 SkDebugf(" oppValue=%d", fOppValue);
677 }
caryclarkdac1d172014-06-17 05:15:38 -0700678 if (fFromAngle && fFromAngle->debugID()) {
679 SkDebugf(" from=%d", fFromAngle->debugID());
680 }
681 if (fToAngle && fToAngle->debugID()) {
682 SkDebugf(" to=%d", fToAngle->debugID());
683 }
684 if (fChased) {
685 SkDebugf(" chased");
686 }
687 if (fCoincident) {
688 SkDebugf(" coincident");
689 }
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000690 if (fDone) {
691 SkDebugf(" done");
692 }
caryclarkdac1d172014-06-17 05:15:38 -0700693 if (fLoop) {
694 SkDebugf(" loop");
695 }
696 if (fMultiple) {
697 SkDebugf(" multiple");
698 }
699 if (fNear) {
700 SkDebugf(" near");
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000701 }
702 if (fSmall) {
703 SkDebugf(" small");
704 }
caryclarkdac1d172014-06-17 05:15:38 -0700705 if (fTiny) {
706 SkDebugf(" tiny");
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000707 }
708 SkDebugf("\n");
709}
710
711void SkOpSpan::dump() const {
712 ptrdiff_t spanIndex;
713 const SkOpSegment* segment = debugToSegment(&spanIndex);
714 if (segment) {
715 SkDebugf("((SkOpSegment*) 0x%p) [%d]\n", segment, segment->debugID());
716 SkDebugf(" [%d] ", spanIndex);
717 } else {
718 SkDebugf("((SkOpSegment*) ?) [?]\n");
719 SkDebugf(" [?] ");
720 }
721 dumpOne();
722}
723
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000724void Dump(const SkTArray<class SkOpContour, true>& contours) {
725 SkPathOpsDebug::DumpContours(contours);
726}
727
728void Dump(const SkTArray<class SkOpContour* , true>& contours) {
729 SkPathOpsDebug::DumpContours(contours);
730}
731
732void Dump(const SkTArray<class SkOpContour, true>* contours) {
733 SkPathOpsDebug::DumpContours(*contours);
734}
735
736void Dump(const SkTArray<class SkOpContour* , true>* contours) {
737 SkPathOpsDebug::DumpContours(*contours);
738}
739
caryclarkdac1d172014-06-17 05:15:38 -0700740void Dump(const SkTDArray<SkOpSpan *>& chase) {
741 SkPathOpsDebug::DumpSpans(chase);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000742}
743
caryclarkdac1d172014-06-17 05:15:38 -0700744void Dump(const SkTDArray<SkOpSpan *>* chase) {
745 SkPathOpsDebug::DumpSpans(*chase);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000746}
747
748void DumpAngles(const SkTArray<class SkOpContour, true>& contours) {
749 SkPathOpsDebug::DumpContourAngles(contours);
750}
751
752void DumpAngles(const SkTArray<class SkOpContour* , true>& contours) {
753 SkPathOpsDebug::DumpContourAngles(contours);
754}
755
756void DumpAngles(const SkTArray<class SkOpContour, true>* contours) {
757 SkPathOpsDebug::DumpContourAngles(*contours);
758}
759
760void DumpAngles(const SkTArray<class SkOpContour* , true>* contours) {
761 SkPathOpsDebug::DumpContourAngles(*contours);
762}
763
caryclarkdac1d172014-06-17 05:15:38 -0700764void DumpCoin(const SkTArray<class SkOpContour, true>& contours) {
765 SkPathOpsDebug::DumpCoincidence(contours);
766}
767
768void DumpCoin(const SkTArray<class SkOpContour* , true>& contours) {
769 SkPathOpsDebug::DumpCoincidence(contours);
770}
771
772void DumpCoin(const SkTArray<class SkOpContour, true>* contours) {
773 SkPathOpsDebug::DumpCoincidence(*contours);
774}
775
776void DumpCoin(const SkTArray<class SkOpContour* , true>* contours) {
777 SkPathOpsDebug::DumpCoincidence(*contours);
778}
779
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000780void DumpSpans(const SkTArray<class SkOpContour, true>& contours) {
781 SkPathOpsDebug::DumpContourSpans(contours);
782}
783
784void DumpSpans(const SkTArray<class SkOpContour* , true>& contours) {
785 SkPathOpsDebug::DumpContourSpans(contours);
786}
787
788void DumpSpans(const SkTArray<class SkOpContour, true>* contours) {
789 SkPathOpsDebug::DumpContourSpans(*contours);
790}
791
792void DumpSpans(const SkTArray<class SkOpContour* , true>* contours) {
793 SkPathOpsDebug::DumpContourSpans(*contours);
794}
795
caryclarkdac1d172014-06-17 05:15:38 -0700796void DumpSpan(const SkTArray<class SkOpContour, true>& contours, int segmentID) {
797 SkPathOpsDebug::DumpContourSpan(contours, segmentID);
798}
799
800void DumpSpan(const SkTArray<class SkOpContour* , true>& contours, int segmentID) {
801 SkPathOpsDebug::DumpContourSpan(contours, segmentID);
802}
803
804void DumpSpan(const SkTArray<class SkOpContour, true>* contours, int segmentID) {
805 SkPathOpsDebug::DumpContourSpan(*contours, segmentID);
806}
807
808void DumpSpan(const SkTArray<class SkOpContour* , true>* contours, int segmentID) {
809 SkPathOpsDebug::DumpContourSpan(*contours, segmentID);
810}
811
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000812void DumpPts(const SkTArray<class SkOpContour, true>& contours) {
813 SkPathOpsDebug::DumpContourPts(contours);
814}
815
816void DumpPts(const SkTArray<class SkOpContour* , true>& contours) {
817 SkPathOpsDebug::DumpContourPts(contours);
818}
819
820void DumpPts(const SkTArray<class SkOpContour, true>* contours) {
821 SkPathOpsDebug::DumpContourPts(*contours);
822}
823
824void DumpPts(const SkTArray<class SkOpContour* , true>* contours) {
825 SkPathOpsDebug::DumpContourPts(*contours);
826}
827
caryclarkdac1d172014-06-17 05:15:38 -0700828void DumpPt(const SkTArray<class SkOpContour, true>& contours, int segmentID) {
829 SkPathOpsDebug::DumpContourPt(contours, segmentID);
830}
831
832void DumpPt(const SkTArray<class SkOpContour* , true>& contours, int segmentID) {
833 SkPathOpsDebug::DumpContourPt(contours, segmentID);
834}
835
836void DumpPt(const SkTArray<class SkOpContour, true>* contours, int segmentID) {
837 SkPathOpsDebug::DumpContourPt(*contours, segmentID);
838}
839
840void DumpPt(const SkTArray<class SkOpContour* , true>* contours, int segmentID) {
841 SkPathOpsDebug::DumpContourPt(*contours, segmentID);
842}
843
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000844static void dumpTestCase(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) {
845 SkDebugf("<div id=\"quad%d\">\n", testNo);
846 quad1.dumpComma(",");
847 quad2.dump();
848 SkDebugf("</div>\n\n");
849}
850
851static void dumpTestTrailer() {
852 SkDebugf("</div>\n\n<script type=\"text/javascript\">\n\n");
853 SkDebugf(" var testDivs = [\n");
854}
855
856static void dumpTestList(int testNo, double min) {
857 SkDebugf(" quad%d,", testNo);
858 if (min > 0) {
859 SkDebugf(" // %1.9g", min);
860 }
861 SkDebugf("\n");
862}
863
864void DumpQ(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) {
865 SkDebugf("\n");
866 dumpTestCase(quad1, quad2, testNo);
867 dumpTestTrailer();
868 dumpTestList(testNo, 0);
869 SkDebugf("\n");
870}
871
872void DumpT(const SkDQuad& quad, double t) {
873 SkDLine line = {{quad.ptAtT(t), quad[0]}};
874 line.dump();
875}