blob: 93fe33d99a64c1f1e5ef62700d43f0bb63a6aab9 [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
8#include "PathOpsTSectDebug.h"
9#include "SkOpCoincidence.h"
commit-bot@chromium.org4431e772014-04-14 17:08:59 +000010#include "SkOpContour.h"
11#include "SkIntersectionHelper.h"
12#include "SkOpSegment.h"
caryclark19eb3b22014-07-18 05:08:14 -070013#include "SkString.h"
commit-bot@chromium.org4431e772014-04-14 17:08:59 +000014
15inline void DebugDumpDouble(double x) {
16 if (x == floor(x)) {
17 SkDebugf("%.0f", x);
18 } else {
19 SkDebugf("%1.19g", x);
20 }
21}
22
23inline void DebugDumpFloat(float x) {
24 if (x == floorf(x)) {
25 SkDebugf("%.0f", x);
26 } else {
27 SkDebugf("%1.9gf", x);
28 }
29}
30
caryclark65f55312014-11-13 06:58:52 -080031inline void DebugDumpHexFloat(float x) {
32 SkDebugf("SkBits2Float(0x%08x)", SkFloat2Bits(x));
33}
caryclark19eb3b22014-07-18 05:08:14 -070034
35#if DEBUG_SHOW_TEST_NAME
36
37static void output_scalar(SkScalar num) {
38 if (num == (int) num) {
39 SkDebugf("%d", (int) num);
40 } else {
41 SkString str;
42 str.printf("%1.9g", num);
43 int width = (int) str.size();
44 const char* cStr = str.c_str();
45 while (cStr[width - 1] == '0') {
46 --width;
47 }
48 str.resize(width);
49 SkDebugf("%sf", str.c_str());
50 }
51}
52
53static void output_points(const SkPoint* pts, int count) {
54 for (int index = 0; index < count; ++index) {
55 output_scalar(pts[index].fX);
56 SkDebugf(", ");
57 output_scalar(pts[index].fY);
58 if (index + 1 < count) {
59 SkDebugf(", ");
60 }
61 }
caryclark19eb3b22014-07-18 05:08:14 -070062}
63
64static void showPathContours(SkPath::RawIter& iter, const char* pathName) {
65 uint8_t verb;
66 SkPoint pts[4];
67 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
68 switch (verb) {
69 case SkPath::kMove_Verb:
70 SkDebugf(" %s.moveTo(", pathName);
71 output_points(&pts[0], 1);
caryclark54359292015-03-26 07:52:43 -070072 SkDebugf(");\n");
caryclark19eb3b22014-07-18 05:08:14 -070073 continue;
74 case SkPath::kLine_Verb:
75 SkDebugf(" %s.lineTo(", pathName);
76 output_points(&pts[1], 1);
caryclark54359292015-03-26 07:52:43 -070077 SkDebugf(");\n");
caryclark19eb3b22014-07-18 05:08:14 -070078 break;
79 case SkPath::kQuad_Verb:
80 SkDebugf(" %s.quadTo(", pathName);
81 output_points(&pts[1], 2);
caryclark54359292015-03-26 07:52:43 -070082 SkDebugf(");\n");
83 break;
84 case SkPath::kConic_Verb:
85 SkDebugf(" %s.conicTo(", pathName);
86 output_points(&pts[1], 2);
87 SkDebugf(", %1.9gf);\n", iter.conicWeight());
caryclark19eb3b22014-07-18 05:08:14 -070088 break;
89 case SkPath::kCubic_Verb:
90 SkDebugf(" %s.cubicTo(", pathName);
91 output_points(&pts[1], 3);
caryclark54359292015-03-26 07:52:43 -070092 SkDebugf(");\n");
caryclark19eb3b22014-07-18 05:08:14 -070093 break;
94 case SkPath::kClose_Verb:
95 SkDebugf(" %s.close();\n", pathName);
96 break;
97 default:
98 SkDEBUGFAIL("bad verb");
99 return;
100 }
101 }
102}
103
104static const char* gFillTypeStr[] = {
105 "kWinding_FillType",
106 "kEvenOdd_FillType",
107 "kInverseWinding_FillType",
108 "kInverseEvenOdd_FillType"
109};
110
111void SkPathOpsDebug::ShowOnePath(const SkPath& path, const char* name, bool includeDeclaration) {
112 SkPath::RawIter iter(path);
113#define SUPPORT_RECT_CONTOUR_DETECTION 0
114#if SUPPORT_RECT_CONTOUR_DETECTION
115 int rectCount = path.isRectContours() ? path.rectContours(NULL, NULL) : 0;
116 if (rectCount > 0) {
117 SkTDArray<SkRect> rects;
118 SkTDArray<SkPath::Direction> directions;
119 rects.setCount(rectCount);
120 directions.setCount(rectCount);
121 path.rectContours(rects.begin(), directions.begin());
122 for (int contour = 0; contour < rectCount; ++contour) {
123 const SkRect& rect = rects[contour];
124 SkDebugf("path.addRect(%1.9g, %1.9g, %1.9g, %1.9g, %s);\n", rect.fLeft, rect.fTop,
125 rect.fRight, rect.fBottom, directions[contour] == SkPath::kCCW_Direction
126 ? "SkPath::kCCW_Direction" : "SkPath::kCW_Direction");
127 }
128 return;
129 }
130#endif
131 SkPath::FillType fillType = path.getFillType();
132 SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInverseEvenOdd_FillType);
133 if (includeDeclaration) {
134 SkDebugf(" SkPath %s;\n", name);
135 }
136 SkDebugf(" %s.setFillType(SkPath::%s);\n", name, gFillTypeStr[fillType]);
137 iter.setPath(path);
138 showPathContours(iter, name);
139}
140
141static void show_function_header(const char* functionName) {
142 SkDebugf("\nstatic void %s(skiatest::Reporter* reporter, const char* filename) {\n", functionName);
143 if (strcmp("skphealth_com76", functionName) == 0) {
144 SkDebugf("found it\n");
145 }
146}
147
148static const char* gOpStrs[] = {
caryclark54359292015-03-26 07:52:43 -0700149 "kDifference_SkPathOp",
150 "kIntersect_SkPathOp",
151 "kUnion_SkPathOp",
caryclark19eb3b22014-07-18 05:08:14 -0700152 "kXor_PathOp",
caryclark54359292015-03-26 07:52:43 -0700153 "kReverseDifference_SkPathOp",
caryclark19eb3b22014-07-18 05:08:14 -0700154};
155
156static void show_op(SkPathOp op, const char* pathOne, const char* pathTwo) {
157 SkDebugf(" testPathOp(reporter, %s, %s, %s, filename);\n", pathOne, pathTwo, gOpStrs[op]);
158 SkDebugf("}\n");
159}
160
161SK_DECLARE_STATIC_MUTEX(gTestMutex);
162
163void SkPathOpsDebug::ShowPath(const SkPath& a, const SkPath& b, SkPathOp shapeOp,
164 const char* testName) {
165 SkAutoMutexAcquire ac(gTestMutex);
166 show_function_header(testName);
167 ShowOnePath(a, "path", true);
168 ShowOnePath(b, "pathB", true);
169 show_op(shapeOp, "path", "pathB");
170}
171#endif
172
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000173// if not defined by PathOpsDebug.cpp ...
174#if !defined SK_DEBUG && FORCE_RELEASE
175bool SkPathOpsDebug::ValidWind(int wind) {
176 return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF;
177}
178
179void SkPathOpsDebug::WindingPrintf(int wind) {
180 if (wind == SK_MinS32) {
181 SkDebugf("?");
182 } else {
183 SkDebugf("%d", wind);
184 }
185}
186#endif
187
caryclark54359292015-03-26 07:52:43 -0700188void SkDCubic::dump() const {
189 dumpInner();
190 SkDebugf("}},\n");
reed0dc4dd62015-03-24 13:55:33 -0700191}
192
caryclark54359292015-03-26 07:52:43 -0700193void SkDCubic::dumpID(int id) const {
194 dumpInner();
195 SkDebugf("}} id=%d\n", id);
reed0dc4dd62015-03-24 13:55:33 -0700196}
197
caryclark54359292015-03-26 07:52:43 -0700198static inline bool double_is_NaN(double x) { return x != x; }
199
200void SkDCubic::dumpInner() const {
201 SkDebugf("{{");
202 int index = 0;
reed0dc4dd62015-03-24 13:55:33 -0700203 do {
caryclark54359292015-03-26 07:52:43 -0700204 if (index != 0) {
205 if (double_is_NaN(fPts[index].fX) && double_is_NaN(fPts[index].fY)) {
206 return;
reed0dc4dd62015-03-24 13:55:33 -0700207 }
caryclark54359292015-03-26 07:52:43 -0700208 SkDebugf(", ");
reed0dc4dd62015-03-24 13:55:33 -0700209 }
caryclark54359292015-03-26 07:52:43 -0700210 fPts[index].dump();
211 } while (++index < 3);
212 if (double_is_NaN(fPts[index].fX) && double_is_NaN(fPts[index].fY)) {
reed0dc4dd62015-03-24 13:55:33 -0700213 return;
214 }
caryclark54359292015-03-26 07:52:43 -0700215 SkDebugf(", ");
reed0dc4dd62015-03-24 13:55:33 -0700216 fPts[index].dump();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000217}
218
219void SkDLine::dump() const {
220 SkDebugf("{{");
221 fPts[0].dump();
222 SkDebugf(", ");
223 fPts[1].dump();
caryclark54359292015-03-26 07:52:43 -0700224 SkDebugf("}},\n");
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000225}
226
227void SkDPoint::dump() const {
228 SkDebugf("{");
229 DebugDumpDouble(fX);
230 SkDebugf(", ");
231 DebugDumpDouble(fY);
232 SkDebugf("}");
233}
234
235void SkDPoint::Dump(const SkPoint& pt) {
236 SkDebugf("{");
237 DebugDumpFloat(pt.fX);
238 SkDebugf(", ");
239 DebugDumpFloat(pt.fY);
240 SkDebugf("}");
241}
242
caryclark65f55312014-11-13 06:58:52 -0800243void SkDPoint::DumpHex(const SkPoint& pt) {
244 SkDebugf("{");
245 DebugDumpHexFloat(pt.fX);
246 SkDebugf(", ");
247 DebugDumpHexFloat(pt.fY);
248 SkDebugf("}");
249}
250
251void SkDQuad::dump() const {
caryclark54359292015-03-26 07:52:43 -0700252 dumpInner();
253 SkDebugf("}},\n");
caryclark65f55312014-11-13 06:58:52 -0800254}
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000255
caryclark54359292015-03-26 07:52:43 -0700256void SkDQuad::dumpID(int id) const {
257 dumpInner();
258 SkDebugf("}} id=%d\n", id);
259}
260
261void SkDQuad::dumpInner() const {
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000262 SkDebugf("{{");
263 int index = 0;
264 do {
265 fPts[index].dump();
266 SkDebugf(", ");
267 } while (++index < 2);
268 fPts[index].dump();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000269}
270
caryclark54359292015-03-26 07:52:43 -0700271void SkIntersections::dump() const {
272 SkDebugf("used=%d of %d", fUsed, fMax);
273 for (int index = 0; index < fUsed; ++index) {
274 SkDebugf(" t=(%s%1.9g,%s%1.9g) pt=(%1.9g,%1.9g)",
275 fIsCoincident[0] & (1 << index) ? "*" : "", fT[0][index],
276 fIsCoincident[1] & (1 << index) ? "*" : "", fT[1][index],
277 fPt[index].fX, fPt[index].fY);
278 if (index < 2 && fNearlySame[index]) {
279 SkDebugf(" pt2=(%1.9g,%1.9g)",fPt2[index].fX, fPt2[index].fY);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000280 }
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000281 }
282 SkDebugf("\n");
283}
284
caryclark54359292015-03-26 07:52:43 -0700285const SkOpAngle* SkPathOpsDebug::DebugAngleAngle(const SkOpAngle* angle, int id) {
286 return angle->debugAngle(id);
287}
288
289SkOpContour* SkPathOpsDebug::DebugAngleContour(SkOpAngle* angle, int id) {
290 return angle->debugContour(id);
291}
292
293const SkOpPtT* SkPathOpsDebug::DebugAnglePtT(const SkOpAngle* angle, int id) {
294 return angle->debugPtT(id);
295}
296
297const SkOpSegment* SkPathOpsDebug::DebugAngleSegment(const SkOpAngle* angle, int id) {
298 return angle->debugSegment(id);
299}
300
301const SkOpSpanBase* SkPathOpsDebug::DebugAngleSpan(const SkOpAngle* angle, int id) {
302 return angle->debugSpan(id);
303}
304
305const SkOpAngle* SkPathOpsDebug::DebugContourAngle(SkOpContour* contour, int id) {
306 return contour->debugAngle(id);
307}
308
309SkOpContour* SkPathOpsDebug::DebugContourContour(SkOpContour* contour, int id) {
310 return contour->debugContour(id);
311}
312
313const SkOpPtT* SkPathOpsDebug::DebugContourPtT(SkOpContour* contour, int id) {
314 return contour->debugPtT(id);
315}
316
317const SkOpSegment* SkPathOpsDebug::DebugContourSegment(SkOpContour* contour, int id) {
318 return contour->debugSegment(id);
319}
320
321const SkOpSpanBase* SkPathOpsDebug::DebugContourSpan(SkOpContour* contour, int id) {
322 return contour->debugSpan(id);
323}
324
325const SkOpAngle* SkPathOpsDebug::DebugPtTAngle(const SkOpPtT* ptT, int id) {
326 return ptT->debugAngle(id);
327}
328
329SkOpContour* SkPathOpsDebug::DebugPtTContour(SkOpPtT* ptT, int id) {
330 return ptT->debugContour(id);
331}
332
333const SkOpPtT* SkPathOpsDebug::DebugPtTPtT(const SkOpPtT* ptT, int id) {
334 return ptT->debugPtT(id);
335}
336
337const SkOpSegment* SkPathOpsDebug::DebugPtTSegment(const SkOpPtT* ptT, int id) {
338 return ptT->debugSegment(id);
339}
340
341const SkOpSpanBase* SkPathOpsDebug::DebugPtTSpan(const SkOpPtT* ptT, int id) {
342 return ptT->debugSpan(id);
343}
344
345const SkOpAngle* SkPathOpsDebug::DebugSegmentAngle(const SkOpSegment* span, int id) {
346 return span->debugAngle(id);
347}
348
349SkOpContour* SkPathOpsDebug::DebugSegmentContour(SkOpSegment* span, int id) {
350 return span->debugContour(id);
351}
352
353const SkOpPtT* SkPathOpsDebug::DebugSegmentPtT(const SkOpSegment* span, int id) {
354 return span->debugPtT(id);
355}
356
357const SkOpSegment* SkPathOpsDebug::DebugSegmentSegment(const SkOpSegment* span, int id) {
358 return span->debugSegment(id);
359}
360
361const SkOpSpanBase* SkPathOpsDebug::DebugSegmentSpan(const SkOpSegment* span, int id) {
362 return span->debugSpan(id);
363}
364
365const SkOpAngle* SkPathOpsDebug::DebugSpanAngle(const SkOpSpanBase* span, int id) {
366 return span->debugAngle(id);
367}
368
369SkOpContour* SkPathOpsDebug::DebugSpanContour(SkOpSpanBase* span, int id) {
370 return span->debugContour(id);
371}
372
373const SkOpPtT* SkPathOpsDebug::DebugSpanPtT(const SkOpSpanBase* span, int id) {
374 return span->debugPtT(id);
375}
376
377const SkOpSegment* SkPathOpsDebug::DebugSpanSegment(const SkOpSpanBase* span, int id) {
378 return span->debugSegment(id);
379}
380
381const SkOpSpanBase* SkPathOpsDebug::DebugSpanSpan(const SkOpSpanBase* span, int id) {
382 return span->debugSpan(id);
383}
384
385void SkPathOpsDebug::DumpContours(SkTDArray<SkOpContour* >* contours) {
386 int count = contours->count();
387 for (int index = 0; index < count; ++index) {
388 (*contours)[index]->dump();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000389 }
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000390}
391
caryclark54359292015-03-26 07:52:43 -0700392void SkPathOpsDebug::DumpContoursAll(SkTDArray<SkOpContour* >* contours) {
393 int count = contours->count();
394 for (int index = 0; index < count; ++index) {
395 (*contours)[index]->dumpAll();
396 }
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000397}
398
caryclark54359292015-03-26 07:52:43 -0700399void SkPathOpsDebug::DumpContoursAngles(const SkTDArray<SkOpContour* >* contours) {
400 int count = contours->count();
401 for (int index = 0; index < count; ++index) {
402 (*contours)[index]->dumpAngles();
403 }
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000404}
405
caryclark54359292015-03-26 07:52:43 -0700406void SkPathOpsDebug::DumpContoursPts(const SkTDArray<SkOpContour* >* contours) {
407 int count = contours->count();
408 for (int index = 0; index < count; ++index) {
409 (*contours)[index]->dumpPts();
410 }
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000411}
412
caryclark54359292015-03-26 07:52:43 -0700413void SkPathOpsDebug::DumpContoursPt(const SkTDArray<SkOpContour* >* contours, int segmentID) {
414 int count = contours->count();
415 for (int index = 0; index < count; ++index) {
416 (*contours)[index]->dumpPt(segmentID);
417 }
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000418}
419
caryclark54359292015-03-26 07:52:43 -0700420void SkPathOpsDebug::DumpContoursSegment(const SkTDArray<SkOpContour* >* contours,
421 int segmentID) {
422 if (contours->count()) {
423 (*contours)[0]->dumpSegment(segmentID);
424 }
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000425}
426
caryclark54359292015-03-26 07:52:43 -0700427void SkPathOpsDebug::DumpContoursSpan(const SkTDArray<SkOpContour* >* contours,
428 int spanID) {
429 if (contours->count()) {
430 (*contours)[0]->dumpSpan(spanID);
431 }
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000432}
433
caryclark54359292015-03-26 07:52:43 -0700434void SkPathOpsDebug::DumpContoursSpans(const SkTDArray<SkOpContour* >* contours) {
435 int count = contours->count();
436 for (int index = 0; index < count; ++index) {
437 (*contours)[index]->dumpSpans();
438 }
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000439}
440
caryclark54359292015-03-26 07:52:43 -0700441const SkTSpan<SkDCubic>* DebugSpan(const SkTSect<SkDCubic>* sect, int id) {
442 return sect->debugSpan(id);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000443}
444
caryclark54359292015-03-26 07:52:43 -0700445const SkTSpan<SkDQuad>* DebugSpan(const SkTSect<SkDQuad>* sect, int id) {
446 return sect->debugSpan(id);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000447}
448
caryclark54359292015-03-26 07:52:43 -0700449const SkTSpan<SkDCubic>* DebugT(const SkTSect<SkDCubic>* sect, double t) {
450 return sect->debugT(t);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000451}
452
caryclark54359292015-03-26 07:52:43 -0700453const SkTSpan<SkDQuad>* DebugT(const SkTSect<SkDQuad>* sect, double t) {
454 return sect->debugT(t);
caryclarkdac1d172014-06-17 05:15:38 -0700455}
456
caryclark54359292015-03-26 07:52:43 -0700457const SkTSpan<SkDCubic>* DebugSpan(const SkTSpan<SkDCubic>* span, int id) {
458 return span->debugSpan(id);
caryclarkdac1d172014-06-17 05:15:38 -0700459}
460
caryclark54359292015-03-26 07:52:43 -0700461const SkTSpan<SkDQuad>* DebugSpan(const SkTSpan<SkDQuad>* span, int id) {
462 return span->debugSpan(id);
caryclarkdac1d172014-06-17 05:15:38 -0700463}
464
caryclark54359292015-03-26 07:52:43 -0700465const SkTSpan<SkDCubic>* DebugT(const SkTSpan<SkDCubic>* span, double t) {
466 return span->debugT(t);
caryclarkdac1d172014-06-17 05:15:38 -0700467}
468
caryclark54359292015-03-26 07:52:43 -0700469const SkTSpan<SkDQuad>* DebugT(const SkTSpan<SkDQuad>* span, double t) {
470 return span->debugT(t);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000471}
472
caryclark54359292015-03-26 07:52:43 -0700473void Dump(const SkTSect<SkDCubic>* sect) {
474 sect->dump();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000475}
476
caryclark54359292015-03-26 07:52:43 -0700477void Dump(const SkTSect<SkDQuad>* sect) {
478 sect->dump();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000479}
480
caryclark54359292015-03-26 07:52:43 -0700481void Dump(const SkTSpan<SkDCubic>* span) {
482 span->dump();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000483}
484
caryclark54359292015-03-26 07:52:43 -0700485void Dump(const SkTSpan<SkDQuad>* span) {
486 span->dump();
caryclarkdac1d172014-06-17 05:15:38 -0700487}
488
caryclark54359292015-03-26 07:52:43 -0700489void DumpBoth(SkTSect<SkDCubic>* sect1, SkTSect<SkDCubic>* sect2) {
490 sect1->dumpBoth(sect2);
caryclarkdac1d172014-06-17 05:15:38 -0700491}
492
caryclark54359292015-03-26 07:52:43 -0700493void DumpBoth(SkTSect<SkDQuad>* sect1, SkTSect<SkDQuad>* sect2) {
494 sect1->dumpBoth(sect2);
caryclarkdac1d172014-06-17 05:15:38 -0700495}
496
caryclark54359292015-03-26 07:52:43 -0700497void DumpCoin(SkTSect<SkDCubic>* sect1) {
498 sect1->dumpCoin();
caryclarkdac1d172014-06-17 05:15:38 -0700499}
500
caryclark54359292015-03-26 07:52:43 -0700501void DumpCoin(SkTSect<SkDQuad>* sect1) {
502 sect1->dumpCoin();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000503}
504
caryclark54359292015-03-26 07:52:43 -0700505void DumpCoinCurves(SkTSect<SkDCubic>* sect1) {
506 sect1->dumpCoinCurves();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000507}
508
caryclark54359292015-03-26 07:52:43 -0700509void DumpCoinCurves(SkTSect<SkDQuad>* sect1) {
510 sect1->dumpCoinCurves();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000511}
512
caryclark54359292015-03-26 07:52:43 -0700513void DumpCurves(const SkTSect<SkDQuad>* sect) {
514 sect->dumpCurves();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000515}
516
caryclark54359292015-03-26 07:52:43 -0700517void DumpCurves(const SkTSect<SkDCubic>* sect) {
518 sect->dumpCurves();
caryclarkdac1d172014-06-17 05:15:38 -0700519}
520
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000521static void dumpTestCase(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) {
caryclark54359292015-03-26 07:52:43 -0700522 SkDebugf("\n<div id=\"quad%d\">\n", testNo);
523 quad1.dumpInner();
524 SkDebugf("}}, ");
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000525 quad2.dump();
526 SkDebugf("</div>\n\n");
527}
528
529static void dumpTestTrailer() {
530 SkDebugf("</div>\n\n<script type=\"text/javascript\">\n\n");
531 SkDebugf(" var testDivs = [\n");
532}
533
534static void dumpTestList(int testNo, double min) {
535 SkDebugf(" quad%d,", testNo);
536 if (min > 0) {
537 SkDebugf(" // %1.9g", min);
538 }
539 SkDebugf("\n");
540}
541
542void DumpQ(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) {
543 SkDebugf("\n");
544 dumpTestCase(quad1, quad2, testNo);
545 dumpTestTrailer();
546 dumpTestList(testNo, 0);
547 SkDebugf("\n");
548}
549
550void DumpT(const SkDQuad& quad, double t) {
551 SkDLine line = {{quad.ptAtT(t), quad[0]}};
552 line.dump();
553}
caryclark54359292015-03-26 07:52:43 -0700554
555const SkOpAngle* SkOpAngle::debugAngle(int id) const {
556 return this->segment()->debugAngle(id);
557}
558
559SkOpContour* SkOpAngle::debugContour(int id) {
560 return this->segment()->debugContour(id);
561}
562
563const SkOpPtT* SkOpAngle::debugPtT(int id) const {
564 return this->segment()->debugPtT(id);
565}
566
567const SkOpSegment* SkOpAngle::debugSegment(int id) const {
568 return this->segment()->debugSegment(id);
569}
570
571const SkOpSpanBase* SkOpAngle::debugSpan(int id) const {
572 return this->segment()->debugSpan(id);
573}
574
575void SkOpAngle::dump() const {
576 dumpOne(true);
577 SkDebugf("\n");
578}
579
580void SkOpAngle::dumpOne(bool functionHeader) const {
581// fSegment->debugValidate();
582 const SkOpSegment* segment = this->segment();
583 const SkOpSpan& mSpan = *fStart->starter(fEnd);
584 if (functionHeader) {
585 SkDebugf("%s ", __FUNCTION__);
586 }
587 SkDebugf("[%d", segment->debugID());
588 SkDebugf("/%d", debugID());
589 SkDebugf("] next=");
590 if (fNext) {
591 SkDebugf("%d", fNext->fStart->segment()->debugID());
592 SkDebugf("/%d", fNext->debugID());
593 } else {
594 SkDebugf("?");
595 }
596 SkDebugf(" sect=%d/%d ", fSectorStart, fSectorEnd);
597 SkDebugf(" s=%1.9g [%d] e=%1.9g [%d]", fStart->t(), fStart->debugID(),
598 fEnd->t(), fEnd->debugID());
599 SkDebugf(" sgn=%d windVal=%d", this->sign(), mSpan.windValue());
600
601 SkDebugf(" windSum=");
602 SkPathOpsDebug::WindingPrintf(mSpan.windSum());
603 if (mSpan.oppValue() != 0 || mSpan.oppSum() != SK_MinS32) {
604 SkDebugf(" oppVal=%d", mSpan.oppValue());
605 SkDebugf(" oppSum=");
606 SkPathOpsDebug::WindingPrintf(mSpan.oppSum());
607 }
608 if (mSpan.done()) {
609 SkDebugf(" done");
610 }
611 if (unorderable()) {
612 SkDebugf(" unorderable");
613 }
614 if (segment->operand()) {
615 SkDebugf(" operand");
616 }
617 if (fStop) {
618 SkDebugf(" stop");
619 }
620}
621
622void SkOpAngle::dumpTo(const SkOpSegment* segment, const SkOpAngle* to) const {
623 const SkOpAngle* first = this;
624 const SkOpAngle* next = this;
625 const char* indent = "";
626 do {
627 SkDebugf("%s", indent);
628 next->dumpOne(false);
629 if (segment == next->fStart->segment()) {
630 if (this == fNext) {
631 SkDebugf(" << from");
632 }
633 if (to == fNext) {
634 SkDebugf(" << to");
635 }
636 }
637 SkDebugf("\n");
638 indent = " ";
639 next = next->fNext;
640 } while (next && next != first);
641}
642
643void SkOpAngle::dumpCurves() const {
644 const SkOpAngle* first = this;
645 const SkOpAngle* next = this;
646 do {
647 next->fCurvePart.dumpID(next->segment()->debugID());
648 next = next->fNext;
649 } while (next && next != first);
650}
651
652void SkOpAngle::dumpLoop() const {
653 const SkOpAngle* first = this;
654 const SkOpAngle* next = this;
655 do {
656 next->dumpOne(false);
657 SkDebugf("\n");
658 next = next->fNext;
659 } while (next && next != first);
660}
661
662void SkOpAngle::dumpTest() const {
663 const SkOpAngle* first = this;
664 const SkOpAngle* next = this;
665 do {
666 SkDebugf("{ ");
667 SkOpSegment* segment = next->segment();
668 segment->dumpPts();
669 SkDebugf(", %d, %1.9g, %1.9g, {} },\n", SkPathOpsVerbToPoints(segment->verb()) + 1,
670 next->start()->t(), next->end()->t());
671 next = next->fNext;
672 } while (next && next != first);
673}
674
675bool SkOpPtT::debugMatchID(int id) const {
676 int limit = this->debugLoopLimit(false);
677 int loop = 0;
678 const SkOpPtT* ptT = this;
679 do {
680 if (ptT->debugID() == id) {
681 return true;
682 }
683 } while ((!limit || ++loop <= limit) && (ptT = ptT->next()) && ptT != this);
684 return false;
685}
686
687const SkOpAngle* SkOpPtT::debugAngle(int id) const {
688 return this->span()->debugAngle(id);
689}
690
691SkOpContour* SkOpPtT::debugContour(int id) {
692 return this->span()->debugContour(id);
693}
694
695const SkOpPtT* SkOpPtT::debugPtT(int id) const {
696 return this->span()->debugPtT(id);
697}
698
699const SkOpSegment* SkOpPtT::debugSegment(int id) const {
700 return this->span()->debugSegment(id);
701}
702
703const SkOpSpanBase* SkOpPtT::debugSpan(int id) const {
704 return this->span()->debugSpan(id);
705}
706
707void SkOpPtT::dump() const {
708 SkDebugf("seg=%d span=%d ptT=%d",
709 this->segment()->debugID(), this->span()->debugID(), this->debugID());
710 this->dumpBase();
711 SkDebugf("\n");
712}
713
714void SkOpPtT::dumpAll() const {
715 contour()->indentDump();
716 const SkOpPtT* next = this;
717 int limit = debugLoopLimit(true);
718 int loop = 0;
719 do {
720 SkDebugf("%.*s", contour()->debugIndent(), " ");
721 SkDebugf("seg=%d span=%d ptT=%d",
722 next->segment()->debugID(), next->span()->debugID(), next->debugID());
723 next->dumpBase();
724 SkDebugf("\n");
725 if (limit && ++loop >= limit) {
726 SkDebugf("*** abort loop ***\n");
727 break;
728 }
729 } while ((next = next->fNext) && next != this);
730 contour()->outdentDump();
731}
732
733void SkOpPtT::dumpBase() const {
734 SkDebugf(" t=%1.9g pt=(%1.9g,%1.9g)%s%s", this->fT, this->fPt.fX, this->fPt.fY,
735 this->fDuplicatePt ? " dup" : "", this->fDeleted ? " deleted" : "");
736}
737
738const SkOpAngle* SkOpSpanBase::debugAngle(int id) const {
739 return this->segment()->debugAngle(id);
740}
741
742SkOpContour* SkOpSpanBase::debugContour(int id) {
743 return this->segment()->debugContour(id);
744}
745
746const SkOpPtT* SkOpSpanBase::debugPtT(int id) const {
747 return this->segment()->debugPtT(id);
748}
749
750const SkOpSegment* SkOpSpanBase::debugSegment(int id) const {
751 return this->segment()->debugSegment(id);
752}
753
754const SkOpSpanBase* SkOpSpanBase::debugSpan(int id) const {
755 return this->segment()->debugSpan(id);
756}
757
758void SkOpSpanBase::dump() const {
759 this->dumpAll();
760 SkDebugf("\n");
761}
762
763void SkOpSpanBase::dumpAll() const {
764 SkDebugf("%.*s", contour()->debugIndent(), " ");
765 SkDebugf("seg=%d span=%d", this->segment()->debugID(), this->debugID());
766 this->dumpBase();
767 SkDebugf("\n");
768 this->fPtT.dumpAll();
769}
770
771void SkOpSpanBase::dumpBase() const {
772 if (this->fAligned) {
773 SkDebugf(" aligned");
774 }
775 if (this->fChased) {
776 SkDebugf(" chased");
777 }
778 if (!this->final()) {
779 this->upCast()->dumpSpan();
780 }
781 const SkOpSpanBase* coin = this->coinEnd();
782 if (this != coin) {
783 SkDebugf(" coinEnd seg/span=%d/%d", coin->segment()->debugID(), coin->debugID());
784 } else if (this->final() || !this->upCast()->isCoincident()) {
785 const SkOpPtT* oPt = this->ptT()->next();
786 SkDebugf(" seg/span=%d/%d", oPt->segment()->debugID(), oPt->span()->debugID());
787 }
788}
789
790void SkOpSpanBase::dumpCoin() const {
791 const SkOpSpan* span = this->upCastable();
792 if (!span) {
793 return;
794 }
795 if (!span->isCoincident()) {
796 return;
797 }
798 span->dumpCoin();
799}
800
801void SkOpSpan::dumpCoin() const {
802 const SkOpSpan* coincident = fCoincident;
803 bool ok = debugCoinLoopCheck();
804 this->dump();
805 int loop = 0;
806 do {
807 coincident->dump();
808 if (!ok && ++loop > 10) {
809 SkDebugf("*** abort loop ***\n");
810 break;
811 }
812 } while ((coincident = coincident->fCoincident) != this);
813}
814
815bool SkOpSpan::dumpSpan() const {
816 SkOpSpan* coin = fCoincident;
817 if (this != coin) {
818 SkDebugf(" coinStart seg/span=%d/%d", coin->segment()->debugID(), coin->debugID());
819 }
820 SkDebugf(" windVal=%d", this->windValue());
821 SkDebugf(" windSum=");
822 SkPathOpsDebug::WindingPrintf(this->windSum());
823 if (this->oppValue() != 0 || this->oppSum() != SK_MinS32) {
824 SkDebugf(" oppVal=%d", this->oppValue());
825 SkDebugf(" oppSum=");
826 SkPathOpsDebug::WindingPrintf(this->oppSum());
827 }
828 if (this->done()) {
829 SkDebugf(" done");
830 }
831 return this != coin;
832}
833
834const SkOpAngle* SkOpSegment::debugAngle(int id) const {
835 return this->contour()->debugAngle(id);
836}
837
838SkOpContour* SkOpSegment::debugContour(int id) {
839 return this->contour()->debugContour(id);
840}
841
842const SkOpPtT* SkOpSegment::debugPtT(int id) const {
843 return this->contour()->debugPtT(id);
844}
845
846const SkOpSegment* SkOpSegment::debugSegment(int id) const {
847 return this->contour()->debugSegment(id);
848}
849
850const SkOpSpanBase* SkOpSegment::debugSpan(int id) const {
851 return this->contour()->debugSpan(id);
852}
853
854void SkOpSegment::dump() const {
855 SkDebugf("%.*s", contour()->debugIndent(), " ");
856 this->dumpPts();
857 const SkOpSpanBase* span = &fHead;
858 contour()->indentDump();
859 do {
860 SkDebugf("%.*s span=%d ", contour()->debugIndent(), " ", span->debugID());
861 span->ptT()->dumpBase();
862 span->dumpBase();
863 SkDebugf("\n");
864 } while (!span->final() && (span = span->upCast()->next()));
865 contour()->outdentDump();
866}
867
868void SkOpSegment::dumpAll() const {
869 SkDebugf("%.*s", contour()->debugIndent(), " ");
870 this->dumpPts();
871 const SkOpSpanBase* span = &fHead;
872 contour()->indentDump();
873 do {
874 span->dumpAll();
875 } while (!span->final() && (span = span->upCast()->next()));
876 contour()->outdentDump();
877}
878
879void SkOpSegment::dumpAngles() const {
880 SkDebugf("seg=%d\n", debugID());
881 const SkOpSpanBase* span = &fHead;
882 do {
883 const SkOpAngle* fAngle = span->fromAngle();
884 const SkOpAngle* tAngle = span->final() ? NULL : span->upCast()->toAngle();
885 if (fAngle) {
886 SkDebugf(" span=%d from=%d ", span->debugID(), fAngle->debugID());
887 fAngle->dumpTo(this, tAngle);
888 }
889 if (tAngle) {
890 SkDebugf(" span=%d to=%d ", span->debugID(), tAngle->debugID());
891 tAngle->dumpTo(this, fAngle);
892 }
893 } while (!span->final() && (span = span->upCast()->next()));
894}
895
896void SkOpSegment::dumpCoin() const {
897 const SkOpSpan* span = &fHead;
898 do {
899 span->dumpCoin();
900 } while ((span = span->next()->upCastable()));
901}
902
903void SkOpSegment::dumpPts() const {
904 int last = SkPathOpsVerbToPoints(fVerb);
905 SkDebugf("seg=%d {{", this->debugID());
906 int index = 0;
907 do {
908 SkDPoint::Dump(fPts[index]);
909 SkDebugf(", ");
910 } while (++index < last);
911 SkDPoint::Dump(fPts[index]);
912 SkDebugf("}}\n");
913}
914
915void SkCoincidentSpans::dump() const {
916 SkDebugf("- seg=%d span=%d ptT=%d ", fCoinPtTStart->segment()->debugID(),
917 fCoinPtTStart->span()->debugID(), fCoinPtTStart->debugID());
918 fCoinPtTStart->dumpBase();
919 SkDebugf(" span=%d ptT=%d ", fCoinPtTEnd->span()->debugID(), fCoinPtTEnd->debugID());
920 fCoinPtTEnd->dumpBase();
921 if (fCoinPtTStart->segment()->operand()) {
922 SkDebugf(" operand");
923 }
924 if (fCoinPtTStart->segment()->isXor()) {
925 SkDebugf(" xor");
926 }
927 SkDebugf("\n");
928 SkDebugf("+ seg=%d span=%d ptT=%d ", fOppPtTStart->segment()->debugID(),
929 fOppPtTStart->span()->debugID(), fOppPtTStart->debugID());
930 fOppPtTStart->dumpBase();
931 SkDebugf(" span=%d ptT=%d ", fOppPtTEnd->span()->debugID(), fOppPtTEnd->debugID());
932 fOppPtTEnd->dumpBase();
933 if (fOppPtTStart->segment()->operand()) {
934 SkDebugf(" operand");
935 }
936 if (fOppPtTStart->segment()->isXor()) {
937 SkDebugf(" xor");
938 }
939 SkDebugf("\n");
940}
941
942void SkOpCoincidence::dump() const {
943 SkCoincidentSpans* span = fHead;
944 while (span) {
945 span->dump();
946 span = span->fNext;
947 }
948}
949
950void SkOpContour::dump() {
951 SkDebugf("contour=%d count=%d\n", this->debugID(), fCount);
952 if (!fCount) {
953 return;
954 }
955 const SkOpSegment* segment = &fHead;
956 PATH_OPS_DEBUG_CODE(fIndent = 0);
957 indentDump();
958 do {
959 segment->dump();
960 } while ((segment = segment->next()));
961 outdentDump();
962}
963
964void SkOpContour::dumpAll() {
965 SkDebugf("contour=%d count=%d\n", this->debugID(), fCount);
966 if (!fCount) {
967 return;
968 }
969 const SkOpSegment* segment = &fHead;
970 PATH_OPS_DEBUG_CODE(fIndent = 0);
971 indentDump();
972 do {
973 segment->dumpAll();
974 } while ((segment = segment->next()));
975 outdentDump();
976}
977
978
979void SkOpContour::dumpAngles() const {
980 SkDebugf("contour=%d\n", this->debugID());
981 const SkOpSegment* segment = &fHead;
982 do {
983 SkDebugf(" seg=%d ", segment->debugID());
984 segment->dumpAngles();
985 } while ((segment = segment->next()));
986}
987
988void SkOpContour::dumpPt(int index) const {
989 const SkOpSegment* segment = &fHead;
990 do {
991 if (segment->debugID() == index) {
992 segment->dumpPts();
993 }
994 } while ((segment = segment->next()));
995}
996
997void SkOpContour::dumpPts() const {
998 SkDebugf("contour=%d\n", this->debugID());
999 const SkOpSegment* segment = &fHead;
1000 do {
1001 SkDebugf(" seg=%d ", segment->debugID());
1002 segment->dumpPts();
1003 } while ((segment = segment->next()));
1004}
1005
1006void SkOpContour::dumpPtsX() const {
1007 if (!this->fCount) {
1008 SkDebugf("<empty>\n");
1009 return;
1010 }
1011 const SkOpSegment* segment = &fHead;
1012 do {
1013 segment->dumpPts();
1014 } while ((segment = segment->next()));
1015}
1016
1017void SkOpContour::dumpSegment(int index) const {
1018 debugSegment(index)->dump();
1019}
1020
1021void SkOpContour::dumpSegments(SkPathOp op) const {
1022 bool firstOp = false;
1023 const SkOpContour* c = this;
1024 do {
1025 if (!firstOp && c->operand()) {
1026#if DEBUG_ACTIVE_OP
1027 SkDebugf("op %s\n", SkPathOpsDebug::kPathOpStr[op]);
1028#endif
1029 firstOp = true;
1030 }
1031 c->dumpPtsX();
1032 } while ((c = c->next()));
1033}
1034
1035void SkOpContour::dumpSpan(int index) const {
1036 debugSpan(index)->dump();
1037}
1038
1039void SkOpContour::dumpSpans() const {
1040 SkDebugf("contour=%d\n", this->debugID());
1041 const SkOpSegment* segment = &fHead;
1042 do {
1043 SkDebugf(" seg=%d ", segment->debugID());
1044 segment->dump();
1045 } while ((segment = segment->next()));
1046}
1047
1048#ifdef SK_DEBUG
1049const SkOpAngle* SkOpGlobalState::debugAngle(int id) const {
1050 const SkOpContour* contour = fHead;
1051 do {
1052 const SkOpSegment* segment = contour->first();
1053 while (segment) {
1054 const SkOpSpan* span = segment->head();
1055 do {
1056 SkOpAngle* angle = span->fromAngle();
1057 if (angle && angle->debugID() == id) {
1058 return angle;
1059 }
1060 angle = span->toAngle();
1061 if (angle && angle->debugID() == id) {
1062 return angle;
1063 }
1064 } while ((span = span->next()->upCastable()));
1065 const SkOpSpanBase* tail = segment->tail();
1066 SkOpAngle* angle = tail->fromAngle();
1067 if (angle && angle->debugID() == id) {
1068 return angle;
1069 }
1070 segment = segment->next();
1071 }
1072 } while ((contour = contour->next()));
1073 return NULL;
1074}
1075
1076SkOpContour* SkOpGlobalState::debugContour(int id) {
1077 SkOpContour* contour = fHead;
1078 do {
1079 if (contour->debugID() == id) {
1080 return contour;
1081 }
1082 } while ((contour = contour->next()));
1083 return NULL;
1084}
1085
1086const SkOpPtT* SkOpGlobalState::debugPtT(int id) const {
1087 const SkOpContour* contour = fHead;
1088 do {
1089 const SkOpSegment* segment = contour->first();
1090 while (segment) {
1091 const SkOpSpan* span = segment->head();
1092 do {
1093 const SkOpPtT* ptT = span->ptT();
1094 if (ptT->debugMatchID(id)) {
1095 return ptT;
1096 }
1097 } while ((span = span->next()->upCastable()));
1098 const SkOpSpanBase* tail = segment->tail();
1099 const SkOpPtT* ptT = tail->ptT();
1100 if (ptT->debugMatchID(id)) {
1101 return ptT;
1102 }
1103 segment = segment->next();
1104 }
1105 } while ((contour = contour->next()));
1106 return NULL;
1107}
1108
1109const SkOpSegment* SkOpGlobalState::debugSegment(int id) const {
1110 const SkOpContour* contour = fHead;
1111 do {
1112 const SkOpSegment* segment = contour->first();
1113 while (segment) {
1114 if (segment->debugID() == id) {
1115 return segment;
1116 }
1117 segment = segment->next();
1118 }
1119 } while ((contour = contour->next()));
1120 return NULL;
1121}
1122
1123const SkOpSpanBase* SkOpGlobalState::debugSpan(int id) const {
1124 const SkOpContour* contour = fHead;
1125 do {
1126 const SkOpSegment* segment = contour->first();
1127 while (segment) {
1128 const SkOpSpan* span = segment->head();
1129 do {
1130 if (span->debugID() == id) {
1131 return span;
1132 }
1133 } while ((span = span->next()->upCastable()));
1134 const SkOpSpanBase* tail = segment->tail();
1135 if (tail->debugID() == id) {
1136 return tail;
1137 }
1138 segment = segment->next();
1139 }
1140 } while ((contour = contour->next()));
1141 return NULL;
1142}
1143#endif
1144
1145const SkOpAngle* DebugAngle(const SkTArray<SkOpContour*, true>* contours, int id) {
1146 return (*contours)[0]->debugAngle(id);
1147}
1148
1149SkOpContour* DumpContour(const SkTArray<SkOpContour*, true>* contours, int id) {
1150 return (*contours)[0]->debugContour(id);
1151}
1152
1153const SkOpPtT* DebugPtT(const SkTArray<SkOpContour*, true>* contours, int id) {
1154 return (*contours)[0]->debugPtT(id);
1155}
1156
1157const SkOpSegment* DebugSegment(const SkTArray<SkOpContour*, true>* contours, int id) {
1158 return (*contours)[0]->debugSegment(id);
1159}
1160
1161const SkOpSpanBase* DebugSpan(const SkTArray<SkOpContour*, true>* contours, int id) {
1162 return (*contours)[0]->debugSpan(id);
1163}
1164
1165void Dump(SkTDArray<SkOpContour* >* contours) {
1166 SkPathOpsDebug::DumpContours(contours);
1167}
1168
1169void DumpAll(SkTDArray<SkOpContour* >* contours) {
1170 SkPathOpsDebug::DumpContoursAll(contours);
1171}
1172
1173void DumpAngles(const SkTDArray<SkOpContour* >* contours) {
1174 SkPathOpsDebug::DumpContoursAngles(contours);
1175}
1176
1177void DumpSegment(const SkTDArray<SkOpContour* >* contours, int segmentID) {
1178 SkPathOpsDebug::DumpContoursSegment(contours, segmentID);
1179}
1180
1181void DumpSpan(const SkTDArray<SkOpContour* >* contours, int spanID) {
1182 SkPathOpsDebug::DumpContoursSpan(contours, spanID);
1183}
1184
1185void DumpSpans(const SkTDArray<SkOpContour* >* contours) {
1186 SkPathOpsDebug::DumpContoursSpans(contours);
1187}
1188
1189void DumpPt(const SkTDArray<SkOpContour* >* contours, int segmentID) {
1190 SkPathOpsDebug::DumpContoursPt(contours, segmentID);
1191}
1192
1193void DumpPts(const SkTDArray<SkOpContour* >* contours) {
1194 SkPathOpsDebug::DumpContoursPts(contours);
1195}
1196
1197#if DEBUG_T_SECT_DUMP > 1
1198int gDumpTSectNum;
1199#endif