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

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

Issue 2356363003: fix tiger b (Closed)
Patch Set: reset debug flags Created 4 years, 2 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/SkPathOpsDebug.cpp ('k') | tests/PathOpsConicQuadIntersectionTest.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 13 matching lines...) Expand all
24 class SkTCoincident { 24 class SkTCoincident {
25 public: 25 public:
26 SkTCoincident() { 26 SkTCoincident() {
27 this->init(); 27 this->init();
28 } 28 }
29 29
30 void debugInit() { 30 void debugInit() {
31 #ifdef SK_DEBUG 31 #ifdef SK_DEBUG
32 this->fPerpPt.fX = this->fPerpPt.fY = SK_ScalarNaN; 32 this->fPerpPt.fX = this->fPerpPt.fY = SK_ScalarNaN;
33 this->fPerpT = SK_ScalarNaN; 33 this->fPerpT = SK_ScalarNaN;
34 this->fCoincident = 0xFF; 34 this->fMatch = 0xFF;
35 #endif 35 #endif
36 } 36 }
37 37
38 char dumpIsCoincidentStr() const; 38 char dumpIsCoincidentStr() const;
39 void dump() const; 39 void dump() const;
40 40
41 bool isCoincident() const { 41 bool isMatch() const {
42 SkASSERT(!!fCoincident == fCoincident); 42 SkASSERT(!!fMatch == fMatch);
43 return SkToBool(fCoincident); 43 return SkToBool(fMatch);
44 } 44 }
45 45
46 void init() { 46 void init() {
47 fPerpT = -1; 47 fPerpT = -1;
48 fCoincident = false; 48 fMatch = false;
49 fPerpPt.fX = fPerpPt.fY = SK_ScalarNaN; 49 fPerpPt.fX = fPerpPt.fY = SK_ScalarNaN;
50 } 50 }
51 51
52 void markCoincident() { 52 void markCoincident() {
53 if (!fCoincident) { 53 if (!fMatch) {
54 fPerpT = -1; 54 fPerpT = -1;
55 } 55 }
56 fCoincident = true; 56 fMatch = true;
57 } 57 }
58 58
59 const SkDPoint& perpPt() const { 59 const SkDPoint& perpPt() const {
60 return fPerpPt; 60 return fPerpPt;
61 } 61 }
62 62
63 double perpT() const { 63 double perpT() const {
64 return fPerpT; 64 return fPerpT;
65 } 65 }
66 66
67 void setPerp(const TCurve& c1, double t, const SkDPoint& cPt, const OppCurve & ); 67 void setPerp(const TCurve& c1, double t, const SkDPoint& cPt, const OppCurve & );
68 68
69 private: 69 private:
70 SkDPoint fPerpPt; 70 SkDPoint fPerpPt;
71 double fPerpT; // perpendicular intersection on opposite curve 71 double fPerpT; // perpendicular intersection on opposite curve
72 SkOpDebugBool fCoincident; 72 SkOpDebugBool fMatch;
73 }; 73 };
74 74
75 template<typename TCurve, typename OppCurve> class SkTSect; 75 template<typename TCurve, typename OppCurve> class SkTSect;
76 template<typename TCurve, typename OppCurve> class SkTSpan; 76 template<typename TCurve, typename OppCurve> class SkTSpan;
77 77
78 template<typename TCurve, typename OppCurve> 78 template<typename TCurve, typename OppCurve>
79 struct SkTSpanBounded { 79 struct SkTSpanBounded {
80 SkTSpan<TCurve, OppCurve>* fBounded; 80 SkTSpan<TCurve, OppCurve>* fBounded;
81 SkTSpanBounded* fNext; 81 SkTSpanBounded* fNext;
82 }; 82 };
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 SkTSpan<OppCurve, TCurve>* oppFirst); 323 SkTSpan<OppCurve, TCurve>* oppFirst);
324 void validate() const; 324 void validate() const;
325 void validateBounded() const; 325 void validateBounded() const;
326 326
327 const TCurve& fCurve; 327 const TCurve& fCurve;
328 SkChunkAlloc fHeap; 328 SkChunkAlloc fHeap;
329 SkTSpan<TCurve, OppCurve>* fHead; 329 SkTSpan<TCurve, OppCurve>* fHead;
330 SkTSpan<TCurve, OppCurve>* fCoincident; 330 SkTSpan<TCurve, OppCurve>* fCoincident;
331 SkTSpan<TCurve, OppCurve>* fDeleted; 331 SkTSpan<TCurve, OppCurve>* fDeleted;
332 int fActiveCount; 332 int fActiveCount;
333 bool fRemovedStartT;
334 bool fRemovedEndT;
333 SkDEBUGCODE(SkOpGlobalState* fDebugGlobalState); 335 SkDEBUGCODE(SkOpGlobalState* fDebugGlobalState);
334 SkDEBUGCODE(SkTSect<OppCurve, TCurve>* fOppSect); 336 SkDEBUGCODE(SkTSect<OppCurve, TCurve>* fOppSect);
335 PATH_OPS_DEBUG_T_SECT_CODE(int fID); 337 PATH_OPS_DEBUG_T_SECT_CODE(int fID);
336 PATH_OPS_DEBUG_T_SECT_CODE(int fDebugCount); 338 PATH_OPS_DEBUG_T_SECT_CODE(int fDebugCount);
337 #if DEBUG_T_SECT 339 #if DEBUG_T_SECT
338 int fDebugAllocatedCount; 340 int fDebugAllocatedCount;
339 #endif 341 #endif
340 friend class SkTSpan<TCurve, OppCurve>; 342 friend class SkTSpan<TCurve, OppCurve>;
341 friend class SkTSpan<OppCurve, TCurve>; 343 friend class SkTSpan<OppCurve, TCurve>;
342 friend class SkTSect<OppCurve, TCurve>; 344 friend class SkTSect<OppCurve, TCurve>;
(...skipping 22 matching lines...) Expand all
365 if (dist2Sq < distSq) { 367 if (dist2Sq < distSq) {
366 fPerpT = i[0][1]; 368 fPerpT = i[0][1];
367 fPerpPt = i.pt(1); 369 fPerpPt = i.pt(1);
368 } 370 }
369 } 371 }
370 #if DEBUG_T_SECT 372 #if DEBUG_T_SECT
371 SkDebugf("setPerp t=%1.9g cPt=(%1.9g,%1.9g) %s oppT=%1.9g fPerpPt=(%1.9g,%1. 9g)\n", 373 SkDebugf("setPerp t=%1.9g cPt=(%1.9g,%1.9g) %s oppT=%1.9g fPerpPt=(%1.9g,%1. 9g)\n",
372 t, cPt.fX, cPt.fY, 374 t, cPt.fX, cPt.fY,
373 cPt.approximatelyEqual(fPerpPt) ? "==" : "!=", fPerpT, fPerpPt.fX, f PerpPt.fY); 375 cPt.approximatelyEqual(fPerpPt) ? "==" : "!=", fPerpT, fPerpPt.fX, f PerpPt.fY);
374 #endif 376 #endif
375 fCoincident = cPt.approximatelyEqual(fPerpPt); 377 fMatch = cPt.approximatelyEqual(fPerpPt);
376 #if DEBUG_T_SECT 378 #if DEBUG_T_SECT
377 if (fCoincident) { 379 if (fMatch) {
378 SkDebugf(""); // allow setting breakpoint 380 SkDebugf(""); // allow setting breakpoint
379 } 381 }
380 #endif 382 #endif
381 } 383 }
382 384
383 template<typename TCurve, typename OppCurve> 385 template<typename TCurve, typename OppCurve>
384 void SkTSpan<TCurve, OppCurve>::addBounded(SkTSpan<OppCurve, TCurve>* span, SkCh unkAlloc* heap) { 386 void SkTSpan<TCurve, OppCurve>::addBounded(SkTSpan<OppCurve, TCurve>* span, SkCh unkAlloc* heap) {
385 SkTSpanBounded<OppCurve, TCurve>* bounded = new (heap->allocThrow( 387 SkTSpanBounded<OppCurve, TCurve>* bounded = new (heap->allocThrow(
386 sizeof(SkTSpanBounded<OppCurve, TCurve>)))(SkTSpanBounded<OppCurve, TCurve>); 388 sizeof(SkTSpanBounded<OppCurve, TCurve>)))(SkTSpanBounded<OppCurve, TCurve>);
387 bounded->fBounded = span; 389 bounded->fBounded = span;
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 this->validateBounded(); 796 this->validateBounded();
795 #endif 797 #endif
796 #if DEBUG_T_SECT 798 #if DEBUG_T_SECT
797 SkASSERT(fBounds.width() || fBounds.height() || fCollapsed); 799 SkASSERT(fBounds.width() || fBounds.height() || fCollapsed);
798 SkASSERT(fBoundsMax == SkTMax(fBounds.width(), fBounds.height()) || fCollaps ed == 0xFF); 800 SkASSERT(fBoundsMax == SkTMax(fBounds.width(), fBounds.height()) || fCollaps ed == 0xFF);
799 SkASSERT(0 <= fStartT); 801 SkASSERT(0 <= fStartT);
800 SkASSERT(fEndT <= 1); 802 SkASSERT(fEndT <= 1);
801 SkASSERT(fStartT <= fEndT); 803 SkASSERT(fStartT <= fEndT);
802 SkASSERT(fBounded || fCollapsed == 0xFF); 804 SkASSERT(fBounded || fCollapsed == 0xFF);
803 if (fHasPerp) { 805 if (fHasPerp) {
804 if (fCoinStart.isCoincident()) { 806 if (fCoinStart.isMatch()) {
805 validatePerpT(fCoinStart.perpT()); 807 validatePerpT(fCoinStart.perpT());
806 validatePerpPt(fCoinStart.perpT(), fCoinStart.perpPt()); 808 validatePerpPt(fCoinStart.perpT(), fCoinStart.perpPt());
807 } 809 }
808 if (fCoinEnd.isCoincident()) { 810 if (fCoinEnd.isMatch()) {
809 validatePerpT(fCoinEnd.perpT()); 811 validatePerpT(fCoinEnd.perpT());
810 validatePerpPt(fCoinEnd.perpT(), fCoinEnd.perpPt()); 812 validatePerpPt(fCoinEnd.perpT(), fCoinEnd.perpPt());
811 } 813 }
812 } 814 }
813 #endif 815 #endif
814 } 816 }
815 817
816 template<typename TCurve, typename OppCurve> 818 template<typename TCurve, typename OppCurve>
817 void SkTSpan<TCurve, OppCurve>::validateBounded() const { 819 void SkTSpan<TCurve, OppCurve>::validateBounded() const {
818 #if DEBUG_VALIDATE 820 #if DEBUG_VALIDATE
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 } 921 }
920 work.initBounds(fCurve); 922 work.initBounds(fCurve);
921 if (work.fCollapsed) { 923 if (work.fCollapsed) {
922 return false; 924 return false;
923 } 925 }
924 if (last.approximatelyEqual(work.fPart[0])) { 926 if (last.approximatelyEqual(work.fPart[0])) {
925 break; 927 break;
926 } 928 }
927 last = work.fPart[0]; 929 last = work.fPart[0];
928 work.fCoinStart.setPerp(fCurve, work.fStartT, last, opp); 930 work.fCoinStart.setPerp(fCurve, work.fStartT, last, opp);
929 if (work.fCoinStart.isCoincident()) { 931 if (work.fCoinStart.isMatch()) {
930 #if DEBUG_T_SECT 932 #if DEBUG_T_SECT
931 work.validatePerpPt(work.fCoinStart.perpT(), work.fCoinStart.perpPt( )); 933 work.validatePerpPt(work.fCoinStart.perpT(), work.fCoinStart.perpPt( ));
932 #endif 934 #endif
933 double oppTTest = work.fCoinStart.perpT(); 935 double oppTTest = work.fCoinStart.perpT();
934 if (sect2->fHead->contains(oppTTest)) { 936 if (sect2->fHead->contains(oppTTest)) {
935 *oppT = oppTTest; 937 *oppT = oppTTest;
936 oppPt = work.fCoinStart.perpPt(); 938 oppPt = work.fCoinStart.perpPt();
937 contained = true; 939 contained = true;
938 SkASSERT(down ? result > work.fStartT : result < work.fStartT); 940 SkASSERT(down ? result > work.fStartT : result < work.fStartT);
939 result = work.fStartT; 941 result = work.fStartT;
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1076 const OppCurve& opp = sect2->fCurve; 1078 const OppCurve& opp = sect2->fCurve;
1077 SkTSpan<TCurve, OppCurve>* work = first; 1079 SkTSpan<TCurve, OppCurve>* work = first;
1078 SkTSpan<TCurve, OppCurve>* prior = nullptr; 1080 SkTSpan<TCurve, OppCurve>* prior = nullptr;
1079 do { 1081 do {
1080 if (!work->fHasPerp && !work->fCollapsed) { 1082 if (!work->fHasPerp && !work->fCollapsed) {
1081 if (prior) { 1083 if (prior) {
1082 work->fCoinStart = prior->fCoinEnd; 1084 work->fCoinStart = prior->fCoinEnd;
1083 } else { 1085 } else {
1084 work->fCoinStart.setPerp(fCurve, work->fStartT, work->fPart[0], opp); 1086 work->fCoinStart.setPerp(fCurve, work->fStartT, work->fPart[0], opp);
1085 } 1087 }
1086 if (work->fCoinStart.isCoincident()) { 1088 if (work->fCoinStart.isMatch()) {
1087 double perpT = work->fCoinStart.perpT(); 1089 double perpT = work->fCoinStart.perpT();
1088 if (sect2->coincidentHasT(perpT)) { 1090 if (sect2->coincidentHasT(perpT)) {
1089 work->fCoinStart.init(); 1091 work->fCoinStart.init();
1090 } else { 1092 } else {
1091 sect2->addForPerp(work, perpT); 1093 sect2->addForPerp(work, perpT);
1092 } 1094 }
1093 } 1095 }
1094 work->fCoinEnd.setPerp(fCurve, work->fEndT, work->fPart[TCurve::kPoi ntLast], opp); 1096 work->fCoinEnd.setPerp(fCurve, work->fEndT, work->fPart[TCurve::kPoi ntLast], opp);
1095 if (work->fCoinEnd.isCoincident()) { 1097 if (work->fCoinEnd.isMatch()) {
1096 double perpT = work->fCoinEnd.perpT(); 1098 double perpT = work->fCoinEnd.perpT();
1097 if (sect2->coincidentHasT(perpT)) { 1099 if (sect2->coincidentHasT(perpT)) {
1098 work->fCoinEnd.init(); 1100 work->fCoinEnd.init();
1099 } else { 1101 } else {
1100 sect2->addForPerp(work, perpT); 1102 sect2->addForPerp(work, perpT);
1101 } 1103 }
1102 } 1104 }
1103 work->fHasPerp = true; 1105 work->fHasPerp = true;
1104 } 1106 }
1105 if (work == last) { 1107 if (work == last) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 first = findCoincidentRun(first, &last); 1170 first = findCoincidentRun(first, &last);
1169 if (!first || !last) { 1171 if (!first || !last) {
1170 *result = nullptr; 1172 *result = nullptr;
1171 return true; 1173 return true;
1172 } 1174 }
1173 // march outwards to find limit of coincidence from here to previous and nex t spans 1175 // march outwards to find limit of coincidence from here to previous and nex t spans
1174 double startT = first->fStartT; 1176 double startT = first->fStartT;
1175 double oppStartT SK_INIT_TO_AVOID_WARNING; 1177 double oppStartT SK_INIT_TO_AVOID_WARNING;
1176 double oppEndT SK_INIT_TO_AVOID_WARNING; 1178 double oppEndT SK_INIT_TO_AVOID_WARNING;
1177 SkTSpan<TCurve, OppCurve>* prev = first->fPrev; 1179 SkTSpan<TCurve, OppCurve>* prev = first->fPrev;
1178 SkASSERT(first->fCoinStart.isCoincident()); 1180 SkASSERT(first->fCoinStart.isMatch());
1179 SkTSpan<OppCurve, TCurve>* oppFirst = first->findOppT(first->fCoinStart.perp T()); 1181 SkTSpan<OppCurve, TCurve>* oppFirst = first->findOppT(first->fCoinStart.perp T());
1180 SkOPASSERT(last->fCoinEnd.isCoincident()); 1182 SkOPASSERT(last->fCoinEnd.isMatch());
1181 bool oppMatched = first->fCoinStart.perpT() < first->fCoinEnd.perpT(); 1183 bool oppMatched = first->fCoinStart.perpT() < first->fCoinEnd.perpT();
1182 double coinStart; 1184 double coinStart;
1183 SkDEBUGCODE(double coinEnd); 1185 SkDEBUGCODE(double coinEnd);
1184 SkTSpan<OppCurve, TCurve>* cutFirst; 1186 SkTSpan<OppCurve, TCurve>* cutFirst;
1185 if (prev && prev->fEndT == startT 1187 if (prev && prev->fEndT == startT
1186 && this->binarySearchCoin(sect2, startT, prev->fStartT - startT, &co inStart, 1188 && this->binarySearchCoin(sect2, startT, prev->fStartT - startT, &co inStart,
1187 &oppStartT) 1189 &oppStartT)
1188 && prev->fStartT < coinStart && coinStart < startT 1190 && prev->fStartT < coinStart && coinStart < startT
1189 && (cutFirst = prev->oppT(oppStartT))) { 1191 && (cutFirst = prev->oppT(oppStartT))) {
1190 oppFirst = cutFirst; 1192 oppFirst = cutFirst;
(...skipping 10 matching lines...) Expand all
1201 oppFirst->markCoincident(); 1203 oppFirst->markCoincident();
1202 oppHalf->fCoinStart.markCoincident(); 1204 oppHalf->fCoinStart.markCoincident();
1203 } 1205 }
1204 } 1206 }
1205 } else { 1207 } else {
1206 SkDEBUGCODE(coinStart = first->fStartT); 1208 SkDEBUGCODE(coinStart = first->fStartT);
1207 SkDEBUGCODE(oppStartT = oppMatched ? oppFirst->fStartT : oppFirst->fEndT ); 1209 SkDEBUGCODE(oppStartT = oppMatched ? oppFirst->fStartT : oppFirst->fEndT );
1208 } 1210 }
1209 // FIXME: incomplete : if we're not at the end, find end of coin 1211 // FIXME: incomplete : if we're not at the end, find end of coin
1210 SkTSpan<OppCurve, TCurve>* oppLast; 1212 SkTSpan<OppCurve, TCurve>* oppLast;
1211 SkOPASSERT(last->fCoinEnd.isCoincident()); 1213 SkOPASSERT(last->fCoinEnd.isMatch());
1212 oppLast = last->findOppT(last->fCoinEnd.perpT()); 1214 oppLast = last->findOppT(last->fCoinEnd.perpT());
1213 SkDEBUGCODE(coinEnd = last->fEndT); 1215 SkDEBUGCODE(coinEnd = last->fEndT);
1214 #ifdef SK_DEBUG 1216 #ifdef SK_DEBUG
1215 if (!this->globalState() || !this->globalState()->debugSkipAssert()) { 1217 if (!this->globalState() || !this->globalState()->debugSkipAssert()) {
1216 oppEndT = oppMatched ? oppLast->fEndT : oppLast->fStartT; 1218 oppEndT = oppMatched ? oppLast->fEndT : oppLast->fStartT;
1217 } 1219 }
1218 #endif 1220 #endif
1219 if (!oppMatched) { 1221 if (!oppMatched) {
1220 SkTSwap(oppFirst, oppLast); 1222 SkTSwap(oppFirst, oppLast);
1221 SkTSwap(oppStartT, oppEndT); 1223 SkTSwap(oppStartT, oppEndT);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 } 1274 }
1273 1275
1274 template<typename TCurve, typename OppCurve> 1276 template<typename TCurve, typename OppCurve>
1275 SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::findCoincidentRun( 1277 SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::findCoincidentRun(
1276 SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCurve>** lastPtr) { 1278 SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCurve>** lastPtr) {
1277 SkTSpan<TCurve, OppCurve>* work = first; 1279 SkTSpan<TCurve, OppCurve>* work = first;
1278 SkTSpan<TCurve, OppCurve>* lastCandidate = nullptr; 1280 SkTSpan<TCurve, OppCurve>* lastCandidate = nullptr;
1279 first = nullptr; 1281 first = nullptr;
1280 // find the first fully coincident span 1282 // find the first fully coincident span
1281 do { 1283 do {
1282 if (work->fCoinStart.isCoincident()) { 1284 if (work->fCoinStart.isMatch()) {
1283 #if DEBUG_T_SECT 1285 #if DEBUG_T_SECT
1284 work->validatePerpT(work->fCoinStart.perpT()); 1286 work->validatePerpT(work->fCoinStart.perpT());
1285 work->validatePerpPt(work->fCoinStart.perpT(), work->fCoinStart.perp Pt()); 1287 work->validatePerpPt(work->fCoinStart.perpT(), work->fCoinStart.perp Pt());
1286 #endif 1288 #endif
1287 SkASSERT(work->hasOppT(work->fCoinStart.perpT())); 1289 SkASSERT(work->hasOppT(work->fCoinStart.perpT()));
1288 if (!work->fCoinEnd.isCoincident()) { 1290 if (!work->fCoinEnd.isMatch()) {
1289 break; 1291 break;
1290 } 1292 }
1291 lastCandidate = work; 1293 lastCandidate = work;
1292 if (!first) { 1294 if (!first) {
1293 first = work; 1295 first = work;
1294 } 1296 }
1295 } else if (first && work->fCollapsed) { 1297 } else if (first && work->fCollapsed) {
1296 *lastPtr = lastCandidate; 1298 *lastPtr = lastCandidate;
1297 return first; 1299 return first;
1298 } else { 1300 } else {
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
1525 SkDPoint workPt; 1527 SkDPoint workPt;
1526 do { 1528 do {
1527 tStep *= 0.5; 1529 tStep *= 0.5;
1528 if (precisely_zero(tStep)) { 1530 if (precisely_zero(tStep)) {
1529 return 0; 1531 return 0;
1530 } 1532 }
1531 workT += tStep; 1533 workT += tStep;
1532 workPt = fCurve.ptAtT(workT); 1534 workPt = fCurve.ptAtT(workT);
1533 coinW.setPerp(fCurve, workT, workPt, opp->fCurve); 1535 coinW.setPerp(fCurve, workT, workPt, opp->fCurve);
1534 double perpT = coinW.perpT(); 1536 double perpT = coinW.perpT();
1535 if (coinW.isCoincident() ? !between(oppSpan->fStartT, perpT, oppSpan->fE ndT) : perpT < 0) { 1537 if (coinW.isMatch() ? !between(oppSpan->fStartT, perpT, oppSpan->fEndT) : perpT < 0) {
1536 continue; 1538 continue;
1537 } 1539 }
1538 SkDVector perpW = workPt - coinW.perpPt(); 1540 SkDVector perpW = workPt - coinW.perpPt();
1539 if ((perpS.dot(perpW) >= 0) == (tStep < 0)) { 1541 if ((perpS.dot(perpW) >= 0) == (tStep < 0)) {
1540 tStep = -tStep; 1542 tStep = -tStep;
1541 } 1543 }
1542 if (workPt.approximatelyEqual(coinW.perpPt())) { 1544 if (workPt.approximatelyEqual(coinW.perpPt())) {
1543 break; 1545 break;
1544 } 1546 }
1545 } while (true); 1547 } while (true);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1621 larger = test; 1623 larger = test;
1622 } while ((prior = test), (test = test->fNext)); 1624 } while ((prior = test), (test = test->fNext));
1623 if (!larger) { 1625 if (!larger) {
1624 continue; 1626 continue;
1625 } 1627 }
1626 // check middle t value to see if it is coincident as well 1628 // check middle t value to see if it is coincident as well
1627 double midT = (smaller->fEndT + larger->fStartT) / 2; 1629 double midT = (smaller->fEndT + larger->fStartT) / 2;
1628 SkDPoint midPt = fCurve.ptAtT(midT); 1630 SkDPoint midPt = fCurve.ptAtT(midT);
1629 SkTCoincident<TCurve, OppCurve> coin; 1631 SkTCoincident<TCurve, OppCurve> coin;
1630 coin.setPerp(fCurve, midT, midPt, sect2->fCurve); 1632 coin.setPerp(fCurve, midT, midPt, sect2->fCurve);
1631 if (coin.isCoincident()) { 1633 if (coin.isMatch()) {
1632 smaller->fEndT = larger->fEndT; 1634 smaller->fEndT = larger->fEndT;
1633 smaller->fCoinEnd = larger->fCoinEnd; 1635 smaller->fCoinEnd = larger->fCoinEnd;
1634 if (largerPrior) { 1636 if (largerPrior) {
1635 largerPrior->fNext = larger->fNext; 1637 largerPrior->fNext = larger->fNext;
1636 largerPrior->validate(); 1638 largerPrior->validate();
1637 } else { 1639 } else {
1638 fCoincident = larger->fNext; 1640 fCoincident = larger->fNext;
1639 } 1641 }
1640 } 1642 }
1641 } while (true); 1643 } while (true);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1721 --fActiveCount; 1723 --fActiveCount;
1722 span->fNext = fCoincident; 1724 span->fNext = fCoincident;
1723 fCoincident = span; 1725 fCoincident = span;
1724 } else { 1726 } else {
1725 this->markSpanGone(span); 1727 this->markSpanGone(span);
1726 } 1728 }
1727 } 1729 }
1728 1730
1729 template<typename TCurve, typename OppCurve> 1731 template<typename TCurve, typename OppCurve>
1730 bool SkTSect<TCurve, OppCurve>::removeSpan(SkTSpan<TCurve, OppCurve>* span) { 1732 bool SkTSect<TCurve, OppCurve>::removeSpan(SkTSpan<TCurve, OppCurve>* span) {
1733 if (!span->fStartT) {
1734 fRemovedStartT = true;
1735 }
1736 if (1 == span->fEndT) {
1737 fRemovedEndT = true;
1738 }
1731 this->unlinkSpan(span); 1739 this->unlinkSpan(span);
1732 return this->markSpanGone(span); 1740 return this->markSpanGone(span);
1733 } 1741 }
1734 1742
1735 template<typename TCurve, typename OppCurve> 1743 template<typename TCurve, typename OppCurve>
1736 void SkTSect<TCurve, OppCurve>::removeSpanRange(SkTSpan<TCurve, OppCurve>* first , 1744 void SkTSect<TCurve, OppCurve>::removeSpanRange(SkTSpan<TCurve, OppCurve>* first ,
1737 SkTSpan<TCurve, OppCurve>* last) { 1745 SkTSpan<TCurve, OppCurve>* last) {
1738 if (first == last) { 1746 if (first == last) {
1739 return; 1747 return;
1740 } 1748 }
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
2119 int coinLoopCount = kMaxCoinLoopCount; 2127 int coinLoopCount = kMaxCoinLoopCount;
2120 double start1s SK_INIT_TO_AVOID_WARNING; 2128 double start1s SK_INIT_TO_AVOID_WARNING;
2121 double start1e SK_INIT_TO_AVOID_WARNING; 2129 double start1e SK_INIT_TO_AVOID_WARNING;
2122 do { 2130 do {
2123 // find the largest bounds 2131 // find the largest bounds
2124 SkTSpan<TCurve, OppCurve>* largest1 = sect1->boundsMax(); 2132 SkTSpan<TCurve, OppCurve>* largest1 = sect1->boundsMax();
2125 if (!largest1) { 2133 if (!largest1) {
2126 break; 2134 break;
2127 } 2135 }
2128 SkTSpan<OppCurve, TCurve>* largest2 = sect2->boundsMax(); 2136 SkTSpan<OppCurve, TCurve>* largest2 = sect2->boundsMax();
2137 sect1->fRemovedStartT = sect1->fRemovedEndT = false;
2138 sect2->fRemovedStartT = sect2->fRemovedEndT = false;
2129 // split it 2139 // split it
2130 if (!largest2 || (largest1 && (largest1->fBoundsMax > largest2->fBoundsM ax 2140 if (!largest2 || (largest1 && (largest1->fBoundsMax > largest2->fBoundsM ax
2131 || (!largest1->fCollapsed && largest2->fCollapsed)))) { 2141 || (!largest1->fCollapsed && largest2->fCollapsed)))) {
2132 if (largest1->fCollapsed) { 2142 if (largest1->fCollapsed) {
2133 break; 2143 break;
2134 } 2144 }
2135 // trim parts that don't intersect the opposite 2145 // trim parts that don't intersect the opposite
2136 SkTSpan<TCurve, OppCurve>* half1 = sect1->addOne(); 2146 SkTSpan<TCurve, OppCurve>* half1 = sect1->addOne();
2137 SkDEBUGCODE(half1->debugSetGlobalState(sect1->globalState())); 2147 SkDEBUGCODE(half1->debugSetGlobalState(sect1->globalState()));
2138 if (!half1->split(largest1, &sect1->fHeap)) { 2148 if (!half1->split(largest1, &sect1->fHeap)) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2207 } while (true); 2217 } while (true);
2208 SkTSpan<TCurve, OppCurve>* coincident = sect1->fCoincident; 2218 SkTSpan<TCurve, OppCurve>* coincident = sect1->fCoincident;
2209 if (coincident) { 2219 if (coincident) {
2210 // if there is more than one coincident span, check loosely to see if th ey should be joined 2220 // if there is more than one coincident span, check loosely to see if th ey should be joined
2211 if (coincident->fNext) { 2221 if (coincident->fNext) {
2212 sect1->mergeCoincidence(sect2); 2222 sect1->mergeCoincidence(sect2);
2213 coincident = sect1->fCoincident; 2223 coincident = sect1->fCoincident;
2214 } 2224 }
2215 SkASSERT(sect2->fCoincident); // courtesy check : coincidence only look s at sect 1 2225 SkASSERT(sect2->fCoincident); // courtesy check : coincidence only look s at sect 1
2216 do { 2226 do {
2217 if (!coincident->fCoinStart.isCoincident()) { 2227 if (!coincident->fCoinStart.isMatch()) {
2218 continue; 2228 continue;
2219 } 2229 }
2220 if (!coincident->fCoinEnd.isCoincident()) { 2230 if (!coincident->fCoinEnd.isMatch()) {
2221 continue; 2231 continue;
2222 } 2232 }
2223 int index = intersections->insertCoincident(coincident->fStartT, 2233 int index = intersections->insertCoincident(coincident->fStartT,
2224 coincident->fCoinStart.perpT(), coincident->fPart[0]); 2234 coincident->fCoinStart.perpT(), coincident->fPart[0]);
2225 if ((intersections->insertCoincident(coincident->fEndT, 2235 if ((intersections->insertCoincident(coincident->fEndT,
2226 coincident->fCoinEnd.perpT(), 2236 coincident->fCoinEnd.perpT(),
2227 coincident->fPart[TCurve::kPointLast]) < 0) && index >= 0) { 2237 coincident->fPart[TCurve::kPointLast]) < 0) && index >= 0) {
2228 intersections->clearCoincidence(index); 2238 intersections->clearCoincidence(index);
2229 } 2239 }
2230 } while ((coincident = coincident->fNext)); 2240 } while ((coincident = coincident->fNext));
2231 } 2241 }
2232 int zeroOneSet = EndsEqual(sect1, sect2, intersections); 2242 int zeroOneSet = EndsEqual(sect1, sect2, intersections);
2233 if (!sect1->fHead || !sect2->fHead) { 2243 if (!sect1->fHead || !sect2->fHead) {
2244 // if the final iteration contains an end (0 or 1),
2245 if (sect1->fRemovedStartT && !(zeroOneSet & kZeroS1Set)) {
2246 SkTCoincident<TCurve, OppCurve> perp; // intersect perpendicular w ith opposite curve
2247 perp.setPerp(sect1->fCurve, 0, sect1->fCurve.fPts[0], sect2->fCurve) ;
2248 if (perp.isMatch()) {
2249 intersections->insert(0, perp.perpT(), perp.perpPt());
2250 }
2251 }
2252 if (sect1->fRemovedEndT && !(zeroOneSet & kOneS1Set)) {
2253 SkTCoincident<TCurve, OppCurve> perp;
2254 perp.setPerp(sect1->fCurve, 1, sect1->fCurve.fPts[TCurve::kPointLast ], sect2->fCurve);
2255 if (perp.isMatch()) {
2256 intersections->insert(1, perp.perpT(), perp.perpPt());
2257 }
2258 }
2259 if (sect2->fRemovedStartT && !(zeroOneSet & kZeroS2Set)) {
2260 SkTCoincident<OppCurve, TCurve> perp;
2261 perp.setPerp(sect2->fCurve, 0, sect2->fCurve.fPts[0], sect1->fCurve) ;
2262 if (perp.isMatch()) {
2263 intersections->insert(perp.perpT(), 0, perp.perpPt());
2264 }
2265 }
2266 if (sect2->fRemovedEndT && !(zeroOneSet & kOneS2Set)) {
2267 SkTCoincident<OppCurve, TCurve> perp;
2268 perp.setPerp(sect2->fCurve, 1, sect2->fCurve.fPts[OppCurve::kPointLa st], sect1->fCurve);
2269 if (perp.isMatch()) {
2270 intersections->insert(perp.perpT(), 1, perp.perpPt());
2271 }
2272 }
2234 return; 2273 return;
2235 } 2274 }
2236 sect1->recoverCollapsed(); 2275 sect1->recoverCollapsed();
2237 sect2->recoverCollapsed(); 2276 sect2->recoverCollapsed();
2238 SkTSpan<TCurve, OppCurve>* result1 = sect1->fHead; 2277 SkTSpan<TCurve, OppCurve>* result1 = sect1->fHead;
2239 // check heads and tails for zero and ones and insert them if we haven't alr eady done so 2278 // check heads and tails for zero and ones and insert them if we haven't alr eady done so
2240 const SkTSpan<TCurve, OppCurve>* head1 = result1; 2279 const SkTSpan<TCurve, OppCurve>* head1 = result1;
2241 if (!(zeroOneSet & kZeroS1Set) && approximately_less_than_zero(head1->fStart T)) { 2280 if (!(zeroOneSet & kZeroS1Set) && approximately_less_than_zero(head1->fStart T)) {
2242 const SkDPoint& start1 = sect1->fCurve[0]; 2281 const SkDPoint& start1 = sect1->fCurve[0];
2243 if (head1->isBounded()) { 2282 if (head1->isBounded()) {
(...skipping 28 matching lines...) Expand all
2272 const SkDPoint& end2 = sect2->fCurve[OppCurve::kPointLast]; 2311 const SkDPoint& end2 = sect2->fCurve[OppCurve::kPointLast];
2273 if (tail2->isBounded()) { 2312 if (tail2->isBounded()) {
2274 double t = tail2->closestBoundedT(end2); 2313 double t = tail2->closestBoundedT(end2);
2275 if (sect1->fCurve.ptAtT(t).approximatelyEqual(end2)) { 2314 if (sect1->fCurve.ptAtT(t).approximatelyEqual(end2)) {
2276 intersections->insert(t, 1, end2); 2315 intersections->insert(t, 1, end2);
2277 } 2316 }
2278 } 2317 }
2279 } 2318 }
2280 SkClosestSect<TCurve, OppCurve> closest; 2319 SkClosestSect<TCurve, OppCurve> closest;
2281 do { 2320 do {
2282 while (result1 && result1->fCoinStart.isCoincident() && result1->fCoinEn d.isCoincident()) { 2321 while (result1 && result1->fCoinStart.isMatch() && result1->fCoinEnd.isM atch()) {
2283 result1 = result1->fNext; 2322 result1 = result1->fNext;
2284 } 2323 }
2285 if (!result1) { 2324 if (!result1) {
2286 break; 2325 break;
2287 } 2326 }
2288 SkTSpan<OppCurve, TCurve>* result2 = sect2->fHead; 2327 SkTSpan<OppCurve, TCurve>* result2 = sect2->fHead;
2289 bool found = false; 2328 bool found = false;
2290 while (result2) { 2329 while (result2) {
2291 found |= closest.find(result1, result2 SkDEBUGPARAMS(intersections) ); 2330 found |= closest.find(result1, result2 SkDEBUGPARAMS(intersections) );
2292 result2 = result2->fNext; 2331 result2 = result2->fNext;
2293 } 2332 }
2294 } while ((result1 = result1->fNext)); 2333 } while ((result1 = result1->fNext));
2295 closest.finish(intersections); 2334 closest.finish(intersections);
2296 // if there is more than one intersection and it isn't already coincident, c heck 2335 // if there is more than one intersection and it isn't already coincident, c heck
2297 int last = intersections->used() - 1; 2336 int last = intersections->used() - 1;
2298 for (int index = 0; index < last; ) { 2337 for (int index = 0; index < last; ) {
2299 if (intersections->isCoincident(index) && intersections->isCoincident(in dex + 1)) { 2338 if (intersections->isCoincident(index) && intersections->isCoincident(in dex + 1)) {
2300 ++index; 2339 ++index;
2301 continue; 2340 continue;
2302 } 2341 }
2303 double midT = ((*intersections)[0][index] + (*intersections)[0][index + 1]) / 2; 2342 double midT = ((*intersections)[0][index] + (*intersections)[0][index + 1]) / 2;
2304 SkDPoint midPt = sect1->fCurve.ptAtT(midT); 2343 SkDPoint midPt = sect1->fCurve.ptAtT(midT);
2305 // intersect perpendicular with opposite curve 2344 // intersect perpendicular with opposite curve
2306 SkTCoincident<TCurve, OppCurve> perp; 2345 SkTCoincident<TCurve, OppCurve> perp;
2307 perp.setPerp(sect1->fCurve, midT, midPt, sect2->fCurve); 2346 perp.setPerp(sect1->fCurve, midT, midPt, sect2->fCurve);
2308 if (!perp.isCoincident()) { 2347 if (!perp.isMatch()) {
2309 ++index; 2348 ++index;
2310 continue; 2349 continue;
2311 } 2350 }
2312 if (intersections->isCoincident(index)) { 2351 if (intersections->isCoincident(index)) {
2313 intersections->removeOne(index); 2352 intersections->removeOne(index);
2314 --last; 2353 --last;
2315 } else if (intersections->isCoincident(index + 1)) { 2354 } else if (intersections->isCoincident(index + 1)) {
2316 intersections->removeOne(index + 1); 2355 intersections->removeOne(index + 1);
2317 --last; 2356 --last;
2318 } else { 2357 } else {
2319 intersections->setCoincident(index++); 2358 intersections->setCoincident(index++);
2320 } 2359 }
2321 intersections->setCoincident(index); 2360 intersections->setCoincident(index);
2322 } 2361 }
2323 SkASSERT(intersections->used() <= TCurve::kMaxIntersections); 2362 SkASSERT(intersections->used() <= TCurve::kMaxIntersections);
2324 } 2363 }
2325 2364
2326 #endif 2365 #endif
OLDNEW
« no previous file with comments | « src/pathops/SkPathOpsDebug.cpp ('k') | tests/PathOpsConicQuadIntersectionTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698