Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: src/pathops/SkPathOpsTSect.h

Issue 2224823004: template intersection fuzz fixes (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix for 633608 Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pathops/SkPathOpsOp.cpp ('k') | tests/PathOpsOpTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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, &sect1->fHeap)) { 2118 if (!half1->split(largest1, &sect1->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, &sect2->fHeap)) { 2130 if (!half2->split(largest2, &sect2->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
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
OLDNEW
« no previous file with comments | « src/pathops/SkPathOpsOp.cpp ('k') | tests/PathOpsOpTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698