SkRegion.h revision 4f1dae40e24d57d647db01443b8bf2410514b8b5
11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2005 The Android Open Source Project 40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */ 80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifndef SkRegion_DEFINED 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkRegion_DEFINED 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkRect.h" 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkPath; 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkRgnBuilder; 170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectnamespace android { 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project class Region; 200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkRegion_gEmptyRunHeadPtr ((SkRegion::RunHead*)-1) 230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkRegion_gRectRunHeadPtr 0 240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** \class SkRegion 260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project The SkRegion class encapsulates the geometric region used to specify 280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project clipping areas for drawing. 290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 30137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenbergerclass SK_API SkRegion { 310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project typedef int32_t RunType; 330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project enum { 340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kRunTypeSentinel = 0x7FFFFFFF 350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion(); 380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion(const SkRegion&); 390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project explicit SkRegion(const SkIRect&); 400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ~SkRegion(); 410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRegion& operator=(const SkRegion&); 4387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 4487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 4587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the two regions are equal. i.e. The enclose exactly 4687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * the same area. 4787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger bool operator==(const SkRegion& other) const; 4987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 5087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 5187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the two regions are not equal. 5287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger bool operator!=(const SkRegion& other) const { 544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return !(*this == other); 550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 5887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Replace this region with the specified region, and return true if the 5987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * resulting region is non-empty. 6087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool set(const SkRegion& src) { 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(&src); 630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *this = src; 640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return !this->isEmpty(); 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 6887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Swap the contents of this and the specified region. This operation 6987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * is gauarenteed to never fail. 7087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 7187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger void swap(SkRegion&); 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project /** Return true if this region is empty */ 7487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool isEmpty() const { return fRunHead == SkRegion_gEmptyRunHeadPtr; } 7587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project /** Return true if this region is a single, non-empty rectangle */ 7787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool isRect() const { return fRunHead == SkRegion_gRectRunHeadPtr; } 7887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project /** Return true if this region consists of more than 1 rectangular area */ 8087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool isComplex() const { return !this->isEmpty() && !this->isRect(); } 8187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 8287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 8387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return the bounds of this region. If the region is empty, returns an 8487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * empty rectangle. 8587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkIRect& getBounds() const { return fBounds; } 870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Returns true if the region is non-empty, and if so, appends the 901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * boundary(s) of the region to the specified path. 911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * If the region is empty, returns false, and path is left unmodified. 9287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool getBoundaryPath(SkPath* path) const; 940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 9687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Set the region to be empty, and return false, since the resulting 9787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * region is empty 9887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 9987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool setEmpty(); 1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 10287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * If rect is non-empty, set this region to that rectangle and return true, 10387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * otherwise set this region to empty and return false. 10487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 10587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool setRect(const SkIRect&); 1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 10887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * If left < right and top < bottom, set this region to that rectangle and 10987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * return true, otherwise set this region to empty and return false. 11087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 11187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool setRect(int32_t left, int32_t top, int32_t right, int32_t bottom); 1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 11487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Set this region to the union of an array of rects. This is generally 11587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * faster than calling region.op(rect, kUnion_Op) in a loop. If count is 11687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * 0, then this region is set to the empty region. 11787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * @return true if the resulting region is non-empty 11840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */ 11940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger bool setRects(const SkIRect rects[], int count); 12040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 12187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 12287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Set this region to the specified region, and return true if it is 12387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * non-empty. 12487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 12587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool setRegion(const SkRegion&); 12687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 12787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 12887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Set this region to the area described by the path, clipped. 12987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the resulting region is non-empty. 13087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * This produces a region that is identical to the pixels that would be 13187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * drawn by the path (with no antialiasing) with the specified clip. 13287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 13387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool setPath(const SkPath&, const SkRegion& clip); 1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 13687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Returns true if the specified rectangle has a non-empty intersection 13787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * with this region. 13887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 13987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool intersects(const SkIRect&) const; 1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 14187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 14287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Returns true if the specified region has a non-empty intersection 14387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * with this region. 14487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 14587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool intersects(const SkRegion&) const; 14687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 14787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 14887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the specified x,y coordinate is inside the region. 14987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 15087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool contains(int32_t x, int32_t y) const; 15187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 15287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 15387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the specified rectangle is completely inside the region. 15487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * This works for simple (rectangular) and complex regions, and always 15587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * returns the correct result. Note: if either this region or the rectangle 15687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * is empty, contains() returns false. 15787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 15887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool contains(const SkIRect&) const; 15987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 16087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 16187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the specified region is completely inside the region. 16287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * This works for simple (rectangular) and complex regions, and always 16387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * returns the correct result. Note: if either region is empty, contains() 16487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * returns false. 16587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 16687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool contains(const SkRegion&) const; 16787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 16887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 16987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if this region is a single rectangle (not complex) and the 17087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * specified rectangle is contained by this region. Returning false is not 17187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * a guarantee that the rectangle is not contained by this region, but 17287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * return true is a guarantee that the rectangle is contained by this region. 17387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 1740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool quickContains(const SkIRect& r) const { 1750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->quickContains(r.fLeft, r.fTop, r.fRight, r.fBottom); 1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 17887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 17987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if this region is a single rectangle (not complex) and the 18087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * specified rectangle is contained by this region. Returning false is not 18187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * a guarantee that the rectangle is not contained by this region, but 18287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * return true is a guarantee that the rectangle is contained by this 18387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * region. 18487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool quickContains(int32_t left, int32_t top, int32_t right, 1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int32_t bottom) const { 1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(this->isEmpty() == fBounds.isEmpty()); // valid region 1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return left < right && top < bottom && 1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRunHead == SkRegion_gRectRunHeadPtr && // this->isRect() 1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project /* fBounds.contains(left, top, right, bottom); */ 1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBounds.fLeft <= left && fBounds.fTop <= top && 1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fBounds.fRight >= right && fBounds.fBottom >= bottom; 1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 19687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 19787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if this region is empty, or if the specified rectangle does 19887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * not intersect the region. Returning false is not a guarantee that they 19987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * intersect, but returning true is a guarantee that they do not. 20087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 20187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool quickReject(const SkIRect& rect) const { 2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->isEmpty() || rect.isEmpty() || 2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project !SkIRect::Intersects(fBounds, rect); 2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 20787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if this region, or rgn, is empty, or if their bounds do not 20887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * intersect. Returning false is not a guarantee that they intersect, but 20987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * returning true is a guarantee that they do not. 21087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool quickReject(const SkRegion& rgn) const { 2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->isEmpty() || rgn.isEmpty() || 2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project !SkIRect::Intersects(fBounds, rgn.fBounds); 2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 21687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** Translate the region by the specified (dx, dy) amount. */ 2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void translate(int dx, int dy) { this->translate(dx, dy, this); } 2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 21987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 22087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Translate the region by the specified (dx, dy) amount, writing the 22187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * resulting region into dst. Note: it is legal to pass this region as the 22287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * dst parameter, effectively translating the region in place. If dst is 22387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * null, nothing happens. 22487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void translate(int dx, int dy, SkRegion* dst) const; 2260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 22787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 22887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * The logical operations that can be performed when combining two regions. 22987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 2300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project enum Op { 2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kDifference_Op, //!< subtract the op region from the first region 2320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kIntersect_Op, //!< intersect the two regions 2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kUnion_Op, //!< union (inclusive-or) the two regions 2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kXOR_Op, //!< exclusive-or the two regions 2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project /** subtract the first region from the op region */ 2360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kReverseDifference_Op, 2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kReplace_Op //!< replace the dst region with the op region 2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 24087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 24187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Set this region to the result of applying the Op to this region and the 24287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * specified rectangle: this = (this op rect). 24387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the resulting region is non-empty. 24487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool op(const SkIRect& rect, Op op) { return this->op(*this, rect, op); } 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(int left, int top, int right, int bottom, Op op) { 2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIRect rect; 2540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rect.set(left, top, right, bottom); 2550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->op(*this, rect, op); 2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 25887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 25987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Set this region to the result of applying the Op to this region and the 26087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * specified region: this = (this op rgn). 26187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the resulting region is non-empty. 26287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool op(const SkRegion& rgn, Op op) { return this->op(*this, rgn, op); } 26487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 26587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 26687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Set this region to the result of applying the Op to the specified 26787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * rectangle and region: this = (rect op rgn). 26887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the resulting region is non-empty. 26987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool op(const SkIRect& rect, const SkRegion& rgn, Op); 27187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 27287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 27387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Set this region to the result of applying the Op to the specified 27487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * region and rectangle: this = (rgn op rect). 27587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the resulting region is non-empty. 27687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool op(const SkRegion& rgn, const SkIRect& rect, Op); 27887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 27987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 28087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Set this region to the result of applying the Op to the specified 28187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * regions: this = (rgna op rgnb). 28287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Return true if the resulting region is non-empty. 28387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 2840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op); 2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 2879221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato /** Returns a new char* containing the list of rectangles in this region 2889221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato */ 2899221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato char* toString(); 29005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#endif 2919221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato 29287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 29387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Returns the sequence of rectangles, sorted in Y and X, that make up 29487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * this region. 29587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 296137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger class SK_API Iterator { 2970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project public: 2980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Iterator() : fRgn(NULL), fDone(true) {} 2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Iterator(const SkRegion&); 3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // if we have a region, reset to it and return true, else return false 3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool rewind(); 3020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // reset the iterator, using the new region 3030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void reset(const SkRegion&); 30405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger bool done() const { return fDone; } 3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void next(); 3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkIRect& rect() const { return fRect; } 30740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // may return null 30840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const SkRegion* rgn() const { return fRgn; } 30987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project private: 3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkRegion* fRgn; 3120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const RunType* fRuns; 3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIRect fRect; 3140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool fDone; 3150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 3160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 31787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 31887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Returns the sequence of rectangles, sorted in Y and X, that make up 31987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * this region intersected with the specified clip rectangle. 32087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 321137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger class SK_API Cliperator { 3220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project public: 3230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Cliperator(const SkRegion&, const SkIRect& clip); 32487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool done() { return fDone; } 32587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger void next(); 3260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkIRect& rect() const { return fRect; } 3270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project private: 3290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Iterator fIter; 3300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIRect fClip; 3310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIRect fRect; 3320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool fDone; 3330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 3340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 33587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 33687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Returns the sequence of runs that make up this region for the specified 33787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Y scanline, clipped to the specified left and right X values. 33887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 3390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project class Spanerator { 3400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project public: 3410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Spanerator(const SkRegion&, int y, int left, int right); 34287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger bool next(int* left, int* right); 3430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project private: 3450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkRegion::RunType* fRuns; 3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int fLeft, fRight; 3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool fDone; 3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 3490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 35087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 35187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Write the region to the buffer, and return the number of bytes written. 35287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * If buffer is NULL, it still returns the number of bytes. 35387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 3540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint32_t flatten(void* buffer) const; 35587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 35687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 35787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Initialized the region from the buffer, returning the number 35887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * of bytes actually read. 35987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 3600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint32_t unflatten(const void* buffer); 36187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 36287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger /** 36387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * Returns a reference to a global empty region. Just a convenience for 36487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger * callers that need a const empty region. 36587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */ 36687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger static const SkRegion& GetEmptyRegion(); 36787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 3680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(void dump() const;) 3690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(void validate() const;) 3700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(static void UnitTest();) 3710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // expose this to allow for regression test on complex regions 3730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(bool debugSetRuns(const RunType runs[], int count);) 3740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 3760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project enum { 3770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kOpCount = kReplace_Op + 1 3780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 3790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project enum { 3810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project kRectRegionRuns = 6 // need to store a region of a rect [T B L R S S] 3820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 3830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project friend class android::Region; // needed for marshalling efficiently 3850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void allocateRuns(int count); // allocate space for count runs 3860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project struct RunHead; 3880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIRect fBounds; 3900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project RunHead* fRunHead; 3910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void freeRuns(); 3930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const RunType* getRuns(RunType tmpStorage[], int* count) const; 3940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool setRuns(RunType runs[], int count); 3950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int count_runtype_values(int* itop, int* ibot) const; 3970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static void BuildRectRuns(const SkIRect& bounds, 3990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project RunType runs[kRectRegionRuns]); 4000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // returns true if runs are just a rect 4010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static bool ComputeRunBounds(const RunType runs[], int count, 4020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIRect* bounds); 4030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project friend struct RunHead; 4050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project friend class Iterator; 4060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project friend class Spanerator; 4070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project friend class SkRgnBuilder; 4080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project friend class SkFlatRegion; 4090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 4100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 412