blob: 2136984f74000c15e990202472ad94599375ed1f [file] [log] [blame]
#Topic RRect
#Alias Round_Rect ##
#Alias RRect_Reference ##
#Class SkRRect
#Code
class SkRRect {
public:
SkRRect() = default;
SkRRect(const SkRRect& rrect) = default;
SkRRect& operator=(const SkRRect& rrect) = default;
enum Type {
kEmpty_Type,
kRect_Type,
kOval_Type,
kSimple_Type,
kNinePatch_Type,
kComplex_Type,
kLastType = kComplex_Type,
};
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);
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);
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]);
enum Corner {
kUpperLeft_Corner,
kUpperRight_Corner,
kLowerRight_Corner,
kLowerLeft_Corner,
};
const SkRect& rect() const;
SkVector radii(Corner corner) const;
const SkRect& getBounds() const;
friend bool operator==(const SkRRect& a, const SkRRect& b);
friend bool operator!=(const SkRRect& a, const SkRRect& b);
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;
static constexpr size_t kSizeInMemory = 12 * sizeof(SkScalar);
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;
void dump() const;
void dumpHex() const;
};
##
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.
# ------------------------------------------------------------------------------
#Method SkRRect()
#In Constructors
#Line # creates with zeroed bounds and corner radii ##
#Populate
#Example
#Height 60
SkRRect rrect;
SkPaint p;
p.setStyle(SkPaint::kStroke_Style);
p.setStrokeWidth(10);
canvas->drawRRect(rrect, p);
rrect.setRect({10, 10, 100, 50});
canvas->drawRRect(rrect, p);
##
#SeeAlso setEmpty isEmpty
#Method ##
# ------------------------------------------------------------------------------
#Method SkRRect(const SkRRect& rrect)
#In Constructors
#Line # copies bounds and corner radii ##
#Populate
#Example
#Height 60
SkRRect rrect = SkRRect::MakeRect({10, 10, 100, 50});
SkRRect rrect2(rrect);
rrect2.inset(20, 20);
SkPaint p;
p.setStyle(SkPaint::kStroke_Style);
p.setStrokeWidth(10);
canvas->drawRRect(rrect, p);
canvas->drawRRect(rrect2, p);
##
#SeeAlso operator=(const SkRRect& rrect) MakeRect
#Method ##
# ------------------------------------------------------------------------------
#Method SkRRect& operator=(const SkRRect& rrect)
#In Operators
#Line # copies bounds and corner radii ##
#Populate
#Example
#Height 110
SkRRect rrect = SkRRect::MakeRect({40, 40, 100, 70});
SkRRect rrect2 = rrect;
rrect2.inset(-20, -20);
SkPaint p;
p.setStyle(SkPaint::kStroke_Style);
p.setStrokeWidth(10);
canvas->drawRRect(rrect, p);
canvas->drawRRect(rrect2, p);
##
#SeeAlso SkRRect(const SkRRect& rrect) MakeRect
#Method ##
# ------------------------------------------------------------------------------
#Subtopic Type
#Line # specialization of Round_Rect geometry ##
#PhraseDef list_of_rrect_types
kEmpty_Type, kRect_Type, kOval_Type, kSimple_Type, kNinePatch_Type,
kComplex_Type
##
#Enum Type
#Line # specialization of Round_Rect geometry ##
#Code
enum Type {
kEmpty_Type,
kRect_Type,
kOval_Type,
kSimple_Type,
kNinePatch_Type,
kComplex_Type,
kLastType = kComplex_Type,
};
##
Type describes possible specializations of Round_Rect. Each Type is
exclusive; a Round_Rect may only have one type.
Type members become progressively less restrictive; larger values of
Type have more degrees of freedom than smaller values.
#Const kEmpty_Type 0
#Line # zero width or height ##
Round_Rect has zero width or height. All radii are zero.
##
#Const kRect_Type 1
#Line # non-zero width and height, and zeroed radii ##
Round_Rect has width and height. All radii are zero.
##
#Const kOval_Type 2
#Line # non-zero width and height filled with radii ##
Round_Rect has width and height. All four x-radii are equal,
and at least half the width. All four y-radii are equal,
and at least half the height.
##
#Const kSimple_Type 3
#Line # non-zero width and height with equal radii ##
Round_Rect has width and height. All four x-radii are equal and
greater than zero, and all four y-radii are equal and greater than
zero. Either x-radii are less than half the width, or y-radii is
less than half the height, or both.
##
#Const kNinePatch_Type 4
#Line # non-zero width and height with axis-aligned radii ##
Round_Rect has width and height. Left x-radii are equal, top
y-radii are equal, right x-radii are equal, and bottom y-radii
are equal. The radii do not describe Rect, Oval, or simple type.
The centers of the corner ellipses form an axis-aligned rectangle
that divides the Round_Rect into nine rectangular patches; an
interior rectangle, four edges, and four corners.
##
#Const kComplex_Type 5
#Line # non-zero width and height with arbitrary radii ##
both radii are non-zero.
##
#Const kLastType 5
#Line # largest Type value ##
##
#Example
#Height 128
struct Radii { SkVector data[4]; };
auto drawRRectType = [=](const SkRect& rect, const Radii& radii) {
SkRRect rrect;
rrect.setRectRadii(rect, radii.data);
SkPaint paint;
paint.setAntiAlias(true);
const char* typeStr[] = { "empty", "rect", "oval", "simple", "nine patch", "complex" };
canvas->drawString(typeStr[(int) rrect.type()], rect.centerX(), rect.bottom() + 20, paint);
paint.setStyle(SkPaint::kStroke_Style);
canvas->drawRRect(rrect, paint);
};
drawRRectType({ 45, 30, 45, 30}, {{{ 5, 5}, { 5, 5}, { 5, 5}, { 5, 5}}});
drawRRectType({ 90, 10, 140, 30}, {{{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}});
drawRRectType({160, 10, 210, 30}, {{{25, 10}, {25, 10}, {25, 10}, {25, 10}}});
drawRRectType({ 20, 80, 70, 100}, {{{ 5, 5}, { 5, 5}, { 5, 5}, { 5, 5}}});
drawRRectType({ 90, 80, 140, 100}, {{{ 5, 5}, {10, 5}, {10, 5}, { 5, 5}}});
drawRRectType({160, 80, 210, 100}, {{{ 5, 5}, {10, 5}, { 5, 5}, { 5, 5}}});
##
#SeeAlso Rect Path
#Enum ##
# ------------------------------------------------------------------------------
#Method Type getType() const
#In Property
#Line # returns Type ##
Returns Type, one of: #list_of_rrect_types#.
#Return Type ##
#Example
#Height 100
#Description
rrect2 is not a Rect; inset() has made it empty.
##
SkRRect rrect = SkRRect::MakeRect({10, 10, 100, 50});
SkRRect rrect2(rrect);
rrect2.inset(20, 20);
SkPaint p;
p.setStyle(SkPaint::kStroke_Style);
p.setStrokeWidth(10);
std::string str("Type ");
str += SkRRect::kRect_Type == rrect2.getType() ? "=" : "!";
str += "= SkRRect::kRect_Type";
canvas->drawString(str.c_str(), 20, 80, SkPaint());
canvas->drawRRect(rrect2, p);
##
#SeeAlso Type type
#Method ##
# ------------------------------------------------------------------------------
#Method Type type() const
#In Property
#Line # returns Type ##
Returns Type, one of: #list_of_rrect_types#.
#Return Type ##
#Example
#Height 100
#Description
inset() has made rrect2 empty.
##
SkRRect rrect = SkRRect::MakeRect({10, 10, 100, 50});
SkRRect rrect2(rrect);
rrect2.inset(20, 20);
SkPaint p;
p.setStyle(SkPaint::kStroke_Style);
p.setStrokeWidth(10);
std::string str("Type ");
str += SkRRect::kEmpty_Type == rrect2.type() ? "=" : "!";
str += "= SkRRect::kEmpty_Type";
canvas->drawString(str.c_str(), 20, 80, SkPaint());
canvas->drawRRect(rrect2, p);
##
#SeeAlso Type getType
#Method ##
#Subtopic Type ##
# ------------------------------------------------------------------------------
#Method bool isEmpty() const
#In Property
#Line # returns true if width or height are zero ##
#Populate
#Example
#Height 100
SkPaint paint;
paint.setAntiAlias(true);
paint.setTextSize(16);
SkRRect rrect = SkRRect::MakeRectXY({30, 10, 100, 60}, 10, 5);
canvas->drawRRect(rrect, paint);
canvas->drawString(rrect.isEmpty() ? "empty" : "not empty", 64, 90, paint);
rrect.inset(40, 0);
canvas->translate(128, 0);
canvas->drawRRect(rrect, paint);
canvas->drawString(rrect.isEmpty() ? "empty" : "not empty", 64, 90, paint);
##
#SeeAlso SkRect::isEmpty height width
#Method ##
# ------------------------------------------------------------------------------
#Method bool isRect() const
#In Property
#Line # returns true if not empty, and one radius at each corner is zero ##
#Populate
#Example
#Height 100
SkPaint paint;
paint.setAntiAlias(true);
paint.setTextSize(16);
SkRRect rrect = SkRRect::MakeRect({30, 10, 100, 60});
canvas->drawRRect(rrect, paint);
canvas->drawString(rrect.isRect() ? "rect" : "not rect", 64, 90, paint);
SkVector radii[] = {{10, 10}, {0, 0}, {0, 0}, {0, 0}};
rrect.setRectRadii(rrect.getBounds(), radii);
canvas->translate(128, 0);
canvas->drawRRect(rrect, paint);
canvas->drawString(rrect.isRect() ? "rect" : "not rect", 64, 90, paint);
##
#SeeAlso isEmpty radii
#Method ##
# ------------------------------------------------------------------------------
#Method bool isOval() const
#In Property
#Line # returns true if not empty, axes radii are equal, radii fill bounds ##
#Populate
#Example
#Height 100
#Description
The first radii are scaled down proportionately until both x-axis and y-axis fit
within the bounds. After scaling, x-axis radius is smaller than half the width;
left Round_Rect is not an oval. The second radii are equal to half the
dimensions; right Round_Rect is an oval.
##
SkPaint paint;
paint.setAntiAlias(true);
paint.setTextSize(16);
SkRRect rrect = SkRRect::MakeRectXY({30, 10, 100, 60}, 40, 30);
canvas->drawRRect(rrect, paint);
canvas->drawString(rrect.isOval() ? "oval" : "not oval", 64, 90, paint);
rrect.setRectXY(rrect.getBounds(), 35, 25);
canvas->translate(128, 0);
canvas->drawRRect(rrect, paint);
canvas->drawString(rrect.isOval() ? "oval" : "not oval", 64, 90, paint);
##
#SeeAlso isEmpty isSimple SkCanvas::drawOval
#Method ##
# ------------------------------------------------------------------------------
#Method bool isSimple() const
#In Property
#Line # returns true if not empty, Rect or Oval; and axes radii are equal ##
#Populate
#Example
#Height 100
SkPaint paint;
paint.setAntiAlias(true);
paint.setTextSize(16);
SkVector radii[] = {{40, 30}, {40, 30}, {40, 30}, {40, 30}};
SkRRect rrect;
rrect.setRectRadii({30, 10, 100, 60}, radii);
canvas->drawRRect(rrect, paint);
canvas->drawString(rrect.isSimple() ? "simple" : "not simple", 64, 90, paint);
radii[0].fX = 35;
rrect.setRectRadii(rrect.getBounds(), radii);
canvas->translate(128, 0);
canvas->drawRRect(rrect, paint);
canvas->drawString(rrect.isSimple() ? "simple" : "not simple", 64, 90, paint);
##
#SeeAlso isEmpty isRect isOval isNinePatch
#Method ##
# ------------------------------------------------------------------------------
#Method bool isNinePatch() const
#In Property
#Line # returns true if not empty, Rect, Oval or simple; and radii are axis-aligned ##
#Populate
#Example
#Height 100
SkPaint paint;
paint.setAntiAlias(true);
paint.setTextSize(16);
SkVector radii[] = {{20, 30}, {40, 30}, {40, 30}, {20, 30}};
SkRRect rrect;
rrect.setRectRadii({30, 10, 100, 60}, radii);
canvas->drawRRect(rrect, paint);
canvas->drawString(rrect.isNinePatch() ? "9 patch" : "not 9 patch", 64, 90, paint);
radii[0].fX = 35;
rrect.setRectRadii(rrect.getBounds(), radii);
canvas->translate(128, 0);
canvas->drawRRect(rrect, paint);
canvas->drawString(rrect.isNinePatch() ? "9 patch" : "not 9 patch", 64, 90, paint);
##
#SeeAlso isEmpty isRect isOval isSimple isComplex
#Method ##
# ------------------------------------------------------------------------------
#Method bool isComplex() const
#In Property
#Line # returns true if not empty, Rect, Oval, simple, or nine-patch ##
#Populate
#Example
#Height 100
SkPaint paint;
paint.setAntiAlias(true);
paint.setTextSize(16);
SkVector radii[] = {{25, 30}, {40, 30}, {40, 30}, {20, 30}};
SkRRect rrect;
rrect.setRectRadii({30, 10, 100, 60}, radii);
canvas->drawRRect(rrect, paint);
canvas->drawString(rrect.isComplex() ? "complex" : "not complex", 64, 90, paint);
radii[0].fX = 20;
rrect.setRectRadii(rrect.getBounds(), radii);
canvas->translate(128, 0);
canvas->drawRRect(rrect, paint);
canvas->drawString(rrect.isComplex() ? "complex" : "not complex", 64, 90, paint);
##
#SeeAlso isEmpty isRect isOval isSimple isNinePatch
#Method ##
# ------------------------------------------------------------------------------
#Method SkScalar width() const
#In Property
#Line # returns span in x-axis ##
#Populate
#Example
#Description
SkRRect::MakeRect sorts its input, so width() is always zero or larger.
##
SkRRect unsorted = SkRRect::MakeRect({ 15, 25, 10, 5 });
SkDebugf("unsorted width: %g\n", unsorted.width());
SkRRect large = SkRRect::MakeRect({ -FLT_MAX, 1, FLT_MAX, 2 });
SkDebugf("large width: %.0f\n", large.width());
#StdOut
unsorted width: 5
large width: inf
##
##
#SeeAlso SkRect::width height getBounds
#Method ##
# ------------------------------------------------------------------------------
#Method SkScalar height() const
#In Property
#Line # returns span in y-axis ##
#Populate
#Example
#Description
SkRRect::MakeRect sorts its input, so height() is always zero or larger.
##
SkRRect unsorted = SkRRect::MakeRect({ 15, 25, 10, 20 });
SkDebugf("unsorted height: %g\n", unsorted.height());
SkRRect large = SkRRect::MakeRect({ 1, -FLT_MAX, 2, FLT_MAX });
SkDebugf("large height: %.0f\n", large.height());
#StdOut
unsorted height: 5
large height: inf
##
##
#SeeAlso SkRect::height width getBounds
#Method ##
# ------------------------------------------------------------------------------
#Method SkVector getSimpleRadii() const
#In Property
#Line # returns corner radii for simple types ##
#Populate
#Example
#Height 100
auto drawDetails = [=](const SkRRect& rrect) {
SkPaint paint;
paint.setAntiAlias(true);
paint.setTextSize(12);
canvas->drawRRect(rrect, paint);
SkVector corner = rrect.getSimpleRadii();
std::string label = "corner: " + std::to_string(corner.fX).substr(0, 3) + ", " +
std::to_string(corner.fY).substr(0, 3);
canvas->drawString(label.c_str(), 64, 90, paint);
canvas->translate(128, 0);
};
SkRRect rrect = SkRRect::MakeRect({30, 10, 100, 60});
drawDetails(rrect);
rrect.setRectXY(rrect.getBounds(), 5, 8);
drawDetails(rrect);
##
#SeeAlso radii getBounds getType isSimple
#Method ##
# ------------------------------------------------------------------------------
#Method void setEmpty()
#In Set
#Line # zeroes width, height, and corner radii ##
#Populate
#Example
#Height 80
#Description
Nothing blue is drawn because Round_Rect is set to empty.
##
SkPaint paint;
SkRRect rrect = SkRRect::MakeRect({30, 10, 100, 60});
canvas->drawRRect(rrect, paint);
rrect.setEmpty();
paint.setColor(SK_ColorBLUE);
canvas->drawRRect(rrect, paint);
##
#SeeAlso MakeEmpty setRect
#Method ##
# ------------------------------------------------------------------------------
#Method void setRect(const SkRect& rect)
#In Set
#Line # sets Round_Rect bounds with zeroed corners ##
#Populate
#Example
#Height 90
SkPaint paint;
SkRRect rrect = SkRRect::MakeRect({30, 10, 100, 60});
canvas->drawRRect(rrect, paint);
rrect.setRect({60, 30, 120, 80});
paint.setColor(SK_ColorBLUE);
canvas->drawRRect(rrect, paint);
##
#SeeAlso MakeRect setRectXY
#Method ##
# ------------------------------------------------------------------------------
#Method static SkRRect MakeEmpty()
#In Constructors
#Line # creates with zeroed bounds and corner radii ##
#Populate
#Example
#Height 90
SkRRect rrect = SkRRect::MakeEmpty();
SkRRect rrect2(rrect);
rrect2.inset(-20, -20);
SkPaint p;
p.setStyle(SkPaint::kStroke_Style);
p.setStrokeWidth(10);
std::string str("Type ");
str += SkRRect::kEmpty_Type == rrect2.type() ? "=" : "!";
str += "= SkRRect::kEmpty_Type";
canvas->drawString(str.c_str(), 20, 80, SkPaint());
canvas->drawRRect(rrect2, p);
##
#SeeAlso SkRRect() SkRect::MakeEmpty
#Method ##
# ------------------------------------------------------------------------------
#Method static SkRRect MakeRect(const SkRect& r)
#In Constructors
#Line # copies bounds and zeroes corner radii ##
#Populate
#Example
#Height 70
SkPaint paint;
SkRRect rrect = SkRRect::MakeRect({30, 10, 100, 60});
canvas->drawRRect(rrect, paint);
rrect.setOval(rrect.getBounds());
paint.setColor(SK_ColorBLUE);
canvas->drawRRect(rrect, paint);
##
#SeeAlso setRect MakeOval MakeRectXY
#Method ##
# ------------------------------------------------------------------------------
#Method static SkRRect MakeOval(const SkRect& oval)
#In Constructors
#Line # creates Oval to fit bounds ##
#Populate
#Example
#Height 70
SkPaint paint;
SkRRect rrect = SkRRect::MakeOval({30, 10, 100, 60});
canvas->drawRRect(rrect, paint);
rrect.setRect(rrect.getBounds());
paint.setColor(SK_ColorBLUE);
paint.setBlendMode(SkBlendMode::kDifference);
canvas->drawRRect(rrect, paint);
##
#SeeAlso setOval MakeRect MakeRectXY
#Method ##
# ------------------------------------------------------------------------------
#Method static SkRRect MakeRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad)
#In Constructors
#Line # creates rounded rectangle ##
#Populate
#Example
#Height 70
SkPaint paint;
SkRRect rrect = SkRRect::MakeRectXY({30, 10, 100, 60}, 20, 20);
canvas->drawRRect(rrect, paint);
rrect.setRect(rrect.getBounds());
paint.setColor(SK_ColorBLUE);
paint.setBlendMode(SkBlendMode::kModulate);
canvas->drawRRect(rrect, paint);
##
#SeeAlso setRectXY
#Method ##
# ------------------------------------------------------------------------------
#Method void setOval(const SkRect& oval)
#In Set
#Line # replaces with Oval to fit bounds ##
#Populate
#Example
#Height 70
SkPaint paint;
SkRRect rrect = SkRRect::MakeRectXY({30, 10, 100, 60}, 20, 20);
canvas->drawRRect(rrect, paint);
rrect.setOval(rrect.getBounds());
paint.setColor(SK_ColorWHITE);
paint.setBlendMode(SkBlendMode::kExclusion);
canvas->drawRRect(rrect, paint);
##
#SeeAlso MakeOval
#Method ##
# ------------------------------------------------------------------------------
#Method void setRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad)
#In Set
#Line # replaces with rounded rectangle ##
#Populate
#Example
#Height 70
SkPaint paint;
SkRRect rrect = SkRRect::MakeRectXY({30, 10, 100, 60}, 20, 20);
canvas->drawRRect(rrect, paint);
rrect.setRectXY(rrect.getBounds(), 5, 5);
paint.setColor(SK_ColorWHITE);
paint.setBlendMode(SkBlendMode::kExclusion);
canvas->drawRRect(rrect, paint);
##
#SeeAlso MakeRectXY SkPath::addRoundRect
#Method ##
# ------------------------------------------------------------------------------
#Method void setNinePatch(const SkRect& rect, SkScalar leftRad, SkScalar topRad,
SkScalar rightRad, SkScalar bottomRad)
#In Set
#Line # replaces with rounded rectangle ##
#Populate
#Example
#Height 70
SkPaint paint;
paint.setAntiAlias(true);
SkRRect rrect;
rrect.setNinePatch({30, 10, 100, 60}, 10, 20, 20, 10);
canvas->drawRRect(rrect, paint);
paint.setColor(SK_ColorWHITE);
const SkRect r = rrect.getBounds();
canvas->drawLine(r.fLeft, r.fTop + rrect.radii(SkRRect::kUpperLeft_Corner).fY,
r.fRight, r.fTop + rrect.radii(SkRRect::kUpperRight_Corner).fY, paint);
canvas->drawLine(r.fLeft, r.fBottom - rrect.radii(SkRRect::kLowerLeft_Corner).fY,
r.fRight, r.fBottom - rrect.radii(SkRRect::kLowerRight_Corner).fY, paint);
canvas->drawLine(r.fLeft + rrect.radii(SkRRect::kUpperLeft_Corner).fX, r.fTop,
r.fLeft + rrect.radii(SkRRect::kLowerLeft_Corner).fX, r.fBottom, paint);
canvas->drawLine(r.fRight - rrect.radii(SkRRect::kUpperRight_Corner).fX, r.fTop,
r.fRight - rrect.radii(SkRRect::kLowerRight_Corner).fX, r.fBottom, paint);
##
#SeeAlso setRectRadii
#Method ##
# ------------------------------------------------------------------------------
#Method void setRectRadii(const SkRect& rect, const SkVector radii[4])
#In Set
#Line # replaces with rounded rectangle ##
#Populate
#Example
#Height 128
SkPaint paint;
paint.setStrokeWidth(15);
paint.setStrokeCap(SkPaint::kSquare_Cap);
paint.setAntiAlias(true);
float intervals[] = { 5, 21.75f };
paint.setStyle(SkPaint::kStroke_Style);
paint.setPathEffect(SkDashPathEffect::Make(intervals, SK_ARRAY_COUNT(intervals), 0));
SkPath path;
SkRRect rrect;
SkVector corners[] = {{15, 17}, {17, 19}, {19, 15}, {15, 15}};
rrect.setRectRadii({20, 20, 100, 100}, corners);
path.addRRect(rrect, SkPath::kCW_Direction);
canvas->drawPath(path, paint);
path.rewind();
path.addRRect(rrect, SkPath::kCCW_Direction, 1);
canvas->translate(120, 0);
canvas->drawPath(path, paint);
##
#SeeAlso setNinePatch SkPath::addRoundRect
#Method ##
# ------------------------------------------------------------------------------
#Enum Corner
#Line # corner radii order ##
#Code
enum Corner {
kUpperLeft_Corner,
kUpperRight_Corner,
kLowerRight_Corner,
kLowerLeft_Corner,
};
##
The radii are stored: top-left, top-right, bottom-right, bottom-left.
#Const kUpperLeft_Corner 0
#Line # index of top-left corner radii ##
##
#Const kUpperRight_Corner 1
#Line # index of top-right corner radii ##
##
#Const kLowerRight_Corner 2
#Line # index of bottom-right corner radii ##
##
#Const kLowerLeft_Corner 3
#Line # index of bottom-left corner radii ##
##
#Example
#Height 70
SkPaint paint;
paint.setAntiAlias(true);
SkRRect rrect;
SkVector corners[] = {{25, 17}, {17, 19}, {19, 15}, {15, 15}};
rrect.setRectRadii({30, 10, 100, 60}, corners);
canvas->drawRRect(rrect, paint);
paint.setColor(SK_ColorWHITE);
const SkRect r = rrect.getBounds();
canvas->drawLine(r.fLeft, r.fTop + rrect.radii(SkRRect::kUpperLeft_Corner).fY,
r.fRight, r.fTop + rrect.radii(SkRRect::kUpperRight_Corner).fY, paint);
canvas->drawLine(r.fLeft, r.fBottom - rrect.radii(SkRRect::kLowerLeft_Corner).fY,
r.fRight, r.fBottom - rrect.radii(SkRRect::kLowerRight_Corner).fY, paint);
canvas->drawLine(r.fLeft + rrect.radii(SkRRect::kUpperLeft_Corner).fX, r.fTop,
r.fLeft + rrect.radii(SkRRect::kLowerLeft_Corner).fX, r.fBottom, paint);
canvas->drawLine(r.fRight - rrect.radii(SkRRect::kUpperRight_Corner).fX, r.fTop,
r.fRight - rrect.radii(SkRRect::kLowerRight_Corner).fX, r.fBottom, paint);
##
#SeeAlso radii
#Enum ##
# ------------------------------------------------------------------------------
#Method const SkRect& rect() const
#In Property
#Line # returns bounds ##
#Populate
#Example
for (SkScalar left : { SK_ScalarNaN, SK_ScalarInfinity, 100.f, 50.f, 25.f} ) {
SkRRect rrect1 = SkRRect::MakeRectXY({left, 20, 60, 220}, 50, 200);
SkDebugf("left bounds: (%g) %g\n", left, rrect1.rect().fLeft);
}
#StdOut
left bounds: (nan) 0
left bounds: (inf) 0
left bounds: (100) 60
left bounds: (50) 50
left bounds: (25) 25
##
##
#SeeAlso getBounds
#Method ##
# ------------------------------------------------------------------------------
#Method SkVector radii(Corner corner) const
#In Property
#Line # returns x-axis and y-axis radii for one corner ##
#Populate
#Example
#Description
Finite values are scaled proportionately to fit; other values are set to zero.
Scaled values cannot be larger than 25, half the bounding Round_Rect width.
Small scaled values are halved to scale in proportion to the y-axis corner
radius, which is twice the bounds height.
##
for (SkScalar radiusX : { SK_ScalarNaN, SK_ScalarInfinity, 100.f, 50.f, 25.f} ) {
SkRRect rrect1 = SkRRect::MakeRectXY({10, 20, 60, 220}, radiusX, 200);
SkDebugf("left corner: (%g) %g\n", radiusX, rrect1.radii(SkRRect::kUpperLeft_Corner).fX);
}
#StdOut
left corner: (nan) 0
left corner: (inf) 0
left corner: (100) 25
left corner: (50) 25
left corner: (25) 12.5
##
##
#SeeAlso Corner
#Method ##
# ------------------------------------------------------------------------------
#Method const SkRect& getBounds() const
#In Property
#Line # returns bounds ##
#Populate
#Example
#Height 120
SkPaint paint;
SkRRect rrect = SkRRect::MakeRectXY({20, 20, 220, 100}, 15, 15);
canvas->drawRRect(rrect, paint);
paint.setColor(SK_ColorWHITE);
rrect = SkRRect::MakeOval(rrect.getBounds());
canvas->drawRRect(rrect, paint);
##
#SeeAlso rect
#Method ##
# ------------------------------------------------------------------------------
#Method bool operator==(const SkRRect& a, const SkRRect& b)
#In Operators
#Line # returns true if members are equal ##
#Populate
#Example
SkRRect rrect1 = SkRRect::MakeRectXY({10, 20, 60, 220}, 50, 200);
SkRRect rrect2 = SkRRect::MakeRectXY(rrect1.rect(), 25, 100);
SkRRect rrect3 = SkRRect::MakeOval(rrect1.rect());
canvas->drawRRect(rrect1, SkPaint());
std::string str = "rrect1 " + std::string(rrect1 == rrect2 ? "=" : "!") + "= rrect2";
canvas->drawString(str.c_str(), 10, 240, SkPaint());
canvas->translate(70, 0);
canvas->drawRRect(rrect2, SkPaint());
canvas->translate(70, 0);
canvas->drawRRect(rrect3, SkPaint());
str = "rrect2 " + std::string(rrect2 == rrect3 ? "=" : "!") + "= rrect3";
canvas->drawString(str.c_str(), -20, 240, SkPaint());
##
#SeeAlso operator!=(const SkRRect& a, const SkRRect& b)
#Method ##
# ------------------------------------------------------------------------------
#Method bool operator!=(const SkRRect& a, const SkRRect& b)
#In Operators
#Line # returns true if members are unequal ##
#Populate
#Example
SkRRect rrect1 = SkRRect::MakeRectXY({10, 20, 60, 220}, 50, 100);
SkRRect rrect2 = SkRRect::MakeRectXY(rrect1.rect(), 50, 50);
SkRRect rrect3 = SkRRect::MakeOval(rrect1.rect());
canvas->drawRRect(rrect1, SkPaint());
std::string str = "rrect1 " + std::string(rrect1 == rrect2 ? "=" : "!") + "= rrect2";
canvas->drawString(str.c_str(), 10, 240, SkPaint());
canvas->translate(70, 0);
canvas->drawRRect(rrect2, SkPaint());
canvas->translate(70, 0);
canvas->drawRRect(rrect3, SkPaint());
str = "rrect2 " + std::string(rrect2 == rrect3 ? "=" : "!") + "= rrect3";
canvas->drawString(str.c_str(), -20, 240, SkPaint());
##
#SeeAlso operator==(const SkRRect& a, const SkRRect& b)
#Method ##
# ------------------------------------------------------------------------------
#Method void inset(SkScalar dx, SkScalar dy, SkRRect* dst) const
#In Inset_Outset_Offset
#Line # insets bounds and radii ##
#Populate
#Example
SkPaint paint;
paint.setAntiAlias(true);
paint.setStyle(SkPaint::kStroke_Style);
SkRRect rrect = SkRRect::MakeRectXY({100, 20, 140, 220}, 50, 100);
for (int index = 0; index < 25; ++index) {
canvas->drawRRect(rrect, paint);
rrect.inset(-3, 3, &rrect);
}
##
#SeeAlso outset offset makeOffset
#Method ##
# ------------------------------------------------------------------------------
#Method void inset(SkScalar dx, SkScalar dy)
#In Inset_Outset_Offset
#Line # insets bounds and radii ##
#Populate
#Example
SkPaint paint;
paint.setAntiAlias(true);
paint.setStyle(SkPaint::kStroke_Style);
SkRRect rrect = SkRRect::MakeRectXY({10, 20, 180, 220}, 50, 100);
for (int index = 0; index < 25; ++index) {
canvas->drawRRect(rrect, paint);
rrect.inset(3, 3);
}
##
#SeeAlso outset offset makeOffset
#Method ##
# ------------------------------------------------------------------------------
#Method void outset(SkScalar dx, SkScalar dy, SkRRect* dst) const
#In Inset_Outset_Offset
#Line # outsets bounds and radii ##
#Populate
#Example
SkPaint paint;
paint.setAntiAlias(true);
paint.setStyle(SkPaint::kStroke_Style);
SkRRect rrect = SkRRect::MakeRectXY({100, 20, 140, 220}, 50, 100);
for (int index = 0; index < 25; ++index) {
canvas->drawRRect(rrect, paint);
rrect.outset(-3, 3, &rrect);
}
##
#SeeAlso inset offset makeOffset
#Method ##
# ------------------------------------------------------------------------------
#Method void outset(SkScalar dx, SkScalar dy)
#In Inset_Outset_Offset
#Line # outsets bounds and radii ##
#Populate
#Example
SkPaint paint;
paint.setAntiAlias(true);
paint.setStyle(SkPaint::kStroke_Style);
SkRRect rrect = SkRRect::MakeRectXY({100, 20, 140, 220}, 50, 100);
for (int index = 0; index < 25; ++index) {
canvas->drawRRect(rrect, paint);
rrect.outset(3, 3);
}
##
#SeeAlso inset offset makeOffset
#Method ##
# ------------------------------------------------------------------------------
#Method void offset(SkScalar dx, SkScalar dy)
#In Inset_Outset_Offset
#Line # offsets bounds and radii ##
#Populate
#Example
SkPaint paint;
paint.setAntiAlias(true);
paint.setStyle(SkPaint::kStroke_Style);
SkRRect rrect = SkRRect::MakeRectXY({100, 20, 140, 220}, 50, 100);
for (int index = 0; index < 25; ++index) {
canvas->drawRRect(rrect, paint);
rrect.offset(3, 3);
}
##
#SeeAlso makeOffset inset outset
#Method ##
# ------------------------------------------------------------------------------
#Method SkRRect makeOffset(SkScalar dx, SkScalar dy) const
#In Inset_Outset_Offset
#Line # offsets bounds and radii ##
#Populate
#Example
SkPaint paint;
paint.setAntiAlias(true);
paint.setStyle(SkPaint::kStroke_Style);
SkRRect rrect = SkRRect::MakeRectXY({100, 20, 140, 220}, 50, 100);
for (int index = 0; index < 25; ++index) {
canvas->drawRRect(rrect, paint);
rrect = rrect.makeOffset(-3, 3);
}
##
#SeeAlso offset inset outset
#Method ##
# ------------------------------------------------------------------------------
#Method bool contains(const SkRect& rect) const
#In Intersection
#Line # returns true if Rect is inside ##
#Populate
#Example
#Height 110
SkRect test = {10, 10, 110, 80};
SkRRect rrect = SkRRect::MakeRect(test);
SkRRect oval = SkRRect::MakeOval(test);
test.inset(10, 10);
SkPaint paint;
paint.setAntiAlias(true);
canvas->drawString(rrect.contains(test) ? "contains" : "does not contain", 55, 100, paint);
canvas->drawString(oval.contains(test) ? "contains" : "does not contain", 185, 100, paint);
paint.setStyle(SkPaint::kStroke_Style);
canvas->drawRRect(rrect, paint);
canvas->drawRect(test, paint);
canvas->translate(120, 0);
canvas->drawRRect(oval, paint);
canvas->drawRect(test, paint);
##
#SeeAlso SkRect::contains
#Method ##
# ------------------------------------------------------------------------------
#Method bool isValid() const
#In Utility
#Line # returns if type() matches bounds and radii ##
#Populate
#Example
#Height 110
SkRRect rrect = SkRRect::MakeRect({10, 10, 110, 80});
SkRRect corrupt = rrect;
*((float*) &corrupt) = 120;
SkPaint paint;
paint.setAntiAlias(true);
canvas->drawString(rrect.isValid() ? "is valid" : "is corrupted", 55, 100, paint);
canvas->drawString(corrupt.isValid() ? "is valid" : "is corrupted", 185, 100, paint);
paint.setStyle(SkPaint::kStroke_Style);
canvas->drawRRect(rrect, paint);
canvas->translate(120, 0);
canvas->drawRRect(corrupt, paint);
##
#SeeAlso Type getType
#Method ##
# ------------------------------------------------------------------------------
#Const kSizeInMemory 48
#Line # storage space for Round_Rect ##
Space required to write the contents of SkRRect into a buffer; always a multiple of four.
#Const ##
# ------------------------------------------------------------------------------
#Method size_t writeToMemory(void* buffer) const
#In Utility
#Line # writes Round_Rect to buffer ##
#Populate
#Example
#Height 110
SkRRect rrect = SkRRect::MakeRect({10, 10, 110, 80});
char storage[SkRRect::kSizeInMemory];
rrect.writeToMemory(storage);
SkRRect copy;
copy.readFromMemory(storage, sizeof(storage));
SkPaint paint;
paint.setAntiAlias(true);
canvas->drawString("rrect", 55, 100, paint);
canvas->drawString("copy", 185, 100, paint);
paint.setStyle(SkPaint::kStroke_Style);
canvas->drawRRect(rrect, paint);
canvas->translate(120, 0);
canvas->drawRRect(copy, paint);
##
#SeeAlso readFromMemory
#Method ##
# ------------------------------------------------------------------------------
#Method size_t readFromMemory(const void* buffer, size_t length)
#In Utility
#Line # reads Round_Rect from buffer ##
#Populate
#Example
#Height 110
SkVector radii[] = {{5, 5}, {10, 10}, {15, 15}, {5, 5}};
SkRRect rrect;
rrect.setRectRadii({10, 10, 110, 80}, radii);
char storage[SkRRect::kSizeInMemory];
rrect.writeToMemory(storage);
SkRRect copy;
copy.readFromMemory(storage, sizeof(storage));
SkPaint paint;
paint.setAntiAlias(true);
canvas->drawString("rrect", 55, 100, paint);
canvas->drawString("copy", 185, 100, paint);
paint.setStyle(SkPaint::kStroke_Style);
canvas->drawRRect(rrect, paint);
canvas->translate(120, 0);
canvas->drawRRect(copy, paint);
##
#SeeAlso writeToMemory
#Method ##
# ------------------------------------------------------------------------------
#Method bool transform(const SkMatrix& matrix, SkRRect* dst) const
#In Inset_Outset_Offset
#Line # scales and offsets into copy ##
#Populate
#Example
#Height 110
SkVector radii[] = {{5, 5}, {10, 10}, {15, 15}, {5, 5}};
SkRRect rrect;
rrect.setRectRadii({10, 10, 110, 80}, radii);
SkRRect transformed;
SkMatrix matrix = SkMatrix::MakeRectToRect(rrect.rect(), {140, 30, 220, 80},
SkMatrix::kCenter_ScaleToFit);
bool success = rrect.transform(matrix, &transformed);
SkPaint paint;
paint.setAntiAlias(true);
canvas->drawString("rrect", 55, 100, paint);
canvas->drawString(success ? "transformed" : "transform failed", 185, 100, paint);
paint.setStyle(SkPaint::kStroke_Style);
canvas->drawRRect(rrect, paint);
canvas->drawRRect(transformed, paint);
##
#SeeAlso SkPath::transform
#Method ##
# ------------------------------------------------------------------------------
#Method void dump(bool asHex) const
#In Utility
#Line # sends text representation to standard output ##
#Populate
#Example
SkRRect rrect = SkRRect::MakeRect({6.f / 7, 2.f / 3, 6.f / 7, 2.f / 3});
for (bool dumpAsHex : { false, true } ) {
rrect.dump(dumpAsHex);
}
#StdOut
SkRect::MakeLTRB(0.857143f, 0.666667f, 0.857143f, 0.666667f);
const SkPoint corners[] = {
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
};
SkRect::MakeLTRB(SkBits2Float(0x3f5b6db7), /* 0.857143 */
SkBits2Float(0x3f2aaaab), /* 0.666667 */
SkBits2Float(0x3f5b6db7), /* 0.857143 */
SkBits2Float(0x3f2aaaab) /* 0.666667 */);
const SkPoint corners[] = {
{ SkBits2Float(0x00000000), SkBits2Float(0x00000000) }, /* 0.000000 0.000000 */
{ SkBits2Float(0x00000000), SkBits2Float(0x00000000) }, /* 0.000000 0.000000 */
{ SkBits2Float(0x00000000), SkBits2Float(0x00000000) }, /* 0.000000 0.000000 */
{ SkBits2Float(0x00000000), SkBits2Float(0x00000000) }, /* 0.000000 0.000000 */
};
##
##
#SeeAlso dumpHex SkRect::dump SkPath::dump SkPathMeasure::dump
#Method ##
# ------------------------------------------------------------------------------
#Method void dump() const
#In Utility
#Line # sends text representation using floats to standard output ##
#Populate
#Example
SkRRect rrect = SkRRect::MakeRect({6.f / 7, 2.f / 3, 6.f / 7, 2.f / 3});
rrect.dump();
SkRect bounds = SkRect::MakeLTRB(0.857143f, 0.666667f, 0.857143f, 0.666667f);
const SkPoint corners[] = {
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
};
SkRRect copy;
copy.setRectRadii(bounds, corners);
SkDebugf("rrect is " "%s" "equal to copy\n", rrect == copy ? "" : "not ");
#StdOut
SkRect::MakeLTRB(0.857143f, 0.666667f, 0.857143f, 0.666667f);
const SkPoint corners[] = {
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
};
rrect is not equal to copy
##
##
#SeeAlso dumpHex SkRect::dump SkPath::dump SkPathMeasure::dump
#Method ##
# ------------------------------------------------------------------------------
#Method void dumpHex() const
#In Utility
#Line # sends text representation using hexadecimal to standard output ##
#Populate
#Example
SkRRect rrect = SkRRect::MakeRect({6.f / 7, 2.f / 3, 6.f / 7, 2.f / 3});
rrect.dumpHex();
SkRect bounds = SkRect::MakeLTRB(SkBits2Float(0x3f5b6db7), /* 0.857143 */
SkBits2Float(0x3f2aaaab), /* 0.666667 */
SkBits2Float(0x3f5b6db7), /* 0.857143 */
SkBits2Float(0x3f2aaaab) /* 0.666667 */);
const SkPoint corners[] = {
{ SkBits2Float(0x00000000), SkBits2Float(0x00000000) }, /* 0.000000 0.000000 */
{ SkBits2Float(0x00000000), SkBits2Float(0x00000000) }, /* 0.000000 0.000000 */
{ SkBits2Float(0x00000000), SkBits2Float(0x00000000) }, /* 0.000000 0.000000 */
{ SkBits2Float(0x00000000), SkBits2Float(0x00000000) }, /* 0.000000 0.000000 */
};
SkRRect copy;
copy.setRectRadii(bounds, corners);
SkDebugf("rrect is " "%s" "equal to copy\n", rrect == copy ? "" : "not ");
#StdOut
SkRect::MakeLTRB(SkBits2Float(0x3f5b6db7), /* 0.857143 */
SkBits2Float(0x3f2aaaab), /* 0.666667 */
SkBits2Float(0x3f5b6db7), /* 0.857143 */
SkBits2Float(0x3f2aaaab) /* 0.666667 */);
const SkPoint corners[] = {
{ SkBits2Float(0x00000000), SkBits2Float(0x00000000) }, /* 0.000000 0.000000 */
{ SkBits2Float(0x00000000), SkBits2Float(0x00000000) }, /* 0.000000 0.000000 */
{ SkBits2Float(0x00000000), SkBits2Float(0x00000000) }, /* 0.000000 0.000000 */
{ SkBits2Float(0x00000000), SkBits2Float(0x00000000) }, /* 0.000000 0.000000 */
};
rrect is equal to copy
##
##
#SeeAlso dump SkRect::dumpHex SkPath::dumpHex
#Method ##
#Class SkRRect ##
#Topic RRect ##