From a5d9d5ec96a5ccdc711aa13b8953e8d34e696ded Mon Sep 17 00:00:00 2001 From: Sara Date: Fri, 21 Apr 2023 00:25:05 +0200 Subject: [PATCH 1/7] updated font asset handling --- src/corelib/assets.c | 22 +++++++++++++++++++--- src/corelib/assets.h | 5 ++++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/corelib/assets.c b/src/corelib/assets.c index ed853c1..d753967 100644 --- a/src/corelib/assets.c +++ b/src/corelib/assets.c @@ -53,10 +53,13 @@ TTF_Font* load_font(const char* file, int size) { .type = RESOURCETYPE_FONT, .hash = hashstr(file), .name = calloc(len+1, sizeof(char)), - .font = TTF_OpenFont(file, size) + .font = { + .size = size, + .font = TTF_OpenFont(file, size) + } }; strcpy(res.name, file); - return insert_asset(&res)->font; + return insert_asset(&res)->font.font; } SDL_Texture* get_texture(const char* file) { @@ -68,6 +71,19 @@ SDL_Texture* get_texture(const char* file) { } } +TTF_Font* get_font(const char *file, int size) { + uint32_t hash = hashstr(file); + for(resource_t* res = g_assets; res != g_assets_endptr; ++res) { + if(res->hash == hash + && strcmp(res->name, file) == 0 + && res->type == RESOURCETYPE_FONT + && res->font.size == size) { + return res->font.font; + } + } + return load_font(file, size); +} + resource_t* get_asset(const char* file) { uint32_t hash = hashstr(file); for(resource_t* res = g_assets; res != g_assets_endptr; ++res) { @@ -88,7 +104,7 @@ void _delete_referenced_asset(resource_t* res) { SDL_DestroyTexture(res->texture); break; case RESOURCETYPE_FONT: - TTF_CloseFont(res->font); + TTF_CloseFont(res->font.font); break; case RESOURCETYPE_ARBITRARY: res->arbitrary_type.deleter(res->arbitrary_type.memory); diff --git a/src/corelib/assets.h b/src/corelib/assets.h index ee4983c..89360ef 100644 --- a/src/corelib/assets.h +++ b/src/corelib/assets.h @@ -25,7 +25,10 @@ typedef struct resource_t { char* name; union { SDL_Texture* texture; - TTF_Font* font; + struct { + int size; + TTF_Font* font; + } font; struct { void* memory; deleter_t deleter; From 4c4851546fcbad6ed70668a89d1c8eba8aa26fd1 Mon Sep 17 00:00:00 2001 From: Sara Date: Fri, 21 Apr 2023 00:25:28 +0200 Subject: [PATCH 2/7] now quitting sdl-ttf correctly --- src/corelib/context.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/context.c b/src/corelib/context.c index 9108fa8..a8b84bc 100644 --- a/src/corelib/context.c +++ b/src/corelib/context.c @@ -30,6 +30,7 @@ void init_context() { void close_context() { SDL_DestroyRenderer(g_context.renderer); SDL_DestroyWindow(g_context.window); + TTF_Quit(); IMG_Quit(); SDL_Quit(); } From 38e6908dc3b5b0fa1556b9a1126307e70ad36939 Mon Sep 17 00:00:00 2001 From: Sara Date: Fri, 21 Apr 2023 00:26:03 +0200 Subject: [PATCH 3/7] added -lm arg to CMakeLists --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6610d7d..d5cd436 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,8 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin/") set(CMAKE_EXPORT_COMPILE_COMMANDS) +set(CMAKE_C_FLAGS "-lm") + find_package(SDL2) find_package(SDL2_image) find_package(SDL2_ttf) From 55311d0bb828d73ec33d5eaa262c88f9d4d3dded Mon Sep 17 00:00:00 2001 From: Sara Date: Fri, 21 Apr 2023 00:26:36 +0200 Subject: [PATCH 4/7] fixed translation issue with ninesliced images --- src/corelib/render.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/corelib/render.c b/src/corelib/render.c index 4f3be4b..35916f8 100644 --- a/src/corelib/render.c +++ b/src/corelib/render.c @@ -160,7 +160,7 @@ void exec_sliced_cmd(const drawcmd_t* cmd) { tw - sliced->corner_size*2, sliced->corner_size }; dstr = get_dest_with_size((SDL_FRect){ - rect.x + sliced->radius, 0.0, sliced->rect.w - sliced->radius * 2, sliced->radius + rect.x + sliced->radius, rect.y, sliced->rect.w - sliced->radius * 2, sliced->radius }, cmd->ui); SDL_RenderCopyF(g_context.renderer, t, &srcr, &dstr); @@ -169,7 +169,7 @@ void exec_sliced_cmd(const drawcmd_t* cmd) { tw - sliced->corner_size, 0, sliced->corner_size, sliced->corner_size }; dstr = get_dest_with_size((SDL_FRect){ - rect.w - sliced->radius, 0, sliced->radius, sliced->radius + rect.x + rect.w - sliced->radius, rect.y, sliced->radius, sliced->radius }, cmd->ui); SDL_RenderCopyF(g_context.renderer, t, &srcr, &dstr); @@ -178,7 +178,7 @@ void exec_sliced_cmd(const drawcmd_t* cmd) { 0, sliced->corner_size, sliced->corner_size, th - sliced->corner_size * 2 }; dstr = get_dest_with_size((SDL_FRect) { - 0, sliced->radius, sliced->radius, rect.h - sliced->radius * 2 + rect.x, rect.y + sliced->radius, sliced->radius, rect.h - sliced->radius * 2 }, cmd->ui); SDL_RenderCopyF(g_context.renderer, t, &srcr, &dstr); @@ -187,7 +187,7 @@ void exec_sliced_cmd(const drawcmd_t* cmd) { sliced->corner_size, sliced->corner_size, tw - sliced->corner_size * 2, th - sliced->corner_size * 2 }; dstr = get_dest_with_size((SDL_FRect) { - sliced->radius, sliced->radius, rect.w - sliced->radius * 2, rect.h - sliced->radius * 2 + rect.x + sliced->radius, rect.y + sliced->radius, rect.w - sliced->radius * 2, rect.h - sliced->radius * 2 }, cmd->ui); SDL_RenderCopyF(g_context.renderer, t, &srcr, &dstr); @@ -196,18 +196,16 @@ void exec_sliced_cmd(const drawcmd_t* cmd) { tw - sliced->corner_size, sliced->corner_size, sliced->corner_size, th - sliced->corner_size * 2 }; dstr = get_dest_with_size((SDL_FRect) { - rect.w - sliced->radius, sliced->radius, sliced->radius, rect.h - sliced->radius * 2 + rect.x + rect.w - sliced->radius, rect.y + sliced->radius, sliced->radius, rect.h - sliced->radius * 2 }, cmd->ui); SDL_RenderCopyF(g_context.renderer, t, &srcr, &dstr); // bottom-left srcr = (SDL_Rect) { - 0, th - sliced->corner_size, - sliced->corner_size, sliced->corner_size + 0, th - sliced->corner_size, sliced->corner_size, sliced->corner_size }; dstr = get_dest_with_size((SDL_FRect){ - 0, rect.h - sliced->radius, - sliced->radius, sliced->radius + rect.x, rect.y + rect.h - sliced->radius, sliced->radius, sliced->radius }, cmd->ui); SDL_RenderCopyF(g_context.renderer, t, &srcr, &dstr); @@ -216,7 +214,7 @@ void exec_sliced_cmd(const drawcmd_t* cmd) { sliced->corner_size, th - sliced->corner_size, tw - sliced->corner_size * 2, sliced->corner_size }; dstr = get_dest_with_size((SDL_FRect) { - sliced->radius, rect.h - sliced->radius, rect.w - sliced->radius * 2, sliced->radius + rect.x + sliced->radius, rect.y + rect.h - sliced->radius, rect.w - sliced->radius * 2, sliced->radius }, cmd->ui); SDL_RenderCopyF(g_context.renderer, t, &srcr, &dstr); From 5686c17fee8916d5d81bbcc627f2a412b5f7af92 Mon Sep 17 00:00:00 2001 From: Sara Date: Fri, 21 Apr 2023 00:27:05 +0200 Subject: [PATCH 5/7] started work on text rendering --- src/corelib/render.c | 33 +++++++++++++++++++++++++-------- src/corelib/render.h | 10 ++++++++-- src/game.c | 5 ++++- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/corelib/render.c b/src/corelib/render.c index 35916f8..09f9367 100644 --- a/src/corelib/render.c +++ b/src/corelib/render.c @@ -223,25 +223,34 @@ void exec_sliced_cmd(const drawcmd_t* cmd) { tw - sliced->corner_size, th - sliced->corner_size, sliced->corner_size, sliced->corner_size }; dstr = get_dest_with_size((SDL_FRect) { - rect.w - sliced->radius, rect.h - sliced->radius, sliced->radius, sliced->radius + rect.x + rect.w - sliced->radius, rect.y + rect.h - sliced->radius, sliced->radius, sliced->radius }, cmd->ui); SDL_RenderCopyF(g_context.renderer, t, &srcr, &dstr); } void exec_text_cmd(const drawcmd_t* cmd) { SDL_FRect r = get_dest_with_size(cmd->text.area, cmd->ui); - SDL_FRect rt = {r.x*100, r.y*100, r.w*100, r.h*100}; - SDL_Surface* s = TTF_RenderText_Solid_Wrapped(cmd->text.font, cmd->text.text, cmd->text.fg, floor(cmd->text.area.y * 100)); + + float scale = 1.0 / (float)TTF_FontHeight(cmd->text.style.font) * cmd->text.style.size; + int pt_width = r.w * scale; + printf("scale %f ptwidth %d\n", scale, pt_width); + SDL_Surface* s = TTF_RenderText_Solid_Wrapped(cmd->text.style.font, cmd->text.text, cmd->text.fg, pt_width); if(s != NULL) { - SDL_FreeSurface(s); SDL_Texture* t = SDL_CreateTextureFromSurface(g_context.renderer, s); + SDL_FreeSurface(s); + + float ratio = (float)s->w / (float)pt_width; + r.w *= ratio; + r.h *= ratio; + printf("r.w %f\n", r.w); + float ar = r.w / r.h; float ar2 = (float)s->w / (float)s->h; SDL_Rect srcr = {0, 0, s->w, s->h}; if(ar > ar2) { - srcr.h = srcr.w * ar; + srcr.h = srcr.w / ar; } else if(ar < ar2) { - r.h = r.w * ar2; + r.h = r.w / ar2; } SDL_RenderCopyF(g_context.renderer, t, &srcr, &r); SDL_DestroyTexture(t); @@ -352,13 +361,13 @@ void draw_sliced(const nineslice_t *sliced) { draw(&d); } -void draw_text(const char *str, SDL_FRect area, TTF_Font *font, SDL_Color font_color, depth_t depth) { +void draw_text(const char *str, SDL_FRect area, text_style_t style, SDL_Color font_color, depth_t depth) { int len = strlen(str); textarea_t t = { .text = calloc(len+1, sizeof(char)), .area = area, .fg = font_color, - .font = font, + .style = style, }; strcpy(t.text, str); drawcmd_t d = { @@ -419,6 +428,14 @@ sprite_t sprite_from_spritesheet(spritesheet_t *sheet, int index) { }; } +text_style_t make_text_style(const char *font, int dpi, float size) { + TTF_Font* fnt = get_font(font, dpi); + return (text_style_t){ + .font = fnt, + .size = size + }; +} + SDL_Rect get_srcrect_from(spritesheet_t *sheet, int index) { int pixels = index * sheet->tile_width; int w = sheet->w / sheet->tile_width; diff --git a/src/corelib/render.h b/src/corelib/render.h index 48490a6..eacb08d 100644 --- a/src/corelib/render.h +++ b/src/corelib/render.h @@ -21,6 +21,11 @@ typedef enum drawcmdtype_t { DRAWCMDTYPE_MAX } drawcmdtype_t; +typedef struct text_style_t { + TTF_Font* font; + float size; +} text_style_t; + typedef struct spritesheet_t { SDL_Texture* texture; int w, h; // width and height of texture @@ -37,7 +42,7 @@ typedef struct nineslice_t { typedef struct textarea_t { char* text; - TTF_Font* font; + text_style_t style; SDL_Color fg; SDL_FRect area; } textarea_t; @@ -89,11 +94,12 @@ extern void draw(const drawcmd_t* cmd); extern void draw_sprite(const sprite_t* sprite); extern void draw_rect(const rectshape_t* rect); extern void draw_sliced(const nineslice_t* sliced); -extern void draw_text(const char* str, SDL_FRect area, TTF_Font* font, SDL_Color font_color, depth_t depth); +extern void draw_text(const char* str, SDL_FRect area, text_style_t style, SDL_Color font_color, depth_t depth); extern spritesheet_t make_spritesheet(const char* file, int tile_width, int tile_height); extern nineslice_t make_nineslice(const char* file, int corner_px, float radius); extern sprite_t make_sprite(const char* file, float x, float y); extern sprite_t sprite_from_spritesheet(spritesheet_t* sheet, int index); +extern text_style_t make_text_style(const char* font, int dpi, float size); extern SDL_Rect get_srcrect_from(spritesheet_t* sheet, int index); extern void set_active_view(const view_t* view); diff --git a/src/game.c b/src/game.c index 0e61f9f..2e442fd 100644 --- a/src/game.c +++ b/src/game.c @@ -191,7 +191,7 @@ void update_ui() { update_input(); nineslice_t sliced = style.button.active; - sliced.rect = (SDL_FRect){0, 0, 0.1, 0.1}; + sliced.rect = (SDL_FRect){0, 0.25f, 0.2, 0.05}; sliced.depth = RLAYER_UI - 20; draw_sliced(&sliced); @@ -208,6 +208,9 @@ void update_ui() { {100,100,100,255}, {0,0,0,0} }; draw_rect(&shape); + text_style_t style = make_text_style("ui_font.otf", 100, 0.01); + draw_text("M", + (SDL_FRect){0.0, 0.0, 10.0, 10.0}, style, (SDL_Color){255, 255, 255, 255}, RLAYER_UI - 100); float mx, my; mouse_screen_position(&mx, &my); From 3c3c565bfa0d885d1552304d4da0fe396a2f3b46 Mon Sep 17 00:00:00 2001 From: Sara Date: Sun, 23 Apr 2023 00:47:35 +0200 Subject: [PATCH 6/7] finished text scaling code --- TODO.txt | 9 ++++++++- src/corelib/render.c | 35 ++++++++++++++++------------------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/TODO.txt b/TODO.txt index 1270ec5..4c55b6f 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,9 +1,16 @@ # TODOs -[ ] add nineslice drawcmd functions +[x] add nineslice drawcmd functions [x] draw_* [x] exec_* +[ ] add text rendering + [x] loading fonts + [x] managing font style + [x] rendering fonts to surface to texture + [x] correctly scaling fonts + [ ] cache rendered text + [ ] add imgui [ ] ui windows [ ] input fields diff --git a/src/corelib/render.c b/src/corelib/render.c index 09f9367..bf56b37 100644 --- a/src/corelib/render.c +++ b/src/corelib/render.c @@ -4,10 +4,11 @@ #include "layers.h" #include "signal.h" #include "inttypes.h" +#include "string.h" #include "SDL2/SDL_blendmode.h" #include "SDL2/SDL_render.h" #include "SDL2/SDL_surface.h" -#include "string.h" +#include "SDL2/SDL_ttf.h" #define NUM_DRAWCMDS 2048 @@ -229,29 +230,25 @@ void exec_sliced_cmd(const drawcmd_t* cmd) { } void exec_text_cmd(const drawcmd_t* cmd) { - SDL_FRect r = get_dest_with_size(cmd->text.area, cmd->ui); - - float scale = 1.0 / (float)TTF_FontHeight(cmd->text.style.font) * cmd->text.style.size; - int pt_width = r.w * scale; - printf("scale %f ptwidth %d\n", scale, pt_width); - SDL_Surface* s = TTF_RenderText_Solid_Wrapped(cmd->text.style.font, cmd->text.text, cmd->text.fg, pt_width); + SDL_FRect r = cmd->text.area; + int fh = TTF_FontHeight(cmd->text.style.font); + int wrap = (int)(fh * r.w / cmd->text.style.size); + SDL_Surface* s = TTF_RenderText_Solid_Wrapped(cmd->text.style.font, cmd->text.text, cmd->text.fg, wrap); if(s != NULL) { + SDL_Rect srcr = {0,0,s->w, s->h}; SDL_Texture* t = SDL_CreateTextureFromSurface(g_context.renderer, s); SDL_FreeSurface(s); - float ratio = (float)s->w / (float)pt_width; - r.w *= ratio; - r.h *= ratio; - printf("r.w %f\n", r.w); - - float ar = r.w / r.h; - float ar2 = (float)s->w / (float)s->h; - SDL_Rect srcr = {0, 0, s->w, s->h}; - if(ar > ar2) { - srcr.h = srcr.w / ar; - } else if(ar < ar2) { - r.h = r.w / ar2; + float asp_dst = r.w / r.h; + float asp_src = (float)srcr.w / (float)srcr.h; + if(asp_src < asp_dst) { + srcr.h = srcr.w * asp_dst; } + + r.w = (float)srcr.w / fh * cmd->text.style.size; + r.h = (float)srcr.h / fh * cmd->text.style.size; + + r = get_dest_with_size(r, cmd->ui); SDL_RenderCopyF(g_context.renderer, t, &srcr, &r); SDL_DestroyTexture(t); } From 3a5ec4a0d1a37ca9627cfc608f601f99e8fc223e Mon Sep 17 00:00:00 2001 From: Sara Date: Wed, 26 Apr 2023 00:34:11 +0200 Subject: [PATCH 7/7] finished basic text rendering --- src/corelib/render.c | 53 ++++++++++++++++++++++++++++++++++++++------ src/corelib/render.h | 7 +++--- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/corelib/render.c b/src/corelib/render.c index bf56b37..543e7d1 100644 --- a/src/corelib/render.c +++ b/src/corelib/render.c @@ -233,7 +233,7 @@ void exec_text_cmd(const drawcmd_t* cmd) { SDL_FRect r = cmd->text.area; int fh = TTF_FontHeight(cmd->text.style.font); int wrap = (int)(fh * r.w / cmd->text.style.size); - SDL_Surface* s = TTF_RenderText_Solid_Wrapped(cmd->text.style.font, cmd->text.text, cmd->text.fg, wrap); + SDL_Surface* s = TTF_RenderText_Solid_Wrapped(cmd->text.style.font, cmd->text.text, cmd->text.style.color, wrap); if(s != NULL) { SDL_Rect srcr = {0,0,s->w, s->h}; SDL_Texture* t = SDL_CreateTextureFromSurface(g_context.renderer, s); @@ -241,8 +241,8 @@ void exec_text_cmd(const drawcmd_t* cmd) { float asp_dst = r.w / r.h; float asp_src = (float)srcr.w / (float)srcr.h; - if(asp_src < asp_dst) { - srcr.h = srcr.w * asp_dst; + if((float)s->h / fh * cmd->text.style.size > r.h) { + srcr.h = srcr.w / asp_dst; } r.w = (float)srcr.w / fh * cmd->text.style.size; @@ -255,6 +255,45 @@ void exec_text_cmd(const drawcmd_t* cmd) { free(cmd->text.text); } +sprite_t render_text(const char* str, SDL_FRect area, text_style_t style) { + SDL_FRect r = area; + int fh = TTF_FontHeight(style.font); + int wrap = (int)(fh * r.w / style.size); + SDL_Surface* s = TTF_RenderText_Solid_Wrapped(style.font, str, style.color, wrap); + if(s != NULL) { + SDL_Rect srcr = {0,0,s->w, s->h}; + SDL_Texture* t = SDL_CreateTextureFromSurface(g_context.renderer, s); + SDL_FreeSurface(s); + + float asp_dst = r.w / r.h; + float asp_src = (float)srcr.w / (float)srcr.h; + if((float)s->h / fh * style.size > r.h) { + srcr.h = srcr.w / asp_dst; + } + + r.w = (float)srcr.w / fh * style.size; + r.h = (float)srcr.h / fh * style.size; + + return (sprite_t) { + .depth=RLAYER_SPRITES, + .origin={0,0}, + .rot=0, + .sx=area.w, .sy=area.h, + .x=area.x, .y=area.y, + .texture=t, + .uv=srcr, + }; + } + return (sprite_t) { + .depth=0, + .origin={0,0}, .rot=0, + .sx=0, .sy=0, + .texture=NULL, + .uv={0,0,0,0}, + .x=0,.y=0 + }; +} + typedef void(*drawcmd_delegate)(const drawcmd_t*); drawcmd_delegate const drawcmd_funcs[] = { &exec_sprite_cmd, @@ -358,12 +397,11 @@ void draw_sliced(const nineslice_t *sliced) { draw(&d); } -void draw_text(const char *str, SDL_FRect area, text_style_t style, SDL_Color font_color, depth_t depth) { +void draw_text(const char *str, SDL_FRect area, text_style_t style, depth_t depth) { int len = strlen(str); textarea_t t = { .text = calloc(len+1, sizeof(char)), .area = area, - .fg = font_color, .style = style, }; strcpy(t.text, str); @@ -425,11 +463,12 @@ sprite_t sprite_from_spritesheet(spritesheet_t *sheet, int index) { }; } -text_style_t make_text_style(const char *font, int dpi, float size) { +text_style_t make_text_style(const char *font, SDL_Color color, int dpi, float size) { TTF_Font* fnt = get_font(font, dpi); return (text_style_t){ .font = fnt, - .size = size + .size = size, + .color = color }; } diff --git a/src/corelib/render.h b/src/corelib/render.h index eacb08d..62ce38f 100644 --- a/src/corelib/render.h +++ b/src/corelib/render.h @@ -24,6 +24,7 @@ typedef enum drawcmdtype_t { typedef struct text_style_t { TTF_Font* font; float size; + SDL_Color color; } text_style_t; typedef struct spritesheet_t { @@ -43,7 +44,6 @@ typedef struct nineslice_t { typedef struct textarea_t { char* text; text_style_t style; - SDL_Color fg; SDL_FRect area; } textarea_t; @@ -91,15 +91,16 @@ extern void clear_buffer(); extern void swap_buffer(); extern void draw(const drawcmd_t* cmd); +extern sprite_t render_text(const char* str, SDL_FRect area, text_style_t style); extern void draw_sprite(const sprite_t* sprite); extern void draw_rect(const rectshape_t* rect); extern void draw_sliced(const nineslice_t* sliced); -extern void draw_text(const char* str, SDL_FRect area, text_style_t style, SDL_Color font_color, depth_t depth); +extern void draw_text(const char* str, SDL_FRect area, text_style_t style, depth_t depth); extern spritesheet_t make_spritesheet(const char* file, int tile_width, int tile_height); extern nineslice_t make_nineslice(const char* file, int corner_px, float radius); extern sprite_t make_sprite(const char* file, float x, float y); extern sprite_t sprite_from_spritesheet(spritesheet_t* sheet, int index); -extern text_style_t make_text_style(const char* font, int dpi, float size); +extern text_style_t make_text_style(const char* font, SDL_Color color, int dpi, float size); extern SDL_Rect get_srcrect_from(spritesheet_t* sheet, int index); extern void set_active_view(const view_t* view);