Skia
2DGraphicsLibrary
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SkRegion.h
1 
2 /*
3  * Copyright 2005 The Android Open Source Project
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 
10 #ifndef SkRegion_DEFINED
11 #define SkRegion_DEFINED
12 
13 #include "SkRect.h"
14 
15 class SkPath;
16 class SkRgnBuilder;
17 
18 namespace android {
19  class Region;
20 }
21 
22 #define SkRegion_gEmptyRunHeadPtr ((SkRegion::RunHead*)-1)
23 #define SkRegion_gRectRunHeadPtr 0
24 
30 class SK_API SkRegion {
31 public:
32  typedef int32_t RunType;
33  enum {
34  kRunTypeSentinel = 0x7FFFFFFF
35  };
36 
37  SkRegion();
38  SkRegion(const SkRegion&);
39  explicit SkRegion(const SkIRect&);
40  ~SkRegion();
41 
42  SkRegion& operator=(const SkRegion&);
43 
48  bool operator==(const SkRegion& other) const;
49 
53  bool operator!=(const SkRegion& other) const {
54  return !(*this == other);
55  }
56 
61  bool set(const SkRegion& src) {
62  *this = src;
63  return !this->isEmpty();
64  }
65 
70  void swap(SkRegion&);
71 
73  bool isEmpty() const { return fRunHead == SkRegion_gEmptyRunHeadPtr; }
74 
76  bool isRect() const { return fRunHead == SkRegion_gRectRunHeadPtr; }
77 
79  bool isComplex() const { return !this->isEmpty() && !this->isRect(); }
80 
85  const SkIRect& getBounds() const { return fBounds; }
86 
95  int computeRegionComplexity() const;
96 
102  bool getBoundaryPath(SkPath* path) const;
103 
108  bool setEmpty();
109 
114  bool setRect(const SkIRect&);
115 
120  bool setRect(int32_t left, int32_t top, int32_t right, int32_t bottom);
121 
128  bool setRects(const SkIRect rects[], int count);
129 
134  bool setRegion(const SkRegion&);
135 
142  bool setPath(const SkPath&, const SkRegion& clip);
143 
148  bool intersects(const SkIRect&) const;
149 
154  bool intersects(const SkRegion&) const;
155 
159  bool contains(int32_t x, int32_t y) const;
160 
167  bool contains(const SkIRect&) const;
168 
175  bool contains(const SkRegion&) const;
176 
183  bool quickContains(const SkIRect& r) const {
184  return this->quickContains(r.fLeft, r.fTop, r.fRight, r.fBottom);
185  }
186 
194  bool quickContains(int32_t left, int32_t top, int32_t right,
195  int32_t bottom) const {
196  SkASSERT(this->isEmpty() == fBounds.isEmpty()); // valid region
197 
198  return left < right && top < bottom &&
199  fRunHead == SkRegion_gRectRunHeadPtr && // this->isRect()
200  /* fBounds.contains(left, top, right, bottom); */
201  fBounds.fLeft <= left && fBounds.fTop <= top &&
202  fBounds.fRight >= right && fBounds.fBottom >= bottom;
203  }
204 
210  bool quickReject(const SkIRect& rect) const {
211  return this->isEmpty() || rect.isEmpty() ||
212  !SkIRect::Intersects(fBounds, rect);
213  }
214 
220  bool quickReject(const SkRegion& rgn) const {
221  return this->isEmpty() || rgn.isEmpty() ||
222  !SkIRect::Intersects(fBounds, rgn.fBounds);
223  }
224 
226  void translate(int dx, int dy) { this->translate(dx, dy, this); }
227 
234  void translate(int dx, int dy, SkRegion* dst) const;
235 
239  enum Op {
244 
247 
248  kLastOp = kReplace_Op
249  };
250 
251  static const int kOpCnt = kLastOp + 1;
252 
258  bool op(const SkIRect& rect, Op op) {
259  if (this->isRect() && kIntersect_Op == op) {
260  if (!fBounds.intersect(rect)) {
261  return this->setEmpty();
262  }
263  return true;
264  }
265  return this->op(*this, rect, op);
266  }
267 
273  bool op(int left, int top, int right, int bottom, Op op) {
274  SkIRect rect;
275  rect.set(left, top, right, bottom);
276  return this->op(*this, rect, op);
277  }
278 
284  bool op(const SkRegion& rgn, Op op) { return this->op(*this, rgn, op); }
285 
291  bool op(const SkIRect& rect, const SkRegion& rgn, Op);
292 
298  bool op(const SkRegion& rgn, const SkIRect& rect, Op);
299 
305  bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op);
306 
307 #ifdef SK_BUILD_FOR_ANDROID
308 
310  char* toString();
311 #endif
312 
317  class SK_API Iterator {
318  public:
319  Iterator() : fRgn(NULL), fDone(true) {}
320  Iterator(const SkRegion&);
321  // if we have a region, reset to it and return true, else return false
322  bool rewind();
323  // reset the iterator, using the new region
324  void reset(const SkRegion&);
325  bool done() const { return fDone; }
326  void next();
327  const SkIRect& rect() const { return fRect; }
328  // may return null
329  const SkRegion* rgn() const { return fRgn; }
330 
331  private:
332  const SkRegion* fRgn;
333  const RunType* fRuns;
334  SkIRect fRect;
335  bool fDone;
336  };
337 
342  class SK_API Cliperator {
343  public:
344  Cliperator(const SkRegion&, const SkIRect& clip);
345  bool done() { return fDone; }
346  void next();
347  const SkIRect& rect() const { return fRect; }
348 
349  private:
350  Iterator fIter;
351  SkIRect fClip;
352  SkIRect fRect;
353  bool fDone;
354  };
355 
360  class Spanerator {
361  public:
362  Spanerator(const SkRegion&, int y, int left, int right);
363  bool next(int* left, int* right);
364 
365  private:
366  const SkRegion::RunType* fRuns;
367  int fLeft, fRight;
368  bool fDone;
369  };
370 
375  size_t writeToMemory(void* buffer) const;
384  size_t readFromMemory(const void* buffer, size_t length);
385 
390  static const SkRegion& GetEmptyRegion();
391 
392  SkDEBUGCODE(void dump() const;)
393  SkDEBUGCODE(void validate() const;)
394  SkDEBUGCODE(static void UnitTest();)
395 
396  // expose this to allow for regression test on complex regions
397  SkDEBUGCODE(bool debugSetRuns(const RunType runs[], int count);)
398 
399 private:
400  enum {
401  kOpCount = kReplace_Op + 1
402  };
403 
404  enum {
405  // T
406  // [B N L R S]
407  // S
408  kRectRegionRuns = 7
409  };
410 
411  friend class android::Region; // needed for marshalling efficiently
412 
413  struct RunHead;
414 
415  // allocate space for count runs
416  void allocateRuns(int count);
417  void allocateRuns(int count, int ySpanCount, int intervalCount);
418  void allocateRuns(const RunHead& src);
419 
420  SkIRect fBounds;
421  RunHead* fRunHead;
422 
423  void freeRuns();
424 
430  const RunType* getRuns(RunType tmpStorage[], int* intervals) const;
431 
432  // This is called with runs[] that do not yet have their interval-count
433  // field set on each scanline. That is computed as part of this call
434  // (inside ComputeRunBounds).
435  bool setRuns(RunType runs[], int count);
436 
437  int count_runtype_values(int* itop, int* ibot) const;
438 
439  bool isValid() const;
440 
441  static void BuildRectRuns(const SkIRect& bounds,
442  RunType runs[kRectRegionRuns]);
443 
444  // If the runs define a simple rect, return true and set bounds to that
445  // rect. If not, return false and ignore bounds.
446  static bool RunsAreARect(const SkRegion::RunType runs[], int count,
447  SkIRect* bounds);
448 
453  static bool Oper(const SkRegion&, const SkRegion&, SkRegion::Op, SkRegion*);
454 
455  friend struct RunHead;
456  friend class Iterator;
457  friend class Spanerator;
458  friend class SkRgnBuilder;
459  friend class SkFlatRegion;
460 };
461 
462 #endif
bool quickContains(const SkIRect &r) const
Return true if this region is a single rectangle (not complex) and the specified rectangle is contain...
Definition: SkRegion.h:183
static bool Intersects(const SkIRect &a, const SkIRect &b)
Returns true if a and b are not empty, and they intersect.
Definition: SkRect.h:344
The SkPath class encapsulates compound (multiple contour) geometric paths consisting of straight line...
Definition: SkPath.h:25
bool isRect() const
Return true if this region is a single, non-empty rectangle.
Definition: SkRegion.h:76
bool isEmpty() const
Return true if this region is empty.
Definition: SkRegion.h:73
union (inclusive-or) the two regions
Definition: SkRegion.h:242
Returns the sequence of rectangles, sorted in Y and X, that make up this region intersected with the ...
Definition: SkRegion.h:342
bool set(const SkRegion &src)
Replace this region with the specified region, and return true if the resulting region is non-empty...
Definition: SkRegion.h:61
bool quickReject(const SkRegion &rgn) const
Return true if this region, or rgn, is empty, or if their bounds do not intersect.
Definition: SkRegion.h:220
subtract the op region from the first region
Definition: SkRegion.h:240
bool op(int left, int top, int right, int bottom, Op op)
Set this region to the result of applying the Op to this region and the specified rectangle: this = (...
Definition: SkRegion.h:273
Returns the sequence of runs that make up this region for the specified Y scanline, clipped to the specified left and right X values.
Definition: SkRegion.h:360
Returns the sequence of rectangles, sorted in Y and X, that make up this region.
Definition: SkRegion.h:317
void translate(int dx, int dy)
Translate the region by the specified (dx, dy) amount.
Definition: SkRegion.h:226
exclusive-or the two regions
Definition: SkRegion.h:243
bool quickContains(int32_t left, int32_t top, int32_t right, int32_t bottom) const
Return true if this region is a single rectangle (not complex) and the specified rectangle is contain...
Definition: SkRegion.h:194
bool isEmpty() const
Return true if the rectangle's width or height are <= 0.
Definition: SkRect.h:103
bool isComplex() const
Return true if this region consists of more than 1 rectangular area.
Definition: SkRegion.h:79
const SkIRect & getBounds() const
Return the bounds of this region.
Definition: SkRegion.h:85
bool op(const SkIRect &rect, Op op)
Set this region to the result of applying the Op to this region and the specified rectangle: this = (...
Definition: SkRegion.h:258
The SkRegion class encapsulates the geometric region used to specify clipping areas for drawing...
Definition: SkRegion.h:30
replace the dst region with the op region
Definition: SkRegion.h:246
bool op(const SkRegion &rgn, Op op)
Set this region to the result of applying the Op to this region and the specified region: this = (thi...
Definition: SkRegion.h:284
subtract the first region from the op region
Definition: SkRegion.h:245
intersect the two regions
Definition: SkRegion.h:241
SkIRect holds four 32 bit integer coordinates for a rectangle.
Definition: SkRect.h:20
Op
The logical operations that can be performed when combining two regions.
Definition: SkRegion.h:239
bool quickReject(const SkIRect &rect) const
Return true if this region is empty, or if the specified rectangle does not intersect the region...
Definition: SkRegion.h:210
bool operator!=(const SkRegion &other) const
Return true if the two regions are not equal.
Definition: SkRegion.h:53