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:
parent
67211341ca
commit
077ba1078b
@ -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.
|
||||
*
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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, ¢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
|
||||
);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user