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

#include <SkRRect.h>

Public Types

enum  Type {
  kEmpty_Type , kRect_Type , kOval_Type , kSimple_Type ,
  kNinePatch_Type , kComplex_Type , kLastType = kComplex_Type
}
 
enum  Corner { kUpperLeft_Corner , kUpperRight_Corner , kLowerRight_Corner , kLowerLeft_Corner }
 

Public Member Functions

 SkRRect ()=default
 
 SkRRect (const SkRRect &rrect)=default
 
SkRRectoperator= (const SkRRect &rrect)=default
 
Type getType () const
 
Type type () const
 
bool isEmpty () const
 
bool isRect () const
 
bool isOval () const
 
bool isSimple () const
 
bool isNinePatch () const
 
bool isComplex () const
 
SkScalar width () const
 
SkScalar height () const
 
SkVector getSimpleRadii () const
 
void setEmpty ()
 
void setRect (const SkRect &rect)
 
void setOval (const SkRect &oval)
 
void setRectXY (const SkRect &rect, SkScalar xRad, SkScalar yRad)
 
void setNinePatch (const SkRect &rect, SkScalar leftRad, SkScalar topRad, SkScalar rightRad, SkScalar bottomRad)
 
void setRectRadii (const SkRect &rect, const SkVector radii[4])
 
const SkRectrect () const
 
SkVector radii (Corner corner) const
 
const SkRectgetBounds () const
 
void inset (SkScalar dx, SkScalar dy, SkRRect *dst) const
 
void inset (SkScalar dx, SkScalar dy)
 
void outset (SkScalar dx, SkScalar dy, SkRRect *dst) const
 
void outset (SkScalar dx, SkScalar dy)
 
void offset (SkScalar dx, SkScalar dy)
 
SkRRect makeOffset (SkScalar dx, SkScalar dy) const
 
bool contains (const SkRect &rect) const
 
bool isValid () const
 
size_t writeToMemory (void *buffer) const
 
size_t readFromMemory (const void *buffer, size_t length)
 
bool transform (const SkMatrix &matrix, SkRRect *dst) const
 
void dump (bool asHex) const
 
SkString dumpToString (bool asHex) const
 
void dump () const
 
void dumpHex () const
 

Static Public Member Functions

static SkRRect MakeEmpty ()
 
static SkRRect MakeRect (const SkRect &r)
 
static SkRRect MakeOval (const SkRect &oval)
 
static SkRRect MakeRectXY (const SkRect &rect, SkScalar xRad, SkScalar yRad)
 

Static Public Attributes

static constexpr size_t kSizeInMemory = 12 * sizeof(SkScalar)
 

Friends

class SkPath
 
class SkRRectPriv
 
bool operator== (const SkRRect &a, const SkRRect &b)
 
bool operator!= (const SkRRect &a, const SkRRect &b)
 

Detailed Description

SkRRect describes a rounded rectangle with a bounds and a pair of radii for each corner. The bounds and radii can be set so that SkRRect describes: a rectangle with sharp corners; a circle; an oval; or a rectangle with one or more rounded corners.

SkRRect allows implementing CSS properties that describe rounded corners. SkRRect may have up to eight different radii, one for each axis on each of its four corners.

SkRRect may modify the provided parameters when initializing bounds and radii. If either axis radii is zero or less: radii are stored as zero; corner is square. If corner curves overlap, radii are proportionally reduced to fit within bounds.

Definition at line 35 of file SkRRect.h.

Member Enumeration Documentation

◆ Corner

Enumerator
kUpperLeft_Corner 

index of top-left corner radii

kUpperRight_Corner 

index of top-right corner radii

kLowerRight_Corner 

index of bottom-right corner radii

kLowerLeft_Corner 

index of bottom-left corner radii

Definition at line 251 of file SkRRect.h.

251 {
252 kUpperLeft_Corner, //!< index of top-left corner radii
253 kUpperRight_Corner, //!< index of top-right corner radii
254 kLowerRight_Corner, //!< index of bottom-right corner radii
255 kLowerLeft_Corner, //!< index of bottom-left corner radii
256 };
@ kUpperLeft_Corner
index of top-left corner radii
Definition: SkRRect.h:252
@ kLowerRight_Corner
index of bottom-right corner radii
Definition: SkRRect.h:254
@ kUpperRight_Corner
index of top-right corner radii
Definition: SkRRect.h:253
@ kLowerLeft_Corner
index of bottom-left corner radii
Definition: SkRRect.h:255

◆ Type

Enumerator
kEmpty_Type 

zero width or height

kRect_Type 

non-zero width and height, and zeroed radii

kOval_Type 

non-zero width and height filled with radii

kSimple_Type 

non-zero width and height with equal radii

kNinePatch_Type 

non-zero width and height with axis-aligned radii

kComplex_Type 

non-zero width and height with arbitrary radii

kLastType 

largest Type value

Definition at line 66 of file SkRRect.h.

66 {
67 kEmpty_Type, //!< zero width or height
68 kRect_Type, //!< non-zero width and height, and zeroed radii
69 kOval_Type, //!< non-zero width and height filled with radii
70 kSimple_Type, //!< non-zero width and height with equal radii
71 kNinePatch_Type, //!< non-zero width and height with axis-aligned radii
72 kComplex_Type, //!< non-zero width and height with arbitrary radii
73 kLastType = kComplex_Type, //!< largest Type value
74 };
@ kOval_Type
non-zero width and height filled with radii
Definition: SkRRect.h:69
@ kLastType
largest Type value
Definition: SkRRect.h:73
@ kSimple_Type
non-zero width and height with equal radii
Definition: SkRRect.h:70
@ kEmpty_Type
zero width or height
Definition: SkRRect.h:67
@ kNinePatch_Type
non-zero width and height with axis-aligned radii
Definition: SkRRect.h:71
@ kRect_Type
non-zero width and height, and zeroed radii
Definition: SkRRect.h:68
@ kComplex_Type
non-zero width and height with arbitrary radii
Definition: SkRRect.h:72

