1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2005 The Android Open Source Project 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkRegion_DEFINED 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkRegion_DEFINED 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRect.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkPath; 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkRgnBuilder; 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comnamespace android { 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com class Region; 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkRegion_gEmptyRunHeadPtr ((SkRegion::RunHead*)-1) 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkRegion_gRectRunHeadPtr 0 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \class SkRegion 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The SkRegion class encapsulates the geometric region used to specify 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com clipping areas for drawing. 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 307ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgclass SK_API SkRegion { 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef int32_t RunType; 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com enum { 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kRunTypeSentinel = 0x7FFFFFFF 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 36fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion(); 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion(const SkRegion&); 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com explicit SkRegion(const SkIRect&); 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~SkRegion(); 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion& operator=(const SkRegion&); 4397fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com 4497fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 4597fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Return true if the two regions are equal. i.e. The enclose exactly 4697fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * the same area. 4797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 486d428d3e6e4238786a38caca6002dae92637958dreed@google.com bool operator==(const SkRegion& other) const; 4997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com 5097fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 5197fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Return true if the two regions are not equal. 5297fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 536d428d3e6e4238786a38caca6002dae92637958dreed@google.com bool operator!=(const SkRegion& other) const { 546d428d3e6e4238786a38caca6002dae92637958dreed@google.com return !(*this == other); 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 56fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 5797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 5897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Replace this region with the specified region, and return true if the 5997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * resulting region is non-empty. 6097fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool set(const SkRegion& src) { 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(&src); 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *this = src; 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return !this->isEmpty(); 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 6897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Swap the contents of this and the specified region. This operation 6997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * is gauarenteed to never fail. 7097fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 7197fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com void swap(SkRegion&); 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return true if this region is empty */ 7497fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com bool isEmpty() const { return fRunHead == SkRegion_gEmptyRunHeadPtr; } 7597fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return true if this region is a single, non-empty rectangle */ 7797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com bool isRect() const { return fRunHead == SkRegion_gRectRunHeadPtr; } 7897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return true if this region consists of more than 1 rectangular area */ 8097fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com bool isComplex() const { return !this->isEmpty() && !this->isRect(); } 8197fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com 8297fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 8397fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Return the bounds of this region. If the region is empty, returns an 8497fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * empty rectangle. 8597fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkIRect& getBounds() const { return fBounds; } 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 895dd567c2a55c16c8bc2668902cdfce1734dfae8fcommit-bot@chromium.org * Returns a value that grows approximately linearly with the number of 905dd567c2a55c16c8bc2668902cdfce1734dfae8fcommit-bot@chromium.org * intervals comprised in the region. Empty region will return 0, Rect 915dd567c2a55c16c8bc2668902cdfce1734dfae8fcommit-bot@chromium.org * will return 1, Complex will return a value > 1. 925dd567c2a55c16c8bc2668902cdfce1734dfae8fcommit-bot@chromium.org * 935dd567c2a55c16c8bc2668902cdfce1734dfae8fcommit-bot@chromium.org * Use this to compare two regions, where the larger count likely 945dd567c2a55c16c8bc2668902cdfce1734dfae8fcommit-bot@chromium.org * indicates a more complex region. 955dd567c2a55c16c8bc2668902cdfce1734dfae8fcommit-bot@chromium.org */ 965dd567c2a55c16c8bc2668902cdfce1734dfae8fcommit-bot@chromium.org int computeRegionComplexity() const; 975dd567c2a55c16c8bc2668902cdfce1734dfae8fcommit-bot@chromium.org 985dd567c2a55c16c8bc2668902cdfce1734dfae8fcommit-bot@chromium.org /** 99d5d9dadcdd5fdbc8a17f3f398e3199b9d12c8d70tomhudson@google.com * Returns true if the region is non-empty, and if so, appends the 100d5d9dadcdd5fdbc8a17f3f398e3199b9d12c8d70tomhudson@google.com * boundary(s) of the region to the specified path. 101d5d9dadcdd5fdbc8a17f3f398e3199b9d12c8d70tomhudson@google.com * If the region is empty, returns false, and path is left unmodified. 10297fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool getBoundaryPath(SkPath* path) const; 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10597fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 10697fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Set the region to be empty, and return false, since the resulting 10797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * region is empty 10897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 10997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com bool setEmpty(); 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11197fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 11297fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * If rect is non-empty, set this region to that rectangle and return true, 11397fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * otherwise set this region to empty and return false. 11497fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 11597fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com bool setRect(const SkIRect&); 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 11897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * If left < right and top < bottom, set this region to that rectangle and 11997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * return true, otherwise set this region to empty and return false. 12097fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 12197fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com bool setRect(int32_t left, int32_t top, int32_t right, int32_t bottom); 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12397fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 12497fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Set this region to the union of an array of rects. This is generally 12597fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * faster than calling region.op(rect, kUnion_Op) in a loop. If count is 12697fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * 0, then this region is set to the empty region. 12797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * @return true if the resulting region is non-empty 128097a3513535ad854c1b049c32c080ec875ab1411reed@android.com */ 129097a3513535ad854c1b049c32c080ec875ab1411reed@android.com bool setRects(const SkIRect rects[], int count); 130fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 13197fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 13297fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Set this region to the specified region, and return true if it is 13397fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * non-empty. 13497fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 13597fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com bool setRegion(const SkRegion&); 13697fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com 13797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 13897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Set this region to the area described by the path, clipped. 13997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Return true if the resulting region is non-empty. 14097fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * This produces a region that is identical to the pixels that would be 14197fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * drawn by the path (with no antialiasing) with the specified clip. 14297fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 14397fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com bool setPath(const SkPath&, const SkRegion& clip); 144fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 14597fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 14697fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Returns true if the specified rectangle has a non-empty intersection 14797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * with this region. 14897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 14997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com bool intersects(const SkIRect&) const; 150fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 15197fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 15297fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Returns true if the specified region has a non-empty intersection 15397fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * with this region. 15497fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 15597fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com bool intersects(const SkRegion&) const; 15697fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com 15797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 15897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Return true if the specified x,y coordinate is inside the region. 15997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 16097fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com bool contains(int32_t x, int32_t y) const; 16197fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com 16297fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 16397fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Return true if the specified rectangle is completely inside the region. 16497fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * This works for simple (rectangular) and complex regions, and always 16597fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * returns the correct result. Note: if either this region or the rectangle 16697fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * is empty, contains() returns false. 16797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 16897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com bool contains(const SkIRect&) const; 16997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com 17097fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 17197fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Return true if the specified region is completely inside the region. 17297fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * This works for simple (rectangular) and complex regions, and always 17397fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * returns the correct result. Note: if either region is empty, contains() 17497fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * returns false. 17597fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 17697fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com bool contains(const SkRegion&) const; 17797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com 17897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 17997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Return true if this region is a single rectangle (not complex) and the 18097fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * specified rectangle is contained by this region. Returning false is not 18197fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * a guarantee that the rectangle is not contained by this region, but 18297fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * return true is a guarantee that the rectangle is contained by this region. 18397fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool quickContains(const SkIRect& r) const { 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->quickContains(r.fLeft, r.fTop, r.fRight, r.fBottom); 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 18997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Return true if this region is a single rectangle (not complex) and the 19097fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * specified rectangle is contained by this region. Returning false is not 19197fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * a guarantee that the rectangle is not contained by this region, but 19297fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * return true is a guarantee that the rectangle is contained by this 19397fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * region. 19497fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool quickContains(int32_t left, int32_t top, int32_t right, 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int32_t bottom) const { 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(this->isEmpty() == fBounds.isEmpty()); // valid region 198fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return left < right && top < bottom && 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRunHead == SkRegion_gRectRunHeadPtr && // this->isRect() 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* fBounds.contains(left, top, right, bottom); */ 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBounds.fLeft <= left && fBounds.fTop <= top && 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBounds.fRight >= right && fBounds.fBottom >= bottom; 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 205fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 20697fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 20797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Return true if this region is empty, or if the specified rectangle does 20897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * not intersect the region. Returning false is not a guarantee that they 20997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * intersect, but returning true is a guarantee that they do not. 21097fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 21197fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com bool quickReject(const SkIRect& rect) const { 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->isEmpty() || rect.isEmpty() || 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com !SkIRect::Intersects(fBounds, rect); 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21697fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 21797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Return true if this region, or rgn, is empty, or if their bounds do not 21897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * intersect. Returning false is not a guarantee that they intersect, but 21997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * returning true is a guarantee that they do not. 22097fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool quickReject(const SkRegion& rgn) const { 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->isEmpty() || rgn.isEmpty() || 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com !SkIRect::Intersects(fBounds, rgn.fBounds); 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22697fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** Translate the region by the specified (dx, dy) amount. */ 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void translate(int dx, int dy) { this->translate(dx, dy, this); } 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 23097fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Translate the region by the specified (dx, dy) amount, writing the 23197fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * resulting region into dst. Note: it is legal to pass this region as the 23297fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * dst parameter, effectively translating the region in place. If dst is 23397fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * null, nothing happens. 23497fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void translate(int dx, int dy, SkRegion* dst) const; 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 23897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * The logical operations that can be performed when combining two regions. 23997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com enum Op { 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kDifference_Op, //!< subtract the op region from the first region 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kIntersect_Op, //!< intersect the two regions 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kUnion_Op, //!< union (inclusive-or) the two regions 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kXOR_Op, //!< exclusive-or the two regions 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** subtract the first region from the op region */ 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kReverseDifference_Op, 247b6b02526438d6839481fb40ccf610d28f7652397bsalomon kReplace_Op, //!< replace the dst region with the op region 248b6b02526438d6839481fb40ccf610d28f7652397bsalomon 249b6b02526438d6839481fb40ccf610d28f7652397bsalomon kLastOp = kReplace_Op 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 251fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 252b6b02526438d6839481fb40ccf610d28f7652397bsalomon static const int kOpCnt = kLastOp + 1; 253b6b02526438d6839481fb40ccf610d28f7652397bsalomon 25497fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 25597fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Set this region to the result of applying the Op to this region and the 25697fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * specified rectangle: this = (this op rect). 25797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Return true if the resulting region is non-empty. 25897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool op(const SkIRect& rect, Op op) { return this->op(*this, rect, op); } 260fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 26197fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 26297fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Set this region to the result of applying the Op to this region and the 26397fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * specified rectangle: this = (this op rect). 26497fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Return true if the resulting region is non-empty. 26597fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool op(int left, int top, int right, int bottom, Op op) { 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect rect; 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rect.set(left, top, right, bottom); 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->op(*this, rect, op); 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 271fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 27297fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 27397fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Set this region to the result of applying the Op to this region and the 27497fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * specified region: this = (this op rgn). 27597fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Return true if the resulting region is non-empty. 27697fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool op(const SkRegion& rgn, Op op) { return this->op(*this, rgn, op); } 27897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com 27997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 28097fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Set this region to the result of applying the Op to the specified 28197fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * rectangle and region: this = (rect op rgn). 28297fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Return true if the resulting region is non-empty. 28397fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool op(const SkIRect& rect, const SkRegion& rgn, Op); 28597fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com 28697fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 28797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Set this region to the result of applying the Op to the specified 28897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * region and rectangle: this = (rgn op rect). 28997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Return true if the resulting region is non-empty. 29097fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool op(const SkRegion& rgn, const SkIRect& rect, Op); 29297fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com 29397fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 29497fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Set this region to the result of applying the Op to the specified 29597fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * regions: this = (rgna op rgnb). 29697fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Return true if the resulting region is non-empty. 29797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op); 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30056c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID 301cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com /** Returns a new char* containing the list of rectangles in this region 302cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com */ 303cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com char* toString(); 304cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com#endif 305cd9d69b9ce7eb301a9fd8d91b9f95fd99b07bae5djsollen@google.com 30697fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 30797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Returns the sequence of rectangles, sorted in Y and X, that make up 30897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * this region. 30997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 3107ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.org class SK_API Iterator { 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com public: 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Iterator() : fRgn(NULL), fDone(true) {} 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Iterator(const SkRegion&); 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // if we have a region, reset to it and return true, else return false 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool rewind(); 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // reset the iterator, using the new region 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void reset(const SkRegion&); 318d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com bool done() const { return fDone; } 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void next(); 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkIRect& rect() const { return fRect; } 321f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com // may return null 322f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com const SkRegion* rgn() const { return fRgn; } 32397fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com private: 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkRegion* fRgn; 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const RunType* fRuns; 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect fRect; 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool fDone; 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 33197fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 33297fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Returns the sequence of rectangles, sorted in Y and X, that make up 33397fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * this region intersected with the specified clip rectangle. 33497fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 3357ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.org class SK_API Cliperator { 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com public: 3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Cliperator(const SkRegion&, const SkIRect& clip); 33897fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com bool done() { return fDone; } 33997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com void next(); 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkIRect& rect() const { return fRect; } 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com private: 3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Iterator fIter; 3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect fClip; 3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect fRect; 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool fDone; 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 34997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 35097fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Returns the sequence of runs that make up this region for the specified 35197fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Y scanline, clipped to the specified left and right X values. 35297fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com class Spanerator { 3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com public: 3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Spanerator(const SkRegion&, int y, int left, int right); 35697fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com bool next(int* left, int* right); 3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com private: 3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkRegion::RunType* fRuns; 3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int fLeft, fRight; 3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool fDone; 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 36497fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 36597fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * Write the region to the buffer, and return the number of bytes written. 36697fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com * If buffer is NULL, it still returns the number of bytes. 36797fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 3684faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org size_t writeToMemory(void* buffer) const; 36997fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com /** 3704faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * Initializes the region from the buffer 3714faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * 3724faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * @param buffer Memory to read from 3734faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * @param length Amount of memory available in the buffer 3744faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * @return number of bytes read (must be a multiple of 4) or 3754faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * 0 if there was not enough memory available 37697fa34c5f0079c4ae5fdf2c9f86772ff793d0133reed@google.com */ 3774faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org size_t readFromMemory(const void* buffer, size_t length); 3780a0a236c3ba241046d38caaf78226ec68ff9c998reed@google.com 3790a0a236c3ba241046d38caaf78226ec68ff9c998reed@google.com /** 3800a0a236c3ba241046d38caaf78226ec68ff9c998reed@google.com * Returns a reference to a global empty region. Just a convenience for 3810a0a236c3ba241046d38caaf78226ec68ff9c998reed@google.com * callers that need a const empty region. 3820a0a236c3ba241046d38caaf78226ec68ff9c998reed@google.com */ 3830a0a236c3ba241046d38caaf78226ec68ff9c998reed@google.com static const SkRegion& GetEmptyRegion(); 3840a0a236c3ba241046d38caaf78226ec68ff9c998reed@google.com 3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(void dump() const;) 3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(void validate() const;) 3878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(static void UnitTest();) 3888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // expose this to allow for regression test on complex regions 3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bool debugSetRuns(const RunType runs[], int count);) 3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com enum { 3948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kOpCount = kReplace_Op + 1 3958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com enum { 3989c36a76102453db964cb6e51078a3d74d4126b2creed@google.com // T 3999c36a76102453db964cb6e51078a3d74d4126b2creed@google.com // [B N L R S] 4009c36a76102453db964cb6e51078a3d74d4126b2creed@google.com // S 4019c36a76102453db964cb6e51078a3d74d4126b2creed@google.com kRectRegionRuns = 7 4028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 4038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend class android::Region; // needed for marshalling efficiently 4058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com struct RunHead; 407fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 408af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com // allocate space for count runs 4099c36a76102453db964cb6e51078a3d74d4126b2creed@google.com void allocateRuns(int count); 410af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com void allocateRuns(int count, int ySpanCount, int intervalCount); 411af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com void allocateRuns(const RunHead& src); 4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect fBounds; 4148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com RunHead* fRunHead; 4158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4169c36a76102453db964cb6e51078a3d74d4126b2creed@google.com void freeRuns(); 417fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 4189c36a76102453db964cb6e51078a3d74d4126b2creed@google.com /** 4199c36a76102453db964cb6e51078a3d74d4126b2creed@google.com * Return the runs from this region, consing up fake runs if the region 4209c36a76102453db964cb6e51078a3d74d4126b2creed@google.com * is empty or a rect. In those 2 cases, we use tmpStorage to hold the 4219c36a76102453db964cb6e51078a3d74d4126b2creed@google.com * run data. 4229c36a76102453db964cb6e51078a3d74d4126b2creed@google.com */ 423af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com const RunType* getRuns(RunType tmpStorage[], int* intervals) const; 424fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 4259c36a76102453db964cb6e51078a3d74d4126b2creed@google.com // This is called with runs[] that do not yet have their interval-count 4269c36a76102453db964cb6e51078a3d74d4126b2creed@google.com // field set on each scanline. That is computed as part of this call 4279c36a76102453db964cb6e51078a3d74d4126b2creed@google.com // (inside ComputeRunBounds). 4289c36a76102453db964cb6e51078a3d74d4126b2creed@google.com bool setRuns(RunType runs[], int count); 4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count_runtype_values(int* itop, int* ibot) const; 431fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void BuildRectRuns(const SkIRect& bounds, 4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com RunType runs[kRectRegionRuns]); 4349c36a76102453db964cb6e51078a3d74d4126b2creed@google.com 4359c36a76102453db964cb6e51078a3d74d4126b2creed@google.com // If the runs define a simple rect, return true and set bounds to that 4369c36a76102453db964cb6e51078a3d74d4126b2creed@google.com // rect. If not, return false and ignore bounds. 4379c36a76102453db964cb6e51078a3d74d4126b2creed@google.com static bool RunsAreARect(const SkRegion::RunType runs[], int count, 4389c36a76102453db964cb6e51078a3d74d4126b2creed@google.com SkIRect* bounds); 4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4407d4aee34e23e536e1115f132d20a20fb629bb66areed@google.com /** 4417d4aee34e23e536e1115f132d20a20fb629bb66areed@google.com * If the last arg is null, just return if the result is non-empty, 4427d4aee34e23e536e1115f132d20a20fb629bb66areed@google.com * else store the result in the last arg. 4437d4aee34e23e536e1115f132d20a20fb629bb66areed@google.com */ 4447d4aee34e23e536e1115f132d20a20fb629bb66areed@google.com static bool Oper(const SkRegion&, const SkRegion&, SkRegion::Op, SkRegion*); 4457d4aee34e23e536e1115f132d20a20fb629bb66areed@google.com 4468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend struct RunHead; 4478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend class Iterator; 4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend class Spanerator; 4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend class SkRgnBuilder; 4508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend class SkFlatRegion; 4518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 454