1#include "SkOpContour.h"
2#include "SkIntersectionHelper.h"
3#include "SkOpSegment.h"
4
5inline void DebugDumpDouble(double x) {
6    if (x == floor(x)) {
7        SkDebugf("%.0f", x);
8    } else {
9        SkDebugf("%1.19g", x);
10    }
11}
12
13inline void DebugDumpFloat(float x) {
14    if (x == floorf(x)) {
15        SkDebugf("%.0f", x);
16    } else {
17        SkDebugf("%1.9gf", x);
18    }
19}
20
21// if not defined by PathOpsDebug.cpp ...
22#if !defined SK_DEBUG && FORCE_RELEASE
23bool SkPathOpsDebug::ValidWind(int wind) {
24    return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF;
25}
26
27void SkPathOpsDebug::WindingPrintf(int wind) {
28    if (wind == SK_MinS32) {
29        SkDebugf("?");
30    } else {
31        SkDebugf("%d", wind);
32    }
33}
34#endif
35
36void SkOpAngle::dump() const {
37    dumpOne(true);
38    SkDebugf("\n");
39}
40
41void SkOpAngle::dumpOne(bool functionHeader) const {
42//    fSegment->debugValidate();
43    const SkOpSpan& mSpan = fSegment->span(SkMin32(fStart, fEnd));
44    if (functionHeader) {
45        SkDebugf("%s ", __FUNCTION__);
46    }
47    SkDebugf("[%d", fSegment->debugID());
48    SkDebugf("/%d", debugID());
49    SkDebugf("] next=");
50    if (fNext) {
51        SkDebugf("%d", fNext->fSegment->debugID());
52        SkDebugf("/%d", fNext->debugID());
53    } else {
54        SkDebugf("?");
55    }
56    SkDebugf(" sect=%d/%d ", fSectorStart, fSectorEnd);
57    SkDebugf(" s=%1.9g [%d] e=%1.9g [%d]", fSegment->span(fStart).fT, fStart,
58            fSegment->span(fEnd).fT, fEnd);
59    SkDebugf(" sgn=%d windVal=%d", sign(), mSpan.fWindValue);
60
61    SkDebugf(" windSum=");
62    SkPathOpsDebug::WindingPrintf(mSpan.fWindSum);
63    if (mSpan.fOppValue != 0 || mSpan.fOppSum != SK_MinS32) {
64        SkDebugf(" oppVal=%d", mSpan.fOppValue);
65        SkDebugf(" oppSum=");
66        SkPathOpsDebug::WindingPrintf(mSpan.fOppSum);
67    }
68    if (mSpan.fDone) {
69        SkDebugf(" done");
70    }
71    if (unorderable()) {
72        SkDebugf(" unorderable");
73    }
74    if (small()) {
75        SkDebugf(" small");
76    }
77    if (mSpan.fTiny) {
78        SkDebugf(" tiny");
79    }
80    if (fSegment->operand()) {
81        SkDebugf(" operand");
82    }
83    if (fStop) {
84        SkDebugf(" stop");
85    }
86}
87
88void SkOpAngle::dumpTo(const SkOpSegment* segment, const SkOpAngle* to) const {
89    const SkOpAngle* first = this;
90    const SkOpAngle* next = this;
91    const char* indent = "";
92    do {
93        SkDebugf("%s", indent);
94        next->dumpOne(false);
95        if (segment == next->fSegment) {
96            if (this == fNext) {
97                SkDebugf(" << from");
98            }
99            if (to == fNext) {
100                SkDebugf(" << to");
101            }
102        }
103        SkDebugf("\n");
104        indent = "           ";
105        next = next->fNext;
106    } while (next && next != first);
107}
108
109void SkOpAngle::dumpLoop() const {
110    const SkOpAngle* first = this;
111    const SkOpAngle* next = this;
112    do {
113        next->dumpOne(false);
114        SkDebugf("\n");
115        next = next->fNext;
116    } while (next && next != first);
117}
118
119void SkOpAngle::dumpPartials() const {
120    const SkOpAngle* first = this;
121    const SkOpAngle* next = this;
122    do {
123        next->fCurvePart.dumpNumber();
124        next = next->fNext;
125    } while (next && next != first);
126}
127
128void SkOpAngleSet::dump() const {
129    // FIXME: unimplemented
130/* This requires access to the internal SkChunkAlloc data
131   Defer implementing this until it is needed for debugging
132*/
133    SkASSERT(0);
134}
135
136void SkOpContour::dump() const {
137    int segmentCount = fSegments.count();
138    SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID());
139    for (int test = 0; test < segmentCount; ++test) {
140        SkDebugf("  [%d] ((SkOpSegment*) 0x%p) [%d]\n", test, &fSegments[test],
141                fSegments[test].debugID());
142    }
143}
144
145void SkOpContour::dumpAngles() const {
146    int segmentCount = fSegments.count();
147    SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID());
148    for (int test = 0; test < segmentCount; ++test) {
149        SkDebugf("  [%d] ", test);
150        fSegments[test].dumpAngles();
151    }
152}
153
154void SkOpContour::dumpCoincidence(const SkCoincidence& coin) const {
155    int thisIndex = coin.fSegments[0];
156    const SkOpSegment& s1 = fSegments[thisIndex];
157    int otherIndex = coin.fSegments[1];
158    const SkOpSegment& s2 = coin.fOther->fSegments[otherIndex];
159    SkDebugf("((SkOpSegment*) 0x%p) [%d]  ((SkOpSegment*) 0x%p) [%d]\n", &s1, s1.debugID(),
160            &s2, s2.debugID());
161    for (int index = 0; index < 2; ++index) {
162        SkDebugf("    {%1.9gf, %1.9gf}", coin.fPts[0][index].fX, coin.fPts[0][index].fY);
163        if (coin.fNearly[index]) {
164            SkDebugf("    {%1.9gf, %1.9gf}", coin.fPts[1][index].fX, coin.fPts[1][index].fY);
165        }
166        SkDebugf("  seg1t=%1.9g seg2t=%1.9g\n", coin.fTs[0][index], coin.fTs[1][index]);
167    }
168}
169
170void SkOpContour::dumpCoincidences() const {
171    int count = fCoincidences.count();
172    if (count > 0) {
173        SkDebugf("fCoincidences count=%d\n", count);
174        for (int test = 0; test < count; ++test) {
175            dumpCoincidence(fCoincidences[test]);
176        }
177    }
178    count = fPartialCoincidences.count();
179    if (count == 0) {
180        return;
181    }
182    SkDebugf("fPartialCoincidences count=%d\n", count);
183    for (int test = 0; test < count; ++test) {
184        dumpCoincidence(fPartialCoincidences[test]);
185    }
186}
187
188void SkOpContour::dumpPt(int index) const {
189    int segmentCount = fSegments.count();
190    for (int test = 0; test < segmentCount; ++test) {
191        const SkOpSegment& segment = fSegments[test];
192        if (segment.debugID() == index) {
193            fSegments[test].dumpPts();
194        }
195    }
196}
197
198void SkOpContour::dumpPts() const {
199    int segmentCount = fSegments.count();
200    SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID());
201    for (int test = 0; test < segmentCount; ++test) {
202        SkDebugf("  [%d] ", test);
203        fSegments[test].dumpPts();
204    }
205}
206
207void SkOpContour::dumpSpan(int index) const {
208    int segmentCount = fSegments.count();
209    for (int test = 0; test < segmentCount; ++test) {
210        const SkOpSegment& segment = fSegments[test];
211        if (segment.debugID() == index) {
212            fSegments[test].dumpSpans();
213        }
214    }
215}
216
217void SkOpContour::dumpSpans() const {
218    int segmentCount = fSegments.count();
219    SkDebugf("((SkOpContour*) 0x%p) [%d]\n", this, debugID());
220    for (int test = 0; test < segmentCount; ++test) {
221        SkDebugf("  [%d] ", test);
222        fSegments[test].dumpSpans();
223    }
224}
225
226void SkDCubic::dump() const {
227    SkDebugf("{{");
228    int index = 0;
229    do {
230        fPts[index].dump();
231        SkDebugf(", ");
232    } while (++index < 3);
233    fPts[index].dump();
234    SkDebugf("}}\n");
235}
236
237void SkDCubic::dumpNumber() const {
238    SkDebugf("{{");
239    int index = 0;
240    bool dumpedOne = false;
241    do {
242        if (!(fPts[index].fX == fPts[index].fX && fPts[index].fY == fPts[index].fY)) {
243            continue;
244        }
245        if (dumpedOne) {
246            SkDebugf(", ");
247        }
248        fPts[index].dump();
249        dumpedOne = true;
250    } while (++index < 3);
251    if (fPts[index].fX == fPts[index].fX && fPts[index].fY == fPts[index].fY) {
252        if (dumpedOne) {
253            SkDebugf(", ");
254        }
255        fPts[index].dump();
256    }
257    SkDebugf("}}\n");
258}
259
260void SkDLine::dump() const {
261    SkDebugf("{{");
262    fPts[0].dump();
263    SkDebugf(", ");
264    fPts[1].dump();
265    SkDebugf("}}\n");
266}
267
268void SkDPoint::dump() const {
269    SkDebugf("{");
270    DebugDumpDouble(fX);
271    SkDebugf(", ");
272    DebugDumpDouble(fY);
273    SkDebugf("}");
274}
275
276void SkDPoint::Dump(const SkPoint& pt) {
277    SkDebugf("{");
278    DebugDumpFloat(pt.fX);
279    SkDebugf(", ");
280    DebugDumpFloat(pt.fY);
281    SkDebugf("}");
282}
283
284
285void SkDQuad::dumpComma(const char* comma) const {
286    SkDebugf("{{");
287    int index = 0;
288    do {
289        fPts[index].dump();
290        SkDebugf(", ");
291    } while (++index < 2);
292    fPts[index].dump();
293    SkDebugf("}}%s\n", comma ? comma : "");
294}
295
296void SkDQuad::dump() const {
297    dumpComma("");
298}
299
300void SkIntersectionHelper::dump() const {
301    SkDPoint::Dump(pts()[0]);
302    SkDPoint::Dump(pts()[1]);
303    if (verb() >= SkPath::kQuad_Verb) {
304        SkDPoint::Dump(pts()[2]);
305    }
306    if (verb() >= SkPath::kCubic_Verb) {
307        SkDPoint::Dump(pts()[3]);
308    }
309}
310
311const SkTDArray<SkOpSpan>& SkOpSegment::debugSpans() const {
312    return fTs;
313}
314
315void SkOpSegment::dumpAngles() const {
316    SkDebugf("((SkOpSegment*) 0x%p) [%d]\n", this, debugID());
317    const SkOpAngle* fromAngle = NULL;
318    const SkOpAngle* toAngle = NULL;
319    for (int index = 0; index < count(); ++index) {
320        const SkOpAngle* fAngle = fTs[index].fFromAngle;
321        const SkOpAngle* tAngle = fTs[index].fToAngle;
322        if (fromAngle == fAngle && toAngle == tAngle) {
323            continue;
324        }
325        if (fAngle) {
326            SkDebugf("  [%d] from=%d ", index, fAngle->debugID());
327            fAngle->dumpTo(this, tAngle);
328        }
329        if (tAngle) {
330            SkDebugf("  [%d] to=%d   ", index, tAngle->debugID());
331            tAngle->dumpTo(this, fAngle);
332        }
333        fromAngle = fAngle;
334        toAngle = tAngle;
335    }
336}
337
338void SkOpSegment::dumpContour(int firstID, int lastID) const {
339    if (debugID() < 0) {
340        return;
341    }
342    const SkOpSegment* test = this - (debugID() - 1);
343    test += (firstID - 1);
344    const SkOpSegment* last = test + (lastID - firstID);
345    while (test <= last) {
346        test->dumpSpans();
347        ++test;
348    }
349}
350
351void SkOpSegment::dumpPts() const {
352    int last = SkPathOpsVerbToPoints(fVerb);
353    SkDebugf("((SkOpSegment*) 0x%p) [%d] {{", this, debugID());
354    int index = 0;
355    do {
356        SkDPoint::Dump(fPts[index]);
357        SkDebugf(", ");
358    } while (++index < last);
359    SkDPoint::Dump(fPts[index]);
360    SkDebugf("}}\n");
361}
362
363void SkOpSegment::dumpDPts() const {
364    int count = SkPathOpsVerbToPoints(fVerb);
365    SkDebugf("((SkOpSegment*) 0x%p) [%d] {{", this, debugID());
366    int index = 0;
367    do {
368        SkDPoint dPt = {fPts[index].fX, fPts[index].fY};
369        dPt.dump();
370        if (index != count) {
371            SkDebugf(", ");
372        }
373    } while (++index <= count);
374    SkDebugf("}}\n");
375}
376
377void SkOpSegment::dumpSpans() const {
378    int count = this->count();
379    SkDebugf("((SkOpSegment*) 0x%p) [%d]\n", this, debugID());
380    for (int index = 0; index < count; ++index) {
381        const SkOpSpan& span = this->span(index);
382        SkDebugf("  [%d] ", index);
383        span.dumpOne();
384    }
385}
386
387void SkPathOpsDebug::DumpCoincidence(const SkTArray<SkOpContour, true>& contours) {
388    int count = contours.count();
389    for (int index = 0; index < count; ++index) {
390        contours[index].dumpCoincidences();
391    }
392}
393
394void SkPathOpsDebug::DumpCoincidence(const SkTArray<SkOpContour* , true>& contours) {
395    int count = contours.count();
396    for (int index = 0; index < count; ++index) {
397        contours[index]->dumpCoincidences();
398    }
399}
400
401void SkPathOpsDebug::DumpContours(const SkTArray<SkOpContour, true>& contours) {
402    int count = contours.count();
403    for (int index = 0; index < count; ++index) {
404        contours[index].dump();
405    }
406}
407
408void SkPathOpsDebug::DumpContours(const SkTArray<SkOpContour* , true>& contours) {
409    int count = contours.count();
410    for (int index = 0; index < count; ++index) {
411        contours[index]->dump();
412    }
413}
414
415void SkPathOpsDebug::DumpContourAngles(const SkTArray<SkOpContour, true>& contours) {
416    int count = contours.count();
417    for (int index = 0; index < count; ++index) {
418        contours[index].dumpAngles();
419    }
420}
421
422void SkPathOpsDebug::DumpContourAngles(const SkTArray<SkOpContour* , true>& contours) {
423    int count = contours.count();
424    for (int index = 0; index < count; ++index) {
425        contours[index]->dumpAngles();
426    }
427}
428
429void SkPathOpsDebug::DumpContourPts(const SkTArray<SkOpContour, true>& contours) {
430    int count = contours.count();
431    for (int index = 0; index < count; ++index) {
432        contours[index].dumpPts();
433    }
434}
435
436void SkPathOpsDebug::DumpContourPts(const SkTArray<SkOpContour* , true>& contours) {
437    int count = contours.count();
438    for (int index = 0; index < count; ++index) {
439        contours[index]->dumpPts();
440    }
441}
442
443void SkPathOpsDebug::DumpContourPt(const SkTArray<SkOpContour, true>& contours, int segmentID) {
444    int count = contours.count();
445    for (int index = 0; index < count; ++index) {
446        contours[index].dumpPt(segmentID);
447    }
448}
449
450void SkPathOpsDebug::DumpContourPt(const SkTArray<SkOpContour* , true>& contours, int segmentID) {
451    int count = contours.count();
452    for (int index = 0; index < count; ++index) {
453        contours[index]->dumpPt(segmentID);
454    }
455}
456
457void SkPathOpsDebug::DumpContourSpans(const SkTArray<SkOpContour, true>& contours) {
458    int count = contours.count();
459    for (int index = 0; index < count; ++index) {
460        contours[index].dumpSpans();
461    }
462}
463
464void SkPathOpsDebug::DumpContourSpans(const SkTArray<SkOpContour* , true>& contours) {
465    int count = contours.count();
466    for (int index = 0; index < count; ++index) {
467        contours[index]->dumpSpans();
468    }
469}
470
471void SkPathOpsDebug::DumpContourSpan(const SkTArray<SkOpContour, true>& contours, int segmentID) {
472    int count = contours.count();
473    for (int index = 0; index < count; ++index) {
474        contours[index].dumpSpan(segmentID);
475    }
476}
477
478void SkPathOpsDebug::DumpContourSpan(const SkTArray<SkOpContour* , true>& contours, int segmentID) {
479    int count = contours.count();
480    for (int index = 0; index < count; ++index) {
481        contours[index]->dumpSpan(segmentID);
482    }
483}
484
485void SkPathOpsDebug::DumpSpans(const SkTDArray<SkOpSpan *>& spans) {
486    int count = spans.count();
487    for (int index = 0; index < count; ++index) {
488        const SkOpSpan* span = spans[index];
489        const SkOpSpan& oSpan = span->fOther->span(span->fOtherIndex);
490        const SkOpSegment* segment = oSpan.fOther;
491        SkDebugf("((SkOpSegment*) 0x%p) [%d] ", segment, segment->debugID());
492        SkDebugf("spanIndex:%d ", oSpan.fOtherIndex);
493        span->dumpOne();
494    }
495}
496
497// this does not require that other T index is initialized or correct
498const SkOpSegment* SkOpSpan::debugToSegment(ptrdiff_t* spanIndex) const {
499    if (!fOther) {
500        return NULL;
501    }
502    int oppCount = fOther->count();
503    for (int index = 0; index < oppCount; ++index) {
504        const SkOpSpan& otherSpan = fOther->span(index);
505        double otherTestT = otherSpan.fT;
506        if (otherTestT < fOtherT) {
507            continue;
508        }
509        SkASSERT(otherTestT == fOtherT);
510        const SkOpSegment* candidate = otherSpan.fOther;
511        const SkOpSpan* first = candidate->debugSpans().begin();
512        const SkOpSpan* last = candidate->debugSpans().end() - 1;
513        if (first <= this && this <= last) {
514            if (spanIndex) {
515                *spanIndex = this - first;
516            }
517            return candidate;
518        }
519    }
520    SkASSERT(0);
521    return NULL;
522}
523
524void SkOpSpan::dumpOne() const {
525    SkDebugf("t=");
526    DebugDumpDouble(fT);
527    SkDebugf(" pt=");
528    SkDPoint::Dump(fPt);
529    if (fOther) {
530        SkDebugf(" other.fID=%d", fOther->debugID());
531        SkDebugf(" [%d] otherT=", fOtherIndex);
532        DebugDumpDouble(fOtherT);
533    } else {
534        SkDebugf(" other.fID=? [?] otherT=?");
535    }
536    if (fWindSum != SK_MinS32) {
537        SkDebugf(" windSum=%d", fWindSum);
538    }
539    if (fOppSum != SK_MinS32 && (SkPathOpsDebug::ValidWind(fOppSum) || fOppValue != 0)) {
540        SkDebugf(" oppSum=%d", fOppSum);
541    }
542    SkDebugf(" windValue=%d", fWindValue);
543    if (SkPathOpsDebug::ValidWind(fOppSum) || fOppValue != 0) {
544        SkDebugf(" oppValue=%d", fOppValue);
545    }
546    if (fFromAngle && fFromAngle->debugID()) {
547        SkDebugf(" from=%d", fFromAngle->debugID());
548    }
549    if (fToAngle && fToAngle->debugID()) {
550        SkDebugf(" to=%d", fToAngle->debugID());
551    }
552    if (fChased) {
553        SkDebugf(" chased");
554    }
555    if (fCoincident) {
556        SkDebugf(" coincident");
557    }
558    if (fDone) {
559        SkDebugf(" done");
560    }
561    if (fLoop) {
562        SkDebugf(" loop");
563    }
564    if (fMultiple) {
565        SkDebugf(" multiple");
566    }
567    if (fNear) {
568        SkDebugf(" near");
569    }
570    if (fSmall) {
571        SkDebugf(" small");
572    }
573    if (fTiny) {
574        SkDebugf(" tiny");
575    }
576    SkDebugf("\n");
577}
578
579void SkOpSpan::dump() const {
580    ptrdiff_t spanIndex;
581    const SkOpSegment* segment = debugToSegment(&spanIndex);
582    if (segment) {
583        SkDebugf("((SkOpSegment*) 0x%p) [%d]\n", segment, segment->debugID());
584        SkDebugf("  [%d] ", spanIndex);
585    } else {
586        SkDebugf("((SkOpSegment*) ?) [?]\n");
587        SkDebugf("  [?] ");
588    }
589    dumpOne();
590}
591
592void Dump(const SkTArray<class SkOpContour, true>& contours) {
593    SkPathOpsDebug::DumpContours(contours);
594}
595
596void Dump(const SkTArray<class SkOpContour* , true>& contours) {
597    SkPathOpsDebug::DumpContours(contours);
598}
599
600void Dump(const SkTArray<class SkOpContour, true>* contours) {
601    SkPathOpsDebug::DumpContours(*contours);
602}
603
604void Dump(const SkTArray<class SkOpContour* , true>* contours) {
605    SkPathOpsDebug::DumpContours(*contours);
606}
607
608void Dump(const SkTDArray<SkOpSpan *>& chase) {
609    SkPathOpsDebug::DumpSpans(chase);
610}
611
612void Dump(const SkTDArray<SkOpSpan *>* chase) {
613    SkPathOpsDebug::DumpSpans(*chase);
614}
615
616void DumpAngles(const SkTArray<class SkOpContour, true>& contours) {
617    SkPathOpsDebug::DumpContourAngles(contours);
618}
619
620void DumpAngles(const SkTArray<class SkOpContour* , true>& contours) {
621    SkPathOpsDebug::DumpContourAngles(contours);
622}
623
624void DumpAngles(const SkTArray<class SkOpContour, true>* contours) {
625    SkPathOpsDebug::DumpContourAngles(*contours);
626}
627
628void DumpAngles(const SkTArray<class SkOpContour* , true>* contours) {
629    SkPathOpsDebug::DumpContourAngles(*contours);
630}
631
632void DumpCoin(const SkTArray<class SkOpContour, true>& contours) {
633    SkPathOpsDebug::DumpCoincidence(contours);
634}
635
636void DumpCoin(const SkTArray<class SkOpContour* , true>& contours) {
637    SkPathOpsDebug::DumpCoincidence(contours);
638}
639
640void DumpCoin(const SkTArray<class SkOpContour, true>* contours) {
641    SkPathOpsDebug::DumpCoincidence(*contours);
642}
643
644void DumpCoin(const SkTArray<class SkOpContour* , true>* contours) {
645    SkPathOpsDebug::DumpCoincidence(*contours);
646}
647
648void DumpSpans(const SkTArray<class SkOpContour, true>& contours) {
649    SkPathOpsDebug::DumpContourSpans(contours);
650}
651
652void DumpSpans(const SkTArray<class SkOpContour* , true>& contours) {
653    SkPathOpsDebug::DumpContourSpans(contours);
654}
655
656void DumpSpans(const SkTArray<class SkOpContour, true>* contours) {
657    SkPathOpsDebug::DumpContourSpans(*contours);
658}
659
660void DumpSpans(const SkTArray<class SkOpContour* , true>* contours) {
661    SkPathOpsDebug::DumpContourSpans(*contours);
662}
663
664void DumpSpan(const SkTArray<class SkOpContour, true>& contours, int segmentID) {
665    SkPathOpsDebug::DumpContourSpan(contours, segmentID);
666}
667
668void DumpSpan(const SkTArray<class SkOpContour* , true>& contours, int segmentID) {
669    SkPathOpsDebug::DumpContourSpan(contours, segmentID);
670}
671
672void DumpSpan(const SkTArray<class SkOpContour, true>* contours, int segmentID) {
673    SkPathOpsDebug::DumpContourSpan(*contours, segmentID);
674}
675
676void DumpSpan(const SkTArray<class SkOpContour* , true>* contours, int segmentID) {
677    SkPathOpsDebug::DumpContourSpan(*contours, segmentID);
678}
679
680void DumpPts(const SkTArray<class SkOpContour, true>& contours) {
681    SkPathOpsDebug::DumpContourPts(contours);
682}
683
684void DumpPts(const SkTArray<class SkOpContour* , true>& contours) {
685    SkPathOpsDebug::DumpContourPts(contours);
686}
687
688void DumpPts(const SkTArray<class SkOpContour, true>* contours) {
689    SkPathOpsDebug::DumpContourPts(*contours);
690}
691
692void DumpPts(const SkTArray<class SkOpContour* , true>* contours) {
693    SkPathOpsDebug::DumpContourPts(*contours);
694}
695
696void DumpPt(const SkTArray<class SkOpContour, true>& contours, int segmentID) {
697    SkPathOpsDebug::DumpContourPt(contours, segmentID);
698}
699
700void DumpPt(const SkTArray<class SkOpContour* , true>& contours, int segmentID) {
701    SkPathOpsDebug::DumpContourPt(contours, segmentID);
702}
703
704void DumpPt(const SkTArray<class SkOpContour, true>* contours, int segmentID) {
705    SkPathOpsDebug::DumpContourPt(*contours, segmentID);
706}
707
708void DumpPt(const SkTArray<class SkOpContour* , true>* contours, int segmentID) {
709    SkPathOpsDebug::DumpContourPt(*contours, segmentID);
710}
711
712static void dumpTestCase(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) {
713    SkDebugf("<div id=\"quad%d\">\n", testNo);
714    quad1.dumpComma(",");
715    quad2.dump();
716    SkDebugf("</div>\n\n");
717}
718
719static void dumpTestTrailer() {
720    SkDebugf("</div>\n\n<script type=\"text/javascript\">\n\n");
721    SkDebugf("    var testDivs = [\n");
722}
723
724static void dumpTestList(int testNo, double min) {
725    SkDebugf("        quad%d,", testNo);
726    if (min > 0) {
727        SkDebugf("  // %1.9g", min);
728    }
729    SkDebugf("\n");
730}
731
732void DumpQ(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) {
733    SkDebugf("\n");
734    dumpTestCase(quad1, quad2, testNo);
735    dumpTestTrailer();
736    dumpTestList(testNo, 0);
737    SkDebugf("\n");
738}
739
740void DumpT(const SkDQuad& quad, double t) {
741    SkDLine line = {{quad.ptAtT(t), quad[0]}};
742    line.dump();
743}
744