Constructor & Destructor Documentation

◆ SkRRect() [1/2]

SkRRect::SkRRect ( )
default

Initializes bounds at (0, 0), the origin, with zero width and height. Initializes corner radii to (0, 0), and sets type of kEmpty_Type.

Returns
empty SkRRect

◆ SkRRect() [2/2]

SkRRect::SkRRect ( const SkRRect rrect)
default

Initializes to copy of rrect bounds and corner radii.

Parameters
rrectbounds and corner to copy
Returns
copy of rrect

Member Function Documentation

◆ contains()

bool SkRRect::contains ( const SkRect rect) const

Returns true if rect is inside the bounds and corner radii, and if SkRRect and rect are not empty.

Parameters
rectarea tested for containment
Returns
true if SkRRect contains rect

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

Definition at line 360 of file SkRRect.cpp.

360 {
361 if (!this->getBounds().contains(rect)) {
362 // If 'rect' isn't contained by the RR's bounds then the
363 // RR definitely doesn't contain it
364 return false;
365 }
366
367 if (this->isRect()) {
368 // the prior test was sufficient
369 return true;
370 }
371
372 // At this point we know all four corners of 'rect' are inside the
373 // bounds of of this RR. Check to make sure all the corners are inside
374 // all the curves
375 return this->checkCornerContainment(rect.fLeft, rect.fTop) &&
376 this->checkCornerContainment(rect.fRight, rect.fTop) &&
377 this->checkCornerContainment(rect.fRight, rect.fBottom) &&
378 this->checkCornerContainment(rect.fLeft, rect.fBottom);
379}
const SkRect & rect() const
Definition: SkRRect.h:264
bool isRect() const
Definition: SkRRect.h:84
bool contains(const SkRect &rect) const
Definition: SkRRect.cpp:360
const SkRect & getBounds() const
Definition: SkRRect.h:279
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
SkScalar fTop
smaller y-axis bounds
Definition: extension.cpp:15

◆ dump() [1/2]

void SkRRect::dump ( ) const
inline

Writes text representation of SkRRect to standard output. The representation may be directly compiled as C++ code. Floating point values are written with limited precision; it may not be possible to reconstruct original SkRRect from output.

Definition at line 476 of file SkRRect.h.

476{ this->dump(false); }
void dump() const
Definition: SkRRect.h:476

◆ dump() [2/2]

void SkRRect::dump ( bool  asHex) const

Writes text representation of SkRRect to standard output. Set asHex true to generate exact binary representations of floating point numbers.

Parameters
asHextrue if SkScalar values are written as hexadecimal

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

Definition at line 651 of file SkRRect.cpp.

651{ SkDebugf("%s\n", this->dumpToString(asHex).c_str()); }
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
SkString dumpToString(bool asHex) const
Definition: SkRRect.cpp:632

◆ dumpHex()

void SkRRect::dumpHex ( ) const
inline

Writes text representation of SkRRect to standard output. The representation may be directly compiled as C++ code. Floating point values are written in hexadecimal to preserve their exact bit pattern. The output reconstructs the original SkRRect.

Definition at line 483 of file SkRRect.h.

483{ this->dump(true); }

◆ dumpToString()

SkString SkRRect::dumpToString ( bool  asHex) const

Definition at line 632 of file SkRRect.cpp.

632 {
634
635 fRect.dump(asHex);
636 SkString line("const SkPoint corners[] = {\n");
637 for (int i = 0; i < 4; ++i) {
638 SkString strX, strY;
639 SkAppendScalar(&strX, fRadii[i].x(), asType);
640 SkAppendScalar(&strY, fRadii[i].y(), asType);
641 line.appendf(" { %s, %s },", strX.c_str(), strY.c_str());
642 if (asHex) {
643 line.appendf(" /* %f %f */", fRadii[i].x(), fRadii[i].y());
644 }
645 line.append("\n");
646 }
647 line.append("};");
648 return line;
649}
void SkAppendScalar(SkString *str, SkScalar value, SkScalarAsStringType asType)
SkScalarAsStringType
Definition: SkStringUtils.h:18
@ kHex_SkScalarAsStringType
Definition: SkStringUtils.h:20
@ kDec_SkScalarAsStringType
Definition: SkStringUtils.h:19
const char * c_str() const
Definition: SkString.h:133
double y
double x
void dump(bool asHex) const
Definition: SkRect.cpp:152

◆ getBounds()

const SkRect & SkRRect::getBounds ( ) const
inline

Returns bounds. Bounds may have zero width or zero height. Bounds right is greater than or equal to left; bounds bottom is greater than or equal to top. Result is identical to rect().

Returns
bounding box

Definition at line 279 of file SkRRect.h.

279{ return fRect; }

◆ getSimpleRadii()

SkVector SkRRect::getSimpleRadii ( ) const
inline

Returns top-left corner radii. If type() returns kEmpty_Type, kRect_Type, kOval_Type, or kSimple_Type, returns a value representative of all corner radii. If type() returns kNinePatch_Type or kComplex_Type, at least one of the remaining three corners has a different value.

