blob: c4fbbfa69517610c7168e6fb9e6f361b2c455e78 [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
caryclark65f55312014-11-13 06:58:52 -080022inline void DebugDumpHexFloat(float x) {
23 SkDebugf("SkBits2Float(0x%08x)", SkFloat2Bits(x));
24}
caryclark19eb3b22014-07-18 05:08:14 -070025
26#if DEBUG_SHOW_TEST_NAME
27
28static void output_scalar(SkScalar num) {
29 if (num == (int) num) {
30 SkDebugf("%d", (int) num);
31 } else {
32 SkString str;
33 str.printf("%1.9g", num);
34 int width = (int) str.size();
35 const char* cStr = str.c_str();
36 while (cStr[width - 1] == '0') {
37 --width;
38 }
39 str.resize(width);
40 SkDebugf("%sf", str.c_str());
41 }
42}
43
44static void output_points(const SkPoint* pts, int count) {
45 for (int index = 0; index < count; ++index) {
46 output_scalar(pts[index].fX);
47 SkDebugf(", ");
48 output_scalar(pts[index].fY);
49 if (index + 1 < count) {
50 SkDebugf(", ");
51 }
52 }
53 SkDebugf(");\n");
54}
55
56static void showPathContours(SkPath::RawIter& iter, const char* pathName) {
57 uint8_t verb;
58 SkPoint pts[4];
59 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
60 switch (verb) {
61 case SkPath::kMove_Verb:
62 SkDebugf(" %s.moveTo(", pathName);
63 output_points(&pts[0], 1);
64 continue;
65 case SkPath::kLine_Verb:
66 SkDebugf(" %s.lineTo(", pathName);
67 output_points(&pts[1], 1);
68 break;
69 case SkPath::kQuad_Verb:
70 SkDebugf(" %s.quadTo(", pathName);
71 output_points(&pts[1], 2);
72 break;
73 case SkPath::kCubic_Verb:
74 SkDebugf(" %s.cubicTo(", pathName);
75 output_points(&pts[1], 3);
76 break;
77 case SkPath::kClose_Verb:
78 SkDebugf(" %s.close();\n", pathName);
79 break;
80 default:
81 SkDEBUGFAIL("bad verb");
82 return;
83 }
84 }
85}
86
87static const char* gFillTypeStr[] = {
88 "kWinding_FillType",
89 "kEvenOdd_FillType",
90 "kInverseWinding_FillType",
91 "kInverseEvenOdd_FillType"
92};
93
94void SkPathOpsDebug::ShowOnePath(const SkPath& path, const char* name, bool includeDeclaration) {
95 SkPath::RawIter iter(path);
96#define SUPPORT_RECT_CONTOUR_DETECTION 0
97#if SUPPORT_RECT_CONTOUR_DETECTION
98 int rectCount = path.isRectContours() ? path.rectContours(NULL, NULL) : 0;
99 if (rectCount > 0) {
100 SkTDArray<SkRect> rects;
101 SkTDArray<SkPath::Direction> directions;
102 rects.setCount(rectCount);
103 directions.setCount(rectCount);
104 path.rectContours(rects.begin(), directions.begin());
105 for (int contour = 0; contour < rectCount; ++contour) {
106 const SkRect& rect = rects[contour];
107 SkDebugf("path.addRect(%1.9g, %1.9g, %1.9g, %1.9g, %s);\n", rect.fLeft, rect.fTop,
108 rect.fRight, rect.fBottom, directions[contour] == SkPath::kCCW_Direction
109 ? "SkPath::kCCW_Direction" : "SkPath::kCW_Direction");
110 }
111 return;
112 }
113#endif
114 SkPath::FillType fillType = path.getFillType();
115 SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInverseEvenOdd_FillType);
116 if (includeDeclaration) {
117 SkDebugf(" SkPath %s;\n", name);
118 }
119 SkDebugf(" %s.setFillType(SkPath::%s);\n", name, gFillTypeStr[fillType]);
120 iter.setPath(path);
121 showPathContours(iter, name);
122}
123
124static void show_function_header(const char* functionName) {
125 SkDebugf("\nstatic void %s(skiatest::Reporter* reporter, const char* filename) {\n", functionName);
126 if (strcmp("skphealth_com76", functionName) == 0) {
127 SkDebugf("found it\n");
128 }
129}
130
131static const char* gOpStrs[] = {
132 "kDifference_PathOp",
133 "kIntersect_PathOp",
134 "kUnion_PathOp",
135 "kXor_PathOp",
136 "kReverseDifference_PathOp",
137};
138
139static void show_op(SkPathOp op, const char* pathOne, const char* pathTwo) {
140 SkDebugf(" testPathOp(reporter, %s, %s, %s, filename);\n", pathOne, pathTwo, gOpStrs[op]);
141 SkDebugf("}\n");
142}
143
144SK_DECLARE_STATIC_MUTEX(gTestMutex);
145
146void SkPathOpsDebug::ShowPath(const SkPath& a, const SkPath& b, SkPathOp shapeOp,
147 const char* testName) {
148 SkAutoMutexAcquire ac(gTestMutex);
149 show_function_header(testName);
150 ShowOnePath(a, "path", true);
151 ShowOnePath(b, "pathB", true);
152 show_op(shapeOp, "path", "pathB");
153}
154#endif
155
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000156// if not defined by PathOpsDebug.cpp ...
157#if !defined SK_DEBUG && FORCE_RELEASE
158bool SkPathOpsDebug::ValidWind(int wind) {
159 return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF;
160}
161
162void SkPathOpsDebug::WindingPrintf(int wind) {
163 if (wind == SK_MinS32) {
164 SkDebugf("?");
165 } else {
166 SkDebugf("%d", wind);
167 }
168}
169#endif
170
171void SkOpAngle::dump() const {
caryclarkdac1d172014-06-17 05:15:38 -0700172 dumpOne(true);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000173 SkDebugf("\n");
174}
175
caryclarkdac1d172014-06-17 05:15:38 -0700176void SkOpAngle::dumpOne(bool functionHeader) const {
177// fSegment->debugValidate();
178 const SkOpSpan& mSpan = fSegment->span(SkMin32(fStart, fEnd));
179 if (functionHeader) {
180 SkDebugf("%s ", __FUNCTION__);
181 }
182 SkDebugf("[%d", fSegment->debugID());
183 SkDebugf("/%d", debugID());
184 SkDebugf("] next=");
185 if (fNext) {
186 SkDebugf("%d", fNext->fSegment->debugID());
187 SkDebugf("/%d", fNext->debugID());
188 } else {
189 SkDebugf("?");
190 }
191 SkDebugf(" sect=%d/%d ", fSectorStart, fSectorEnd);
192 SkDebugf(" s=%1.9g [%d] e=%1.9g [%d]", fSegment->span(fStart).fT, fStart,
193 fSegment->span(fEnd).fT, fEnd);
194 SkDebugf(" sgn=%d windVal=%d", sign(), mSpan.fWindValue);
195
196 SkDebugf(" windSum=");
197 SkPathOpsDebug::WindingPrintf(mSpan.fWindSum);
198 if (mSpan.fOppValue != 0 || mSpan.fOppSum != SK_MinS32) {
199 SkDebugf(" oppVal=%d", mSpan.fOppValue);
200 SkDebugf(" oppSum=");
201 SkPathOpsDebug::WindingPrintf(mSpan.fOppSum);
202 }
203 if (mSpan.fDone) {
204 SkDebugf(" done");
205 }
206 if (unorderable()) {
207 SkDebugf(" unorderable");
208 }
209 if (small()) {
210 SkDebugf(" small");
211 }
212 if (mSpan.fTiny) {
213 SkDebugf(" tiny");
214 }
215 if (fSegment->operand()) {
216 SkDebugf(" operand");
217 }
218 if (fStop) {
219 SkDebugf(" stop");
220 }
221}
222
223void SkOpAngle::dumpTo(const SkOpSegment* segment, const SkOpAngle* to) const {
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000224 const SkOpAngle* first = this;
225 const SkOpAngle* next = this;
226 const char* indent = "";
227 do {
228 SkDebugf("%s", indent);
caryclarkdac1d172014-06-17 05:15:38 -0700229 next->dumpOne(false);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000230 if (segment == next->fSegment) {
caryclarkdac1d172014-06-17 05:15:38 -0700231 if (this == fNext) {
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000232 SkDebugf(" << from");
233 }
caryclarkdac1d172014-06-17 05:15:38 -0700234 if (to == fNext) {
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000235 SkDebugf(" << to");
236 }
237 }
238 SkDebugf("\n");
239 indent = " ";
240 next = next->fNext;
241 } while (next && next != first);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000242}
243
244void SkOpAngle::dumpLoop() const {
245 const SkOpAngle* first = this;
246 const SkOpAngle* next = this;
247 do {
caryclarke4097e32014-06-18 07:24:19 -0700248 next->dumpOne(false);
249 SkDebugf("\n");
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000250 next = next->fNext;
251 } while (next && next != first);
252}
253
254void SkOpAngle::dumpPartials() const {
255 const SkOpAngle* first = this;
256 const SkOpAngle* next = this;
257 do {
258 next->fCurvePart.dumpNumber();
259 next = next->fNext;
260 } while (next && next != first);
261}
262
caryclarkdac1d172014-06-17 05:15:38 -0700263void SkOpAngleSet::dump() const {
264 // FIXME: unimplemented
265/* This requires access to the internal SkChunkAlloc data
266 Defer implementing this until it is needed for debugging
267*/
268 SkASSERT(0);
269}
270
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000271void SkOpContour::dump() const {
272 int segmentCount = fSegments.count();
273 SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID());
274 for (int test = 0; test < segmentCount; ++test) {
275 SkDebugf(" [%d] ((SkOpSegment*) 0x%p) [%d]\n", test, &fSegments[test],
276 fSegments[test].debugID());
277 }
278}
279
280void SkOpContour::dumpAngles() const {
281 int segmentCount = fSegments.count();
282 SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID());
283 for (int test = 0; test < segmentCount; ++test) {
284 SkDebugf(" [%d] ", test);
285 fSegments[test].dumpAngles();
286 }
287}
288
caryclarkdac1d172014-06-17 05:15:38 -0700289void SkOpContour::dumpCoincidence(const SkCoincidence& coin) const {
290 int thisIndex = coin.fSegments[0];
291 const SkOpSegment& s1 = fSegments[thisIndex];
292 int otherIndex = coin.fSegments[1];
293 const SkOpSegment& s2 = coin.fOther->fSegments[otherIndex];
294 SkDebugf("((SkOpSegment*) 0x%p) [%d] ((SkOpSegment*) 0x%p) [%d]\n", &s1, s1.debugID(),
295 &s2, s2.debugID());
296 for (int index = 0; index < 2; ++index) {
297 SkDebugf(" {%1.9gf, %1.9gf}", coin.fPts[0][index].fX, coin.fPts[0][index].fY);
298 if (coin.fNearly[index]) {
299 SkDebugf(" {%1.9gf, %1.9gf}", coin.fPts[1][index].fX, coin.fPts[1][index].fY);
300 }
301 SkDebugf(" seg1t=%1.9g seg2t=%1.9g\n", coin.fTs[0][index], coin.fTs[1][index]);
302 }
303}
304
305void SkOpContour::dumpCoincidences() const {
306 int count = fCoincidences.count();
307 if (count > 0) {
308 SkDebugf("fCoincidences count=%d\n", count);
309 for (int test = 0; test < count; ++test) {
310 dumpCoincidence(fCoincidences[test]);
311 }
312 }
313 count = fPartialCoincidences.count();
314 if (count == 0) {
315 return;
316 }
317 SkDebugf("fPartialCoincidences count=%d\n", count);
318 for (int test = 0; test < count; ++test) {
319 dumpCoincidence(fPartialCoincidences[test]);
320 }
321}
322
323void SkOpContour::dumpPt(int index) const {
324 int segmentCount = fSegments.count();
325 for (int test = 0; test < segmentCount; ++test) {
326 const SkOpSegment& segment = fSegments[test];
327 if (segment.debugID() == index) {
328 fSegments[test].dumpPts();
329 }
330 }
331}
332
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000333void SkOpContour::dumpPts() const {
334 int segmentCount = fSegments.count();
335 SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID());
336 for (int test = 0; test < segmentCount; ++test) {
337 SkDebugf(" [%d] ", test);
338 fSegments[test].dumpPts();
339 }
340}
341
caryclarkdac1d172014-06-17 05:15:38 -0700342void SkOpContour::dumpSpan(int index) const {
343 int segmentCount = fSegments.count();
344 for (int test = 0; test < segmentCount; ++test) {
345 const SkOpSegment& segment = fSegments[test];
346 if (segment.debugID() == index) {
347 fSegments[test].dumpSpans();
348 }
349 }
350}
351
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000352void SkOpContour::dumpSpans() const {
353 int segmentCount = fSegments.count();
354 SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID());
355 for (int test = 0; test < segmentCount; ++test) {
356 SkDebugf(" [%d] ", test);
357 fSegments[test].dumpSpans();
358 }
359}
360
361void SkDCubic::dump() const {
362 SkDebugf("{{");
363 int index = 0;
364 do {
365 fPts[index].dump();
366 SkDebugf(", ");
367 } while (++index < 3);
368 fPts[index].dump();
369 SkDebugf("}}\n");
370}
371
372void SkDCubic::dumpNumber() const {
373 SkDebugf("{{");
374 int index = 0;
375 bool dumpedOne = false;
376 do {
377 if (!(fPts[index].fX == fPts[index].fX && fPts[index].fY == fPts[index].fY)) {
378 continue;
379 }
380 if (dumpedOne) {
381 SkDebugf(", ");
382 }
383 fPts[index].dump();
384 dumpedOne = true;
385 } while (++index < 3);
386 if (fPts[index].fX == fPts[index].fX && fPts[index].fY == fPts[index].fY) {
387 if (dumpedOne) {
388 SkDebugf(", ");
389 }
390 fPts[index].dump();
391 }
392 SkDebugf("}}\n");
393}
394
395void SkDLine::dump() const {
396 SkDebugf("{{");
397 fPts[0].dump();
398 SkDebugf(", ");
399 fPts[1].dump();
400 SkDebugf("}}\n");
401}
402
403void SkDPoint::dump() const {
404 SkDebugf("{");
405 DebugDumpDouble(fX);
406 SkDebugf(", ");
407 DebugDumpDouble(fY);
408 SkDebugf("}");
409}
410
411void SkDPoint::Dump(const SkPoint& pt) {
412 SkDebugf("{");
413 DebugDumpFloat(pt.fX);
414 SkDebugf(", ");
415 DebugDumpFloat(pt.fY);
416 SkDebugf("}");
417}
418
caryclark65f55312014-11-13 06:58:52 -0800419void SkDPoint::DumpHex(const SkPoint& pt) {
420 SkDebugf("{");
421 DebugDumpHexFloat(pt.fX);
422 SkDebugf(", ");
423 DebugDumpHexFloat(pt.fY);
424 SkDebugf("}");
425}
426
427void SkDQuad::dump() const {
428 dumpComma("");
429}
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000430
431void SkDQuad::dumpComma(const char* comma) const {
432 SkDebugf("{{");
433 int index = 0;
434 do {
435 fPts[index].dump();
436 SkDebugf(", ");
437 } while (++index < 2);
438 fPts[index].dump();
439 SkDebugf("}}%s\n", comma ? comma : "");
440}
441
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000442void SkIntersectionHelper::dump() const {
443 SkDPoint::Dump(pts()[0]);
444 SkDPoint::Dump(pts()[1]);
445 if (verb() >= SkPath::kQuad_Verb) {
446 SkDPoint::Dump(pts()[2]);
447 }
448 if (verb() >= SkPath::kCubic_Verb) {
449 SkDPoint::Dump(pts()[3]);
450 }
451}
452
commit-bot@chromium.org8cb1daa2014-04-25 12:59:11 +0000453const SkTDArray<SkOpSpan>& SkOpSegment::debugSpans() const {
454 return fTs;
455}
456
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000457void SkOpSegment::dumpAngles() const {
458 SkDebugf("((SkOpSegment*) 0x%p) [%d]\n", this, debugID());
caryclarkdac1d172014-06-17 05:15:38 -0700459 const SkOpAngle* fromAngle = NULL;
460 const SkOpAngle* toAngle = NULL;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000461 for (int index = 0; index < count(); ++index) {
caryclarkdac1d172014-06-17 05:15:38 -0700462 const SkOpAngle* fAngle = fTs[index].fFromAngle;
463 const SkOpAngle* tAngle = fTs[index].fToAngle;
464 if (fromAngle == fAngle && toAngle == tAngle) {
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000465 continue;
466 }
caryclarkdac1d172014-06-17 05:15:38 -0700467 if (fAngle) {
468 SkDebugf(" [%d] from=%d ", index, fAngle->debugID());
469 fAngle->dumpTo(this, tAngle);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000470 }
caryclarkdac1d172014-06-17 05:15:38 -0700471 if (tAngle) {
472 SkDebugf(" [%d] to=%d ", index, tAngle->debugID());
473 tAngle->dumpTo(this, fAngle);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000474 }
caryclarkdac1d172014-06-17 05:15:38 -0700475 fromAngle = fAngle;
476 toAngle = tAngle;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000477 }
478}
479
480void SkOpSegment::dumpContour(int firstID, int lastID) const {
481 if (debugID() < 0) {
482 return;
483 }
484 const SkOpSegment* test = this - (debugID() - 1);
485 test += (firstID - 1);
486 const SkOpSegment* last = test + (lastID - firstID);
487 while (test <= last) {
488 test->dumpSpans();
489 ++test;
490 }
491}
492
493void SkOpSegment::dumpPts() const {
494 int last = SkPathOpsVerbToPoints(fVerb);
495 SkDebugf("((SkOpSegment*) 0x%p) [%d] {{", this, debugID());
496 int index = 0;
497 do {
498 SkDPoint::Dump(fPts[index]);
499 SkDebugf(", ");
500 } while (++index < last);
501 SkDPoint::Dump(fPts[index]);
502 SkDebugf("}}\n");
503}
504
caryclark65f55312014-11-13 06:58:52 -0800505void SkOpSegment::dumpHexPts() const {
506 int last = SkPathOpsVerbToPoints(fVerb);
507 SkDebugf("((SkOpSegment*) 0x%p) [%d] {{", this, debugID());
508 int index = 0;
509 do {
510 SkDPoint::DumpHex(fPts[index]);
511 SkDebugf(", ");
512 } while (++index < last);
513 SkDPoint::DumpHex(fPts[index]);
514 SkDebugf("}}\n");
515}
516
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000517void SkOpSegment::dumpDPts() const {
518 int count = SkPathOpsVerbToPoints(fVerb);
519 SkDebugf("((SkOpSegment*) 0x%p) [%d] {{", this, debugID());
520 int index = 0;
521 do {
522 SkDPoint dPt = {fPts[index].fX, fPts[index].fY};
523 dPt.dump();
524 if (index != count) {
525 SkDebugf(", ");
526 }
527 } while (++index <= count);
528 SkDebugf("}}\n");
529}
530
531void SkOpSegment::dumpSpans() const {
532 int count = this->count();
533 SkDebugf("((SkOpSegment*) 0x%p) [%d]\n", this, debugID());
534 for (int index = 0; index < count; ++index) {
535 const SkOpSpan& span = this->span(index);
536 SkDebugf(" [%d] ", index);
537 span.dumpOne();
538 }
539}
540
caryclarkdac1d172014-06-17 05:15:38 -0700541void SkPathOpsDebug::DumpCoincidence(const SkTArray<SkOpContour, true>& contours) {
542 int count = contours.count();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000543 for (int index = 0; index < count; ++index) {
caryclarkdac1d172014-06-17 05:15:38 -0700544 contours[index].dumpCoincidences();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000545 }
546}
547
caryclarkdac1d172014-06-17 05:15:38 -0700548void SkPathOpsDebug::DumpCoincidence(const SkTArray<SkOpContour* , true>& contours) {
549 int count = contours.count();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000550 for (int index = 0; index < count; ++index) {
caryclarkdac1d172014-06-17 05:15:38 -0700551 contours[index]->dumpCoincidences();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000552 }
553}
554
555void SkPathOpsDebug::DumpContours(const SkTArray<SkOpContour, true>& contours) {
556 int count = contours.count();
557 for (int index = 0; index < count; ++index) {
558 contours[index].dump();
559 }
560}
561
562void SkPathOpsDebug::DumpContours(const SkTArray<SkOpContour* , true>& contours) {
563 int count = contours.count();
564 for (int index = 0; index < count; ++index) {
565 contours[index]->dump();
566 }
567}
568
569void SkPathOpsDebug::DumpContourAngles(const SkTArray<SkOpContour, true>& contours) {
570 int count = contours.count();
571 for (int index = 0; index < count; ++index) {
572 contours[index].dumpAngles();
573 }
574}
575
576void SkPathOpsDebug::DumpContourAngles(const SkTArray<SkOpContour* , true>& contours) {
577 int count = contours.count();
578 for (int index = 0; index < count; ++index) {
579 contours[index]->dumpAngles();
580 }
581}
582
583void SkPathOpsDebug::DumpContourPts(const SkTArray<SkOpContour, true>& contours) {
584 int count = contours.count();
585 for (int index = 0; index < count; ++index) {
586 contours[index].dumpPts();
587 }
588}
589
590void SkPathOpsDebug::DumpContourPts(const SkTArray<SkOpContour* , true>& contours) {
591 int count = contours.count();
592 for (int index = 0; index < count; ++index) {
593 contours[index]->dumpPts();
594 }
595}
596
caryclarkdac1d172014-06-17 05:15:38 -0700597void SkPathOpsDebug::DumpContourPt(const SkTArray<SkOpContour, true>& contours, int segmentID) {
598 int count = contours.count();
599 for (int index = 0; index < count; ++index) {
600 contours[index].dumpPt(segmentID);
601 }
602}
603
604void SkPathOpsDebug::DumpContourPt(const SkTArray<SkOpContour* , true>& contours, int segmentID) {
605 int count = contours.count();
606 for (int index = 0; index < count; ++index) {
607 contours[index]->dumpPt(segmentID);
608 }
609}
610
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000611void SkPathOpsDebug::DumpContourSpans(const SkTArray<SkOpContour, true>& contours) {
612 int count = contours.count();
613 for (int index = 0; index < count; ++index) {
614 contours[index].dumpSpans();
615 }
616}
617
618void SkPathOpsDebug::DumpContourSpans(const SkTArray<SkOpContour* , true>& contours) {
619 int count = contours.count();
620 for (int index = 0; index < count; ++index) {
621 contours[index]->dumpSpans();
622 }
623}
624
caryclarkdac1d172014-06-17 05:15:38 -0700625void SkPathOpsDebug::DumpContourSpan(const SkTArray<SkOpContour, true>& contours, int segmentID) {
626 int count = contours.count();
627 for (int index = 0; index < count; ++index) {
628 contours[index].dumpSpan(segmentID);
629 }
630}
631
632void SkPathOpsDebug::DumpContourSpan(const SkTArray<SkOpContour* , true>& contours, int segmentID) {
633 int count = contours.count();
634 for (int index = 0; index < count; ++index) {
635 contours[index]->dumpSpan(segmentID);
636 }
637}
638
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000639void SkPathOpsDebug::DumpSpans(const SkTDArray<SkOpSpan *>& spans) {
640 int count = spans.count();
641 for (int index = 0; index < count; ++index) {
642 const SkOpSpan* span = spans[index];
643 const SkOpSpan& oSpan = span->fOther->span(span->fOtherIndex);
644 const SkOpSegment* segment = oSpan.fOther;
645 SkDebugf("((SkOpSegment*) 0x%p) [%d] ", segment, segment->debugID());
646 SkDebugf("spanIndex:%d ", oSpan.fOtherIndex);
647 span->dumpOne();
648 }
649}
650
651// this does not require that other T index is initialized or correct
652const SkOpSegment* SkOpSpan::debugToSegment(ptrdiff_t* spanIndex) const {
653 if (!fOther) {
654 return NULL;
655 }
656 int oppCount = fOther->count();
657 for (int index = 0; index < oppCount; ++index) {
658 const SkOpSpan& otherSpan = fOther->span(index);
659 double otherTestT = otherSpan.fT;
660 if (otherTestT < fOtherT) {
661 continue;
662 }
663 SkASSERT(otherTestT == fOtherT);
664 const SkOpSegment* candidate = otherSpan.fOther;
commit-bot@chromium.org8cb1daa2014-04-25 12:59:11 +0000665 const SkOpSpan* first = candidate->debugSpans().begin();
666 const SkOpSpan* last = candidate->debugSpans().end() - 1;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000667 if (first <= this && this <= last) {
668 if (spanIndex) {
669 *spanIndex = this - first;
670 }
671 return candidate;
672 }
673 }
674 SkASSERT(0);
675 return NULL;
676}
677
678void SkOpSpan::dumpOne() const {
679 SkDebugf("t=");
680 DebugDumpDouble(fT);
681 SkDebugf(" pt=");
682 SkDPoint::Dump(fPt);
683 if (fOther) {
684 SkDebugf(" other.fID=%d", fOther->debugID());
685 SkDebugf(" [%d] otherT=", fOtherIndex);
686 DebugDumpDouble(fOtherT);
687 } else {
688 SkDebugf(" other.fID=? [?] otherT=?");
689 }
caryclarkdac1d172014-06-17 05:15:38 -0700690 if (fWindSum != SK_MinS32) {
691 SkDebugf(" windSum=%d", fWindSum);
692 }
693 if (fOppSum != SK_MinS32 && (SkPathOpsDebug::ValidWind(fOppSum) || fOppValue != 0)) {
694 SkDebugf(" oppSum=%d", fOppSum);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000695 }
696 SkDebugf(" windValue=%d", fWindValue);
697 if (SkPathOpsDebug::ValidWind(fOppSum) || fOppValue != 0) {
698 SkDebugf(" oppValue=%d", fOppValue);
699 }
caryclarkdac1d172014-06-17 05:15:38 -0700700 if (fFromAngle && fFromAngle->debugID()) {
701 SkDebugf(" from=%d", fFromAngle->debugID());
702 }
703 if (fToAngle && fToAngle->debugID()) {
704 SkDebugf(" to=%d", fToAngle->debugID());
705 }
706 if (fChased) {
707 SkDebugf(" chased");
708 }
709 if (fCoincident) {
710 SkDebugf(" coincident");
711 }
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000712 if (fDone) {
713 SkDebugf(" done");
714 }
caryclarkdac1d172014-06-17 05:15:38 -0700715 if (fLoop) {
716 SkDebugf(" loop");
717 }
718 if (fMultiple) {
719 SkDebugf(" multiple");
720 }
721 if (fNear) {
722 SkDebugf(" near");
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000723 }
724 if (fSmall) {
725 SkDebugf(" small");
726 }
caryclarkdac1d172014-06-17 05:15:38 -0700727 if (fTiny) {
728 SkDebugf(" tiny");
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000729 }
730 SkDebugf("\n");
731}
732
733void SkOpSpan::dump() const {
734 ptrdiff_t spanIndex;
735 const SkOpSegment* segment = debugToSegment(&spanIndex);
736 if (segment) {
737 SkDebugf("((SkOpSegment*) 0x%p) [%d]\n", segment, segment->debugID());
738 SkDebugf(" [%d] ", spanIndex);
739 } else {
740 SkDebugf("((SkOpSegment*) ?) [?]\n");
741 SkDebugf(" [?] ");
742 }
743 dumpOne();
744}
745
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000746void Dump(const SkTArray<class SkOpContour, true>& contours) {
747 SkPathOpsDebug::DumpContours(contours);
748}
749
750void Dump(const SkTArray<class SkOpContour* , true>& contours) {
751 SkPathOpsDebug::DumpContours(contours);
752}
753
754void Dump(const SkTArray<class SkOpContour, true>* contours) {
755 SkPathOpsDebug::DumpContours(*contours);
756}
757
758void Dump(const SkTArray<class SkOpContour* , true>* contours) {
759 SkPathOpsDebug::DumpContours(*contours);
760}
761
caryclarkdac1d172014-06-17 05:15:38 -0700762void Dump(const SkTDArray<SkOpSpan *>& chase) {
763 SkPathOpsDebug::DumpSpans(chase);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000764}
765
caryclarkdac1d172014-06-17 05:15:38 -0700766void Dump(const SkTDArray<SkOpSpan *>* chase) {
767 SkPathOpsDebug::DumpSpans(*chase);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000768}
769
770void DumpAngles(const SkTArray<class SkOpContour, true>& contours) {
771 SkPathOpsDebug::DumpContourAngles(contours);
772}
773
774void DumpAngles(const SkTArray<class SkOpContour* , true>& contours) {
775 SkPathOpsDebug::DumpContourAngles(contours);
776}
777
778void DumpAngles(const SkTArray<class SkOpContour, true>* contours) {
779 SkPathOpsDebug::DumpContourAngles(*contours);
780}
781
782void DumpAngles(const SkTArray<class SkOpContour* , true>* contours) {
783 SkPathOpsDebug::DumpContourAngles(*contours);
784}
785
caryclarkdac1d172014-06-17 05:15:38 -0700786void DumpCoin(const SkTArray<class SkOpContour, true>& contours) {
787 SkPathOpsDebug::DumpCoincidence(contours);
788}
789
790void DumpCoin(const SkTArray<class SkOpContour* , true>& contours) {
791 SkPathOpsDebug::DumpCoincidence(contours);
792}
793
794void DumpCoin(const SkTArray<class SkOpContour, true>* contours) {
795 SkPathOpsDebug::DumpCoincidence(*contours);
796}
797
798void DumpCoin(const SkTArray<class SkOpContour* , true>* contours) {
799 SkPathOpsDebug::DumpCoincidence(*contours);
800}
801
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000802void DumpSpans(const SkTArray<class SkOpContour, true>& contours) {
803 SkPathOpsDebug::DumpContourSpans(contours);
804}
805
806void DumpSpans(const SkTArray<class SkOpContour* , true>& contours) {
807 SkPathOpsDebug::DumpContourSpans(contours);
808}
809
810void DumpSpans(const SkTArray<class SkOpContour, true>* contours) {
811 SkPathOpsDebug::DumpContourSpans(*contours);
812}
813
814void DumpSpans(const SkTArray<class SkOpContour* , true>* contours) {
815 SkPathOpsDebug::DumpContourSpans(*contours);
816}
817
caryclarkdac1d172014-06-17 05:15:38 -0700818void DumpSpan(const SkTArray<class SkOpContour, true>& contours, int segmentID) {
819 SkPathOpsDebug::DumpContourSpan(contours, segmentID);
820}
821
822void DumpSpan(const SkTArray<class SkOpContour* , true>& contours, int segmentID) {
823 SkPathOpsDebug::DumpContourSpan(contours, segmentID);
824}
825
826void DumpSpan(const SkTArray<class SkOpContour, true>* contours, int segmentID) {
827 SkPathOpsDebug::DumpContourSpan(*contours, segmentID);
828}
829
830void DumpSpan(const SkTArray<class SkOpContour* , true>* contours, int segmentID) {
831 SkPathOpsDebug::DumpContourSpan(*contours, segmentID);
832}
833
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000834void DumpPts(const SkTArray<class SkOpContour, true>& contours) {
835 SkPathOpsDebug::DumpContourPts(contours);
836}
837
838void DumpPts(const SkTArray<class SkOpContour* , true>& contours) {
839 SkPathOpsDebug::DumpContourPts(contours);
840}
841
842void DumpPts(const SkTArray<class SkOpContour, true>* contours) {
843 SkPathOpsDebug::DumpContourPts(*contours);
844}
845
846void DumpPts(const SkTArray<class SkOpContour* , true>* contours) {
847 SkPathOpsDebug::DumpContourPts(*contours);
848}
849
caryclarkdac1d172014-06-17 05:15:38 -0700850void DumpPt(const SkTArray<class SkOpContour, true>& contours, int segmentID) {
851 SkPathOpsDebug::DumpContourPt(contours, segmentID);
852}
853
854void DumpPt(const SkTArray<class SkOpContour* , true>& contours, int segmentID) {
855 SkPathOpsDebug::DumpContourPt(contours, segmentID);
856}
857
858void DumpPt(const SkTArray<class SkOpContour, true>* contours, int segmentID) {
859 SkPathOpsDebug::DumpContourPt(*contours, segmentID);
860}
861
862void DumpPt(const SkTArray<class SkOpContour* , true>* contours, int segmentID) {
863 SkPathOpsDebug::DumpContourPt(*contours, segmentID);
864}
865
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000866static void dumpTestCase(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) {
867 SkDebugf("<div id=\"quad%d\">\n", testNo);
868 quad1.dumpComma(",");
869 quad2.dump();
870 SkDebugf("</div>\n\n");
871}
872
873static void dumpTestTrailer() {
874 SkDebugf("</div>\n\n<script type=\"text/javascript\">\n\n");
875 SkDebugf(" var testDivs = [\n");
876}
877
878static void dumpTestList(int testNo, double min) {
879 SkDebugf(" quad%d,", testNo);
880 if (min > 0) {
881 SkDebugf(" // %1.9g", min);
882 }
883 SkDebugf("\n");
884}
885
886void DumpQ(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) {
887 SkDebugf("\n");
888 dumpTestCase(quad1, quad2, testNo);
889 dumpTestTrailer();
890 dumpTestList(testNo, 0);
891 SkDebugf("\n");
892}
893
894void DumpT(const SkDQuad& quad, double t) {
895 SkDLine line = {{quad.ptAtT(t), quad[0]}};
896 line.dump();
897}