Region.cpp revision 4c0a170585d5c8a1f3508ac55f799ebaf86e91db
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 6920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion::~Region() 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::operator = (const Region& rhs) 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 7520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 76d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(*this, "this->operator="); 77d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(rhs, "rhs.operator="); 7820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 7920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mBounds = rhs.mBounds; 8020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage = rhs.mStorage; 8120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return *this; 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 849f96145725ff3f265712d607d19078fb91a5c8ecMathias AgopianRegion& Region::makeBoundsSelf() 859f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian{ 869f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian mStorage.clear(); 879f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian return *this; 889f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian} 899f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian 90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Region::clear() 91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 9220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mBounds.clear(); 9320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage.clear(); 94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Region::set(const Rect& r) 97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 9820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mBounds = r; 9920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage.clear(); 100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1020926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianvoid Region::set(uint32_t w, uint32_t h) 1030926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian{ 10420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mBounds = Rect(int(w), int(h)); 10520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage.clear(); 1060926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian} 1070926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::addRectUnchecked(int l, int t, int r, int b) 111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 11220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage.add(Rect(l,t,r,b)); 11320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 11420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(*this, "addRectUnchecked"); 11520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 11820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 11920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 12020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::orSelf(const Rect& r) { 12120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(r, op_or); 12220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 123b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain GuyRegion& Region::xorSelf(const Rect& r) { 124b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy return operationSelf(r, op_xor); 125b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 12620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::andSelf(const Rect& r) { 12720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(r, op_and); 12820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 12920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::subtractSelf(const Rect& r) { 13020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(r, op_nand); 13120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 13220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::operationSelf(const Rect& r, int op) { 13320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region lhs(*this); 13420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, *this, lhs, r); 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *this; 136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::orSelf(const Region& rhs) { 14120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, op_or); 142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 143b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain GuyRegion& Region::xorSelf(const Region& rhs) { 144b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy return operationSelf(rhs, op_xor); 145b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 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} 168b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guyconst Region Region::mergeExclusive(const Rect& rhs) const { 169b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy return operation(rhs, op_xor); 170b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 171bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::intersect(const Rect& rhs) const { 17220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_and); 17320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 174bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::subtract(const Rect& rhs) const { 17520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_nand); 17620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 177bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::operation(const Rect& rhs, int op) const { 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region result; 17920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, result, *this, rhs); 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return result; 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 18320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 18420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 185bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::merge(const Region& rhs) const { 18620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_or); 18720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 188b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guyconst Region Region::mergeExclusive(const Region& rhs) const { 189b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy return operation(rhs, op_xor); 190b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 191bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::intersect(const Region& rhs) const { 19220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_and); 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 194bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::subtract(const Region& rhs) const { 19520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_nand); 19620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 197bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::operation(const Region& rhs, int op) const { 198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region result; 19920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, result, *this, rhs); 200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return result; 201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 203bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::translate(int x, int y) const { 204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region result; 20520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian translate(result, *this, x, y); 206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return result; 207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::orSelf(const Region& rhs, int dx, int dy) { 21220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, dx, dy, op_or); 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 214b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain GuyRegion& Region::xorSelf(const Region& rhs, int dx, int dy) { 215b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy return operationSelf(rhs, dx, dy, op_xor); 216b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::andSelf(const Region& rhs, int dx, int dy) { 21820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, dx, dy, op_and); 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::subtractSelf(const Region& rhs, int dx, int dy) { 22120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, dx, dy, op_nand); 22220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 22320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::operationSelf(const Region& rhs, int dx, int dy, int op) { 22420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region lhs(*this); 22520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, *this, lhs, rhs, dx, dy); 226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *this; 227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 22920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 23020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 231bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::merge(const Region& rhs, int dx, int dy) const { 23220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, dx, dy, op_or); 233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 234b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guyconst Region Region::mergeExclusive(const Region& rhs, int dx, int dy) const { 235b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy return operation(rhs, dx, dy, op_xor); 236b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 237bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::intersect(const Region& rhs, int dx, int dy) const { 23820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, dx, dy, op_and); 239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 240bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::subtract(const Region& rhs, int dx, int dy) const { 24120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, dx, dy, op_nand); 24220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 243bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::operation(const Region& rhs, int dx, int dy, int op) const { 244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region result; 24520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, result, *this, rhs, dx, dy); 246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return result; 247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 25120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// This is our region rasterizer, which merges rects and spans together 25220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// to obtain an optimal region. 25320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianclass Region::rasterizer : public region_operator<Rect>::region_rasterizer 25420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 25520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect& bounds; 25620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Vector<Rect>& storage; 25720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect* head; 25820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect* tail; 25920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Vector<Rect> span; 26020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect* cur; 26120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianpublic: 26220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rasterizer(Region& reg) 26320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian : bounds(reg.mBounds), storage(reg.mStorage), head(), tail(), cur() { 26420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.top = bounds.bottom = 0; 26520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.left = INT_MAX; 26620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.right = INT_MIN; 26720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian storage.clear(); 26820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 26920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 27020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian ~rasterizer() { 27120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (span.size()) { 27220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian flushSpan(); 27320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 27420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (storage.size()) { 27520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.top = storage.itemAt(0).top; 27620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.bottom = storage.top().bottom; 27720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (storage.size() == 1) { 27820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian storage.clear(); 27920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 28020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } else { 28120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.left = 0; 28220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.right = 0; 28320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 28420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 28520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 28620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian virtual void operator()(const Rect& rect) { 2879d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD(">>> %3d, %3d, %3d, %3d", 28820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian // rect.left, rect.top, rect.right, rect.bottom); 28920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (span.size()) { 29020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (cur->top != rect.top) { 29120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian flushSpan(); 29220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } else if (cur->right == rect.left) { 29320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian cur->right = rect.right; 29420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return; 29520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 29620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 29720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian span.add(rect); 29820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian cur = span.editArray() + (span.size() - 1); 29920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 30020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianprivate: 30120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian template<typename T> 30220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian static inline T min(T rhs, T lhs) { return rhs < lhs ? rhs : lhs; } 30320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian template<typename T> 30420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian static inline T max(T rhs, T lhs) { return rhs > lhs ? rhs : lhs; } 30520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian void flushSpan() { 30620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bool merge = false; 30720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (tail-head == ssize_t(span.size())) { 308b801624dc4f03c930ec35f406f07fa5fd8f65dd9Romain Guy Rect const* p = span.editArray(); 30920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect const* q = head; 31020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (p->top == q->bottom) { 31120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian merge = true; 31220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (q != tail) { 31320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if ((p->left != q->left) || (p->right != q->right)) { 31420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian merge = false; 31520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian break; 31620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 31720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian p++, q++; 31820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 31920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 32020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 32120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (merge) { 32220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const int bottom = span[0].bottom; 32320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect* r = head; 32420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (r != tail) { 32520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian r->bottom = bottom; 32620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian r++; 32720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 32820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } else { 32920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.left = min(span.itemAt(0).left, bounds.left); 33020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.right = max(span.top().right, bounds.right); 33120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian storage.appendVector(span); 33220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian tail = storage.editArray() + storage.size(); 33320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head = tail - span.size(); 33420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 33520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian span.clear(); 33620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 33720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian}; 33820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 33920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianbool Region::validate(const Region& reg, const char* name) 340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 34120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bool result = true; 34220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator cur = reg.begin(); 34320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator const tail = reg.end(); 34420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator prev = cur++; 34520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect b(*prev); 34620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (cur != tail) { 34720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian b.left = b.left < cur->left ? b.left : cur->left; 34820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian b.top = b.top < cur->top ? b.top : cur->top; 34920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian b.right = b.right > cur->right ? b.right : cur->right; 35020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian b.bottom = b.bottom > cur->bottom ? b.bottom : cur->bottom; 35120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (cur->top == prev->top) { 35220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (cur->bottom != prev->bottom) { 353e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("%s: invalid span %p", name, cur); 35420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian result = false; 35520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } else if (cur->left < prev->right) { 356e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("%s: spans overlap horizontally prev=%p, cur=%p", 35720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian name, prev, cur); 35820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian result = false; 35920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 36020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } else if (cur->top < prev->bottom) { 361e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("%s: spans overlap vertically prev=%p, cur=%p", 36220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian name, prev, cur); 36320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian result = false; 36420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 36520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian prev = cur; 36620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian cur++; 36720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 36820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (b != reg.getBounds()) { 36920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian result = false; 370e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("%s: invalid bounds [%d,%d,%d,%d] vs. [%d,%d,%d,%d]", name, 37120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian b.left, b.top, b.right, b.bottom, 37220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian reg.getBounds().left, reg.getBounds().top, 37320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian reg.getBounds().right, reg.getBounds().bottom); 37420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 37520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (result == false) { 37620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian reg.dump(name); 37720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 37820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return result; 379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 38120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::boolean_operation(int op, Region& dst, 38220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& lhs, 38320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& rhs, int dx, int dy) 384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 385d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian#if VALIDATE_REGIONS 386d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(lhs, "boolean_operation (before): lhs"); 387d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(rhs, "boolean_operation (before): rhs"); 388d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(dst, "boolean_operation (before): dst"); 389d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian#endif 390d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian 39120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian size_t lhs_count; 39220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect const * const lhs_rects = lhs.getArray(&lhs_count); 39320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 39420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian size_t rhs_count; 39520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect const * const rhs_rects = rhs.getArray(&rhs_count); 39620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 39720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect>::region lhs_region(lhs_rects, lhs_count); 39820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect>::region rhs_region(rhs_rects, rhs_count, dx, dy); 39920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect> operation(op, lhs_region, rhs_region); 40020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian { // scope for rasterizer (dtor has side effects) 40120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rasterizer r(dst); 40220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian operation(r); 40320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 40420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 40520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 40620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(lhs, "boolean_operation: lhs"); 40720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(rhs, "boolean_operation: rhs"); 40820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(dst, "boolean_operation: dst"); 40920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 41020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 41120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_WITH_CORECG 41220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion sk_lhs; 41320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion sk_rhs; 41420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion sk_dst; 41520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 41620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian for (size_t i=0 ; i<lhs_count ; i++) 41720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian sk_lhs.op( 41820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs_rects[i].left + dx, 41920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs_rects[i].top + dy, 42020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs_rects[i].right + dx, 42120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs_rects[i].bottom + dy, 42220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::kUnion_Op); 42320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 42420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian for (size_t i=0 ; i<rhs_count ; i++) 42520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian sk_rhs.op( 42620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs_rects[i].left + dx, 42720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs_rects[i].top + dy, 42820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs_rects[i].right + dx, 42920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs_rects[i].bottom + dy, 43020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::kUnion_Op); 43120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 43220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const char* name = "---"; 43320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::Op sk_op; 43420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian switch (op) { 43520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian case op_or: sk_op = SkRegion::kUnion_Op; name="OR"; break; 436b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy case op_xor: sk_op = SkRegion::kUnion_XOR; name="XOR"; break; 43720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian case op_and: sk_op = SkRegion::kIntersect_Op; name="AND"; break; 43820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian case op_nand: sk_op = SkRegion::kDifference_Op; name="NAND"; break; 43920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 44020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian sk_dst.op(sk_lhs, sk_rhs, sk_op); 44120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 44220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (sk_dst.isEmpty() && dst.isEmpty()) 44320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return; 44420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 44520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bool same = true; 44620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator head = dst.begin(); 44720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const tail = dst.end(); 44820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::Iterator it(sk_dst); 44920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (!it.done()) { 45020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (head != tail) { 45120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if ( 45220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->left != it.rect().fLeft || 45320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->top != it.rect().fTop || 45420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->right != it.rect().fRight || 45520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->bottom != it.rect().fBottom 45620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian ) { 45720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian same = false; 45820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian break; 45920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 46020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } else { 46120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian same = false; 46220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian break; 46320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 46420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head++; 46520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.next(); 46620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 46720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 46820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (head != tail) { 46920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian same = false; 47020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 47120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 47220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if(!same) { 4739d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("---\nregion boolean %s failed", name); 47420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs.dump("lhs"); 47520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs.dump("rhs"); 47620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian dst.dump("dst"); 4779d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("should be"); 47820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::Iterator it(sk_dst); 47920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (!it.done()) { 4809d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD(" [%3d, %3d, %3d, %3d]", 48120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.rect().fLeft, 48220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.rect().fTop, 48320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.rect().fRight, 48420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.rect().fBottom); 48520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.next(); 48620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 48720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 48820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 49120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::boolean_operation(int op, Region& dst, 49220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& lhs, 49320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& rhs, int dx, int dy) 49420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 4950450452e8c6ea48341d57d8bc51d56252e9806b8Mathias Agopian if (!rhs.isValid()) { 496e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Region::boolean_operation(op=%d) invalid Rect={%d,%d,%d,%d}", 4970450452e8c6ea48341d57d8bc51d56252e9806b8Mathias Agopian op, rhs.left, rhs.top, rhs.right, rhs.bottom); 4980857c8f7f1905008b285a5473c906639fdd0288bMathias Agopian return; 4990450452e8c6ea48341d57d8bc51d56252e9806b8Mathias Agopian } 5000450452e8c6ea48341d57d8bc51d56252e9806b8Mathias Agopian 50120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_WITH_CORECG || VALIDATE_REGIONS 50220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, dst, lhs, Region(rhs), dx, dy); 50320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#else 50420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian size_t lhs_count; 50520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect const * const lhs_rects = lhs.getArray(&lhs_count); 50620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 50720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect>::region lhs_region(lhs_rects, lhs_count); 50820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect>::region rhs_region(&rhs, 1, dx, dy); 50920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect> operation(op, lhs_region, rhs_region); 51020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian { // scope for rasterizer (dtor has side effects) 51120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rasterizer r(dst); 51220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian operation(r); 51320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 51520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 51620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 51720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 51820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::boolean_operation(int op, Region& dst, 51920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& lhs, const Region& rhs) 52020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 52120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, dst, lhs, rhs, 0, 0); 52220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 52320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 52420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::boolean_operation(int op, Region& dst, 52520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& lhs, const Rect& rhs) 52620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 52720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, dst, lhs, rhs, 0, 0); 52820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 52920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 53020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::translate(Region& reg, int dx, int dy) 53120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 5324c0a170585d5c8a1f3508ac55f799ebaf86e91dbMathias Agopian if ((dx || dy) && !reg.isEmpty()) { 53320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 53420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(reg, "translate (before)"); 53520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 53620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian reg.mBounds.translate(dx, dy); 53720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian size_t count = reg.mStorage.size(); 53820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect* rects = reg.mStorage.editArray(); 53920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (count) { 54020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rects->translate(dx, dy); 54120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rects++; 54220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian count--; 54320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 54420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 54520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(reg, "translate (after)"); 54620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 54720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 54820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 54920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 55020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::translate(Region& dst, const Region& reg, int dx, int dy) 55120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 55220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian dst = reg; 55320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian translate(dst, dx, dy); 55420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 55520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 55620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5588683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopiansize_t Region::getSize() const { 5598683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian return (mStorage.size() + 1) * sizeof(Rect); 560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5628683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopianstatus_t Region::flatten(void* buffer) const { 5638683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian Rect* rects = reinterpret_cast<Rect*>(buffer); 5648683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian *rects++ = mBounds; 5658683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian memcpy(rects, mStorage.array(), mStorage.size() * sizeof(Rect)); 5668683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian return NO_ERROR; 567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5698683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopianstatus_t Region::unflatten(void const* buffer, size_t size) { 5708683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian mStorage.clear(); 5718683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian if (size >= sizeof(Rect)) { 5728683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian Rect const* rects = reinterpret_cast<Rect const*>(buffer); 5738683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian mBounds = *rects++; 5748683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian size -= sizeof(Rect); 5758683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian size_t count = size / sizeof(Rect); 5768683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian if (count > 0) { 5778683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian ssize_t err = mStorage.insertAt(0, count); 5788683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian if (err < 0) { 5798683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian return status_t(err); 5808683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian } 5818683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian memcpy(mStorage.editArray(), rects, count*sizeof(Rect)); 5828683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian } 5838683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian } 5848683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian return NO_ERROR; 58520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 58620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 58720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 58820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 58920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion::const_iterator Region::begin() const { 59020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return isRect() ? &mBounds : mStorage.array(); 59120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 59220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 59320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion::const_iterator Region::end() const { 5943aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian if (isRect()) { 5953aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian if (isEmpty()) { 5963aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian return &mBounds; 5973aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian } else { 5983aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian return &mBounds + 1; 5993aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian } 6003aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian } else { 6013aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian return mStorage.array() + mStorage.size(); 6023aecbb0715cb6928e0530ff1e4caa9c0993cc371Mathias Agopian } 60320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 60420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 60520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRect const* Region::getArray(size_t* count) const { 60620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator const b(begin()); 60720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator const e(end()); 60820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (count) *count = e-b; 60920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return b; 610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 61220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopiansize_t Region::getRects(Vector<Rect>& rectList) const 613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 61420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rectList = mStorage; 61520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (rectList.isEmpty()) { 61620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rectList.clear(); 61720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rectList.add(mBounds); 618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return rectList.size(); 620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 62220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 62320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Region::dump(String8& out, const char* what, uint32_t flags) const 625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project (void)flags; 62720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator head = begin(); 62820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator const tail = end(); 62920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t SIZE = 256; 631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 63220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 63320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian snprintf(buffer, SIZE, " Region %s (this=%p, count=%d)\n", 63420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian what, this, tail-head); 635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.append(buffer); 63620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (head != tail) { 637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, " [%3d, %3d, %3d, %3d]\n", 63820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->left, head->top, head->right, head->bottom); 639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.append(buffer); 64020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head++; 641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Region::dump(const char* what, uint32_t flags) const 645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project (void)flags; 64720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator head = begin(); 64820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator const tail = end(); 6499d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD(" Region %s (this=%p, count=%d)\n", what, this, tail-head); 65020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (head != tail) { 6519d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD(" [%3d, %3d, %3d, %3d]\n", 65220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->left, head->top, head->right, head->bottom); 65320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head++; 654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 660