Returns
corner radii for simple types

Definition at line 111 of file SkRRect.h.

111 {
112 return fRadii[0];
113 }

◆ getType()

Type SkRRect::getType ( ) const
inline

Definition at line 76 of file SkRRect.h.

76 {
77 SkASSERT(this->isValid());
78 return static_cast<Type>(fType);
79 }
#define SkASSERT(cond)
Definition: SkAssert.h:116
bool isValid() const
Definition: SkRRect.cpp:663

◆ height()

SkScalar SkRRect::height ( ) const
inline

Returns span on the y-axis. This does not check if result fits in 32-bit float; result may be infinity.

Returns
rect().fBottom minus rect().fTop

Definition at line 102 of file SkRRect.h.

102{ return fRect.height(); }
constexpr float height() const
Definition: SkRect.h:769

◆ inset() [1/2]

void SkRRect::inset ( SkScalar  dx,
SkScalar  dy 
)
inline

Insets bounds by dx and dy, and adjusts radii by dx and dy. dx and dy may be positive, negative, or zero.

If either corner radius is zero, the corner has no curvature and is unchanged. Otherwise, if adjusted radius becomes negative, pins radius to zero. If dx exceeds half bounds width, bounds left and right are set to bounds x-axis center. If dy exceeds half bounds height, bounds top and bottom are set to bounds y-axis center.

If dx or dy cause the bounds to become infinite, bounds is zeroed.

Parameters
dxadded to rect().fLeft, and subtracted from rect().fRight
dyadded to rect().fTop, and subtracted from rect().fBottom

Definition at line 341 of file SkRRect.h.

341 {
342 this->inset(dx, dy, this);
343 }
void inset(SkScalar dx, SkScalar dy, SkRRect *dst) const
Definition: SkRRect.cpp:562
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition: SkRecords.h:208

◆ inset() [2/2]

void SkRRect::inset ( SkScalar  dx,
SkScalar  dy,
SkRRect dst 
) const

Copies SkRRect to dst, then insets dst bounds by dx and dy, and adjusts dst radii by dx and dy. dx and dy may be positive, negative, or zero. dst may be SkRRect.

If either corner radius is zero, the corner has no curvature and is unchanged. Otherwise, if adjusted radius becomes negative, pins radius to zero. If dx exceeds half dst bounds width, dst bounds left and right are set to bounds x-axis center. If dy exceeds half dst bounds height, dst bounds top and bottom are set to bounds y-axis center.

If dx or dy cause the bounds to become infinite, dst bounds is zeroed.

Parameters
dxadded to rect().fLeft, and subtracted from rect().fRight
dyadded to rect().fTop, and subtracted from rect().fBottom
dstinsets bounds and radii

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

Definition at line 562 of file SkRRect.cpp.

562 {
563 SkRect r = fRect.makeInset(dx, dy);
564 bool degenerate = false;
565 if (r.fRight <= r.fLeft) {
566 degenerate = true;
567 r.fLeft = r.fRight = SkScalarAve(r.fLeft, r.fRight);
568 }
569 if (r.fBottom <= r.fTop) {
570 degenerate = true;
571 r.fTop = r.fBottom = SkScalarAve(r.fTop, r.fBottom);
572 }
573 if (degenerate) {
574 dst->fRect = r;
575 memset(dst->fRadii, 0, sizeof(dst->fRadii));
576 dst->fType = kEmpty_Type;
577 return;
578 }
579 if (!r.isFinite()) {
580 *dst = SkRRect();
581 return;
582 }
583
584 SkVector radii[4];
585 memcpy(radii, fRadii, sizeof(radii));
586 for (int i = 0; i < 4; ++i) {
587 if (radii[i].fX) {
588 radii[i].fX -= dx;
589 }
590 if (radii[i].fY) {
591 radii[i].fY -= dy;
592 }
593 }
594 dst->setRectRadii(r, radii);
595}
#define SkScalarAve(a, b)
Definition: SkScalar.h:74
SkVector radii(Corner corner) const
Definition: SkRRect.h:271
SkRRect()=default
dst
Definition: cp.py:12
float fX
x-axis value
Definition: SkPoint_impl.h:164
float fY
y-axis value
Definition: SkPoint_impl.h:165
bool isFinite() const
Definition: SkRect.h:711
SkRect makeInset(float dx, float dy) const
Definition: SkRect.h:987

◆ isComplex()

bool SkRRect::isComplex ( ) const
inline

Definition at line 88 of file SkRRect.h.

88{ return kComplex_Type == this->getType(); }
Type getType() const
Definition: SkRRect.h:76

◆ isEmpty()

bool SkRRect::isEmpty ( ) const
inline

Definition at line 83 of file SkRRect.h.

83{ return kEmpty_Type == this->getType(); }

◆ isNinePatch()

bool SkRRect::isNinePatch ( ) const
inline

Definition at line 87 of file SkRRect.h.

87{ return kNinePatch_Type == this->getType(); }

◆ isOval()

bool SkRRect::isOval ( ) const
inline

Definition at line 85 of file SkRRect.h.

85{ return kOval_Type == this->getType(); }

◆ isRect()

bool SkRRect::isRect ( ) const
inline

Definition at line 84 of file SkRRect.h.

84{ return kRect_Type == this->getType(); }

◆ isSimple()

bool SkRRect::isSimple ( ) const
inline

Definition at line 86 of file SkRRect.h.

