| /* |
| * Copyright 2014 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "SkPathOpsTSect.h" |
| |
| template<typename TCurve, typename OppCurve> |
| char SkTCoincident<TCurve, OppCurve>::dumpIsCoincidentStr() const { |
| if (!!fCoincident != fCoincident) { |
| return '?'; |
| } |
| return fCoincident ? '*' : 0; |
| } |
| |
| template<typename TCurve, typename OppCurve> |
| void SkTCoincident<TCurve, OppCurve>::dump() const { |
| SkDebugf("t=%1.9g pt=(%1.9g,%1.9g)%s\n", fPerpT, fPerpPt.fX, fPerpPt.fY, |
| fCoincident ? " coincident" : ""); |
| } |
| |
| template<typename TCurve, typename OppCurve> |
| const SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::debugSpan(int id) const { |
| const SkTSpan<TCurve, OppCurve>* test = fHead; |
| do { |
| if (test->debugID() == id) { |
| return test; |
| } |
| } while ((test = test->next())); |
| return nullptr; |
| } |
| |
| template<typename TCurve, typename OppCurve> |
| const SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::debugT(double t) const { |
| const SkTSpan<TCurve, OppCurve>* test = fHead; |
| const SkTSpan<TCurve, OppCurve>* closest = nullptr; |
| double bestDist = DBL_MAX; |
| do { |
| if (between(test->fStartT, t, test->fEndT)) { |
| return test; |
| } |
| double testDist = SkTMin(fabs(test->fStartT - t), fabs(test->fEndT - t)); |
| if (bestDist > testDist) { |
| bestDist = testDist; |
| closest = test; |
| } |
| } while ((test = test->next())); |
| SkASSERT(closest); |
| return closest; |
| } |
| |
| template<typename TCurve, typename OppCurve> |
| void SkTSect<TCurve, OppCurve>::dump() const { |
| dumpCommon(fHead); |
| } |
| |
| extern int gDumpTSectNum; |
| |
| template<typename TCurve, typename OppCurve> |
| void SkTSect<TCurve, OppCurve>::dumpBoth(SkTSect<OppCurve, TCurve>* opp) const { |
| #if DEBUG_T_SECT_DUMP <= 2 |
| #if DEBUG_T_SECT_DUMP == 2 |
| SkDebugf("%d ", ++gDumpTSectNum); |
| #endif |
| this->dump(); |
| SkDebugf(" "); |
| opp->dump(); |
| SkDebugf("\n"); |
| #elif DEBUG_T_SECT_DUMP == 3 |
| SkDebugf("<div id=\"sect%d\">\n", ++gDumpTSectNum); |
| if (this->fHead) { |
| this->dumpCurves(); |
| } |
| if (opp->fHead) { |
| opp->dumpCurves(); |
| } |
| SkDebugf("</div>\n\n"); |
| #endif |
| } |
| |
| template<typename TCurve, typename OppCurve> |
| void SkTSect<TCurve, OppCurve>::dumpBounded(int id) const { |
| const SkTSpan<TCurve, OppCurve>* bounded = debugSpan(id); |
| if (!bounded) { |
| SkDebugf("no span matches %d\n", id); |
| return; |
| } |
| const SkTSpan<OppCurve, TCurve>* test = bounded->debugOpp()->fHead; |
| do { |
| if (test->findOppSpan(bounded)) { |
| test->dump(); |
| SkDebugf(" "); |
| } |
| } while ((test = test->next())); |
| SkDebugf("\n"); |
| } |
| |
| template<typename TCurve, typename OppCurve> |
| void SkTSect<TCurve, OppCurve>::dumpBounds() const { |
| const SkTSpan<TCurve, OppCurve>* test = fHead; |
| do { |
| test->dumpBounds(); |
| } while ((test = test->next())); |
| } |
| |
| template<typename TCurve, typename OppCurve> |
| void SkTSect<TCurve, OppCurve>::dumpCoin() const { |
| dumpCommon(fCoincident); |
| } |
| |
| template<typename TCurve, typename OppCurve> |
| void SkTSect<TCurve, OppCurve>::dumpCoinCurves() const { |
| dumpCommonCurves(fCoincident); |
| } |
| |
| template<typename TCurve, typename OppCurve> |
| void SkTSect<TCurve, OppCurve>::dumpCommon(const SkTSpan<TCurve, OppCurve>* test) const { |
| SkDebugf("id=%d", debugID()); |
| if (!test) { |
| SkDebugf(" (empty)"); |
| return; |
| } |
| do { |
| SkDebugf(" "); |
| test->dump(); |
| } while ((test = test->next())); |
| } |
| |
| template<typename TCurve, typename OppCurve> |
| void SkTSect<TCurve, OppCurve>::dumpCommonCurves(const SkTSpan<TCurve, OppCurve>* test) const { |
| do { |
| test->fPart.dumpID(test->debugID()); |
| } while ((test = test->next())); |
| } |
| |
| template<typename TCurve, typename OppCurve> |
| void SkTSect<TCurve, OppCurve>::dumpCurves() const { |
| dumpCommonCurves(fHead); |
| } |
| |
| template<typename TCurve, typename OppCurve> |
| const SkTSpan<TCurve, OppCurve>* SkTSpan<TCurve, OppCurve>::debugSpan(int id) const { |
| return SkDEBUGRELEASE(fDebugSect->debugSpan(id), nullptr); |
| } |
| |
| template<typename TCurve, typename OppCurve> |
| const SkTSpan<TCurve, OppCurve>* SkTSpan<TCurve, OppCurve>::debugT(double t) const { |
| return SkDEBUGRELEASE(fDebugSect->debugT(t), nullptr); |
| } |
| |
| template<typename TCurve, typename OppCurve> |
| void SkTSpan<TCurve, OppCurve>::dumpAll() const { |
| dumpID(); |
| SkDebugf("=(%g,%g) [", fStartT, fEndT); |
| const SkTSpanBounded<OppCurve, TCurve>* testBounded = fBounded; |
| while (testBounded) { |
| const SkTSpan<OppCurve, TCurve>* span = testBounded->fBounded; |
| const SkTSpanBounded<OppCurve, TCurve>* next = testBounded->fNext; |
| span->dumpID(); |
| SkDebugf("=(%g,%g)", span->fStartT, span->fEndT); |
| if (next) { |
| SkDebugf(" "); |
| } |
| testBounded = next; |
| } |
| SkDebugf("]\n"); |
| } |
| |
| template<typename TCurve, typename OppCurve> |
| void SkTSpan<TCurve, OppCurve>::dump() const { |
| dumpID(); |
| SkDebugf("=(%g,%g) [", fStartT, fEndT); |
| const SkTSpanBounded<OppCurve, TCurve>* testBounded = fBounded; |
| while (testBounded) { |
| const SkTSpan<OppCurve, TCurve>* span = testBounded->fBounded; |
| const SkTSpanBounded<OppCurve, TCurve>* next = testBounded->fNext; |
| span->dumpID(); |
| if (next) { |
| SkDebugf(","); |
| } |
| testBounded = next; |
| } |
| SkDebugf("]"); |
| } |
| |
| template<typename TCurve, typename OppCurve> |
| void SkTSpan<TCurve, OppCurve>::dumpBounded(int id) const { |
| SkDEBUGCODE(fDebugSect->dumpBounded(id)); |
| } |
| |
| template<typename TCurve, typename OppCurve> |
| void SkTSpan<TCurve, OppCurve>::dumpBounds() const { |
| dumpID(); |
| SkDebugf(" bounds=(%1.9g,%1.9g, %1.9g,%1.9g) boundsMax=%1.9g%s\n", |
| fBounds.fLeft, fBounds.fTop, fBounds.fRight, fBounds.fBottom, fBoundsMax, |
| fCollapsed ? " collapsed" : ""); |
| } |
| |
| template<typename TCurve, typename OppCurve> |
| void SkTSpan<TCurve, OppCurve>::dumpCoin() const { |
| dumpID(); |
| SkDebugf(" coinStart "); |
| fCoinStart.dump(); |
| SkDebugf(" coinEnd "); |
| fCoinEnd.dump(); |
| } |
| |
| template<typename TCurve, typename OppCurve> |
| void SkTSpan<TCurve, OppCurve>::dumpID() const { |
| char cS = fCoinStart.dumpIsCoincidentStr(); |
| if (cS) { |
| SkDebugf("%c", cS); |
| } |
| SkDebugf("%d", debugID()); |
| char cE = fCoinEnd.dumpIsCoincidentStr(); |
| if (cE) { |
| SkDebugf("%c", cE); |
| } |
| } |