1 /*
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 "SkPathOpsTSect.h"
9
10 template<typename TCurve, typename OppCurve>
dump()11 void SkTCoincident<TCurve, OppCurve>::dump() const {
12 SkDebugf("t=%1.9g pt=(%1.9g,%1.9g)%s\n", fPerpT, fPerpPt.fX, fPerpPt.fY,
13 fCoincident ? " coincident" : "");
14 }
15
16 template<typename TCurve, typename OppCurve>
debugSpan(int id)17 const SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::debugSpan(int id) const {
18 const SkTSpan<TCurve, OppCurve>* test = fHead;
19 do {
20 if (test->debugID() == id) {
21 return test;
22 }
23 } while ((test = test->next()));
24 return NULL;
25 }
26
27 template<typename TCurve, typename OppCurve>
debugT(double t)28 const SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::debugT(double t) const {
29 const SkTSpan<TCurve, OppCurve>* test = fHead;
30 const SkTSpan<TCurve, OppCurve>* closest = NULL;
31 double bestDist = DBL_MAX;
32 do {
33 if (between(test->fStartT, t, test->fEndT)) {
34 return test;
35 }
36 double testDist = SkTMin(fabs(test->fStartT - t), fabs(test->fEndT - t));
37 if (bestDist > testDist) {
38 bestDist = testDist;
39 closest = test;
40 }
41 } while ((test = test->next()));
42 SkASSERT(closest);
43 return closest;
44 }
45
46 template<typename TCurve, typename OppCurve>
dump()47 void SkTSect<TCurve, OppCurve>::dump() const {
48 dumpCommon(fHead);
49 }
50
51 extern int gDumpTSectNum;
52
53 template<typename TCurve, typename OppCurve>
dumpBoth(SkTSect<OppCurve,TCurve> * opp)54 void SkTSect<TCurve, OppCurve>::dumpBoth(SkTSect<OppCurve, TCurve>* opp) const {
55 #if DEBUG_T_SECT_DUMP <= 2
56 #if DEBUG_T_SECT_DUMP == 2
57 SkDebugf("%d ", ++gDumpTSectNum);
58 #endif
59 this->dump();
60 SkDebugf(" ");
61 opp->dump();
62 SkDebugf("\n");
63 #elif DEBUG_T_SECT_DUMP == 3
64 SkDebugf("<div id=\"sect%d\">\n", ++gDumpTSectNum);
65 if (this->fHead) {
66 this->dumpCurves();
67 }
68 if (opp->fHead) {
69 opp->dumpCurves();
70 }
71 SkDebugf("</div>\n\n");
72 #endif
73 }
74
75 template<typename TCurve, typename OppCurve>
dumpBounded(int id)76 void SkTSect<TCurve, OppCurve>::dumpBounded(int id) const {
77 const SkTSpan<TCurve, OppCurve>* bounded = debugSpan(id);
78 if (!bounded) {
79 SkDebugf("no span matches %d\n", id);
80 return;
81 }
82 const SkTSpan<OppCurve, TCurve>* test = bounded->debugOpp()->fHead;
83 do {
84 if (test->findOppSpan(bounded)) {
85 test->dump();
86 }
87 } while ((test = test->next()));
88 }
89
90 template<typename TCurve, typename OppCurve>
dumpBounds()91 void SkTSect<TCurve, OppCurve>::dumpBounds() const {
92 const SkTSpan<TCurve, OppCurve>* test = fHead;
93 do {
94 test->dumpBounds();
95 } while ((test = test->next()));
96 }
97
98 template<typename TCurve, typename OppCurve>
dumpCoin()99 void SkTSect<TCurve, OppCurve>::dumpCoin() const {
100 dumpCommon(fCoincident);
101 }
102
103 template<typename TCurve, typename OppCurve>
dumpCoinCurves()104 void SkTSect<TCurve, OppCurve>::dumpCoinCurves() const {
105 dumpCommonCurves(fCoincident);
106 }
107
108 template<typename TCurve, typename OppCurve>
dumpCommon(const SkTSpan<TCurve,OppCurve> * test)109 void SkTSect<TCurve, OppCurve>::dumpCommon(const SkTSpan<TCurve, OppCurve>* test) const {
110 SkDebugf("id=%d", debugID());
111 if (!test) {
112 SkDebugf(" (empty)");
113 return;
114 }
115 do {
116 SkDebugf(" ");
117 test->dump();
118 } while ((test = test->next()));
119 }
120
121 template<typename TCurve, typename OppCurve>
dumpCommonCurves(const SkTSpan<TCurve,OppCurve> * test)122 void SkTSect<TCurve, OppCurve>::dumpCommonCurves(const SkTSpan<TCurve, OppCurve>* test) const {
123 do {
124 test->fPart.dumpID(test->debugID());
125 } while ((test = test->next()));
126 }
127
128 template<typename TCurve, typename OppCurve>
dumpCurves()129 void SkTSect<TCurve, OppCurve>::dumpCurves() const {
130 dumpCommonCurves(fHead);
131 }
132
133 template<typename TCurve, typename OppCurve>
debugSpan(int id)134 const SkTSpan<TCurve, OppCurve>* SkTSpan<TCurve, OppCurve>::debugSpan(int id) const {
135 return SkDEBUGRELEASE(fDebugSect->debugSpan(id), NULL);
136 }
137
138 template<typename TCurve, typename OppCurve>
debugT(double t)139 const SkTSpan<TCurve, OppCurve>* SkTSpan<TCurve, OppCurve>::debugT(double t) const {
140 return SkDEBUGRELEASE(fDebugSect->debugT(t), NULL);
141 }
142
143 template<typename TCurve, typename OppCurve>
dump()144 void SkTSpan<TCurve, OppCurve>::dump() const {
145 dumpID();
146 SkDebugf("=(%g,%g) [", fStartT, fEndT);
147 const SkTSpanBounded<OppCurve, TCurve>* testBounded = fBounded;
148 while (testBounded) {
149 const SkTSpan<OppCurve, TCurve>* span = testBounded->fBounded;
150 const SkTSpanBounded<OppCurve, TCurve>* next = testBounded->fNext;
151 span->dumpID();
152 if (next) {
153 SkDebugf(",");
154 }
155 testBounded = next;
156 }
157 SkDebugf("]");
158 }
159
160 template<typename TCurve, typename OppCurve>
dumpBounded(int id)161 void SkTSpan<TCurve, OppCurve>::dumpBounded(int id) const {
162 SkDEBUGCODE(fDebugSect->dumpBounded(id));
163 }
164
165 template<typename TCurve, typename OppCurve>
dumpBounds()166 void SkTSpan<TCurve, OppCurve>::dumpBounds() const {
167 dumpID();
168 SkDebugf(" bounds=(%1.9g,%1.9g, %1.9g,%1.9g) boundsMax=%1.9g%s\n",
169 fBounds.fLeft, fBounds.fTop, fBounds.fRight, fBounds.fBottom, fBoundsMax,
170 fCollapsed ? " collapsed" : "");
171 }
172
173 template<typename TCurve, typename OppCurve>
dumpCoin()174 void SkTSpan<TCurve, OppCurve>::dumpCoin() const {
175 dumpID();
176 SkDebugf(" coinStart ");
177 fCoinStart.dump();
178 SkDebugf(" coinEnd ");
179 fCoinEnd.dump();
180 }
181
182 template<typename TCurve, typename OppCurve>
dumpID()183 void SkTSpan<TCurve, OppCurve>::dumpID() const {
184 if (fCoinStart.isCoincident()) {
185 SkDebugf("%c", '*');
186 }
187 SkDebugf("%d", debugID());
188 if (fCoinEnd.isCoincident()) {
189 SkDebugf("%c", '*');
190 }
191 }
192