86{ return kSimple_Type == this->getType(); }

◆ isValid()

bool SkRRect::isValid ( ) const

Returns true if bounds and radii values are finite and describe a SkRRect SkRRect::Type that matches getType(). All SkRRect methods construct valid types, even if the input values are not valid. Invalid SkRRect data can only be generated by corrupting memory.

Returns
true if bounds and radii match type()

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

Definition at line 663 of file SkRRect.cpp.

663 {
664 if (!AreRectAndRadiiValid(fRect, fRadii)) {
665 return false;
666 }
667
668 bool allRadiiZero = (0 == fRadii[0].fX && 0 == fRadii[0].fY);
669 bool allCornersSquare = (0 == fRadii[0].fX || 0 == fRadii[0].fY);
670 bool allRadiiSame = true;
671
672 for (int i = 1; i < 4; ++i) {
673 if (0 != fRadii[i].fX || 0 != fRadii[i].fY) {
674 allRadiiZero = false;
675 }
676
677 if (fRadii[i].fX != fRadii[i-1].fX || fRadii[i].fY != fRadii[i-1].fY) {
678 allRadiiSame = false;
679 }
680
681 if (0 != fRadii[i].fX && 0 != fRadii[i].fY) {
682 allCornersSquare = false;
683 }
684 }
685 bool patchesOfNine = radii_are_nine_patch(fRadii);
686
687 if (fType < 0 || fType > kLastType) {
688 return false;
689 }
690
691 switch (fType) {
692 case kEmpty_Type:
693 if (!fRect.isEmpty() || !allRadiiZero || !allRadiiSame || !allCornersSquare) {
694 return false;
695 }
696 break;
697 case kRect_Type:
698 if (fRect.isEmpty() || !allRadiiZero || !allRadiiSame || !allCornersSquare) {
699 return false;
700 }
701 break;
702 case kOval_Type:
703 if (fRect.isEmpty() || allRadiiZero || !allRadiiSame || allCornersSquare) {
704 return false;
705 }
706
707 for (int i = 0; i < 4; ++i) {
708 if (!SkScalarNearlyEqual(fRadii[i].fX, SkRectPriv::HalfWidth(fRect)) ||
709 !SkScalarNearlyEqual(fRadii[i].fY, SkRectPriv::HalfHeight(fRect))) {
710 return false;
711 }
712 }
713 break;
714 case kSimple_Type:
715 if (fRect.isEmpty() || allRadiiZero || !allRadiiSame || allCornersSquare) {
716 return false;
717 }
718 break;
719 case kNinePatch_Type:
720 if (fRect.isEmpty() || allRadiiZero || allRadiiSame || allCornersSquare ||
721 !patchesOfNine) {
722 return false;
723 }
724 break;
725 case kComplex_Type:
726 if (fRect.isEmpty() || allRadiiZero || allRadiiSame || allCornersSquare ||
727 patchesOfNine) {
728 return false;
729 }
730 break;
731 }
732
733 return true;
734}
static bool radii_are_nine_patch(const SkVector radii[4])
Definition: SkRRect.cpp:108
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition: SkScalar.h:107
static constexpr float HalfWidth(const SkRect &r)
Definition: SkRectPriv.h:62
static constexpr float HalfHeight(const SkRect &r)
Definition: SkRectPriv.h:66
bool isEmpty() const
Definition: SkRect.h:693

◆ MakeEmpty()

static SkRRect SkRRect::MakeEmpty ( )
inlinestatic

Initializes bounds at (0, 0), the origin, with zero width and height. Initializes corner radii to (0, 0), and sets type of kEmpty_Type.

Returns
empty SkRRect

Definition at line 142 of file SkRRect.h.

142{ return SkRRect(); }

◆ makeOffset()

SkRRect SkRRect::makeOffset ( SkScalar  dx,
SkScalar  dy 
) const
inline

Returns SkRRect translated by (dx, dy).

Parameters
dxoffset added to rect().fLeft and rect().fRight
dyoffset added to rect().fTop and rect().fBottom
Returns
SkRRect bounds offset by (dx, dy), with unchanged corner radii

Definition at line 397 of file SkRRect.h.

397 {
398 return SkRRect(fRect.makeOffset(dx, dy), fRadii, fType);
399 }
constexpr SkRect makeOffset(float dx, float dy) const
Definition: SkRect.h:965

◆ MakeOval()

static SkRRect SkRRect::MakeOval ( const SkRect oval)
inlinestatic

Sets bounds to oval, x-axis radii to half oval.width(), and all y-axis radii to half oval.height(). If oval bounds is empty, sets to kEmpty_Type. Otherwise, sets to kOval_Type.

Parameters
ovalbounds of oval
Returns
oval

Definition at line 162 of file SkRRect.h.

162 {
163 SkRRect rr;
164 rr.setOval(oval);
165 return rr;
166 }
void setOval(const SkRect &oval)
Definition: SkRRect.cpp:30
SkRect oval
Definition: SkRecords.h:249

◆ MakeRect()

static SkRRect SkRRect::MakeRect ( const SkRect r)
inlinestatic

Initializes to copy of r bounds and zeroes corner radii.

Parameters
rbounds to copy
Returns
copy of r

Definition at line 149 of file SkRRect.h.

149 {
150 SkRRect rr;
151 rr.setRect(r);
152 return rr;
153 }
void setRect(const SkRect &rect)
Definition: SkRRect.h:126

◆ MakeRectXY()

