aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/corecg/SkRegion.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/corecg/SkRegion.h')
-rw-r--r--include/corecg/SkRegion.h249
1 files changed, 249 insertions, 0 deletions
diff --git a/include/corecg/SkRegion.h b/include/corecg/SkRegion.h
new file mode 100644
index 0000000000..73daa9ce68
--- /dev/null
+++ b/include/corecg/SkRegion.h
@@ -0,0 +1,249 @@
+#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 SkRegion {
+public:
+ typedef int16_t RunType;
+
+ SkRegion();
+ explicit SkRegion(const SkRegion&);
+ explicit SkRegion(const SkRect16&);
+ ~SkRegion();
+
+ SkRegion& operator=(const SkRegion&);
+
+ friend int operator==(const SkRegion& a, const SkRegion& b);
+ friend int operator!=(const SkRegion& a, const SkRegion& b)
+ {
+ return !(a == b);
+ }
+
+ // provide explicitly, so we'll have a java equivalent
+ void set(const SkRegion& src)
+ {
+ SkASSERT(&src);
+ *this = src;
+ }
+ /** 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 SkRect16& getBounds() const { return fBounds; }
+
+ /** Returns true if the region is non-empty, and if so, sets the specified path to the
+ boundary(s) of the region.
+ */
+ bool getBoundaryPath(SkPath* path) const;
+
+ /** Set the region to be empty, and return false */
+ 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 SkRect16&);
+ /** 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(S16CPU left, S16CPU top, S16CPU right, S16CPU bottom);
+ /** 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, optionally clipped (if clip is
+ not nil). 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).
+ */
+ bool setPath(const SkPath&, const SkRegion* clip = nil);
+ /** Return true if the specified x,y coordinate is inside the region.
+ */
+ bool contains(S16CPU x, S16CPU y) 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 SkRect16& r) const
+ {
+ return this->isRect() && fBounds.contains(r);
+ }
+ /** 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(S16CPU left, S16CPU top, S16CPU right, S16CPU bottom) const
+ {
+ return this->isRect() && fBounds.contains(left, top, right, 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 SkRect16& rect) const
+ {
+ return this->isEmpty() || !SkRect16::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() || !SkRect16::Intersects(fBounds, rgn.fBounds);
+ }
+
+ void translate(int dx, int dy)
+ {
+ this->translate(dx, dy, this);
+ }
+ void translate(int dx, int dy, SkRegion* dst) const;
+
+ enum Op {
+ kDifference_Op,
+ kIntersect_Op,
+ kUnion_Op,
+ kXOR_Op,
+
+ kOpCount
+ };
+ /** Set this region to the result of applying the Opereation to this region and the specified
+ rectangle. Return true if the resulting region is non-empty.
+ */
+ bool op(const SkRect16&, Op);
+ // helper for java, so it doesn't have to create a Rect object
+ bool op(S16CPU left, S16CPU top, S16CPU right, S16CPU bottom, Op op)
+ {
+ SkRect16 r;
+ r.set(left, top, right, bottom);
+ return this->op(r, op);
+ }
+ /** Set this region to the result of applying the Opereation to this region and the specified
+ region. 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 Opereation to the specified rectangle and region.
+ Return true if the resulting region is non-empty.
+ */
+ bool op(const SkRect16&, const SkRegion&, Op);
+ /** Set this region to the result of applying the Opereation to the specified regions.
+ Return true if the resulting region is non-empty.
+ */
+ bool op(const SkRegion&, const SkRegion&, Op);
+
+ /** Helper class that returns the sequence of rectangles that make up this region.
+ */
+ class Iterator {
+ public:
+ Iterator();
+ Iterator(const SkRegion&);
+ void reset(const SkRegion&);
+ bool done() { return fDone; }
+ void next();
+ const SkRect16& rect() const { return fRect; }
+
+ private:
+ const RunType* fRuns;
+ SkRect16 fRect;
+ bool fDone;
+ };
+
+ /** Helper class that returns the sequence of rectangles that make up this region,
+ intersected with the clip rectangle.
+ */
+ class Cliperator {
+ public:
+ Cliperator(const SkRegion&, const SkRect16& clip);
+ bool done() { return fDone; }
+ void next();
+ const SkRect16& rect() const { return fRect; }
+
+ private:
+ Iterator fIter;
+ SkRect16 fClip;
+ SkRect16 fRect;
+ bool fDone;
+ };
+
+ /** Helper class that returns the sequence of scanline runs that make up this region.
+ */
+ 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;
+ };
+
+ /** Return the number of bytes need to write this region to a buffer.
+ */
+ size_t computeBufferSize() const;
+ /** Write the region to the buffer, and return the number of bytes written.
+ */
+ size_t writeToBuffer(void* buffer) const;
+ /** Initialized the region from the buffer, returning the number
+ of bytes actually read.
+ */
+ size_t readFromBuffer(const void* buffer);
+
+ SkDEBUGCODE(void dump() const;)
+ SkDEBUGCODE(void validate() const;)
+ SkDEBUGCODE(static void UnitTest();)
+
+private:
+ enum {
+ kRectRegionRuns = 6, // need to store a region of a rect [T B L R S S]
+ kRunTypeSentinel = 0x7FFF
+ };
+
+ friend class android::Region; // needed for marshalling efficiently
+ void allocateRuns(int count); // allocate space for count runs
+
+ struct RunHead;
+
+ SkRect16 fBounds;
+ RunHead* fRunHead;
+
+ void freeRuns();
+ const RunType* getRuns(RunType tmpStorage[], int* count) const;
+ bool setRuns(RunType runs[], int count);
+
+ int count_runtype_values(int* itop, int* ibot) const;
+
+ static void build_rect_runs(const SkRect16& bounds, RunType runs[kRectRegionRuns]);
+ static bool compute_run_bounds(const RunType runs[], int count, SkRect16* bounds);
+
+ friend struct RunHead;
+ friend class Iterator;
+ friend class Spanerator;
+ friend class SkRgnBuilder;
+};
+
+
+#endif
+