Flutter Engine
The Flutter Engine
Classes | Public Types | Public Member Functions | Static Public Attributes | Friends | List of all members
SkRegion Class Reference

#include <SkRegion.h>

Classes

class  Cliperator
 
class  Iterator
 
struct  RunHead
 
class  Spanerator
 

Public Types

enum  Op {
  kDifference_Op , kIntersect_Op , kUnion_Op , kXOR_Op ,
  kReverseDifference_Op , kReplace_Op , kLastOp = kReplace_Op
}
 
using sk_is_trivially_relocatable = std::true_type
 

Public Member Functions

 SkRegion ()
 
 SkRegion (const SkRegion &region)
 
 SkRegion (const SkIRect &rect)
 
 ~SkRegion ()
 
SkRegionoperator= (const SkRegion &region)
 
bool operator== (const SkRegion &other) const
 
bool operator!= (const SkRegion &other) const
 
bool set (const SkRegion &src)
 
void swap (SkRegion &other)
 
bool isEmpty () const
 
bool isRect () const
 
bool isComplex () const
 
const SkIRectgetBounds () const
 
int computeRegionComplexity () const
 
bool getBoundaryPath (SkPath *path) const
 
bool setEmpty ()
 
bool setRect (const SkIRect &rect)
 
bool setRects (const SkIRect rects[], int count)
 
bool setRegion (const SkRegion &region)
 
bool setPath (const SkPath &path, const SkRegion &clip)
 
bool intersects (const SkIRect &rect) const
 
bool intersects (const SkRegion &other) const
 
bool contains (int32_t x, int32_t y) const
 
bool contains (const SkIRect &other) const
 
bool contains (const SkRegion &other) const
 
bool quickContains (const SkIRect &r) const
 
bool quickReject (const SkIRect &rect) const
 
bool quickReject (const SkRegion &rgn) const
 
void translate (int dx, int dy)
 
void translate (int dx, int dy, SkRegion *dst) const
 
bool op (const SkIRect &rect, Op op)
 
bool op (const SkRegion &rgn, Op op)
 
bool op (const SkIRect &rect, const SkRegion &rgn, Op op)
 
bool op (const SkRegion &rgn, const SkIRect &rect, Op op)
 
bool op (const SkRegion &rgna, const SkRegion &rgnb, Op op)
 
size_t writeToMemory (void *buffer) const
 
size_t readFromMemory (const void *buffer, size_t length)
 

Static Public Attributes

static const int kOpCnt = kLastOp + 1
 

Friends

struct RunHead
 
class Iterator
 
class Spanerator
 
class SkRegionPriv
 
class SkRgnBuilder
 
class SkFlatRegion
 

Detailed Description

SkRegion describes the set of pixels used to clip SkCanvas. SkRegion is compact, efficiently storing a single integer rectangle, or a run length encoded array of rectangles. SkRegion may reduce the current SkCanvas clip, or may be drawn as one or more integer rectangles. SkRegion iterator returns the scan lines or rectangles contained by it, optionally intersecting a bounding rectangle.

Definition at line 30 of file SkRegion.h.

Member Typedef Documentation

◆ sk_is_trivially_relocatable

using SkRegion::sk_is_trivially_relocatable = std::true_type

Definition at line 616 of file SkRegion.h.

Member Enumeration Documentation

◆ Op

Enumerator
kDifference_Op 

target minus operand

kIntersect_Op 

target intersected with operand

kUnion_Op 

target unioned with operand

kXOR_Op 

target exclusive or with operand

kReverseDifference_Op 

operand minus target

kReplace_Op 

replace target with operand

kLastOp 

last operator

Definition at line 366 of file SkRegion.h.

366 {
367 kDifference_Op, //!< target minus operand
368 kIntersect_Op, //!< target intersected with operand
369 kUnion_Op, //!< target unioned with operand
370 kXOR_Op, //!< target exclusive or with operand
371 kReverseDifference_Op, //!< operand minus target
372 kReplace_Op, //!< replace target with operand
373 kLastOp = kReplace_Op, //!< last operator
374 };
@ kReverseDifference_Op
operand minus target
Definition: SkRegion.h:371
@ kUnion_Op
target unioned with operand
Definition: SkRegion.h:369
@ kLastOp
last operator
Definition: SkRegion.h:373
@ 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

Constructor & Destructor Documentation

◆ SkRegion() [1/3]

SkRegion::SkRegion ( )

Constructs an empty SkRegion. SkRegion is set to empty bounds at (0, 0) with zero width and height.

Returns
empty SkRegion

example: https://fiddle.skia.org/c/@Region_empty_constructor

Definition at line 123 of file SkRegion.cpp.

123 {
125 fRunHead = SkRegion_gEmptyRunHeadPtr;
126}
const SkRect fBounds
#define SkRegion_gEmptyRunHeadPtr
Definition: SkRegion.cpp:38
void setEmpty()
Definition: SkRect.h:842

◆ SkRegion() [2/3]

SkRegion::SkRegion ( const SkRegion region)

Constructs a copy of an existing region. Copy constructor makes two regions identical by value. Internally, region and the returned result share pointer values. The underlying SkRect array is copied when modified.

Creating a SkRegion copy is very efficient and never allocates memory. SkRegion are always copied by value from the interface; the underlying shared pointers are not exposed.

Parameters
regionSkRegion to copy by value
Returns
copy of SkRegion

example: https://fiddle.skia.org/c/@Region_copy_const_SkRegion

Definition at line 128 of file SkRegion.cpp.

