11. Rounded Rectangle
This rounded rectangle is based off of the algorithm used in the Adafruit graphics library.
11.1. Stroked Rounded Rectangle
<<funcdefs>>=
void btprnt_draw_roundrect(btprnt_region *reg,
int x, int y,
int w, int h,
int r,
int clr);
<<funcs>>=
static void quadcirc(btprnt_region *reg,
int x0, int y0,
int r,
int corner,
int clr)
{
int f;
int ddf_x;
int ddf_y;
int x;
int y;
f = 1 - r;
ddf_x = 1;
ddf_y = -2 * r;
x = 0;
y = r;
while (x < y) {
if (f >= 0) {
y--;
ddf_y += 2;
f += ddf_y;
}
x++;
ddf_x += 2;
f += ddf_x;
if (corner & 0x4) {
btprnt_region_draw(reg, x0 + x, y0 + y, clr);
btprnt_region_draw(reg, x0 + y, y0 + x, clr);
}
if (corner & 0x2) {
btprnt_region_draw(reg, x0 + x, y0 - y, clr);
btprnt_region_draw(reg, x0 + y, y0 - x, clr);
}
if (corner & 0x8) {
btprnt_region_draw(reg, x0 - y, y0 + x, clr);
btprnt_region_draw(reg, x0 - x, y0 + y, clr);
}
if (corner & 0x1) {
btprnt_region_draw(reg, x0 - y, y0 - x, clr);
btprnt_region_draw(reg, x0 - x, y0 - y, clr);
}
}
}
void btprnt_draw_roundrect(btprnt_region *reg,
int x, int y,
int w, int h,
int r,
int clr)
{
btprnt_draw_hline(reg, x + r, y, w - 2 * r, clr);
btprnt_draw_hline(reg, x + r, y + h - 1, w - 2 * r, clr);
btprnt_draw_vline(reg, x, y + r, h - 2 * r, clr);
btprnt_draw_vline(reg, x + w - 1, y + r, h - 2 * r, clr);
quadcirc(reg, x + r, y + r, r, 1, clr);
quadcirc(reg, x + w - r - 1, y + r, r, 2, clr);
quadcirc(reg, x + w - r - 1, y + h - r - 1, r, 4, clr);
quadcirc(reg, x + r, y + h - r - 1, r, 8, clr);
}
11.2. Filled Rounded Rectangle
<<funcdefs>>=
void btprnt_draw_roundrect_filled(btprnt_region *r,
int x, int y,
int w, int h,
int rad,
int clr);
<<funcs>>=
static void quadcirc_filled(btprnt_region *reg,
int x0, int y0, int r,
int corner, int delta,
int clr)
{
int f;
int ddf_x;
int ddf_y;
int x;
int y;
int px;
int py;
f = 1 - r;
ddf_x = 1;
ddf_y = -2 * r;
x = 0;
y = r;
px = x;
py = y;
delta++;
while (x < y) {
if (f >= 0) {
y--;
ddf_y += 2;
f += ddf_y;
}
x++;
ddf_x += 2;
f += ddf_x;
if (x < (y + 1)) {
if (corner & 1) {
btprnt_draw_vline(reg,
x0 + x, y0 - y,
2 * y + delta, clr);
}
if (corner & 2) {
btprnt_draw_vline(reg,
x0 - x, y0 - y,
2 * y + delta, clr);
}
}
if (y != py) {
if (corner & 1) {
btprnt_draw_vline(reg,
x0 + py, y0 - px,
2 * px + delta, clr);
}
if (corner & 2) {
btprnt_draw_vline(reg,
x0 - py, y0 - px,
2 * px + delta, clr);
}
py = y;
}
px = x;
}
}
void btprnt_draw_roundrect_filled(btprnt_region *reg,
int x, int y,
int w, int h,
int r,
int clr)
{
int max_radius = ((w < h) ? w : h) / 2;
if (r > max_radius)
r = max_radius;
btprnt_draw_rect_filled(reg, x + r, y, w - 2 * r, h, clr);
quadcirc_filled(reg,
x + w - r - 1, y + r,
r, 1, h - 2 * r - 1, clr);
quadcirc_filled(reg,
x + r, y + r,
r, 2, h - 2 * r - 1, clr);
}
prev | home | next