1 /*
2 * Copyright (C) 2007 The Android Open Source Project
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 #ifndef ANDROID_UI_REGION_H
18 #define ANDROID_UI_REGION_H
19
20 #include <stdint.h>
21 #include <sys/types.h>
22 #include <ostream>
23
24 #include <ui/Rect.h>
25 #include <utils/Flattenable.h>
26
27 #include <android-base/macros.h>
28
29 #include "FatVector.h"
30
31 #include <string>
32
33 namespace android {
34 // ---------------------------------------------------------------------------
35
36 class Region : public LightFlattenable<Region>
37 {
38 public:
39 static const Region INVALID_REGION;
40
41 Region();
42 Region(const Region& rhs);
43 explicit Region(const Rect& rhs);
44 ~Region();
45
46 static Region createTJunctionFreeRegion(const Region& r);
47
48 Region& operator = (const Region& rhs);
49
isEmpty()50 inline bool isEmpty() const { return getBounds().isEmpty(); }
isRect()51 inline bool isRect() const { return mStorage.size() == 1; }
52
getBounds()53 inline Rect getBounds() const { return mStorage[mStorage.size() - 1]; }
bounds()54 inline Rect bounds() const { return getBounds(); }
55
56 bool contains(const Point& point) const;
57 bool contains(int x, int y) const;
58
59 // the region becomes its bounds
60 Region& makeBoundsSelf();
61
62 void clear();
63 void set(const Rect& r);
64 void set(int32_t w, int32_t h);
65 void set(uint32_t w, uint32_t h);
66
67 Region& orSelf(const Rect& rhs);
68 Region& xorSelf(const Rect& rhs);
69 Region& andSelf(const Rect& rhs);
70 Region& subtractSelf(const Rect& rhs);
71
72 // boolean operators, applied on this
73 Region& orSelf(const Region& rhs);
74 Region& xorSelf(const Region& rhs);
75 Region& andSelf(const Region& rhs);
76 Region& subtractSelf(const Region& rhs);
77
78 // boolean operators
79 const Region merge(const Rect& rhs) const;
80 const Region mergeExclusive(const Rect& rhs) const;
81 const Region intersect(const Rect& rhs) const;
82 const Region subtract(const Rect& rhs) const;
83
84 // boolean operators
85 const Region merge(const Region& rhs) const;
86 const Region mergeExclusive(const Region& rhs) const;
87 const Region intersect(const Region& rhs) const;
88 const Region subtract(const Region& rhs) const;
89
90 // these translate rhs first
91 Region& translateSelf(int dx, int dy);
92 Region& scaleSelf(float sx, float sy);
93 Region& orSelf(const Region& rhs, int dx, int dy);
94 Region& xorSelf(const Region& rhs, int dx, int dy);
95 Region& andSelf(const Region& rhs, int dx, int dy);
96 Region& subtractSelf(const Region& rhs, int dx, int dy);
97
98
99 // these translate rhs first
100 const Region translate(int dx, int dy) const WARN_UNUSED;
101 const Region merge(const Region& rhs, int dx, int dy) const WARN_UNUSED;
102 const Region mergeExclusive(const Region& rhs, int dx, int dy) const WARN_UNUSED;
103 const Region intersect(const Region& rhs, int dx, int dy) const WARN_UNUSED;
104 const Region subtract(const Region& rhs, int dx, int dy) const WARN_UNUSED;
105
106 // convenience operators overloads
107 inline const Region operator | (const Region& rhs) const;
108 inline const Region operator ^ (const Region& rhs) const;
109 inline const Region operator & (const Region& rhs) const;
110 inline const Region operator - (const Region& rhs) const;
111 inline const Region operator + (const Point& pt) const;
112
113 inline Region& operator |= (const Region& rhs);
114 inline Region& operator ^= (const Region& rhs);
115 inline Region& operator &= (const Region& rhs);
116 inline Region& operator -= (const Region& rhs);
117 inline Region& operator += (const Point& pt);
118
119
120 // returns true if the regions share the same underlying storage
121 bool isTriviallyEqual(const Region& region) const;
122
123 // returns true if the regions consist of the same rectangle sequence
124 bool hasSameRects(const Region& region) const;
125
126 /* various ways to access the rectangle list */
127
128
129 // STL-like iterators
130 typedef Rect const* const_iterator;
131 const_iterator begin() const;
132 const_iterator end() const;
133
134 // returns an array of rect which has the same life-time has this
135 // Region object.
136 Rect const* getArray(size_t* count) const;
137
138 /* no user serviceable parts here... */
139
140 // add a rectangle to the internal list. This rectangle must
141 // be sorted in Y and X and must not make the region invalid.
142 void addRectUnchecked(int l, int t, int r, int b);
143
isFixedSize()144 inline bool isFixedSize() const { return false; }
145 size_t getFlattenedSize() const;
146 status_t flatten(void* buffer, size_t size) const;
147 status_t unflatten(void const* buffer, size_t size);
148
149 void dump(std::string& out, const char* what, uint32_t flags=0) const;
150 void dump(const char* what, uint32_t flags=0) const;
151
152 private:
153 class rasterizer;
154 friend class rasterizer;
155
156 Region& operationSelf(const Rect& r, uint32_t op);
157 Region& operationSelf(const Region& r, uint32_t op);
158 Region& operationSelf(const Region& r, int dx, int dy, uint32_t op);
159 const Region operation(const Rect& rhs, uint32_t op) const;
160 const Region operation(const Region& rhs, uint32_t op) const;
161 const Region operation(const Region& rhs, int dx, int dy, uint32_t op) const;
162
163 static void boolean_operation(uint32_t op, Region& dst,
164 const Region& lhs, const Region& rhs, int dx, int dy);
165 static void boolean_operation(uint32_t op, Region& dst,
166 const Region& lhs, const Rect& rhs, int dx, int dy);
167
168 static void boolean_operation(uint32_t op, Region& dst,
169 const Region& lhs, const Region& rhs);
170 static void boolean_operation(uint32_t op, Region& dst,
171 const Region& lhs, const Rect& rhs);
172
173 static void translate(Region& reg, int dx, int dy);
174 static void translate(Region& dst, const Region& reg, int dx, int dy);
175
176 static bool validate(const Region& reg,
177 const char* name, bool silent = false);
178
179 // mStorage is a (manually) sorted array of Rects describing the region
180 // with an extra Rect as the last element which is set to the
181 // bounds of the region. However, if the region is
182 // a simple Rect then mStorage contains only that rect.
183 FatVector<Rect> mStorage;
184 };
185
186
187 const Region Region::operator | (const Region& rhs) const {
188 return merge(rhs);
189 }
190 const Region Region::operator ^ (const Region& rhs) const {
191 return mergeExclusive(rhs);
192 }
193 const Region Region::operator & (const Region& rhs) const {
194 return intersect(rhs);
195 }
196 const Region Region::operator - (const Region& rhs) const {
197 return subtract(rhs);
198 }
199 const Region Region::operator + (const Point& pt) const {
200 return translate(pt.x, pt.y);
201 }
202
203
204 Region& Region::operator |= (const Region& rhs) {
205 return orSelf(rhs);
206 }
207 Region& Region::operator ^= (const Region& rhs) {
208 return xorSelf(rhs);
209 }
210 Region& Region::operator &= (const Region& rhs) {
211 return andSelf(rhs);
212 }
213 Region& Region::operator -= (const Region& rhs) {
214 return subtractSelf(rhs);
215 }
216 Region& Region::operator += (const Point& pt) {
217 return translateSelf(pt.x, pt.y);
218 }
219
220 // Defining PrintTo helps with Google Tests.
PrintTo(const Region & region,::std::ostream * os)221 static inline void PrintTo(const Region& region, ::std::ostream* os) {
222 Region::const_iterator head = region.begin();
223 Region::const_iterator const tail = region.end();
224 bool first = true;
225 while (head != tail) {
226 *os << (first ? "Region(" : ", ");
227 PrintTo(*head, os);
228 head++;
229 first = false;
230 }
231 *os << ")";
232 }
233
234 // ---------------------------------------------------------------------------
235 }; // namespace android
236
237 #endif // ANDROID_UI_REGION_H
238