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

Side by Side Diff: src/pathops/SkOpCoincidence.cpp

Issue 2237223002: pathops coincident work (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: remove unused code Created 4 years, 3 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/SkOpCoincidence.h ('k') | src/pathops/SkOpContour.h » ('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 2015 Google Inc. 2 * Copyright 2015 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 #include "SkOpCoincidence.h" 7 #include "SkOpCoincidence.h"
8 #include "SkOpSegment.h" 8 #include "SkOpSegment.h"
9 #include "SkPathOpsTSect.h" 9 #include "SkPathOpsTSect.h"
10 10
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 return; 243 return;
244 } 244 }
245 SkASSERT(Ordered(coinPtTStart, oppPtTStart)); 245 SkASSERT(Ordered(coinPtTStart, oppPtTStart));
246 // choose the ptT at the front of the list to track 246 // choose the ptT at the front of the list to track
247 coinPtTStart = coinPtTStart->span()->ptT(); 247 coinPtTStart = coinPtTStart->span()->ptT();
248 coinPtTEnd = coinPtTEnd->span()->ptT(); 248 coinPtTEnd = coinPtTEnd->span()->ptT();
249 oppPtTStart = oppPtTStart->span()->ptT(); 249 oppPtTStart = oppPtTStart->span()->ptT();
250 oppPtTEnd = oppPtTEnd->span()->ptT(); 250 oppPtTEnd = oppPtTEnd->span()->ptT();
251 SkASSERT(coinPtTStart->fT < coinPtTEnd->fT); 251 SkASSERT(coinPtTStart->fT < coinPtTEnd->fT);
252 SkASSERT(oppPtTStart->fT != oppPtTEnd->fT); 252 SkASSERT(oppPtTStart->fT != oppPtTEnd->fT);
253 SkASSERT(!coinPtTStart->deleted()); 253 SkOPASSERT(!coinPtTStart->deleted());
254 SkASSERT(!coinPtTEnd->deleted()); 254 SkOPASSERT(!coinPtTEnd->deleted());
255 SkASSERT(!oppPtTStart->deleted()); 255 SkOPASSERT(!oppPtTStart->deleted());
256 SkASSERT(!oppPtTEnd->deleted()); 256 SkOPASSERT(!oppPtTEnd->deleted());
257 DebugCheckAdd(fHead, coinPtTStart, coinPtTEnd, oppPtTStart, oppPtTEnd); 257 DebugCheckAdd(fHead, coinPtTStart, coinPtTEnd, oppPtTStart, oppPtTEnd);
258 DebugCheckAdd(fTop, coinPtTStart, coinPtTEnd, oppPtTStart, oppPtTEnd); 258 DebugCheckAdd(fTop, coinPtTStart, coinPtTEnd, oppPtTStart, oppPtTEnd);
259 SkCoincidentSpans* coinRec = SkOpTAllocator<SkCoincidentSpans>::Allocate( 259 SkCoincidentSpans* coinRec = SkOpTAllocator<SkCoincidentSpans>::Allocate(
260 this->globalState()->allocator()); 260 this->globalState()->allocator());
261 coinRec->init(SkDEBUGCODE(fGlobalState)); 261 coinRec->init(SkDEBUGCODE(fGlobalState));
262 coinRec->set(this->fHead, coinPtTStart, coinPtTEnd, oppPtTStart, oppPtTEnd 262 coinRec->set(this->fHead, coinPtTStart, coinPtTEnd, oppPtTStart, oppPtTEnd
263 SkDEBUGPARAMS(fGlobalState->nextCoinID())); 263 SkDEBUGPARAMS(fGlobalState->nextCoinID()));
264 fHead = coinRec; 264 fHead = coinRec;
265 } 265 }
266 266
(...skipping 27 matching lines...) Expand all
294 if (!between(0, t, 1)) { 294 if (!between(0, t, 1)) {
295 continue; 295 continue;
296 } 296 }
297 SkDPoint oppPt = i.pt(index); 297 SkDPoint oppPt = i.pt(index);
298 if (!oppPt.approximatelyEqual(pt)) { 298 if (!oppPt.approximatelyEqual(pt)) {
299 continue; 299 continue;
300 } 300 }
301 SkOpSegment* writableSeg = const_cast<SkOpSegment*>(testSeg); 301 SkOpSegment* writableSeg = const_cast<SkOpSegment*>(testSeg);
302 SkOpPtT* oppStart = writableSeg->addT(t); 302 SkOpPtT* oppStart = writableSeg->addT(t);
303 SkOpSpan* writableBase = const_cast<SkOpSpan*>(base); 303 SkOpSpan* writableBase = const_cast<SkOpSpan*>(base);
304 oppStart->span()->addOppAndMerge(writableBase); 304 oppStart->span()->addOpp(writableBase);
305 if (oppStart->deleted()) { 305 if (oppStart->deleted()) {
306 continue; 306 continue;
307 } 307 }
308 SkOpSegment* coinSeg = base->segment(); 308 SkOpSegment* coinSeg = base->segment();
309 SkOpSegment* oppSeg = oppStart->segment(); 309 SkOpSegment* oppSeg = oppStart->segment();
310 double coinTs, coinTe, oppTs, oppTe; 310 double coinTs, coinTe, oppTs, oppTe;
311 if (coinSeg < oppSeg) { 311 if (coinSeg < oppSeg) {
312 coinTs = base->t(); 312 coinTs = base->t();
313 coinTe = testSpan->t(); 313 coinTe = testSpan->t();
314 oppTs = oppStart->fT; 314 oppTs = oppStart->fT;
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 SkASSERT(startPtT->contains(oStartPtT)); 419 SkASSERT(startPtT->contains(oStartPtT));
420 SkOPASSERT(coin->coinPtTEnd()->contains(coin->oppPtTEnd())); 420 SkOPASSERT(coin->coinPtTEnd()->contains(coin->oppPtTEnd()));
421 const SkOpSpanBase* start = startPtT->span(); 421 const SkOpSpanBase* start = startPtT->span();
422 const SkOpSpanBase* oStart = oStartPtT->span(); 422 const SkOpSpanBase* oStart = oStartPtT->span();
423 const SkOpSpanBase* end = coin->coinPtTEnd()->span(); 423 const SkOpSpanBase* end = coin->coinPtTEnd()->span();
424 const SkOpSpanBase* oEnd = coin->oppPtTEnd()->span(); 424 const SkOpSpanBase* oEnd = coin->oppPtTEnd()->span();
425 FAIL_IF(oEnd->deleted()); 425 FAIL_IF(oEnd->deleted());
426 FAIL_IF(!start->upCastable()); 426 FAIL_IF(!start->upCastable());
427 const SkOpSpanBase* test = start->upCast()->next(); 427 const SkOpSpanBase* test = start->upCast()->next();
428 const SkOpSpanBase* oTest = coin->flipped() ? oStart->prev() : oStart->u pCast()->next(); 428 const SkOpSpanBase* oTest = coin->flipped() ? oStart->prev() : oStart->u pCast()->next();
429 if (!oTest) { 429 FAIL_IF(!oTest);
430 return false;
431 }
432 while (test != end || oTest != oEnd) { 430 while (test != end || oTest != oEnd) {
433 if (!test->ptT()->contains(oStart->segment()) 431 if (!test->ptT()->contains(oStart->segment())
434 || !oTest->ptT()->contains(start->segment())) { 432 || !oTest->ptT()->contains(start->segment())) {
435 // use t ranges to guess which one is missing 433 // use t ranges to guess which one is missing
436 double startRange = coin->coinPtTEnd()->fT - startPtT->fT; 434 double startRange = coin->coinPtTEnd()->fT - startPtT->fT;
437 FAIL_IF(!startRange); 435 FAIL_IF(!startRange);
438 double startPart = (test->t() - startPtT->fT) / startRange; 436 double startPart = (test->t() - startPtT->fT) / startRange;
439 double oStartRange = coin->oppPtTEnd()->fT - oStartPtT->fT; 437 double oStartRange = coin->oppPtTEnd()->fT - oStartPtT->fT;
440 FAIL_IF(!oStartRange); 438 FAIL_IF(!oStartRange);
441 double oStartPart = (oTest->t() - oStartPtT->fT) / oStartRange; 439 double oStartPart = (oTest->t() - oStartPtT->fT) / oStartRange;
442 FAIL_IF(startPart == oStartPart); 440 FAIL_IF(startPart == oStartPart);
443 bool startOver = false; 441 bool startOver = false;
444 bool success = startPart < oStartPart 442 bool success = startPart < oStartPart
445 ? oStart->segment()->addExpanded( 443 ? oStart->segment()->addExpanded(
446 oStartPtT->fT + oStartRange * startPart, test, & startOver) 444 oStartPtT->fT + oStartRange * startPart, test, & startOver)
447 : start->segment()->addExpanded( 445 : start->segment()->addExpanded(
448 startPtT->fT + startRange * oStartPart, oTest, & startOver); 446 startPtT->fT + startRange * oStartPart, oTest, & startOver);
449 if (!success) { 447 FAIL_IF(!success);
450 SkOPASSERT(false);
451 return false;
452 }
453 if (startOver) { 448 if (startOver) {
454 test = start; 449 test = start;
455 oTest = oStart; 450 oTest = oStart;
456 } 451 }
452 end = coin->coinPtTEnd()->span();
453 oEnd = coin->oppPtTEnd()->span();
457 } 454 }
458 if (test != end) { 455 if (test != end) {
459 if (!test->upCastable()) { 456 FAIL_IF(!test->upCastable());
460 return false;
461 }
462 test = test->upCast()->next(); 457 test = test->upCast()->next();
463 } 458 }
464 if (oTest != oEnd) { 459 if (oTest != oEnd) {
465 oTest = coin->flipped() ? oTest->prev() : oTest->upCast()->next( ); 460 oTest = coin->flipped() ? oTest->prev() : oTest->upCast()->next( );
466 if (!oTest) { 461 FAIL_IF(!oTest);
467 return false;
468 }
469 } 462 }
470 } 463 }
471 } while ((coin = coin->next())); 464 } while ((coin = coin->next()));
472 return true; 465 return true;
473 } 466 }
474 467
475 // checks to see if coincidence has already been found 468 // checks to see if coincidence has already been found
476 bool SkOpCoincidence::alreadyAdded(const SkCoincidentSpans* check, const SkCoinc identSpans* outer, 469 bool SkOpCoincidence::alreadyAdded(const SkCoincidentSpans* check, const SkCoinc identSpans* outer,
477 const SkOpPtT* over1s, const SkOpPtT* over1e) const { 470 const SkOpPtT* over1s, const SkOpPtT* over1e) const {
478 do { 471 do {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 *overlaps->append() = check; // partial overlap, extend existing entry 565 *overlaps->append() = check; // partial overlap, extend existing entry
573 } while ((check = check->next())); 566 } while ((check = check->next()));
574 return true; 567 return true;
575 } 568 }
576 569
577 /* Please keep this in sync with debugAddIfMissing() */ 570 /* Please keep this in sync with debugAddIfMissing() */
578 bool SkOpCoincidence::addIfMissing(const SkOpPtT* over1s, const SkOpPtT* over1e, 571 bool SkOpCoincidence::addIfMissing(const SkOpPtT* over1s, const SkOpPtT* over1e,
579 const SkOpPtT* over2s, const SkOpPtT* over2e, double tStart, double tEnd , 572 const SkOpPtT* over2s, const SkOpPtT* over2e, double tStart, double tEnd ,
580 SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, 573 SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd,
581 SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd) { 574 SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd) {
575 SkOpSegment* coinSeg = coinPtTStart->segment();
576 SkOpSegment* oppSeg = oppPtTStart->segment();
577 if (coinSeg == oppSeg) {
578 return false;
579 }
582 double coinTs, coinTe, oppTs, oppTe; 580 double coinTs, coinTe, oppTs, oppTe;
583 TRange(over1s, over1e, tStart, tEnd, coinPtTStart, coinPtTEnd, &coinTs, &coi nTe); 581 TRange(over1s, over1e, tStart, tEnd, coinPtTStart, coinPtTEnd, &coinTs, &coi nTe);
582 if (coinSeg->collapsed(coinTs, coinTe)) {
583 return false;
584 }
584 TRange(over2s, over2e, tStart, tEnd, oppPtTStart, oppPtTEnd, &oppTs, &oppTe) ; 585 TRange(over2s, over2e, tStart, tEnd, oppPtTStart, oppPtTEnd, &oppTs, &oppTe) ;
586 if (oppSeg->collapsed(oppTs, oppTe)) {
587 return false;
588 }
585 bool swap = coinTs > coinTe; 589 bool swap = coinTs > coinTe;
586 if (swap) { 590 if (swap) {
587 SkTSwap(coinTs, coinTe); 591 SkTSwap(coinTs, coinTe);
588 } 592 }
589 if ((over1s->fT < over1e->fT) != (over2s->fT < over2e->fT)) { 593 if ((over1s->fT < over1e->fT) != (over2s->fT < over2e->fT)) {
590 SkTSwap(oppTs, oppTe); 594 SkTSwap(oppTs, oppTe);
591 } 595 }
592 if (swap) { 596 if (swap) {
593 SkTSwap(oppTs, oppTe); 597 SkTSwap(oppTs, oppTe);
594 } 598 }
595 SkOpSegment* coinSeg = coinPtTStart->segment();
596 SkOpSegment* oppSeg = oppPtTStart->segment();
597 if (coinSeg == oppSeg) {
598 return false;
599 }
600 return this->addOrOverlap(coinSeg, oppSeg, coinTs, coinTe, oppTs, oppTe 599 return this->addOrOverlap(coinSeg, oppSeg, coinTs, coinTe, oppTs, oppTe
601 SkDEBUGPARAMS(false) /* don't assert if addOrOverlap fails */ ); 600 SkDEBUGPARAMS(false) /* don't assert if addOrOverlap fails */ );
602 } 601 }
603 602
604 /* Please keep this in sync with debugAddOrOverlap() */ 603 /* Please keep this in sync with debugAddOrOverlap() */
605 // If this is called by addEndMovedSpans(), a returned false propogates out to a n abort. 604 // If this is called by addEndMovedSpans(), a returned false propogates out to a n abort.
606 // If this is called by AddIfMissing(), a returned false indicates there was not hing to add 605 // If this is called by AddIfMissing(), a returned false indicates there was not hing to add
607 bool SkOpCoincidence::addOrOverlap(SkOpSegment* coinSeg, SkOpSegment* oppSeg, 606 bool SkOpCoincidence::addOrOverlap(SkOpSegment* coinSeg, SkOpSegment* oppSeg,
608 double coinTs, double coinTe, double oppTs, double oppTe 607 double coinTs, double coinTe, double oppTs, double oppTe
609 SkDEBUGPARAMS(bool callerAborts)) { 608 SkDEBUGPARAMS(bool callerAborts)) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 RETURN_FALSE_IF(callerAborts, oeExisting && (oeExisting == os || 664 RETURN_FALSE_IF(callerAborts, oeExisting && (oeExisting == os ||
666 oeExisting->contains(osExisting ? osExisting : os))); 665 oeExisting->contains(osExisting ? osExisting : os)));
667 // extra line in debug code 666 // extra line in debug code
668 this->debugValidate(); 667 this->debugValidate();
669 if (!cs || !os) { 668 if (!cs || !os) {
670 SkOpPtT* csWritable = cs ? const_cast<SkOpPtT*>(cs) 669 SkOpPtT* csWritable = cs ? const_cast<SkOpPtT*>(cs)
671 : coinSeg->addT(coinTs); 670 : coinSeg->addT(coinTs);
672 SkOpPtT* osWritable = os ? const_cast<SkOpPtT*>(os) 671 SkOpPtT* osWritable = os ? const_cast<SkOpPtT*>(os)
673 : oppSeg->addT(oppTs); 672 : oppSeg->addT(oppTs);
674 RETURN_FALSE_IF(callerAborts, !csWritable || !osWritable); 673 RETURN_FALSE_IF(callerAborts, !csWritable || !osWritable);
675 csWritable->span()->addOppAndMerge(osWritable->span()); 674 csWritable->span()->addOpp(osWritable->span());
676 cs = csWritable; 675 cs = csWritable;
677 os = osWritable; 676 os = osWritable->active();
678 RETURN_FALSE_IF(callerAborts, (ce && ce->deleted()) || (oe && oe->delete d())); 677 RETURN_FALSE_IF(callerAborts, (ce && ce->deleted()) || (oe && oe->delete d()));
679 } 678 }
680 if (!ce || !oe) { 679 if (!ce || !oe) {
681 SkOpPtT* ceWritable = ce ? const_cast<SkOpPtT*>(ce) 680 SkOpPtT* ceWritable = ce ? const_cast<SkOpPtT*>(ce)
682 : coinSeg->addT(coinTe); 681 : coinSeg->addT(coinTe);
683 SkOpPtT* oeWritable = oe ? const_cast<SkOpPtT*>(oe) 682 SkOpPtT* oeWritable = oe ? const_cast<SkOpPtT*>(oe)
684 : oppSeg->addT(oppTe); 683 : oppSeg->addT(oppTe);
685 ceWritable->span()->addOppAndMerge(oeWritable->span()); 684 ceWritable->span()->addOpp(oeWritable->span());
686 ce = ceWritable; 685 ce = ceWritable;
687 oe = oeWritable; 686 oe = oeWritable;
688 } 687 }
689 this->debugValidate(); 688 this->debugValidate();
690 RETURN_FALSE_IF(callerAborts, cs->deleted()); 689 RETURN_FALSE_IF(callerAborts, cs->deleted());
691 RETURN_FALSE_IF(callerAborts, os->deleted()); 690 RETURN_FALSE_IF(callerAborts, os->deleted());
692 RETURN_FALSE_IF(callerAborts, ce->deleted()); 691 RETURN_FALSE_IF(callerAborts, ce->deleted());
693 RETURN_FALSE_IF(callerAborts, oe->deleted()); 692 RETURN_FALSE_IF(callerAborts, oe->deleted());
694 RETURN_FALSE_IF(callerAborts, cs->contains(ce) || os->contains(oe)); 693 RETURN_FALSE_IF(callerAborts, cs->contains(ce) || os->contains(oe));
695 bool result = true; 694 bool result = true;
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
1134 } else { 1133 } else {
1135 fTop = next; 1134 fTop = next;
1136 } 1135 }
1137 break; 1136 break;
1138 } 1137 }
1139 prev = coin; 1138 prev = coin;
1140 } while ((coin = next)); 1139 } while ((coin = next));
1141 return coin != nullptr; 1140 return coin != nullptr;
1142 } 1141 }
1143 1142
1143 void SkOpCoincidence::releaseDeleted(SkCoincidentSpans* coin) {
1144 if (!coin) {
1145 return;
1146 }
1147 SkCoincidentSpans* head = coin;
1148 SkCoincidentSpans* prev = nullptr;
1149 SkCoincidentSpans* next;
1150 do {
1151 next = coin->next();
1152 if (coin->coinPtTStart()->deleted()) {
1153 SkOPASSERT(coin->flipped() ? coin->oppPtTEnd()->deleted() :
1154 coin->oppPtTStart()->deleted());
1155 if (prev) {
1156 prev->setNext(next);
1157 } else if (head == fHead) {
1158 fHead = next;
1159 } else {
1160 fTop = next;
1161 }
1162 } else {
1163 SkOPASSERT(coin->flipped() ? !coin->oppPtTEnd()->deleted() :
1164 !coin->oppPtTStart()->deleted());
1165 prev = coin;
1166 }
1167 } while ((coin = next));
1168 }
1169
1170 void SkOpCoincidence::releaseDeleted() {
1171 this->releaseDeleted(fHead);
1172 this->releaseDeleted(fTop);
1173 }
1174
1144 // Please keep this in sync with debugReorder() 1175 // Please keep this in sync with debugReorder()
1145 // iterate through all coincident pairs, looking for ranges greater than 1 1176 // iterate through all coincident pairs, looking for ranges greater than 1
1146 // if found, see if the opposite pair can match it -- which may require 1177 // if found, see if the opposite pair can match it -- which may require
1147 // reordering the ptT pairs 1178 // reordering the ptT pairs
1148 bool SkOpCoincidence::reorder() { 1179 bool SkOpCoincidence::reorder() {
1149 SkCoincidentSpans* coin = fHead; 1180 SkCoincidentSpans* coin = fHead;
1150 if (!coin) { 1181 if (!coin) {
1151 return true; 1182 return true;
1152 } 1183 }
1153 do { 1184 do {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1189 SkCoincidentSpans* test = *headPtr; 1220 SkCoincidentSpans* test = *headPtr;
1190 if (test->coinPtTStart()->segment()->done() || test->oppPtTStart()->segm ent()->done()) { 1221 if (test->coinPtTStart()->segment()->done() || test->oppPtTStart()->segm ent()->done()) {
1191 *headPtr = test->next(); 1222 *headPtr = test->next();
1192 continue; 1223 continue;
1193 } 1224 }
1194 headPtr = (*headPtr)->nextPtr(); 1225 headPtr = (*headPtr)->nextPtr();
1195 } 1226 }
1196 } 1227 }
1197 1228
1198 // Please keep this in sync with debugExpand() 1229 // Please keep this in sync with debugExpand()
1230 // expand the range by checking adjacent spans for coincidence
1199 bool SkOpCoincidence::expand() { 1231 bool SkOpCoincidence::expand() {
1200 SkCoincidentSpans* coin = fHead; 1232 SkCoincidentSpans* coin = fHead;
1201 if (!coin) { 1233 if (!coin) {
1202 return false; 1234 return false;
1203 } 1235 }
1204 bool expanded = false; 1236 bool expanded = false;
1205 do { 1237 do {
1206 if (coin->expand()) { 1238 if (coin->expand()) {
1207 // check to see if multiple spans expanded so they are now identical 1239 // check to see if multiple spans expanded so they are now identical
1208 SkCoincidentSpans* test = fHead; 1240 SkCoincidentSpans* test = fHead;
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1447 this->release(fHead, coin); 1479 this->release(fHead, coin);
1448 } 1480 }
1449 } while ((coin = coin->next())); 1481 } while ((coin = coin->next()));
1450 } 1482 }
1451 1483
1452 bool SkOpCoincidence::testForCoincidence(const SkCoincidentSpans* outer, const S kOpPtT* testS, 1484 bool SkOpCoincidence::testForCoincidence(const SkCoincidentSpans* outer, const S kOpPtT* testS,
1453 const SkOpPtT* testE) const { 1485 const SkOpPtT* testE) const {
1454 return testS->segment()->testForCoincidence(testS, testE, testS->span(), 1486 return testS->segment()->testForCoincidence(testS, testE, testS->span(),
1455 testE->span(), outer->coinPtTStart()->segment()); 1487 testE->span(), outer->coinPtTStart()->segment());
1456 } 1488 }
OLDNEW
« no previous file with comments | « src/pathops/SkOpCoincidence.h ('k') | src/pathops/SkOpContour.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698