2 #include "system/stacktrace.h"
7 #include "sdl/renderer.h"
8 #include "sprite_font.h"
10 #include "system/nth_alloc.h"
11 #include "system/log.h"
13 #define FONT_ROW_SIZE 18
21 Sprite_font *create_sprite_font_from_file(const char *bmp_file_path,
22 SDL_Renderer *renderer)
24 trace_assert(bmp_file_path);
25 trace_assert(renderer);
27 Lt * const lt = create_lt();
32 Sprite_font * const sprite_font = PUSH_LT(lt, nth_alloc(sizeof(Sprite_font)), free);
33 if (sprite_font == NULL) {
37 SDL_Surface * const surface = PUSH_LT(lt, SDL_LoadBMP(bmp_file_path), SDL_FreeSurface);
38 if (surface == NULL) {
39 log_fail("Could not load %s: %s\n", bmp_file_path, SDL_GetError());
43 if (SDL_SetColorKey(surface,
45 SDL_MapRGB(surface->format,
47 log_fail("SDL_SetColorKey: %s\n", SDL_GetError());
51 sprite_font->texture = PUSH_LT(
53 SDL_CreateTextureFromSurface(renderer, surface),
55 if (sprite_font->texture == NULL) {
56 log_fail("SDL_CreateTextureFromSurface: %s\n", SDL_GetError());
60 SDL_FreeSurface(RELEASE_LT(lt, surface));
67 void destroy_sprite_font(Sprite_font *sprite_font)
69 trace_assert(sprite_font);
70 RETURN_LT0(sprite_font->lt);
73 static SDL_Rect sprite_font_char_rect(const Sprite_font *sprite_font, char x)
75 trace_assert(sprite_font);
77 if (32 <= x && x <= 126) {
78 const SDL_Rect rect = {
79 .x = ((x - 32) % FONT_ROW_SIZE) * FONT_CHAR_WIDTH,
80 .y = ((x - 32) / FONT_ROW_SIZE) * FONT_CHAR_HEIGHT,
86 return sprite_font_char_rect(sprite_font, '?');
90 int sprite_font_render_text(const Sprite_font *sprite_font,
91 SDL_Renderer *renderer,
97 trace_assert(sprite_font);
98 trace_assert(renderer);
101 const SDL_Color sdl_color = color_for_sdl(color);
103 if (SDL_SetTextureColorMod(sprite_font->texture, sdl_color.r, sdl_color.g, sdl_color.b) < 0) {
104 log_fail("SDL_SetTextureColorMod: %s\n", SDL_GetError());
108 if (SDL_SetTextureAlphaMod(sprite_font->texture, sdl_color.a) < 0) {
109 log_fail("SDL_SetTextureAlphaMod: %s\n", SDL_GetError());
113 const size_t text_size = strlen(text);
114 for (size_t i = 0; i < text_size; ++i) {
115 const SDL_Rect char_rect = sprite_font_char_rect(sprite_font, text[i]);
116 const SDL_Rect dest_rect = rect_for_sdl(
118 position.x + (float) FONT_CHAR_WIDTH * (float) i * size.x,
120 (float) char_rect.w * size.x,
121 (float) char_rect.h * size.y));
122 if (SDL_RenderCopy(renderer, sprite_font->texture, &char_rect, &dest_rect) < 0) {
130 Rect sprite_font_boundary_box(const Sprite_font *sprite_font,
135 trace_assert(sprite_font);
138 position.x, position.y,
139 size.x * FONT_CHAR_WIDTH * (float) strlen(text),
140 size.y * FONT_CHAR_HEIGHT);