From e9613ccbdf82deb0f8275e63ad6b5ca23077095c Mon Sep 17 00:00:00 2001 From: Sam Anthony Date: Wed, 30 Apr 2025 20:21:40 -0400 Subject: draw circle on canvas --- renderer.c | 67 ++++++++++++++++++++++++++++---------------------------------- renderer.h | 2 +- widget.c | 5 +++++ widget.h | 1 + 4 files changed, 37 insertions(+), 38 deletions(-) diff --git a/renderer.c b/renderer.c index 4d6b378..c40fcf8 100644 --- a/renderer.c +++ b/renderer.c @@ -18,6 +18,12 @@ } while (0) +#define PIXEL_DEPTH 32 +#define RMASK 0xFF000000u +#define GMASK 0x00FF0000u +#define BMASK 0x0000FF00u +#define AMASK 0x000000FFu + enum window { WIDTH = 640, HEIGHT = 480, @@ -32,16 +38,6 @@ enum { enum { CIRCLE_RADIUS = 16 }; -enum rgb { - RGBA_DEPTH = 4*4, - - RGB_RED = 0xFu << 3, - RGB_GREEN = 0xFu << 2, - RGB_BLUE = 0xFu << 1, - - RGBA_BYTES_PER_PIXEL = RGBA_DEPTH / 8, -}; - static const char FONT[] = "font/P052-Roman.ttf"; enum font { FONTSIZE = 14, }; @@ -70,6 +66,8 @@ typedef struct { int icon_id; } Canvas; +typedef uint32_t Pixel; + static void print_info(void); static int text_width(mu_Font mufont, const char *str, int len); @@ -81,6 +79,8 @@ static void clip(mu_Rect rect); static void draw_rect(mu_Rect rect, mu_Color color); static void draw_text(mu_Font font, mu_Vec2 pos, mu_Color color, const char *str); static void draw_icon(int id, mu_Rect r); +static void set_pixel(SDL_Surface *s, int x, int y, mu_Color color); +static Pixel pixel(mu_Color c); static void clear_surface(SDL_Surface *s); static SDL_Rect surface_rect(const SDL_Surface *s); static void free_canvas(Canvas *c); @@ -396,14 +396,14 @@ r_add_canvas(const char *bg_img_path) { return -1; } - c->fg = SDL_CreateRGBSurface(0, c->bg->w, c->bg->h, RGBA_DEPTH, 0, 0, 0, 0); + c->fg = SDL_CreateRGBSurface(0, c->bg->w, c->bg->h, PIXEL_DEPTH, RMASK, GMASK, BMASK, AMASK); if (!c->fg) { fprintf(stderr, "%s\n", SDL_GetError()); SDL_FreeSurface(c->bg); return -1; } - c->dst = SDL_CreateRGBSurface(0, c->bg->w, c->bg->h, RGBA_DEPTH, 0, 0, 0, 0); + c->dst = SDL_CreateRGBSurface(0, c->bg->w, c->bg->h, PIXEL_DEPTH, RMASK, GMASK, BMASK, AMASK); if (!c->dst) { fprintf(stderr, "%s\n", SDL_GetError()); SDL_FreeSurface(c->bg); @@ -443,42 +443,35 @@ r_remove_canvas(int id) { canvas_list.idx--; } -int +void r_canvas_draw_circle(int id, int x, int y, int r, mu_Color color) { - SDL_Surface *circle; - int i, j; - uint8_t *p; - SDL_Rect src_rect, dst_rect; const Canvas *canvas; + int dy, dx; expect(id >= 0 && id < canvas_list.idx); - circle = SDL_CreateRGBSurface(0, 2*r, 2*r, RGBA_DEPTH, 0, 0, 0, 0); - if (!circle) { - fprintf(stderr, "%s\n", SDL_GetError()); - return 1; - } + canvas = &canvas_list.items[id]; - /* TODO */ - for (j = 0; j < circle->h; j++) { - for (i = 0; i < circle->w; i++) { - p = (uint8_t *) circle->pixels + j*circle->pitch + i*RGBA_BYTES_PER_PIXEL; - p[0] = RGB_RED; + for (dy = -r; dy <= r; dy++) { + for (dx = -r; dx <= r; dx++) { + if (dx*dx + dy*dy <= r*r) { + set_pixel(canvas->fg, x+dx, y+dy, color); + } } } +} - src_rect = (SDL_Rect) {0, 0, circle->w, circle->h}; - canvas = &canvas_list.items[id]; - dst_rect = (SDL_Rect) {x+r, y+r, 2*r, 2*r}; - if (SDL_BlitSurface(circle, &src_rect, canvas->fg, &dst_rect) != 0) { - fprintf(stderr, "%s\n", SDL_GetError()); - SDL_FreeSurface(circle); - return 1; - } +static void +set_pixel(SDL_Surface *s, int x, int y, mu_Color color) { + Pixel *p; - SDL_FreeSurface(circle); + p = (Pixel *) ((uint8_t *) s->pixels + y*s->pitch + x*s->format->BytesPerPixel); + *p = pixel(color); +} - return 0; +static Pixel +pixel(mu_Color c) { + return (c.r << 24) | (c.g << 16) | (c.b << 8) | (c.a << 0); } void diff --git a/renderer.h b/renderer.h index 9bdbfa5..5e668a3 100644 --- a/renderer.h +++ b/renderer.h @@ -10,6 +10,6 @@ void r_get_icon_size(int id, int *w, int *h); int r_add_canvas(const char *bg_img_path); void r_remove_canvas(int id); -int r_canvas_draw_circle(int id, int x, int y, int r, mu_Color color); +void r_canvas_draw_circle(int id, int x, int y, int r, mu_Color color); void r_clear_canvas(int id); int r_render_canvas(int id); diff --git a/widget.c b/widget.c index ec9880c..5c6cb4b 100644 --- a/widget.c +++ b/widget.c @@ -385,3 +385,8 @@ render_canvas(w_Canvas *canvas) { canvas->dirty = 0; return canvas->icon_id; } + +void +w_canvas_draw_circle(w_Canvas canvas, int x, int y, int r, mu_Color color) { + r_canvas_draw_circle(canvas.id, x, y, r, color); +} diff --git a/widget.h b/widget.h index e72da7a..87ef504 100644 --- a/widget.h +++ b/widget.h @@ -85,3 +85,4 @@ typedef struct { int w_init_canvas(w_Canvas *c, const char *bg_img_path); void w_free_canvas(w_Canvas *c); void w_canvas(mu_Context *ctx, w_Canvas *canvas); +void w_canvas_draw_circle(w_Canvas canvas, int x, int y, int r, mu_Color color); -- cgit v1.2.3