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 #include "include/private/base/SkAPI.h"
13 #include "include/private/base/SkAssert.h"
14 #include "include/private/base/SkDebug.h"
15 #include "include/private/base/SkTypeTraits.h"
16 
17 #include <cstddef>
18 #include <cstdint>
19 #include <type_traits>
20 
21 class SkPath;
22 
30 class SK_API SkRegion {
31  typedef int32_t RunType;
32 public:
33 
42 
57  SkRegion(const SkRegion& region);
58 
66  explicit SkRegion(const SkIRect& rect);
67 
73 
88  SkRegion& operator=(const SkRegion& region);
89 
98  bool operator==(const SkRegion& other) const;
99 
105  bool operator!=(const SkRegion& other) const {
106  return !(*this == other);
107  }
108 
121  bool set(const SkRegion& src) {
122  *this = src;
123  return !this->isEmpty();
124  }
125 
137  void swap(SkRegion& other);
138 
146  bool isEmpty() const { return fRunHead == emptyRunHeadPtr(); }
147 
152  bool isRect() const { return fRunHead == kRectRunHeadPtr; }
153 
158  bool isComplex() const { return !this->isEmpty() && !this->isRect(); }
159 
165  const SkIRect& getBounds() const { return fBounds; }
166 
179 
189  bool getBoundaryPath(SkPath* path) const;
190 
198  bool setEmpty();
199 
208  bool setRect(const SkIRect& rect);
209 
221  bool setRects(const SkIRect rects[], int count);
222 
237  bool setRegion(const SkRegion& region);
238 
251  bool setPath(const SkPath& path, const SkRegion& clip);
252 
261  bool intersects(const SkIRect& rect) const;
262 
271  bool intersects(const SkRegion& other) const;
272 
282  bool contains(int32_t x, int32_t y) const;
283 
292  bool contains(const SkIRect& other) const;
293 
302  bool contains(const SkRegion& other) const;
303 
310  bool quickContains(const SkIRect& r) const {
311  SkASSERT(this->isEmpty() == fBounds.isEmpty()); // valid region
312 
313  return r.fLeft < r.fRight && r.fTop < r.fBottom &&
314  fRunHead == kRectRunHeadPtr && // this->isRect()
315  /* fBounds.contains(left, top, right, bottom); */
316  fBounds.fLeft <= r.fLeft && fBounds.fTop <= r.fTop &&
317  fBounds.fRight >= r.fRight && fBounds.fBottom >= r.fBottom;
318  }
319 
327  bool quickReject(const SkIRect& rect) const {
328  return this->isEmpty() || rect.isEmpty() ||
329  !SkIRect::Intersects(fBounds, rect);
330  }
331 
339  bool quickReject(const SkRegion& rgn) const {
340  return this->isEmpty() || rgn.isEmpty() ||
341  !SkIRect::Intersects(fBounds, rgn.fBounds);
342  }
343 
349  void translate(int dx, int dy) { this->translate(dx, dy, this); }
350 
361  void translate(int dx, int dy, SkRegion* dst) const;
362 
366  enum Op {
373  kLastOp = kReplace_Op,
374  };
375 
376  static const int kOpCnt = kLastOp + 1;
377 
384  bool op(const SkIRect& rect, Op op) {
385  if (this->isRect() && kIntersect_Op == op) {
386  if (!fBounds.intersect(rect)) {
387  return this->setEmpty();
388  }
389  return true;
390  }
391  return this->op(*this, rect, op);
392  }
393 
400  bool op(const SkRegion& rgn, Op op) { return this->op(*this, rgn, op); }
401 
411  bool op(const SkIRect& rect, const SkRegion& rgn, Op op);
412 
422  bool op(const SkRegion& rgn, const SkIRect& rect, Op op);
423 
433  bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op);
434 
435 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
440  char* toString();
441 #endif
442 
447  class SK_API Iterator {
448  public:
449 
456  Iterator() : fRgn(nullptr), fDone(true) {}
457 
465  Iterator(const SkRegion& region);
466 
474  bool rewind();
475 
482  void reset(const SkRegion& region);
483 
488  bool done() const { return fDone; }
489 
494  void next();
495 
501  const SkIRect& rect() const { return fRect; }
502 
507  const SkRegion* rgn() const { return fRgn; }
508 
509  private:
510  const SkRegion* fRgn;
511  const SkRegion::RunType* fRuns;
512  SkIRect fRect = {0, 0, 0, 0};
513  bool fDone;
514  };
515 
520  class SK_API Cliperator {
521  public:
522 
531  Cliperator(const SkRegion& region, const SkIRect& clip);
532 
537  bool done() { return fDone; }
538 
543  void next();
544 
551  const SkIRect& rect() const { return fRect; }
552 
553  private:
554  Iterator fIter;
555  SkIRect fClip;
556  SkIRect fRect = {0, 0, 0, 0};
557  bool fDone;
558  };
559 
563  class Spanerator {
564  public:
565 
576  Spanerator(const SkRegion& region, int y, int left, int right);
577 
587  bool next(int* left, int* right);
588 
589  private:
590  const SkRegion::RunType* fRuns;
591  int fLeft, fRight;
592  bool fDone;
593  };
594 
603  size_t writeToMemory(void* buffer) const;
604 
614  size_t readFromMemory(const void* buffer, size_t length);
615 
616  using sk_is_trivially_relocatable = std::true_type;
617 
618 private:
619  static constexpr int kOpCount = kReplace_Op + 1;
620 
621  // T
622  // [B N L R S]
623  // S
624  static constexpr int kRectRegionRuns = 7;
625 
626  struct RunHead;
627 
628  static RunHead* emptyRunHeadPtr() { return (SkRegion::RunHead*) -1; }
629  static constexpr RunHead* kRectRunHeadPtr = nullptr;
630 
631  // allocate space for count runs
632  void allocateRuns(int count);
633  void allocateRuns(int count, int ySpanCount, int intervalCount);
634  void allocateRuns(const RunHead& src);
635 
636  SkDEBUGCODE(void dump() const;)
637 
638  SkIRect fBounds;
639  RunHead* fRunHead;
640 
641  static_assert(::sk_is_trivially_relocatable<decltype(fBounds)>::value);
642  static_assert(::sk_is_trivially_relocatable<decltype(fRunHead)>::value);
643 
644  void freeRuns();
645 
651  const RunType* getRuns(RunType tmpStorage[], int* intervals) const;
652 
653  // This is called with runs[] that do not yet have their interval-count
654  // field set on each scanline. That is computed as part of this call
655  // (inside ComputeRunBounds).
656  bool setRuns(RunType runs[], int count);
657 
658  int count_runtype_values(int* itop, int* ibot) const;
659 
660  bool isValid() const;
661 
662  static void BuildRectRuns(const SkIRect& bounds,
663  RunType runs[kRectRegionRuns]);
664 
665  // If the runs define a simple rect, return true and set bounds to that
666  // rect. If not, return false and ignore bounds.
667  static bool RunsAreARect(const SkRegion::RunType runs[], int count,
668  SkIRect* bounds);
669 
674  static bool Oper(const SkRegion&, const SkRegion&, SkRegion::Op, SkRegion*);
675 
676  friend struct RunHead;
677  friend class Iterator;
678  friend class Spanerator;
679  friend class SkRegionPriv;
680  friend class SkRgnBuilder;
681  friend class SkFlatRegion;
682 };
683 
684 #endif
SkPath contain geometry.
Definition: SkPath.h:58
Returns the sequence of rectangles, sorted along y-axis, then x-axis, that make up SkRegion intersect...
Definition: SkRegion.h:520
const SkIRect & rect() const
Returns SkIRect element in SkRegion, intersected with clip passed to SkRegion::Cliperator constructor...
Definition: SkRegion.h:551
Cliperator(const SkRegion &region, const SkIRect &clip)
Sets SkRegion::Cliperator to return elements of SkIRect array in SkRegion within clip.
bool done()
Returns true if SkRegion::Cliperator is pointing to final SkIRect in SkRegion.
Definition: SkRegion.h:537
void next()
Advances iterator to next SkIRect in SkRegion contained by clip.
Returns sequence of rectangles, sorted along y-axis, then x-axis, that make up SkRegion.
Definition: SkRegion.h:447
bool done() const
Returns true if SkRegion::Iterator is pointing to final SkIRect in SkRegion.
Definition: SkRegion.h:488
const SkRegion * rgn() const
Returns SkRegion if set; otherwise, returns nullptr.
Definition: SkRegion.h:507
bool rewind()
SkPoint SkRegion::Iterator to start of SkRegion.
void reset(const SkRegion &region)
Resets iterator, using the new SkRegion.
const SkIRect & rect() const
Returns SkIRect element in SkRegion.
Definition: SkRegion.h:501
Iterator(const SkRegion &region)
Sets SkRegion::Iterator to return elements of SkIRect array in region.
void next()
Advances SkRegion::Iterator to next SkIRect in SkRegion if it is not done.
Iterator()
Initializes SkRegion::Iterator with an empty SkRegion.
Definition: SkRegion.h:456
Returns the line segment ends within SkRegion that intersect a horizontal line.
Definition: SkRegion.h:563
bool next(int *left, int *right)
Advances iterator to next span intersecting SkRegion within line segment provided in constructor.
Spanerator(const SkRegion &region, int y, int left, int right)
Sets SkRegion::Spanerator to return line segments in SkRegion on scan line.
SkRegion describes the set of pixels used to clip SkCanvas.
Definition: SkRegion.h:30
void translate(int dx, int dy)
Offsets SkRegion by ivector (dx, dy).
Definition: SkRegion.h:349
bool getBoundaryPath(SkPath *path) const
Appends outline of SkRegion to path.
bool op(const SkRegion &rgn, const SkIRect &rect, Op op)
Replaces SkRegion with the result of rgn op rect.
size_t readFromMemory(const void *buffer, size_t length)
Constructs SkRegion from buffer of size length.
~SkRegion()
Releases ownership of any shared data and deletes data if SkRegion is sole owner.
bool set(const SkRegion &src)
Sets SkRegion to src, and returns true if src bounds is not empty.
Definition: SkRegion.h:121
bool setEmpty()
Constructs an empty SkRegion.
bool contains(int32_t x, int32_t y) const
Returns true if SkIPoint (x, y) is inside SkRegion.
bool operator==(const SkRegion &other) const
Compares SkRegion and other; returns true if they enclose exactly the same area.
Op
Definition: SkRegion.h:366
@ kReverseDifference_Op
operand minus target
Definition: SkRegion.h:371
@ kUnion_Op
target unioned with operand
Definition: SkRegion.h:369
@ kReplace_Op
replace target with operand
Definition: SkRegion.h:372
@ kIntersect_Op
target intersected with operand
Definition: SkRegion.h:368
@ kDifference_Op
target minus operand
Definition: SkRegion.h:367
@ kXOR_Op
target exclusive or with operand
Definition: SkRegion.h:370
SkRegion()
Constructs an empty SkRegion.
bool setRects(const SkIRect rects[], int count)
Constructs SkRegion as the union of SkIRect in rects array.
bool op(const SkRegion &rgna, const SkRegion &rgnb, Op op)
Replaces SkRegion with the result of rgna op rgnb.
bool isComplex() const
Returns true if SkRegion is described by more than one rectangle.
Definition: SkRegion.h:158
const SkIRect & getBounds() const
Returns minimum and maximum axes values of SkIRect array.
Definition: SkRegion.h:165
friend struct RunHead
Definition: SkRegion.h:676
int computeRegionComplexity() const
Returns a value that increases with the number of elements in SkRegion.
bool isRect() const
Returns true if SkRegion is one SkIRect with positive dimensions.
Definition: SkRegion.h:152
bool contains(const SkIRect &other) const
Returns true if other is completely inside SkRegion.
void translate(int dx, int dy, SkRegion *dst) const
Offsets SkRegion by ivector (dx, dy), writing result to dst.
bool quickContains(const SkIRect &r) const
Returns true if SkRegion is a single rectangle and contains r.
Definition: SkRegion.h:310
bool op(const SkIRect &rect, Op op)
Replaces SkRegion with the result of SkRegion op rect.
Definition: SkRegion.h:384
bool setRect(const SkIRect &rect)
Constructs a rectangular SkRegion matching the bounds of rect.
bool contains(const SkRegion &other) const
Returns true if other is completely inside SkRegion.
bool quickReject(const SkRegion &rgn) const
Returns true if SkRegion does not intersect rgn.
Definition: SkRegion.h:339
bool intersects(const SkRegion &other) const
Returns true if SkRegion intersects other.
bool isEmpty() const
Returns true if SkRegion is empty.
Definition: SkRegion.h:146
bool setPath(const SkPath &path, const SkRegion &clip)
Constructs SkRegion to match outline of path within clip.
std::true_type sk_is_trivially_relocatable
Definition: SkRegion.h:616
void swap(SkRegion &other)
Exchanges SkIRect array of SkRegion and other.
bool setRegion(const SkRegion &region)
Constructs a copy of an existing region.
SkRegion(const SkIRect &rect)
Constructs a rectangular SkRegion matching the bounds of rect.
bool quickReject(const SkIRect &rect) const
Returns true if SkRegion does not intersect rect.
Definition: SkRegion.h:327
SkRegion(const SkRegion &region)
Constructs a copy of an existing region.
bool operator!=(const SkRegion &other) const
Compares SkRegion and other; returns true if they do not enclose the same area.
Definition: SkRegion.h:105
size_t writeToMemory(void *buffer) const
Writes SkRegion to buffer, and returns number of bytes written.
bool op(const SkRegion &rgn, Op op)
Replaces SkRegion with the result of SkRegion op rgn.
Definition: SkRegion.h:400
bool op(const SkIRect &rect, const SkRegion &rgn, Op op)
Replaces SkRegion with the result of rect op rgn.
bool intersects(const SkIRect &rect) const
Returns true if SkRegion intersects rect.
SkRegion & operator=(const SkRegion &region)
Constructs a copy of an existing region.
SkIRect holds four 32-bit integer coordinates describing the upper and lower bounds of a rectangle.
Definition: SkRect.h:32
static bool Intersects(const SkIRect &a, const SkIRect &b)
Returns true if a intersects b.
Definition: SkRect.h:535
int32_t fBottom
larger y-axis bounds
Definition: SkRect.h:36
int32_t fTop
smaller y-axis bounds
Definition: SkRect.h:34
bool isEmpty() const
Returns true if width() or height() are zero or negative.
Definition: SkRect.h:202
int32_t fLeft
smaller x-axis bounds
Definition: SkRect.h:33
int32_t fRight
larger x-axis bounds
Definition: SkRect.h:35