blob: c2613bbe255156a3e173fdd4612a56478a809a04 [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()
bsalomon@google.coma55847b2011-04-20 15:47:04 +000021 : fList(&fListStorage) {
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000022 fConservativeBounds.setEmpty();
23 fConservativeBoundsValid = true;
reed@google.comac10a2d2010-12-22 21:39:39 +000024}
25
bsalomon@google.comd302f142011-03-03 13:54:13 +000026GrClip::GrClip(const GrClip& src)
bsalomon@google.coma55847b2011-04-20 15:47:04 +000027 : fList(&fListStorage) {
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)
bsalomon@google.coma55847b2011-04-20 15:47:04 +000032 : fList(&fListStorage) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000033 this->setFromIRect(rect);
34}
35
36GrClip::GrClip(const GrRect& rect)
bsalomon@google.coma55847b2011-04-20 15:47:04 +000037 : fList(&fListStorage) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000038 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.coma55847b2011-04-20 15:47:04 +000043 : fList(&fListStorage) {
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;
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000051 fConservativeBounds = src.fConservativeBounds;
52 fConservativeBoundsValid = src.fConservativeBoundsValid;
reed@google.comac10a2d2010-12-22 21:39:39 +000053 return *this;
54}
55
56void GrClip::setEmpty() {
57 fList.reset();
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000058 fConservativeBounds.setEmpty();
59 fConservativeBoundsValid = 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;
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000071 fConservativeBounds = r;
72 fConservativeBoundsValid = true;
bsalomon@google.comd302f142011-03-03 13:54:13 +000073 }
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;
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000085 fConservativeBounds.set(r);
86 fConservativeBoundsValid = true;
bsalomon@google.comd302f142011-03-03 13:54:13 +000087 }
88}
89
reed@google.com20efde72011-05-09 17:00:02 +000090static void intersectWith(SkRect* dst, const SkRect& src) {
91 if (!dst->intersect(src)) {
92 dst->setEmpty();
93 }
94}
95
reed@google.com6f8f2922011-03-04 22:27:10 +000096void GrClip::setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty,
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +000097 const GrRect* conservativeBounds) {
reed@google.comac10a2d2010-12-22 21:39:39 +000098 fList.reset();
99
bsalomon@google.comd302f142011-03-03 13:54:13 +0000100 int rectCount = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000101
bsalomon@google.comd302f142011-03-03 13:54:13 +0000102 // compute bounds for common case of series of intersecting rects.
103 bool isectRectValid = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000104
reed@google.comac10a2d2010-12-22 21:39:39 +0000105 if (iter) {
106 for (iter->rewind(); !iter->isDone(); iter->next()) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000107 Element& e = fList.push_back();
108 e.fType = iter->getType();
109 e.fOp = iter->getOp();
110 // iterators should not emit replace
111 GrAssert(kReplace_SetOp != e.fOp);
112 switch (e.fType) {
113 case kRect_ClipType:
114 iter->getRect(&e.fRect);
reed@google.com6f8f2922011-03-04 22:27:10 +0000115 if (tx || ty) {
116 e.fRect.offset(tx, ty);
117 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000118 ++rectCount;
119 if (isectRectValid) {
120 if (1 == rectCount || kIntersect_SetOp == e.fOp) {
121 GrAssert(fList.count() <= 2);
122 if (fList.count() > 1) {
123 GrAssert(2 == rectCount);
124 rectCount = 1;
125 fList.pop_back();
126 GrAssert(kRect_ClipType == fList.back().fType);
reed@google.com20efde72011-05-09 17:00:02 +0000127 intersectWith(&fList.back().fRect, e.fRect);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000128 }
129 } else {
130 isectRectValid = false;
131 }
132 }
133 break;
134 case kPath_ClipType:
reed@google.com07f3ee12011-05-16 17:21:57 +0000135 e.fPath = *iter->getPath();
reed@google.com6f8f2922011-03-04 22:27:10 +0000136 if (tx || ty) {
137 e.fPath.offset(tx, ty);
138 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000139 e.fPathFill = iter->getPathFill();
140 isectRectValid = false;
141 break;
142 default:
143 GrCrash("Unknown clip element type.");
reed@google.comac10a2d2010-12-22 21:39:39 +0000144 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000145 }
146 }
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000147 fConservativeBoundsValid = false;
148 if (isectRectValid) {
149 fConservativeBoundsValid = true;
150 if (rectCount > 0) {
151 fConservativeBounds = fList[0].fRect;
152 } else {
153 fConservativeBounds.setEmpty();
bsalomon@google.comd302f142011-03-03 13:54:13 +0000154 }
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000155 } else if (NULL != conservativeBounds) {
156 fConservativeBounds = *conservativeBounds;
157 fConservativeBoundsValid = true;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000158 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000159}