Browse Source

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>
pull/92275/head
Yishai Jaffe 1 month ago committed by Daniel DeGrasse
parent
commit
077ba1078b
  1. 11
      include/zephyr/display/cfb.h
  2. 30
      subsys/fb/cfb.c
  3. 23
      subsys/fb/cfb_shell.c

11
include/zephyr/display/cfb.h

@ -136,6 +136,17 @@ int cfb_draw_line(const struct device *dev, const struct cfb_position *start, @@ -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.
*

30
subsys/fb/cfb.c

@ -394,6 +394,36 @@ int cfb_draw_rect(const struct device *dev, const struct cfb_position *start, @@ -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);

23
subsys/fb/cfb_shell.c

@ -21,6 +21,7 @@ @@ -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[]) @@ -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, @@ -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
);

Loading…
Cancel
Save