128 {
129 fRunHead = SkRegion_gEmptyRunHeadPtr; // just need a value that won't trigger sk_free(fRunHead)
130 this->setRegion(src);
131}
bool setRegion(const SkRegion &region)
Definition: SkRegion.cpp:204

◆ SkRegion() [3/3]

SkRegion::SkRegion ( const SkIRect rect)
explicit

Constructs a rectangular SkRegion matching the bounds of rect.

Parameters
rectbounds of constructed SkRegion
Returns
rectangular SkRegion

example: https://fiddle.skia.org/c/@Region_copy_const_SkIRect

Definition at line 133 of file SkRegion.cpp.

133 {
134 fRunHead = SkRegion_gEmptyRunHeadPtr; // just need a value that won't trigger sk_free(fRunHead)
135 this->setRect(rect);
136}
bool setRect(const SkIRect &rect)
Definition: SkRegion.cpp:192

◆ ~SkRegion()

SkRegion::~SkRegion ( )

Releases ownership of any shared data and deletes data if SkRegion is sole owner.

example: https://fiddle.skia.org/c/@Region_destructor

Definition at line 138 of file SkRegion.cpp.

138 {
139 this->freeRuns();
140}

Member Function Documentation

◆ computeRegionComplexity()

int SkRegion::computeRegionComplexity ( ) const

Returns a value that increases with the number of elements in SkRegion. Returns zero if SkRegion is empty. Returns one if SkRegion equals SkIRect; otherwise, returns value greater than one indicating that SkRegion is complex.

Call to compare SkRegion for relative complexity.

Returns
relative complexity

example: https://fiddle.skia.org/c/@Region_computeRegionComplexity

Definition at line 176 of file SkRegion.cpp.

176 {
177 if (this->isEmpty()) {
178 return 0;
179 } else if (this->isRect()) {
180 return 1;
181 }
182 return fRunHead->getIntervalCount();
183}
bool isRect() const
Definition: SkRegion.h:152
bool isEmpty() const
Definition: SkRegion.h:146
int getIntervalCount() const
Definition: SkRegionPriv.h:81

◆ contains() [1/3]

bool SkRegion::contains ( const SkIRect other) const

Returns true if other is completely inside SkRegion. Returns false if SkRegion or other is empty.

Parameters
otherSkIRect to contain
Returns
true if other is inside SkRegion

example: https://fiddle.skia.org/c/@Region_contains_2

Definition at line 422 of file SkRegion.cpp.

422 {
423 SkDEBUGCODE(SkRegionPriv::Validate(*this));
424
425 if (!fBounds.contains(r)) {
426 return false;
427 }
428 if (this->isRect()) {
429 return true;
430 }
431 SkASSERT(this->isComplex());
432
433 const RunType* scanline = fRunHead->findScanline(r.fTop);
434 for (;;) {
435 if (!scanline_contains(scanline, r.fLeft, r.fRight)) {
436 return false;
437 }
438 if (r.fBottom <= scanline_bottom(scanline)) {
439 break;
440 }
441 scanline = scanline_next(scanline);
442 }
443 return true;
444}
#define SkASSERT(cond)
Definition: SkAssert.h:116
static const SkRegionPriv::RunType * scanline_next(const SkRegionPriv::RunType runs[])
Definition: SkRegion.cpp:402
static SkRegionPriv::RunType scanline_bottom(const SkRegionPriv::RunType runs[])
Definition: SkRegion.cpp:398
static bool scanline_contains(const SkRegionPriv::RunType runs[], SkRegionPriv::RunType L, SkRegionPriv::RunType R)
Definition: SkRegion.cpp:407
bool isComplex() const
Definition: SkRegion.h:158
void Validate(const Table &table)
bool contains(SkScalar x, SkScalar y) const
Definition: extension.cpp:19
SkRegion::RunType * findScanline(int y) const
Definition: SkRegionPriv.h:174

◆ contains() [2/3]

bool SkRegion::contains ( const SkRegion other) const

Returns true if other is completely inside SkRegion. Returns false if SkRegion or other is empty.

Parameters
otherSkRegion to contain
Returns
true if other is inside SkRegion

example: https://fiddle.skia.org/c/@Region_contains_3

Definition at line 446 of file SkRegion.cpp.

446 {
447 SkDEBUGCODE(SkRegionPriv::Validate(*this));
448 SkDEBUGCODE(SkRegionPriv::Validate(rgn));
449
450 if (this->isEmpty() || rgn.isEmpty() || !fBounds.contains(rgn.fBounds)) {
451 return false;
452 }
453 if (this->isRect()) {
454 return true;
455 }
456 if (rgn.isRect()) {
457 return this->contains(rgn.getBounds());
458 }
459
460 /*
461 * A contains B is equivalent to
462 * B - A == 0
463 */
464 return !Oper(rgn, *this, kDifference_Op, nullptr);
465}
bool contains(int32_t x, int32_t y) const
Definition: SkRegion.cpp:364

◆ contains() [3/3]

bool SkRegion::contains ( int32_t  x,
int32_t  y 
) const

Returns true if SkIPoint (x, y) is inside SkRegion. Returns false if SkRegion is empty.

Parameters
xtest SkIPoint x-coordinate
ytest SkIPoint y-coordinate
Returns
true if (x, y) is inside SkRegion

example: https://fiddle.skia.org/c/@Region_contains

Definition at line 364 of file SkRegion.cpp.

