
/*
 * Copyright 2005 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#ifndef SkRegion_DEFINED
#define SkRegion_DEFINED

#include "SkRect.h"

class SkPath;
class SkRgnBuilder;

namespace android {
    class Region;
}

#define SkRegion_gEmptyRunHeadPtr   ((SkRegion::RunHead*)-1)
#define SkRegion_gRectRunHeadPtr    0

/** \class SkRegion

    The SkRegion class encapsulates the geometric region used to specify
    clipping areas for drawing.
*/
class SK_API SkRegion {
public:
    typedef int32_t RunType;
    enum {
        kRunTypeSentinel = 0x7FFFFFFF
    };

    SkRegion();
    SkRegion(const SkRegion&);
    explicit SkRegion(const SkIRect&);
    ~SkRegion();

    SkRegion& operator=(const SkRegion&);

    /**
     *  Return true if the two regions are equal. i.e. The enclose exactly
     *  the same area.
     */
    bool operator==(const SkRegion& other) const;

    /**
     *  Return true if the two regions are not equal.
     */
    bool operator!=(const SkRegion& other) const {
        return !(*this == other);
    }

    /**
     *  Replace this region with the specified region, and return true if the
     *  resulting region is non-empty.
     */
    bool set(const SkRegion& src) {
        SkASSERT(&src);
        *this = src;
        return !this->isEmpty();
    }

    /**
     *  Swap the contents of this and the specified region. This operation
     *  is gauarenteed to never fail.
     */
    void swap(SkRegion&);

    /** Return true if this region is empty */
    bool isEmpty() const { return fRunHead == SkRegion_gEmptyRunHeadPtr; }

    /** Return true if this region is a single, non-empty rectangle */
    bool isRect() const { return fRunHead == SkRegion_gRectRunHeadPtr; }

    /** Return true if this region consists of more than 1 rectangular area */
    bool isComplex() const { return !this->isEmpty() && !this->isRect(); }

    /**
     *  Return the bounds of this region. If the region is empty, returns an
     *  empty rectangle.
     */
    const SkIRect& getBounds() const { return fBounds; }

    /**
     *  Returns a value that grows approximately linearly with the number of
     *  intervals comprised in the region. Empty region will return 0, Rect
     *  will return 1, Complex will return a value > 1.
     *
     *  Use this to compare two regions, where the larger count likely
     *  indicates a more complex region.
     */
    int computeRegionComplexity() const;

    /**
     *  Returns true if the region is non-empty, and if so, appends the
     *  boundary(s) of the region to the specified path.
     *  If the region is empty, returns false, and path is left unmodified.
     */
    bool getBoundaryPath(SkPath* path) const;

    /**
     *  Set the region to be empty, and return false, since the resulting
     *  region is empty
     */
    bool setEmpty();

    /**
     *  If rect is non-empty, set this region to that rectangle and return true,
     *  otherwise set this region to empty and return false.
     */
    bool setRect(const SkIRect&);

    /**
     *  If left < right and top < bottom, set this region to that rectangle and
     *  return true, otherwise set this region to empty and return false.
     */
    bool setRect(int32_t left, int32_t top, int32_t right, int32_t bottom);

    /**
     *  Set this region to the union of an array of rects. This is generally
     *  faster than calling region.op(rect, kUnion_Op) in a loop. If count is
     *  0, then this region is set to the empty region.
     *  @return true if the resulting region is non-empty
     */
    bool setRects(const SkIRect rects[], int count);

    /**
     *  Set this region to the specified region, and return true if it is
     *  non-empty.
     */
    bool setRegion(const SkRegion&);

    /**
     *  Set this region to the area described by the path, clipped.
     *  Return true if the resulting region is non-empty.
     *  This produces a region that is identical to the pixels that would be
     *  drawn by the path (with no antialiasing) with the specified clip.
     */
    bool setPath(const SkPath&, const SkRegion& clip);

    /**
     *  Returns true if the specified rectangle has a non-empty intersection
     *  with this region.
     */
    bool intersects(const SkIRect&) const;

    /**
     *  Returns true if the specified region has a non-empty intersection
     *  with this region.
     */
    bool intersects(const SkRegion&) const;

    /**
     *  Return true if the specified x,y coordinate is inside the region.
     */
    bool contains(int32_t x, int32_t y) const;

    /**
     *  Return true if the specified rectangle is completely inside the region.
     *  This works for simple (rectangular) and complex regions, and always
     *  returns the correct result. Note: if either this region or the rectangle
     *  is empty, contains() returns false.
     */
    bool contains(const SkIRect&) const;

