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

Side by Side Diff: src/core/SkClipStack.cpp

Issue 2355483002: abstract name of clipping ops, to transtion to a more restricted set (Closed)
Patch Set: no need for ifdef for globals Created 4 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 | « src/core/SkCanvas.cpp ('k') | src/core/SkLiteDL.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 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 case kPath_Type: 76 case kPath_Type:
77 visitor->clipPath(this->getPath(), this->getOp(), this->isAA()); 77 visitor->clipPath(this->getPath(), this->getOp(), this->isAA());
78 break; 78 break;
79 case kRRect_Type: 79 case kRRect_Type:
80 visitor->clipRRect(this->getRRect(), this->getOp(), this->isAA()); 80 visitor->clipRRect(this->getRRect(), this->getOp(), this->isAA());
81 break; 81 break;
82 case kRect_Type: 82 case kRect_Type:
83 visitor->clipRect(this->getRect(), this->getOp(), this->isAA()); 83 visitor->clipRect(this->getRect(), this->getOp(), this->isAA());
84 break; 84 break;
85 case kEmpty_Type: 85 case kEmpty_Type:
86 visitor->clipRect(kEmptyRect, SkRegion::kIntersect_Op, false); 86 visitor->clipRect(kEmptyRect, SkCanvas::kIntersect_Op, false);
87 break; 87 break;
88 } 88 }
89 } 89 }
90 90
91 void SkClipStack::Element::invertShapeFillType() { 91 void SkClipStack::Element::invertShapeFillType() {
92 switch (fType) { 92 switch (fType) {
93 case kRect_Type: 93 case kRect_Type:
94 fPath.init(); 94 fPath.init();
95 fPath.get()->addRect(this->getRect()); 95 fPath.get()->addRect(this->getRect());
96 fPath.get()->setFillType(SkPath::kInverseEvenOdd_FillType); 96 fPath.get()->setFillType(SkPath::kInverseEvenOdd_FillType);
97 fType = kPath_Type; 97 fType = kPath_Type;
98 break; 98 break;
99 case kRRect_Type: 99 case kRRect_Type:
100 fPath.init(); 100 fPath.init();
101 fPath.get()->addRRect(fRRect); 101 fPath.get()->addRRect(fRRect);
102 fPath.get()->setFillType(SkPath::kInverseEvenOdd_FillType); 102 fPath.get()->setFillType(SkPath::kInverseEvenOdd_FillType);
103 fType = kPath_Type; 103 fType = kPath_Type;
104 break; 104 break;
105 case kPath_Type: 105 case kPath_Type:
106 fPath.get()->toggleInverseFillType(); 106 fPath.get()->toggleInverseFillType();
107 break; 107 break;
108 case kEmpty_Type: 108 case kEmpty_Type:
109 // Should this set to an empty, inverse filled path? 109 // Should this set to an empty, inverse filled path?
110 break; 110 break;
111 } 111 }
112 } 112 }
113 113
114 void SkClipStack::Element::initPath(int saveCount, const SkPath& path, SkRegion: :Op op, 114 void SkClipStack::Element::initPath(int saveCount, const SkPath& path, SkCanvas: :ClipOp op,
115 bool doAA) { 115 bool doAA) {
116 if (!path.isInverseFillType()) { 116 if (!path.isInverseFillType()) {
117 SkRect r; 117 SkRect r;
118 if (path.isRect(&r)) { 118 if (path.isRect(&r)) {
119 this->initRect(saveCount, r, op, doAA); 119 this->initRect(saveCount, r, op, doAA);
120 return; 120 return;
121 } 121 }
122 SkRect ovalRect; 122 SkRect ovalRect;
123 if (path.isOval(&ovalRect)) { 123 if (path.isOval(&ovalRect)) {
124 SkRRect rrect; 124 SkRRect rrect;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 169
170 void SkClipStack::Element::checkEmpty() const { 170 void SkClipStack::Element::checkEmpty() const {
171 SkASSERT(fFiniteBound.isEmpty()); 171 SkASSERT(fFiniteBound.isEmpty());
172 SkASSERT(kNormal_BoundsType == fFiniteBoundType); 172 SkASSERT(kNormal_BoundsType == fFiniteBoundType);
173 SkASSERT(!fIsIntersectionOfRects); 173 SkASSERT(!fIsIntersectionOfRects);
174 SkASSERT(kEmptyGenID == fGenID); 174 SkASSERT(kEmptyGenID == fGenID);
175 SkASSERT(fRRect.isEmpty()); 175 SkASSERT(fRRect.isEmpty());
176 SkASSERT(!fPath.isValid()); 176 SkASSERT(!fPath.isValid());
177 } 177 }
178 178
179 bool SkClipStack::Element::canBeIntersectedInPlace(int saveCount, SkRegion::Op o p) const { 179 bool SkClipStack::Element::canBeIntersectedInPlace(int saveCount, SkCanvas::Clip Op op) const {
180 if (kEmpty_Type == fType && 180 if (kEmpty_Type == fType &&
181 (SkRegion::kDifference_Op == op || SkRegion::kIntersect_Op == op)) { 181 (SkCanvas::kDifference_Op == op || SkCanvas::kIntersect_Op == op)) {
182 return true; 182 return true;
183 } 183 }
184 // Only clips within the same save/restore frame (as captured by 184 // Only clips within the same save/restore frame (as captured by
185 // the save count) can be merged 185 // the save count) can be merged
186 return fSaveCount == saveCount && 186 return fSaveCount == saveCount &&
187 SkRegion::kIntersect_Op == op && 187 SkCanvas::kIntersect_Op == op &&
188 (SkRegion::kIntersect_Op == fOp || SkRegion::kReplace_Op == fOp); 188 (SkCanvas::kIntersect_Op == fOp || SkCanvas::kReplace_Op == fOp);
189 } 189 }
190 190
191 bool SkClipStack::Element::rectRectIntersectAllowed(const SkRect& newR, bool new AA) const { 191 bool SkClipStack::Element::rectRectIntersectAllowed(const SkRect& newR, bool new AA) const {
192 SkASSERT(kRect_Type == fType); 192 SkASSERT(kRect_Type == fType);
193 193
194 if (fDoAA == newAA) { 194 if (fDoAA == newAA) {
195 // if the AA setting is the same there is no issue 195 // if the AA setting is the same there is no issue
196 return true; 196 return true;
197 } 197 }
198 198
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 fGenID = GetNextGenID(); 392 fGenID = GetNextGenID();
393 393
394 // First, optimistically update the current Element's bound information 394 // First, optimistically update the current Element's bound information
395 // with the current clip's bound 395 // with the current clip's bound
396 fIsIntersectionOfRects = false; 396 fIsIntersectionOfRects = false;
397 switch (fType) { 397 switch (fType) {
398 case kRect_Type: 398 case kRect_Type:
399 fFiniteBound = this->getRect(); 399 fFiniteBound = this->getRect();
400 fFiniteBoundType = kNormal_BoundsType; 400 fFiniteBoundType = kNormal_BoundsType;
401 401
402 if (SkRegion::kReplace_Op == fOp || 402 if (SkCanvas::kReplace_Op == fOp ||
403 (SkRegion::kIntersect_Op == fOp && nullptr == prior) || 403 (SkCanvas::kIntersect_Op == fOp && nullptr == prior) ||
404 (SkRegion::kIntersect_Op == fOp && prior->fIsIntersectionOfRects && 404 (SkCanvas::kIntersect_Op == fOp && prior->fIsIntersectionOfRects &&
405 prior->rectRectIntersectAllowed(this->getRect(), fDoAA))) { 405 prior->rectRectIntersectAllowed(this->getRect(), fDoAA))) {
406 fIsIntersectionOfRects = true; 406 fIsIntersectionOfRects = true;
407 } 407 }
408 break; 408 break;
409 case kRRect_Type: 409 case kRRect_Type:
410 fFiniteBound = fRRect.getBounds(); 410 fFiniteBound = fRRect.getBounds();
411 fFiniteBoundType = kNormal_BoundsType; 411 fFiniteBoundType = kNormal_BoundsType;
412 break; 412 break;
413 case kPath_Type: 413 case kPath_Type:
414 fFiniteBound = fPath.get()->getBounds(); 414 fFiniteBound = fPath.get()->getBounds();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 combination = (FillCombo) (combination | 0x02); 453 combination = (FillCombo) (combination | 0x02);
454 } 454 }
455 455
456 SkASSERT(kInvPrev_InvCur_FillCombo == combination || 456 SkASSERT(kInvPrev_InvCur_FillCombo == combination ||
457 kInvPrev_Cur_FillCombo == combination || 457 kInvPrev_Cur_FillCombo == combination ||
458 kPrev_InvCur_FillCombo == combination || 458 kPrev_InvCur_FillCombo == combination ||
459 kPrev_Cur_FillCombo == combination); 459 kPrev_Cur_FillCombo == combination);
460 460
461 // Now integrate with clip with the prior clips 461 // Now integrate with clip with the prior clips
462 switch (fOp) { 462 switch (fOp) {
463 case SkRegion::kDifference_Op: 463 case SkCanvas::kDifference_Op:
464 this->combineBoundsDiff(combination, prevFinite); 464 this->combineBoundsDiff(combination, prevFinite);
465 break; 465 break;
466 case SkRegion::kXOR_Op: 466 case SkCanvas::kXOR_Op:
467 this->combineBoundsXOR(combination, prevFinite); 467 this->combineBoundsXOR(combination, prevFinite);
468 break; 468 break;
469 case SkRegion::kUnion_Op: 469 case SkCanvas::kUnion_Op:
470 this->combineBoundsUnion(combination, prevFinite); 470 this->combineBoundsUnion(combination, prevFinite);
471 break; 471 break;
472 case SkRegion::kIntersect_Op: 472 case SkCanvas::kIntersect_Op:
473 this->combineBoundsIntersection(combination, prevFinite); 473 this->combineBoundsIntersection(combination, prevFinite);
474 break; 474 break;
475 case SkRegion::kReverseDifference_Op: 475 case SkCanvas::kReverseDifference_Op:
476 this->combineBoundsRevDiff(combination, prevFinite); 476 this->combineBoundsRevDiff(combination, prevFinite);
477 break; 477 break;
478 case SkRegion::kReplace_Op: 478 case SkCanvas::kReplace_Op:
479 // Replace just ignores everything prior 479 // Replace just ignores everything prior
480 // The current clip's bound information is already filled in 480 // The current clip's bound information is already filled in
481 // so nothing to do 481 // so nothing to do
482 break; 482 break;
483 default: 483 default:
484 SkDebugf("SkRegion::Op error\n"); 484 SkDebugf("SkCanvas::ClipOp error\n");
485 SkASSERT(0); 485 SkASSERT(0);
486 break; 486 break;
487 } 487 }
488 } 488 }
489 489
490 // This constant determines how many Element's are allocated together as a block in 490 // This constant determines how many Element's are allocated together as a block in
491 // the deque. As such it needs to balance allocating too much memory vs. 491 // the deque. As such it needs to balance allocating too much memory vs.
492 // incurring allocation/deallocation thrashing. It should roughly correspond to 492 // incurring allocation/deallocation thrashing. It should roughly correspond to
493 // the deepest save/restore stack we expect to see. 493 // the deepest save/restore stack we expect to see.
494 static const int kDefaultElementAllocCnt = 8; 494 static const int kDefaultElementAllocCnt = 8;
495 495
496 SkClipStack::SkClipStack() 496 SkClipStack::SkClipStack()
497 : fDeque(sizeof(Element), kDefaultElementAllocCnt) 497 : fDeque(sizeof(Element), kDefaultElementAllocCnt)
498 , fSaveCount(0) { 498 , fSaveCount(0) {
499 } 499 }
500 500
501 SkClipStack::SkClipStack(const SkClipStack& b) 501 SkClipStack::SkClipStack(const SkClipStack& b)
502 : fDeque(sizeof(Element), kDefaultElementAllocCnt) { 502 : fDeque(sizeof(Element), kDefaultElementAllocCnt) {
503 *this = b; 503 *this = b;
504 } 504 }
505 505
506 SkClipStack::SkClipStack(const SkRect& r) 506 SkClipStack::SkClipStack(const SkRect& r)
507 : fDeque(sizeof(Element), kDefaultElementAllocCnt) 507 : fDeque(sizeof(Element), kDefaultElementAllocCnt)
508 , fSaveCount(0) { 508 , fSaveCount(0) {
509 if (!r.isEmpty()) { 509 if (!r.isEmpty()) {
510 this->clipDevRect(r, SkRegion::kReplace_Op, false); 510 this->clipDevRect(r, SkCanvas::kReplace_Op, false);
511 } 511 }
512 } 512 }
513 513
514 SkClipStack::SkClipStack(const SkIRect& r) 514 SkClipStack::SkClipStack(const SkIRect& r)
515 : fDeque(sizeof(Element), kDefaultElementAllocCnt) 515 : fDeque(sizeof(Element), kDefaultElementAllocCnt)
516 , fSaveCount(0) { 516 , fSaveCount(0) {
517 if (!r.isEmpty()) { 517 if (!r.isEmpty()) {
518 SkRect temp; 518 SkRect temp;
519 temp.set(r); 519 temp.set(r);
520 this->clipDevRect(temp, SkRegion::kReplace_Op, false); 520 this->clipDevRect(temp, SkCanvas::kReplace_Op, false);
521 } 521 }
522 } 522 }
523 523
524 SkClipStack::~SkClipStack() { 524 SkClipStack::~SkClipStack() {
525 reset(); 525 reset();
526 } 526 }
527 527
528 SkClipStack& SkClipStack::operator=(const SkClipStack& b) { 528 SkClipStack& SkClipStack::operator=(const SkClipStack& b) {
529 if (this == &b) { 529 if (this == &b) {
530 return *this; 530 return *this;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 if (isIntersectionOfRects) { 619 if (isIntersectionOfRects) {
620 *isIntersectionOfRects = element->fIsIntersectionOfRects; 620 *isIntersectionOfRects = element->fIsIntersectionOfRects;
621 } 621 }
622 } 622 }
623 623
624 bool SkClipStack::internalQuickContains(const SkRect& rect) const { 624 bool SkClipStack::internalQuickContains(const SkRect& rect) const {
625 625
626 Iter iter(*this, Iter::kTop_IterStart); 626 Iter iter(*this, Iter::kTop_IterStart);
627 const Element* element = iter.prev(); 627 const Element* element = iter.prev();
628 while (element != nullptr) { 628 while (element != nullptr) {
629 if (SkRegion::kIntersect_Op != element->getOp() && SkRegion::kReplace_Op != element->getOp()) 629 if (SkCanvas::kIntersect_Op != element->getOp() && SkCanvas::kReplace_Op != element->getOp())
630 return false; 630 return false;
631 if (element->isInverseFilled()) { 631 if (element->isInverseFilled()) {
632 // Part of 'rect' could be trimmed off by the inverse-filled clip el ement 632 // Part of 'rect' could be trimmed off by the inverse-filled clip el ement
633 if (SkRect::Intersects(element->getBounds(), rect)) { 633 if (SkRect::Intersects(element->getBounds(), rect)) {
634 return false; 634 return false;
635 } 635 }
636 } else { 636 } else {
637 if (!element->contains(rect)) { 637 if (!element->contains(rect)) {
638 return false; 638 return false;
639 } 639 }
640 } 640 }
641 if (SkRegion::kReplace_Op == element->getOp()) { 641 if (SkCanvas::kReplace_Op == element->getOp()) {
642 break; 642 break;
643 } 643 }
644 element = iter.prev(); 644 element = iter.prev();
645 } 645 }
646 return true; 646 return true;
647 } 647 }
648 648
649 bool SkClipStack::internalQuickContains(const SkRRect& rrect) const { 649 bool SkClipStack::internalQuickContains(const SkRRect& rrect) const {
650 650
651 Iter iter(*this, Iter::kTop_IterStart); 651 Iter iter(*this, Iter::kTop_IterStart);
652 const Element* element = iter.prev(); 652 const Element* element = iter.prev();
653 while (element != nullptr) { 653 while (element != nullptr) {
654 if (SkRegion::kIntersect_Op != element->getOp() && SkRegion::kReplace_Op != element->getOp()) 654 if (SkCanvas::kIntersect_Op != element->getOp() && SkCanvas::kReplace_Op != element->getOp())
655 return false; 655 return false;
656 if (element->isInverseFilled()) { 656 if (element->isInverseFilled()) {
657 // Part of 'rrect' could be trimmed off by the inverse-filled clip e lement 657 // Part of 'rrect' could be trimmed off by the inverse-filled clip e lement
658 if (SkRect::Intersects(element->getBounds(), rrect.getBounds())) { 658 if (SkRect::Intersects(element->getBounds(), rrect.getBounds())) {
659 return false; 659 return false;
660 } 660 }
661 } else { 661 } else {
662 if (!element->contains(rrect)) { 662 if (!element->contains(rrect)) {
663 return false; 663 return false;
664 } 664 }
665 } 665 }
666 if (SkRegion::kReplace_Op == element->getOp()) { 666 if (SkCanvas::kReplace_Op == element->getOp()) {
667 break; 667 break;
668 } 668 }
669 element = iter.prev(); 669 element = iter.prev();
670 } 670 }
671 return true; 671 return true;
672 } 672 }
673 673
674 bool SkClipStack::asPath(SkPath *path) const { 674 bool SkClipStack::asPath(SkPath *path) const {
675 bool isAA = false; 675 bool isAA = false;
676 676
677 path->reset(); 677 path->reset();
678 path->setFillType(SkPath::kInverseEvenOdd_FillType); 678 path->setFillType(SkPath::kInverseEvenOdd_FillType);
679 679
680 SkClipStack::Iter iter(*this, SkClipStack::Iter::kBottom_IterStart); 680 SkClipStack::Iter iter(*this, SkClipStack::Iter::kBottom_IterStart);
681 while (const SkClipStack::Element* element = iter.next()) { 681 while (const SkClipStack::Element* element = iter.next()) {
682 SkPath operand; 682 SkPath operand;
683 if (element->getType() != SkClipStack::Element::kEmpty_Type) { 683 if (element->getType() != SkClipStack::Element::kEmpty_Type) {
684 element->asPath(&operand); 684 element->asPath(&operand);
685 } 685 }
686 686
687 SkRegion::Op elementOp = element->getOp(); 687 SkCanvas::ClipOp elementOp = element->getOp();
688 if (elementOp == SkRegion::kReplace_Op) { 688 if (elementOp == SkCanvas::kReplace_Op) {
689 *path = operand; 689 *path = operand;
690 } else { 690 } else {
691 Op(*path, operand, (SkPathOp)elementOp, path); 691 Op(*path, operand, (SkPathOp)elementOp, path);
692 } 692 }
693 693
694 // if the prev and curr clips disagree about aa -vs- not, favor the aa r equest. 694 // if the prev and curr clips disagree about aa -vs- not, favor the aa r equest.
695 // perhaps we need an API change to avoid this sort of mixed-signals abo ut 695 // perhaps we need an API change to avoid this sort of mixed-signals abo ut
696 // clipping. 696 // clipping.
697 isAA = (isAA || element->isAA()); 697 isAA = (isAA || element->isAA());
698 } 698 }
(...skipping 30 matching lines...) Expand all
729 break; 729 break;
730 } 730 }
731 // fallthrough 731 // fallthrough
732 default: 732 default:
733 if (!SkRect::Intersects(prior->getBounds(), element.getBound s())) { 733 if (!SkRect::Intersects(prior->getBounds(), element.getBound s())) {
734 prior->setEmpty(); 734 prior->setEmpty();
735 return; 735 return;
736 } 736 }
737 break; 737 break;
738 } 738 }
739 } else if (SkRegion::kReplace_Op == element.getOp()) { 739 } else if (SkCanvas::kReplace_Op == element.getOp()) {
740 this->restoreTo(fSaveCount - 1); 740 this->restoreTo(fSaveCount - 1);
741 prior = (Element*) fDeque.back(); 741 prior = (Element*) fDeque.back();
742 } 742 }
743 } 743 }
744 Element* newElement = new (fDeque.push_back()) Element(element); 744 Element* newElement = new (fDeque.push_back()) Element(element);
745 newElement->updateBoundAndGenID(prior); 745 newElement->updateBoundAndGenID(prior);
746 } 746 }
747 747
748 void SkClipStack::clipDevRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { 748 void SkClipStack::clipDevRRect(const SkRRect& rrect, SkCanvas::ClipOp op, bool d oAA) {
749 Element element(fSaveCount, rrect, op, doAA); 749 Element element(fSaveCount, rrect, op, doAA);
750 this->pushElement(element); 750 this->pushElement(element);
751 } 751 }
752 752
753 void SkClipStack::clipDevRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 753 void SkClipStack::clipDevRect(const SkRect& rect, SkCanvas::ClipOp op, bool doAA ) {
754 Element element(fSaveCount, rect, op, doAA); 754 Element element(fSaveCount, rect, op, doAA);
755 this->pushElement(element); 755 this->pushElement(element);
756 } 756 }
757 757
758 void SkClipStack::clipDevPath(const SkPath& path, SkRegion::Op op, bool doAA) { 758 void SkClipStack::clipDevPath(const SkPath& path, SkCanvas::ClipOp op, bool doAA ) {
759 Element element(fSaveCount, path, op, doAA); 759 Element element(fSaveCount, path, op, doAA);
760 this->pushElement(element); 760 this->pushElement(element);
761 } 761 }
762 762
763 void SkClipStack::clipEmpty() { 763 void SkClipStack::clipEmpty() {
764 Element* element = (Element*) fDeque.back(); 764 Element* element = (Element*) fDeque.back();
765 765
766 if (element && element->canBeIntersectedInPlace(fSaveCount, SkRegion::kInter sect_Op)) { 766 if (element && element->canBeIntersectedInPlace(fSaveCount, SkCanvas::kInter sect_Op)) {
767 element->setEmpty(); 767 element->setEmpty();
768 } 768 }
769 new (fDeque.push_back()) Element(fSaveCount); 769 new (fDeque.push_back()) Element(fSaveCount);
770 770
771 ((Element*)fDeque.back())->fGenID = kEmptyGenID; 771 ((Element*)fDeque.back())->fGenID = kEmptyGenID;
772 } 772 }
773 773
774 /////////////////////////////////////////////////////////////////////////////// 774 ///////////////////////////////////////////////////////////////////////////////
775 775
776 SkClipStack::Iter::Iter() : fStack(nullptr) { 776 SkClipStack::Iter::Iter() : fStack(nullptr) {
777 } 777 }
778 778
779 SkClipStack::Iter::Iter(const SkClipStack& stack, IterStart startLoc) 779 SkClipStack::Iter::Iter(const SkClipStack& stack, IterStart startLoc)
780 : fStack(&stack) { 780 : fStack(&stack) {
781 this->reset(stack, startLoc); 781 this->reset(stack, startLoc);
782 } 782 }
783 783
784 const SkClipStack::Element* SkClipStack::Iter::next() { 784 const SkClipStack::Element* SkClipStack::Iter::next() {
785 return (const SkClipStack::Element*)fIter.next(); 785 return (const SkClipStack::Element*)fIter.next();
786 } 786 }
787 787
788 const SkClipStack::Element* SkClipStack::Iter::prev() { 788 const SkClipStack::Element* SkClipStack::Iter::prev() {
789 return (const SkClipStack::Element*)fIter.prev(); 789 return (const SkClipStack::Element*)fIter.prev();
790 } 790 }
791 791
792 const SkClipStack::Element* SkClipStack::Iter::skipToTopmost(SkRegion::Op op) { 792 const SkClipStack::Element* SkClipStack::Iter::skipToTopmost(SkCanvas::ClipOp op ) {
793 793
794 if (nullptr == fStack) { 794 if (nullptr == fStack) {
795 return nullptr; 795 return nullptr;
796 } 796 }
797 797
798 fIter.reset(fStack->fDeque, SkDeque::Iter::kBack_IterStart); 798 fIter.reset(fStack->fDeque, SkDeque::Iter::kBack_IterStart);
799 799
800 const SkClipStack::Element* element = nullptr; 800 const SkClipStack::Element* element = nullptr;
801 801
802 for (element = (const SkClipStack::Element*) fIter.prev(); 802 for (element = (const SkClipStack::Element*) fIter.prev();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 // it is an rrect. 867 // it is an rrect.
868 int cnt = fDeque.count(); 868 int cnt = fDeque.count();
869 if (!cnt || cnt > 5) { 869 if (!cnt || cnt > 5) {
870 return false; 870 return false;
871 } 871 }
872 const Element* back = static_cast<const Element*>(fDeque.back()); 872 const Element* back = static_cast<const Element*>(fDeque.back());
873 if (back->getType() != SkClipStack::Element::kRect_Type && 873 if (back->getType() != SkClipStack::Element::kRect_Type &&
874 back->getType() != SkClipStack::Element::kRRect_Type) { 874 back->getType() != SkClipStack::Element::kRRect_Type) {
875 return false; 875 return false;
876 } 876 }
877 if (back->getOp() == SkRegion::kReplace_Op) { 877 if (back->getOp() == SkCanvas::kReplace_Op) {
878 *rrect = back->asRRect(); 878 *rrect = back->asRRect();
879 *aa = back->isAA(); 879 *aa = back->isAA();
880 return true; 880 return true;
881 } 881 }
882 882
883 if (back->getOp() == SkRegion::kIntersect_Op) { 883 if (back->getOp() == SkCanvas::kIntersect_Op) {
884 SkRect backBounds; 884 SkRect backBounds;
885 if (!backBounds.intersect(bounds, back->asRRect().rect())) { 885 if (!backBounds.intersect(bounds, back->asRRect().rect())) {
886 return false; 886 return false;
887 } 887 }
888 if (cnt > 1) { 888 if (cnt > 1) {
889 SkDeque::Iter iter(fDeque, SkDeque::Iter::kBack_IterStart); 889 SkDeque::Iter iter(fDeque, SkDeque::Iter::kBack_IterStart);
890 SkAssertResult(static_cast<const Element*>(iter.prev()) == back); 890 SkAssertResult(static_cast<const Element*>(iter.prev()) == back);
891 while (const Element* prior = (const Element*)iter.prev()) { 891 while (const Element* prior = (const Element*)iter.prev()) {
892 if ((prior->getOp() != SkRegion::kIntersect_Op && 892 if ((prior->getOp() != SkCanvas::kIntersect_Op &&
893 prior->getOp() != SkRegion::kReplace_Op) || 893 prior->getOp() != SkCanvas::kReplace_Op) ||
894 !prior->contains(backBounds)) { 894 !prior->contains(backBounds)) {
895 return false; 895 return false;
896 } 896 }
897 if (prior->getOp() == SkRegion::kReplace_Op) { 897 if (prior->getOp() == SkCanvas::kReplace_Op) {
898 break; 898 break;
899 } 899 }
900 } 900 }
901 } 901 }
902 *rrect = back->asRRect(); 902 *rrect = back->asRRect();
903 *aa = back->isAA(); 903 *aa = back->isAA();
904 return true; 904 return true;
905 } 905 }
906 return false; 906 return false;
907 } 907 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
939 static_assert(SK_ARRAY_COUNT(kTypeStrings) == kTypeCnt, "type_str"); 939 static_assert(SK_ARRAY_COUNT(kTypeStrings) == kTypeCnt, "type_str");
940 940
941 static const char* kOpStrings[] = { 941 static const char* kOpStrings[] = {
942 "difference", 942 "difference",
943 "intersect", 943 "intersect",
944 "union", 944 "union",
945 "xor", 945 "xor",
946 "reverse-difference", 946 "reverse-difference",
947 "replace", 947 "replace",
948 }; 948 };
949 static_assert(0 == SkRegion::kDifference_Op, "op_str"); 949 static_assert(0 == SkCanvas::kDifference_Op, "op_str");
950 static_assert(1 == SkRegion::kIntersect_Op, "op_str"); 950 static_assert(1 == SkCanvas::kIntersect_Op, "op_str");
951 static_assert(2 == SkRegion::kUnion_Op, "op_str"); 951 static_assert(2 == SkCanvas::kUnion_Op, "op_str");
952 static_assert(3 == SkRegion::kXOR_Op, "op_str"); 952 static_assert(3 == SkCanvas::kXOR_Op, "op_str");
953 static_assert(4 == SkRegion::kReverseDifference_Op, "op_str"); 953 static_assert(4 == SkCanvas::kReverseDifference_Op, "op_str");
954 static_assert(5 == SkRegion::kReplace_Op, "op_str"); 954 static_assert(5 == SkCanvas::kReplace_Op, "op_str");
955 static_assert(SK_ARRAY_COUNT(kOpStrings) == SkRegion::kOpCnt, "op_str"); 955 static_assert(SK_ARRAY_COUNT(kOpStrings) == SkRegion::kOpCnt, "op_str");
956 956
957 SkDebugf("Type: %s, Op: %s, AA: %s, Save Count: %d\n", kTypeStrings[fType], 957 SkDebugf("Type: %s, Op: %s, AA: %s, Save Count: %d\n", kTypeStrings[fType],
958 kOpStrings[fOp], (fDoAA ? "yes" : "no"), fSaveCount); 958 kOpStrings[fOp], (fDoAA ? "yes" : "no"), fSaveCount);
959 switch (fType) { 959 switch (fType) {
960 case kEmpty_Type: 960 case kEmpty_Type:
961 SkDebugf("\n"); 961 SkDebugf("\n");
962 break; 962 break;
963 case kRect_Type: 963 case kRect_Type:
964 this->getRect().dump(); 964 this->getRect().dump();
(...skipping 11 matching lines...) Expand all
976 976
977 void SkClipStack::dump() const { 977 void SkClipStack::dump() const {
978 B2TIter iter(*this); 978 B2TIter iter(*this);
979 const Element* e; 979 const Element* e;
980 while ((e = iter.next())) { 980 while ((e = iter.next())) {
981 e->dump(); 981 e->dump();
982 SkDebugf("\n"); 982 SkDebugf("\n");
983 } 983 }
984 } 984 }
985 #endif 985 #endif
OLDNEW
« no previous file with comments | « src/core/SkCanvas.cpp ('k') | src/core/SkLiteDL.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698