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

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

Issue 556433002: fail when coincidence is too far apart (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: merge fix from trunk for issue 410552 Created 6 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 | « no previous file | src/pathops/SkOpSegment.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 2013 Google Inc. 2 * Copyright 2013 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 "SkIntersections.h" 7 #include "SkIntersections.h"
8 #include "SkOpContour.h" 8 #include "SkOpContour.h"
9 #include "SkPathWriter.h" 9 #include "SkPathWriter.h"
10 #include "SkTSort.h" 10 #include "SkTSort.h"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 *start = *end = 0; 50 *start = *end = 0;
51 while (testSegment->nextCandidate(start, end)) { 51 while (testSegment->nextCandidate(start, end)) {
52 if (!testSegment->isVertical(*start, *end)) { 52 if (!testSegment->isVertical(*start, *end)) {
53 return testSegment; 53 return testSegment;
54 } 54 }
55 } 55 }
56 } 56 }
57 return NULL; 57 return NULL;
58 } 58 }
59 59
60 // if one is very large the smaller may have collapsed to nothing
61 static void bump_out_close_span(double* startTPtr, double* endTPtr) {
62 double startT = *startTPtr;
63 double endT = *endTPtr;
64 if (approximately_negative(endT - startT)) {
65 if (endT <= 1 - FLT_EPSILON) {
66 *endTPtr += FLT_EPSILON;
67 SkASSERT(*endTPtr <= 1);
68 } else {
69 *startTPtr -= FLT_EPSILON;
70 SkASSERT(*startTPtr >= 0);
71 }
72 }
73 }
74
60 // first pass, add missing T values 75 // first pass, add missing T values
61 // second pass, determine winding values of overlaps 76 // second pass, determine winding values of overlaps
62 void SkOpContour::addCoincidentPoints() { 77 void SkOpContour::addCoincidentPoints() {
63 int count = fCoincidences.count(); 78 int count = fCoincidences.count();
64 for (int index = 0; index < count; ++index) { 79 for (int index = 0; index < count; ++index) {
65 SkCoincidence& coincidence = fCoincidences[index]; 80 SkCoincidence& coincidence = fCoincidences[index];
66 int thisIndex = coincidence.fSegments[0]; 81 int thisIndex = coincidence.fSegments[0];
67 SkOpSegment& thisOne = fSegments[thisIndex]; 82 SkOpSegment& thisOne = fSegments[thisIndex];
68 SkOpContour* otherContour = coincidence.fOther; 83 SkOpContour* otherContour = coincidence.fOther;
69 int otherIndex = coincidence.fSegments[1]; 84 int otherIndex = coincidence.fSegments[1];
70 SkOpSegment& other = otherContour->fSegments[otherIndex]; 85 SkOpSegment& other = otherContour->fSegments[otherIndex];
71 if ((thisOne.done() || other.done()) && thisOne.complete() && other.comp lete()) { 86 if ((thisOne.done() || other.done()) && thisOne.complete() && other.comp lete()) {
72 // OPTIMIZATION: remove from array 87 // OPTIMIZATION: remove from array
73 continue; 88 continue;
74 } 89 }
75 #if DEBUG_CONCIDENT 90 #if DEBUG_CONCIDENT
76 thisOne.debugShowTs("-"); 91 thisOne.debugShowTs("-");
77 other.debugShowTs("o"); 92 other.debugShowTs("o");
78 #endif 93 #endif
79 double startT = coincidence.fTs[0][0]; 94 double startT = coincidence.fTs[0][0];
80 double endT = coincidence.fTs[0][1]; 95 double endT = coincidence.fTs[0][1];
81 bool startSwapped, oStartSwapped, cancelers; 96 bool startSwapped, oStartSwapped, cancelers;
82 if ((cancelers = startSwapped = startT > endT)) { 97 if ((cancelers = startSwapped = startT > endT)) {
83 SkTSwap(startT, endT); 98 SkTSwap(startT, endT);
84 } 99 }
85 if (startT == endT) { // if one is very large the smaller may have colla psed to nothing 100 bump_out_close_span(&startT, &endT);
86 if (endT <= 1 - FLT_EPSILON) {
87 endT += FLT_EPSILON;
88 SkASSERT(endT <= 1);
89 } else {
90 startT -= FLT_EPSILON;
91 SkASSERT(startT >= 0);
92 }
93 }
94 SkASSERT(!approximately_negative(endT - startT)); 101 SkASSERT(!approximately_negative(endT - startT));
95 double oStartT = coincidence.fTs[1][0]; 102 double oStartT = coincidence.fTs[1][0];
96 double oEndT = coincidence.fTs[1][1]; 103 double oEndT = coincidence.fTs[1][1];
97 if ((oStartSwapped = oStartT > oEndT)) { 104 if ((oStartSwapped = oStartT > oEndT)) {
98 SkTSwap(oStartT, oEndT); 105 SkTSwap(oStartT, oEndT);
99 cancelers ^= true; 106 cancelers ^= true;
100 } 107 }
108 bump_out_close_span(&oStartT, &oEndT);
101 SkASSERT(!approximately_negative(oEndT - oStartT)); 109 SkASSERT(!approximately_negative(oEndT - oStartT));
102 const SkPoint& startPt = coincidence.fPts[0][startSwapped]; 110 const SkPoint& startPt = coincidence.fPts[0][startSwapped];
103 if (cancelers) { 111 if (cancelers) {
104 // make sure startT and endT have t entries 112 // make sure startT and endT have t entries
105 if (startT > 0 || oEndT < 1 113 if (startT > 0 || oEndT < 1
106 || thisOne.isMissing(startT, startPt) || other.isMissing(oEn dT, startPt)) { 114 || thisOne.isMissing(startT, startPt) || other.isMissing(oEn dT, startPt)) {
107 thisOne.addTPair(startT, &other, oEndT, true, startPt, 115 thisOne.addTPair(startT, &other, oEndT, true, startPt,
108 coincidence.fPts[1][startSwapped]); 116 coincidence.fPts[1][startSwapped]);
109 } 117 }
110 const SkPoint& oStartPt = coincidence.fPts[1][oStartSwapped]; 118 const SkPoint& oStartPt = coincidence.fPts[1][oStartSwapped];
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 } 560 }
553 double startT = coincidence.fTs[0][0]; 561 double startT = coincidence.fTs[0][0];
554 double endT = coincidence.fTs[0][1]; 562 double endT = coincidence.fTs[0][1];
555 const SkPoint* startPt = &coincidence.fPts[0][0]; 563 const SkPoint* startPt = &coincidence.fPts[0][0];
556 const SkPoint* endPt = &coincidence.fPts[0][1]; 564 const SkPoint* endPt = &coincidence.fPts[0][1];
557 bool cancelers; 565 bool cancelers;
558 if ((cancelers = startT > endT)) { 566 if ((cancelers = startT > endT)) {
559 SkTSwap<double>(startT, endT); 567 SkTSwap<double>(startT, endT);
560 SkTSwap<const SkPoint*>(startPt, endPt); 568 SkTSwap<const SkPoint*>(startPt, endPt);
561 } 569 }
562 if (startT == endT) { // if span is very large, the smaller may have collaps ed to nothing 570 bump_out_close_span(&startT, &endT);
563 if (endT <= 1 - FLT_EPSILON) {
564 endT += FLT_EPSILON;
565 SkASSERT(endT <= 1);
566 } else {
567 startT -= FLT_EPSILON;
568 SkASSERT(startT >= 0);
569 }
570 }
571 SkASSERT(!approximately_negative(endT - startT)); 571 SkASSERT(!approximately_negative(endT - startT));
572 double oStartT = coincidence.fTs[1][0]; 572 double oStartT = coincidence.fTs[1][0];
573 double oEndT = coincidence.fTs[1][1]; 573 double oEndT = coincidence.fTs[1][1];
574 if (oStartT > oEndT) { 574 if (oStartT > oEndT) {
575 SkTSwap<double>(oStartT, oEndT); 575 SkTSwap<double>(oStartT, oEndT);
576 cancelers ^= true; 576 cancelers ^= true;
577 } 577 }
578 bump_out_close_span(&oStartT, &oEndT);
578 SkASSERT(!approximately_negative(oEndT - oStartT)); 579 SkASSERT(!approximately_negative(oEndT - oStartT));
579 if (cancelers) { 580 if (cancelers) {
580 thisOne.addTCancel(*startPt, *endPt, &other); 581 thisOne.addTCancel(*startPt, *endPt, &other);
581 } else { 582 } else {
582 thisOne.addTCoincident(*startPt, *endPt, endT, &other); 583 thisOne.addTCoincident(*startPt, *endPt, endT, &other);
583 } 584 }
584 #if DEBUG_CONCIDENT 585 #if DEBUG_CONCIDENT
585 thisOne.debugShowTs("p"); 586 thisOne.debugShowTs("p");
586 other.debugShowTs("o"); 587 other.debugShowTs("o");
587 #endif 588 #endif
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 SkDebugf("%s empty contour\n", __FUNCTION__); 748 SkDebugf("%s empty contour\n", __FUNCTION__);
748 SkASSERT(0); 749 SkASSERT(0);
749 // FIXME: delete empty contour? 750 // FIXME: delete empty contour?
750 return; 751 return;
751 } 752 }
752 fBounds = fSegments.front().bounds(); 753 fBounds = fSegments.front().bounds();
753 for (int index = 1; index < count; ++index) { 754 for (int index = 1; index < count; ++index) {
754 fBounds.add(fSegments[index].bounds()); 755 fBounds.add(fSegments[index].bounds());
755 } 756 }
756 } 757 }
OLDNEW
« no previous file with comments | « no previous file | src/pathops/SkOpSegment.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698