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> 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> 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> 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> 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> 55 void SkTSect<TCurve, OppCurve>::dump() const { 56 dumpCommon(fHead); 57 } 58 59 extern int gDumpTSectNum; 60 61 template<typename TCurve, typename OppCurve> 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> 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> 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> 109 void SkTSect<TCurve, OppCurve>::dumpCoin() const { 110 dumpCommon(fCoincident); 111 } 112 113 template<typename TCurve, typename OppCurve> 114 void SkTSect<TCurve, OppCurve>::dumpCoinCurves() const { 115 dumpCommonCurves(fCoincident); 116 } 117 118 template<typename TCurve, typename OppCurve> 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> 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> 139 void SkTSect<TCurve, OppCurve>::dumpCurves() const { 140 dumpCommonCurves(fHead); 141 } 142 143 template<typename TCurve, typename OppCurve> 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> 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> 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> 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> 189 void SkTSpan<TCurve, OppCurve>::dumpBounded(int id) const { 190 SkDEBUGCODE(fDebugSect->dumpBounded(id)); 191 } 192 193 template<typename TCurve, typename OppCurve> 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> 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> 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