Region.cpp revision 3e010f3138593cc6953039ee0e3db8ee31881296
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> 23068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian#include <utils/CallStack.h> 2420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 2520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#include <ui/Rect.h> 26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Region.h> 2720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#include <ui/Point.h> 2820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 2920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#include <private/ui/RegionHelper.h> 3020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 3120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 3220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#define VALIDATE_REGIONS (false) 3320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#define VALIDATE_WITH_CORECG (false) 3420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 3520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 3620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_WITH_CORECG 3720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#include <core/SkRegion.h> 3820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 4120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 4220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 4320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianenum { 4420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian op_nand = region_operator<Rect>::op_nand, 4520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian op_and = region_operator<Rect>::op_and, 4620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian op_or = region_operator<Rect>::op_or, 4720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian op_xor = region_operator<Rect>::op_xor 4820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian}; 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 503e010f3138593cc6953039ee0e3db8ee31881296Chris Craikenum { 513e010f3138593cc6953039ee0e3db8ee31881296Chris Craik direction_LTR, 523e010f3138593cc6953039ee0e3db8ee31881296Chris Craik direction_RTL 533e010f3138593cc6953039ee0e3db8ee31881296Chris Craik}; 543e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 573ab68558fa5a4b8f792a54965a010f03385bd271Mathias AgopianRegion::Region() { 583ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian mStorage.add(Rect(0,0)); 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion::Region(const Region& rhs) 623ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian : mStorage(rhs.mStorage) 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 64d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian#if VALIDATE_REGIONS 65d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(rhs, "rhs copy-ctor"); 66d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian#endif 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 693ab68558fa5a4b8f792a54965a010f03385bd271Mathias AgopianRegion::Region(const Rect& rhs) { 703ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian mStorage.add(rhs); 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion::~Region() 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 773e010f3138593cc6953039ee0e3db8ee31881296Chris Craik/** 783e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * Copy rects from the src vector into the dst vector, resolving vertical T-Junctions along the way 793e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * 803e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * First pass through, divideSpanRTL will be set because the 'previous span' (indexing into the dst 813e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * vector) will be reversed. Each rectangle in the original list, starting from the bottom, will be 823e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * compared with the span directly below, and subdivided as needed to resolve T-junctions. 833e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * 843e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * The resulting temporary vector will be a completely reversed copy of the original, without any 853e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * bottom-up T-junctions. 863e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * 873e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * Second pass through, divideSpanRTL will be false since the previous span will index into the 883e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * final, correctly ordered region buffer. Each rectangle will be compared with the span directly 893e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * above it, and subdivided to resolve any remaining T-junctions. 903e010f3138593cc6953039ee0e3db8ee31881296Chris Craik */ 913e010f3138593cc6953039ee0e3db8ee31881296Chris Craikstatic void reverseRectsResolvingJunctions(const Rect* begin, const Rect* end, 923e010f3138593cc6953039ee0e3db8ee31881296Chris Craik Vector<Rect>& dst, int spanDirection) { 933e010f3138593cc6953039ee0e3db8ee31881296Chris Craik dst.clear(); 943e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 953e010f3138593cc6953039ee0e3db8ee31881296Chris Craik const Rect* current = end - 1; 963e010f3138593cc6953039ee0e3db8ee31881296Chris Craik int lastTop = current->top; 973e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 983e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // add first span immediately 993e010f3138593cc6953039ee0e3db8ee31881296Chris Craik do { 1003e010f3138593cc6953039ee0e3db8ee31881296Chris Craik dst.add(*current); 1013e010f3138593cc6953039ee0e3db8ee31881296Chris Craik current--; 1023e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } while (current->top == lastTop && current >= begin); 1033e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1043e010f3138593cc6953039ee0e3db8ee31881296Chris Craik unsigned int beginLastSpan = -1; 1053e010f3138593cc6953039ee0e3db8ee31881296Chris Craik unsigned int endLastSpan = -1; 1063e010f3138593cc6953039ee0e3db8ee31881296Chris Craik int top = -1; 1073e010f3138593cc6953039ee0e3db8ee31881296Chris Craik int bottom = -1; 1083e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1093e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // for all other spans, split if a t-junction exists in the span directly above 1103e010f3138593cc6953039ee0e3db8ee31881296Chris Craik while (current >= begin) { 1113e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if (current->top != (current + 1)->top) { 1123e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // new span 1133e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if ((spanDirection == direction_RTL && current->bottom != (current + 1)->top) || 1143e010f3138593cc6953039ee0e3db8ee31881296Chris Craik (spanDirection == direction_LTR && current->top != (current + 1)->bottom)) { 1153e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // previous span not directly adjacent, don't check for T junctions 1163e010f3138593cc6953039ee0e3db8ee31881296Chris Craik beginLastSpan = INT_MAX; 1173e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } else { 1183e010f3138593cc6953039ee0e3db8ee31881296Chris Craik beginLastSpan = endLastSpan + 1; 1193e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1203e010f3138593cc6953039ee0e3db8ee31881296Chris Craik endLastSpan = dst.size() - 1; 1213e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1223e010f3138593cc6953039ee0e3db8ee31881296Chris Craik top = current->top; 1233e010f3138593cc6953039ee0e3db8ee31881296Chris Craik bottom = current->bottom; 1243e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1253e010f3138593cc6953039ee0e3db8ee31881296Chris Craik int left = current->left; 1263e010f3138593cc6953039ee0e3db8ee31881296Chris Craik int right = current->right; 1273e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1283e010f3138593cc6953039ee0e3db8ee31881296Chris Craik for (unsigned int prevIndex = beginLastSpan; prevIndex <= endLastSpan; prevIndex++) { 1293e010f3138593cc6953039ee0e3db8ee31881296Chris Craik const Rect* prev = &dst[prevIndex]; 1303e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if (spanDirection == direction_RTL) { 1313e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // iterating over previous span RTL, quit if it's too far left 1323e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if (prev->right <= left) break; 1333e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1343e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if (prev->right > left && prev->right < right) { 1353e010f3138593cc6953039ee0e3db8ee31881296Chris Craik dst.add(Rect(prev->right, top, right, bottom)); 1363e010f3138593cc6953039ee0e3db8ee31881296Chris Craik right = prev->right; 1373e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1383e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1393e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if (prev->left > left && prev->left < right) { 1403e010f3138593cc6953039ee0e3db8ee31881296Chris Craik dst.add(Rect(prev->left, top, right, bottom)); 1413e010f3138593cc6953039ee0e3db8ee31881296Chris Craik right = prev->left; 1423e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1433e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1443e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // if an entry in the previous span is too far right, nothing further left in the 1453e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // current span will need it 1463e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if (prev->left >= right) { 1473e010f3138593cc6953039ee0e3db8ee31881296Chris Craik beginLastSpan = prevIndex; 1483e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1493e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } else { 1503e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // iterating over previous span LTR, quit if it's too far right 1513e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if (prev->left >= right) break; 1523e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1533e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if (prev->left > left && prev->left < right) { 1543e010f3138593cc6953039ee0e3db8ee31881296Chris Craik dst.add(Rect(left, top, prev->left, bottom)); 1553e010f3138593cc6953039ee0e3db8ee31881296Chris Craik left = prev->left; 1563e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1573e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1583e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if (prev->right > left && prev->right < right) { 1593e010f3138593cc6953039ee0e3db8ee31881296Chris Craik dst.add(Rect(left, top, prev->right, bottom)); 1603e010f3138593cc6953039ee0e3db8ee31881296Chris Craik left = prev->right; 1613e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1623e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // if an entry in the previous span is too far left, nothing further right in the 1633e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // current span will need it 1643e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if (prev->right <= left) { 1653e010f3138593cc6953039ee0e3db8ee31881296Chris Craik beginLastSpan = prevIndex; 1663e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1673e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1683e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1693e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1703e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if (left < right) { 1713e010f3138593cc6953039ee0e3db8ee31881296Chris Craik dst.add(Rect(left, top, right, bottom)); 1723e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1733e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1743e010f3138593cc6953039ee0e3db8ee31881296Chris Craik current--; 1753e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1763e010f3138593cc6953039ee0e3db8ee31881296Chris Craik} 1773e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1783e010f3138593cc6953039ee0e3db8ee31881296Chris Craik/** 1793e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * Creates a new region with the same data as the argument, but divides rectangles as necessary to 1803e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * remove T-Junctions 1813e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * 1823e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * Note: the output will not necessarily be a very efficient representation of the region, since it 1833e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * may be that a triangle-based approach would generate significantly simpler geometry 1843e010f3138593cc6953039ee0e3db8ee31881296Chris Craik */ 1853e010f3138593cc6953039ee0e3db8ee31881296Chris CraikRegion Region::createTJunctionFreeRegion(const Region& r) { 1863e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if (r.isEmpty()) return r; 1873e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if (r.isRect()) return r; 1883e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1893e010f3138593cc6953039ee0e3db8ee31881296Chris Craik Vector<Rect> reversed; 1903e010f3138593cc6953039ee0e3db8ee31881296Chris Craik reverseRectsResolvingJunctions(r.begin(), r.end(), reversed, direction_RTL); 1913e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1923e010f3138593cc6953039ee0e3db8ee31881296Chris Craik Region outputRegion; 1933e010f3138593cc6953039ee0e3db8ee31881296Chris Craik reverseRectsResolvingJunctions(reversed.begin(), reversed.end(), 1943e010f3138593cc6953039ee0e3db8ee31881296Chris Craik outputRegion.mStorage, direction_LTR); 1953e010f3138593cc6953039ee0e3db8ee31881296Chris Craik outputRegion.mStorage.add(r.getBounds()); // to make region valid, mStorage must end with bounds 1963e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1973e010f3138593cc6953039ee0e3db8ee31881296Chris Craik#if VALIDATE_REGIONS 1983e010f3138593cc6953039ee0e3db8ee31881296Chris Craik validate(outputRegion, "T-Junction free region"); 1993e010f3138593cc6953039ee0e3db8ee31881296Chris Craik#endif 2003e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 2013e010f3138593cc6953039ee0e3db8ee31881296Chris Craik return outputRegion; 2023e010f3138593cc6953039ee0e3db8ee31881296Chris Craik} 2033e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 20420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::operator = (const Region& rhs) 205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 20620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 207d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(*this, "this->operator="); 208d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(rhs, "rhs.operator="); 20920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 21020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage = rhs.mStorage; 21120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return *this; 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2149f96145725ff3f265712d607d19078fb91a5c8ecMathias AgopianRegion& Region::makeBoundsSelf() 2159f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian{ 2163ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian if (mStorage.size() >= 2) { 2173ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian const Rect bounds(getBounds()); 2183ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian mStorage.clear(); 2193ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian mStorage.add(bounds); 2203ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian } 2219f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian return *this; 2229f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian} 2239f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Region::clear() 225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 22620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage.clear(); 2273ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian mStorage.add(Rect(0,0)); 228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Region::set(const Rect& r) 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 23220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage.clear(); 2333ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian mStorage.add(r); 234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2360926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianvoid Region::set(uint32_t w, uint32_t h) 2370926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian{ 23820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage.clear(); 2393ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian mStorage.add(Rect(w,h)); 2400926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian} 2410926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 24420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::addRectUnchecked(int l, int t, int r, int b) 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2463ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian Rect rect(l,t,r,b); 2473ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian size_t where = mStorage.size() - 1; 2483ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian mStorage.insertAt(rect, where, 1); 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 25120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 25220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 25320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::orSelf(const Rect& r) { 25420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(r, op_or); 25520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 256b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain GuyRegion& Region::xorSelf(const Rect& r) { 257b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy return operationSelf(r, op_xor); 258b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 25920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::andSelf(const Rect& r) { 26020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(r, op_and); 26120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 26220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::subtractSelf(const Rect& r) { 26320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(r, op_nand); 26420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 26520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::operationSelf(const Rect& r, int op) { 26620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region lhs(*this); 26720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, *this, lhs, r); 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *this; 269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::orSelf(const Region& rhs) { 27420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, op_or); 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 276b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain GuyRegion& Region::xorSelf(const Region& rhs) { 277b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy return operationSelf(rhs, op_xor); 278b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::andSelf(const Region& rhs) { 28020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, op_and); 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::subtractSelf(const Region& rhs) { 28320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, op_nand); 28420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 28520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::operationSelf(const Region& rhs, int op) { 28620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region lhs(*this); 28720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, *this, lhs, rhs); 288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *this; 289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::translateSelf(int x, int y) { 29220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (x|y) translate(*this, x, y); 293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *this; 294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 29620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 29720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 298bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::merge(const Rect& rhs) const { 29920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_or); 30020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 301b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guyconst Region Region::mergeExclusive(const Rect& rhs) const { 302b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy return operation(rhs, op_xor); 303b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 304bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::intersect(const Rect& rhs) const { 30520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_and); 30620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 307bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::subtract(const Rect& rhs) const { 30820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_nand); 30920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 310bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::operation(const Rect& rhs, int op) const { 311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region result; 31220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, result, *this, rhs); 313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return result; 314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 31620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 31720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 318bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::merge(const Region& rhs) const { 31920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_or); 32020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 321b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guyconst Region Region::mergeExclusive(const Region& rhs) const { 322b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy return operation(rhs, op_xor); 323b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 324bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::intersect(const Region& rhs) const { 32520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_and); 326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 327bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::subtract(const Region& rhs) const { 32820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_nand); 32920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 330bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::operation(const Region& rhs, int op) const { 331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region result; 33220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, result, *this, rhs); 333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return result; 334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 336bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::translate(int x, int y) const { 337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region result; 33820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian translate(result, *this, x, y); 339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return result; 340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::orSelf(const Region& rhs, int dx, int dy) { 34520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, dx, dy, op_or); 346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 347b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain GuyRegion& Region::xorSelf(const Region& rhs, int dx, int dy) { 348b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy return operationSelf(rhs, dx, dy, op_xor); 349b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::andSelf(const Region& rhs, int dx, int dy) { 35120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, dx, dy, op_and); 352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::subtractSelf(const Region& rhs, int dx, int dy) { 35420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, dx, dy, op_nand); 35520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 35620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::operationSelf(const Region& rhs, int dx, int dy, int op) { 35720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region lhs(*this); 35820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, *this, lhs, rhs, dx, dy); 359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *this; 360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 36220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 36320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 364bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::merge(const Region& rhs, int dx, int dy) const { 36520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, dx, dy, op_or); 366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 367b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guyconst Region Region::mergeExclusive(const Region& rhs, int dx, int dy) const { 368b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy return operation(rhs, dx, dy, op_xor); 369b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 370bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::intersect(const Region& rhs, int dx, int dy) const { 37120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, dx, dy, op_and); 372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 373bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::subtract(const Region& rhs, int dx, int dy) const { 37420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, dx, dy, op_nand); 37520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 376bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::operation(const Region& rhs, int dx, int dy, int op) const { 377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region result; 37820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, result, *this, rhs, dx, dy); 379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return result; 380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 38420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// This is our region rasterizer, which merges rects and spans together 38520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// to obtain an optimal region. 38620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianclass Region::rasterizer : public region_operator<Rect>::region_rasterizer 38720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 3883ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian Rect bounds; 38920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Vector<Rect>& storage; 39020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect* head; 39120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect* tail; 39220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Vector<Rect> span; 39320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect* cur; 39420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianpublic: 39520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rasterizer(Region& reg) 3963ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian : bounds(INT_MAX, 0, INT_MIN, 0), storage(reg.mStorage), head(), tail(), cur() { 39720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian storage.clear(); 39820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 39920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 40020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian ~rasterizer() { 40120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (span.size()) { 40220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian flushSpan(); 40320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 40420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (storage.size()) { 40520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.top = storage.itemAt(0).top; 40620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.bottom = storage.top().bottom; 40720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (storage.size() == 1) { 40820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian storage.clear(); 40920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 41020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } else { 41120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.left = 0; 41220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.right = 0; 41320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 4143ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian storage.add(bounds); 41520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 41620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 41720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian virtual void operator()(const Rect& rect) { 4189d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD(">>> %3d, %3d, %3d, %3d", 41920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian // rect.left, rect.top, rect.right, rect.bottom); 42020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (span.size()) { 42120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (cur->top != rect.top) { 42220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian flushSpan(); 42320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } else if (cur->right == rect.left) { 42420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian cur->right = rect.right; 42520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return; 42620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 42720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 42820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian span.add(rect); 42920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian cur = span.editArray() + (span.size() - 1); 43020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 43120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianprivate: 43220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian template<typename T> 43320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian static inline T min(T rhs, T lhs) { return rhs < lhs ? rhs : lhs; } 43420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian template<typename T> 43520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian static inline T max(T rhs, T lhs) { return rhs > lhs ? rhs : lhs; } 43620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian void flushSpan() { 43720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bool merge = false; 43820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (tail-head == ssize_t(span.size())) { 439b801624dc4f03c930ec35f406f07fa5fd8f65dd9Romain Guy Rect const* p = span.editArray(); 44020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect const* q = head; 44120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (p->top == q->bottom) { 44220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian merge = true; 44320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (q != tail) { 44420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if ((p->left != q->left) || (p->right != q->right)) { 44520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian merge = false; 44620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian break; 44720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 44820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian p++, q++; 44920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 45020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 45120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 45220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (merge) { 45320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const int bottom = span[0].bottom; 45420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect* r = head; 45520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (r != tail) { 45620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian r->bottom = bottom; 45720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian r++; 45820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 45920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } else { 46020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.left = min(span.itemAt(0).left, bounds.left); 46120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bounds.right = max(span.top().right, bounds.right); 46220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian storage.appendVector(span); 46320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian tail = storage.editArray() + storage.size(); 46420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head = tail - span.size(); 46520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 46620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian span.clear(); 46720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 46820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian}; 46920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 470068d47f29dfead847999a7b33b4217ee9514152bMathias Agopianbool Region::validate(const Region& reg, const char* name, bool silent) 471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 47220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bool result = true; 47320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator cur = reg.begin(); 47420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator const tail = reg.end(); 475068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian const_iterator prev = cur; 47620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect b(*prev); 47720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (cur != tail) { 478068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian if (cur->isValid() == false) { 479068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ALOGE_IF(!silent, "%s: region contains an invalid Rect", name); 480068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian result = false; 481068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian } 482068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian if (cur->right > region_operator<Rect>::max_value) { 483068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ALOGE_IF(!silent, "%s: rect->right > max_value", name); 484068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian result = false; 485068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian } 486068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian if (cur->bottom > region_operator<Rect>::max_value) { 487068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ALOGE_IF(!silent, "%s: rect->right > max_value", name); 488068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian result = false; 489068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian } 490068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian if (prev != cur) { 491068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian b.left = b.left < cur->left ? b.left : cur->left; 492068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian b.top = b.top < cur->top ? b.top : cur->top; 493068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian b.right = b.right > cur->right ? b.right : cur->right; 494068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian b.bottom = b.bottom > cur->bottom ? b.bottom : cur->bottom; 495068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian if ((*prev < *cur) == false) { 496068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ALOGE_IF(!silent, "%s: region's Rects not sorted", name); 49720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian result = false; 498068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian } 499068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian if (cur->top == prev->top) { 500068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian if (cur->bottom != prev->bottom) { 501068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ALOGE_IF(!silent, "%s: invalid span %p", name, cur); 502068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian result = false; 503068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian } else if (cur->left < prev->right) { 504068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ALOGE_IF(!silent, 505068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian "%s: spans overlap horizontally prev=%p, cur=%p", 506068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian name, prev, cur); 507068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian result = false; 508068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian } 509068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian } else if (cur->top < prev->bottom) { 510068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ALOGE_IF(!silent, 511068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian "%s: spans overlap vertically prev=%p, cur=%p", 51220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian name, prev, cur); 51320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian result = false; 51420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 515068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian prev = cur; 51620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 51720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian cur++; 51820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 51920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (b != reg.getBounds()) { 52020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian result = false; 521068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ALOGE_IF(!silent, 522068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian "%s: invalid bounds [%d,%d,%d,%d] vs. [%d,%d,%d,%d]", name, 52320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian b.left, b.top, b.right, b.bottom, 52420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian reg.getBounds().left, reg.getBounds().top, 52520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian reg.getBounds().right, reg.getBounds().bottom); 52620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 5273ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian if (reg.mStorage.size() == 2) { 528068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian result = false; 529068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ALOGE_IF(!silent, "%s: mStorage size is 2, which is never valid", name); 5303ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian } 531068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian if (result == false && !silent) { 53220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian reg.dump(name); 533068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian CallStack stack; 534068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian stack.update(); 535068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian stack.dump(""); 53620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 53720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return result; 538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 54020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::boolean_operation(int op, Region& dst, 54120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& lhs, 54220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& rhs, int dx, int dy) 543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 544d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian#if VALIDATE_REGIONS 545d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(lhs, "boolean_operation (before): lhs"); 546d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(rhs, "boolean_operation (before): rhs"); 547d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(dst, "boolean_operation (before): dst"); 548d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian#endif 549d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian 55020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian size_t lhs_count; 55120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect const * const lhs_rects = lhs.getArray(&lhs_count); 55220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 55320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian size_t rhs_count; 55420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect const * const rhs_rects = rhs.getArray(&rhs_count); 55520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 55620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect>::region lhs_region(lhs_rects, lhs_count); 55720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect>::region rhs_region(rhs_rects, rhs_count, dx, dy); 55820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect> operation(op, lhs_region, rhs_region); 55920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian { // scope for rasterizer (dtor has side effects) 56020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rasterizer r(dst); 56120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian operation(r); 56220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 56320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 56420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 56520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(lhs, "boolean_operation: lhs"); 56620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(rhs, "boolean_operation: rhs"); 56720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(dst, "boolean_operation: dst"); 56820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 56920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 57020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_WITH_CORECG 57120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion sk_lhs; 57220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion sk_rhs; 57320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion sk_dst; 57420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 57520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian for (size_t i=0 ; i<lhs_count ; i++) 57620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian sk_lhs.op( 57720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs_rects[i].left + dx, 57820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs_rects[i].top + dy, 57920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs_rects[i].right + dx, 58020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs_rects[i].bottom + dy, 58120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::kUnion_Op); 58220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 58320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian for (size_t i=0 ; i<rhs_count ; i++) 58420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian sk_rhs.op( 58520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs_rects[i].left + dx, 58620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs_rects[i].top + dy, 58720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs_rects[i].right + dx, 58820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs_rects[i].bottom + dy, 58920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::kUnion_Op); 59020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 59120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const char* name = "---"; 59220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::Op sk_op; 59320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian switch (op) { 59420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian case op_or: sk_op = SkRegion::kUnion_Op; name="OR"; break; 595b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy case op_xor: sk_op = SkRegion::kUnion_XOR; name="XOR"; break; 59620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian case op_and: sk_op = SkRegion::kIntersect_Op; name="AND"; break; 59720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian case op_nand: sk_op = SkRegion::kDifference_Op; name="NAND"; break; 59820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 59920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian sk_dst.op(sk_lhs, sk_rhs, sk_op); 60020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 60120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (sk_dst.isEmpty() && dst.isEmpty()) 60220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return; 60320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 60420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bool same = true; 60520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator head = dst.begin(); 60620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const tail = dst.end(); 60720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::Iterator it(sk_dst); 60820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (!it.done()) { 60920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (head != tail) { 61020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if ( 61120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->left != it.rect().fLeft || 61220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->top != it.rect().fTop || 61320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->right != it.rect().fRight || 61420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->bottom != it.rect().fBottom 61520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian ) { 61620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian same = false; 61720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian break; 61820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 61920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } else { 62020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian same = false; 62120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian break; 62220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 62320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head++; 62420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.next(); 62520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 62620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 62720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (head != tail) { 62820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian same = false; 62920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 63020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 63120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if(!same) { 6329d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("---\nregion boolean %s failed", name); 63320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs.dump("lhs"); 63420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs.dump("rhs"); 63520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian dst.dump("dst"); 6369d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("should be"); 63720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::Iterator it(sk_dst); 63820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (!it.done()) { 6399d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD(" [%3d, %3d, %3d, %3d]", 64020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.rect().fLeft, 64120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.rect().fTop, 64220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.rect().fRight, 64320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.rect().fBottom); 64420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.next(); 64520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 64620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 64720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 65020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::boolean_operation(int op, Region& dst, 65120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& lhs, 65220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& rhs, int dx, int dy) 65320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 6540450452e8c6ea48341d57d8bc51d56252e9806b8Mathias Agopian if (!rhs.isValid()) { 655e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Region::boolean_operation(op=%d) invalid Rect={%d,%d,%d,%d}", 6560450452e8c6ea48341d57d8bc51d56252e9806b8Mathias Agopian op, rhs.left, rhs.top, rhs.right, rhs.bottom); 6570857c8f7f1905008b285a5473c906639fdd0288bMathias Agopian return; 6580450452e8c6ea48341d57d8bc51d56252e9806b8Mathias Agopian } 6590450452e8c6ea48341d57d8bc51d56252e9806b8Mathias Agopian 66020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_WITH_CORECG || VALIDATE_REGIONS 66120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, dst, lhs, Region(rhs), dx, dy); 66220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#else 66320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian size_t lhs_count; 66420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect const * const lhs_rects = lhs.getArray(&lhs_count); 66520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 66620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect>::region lhs_region(lhs_rects, lhs_count); 66720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect>::region rhs_region(&rhs, 1, dx, dy); 66820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect> operation(op, lhs_region, rhs_region); 66920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian { // scope for rasterizer (dtor has side effects) 67020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rasterizer r(dst); 67120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian operation(r); 67220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 67420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 67520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 67620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 67720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::boolean_operation(int op, Region& dst, 67820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& lhs, const Region& rhs) 67920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 68020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, dst, lhs, rhs, 0, 0); 68120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 68220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 68320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::boolean_operation(int op, Region& dst, 68420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& lhs, const Rect& rhs) 68520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 68620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, dst, lhs, rhs, 0, 0); 68720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 68820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 68920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::translate(Region& reg, int dx, int dy) 69020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 6914c0a170585d5c8a1f3508ac55f799ebaf86e91dbMathias Agopian if ((dx || dy) && !reg.isEmpty()) { 69220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 69320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(reg, "translate (before)"); 69420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 69520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian size_t count = reg.mStorage.size(); 69620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect* rects = reg.mStorage.editArray(); 69720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (count) { 69820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rects->translate(dx, dy); 69920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rects++; 70020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian count--; 70120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 70220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 70320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(reg, "translate (after)"); 70420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 70520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 70620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 70720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 70820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::translate(Region& dst, const Region& reg, int dx, int dy) 70920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 71020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian dst = reg; 71120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian translate(dst, dx, dy); 71220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 71320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 71420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7168683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopiansize_t Region::getSize() const { 7173ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian return mStorage.size() * sizeof(Rect); 718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7208683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopianstatus_t Region::flatten(void* buffer) const { 721068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian#if VALIDATE_REGIONS 722068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian validate(*this, "Region::flatten"); 723068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian#endif 7248683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian Rect* rects = reinterpret_cast<Rect*>(buffer); 7258683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian memcpy(rects, mStorage.array(), mStorage.size() * sizeof(Rect)); 7268683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian return NO_ERROR; 727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7298683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopianstatus_t Region::unflatten(void const* buffer, size_t size) { 730068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian Region result; 7318683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian if (size >= sizeof(Rect)) { 7328683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian Rect const* rects = reinterpret_cast<Rect const*>(buffer); 7338683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian size_t count = size / sizeof(Rect); 7348683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian if (count > 0) { 735068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian result.mStorage.clear(); 736068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ssize_t err = result.mStorage.insertAt(0, count); 7378683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian if (err < 0) { 7388683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian return status_t(err); 7398683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian } 740068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian memcpy(result.mStorage.editArray(), rects, count*sizeof(Rect)); 7418683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian } 7428683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian } 7433ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian#if VALIDATE_REGIONS 744068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian validate(result, "Region::unflatten"); 7453ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian#endif 746068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian 747068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian if (!result.validate(result, "Region::unflatten", true)) { 748068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ALOGE("Region::unflatten() failed, invalid region"); 749068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian return BAD_VALUE; 750068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian } 751068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian mStorage = result.mStorage; 7528683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian return NO_ERROR; 75320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 75420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 75520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 75620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 75720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion::const_iterator Region::begin() const { 7583ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian return mStorage.array(); 75920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 76020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 76120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion::const_iterator Region::end() const { 7623ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian size_t numRects = isRect() ? 1 : mStorage.size() - 1; 7633ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian return mStorage.array() + numRects; 76420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 76520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 76620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRect const* Region::getArray(size_t* count) const { 76720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator const b(begin()); 76820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator const e(end()); 76920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (count) *count = e-b; 77020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return b; 771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7732401ead70099c982796ecc3ec63ec8a5570948fcMathias AgopianSharedBuffer const* Region::getSharedBuffer(size_t* count) const { 7742401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian // We can get to the SharedBuffer of a Vector<Rect> because Rect has 7752401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian // a trivial destructor. 7762401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian SharedBuffer const* sb = SharedBuffer::bufferFromData(mStorage.array()); 7772401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian if (count) { 7782401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian size_t numRects = isRect() ? 1 : mStorage.size() - 1; 7792401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian count[0] = numRects; 7802401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian } 7812401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian sb->acquire(); 7822401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian return sb; 7832401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian} 7842401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian 78520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 78620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Region::dump(String8& out, const char* what, uint32_t flags) const 788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project (void)flags; 79020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator head = begin(); 79120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator const tail = end(); 79220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t SIZE = 256; 794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char buffer[SIZE]; 79520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 79620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian snprintf(buffer, SIZE, " Region %s (this=%p, count=%d)\n", 79720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian what, this, tail-head); 798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.append(buffer); 79920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (head != tail) { 800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project snprintf(buffer, SIZE, " [%3d, %3d, %3d, %3d]\n", 80120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->left, head->top, head->right, head->bottom); 802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.append(buffer); 80320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head++; 804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Region::dump(const char* what, uint32_t flags) const 808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project (void)flags; 81020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator head = begin(); 81120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator const tail = end(); 8129d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD(" Region %s (this=%p, count=%d)\n", what, this, tail-head); 81320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (head != tail) { 8149d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD(" [%3d, %3d, %3d, %3d]\n", 81520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->left, head->top, head->right, head->bottom); 81620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head++; 817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 823