diff --git a/include/zephyr/display/cfb.h b/include/zephyr/display/cfb.h index ea00b8aa2fd..1fcdcff1070 100644 --- a/include/zephyr/display/cfb.h +++ b/include/zephyr/display/cfb.h @@ -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. * diff --git a/subsys/fb/cfb.c b/subsys/fb/cfb.c index 65f3edc113e..b5f3bb12564 100644 --- a/subsys/fb/cfb.c +++ b/subsys/fb/cfb.c @@ -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); diff --git a/subsys/fb/cfb_shell.c b/subsys/fb/cfb_shell.c index 7d63c10b893..77286f719d3 100644 --- a/subsys/fb/cfb_shell.c +++ b/subsys/fb/cfb_shell.c @@ -21,6 +21,7 @@ #define HELP_DRAW_POINT " " #define HELP_DRAW_LINE " " #define HELP_DRAW_RECT " " +#define HELP_DRAW_CIRCLE " " #define HELP_INVERT "[ ]" 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, ¢er, 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 );