OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "SkClipStack.h" | 8 #include "SkClipStack.h" |
9 #include "SkPath.h" | 9 #include "SkPath.h" |
10 #include "SkThread.h" | 10 #include "SkThread.h" |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 | 436 |
437 fSaveCount = 0; | 437 fSaveCount = 0; |
438 } | 438 } |
439 | 439 |
440 void SkClipStack::save() { | 440 void SkClipStack::save() { |
441 fSaveCount += 1; | 441 fSaveCount += 1; |
442 } | 442 } |
443 | 443 |
444 void SkClipStack::restore() { | 444 void SkClipStack::restore() { |
445 fSaveCount -= 1; | 445 fSaveCount -= 1; |
| 446 restoreTo(fSaveCount); |
| 447 } |
| 448 |
| 449 void SkClipStack::restoreTo(int saveCount) { |
446 while (!fDeque.empty()) { | 450 while (!fDeque.empty()) { |
447 Element* element = (Element*)fDeque.back(); | 451 Element* element = (Element*)fDeque.back(); |
448 if (element->fSaveCount <= fSaveCount) { | 452 if (element->fSaveCount <= saveCount) { |
449 break; | 453 break; |
450 } | 454 } |
451 this->purgeClip(element); | 455 this->purgeClip(element); |
452 element->~Element(); | 456 element->~Element(); |
453 fDeque.pop_back(); | 457 fDeque.pop_back(); |
454 } | 458 } |
455 } | 459 } |
456 | 460 |
457 void SkClipStack::getBounds(SkRect* canvFiniteBound, | 461 void SkClipStack::getBounds(SkRect* canvFiniteBound, |
458 BoundsType* boundType, | 462 BoundsType* boundType, |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 } | 525 } |
522 return true; | 526 return true; |
523 } | 527 } |
524 | 528 |
525 void SkClipStack::clipDevRect(const SkRect& rect, SkRegion::Op op, bool doAA) { | 529 void SkClipStack::clipDevRect(const SkRect& rect, SkRegion::Op op, bool doAA) { |
526 | 530 |
527 // Use reverse iterator instead of back because Rect path may need previous | 531 // Use reverse iterator instead of back because Rect path may need previous |
528 SkDeque::Iter iter(fDeque, SkDeque::Iter::kBack_IterStart); | 532 SkDeque::Iter iter(fDeque, SkDeque::Iter::kBack_IterStart); |
529 Element* element = (Element*) iter.prev(); | 533 Element* element = (Element*) iter.prev(); |
530 | 534 |
531 if (element && element->canBeIntersectedInPlace(fSaveCount, op)) { | 535 if (NULL != element) { |
532 switch (element->fType) { | 536 if (element->canBeIntersectedInPlace(fSaveCount, op)) { |
533 case Element::kEmpty_Type: | 537 switch (element->fType) { |
534 element->checkEmpty(); | 538 case Element::kEmpty_Type: |
535 return; | 539 element->checkEmpty(); |
536 case Element::kRect_Type: | 540 return; |
537 if (element->rectRectIntersectAllowed(rect, doAA)) { | 541 case Element::kRect_Type: |
538 this->purgeClip(element); | 542 if (element->rectRectIntersectAllowed(rect, doAA)) { |
539 if (!element->fRect.intersect(rect)) { | 543 this->purgeClip(element); |
| 544 if (!element->fRect.intersect(rect)) { |
| 545 element->setEmpty(); |
| 546 return; |
| 547 } |
| 548 |
| 549 element->fDoAA = doAA; |
| 550 Element* prev = (Element*) iter.prev(); |
| 551 element->updateBoundAndGenID(prev); |
| 552 return; |
| 553 } |
| 554 break; |
| 555 case Element::kPath_Type: |
| 556 if (!SkRect::Intersects(element->fPath.getBounds(), rect)) { |
| 557 this->purgeClip(element); |
540 element->setEmpty(); | 558 element->setEmpty(); |
541 return; | 559 return; |
542 } | 560 } |
543 | 561 break; |
544 element->fDoAA = doAA; | 562 } |
545 Element* prev = (Element*) iter.prev(); | 563 } else if (SkRegion::kReplace_Op == op) { |
546 element->updateBoundAndGenID(prev); | 564 this->restoreTo(fSaveCount - 1); |
547 return; | 565 element = (Element*) fDeque.back(); |
548 } | |
549 break; | |
550 case Element::kPath_Type: | |
551 if (!SkRect::Intersects(element->fPath.getBounds(), rect)) { | |
552 this->purgeClip(element); | |
553 element->setEmpty(); | |
554 return; | |
555 } | |
556 break; | |
557 } | 566 } |
558 } | 567 } |
559 new (fDeque.push_back()) Element(fSaveCount, rect, op, doAA); | 568 new (fDeque.push_back()) Element(fSaveCount, rect, op, doAA); |
560 ((Element*) fDeque.back())->updateBoundAndGenID(element); | 569 ((Element*) fDeque.back())->updateBoundAndGenID(element); |
561 | 570 |
562 if (element && element->fSaveCount == fSaveCount) { | 571 if (element && element->fSaveCount == fSaveCount) { |
563 this->purgeClip(element); | 572 this->purgeClip(element); |
564 } | 573 } |
565 } | 574 } |
566 | 575 |
567 void SkClipStack::clipDevPath(const SkPath& path, SkRegion::Op op, bool doAA) { | 576 void SkClipStack::clipDevPath(const SkPath& path, SkRegion::Op op, bool doAA) { |
568 SkRect alt; | 577 SkRect alt; |
569 if (path.isRect(&alt) && !path.isInverseFillType()) { | 578 if (path.isRect(&alt) && !path.isInverseFillType()) { |
570 return this->clipDevRect(alt, op, doAA); | 579 return this->clipDevRect(alt, op, doAA); |
571 } | 580 } |
572 | 581 |
573 Element* element = (Element*)fDeque.back(); | 582 Element* element = (Element*)fDeque.back(); |
574 if (element && element->canBeIntersectedInPlace(fSaveCount, op)) { | 583 if (NULL != element) { |
575 const SkRect& pathBounds = path.getBounds(); | 584 if (element->canBeIntersectedInPlace(fSaveCount, op)) { |
576 switch (element->fType) { | 585 const SkRect& pathBounds = path.getBounds(); |
577 case Element::kEmpty_Type: | 586 switch (element->fType) { |
578 element->checkEmpty(); | 587 case Element::kEmpty_Type: |
579 return; | 588 element->checkEmpty(); |
580 case Element::kRect_Type: | |
581 if (!SkRect::Intersects(element->fRect, pathBounds)) { | |
582 this->purgeClip(element); | |
583 element->setEmpty(); | |
584 return; | 589 return; |
585 } | 590 case Element::kRect_Type: |
586 break; | 591 if (!SkRect::Intersects(element->fRect, pathBounds)) { |
587 case Element::kPath_Type: | 592 this->purgeClip(element); |
588 if (!SkRect::Intersects(element->fPath.getBounds(), pathBounds))
{ | 593 element->setEmpty(); |
589 this->purgeClip(element); | 594 return; |
590 element->setEmpty(); | 595 } |
591 return; | 596 break; |
592 } | 597 case Element::kPath_Type: |
593 break; | 598 if (!SkRect::Intersects(element->fPath.getBounds(), pathBoun
ds)) { |
| 599 this->purgeClip(element); |
| 600 element->setEmpty(); |
| 601 return; |
| 602 } |
| 603 break; |
| 604 } |
| 605 } else if (SkRegion::kReplace_Op == op) { |
| 606 this->restoreTo(fSaveCount - 1); |
| 607 element = (Element*) fDeque.back(); |
594 } | 608 } |
595 } | 609 } |
596 new (fDeque.push_back()) Element(fSaveCount, path, op, doAA); | 610 new (fDeque.push_back()) Element(fSaveCount, path, op, doAA); |
597 ((Element*) fDeque.back())->updateBoundAndGenID(element); | 611 ((Element*) fDeque.back())->updateBoundAndGenID(element); |
598 | 612 |
599 if (element && element->fSaveCount == fSaveCount) { | 613 if (element && element->fSaveCount == fSaveCount) { |
600 this->purgeClip(element); | 614 this->purgeClip(element); |
601 } | 615 } |
602 } | 616 } |
603 | 617 |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 | 775 |
762 int32_t SkClipStack::getTopmostGenID() const { | 776 int32_t SkClipStack::getTopmostGenID() const { |
763 | 777 |
764 if (fDeque.empty()) { | 778 if (fDeque.empty()) { |
765 return kInvalidGenID; | 779 return kInvalidGenID; |
766 } | 780 } |
767 | 781 |
768 Element* element = (Element*)fDeque.back(); | 782 Element* element = (Element*)fDeque.back(); |
769 return element->fGenID; | 783 return element->fGenID; |
770 } | 784 } |
OLD | NEW |