364 {
365 SkDEBUGCODE(SkRegionPriv::Validate(*this));
366
367 if (!fBounds.contains(x, y)) {
368 return false;
369 }
370 if (this->isRect()) {
371 return true;
372 }
373 SkASSERT(this->isComplex());
374
375 const RunType* runs = fRunHead->findScanline(y);
376
377 // Skip the Bottom and IntervalCount
378 runs += 2;
379
380 // Just walk this scanline, checking each interval. The X-sentinel will
381 // appear as a left-inteval (runs[0]) and should abort the search.
382 //
383 // We could do a bsearch, using interval-count (runs[1]), but need to time
384 // when that would be worthwhile.
385 //
386 for (;;) {
387 if (x < runs[0]) {
388 break;
389 }
390 if (x < runs[1]) {
391 return true;
392 }
393 runs += 2;
394 }
395 return false;
396}
double y
double x

◆ getBoundaryPath()

bool SkRegion::getBoundaryPath ( SkPath path) const

Appends outline of SkRegion to path. Returns true if SkRegion is not empty; otherwise, returns false, and leaves path unmodified.

Parameters
pathSkPath to append to
Returns
true if path changed

example: https://fiddle.skia.org/c/@Region_getBoundaryPath

Definition at line 551 of file SkRegion_path.cpp.

551 {
552 // path could safely be nullptr if we're empty, but the caller shouldn't
553 // *know* that
554 SkASSERT(path);
555
556 if (this->isEmpty()) {
557 return false;
558 }
559
560 const SkIRect& bounds = this->getBounds();
561
562 if (this->isRect()) {
563 SkRect r;
564 r.set(bounds); // this converts the ints to scalars
565 path->addRect(r);
566 return true;
567 }
568
569 SkRegion::Iterator iter(*this);
570 SkTDArray<Edge> edges;
571
572 for (const SkIRect& r = iter.rect(); !iter.done(); iter.next()) {
573 Edge* edge = edges.append(2);
574 edge[0].set(r.fLeft, r.fBottom, r.fTop);
575 edge[1].set(r.fRight, r.fTop, r.fBottom);
576 }
577
578 int count = edges.size();
579 Edge* start = edges.begin();
580 Edge* stop = start + count;
581 SkTQSort<Edge>(start, stop, EdgeLT());
582
583 Edge* e;
584 for (e = start; e != stop; e++) {
585 find_link(e, stop);
586 }
587
588#ifdef SK_DEBUG
589 for (e = start; e != stop; e++) {
590 SkASSERT(e->fNext != nullptr);
591 SkASSERT(e->fFlags == Edge::kCompleteLink);
592 }
593#endif
594
595 path->incReserve(count << 1);
596 do {
597 SkASSERT(count > 1);
598 count -= extract_path(start, stop, path);
599 } while (count > 0);
600
601 return true;
602}
int count
Definition: FontMgrTest.cpp:50
static void find_link(Edge *base, Edge *stop)
static int extract_path(Edge *edge, Edge *stop, SkPath *path)
const SkIRect & getBounds() const
Definition: SkRegion.h:165
int size() const
Definition: SkTDArray.h:138
T * begin()
Definition: SkTDArray.h:150
T * append()
Definition: SkTDArray.h:191
Optional< SkRect > bounds
Definition: SkRecords.h:189
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
void set(int x, int y0, int y1)
@ kCompleteLink
Definition: SkRect.h:32
SkScalar fBottom
larger y-axis bounds
Definition: extension.cpp:17
SkScalar fLeft
smaller x-axis bounds
Definition: extension.cpp:14
SkScalar fRight
larger x-axis bounds
Definition: extension.cpp:16
void set(const SkIRect &src)
Definition: SkRect.h:849
SkScalar fTop
smaller y-axis bounds
Definition: extension.cpp:15

◆ getBounds()

const SkIRect & SkRegion::getBounds ( ) const
inline

Returns minimum and maximum axes values of SkIRect array. Returns (0, 0, 0, 0) if SkRegion is empty.

Returns
combined bounds of all SkIRect elements

Definition at line 165 of file SkRegion.h.

165{ return fBounds; }

◆ intersects() [1/2]

bool SkRegion::intersects ( const SkIRect rect) const

Returns true if SkRegion intersects rect. Returns false if either rect or SkRegion is empty, or do not intersect.

Parameters
rectSkIRect to intersect
Returns
true if rect and SkRegion have area in common

example: https://fiddle.skia.org/c/@Region_intersects

Definition at line 502 of file SkRegion.cpp.

502 {
503 SkDEBUGCODE(SkRegionPriv::Validate(*this));
504
505 if (this->isEmpty() || r.isEmpty()) {
506 return false;
507 }
508
509 SkIRect sect;
510 if (!sect.intersect(fBounds, r)) {
511 return false;
512 }
513 if (this->isRect()) {
514 return true;
515 }
516 SkASSERT(this->isComplex());
517
518 const RunType* scanline = fRunHead->findScanline(sect.fTop);
519 for (;;) {
520 if (scanline_intersects(scanline, sect.fLeft, sect.fRight)) {
521 return true;
522 }
523 if (sect.fBottom <= scanline_bottom(scanline)) {
524 break;
525 }
526 scanline = scanline_next(scanline);
527 }
528 return false;
529}
static bool scanline_intersects(const SkRegionPriv::RunType runs[], SkRegionPriv::RunType L, SkRegionPriv::RunType R)
Definition: SkRegion.cpp:487
bool intersect(const SkIRect &r)
Definition: SkRect.h:513
int32_t fBottom
larger y-axis bounds
Definition: SkRect.h:36
int32_t fTop
smaller y-axis bounds
Definition: SkRect.h:34
int32_t fLeft
smaller x-axis bounds
Definition: SkRect.h:33
int32_t fRight
larger x-axis bounds
Definition: SkRect.h:35