static SkRRect SkRRect::MakeRectXY ( const SkRect rect,
SkScalar  xRad,
SkScalar  yRad 
)
inlinestatic

Sets to rounded rectangle with the same radii for all four corners. If rect is empty, sets to kEmpty_Type. Otherwise, if xRad and yRad are zero, sets to kRect_Type. Otherwise, if xRad is at least half rect.width() and yRad is at least half rect.height(), sets to kOval_Type. Otherwise, sets to kSimple_Type.

Parameters
rectbounds of rounded rectangle
xRadx-axis radius of corners
yRady-axis radius of corners
Returns
rounded rectangle

Definition at line 180 of file SkRRect.h.

180 {
181 SkRRect rr;
182 rr.setRectXY(rect, xRad, yRad);
183 return rr;
184 }
void setRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition: SkRRect.cpp:52

◆ offset()

void SkRRect::offset ( SkScalar  dx,
SkScalar  dy 
)
inline

Translates SkRRect by (dx, dy).

Parameters
dxoffset added to rect().fLeft and rect().fRight
dyoffset added to rect().fTop and rect().fBottom

Definition at line 387 of file SkRRect.h.

387 {
388 fRect.offset(dx, dy);
389 }
void offset(float dx, float dy)
Definition: SkRect.h:1016

◆ operator=()

SkRRect & SkRRect::operator= ( const SkRRect rrect)
default

Copies rrect bounds and corner radii.

Parameters
rrectbounds and corner to copy
Returns
copy of rrect

◆ outset() [1/2]

void SkRRect::outset ( SkScalar  dx,
SkScalar  dy 
)
inline

Outsets bounds by dx and dy, and adjusts radii by dx and dy. dx and dy may be positive, negative, or zero.

If either corner radius is zero, the corner has no curvature and is unchanged. Otherwise, if adjusted radius becomes negative, pins radius to zero. If dx exceeds half bounds width, bounds left and right are set to bounds x-axis center. If dy exceeds half bounds height, bounds top and bottom are set to bounds y-axis center.

If dx or dy cause the bounds to become infinite, bounds is zeroed.

Parameters
dxsubtracted from rect().fLeft, and added to rect().fRight
dysubtracted from rect().fTop, and added to rect().fBottom

Definition at line 378 of file SkRRect.h.

378 {
379 this->inset(-dx, -dy, this);
380 }

◆ outset() [2/2]

void SkRRect::outset ( SkScalar  dx,
SkScalar  dy,
SkRRect dst 
) const
inline

Outsets dst bounds by dx and dy, and adjusts radii by dx and dy. dx and dy may be positive, negative, or zero.

If either corner radius is zero, the corner has no curvature and is unchanged. Otherwise, if adjusted radius becomes negative, pins radius to zero. If dx exceeds half dst bounds width, dst bounds left and right are set to bounds x-axis center. If dy exceeds half dst bounds height, dst bounds top and bottom are set to bounds y-axis center.

If dx or dy cause the bounds to become infinite, dst bounds is zeroed.

Parameters
dxsubtracted from rect().fLeft, and added to rect().fRight
dysubtracted from rect().fTop, and added to rect().fBottom
dstoutset bounds and radii

Definition at line 360 of file SkRRect.h.

360 {
361 this->inset(-dx, -dy, dst);
362 }

◆ radii()

SkVector SkRRect::radii ( Corner  corner) const
inline

Returns scalar pair for radius of curve on x-axis and y-axis for one corner. Both radii may be zero. If not zero, both are positive and finite.

Returns
x-axis and y-axis radii for one corner

Definition at line 271 of file SkRRect.h.

271{ return fRadii[corner]; }

◆ readFromMemory()

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

Reads SkRRect from buffer, reading kSizeInMemory bytes. Returns kSizeInMemory, bytes read if length is at least kSizeInMemory. Otherwise, returns zero.

Parameters
buffermemory to read from
lengthsize of buffer
Returns
bytes read, or 0 if length is less than kSizeInMemory

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

Definition at line 610 of file SkRRect.cpp.

610 {
611 if (length < kSizeInMemory) {
612 return 0;
613 }
614
615 // The extra (void*) tells GCC not to worry that kSizeInMemory < sizeof(SkRRect).
616
617 SkRRect raw;
618 memcpy((void*)&raw, buffer, kSizeInMemory);
619 this->setRectRadii(raw.fRect, raw.fRadii);
620 return kSizeInMemory;
621}
void setRectRadii(const SkRect &rect, const SkVector radii[4])
Definition: SkRRect.cpp:189
static constexpr size_t kSizeInMemory
Definition: SkRRect.h:422
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

◆ rect()

const SkRect & SkRRect::rect ( ) const
inline

Returns bounds. Bounds may have zero width or zero height. Bounds right is greater than or equal to left; bounds bottom is greater than or equal to top. Result is identical to getBounds().

Returns
bounding box

Definition at line 264 of file SkRRect.h.

264{ return fRect; }

◆ setEmpty()

void SkRRect::setEmpty ( )
inline

Sets bounds to zero width and height at (0, 0), the origin. Sets corner radii to zero and sets type to kEmpty_Type.

Definition at line 118 of file SkRRect.h.

118{ *this = SkRRect(); }

◆ setNinePatch()

void SkRRect::setNinePatch ( const SkRect rect,
SkScalar  leftRad,
SkScalar  topRad,
SkScalar  rightRad,
SkScalar  bottomRad 
)

Sets bounds to rect. Sets radii to (leftRad, topRad), (rightRad, topRad), (rightRad, bottomRad), (leftRad, bottomRad).

