blob: 5ba991bb1c37e140e7a9e8b2e4116cf29e1434ff [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
reed@google.com6f8f2922011-03-04 22:27:10 +000041GrClip::GrClip(GrClipIterator* iter, GrScalar tx, GrScalar ty,
42 const GrRect* bounds)
bsalomon@google.comd302f142011-03-03 13:54:13 +000043 : fList(fListMemory, kPreAllocElements) {
reed@google.com6f8f2922011-03-04 22:27:10 +000044 this->setFromIterator(iter, tx, ty, bounds);
reed@google.comac10a2d2010-12-22 21:39:39 +000045}
46
47GrClip::~GrClip() {}
48
49GrClip& GrClip::operator=(const GrClip& src) {
50 fList = src.fList;
51 fBounds = src.fBounds;
bsalomon@google.comd302f142011-03-03 13:54:13 +000052 fBoundsValid = src.fBoundsValid;
reed@google.comac10a2d2010-12-22 21:39:39 +000053 return *this;
54}
55
56void GrClip::setEmpty() {
57 fList.reset();
58 fBounds.setEmpty();
bsalomon@google.comd302f142011-03-03 13:54:13 +000059 fBoundsValid = true;
reed@google.comac10a2d2010-12-22 21:39:39 +000060}
61
bsalomon@google.comd302f142011-03-03 13:54:13 +000062void GrClip::setFromRect(const GrRect& r) {
63 fList.reset();
64 if (r.isEmpty()) {
65 // use a canonical empty rect for == testing.
66 setEmpty();
67 } else {
68 fList.push_back();
69 fList.back().fRect = r;
70 fList.back().fType = kRect_ClipType;
71 fBounds = r;
72 fBoundsValid = true;
73 }
74}
75
76void GrClip::setFromIRect(const GrIRect& r) {
77 fList.reset();
78 if (r.isEmpty()) {
79 // use a canonical empty rect for == testing.
80 setEmpty();
81 } else {
82 fList.push_back();
83 fList.back().fRect.set(r);
84 fList.back().fType = kRect_ClipType;
85 fBounds.set(r);
86 fBoundsValid = true;
87 }
88}
89
reed@google.com6f8f2922011-03-04 22:27:10 +000090void GrClip::setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty,
91 const GrRect* bounds) {
reed@google.comac10a2d2010-12-22 21:39:39 +000092 fList.reset();
93
bsalomon@google.comd302f142011-03-03 13:54:13 +000094 int rectCount = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +000095
bsalomon@google.comd302f142011-03-03 13:54:13 +000096 // compute bounds for common case of series of intersecting rects.
97 bool isectRectValid = true;
reed@google.comac10a2d2010-12-22 21:39:39 +000098
reed@google.comac10a2d2010-12-22 21:39:39 +000099 if (iter) {
100 for (iter->rewind(); !iter->isDone(); iter->next()) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000101 Element& e = fList.push_back();
102 e.fType = iter->getType();
103 e.fOp = iter->getOp();
104 // iterators should not emit replace
105 GrAssert(kReplace_SetOp != e.fOp);
106 switch (e.fType) {
107 case kRect_ClipType:
108 iter->getRect(&e.fRect);
reed@google.com6f8f2922011-03-04 22:27:10 +0000109 if (tx || ty) {
110 e.fRect.offset(tx, ty);
111 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000112 ++rectCount;
113 if (isectRectValid) {
114 if (1 == rectCount || kIntersect_SetOp == e.fOp) {
115 GrAssert(fList.count() <= 2);
116 if (fList.count() > 1) {
117 GrAssert(2 == rectCount);
118 rectCount = 1;
119 fList.pop_back();
120 GrAssert(kRect_ClipType == fList.back().fType);
121 fList.back().fRect.intersectWith(e.fRect);
122 }
123 } else {
124 isectRectValid = false;
125 }
126 }
127 break;
128 case kPath_ClipType:
129 e.fPath.resetFromIter(iter->getPathIter());
reed@google.com6f8f2922011-03-04 22:27:10 +0000130 if (tx || ty) {
131 e.fPath.offset(tx, ty);
132 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000133 e.fPathFill = iter->getPathFill();
134 isectRectValid = false;
135 break;
136 default:
137 GrCrash("Unknown clip element type.");
reed@google.comac10a2d2010-12-22 21:39:39 +0000138 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000139 }
140 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000141 fBoundsValid = false;
142 if (NULL == bounds) {
143 if (isectRectValid) {
144 fBoundsValid = true;
145 if (rectCount > 0) {
146 fBounds = fList[0].fRect;
147 } else {
148 fBounds.setEmpty();
149 }
150 }
151 } else {
152 fBounds = *bounds;
153 fBoundsValid = true;
154 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000155}