    /**
     *  Return true if the specified region is completely inside the region.
     *  This works for simple (rectangular) and complex regions, and always
     *  returns the correct result. Note: if either region is empty, contains()
     *  returns false.
     */
    bool contains(const SkRegion&) const;

    /**
     *  Return true if this region is a single rectangle (not complex) and the
     *  specified rectangle is contained by this region. Returning false is not
     *  a guarantee that the rectangle is not contained by this region, but
     *  return true is a guarantee that the rectangle is contained by this region.
     */
    bool quickContains(const SkIRect& r) const {
        return this->quickContains(r.fLeft, r.fTop, r.fRight, r.fBottom);
    }

    /**
     *  Return true if this region is a single rectangle (not complex) and the
     *  specified rectangle is contained by this region. Returning false is not
     *  a guarantee that the rectangle is not contained by this region, but
     *  return true is a guarantee that the rectangle is contained by this
     *  region.
     */
    bool quickContains(int32_t left, int32_t top, int32_t right,
                       int32_t bottom) const {
        SkASSERT(this->isEmpty() == fBounds.isEmpty()); // valid region

        return left < right && top < bottom &&
               fRunHead == SkRegion_gRectRunHeadPtr &&  // this->isRect()
               /* fBounds.contains(left, top, right, bottom); */
               fBounds.fLeft <= left && fBounds.fTop <= top &&
               fBounds.fRight >= right && fBounds.fBottom >= bottom;
    }

    /**
     *  Return true if this region is empty, or if the specified rectangle does
     *  not intersect the region. Returning false is not a guarantee that they
     *  intersect, but returning true is a guarantee that they do not.
     */
    bool quickReject(const SkIRect& rect) const {
        return this->isEmpty() || rect.isEmpty() ||
                !SkIRect::Intersects(fBounds, rect);
    }

    /**
     *  Return true if this region, or rgn, is empty, or if their bounds do not
     *  intersect. Returning false is not a guarantee that they intersect, but
     *  returning true is a guarantee that they do not.
     */
    bool quickReject(const SkRegion& rgn) const {
        return this->isEmpty() || rgn.isEmpty() ||
               !SkIRect::Intersects(fBounds, rgn.fBounds);
    }

    /** Translate the region by the specified (dx, dy) amount. */
    void translate(int dx, int dy) { this->translate(dx, dy, this); }

    /**
     *  Translate the region by the specified (dx, dy) amount, writing the
     *  resulting region into dst. Note: it is legal to pass this region as the
     *  dst parameter, effectively translating the region in place. If dst is
     *  null, nothing happens.
     */
    void translate(int dx, int dy, SkRegion* dst) const;

    /**
     *  The logical operations that can be performed when combining two regions.
     */
    enum Op {
        kDifference_Op, //!< subtract the op region from the first region
        kIntersect_Op,  //!< intersect the two regions
        kUnion_Op,      //!< union (inclusive-or) the two regions
        kXOR_Op,        //!< exclusive-or the two regions
        /** subtract the first region from the op region */
        kReverseDifference_Op,
        kReplace_Op,    //!< replace the dst region with the op region

        kLastOp = kReplace_Op
    };

    static const int kOpCnt = kLastOp + 1;

    /**
     *  Set this region to the result of applying the Op to this region and the
     *  specified rectangle: this = (this op rect).
     *  Return true if the resulting region is non-empty.
     */
    bool op(const SkIRect& rect, Op op) { return this->op(*this, rect, op); }

    /**
     *  Set this region to the result of applying the Op to this region and the
     *  specified rectangle: this = (this op rect).
     *  Return true if the resulting region is non-empty.
     */
    bool op(int left, int top, int right, int bottom, Op op) {
        SkIRect rect;
        rect.set(left, top, right, bottom);
        return this->op(*this, rect, op);
    }

    /**
     *  Set this region to the result of applying the Op to this region and the
     *  specified region: this = (this op rgn).
     *  Return true if the resulting region is non-empty.
     */
    bool op(const SkRegion& rgn, Op op) { return this->op(*this, rgn, op); }

    /**
     *  Set this region to the result of applying the Op to the specified
     *  rectangle and region: this = (rect op rgn).
     *  Return true if the resulting region is non-empty.
     */
    bool op(const SkIRect& rect, const SkRegion& rgn, Op);

    /**
     *  Set this region to the result of applying the Op to the specified
     *  region and rectangle: this = (rgn op rect).
     *  Return true if the resulting region is non-empty.
     */
    bool op(const SkRegion& rgn, const SkIRect& rect, Op);

