From 205004086bf69f3ce34f79fb07dc04da3ee2e9c3 Mon Sep 17 00:00:00 2001 From: kichikuou Date: Fri, 4 Sep 2026 17:33:25 +0900 Subject: [PATCH] Move drawing text to the screen out of font.c This makes font.c unit-testable. --- src/ags.c | 2 +- src/font.c | 58 ++++---------------------------------------------- src/font.h | 3 +-- src/gfx_draw.c | 38 ++++++++++++++++++++++++++++++++- src/modal.c | 2 +- 5 files changed, 44 insertions(+), 59 deletions(-) diff --git a/src/ags.c b/src/ags.c index 7dd7ec0..285d2e3 100644 --- a/src/ags.c +++ b/src/ags.c @@ -479,7 +479,7 @@ int ags_drawString(int x, int y, const char *src, int col, int size, SDL_Rect *r SDL_Surface *ags_drawStringToSurface(const char *str, int r, int g, int b, FontSpec font) { char *utf8 = toUTF8(str); SDL_Color color = {r, g, b, 255}; - SDL_Surface *sf = font_render_text(font, utf8, color); + SDL_Surface *sf = font_render_text(font, utf8, color, true); free(utf8); return sf; } diff --git a/src/font.c b/src/font.c index e35105c..c97f1fd 100644 --- a/src/font.c +++ b/src/font.c @@ -35,8 +35,6 @@ #include "portab.h" #include "system.h" #include "font.h" -#include "gfx.h" -#include "hacks.h" typedef struct { int size; @@ -118,13 +116,14 @@ static FontTable *font_resolve(FontSpec font) { return tbl; } -SDL_Surface *font_render_text(FontSpec font, const char *str_utf8, SDL_Color color) { +SDL_Surface *font_render_text(FontSpec font, const char *str_utf8, SDL_Color color, bool antialias) { FontTable *fontset = font_resolve(font); if (!fontset) return NULL; - SDL_Surface *fs; - fs = TTF_RenderUTF8_Blended(fontset->id, str_utf8, color); + SDL_Surface *fs = antialias + ? TTF_RenderUTF8_Blended(fontset->id, str_utf8, color) + : TTF_RenderUTF8_Solid(fontset->id, str_utf8, color); if (!fs) WARNING("Text rendering failed: %s", TTF_GetError()); @@ -155,55 +154,6 @@ void font_measure_text(FontSpec font, const char *str_utf8, int len, int *w, int } } -SDL_Rect font_draw_text(FontSpec font, int x, int y, const char *str_utf8, uint8_t cl) { - SDL_Surface *fs; - SDL_Rect r_src, r_dst = {}; - int w, h; - - if (!*str_utf8) - return r_dst; - FontTable *fontset = font_resolve(font); - if (!fontset) - return r_dst; - - bool antialias = this.antialiase_on; - // The post-effect in Rance 3 opening does not work properly if colors other - // than the specified text color (32) are used. - // https://github.com/kichikuou/xsystem35-sdl2/issues/54 - // In Rance 3, text color 32 is only used in the opening. - if ((game_id == GAME_RANCE3 || game_id == GAME_RANCE3_ENG) && cl == 32) - antialias = false; - - SDL_Color color = gfx_getPaletteColor(cl); - if (antialias) - fs = TTF_RenderUTF8_Blended(fontset->id, str_utf8, color); - else - fs = TTF_RenderUTF8_Solid(fontset->id, str_utf8, color); - if (!fs) { - WARNING("Text rendering failed: %s", TTF_GetError()); - return r_dst; - } - - TTF_SizeUTF8(fontset->id, str_utf8, &w, &h); - // Center vertically to the box. - y -= (TTF_FontHeight(fontset->id) - fontset->size) / 2; - r_dst = (SDL_Rect){x, y, w, h}; - - if (main_surface->format->BitsPerPixel == 8 && antialias) { - gfx_drawAntiAlias_8bpp(x, y, fs, cl); - } else { - r_src = (SDL_Rect){0, 0, w, h}; - SDL_BlitSurface(fs, &r_src, main_surface, &r_dst); - } - - SDL_FreeSurface(fs); - if (r_dst.y < 0) { - r_dst.h += r_dst.y; - r_dst.y = 0; - } - return r_dst; -} - void font_init(void) { this.antialiase_on = false; diff --git a/src/font.h b/src/font.h index 02f4f4d..e2d7f0a 100644 --- a/src/font.h +++ b/src/font.h @@ -49,8 +49,7 @@ extern void font_init(void); extern void font_set_name_and_index(FontType type, const char *name, int index); extern void font_set_antialias(bool enable); extern bool font_get_antialias(void); -extern struct SDL_Surface *font_render_text(FontSpec font, const char *str_utf8, SDL_Color color); -extern SDL_Rect font_draw_text(FontSpec font, int x, int y, const char *str_utf8, uint8_t col); +extern struct SDL_Surface *font_render_text(FontSpec font, const char *str_utf8, SDL_Color color, bool antialias); extern void font_measure_text(FontSpec font, const char *str_utf8, int len, int *w, int *h); #ifdef __EMSCRIPTEN__ diff --git a/src/gfx_draw.c b/src/gfx_draw.c index 47d80be..14272dc 100644 --- a/src/gfx_draw.c +++ b/src/gfx_draw.c @@ -38,6 +38,7 @@ #include "gfx_private.h" #include "font.h" #include "ags.h" +#include "hacks.h" #include "image.h" #include "nact.h" #include "modal.h" @@ -317,8 +318,43 @@ void gfx_drawAntiAlias_8bpp(int dstx, int dsty, SDL_Surface *src, uint8_t col) { } SDL_Rect gfx_drawString(int x, int y, const char *str_utf8, uint8_t col, FontSpec font) { + SDL_Rect r_dst = {}; + gfx_pal_check(); - return font_draw_text(font, x, y, str_utf8, col); + if (!*str_utf8) + return r_dst; + + bool antialias = font_get_antialias(); + // The post-effect in Rance 3 opening does not work properly if colors other + // than the specified text color (32) are used. + // https://github.com/kichikuou/xsystem35-sdl2/issues/54 + // In Rance 3, text color 32 is only used in the opening. + if ((game_id == GAME_RANCE3 || game_id == GAME_RANCE3_ENG) && col == 32) + antialias = false; + + SDL_Surface *fs = font_render_text(font, str_utf8, gfx_getPaletteColor(col), antialias); + if (!fs) + return r_dst; + + // Center vertically to the box. + int font_height; + font_measure_text(font, "", -1, NULL, &font_height); + y -= (font_height - font.size) / 2; + r_dst = (SDL_Rect){x, y, fs->w, fs->h}; + + if (main_surface->format->BitsPerPixel == 8 && antialias) { + gfx_drawAntiAlias_8bpp(x, y, fs, col); + } else { + SDL_Rect r_src = {0, 0, fs->w, fs->h}; + SDL_BlitSurface(fs, &r_src, main_surface, &r_dst); + } + + SDL_FreeSurface(fs); + if (r_dst.y < 0) { + r_dst.h += r_dst.y; + r_dst.y = 0; + } + return r_dst; } /* diff --git a/src/modal.c b/src/modal.c index 943435d..5d95a44 100644 --- a/src/modal.c +++ b/src/modal.c @@ -198,7 +198,7 @@ static void render_text(mu_Font font, const char *str, mu_Vec2 pos, mu_Color col if (!*str) return; SDL_Color col = { color.r, color.g, color.b, color.a }; - SDL_Surface *s = font_render_text(*(const FontSpec *)font, str, col); + SDL_Surface *s = font_render_text(*(const FontSpec *)font, str, col, true); if (!s) return; SDL_Texture *t = SDL_CreateTextureFromSurface(gfx_renderer, s);