◆ intersects() [2/2]

bool SkRegion::intersects ( const SkRegion other) const

Returns true if SkRegion intersects other. Returns false if either other or SkRegion is empty, or do not intersect.

Parameters
otherSkRegion to intersect
Returns
true if other and SkRegion have area in common

example: https://fiddle.skia.org/c/@Region_intersects_2

Definition at line 531 of file SkRegion.cpp.

531 {
532 if (this->isEmpty() || rgn.isEmpty()) {
533 return false;
534 }
535
536 if (!SkIRect::Intersects(fBounds, rgn.fBounds)) {
537 return false;
538 }
539
540 bool weAreARect = this->isRect();
541 bool theyAreARect = rgn.isRect();
542
543 if (weAreARect && theyAreARect) {
544 return true;
545 }
546 if (weAreARect) {
547 return rgn.intersects(this->getBounds());
548 }
549 if (theyAreARect) {
550 return this->intersects(rgn.getBounds());
551 }
552
553 // both of us are complex
554 return Oper(*this, rgn, kIntersect_Op, nullptr);
555}
bool intersects(const SkIRect &rect) const
Definition: SkRegion.cpp:502
static bool Intersects(const SkIRect &a, const SkIRect &b)
Definition: SkRect.h:535

◆ isComplex()

bool SkRegion::isComplex ( ) const
inline

Returns true if SkRegion is described by more than one rectangle.

Returns
true if SkRegion contains more than one SkIRect

Definition at line 158 of file SkRegion.h.

158{ return !this->isEmpty() && !this->isRect(); }

◆ isEmpty()

bool SkRegion::isEmpty ( ) const
inline

Returns true if SkRegion is empty. Empty SkRegion has bounds width or height less than or equal to zero. SkRegion() constructs empty SkRegion; setEmpty() and setRect() with dimensionless data make SkRegion empty.

Returns
true if bounds has no width or height

Definition at line 146 of file SkRegion.h.

146{ return fRunHead == emptyRunHeadPtr(); }

◆ isRect()

bool SkRegion::isRect ( ) const
inline

Returns true if SkRegion is one SkIRect with positive dimensions.

Returns
true if SkRegion contains one SkIRect

Definition at line 152 of file SkRegion.h.

152{ return fRunHead == kRectRunHeadPtr; }

◆ op() [1/5]

bool SkRegion::op ( const SkIRect rect,
const SkRegion rgn,
Op  op 
)

Replaces SkRegion with the result of rect op rgn. Returns true if replaced SkRegion is not empty.

Parameters
rectSkIRect operand
rgnSkRegion operand
Returns
false if result is empty

example: https://fiddle.skia.org/c/@Region_op_4

Definition at line 217 of file SkRegion.cpp.

217 {
218 SkRegion tmp(rect);
219
220 return this->op(tmp, rgn, op);
221}
bool op(const SkIRect &rect, Op op)
Definition: SkRegion.h:384
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350

◆ op() [2/5]

bool SkRegion::op ( const SkIRect rect,
Op  op 
)
inline

Replaces SkRegion with the result of SkRegion op rect. Returns true if replaced SkRegion is not empty.

Parameters
rectSkIRect operand
Returns
false if result is empty

Definition at line 384 of file SkRegion.h.

384 {
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 }
bool setEmpty()
Definition: SkRegion.cpp:185
bool intersect(const SkRect &r)
Definition: SkRect.cpp:114

◆ op() [3/5]

bool SkRegion::op ( const SkRegion rgn,
const SkIRect rect,
Op  op 
)

Replaces SkRegion with the result of rgn op rect. Returns true if replaced SkRegion is not empty.

Parameters
rgnSkRegion operand
rectSkIRect operand
Returns
false if result is empty

example: https://fiddle.skia.org/c/@Region_op_5

Definition at line 223 of file SkRegion.cpp.

223 {
224 SkRegion tmp(rect);
225
226 return this->op(rgn, tmp, op);
227}

◆ op() [4/5]

bool SkRegion::op ( const SkRegion rgn,
Op  op 
)
inline

Replaces SkRegion with the result of SkRegion op rgn. Returns true if replaced SkRegion is not empty.

Parameters
rgnSkRegion operand
Returns
false if result is empty

Definition at line 400 of file SkRegion.h.

400{ return this->op(*this, rgn, op); }

◆ op() [5/5]

bool SkRegion::op ( const SkRegion rgna,
const SkRegion rgnb,
Op  op 
)

Replaces SkRegion with the result of rgna op rgnb. Returns true if replaced SkRegion is not empty.

Parameters
rgnaSkRegion operand
rgnbSkRegion operand
Returns
false if result is empty

example: https://fiddle.skia.org/c/@Region_op_6

Definition at line 1142 of file SkRegion.cpp.

1142 {
1143 SkDEBUGCODE(SkRegionPriv::Validate(*this));
1144 return SkRegion::Oper(rgna, rgnb, op, this);
1145}

◆ operator!=()

bool SkRegion::operator!= ( const SkRegion other) const
inline

Compares SkRegion and other; returns true if they do not enclose the same area.

Parameters
otherSkRegion to compare
Returns
true if SkRegion pair are not equivalent

