Options
These globals are now defined:
double duration; // The requested duration of the animation. double frame; // A value in [0, 1] of where we are in the animation.
This global is now defined:
GrBackendRenderTarget backEndRenderTarget;
GrBackendTexture backEndTextureRenderTarget;
Optional source image
These globals are now defined:
SkBitmap source; sk_sp<SkImage> image; GrBackendTexture backEndTexture; // GPU Only.
Note:
Adding comments with SK_FOLD_START and SK_FOLD_END creates
foldable code blocks.
These blocks will be folded by default and are useful for highlighting specific lines of code.
You can also use the keyboard shortcuts Ctrl+S and Ctrl+E in the code editor to set them.
These blocks will be folded by default and are useful for highlighting specific lines of code.
You can also use the keyboard shortcuts Ctrl+S and Ctrl+E in the code editor to set them.
xxxxxxxxxx
104
struct Borders {
SkScalar left, top, right, bottom;
};
SkRect MakeInnerCorner(
SkRect const& outerCorner,
SkScalar bx,
SkScalar by)
{
SkRect result = outerCorner.makeInset(bx, by);
if (result.width() < 0) {
SkScalar x = fmin(result.fLeft, result.fRight);
result.fLeft = result.fRight = x;
}
if (result.height() < 0) {
SkScalar y = fmin(result.fTop, result.fBottom);
result.fTop = result.fBottom = y;
}
return result;
}
void draw(SkCanvas* canvas) {
// Surface size
SkScalar width = 300;
SkScalar height = 100;
// Configurable parameters
SkScalar radii[4] { 64, 16, 48, 8 };
Borders borders { 4, 16, 4, 16 };
SkColor fillColor = 0xFF'46278E;
SkColor borderColor = 0x80'0FDEBD;
// Start angles for each arc
SkScalar startAngles[4] { -180, -90, 0, 90 };
// Outer corner ovals
SkRect corners[4] {
SkRect::MakeXYWH(0, 0, radii[0]*2, radii[0]*2),
SkRect::MakeXYWH(width-radii[1]*2, 0, radii[1]*2, radii[1]*2),
SkRect::MakeXYWH(width-radii[2]*2, height-radii[2]*2, radii[2]*2, radii[2]*2),
SkRect::MakeXYWH(0, height-radii[3]*2, radii[3]*2, radii[3]*2),
};
// Starting points for each outer arc
SkPoint startPoints[4] {
{ corners[0].left(), corners[0].centerY() },
{ corners[1].centerX(), corners[1].top() },
{ corners[2].right(), corners[2].centerY() },
{ corners[3].centerX(), corners[3].bottom() },
};
// Inner corner ovals
SkRect innerCorners[4] {
MakeInnerCorner(corners[0], borders.left, borders.top),
MakeInnerCorner(corners[1], borders.right, borders.top),
MakeInnerCorner(corners[2], borders.right, borders.bottom),
MakeInnerCorner(corners[3], borders.left, borders.bottom),
};
// Starting points for each inner arc
SkPoint innerStartPoints[4] {
{ innerCorners[0].left(), innerCorners[0].centerY() },
{ innerCorners[1].centerX(), innerCorners[1].top() },
{ innerCorners[2].right(), innerCorners[2].centerY() },
{ innerCorners[3].centerX(), innerCorners[3].bottom() },
};
// Prepare our paint and canvas
SkPaint paint;
paint.setAntiAlias(true);
paint.setStyle(SkPaint::kFill_Style);
canvas->clear(SK_ColorTRANSPARENT);
// Trace the outer path
SkPath outer;
for (int i = 0; i < 4; ++i) {
outer.arcTo(corners[i], startAngles[i], 90, i == 0);
outer.lineTo(startPoints[(i + 1) % 4]);
}
outer.close();
// Trace the inner path
SkPath inner;
for (int i = 0; i < 4; ++i) {
inner.arcTo(innerCorners[i], startAngles[i], 90, i == 0);
inner.lineTo(innerStartPoints[(i + 1) % 4]);
}
inner.close();
// Paint the fill color
paint.setColor(fillColor);
canvas->drawPath(outer, paint);
// Subtract inner from outer
outer.reverseAddPath(inner);
// Paint the border color
paint.setColor(borderColor);
canvas->drawPath(outer, paint);
}