cfb: added API for drawing a circle

Added a new CFB API for drawing a circle. Using the Midpoint Circle
Algorithm for optimization.

Signed-off-by: Yishai Jaffe <yishai1999@gmail.com>
This commit is contained in:
Yishai Jaffe 2025-06-08 18:18:16 +03:00 committed by Daniel DeGrasse
parent 67211341ca
commit 077ba1078b
3 changed files with 64 additions and 0 deletions

View File

@ -136,6 +136,17 @@ int cfb_draw_line(const struct device *dev, const struct cfb_position *start,
int cfb_draw_rect(const struct device *dev, const struct cfb_position *start,
const struct cfb_position *end);
/**
* @brief Draw a circle.
*
* @param dev Pointer to device structure for driver instance
* @param start Center position of the circle
* @param radius Radius of the circle
*
* @return 0 on success, negative value otherwise
*/
int cfb_draw_circle(const struct device *dev, const struct cfb_position *start, uint16_t radius);
/**
* @brief Clear framebuffer.
*

View File

@ -394,6 +394,36 @@ int cfb_draw_rect(const struct device *dev, const struct cfb_position *start,
return 0;
}
int cfb_draw_circle(const struct device *dev, const struct cfb_position *center, uint16_t radius)
{
struct char_framebuffer *fb = &char_fb;
uint16_t x = 0;
int16_t y = -radius;
int16_t p = -radius;
/* Using the Midpoint Circle Algorithm */
while (x < -y) {
if (p > 0) {
p += 2 * (x + ++y) + 1;
} else {
p += 2 * x + 1;
}
draw_point(fb, center->x + x, center->y + y);
draw_point(fb, center->x - x, center->y + y);
draw_point(fb, center->x + x, center->y - y);
draw_point(fb, center->x - x, center->y - y);
draw_point(fb, center->x + y, center->y + x);
draw_point(fb, center->x + y, center->y - x);
draw_point(fb, center->x - y, center->y + x);
draw_point(fb, center->x - y, center->y - x);
x++;
}
return 0;
}
int cfb_draw_text(const struct device *dev, const char *const str, int16_t x, int16_t y)
{
return draw_text(dev, str, x, y, false);

View File

@ -21,6 +21,7 @@
#define HELP_DRAW_POINT "<x> <y>"
#define HELP_DRAW_LINE "<x0> <y0> <x1> <y1>"
#define HELP_DRAW_RECT "<x0> <y0> <x1> <y1>"
#define HELP_DRAW_CIRCLE "<x> <y> <radius>"
#define HELP_INVERT "[<x> <y> <width> <height>]"
static const struct device *const dev =
@ -187,6 +188,27 @@ static int cmd_draw_rect(const struct shell *sh, size_t argc, char *argv[])
return err;
}
static int cmd_draw_circle(const struct shell *sh, size_t argc, char *argv[])
{
int err;
struct cfb_position center;
uint16_t radius;
center.x = strtol(argv[1], NULL, 10);
center.y = strtol(argv[2], NULL, 10);
radius = strtol(argv[3], NULL, 10);
err = cfb_draw_circle(dev, &center, radius);
if (err) {
shell_error(sh, "Failed circle drawing to Framebuffer error=%d", err);
return err;
}
err = cfb_framebuffer_finalize(dev);
return err;
}
static int cmd_scroll_vert(const struct shell *sh, size_t argc, char *argv[])
{
int err = 0;
@ -509,6 +531,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_cmd_draw,
SHELL_CMD_ARG(point, NULL, HELP_DRAW_POINT, cmd_draw_point, 3, 0),
SHELL_CMD_ARG(line, NULL, HELP_DRAW_LINE, cmd_draw_line, 5, 0),
SHELL_CMD_ARG(rect, NULL, HELP_DRAW_RECT, cmd_draw_rect, 5, 0),
SHELL_CMD_ARG(circle, NULL, HELP_DRAW_RECT, cmd_draw_circle, 4, 0),
SHELL_SUBCMD_SET_END
);