Definition at line 105 of file SkRegion.h.

105 {
106 return !(*this == other);
107 }

◆ operator=()

SkRegion & SkRegion::operator= ( const SkRegion region)

Constructs a copy of an existing region. Makes two regions identical by value. Internally, region and the returned result share pointer values. The underlying SkRect array is copied when modified.

Creating a SkRegion copy is very efficient and never allocates memory. SkRegion are always copied by value from the interface; the underlying shared pointers are not exposed.

Parameters
regionSkRegion to copy by value
Returns
SkRegion to copy by value

example: https://fiddle.skia.org/c/@Region_copy_operator

Definition at line 165 of file SkRegion.cpp.

165 {
166 (void)this->setRegion(src);
167 return *this;
168}

◆ operator==()

bool SkRegion::operator== ( const SkRegion other) const

Compares SkRegion and other; returns true if they enclose exactly the same area.

Parameters
otherSkRegion to compare
Returns
true if SkRegion pair are equivalent

example: https://fiddle.skia.org/c/@Region_equal1_operator

Definition at line 559 of file SkRegion.cpp.

559 {
560 SkDEBUGCODE(SkRegionPriv::Validate(*this));
561 SkDEBUGCODE(SkRegionPriv::Validate(b));
562
563 if (this == &b) {
564 return true;
565 }
566 if (fBounds != b.fBounds) {
567 return false;
568 }
569
570 const SkRegion::RunHead* ah = fRunHead;
571 const SkRegion::RunHead* bh = b.fRunHead;
572
573 // this catches empties and rects being equal
574 if (ah == bh) {
575 return true;
576 }
577 // now we insist that both are complex (but different ptrs)
578 if (!this->isComplex() || !b.isComplex()) {
579 return false;
580 }
581 return ah->fRunCount == bh->fRunCount &&
582 !memcmp(ah->readonly_runs(), bh->readonly_runs(),
583 ah->fRunCount * sizeof(SkRegion::RunType));
584}
static bool b
const SkRegion::RunType * readonly_runs() const
Definition: SkRegionPriv.h:121

◆ quickContains()

bool SkRegion::quickContains ( const SkIRect r) const
inline

Returns true if SkRegion is a single rectangle and contains r. May return false even though SkRegion contains r.

Parameters
rSkIRect to contain
Returns
true quickly if r points are equal or inside

Definition at line 310 of file SkRegion.h.

310 {
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 &&
318 }
bool isEmpty() const
Definition: SkRect.h:693

◆ quickReject() [1/2]

bool SkRegion::quickReject ( const SkIRect rect) const
inline

Returns true if SkRegion does not intersect rect. Returns true if rect is empty or SkRegion is empty. May return false even though SkRegion does not intersect rect.

Parameters
rectSkIRect to intersect
Returns
true if rect does not intersect

Definition at line 327 of file SkRegion.h.

327 {
328 return this->isEmpty() || rect.isEmpty() ||
330 }
bool isEmpty() const
Definition: SkRect.h:202

◆ quickReject() [2/2]

bool SkRegion::quickReject ( const SkRegion rgn) const
inline

Returns true if SkRegion does not intersect rgn. Returns true if rgn is empty or SkRegion is empty. May return false even though SkRegion does not intersect rgn.

Parameters
rgnSkRegion to intersect
Returns
true if rgn does not intersect

Definition at line 339 of file SkRegion.h.

339 {
340 return this->isEmpty() || rgn.isEmpty() ||
341 !SkIRect::Intersects(fBounds, rgn.fBounds);
342 }

◆ readFromMemory()

size_t SkRegion::readFromMemory ( const void *  buffer,
size_t  length 
)

Constructs SkRegion from buffer of size length. Returns bytes read. Returned value will be multiple of four or zero if length was too small.

Parameters
bufferstorage for binary data
lengthsize of buffer
Returns
bytes read

example: https://fiddle.skia.org/c/@Region_readFromMemory

Definition at line 1276 of file SkRegion.cpp.

1276 {
1277 SkRBuffer buffer(storage, length);
1278 SkRegion tmp;
1279 int32_t count;
1280
1281 // Serialized Region Format:
1282 // Empty:
1283 // -1
1284 // Simple Rect:
1285 // 0 LEFT TOP RIGHT BOTTOM
1286 // Complex Region:
1287 // COUNT LEFT TOP RIGHT BOTTOM Y_SPAN_COUNT TOTAL_INTERVAL_COUNT [RUNS....]
1288 if (!buffer.readS32(&count) || count < -1) {
1289 return 0;
1290 }
1291 if (count >= 0) {
1292 if (!buffer.read(&tmp.fBounds, sizeof(tmp.fBounds)) || tmp.fBounds.isEmpty()) {
1293 return 0; // Short buffer or bad bounds for non-empty region; report failure.
1294 }
1295 if (count == 0) {
1296 tmp.fRunHead = SkRegion_gRectRunHeadPtr;
1297 } else {
1298 int32_t ySpanCount, intervalCount;
1299 if (!buffer.readS32(&ySpanCount) ||
1300 !buffer.readS32(&intervalCount) ||
1301 buffer.available() < count * sizeof(int32_t)) {
1302 return 0;
1303 }
1304 if (!validate_run((const int32_t*)((const char*)storage + buffer.pos()), count,
1305 tmp.fBounds, ySpanCount, intervalCount)) {
1306 return 0; // invalid runs, don't even allocate
1307 }
1308 tmp.allocateRuns(count, ySpanCount, intervalCount);
1309 SkASSERT(tmp.isComplex());
1310 SkAssertResult(buffer.read(tmp.fRunHead->writable_runs(), count * sizeof(int32_t)));
1311 }
1312 }
1313 SkASSERT(tmp.isValid());
1314 SkASSERT(buffer.isValid());
1315 this->swap(tmp);
1316 return buffer.pos();
1317}
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
static bool validate_run(const int32_t *runs, int runCount, const SkIRect &givenBounds, int32_t ySpanCount, int32_t intervalCount)
Definition: SkRegion.cpp:1200
#define SkRegion_gRectRunHeadPtr
Definition: SkRegion.cpp:39
void swap(SkRegion &other)
Definition: SkRegion.cpp:170
size_t length
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
SkRegion::RunType * writable_runs()
Definition: SkRegionPriv.h:116

