Region.cpp revision 7c1b96a165f970a09ed239bb4fb3f1b0d8f2a407
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#define LOG_TAG "Region" 18 19#include <stdio.h> 20#include <utils/Atomic.h> 21#include <utils/Debug.h> 22#include <utils/String8.h> 23#include <ui/Region.h> 24#include <corecg/SkRegion.h> 25#include <corecg/SkRect.h> 26 27namespace android { 28 29// ---------------------------------------------------------------------------- 30 31Region::Region() 32{ 33} 34 35Region::Region(const Region& rhs) 36 : mRegion(rhs.mRegion) 37{ 38} 39 40Region::Region(const SkRegion& rhs) 41 : mRegion(rhs) 42{ 43} 44 45Region::~Region() 46{ 47} 48 49Region::Region(const Rect& rhs) 50{ 51 set(rhs); 52} 53 54Region::Region(const Parcel& parcel) 55{ 56 read(parcel); 57} 58 59Region::Region(const void* buffer) 60{ 61 read(buffer); 62} 63 64Region& Region::operator = (const Region& rhs) 65{ 66 mRegion = rhs.mRegion; 67 return *this; 68} 69 70const SkRegion& Region::toSkRegion() const 71{ 72 return mRegion; 73} 74 75Rect Region::bounds() const 76{ 77 const SkIRect& b(mRegion.getBounds()); 78 return Rect(b.fLeft, b.fTop, b.fRight, b.fBottom); 79} 80 81void Region::clear() 82{ 83 mRegion.setEmpty(); 84} 85 86void Region::set(const Rect& r) 87{ 88 SkIRect ir; 89 ir.set(r.left, r.top, r.right, r.bottom); 90 mRegion.setRect(ir); 91} 92 93// ---------------------------------------------------------------------------- 94 95Region& Region::orSelf(const Rect& r) 96{ 97 SkIRect ir; 98 ir.set(r.left, r.top, r.right, r.bottom); 99 mRegion.op(ir, SkRegion::kUnion_Op); 100 return *this; 101} 102 103Region& Region::andSelf(const Rect& r) 104{ 105 SkIRect ir; 106 ir.set(r.left, r.top, r.right, r.bottom); 107 mRegion.op(ir, SkRegion::kIntersect_Op); 108 return *this; 109} 110 111// ---------------------------------------------------------------------------- 112 113Region& Region::orSelf(const Region& rhs) { 114 mRegion.op(rhs.mRegion, SkRegion::kUnion_Op); 115 return *this; 116} 117 118Region& Region::andSelf(const Region& rhs) { 119 mRegion.op(rhs.mRegion, SkRegion::kIntersect_Op); 120 return *this; 121} 122 123Region& Region::subtractSelf(const Region& rhs) { 124 mRegion.op(rhs.mRegion, SkRegion::kDifference_Op); 125 return *this; 126} 127 128Region& Region::translateSelf(int x, int y) { 129 if (x|y) mRegion.translate(x, y); 130 return *this; 131} 132 133Region Region::merge(const Region& rhs) const { 134 Region result; 135 result.mRegion.op(mRegion, rhs.mRegion, SkRegion::kUnion_Op); 136 return result; 137} 138 139Region Region::intersect(const Region& rhs) const { 140 Region result; 141 result.mRegion.op(mRegion, rhs.mRegion, SkRegion::kIntersect_Op); 142 return result; 143} 144 145Region Region::subtract(const Region& rhs) const { 146 Region result; 147 result.mRegion.op(mRegion, rhs.mRegion, SkRegion::kDifference_Op); 148 return result; 149} 150 151Region Region::translate(int x, int y) const { 152 Region result; 153 mRegion.translate(x, y, &result.mRegion); 154 return result; 155} 156 157// ---------------------------------------------------------------------------- 158 159Region& Region::orSelf(const Region& rhs, int dx, int dy) { 160 SkRegion r(rhs.mRegion); 161 r.translate(dx, dy); 162 mRegion.op(r, SkRegion::kUnion_Op); 163 return *this; 164} 165 166Region& Region::andSelf(const Region& rhs, int dx, int dy) { 167 SkRegion r(rhs.mRegion); 168 r.translate(dx, dy); 169 mRegion.op(r, SkRegion::kIntersect_Op); 170 return *this; 171} 172 173Region& Region::subtractSelf(const Region& rhs, int dx, int dy) { 174 SkRegion r(rhs.mRegion); 175 r.translate(dx, dy); 176 mRegion.op(r, SkRegion::kDifference_Op); 177 return *this; 178} 179 180Region Region::merge(const Region& rhs, int dx, int dy) const { 181 Region result; 182 SkRegion r(rhs.mRegion); 183 r.translate(dx, dy); 184 result.mRegion.op(mRegion, r, SkRegion::kUnion_Op); 185 return result; 186} 187 188Region Region::intersect(const Region& rhs, int dx, int dy) const { 189 Region result; 190 SkRegion r(rhs.mRegion); 191 r.translate(dx, dy); 192 result.mRegion.op(mRegion, r, SkRegion::kIntersect_Op); 193 return result; 194} 195 196Region Region::subtract(const Region& rhs, int dx, int dy) const { 197 Region result; 198 SkRegion r(rhs.mRegion); 199 r.translate(dx, dy); 200 result.mRegion.op(mRegion, r, SkRegion::kDifference_Op); 201 return result; 202} 203 204// ---------------------------------------------------------------------------- 205 206Region::iterator::iterator(const Region& r) 207 : mIt(r.mRegion) 208{ 209} 210 211int Region::iterator::iterate(Rect* rect) 212{ 213 if (mIt.done()) 214 return 0; 215 const SkIRect& r(mIt.rect()); 216 rect->left = r.fLeft; 217 rect->top = r.fTop; 218 rect->right = r.fRight; 219 rect->bottom= r.fBottom; 220 mIt.next(); 221 return 1; 222} 223 224// ---------------------------------------------------------------------------- 225 226// we write a 4byte size ahead of the actual region, so we know how much we'll need for reading 227 228status_t Region::write(Parcel& parcel) const 229{ 230 int32_t size = mRegion.flatten(NULL); 231 parcel.writeInt32(size); 232 mRegion.flatten(parcel.writeInplace(size)); 233 return NO_ERROR; 234} 235 236status_t Region::read(const Parcel& parcel) 237{ 238 size_t size = parcel.readInt32(); 239 mRegion.unflatten(parcel.readInplace(size)); 240 return NO_ERROR; 241} 242 243ssize_t Region::write(void* buffer, size_t size) const 244{ 245 size_t sizeNeeded = mRegion.flatten(NULL); 246 if (sizeNeeded > size) return NO_MEMORY; 247 return mRegion.flatten(buffer); 248} 249 250ssize_t Region::read(const void* buffer) 251{ 252 return mRegion.unflatten(buffer); 253} 254 255ssize_t Region::writeEmpty(void* buffer, size_t size) 256{ 257 if (size < 4) return NO_MEMORY; 258 // this needs to stay in sync with SkRegion 259 *static_cast<int32_t*>(buffer) = -1; 260 return 4; 261} 262 263bool Region::isEmpty(void* buffer) 264{ 265 // this needs to stay in sync with SkRegion 266 return *static_cast<int32_t*>(buffer) == -1; 267} 268 269size_t Region::rects(Vector<Rect>& rectList) const 270{ 271 rectList.clear(); 272 if (!isEmpty()) { 273 SkRegion::Iterator iterator(mRegion); 274 while( !iterator.done() ) { 275 const SkIRect& ir(iterator.rect()); 276 rectList.push(Rect(ir.fLeft, ir.fTop, ir.fRight, ir.fBottom)); 277 iterator.next(); 278 } 279 } 280 return rectList.size(); 281} 282 283void Region::dump(String8& out, const char* what, uint32_t flags) const 284{ 285 (void)flags; 286 Vector<Rect> r; 287 rects(r); 288 289 size_t SIZE = 256; 290 char buffer[SIZE]; 291 292 snprintf(buffer, SIZE, " Region %s (this=%p, count=%d)\n", what, this, r.size()); 293 out.append(buffer); 294 for (size_t i=0 ; i<r.size() ; i++) { 295 snprintf(buffer, SIZE, " [%3d, %3d, %3d, %3d]\n", 296 r[i].left, r[i].top,r[i].right,r[i].bottom); 297 out.append(buffer); 298 } 299} 300 301void Region::dump(const char* what, uint32_t flags) const 302{ 303 (void)flags; 304 Vector<Rect> r; 305 rects(r); 306 LOGD(" Region %s (this=%p, count=%d)\n", what, this, r.size()); 307 for (size_t i=0 ; i<r.size() ; i++) { 308 LOGD(" [%3d, %3d, %3d, %3d]\n", 309 r[i].left, r[i].top,r[i].right,r[i].bottom); 310 } 311} 312 313// ---------------------------------------------------------------------------- 314 315}; // namespace android 316