OLD | NEW |
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 "SkOpCoincidence.h" | 8 #include "SkOpCoincidence.h" |
9 #include "SkOpEdgeBuilder.h" | 9 #include "SkOpEdgeBuilder.h" |
10 #include "SkPathOpsCommon.h" | 10 #include "SkPathOpsCommon.h" |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 SkOpContour* contour = contourList; | 443 SkOpContour* contour = contourList; |
444 do { | 444 do { |
445 contour->sortAngles(); | 445 contour->sortAngles(); |
446 } while ((contour = contour->next())); | 446 } while ((contour = contour->next())); |
447 } | 447 } |
448 | 448 |
449 bool HandleCoincidence(SkOpContourHead* contourList, SkOpCoincidence* coincidenc
e, | 449 bool HandleCoincidence(SkOpContourHead* contourList, SkOpCoincidence* coincidenc
e, |
450 SkChunkAlloc* allocator) { | 450 SkChunkAlloc* allocator) { |
451 SkOpGlobalState* globalState = contourList->globalState(); | 451 SkOpGlobalState* globalState = contourList->globalState(); |
452 // combine t values when multiple intersections occur on some segments but n
ot others | 452 // combine t values when multiple intersections occur on some segments but n
ot others |
| 453 DEBUG_COINCIDENCE_HEALTH(contourList, "start"); |
453 moveMultiples(contourList); | 454 moveMultiples(contourList); |
| 455 DEBUG_COINCIDENCE_HEALTH(contourList, "moveMultiples"); |
454 findCollapsed(contourList); | 456 findCollapsed(contourList); |
| 457 DEBUG_COINCIDENCE_HEALTH(contourList, "findCollapsed"); |
455 // move t values and points together to eliminate small/tiny gaps | 458 // move t values and points together to eliminate small/tiny gaps |
456 moveNearby(contourList); | 459 moveNearby(contourList); |
| 460 DEBUG_COINCIDENCE_HEALTH(contourList, "moveNearby"); |
457 align(contourList); // give all span members common values | 461 align(contourList); // give all span members common values |
| 462 DEBUG_COINCIDENCE_HEALTH(contourList, "align"); |
458 coincidence->fixAligned(); // aligning may have marked a coincidence pt-t d
eleted | 463 coincidence->fixAligned(); // aligning may have marked a coincidence pt-t d
eleted |
| 464 DEBUG_COINCIDENCE_HEALTH(contourList, "fixAligned"); |
459 #if DEBUG_VALIDATE | 465 #if DEBUG_VALIDATE |
460 globalState->setPhase(SkOpGlobalState::kIntersecting); | 466 globalState->setPhase(SkOpGlobalState::kIntersecting); |
461 #endif | 467 #endif |
462 // look for intersections on line segments formed by moving end points | 468 // look for intersections on line segments formed by moving end points |
463 addAlignIntersections(contourList, allocator); | 469 addAlignIntersections(contourList, allocator); |
464 coincidence->addMissing(allocator); | 470 DEBUG_COINCIDENCE_HEALTH(contourList, "addAlignIntersections"); |
| 471 if (coincidence->addMissing(allocator)) { |
| 472 DEBUG_COINCIDENCE_HEALTH(contourList, "addMissing"); |
| 473 moveNearby(contourList); |
| 474 DEBUG_COINCIDENCE_HEALTH(contourList, "moveNearby2"); |
| 475 align(contourList); // give all span members common values |
| 476 DEBUG_COINCIDENCE_HEALTH(contourList, "align2"); |
| 477 coincidence->fixAligned(); // aligning may have marked a coincidence pt
-t deleted |
| 478 DEBUG_COINCIDENCE_HEALTH(contourList, "fixAligned2"); |
| 479 } |
465 #if DEBUG_VALIDATE | 480 #if DEBUG_VALIDATE |
466 globalState->setPhase(SkOpGlobalState::kWalking); | 481 globalState->setPhase(SkOpGlobalState::kWalking); |
467 #endif | 482 #endif |
468 // check to see if, loosely, coincident ranges may be expanded | 483 // check to see if, loosely, coincident ranges may be expanded |
469 if (coincidence->expand()) { | 484 if (coincidence->expand()) { |
470 coincidence->addExpanded(allocator PATH_OPS_DEBUG_VALIDATE_PARAMS(globa
lState)); | 485 DEBUG_COINCIDENCE_HEALTH(contourList, "expand1"); |
| 486 if (!coincidence->addExpanded(allocator PATH_OPS_DEBUG_VALIDATE_PARAMS(
globalState))) { |
| 487 return false; |
| 488 } |
471 } | 489 } |
| 490 DEBUG_COINCIDENCE_HEALTH(contourList, "expand2"); |
472 // the expanded ranges may not align -- add the missing spans | 491 // the expanded ranges may not align -- add the missing spans |
473 coincidence->mark(); // mark spans of coincident segments as coincident | 492 coincidence->mark(); // mark spans of coincident segments as coincident |
| 493 DEBUG_COINCIDENCE_HEALTH(contourList, "mark1"); |
474 // look for coincidence missed earlier | 494 // look for coincidence missed earlier |
475 if (missingCoincidence(contourList, coincidence, allocator)) { | 495 if (missingCoincidence(contourList, coincidence, allocator)) { |
| 496 DEBUG_COINCIDENCE_HEALTH(contourList, "missingCoincidence1"); |
476 (void) coincidence->expand(); | 497 (void) coincidence->expand(); |
477 coincidence->addExpanded(allocator PATH_OPS_DEBUG_VALIDATE_PARAMS(globa
lState)); | 498 DEBUG_COINCIDENCE_HEALTH(contourList, "expand3"); |
| 499 if (!coincidence->addExpanded(allocator PATH_OPS_DEBUG_VALIDATE_PARAMS(
globalState))) { |
| 500 return false; |
| 501 } |
| 502 DEBUG_COINCIDENCE_HEALTH(contourList, "addExpanded2"); |
478 coincidence->mark(); | 503 coincidence->mark(); |
479 } | 504 } |
| 505 DEBUG_COINCIDENCE_HEALTH(contourList, "missingCoincidence2"); |
480 SkOpCoincidence overlaps; | 506 SkOpCoincidence overlaps; |
481 do { | 507 do { |
482 SkOpCoincidence* pairs = overlaps.isEmpty() ? coincidence : &overlaps; | 508 SkOpCoincidence* pairs = overlaps.isEmpty() ? coincidence : &overlaps; |
483 if (!pairs->apply()) { // adjust the winding value to account for coinc
ident edges | 509 if (!pairs->apply()) { // adjust the winding value to account for coinc
ident edges |
484 return false; | 510 return false; |
485 } | 511 } |
| 512 DEBUG_COINCIDENCE_HEALTH(contourList, "pairs->apply"); |
486 // For each coincident pair that overlaps another, when the receivers (t
he 1st of the pair) | 513 // For each coincident pair that overlaps another, when the receivers (t
he 1st of the pair) |
487 // are different, construct a new pair to resolve their mutual span | 514 // are different, construct a new pair to resolve their mutual span |
488 pairs->findOverlaps(&overlaps, allocator); | 515 pairs->findOverlaps(&overlaps, allocator); |
| 516 DEBUG_COINCIDENCE_HEALTH(contourList, "pairs->findOverlaps"); |
489 } while (!overlaps.isEmpty()); | 517 } while (!overlaps.isEmpty()); |
490 calcAngles(contourList, allocator); | 518 calcAngles(contourList, allocator); |
491 sortAngles(contourList); | 519 sortAngles(contourList); |
492 if (globalState->angleCoincidence()) { | 520 if (globalState->angleCoincidence()) { |
493 (void) missingCoincidence(contourList, coincidence, allocator); | 521 (void) missingCoincidence(contourList, coincidence, allocator); |
494 if (!coincidence->apply()) { | 522 if (!coincidence->apply()) { |
495 return false; | 523 return false; |
496 } | 524 } |
497 } | 525 } |
498 #if DEBUG_ACTIVE_SPANS | 526 #if DEBUG_ACTIVE_SPANS |
499 coincidence->debugShowCoincidence(); | 527 coincidence->debugShowCoincidence(); |
500 DebugShowActiveSpans(contourList); | 528 DebugShowActiveSpans(contourList); |
501 #endif | 529 #endif |
502 return true; | 530 return true; |
503 } | 531 } |
OLD | NEW |