◆ set()

bool SkRegion::set ( const SkRegion src)
inline

Sets SkRegion to src, and returns true if src bounds is not empty. This makes SkRegion and src identical by value. Internally, SkRegion and src share pointer values. The underlying SkRect array is copied when modified.

Creating a SkRegion copy is very efficient and never allocates memory. SkRegion are always copied by value from the interface; the underlying shared pointers are not exposed.

Parameters
srcSkRegion to copy
Returns
copy of src

Definition at line 121 of file SkRegion.h.

121 {
122 *this = src;
123 return !this->isEmpty();
124 }

◆ setEmpty()

bool SkRegion::setEmpty ( )

Constructs an empty SkRegion. SkRegion is set to empty bounds at (0, 0) with zero width and height. Always returns false.

Returns
false

example: https://fiddle.skia.org/c/@Region_setEmpty

Definition at line 185 of file SkRegion.cpp.

185 {
186 this->freeRuns();
188 fRunHead = SkRegion_gEmptyRunHeadPtr;
189 return false;
190}

◆ setPath()

bool SkRegion::setPath ( const SkPath path,
const SkRegion clip 
)

Constructs SkRegion to match outline of path within clip. Returns false if constructed SkRegion is empty.

Constructed SkRegion draws the same pixels as path through clip when anti-aliasing is disabled.

Parameters
pathSkPath providing outline
clipSkRegion containing path
Returns
true if constructed SkRegion is not empty

example: https://fiddle.skia.org/c/@Region_setPath

Definition at line 338 of file SkRegion_path.cpp.

338 {
339 SkDEBUGCODE(SkRegionPriv::Validate(*this));
340
341 if (clip.isEmpty() || !path.isFinite() || path.isEmpty()) {
342 // This treats non-finite paths as empty as well, so this returns empty or 'clip' if
343 // it's inverse-filled. If clip is also empty, path's fill type doesn't really matter
344 // and this region ends up empty.
346 }
347
348 // Our builder is very fragile, and can't be called with spans/rects out of Y->X order.
349 // To ensure this, we only "fill" clipped to a rect (the clip's bounds), and if the
350 // clip is more complex than that, we just post-intersect the result with the clip.
351 const SkIRect clipBounds = clip.getBounds();
352 if (clip.isComplex()) {
353 if (!this->setPath(path, SkRegion(clipBounds))) {
354 return false;
355 }
356 return this->op(clip, kIntersect_Op);
357 }
358
359 // SkScan::FillPath has limits on the coordinate range of the clipping SkRegion. If it's too
360 // big, tile the clip bounds and union the pieces back together.
361 if (SkScan::PathRequiresTiling(clipBounds)) {
362 static constexpr int kTileSize = 32767 >> 1; // Limit so coords can fit into SkFixed (16.16)
363 const SkIRect pathBounds = path.getBounds().roundOut();
364
365 this->setEmpty();
366
367 // Note: With large integers some intermediate calculations can overflow, but the
368 // end results will still be in integer range. Using int64_t for the intermediate
369 // values will handle this situation.
370 for (int64_t top = clipBounds.fTop; top < clipBounds.fBottom; top += kTileSize) {
371 int64_t bot = std::min(top + kTileSize, (int64_t)clipBounds.fBottom);
372 for (int64_t left = clipBounds.fLeft; left < clipBounds.fRight; left += kTileSize) {
373 int64_t right = std::min(left + kTileSize, (int64_t)clipBounds.fRight);
374
375 SkIRect tileClipBounds = {(int)left, (int)top, (int)right, (int)bot};
376 if (!SkIRect::Intersects(pathBounds, tileClipBounds)) {
377 continue;
378 }
379
380 // Shift coordinates so the top left is (0,0) during scan conversion and then
381 // translate the SkRegion afterwards.
382 tileClipBounds.offset(-left, -top);
383 SkASSERT(!SkScan::PathRequiresTiling(tileClipBounds));
384 SkRegion tile;
385 tile.setPath(path.makeTransform(SkMatrix::Translate(-left, -top)),
386 SkRegion(tileClipBounds));
387 tile.translate(left, top);
388 this->op(tile, kUnion_Op);
389 }
390 }
391 // During tiling we only applied the bounds of the tile, now that we have a full SkRegion,
392 // apply the original clip.
393 return this->op(clip, kIntersect_Op);
394 }
395
396 // compute worst-case rgn-size for the path
397 int pathTop, pathBot;
398 int pathTransitions = count_path_runtype_values(path, &pathTop, &pathBot);
399 if (0 == pathTransitions) {
401 }
402
403 int clipTop, clipBot;
404 int clipTransitions = clip.count_runtype_values(&clipTop, &clipBot);
405
406 int top = std::max(pathTop, clipTop);
407 int bot = std::min(pathBot, clipBot);
408 if (top >= bot) {
410 }
411
413
414 if (!builder.init(bot - top,
415 std::max(pathTransitions, clipTransitions),
416 path.isInverseFillType())) {
417 // can't allocate working space, so return false
418 return this->setEmpty();
419 }
420
422 builder.done();
423
424 int count = builder.computeRunCount();
425 if (count == 0) {
426 return this->setEmpty();
427 } else if (count == kRectRegionRuns) {
428 builder.copyToRect(&fBounds);
429 this->setRect(fBounds);
430 } else {
431 SkRegion tmp;
432
433 tmp.fRunHead = RunHead::Alloc(count);
434 builder.copyToRgn(tmp.fRunHead->writable_runs());
435 tmp.fRunHead->computeRunBounds(&tmp.fBounds);
436 this->swap(tmp);
437 }
438 SkDEBUGCODE(SkRegionPriv::Validate(*this));
439 return true;
440}
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
static int count_path_runtype_values(const SkPath &path, int *itop, int *ibot)
static bool check_inverse_on_empty_return(SkRegion *dst, const SkPath &path, const SkRegion &clip)
static SkMatrix Translate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.h:91
bool isEmpty() const
Definition: SkPath.cpp:416
const SkRect & getBounds() const
Definition: SkPath.cpp:430
void translate(int dx, int dy)
Definition: SkRegion.h:349
bool setPath(const SkPath &path, const SkRegion &clip)
static bool PathRequiresTiling(const SkIRect &bounds)
static void FillPath(const SkPath &, const SkIRect &, SkBlitter *)
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48
void offset(int32_t dx, int32_t dy)
Definition: SkRect.h:367
static RunHead * Alloc(int count)
Definition: SkRegionPriv.h:85
void computeRunBounds(SkIRect *bounds)
Definition: SkRegionPriv.h:195

