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

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

Issue 686843002: Revert of harden pathops for pathological test (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 1 month 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/SkOpSegment.cpp ('k') | src/pathops/SkPathOpsDebug.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 2012 Google Inc. 2 * Copyright 2012 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 "SkAddIntersections.h" 7 #include "SkAddIntersections.h"
8 #include "SkOpEdgeBuilder.h" 8 #include "SkOpEdgeBuilder.h"
9 #include "SkPathOpsCommon.h" 9 #include "SkPathOpsCommon.h"
10 #include "SkPathWriter.h" 10 #include "SkPathWriter.h"
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 *chase->append() = span; 154 *chase->append() = span;
155 #endif 155 #endif
156 return last->segment(); 156 return last->segment();
157 } 157 }
158 if (done) { 158 if (done) {
159 continue; 159 continue;
160 } 160 }
161 if (!sortable) { 161 if (!sortable) {
162 continue; 162 continue;
163 } 163 }
164 // find first angle, initialize winding to computed wind sum 164 // find first angle, initialize winding to computed fWindSum
165 const SkOpAngle* angle = segment->spanToAngle(*tIndex, *endIndex); 165 const SkOpAngle* angle = segment->spanToAngle(*tIndex, *endIndex);
166 const SkOpAngle* firstAngle; 166 const SkOpAngle* firstAngle;
167 SkDEBUGCODE(firstAngle = angle); 167 SkDEBUGCODE(firstAngle = angle);
168 SkDEBUGCODE(bool loop = false); 168 SkDEBUGCODE(bool loop = false);
169 int winding; 169 int winding;
170 do { 170 do {
171 angle = angle->next(); 171 angle = angle->next();
172 SkASSERT(angle != firstAngle || !loop); 172 SkASSERT(angle != firstAngle || !loop);
173 SkDEBUGCODE(loop |= angle == firstAngle); 173 SkDEBUGCODE(loop |= angle == firstAngle);
174 segment = angle->segment(); 174 segment = angle->segment();
(...skipping 26 matching lines...) Expand all
201 *endIndex = angle->end(); 201 *endIndex = angle->end();
202 int lesser = SkMin32(*tIndex, *endIndex); 202 int lesser = SkMin32(*tIndex, *endIndex);
203 const SkOpSpan& nextSpan = segment->span(lesser); 203 const SkOpSpan& nextSpan = segment->span(lesser);
204 if (!nextSpan.fDone) { 204 if (!nextSpan.fDone) {
205 // FIXME: this be wrong? assign startWinding if edge is in 205 // FIXME: this be wrong? assign startWinding if edge is in
206 // same direction. If the direction is opposite, winding to 206 // same direction. If the direction is opposite, winding to
207 // assign is flipped sign or +/- 1? 207 // assign is flipped sign or +/- 1?
208 if (SkOpSegment::UseInnerWinding(maxWinding, winding)) { 208 if (SkOpSegment::UseInnerWinding(maxWinding, winding)) {
209 maxWinding = winding; 209 maxWinding = winding;
210 } 210 }
211 // allowed to do nothing 211 (void) segment->markAndChaseWinding(angle, maxWinding, 0);
212 (void) segment->markAndChaseWinding(angle, maxWinding, 0, NULL);
213 break; 212 break;
214 } 213 }
215 } 214 }
216 *chase->insert(0) = span; 215 *chase->insert(0) = span;
217 return segment; 216 return segment;
218 } 217 }
219 return NULL; 218 return NULL;
220 } 219 }
221 220
222 #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY 221 #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 } 308 }
310 SkOpSegment* nonVertical = contour->nonVerticalSegment(index, endIndex); 309 SkOpSegment* nonVertical = contour->nonVerticalSegment(index, endIndex);
311 if (nonVertical) { 310 if (nonVertical) {
312 *current = nonVertical; 311 *current = nonVertical;
313 return; 312 return;
314 } 313 }
315 } 314 }
316 return; 315 return;
317 } 316 }
318 317
319 struct SortableTop { // error if local in pre-C++11
320 SkOpSegment* fSegment;
321 int fIndex;
322 int fEndIndex;
323 };
324
325 SkOpSegment* FindSortableTop(const SkTArray<SkOpContour*, true>& contourList, 318 SkOpSegment* FindSortableTop(const SkTArray<SkOpContour*, true>& contourList,
326 SkOpAngle::IncludeType angleIncludeType, bool* firstContour, int* indexP tr, 319 SkOpAngle::IncludeType angleIncludeType, bool* firstContour, int* indexP tr,
327 int* endIndexPtr, SkPoint* topLeft, bool* unsortable, bool* done, bool* onlyVertical, 320 int* endIndexPtr, SkPoint* topLeft, bool* unsortable, bool* done, bool* onlyVertical,
328 bool firstPass) { 321 bool firstPass) {
329 SkOpSegment* current = findTopSegment(contourList, indexPtr, endIndexPtr, to pLeft, unsortable, 322 SkOpSegment* current = findTopSegment(contourList, indexPtr, endIndexPtr, to pLeft, unsortable,
330 done, firstPass); 323 done, firstPass);
331 if (!current) { 324 if (!current) {
332 return NULL; 325 return NULL;
333 } 326 }
334 const int startIndex = *indexPtr; 327 const int startIndex = *indexPtr;
(...skipping 21 matching lines...) Expand all
356 return current; 349 return current;
357 } 350 }
358 int contourWinding; 351 int contourWinding;
359 int oppContourWinding = 0; 352 int oppContourWinding = 0;
360 // the simple upward projection of the unresolved points hit unsortable angl es 353 // the simple upward projection of the unresolved points hit unsortable angl es
361 // shoot rays at right angles to the segment to find its winding, ignoring a ngle cases 354 // shoot rays at right angles to the segment to find its winding, ignoring a ngle cases
362 bool tryAgain; 355 bool tryAgain;
363 double tHit; 356 double tHit;
364 SkScalar hitDx = 0; 357 SkScalar hitDx = 0;
365 SkScalar hitOppDx = 0; 358 SkScalar hitOppDx = 0;
366 // keep track of subsequent returns to detect infinite loops
367 SkTDArray<SortableTop> sortableTops;
368 do { 359 do {
369 // if current is vertical, find another candidate which is not 360 // if current is vertical, find another candidate which is not
370 // if only remaining candidates are vertical, then they can be marked do ne 361 // if only remaining candidates are vertical, then they can be marked do ne
371 SkASSERT(*indexPtr != *endIndexPtr && *indexPtr >= 0 && *endIndexPtr >= 0); 362 SkASSERT(*indexPtr != *endIndexPtr && *indexPtr >= 0 && *endIndexPtr >= 0);
372 skipVertical(contourList, &current, indexPtr, endIndexPtr); 363 skipVertical(contourList, &current, indexPtr, endIndexPtr);
373 SkASSERT(current); // FIXME: if null, all remaining are vertical 364 SkASSERT(current); // FIXME: if null, all remaining are vertical
374 SkASSERT(*indexPtr != *endIndexPtr && *indexPtr >= 0 && *endIndexPtr >= 0); 365 SkASSERT(*indexPtr != *endIndexPtr && *indexPtr >= 0 && *endIndexPtr >= 0);
375 tryAgain = false; 366 tryAgain = false;
376 contourWinding = rightAngleWinding(contourList, &current, indexPtr, endI ndexPtr, &tHit, 367 contourWinding = rightAngleWinding(contourList, &current, indexPtr, endI ndexPtr, &tHit,
377 &hitDx, &tryAgain, onlyVertical, false); 368 &hitDx, &tryAgain, onlyVertical, false);
378 if (tryAgain) {
379 bool giveUp = false;
380 int count = sortableTops.count();
381 for (int index = 0; index < count; ++index) {
382 const SortableTop& prev = sortableTops[index];
383 if (giveUp) {
384 prev.fSegment->markDoneFinal(prev.fIndex);
385 } else if (prev.fSegment == current
386 && (prev.fIndex == *indexPtr || prev.fEndIndex == *endIn dexPtr)) {
387 // remaining edges are non-vertical and cannot have their wi nding computed
388 // mark them as done and return, and hope that assembly can fill the holes
389 giveUp = true;
390 index = -1;
391 }
392 }
393 if (giveUp) {
394 *done = true;
395 return NULL;
396 }
397 }
398 SortableTop* sortableTop = sortableTops.append();
399 sortableTop->fSegment = current;
400 sortableTop->fIndex = *indexPtr;
401 sortableTop->fEndIndex = *endIndexPtr;
402 #if DEBUG_SORT
403 SkDebugf("%s current=%d index=%d endIndex=%d tHit=%1.9g hitDx=%1.9g try= %d vert=%d\n",
404 __FUNCTION__, current->debugID(), *indexPtr, *endIndexPtr, tHit, hitDx, tryAgain,
405 *onlyVertical);
406 #endif
407 if (*onlyVertical) { 369 if (*onlyVertical) {
408 return current; 370 return current;
409 } 371 }
410 if (tryAgain) { 372 if (tryAgain) {
411 continue; 373 continue;
412 } 374 }
413 if (angleIncludeType < SkOpAngle::kBinarySingle) { 375 if (angleIncludeType < SkOpAngle::kBinarySingle) {
414 break; 376 break;
415 } 377 }
416 oppContourWinding = rightAngleWinding(contourList, &current, indexPtr, e ndIndexPtr, &tHit, 378 oppContourWinding = rightAngleWinding(contourList, &current, indexPtr, e ndIndexPtr, &tHit,
417 &hitOppDx, &tryAgain, NULL, true); 379 &hitOppDx, &tryAgain, NULL, true);
418 } while (tryAgain); 380 } while (tryAgain);
419 bool success = current->initWinding(*indexPtr, *endIndexPtr, tHit, contourWi nding, hitDx, 381 current->initWinding(*indexPtr, *endIndexPtr, tHit, contourWinding, hitDx, o ppContourWinding,
420 oppContourWinding, hitOppDx); 382 hitOppDx);
421 if (current->done()) { 383 if (current->done()) {
422 return NULL; 384 return NULL;
423 } else if (!success) { // check if the span has a valid winding
424 int min = SkTMin(*indexPtr, *endIndexPtr);
425 const SkOpSpan& span = current->span(min);
426 if (span.fWindSum == SK_MinS32) {
427 return NULL;
428 }
429 } 385 }
430 return current; 386 return current;
431 } 387 }
432 388
433 static bool calcAngles(SkTArray<SkOpContour*, true>* contourList) { 389 static bool calcAngles(SkTArray<SkOpContour*, true>* contourList) {
434 int contourCount = (*contourList).count(); 390 int contourCount = (*contourList).count();
435 for (int cTest = 0; cTest < contourCount; ++cTest) { 391 for (int cTest = 0; cTest < contourCount; ++cTest) {
436 SkOpContour* contour = (*contourList)[cTest]; 392 SkOpContour* contour = (*contourList)[cTest];
437 if (!contour->calcAngles()) { 393 if (!contour->calcAngles()) {
438 return false; 394 return false;
439 } 395 }
440 } 396 }
441 return true; 397 return true;
442 } 398 }
443 399
444 static void checkDuplicates(SkTArray<SkOpContour*, true>* contourList) { 400 static void checkDuplicates(SkTArray<SkOpContour*, true>* contourList) {
445 int contourCount = (*contourList).count(); 401 int contourCount = (*contourList).count();
446 for (int cTest = 0; cTest < contourCount; ++cTest) { 402 for (int cTest = 0; cTest < contourCount; ++cTest) {
447 SkOpContour* contour = (*contourList)[cTest]; 403 SkOpContour* contour = (*contourList)[cTest];
448 contour->checkDuplicates(); 404 contour->checkDuplicates();
449 } 405 }
450 } 406 }
451 407
452 static bool checkEnds(SkTArray<SkOpContour*, true>* contourList) { 408 static void checkEnds(SkTArray<SkOpContour*, true>* contourList) {
453 // it's hard to determine if the end of a cubic or conic nearly intersects a nother curve. 409 // it's hard to determine if the end of a cubic or conic nearly intersects a nother curve.
454 // instead, look to see if the connecting curve intersected at that same end . 410 // instead, look to see if the connecting curve intersected at that same end .
455 int contourCount = (*contourList).count(); 411 int contourCount = (*contourList).count();
456 for (int cTest = 0; cTest < contourCount; ++cTest) { 412 for (int cTest = 0; cTest < contourCount; ++cTest) {
457 SkOpContour* contour = (*contourList)[cTest]; 413 SkOpContour* contour = (*contourList)[cTest];
458 if (!contour->checkEnds()) { 414 contour->checkEnds();
459 return false;
460 }
461 } 415 }
462 return true;
463 } 416 }
464 417
465 static bool checkMultiples(SkTArray<SkOpContour*, true>* contourList) { 418 static bool checkMultiples(SkTArray<SkOpContour*, true>* contourList) {
466 bool hasMultiples = false; 419 bool hasMultiples = false;
467 int contourCount = (*contourList).count(); 420 int contourCount = (*contourList).count();
468 for (int cTest = 0; cTest < contourCount; ++cTest) { 421 for (int cTest = 0; cTest < contourCount; ++cTest) {
469 SkOpContour* contour = (*contourList)[cTest]; 422 SkOpContour* contour = (*contourList)[cTest];
470 contour->checkMultiples(); 423 contour->checkMultiples();
471 hasMultiples |= contour->hasMultiples(); 424 hasMultiples |= contour->hasMultiples();
472 } 425 }
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 #if DEBUG_SHOW_WINDING 699 #if DEBUG_SHOW_WINDING
747 SkOpContour::debugShowWindingValues(contourList); 700 SkOpContour::debugShowWindingValues(contourList);
748 #endif 701 #endif
749 if (!CoincidenceCheck(contourList, total)) { 702 if (!CoincidenceCheck(contourList, total)) {
750 return false; 703 return false;
751 } 704 }
752 #if DEBUG_SHOW_WINDING 705 #if DEBUG_SHOW_WINDING
753 SkOpContour::debugShowWindingValues(contourList); 706 SkOpContour::debugShowWindingValues(contourList);
754 #endif 707 #endif
755 fixOtherTIndex(contourList); 708 fixOtherTIndex(contourList);
756 if (!checkEnds(contourList)) { // check if connecting curve intersected at the same end 709 checkEnds(contourList); // check if connecting curve intersected at the sam e end
757 return false;
758 }
759 bool hasM = checkMultiples(contourList); // check if intersections agree on t and point values 710 bool hasM = checkMultiples(contourList); // check if intersections agree on t and point values
760 SkTDArray<SkOpSegment::AlignedSpan> aligned; 711 SkTDArray<SkOpSegment::AlignedSpan> aligned;
761 if (hasM) { 712 if (hasM) {
762 alignMultiples(contourList, &aligned); // align pairs of identical poin ts 713 alignMultiples(contourList, &aligned); // align pairs of identical poin ts
763 alignCoincidence(contourList, aligned); 714 alignCoincidence(contourList, aligned);
764 } 715 }
765 checkDuplicates(contourList); // check if spans have the same number on the other end 716 checkDuplicates(contourList); // check if spans have the same number on the other end
766 checkTiny(contourList); // if pair have the same end points, mark them as p arallel 717 checkTiny(contourList); // if pair have the same end points, mark them as p arallel
767 checkSmall(contourList); // a pair of curves with a small span may turn int o coincident lines 718 checkSmall(contourList); // a pair of curves with a small span may turn int o coincident lines
768 joinCoincidence(contourList); // join curves that connect to a coincident p air 719 joinCoincidence(contourList); // join curves that connect to a coincident p air
769 sortSegments(contourList); 720 sortSegments(contourList);
770 if (!calcAngles(contourList)) { 721 if (!calcAngles(contourList)) {
771 return false; 722 return false;
772 } 723 }
773 sortAngles(contourList); 724 sortAngles(contourList);
774 #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY 725 #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY
775 DebugShowActiveSpans(*contourList); 726 DebugShowActiveSpans(*contourList);
776 #endif 727 #endif
777 return true; 728 return true;
778 } 729 }
OLDNEW
« no previous file with comments | « src/pathops/SkOpSegment.cpp ('k') | src/pathops/SkPathOpsDebug.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698