If rect is empty, sets to kEmpty_Type. Otherwise, if leftRad and rightRad are zero, sets to kRect_Type. Otherwise, if topRad and bottomRad are zero, sets to kRect_Type. Otherwise, if leftRad and rightRad are equal and at least half rect.width(), and topRad and bottomRad are equal at least half rect.height(), sets to kOval_Type. Otherwise, if leftRad and rightRad are equal, and topRad and bottomRad are equal, sets to kSimple_Type. Otherwise, sets to kNinePatch_Type.

Nine patch refers to the nine parts defined by the radii: one center rectangle, four edge patches, and four corner patches.

Parameters
rectbounds of rounded rectangle
leftRadleft-top and left-bottom x-axis radius
topRadleft-top and right-top y-axis radius
rightRadright-top and right-bottom x-axis radius
bottomRadleft-bottom and right-bottom y-axis radius

Definition at line 115 of file SkRRect.cpp.

116 {
117 if (!this->initializeRect(rect)) {
118 return;
119 }
120
121 if (!SkIsFinite(leftRad, topRad, rightRad, bottomRad)) {
122 this->setRect(rect); // devolve into a simple rect
123 return;
124 }
125
126 leftRad = std::max(leftRad, 0.0f);
127 topRad = std::max(topRad, 0.0f);
128 rightRad = std::max(rightRad, 0.0f);
129 bottomRad = std::max(bottomRad, 0.0f);
130
132 if (leftRad + rightRad > fRect.width()) {
133 scale = fRect.width() / (leftRad + rightRad);
134 }
135 if (topRad + bottomRad > fRect.height()) {
136 scale = std::min(scale, fRect.height() / (topRad + bottomRad));
137 }
138
139 if (scale < SK_Scalar1) {
140 leftRad *= scale;
141 topRad *= scale;
142 rightRad *= scale;
143 bottomRad *= scale;
144 }
145
146 if (leftRad == rightRad && topRad == bottomRad) {
147 if (leftRad >= SkScalarHalf(fRect.width()) && topRad >= SkScalarHalf(fRect.height())) {
148 fType = kOval_Type;
149 } else if (0 == leftRad || 0 == topRad) {
150 // If the left and (by equality check above) right radii are zero then it is a rect.
151 // Same goes for top/bottom.
152 fType = kRect_Type;
153 leftRad = 0;
154 topRad = 0;
155 rightRad = 0;
156 bottomRad = 0;
157 } else {
158 fType = kSimple_Type;
159 }
160 } else {
161 fType = kNinePatch_Type;
162 }
163
164 fRadii[kUpperLeft_Corner].set(leftRad, topRad);
165 fRadii[kUpperRight_Corner].set(rightRad, topRad);
166 fRadii[kLowerRight_Corner].set(rightRad, bottomRad);
167 fRadii[kLowerLeft_Corner].set(leftRad, bottomRad);
168 if (clamp_to_zero(fRadii)) {
169 this->setRect(rect); // devolve into a simple rect
170 return;
171 }
172 if (fType == kNinePatch_Type && !radii_are_nine_patch(fRadii)) {
173 fType = kComplex_Type;
174 }
175
176 SkASSERT(this->isValid());
177}
static bool SkIsFinite(T x, Pack... values)
static bool clamp_to_zero(SkVector radii[4])
Definition: SkRRect.cpp:88
#define SK_Scalar1
Definition: SkScalar.h:18
#define SkScalarHalf(a)
Definition: SkScalar.h:75
float SkScalar
Definition: extension.cpp:12
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
const Scalar scale
void set(float x, float y)
Definition: SkPoint_impl.h:200
constexpr float width() const
Definition: SkRect.h:762

◆ setOval()

void SkRRect::setOval ( const SkRect oval)

Sets bounds to oval, x-axis radii to half oval.width(), and all y-axis radii to half oval.height(). If oval bounds is empty, sets to kEmpty_Type. Otherwise, sets to kOval_Type.

Parameters
ovalbounds of oval

Definition at line 30 of file SkRRect.cpp.

30 {
31 if (!this->initializeRect(oval)) {
32 return;
33 }
34
35 SkScalar xRad = SkRectPriv::HalfWidth(fRect);
36 SkScalar yRad = SkRectPriv::HalfHeight(fRect);
37
38 if (xRad == 0.0f || yRad == 0.0f) {
39 // All the corners will be square
40 memset(fRadii, 0, sizeof(fRadii));
41 fType = kRect_Type;
42 } else {
43 for (int i = 0; i < 4; ++i) {
44 fRadii[i].set(xRad, yRad);
45 }
46 fType = kOval_Type;
47 }
48
49 SkASSERT(this->isValid());
50}

◆ setRect()

void SkRRect::setRect ( const SkRect rect)
inline

Sets bounds to sorted rect, and sets corner radii to zero. If set bounds has width and height, and sets type to kRect_Type; otherwise, sets type to kEmpty_Type.

Parameters
rectbounds to set

Definition at line 126 of file SkRRect.h.

126 {
127 if (!this->initializeRect(rect)) {
128 return;
129 }
130
131 memset(fRadii, 0, sizeof(fRadii));
132 fType = kRect_Type;
133
134 SkASSERT(this->isValid());
135 }

◆ setRectRadii()

void SkRRect::setRectRadii ( const SkRect rect,
const SkVector  radii[4] 
)

Sets bounds to rect. Sets radii array for individual control of all for corners.