◆ setRect()

bool SkRegion::setRect ( const SkIRect rect)

Constructs a rectangular SkRegion matching the bounds of rect. If rect is empty, constructs empty and returns false.

Parameters
rectbounds of constructed SkRegion
Returns
true if rect is not empty

example: https://fiddle.skia.org/c/@Region_setRect

Definition at line 192 of file SkRegion.cpp.

192 {
193 if (r.isEmpty() ||
194 SkRegion_kRunTypeSentinel == r.right() ||
195 SkRegion_kRunTypeSentinel == r.bottom()) {
196 return this->setEmpty();
197 }
198 this->freeRuns();
199 fBounds = r;
200 fRunHead = SkRegion_gRectRunHeadPtr;
201 return true;
202}
static constexpr int SkRegion_kRunTypeSentinel
Definition: SkRegionPriv.h:35

◆ setRects()

bool SkRegion::setRects ( const SkIRect  rects[],
int  count 
)

Constructs SkRegion as the union of SkIRect in rects array. If count is zero, constructs empty SkRegion. Returns false if constructed SkRegion is empty.

May be faster than repeated calls to op().

Parameters
rectsarray of SkIRect
countarray size
Returns
true if constructed SkRegion is not empty

example: https://fiddle.skia.org/c/@Region_setRects

Definition at line 657 of file SkRegion.cpp.

657 {
658 if (0 == count) {
659 this->setEmpty();
660 } else {
661 this->setRect(rects[0]);
662 for (int i = 1; i < count; i++) {
663 this->op(rects[i], kUnion_Op);
664 }
665 }
666 return !this->isEmpty();
667}

◆ setRegion()

bool SkRegion::setRegion ( const SkRegion region)

Constructs a copy of an existing region. Makes two regions identical by value. Internally, region and the returned result share pointer values. The underlying SkRect array is copied when modified.

Creating a SkRegion copy is very efficient and never allocates memory. SkRegion are always copied by value from the interface; the underlying shared pointers are not exposed.

Parameters
regionSkRegion to copy by value
Returns
SkRegion to copy by value

example: https://fiddle.skia.org/c/@Region_setRegion

Definition at line 204 of file SkRegion.cpp.

204 {
205 if (this != &src) {
206 this->freeRuns();
207
208 fBounds = src.fBounds;
209 fRunHead = src.fRunHead;
210 if (this->isComplex()) {
211 fRunHead->fRefCnt++;
212 }
213 }
214 return fRunHead != SkRegion_gEmptyRunHeadPtr;
215}
std::atomic< int32_t > fRefCnt
Definition: SkRegionPriv.h:63

◆ swap()

void SkRegion::swap ( SkRegion other)

Exchanges SkIRect array of SkRegion and other. swap() internally exchanges pointers, so it is lightweight and does not allocate memory.

swap() usage has largely been replaced by operator=(const SkRegion& region). SkPath do not copy their content on assignment until they are written to, making assignment as efficient as swap().

Parameters
otheroperator=(const SkRegion& region) set

example: https://fiddle.skia.org/c/@Region_swap

Definition at line 170 of file SkRegion.cpp.

170 {
171 using std::swap;
172 swap(fBounds, other.fBounds);
173 swap(fRunHead, other.fRunHead);
174}
void swap(sk_sp< T > &a, sk_sp< T > &b)
Definition: SkRefCnt.h:341

◆ translate() [1/2]

void SkRegion::translate ( int  dx,
int  dy 
)
inline

Offsets SkRegion by ivector (dx, dy). Has no effect if SkRegion is empty.

