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 10template<typename TCurve, typename OppCurve> 11char SkTCoincident<TCurve, OppCurve>::dumpIsCoincidentStr() const { 12 if (!!fCoincident != fCoincident) { 13 return '?'; 14 } 15 return fCoincident ? '*' : 0; 16} 17 18template<typename TCurve, typename OppCurve> 19void 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 24template<typename TCurve, typename OppCurve> 25const 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 35template<typename TCurve, typename OppCurve> 36const 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 54template<typename TCurve, typename OppCurve> 55void SkTSect<TCurve, OppCurve>::dump() const { 56 dumpCommon(fHead); 57} 58 59extern int gDumpTSectNum; 60 61template<typename TCurve, typename OppCurve> 62void 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 83template<typename TCurve, typename OppCurve> 84void 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 100template<typename TCurve, typename OppCurve> 101void SkTSect<TCurve, OppCurve>::dumpBounds() const { 102 const SkTSpan<TCurve, OppCurve>* test = fHead; 103 do { 104 test->dumpBounds(); 105 } while ((test = test->next())); 106} 107 108template<typename TCurve, typename OppCurve> 109void SkTSect<TCurve, OppCurve>::dumpCoin() const { 110 dumpCommon(fCoincident); 111} 112 113template<typename TCurve, typename OppCurve> 114void SkTSect<TCurve, OppCurve>::dumpCoinCurves() const { 115 dumpCommonCurves(fCoincident); 116} 117 118template<typename TCurve, typename OppCurve> 119void 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 131template<typename TCurve, typename OppCurve> 132void 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 138template<typename TCurve, typename OppCurve> 139void SkTSect<TCurve, OppCurve>::dumpCurves() const { 140 dumpCommonCurves(fHead); 141} 142 143template<typename TCurve, typename OppCurve> 144const SkTSpan<TCurve, OppCurve>* SkTSpan<TCurve, OppCurve>::debugSpan(int id) const { 145 return SkDEBUGRELEASE(fDebugSect->debugSpan(id), nullptr); 146} 147 148template<typename TCurve, typename OppCurve> 149const SkTSpan<TCurve, OppCurve>* SkTSpan<TCurve, OppCurve>::debugT(double t) const { 150 return SkDEBUGRELEASE(fDebugSect->debugT(t), nullptr); 151} 152 153template<typename TCurve, typename OppCurve> 154void 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 171template<typename TCurve, typename OppCurve> 172void 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 188template<typename TCurve, typename OppCurve> 189void SkTSpan<TCurve, OppCurve>::dumpBounded(int id) const { 190 SkDEBUGCODE(fDebugSect->dumpBounded(id)); 191} 192 193template<typename TCurve, typename OppCurve> 194void 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 201template<typename TCurve, typename OppCurve> 202void SkTSpan<TCurve, OppCurve>::dumpCoin() const { 203 dumpID(); 204 SkDebugf(" coinStart "); 205 fCoinStart.dump(); 206 SkDebugf(" coinEnd "); 207 fCoinEnd.dump(); 208} 209 210template<typename TCurve, typename OppCurve> 211void 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