    /**
     *  Set this region to the result of applying the Op to the specified
     *  regions: this = (rgna op rgnb).
     *  Return true if the resulting region is non-empty.
     */
    bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op);

#ifdef SK_BUILD_FOR_ANDROID
    /** Returns a new char* containing the list of rectangles in this region
     */
    char* toString();
#endif

    /**
     *  Returns the sequence of rectangles, sorted in Y and X, that make up
     *  this region.
     */
    class SK_API Iterator {
    public:
        Iterator() : fRgn(NULL), fDone(true) {}
        Iterator(const SkRegion&);
        // if we have a region, reset to it and return true, else return false
        bool rewind();
        // reset the iterator, using the new region
        void reset(const SkRegion&);
        bool done() const { return fDone; }
        void next();
        const SkIRect& rect() const { return fRect; }
        // may return null
        const SkRegion* rgn() const { return fRgn; }

    private:
        const SkRegion* fRgn;
        const RunType*  fRuns;
        SkIRect         fRect;
        bool            fDone;
    };

    /**
     *  Returns the sequence of rectangles, sorted in Y and X, that make up
     *  this region intersected with the specified clip rectangle.
     */
    class SK_API Cliperator {
    public:
        Cliperator(const SkRegion&, const SkIRect& clip);
        bool done() { return fDone; }
        void  next();
        const SkIRect& rect() const { return fRect; }

    private:
        Iterator    fIter;
        SkIRect     fClip;
        SkIRect     fRect;
        bool        fDone;
    };

    /**
     *  Returns the sequence of runs that make up this region for the specified
     *  Y scanline, clipped to the specified left and right X values.
     */
    class Spanerator {
    public:
        Spanerator(const SkRegion&, int y, int left, int right);
        bool next(int* left, int* right);

    private:
        const SkRegion::RunType* fRuns;
        int     fLeft, fRight;
        bool    fDone;
    };

    /**
     *  Write the region to the buffer, and return the number of bytes written.
     *  If buffer is NULL, it still returns the number of bytes.
     */
    size_t writeToMemory(void* buffer) const;
    /**
     * Initializes the region from the buffer
     *
     * @param buffer Memory to read from
     * @param length Amount of memory available in the buffer
     * @return number of bytes read (must be a multiple of 4) or
     *         0 if there was not enough memory available
     */
    size_t readFromMemory(const void* buffer, size_t length);

    /**
     *  Returns a reference to a global empty region. Just a convenience for
     *  callers that need a const empty region.
     */
    static const SkRegion& GetEmptyRegion();

    SkDEBUGCODE(void dump() const;)
    SkDEBUGCODE(void validate() const;)
    SkDEBUGCODE(static void UnitTest();)

    // expose this to allow for regression test on complex regions
    SkDEBUGCODE(bool debugSetRuns(const RunType runs[], int count);)

private:
    enum {
        kOpCount = kReplace_Op + 1
    };

    enum {
        // T
        // [B N L R S]
        // S
        kRectRegionRuns = 7
    };

    friend class android::Region;    // needed for marshalling efficiently

    struct RunHead;

    // allocate space for count runs
    void allocateRuns(int count);
    void allocateRuns(int count, int ySpanCount, int intervalCount);
    void allocateRuns(const RunHead& src);

    SkIRect     fBounds;
    RunHead*    fRunHead;

    void freeRuns();

    /**
     *  Return the runs from this region, consing up fake runs if the region
     *  is empty or a rect. In those 2 cases, we use tmpStorage to hold the
     *  run data.
     */
    const RunType*  getRuns(RunType tmpStorage[], int* intervals) const;

    // This is called with runs[] that do not yet have their interval-count
    // field set on each scanline. That is computed as part of this call
    // (inside ComputeRunBounds).
    bool setRuns(RunType runs[], int count);

    int count_runtype_values(int* itop, int* ibot) const;

    static void BuildRectRuns(const SkIRect& bounds,
                              RunType runs[kRectRegionRuns]);

    // If the runs define a simple rect, return true and set bounds to that
    // rect. If not, return false and ignore bounds.
    static bool RunsAreARect(const SkRegion::RunType runs[], int count,
                             SkIRect* bounds);

    /**
     *  If the last arg is null, just return if the result is non-empty,
     *  else store the result in the last arg.
     */
    static bool Oper(const SkRegion&, const SkRegion&, SkRegion::Op, SkRegion*);

    friend struct RunHead;
    friend class Iterator;
    friend class Spanerator;
    friend class SkRgnBuilder;
    friend class SkFlatRegion;
};

#endif
