From fe427689cf1a7db4f769904b201fd220169fbdcb Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Sun, 1 Oct 2023 15:20:59 +0100 Subject: [PATCH] Add support for rendering text with a bitmap font --- include/BitmapFont.h | 17 +++++--- src/BitmapFont.c | 96 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 91 insertions(+), 22 deletions(-) diff --git a/include/BitmapFont.h b/include/BitmapFont.h index fdea49f..71f666c 100644 --- a/include/BitmapFont.h +++ b/include/BitmapFont.h @@ -3,6 +3,7 @@ #include "AssetManager.h" #include "Renderer.h" +#include "SDL_pixels.h" #ifdef __cplusplus extern "C" { @@ -10,13 +11,19 @@ extern "C" { typedef struct bitmap_font BitmapFont; -BitmapFont *load_bitmap_font(AssetManager *am, const Renderer *renderer, - const char *filepath, u64 tile_width, - u64 tile_height); +BitmapFont *create_bitmap_font(AssetManager *am, const Renderer *renderer, + const char *filepath, u64 tile_width, + u64 tile_height); -RenderRect get_character_sprite(BitmapFont *font, u64 index); +TextSize get_text_size_from_bitmap_font(BitmapFont *font, u64 font_size, + const char *text); -void unload_bitmap_font(AssetManager *am, BitmapFont **font); +void render_bitmap_font_text(AssetManager *am, Renderer *renderer, + BitmapFont *font, u64 font_size, const char *text, + u64 start_index, RenderRect dst_rect, + SDL_Color text_color); + +void destroy_bitmap_font(AssetManager *am, BitmapFont **font); #ifdef __cplusplus } diff --git a/src/BitmapFont.c b/src/BitmapFont.c index e89156d..54ffdf1 100644 --- a/src/BitmapFont.c +++ b/src/BitmapFont.c @@ -5,6 +5,7 @@ #include "aliases.h" #include "reusable_ids.h" #include +#include struct bitmap_font { AssetID font_atlas; @@ -16,9 +17,11 @@ struct bitmap_font { u64 cols; }; -BitmapFont *load_bitmap_font(AssetManager *am, const Renderer *renderer, - const char *filepath, u64 tile_width, - u64 tile_height) { +RenderRect get_character_sprite(BitmapFont *font, u64 index); + +BitmapFont *create_bitmap_font(AssetManager *am, const Renderer *renderer, + const char *filepath, u64 tile_width, + u64 tile_height) { BitmapFont *font = (BitmapFont *)malloc(sizeof(BitmapFont)); if (!font) { return NULL; @@ -28,7 +31,7 @@ BitmapFont *load_bitmap_font(AssetManager *am, const Renderer *renderer, load_asset_to_manager(am, filepath, ASSET_TYPE_IMAGE, renderer); if (font->font_atlas == INVALID_ID) { - unload_bitmap_font(am, &font); + destroy_bitmap_font(am, &font); return NULL; } @@ -39,7 +42,7 @@ BitmapFont *load_bitmap_font(AssetManager *am, const Renderer *renderer, i32 h; if (SDL_QueryTexture(texture, NULL, NULL, &w, &h) != 0) { - unload_bitmap_font(am, &font); + destroy_bitmap_font(am, &font); return NULL; } @@ -56,7 +59,78 @@ BitmapFont *load_bitmap_font(AssetManager *am, const Renderer *renderer, return font; } +TextSize get_text_size_from_bitmap_font(BitmapFont *font, u64 font_size, + const char *text) { + u64 length = strlen(text); + + if (!font || font_size == 0 || length == 0) { + return (TextSize){0}; + } + + TextSize size = {.width = 0, .height = font_size}; + + f64 ratio = (f64)font_size / font->tile_height; + + size.width = (i32)(font->tile_width * ratio * length); + + return size; +} + +void render_bitmap_font_text(AssetManager *am, Renderer *renderer, + BitmapFont *font, u64 font_size, const char *text, + u64 start_index, RenderRect dst_rect, + SDL_Color text_color) { + if (!am || !renderer || !font || font_size == 0) { + return; + } + + u64 length = strlen(text); + + if (length == 0) { + return; + } + + SDL_Texture *texture = get_texture(am, font->font_atlas); + + u64 char_index = 0; + RenderRect src = {0}; + RenderRect dst = { + .y = dst_rect.y, + .width = font->tile_width, + .height = font->tile_height, + }; + + for (u64 i = 0; i < length; ++i) { + char_index = (u64)(text[i]) - start_index; + + src = get_character_sprite(font, char_index); + dst.x = i * font->tile_width + dst_rect.x; + + set_texture_color_modulation(texture, text_color); + + render_texture(renderer, texture, &src, &dst); + } +} + +void destroy_bitmap_font(AssetManager *am, BitmapFont **font) { + if (!am || !(*font)) { + return; + } + + remove_asset_from_manager(am, &((*font)->font_atlas)); + + free(*font); + + *font = NULL; +} + RenderRect get_character_sprite(BitmapFont *font, u64 index) { + u64 char_count = font->cols * font->rows; + + if (index >= char_count) { + return (RenderRect){0}; + } + u64 col = index % font->cols; u64 row = index / font->cols; @@ -69,15 +143,3 @@ RenderRect get_character_sprite(BitmapFont *font, u64 index) { return rect; } - -void unload_bitmap_font(AssetManager *am, BitmapFont **font) { - if (!am || !(*font)) { - return; - } - - remove_asset_from_manager(am, &((*font)->font_atlas)); - - free(*font); - - *font = NULL; -}