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