diff options
-rw-r--r-- | meme/gaux.c | 19 | ||||
-rw-r--r-- | meme/gaux.h | 5 | ||||
-rw-r--r-- | meme/gui.c | 47 |
3 files changed, 57 insertions, 14 deletions
diff --git a/meme/gaux.c b/meme/gaux.c index 9295448..272c64b 100644 --- a/meme/gaux.c +++ b/meme/gaux.c @@ -1,8 +1,8 @@ /* * gaux.c - Auxiliary graphics functions * - * Written 2014 by Werner Almesberger - * Copyright 2014 Werner Almesberger + * Written 2014, 2016 by Werner Almesberger + * Copyright 2014, 2016 Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,3 +22,18 @@ SDL_Surface *sdl_surface(Uint32 flags, int width, int height) return SDL_CreateRGBSurface(flags, width, height, fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, fmt->Amask); } + + +/* + * Loosely based on + * https://forums.libsdl.org/viewtopic.php?t=3653&sid=964c840d9a6461f79e00ccd745da6c1c + */ + +Uint32 get_pixel(const SDL_Surface *s, Sint16 x, Sint16 y, Uint32 null) +{ + if (x < 0 || y < 0) + return null; + if (x >= s->w || y >= s->h) + return null; + return ((Uint32 *) s->pixels)[y * (s->pitch / sizeof(Uint32)) + x]; +} diff --git a/meme/gaux.h b/meme/gaux.h index 0685178..b3551e8 100644 --- a/meme/gaux.h +++ b/meme/gaux.h @@ -1,8 +1,8 @@ /* * gaux.h - Auxiliary graphics functions * - * Written 2014 by Werner Almesberger - * Copyright 2014 Werner Almesberger + * Written 2014, 2016 by Werner Almesberger + * Copyright 2014, 2016 Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,5 +18,6 @@ SDL_Surface *sdl_surface(Uint32 flags, int width, int height); +Uint32 get_pixel(const SDL_Surface *s, Sint16 x, Sint16 y, Uint32 null); #endif /* !GAUX_H */ @@ -975,27 +975,54 @@ static void marker_line(void *user, int xa, int ya, int xb, int yb, } +#define TEXT_BG_RGBA 0xffffffff +#define TEXT_BORDER_RGBA 0xffffffc0 +#define MASK_GB 0x00ffff00 /* works with RGBA and ABGR */ + + +static void text_with_outline(SDL_Surface *s, const SDL_Surface *t, + Sint16 x, Sint16 y) +{ + Uint16 ix, iy; + int8_t dx, dy; + Uint32 col; + uint8_t v, v2; + + for (iy = 0; iy != t->h; iy++) + for (ix = 0; ix != t->w; ix++) { + col = get_pixel(t, ix, iy, TEXT_BG_RGBA); + if ((col ^ TEXT_BG_RGBA) & MASK_GB) { + v = col >> 16; + v2 = (255 + v) >> 1; + pixelRGBA(s, x + ix, y + iy, v, v2, v, 255); + continue; + } + col = TEXT_BG_RGBA; + for (dy = -1; dy <= 1; dy++) + for (dx = -1; dx <= 1; dx++) + if (dx || dy) + col &= get_pixel(t, + ix + dx, iy + dy, + TEXT_BG_RGBA); + if ((col ^ TEXT_BG_RGBA) & MASK_GB) + pixelColor(s, x + ix, y + iy, TEXT_BORDER_RGBA); + } +} + + static void marker_text(void *user, int x, int y, float nx, float ny, const char *txt) { SDL_Surface *s = user; Sint16 xx, yy; SDL_Surface *t; - SDL_Rect r; if (coord(x, y, &xx, &yy) <= 0) return; t = text(txt); - r.x = xx + TEXT_OFFSET_X + TEXT_DIST * nx; - r.y = yy + TEXT_OFFSET_Y + TEXT_DIST * ny; - - r.w = t->w; - r.h = t->h; - if (SDL_BlitSurface(t, NULL, s, &r)) { - fprintf(stderr, "SDL_BlitSurface: %s \n", SDL_GetError()); - exit(1); - } + text_with_outline(s, t, xx + TEXT_OFFSET_X + TEXT_DIST * nx, + yy + TEXT_OFFSET_Y + TEXT_DIST * ny); SDL_FreeSurface(t); } |