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