| 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 14 matching lines...) Expand all Loading... |
| 25 fDoAA != element.fDoAA || | 25 fDoAA != element.fDoAA || |
| 26 fSaveCount != element.fSaveCount) { | 26 fSaveCount != element.fSaveCount) { |
| 27 return false; | 27 return false; |
| 28 } | 28 } |
| 29 switch (fType) { | 29 switch (fType) { |
| 30 case kPath_Type: | 30 case kPath_Type: |
| 31 return fPath == element.fPath; | 31 return fPath == element.fPath; |
| 32 case kRRect_Type: | 32 case kRRect_Type: |
| 33 return fRRect == element.fRRect; | 33 return fRRect == element.fRRect; |
| 34 case kRect_Type: | 34 case kRect_Type: |
| 35 return fRect == element.fRect; | 35 return this->getRect() == element.getRect(); |
| 36 case kEmpty_Type: | 36 case kEmpty_Type: |
| 37 return true; | 37 return true; |
| 38 default: | 38 default: |
| 39 SkDEBUGFAIL("Unexpected type."); | 39 SkDEBUGFAIL("Unexpected type."); |
| 40 return false; | 40 return false; |
| 41 } | 41 } |
| 42 } | 42 } |
| 43 | 43 |
| 44 void SkClipStack::Element::invertShapeFillType() { | 44 void SkClipStack::Element::invertShapeFillType() { |
| 45 switch (fType) { | 45 switch (fType) { |
| 46 case kRect_Type: | 46 case kRect_Type: |
| 47 fPath.reset(); | 47 fPath.reset(); |
| 48 fPath.addRect(fRect); | 48 fPath.addRect(this->getRect()); |
| 49 fPath.setFillType(SkPath::kInverseEvenOdd_FillType); | 49 fPath.setFillType(SkPath::kInverseEvenOdd_FillType); |
| 50 fType = kPath_Type; | 50 fType = kPath_Type; |
| 51 break; | 51 break; |
| 52 case kRRect_Type: | 52 case kRRect_Type: |
| 53 fPath.reset(); | 53 fPath.reset(); |
| 54 fPath.addRRect(fRRect); | 54 fPath.addRRect(fRRect); |
| 55 fPath.setFillType(SkPath::kInverseEvenOdd_FillType); | 55 fPath.setFillType(SkPath::kInverseEvenOdd_FillType); |
| 56 fType = kPath_Type; | 56 fType = kPath_Type; |
| 57 break; | 57 break; |
| 58 case kPath_Type: | 58 case kPath_Type: |
| (...skipping 25 matching lines...) Expand all Loading... |
| 84 this->initCommon(saveCount, op, doAA); | 84 this->initCommon(saveCount, op, doAA); |
| 85 } | 85 } |
| 86 | 86 |
| 87 void SkClipStack::Element::asPath(SkPath* path) const { | 87 void SkClipStack::Element::asPath(SkPath* path) const { |
| 88 switch (fType) { | 88 switch (fType) { |
| 89 case kEmpty_Type: | 89 case kEmpty_Type: |
| 90 path->reset(); | 90 path->reset(); |
| 91 break; | 91 break; |
| 92 case kRect_Type: | 92 case kRect_Type: |
| 93 path->reset(); | 93 path->reset(); |
| 94 path->addRect(fRect); | 94 path->addRect(this->getRect()); |
| 95 break; | 95 break; |
| 96 case kRRect_Type: | 96 case kRRect_Type: |
| 97 path->reset(); | 97 path->reset(); |
| 98 path->addRRect(fRRect); | 98 path->addRRect(fRRect); |
| 99 break; | 99 break; |
| 100 case kPath_Type: | 100 case kPath_Type: |
| 101 *path = fPath; | 101 *path = fPath; |
| 102 break; | 102 break; |
| 103 } | 103 } |
| 104 } | 104 } |
| 105 | 105 |
| 106 void SkClipStack::Element::setEmpty() { | 106 void SkClipStack::Element::setEmpty() { |
| 107 fType = kEmpty_Type; | 107 fType = kEmpty_Type; |
| 108 fFiniteBound.setEmpty(); | 108 fFiniteBound.setEmpty(); |
| 109 fFiniteBoundType = kNormal_BoundsType; | 109 fFiniteBoundType = kNormal_BoundsType; |
| 110 fIsIntersectionOfRects = false; | 110 fIsIntersectionOfRects = false; |
| 111 fRect.setEmpty(); | |
| 112 fRRect.setEmpty(); | 111 fRRect.setEmpty(); |
| 113 fPath.reset(); | 112 fPath.reset(); |
| 114 fGenID = kEmptyGenID; | 113 fGenID = kEmptyGenID; |
| 115 SkDEBUGCODE(this->checkEmpty();) | 114 SkDEBUGCODE(this->checkEmpty();) |
| 116 } | 115 } |
| 117 | 116 |
| 118 void SkClipStack::Element::checkEmpty() const { | 117 void SkClipStack::Element::checkEmpty() const { |
| 119 SkASSERT(fFiniteBound.isEmpty()); | 118 SkASSERT(fFiniteBound.isEmpty()); |
| 120 SkASSERT(kNormal_BoundsType == fFiniteBoundType); | 119 SkASSERT(kNormal_BoundsType == fFiniteBoundType); |
| 121 SkASSERT(!fIsIntersectionOfRects); | 120 SkASSERT(!fIsIntersectionOfRects); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 136 } | 135 } |
| 137 | 136 |
| 138 bool SkClipStack::Element::rectRectIntersectAllowed(const SkRect& newR, bool new
AA) const { | 137 bool SkClipStack::Element::rectRectIntersectAllowed(const SkRect& newR, bool new
AA) const { |
| 139 SkASSERT(kRect_Type == fType); | 138 SkASSERT(kRect_Type == fType); |
| 140 | 139 |
| 141 if (fDoAA == newAA) { | 140 if (fDoAA == newAA) { |
| 142 // if the AA setting is the same there is no issue | 141 // if the AA setting is the same there is no issue |
| 143 return true; | 142 return true; |
| 144 } | 143 } |
| 145 | 144 |
| 146 if (!SkRect::Intersects(fRect, newR)) { | 145 if (!SkRect::Intersects(this->getRect(), newR)) { |
| 147 // The calling code will correctly set the result to the empty clip | 146 // The calling code will correctly set the result to the empty clip |
| 148 return true; | 147 return true; |
| 149 } | 148 } |
| 150 | 149 |
| 151 if (fRect.contains(newR)) { | 150 if (this->getRect().contains(newR)) { |
| 152 // if the new rect carves out a portion of the old one there is no | 151 // if the new rect carves out a portion of the old one there is no |
| 153 // issue | 152 // issue |
| 154 return true; | 153 return true; |
| 155 } | 154 } |
| 156 | 155 |
| 157 // So either the two overlap in some complex manner or newR contains oldR. | 156 // So either the two overlap in some complex manner or newR contains oldR. |
| 158 // In the first, case the edges will require different AA. In the second, | 157 // In the first, case the edges will require different AA. In the second, |
| 159 // the AA setting that would be carried forward is incorrect (e.g., oldR | 158 // the AA setting that would be carried forward is incorrect (e.g., oldR |
| 160 // is AA while newR is BW but since newR contains oldR, oldR will be | 159 // is AA while newR is BW but since newR contains oldR, oldR will be |
| 161 // drawn BW) since the new AA setting will predominate. | 160 // drawn BW) since the new AA setting will predominate. |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 void SkClipStack::Element::updateBoundAndGenID(const Element* prior) { | 335 void SkClipStack::Element::updateBoundAndGenID(const Element* prior) { |
| 337 // We set this first here but we may overwrite it later if we determine that
the clip is | 336 // We set this first here but we may overwrite it later if we determine that
the clip is |
| 338 // either wide-open or empty. | 337 // either wide-open or empty. |
| 339 fGenID = GetNextGenID(); | 338 fGenID = GetNextGenID(); |
| 340 | 339 |
| 341 // First, optimistically update the current Element's bound information | 340 // First, optimistically update the current Element's bound information |
| 342 // with the current clip's bound | 341 // with the current clip's bound |
| 343 fIsIntersectionOfRects = false; | 342 fIsIntersectionOfRects = false; |
| 344 switch (fType) { | 343 switch (fType) { |
| 345 case kRect_Type: | 344 case kRect_Type: |
| 346 fFiniteBound = fRect; | 345 fFiniteBound = this->getRect(); |
| 347 fFiniteBoundType = kNormal_BoundsType; | 346 fFiniteBoundType = kNormal_BoundsType; |
| 348 | 347 |
| 349 if (SkRegion::kReplace_Op == fOp || | 348 if (SkRegion::kReplace_Op == fOp || |
| 350 (SkRegion::kIntersect_Op == fOp && NULL == prior) || | 349 (SkRegion::kIntersect_Op == fOp && NULL == prior) || |
| 351 (SkRegion::kIntersect_Op == fOp && prior->fIsIntersectionOfRects
&& | 350 (SkRegion::kIntersect_Op == fOp && prior->fIsIntersectionOfRects
&& |
| 352 prior->rectRectIntersectAllowed(fRect, fDoAA))) { | 351 prior->rectRectIntersectAllowed(this->getRect(), fDoAA))) { |
| 353 fIsIntersectionOfRects = true; | 352 fIsIntersectionOfRects = true; |
| 354 } | 353 } |
| 355 break; | 354 break; |
| 356 case kRRect_Type: | 355 case kRRect_Type: |
| 357 fFiniteBound = fRRect.getBounds(); | 356 fFiniteBound = fRRect.getBounds(); |
| 358 fFiniteBoundType = kNormal_BoundsType; | 357 fFiniteBoundType = kNormal_BoundsType; |
| 359 break; | 358 break; |
| 360 case kPath_Type: | 359 case kPath_Type: |
| 361 fFiniteBound = fPath.getBounds(); | 360 fFiniteBound = fPath.getBounds(); |
| 362 | 361 |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 | 624 |
| 626 if (NULL != prior) { | 625 if (NULL != prior) { |
| 627 if (prior->canBeIntersectedInPlace(fSaveCount, element.getOp())) { | 626 if (prior->canBeIntersectedInPlace(fSaveCount, element.getOp())) { |
| 628 switch (prior->fType) { | 627 switch (prior->fType) { |
| 629 case Element::kEmpty_Type: | 628 case Element::kEmpty_Type: |
| 630 SkDEBUGCODE(prior->checkEmpty();) | 629 SkDEBUGCODE(prior->checkEmpty();) |
| 631 return; | 630 return; |
| 632 case Element::kRect_Type: | 631 case Element::kRect_Type: |
| 633 if (Element::kRect_Type == element.getType()) { | 632 if (Element::kRect_Type == element.getType()) { |
| 634 if (prior->rectRectIntersectAllowed(element.getRect(), e
lement.isAA())) { | 633 if (prior->rectRectIntersectAllowed(element.getRect(), e
lement.isAA())) { |
| 635 if (!prior->fRect.intersect(element.getRect())) { | 634 SkRect isectRect; |
| 635 if (!isectRect.intersect(prior->getRect(), element.g
etRect())) { |
| 636 prior->setEmpty(); | 636 prior->setEmpty(); |
| 637 return; | 637 return; |
| 638 } | 638 } |
| 639 | 639 |
| 640 prior->fRRect.setRect(isectRect); |
| 640 prior->fDoAA = element.isAA(); | 641 prior->fDoAA = element.isAA(); |
| 641 Element* priorPrior = (Element*) iter.prev(); | 642 Element* priorPrior = (Element*) iter.prev(); |
| 642 prior->updateBoundAndGenID(priorPrior); | 643 prior->updateBoundAndGenID(priorPrior); |
| 643 return; | 644 return; |
| 644 } | 645 } |
| 645 break; | 646 break; |
| 646 } | 647 } |
| 647 // fallthrough | 648 // fallthrough |
| 648 default: | 649 default: |
| 649 if (!SkRect::Intersects(prior->getBounds(), element.getBound
s())) { | 650 if (!SkRect::Intersects(prior->getBounds(), element.getBound
s())) { |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 792 return kWideOpenGenID; | 793 return kWideOpenGenID; |
| 793 } | 794 } |
| 794 | 795 |
| 795 const Element* back = static_cast<const Element*>(fDeque.back()); | 796 const Element* back = static_cast<const Element*>(fDeque.back()); |
| 796 if (kInsideOut_BoundsType == back->fFiniteBoundType && back->fFiniteBound.is
Empty()) { | 797 if (kInsideOut_BoundsType == back->fFiniteBoundType && back->fFiniteBound.is
Empty()) { |
| 797 return kWideOpenGenID; | 798 return kWideOpenGenID; |
| 798 } | 799 } |
| 799 | 800 |
| 800 return back->getGenID(); | 801 return back->getGenID(); |
| 801 } | 802 } |
| OLD | NEW |