| 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" |
| 11 | 11 |
| 12 #include <new> | 12 #include <new> |
| 13 | 13 |
| 14 | 14 |
| 15 // 0-2 are reserved for invalid, empty & wide-open | 15 // 0-2 are reserved for invalid, empty & wide-open |
| 16 static const int32_t kFirstUnreservedGenID = 3; | 16 static const int32_t kFirstUnreservedGenID = 3; |
| 17 int32_t SkClipStack::gGenID = kFirstUnreservedGenID; | 17 int32_t SkClipStack::gGenID = kFirstUnreservedGenID; |
| 18 | 18 |
| 19 SkClipStack::Element::Element(const Element& that) { |
| 20 switch (that.getType()) { |
| 21 case kEmpty_Type: |
| 22 fPath.reset(); |
| 23 break; |
| 24 case kRect_Type: // Rect uses rrect |
| 25 case kRRect_Type: |
| 26 fPath.reset(); |
| 27 fRRect = that.fRRect; |
| 28 break; |
| 29 case kPath_Type: |
| 30 fPath.set(that.getPath()); |
| 31 break; |
| 32 } |
| 33 |
| 34 fSaveCount = that.fSaveCount; |
| 35 fOp = that.fOp; |
| 36 fType = that.fType; |
| 37 fDoAA = that.fDoAA; |
| 38 fFiniteBoundType = that.fFiniteBoundType; |
| 39 fFiniteBound = that.fFiniteBound; |
| 40 fIsIntersectionOfRects = that.fIsIntersectionOfRects; |
| 41 fGenID = that.fGenID; |
| 42 } |
| 43 |
| 19 bool SkClipStack::Element::operator== (const Element& element) const { | 44 bool SkClipStack::Element::operator== (const Element& element) const { |
| 20 if (this == &element) { | 45 if (this == &element) { |
| 21 return true; | 46 return true; |
| 22 } | 47 } |
| 23 if (fOp != element.fOp || | 48 if (fOp != element.fOp || |
| 24 fType != element.fType || | 49 fType != element.fType || |
| 25 fDoAA != element.fDoAA || | 50 fDoAA != element.fDoAA || |
| 26 fSaveCount != element.fSaveCount) { | 51 fSaveCount != element.fSaveCount) { |
| 27 return false; | 52 return false; |
| 28 } | 53 } |
| 29 switch (fType) { | 54 switch (fType) { |
| 30 case kPath_Type: | 55 case kPath_Type: |
| 31 return fPath == element.fPath; | 56 return this->getPath() == element.getPath(); |
| 32 case kRRect_Type: | 57 case kRRect_Type: |
| 33 return fRRect == element.fRRect; | 58 return fRRect == element.fRRect; |
| 34 case kRect_Type: | 59 case kRect_Type: |
| 35 return this->getRect() == element.getRect(); | 60 return this->getRect() == element.getRect(); |
| 36 case kEmpty_Type: | 61 case kEmpty_Type: |
| 37 return true; | 62 return true; |
| 38 default: | 63 default: |
| 39 SkDEBUGFAIL("Unexpected type."); | 64 SkDEBUGFAIL("Unexpected type."); |
| 40 return false; | 65 return false; |
| 41 } | 66 } |
| 42 } | 67 } |
| 43 | 68 |
| 44 void SkClipStack::Element::invertShapeFillType() { | 69 void SkClipStack::Element::invertShapeFillType() { |
| 45 switch (fType) { | 70 switch (fType) { |
| 46 case kRect_Type: | 71 case kRect_Type: |
| 47 fPath.reset(); | 72 fPath.init(); |
| 48 fPath.addRect(this->getRect()); | 73 fPath.get()->addRect(this->getRect()); |
| 49 fPath.setFillType(SkPath::kInverseEvenOdd_FillType); | 74 fPath.get()->setFillType(SkPath::kInverseEvenOdd_FillType); |
| 50 fType = kPath_Type; | 75 fType = kPath_Type; |
| 51 break; | 76 break; |
| 52 case kRRect_Type: | 77 case kRRect_Type: |
| 53 fPath.reset(); | 78 fPath.init(); |
| 54 fPath.addRRect(fRRect); | 79 fPath.get()->addRRect(fRRect); |
| 55 fPath.setFillType(SkPath::kInverseEvenOdd_FillType); | 80 fPath.get()->setFillType(SkPath::kInverseEvenOdd_FillType); |
| 56 fType = kPath_Type; | 81 fType = kPath_Type; |
| 57 break; | 82 break; |
| 58 case kPath_Type: | 83 case kPath_Type: |
| 59 fPath.toggleInverseFillType(); | 84 fPath.get()->toggleInverseFillType(); |
| 60 break; | 85 break; |
| 61 case kEmpty_Type: | 86 case kEmpty_Type: |
| 62 // Should this set to an empty, inverse filled path? | 87 // Should this set to an empty, inverse filled path? |
| 63 break; | 88 break; |
| 64 } | 89 } |
| 65 } | 90 } |
| 66 | 91 |
| 67 void SkClipStack::Element::initPath(int saveCount, const SkPath& path, SkRegion:
:Op op, | 92 void SkClipStack::Element::initPath(int saveCount, const SkPath& path, SkRegion:
:Op op, |
| 68 bool doAA) { | 93 bool doAA) { |
| 69 if (!path.isInverseFillType()) { | 94 if (!path.isInverseFillType()) { |
| 70 if (SkPath::kNone_PathAsRect != path.asRect()) { | 95 if (SkPath::kNone_PathAsRect != path.asRect()) { |
| 71 this->initRect(saveCount, path.getBounds(), op, doAA); | 96 this->initRect(saveCount, path.getBounds(), op, doAA); |
| 72 return; | 97 return; |
| 73 } | 98 } |
| 74 SkRect ovalRect; | 99 SkRect ovalRect; |
| 75 if (path.isOval(&ovalRect)) { | 100 if (path.isOval(&ovalRect)) { |
| 76 SkRRect rrect; | 101 SkRRect rrect; |
| 77 rrect.setOval(ovalRect); | 102 rrect.setOval(ovalRect); |
| 78 this->initRRect(saveCount, rrect, op, doAA); | 103 this->initRRect(saveCount, rrect, op, doAA); |
| 79 return; | 104 return; |
| 80 } | 105 } |
| 81 } | 106 } |
| 82 fPath = path; | 107 fPath.set(path); |
| 83 fType = kPath_Type; | 108 fType = kPath_Type; |
| 84 this->initCommon(saveCount, op, doAA); | 109 this->initCommon(saveCount, op, doAA); |
| 85 } | 110 } |
| 86 | 111 |
| 87 void SkClipStack::Element::asPath(SkPath* path) const { | 112 void SkClipStack::Element::asPath(SkPath* path) const { |
| 88 switch (fType) { | 113 switch (fType) { |
| 89 case kEmpty_Type: | 114 case kEmpty_Type: |
| 90 path->reset(); | 115 path->reset(); |
| 91 break; | 116 break; |
| 92 case kRect_Type: | 117 case kRect_Type: |
| 93 path->reset(); | 118 path->reset(); |
| 94 path->addRect(this->getRect()); | 119 path->addRect(this->getRect()); |
| 95 break; | 120 break; |
| 96 case kRRect_Type: | 121 case kRRect_Type: |
| 97 path->reset(); | 122 path->reset(); |
| 98 path->addRRect(fRRect); | 123 path->addRRect(fRRect); |
| 99 break; | 124 break; |
| 100 case kPath_Type: | 125 case kPath_Type: |
| 101 *path = fPath; | 126 *path = *fPath.get(); |
| 102 break; | 127 break; |
| 103 } | 128 } |
| 104 } | 129 } |
| 105 | 130 |
| 106 void SkClipStack::Element::setEmpty() { | 131 void SkClipStack::Element::setEmpty() { |
| 107 fType = kEmpty_Type; | 132 fType = kEmpty_Type; |
| 108 fFiniteBound.setEmpty(); | 133 fFiniteBound.setEmpty(); |
| 109 fFiniteBoundType = kNormal_BoundsType; | 134 fFiniteBoundType = kNormal_BoundsType; |
| 110 fIsIntersectionOfRects = false; | 135 fIsIntersectionOfRects = false; |
| 111 fRRect.setEmpty(); | 136 fRRect.setEmpty(); |
| 112 fPath.reset(); | 137 fPath.reset(); |
| 113 fGenID = kEmptyGenID; | 138 fGenID = kEmptyGenID; |
| 114 SkDEBUGCODE(this->checkEmpty();) | 139 SkDEBUGCODE(this->checkEmpty();) |
| 115 } | 140 } |
| 116 | 141 |
| 117 void SkClipStack::Element::checkEmpty() const { | 142 void SkClipStack::Element::checkEmpty() const { |
| 118 SkASSERT(fFiniteBound.isEmpty()); | 143 SkASSERT(fFiniteBound.isEmpty()); |
| 119 SkASSERT(kNormal_BoundsType == fFiniteBoundType); | 144 SkASSERT(kNormal_BoundsType == fFiniteBoundType); |
| 120 SkASSERT(!fIsIntersectionOfRects); | 145 SkASSERT(!fIsIntersectionOfRects); |
| 121 SkASSERT(kEmptyGenID == fGenID); | 146 SkASSERT(kEmptyGenID == fGenID); |
| 122 SkASSERT(fPath.isEmpty()); | 147 SkASSERT(!fPath.isValid()); |
| 123 } | 148 } |
| 124 | 149 |
| 125 bool SkClipStack::Element::canBeIntersectedInPlace(int saveCount, SkRegion::Op o
p) const { | 150 bool SkClipStack::Element::canBeIntersectedInPlace(int saveCount, SkRegion::Op o
p) const { |
| 126 if (kEmpty_Type == fType && | 151 if (kEmpty_Type == fType && |
| 127 (SkRegion::kDifference_Op == op || SkRegion::kIntersect_Op == op)) { | 152 (SkRegion::kDifference_Op == op || SkRegion::kIntersect_Op == op)) { |
| 128 return true; | 153 return true; |
| 129 } | 154 } |
| 130 // Only clips within the same save/restore frame (as captured by | 155 // Only clips within the same save/restore frame (as captured by |
| 131 // the save count) can be merged | 156 // the save count) can be merged |
| 132 return fSaveCount == saveCount && | 157 return fSaveCount == saveCount && |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 (SkRegion::kIntersect_Op == fOp && prior->fIsIntersectionOfRects
&& | 375 (SkRegion::kIntersect_Op == fOp && prior->fIsIntersectionOfRects
&& |
| 351 prior->rectRectIntersectAllowed(this->getRect(), fDoAA))) { | 376 prior->rectRectIntersectAllowed(this->getRect(), fDoAA))) { |
| 352 fIsIntersectionOfRects = true; | 377 fIsIntersectionOfRects = true; |
| 353 } | 378 } |
| 354 break; | 379 break; |
| 355 case kRRect_Type: | 380 case kRRect_Type: |
| 356 fFiniteBound = fRRect.getBounds(); | 381 fFiniteBound = fRRect.getBounds(); |
| 357 fFiniteBoundType = kNormal_BoundsType; | 382 fFiniteBoundType = kNormal_BoundsType; |
| 358 break; | 383 break; |
| 359 case kPath_Type: | 384 case kPath_Type: |
| 360 fFiniteBound = fPath.getBounds(); | 385 fFiniteBound = fPath.get()->getBounds(); |
| 361 | 386 |
| 362 if (fPath.isInverseFillType()) { | 387 if (fPath.get()->isInverseFillType()) { |
| 363 fFiniteBoundType = kInsideOut_BoundsType; | 388 fFiniteBoundType = kInsideOut_BoundsType; |
| 364 } else { | 389 } else { |
| 365 fFiniteBoundType = kNormal_BoundsType; | 390 fFiniteBoundType = kNormal_BoundsType; |
| 366 } | 391 } |
| 367 break; | 392 break; |
| 368 case kEmpty_Type: | 393 case kEmpty_Type: |
| 369 SkDEBUGFAIL("We shouldn't get here with an empty element."); | 394 SkDEBUGFAIL("We shouldn't get here with an empty element."); |
| 370 break; | 395 break; |
| 371 } | 396 } |
| 372 | 397 |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 793 return kWideOpenGenID; | 818 return kWideOpenGenID; |
| 794 } | 819 } |
| 795 | 820 |
| 796 const Element* back = static_cast<const Element*>(fDeque.back()); | 821 const Element* back = static_cast<const Element*>(fDeque.back()); |
| 797 if (kInsideOut_BoundsType == back->fFiniteBoundType && back->fFiniteBound.is
Empty()) { | 822 if (kInsideOut_BoundsType == back->fFiniteBoundType && back->fFiniteBound.is
Empty()) { |
| 798 return kWideOpenGenID; | 823 return kWideOpenGenID; |
| 799 } | 824 } |
| 800 | 825 |
| 801 return back->getGenID(); | 826 return back->getGenID(); |
| 802 } | 827 } |
| OLD | NEW |