SkRegion.h revision 40528743dbb9ce7f39f093e0cdc47849ac8887cf
10910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/*
20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project
30910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *
40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
50910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * you may not use this file except in compliance with the License.
60910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * You may obtain a copy of the License at
70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *
80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * See the License for the specific language governing permissions and
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * limitations under the License.
150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */
160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifndef SkRegion_DEFINED
180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkRegion_DEFINED
190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkRect.h"
210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkPath;
230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkRgnBuilder;
240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectnamespace android {
260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    class Region;
270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkRegion_gEmptyRunHeadPtr   ((SkRegion::RunHead*)-1)
300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkRegion_gRectRunHeadPtr    0
310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/** \class SkRegion
330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    The SkRegion class encapsulates the geometric region used to specify
350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    clipping areas for drawing.
360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkRegion {
380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    typedef int32_t RunType;
400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    enum {
410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kRunTypeSentinel = 0x7FFFFFFF
420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion();
450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion(const SkRegion&);
460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    explicit SkRegion(const SkIRect&);
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ~SkRegion();
480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion& operator=(const SkRegion&);
500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    friend int operator==(const SkRegion& a, const SkRegion& b);
520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    friend int operator!=(const SkRegion& a, const SkRegion& b) {
530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return !(a == b);
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Replace this region with the specified region, and return true if the
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        resulting region is non-empty.
580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool set(const SkRegion& src) {
600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(&src);
610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *this = src;
620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return !this->isEmpty();
630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Swap the contents of this and the specified region. This operation
660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        is gauarenteed to never fail.
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void    swap(SkRegion&);
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return true if this region is empty */
710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    isEmpty() const { return fRunHead == SkRegion_gEmptyRunHeadPtr; }
720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return true if this region is a single, non-empty rectangle */
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    isRect() const { return fRunHead == SkRegion_gRectRunHeadPtr; }
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return true if this region consists of more than 1 rectangular area */
750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    isComplex() const { return !this->isEmpty() && !this->isRect(); }
760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return the bounds of this region. If the region is empty, returns an
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        empty rectangle.
780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkIRect& getBounds() const { return fBounds; }
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Returns true if the region is non-empty, and if so, sets the specified
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        path to the boundary(s) of the region.
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool getBoundaryPath(SkPath* path) const;
850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Set the region to be empty, and return false, since the resulting
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        region is empty
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    setEmpty();
900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** If rect is non-empty, set this region to that rectangle and return true,
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        otherwise set this region to empty and return false.
930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    setRect(const SkIRect&);
950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** If left < right and top < bottom, set this region to that rectangle and
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true, otherwise set this region to empty and return false.
980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    setRect(int32_t left, int32_t top, int32_t right, int32_t bottom);
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    /** Set this region to the union of an array of rects. This is generally
10240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        faster than calling region.op(rect, kUnion_Op) in a loop. If count is
10340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        0, then this region is set to the empty region.
10440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        @return true if the resulting region is non-empty
10540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger     */
10640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    bool setRects(const SkIRect rects[], int count);
10740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Set this region to the specified region, and return true if it is
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        non-empty. */
1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    setRegion(const SkRegion&);
1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Set this region to the area described by the path, clipped.
1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Return true if the resulting region is non-empty.
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        This produces a region that is identical to the pixels that would be
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        drawn by the path (with no antialiasing) with the specified clip.
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    setPath(const SkPath&, const SkRegion& clip);
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Returns true if the specified rectangle has a non-empty intersection
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        with this region.
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    intersects(const SkIRect&) const;
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Returns true if the specified region has a non-empty intersection
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        with this region.
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    intersects(const SkRegion&) const;
1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return true if the specified x,y coordinate is inside the region.
1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    contains(int32_t x, int32_t y) const;
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return true if the specified rectangle is completely inside the region.
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        This works for simple (rectangular) and complex regions, and always
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        returns the correct result. Note: if either this region or the rectangle
1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        is empty, contains() returns false.
1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    contains(const SkIRect&) const;
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return true if the specified region is completely inside the region.
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        This works for simple (rectangular) and complex regions, and always
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        returns the correct result. Note: if either region is empty, contains()
1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        returns false.
1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    contains(const SkRegion&) const;
1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return true if this region is a single rectangle (not complex) and the
1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        specified rectangle is contained by this region. Returning false is not
1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        a guarantee that the rectangle is not contained by this region, but
1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true is a guarantee that the rectangle is contained by this region.
1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool quickContains(const SkIRect& r) const {
1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return this->quickContains(r.fLeft, r.fTop, r.fRight, r.fBottom);
1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return true if this region is a single rectangle (not complex) and the
1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        specified rectangle is contained by this region. Returning false is not
1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        a guarantee that the rectangle is not contained by this region, but
1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true is a guarantee that the rectangle is contained by this
1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        region.
1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool quickContains(int32_t left, int32_t top, int32_t right,
1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                       int32_t bottom) const {
1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(this->isEmpty() == fBounds.isEmpty()); // valid region
1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return left < right && top < bottom &&
1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project               fRunHead == SkRegion_gRectRunHeadPtr &&  // this->isRect()
1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project               /* fBounds.contains(left, top, right, bottom); */
1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project               fBounds.fLeft <= left && fBounds.fTop <= top &&
1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project               fBounds.fRight >= right && fBounds.fBottom >= bottom;
1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return true if this region is empty, or if the specified rectangle does
1740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        not intersect the region. Returning false is not a guarantee that they
1750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        intersect, but returning true is a guarantee that they do not.
1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool quickReject(const SkIRect& rect) const
1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return this->isEmpty() || rect.isEmpty() ||
1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                !SkIRect::Intersects(fBounds, rect);
1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return true if this region, or rgn, is empty, or if their bounds do not
1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        intersect. Returning false is not a guarantee that they intersect, but
1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        returning true is a guarantee that they do not.
1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool quickReject(const SkRegion& rgn) const {
1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return this->isEmpty() || rgn.isEmpty() ||
1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project               !SkIRect::Intersects(fBounds, rgn.fBounds);
1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Translate the region by the specified (dx, dy) amount.
1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void translate(int dx, int dy) { this->translate(dx, dy, this); }
1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Translate the region by the specified (dx, dy) amount, writing the
1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        resulting region into dst. Note: it is legal to pass this region as the
1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        dst parameter, effectively translating the region in place. If dst is
1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        null, nothing happens.
2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void translate(int dx, int dy, SkRegion* dst) const;
2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** The logical operations that can be performed when combining two regions.
2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    enum Op {
2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kDifference_Op, //!< subtract the op region from the first region
2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kIntersect_Op,  //!< intersect the two regions
2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kUnion_Op,      //!< union (inclusive-or) the two regions
2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kXOR_Op,        //!< exclusive-or the two regions
2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        /** subtract the first region from the op region */
2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kReverseDifference_Op,
2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kReplace_Op     //!< replace the dst region with the op region
2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Set this region to the result of applying the Op to this region and the
2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        specified rectangle: this = (this op rect).
2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Return true if the resulting region is non-empty.
2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        */
2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool op(const SkIRect& rect, Op op) { return this->op(*this, rect, op); }
2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Set this region to the result of applying the Op to this region and the
2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        specified rectangle: this = (this op rect).
2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Return true if the resulting region is non-empty.
2240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool op(int left, int top, int right, int bottom, Op op) {
2260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkIRect rect;
2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rect.set(left, top, right, bottom);
2280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return this->op(*this, rect, op);
2290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Set this region to the result of applying the Op to this region and the
2320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        specified region: this = (this op rgn).
2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Return true if the resulting region is non-empty.
2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool op(const SkRegion& rgn, Op op) { return this->op(*this, rgn, op); }
2360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Set this region to the result of applying the Op to the specified
2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rectangle and region: this = (rect op rgn).
2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Return true if the resulting region is non-empty.
2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool op(const SkIRect& rect, const SkRegion& rgn, Op);
2410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Set this region to the result of applying the Op to the specified
2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        region and rectangle: this = (rgn op rect).
2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Return true if the resulting region is non-empty.
2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool op(const SkRegion& rgn, const SkIRect& rect, Op);
2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Set this region to the result of applying the Op to the specified
2470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        regions: this = (rgna op rgnb).
2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Return true if the resulting region is non-empty.
2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
2500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op);
2510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2529221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato    /** Returns a new char* containing the list of rectangles in this region
2539221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato     */
2549221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato    char* toString();
2559221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato
2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Returns the sequence of rectangles, sorted in Y and X, that make up
2570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this region.
2580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
2590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    class Iterator {
2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    public:
2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Iterator() : fRgn(NULL), fDone(true) {}
2620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Iterator(const SkRegion&);
2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // if we have a region, reset to it and return true, else return false
2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bool rewind();
2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // reset the iterator, using the new region
2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        void reset(const SkRegion&);
2670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bool done() { return fDone; }
2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        void next();
2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& rect() const { return fRect; }
27040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        // may return null
27140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        const SkRegion* rgn() const { return fRgn; }
2720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    private:
2730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkRegion* fRgn;
2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const RunType*  fRuns;
2750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkIRect         fRect;
2760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bool            fDone;
2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Returns the sequence of rectangles, sorted in Y and X, that make up
2800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this region intersected with the specified clip rectangle.
2810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
2820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    class Cliperator {
2830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    public:
2840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Cliperator(const SkRegion&, const SkIRect& clip);
2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bool            done() { return fDone; }
2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        void            next();
2870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& rect() const { return fRect; }
2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    private:
2900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Iterator    fIter;
2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkIRect     fClip;
2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkIRect     fRect;
2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bool        fDone;
2940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
2950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Returns the sequence of runs that make up this region for the specified
2970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Y scanline, clipped to the specified left and right X values.
2980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    class Spanerator {
3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    public:
3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Spanerator(const SkRegion&, int y, int left, int right);
3020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bool    next(int* left, int* right);
3030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    private:
3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkRegion::RunType* fRuns;
3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int     fLeft, fRight;
3070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bool    fDone;
3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
3090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Write the region to the buffer, and return the number of bytes written.
3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        If buffer is NULL, it still returns the number of bytes.
3120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t flatten(void* buffer) const;
3140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Initialized the region from the buffer, returning the number
3150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        of bytes actually read.
3160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t unflatten(const void* buffer);
3180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(void dump() const;)
3200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(void validate() const;)
3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(static void UnitTest();)
3220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // expose this to allow for regression test on complex regions
3240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(bool debugSetRuns(const RunType runs[], int count);)
3250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
3270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    enum {
3280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kOpCount = kReplace_Op + 1
3290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
3300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    enum {
3320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kRectRegionRuns = 6 // need to store a region of a rect [T B L R S S]
3330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
3340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    friend class android::Region;    // needed for marshalling efficiently
3360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void allocateRuns(int count); // allocate space for count runs
3370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    struct RunHead;
3390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkIRect     fBounds;
3410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    RunHead*    fRunHead;
3420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void            freeRuns();
3440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const RunType*  getRuns(RunType tmpStorage[], int* count) const;
3450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool            setRuns(RunType runs[], int count);
3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int count_runtype_values(int* itop, int* ibot) const;
3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    static void BuildRectRuns(const SkIRect& bounds,
3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                              RunType runs[kRectRegionRuns]);
3510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // returns true if runs are just a rect
3520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    static bool ComputeRunBounds(const RunType runs[], int count,
3530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                 SkIRect* bounds);
3540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    friend struct RunHead;
3560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    friend class Iterator;
3570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    friend class Spanerator;
3580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    friend class SkRgnBuilder;
3590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    friend class SkFlatRegion;
3600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
3610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
3640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
365