If rect is empty, sets to kEmpty_Type. Otherwise, if one of each corner radii are zero, sets to kRect_Type. Otherwise, if all x-axis radii are equal and at least half rect.width(), and all y-axis radii are equal at least half rect.height(), sets to kOval_Type. Otherwise, if all x-axis radii are equal, and all y-axis radii are equal, sets to kSimple_Type. Otherwise, sets to kNinePatch_Type.

Parameters
rectbounds of rounded rectangle
radiicorner x-axis and y-axis radii

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

Definition at line 189 of file SkRRect.cpp.

189 {
190 if (!this->initializeRect(rect)) {
191 return;
192 }
193
194 if (!SkIsFinite(&radii[0].fX, 8)) {
195 this->setRect(rect); // devolve into a simple rect
196 return;
197 }
198
199 memcpy(fRadii, radii, sizeof(fRadii));
200
201 if (clamp_to_zero(fRadii)) {
202 this->setRect(rect);
203 return;
204 }
205
206 this->scaleRadii();
207
208 if (!this->isValid()) {
209 this->setRect(rect);
210 return;
211 }
212}

◆ setRectXY()

void SkRRect::setRectXY ( const SkRect rect,
SkScalar  xRad,
SkScalar  yRad 
)

Sets to rounded rectangle with the same radii for all four corners. If rect is empty, sets to kEmpty_Type. Otherwise, if xRad or yRad is zero, sets to kRect_Type. Otherwise, if xRad is at least half rect.width() and yRad is at least half rect.height(), sets to kOval_Type. Otherwise, sets to kSimple_Type.

Parameters
rectbounds of rounded rectangle
xRadx-axis radius of corners
yRady-axis radius of corners

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

Definition at line 52 of file SkRRect.cpp.

52 {
53 if (!this->initializeRect(rect)) {
54 return;
55 }
56
57 if (!SkIsFinite(xRad, yRad)) {
58 xRad = yRad = 0; // devolve into a simple rect
59 }
60
61 if (fRect.width() < xRad+xRad || fRect.height() < yRad+yRad) {
62 // At most one of these two divides will be by zero, and neither numerator is zero.
63 SkScalar scale = std::min(sk_ieee_float_divide(fRect. width(), xRad + xRad),
64 sk_ieee_float_divide(fRect.height(), yRad + yRad));
66 xRad *= scale;
67 yRad *= scale;
68 }
69
70 if (xRad <= 0 || yRad <= 0) {
71 // all corners are square in this case
72 this->setRect(rect);
73 return;
74 }
75
76 for (int i = 0; i < 4; ++i) {
77 fRadii[i].set(xRad, yRad);
78 }
79 fType = kSimple_Type;
80 if (xRad >= SkScalarHalf(fRect.width()) && yRad >= SkScalarHalf(fRect.height())) {
81 fType = kOval_Type;
82 // TODO: assert that all the x&y radii are already W/2 & H/2
83 }
84
85 SkASSERT(this->isValid());
86}
static constexpr float sk_ieee_float_divide(float numer, float denom)
SkScalar width() const
Definition: SkRRect.h:95

◆ transform()

bool SkRRect::transform ( const SkMatrix matrix,
SkRRect dst 
) const

Transforms by SkRRect by matrix, storing result in dst. Returns true if SkRRect transformed can be represented by another SkRRect. Returns false if matrix contains transformations that are not axis aligned.

Asserts in debug builds if SkRRect equals dst.

Parameters
matrixSkMatrix specifying the transform
dstSkRRect to store the result
Returns
true if transformation succeeded.

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

Definition at line 436 of file SkRRect.cpp.

