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