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