436 {
437 if (nullptr == dst) {
438 return false;
439 }
440
441 // Assert that the caller is not trying to do this in place, which
442 // would violate const-ness. Do not return false though, so that
443 // if they know what they're doing and want to violate it they can.
444 SkASSERT(dst != this);
445
446 if (matrix.isIdentity()) {
447 *dst = *this;
448 return true;
449 }
450
451 if (!matrix.preservesAxisAlignment()) {
452 return false;
453 }
454
455 SkRect newRect;
456 if (!matrix.mapRect(&newRect, fRect)) {
457 return false;
458 }
459
460 // The matrix may have scaled us to zero (or due to float madness, we now have collapsed
461 // some dimension of the rect, so we need to check for that. Note that matrix must be
462 // scale and translate and mapRect() produces a sorted rect. So an empty rect indicates
463 // loss of precision.
464 if (!newRect.isFinite() || newRect.isEmpty()) {
465 return false;
466 }
467
468 // At this point, this is guaranteed to succeed, so we can modify dst.
469 dst->fRect = newRect;
470
471 // Since the only transforms that were allowed are axis aligned, the type
472 // remains unchanged.
473 dst->fType = fType;
474
475 if (kRect_Type == fType) {
476 SkASSERT(dst->isValid());
477 return true;
478 }
479 if (kOval_Type == fType) {
480 for (int i = 0; i < 4; ++i) {
481 dst->fRadii[i].fX = SkScalarHalf(newRect.width());
482 dst->fRadii[i].fY = SkScalarHalf(newRect.height());
483 }
484 SkASSERT(dst->isValid());
485 return true;
486 }
487
488 // Now scale each corner
489 SkScalar xScale = matrix.getScaleX();
490 SkScalar yScale = matrix.getScaleY();
491
492 // There is a rotation of 90 (Clockwise 90) or 270 (Counter clockwise 90).
493 // 180 degrees rotations are simply flipX with a flipY and would come under
494 // a scale transform.
495 if (!matrix.isScaleTranslate()) {
496 const bool isClockwise = matrix.getSkewX() < 0;
497
498 // The matrix location for scale changes if there is a rotation.
499 xScale = matrix.getSkewY() * (isClockwise ? 1 : -1);
500 yScale = matrix.getSkewX() * (isClockwise ? -1 : 1);
501
502 const int dir = isClockwise ? 3 : 1;
503 for (int i = 0; i < 4; ++i) {
504 const int src = (i + dir) >= 4 ? (i + dir) % 4 : (i + dir);
505 // Swap X and Y axis for the radii.
506 dst->fRadii[i].fX = fRadii[src].fY;
507 dst->fRadii[i].fY = fRadii[src].fX;
508 }
509 } else {
510 for (int i = 0; i < 4; ++i) {
511 dst->fRadii[i].fX = fRadii[i].fX;
512 dst->fRadii[i].fY = fRadii[i].fY;
513 }
514 }
515
516 const bool flipX = xScale < 0;
517 if (flipX) {
518 xScale = -xScale;
519 }
520
521 const bool flipY = yScale < 0;
522 if (flipY) {
523 yScale = -yScale;
524 }
525
526 // Scale the radii without respecting the flip.
527 for (int i = 0; i < 4; ++i) {
528 dst->fRadii[i].fX *= xScale;
529 dst->fRadii[i].fY *= yScale;
530 }
531
532 // Now swap as necessary.
533 using std::swap;
534 if (flipX) {
535 if (flipY) {
536 // Swap with opposite corners
537 swap(dst->fRadii[kUpperLeft_Corner], dst->fRadii[kLowerRight_Corner]);
538 swap(dst->fRadii[kUpperRight_Corner], dst->fRadii[kLowerLeft_Corner]);
539 } else {
540 // Only swap in x
541 swap(dst->fRadii[kUpperRight_Corner], dst->fRadii[kUpperLeft_Corner]);
542 swap(dst->fRadii[kLowerRight_Corner], dst->fRadii[kLowerLeft_Corner]);
543 }
544 } else if (flipY) {
545 // Only swap in y
546 swap(dst->fRadii[kUpperLeft_Corner], dst->fRadii[kLowerLeft_Corner]);
548 }
549
550 if (!AreRectAndRadiiValid(dst->fRect, dst->fRadii)) {
551 return false;
552 }
553
554 dst->scaleRadii();
555 dst->isValid(); // TODO: is this meant to be SkASSERT(dst->isValid())?
556
557 return true;
558}
void swap(sk_sp< T > &a, sk_sp< T > &b)
Definition: SkRefCnt.h:341
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
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 Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets dir
Definition: switches.h:145

◆ type()

Type SkRRect::type ( ) const
inline

Definition at line 81 of file SkRRect.h.

81{ return this->getType(); }

◆ width()

SkScalar SkRRect::width ( ) const
inline

Returns span on the x-axis. This does not check if result fits in 32-bit float; result may be infinity.

Returns
rect().fRight minus rect().fLeft

Definition at line 95 of file SkRRect.h.

95{ return fRect.width(); }

◆ writeToMemory()

size_t SkRRect::writeToMemory ( void *  buffer) const

Writes SkRRect to buffer. Writes kSizeInMemory bytes, and returns kSizeInMemory, the number of bytes written.

Parameters
bufferstorage for SkRRect
Returns
bytes written, kSizeInMemory

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

Definition at line 599 of file SkRRect.cpp.

599 {
600 // Serialize only the rect and corners, but not the derived type tag.
601 memcpy(buffer, this, kSizeInMemory);
602 return kSizeInMemory;
603}

Friends And Related Function Documentation

◆ operator!=

bool operator!= ( const SkRRect a,
const SkRRect b 
)
friend

Returns true if bounds and radii in a are not equal to bounds and radii in b.

a and b are not equal if either contain NaN. a and b are equal if members contain zeroes with different signs.

Parameters
aSkRect bounds and radii to compare
bSkRect bounds and radii to compare
Returns
true if members are not equal

Definition at line 303 of file SkRRect.h.

303 {
304 return a.fRect != b.fRect || !SkScalarsEqual(&a.fRadii[0].fX, &b.fRadii[0].fX, 8);
305 }
static bool SkScalarsEqual(const SkScalar a[], const SkScalar b[], int n)
Definition: SkScalar.h:151
static bool b
struct MyStruct a[10]

◆ operator==

bool operator== ( const SkRRect a,
const SkRRect b 
)
friend

Returns true if bounds and radii in a are equal to bounds and radii in b.

a and b are not equal if either contain NaN. a and b are equal if members contain zeroes with different signs.

Parameters
aSkRect bounds and radii to compare
bSkRect bounds and radii to compare
Returns
true if members are equal

Definition at line 290 of file SkRRect.h.

290 {
291 return a.fRect == b.fRect && SkScalarsEqual(&a.fRadii[0].fX, &b.fRadii[0].fX, 8);
292 }

◆ SkPath

friend class SkPath
friend

Definition at line 512 of file SkRRect.h.

◆ SkRRectPriv

friend class SkRRectPriv
friend

Definition at line 513 of file SkRRect.h.

Member Data Documentation

◆ kSizeInMemory

constexpr size_t SkRRect::kSizeInMemory = 12 * sizeof(SkScalar)
staticconstexpr

Definition at line 422 of file SkRRect.h.


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