180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2005 The Android Open Source Project 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef SkRegion_DEFINED 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkRegion_DEFINED 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkRect.h" 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkPath; 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkRgnBuilder; 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace android { 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru class Region; 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkRegion_gEmptyRunHeadPtr ((SkRegion::RunHead*)-1) 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkRegion_gRectRunHeadPtr 0 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** \class SkRegion 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru The SkRegion class encapsulates the geometric region used to specify 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru clipping areas for drawing. 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/ 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SK_API SkRegion { 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef int32_t RunType; 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru enum { 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kRunTypeSentinel = 0x7FFFFFFF 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRegion(); 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRegion(const SkRegion&); 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru explicit SkRegion(const SkIRect&); 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ~SkRegion(); 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRegion& operator=(const SkRegion&); 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Return true if the two regions are equal. i.e. The enclose exactly 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * the same area. 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool operator==(const SkRegion& other) const; 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Return true if the two regions are not equal. 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool operator!=(const SkRegion& other) const { 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return !(*this == other); 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Replace this region with the specified region, and return true if the 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * resulting region is non-empty. 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool set(const SkRegion& src) { 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(&src); 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *this = src; 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return !this->isEmpty(); 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Swap the contents of this and the specified region. This operation 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * is gauarenteed to never fail. 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void swap(SkRegion&); 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Return true if this region is empty */ 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool isEmpty() const { return fRunHead == SkRegion_gEmptyRunHeadPtr; } 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Return true if this region is a single, non-empty rectangle */ 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool isRect() const { return fRunHead == SkRegion_gRectRunHeadPtr; } 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Return true if this region consists of more than 1 rectangular area */ 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool isComplex() const { return !this->isEmpty() && !this->isRect(); } 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Return the bounds of this region. If the region is empty, returns an 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * empty rectangle. 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkIRect& getBounds() const { return fBounds; } 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 8958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * Returns a value that grows approximately linearly with the number of 9058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * intervals comprised in the region. Empty region will return 0, Rect 9158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * will return 1, Complex will return a value > 1. 9258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * 9358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * Use this to compare two regions, where the larger count likely 9458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * indicates a more complex region. 9558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger */ 9658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger int computeRegionComplexity() const; 9758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 9858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger /** 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Returns true if the region is non-empty, and if so, appends the 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * boundary(s) of the region to the specified path. 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * If the region is empty, returns false, and path is left unmodified. 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool getBoundaryPath(SkPath* path) const; 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Set the region to be empty, and return false, since the resulting 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * region is empty 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool setEmpty(); 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * If rect is non-empty, set this region to that rectangle and return true, 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * otherwise set this region to empty and return false. 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool setRect(const SkIRect&); 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * If left < right and top < bottom, set this region to that rectangle and 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * return true, otherwise set this region to empty and return false. 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool setRect(int32_t left, int32_t top, int32_t right, int32_t bottom); 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Set this region to the union of an array of rects. This is generally 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * faster than calling region.op(rect, kUnion_Op) in a loop. If count is 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 0, then this region is set to the empty region. 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @return true if the resulting region is non-empty 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool setRects(const SkIRect rects[], int count); 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Set this region to the specified region, and return true if it is 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * non-empty. 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool setRegion(const SkRegion&); 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Set this region to the area described by the path, clipped. 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Return true if the resulting region is non-empty. 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * This produces a region that is identical to the pixels that would be 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * drawn by the path (with no antialiasing) with the specified clip. 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool setPath(const SkPath&, const SkRegion& clip); 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Returns true if the specified rectangle has a non-empty intersection 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * with this region. 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool intersects(const SkIRect&) const; 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Returns true if the specified region has a non-empty intersection 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * with this region. 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool intersects(const SkRegion&) const; 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Return true if the specified x,y coordinate is inside the region. 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool contains(int32_t x, int32_t y) const; 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Return true if the specified rectangle is completely inside the region. 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * This works for simple (rectangular) and complex regions, and always 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * returns the correct result. Note: if either this region or the rectangle 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * is empty, contains() returns false. 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool contains(const SkIRect&) const; 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Return true if the specified region is completely inside the region. 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * This works for simple (rectangular) and complex regions, and always 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * returns the correct result. Note: if either region is empty, contains() 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * returns false. 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool contains(const SkRegion&) const; 17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Return true if this region is a single rectangle (not complex) and the 18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * specified rectangle is contained by this region. Returning false is not 18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * a guarantee that the rectangle is not contained by this region, but 18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * return true is a guarantee that the rectangle is contained by this region. 18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool quickContains(const SkIRect& r) const { 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->quickContains(r.fLeft, r.fTop, r.fRight, r.fBottom); 18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Return true if this region is a single rectangle (not complex) and the 19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * specified rectangle is contained by this region. Returning false is not 19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * a guarantee that the rectangle is not contained by this region, but 19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * return true is a guarantee that the rectangle is contained by this 19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * region. 19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool quickContains(int32_t left, int32_t top, int32_t right, 19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int32_t bottom) const { 19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(this->isEmpty() == fBounds.isEmpty()); // valid region 19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return left < right && top < bottom && 20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRunHead == SkRegion_gRectRunHeadPtr && // this->isRect() 20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* fBounds.contains(left, top, right, bottom); */ 20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fBounds.fLeft <= left && fBounds.fTop <= top && 20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fBounds.fRight >= right && fBounds.fBottom >= bottom; 20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Return true if this region is empty, or if the specified rectangle does 20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * not intersect the region. Returning false is not a guarantee that they 20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * intersect, but returning true is a guarantee that they do not. 21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool quickReject(const SkIRect& rect) const { 21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->isEmpty() || rect.isEmpty() || 21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru !SkIRect::Intersects(fBounds, rect); 21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Return true if this region, or rgn, is empty, or if their bounds do not 21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * intersect. Returning false is not a guarantee that they intersect, but 21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * returning true is a guarantee that they do not. 22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool quickReject(const SkRegion& rgn) const { 22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->isEmpty() || rgn.isEmpty() || 22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru !SkIRect::Intersects(fBounds, rgn.fBounds); 22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Translate the region by the specified (dx, dy) amount. */ 22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void translate(int dx, int dy) { this->translate(dx, dy, this); } 22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Translate the region by the specified (dx, dy) amount, writing the 23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * resulting region into dst. Note: it is legal to pass this region as the 23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * dst parameter, effectively translating the region in place. If dst is 23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * null, nothing happens. 23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void translate(int dx, int dy, SkRegion* dst) const; 23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * The logical operations that can be performed when combining two regions. 23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru enum Op { 24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kDifference_Op, //!< subtract the op region from the first region 24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kIntersect_Op, //!< intersect the two regions 24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kUnion_Op, //!< union (inclusive-or) the two regions 24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kXOR_Op, //!< exclusive-or the two regions 24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** subtract the first region from the op region */ 24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kReverseDifference_Op, 24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kReplace_Op //!< replace the dst region with the op region 24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Set this region to the result of applying the Op to this region and the 25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * specified rectangle: this = (this op rect). 25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Return true if the resulting region is non-empty. 25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool op(const SkIRect& rect, Op op) { return this->op(*this, rect, op); } 25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Set this region to the result of applying the Op to this region and the 25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * specified rectangle: this = (this op rect). 26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Return true if the resulting region is non-empty. 26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool op(int left, int top, int right, int bottom, Op op) { 26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIRect rect; 26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rect.set(left, top, right, bottom); 26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->op(*this, rect, op); 26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Set this region to the result of applying the Op to this region and the 27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * specified region: this = (this op rgn). 27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Return true if the resulting region is non-empty. 27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool op(const SkRegion& rgn, Op op) { return this->op(*this, rgn, op); } 27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Set this region to the result of applying the Op to the specified 27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * rectangle and region: this = (rect op rgn). 27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Return true if the resulting region is non-empty. 27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool op(const SkIRect& rect, const SkRegion& rgn, Op); 28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Set this region to the result of applying the Op to the specified 28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * region and rectangle: this = (rgn op rect). 28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Return true if the resulting region is non-empty. 28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool op(const SkRegion& rgn, const SkIRect& rect, Op); 28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Set this region to the result of applying the Op to the specified 29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * regions: this = (rgna op rgnb). 29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Return true if the resulting region is non-empty. 29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op); 29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_BUILD_FOR_ANDROID 29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Returns a new char* containing the list of rectangles in this region 29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char* toString(); 30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Returns the sequence of rectangles, sorted in Y and X, that make up 30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * this region. 30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru class SK_API Iterator { 30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru public: 30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Iterator() : fRgn(NULL), fDone(true) {} 30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Iterator(const SkRegion&); 31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // if we have a region, reset to it and return true, else return false 31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool rewind(); 31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // reset the iterator, using the new region 31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void reset(const SkRegion&); 31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool done() const { return fDone; } 31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void next(); 31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkIRect& rect() const { return fRect; } 31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // may return null 31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkRegion* rgn() const { return fRgn; } 31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru private: 32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkRegion* fRgn; 32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const RunType* fRuns; 32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIRect fRect; 32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool fDone; 32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Returns the sequence of rectangles, sorted in Y and X, that make up 32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * this region intersected with the specified clip rectangle. 33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru class SK_API Cliperator { 33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru public: 33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Cliperator(const SkRegion&, const SkIRect& clip); 33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool done() { return fDone; } 33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void next(); 33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkIRect& rect() const { return fRect; } 33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru private: 33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Iterator fIter; 34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIRect fClip; 34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIRect fRect; 34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool fDone; 34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Returns the sequence of runs that make up this region for the specified 34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Y scanline, clipped to the specified left and right X values. 34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru class Spanerator { 35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru public: 35180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Spanerator(const SkRegion&, int y, int left, int right); 35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool next(int* left, int* right); 35380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru private: 35580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkRegion::RunType* fRuns; 35680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int fLeft, fRight; 35780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool fDone; 35880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 35980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 36180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Write the region to the buffer, and return the number of bytes written. 36280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * If buffer is NULL, it still returns the number of bytes. 36380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 36480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t writeToMemory(void* buffer) const; 36580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 36780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Initialized the region from the buffer, returning the number 36880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * of bytes actually read. 36980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 37080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t readFromMemory(const void* buffer); 37180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 37280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 37380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Returns a reference to a global empty region. Just a convenience for 37480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * callers that need a const empty region. 37580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 37680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const SkRegion& GetEmptyRegion(); 37780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 37880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(void dump() const;) 37980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(void validate() const;) 38080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(static void UnitTest();) 38180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 38280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // expose this to allow for regression test on complex regions 38380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(bool debugSetRuns(const RunType runs[], int count);) 38480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 38580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 38680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru enum { 38780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kOpCount = kReplace_Op + 1 38880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 38980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 39080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru enum { 39180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // T 39280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // [B N L R S] 39380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // S 39480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kRectRegionRuns = 7 39580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 39680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 39780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru friend class android::Region; // needed for marshalling efficiently 39880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 39980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru struct RunHead; 40080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 40180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // allocate space for count runs 40280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void allocateRuns(int count); 40380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void allocateRuns(int count, int ySpanCount, int intervalCount); 40480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void allocateRuns(const RunHead& src); 40580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 40680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIRect fBounds; 40780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru RunHead* fRunHead; 40880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 40980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void freeRuns(); 41080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 41180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 41280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Return the runs from this region, consing up fake runs if the region 41380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * is empty or a rect. In those 2 cases, we use tmpStorage to hold the 41480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * run data. 41580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 41680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const RunType* getRuns(RunType tmpStorage[], int* intervals) const; 41780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 41880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // This is called with runs[] that do not yet have their interval-count 41980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // field set on each scanline. That is computed as part of this call 42080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // (inside ComputeRunBounds). 42180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool setRuns(RunType runs[], int count); 42280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 42380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int count_runtype_values(int* itop, int* ibot) const; 42480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 42580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static void BuildRectRuns(const SkIRect& bounds, 42680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru RunType runs[kRectRegionRuns]); 42780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 42880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // If the runs define a simple rect, return true and set bounds to that 42980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // rect. If not, return false and ignore bounds. 43080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static bool RunsAreARect(const SkRegion::RunType runs[], int count, 43180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIRect* bounds); 43280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 43380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 43480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * If the last arg is null, just return if the result is non-empty, 43580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * else store the result in the last arg. 43680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 43780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static bool Oper(const SkRegion&, const SkRegion&, SkRegion::Op, SkRegion*); 43880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 43980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru friend struct RunHead; 44080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru friend class Iterator; 44180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru friend class Spanerator; 44280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru friend class SkRgnBuilder; 44380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru friend class SkFlatRegion; 44480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 44580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 44680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 447