Parameters
dxx-axis offset
dyy-axis offset

Definition at line 349 of file SkRegion.h.

349{ this->translate(dx, dy, this); }
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition: SkRecords.h:208

◆ translate() [2/2]

void SkRegion::translate ( int  dx,
int  dy,
SkRegion dst 
) const

Offsets SkRegion by ivector (dx, dy), writing result to dst. SkRegion may be passed as dst parameter, translating SkRegion in place. Has no effect if dst is nullptr. If SkRegion is empty, sets dst to empty.

Parameters
dxx-axis offset
dyy-axis offset
dsttranslated result

example: https://fiddle.skia.org/c/@Region_translate_2

Definition at line 596 of file SkRegion.cpp.

596 {
597 SkDEBUGCODE(SkRegionPriv::Validate(*this));
598
599 if (nullptr == dst) {
600 return;
601 }
602 if (this->isEmpty()) {
603 dst->setEmpty();
604 return;
605 }
606 // pin dx and dy so we don't overflow our existing bounds
609
610 if (this->isRect()) {
611 dst->setRect(fBounds.makeOffset(dx, dy));
612 } else {
613 if (this == dst) {
614 dst->fRunHead = dst->fRunHead->ensureWritable();
615 } else {
616 SkRegion tmp;
617 tmp.allocateRuns(*fRunHead);
618 SkASSERT(tmp.isComplex());
619 tmp.fBounds = fBounds;
620 dst->swap(tmp);
621 }
622
623 dst->fBounds.offset(dx, dy);
624
625 const RunType* sruns = fRunHead->readonly_runs();
626 RunType* druns = dst->fRunHead->writable_runs();
627
628 *druns++ = (SkRegion::RunType)(*sruns++ + dy); // top
629 for (;;) {
630 int bottom = *sruns++;
631 if (bottom == SkRegion_kRunTypeSentinel) {
632 break;
633 }
634 *druns++ = (SkRegion::RunType)(bottom + dy); // bottom;
635 *druns++ = *sruns++; // copy intervalCount;
636 for (;;) {
637 int x = *sruns++;
639 break;
640 }
641 *druns++ = (SkRegion::RunType)(x + dx);
642 *druns++ = (SkRegion::RunType)(*sruns++ + dx);
643 }
644 *druns++ = SkRegion_kRunTypeSentinel; // x sentinel
645 }
646 *druns++ = SkRegion_kRunTypeSentinel; // y sentinel
647
648 SkASSERT(sruns - fRunHead->readonly_runs() == fRunHead->fRunCount);
649 SkASSERT(druns - dst->fRunHead->readonly_runs() == dst->fRunHead->fRunCount);
650 }
651
652 SkDEBUGCODE(SkRegionPriv::Validate(*this));
653}
static int32_t pin_offset_s32(int32_t min, int32_t max, int32_t offset)
Definition: SkRegion.cpp:587
dst
Definition: cp.py:12
constexpr SkRect makeOffset(float dx, float dy) const
Definition: SkRect.h:965

◆ writeToMemory()

size_t SkRegion::writeToMemory ( void *  buffer) const

Writes SkRegion to buffer, and returns number of bytes written. If buffer is nullptr, returns number number of bytes that would be written.

Parameters
bufferstorage for binary data
Returns
size of SkRegion

example: https://fiddle.skia.org/c/@Region_writeToMemory

Definition at line 1149 of file SkRegion.cpp.

1149 {
1150 if (nullptr == storage) {
1151 size_t size = sizeof(int32_t); // -1 (empty), 0 (rect), runCount
1152 if (!this->isEmpty()) {
1153 size += sizeof(fBounds);
1154 if (this->isComplex()) {
1155 size += 2 * sizeof(int32_t); // ySpanCount + intervalCount
1156 size += fRunHead->fRunCount * sizeof(RunType);
1157 }
1158 }
1159 return size;
1160 }
1161
1162 SkWBuffer buffer(storage);
1163
1164 if (this->isEmpty()) {
1165 buffer.write32(-1);
1166 } else {
1167 bool isRect = this->isRect();
1168
1169 buffer.write32(isRect ? 0 : fRunHead->fRunCount);
1170 buffer.write(&fBounds, sizeof(fBounds));
1171
1172 if (!isRect) {
1173 buffer.write32(fRunHead->getYSpanCount());
1174 buffer.write32(fRunHead->getIntervalCount());
1175 buffer.write(fRunHead->readonly_runs(),
1176 fRunHead->fRunCount * sizeof(RunType));
1177 }
1178 }
1179 return buffer.pos();
1180}
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
int getYSpanCount() const
Definition: SkRegionPriv.h:72

Friends And Related Function Documentation

◆ Iterator

friend class Iterator
friend

Definition at line 677 of file SkRegion.h.

◆ RunHead

friend struct RunHead
friend

Definition at line 676 of file SkRegion.h.

◆ SkFlatRegion

friend class SkFlatRegion
friend

Definition at line 681 of file SkRegion.h.

◆ SkRegionPriv

friend class SkRegionPriv
friend

Definition at line 679 of file SkRegion.h.

◆ SkRgnBuilder

friend class SkRgnBuilder
friend

Definition at line 680 of file SkRegion.h.

◆ Spanerator

friend class Spanerator
friend

Definition at line 678 of file SkRegion.h.

Member Data Documentation

◆ kOpCnt

const int SkRegion::kOpCnt = kLastOp + 1
static

Definition at line 376 of file SkRegion.h.


The documentation for this class was generated from the following files: