OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 #ifndef SkPathOpsTSect_DEFINED | 7 #ifndef SkPathOpsTSect_DEFINED |
8 #define SkPathOpsTSect_DEFINED | 8 #define SkPathOpsTSect_DEFINED |
9 | 9 |
10 #include "SkChunkAlloc.h" | 10 #include "SkChunkAlloc.h" |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 void debugInit() { | 92 void debugInit() { |
93 TCurve dummy; | 93 TCurve dummy; |
94 dummy.debugInit(); | 94 dummy.debugInit(); |
95 init(dummy); | 95 init(dummy); |
96 initBounds(dummy); | 96 initBounds(dummy); |
97 fCoinStart.init(); | 97 fCoinStart.init(); |
98 fCoinEnd.init(); | 98 fCoinEnd.init(); |
99 } | 99 } |
100 | 100 |
101 const SkTSect<OppCurve, TCurve>* debugOpp() const; | 101 const SkTSect<OppCurve, TCurve>* debugOpp() const; |
| 102 |
| 103 #ifdef SK_DEBUG |
| 104 void debugSetGlobalState(SkOpGlobalState* state) { |
| 105 fDebugGlobalState = state; |
| 106 } |
| 107 #endif |
| 108 |
102 const SkTSpan* debugSpan(int ) const; | 109 const SkTSpan* debugSpan(int ) const; |
103 const SkTSpan* debugT(double t) const; | 110 const SkTSpan* debugT(double t) const; |
104 #ifdef SK_DEBUG | 111 #ifdef SK_DEBUG |
105 bool debugIsBefore(const SkTSpan* span) const; | 112 bool debugIsBefore(const SkTSpan* span) const; |
106 #endif | 113 #endif |
107 void dump() const; | 114 void dump() const; |
108 void dumpAll() const; | 115 void dumpAll() const; |
109 void dumpBounded(int id) const; | 116 void dumpBounded(int id) const; |
110 void dumpBounds() const; | 117 void dumpBounds() const; |
111 void dumpCoin() const; | 118 void dumpCoin() const; |
112 | 119 |
113 double endT() const { | 120 double endT() const { |
114 return fEndT; | 121 return fEndT; |
115 } | 122 } |
116 | 123 |
117 SkTSpan<OppCurve, TCurve>* findOppSpan(const SkTSpan<OppCurve, TCurve>* opp)
const; | 124 SkTSpan<OppCurve, TCurve>* findOppSpan(const SkTSpan<OppCurve, TCurve>* opp)
const; |
118 | 125 |
119 SkTSpan<OppCurve, TCurve>* findOppT(double t) const { | 126 SkTSpan<OppCurve, TCurve>* findOppT(double t) const { |
120 SkTSpan<OppCurve, TCurve>* result = oppT(t); | 127 SkTSpan<OppCurve, TCurve>* result = oppT(t); |
121 SkASSERT(result); | 128 SkOPASSERT(result); |
122 return result; | 129 return result; |
123 } | 130 } |
124 | 131 |
| 132 SkDEBUGCODE(SkOpGlobalState* globalState() const { return fDebugGlobalState;
}) |
| 133 |
125 bool hasOppT(double t) const { | 134 bool hasOppT(double t) const { |
126 return SkToBool(oppT(t)); | 135 return SkToBool(oppT(t)); |
127 } | 136 } |
128 | 137 |
129 int hullsIntersect(SkTSpan<OppCurve, TCurve>* span, bool* start, bool* oppSt
art); | 138 int hullsIntersect(SkTSpan<OppCurve, TCurve>* span, bool* start, bool* oppSt
art); |
130 void init(const TCurve& ); | 139 void init(const TCurve& ); |
131 void initBounds(const TCurve& ); | 140 void initBounds(const TCurve& ); |
132 | 141 |
133 bool isBounded() const { | 142 bool isBounded() const { |
134 return fBounded != nullptr; | 143 return fBounded != nullptr; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 SkTSpan* fNext; | 210 SkTSpan* fNext; |
202 SkDRect fBounds; | 211 SkDRect fBounds; |
203 double fStartT; | 212 double fStartT; |
204 double fEndT; | 213 double fEndT; |
205 double fBoundsMax; | 214 double fBoundsMax; |
206 SkOpDebugBool fCollapsed; | 215 SkOpDebugBool fCollapsed; |
207 SkOpDebugBool fHasPerp; | 216 SkOpDebugBool fHasPerp; |
208 SkOpDebugBool fIsLinear; | 217 SkOpDebugBool fIsLinear; |
209 SkOpDebugBool fIsLine; | 218 SkOpDebugBool fIsLine; |
210 SkOpDebugBool fDeleted; | 219 SkOpDebugBool fDeleted; |
| 220 SkDEBUGCODE(SkOpGlobalState* fDebugGlobalState); |
211 SkDEBUGCODE_(SkTSect<TCurve, OppCurve>* fDebugSect); | 221 SkDEBUGCODE_(SkTSect<TCurve, OppCurve>* fDebugSect); |
212 PATH_OPS_DEBUG_T_SECT_CODE(int fID); | 222 PATH_OPS_DEBUG_T_SECT_CODE(int fID); |
213 friend class SkTSect<TCurve, OppCurve>; | 223 friend class SkTSect<TCurve, OppCurve>; |
214 friend class SkTSect<OppCurve, TCurve>; | 224 friend class SkTSect<OppCurve, TCurve>; |
215 friend class SkTSpan<OppCurve, TCurve>; | 225 friend class SkTSpan<OppCurve, TCurve>; |
216 }; | 226 }; |
217 | 227 |
218 template<typename TCurve, typename OppCurve> | 228 template<typename TCurve, typename OppCurve> |
219 class SkTSect { | 229 class SkTSect { |
220 public: | 230 public: |
(...skipping 26 matching lines...) Expand all Loading... |
247 kZeroS2Set = 4, | 257 kZeroS2Set = 4, |
248 kOneS2Set = 8 | 258 kOneS2Set = 8 |
249 }; | 259 }; |
250 | 260 |
251 SkTSpan<TCurve, OppCurve>* addFollowing(SkTSpan<TCurve, OppCurve>* prior); | 261 SkTSpan<TCurve, OppCurve>* addFollowing(SkTSpan<TCurve, OppCurve>* prior); |
252 void addForPerp(SkTSpan<OppCurve, TCurve>* span, double t); | 262 void addForPerp(SkTSpan<OppCurve, TCurve>* span, double t); |
253 SkTSpan<TCurve, OppCurve>* addOne(); | 263 SkTSpan<TCurve, OppCurve>* addOne(); |
254 | 264 |
255 SkTSpan<TCurve, OppCurve>* addSplitAt(SkTSpan<TCurve, OppCurve>* span, doubl
e t) { | 265 SkTSpan<TCurve, OppCurve>* addSplitAt(SkTSpan<TCurve, OppCurve>* span, doubl
e t) { |
256 SkTSpan<TCurve, OppCurve>* result = this->addOne(); | 266 SkTSpan<TCurve, OppCurve>* result = this->addOne(); |
| 267 SkDEBUGCODE(result->debugSetGlobalState(this->globalState())); |
257 result->splitAt(span, t, &fHeap); | 268 result->splitAt(span, t, &fHeap); |
258 result->initBounds(fCurve); | 269 result->initBounds(fCurve); |
259 span->initBounds(fCurve); | 270 span->initBounds(fCurve); |
260 return result; | 271 return result; |
261 } | 272 } |
262 | 273 |
263 bool binarySearchCoin(SkTSect<OppCurve, TCurve>* , double tStart, double tSt
ep, double* t, | 274 bool binarySearchCoin(SkTSect<OppCurve, TCurve>* , double tStart, double tSt
ep, double* t, |
264 double* oppT); | 275 double* oppT); |
265 SkTSpan<TCurve, OppCurve>* boundsMax() const; | 276 SkTSpan<TCurve, OppCurve>* boundsMax() const; |
266 void coincidentCheck(SkTSect<OppCurve, TCurve>* sect2); | 277 void coincidentCheck(SkTSect<OppCurve, TCurve>* sect2); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 sizeof(SkTSpanBounded<OppCurve, TCurve>)))(SkTSpanBounded<OppCurve,
TCurve>); | 387 sizeof(SkTSpanBounded<OppCurve, TCurve>)))(SkTSpanBounded<OppCurve,
TCurve>); |
377 bounded->fBounded = span; | 388 bounded->fBounded = span; |
378 bounded->fNext = fBounded; | 389 bounded->fNext = fBounded; |
379 fBounded = bounded; | 390 fBounded = bounded; |
380 } | 391 } |
381 | 392 |
382 template<typename TCurve, typename OppCurve> | 393 template<typename TCurve, typename OppCurve> |
383 SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::addFollowing( | 394 SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::addFollowing( |
384 SkTSpan<TCurve, OppCurve>* prior) { | 395 SkTSpan<TCurve, OppCurve>* prior) { |
385 SkTSpan<TCurve, OppCurve>* result = this->addOne(); | 396 SkTSpan<TCurve, OppCurve>* result = this->addOne(); |
| 397 SkDEBUGCODE(result->debugSetGlobalState(this->globalState())); |
386 result->fStartT = prior ? prior->fEndT : 0; | 398 result->fStartT = prior ? prior->fEndT : 0; |
387 SkTSpan<TCurve, OppCurve>* next = prior ? prior->fNext : fHead; | 399 SkTSpan<TCurve, OppCurve>* next = prior ? prior->fNext : fHead; |
388 result->fEndT = next ? next->fStartT : 1; | 400 result->fEndT = next ? next->fStartT : 1; |
389 result->fPrev = prior; | 401 result->fPrev = prior; |
390 result->fNext = next; | 402 result->fNext = next; |
391 if (prior) { | 403 if (prior) { |
392 prior->fNext = result; | 404 prior->fNext = result; |
393 } else { | 405 } else { |
394 fHead = result; | 406 fHead = result; |
395 } | 407 } |
396 if (next) { | 408 if (next) { |
397 next->fPrev = result; | 409 next->fPrev = result; |
398 } | 410 } |
399 result->resetBounds(fCurve); | 411 result->resetBounds(fCurve); |
| 412 result->validate(); |
400 return result; | 413 return result; |
401 } | 414 } |
402 | 415 |
403 template<typename TCurve, typename OppCurve> | 416 template<typename TCurve, typename OppCurve> |
404 void SkTSect<TCurve, OppCurve>::addForPerp(SkTSpan<OppCurve, TCurve>* span, doub
le t) { | 417 void SkTSect<TCurve, OppCurve>::addForPerp(SkTSpan<OppCurve, TCurve>* span, doub
le t) { |
405 if (!span->hasOppT(t)) { | 418 if (!span->hasOppT(t)) { |
406 SkTSpan<TCurve, OppCurve>* priorSpan; | 419 SkTSpan<TCurve, OppCurve>* priorSpan; |
407 SkTSpan<TCurve, OppCurve>* opp = this->spanAtT(t, &priorSpan); | 420 SkTSpan<TCurve, OppCurve>* opp = this->spanAtT(t, &priorSpan); |
408 if (!opp) { | 421 if (!opp) { |
409 opp = this->addFollowing(priorSpan); | 422 opp = this->addFollowing(priorSpan); |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 prev->fNext = boundedNext; | 736 prev->fNext = boundedNext; |
724 return false; | 737 return false; |
725 } else { | 738 } else { |
726 fBounded = boundedNext; | 739 fBounded = boundedNext; |
727 return fBounded == nullptr; | 740 return fBounded == nullptr; |
728 } | 741 } |
729 } | 742 } |
730 prev = bounded; | 743 prev = bounded; |
731 bounded = boundedNext; | 744 bounded = boundedNext; |
732 } | 745 } |
733 SkASSERT(0); | 746 SkOPASSERT(0); |
734 return false; | 747 return false; |
735 } | 748 } |
736 | 749 |
737 template<typename TCurve, typename OppCurve> | 750 template<typename TCurve, typename OppCurve> |
738 bool SkTSpan<TCurve, OppCurve>::splitAt(SkTSpan* work, double t, SkChunkAlloc* h
eap) { | 751 bool SkTSpan<TCurve, OppCurve>::splitAt(SkTSpan* work, double t, SkChunkAlloc* h
eap) { |
739 fStartT = t; | 752 fStartT = t; |
740 fEndT = work->fEndT; | 753 fEndT = work->fEndT; |
741 if (fStartT == fEndT) { | 754 if (fStartT == fEndT) { |
742 fCollapsed = true; | 755 fCollapsed = true; |
743 return false; | 756 return false; |
744 } | 757 } |
745 work->fEndT = t; | 758 work->fEndT = t; |
746 if (work->fStartT == work->fEndT) { | 759 if (work->fStartT == work->fEndT) { |
747 work->fCollapsed = true; | 760 work->fCollapsed = true; |
748 return false; | 761 return false; |
749 } | 762 } |
750 fPrev = work; | 763 fPrev = work; |
751 fNext = work->fNext; | 764 fNext = work->fNext; |
752 fIsLinear = work->fIsLinear; | 765 fIsLinear = work->fIsLinear; |
753 fIsLine = work->fIsLine; | 766 fIsLine = work->fIsLine; |
754 | 767 |
755 work->fNext = this; | 768 work->fNext = this; |
756 if (fNext) { | 769 if (fNext) { |
757 fNext->fPrev = this; | 770 fNext->fPrev = this; |
758 } | 771 } |
| 772 this->validate(); |
759 SkTSpanBounded<OppCurve, TCurve>* bounded = work->fBounded; | 773 SkTSpanBounded<OppCurve, TCurve>* bounded = work->fBounded; |
760 fBounded = nullptr; | 774 fBounded = nullptr; |
761 while (bounded) { | 775 while (bounded) { |
762 this->addBounded(bounded->fBounded, heap); | 776 this->addBounded(bounded->fBounded, heap); |
763 bounded = bounded->fNext; | 777 bounded = bounded->fNext; |
764 } | 778 } |
765 bounded = fBounded; | 779 bounded = fBounded; |
766 while (bounded) { | 780 while (bounded) { |
767 bounded->fBounded->addBounded(this, heap); | 781 bounded->fBounded->addBounded(this, heap); |
768 bounded = bounded->fNext; | 782 bounded = bounded->fNext; |
769 } | 783 } |
770 return true; | 784 return true; |
771 } | 785 } |
772 | 786 |
773 template<typename TCurve, typename OppCurve> | 787 template<typename TCurve, typename OppCurve> |
774 void SkTSpan<TCurve, OppCurve>::validate() const { | 788 void SkTSpan<TCurve, OppCurve>::validate() const { |
775 #if DEBUG_T_SECT | 789 #if DEBUG_VALIDATE |
| 790 SkASSERT(this != fPrev); |
| 791 SkASSERT(this != fNext); |
776 SkASSERT(fNext == nullptr || fNext != fPrev); | 792 SkASSERT(fNext == nullptr || fNext != fPrev); |
777 SkASSERT(fNext == nullptr || this == fNext->fPrev); | 793 SkASSERT(fNext == nullptr || this == fNext->fPrev); |
778 SkASSERT(fPrev == nullptr || this == fPrev->fNext); | 794 SkASSERT(fPrev == nullptr || this == fPrev->fNext); |
| 795 this->validateBounded(); |
| 796 #endif |
| 797 #if DEBUG_T_SECT |
779 SkASSERT(fBounds.width() || fBounds.height() || fCollapsed); | 798 SkASSERT(fBounds.width() || fBounds.height() || fCollapsed); |
780 SkASSERT(fBoundsMax == SkTMax(fBounds.width(), fBounds.height())); | 799 SkASSERT(fBoundsMax == SkTMax(fBounds.width(), fBounds.height())); |
781 SkASSERT(0 <= fStartT); | 800 SkASSERT(0 <= fStartT); |
782 SkASSERT(fEndT <= 1); | 801 SkASSERT(fEndT <= 1); |
783 SkASSERT(fStartT <= fEndT); | 802 SkASSERT(fStartT <= fEndT); |
784 SkASSERT(fBounded); | 803 SkASSERT(fBounded); |
785 this->validateBounded(); | |
786 if (fHasPerp) { | 804 if (fHasPerp) { |
787 if (fCoinStart.isCoincident()) { | 805 if (fCoinStart.isCoincident()) { |
788 validatePerpT(fCoinStart.perpT()); | 806 validatePerpT(fCoinStart.perpT()); |
789 validatePerpPt(fCoinStart.perpT(), fCoinStart.perpPt()); | 807 validatePerpPt(fCoinStart.perpT(), fCoinStart.perpPt()); |
790 } | 808 } |
791 if (fCoinEnd.isCoincident()) { | 809 if (fCoinEnd.isCoincident()) { |
792 validatePerpT(fCoinEnd.perpT()); | 810 validatePerpT(fCoinEnd.perpT()); |
793 validatePerpPt(fCoinEnd.perpT(), fCoinEnd.perpPt()); | 811 validatePerpPt(fCoinEnd.perpT(), fCoinEnd.perpPt()); |
794 } | 812 } |
795 } | 813 } |
796 #endif | 814 #endif |
797 } | 815 } |
798 | 816 |
799 template<typename TCurve, typename OppCurve> | 817 template<typename TCurve, typename OppCurve> |
800 void SkTSpan<TCurve, OppCurve>::validateBounded() const { | 818 void SkTSpan<TCurve, OppCurve>::validateBounded() const { |
801 #if DEBUG_VALIDATE | 819 #if DEBUG_VALIDATE |
802 const SkTSpanBounded<OppCurve, TCurve>* testBounded = fBounded; | 820 const SkTSpanBounded<OppCurve, TCurve>* testBounded = fBounded; |
803 while (testBounded) { | 821 while (testBounded) { |
804 SkDEBUGCODE_(const SkTSpan<OppCurve, TCurve>* overlap = testBounded->fBo
unded); | 822 SkDEBUGCODE_(const SkTSpan<OppCurve, TCurve>* overlap = testBounded->fBo
unded); |
805 SkASSERT(!overlap->fDeleted); | 823 SkASSERT(!overlap->fDeleted); |
| 824 #if DEBUG_T_SECT |
806 SkASSERT(((this->debugID() ^ overlap->debugID()) & 1) == 1); | 825 SkASSERT(((this->debugID() ^ overlap->debugID()) & 1) == 1); |
807 SkASSERT(overlap->findOppSpan(this)); | 826 SkASSERT(overlap->findOppSpan(this)); |
| 827 #endif |
808 testBounded = testBounded->fNext; | 828 testBounded = testBounded->fNext; |
809 } | 829 } |
810 #endif | 830 #endif |
811 } | 831 } |
812 | 832 |
813 template<typename TCurve, typename OppCurve> | 833 template<typename TCurve, typename OppCurve> |
814 void SkTSpan<TCurve, OppCurve>::validatePerpT(double oppT) const { | 834 void SkTSpan<TCurve, OppCurve>::validatePerpT(double oppT) const { |
815 const SkTSpanBounded<OppCurve, TCurve>* testBounded = fBounded; | 835 const SkTSpanBounded<OppCurve, TCurve>* testBounded = fBounded; |
816 while (testBounded) { | 836 while (testBounded) { |
817 const SkTSpan<OppCurve, TCurve>* overlap = testBounded->fBounded; | 837 const SkTSpan<OppCurve, TCurve>* overlap = testBounded->fBounded; |
(...skipping 19 matching lines...) Expand all Loading... |
837 , fHeap(sizeof(SkTSpan<TCurve, OppCurve>) * 4) | 857 , fHeap(sizeof(SkTSpan<TCurve, OppCurve>) * 4) |
838 , fCoincident(nullptr) | 858 , fCoincident(nullptr) |
839 , fDeleted(nullptr) | 859 , fDeleted(nullptr) |
840 , fActiveCount(0) | 860 , fActiveCount(0) |
841 SkDEBUGPARAMS(fDebugGlobalState(debugGlobalState)) | 861 SkDEBUGPARAMS(fDebugGlobalState(debugGlobalState)) |
842 PATH_OPS_DEBUG_T_SECT_PARAMS(fID(id)) | 862 PATH_OPS_DEBUG_T_SECT_PARAMS(fID(id)) |
843 PATH_OPS_DEBUG_T_SECT_PARAMS(fDebugCount(0)) | 863 PATH_OPS_DEBUG_T_SECT_PARAMS(fDebugCount(0)) |
844 PATH_OPS_DEBUG_T_SECT_PARAMS(fDebugAllocatedCount(0)) | 864 PATH_OPS_DEBUG_T_SECT_PARAMS(fDebugAllocatedCount(0)) |
845 { | 865 { |
846 fHead = addOne(); | 866 fHead = addOne(); |
| 867 SkDEBUGCODE(fHead->debugSetGlobalState(debugGlobalState)); |
847 fHead->init(c); | 868 fHead->init(c); |
848 } | 869 } |
849 | 870 |
850 template<typename TCurve, typename OppCurve> | 871 template<typename TCurve, typename OppCurve> |
851 SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::addOne() { | 872 SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::addOne() { |
852 SkTSpan<TCurve, OppCurve>* result; | 873 SkTSpan<TCurve, OppCurve>* result; |
853 if (fDeleted) { | 874 if (fDeleted) { |
854 result = fDeleted; | 875 result = fDeleted; |
855 fDeleted = result->fNext; | 876 fDeleted = result->fNext; |
856 } else { | 877 } else { |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
975 this->validate(); | 996 this->validate(); |
976 sect2->validate(); | 997 sect2->validate(); |
977 // check to see if a range of points are on the curve | 998 // check to see if a range of points are on the curve |
978 SkTSpan<TCurve, OppCurve>* coinStart = first; | 999 SkTSpan<TCurve, OppCurve>* coinStart = first; |
979 do { | 1000 do { |
980 coinStart = this->extractCoincident(sect2, coinStart, last); | 1001 coinStart = this->extractCoincident(sect2, coinStart, last); |
981 } while (coinStart && !last->fDeleted); | 1002 } while (coinStart && !last->fDeleted); |
982 if (!fHead || !sect2->fHead) { | 1003 if (!fHead || !sect2->fHead) { |
983 break; | 1004 break; |
984 } | 1005 } |
| 1006 if (!next || next->fDeleted) { |
| 1007 break; |
| 1008 } |
985 } while ((first = next)); | 1009 } while ((first = next)); |
986 } | 1010 } |
987 | 1011 |
988 template<typename TCurve, typename OppCurve> | 1012 template<typename TCurve, typename OppCurve> |
989 void SkTSect<TCurve, OppCurve>::coincidentForce(SkTSect<OppCurve, TCurve>* sect2
, | 1013 void SkTSect<TCurve, OppCurve>::coincidentForce(SkTSect<OppCurve, TCurve>* sect2
, |
990 double start1s, double start1e) { | 1014 double start1s, double start1e) { |
991 SkTSpan<TCurve, OppCurve>* first = fHead; | 1015 SkTSpan<TCurve, OppCurve>* first = fHead; |
992 SkTSpan<TCurve, OppCurve>* last = this->tail(); | 1016 SkTSpan<TCurve, OppCurve>* last = this->tail(); |
993 SkTSpan<OppCurve, TCurve>* oppFirst = sect2->fHead; | 1017 SkTSpan<OppCurve, TCurve>* oppFirst = sect2->fHead; |
994 SkTSpan<OppCurve, TCurve>* oppLast = sect2->tail(); | 1018 SkTSpan<OppCurve, TCurve>* oppLast = sect2->tail(); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1138 if (!first) { | 1162 if (!first) { |
1139 return nullptr; | 1163 return nullptr; |
1140 } | 1164 } |
1141 // march outwards to find limit of coincidence from here to previous and nex
t spans | 1165 // march outwards to find limit of coincidence from here to previous and nex
t spans |
1142 double startT = first->fStartT; | 1166 double startT = first->fStartT; |
1143 double oppStartT SK_INIT_TO_AVOID_WARNING; | 1167 double oppStartT SK_INIT_TO_AVOID_WARNING; |
1144 double oppEndT SK_INIT_TO_AVOID_WARNING; | 1168 double oppEndT SK_INIT_TO_AVOID_WARNING; |
1145 SkTSpan<TCurve, OppCurve>* prev = first->fPrev; | 1169 SkTSpan<TCurve, OppCurve>* prev = first->fPrev; |
1146 SkASSERT(first->fCoinStart.isCoincident()); | 1170 SkASSERT(first->fCoinStart.isCoincident()); |
1147 SkTSpan<OppCurve, TCurve>* oppFirst = first->findOppT(first->fCoinStart.perp
T()); | 1171 SkTSpan<OppCurve, TCurve>* oppFirst = first->findOppT(first->fCoinStart.perp
T()); |
1148 SkASSERT(last->fCoinEnd.isCoincident()); | 1172 SkOPASSERT(last->fCoinEnd.isCoincident()); |
1149 bool oppMatched = first->fCoinStart.perpT() < first->fCoinEnd.perpT(); | 1173 bool oppMatched = first->fCoinStart.perpT() < first->fCoinEnd.perpT(); |
1150 double coinStart; | 1174 double coinStart; |
1151 SkDEBUGCODE(double coinEnd); | 1175 SkDEBUGCODE(double coinEnd); |
1152 SkTSpan<OppCurve, TCurve>* cutFirst; | 1176 SkTSpan<OppCurve, TCurve>* cutFirst; |
1153 if (prev && prev->fEndT == startT | 1177 if (prev && prev->fEndT == startT |
1154 && this->binarySearchCoin(sect2, startT, prev->fStartT - startT, &co
inStart, | 1178 && this->binarySearchCoin(sect2, startT, prev->fStartT - startT, &co
inStart, |
1155 &oppStartT) | 1179 &oppStartT) |
1156 && prev->fStartT < coinStart && coinStart < startT | 1180 && prev->fStartT < coinStart && coinStart < startT |
1157 && (cutFirst = prev->oppT(oppStartT))) { | 1181 && (cutFirst = prev->oppT(oppStartT))) { |
1158 oppFirst = cutFirst; | 1182 oppFirst = cutFirst; |
(...skipping 10 matching lines...) Expand all Loading... |
1169 oppFirst->markCoincident(); | 1193 oppFirst->markCoincident(); |
1170 oppHalf->fCoinStart.markCoincident(); | 1194 oppHalf->fCoinStart.markCoincident(); |
1171 } | 1195 } |
1172 } | 1196 } |
1173 } else { | 1197 } else { |
1174 SkDEBUGCODE(coinStart = first->fStartT); | 1198 SkDEBUGCODE(coinStart = first->fStartT); |
1175 SkDEBUGCODE(oppStartT = oppMatched ? oppFirst->fStartT : oppFirst->fEndT
); | 1199 SkDEBUGCODE(oppStartT = oppMatched ? oppFirst->fStartT : oppFirst->fEndT
); |
1176 } | 1200 } |
1177 // FIXME: incomplete : if we're not at the end, find end of coin | 1201 // FIXME: incomplete : if we're not at the end, find end of coin |
1178 SkTSpan<OppCurve, TCurve>* oppLast; | 1202 SkTSpan<OppCurve, TCurve>* oppLast; |
1179 SkASSERT(last->fCoinEnd.isCoincident()); | 1203 SkOPASSERT(last->fCoinEnd.isCoincident()); |
1180 oppLast = last->findOppT(last->fCoinEnd.perpT()); | 1204 oppLast = last->findOppT(last->fCoinEnd.perpT()); |
1181 SkDEBUGCODE(coinEnd = last->fEndT); | 1205 SkDEBUGCODE(coinEnd = last->fEndT); |
1182 SkDEBUGCODE(oppEndT = oppMatched ? oppLast->fEndT : oppLast->fStartT); | 1206 #ifdef SK_DEBUG |
| 1207 if (!this->globalState() || !this->globalState()->debugSkipAssert()) { |
| 1208 oppEndT = oppMatched ? oppLast->fEndT : oppLast->fStartT; |
| 1209 } |
| 1210 #endif |
1183 if (!oppMatched) { | 1211 if (!oppMatched) { |
1184 SkTSwap(oppFirst, oppLast); | 1212 SkTSwap(oppFirst, oppLast); |
1185 SkTSwap(oppStartT, oppEndT); | 1213 SkTSwap(oppStartT, oppEndT); |
1186 } | 1214 } |
1187 SkOPASSERT(oppStartT < oppEndT); | 1215 SkOPASSERT(oppStartT < oppEndT); |
1188 SkASSERT(coinStart == first->fStartT); | 1216 SkASSERT(coinStart == first->fStartT); |
1189 SkASSERT(coinEnd == last->fEndT); | 1217 SkASSERT(coinEnd == last->fEndT); |
1190 SkASSERT(oppStartT == oppFirst->fStartT); | 1218 SkOPASSERT(oppStartT == oppFirst->fStartT); |
1191 SkASSERT(oppEndT == oppLast->fEndT); | 1219 SkOPASSERT(oppEndT == oppLast->fEndT); |
| 1220 if (!oppFirst) { |
| 1221 return nullptr; |
| 1222 } |
1192 // reduce coincident runs to single entries | 1223 // reduce coincident runs to single entries |
1193 this->validate(); | 1224 this->validate(); |
1194 sect2->validate(); | 1225 sect2->validate(); |
1195 bool deleteEmptySpans = this->updateBounded(first, last, oppFirst); | 1226 bool deleteEmptySpans = this->updateBounded(first, last, oppFirst); |
1196 deleteEmptySpans |= sect2->updateBounded(oppFirst, oppLast, first); | 1227 deleteEmptySpans |= sect2->updateBounded(oppFirst, oppLast, first); |
1197 this->removeSpanRange(first, last); | 1228 this->removeSpanRange(first, last); |
1198 sect2->removeSpanRange(oppFirst, oppLast); | 1229 sect2->removeSpanRange(oppFirst, oppLast); |
1199 first->fEndT = last->fEndT; | 1230 first->fEndT = last->fEndT; |
1200 first->resetBounds(this->fCurve); | 1231 first->resetBounds(this->fCurve); |
1201 first->fCoinStart.setPerp(fCurve, first->fStartT, first->fPart[0], sect2->fC
urve); | 1232 first->fCoinStart.setPerp(fCurve, first->fStartT, first->fPart[0], sect2->fC
urve); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1243 } | 1274 } |
1244 lastCandidate = work; | 1275 lastCandidate = work; |
1245 if (!first) { | 1276 if (!first) { |
1246 first = work; | 1277 first = work; |
1247 } | 1278 } |
1248 } else if (first && work->fCollapsed) { | 1279 } else if (first && work->fCollapsed) { |
1249 *lastPtr = lastCandidate; | 1280 *lastPtr = lastCandidate; |
1250 return first; | 1281 return first; |
1251 } else { | 1282 } else { |
1252 lastCandidate = nullptr; | 1283 lastCandidate = nullptr; |
1253 SkASSERT(!first); | 1284 SkOPASSERT(!first); |
1254 } | 1285 } |
1255 if (work == *lastPtr) { | 1286 if (work == *lastPtr) { |
1256 return first; | 1287 return first; |
1257 } | 1288 } |
1258 work = work->fNext; | 1289 work = work->fNext; |
1259 if (!work) { | 1290 if (!work) { |
1260 return nullptr; | 1291 return nullptr; |
1261 } | 1292 } |
1262 } while (true); | 1293 } while (true); |
1263 if (lastCandidate) { | 1294 if (lastCandidate) { |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1575 // check middle t value to see if it is coincident as well | 1606 // check middle t value to see if it is coincident as well |
1576 double midT = (smaller->fEndT + larger->fStartT) / 2; | 1607 double midT = (smaller->fEndT + larger->fStartT) / 2; |
1577 SkDPoint midPt = fCurve.ptAtT(midT); | 1608 SkDPoint midPt = fCurve.ptAtT(midT); |
1578 SkTCoincident<TCurve, OppCurve> coin; | 1609 SkTCoincident<TCurve, OppCurve> coin; |
1579 coin.setPerp(fCurve, midT, midPt, sect2->fCurve); | 1610 coin.setPerp(fCurve, midT, midPt, sect2->fCurve); |
1580 if (coin.isCoincident()) { | 1611 if (coin.isCoincident()) { |
1581 smaller->fEndT = larger->fEndT; | 1612 smaller->fEndT = larger->fEndT; |
1582 smaller->fCoinEnd = larger->fCoinEnd; | 1613 smaller->fCoinEnd = larger->fCoinEnd; |
1583 if (largerPrior) { | 1614 if (largerPrior) { |
1584 largerPrior->fNext = larger->fNext; | 1615 largerPrior->fNext = larger->fNext; |
| 1616 largerPrior->validate(); |
1585 } else { | 1617 } else { |
1586 fCoincident = larger->fNext; | 1618 fCoincident = larger->fNext; |
1587 } | 1619 } |
1588 } | 1620 } |
1589 } while (true); | 1621 } while (true); |
1590 } | 1622 } |
1591 | 1623 |
1592 template<typename TCurve, typename OppCurve> | 1624 template<typename TCurve, typename OppCurve> |
1593 SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::prev( | 1625 SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::prev( |
1594 SkTSpan<TCurve, OppCurve>* span) const { | 1626 SkTSpan<TCurve, OppCurve>* span) const { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1691 SkTSpan<TCurve, OppCurve>* final = last->fNext; | 1723 SkTSpan<TCurve, OppCurve>* final = last->fNext; |
1692 SkTSpan<TCurve, OppCurve>* next = span->fNext; | 1724 SkTSpan<TCurve, OppCurve>* next = span->fNext; |
1693 while ((span = next) && span != final) { | 1725 while ((span = next) && span != final) { |
1694 next = span->fNext; | 1726 next = span->fNext; |
1695 this->markSpanGone(span); | 1727 this->markSpanGone(span); |
1696 } | 1728 } |
1697 if (final) { | 1729 if (final) { |
1698 final->fPrev = first; | 1730 final->fPrev = first; |
1699 } | 1731 } |
1700 first->fNext = final; | 1732 first->fNext = final; |
| 1733 first->validate(); |
1701 } | 1734 } |
1702 | 1735 |
1703 template<typename TCurve, typename OppCurve> | 1736 template<typename TCurve, typename OppCurve> |
1704 void SkTSect<TCurve, OppCurve>::removeSpans(SkTSpan<TCurve, OppCurve>* span, | 1737 void SkTSect<TCurve, OppCurve>::removeSpans(SkTSpan<TCurve, OppCurve>* span, |
1705 SkTSect<OppCurve, TCurve>* opp) { | 1738 SkTSect<OppCurve, TCurve>* opp) { |
1706 SkTSpanBounded<OppCurve, TCurve>* bounded = span->fBounded; | 1739 SkTSpanBounded<OppCurve, TCurve>* bounded = span->fBounded; |
1707 while (bounded) { | 1740 while (bounded) { |
1708 SkTSpan<OppCurve, TCurve>* spanBounded = bounded->fBounded; | 1741 SkTSpan<OppCurve, TCurve>* spanBounded = bounded->fBounded; |
1709 SkTSpanBounded<OppCurve, TCurve>* next = bounded->fNext; | 1742 SkTSpanBounded<OppCurve, TCurve>* next = bounded->fNext; |
1710 if (span->removeBounded(spanBounded)) { // shuffles last into position
0 | 1743 if (span->removeBounded(spanBounded)) { // shuffles last into position
0 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1777 } | 1810 } |
1778 | 1811 |
1779 template<typename TCurve, typename OppCurve> | 1812 template<typename TCurve, typename OppCurve> |
1780 void SkTSect<TCurve, OppCurve>::unlinkSpan(SkTSpan<TCurve, OppCurve>* span) { | 1813 void SkTSect<TCurve, OppCurve>::unlinkSpan(SkTSpan<TCurve, OppCurve>* span) { |
1781 SkTSpan<TCurve, OppCurve>* prev = span->fPrev; | 1814 SkTSpan<TCurve, OppCurve>* prev = span->fPrev; |
1782 SkTSpan<TCurve, OppCurve>* next = span->fNext; | 1815 SkTSpan<TCurve, OppCurve>* next = span->fNext; |
1783 if (prev) { | 1816 if (prev) { |
1784 prev->fNext = next; | 1817 prev->fNext = next; |
1785 if (next) { | 1818 if (next) { |
1786 next->fPrev = prev; | 1819 next->fPrev = prev; |
| 1820 next->validate(); |
1787 } | 1821 } |
1788 } else { | 1822 } else { |
1789 fHead = next; | 1823 fHead = next; |
1790 if (next) { | 1824 if (next) { |
1791 next->fPrev = nullptr; | 1825 next->fPrev = nullptr; |
1792 } | 1826 } |
1793 } | 1827 } |
1794 } | 1828 } |
1795 | 1829 |
1796 template<typename TCurve, typename OppCurve> | 1830 template<typename TCurve, typename OppCurve> |
1797 bool SkTSect<TCurve, OppCurve>::updateBounded(SkTSpan<TCurve, OppCurve>* first, | 1831 bool SkTSect<TCurve, OppCurve>::updateBounded(SkTSpan<TCurve, OppCurve>* first, |
1798 SkTSpan<TCurve, OppCurve>* last, SkTSpan<OppCurve, TCurve>* oppFirst) { | 1832 SkTSpan<TCurve, OppCurve>* last, SkTSpan<OppCurve, TCurve>* oppFirst) { |
1799 SkTSpan<TCurve, OppCurve>* test = first; | 1833 SkTSpan<TCurve, OppCurve>* test = first; |
1800 const SkTSpan<TCurve, OppCurve>* final = last->next(); | 1834 const SkTSpan<TCurve, OppCurve>* final = last->next(); |
1801 bool deleteSpan = false; | 1835 bool deleteSpan = false; |
1802 do { | 1836 do { |
1803 deleteSpan |= test->removeAllBounded(); | 1837 deleteSpan |= test->removeAllBounded(); |
1804 } while ((test = test->fNext) != final && test); | 1838 } while ((test = test->fNext) != final && test); |
1805 first->fBounded = nullptr; | 1839 first->fBounded = nullptr; |
1806 first->addBounded(oppFirst, &fHeap); | 1840 first->addBounded(oppFirst, &fHeap); |
1807 // cannot call validate until remove span range is called | 1841 // cannot call validate until remove span range is called |
1808 return deleteSpan; | 1842 return deleteSpan; |
1809 } | 1843 } |
1810 | 1844 |
1811 | 1845 |
1812 template<typename TCurve, typename OppCurve> | 1846 template<typename TCurve, typename OppCurve> |
1813 void SkTSect<TCurve, OppCurve>::validate() const { | 1847 void SkTSect<TCurve, OppCurve>::validate() const { |
1814 #if DEBUG_T_SECT | 1848 #if DEBUG_VALIDATE |
1815 int count = 0; | 1849 int count = 0; |
| 1850 double last = 0; |
1816 if (fHead) { | 1851 if (fHead) { |
1817 const SkTSpan<TCurve, OppCurve>* span = fHead; | 1852 const SkTSpan<TCurve, OppCurve>* span = fHead; |
1818 SkASSERT(!span->fPrev); | 1853 SkASSERT(!span->fPrev); |
1819 SkDEBUGCODE(double last = 0); | 1854 const SkTSpan<TCurve, OppCurve>* next; |
1820 do { | 1855 do { |
1821 span->validate(); | 1856 span->validate(); |
1822 SkASSERT(span->fStartT >= last); | 1857 SkASSERT(span->fStartT >= last); |
1823 SkDEBUGCODE(last = span->fEndT); | 1858 last = span->fEndT; |
1824 ++count; | 1859 ++count; |
1825 } while ((span = span->fNext) != nullptr); | 1860 next = span->fNext; |
| 1861 SkASSERT(next != span); |
| 1862 } while ((span = next) != nullptr); |
1826 } | 1863 } |
1827 SkASSERT(count == fActiveCount); | 1864 SkASSERT(count == fActiveCount); |
| 1865 #endif |
| 1866 #if DEBUG_T_SECT |
1828 SkASSERT(fActiveCount <= fDebugAllocatedCount); | 1867 SkASSERT(fActiveCount <= fDebugAllocatedCount); |
1829 int deletedCount = 0; | 1868 int deletedCount = 0; |
1830 const SkTSpan<TCurve, OppCurve>* deleted = fDeleted; | 1869 const SkTSpan<TCurve, OppCurve>* deleted = fDeleted; |
1831 while (deleted) { | 1870 while (deleted) { |
1832 ++deletedCount; | 1871 ++deletedCount; |
1833 deleted = deleted->fNext; | 1872 deleted = deleted->fNext; |
1834 } | 1873 } |
1835 const SkTSpan<TCurve, OppCurve>* coincident = fCoincident; | 1874 const SkTSpan<TCurve, OppCurve>* coincident = fCoincident; |
1836 while (coincident) { | 1875 while (coincident) { |
1837 ++deletedCount; | 1876 ++deletedCount; |
1838 coincident = coincident->fNext; | 1877 coincident = coincident->fNext; |
1839 } | 1878 } |
1840 SkASSERT(fActiveCount + deletedCount == fDebugAllocatedCount); | 1879 SkASSERT(fActiveCount + deletedCount == fDebugAllocatedCount); |
1841 #endif | 1880 #endif |
1842 } | 1881 } |
1843 | 1882 |
1844 template<typename TCurve, typename OppCurve> | 1883 template<typename TCurve, typename OppCurve> |
1845 void SkTSect<TCurve, OppCurve>::validateBounded() const { | 1884 void SkTSect<TCurve, OppCurve>::validateBounded() const { |
1846 #if DEBUG_T_SECT | 1885 #if DEBUG_VALIDATE |
1847 if (!fHead) { | 1886 if (!fHead) { |
1848 return; | 1887 return; |
1849 } | 1888 } |
1850 const SkTSpan<TCurve, OppCurve>* span = fHead; | 1889 const SkTSpan<TCurve, OppCurve>* span = fHead; |
1851 do { | 1890 do { |
1852 span->validateBounded(); | 1891 span->validateBounded(); |
1853 } while ((span = span->fNext) != nullptr); | 1892 } while ((span = span->fNext) != nullptr); |
1854 #endif | 1893 #endif |
1855 } | 1894 } |
1856 | 1895 |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2068 } | 2107 } |
2069 SkTSpan<OppCurve, TCurve>* largest2 = sect2->boundsMax(); | 2108 SkTSpan<OppCurve, TCurve>* largest2 = sect2->boundsMax(); |
2070 // split it | 2109 // split it |
2071 if (!largest2 || (largest1 && (largest1->fBoundsMax > largest2->fBoundsM
ax | 2110 if (!largest2 || (largest1 && (largest1->fBoundsMax > largest2->fBoundsM
ax |
2072 || (!largest1->fCollapsed && largest2->fCollapsed)))) { | 2111 || (!largest1->fCollapsed && largest2->fCollapsed)))) { |
2073 if (largest1->fCollapsed) { | 2112 if (largest1->fCollapsed) { |
2074 break; | 2113 break; |
2075 } | 2114 } |
2076 // trim parts that don't intersect the opposite | 2115 // trim parts that don't intersect the opposite |
2077 SkTSpan<TCurve, OppCurve>* half1 = sect1->addOne(); | 2116 SkTSpan<TCurve, OppCurve>* half1 = sect1->addOne(); |
| 2117 SkDEBUGCODE(half1->debugSetGlobalState(sect1->globalState())); |
2078 if (!half1->split(largest1, §1->fHeap)) { | 2118 if (!half1->split(largest1, §1->fHeap)) { |
2079 break; | 2119 break; |
2080 } | 2120 } |
2081 sect1->trim(largest1, sect2); | 2121 sect1->trim(largest1, sect2); |
2082 sect1->trim(half1, sect2); | 2122 sect1->trim(half1, sect2); |
2083 } else { | 2123 } else { |
2084 if (largest2->fCollapsed) { | 2124 if (largest2->fCollapsed) { |
2085 break; | 2125 break; |
2086 } | 2126 } |
2087 // trim parts that don't intersect the opposite | 2127 // trim parts that don't intersect the opposite |
2088 SkTSpan<OppCurve, TCurve>* half2 = sect2->addOne(); | 2128 SkTSpan<OppCurve, TCurve>* half2 = sect2->addOne(); |
| 2129 SkDEBUGCODE(half2->debugSetGlobalState(sect2->globalState())); |
2089 if (!half2->split(largest2, §2->fHeap)) { | 2130 if (!half2->split(largest2, §2->fHeap)) { |
2090 break; | 2131 break; |
2091 } | 2132 } |
2092 sect2->trim(largest2, sect1); | 2133 sect2->trim(largest2, sect1); |
2093 sect2->trim(half2, sect1); | 2134 sect2->trim(half2, sect1); |
2094 } | 2135 } |
2095 sect1->validate(); | 2136 sect1->validate(); |
2096 sect2->validate(); | 2137 sect2->validate(); |
2097 #if DEBUG_T_SECT_LOOP_COUNT | 2138 #if DEBUG_T_SECT_LOOP_COUNT |
2098 intersections->debugBumpLoopCount(SkIntersections::kIterations_DebugLoop
); | 2139 intersections->debugBumpLoopCount(SkIntersections::kIterations_DebugLoop
); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2254 --last; | 2295 --last; |
2255 } else { | 2296 } else { |
2256 intersections->setCoincident(index++); | 2297 intersections->setCoincident(index++); |
2257 } | 2298 } |
2258 intersections->setCoincident(index); | 2299 intersections->setCoincident(index); |
2259 } | 2300 } |
2260 SkASSERT(intersections->used() <= TCurve::kMaxIntersections); | 2301 SkASSERT(intersections->used() <= TCurve::kMaxIntersections); |
2261 } | 2302 } |
2262 | 2303 |
2263 #endif | 2304 #endif |
OLD | NEW |