OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 | 7 |
8 #include "SkAtomics.h" | 8 #include "SkAtomics.h" |
9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
10 #include "SkClipStack.h" | 10 #include "SkClipStack.h" |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 | 388 |
389 // First, optimistically update the current Element's bound information | 389 // First, optimistically update the current Element's bound information |
390 // with the current clip's bound | 390 // with the current clip's bound |
391 fIsIntersectionOfRects = false; | 391 fIsIntersectionOfRects = false; |
392 switch (fType) { | 392 switch (fType) { |
393 case kRect_Type: | 393 case kRect_Type: |
394 fFiniteBound = this->getRect(); | 394 fFiniteBound = this->getRect(); |
395 fFiniteBoundType = kNormal_BoundsType; | 395 fFiniteBoundType = kNormal_BoundsType; |
396 | 396 |
397 if (SkRegion::kReplace_Op == fOp || | 397 if (SkRegion::kReplace_Op == fOp || |
398 (SkRegion::kIntersect_Op == fOp && NULL == prior) || | 398 (SkRegion::kIntersect_Op == fOp && nullptr == prior) || |
399 (SkRegion::kIntersect_Op == fOp && prior->fIsIntersectionOfRects
&& | 399 (SkRegion::kIntersect_Op == fOp && prior->fIsIntersectionOfRects
&& |
400 prior->rectRectIntersectAllowed(this->getRect(), fDoAA))) { | 400 prior->rectRectIntersectAllowed(this->getRect(), fDoAA))) { |
401 fIsIntersectionOfRects = true; | 401 fIsIntersectionOfRects = true; |
402 } | 402 } |
403 break; | 403 break; |
404 case kRRect_Type: | 404 case kRRect_Type: |
405 fFiniteBound = fRRect.getBounds(); | 405 fFiniteBound = fRRect.getBounds(); |
406 fFiniteBoundType = kNormal_BoundsType; | 406 fFiniteBoundType = kNormal_BoundsType; |
407 break; | 407 break; |
408 case kPath_Type: | 408 case kPath_Type: |
(...skipping 15 matching lines...) Expand all Loading... |
424 SkScalarRoundToScalar(fFiniteBound.fTop), | 424 SkScalarRoundToScalar(fFiniteBound.fTop), |
425 SkScalarRoundToScalar(fFiniteBound.fRight), | 425 SkScalarRoundToScalar(fFiniteBound.fRight), |
426 SkScalarRoundToScalar(fFiniteBound.fBottom)); | 426 SkScalarRoundToScalar(fFiniteBound.fBottom)); |
427 } | 427 } |
428 | 428 |
429 // Now determine the previous Element's bound information taking into | 429 // Now determine the previous Element's bound information taking into |
430 // account that there may be no previous clip | 430 // account that there may be no previous clip |
431 SkRect prevFinite; | 431 SkRect prevFinite; |
432 SkClipStack::BoundsType prevType; | 432 SkClipStack::BoundsType prevType; |
433 | 433 |
434 if (NULL == prior) { | 434 if (nullptr == prior) { |
435 // no prior clip means the entire plane is writable | 435 // no prior clip means the entire plane is writable |
436 prevFinite.setEmpty(); // there are no pixels that cannot be drawn to | 436 prevFinite.setEmpty(); // there are no pixels that cannot be drawn to |
437 prevType = kInsideOut_BoundsType; | 437 prevType = kInsideOut_BoundsType; |
438 } else { | 438 } else { |
439 prevFinite = prior->fFiniteBound; | 439 prevFinite = prior->fFiniteBound; |
440 prevType = prior->fFiniteBoundType; | 440 prevType = prior->fFiniteBoundType; |
441 } | 441 } |
442 | 442 |
443 FillCombo combination = kPrev_Cur_FillCombo; | 443 FillCombo combination = kPrev_Cur_FillCombo; |
444 if (kInsideOut_BoundsType == fFiniteBoundType) { | 444 if (kInsideOut_BoundsType == fFiniteBoundType) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
522 | 522 |
523 SkClipStack& SkClipStack::operator=(const SkClipStack& b) { | 523 SkClipStack& SkClipStack::operator=(const SkClipStack& b) { |
524 if (this == &b) { | 524 if (this == &b) { |
525 return *this; | 525 return *this; |
526 } | 526 } |
527 reset(); | 527 reset(); |
528 | 528 |
529 fSaveCount = b.fSaveCount; | 529 fSaveCount = b.fSaveCount; |
530 SkDeque::F2BIter recIter(b.fDeque); | 530 SkDeque::F2BIter recIter(b.fDeque); |
531 for (const Element* element = (const Element*)recIter.next(); | 531 for (const Element* element = (const Element*)recIter.next(); |
532 element != NULL; | 532 element != nullptr; |
533 element = (const Element*)recIter.next()) { | 533 element = (const Element*)recIter.next()) { |
534 new (fDeque.push_back()) Element(*element); | 534 new (fDeque.push_back()) Element(*element); |
535 } | 535 } |
536 | 536 |
537 return *this; | 537 return *this; |
538 } | 538 } |
539 | 539 |
540 bool SkClipStack::operator==(const SkClipStack& b) const { | 540 bool SkClipStack::operator==(const SkClipStack& b) const { |
541 if (this->getTopmostGenID() == b.getTopmostGenID()) { | 541 if (this->getTopmostGenID() == b.getTopmostGenID()) { |
542 return true; | 542 return true; |
543 } | 543 } |
544 if (fSaveCount != b.fSaveCount || | 544 if (fSaveCount != b.fSaveCount || |
545 fDeque.count() != b.fDeque.count()) { | 545 fDeque.count() != b.fDeque.count()) { |
546 return false; | 546 return false; |
547 } | 547 } |
548 SkDeque::F2BIter myIter(fDeque); | 548 SkDeque::F2BIter myIter(fDeque); |
549 SkDeque::F2BIter bIter(b.fDeque); | 549 SkDeque::F2BIter bIter(b.fDeque); |
550 const Element* myElement = (const Element*)myIter.next(); | 550 const Element* myElement = (const Element*)myIter.next(); |
551 const Element* bElement = (const Element*)bIter.next(); | 551 const Element* bElement = (const Element*)bIter.next(); |
552 | 552 |
553 while (myElement != NULL && bElement != NULL) { | 553 while (myElement != nullptr && bElement != nullptr) { |
554 if (*myElement != *bElement) { | 554 if (*myElement != *bElement) { |
555 return false; | 555 return false; |
556 } | 556 } |
557 myElement = (const Element*)myIter.next(); | 557 myElement = (const Element*)myIter.next(); |
558 bElement = (const Element*)bIter.next(); | 558 bElement = (const Element*)bIter.next(); |
559 } | 559 } |
560 return myElement == NULL && bElement == NULL; | 560 return myElement == nullptr && bElement == nullptr; |
561 } | 561 } |
562 | 562 |
563 void SkClipStack::reset() { | 563 void SkClipStack::reset() { |
564 // We used a placement new for each object in fDeque, so we're responsible | 564 // We used a placement new for each object in fDeque, so we're responsible |
565 // for calling the destructor on each of them as well. | 565 // for calling the destructor on each of them as well. |
566 while (!fDeque.empty()) { | 566 while (!fDeque.empty()) { |
567 Element* element = (Element*)fDeque.back(); | 567 Element* element = (Element*)fDeque.back(); |
568 element->~Element(); | 568 element->~Element(); |
569 fDeque.pop_back(); | 569 fDeque.pop_back(); |
570 } | 570 } |
(...skipping 21 matching lines...) Expand all Loading... |
592 } | 592 } |
593 } | 593 } |
594 | 594 |
595 void SkClipStack::getBounds(SkRect* canvFiniteBound, | 595 void SkClipStack::getBounds(SkRect* canvFiniteBound, |
596 BoundsType* boundType, | 596 BoundsType* boundType, |
597 bool* isIntersectionOfRects) const { | 597 bool* isIntersectionOfRects) const { |
598 SkASSERT(canvFiniteBound && boundType); | 598 SkASSERT(canvFiniteBound && boundType); |
599 | 599 |
600 Element* element = (Element*)fDeque.back(); | 600 Element* element = (Element*)fDeque.back(); |
601 | 601 |
602 if (NULL == element) { | 602 if (nullptr == element) { |
603 // the clip is wide open - the infinite plane w/ no pixels un-writeable | 603 // the clip is wide open - the infinite plane w/ no pixels un-writeable |
604 canvFiniteBound->setEmpty(); | 604 canvFiniteBound->setEmpty(); |
605 *boundType = kInsideOut_BoundsType; | 605 *boundType = kInsideOut_BoundsType; |
606 if (isIntersectionOfRects) { | 606 if (isIntersectionOfRects) { |
607 *isIntersectionOfRects = false; | 607 *isIntersectionOfRects = false; |
608 } | 608 } |
609 return; | 609 return; |
610 } | 610 } |
611 | 611 |
612 *canvFiniteBound = element->fFiniteBound; | 612 *canvFiniteBound = element->fFiniteBound; |
613 *boundType = element->fFiniteBoundType; | 613 *boundType = element->fFiniteBoundType; |
614 if (isIntersectionOfRects) { | 614 if (isIntersectionOfRects) { |
615 *isIntersectionOfRects = element->fIsIntersectionOfRects; | 615 *isIntersectionOfRects = element->fIsIntersectionOfRects; |
616 } | 616 } |
617 } | 617 } |
618 | 618 |
619 bool SkClipStack::quickContains(const SkRect& rect) const { | 619 bool SkClipStack::quickContains(const SkRect& rect) const { |
620 | 620 |
621 Iter iter(*this, Iter::kTop_IterStart); | 621 Iter iter(*this, Iter::kTop_IterStart); |
622 const Element* element = iter.prev(); | 622 const Element* element = iter.prev(); |
623 while (element != NULL) { | 623 while (element != nullptr) { |
624 if (SkRegion::kIntersect_Op != element->getOp() && SkRegion::kReplace_Op
!= element->getOp()) | 624 if (SkRegion::kIntersect_Op != element->getOp() && SkRegion::kReplace_Op
!= element->getOp()) |
625 return false; | 625 return false; |
626 if (element->isInverseFilled()) { | 626 if (element->isInverseFilled()) { |
627 // Part of 'rect' could be trimmed off by the inverse-filled clip el
ement | 627 // Part of 'rect' could be trimmed off by the inverse-filled clip el
ement |
628 if (SkRect::Intersects(element->getBounds(), rect)) { | 628 if (SkRect::Intersects(element->getBounds(), rect)) { |
629 return false; | 629 return false; |
630 } | 630 } |
631 } else { | 631 } else { |
632 if (!element->contains(rect)) { | 632 if (!element->contains(rect)) { |
633 return false; | 633 return false; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
740 | 740 |
741 ((Element*)fDeque.back())->fGenID = kEmptyGenID; | 741 ((Element*)fDeque.back())->fGenID = kEmptyGenID; |
742 } | 742 } |
743 | 743 |
744 bool SkClipStack::isWideOpen() const { | 744 bool SkClipStack::isWideOpen() const { |
745 return this->getTopmostGenID() == kWideOpenGenID; | 745 return this->getTopmostGenID() == kWideOpenGenID; |
746 } | 746 } |
747 | 747 |
748 /////////////////////////////////////////////////////////////////////////////// | 748 /////////////////////////////////////////////////////////////////////////////// |
749 | 749 |
750 SkClipStack::Iter::Iter() : fStack(NULL) { | 750 SkClipStack::Iter::Iter() : fStack(nullptr) { |
751 } | 751 } |
752 | 752 |
753 SkClipStack::Iter::Iter(const SkClipStack& stack, IterStart startLoc) | 753 SkClipStack::Iter::Iter(const SkClipStack& stack, IterStart startLoc) |
754 : fStack(&stack) { | 754 : fStack(&stack) { |
755 this->reset(stack, startLoc); | 755 this->reset(stack, startLoc); |
756 } | 756 } |
757 | 757 |
758 const SkClipStack::Element* SkClipStack::Iter::next() { | 758 const SkClipStack::Element* SkClipStack::Iter::next() { |
759 return (const SkClipStack::Element*)fIter.next(); | 759 return (const SkClipStack::Element*)fIter.next(); |
760 } | 760 } |
761 | 761 |
762 const SkClipStack::Element* SkClipStack::Iter::prev() { | 762 const SkClipStack::Element* SkClipStack::Iter::prev() { |
763 return (const SkClipStack::Element*)fIter.prev(); | 763 return (const SkClipStack::Element*)fIter.prev(); |
764 } | 764 } |
765 | 765 |
766 const SkClipStack::Element* SkClipStack::Iter::skipToTopmost(SkRegion::Op op) { | 766 const SkClipStack::Element* SkClipStack::Iter::skipToTopmost(SkRegion::Op op) { |
767 | 767 |
768 if (NULL == fStack) { | 768 if (nullptr == fStack) { |
769 return NULL; | 769 return nullptr; |
770 } | 770 } |
771 | 771 |
772 fIter.reset(fStack->fDeque, SkDeque::Iter::kBack_IterStart); | 772 fIter.reset(fStack->fDeque, SkDeque::Iter::kBack_IterStart); |
773 | 773 |
774 const SkClipStack::Element* element = NULL; | 774 const SkClipStack::Element* element = nullptr; |
775 | 775 |
776 for (element = (const SkClipStack::Element*) fIter.prev(); | 776 for (element = (const SkClipStack::Element*) fIter.prev(); |
777 element; | 777 element; |
778 element = (const SkClipStack::Element*) fIter.prev()) { | 778 element = (const SkClipStack::Element*) fIter.prev()) { |
779 | 779 |
780 if (op == element->fOp) { | 780 if (op == element->fOp) { |
781 // The Deque's iterator is actually one pace ahead of the | 781 // The Deque's iterator is actually one pace ahead of the |
782 // returned value. So while "element" is the element we want to | 782 // returned value. So while "element" is the element we want to |
783 // return, the iterator is actually pointing at (and will | 783 // return, the iterator is actually pointing at (and will |
784 // return on the next "next" or "prev" call) the element | 784 // return on the next "next" or "prev" call) the element |
785 // in front of it in the deque. Bump the iterator forward a | 785 // in front of it in the deque. Bump the iterator forward a |
786 // step so we get the expected result. | 786 // step so we get the expected result. |
787 if (NULL == fIter.next()) { | 787 if (nullptr == fIter.next()) { |
788 // The reverse iterator has run off the front of the deque | 788 // The reverse iterator has run off the front of the deque |
789 // (i.e., the "op" clip is the first clip) and can't | 789 // (i.e., the "op" clip is the first clip) and can't |
790 // recover. Reset the iterator to start at the front. | 790 // recover. Reset the iterator to start at the front. |
791 fIter.reset(fStack->fDeque, SkDeque::Iter::kFront_IterStart); | 791 fIter.reset(fStack->fDeque, SkDeque::Iter::kFront_IterStart); |
792 } | 792 } |
793 break; | 793 break; |
794 } | 794 } |
795 } | 795 } |
796 | 796 |
797 if (NULL == element) { | 797 if (nullptr == element) { |
798 // There were no "op" clips | 798 // There were no "op" clips |
799 fIter.reset(fStack->fDeque, SkDeque::Iter::kFront_IterStart); | 799 fIter.reset(fStack->fDeque, SkDeque::Iter::kFront_IterStart); |
800 } | 800 } |
801 | 801 |
802 return this->next(); | 802 return this->next(); |
803 } | 803 } |
804 | 804 |
805 void SkClipStack::Iter::reset(const SkClipStack& stack, IterStart startLoc) { | 805 void SkClipStack::Iter::reset(const SkClipStack& stack, IterStart startLoc) { |
806 fStack = &stack; | 806 fStack = &stack; |
807 fIter.reset(stack.fDeque, static_cast<SkDeque::Iter::IterStart>(startLoc)); | 807 fIter.reset(stack.fDeque, static_cast<SkDeque::Iter::IterStart>(startLoc)); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 break; | 892 break; |
893 case kRect_Type: | 893 case kRect_Type: |
894 this->getRect().dump(); | 894 this->getRect().dump(); |
895 SkDebugf("\n"); | 895 SkDebugf("\n"); |
896 break; | 896 break; |
897 case kRRect_Type: | 897 case kRRect_Type: |
898 this->getRRect().dump(); | 898 this->getRRect().dump(); |
899 SkDebugf("\n"); | 899 SkDebugf("\n"); |
900 break; | 900 break; |
901 case kPath_Type: | 901 case kPath_Type: |
902 this->getPath().dump(NULL, true, false); | 902 this->getPath().dump(nullptr, true, false); |
903 break; | 903 break; |
904 } | 904 } |
905 } | 905 } |
906 | 906 |
907 void SkClipStack::dump() const { | 907 void SkClipStack::dump() const { |
908 B2TIter iter(*this); | 908 B2TIter iter(*this); |
909 const Element* e; | 909 const Element* e; |
910 while ((e = iter.next())) { | 910 while ((e = iter.next())) { |
911 e->dump(); | 911 e->dump(); |
912 SkDebugf("\n"); | 912 SkDebugf("\n"); |
913 } | 913 } |
914 } | 914 } |
915 #endif | 915 #endif |
OLD | NEW |