SkRegion.h revision 9221e8085d77b0850a07c6585275ec7bb7e0931a
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
1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Set this region to the specified region, and return true if it is
1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        non-empty. */
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    setRegion(const SkRegion&);
1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Set this region to the area described by the path, clipped.
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Return true if the resulting region is non-empty.
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        This produces a region that is identical to the pixels that would be
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        drawn by the path (with no antialiasing) with the specified clip.
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    setPath(const SkPath&, const SkRegion& clip);
1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Returns true if the specified rectangle has a non-empty intersection
1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        with this region.
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    intersects(const SkIRect&) const;
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Returns true if the specified region has a non-empty intersection
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        with this region.
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    intersects(const SkRegion&) const;
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return true if the specified x,y coordinate is inside the region.
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    contains(int32_t x, int32_t y) const;
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return true if the specified rectangle is completely inside the region.
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        This works for simple (rectangular) and complex regions, and always
1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        returns the correct result. Note: if either this region or the rectangle
1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        is empty, contains() returns false.
1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    contains(const SkIRect&) const;
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return true if the specified region 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 region is empty, contains()
1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        returns false.
1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool    contains(const SkRegion&) const;
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return true if this region is a single rectangle (not complex) and the
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        specified rectangle is contained by this region. Returning false is not
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        a guarantee that the rectangle is not contained by this region, but
1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true is a guarantee that the rectangle is contained by this region.
1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool quickContains(const SkIRect& r) const {
1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return this->quickContains(r.fLeft, r.fTop, r.fRight, r.fBottom);
1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return true if this region is a single rectangle (not complex) and the
1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        specified rectangle is contained by this region. Returning false is not
1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        a guarantee that the rectangle is not contained by this region, but
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true is a guarantee that the rectangle is contained by this
1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        region.
1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool quickContains(int32_t left, int32_t top, int32_t right,
1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                       int32_t bottom) const {
1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(this->isEmpty() == fBounds.isEmpty()); // valid region
1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return left < right && top < bottom &&
1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project               fRunHead == SkRegion_gRectRunHeadPtr &&  // this->isRect()
1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project               /* fBounds.contains(left, top, right, bottom); */
1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project               fBounds.fLeft <= left && fBounds.fTop <= top &&
1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project               fBounds.fRight >= right && fBounds.fBottom >= bottom;
1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return true if this region is empty, or if the specified rectangle does
1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        not intersect the region. Returning false is not a guarantee that they
1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        intersect, but returning true is a guarantee that they do not.
1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool quickReject(const SkIRect& rect) const
1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return this->isEmpty() || rect.isEmpty() ||
1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                !SkIRect::Intersects(fBounds, rect);
1740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return true if this region, or rgn, is empty, or if their bounds do not
1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        intersect. Returning false is not a guarantee that they intersect, but
1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        returning true is a guarantee that they do not.
1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool quickReject(const SkRegion& rgn) const {
1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return this->isEmpty() || rgn.isEmpty() ||
1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project               !SkIRect::Intersects(fBounds, rgn.fBounds);
1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Translate the region by the specified (dx, dy) amount.
1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void translate(int dx, int dy) { this->translate(dx, dy, this); }
1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Translate the region by the specified (dx, dy) amount, writing the
1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        resulting region into dst. Note: it is legal to pass this region as the
1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        dst parameter, effectively translating the region in place. If dst is
1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        null, nothing happens.
1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void translate(int dx, int dy, SkRegion* dst) const;
1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** The logical operations that can be performed when combining two regions.
1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    enum Op {
1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kDifference_Op, //!< subtract the op region from the first region
2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kIntersect_Op,  //!< intersect the two regions
2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kUnion_Op,      //!< union (inclusive-or) the two regions
2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kXOR_Op,        //!< exclusive-or the two regions
2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        /** subtract the first region from the op region */
2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kReverseDifference_Op,
2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kReplace_Op     //!< replace the dst region with the op region
2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Set this region to the result of applying the Op to this region and the
2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        specified rectangle: this = (this op rect).
2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Return true if the resulting region is non-empty.
2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        */
2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool op(const SkIRect& rect, Op op) { return this->op(*this, rect, op); }
2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Set this region to the result of applying the Op to this region and the
2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        specified rectangle: this = (this op rect).
2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Return true if the resulting region is non-empty.
2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool op(int left, int top, int right, int bottom, Op op) {
2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkIRect rect;
2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rect.set(left, top, right, bottom);
2210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return this->op(*this, rect, op);
2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Set this region to the result of applying the Op to this region and the
2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        specified region: this = (this op rgn).
2260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Return true if the resulting region is non-empty.
2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
2280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool op(const SkRegion& rgn, Op op) { return this->op(*this, rgn, op); }
2290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Set this region to the result of applying the Op to the specified
2300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rectangle and region: this = (rect op rgn).
2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Return true if the resulting region is non-empty.
2320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool op(const SkIRect& rect, const SkRegion& rgn, Op);
2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Set this region to the result of applying the Op to the specified
2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        region and rectangle: this = (rgn op rect).
2360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Return true if the resulting region is non-empty.
2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool op(const SkRegion& rgn, const SkIRect& rect, Op);
2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Set this region to the result of applying the Op to the specified
2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        regions: this = (rgna op rgnb).
2410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Return true if the resulting region is non-empty.
2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op);
2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2459221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato    /** Returns a new char* containing the list of rectangles in this region
2469221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato     */
2479221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato    char* toString();
2489221e8085d77b0850a07c6585275ec7bb7e0931aJoe Onorato
2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Returns the sequence of rectangles, sorted in Y and X, that make up
2500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this region.
2510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    class Iterator {
2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    public:
2540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Iterator() : fRgn(NULL), fDone(true) {}
2550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Iterator(const SkRegion&);
2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // if we have a region, reset to it and return true, else return false
2570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bool rewind();
2580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // reset the iterator, using the new region
2590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        void reset(const SkRegion&);
2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bool done() { return fDone; }
2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        void next();
2620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& rect() const { return fRect; }
2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    private:
2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkRegion* fRgn;
2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const RunType*  fRuns;
2670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkIRect         fRect;
2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bool            fDone;
2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Returns the sequence of rectangles, sorted in Y and X, that make up
2720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this region intersected with the specified clip rectangle.
2730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    class Cliperator {
2750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    public:
2760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Cliperator(const SkRegion&, const SkIRect& clip);
2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bool            done() { return fDone; }
2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        void            next();
2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& rect() const { return fRect; }
2800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    private:
2820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Iterator    fIter;
2830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkIRect     fClip;
2840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkIRect     fRect;
2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bool        fDone;
2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
2870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Returns the sequence of runs that make up this region for the specified
2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Y scanline, clipped to the specified left and right X values.
2900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    class Spanerator {
2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    public:
2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Spanerator(const SkRegion&, int y, int left, int right);
2940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bool    next(int* left, int* right);
2950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    private:
2970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkRegion::RunType* fRuns;
2980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int     fLeft, fRight;
2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bool    fDone;
3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Write the region to the buffer, and return the number of bytes written.
3030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        If buffer is NULL, it still returns the number of bytes.
3040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t flatten(void* buffer) const;
3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Initialized the region from the buffer, returning the number
3070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        of bytes actually read.
3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
3090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t unflatten(const void* buffer);
3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(void dump() const;)
3120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(void validate() const;)
3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(static void UnitTest();)
3140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // expose this to allow for regression test on complex regions
3160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(bool debugSetRuns(const RunType runs[], int count);)
3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
3190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    enum {
3200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kOpCount = kReplace_Op + 1
3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
3220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    enum {
3240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kRectRegionRuns = 6 // need to store a region of a rect [T B L R S S]
3250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
3260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    friend class android::Region;    // needed for marshalling efficiently
3280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void allocateRuns(int count); // allocate space for count runs
3290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    struct RunHead;
3310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkIRect     fBounds;
3330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    RunHead*    fRunHead;
3340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void            freeRuns();
3360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const RunType*  getRuns(RunType tmpStorage[], int* count) const;
3370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool            setRuns(RunType runs[], int count);
3380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int count_runtype_values(int* itop, int* ibot) const;
3400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    static void BuildRectRuns(const SkIRect& bounds,
3420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                              RunType runs[kRectRegionRuns]);
3430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // returns true if runs are just a rect
3440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    static bool ComputeRunBounds(const RunType runs[], int count,
3450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                 SkIRect* bounds);
3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    friend struct RunHead;
3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    friend class Iterator;
3490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    friend class Spanerator;
3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    friend class SkRgnBuilder;
3510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    friend class SkFlatRegion;
3520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
3530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
3560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
357