aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Anthony <sam@samanthony.xyz>2025-04-30 20:21:40 -0400
committerSam Anthony <sam@samanthony.xyz>2025-04-30 20:21:40 -0400
commite9613ccbdf82deb0f8275e63ad6b5ca23077095c (patch)
tree45413b223b2e083f3fd1b927ecce2bc75e6d48a8
parent2f425edd957b84d92961d78e8377f12db59cf068 (diff)
downloadvolute-e9613ccbdf82deb0f8275e63ad6b5ca23077095c.zip
draw circle on canvas
-rw-r--r--renderer.c67
-rw-r--r--renderer.h2
-rw-r--r--widget.c5
-rw-r--r--widget.h1
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);