Region.cpp revision 60d6922a011fe18c111b8d30fb6ef1f655b6b15e
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 1992dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn#include <inttypes.h> 2072b0ffe4c3776b33844bb00b9be5693bddd391f9Mathias Agopian#include <limits.h> 2172b0ffe4c3776b33844bb00b9be5693bddd391f9Mathias Agopian 2220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#include <utils/Log.h> 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 24068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian#include <utils/CallStack.h> 2520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 2620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#include <ui/Rect.h> 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Region.h> 2820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#include <ui/Point.h> 2920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 3020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#include <private/ui/RegionHelper.h> 3120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 3220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 3320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#define VALIDATE_REGIONS (false) 3420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#define VALIDATE_WITH_CORECG (false) 3520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 3620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 3720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_WITH_CORECG 3820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#include <core/SkRegion.h> 3920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 4220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 4320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 4420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianenum { 4520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian op_nand = region_operator<Rect>::op_nand, 4620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian op_and = region_operator<Rect>::op_and, 4720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian op_or = region_operator<Rect>::op_or, 4820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian op_xor = region_operator<Rect>::op_xor 4920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian}; 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 513e010f3138593cc6953039ee0e3db8ee31881296Chris Craikenum { 523e010f3138593cc6953039ee0e3db8ee31881296Chris Craik direction_LTR, 533e010f3138593cc6953039ee0e3db8ee31881296Chris Craik direction_RTL 543e010f3138593cc6953039ee0e3db8ee31881296Chris Craik}; 553e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 565065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stozaconst Region Region::INVALID_REGION(Rect::INVALID_RECT); 575065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 603ab68558fa5a4b8f792a54965a010f03385bd271Mathias AgopianRegion::Region() { 613ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian mStorage.add(Rect(0,0)); 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion::Region(const Region& rhs) 653ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian : mStorage(rhs.mStorage) 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 67d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian#if VALIDATE_REGIONS 68d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(rhs, "rhs copy-ctor"); 69d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian#endif 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 723ab68558fa5a4b8f792a54965a010f03385bd271Mathias AgopianRegion::Region(const Rect& rhs) { 733ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian mStorage.add(rhs); 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion::~Region() 77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 803e010f3138593cc6953039ee0e3db8ee31881296Chris Craik/** 813e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * Copy rects from the src vector into the dst vector, resolving vertical T-Junctions along the way 823e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * 833e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * First pass through, divideSpanRTL will be set because the 'previous span' (indexing into the dst 843e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * vector) will be reversed. Each rectangle in the original list, starting from the bottom, will be 853e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * compared with the span directly below, and subdivided as needed to resolve T-junctions. 863e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * 873e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * The resulting temporary vector will be a completely reversed copy of the original, without any 883e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * bottom-up T-junctions. 893e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * 903e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * Second pass through, divideSpanRTL will be false since the previous span will index into the 913e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * final, correctly ordered region buffer. Each rectangle will be compared with the span directly 923e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * above it, and subdivided to resolve any remaining T-junctions. 933e010f3138593cc6953039ee0e3db8ee31881296Chris Craik */ 943e010f3138593cc6953039ee0e3db8ee31881296Chris Craikstatic void reverseRectsResolvingJunctions(const Rect* begin, const Rect* end, 953e010f3138593cc6953039ee0e3db8ee31881296Chris Craik Vector<Rect>& dst, int spanDirection) { 963e010f3138593cc6953039ee0e3db8ee31881296Chris Craik dst.clear(); 973e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 983e010f3138593cc6953039ee0e3db8ee31881296Chris Craik const Rect* current = end - 1; 993e010f3138593cc6953039ee0e3db8ee31881296Chris Craik int lastTop = current->top; 1003e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1013e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // add first span immediately 1023e010f3138593cc6953039ee0e3db8ee31881296Chris Craik do { 1033e010f3138593cc6953039ee0e3db8ee31881296Chris Craik dst.add(*current); 1043e010f3138593cc6953039ee0e3db8ee31881296Chris Craik current--; 1053e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } while (current->top == lastTop && current >= begin); 1063e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 107d31824004277f554000417cea349d69f18655e95Dan Stoza int beginLastSpan = -1; 108d31824004277f554000417cea349d69f18655e95Dan Stoza int endLastSpan = -1; 1093e010f3138593cc6953039ee0e3db8ee31881296Chris Craik int top = -1; 1103e010f3138593cc6953039ee0e3db8ee31881296Chris Craik int bottom = -1; 1113e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1123e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // for all other spans, split if a t-junction exists in the span directly above 1133e010f3138593cc6953039ee0e3db8ee31881296Chris Craik while (current >= begin) { 1143e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if (current->top != (current + 1)->top) { 1153e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // new span 1163e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if ((spanDirection == direction_RTL && current->bottom != (current + 1)->top) || 1173e010f3138593cc6953039ee0e3db8ee31881296Chris Craik (spanDirection == direction_LTR && current->top != (current + 1)->bottom)) { 1183e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // previous span not directly adjacent, don't check for T junctions 1193e010f3138593cc6953039ee0e3db8ee31881296Chris Craik beginLastSpan = INT_MAX; 1203e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } else { 1213e010f3138593cc6953039ee0e3db8ee31881296Chris Craik beginLastSpan = endLastSpan + 1; 1223e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 123d31824004277f554000417cea349d69f18655e95Dan Stoza endLastSpan = static_cast<int>(dst.size()) - 1; 1243e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1253e010f3138593cc6953039ee0e3db8ee31881296Chris Craik top = current->top; 1263e010f3138593cc6953039ee0e3db8ee31881296Chris Craik bottom = current->bottom; 1273e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1283e010f3138593cc6953039ee0e3db8ee31881296Chris Craik int left = current->left; 1293e010f3138593cc6953039ee0e3db8ee31881296Chris Craik int right = current->right; 1303e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 131d31824004277f554000417cea349d69f18655e95Dan Stoza for (int prevIndex = beginLastSpan; prevIndex <= endLastSpan; prevIndex++) { 132d31824004277f554000417cea349d69f18655e95Dan Stoza // prevIndex can't be -1 here because if endLastSpan is set to a 133d31824004277f554000417cea349d69f18655e95Dan Stoza // value greater than -1 (allowing the loop to execute), 134d31824004277f554000417cea349d69f18655e95Dan Stoza // beginLastSpan (and therefore prevIndex) will also be increased 135aef0445c6f1fbd818b594383217a13571bbd95adywen const Rect prev = dst[static_cast<size_t>(prevIndex)]; 1363e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if (spanDirection == direction_RTL) { 1373e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // iterating over previous span RTL, quit if it's too far left 138aef0445c6f1fbd818b594383217a13571bbd95adywen if (prev.right <= left) break; 1393e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 140aef0445c6f1fbd818b594383217a13571bbd95adywen if (prev.right > left && prev.right < right) { 141aef0445c6f1fbd818b594383217a13571bbd95adywen dst.add(Rect(prev.right, top, right, bottom)); 142aef0445c6f1fbd818b594383217a13571bbd95adywen right = prev.right; 1433e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1443e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 145aef0445c6f1fbd818b594383217a13571bbd95adywen if (prev.left > left && prev.left < right) { 146aef0445c6f1fbd818b594383217a13571bbd95adywen dst.add(Rect(prev.left, top, right, bottom)); 147aef0445c6f1fbd818b594383217a13571bbd95adywen right = prev.left; 1483e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1493e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1503e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // if an entry in the previous span is too far right, nothing further left in the 1513e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // current span will need it 152aef0445c6f1fbd818b594383217a13571bbd95adywen if (prev.left >= right) { 1533e010f3138593cc6953039ee0e3db8ee31881296Chris Craik beginLastSpan = prevIndex; 1543e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1553e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } else { 1563e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // iterating over previous span LTR, quit if it's too far right 157aef0445c6f1fbd818b594383217a13571bbd95adywen if (prev.left >= right) break; 1583e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 159aef0445c6f1fbd818b594383217a13571bbd95adywen if (prev.left > left && prev.left < right) { 160aef0445c6f1fbd818b594383217a13571bbd95adywen dst.add(Rect(left, top, prev.left, bottom)); 161aef0445c6f1fbd818b594383217a13571bbd95adywen left = prev.left; 1623e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1633e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 164aef0445c6f1fbd818b594383217a13571bbd95adywen if (prev.right > left && prev.right < right) { 165aef0445c6f1fbd818b594383217a13571bbd95adywen dst.add(Rect(left, top, prev.right, bottom)); 166aef0445c6f1fbd818b594383217a13571bbd95adywen left = prev.right; 1673e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1683e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // if an entry in the previous span is too far left, nothing further right in the 1693e010f3138593cc6953039ee0e3db8ee31881296Chris Craik // current span will need it 170aef0445c6f1fbd818b594383217a13571bbd95adywen if (prev.right <= left) { 1713e010f3138593cc6953039ee0e3db8ee31881296Chris Craik beginLastSpan = prevIndex; 1723e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1733e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1743e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1753e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1763e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if (left < right) { 1773e010f3138593cc6953039ee0e3db8ee31881296Chris Craik dst.add(Rect(left, top, right, bottom)); 1783e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1793e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1803e010f3138593cc6953039ee0e3db8ee31881296Chris Craik current--; 1813e010f3138593cc6953039ee0e3db8ee31881296Chris Craik } 1823e010f3138593cc6953039ee0e3db8ee31881296Chris Craik} 1833e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1843e010f3138593cc6953039ee0e3db8ee31881296Chris Craik/** 1853e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * Creates a new region with the same data as the argument, but divides rectangles as necessary to 1863e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * remove T-Junctions 1873e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * 1883e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * Note: the output will not necessarily be a very efficient representation of the region, since it 1893e010f3138593cc6953039ee0e3db8ee31881296Chris Craik * may be that a triangle-based approach would generate significantly simpler geometry 1903e010f3138593cc6953039ee0e3db8ee31881296Chris Craik */ 1913e010f3138593cc6953039ee0e3db8ee31881296Chris CraikRegion Region::createTJunctionFreeRegion(const Region& r) { 1923e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if (r.isEmpty()) return r; 1933e010f3138593cc6953039ee0e3db8ee31881296Chris Craik if (r.isRect()) return r; 1943e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1953e010f3138593cc6953039ee0e3db8ee31881296Chris Craik Vector<Rect> reversed; 1963e010f3138593cc6953039ee0e3db8ee31881296Chris Craik reverseRectsResolvingJunctions(r.begin(), r.end(), reversed, direction_RTL); 1973e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 1983e010f3138593cc6953039ee0e3db8ee31881296Chris Craik Region outputRegion; 1993e010f3138593cc6953039ee0e3db8ee31881296Chris Craik reverseRectsResolvingJunctions(reversed.begin(), reversed.end(), 2003e010f3138593cc6953039ee0e3db8ee31881296Chris Craik outputRegion.mStorage, direction_LTR); 2013e010f3138593cc6953039ee0e3db8ee31881296Chris Craik outputRegion.mStorage.add(r.getBounds()); // to make region valid, mStorage must end with bounds 2023e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 2033e010f3138593cc6953039ee0e3db8ee31881296Chris Craik#if VALIDATE_REGIONS 2043e010f3138593cc6953039ee0e3db8ee31881296Chris Craik validate(outputRegion, "T-Junction free region"); 2053e010f3138593cc6953039ee0e3db8ee31881296Chris Craik#endif 2063e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 2073e010f3138593cc6953039ee0e3db8ee31881296Chris Craik return outputRegion; 2083e010f3138593cc6953039ee0e3db8ee31881296Chris Craik} 2093e010f3138593cc6953039ee0e3db8ee31881296Chris Craik 21020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::operator = (const Region& rhs) 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 21220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 213d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(*this, "this->operator="); 214d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(rhs, "rhs.operator="); 21520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 21620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage = rhs.mStorage; 21720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return *this; 218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2209f96145725ff3f265712d607d19078fb91a5c8ecMathias AgopianRegion& Region::makeBoundsSelf() 2219f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian{ 2223ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian if (mStorage.size() >= 2) { 2233ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian const Rect bounds(getBounds()); 2243ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian mStorage.clear(); 2253ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian mStorage.add(bounds); 2263ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian } 2279f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian return *this; 2289f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian} 2299f96145725ff3f265712d607d19078fb91a5c8ecMathias Agopian 2301c284a9431f98bbefd27a30c3368bbf7366dff3aMichael Wrightbool Region::contains(const Point& point) const { 2311c284a9431f98bbefd27a30c3368bbf7366dff3aMichael Wright return contains(point.x, point.y); 2321c284a9431f98bbefd27a30c3368bbf7366dff3aMichael Wright} 2331c284a9431f98bbefd27a30c3368bbf7366dff3aMichael Wright 2341c284a9431f98bbefd27a30c3368bbf7366dff3aMichael Wrightbool Region::contains(int x, int y) const { 2351c284a9431f98bbefd27a30c3368bbf7366dff3aMichael Wright const_iterator cur = begin(); 2361c284a9431f98bbefd27a30c3368bbf7366dff3aMichael Wright const_iterator const tail = end(); 2371c284a9431f98bbefd27a30c3368bbf7366dff3aMichael Wright while (cur != tail) { 2381c284a9431f98bbefd27a30c3368bbf7366dff3aMichael Wright if (y >= cur->top && y < cur->bottom && x >= cur->left && x < cur->right) { 2391c284a9431f98bbefd27a30c3368bbf7366dff3aMichael Wright return true; 2401c284a9431f98bbefd27a30c3368bbf7366dff3aMichael Wright } 2411c284a9431f98bbefd27a30c3368bbf7366dff3aMichael Wright cur++; 2421c284a9431f98bbefd27a30c3368bbf7366dff3aMichael Wright } 2431c284a9431f98bbefd27a30c3368bbf7366dff3aMichael Wright return false; 2441c284a9431f98bbefd27a30c3368bbf7366dff3aMichael Wright} 2451c284a9431f98bbefd27a30c3368bbf7366dff3aMichael Wright 246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Region::clear() 247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 24820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage.clear(); 2493ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian mStorage.add(Rect(0,0)); 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Region::set(const Rect& r) 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 25420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage.clear(); 2553ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian mStorage.add(r); 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 258d31824004277f554000417cea349d69f18655e95Dan Stozavoid Region::set(int32_t w, int32_t h) 2590926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian{ 26020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian mStorage.clear(); 261d31824004277f554000417cea349d69f18655e95Dan Stoza mStorage.add(Rect(w, h)); 2620926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian} 2630926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 264fe4966d59b31ae6fd6dd4d81dd73d2f4f7be33feBernhard Rosenkraenzervoid Region::set(uint32_t w, uint32_t h) 265fe4966d59b31ae6fd6dd4d81dd73d2f4f7be33feBernhard Rosenkraenzer{ 266fe4966d59b31ae6fd6dd4d81dd73d2f4f7be33feBernhard Rosenkraenzer mStorage.clear(); 267fe4966d59b31ae6fd6dd4d81dd73d2f4f7be33feBernhard Rosenkraenzer mStorage.add(Rect(w, h)); 268fe4966d59b31ae6fd6dd4d81dd73d2f4f7be33feBernhard Rosenkraenzer} 269fe4966d59b31ae6fd6dd4d81dd73d2f4f7be33feBernhard Rosenkraenzer 2702ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopianbool Region::isTriviallyEqual(const Region& region) const { 2712ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian return begin() == region.begin(); 2722ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian} 2732ca79399b933935eb1b6c0ec1f746f8c4475369cMathias Agopian 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 27620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::addRectUnchecked(int l, int t, int r, int b) 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 2783ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian Rect rect(l,t,r,b); 2793ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian size_t where = mStorage.size() - 1; 2803ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian mStorage.insertAt(rect, where, 1); 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 28320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 28420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 28520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::orSelf(const Rect& r) { 28620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(r, op_or); 28720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 288b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain GuyRegion& Region::xorSelf(const Rect& r) { 289b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy return operationSelf(r, op_xor); 290b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 29120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::andSelf(const Rect& r) { 29220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(r, op_and); 29320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 29420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::subtractSelf(const Rect& r) { 29520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(r, op_nand); 29620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 29720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::operationSelf(const Rect& r, int op) { 29820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region lhs(*this); 29920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, *this, lhs, r); 300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *this; 301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::orSelf(const Region& rhs) { 30620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, op_or); 307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 308b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain GuyRegion& Region::xorSelf(const Region& rhs) { 309b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy return operationSelf(rhs, op_xor); 310b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::andSelf(const Region& rhs) { 31220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, op_and); 313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::subtractSelf(const Region& rhs) { 31520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, op_nand); 31620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 31720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::operationSelf(const Region& rhs, int op) { 31820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region lhs(*this); 31920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, *this, lhs, rhs); 320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *this; 321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::translateSelf(int x, int y) { 32420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (x|y) translate(*this, x, y); 325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *this; 326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 32820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 32920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 330bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::merge(const Rect& rhs) const { 33120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_or); 33220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 333b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guyconst Region Region::mergeExclusive(const Rect& rhs) const { 334b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy return operation(rhs, op_xor); 335b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 336bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::intersect(const Rect& rhs) const { 33720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_and); 33820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 339bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::subtract(const Rect& rhs) const { 34020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_nand); 34120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 342bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::operation(const Rect& rhs, int op) const { 343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region result; 34420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, result, *this, rhs); 345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return result; 346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 34820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 34920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 350bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::merge(const Region& rhs) const { 35120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_or); 35220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 353b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guyconst Region Region::mergeExclusive(const Region& rhs) const { 354b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy return operation(rhs, op_xor); 355b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 356bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::intersect(const Region& rhs) const { 35720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_and); 358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 359bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::subtract(const Region& rhs) const { 36020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, op_nand); 36120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 362bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::operation(const Region& rhs, int op) const { 363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region result; 36420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, result, *this, rhs); 365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return result; 366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 368bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::translate(int x, int y) const { 369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region result; 37020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian translate(result, *this, x, y); 371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return result; 372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::orSelf(const Region& rhs, int dx, int dy) { 37720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, dx, dy, op_or); 378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 379b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain GuyRegion& Region::xorSelf(const Region& rhs, int dx, int dy) { 380b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy return operationSelf(rhs, dx, dy, op_xor); 381b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::andSelf(const Region& rhs, int dx, int dy) { 38320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, dx, dy, op_and); 384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion& Region::subtractSelf(const Region& rhs, int dx, int dy) { 38620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operationSelf(rhs, dx, dy, op_nand); 38720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 38820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion& Region::operationSelf(const Region& rhs, int dx, int dy, int op) { 38920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region lhs(*this); 39020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, *this, lhs, rhs, dx, dy); 391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *this; 392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 39420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 39520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 396bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::merge(const Region& rhs, int dx, int dy) const { 39720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, dx, dy, op_or); 398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 399b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guyconst Region Region::mergeExclusive(const Region& rhs, int dx, int dy) const { 400b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy return operation(rhs, dx, dy, op_xor); 401b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy} 402bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::intersect(const Region& rhs, int dx, int dy) const { 40320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, dx, dy, op_and); 404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 405bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::subtract(const Region& rhs, int dx, int dy) const { 40620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return operation(rhs, dx, dy, op_nand); 40720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 408bed9dd128dfbdc7d9dbca005078536dadc0b9359Mathias Agopianconst Region Region::operation(const Region& rhs, int dx, int dy, int op) const { 409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region result; 41020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, result, *this, rhs, dx, dy); 411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return result; 412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 41620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// This is our region rasterizer, which merges rects and spans together 41720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// to obtain an optimal region. 418d31824004277f554000417cea349d69f18655e95Dan Stozaclass Region::rasterizer : public region_operator<Rect>::region_rasterizer 41920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 4203ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian Rect bounds; 42120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Vector<Rect>& storage; 42220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect* head; 42320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect* tail; 42420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Vector<Rect> span; 42520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect* cur; 42620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianpublic: 427d31824004277f554000417cea349d69f18655e95Dan Stoza rasterizer(Region& reg) 4283ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian : bounds(INT_MAX, 0, INT_MIN, 0), storage(reg.mStorage), head(), tail(), cur() { 42920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian storage.clear(); 43020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 43120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 432d31824004277f554000417cea349d69f18655e95Dan Stoza virtual ~rasterizer(); 433d31824004277f554000417cea349d69f18655e95Dan Stoza 434d31824004277f554000417cea349d69f18655e95Dan Stoza virtual void operator()(const Rect& rect); 435d31824004277f554000417cea349d69f18655e95Dan Stoza 436d31824004277f554000417cea349d69f18655e95Dan Stozaprivate: 437d31824004277f554000417cea349d69f18655e95Dan Stoza template<typename T> 438d31824004277f554000417cea349d69f18655e95Dan Stoza static inline T min(T rhs, T lhs) { return rhs < lhs ? rhs : lhs; } 439d31824004277f554000417cea349d69f18655e95Dan Stoza template<typename T> 440d31824004277f554000417cea349d69f18655e95Dan Stoza static inline T max(T rhs, T lhs) { return rhs > lhs ? rhs : lhs; } 441d31824004277f554000417cea349d69f18655e95Dan Stoza 442d31824004277f554000417cea349d69f18655e95Dan Stoza void flushSpan(); 443d31824004277f554000417cea349d69f18655e95Dan Stoza}; 444d31824004277f554000417cea349d69f18655e95Dan Stoza 445d31824004277f554000417cea349d69f18655e95Dan StozaRegion::rasterizer::~rasterizer() 446d31824004277f554000417cea349d69f18655e95Dan Stoza{ 447d31824004277f554000417cea349d69f18655e95Dan Stoza if (span.size()) { 448d31824004277f554000417cea349d69f18655e95Dan Stoza flushSpan(); 449d31824004277f554000417cea349d69f18655e95Dan Stoza } 450d31824004277f554000417cea349d69f18655e95Dan Stoza if (storage.size()) { 451d31824004277f554000417cea349d69f18655e95Dan Stoza bounds.top = storage.itemAt(0).top; 452d31824004277f554000417cea349d69f18655e95Dan Stoza bounds.bottom = storage.top().bottom; 453d31824004277f554000417cea349d69f18655e95Dan Stoza if (storage.size() == 1) { 454d31824004277f554000417cea349d69f18655e95Dan Stoza storage.clear(); 45520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 456d31824004277f554000417cea349d69f18655e95Dan Stoza } else { 457d31824004277f554000417cea349d69f18655e95Dan Stoza bounds.left = 0; 458d31824004277f554000417cea349d69f18655e95Dan Stoza bounds.right = 0; 45920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 460d31824004277f554000417cea349d69f18655e95Dan Stoza storage.add(bounds); 461d31824004277f554000417cea349d69f18655e95Dan Stoza} 462d31824004277f554000417cea349d69f18655e95Dan Stoza 463d31824004277f554000417cea349d69f18655e95Dan Stozavoid Region::rasterizer::operator()(const Rect& rect) 464d31824004277f554000417cea349d69f18655e95Dan Stoza{ 465d31824004277f554000417cea349d69f18655e95Dan Stoza //ALOGD(">>> %3d, %3d, %3d, %3d", 466d31824004277f554000417cea349d69f18655e95Dan Stoza // rect.left, rect.top, rect.right, rect.bottom); 467d31824004277f554000417cea349d69f18655e95Dan Stoza if (span.size()) { 468d31824004277f554000417cea349d69f18655e95Dan Stoza if (cur->top != rect.top) { 469d31824004277f554000417cea349d69f18655e95Dan Stoza flushSpan(); 470d31824004277f554000417cea349d69f18655e95Dan Stoza } else if (cur->right == rect.left) { 471d31824004277f554000417cea349d69f18655e95Dan Stoza cur->right = rect.right; 472d31824004277f554000417cea349d69f18655e95Dan Stoza return; 47320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 47420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 475d31824004277f554000417cea349d69f18655e95Dan Stoza span.add(rect); 476d31824004277f554000417cea349d69f18655e95Dan Stoza cur = span.editArray() + (span.size() - 1); 477d31824004277f554000417cea349d69f18655e95Dan Stoza} 478d31824004277f554000417cea349d69f18655e95Dan Stoza 479d31824004277f554000417cea349d69f18655e95Dan Stozavoid Region::rasterizer::flushSpan() 480d31824004277f554000417cea349d69f18655e95Dan Stoza{ 481d31824004277f554000417cea349d69f18655e95Dan Stoza bool merge = false; 482d31824004277f554000417cea349d69f18655e95Dan Stoza if (tail-head == ssize_t(span.size())) { 483d31824004277f554000417cea349d69f18655e95Dan Stoza Rect const* p = span.editArray(); 484d31824004277f554000417cea349d69f18655e95Dan Stoza Rect const* q = head; 485d31824004277f554000417cea349d69f18655e95Dan Stoza if (p->top == q->bottom) { 486d31824004277f554000417cea349d69f18655e95Dan Stoza merge = true; 487d31824004277f554000417cea349d69f18655e95Dan Stoza while (q != tail) { 488d31824004277f554000417cea349d69f18655e95Dan Stoza if ((p->left != q->left) || (p->right != q->right)) { 489d31824004277f554000417cea349d69f18655e95Dan Stoza merge = false; 490d31824004277f554000417cea349d69f18655e95Dan Stoza break; 49120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 492d31824004277f554000417cea349d69f18655e95Dan Stoza p++, q++; 49320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 49420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 495d31824004277f554000417cea349d69f18655e95Dan Stoza } 496d31824004277f554000417cea349d69f18655e95Dan Stoza if (merge) { 497d31824004277f554000417cea349d69f18655e95Dan Stoza const int bottom = span[0].bottom; 498d31824004277f554000417cea349d69f18655e95Dan Stoza Rect* r = head; 499d31824004277f554000417cea349d69f18655e95Dan Stoza while (r != tail) { 500d31824004277f554000417cea349d69f18655e95Dan Stoza r->bottom = bottom; 501d31824004277f554000417cea349d69f18655e95Dan Stoza r++; 50220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 503d31824004277f554000417cea349d69f18655e95Dan Stoza } else { 504d31824004277f554000417cea349d69f18655e95Dan Stoza bounds.left = min(span.itemAt(0).left, bounds.left); 505d31824004277f554000417cea349d69f18655e95Dan Stoza bounds.right = max(span.top().right, bounds.right); 506d31824004277f554000417cea349d69f18655e95Dan Stoza storage.appendVector(span); 507d31824004277f554000417cea349d69f18655e95Dan Stoza tail = storage.editArray() + storage.size(); 508d31824004277f554000417cea349d69f18655e95Dan Stoza head = tail - span.size(); 50920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 510d31824004277f554000417cea349d69f18655e95Dan Stoza span.clear(); 511d31824004277f554000417cea349d69f18655e95Dan Stoza} 51220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 513068d47f29dfead847999a7b33b4217ee9514152bMathias Agopianbool Region::validate(const Region& reg, const char* name, bool silent) 514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 51520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bool result = true; 51620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator cur = reg.begin(); 51720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator const tail = reg.end(); 518068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian const_iterator prev = cur; 51920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect b(*prev); 52020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (cur != tail) { 521068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian if (cur->isValid() == false) { 5225065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza // We allow this particular flavor of invalid Rect, since it is used 5235065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza // as a signal value in various parts of the system 5245065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza if (*cur != Rect::INVALID_RECT) { 5255065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza ALOGE_IF(!silent, "%s: region contains an invalid Rect", name); 5265065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza result = false; 5275065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza } 528068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian } 529068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian if (cur->right > region_operator<Rect>::max_value) { 530068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ALOGE_IF(!silent, "%s: rect->right > max_value", name); 531068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian result = false; 532068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian } 533068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian if (cur->bottom > region_operator<Rect>::max_value) { 534068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ALOGE_IF(!silent, "%s: rect->right > max_value", name); 535068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian result = false; 536068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian } 537068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian if (prev != cur) { 538068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian b.left = b.left < cur->left ? b.left : cur->left; 539068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian b.top = b.top < cur->top ? b.top : cur->top; 540068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian b.right = b.right > cur->right ? b.right : cur->right; 541068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian b.bottom = b.bottom > cur->bottom ? b.bottom : cur->bottom; 542068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian if ((*prev < *cur) == false) { 543068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ALOGE_IF(!silent, "%s: region's Rects not sorted", name); 54420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian result = false; 545068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian } 546068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian if (cur->top == prev->top) { 547068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian if (cur->bottom != prev->bottom) { 548068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ALOGE_IF(!silent, "%s: invalid span %p", name, cur); 549068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian result = false; 550068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian } else if (cur->left < prev->right) { 551068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ALOGE_IF(!silent, 552068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian "%s: spans overlap horizontally prev=%p, cur=%p", 553068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian name, prev, cur); 554068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian result = false; 555068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian } 556068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian } else if (cur->top < prev->bottom) { 557068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ALOGE_IF(!silent, 558068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian "%s: spans overlap vertically prev=%p, cur=%p", 55920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian name, prev, cur); 56020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian result = false; 56120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 562068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian prev = cur; 56320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 56420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian cur++; 56520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 56620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (b != reg.getBounds()) { 56720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian result = false; 568068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ALOGE_IF(!silent, 569068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian "%s: invalid bounds [%d,%d,%d,%d] vs. [%d,%d,%d,%d]", name, 57020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian b.left, b.top, b.right, b.bottom, 57120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian reg.getBounds().left, reg.getBounds().top, 57220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian reg.getBounds().right, reg.getBounds().bottom); 57320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 5743ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian if (reg.mStorage.size() == 2) { 575068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian result = false; 576068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ALOGE_IF(!silent, "%s: mStorage size is 2, which is never valid", name); 5773ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian } 578068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian if (result == false && !silent) { 57920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian reg.dump(name); 580cab25d680e644d962041d05a319e485b96136a5dMathias Agopian CallStack stack(LOG_TAG); 58120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 58220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return result; 583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 58520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::boolean_operation(int op, Region& dst, 58620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& lhs, 58720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& rhs, int dx, int dy) 588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 589d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian#if VALIDATE_REGIONS 590d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(lhs, "boolean_operation (before): lhs"); 591d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(rhs, "boolean_operation (before): rhs"); 592d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian validate(dst, "boolean_operation (before): dst"); 593d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian#endif 594d0b55c011a311b677493ba72804bf1bc4df68224Mathias Agopian 59520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian size_t lhs_count; 59620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect const * const lhs_rects = lhs.getArray(&lhs_count); 59720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 59820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian size_t rhs_count; 59920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect const * const rhs_rects = rhs.getArray(&rhs_count); 60020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 60120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect>::region lhs_region(lhs_rects, lhs_count); 60220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect>::region rhs_region(rhs_rects, rhs_count, dx, dy); 60320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect> operation(op, lhs_region, rhs_region); 60420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian { // scope for rasterizer (dtor has side effects) 60520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rasterizer r(dst); 60620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian operation(r); 60720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 60820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 60920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 61020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(lhs, "boolean_operation: lhs"); 61120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(rhs, "boolean_operation: rhs"); 61220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(dst, "boolean_operation: dst"); 61320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 61420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 61520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_WITH_CORECG 61620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion sk_lhs; 61720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion sk_rhs; 61820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion sk_dst; 61920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 62020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian for (size_t i=0 ; i<lhs_count ; i++) 62120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian sk_lhs.op( 62220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs_rects[i].left + dx, 62320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs_rects[i].top + dy, 62420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs_rects[i].right + dx, 62520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs_rects[i].bottom + dy, 62620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::kUnion_Op); 62720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 62820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian for (size_t i=0 ; i<rhs_count ; i++) 62920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian sk_rhs.op( 63020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs_rects[i].left + dx, 63120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs_rects[i].top + dy, 63220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs_rects[i].right + dx, 63320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs_rects[i].bottom + dy, 63420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::kUnion_Op); 63520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 63620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const char* name = "---"; 63720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::Op sk_op; 63820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian switch (op) { 63920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian case op_or: sk_op = SkRegion::kUnion_Op; name="OR"; break; 640b8a2e98cd7edbe7513543670c94f6b5efa74462fRomain Guy case op_xor: sk_op = SkRegion::kUnion_XOR; name="XOR"; break; 64120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian case op_and: sk_op = SkRegion::kIntersect_Op; name="AND"; break; 64220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian case op_nand: sk_op = SkRegion::kDifference_Op; name="NAND"; break; 64320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 64420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian sk_dst.op(sk_lhs, sk_rhs, sk_op); 64520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 64620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (sk_dst.isEmpty() && dst.isEmpty()) 64720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian return; 64820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 64920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian bool same = true; 65020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator head = dst.begin(); 65120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const tail = dst.end(); 65220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::Iterator it(sk_dst); 65320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (!it.done()) { 65420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (head != tail) { 65520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if ( 65620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->left != it.rect().fLeft || 65720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->top != it.rect().fTop || 65820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->right != it.rect().fRight || 65920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->bottom != it.rect().fBottom 66020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian ) { 66120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian same = false; 66220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian break; 66320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 66420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } else { 66520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian same = false; 66620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian break; 66720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 66820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head++; 66920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.next(); 67020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 67120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 67220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (head != tail) { 67320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian same = false; 67420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 67520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 67620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if(!same) { 6779d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("---\nregion boolean %s failed", name); 67820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian lhs.dump("lhs"); 67920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rhs.dump("rhs"); 68020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian dst.dump("dst"); 6819d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("should be"); 68220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian SkRegion::Iterator it(sk_dst); 68320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (!it.done()) { 6849d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD(" [%3d, %3d, %3d, %3d]", 68520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.rect().fLeft, 68620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.rect().fTop, 68720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.rect().fRight, 68820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.rect().fBottom); 68920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian it.next(); 69020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 69120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 69220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 69520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::boolean_operation(int op, Region& dst, 69620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& lhs, 69720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& rhs, int dx, int dy) 69820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 6995065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza // We allow this particular flavor of invalid Rect, since it is used as a 7005065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza // signal value in various parts of the system 7015065a55291b67f584d7b0be3fa3cfc4e29a3cd1cDan Stoza if (!rhs.isValid() && rhs != Rect::INVALID_RECT) { 702e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Region::boolean_operation(op=%d) invalid Rect={%d,%d,%d,%d}", 7030450452e8c6ea48341d57d8bc51d56252e9806b8Mathias Agopian op, rhs.left, rhs.top, rhs.right, rhs.bottom); 7040857c8f7f1905008b285a5473c906639fdd0288bMathias Agopian return; 7050450452e8c6ea48341d57d8bc51d56252e9806b8Mathias Agopian } 7060450452e8c6ea48341d57d8bc51d56252e9806b8Mathias Agopian 70720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_WITH_CORECG || VALIDATE_REGIONS 70820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, dst, lhs, Region(rhs), dx, dy); 70920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#else 71020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian size_t lhs_count; 71120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect const * const lhs_rects = lhs.getArray(&lhs_count); 71220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 71320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect>::region lhs_region(lhs_rects, lhs_count); 71420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect>::region rhs_region(&rhs, 1, dx, dy); 71520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian region_operator<Rect> operation(op, lhs_region, rhs_region); 71620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian { // scope for rasterizer (dtor has side effects) 71720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rasterizer r(dst); 71820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian operation(r); 71920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 72120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 72220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 72320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 72420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::boolean_operation(int op, Region& dst, 72520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& lhs, const Region& rhs) 72620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 72720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, dst, lhs, rhs, 0, 0); 72820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 72920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 73020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::boolean_operation(int op, Region& dst, 73120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Region& lhs, const Rect& rhs) 73220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 73320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian boolean_operation(op, dst, lhs, rhs, 0, 0); 73420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 73520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 73620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::translate(Region& reg, int dx, int dy) 73720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 7384c0a170585d5c8a1f3508ac55f799ebaf86e91dbMathias Agopian if ((dx || dy) && !reg.isEmpty()) { 73920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 74020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(reg, "translate (before)"); 74120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 74220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian size_t count = reg.mStorage.size(); 74320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Rect* rects = reg.mStorage.editArray(); 74420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (count) { 7456c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian rects->offsetBy(dx, dy); 74620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian rects++; 74720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian count--; 74820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 74920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#if VALIDATE_REGIONS 75020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian validate(reg, "translate (after)"); 75120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian#endif 75220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian } 75320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 75420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 75520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopianvoid Region::translate(Region& dst, const Region& reg, int dx, int dy) 75620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian{ 75720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian dst = reg; 75820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian translate(dst, dx, dy); 75920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 76020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 76120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 763e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopiansize_t Region::getFlattenedSize() const { 7646fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza return sizeof(uint32_t) + mStorage.size() * sizeof(Rect); 765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 767e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopianstatus_t Region::flatten(void* buffer, size_t size) const { 768068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian#if VALIDATE_REGIONS 769068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian validate(*this, "Region::flatten"); 770068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian#endif 7716fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza if (size < getFlattenedSize()) { 772e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian return NO_MEMORY; 773e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian } 7746fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza // Cast to uint32_t since the size of a size_t can vary between 32- and 7756fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza // 64-bit processes 7766fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza FlattenableUtils::write(buffer, size, static_cast<uint32_t>(mStorage.size())); 7776fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza for (auto rect : mStorage) { 7786fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza status_t result = rect.flatten(buffer, size); 7796fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza if (result != NO_ERROR) { 7806fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza return result; 7816fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza } 7826fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza FlattenableUtils::advance(buffer, size, sizeof(rect)); 7836fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza } 7848683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian return NO_ERROR; 785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7878683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopianstatus_t Region::unflatten(void const* buffer, size_t size) { 7886fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza if (size < sizeof(uint32_t)) { 7896fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza return NO_MEMORY; 7906fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza } 7916fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza 7926fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza uint32_t numRects = 0; 7936fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza FlattenableUtils::read(buffer, size, numRects); 7946fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza if (size < numRects * sizeof(Rect)) { 7956fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza return NO_MEMORY; 7966fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza } 7976fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza 798068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian Region result; 7996fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza result.mStorage.clear(); 8006fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza for (size_t r = 0; r < numRects; ++r) { 80160d6922a011fe18c111b8d30fb6ef1f655b6b15ePablo Ceballos Rect rect(Rect::EMPTY_RECT); 8026fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza status_t status = rect.unflatten(buffer, size); 8036fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza if (status != NO_ERROR) { 8046fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza return status; 8058683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian } 8066fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza FlattenableUtils::advance(buffer, size, sizeof(rect)); 8076fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza result.mStorage.push_back(rect); 8088683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian } 8096fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza 8103ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian#if VALIDATE_REGIONS 811068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian validate(result, "Region::unflatten"); 8123ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian#endif 813068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian 814068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian if (!result.validate(result, "Region::unflatten", true)) { 815068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian ALOGE("Region::unflatten() failed, invalid region"); 816068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian return BAD_VALUE; 817068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian } 818068d47f29dfead847999a7b33b4217ee9514152bMathias Agopian mStorage = result.mStorage; 8198683fca395d01734ec7946e9f0595ec5d7b754c6Mathias Agopian return NO_ERROR; 82020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 82120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 82220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 82320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 82420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion::const_iterator Region::begin() const { 8253ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian return mStorage.array(); 82620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 82720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 82820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRegion::const_iterator Region::end() const { 8293ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian size_t numRects = isRect() ? 1 : mStorage.size() - 1; 8303ab68558fa5a4b8f792a54965a010f03385bd271Mathias Agopian return mStorage.array() + numRects; 83120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian} 83220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 83320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias AgopianRect const* Region::getArray(size_t* count) const { 834d31824004277f554000417cea349d69f18655e95Dan Stoza if (count) *count = static_cast<size_t>(end() - begin()); 835d31824004277f554000417cea349d69f18655e95Dan Stoza return begin(); 836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8382401ead70099c982796ecc3ec63ec8a5570948fcMathias AgopianSharedBuffer const* Region::getSharedBuffer(size_t* count) const { 8392401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian // We can get to the SharedBuffer of a Vector<Rect> because Rect has 8402401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian // a trivial destructor. 8412401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian SharedBuffer const* sb = SharedBuffer::bufferFromData(mStorage.array()); 8422401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian if (count) { 8432401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian size_t numRects = isRect() ? 1 : mStorage.size() - 1; 8442401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian count[0] = numRects; 8452401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian } 8462401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian sb->acquire(); 8472401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian return sb; 8482401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian} 8492401ead70099c982796ecc3ec63ec8a5570948fcMathias Agopian 85020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian// ---------------------------------------------------------------------------- 85120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 852d31824004277f554000417cea349d69f18655e95Dan Stozavoid Region::dump(String8& out, const char* what, uint32_t /* flags */) const 853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 85420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator head = begin(); 85520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator const tail = end(); 85620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 857d31824004277f554000417cea349d69f18655e95Dan Stoza out.appendFormat(" Region %s (this=%p, count=%" PRIdPTR ")\n", 858d31824004277f554000417cea349d69f18655e95Dan Stoza what, this, tail - head); 85920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (head != tail) { 860d31824004277f554000417cea349d69f18655e95Dan Stoza out.appendFormat(" [%3d, %3d, %3d, %3d]\n", head->left, head->top, 861d31824004277f554000417cea349d69f18655e95Dan Stoza head->right, head->bottom); 862d31824004277f554000417cea349d69f18655e95Dan Stoza ++head; 863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 866d31824004277f554000417cea349d69f18655e95Dan Stozavoid Region::dump(const char* what, uint32_t /* flags */) const 867edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 86820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator head = begin(); 86920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const_iterator const tail = end(); 87092dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn ALOGD(" Region %s (this=%p, count=%" PRIdPTR ")\n", what, this, tail-head); 87120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (head != tail) { 8729d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD(" [%3d, %3d, %3d, %3d]\n", 87320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head->left, head->top, head->right, head->bottom); 87420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian head++; 875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 881