Skia
2D Graphics Library
SkRegion.h
Go to the documentation of this file.
1 /*
2  * Copyright 2005 The Android Open Source Project
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkRegion_DEFINED
9 #define SkRegion_DEFINED
10 
11 #include "include/core/SkRect.h"
12 
13 class SkPath;
14 class SkRgnBuilder;
15 
24  typedef int32_t RunType;
25 public:
26 
35 
50  SkRegion(const SkRegion& region);
51 
59  explicit SkRegion(const SkIRect& rect);
60 
66 
81  SkRegion& operator=(const SkRegion& region);
82 
91  bool operator==(const SkRegion& other) const;
92 
98  bool operator!=(const SkRegion& other) const {
99  return !(*this == other);
100  }
101 
114  bool set(const SkRegion& src) {
115  *this = src;
116  return !this->isEmpty();
117  }
118 
130  void swap(SkRegion& other);
131 
139  bool isEmpty() const { return fRunHead == emptyRunHeadPtr(); }
140 
145  bool isRect() const { return fRunHead == kRectRunHeadPtr; }
146 
151  bool isComplex() const { return !this->isEmpty() && !this->isRect(); }
152 
158  const SkIRect& getBounds() const { return fBounds; }
159 
172 
182  bool getBoundaryPath(SkPath* path) const;
183 
191  bool setEmpty();
192 
201  bool setRect(const SkIRect& rect);
202 
214  bool setRects(const SkIRect rects[], int count);
215 
230  bool setRegion(const SkRegion& region);
231 
244  bool setPath(const SkPath& path, const SkRegion& clip);
245 
254  bool intersects(const SkIRect& rect) const;
255 
264  bool intersects(const SkRegion& other) const;
265 
275  bool contains(int32_t x, int32_t y) const;
276 
285  bool contains(const SkIRect& other) const;
286 
295  bool contains(const SkRegion& other) const;
296 
303  bool quickContains(const SkIRect& r) const {
304  SkASSERT(this->isEmpty() == fBounds.isEmpty()); // valid region
305 
306  return r.fLeft < r.fRight && r.fTop < r.fBottom &&
307  fRunHead == kRectRunHeadPtr && // this->isRect()
308  /* fBounds.contains(left, top, right, bottom); */
309  fBounds.fLeft <= r.fLeft && fBounds.fTop <= r.fTop &&
310  fBounds.fRight >= r.fRight && fBounds.fBottom >= r.fBottom;
311  }
312 
320  bool quickReject(const SkIRect& rect) const {
321  return this->isEmpty() || rect.isEmpty() ||
322  !SkIRect::Intersects(fBounds, rect);
323  }
324 
332  bool quickReject(const SkRegion& rgn) const {
333  return this->isEmpty() || rgn.isEmpty() ||
334  !SkIRect::Intersects(fBounds, rgn.fBounds);
335  }
336 
342  void translate(int dx, int dy) { this->translate(dx, dy, this); }
343 
354  void translate(int dx, int dy, SkRegion* dst) const;
355 
359  enum Op {
366  kLastOp = kReplace_Op,
367  };
368 
369  static const int kOpCnt = kLastOp + 1;
370 
377  bool op(const SkIRect& rect, Op op) {
378  if (this->isRect() && kIntersect_Op == op) {
379  if (!fBounds.intersect(rect)) {
380  return this->setEmpty();
381  }
382  return true;
383  }
384  return this->op(*this, rect, op);
385  }
386 
393  bool op(const SkRegion& rgn, Op op) { return this->op(*this, rgn, op); }
394 
404  bool op(const SkIRect& rect, const SkRegion& rgn, Op op);
405 
415  bool op(const SkRegion& rgn, const SkIRect& rect, Op op);
416 
426  bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op);
427 
428 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
429 
433  char* toString();
434 #endif
435 
440  class SK_API Iterator {
441  public:
442 
449  Iterator() : fRgn(nullptr), fDone(true) {}
450 
458  Iterator(const SkRegion& region);
459 
467  bool rewind();
468 
475  void reset(const SkRegion& region);
476 
481  bool done() const { return fDone; }
482 
487  void next();
488 
494  const SkIRect& rect() const { return fRect; }
495 
500  const SkRegion* rgn() const { return fRgn; }
501 
502  private:
503  const SkRegion* fRgn;
504  const SkRegion::RunType* fRuns;
505  SkIRect fRect = {0, 0, 0, 0};
506  bool fDone;
507  };
508 
514  public:
515 
524  Cliperator(const SkRegion& region, const SkIRect& clip);
525 
530  bool done() { return fDone; }
531 
536  void next();
537 
544  const SkIRect& rect() const { return fRect; }
545 
546  private:
547  Iterator fIter;
548  SkIRect fClip;
549  SkIRect fRect = {0, 0, 0, 0};
550  bool fDone;
551  };
552 
556  class Spanerator {
557  public:
558 
569  Spanerator(const SkRegion& region, int y, int left, int right);
570 
580  bool next(int* left, int* right);
581 
582  private:
583  const SkRegion::RunType* fRuns;
584  int fLeft, fRight;
585  bool fDone;
586  };
587 
596  size_t writeToMemory(void* buffer) const;
597 
607  size_t readFromMemory(const void* buffer, size_t length);
608 
609 private:
610  static constexpr int kOpCount = kReplace_Op + 1;
611 
612  // T
613  // [B N L R S]
614  // S
615  static constexpr int kRectRegionRuns = 7;
616 
617  struct RunHead;
618 
619  static RunHead* emptyRunHeadPtr() { return (SkRegion::RunHead*) -1; }
620  static constexpr RunHead* kRectRunHeadPtr = nullptr;
621 
622  // allocate space for count runs
623  void allocateRuns(int count);
624  void allocateRuns(int count, int ySpanCount, int intervalCount);
625  void allocateRuns(const RunHead& src);
626 
627  SkDEBUGCODE(void dump() const;)
628 
629  SkIRect fBounds;
630  RunHead* fRunHead;
631 
632  void freeRuns();
633 
639  const RunType* getRuns(RunType tmpStorage[], int* intervals) const;
640 
641  // This is called with runs[] that do not yet have their interval-count
642  // field set on each scanline. That is computed as part of this call
643  // (inside ComputeRunBounds).
644  bool setRuns(RunType runs[], int count);
645 
646  int count_runtype_values(int* itop, int* ibot) const;
647 
648  bool isValid() const;
649 
650  static void BuildRectRuns(const SkIRect& bounds,
651  RunType runs[kRectRegionRuns]);
652 
653  // If the runs define a simple rect, return true and set bounds to that
654  // rect. If not, return false and ignore bounds.
655  static bool RunsAreARect(const SkRegion::RunType runs[], int count,
656  SkIRect* bounds);
657 
662  static bool Oper(const SkRegion&, const SkRegion&, SkRegion::Op, SkRegion*);
663 
664  friend struct RunHead;
665  friend class Iterator;
666  friend class Spanerator;
667  friend class SkRegionPriv;
668  friend class SkRgnBuilder;
669  friend class SkFlatRegion;
670 };
671 
672 #endif
SkRegion::kIntersect_Op
@ kIntersect_Op
target intersected with operand
Definition: SkRegion.h:361
SkRegion::contains
bool contains(const SkIRect &other) const
Returns true if other is completely inside SkRegion.
SkRegion::setPath
bool setPath(const SkPath &path, const SkRegion &clip)
Constructs SkRegion to match outline of path within clip.
SkRegion::getBounds
const SkIRect & getBounds() const
Returns minimum and maximum axes values of SkIRect array.
Definition: SkRegion.h:158
SkPath
Definition: SkPath.h:44
SkRegion::writeToMemory
size_t writeToMemory(void *buffer) const
Writes SkRegion to buffer, and returns number of bytes written.
SkRegion::Iterator::reset
void reset(const SkRegion &region)
Resets iterator, using the new SkRegion.
SkRegion::contains
bool contains(int32_t x, int32_t y) const
Returns true if SkIPoint (x, y) is inside SkRegion.
SkRegion::Cliperator::next
void next()
Advances iterator to next SkIRect in SkRegion contained by clip.
SkRect.h
SkRegion::translate
void translate(int dx, int dy, SkRegion *dst) const
Offsets SkRegion by ivector (dx, dy), writing result to dst.
SkRegion::op
bool op(const SkRegion &rgn, const SkIRect &rect, Op op)
Replaces SkRegion with the result of rgn op rect.
SkIRect::fLeft
int32_t fLeft
smaller x-axis bounds
Definition: SkRect.h:29
SkRegion::kDifference_Op
@ kDifference_Op
target minus operand
Definition: SkRegion.h:360
SkRegion::quickReject
bool quickReject(const SkIRect &rect) const
Returns true if SkRegion does not intersect rect.
Definition: SkRegion.h:320
SkRegion::kUnion_Op
@ kUnion_Op
target unioned with operand
Definition: SkRegion.h:362
SkRegion::getBoundaryPath
bool getBoundaryPath(SkPath *path) const
Appends outline of SkRegion to path.
SkRegion::Spanerator::Spanerator
Spanerator(const SkRegion &region, int y, int left, int right)
Sets SkRegion::Spanerator to return line segments in SkRegion on scan line.
SkRegion::quickContains
bool quickContains(const SkIRect &r) const
Returns true if SkRegion is a single rectangle and contains r.
Definition: SkRegion.h:303
SkRegion::isRect
bool isRect() const
Returns true if SkRegion is one SkIRect with positive dimensions.
Definition: SkRegion.h:145
SkRegion::SkRegion
SkRegion()
Constructs an empty SkRegion.
SkRegion::Iterator::done
bool done() const
Returns true if SkRegion::Iterator is pointing to final SkIRect in SkRegion.
Definition: SkRegion.h:481
SkRegion
Definition: SkRegion.h:23
SkIRect::fBottom
int32_t fBottom
larger y-axis bounds
Definition: SkRect.h:32
SkRegion::Iterator::Iterator
Iterator(const SkRegion &region)
Sets SkRegion::Iterator to return elements of SkIRect array in region.
SkRegion::operator=
SkRegion & operator=(const SkRegion &region)
Constructs a copy of an existing region.
SkRegion::Iterator::rewind
bool rewind()
SkPoint SkRegion::Iterator to start of SkRegion.
SkIRect::Intersects
static bool Intersects(const SkIRect &a, const SkIRect &b)
Returns true if a intersects b.
Definition: SkRect.h:524
SkDEBUGCODE
#define SkDEBUGCODE(...)
Definition: SkTypes.h:467
SkRegion::Iterator::Iterator
Iterator()
Initializes SkRegion::Iterator with an empty SkRegion.
Definition: SkRegion.h:449
SkRegion::computeRegionComplexity
int computeRegionComplexity() const
Returns a value that increases with the number of elements in SkRegion.
SK_API
#define SK_API
Definition: SkTypes.h:181
SkASSERT
#define SkASSERT(cond)
Definition: SkTypes.h:460
SkRegion::operator==
bool operator==(const SkRegion &other) const
Compares SkRegion and other; returns true if they enclose exactly the same area.
SkRegion::Iterator::next
void next()
Advances SkRegion::Iterator to next SkIRect in SkRegion if it is not done.
SkRegion::readFromMemory
size_t readFromMemory(const void *buffer, size_t length)
Constructs SkRegion from buffer of size length.
SkRegion::operator!=
bool operator!=(const SkRegion &other) const
Compares SkRegion and other; returns true if they do not enclose the same area.
Definition: SkRegion.h:98
SkRegion::set
bool set(const SkRegion &src)
Sets SkRegion to src, and returns true if src bounds is not empty.
Definition: SkRegion.h:114
SkRegion::translate
void translate(int dx, int dy)
Offsets SkRegion by ivector (dx, dy).
Definition: SkRegion.h:342
SkRegion::intersects
bool intersects(const SkRegion &other) const
Returns true if SkRegion intersects other.
SkRegion::Iterator
Definition: SkRegion.h:440
SkRegion::~SkRegion
~SkRegion()
Releases ownership of any shared data and deletes data if SkRegion is sole owner.
SkRegion::Cliperator::rect
const SkIRect & rect() const
Returns SkIRect element in SkRegion, intersected with clip passed to SkRegion::Cliperator constructor...
Definition: SkRegion.h:544
SkRegion::Cliperator
Definition: SkRegion.h:513
SkRegion::quickReject
bool quickReject(const SkRegion &rgn) const
Returns true if SkRegion does not intersect rgn.
Definition: SkRegion.h:332
SkRegion::kXOR_Op
@ kXOR_Op
target exclusive or with operand
Definition: SkRegion.h:363
SkRegion::Cliperator::done
bool done()
Returns true if SkRegion::Cliperator is pointing to final SkIRect in SkRegion.
Definition: SkRegion.h:530
SkRegion::RunHead
friend struct RunHead
Definition: SkRegion.h:664
SkRegion::op
bool op(const SkRegion &rgn, Op op)
Replaces SkRegion with the result of SkRegion op rgn.
Definition: SkRegion.h:393
SkRegion::SkRegion
SkRegion(const SkRegion &region)
Constructs a copy of an existing region.
SkRegion::Cliperator::Cliperator
Cliperator(const SkRegion &region, const SkIRect &clip)
Sets SkRegion::Cliperator to return elements of SkIRect array in SkRegion within clip.
SkRegion::setEmpty
bool setEmpty()
Constructs an empty SkRegion.
SkRegion::Spanerator::next
bool next(int *left, int *right)
Advances iterator to next span intersecting SkRegion within line segment provided in constructor.
SkRegion::setRects
bool setRects(const SkIRect rects[], int count)
Constructs SkRegion as the union of SkIRect in rects array.
SkRegion::Iterator::rgn
const SkRegion * rgn() const
Returns SkRegion if set; otherwise, returns nullptr.
Definition: SkRegion.h:500
SkRegion::op
bool op(const SkIRect &rect, const SkRegion &rgn, Op op)
Replaces SkRegion with the result of rect op rgn.
SkIRect
Definition: SkRect.h:28
SkRegion::intersects
bool intersects(const SkIRect &rect) const
Returns true if SkRegion intersects rect.
SkRegion::kReverseDifference_Op
@ kReverseDifference_Op
operand minus target
Definition: SkRegion.h:364
SkRegion::setRect
bool setRect(const SkIRect &rect)
Constructs a rectangular SkRegion matching the bounds of rect.
SkRegion::Iterator::rect
const SkIRect & rect() const
Returns SkIRect element in SkRegion.
Definition: SkRegion.h:494
SkRegion::op
bool op(const SkRegion &rgna, const SkRegion &rgnb, Op op)
Replaces SkRegion with the result of rgna op rgnb.
SkRegion::kReplace_Op
@ kReplace_Op
replace target with operand
Definition: SkRegion.h:365
SkRegion::isEmpty
bool isEmpty() const
Returns true if SkRegion is empty.
Definition: SkRegion.h:139
SkRegion::contains
bool contains(const SkRegion &other) const
Returns true if other is completely inside SkRegion.
SkRegion::op
bool op(const SkIRect &rect, Op op)
Replaces SkRegion with the result of SkRegion op rect.
Definition: SkRegion.h:377
SkIRect::fRight
int32_t fRight
larger x-axis bounds
Definition: SkRect.h:31
SkRegion::isComplex
bool isComplex() const
Returns true if SkRegion is described by more than one rectangle.
Definition: SkRegion.h:151
SkRegion::Spanerator
Definition: SkRegion.h:556
SkRegion::Op
Op
Definition: SkRegion.h:359
SkIRect::isEmpty
bool isEmpty() const
Returns true if width() or height() are zero or negative.
Definition: SkRect.h:200
SkRegion::SkRegion
SkRegion(const SkIRect &rect)
Constructs a rectangular SkRegion matching the bounds of rect.
SkRegion::setRegion
bool setRegion(const SkRegion &region)
Constructs a copy of an existing region.
SkIRect::fTop
int32_t fTop
smaller y-axis bounds
Definition: SkRect.h:30
SkRegion::swap
void swap(SkRegion &other)
Exchanges SkIRect array of SkRegion and other.