SkRegion.h revision 87b8e645865f9633f410c02252a0fd3feb18f09b
10910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* 20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project 30910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * 40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 50910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * you may not use this file except in compliance with the License. 60910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * You may obtain a copy of the License at 70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * 80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * 100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * See the License for the specific language governing permissions and 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * limitations under the License. 150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */ 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifndef SkRegion_DEFINED 180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkRegion_DEFINED 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkRect.h" 210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkPath; 230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkRgnBuilder; 240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectnamespace android { 260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project class Region; 270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkRegion_gEmptyRunHeadPtr ((SkRegion::RunHead*)-1) 300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkRegion_gRectRunHeadPtr 0 310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** \class SkRegion 330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project The SkRegion class encapsulates the geometric region used to specify 350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project clipping areas for drawing. 360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 37137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenbergerclass SK_API SkRegion { 380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project typedef int32_t RunType; 400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project enum { 410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kRunTypeSentinel = 0x7FFFFFFF 420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion(); 450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion(const SkRegion&); 460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project explicit SkRegion(const SkIRect&); 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ~SkRegion(); 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion& operator=(const SkRegion&); 5087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 5187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 5287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the two regions are equal. i.e. The enclose exactly 5387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * the same area. 5487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 5587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger friend bool operator==(const SkRegion& a, const SkRegion& b); 5687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 5787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 5887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the two regions are not equal. 5987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 6087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger friend bool operator!=(const SkRegion& a, const SkRegion& b) { 610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return !(a == b); 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 6587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Replace this region with the specified region, and return true if the 6687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * resulting region is non-empty. 6787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool set(const SkRegion& src) { 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(&src); 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *this = src; 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return !this->isEmpty(); 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 7587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Swap the contents of this and the specified region. This operation 7687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * is gauarenteed to never fail. 7787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 7887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger void swap(SkRegion&); 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project /** Return true if this region is empty */ 8187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool isEmpty() const { return fRunHead == SkRegion_gEmptyRunHeadPtr; } 8287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project /** Return true if this region is a single, non-empty rectangle */ 8487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool isRect() const { return fRunHead == SkRegion_gRectRunHeadPtr; } 8587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project /** Return true if this region consists of more than 1 rectangular area */ 8787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool isComplex() const { return !this->isEmpty() && !this->isRect(); } 8887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 8987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 9087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return the bounds of this region. If the region is empty, returns an 9187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * empty rectangle. 9287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkIRect& getBounds() const { return fBounds; } 940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 9687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Returns true if the region is non-empty, and if so, sets the specified 9787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * path to the boundary(s) of the region. If the region is empty, then 9887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * this returns false, and path is left unmodified. 9987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool getBoundaryPath(SkPath* path) const; 1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 10387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Set the region to be empty, and return false, since the resulting 10487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * region is empty 10587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 10687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool setEmpty(); 1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 10987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * If rect is non-empty, set this region to that rectangle and return true, 11087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * otherwise set this region to empty and return false. 11187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 11287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool setRect(const SkIRect&); 1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 11587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * If left < right and top < bottom, set this region to that rectangle and 11687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * return true, otherwise set this region to empty and return false. 11787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 11887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool setRect(int32_t left, int32_t top, int32_t right, int32_t bottom); 1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 12187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Set this region to the union of an array of rects. This is generally 12287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * faster than calling region.op(rect, kUnion_Op) in a loop. If count is 12387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * 0, then this region is set to the empty region. 12487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * @return true if the resulting region is non-empty 12540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */ 12640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger bool setRects(const SkIRect rects[], int count); 12740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 12887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 12987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Set this region to the specified region, and return true if it is 13087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * non-empty. 13187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 13287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool setRegion(const SkRegion&); 13387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 13487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 13587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Set this region to the area described by the path, clipped. 13687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the resulting region is non-empty. 13787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * This produces a region that is identical to the pixels that would be 13887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * drawn by the path (with no antialiasing) with the specified clip. 13987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 14087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool setPath(const SkPath&, const SkRegion& clip); 1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 14287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 14387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Returns true if the specified rectangle has a non-empty intersection 14487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * with this region. 14587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 14687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool intersects(const SkIRect&) const; 1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 14887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 14987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Returns true if the specified region has a non-empty intersection 15087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * with this region. 15187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 15287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool intersects(const SkRegion&) const; 15387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 15487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 15587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the specified x,y coordinate is inside the region. 15687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 15787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool contains(int32_t x, int32_t y) const; 15887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 15987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 16087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the specified rectangle is completely inside the region. 16187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * This works for simple (rectangular) and complex regions, and always 16287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * returns the correct result. Note: if either this region or the rectangle 16387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * is empty, contains() returns false. 16487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 16587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool contains(const SkIRect&) const; 16687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 16787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 16887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the specified region is completely inside the region. 16987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * This works for simple (rectangular) and complex regions, and always 17087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * returns the correct result. Note: if either region is empty, contains() 17187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * returns false. 17287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 17387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool contains(const SkRegion&) const; 17487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 17587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 17687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if this region is a single rectangle (not complex) and the 17787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * specified rectangle is contained by this region. Returning false is not 17887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * a guarantee that the rectangle is not contained by this region, but 17987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * return true is a guarantee that the rectangle is contained by this region. 18087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool quickContains(const SkIRect& r) const { 1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->quickContains(r.fLeft, r.fTop, r.fRight, r.fBottom); 1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 18587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 18687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if this region is a single rectangle (not complex) and the 18787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * specified rectangle is contained by this region. Returning false is not 18887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * a guarantee that the rectangle is not contained by this region, but 18987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * return true is a guarantee that the rectangle is contained by this 19087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * region. 19187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool quickContains(int32_t left, int32_t top, int32_t right, 1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int32_t bottom) const { 1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(this->isEmpty() == fBounds.isEmpty()); // valid region 1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return left < right && top < bottom && 1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRunHead == SkRegion_gRectRunHeadPtr && // this->isRect() 1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project /* fBounds.contains(left, top, right, bottom); */ 1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBounds.fLeft <= left && fBounds.fTop <= top && 2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBounds.fRight >= right && fBounds.fBottom >= bottom; 2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 20487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if this region is empty, or if the specified rectangle does 20587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * not intersect the region. Returning false is not a guarantee that they 20687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * intersect, but returning true is a guarantee that they do not. 20787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 20887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool quickReject(const SkIRect& rect) const { 2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->isEmpty() || rect.isEmpty() || 2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project !SkIRect::Intersects(fBounds, rect); 2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 21387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 21487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if this region, or rgn, is empty, or if their bounds do not 21587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * intersect. Returning false is not a guarantee that they intersect, but 21687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * returning true is a guarantee that they do not. 21787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool quickReject(const SkRegion& rgn) const { 2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->isEmpty() || rgn.isEmpty() || 2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project !SkIRect::Intersects(fBounds, rgn.fBounds); 2210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 22387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** Translate the region by the specified (dx, dy) amount. */ 2240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void translate(int dx, int dy) { this->translate(dx, dy, this); } 2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 22687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 22787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Translate the region by the specified (dx, dy) amount, writing the 22887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * resulting region into dst. Note: it is legal to pass this region as the 22987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * dst parameter, effectively translating the region in place. If dst is 23087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * null, nothing happens. 23187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 2320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void translate(int dx, int dy, SkRegion* dst) const; 2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 23487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 23587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * The logical operations that can be performed when combining two regions. 23687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project enum Op { 2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kDifference_Op, //!< subtract the op region from the first region 2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kIntersect_Op, //!< intersect the two regions 2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kUnion_Op, //!< union (inclusive-or) the two regions 2410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kXOR_Op, //!< exclusive-or the two regions 2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project /** subtract the first region from the op region */ 2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kReverseDifference_Op, 2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kReplace_Op //!< replace the dst region with the op region 2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 24787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 24887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Set this region to the result of applying the Op to this region and the 24987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * specified rectangle: this = (this op rect). 25087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the resulting region is non-empty. 25187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool op(const SkIRect& rect, Op op) { return this->op(*this, rect, op); } 2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 25487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 25587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Set this region to the result of applying the Op to this region and the 25687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * specified rectangle: this = (this op rect). 25787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the resulting region is non-empty. 25887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 2590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool op(int left, int top, int right, int bottom, Op op) { 2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIRect rect; 2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rect.set(left, top, right, bottom); 2620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->op(*this, rect, op); 2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 26587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 26687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Set this region to the result of applying the Op to this region and the 26787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * specified region: this = (this op rgn). 26887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the resulting region is non-empty. 26987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool op(const SkRegion& rgn, Op op) { return this->op(*this, rgn, op); } 27187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 27287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 27387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Set this region to the result of applying the Op to the specified 27487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * rectangle and region: this = (rect op rgn). 27587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the resulting region is non-empty. 27687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool op(const SkIRect& rect, const SkRegion& rgn, Op); 27887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 27987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 28087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Set this region to the result of applying the Op to the specified 28187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * region and rectangle: this = (rgn op rect). 28287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the resulting region is non-empty. 28387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 2840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool op(const SkRegion& rgn, const SkIRect& rect, Op); 28587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 28687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 28787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Set this region to the result of applying the Op to the specified 28887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * regions: this = (rgna op rgnb). 28987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the resulting region is non-empty. 29087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op); 2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 29305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#ifdef ANDROID 2949221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato /** Returns a new char* containing the list of rectangles in this region 2959221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato */ 2969221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato char* toString(); 29705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#endif 2989221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato 29987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 30087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Returns the sequence of rectangles, sorted in Y and X, that make up 30187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * this region. 30287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 303137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger class SK_API Iterator { 3040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project public: 3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Iterator() : fRgn(NULL), fDone(true) {} 3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Iterator(const SkRegion&); 3070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // if we have a region, reset to it and return true, else return false 3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool rewind(); 3090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // reset the iterator, using the new region 3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void reset(const SkRegion&); 31105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger bool done() const { return fDone; } 3120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void next(); 3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkIRect& rect() const { return fRect; } 31440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // may return null 31540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const SkRegion* rgn() const { return fRgn; } 31687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project private: 3180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkRegion* fRgn; 3190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const RunType* fRuns; 3200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIRect fRect; 3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool fDone; 3220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 3230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 32487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 32587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Returns the sequence of rectangles, sorted in Y and X, that make up 32687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * this region intersected with the specified clip rectangle. 32787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 328137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger class SK_API Cliperator { 3290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project public: 3300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Cliperator(const SkRegion&, const SkIRect& clip); 33187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool done() { return fDone; } 33287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger void next(); 3330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkIRect& rect() const { return fRect; } 3340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project private: 3360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Iterator fIter; 3370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIRect fClip; 3380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIRect fRect; 3390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool fDone; 3400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 3410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 34287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 34387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Returns the sequence of runs that make up this region for the specified 34487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Y scanline, clipped to the specified left and right X values. 34587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project class Spanerator { 3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project public: 3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Spanerator(const SkRegion&, int y, int left, int right); 34987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool next(int* left, int* right); 3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project private: 3520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkRegion::RunType* fRuns; 3530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int fLeft, fRight; 3540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool fDone; 3550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 3560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 35787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 35887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Write the region to the buffer, and return the number of bytes written. 35987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * If buffer is NULL, it still returns the number of bytes. 36087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 3610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint32_t flatten(void* buffer) const; 36287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 36387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 36487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Initialized the region from the buffer, returning the number 36587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * of bytes actually read. 36687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 3670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint32_t unflatten(const void* buffer); 36887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 36987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 37087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Returns a reference to a global empty region. Just a convenience for 37187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * callers that need a const empty region. 37287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 37387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger static const SkRegion& GetEmptyRegion(); 37487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 3750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(void dump() const;) 3760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(void validate() const;) 3770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(static void UnitTest();) 3780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // expose this to allow for regression test on complex regions 3800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(bool debugSetRuns(const RunType runs[], int count);) 3810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 3830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project enum { 3840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kOpCount = kReplace_Op + 1 3850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 3860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project enum { 3880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kRectRegionRuns = 6 // need to store a region of a rect [T B L R S S] 3890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 3900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project friend class android::Region; // needed for marshalling efficiently 3920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void allocateRuns(int count); // allocate space for count runs 3930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project struct RunHead; 3950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIRect fBounds; 3970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project RunHead* fRunHead; 3980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void freeRuns(); 4000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const RunType* getRuns(RunType tmpStorage[], int* count) const; 4010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool setRuns(RunType runs[], int count); 4020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int count_runtype_values(int* itop, int* ibot) const; 4040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static void BuildRectRuns(const SkIRect& bounds, 4060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project RunType runs[kRectRegionRuns]); 4070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // returns true if runs are just a rect 4080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static bool ComputeRunBounds(const RunType runs[], int count, 4090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIRect* bounds); 4100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project friend struct RunHead; 4120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project friend class Iterator; 4130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project friend class Spanerator; 4140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project friend class SkRgnBuilder; 4150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project friend class SkFlatRegion; 4160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 4170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 419