Region.cpp revision d0b55c011a311b677493ba72804bf1bc4df68224
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* 2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License. 6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at 7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and 14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License. 15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define LOG_TAG "Region" 18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1972b0ffe4c3776b33844bb00b9be5693bddd391f9Mathias Agopian#include <limits.h> 2072b0ffe4c3776b33844bb00b9be5693bddd391f9Mathias Agopian 2120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#include <utils/Log.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 2320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 2420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#include <ui/Rect.h> 25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Region.h> 2620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#include <ui/Point.h> 2720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 2820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#include <private/ui/RegionHelper.h> 2920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 3020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 3120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#define VALIDATE_REGIONS (false) 3220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#define VALIDATE_WITH_CORECG (false) 3320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 3420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 3520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_WITH_CORECG 3620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#include <core/SkRegion.h> 3720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 4020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 4120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 4220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianenum { 4320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian op_nand = region_operator<Rect>::op_nand, 4420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian op_and = region_operator<Rect>::op_and, 4520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian op_or = region_operator<Rect>::op_or, 4620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian op_xor = region_operator<Rect>::op_xor 4720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian}; 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion::Region() 5220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian : mBounds(0,0) 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion::Region(const Region& rhs) 5720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian : mBounds(rhs.mBounds), mStorage(rhs.mStorage) 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 59d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian#if VALIDATE_REGIONS 60d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(rhs, "rhs copy-ctor"); 61d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian#endif 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion::Region(const Rect& rhs) 6520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian : mBounds(rhs) 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion::Region(const void* buffer) 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 7120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian status_t err = read(buffer); 72b6121422ef641dc7317d1c3bf1d38b7d73922250Mathias Agopian LOGE_IF(err<0, "error %s reading Region from buffer", strerror(err)); 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion::~Region() 76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::operator = (const Region& rhs) 80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 8120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 82d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(*this, "this->operator="); 83d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(rhs, "rhs.operator="); 8420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 8520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mBounds = rhs.mBounds; 8620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage = rhs.mStorage; 8720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return *this; 88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 909f96145725ff3f265712d607d19078fb91a5c8ecMathias AgopianRegion& Region::makeBoundsSelf() 919f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian{ 929f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian mStorage.clear(); 939f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian return *this; 949f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian} 959f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian 96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Region::clear() 97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 9820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mBounds.clear(); 9920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage.clear(); 100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Region::set(const Rect& r) 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 10420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mBounds = r; 10520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage.clear(); 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1080926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianvoid Region::set(uint32_t w, uint32_t h) 1090926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian{ 11020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mBounds = Rect(int(w), int(h)); 11120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage.clear(); 1120926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian} 1130926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::addRectUnchecked(int l, int t, int r, int b) 117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 11820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage.add(Rect(l,t,r,b)); 11920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 12020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(*this, "addRectUnchecked"); 12120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 12420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 12520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 12620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::orSelf(const Rect& r) { 12720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(r, op_or); 12820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 12920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::andSelf(const Rect& r) { 13020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(r, op_and); 13120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 13220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::subtractSelf(const Rect& r) { 13320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(r, op_nand); 13420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 13520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::operationSelf(const Rect& r, int op) { 13620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region lhs(*this); 13720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, *this, lhs, r); 138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *this; 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::orSelf(const Region& rhs) { 14420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, op_or); 145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::andSelf(const Region& rhs) { 14720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, op_and); 148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::subtractSelf(const Region& rhs) { 15020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, op_nand); 15120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 15220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::operationSelf(const Region& rhs, int op) { 15320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region lhs(*this); 15420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, *this, lhs, rhs); 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *this; 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::translateSelf(int x, int y) { 15920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (x|y) translate(*this, x, y); 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *this; 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 16320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 16420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 165bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::merge(const Rect& rhs) const { 16620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_or); 16720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 168bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::intersect(const Rect& rhs) const { 16920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_and); 17020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 171bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::subtract(const Rect& rhs) const { 17220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_nand); 17320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 174bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::operation(const Rect& rhs, int op) const { 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region result; 17620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, result, *this, rhs); 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return result; 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 18020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 18120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 182bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::merge(const Region& rhs) const { 18320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_or); 18420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 185bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::intersect(const Region& rhs) const { 18620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_and); 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 188bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::subtract(const Region& rhs) const { 18920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_nand); 19020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 191bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::operation(const Region& rhs, int op) const { 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region result; 19320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, result, *this, rhs); 194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return result; 195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 197bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::translate(int x, int y) const { 198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region result; 19920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian translate(result, *this, x, y); 200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return result; 201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::orSelf(const Region& rhs, int dx, int dy) { 20620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, dx, dy, op_or); 207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::andSelf(const Region& rhs, int dx, int dy) { 20920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, dx, dy, op_and); 210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::subtractSelf(const Region& rhs, int dx, int dy) { 21220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, dx, dy, op_nand); 21320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 21420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::operationSelf(const Region& rhs, int dx, int dy, int op) { 21520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region lhs(*this); 21620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, *this, lhs, rhs, dx, dy); 217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *this; 218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 22020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 22120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 222bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::merge(const Region& rhs, int dx, int dy) const { 22320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, dx, dy, op_or); 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 225bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::intersect(const Region& rhs, int dx, int dy) const { 22620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, dx, dy, op_and); 227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 228bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::subtract(const Region& rhs, int dx, int dy) const { 22920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, dx, dy, op_nand); 23020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 231bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::operation(const Region& rhs, int dx, int dy, int op) const { 232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region result; 23320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, result, *this, rhs, dx, dy); 234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return result; 235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 23920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// This is our region rasterizer, which merges rects and spans together 24020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// to obtain an optimal region. 24120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianclass Region::rasterizer : public region_operator<Rect>::region_rasterizer 24220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 24320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect& bounds; 24420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Vector<Rect>& storage; 24520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect* head; 24620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect* tail; 24720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Vector<Rect> span; 24820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect* cur; 24920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianpublic: 25020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rasterizer(Region& reg) 25120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian : bounds(reg.mBounds), storage(reg.mStorage), head(), tail(), cur() { 25220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.top = bounds.bottom = 0; 25320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.left = INT_MAX; 25420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.right = INT_MIN; 25520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian storage.clear(); 25620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 25720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 25820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian ~rasterizer() { 25920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (span.size()) { 26020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian flushSpan(); 26120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 26220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (storage.size()) { 26320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.top = storage.itemAt(0).top; 26420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.bottom = storage.top().bottom; 26520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (storage.size() == 1) { 26620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian storage.clear(); 26720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 26820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } else { 26920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.left = 0; 27020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.right = 0; 27120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 27220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 27320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 27420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian virtual void operator()(const Rect& rect) { 27520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian //LOGD(">>> %3d, %3d, %3d, %3d", 27620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian // rect.left, rect.top, rect.right, rect.bottom); 27720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (span.size()) { 27820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (cur->top != rect.top) { 27920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian flushSpan(); 28020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } else if (cur->right == rect.left) { 28120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian cur->right = rect.right; 28220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return; 28320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 28420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 28520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian span.add(rect); 28620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian cur = span.editArray() + (span.size() - 1); 28720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 28820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianprivate: 28920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian template<typename T> 29020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian static inline T min(T rhs, T lhs) { return rhs < lhs ? rhs : lhs; } 29120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian template<typename T> 29220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian static inline T max(T rhs, T lhs) { return rhs > lhs ? rhs : lhs; } 29320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian void flushSpan() { 29420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bool merge = false; 29520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (tail-head == ssize_t(span.size())) { 296b801624dc4f03c930ec35f406f07fa5fd8f65dd9Romain Guy Rect const* p = span.editArray(); 29720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect const* q = head; 29820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (p->top == q->bottom) { 29920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian merge = true; 30020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (q != tail) { 30120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if ((p->left != q->left) || (p->right != q->right)) { 30220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian merge = false; 30320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian break; 30420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 30520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian p++, q++; 30620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 30720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 30820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 30920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (merge) { 31020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const int bottom = span[0].bottom; 31120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect* r = head; 31220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (r != tail) { 31320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian r->bottom = bottom; 31420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian r++; 31520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 31620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } else { 31720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.left = min(span.itemAt(0).left, bounds.left); 31820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.right = max(span.top().right, bounds.right); 31920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian storage.appendVector(span); 32020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian tail = storage.editArray() + storage.size(); 32120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head = tail - span.size(); 32220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 32320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian span.clear(); 32420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 32520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian}; 32620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 32720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianbool Region::validate(const Region& reg, const char* name) 328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 32920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bool result = true; 33020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator cur = reg.begin(); 33120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator const tail = reg.end(); 33220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator prev = cur++; 33320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect b(*prev); 33420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (cur != tail) { 33520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian b.left = b.left < cur->left ? b.left : cur->left; 33620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian b.top = b.top < cur->top ? b.top : cur->top; 33720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian b.right = b.right > cur->right ? b.right : cur->right; 33820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian b.bottom = b.bottom > cur->bottom ? b.bottom : cur->bottom; 33920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (cur->top == prev->top) { 34020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (cur->bottom != prev->bottom) { 34120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian LOGE("%s: invalid span %p", name, cur); 34220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian result = false; 34320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } else if (cur->left < prev->right) { 34420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian LOGE("%s: spans overlap horizontally prev=%p, cur=%p", 34520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian name, prev, cur); 34620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian result = false; 34720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 34820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } else if (cur->top < prev->bottom) { 34920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian LOGE("%s: spans overlap vertically prev=%p, cur=%p", 35020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian name, prev, cur); 35120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian result = false; 35220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 35320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian prev = cur; 35420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian cur++; 35520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 35620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (b != reg.getBounds()) { 35720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian result = false; 35820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian LOGE("%s: invalid bounds [%d,%d,%d,%d] vs. [%d,%d,%d,%d]", name, 35920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian b.left, b.top, b.right, b.bottom, 36020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian reg.getBounds().left, reg.getBounds().top, 36120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian reg.getBounds().right, reg.getBounds().bottom); 36220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 36320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (result == false) { 36420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian reg.dump(name); 36520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 36620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return result; 367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 36920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::boolean_operation(int op, Region& dst, 37020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& lhs, 37120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& rhs, int dx, int dy) 372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 373d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian#if VALIDATE_REGIONS 374d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(lhs, "boolean_operation (before): lhs"); 375d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(rhs, "boolean_operation (before): rhs"); 376d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(dst, "boolean_operation (before): dst"); 377d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian#endif 378d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian 37920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian size_t lhs_count; 38020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect const * const lhs_rects = lhs.getArray(&lhs_count); 38120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 38220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian size_t rhs_count; 38320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect const * const rhs_rects = rhs.getArray(&rhs_count); 38420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 38520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect>::region lhs_region(lhs_rects, lhs_count); 38620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect>::region rhs_region(rhs_rects, rhs_count, dx, dy); 38720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect> operation(op, lhs_region, rhs_region); 38820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian { // scope for rasterizer (dtor has side effects) 38920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rasterizer r(dst); 39020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian operation(r); 39120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 39220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 39320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 39420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(lhs, "boolean_operation: lhs"); 39520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(rhs, "boolean_operation: rhs"); 39620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(dst, "boolean_operation: dst"); 39720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 39820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 39920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_WITH_CORECG 40020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion sk_lhs; 40120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion sk_rhs; 40220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion sk_dst; 40320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 40420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian for (size_t i=0 ; i<lhs_count ; i++) 40520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian sk_lhs.op( 40620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs_rects[i].left + dx, 40720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs_rects[i].top + dy, 40820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs_rects[i].right + dx, 40920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs_rects[i].bottom + dy, 41020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::kUnion_Op); 41120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 41220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian for (size_t i=0 ; i<rhs_count ; i++) 41320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian sk_rhs.op( 41420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs_rects[i].left + dx, 41520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs_rects[i].top + dy, 41620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs_rects[i].right + dx, 41720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs_rects[i].bottom + dy, 41820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::kUnion_Op); 41920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 42020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const char* name = "---"; 42120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::Op sk_op; 42220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian switch (op) { 42320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian case op_or: sk_op = SkRegion::kUnion_Op; name="OR"; break; 42420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian case op_and: sk_op = SkRegion::kIntersect_Op; name="AND"; break; 42520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian case op_nand: sk_op = SkRegion::kDifference_Op; name="NAND"; break; 42620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 42720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian sk_dst.op(sk_lhs, sk_rhs, sk_op); 42820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 42920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (sk_dst.isEmpty() && dst.isEmpty()) 43020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return; 43120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 43220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bool same = true; 43320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator head = dst.begin(); 43420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const tail = dst.end(); 43520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::Iterator it(sk_dst); 43620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (!it.done()) { 43720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (head != tail) { 43820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if ( 43920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->left != it.rect().fLeft || 44020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->top != it.rect().fTop || 44120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->right != it.rect().fRight || 44220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->bottom != it.rect().fBottom 44320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian ) { 44420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian same = false; 44520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian break; 44620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 44720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } else { 44820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian same = false; 44920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian break; 45020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 45120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head++; 45220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.next(); 45320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 45420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 45520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (head != tail) { 45620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian same = false; 45720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 45820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 45920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if(!same) { 46020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian LOGD("---\nregion boolean %s failed", name); 46120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs.dump("lhs"); 46220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs.dump("rhs"); 46320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian dst.dump("dst"); 46420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian LOGD("should be"); 46520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::Iterator it(sk_dst); 46620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (!it.done()) { 46720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian LOGD(" [%3d, %3d, %3d, %3d]", 46820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.rect().fLeft, 46920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.rect().fTop, 47020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.rect().fRight, 47120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.rect().fBottom); 47220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.next(); 47320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 47420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 47520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 47820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::boolean_operation(int op, Region& dst, 47920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& lhs, 48020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& rhs, int dx, int dy) 48120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 48220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_WITH_CORECG || VALIDATE_REGIONS 48320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, dst, lhs, Region(rhs), dx, dy); 48420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#else 48520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian size_t lhs_count; 48620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect const * const lhs_rects = lhs.getArray(&lhs_count); 48720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 48820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect>::region lhs_region(lhs_rects, lhs_count); 48920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect>::region rhs_region(&rhs, 1, dx, dy); 49020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect> operation(op, lhs_region, rhs_region); 49120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian { // scope for rasterizer (dtor has side effects) 49220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rasterizer r(dst); 49320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian operation(r); 49420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 49620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 49720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 49820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 49920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::boolean_operation(int op, Region& dst, 50020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& lhs, const Region& rhs) 50120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 50220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, dst, lhs, rhs, 0, 0); 50320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 50420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 50520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::boolean_operation(int op, Region& dst, 50620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& lhs, const Rect& rhs) 50720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 50820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, dst, lhs, rhs, 0, 0); 50920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 51020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 51120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::translate(Region& reg, int dx, int dy) 51220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 51320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (!reg.isEmpty()) { 51420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 51520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(reg, "translate (before)"); 51620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 51720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian reg.mBounds.translate(dx, dy); 51820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian size_t count = reg.mStorage.size(); 51920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect* rects = reg.mStorage.editArray(); 52020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (count) { 52120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rects->translate(dx, dy); 52220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rects++; 52320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian count--; 52420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 52520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 52620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(reg, "translate (after)"); 52720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 52820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 52920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 53020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 53120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::translate(Region& dst, const Region& reg, int dx, int dy) 53220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 53320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian dst = reg; 53420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian translate(dst, dx, dy); 53520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 53620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 53720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectssize_t Region::write(void* buffer, size_t size) const 540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 54120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 54220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(*this, "write(buffer)"); 54320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 54420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const size_t count = mStorage.size(); 54520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const size_t sizeNeeded = sizeof(int32_t) + (1+count)*sizeof(Rect); 546b6121422ef641dc7317d1c3bf1d38b7d73922250Mathias Agopian if (buffer != NULL) { 547b6121422ef641dc7317d1c3bf1d38b7d73922250Mathias Agopian if (sizeNeeded > size) return NO_MEMORY; 548b6121422ef641dc7317d1c3bf1d38b7d73922250Mathias Agopian int32_t* const p = static_cast<int32_t*>(buffer); 549b6121422ef641dc7317d1c3bf1d38b7d73922250Mathias Agopian *p = count; 550b6121422ef641dc7317d1c3bf1d38b7d73922250Mathias Agopian memcpy(p+1, &mBounds, sizeof(Rect)); 551b6121422ef641dc7317d1c3bf1d38b7d73922250Mathias Agopian if (count) { 552b6121422ef641dc7317d1c3bf1d38b7d73922250Mathias Agopian memcpy(p+5, mStorage.array(), count*sizeof(Rect)); 553b6121422ef641dc7317d1c3bf1d38b7d73922250Mathias Agopian } 55420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 55520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return ssize_t(sizeNeeded); 556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectssize_t Region::read(const void* buffer) 559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 56020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian int32_t const* const p = static_cast<int32_t const*>(buffer); 56120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const size_t count = *p; 56220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian memcpy(&mBounds, p+1, sizeof(Rect)); 56320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage.clear(); 56420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (count) { 56520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage.insertAt(0, count); 56620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian memcpy(mStorage.editArray(), p+5, count*sizeof(Rect)); 56720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 56820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 56920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(*this, "read(buffer)"); 57020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 57120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return ssize_t(sizeof(int32_t) + (1+count)*sizeof(Rect)); 572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectssize_t Region::writeEmpty(void* buffer, size_t size) 575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 57620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const size_t sizeNeeded = sizeof(int32_t) + sizeof(Rect); 57720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (sizeNeeded > size) return NO_MEMORY; 57820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian int32_t* const p = static_cast<int32_t*>(buffer); 57920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian memset(p, 0, sizeNeeded); 58020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return ssize_t(sizeNeeded); 581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool Region::isEmpty(void* buffer) 584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 58520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian int32_t const* const p = static_cast<int32_t const*>(buffer); 58620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect const* const b = reinterpret_cast<Rect const *>(p+1); 58720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return b->isEmpty(); 58820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 58920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 59020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 59120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 59220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion::const_iterator Region::begin() const { 59320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return isRect() ? &mBounds : mStorage.array(); 59420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 59520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 59620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion::const_iterator Region::end() const { 59720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return isRect() ? ((&mBounds) + 1) : (mStorage.array() + mStorage.size()); 59820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 59920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 60020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRect const* Region::getArray(size_t* count) const { 60120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator const b(begin()); 60220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator const e(end()); 60320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (count) *count = e-b; 60420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return b; 605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 60720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopiansize_t Region::getRects(Vector<Rect>& rectList) const 608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 60920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rectList = mStorage; 61020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (rectList.isEmpty()) { 61120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rectList.clear(); 61220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rectList.add(mBounds); 613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return rectList.size(); 615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 61720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 61820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Region::dump(String8& out, const char* what, uint32_t flags) const 620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project (void)flags; 62220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator head = begin(); 62320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator const tail = end(); 62420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t SIZE = 256; 626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 62720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 62820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian snprintf(buffer, SIZE, " Region %s (this=%p, count=%d)\n", 62920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian what, this, tail-head); 630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.append(buffer); 63120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (head != tail) { 632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, " [%3d, %3d, %3d, %3d]\n", 63320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->left, head->top, head->right, head->bottom); 634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.append(buffer); 63520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head++; 636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Region::dump(const char* what, uint32_t flags) const 640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project (void)flags; 64220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator head = begin(); 64320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator const tail = end(); 64420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian LOGD(" Region %s (this=%p, count=%d)\n", what, this, tail-head); 64520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (head != tail) { 646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGD(" [%3d, %3d, %3d, %3d]\n", 64720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->left, head->top, head->right, head->bottom); 64820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head++; 649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 655