blob: c8020150c1e47cc31b02630e2adcd0b93afa3aef [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.comac10a2d2010-12-22 21:39:39 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2010 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@google.comac10a2d2010-12-22 21:39:39 +00007 */
8
9
epoger@google.comec3ed6a2011-07-28 14:26:00 +000010
reed@google.comac10a2d2010-12-22 21:39:39 +000011#ifndef GrClip_DEFINED
12#define GrClip_DEFINED
13
14#include "GrClipIterator.h"
15#include "GrRect.h"
bsalomon@google.comd302f142011-03-03 13:54:13 +000016
bsalomon@google.com8d033a12012-04-27 15:52:53 +000017#include "SkPath.h"
bsalomon@google.com49313f62011-09-14 13:54:05 +000018#include "SkTArray.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000019
20class GrClip {
21public:
22 GrClip();
23 GrClip(const GrClip& src);
reed@google.com6f8f2922011-03-04 22:27:10 +000024 /**
robertphillips@google.com3e11c0b2012-07-11 18:20:35 +000025 * The conservativeBounds parameter already takes (tx,ty) into account.
reed@google.com6f8f2922011-03-04 22:27:10 +000026 */
27 GrClip(GrClipIterator* iter, GrScalar tx, GrScalar ty,
robertphillips@google.com3e11c0b2012-07-11 18:20:35 +000028 const GrRect& conservativeBounds);
29 explicit GrClip(const GrIRect& rect);
30 explicit GrClip(const GrRect& rect);
bsalomon@google.comd302f142011-03-03 13:54:13 +000031
reed@google.comac10a2d2010-12-22 21:39:39 +000032 ~GrClip();
33
34 GrClip& operator=(const GrClip& src);
35
robertphillips@google.com3e11c0b2012-07-11 18:20:35 +000036 const GrRect& getConservativeBounds() const {
37 GrAssert(fConservativeBoundsValid);
38 return fConservativeBounds;
39 }
bsalomon@google.comd302f142011-03-03 13:54:13 +000040
robertphillips@google.comfa1d2912012-04-16 14:49:14 +000041 bool requiresAA() const { return fRequiresAA; }
42
robertphillips@google.coma6f11c42012-07-23 17:39:44 +000043 class Iter {
44 public:
45 enum IterStart {
46 kBottom_IterStart,
47 kTop_IterStart
48 };
49
50 /**
51 * Creates an uninitialized iterator. Must be reset()
52 */
53 Iter();
54
55 Iter(const GrClip& stack, IterStart startLoc);
56
57 struct Clip {
58 Clip() : fRect(NULL), fPath(NULL), fOp(SkRegion::kIntersect_Op),
59 fDoAA(false) {}
60
61 const SkRect* fRect; // if non-null, this is a rect clip
62 const SkPath* fPath; // if non-null, this is a path clip
63 SkRegion::Op fOp;
64 bool fDoAA;
65 };
66
67 /**
68 * Return the clip for this element in the iterator. If next() returns
69 * NULL, then the iterator is done. The type of clip is determined by
70 * the pointers fRect and fPath:
71 *
72 * fRect==NULL fPath!=NULL path clip
73 * fRect!=NULL fPath==NULL rect clip
74 * fRect==NULL fPath==NULL empty clip
75 */
76 const Clip* next();
77 const Clip* prev();
78
79 /**
80 * Moves the iterator to the topmost clip with the specified RegionOp
81 * and returns that clip. If no clip with that op is found,
82 * returns NULL.
83 */
84 const Clip* skipToTopmost(SkRegion::Op op);
85
86 /**
87 * Restarts the iterator on a clip stack.
88 */
89 void reset(const GrClip& stack, IterStart startLoc);
90
91 private:
92 const GrClip* fStack;
93 Clip fClip;
94 int fCurIndex;
95
96 /**
97 * updateClip updates fClip to represent the clip in the index slot of
98 * GrClip's list. * It unifies functionality needed by both next() and
99 * prev().
100 */
101 const Clip* updateClip(int index);
102 };
103
104private:
bsalomon@google.comd302f142011-03-03 13:54:13 +0000105 int getElementCount() const { return fList.count(); }
106
107 GrClipType getElementType(int i) const { return fList[i].fType; }
108
bsalomon@google.com8d033a12012-04-27 15:52:53 +0000109 const SkPath& getPath(int i) const {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000110 GrAssert(kPath_ClipType == fList[i].fType);
111 return fList[i].fPath;
reed@google.comac10a2d2010-12-22 21:39:39 +0000112 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000113
114 GrPathFill getPathFill(int i) const {
115 GrAssert(kPath_ClipType == fList[i].fType);
116 return fList[i].fPathFill;
117 }
118
119 const GrRect& getRect(int i) const {
120 GrAssert(kRect_ClipType == fList[i].fType);
121 return fList[i].fRect;
122 }
123
robertphillips@google.com0f191f32012-04-25 15:23:36 +0000124 SkRegion::Op getOp(int i) const { return fList[i].fOp; }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000125
robertphillips@google.comfa1d2912012-04-16 14:49:14 +0000126 bool getDoAA(int i) const { return fList[i].fDoAA; }
127
robertphillips@google.coma6f11c42012-07-23 17:39:44 +0000128public:
bsalomon@google.comd302f142011-03-03 13:54:13 +0000129 bool isRect() const {
bsalomon@google.comab3dee52011-08-29 15:18:41 +0000130 if (1 == fList.count() && kRect_ClipType == fList[0].fType &&
robertphillips@google.com0f191f32012-04-25 15:23:36 +0000131 (SkRegion::kIntersect_Op == fList[0].fOp ||
132 SkRegion::kReplace_Op == fList[0].fOp)) {
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000133 // if we determined that the clip is a single rect
134 // we ought to have also used that rect as the bounds.
135 GrAssert(fConservativeBoundsValid);
136 GrAssert(fConservativeBounds == fList[0].fRect);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000137 return true;
138 } else {
139 return false;
140 }
141 }
142
bsalomon@google.coma3201942012-06-21 19:58:20 +0000143 // FIXME: This word "empty" is confusing. It means that the clip has no
144 // elements (it is the infinite plane) not that it has no area.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000145 bool isEmpty() const { return 0 == fList.count(); }
reed@google.comac10a2d2010-12-22 21:39:39 +0000146
147 /**
bsalomon@google.comd302f142011-03-03 13:54:13 +0000148 * Resets this clip to be empty
reed@google.comac10a2d2010-12-22 21:39:39 +0000149 */
150 void setEmpty();
reed@google.com6f8f2922011-03-04 22:27:10 +0000151
152 /**
153 * If specified, the bounds parameter already takes (tx,ty) into account.
154 */
155 void setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty,
robertphillips@google.com3e11c0b2012-07-11 18:20:35 +0000156 const GrRect& conservativeBounds);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000157 void setFromRect(const GrRect& rect);
158 void setFromIRect(const GrIRect& rect);
reed@google.comac10a2d2010-12-22 21:39:39 +0000159
160 friend bool operator==(const GrClip& a, const GrClip& b) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000161 if (a.fList.count() != b.fList.count()) {
162 return false;
163 }
164 int count = a.fList.count();
165 for (int i = 0; i < count; ++i) {
166 if (a.fList[i] != b.fList[i]) {
167 return false;
168 }
169 }
170 return true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000171 }
172 friend bool operator!=(const GrClip& a, const GrClip& b) {
173 return !(a == b);
174 }
175
reed@google.comac10a2d2010-12-22 21:39:39 +0000176private:
bsalomon@google.comd302f142011-03-03 13:54:13 +0000177 struct Element {
robertphillips@google.com0f191f32012-04-25 15:23:36 +0000178 GrClipType fType;
179 GrRect fRect;
bsalomon@google.com8d033a12012-04-27 15:52:53 +0000180 SkPath fPath;
robertphillips@google.com0f191f32012-04-25 15:23:36 +0000181 GrPathFill fPathFill;
182 SkRegion::Op fOp;
183 bool fDoAA;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000184 bool operator ==(const Element& e) const {
robertphillips@google.comfa1d2912012-04-16 14:49:14 +0000185 if (e.fType != fType || e.fOp != fOp || e.fDoAA != fDoAA) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000186 return false;
187 }
188 switch (fType) {
189 case kRect_ClipType:
190 return fRect == e.fRect;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000191 case kPath_ClipType:
192 return fPath == e.fPath;
193 default:
194 GrCrash("Unknown clip element type.");
195 return false; // suppress warning
196 }
197 }
198 bool operator !=(const Element& e) const { return !(*this == e); }
199 };
reed@google.comac10a2d2010-12-22 21:39:39 +0000200
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000201 GrRect fConservativeBounds;
202 bool fConservativeBoundsValid;
reed@google.comac10a2d2010-12-22 21:39:39 +0000203
robertphillips@google.comfa1d2912012-04-16 14:49:14 +0000204 bool fRequiresAA;
205
bsalomon@google.comd302f142011-03-03 13:54:13 +0000206 enum {
207 kPreAllocElements = 4,
208 };
bsalomon@google.com92669012011-09-27 19:10:05 +0000209 SkSTArray<kPreAllocElements, Element> fList;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000210};
reed@google.comac10a2d2010-12-22 21:39:39 +0000211#endif
212