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 |