blob: 924c01b9f8ef0c5872937d8994680ccec838a325 [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
2 Copyright 2010 Google Inc.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17
18#include "GrClip.h"
19
bsalomon@google.comd302f142011-03-03 13:54:13 +000020GrClip::GrClip()
21 : fList(fListMemory, kPreAllocElements) {
reed@google.comac10a2d2010-12-22 21:39:39 +000022 fBounds.setEmpty();
bsalomon@google.comd302f142011-03-03 13:54:13 +000023 fBoundsValid = true;
reed@google.comac10a2d2010-12-22 21:39:39 +000024}
25
bsalomon@google.comd302f142011-03-03 13:54:13 +000026GrClip::GrClip(const GrClip& src)
27 : fList(fListMemory, kPreAllocElements) {
reed@google.comac10a2d2010-12-22 21:39:39 +000028 *this = src;
29}
30
bsalomon@google.comd302f142011-03-03 13:54:13 +000031GrClip::GrClip(const GrIRect& rect)
32 : fList(fListMemory, kPreAllocElements) {
33 this->setFromIRect(rect);
34}
35
36GrClip::GrClip(const GrRect& rect)
37 : fList(fListMemory, kPreAllocElements) {
38 this->setFromRect(rect);
39}
40
41GrClip::GrClip(GrClipIterator* iter, const GrRect* bounds)
42 : fList(fListMemory, kPreAllocElements) {
43 this->setFromIterator(iter, bounds);
reed@google.comac10a2d2010-12-22 21:39:39 +000044}
45
46GrClip::~GrClip() {}
47
48GrClip& GrClip::operator=(const GrClip& src) {
49 fList = src.fList;
50 fBounds = src.fBounds;
bsalomon@google.comd302f142011-03-03 13:54:13 +000051 fBoundsValid = src.fBoundsValid;
reed@google.comac10a2d2010-12-22 21:39:39 +000052 return *this;
53}
54
55void GrClip::setEmpty() {
56 fList.reset();
57 fBounds.setEmpty();
bsalomon@google.comd302f142011-03-03 13:54:13 +000058 fBoundsValid = true;
reed@google.comac10a2d2010-12-22 21:39:39 +000059}
60
bsalomon@google.comd302f142011-03-03 13:54:13 +000061void GrClip::setFromRect(const GrRect& r) {
62 fList.reset();
63 if (r.isEmpty()) {
64 // use a canonical empty rect for == testing.
65 setEmpty();
66 } else {
67 fList.push_back();
68 fList.back().fRect = r;
69 fList.back().fType = kRect_ClipType;
70 fBounds = r;
71 fBoundsValid = true;
72 }
73}
74
75void GrClip::setFromIRect(const GrIRect& r) {
76 fList.reset();
77 if (r.isEmpty()) {
78 // use a canonical empty rect for == testing.
79 setEmpty();
80 } else {
81 fList.push_back();
82 fList.back().fRect.set(r);
83 fList.back().fType = kRect_ClipType;
84 fBounds.set(r);
85 fBoundsValid = true;
86 }
87}
88
89void GrClip::setFromIterator(GrClipIterator* iter, const GrRect* bounds) {
reed@google.comac10a2d2010-12-22 21:39:39 +000090 fList.reset();
91
bsalomon@google.comd302f142011-03-03 13:54:13 +000092 int rectCount = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +000093
bsalomon@google.comd302f142011-03-03 13:54:13 +000094 // compute bounds for common case of series of intersecting rects.
95 bool isectRectValid = true;
reed@google.comac10a2d2010-12-22 21:39:39 +000096
reed@google.comac10a2d2010-12-22 21:39:39 +000097 if (iter) {
98 for (iter->rewind(); !iter->isDone(); iter->next()) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000099 Element& e = fList.push_back();
100 e.fType = iter->getType();
101 e.fOp = iter->getOp();
102 // iterators should not emit replace
103 GrAssert(kReplace_SetOp != e.fOp);
104 switch (e.fType) {
105 case kRect_ClipType:
106 iter->getRect(&e.fRect);
107 ++rectCount;
108 if (isectRectValid) {
109 if (1 == rectCount || kIntersect_SetOp == e.fOp) {
110 GrAssert(fList.count() <= 2);
111 if (fList.count() > 1) {
112 GrAssert(2 == rectCount);
113 rectCount = 1;
114 fList.pop_back();
115 GrAssert(kRect_ClipType == fList.back().fType);
116 fList.back().fRect.intersectWith(e.fRect);
117 }
118 } else {
119 isectRectValid = false;
120 }
121 }
122 break;
123 case kPath_ClipType:
124 e.fPath.resetFromIter(iter->getPathIter());
125 e.fPathFill = iter->getPathFill();
126 isectRectValid = false;
127 break;
128 default:
129 GrCrash("Unknown clip element type.");
reed@google.comac10a2d2010-12-22 21:39:39 +0000130 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000131 }
132 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000133 fBoundsValid = false;
134 if (NULL == bounds) {
135 if (isectRectValid) {
136 fBoundsValid = true;
137 if (rectCount > 0) {
138 fBounds = fList[0].fRect;
139 } else {
140 fBounds.setEmpty();
141 }
142 }
143 } else {
144 fBounds = *bounds;
145 fBoundsValid = true;
146 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000147}