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