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