font: Replace stateful font_select() with explicit parameter

The font module kept a global "currently selected font" set by
font_select() and implicitly used when drawing. Make it stateless by
introducing a FontSpec {type, weight, size} that font_render_text() /
font_draw_text() and gfx_drawString() take directly.

Make FontWeight a two-valued enum and normalize the 1-9 weight to it
in commandZB().

Removes font_select(), ags_setFont() and ags_setFontWithWeight().
This commit is contained in:
kichikuou
2026-06-24 16:11:49 +09:00
parent c4026f9eb1
commit 50d05e5b56
13 changed files with 74 additions and 80 deletions
+4 -8
View File
@@ -85,8 +85,8 @@ static void draw_log() {
// ページ位置情報
len = snprintf(pinfo, sizeof(pinfo) -1, "%d/%d", curline, list_length(sact.log));
ags_setFont(FONT_GOTHIC, INDEX_FONTSIZE);
gfx_drawString(main_surface->w - INDEX_FONTSIZE * len / 2, 0, pinfo, 255);
gfx_drawString(main_surface->w - INDEX_FONTSIZE * len / 2, 0, pinfo, 255,
(FontSpec){ .size = INDEX_FONTSIZE });
// 表示始め位置
node = list_nth(sact.log, list_length(sact.log) - curline);
@@ -97,12 +97,8 @@ static void draw_log() {
if (0 == strcmp(str, "\n")) {
SDL_BlitSurface(hline, NULL, main_surface, &(SDL_Rect){0, y + FONTSIZE/2, main_surface->w, 3});
} else {
if (cur < 6) {
ags_setFont(FONT_MINCHO, FONTSIZE);
} else {
ags_setFont(FONT_GOTHIC, FONTSIZE);
}
gfx_drawString(0, y, str, 255);
FontSpec font_spec = { .type = cur < 6 ? FONT_MINCHO : FONT_GOTHIC, .size = FONTSIZE };
gfx_drawString(0, y, str, 255, font_spec);
}
y += FONTSIZE;
cur--;
+1 -2
View File
@@ -66,8 +66,7 @@ void dt_setfont(FontType type, int size) {
* @return: 実際に描画した幅
*/
int dt_drawtext_col(SDL_Surface *sf, int x, int y, char *buf, int r, int g, int b) {
ags_setFont(ftype, fsize);
SDL_Surface *glyph = ags_drawStringToSurface(buf, r, g, b);
SDL_Surface *glyph = ags_drawStringToSurface(buf, r, g, b, (FontSpec){ .type = ftype, .size = fsize });
if (glyph == NULL) return 0;
SDL_Rect rect = {x, y, glyph->w, glyph->h};
+2 -4
View File
@@ -220,8 +220,7 @@ void scg_create_text(int wNumCG, int wSize, int wR, int wG, int wB, int wText) {
// 勝手に出ていいのかな?
if (svar_length(wText) == 0) return;
ags_setFont(FONT_GOTHIC, wSize);
SDL_Surface *glyph = ags_drawStringToSurface(svar_get(wText), wR, wG, wB);
SDL_Surface *glyph = ags_drawStringToSurface(svar_get(wText), wR, wG, wB, (FontSpec){ .size = wSize });
SDL_Surface *sf = SDL_CreateRGBSurfaceWithFormat(0, glyph->w, wSize, 32, SDL_PIXELFORMAT_ARGB8888);
SDL_SetSurfaceBlendMode(glyph, SDL_BLENDMODE_NONE);
@@ -245,8 +244,7 @@ void scg_create_textnum(int wNumCG, int wSize, int wR, int wG, int wB, int wFigs
}
sprintf(s, ss, wValue);
ags_setFont(FONT_GOTHIC, wSize);
SDL_Surface *glyph = ags_drawStringToSurface(s, wR, wG, wB);
SDL_Surface *glyph = ags_drawStringToSurface(s, wR, wG, wB, (FontSpec){ .size = wSize });
SDL_Surface *sf = SDL_CreateRGBSurfaceWithFormat(0, glyph->w, wSize, 32, SDL_PIXELFORMAT_ARGB8888);
SDL_SetSurfaceBlendMode(glyph, SDL_BLENDMODE_NONE);
+22 -27
View File
@@ -392,7 +392,9 @@ void ags_delRegion(void *region) {
gfx_delRegion(region);
}
int ags_drawString(int x, int y, const char *src, int col, SDL_Rect *rect_out) {
int ags_drawString(int x, int y, const char *src, int col, int size, SDL_Rect *rect_out) {
FontSpec font = { nact->ags.font_type, nact->ags.font_weight, size };
if (!ags_check_param_xy(&x, &y)) {
if (rect_out) {
rect_out->x = x;
@@ -411,46 +413,46 @@ int ags_drawString(int x, int y, const char *src, int col, SDL_Rect *rect_out) {
adj.x = 0; adj.y = 0; adj.w = 0; adj.h = 0;
break;
case TEXT_DECORATION_DROP_SHADOW_BOTTOM:
gfx_drawString(x, y +1, utf8, nact->ags.text_decoration_color);
gfx_drawString(x, y +1, utf8, nact->ags.text_decoration_color, font);
adj.x = 0; adj.y = 0; adj.w = 0; adj.h = 1;
break;
case TEXT_DECORATION_DROP_SHADOW_RIGHT:
gfx_drawString(x +1, y, utf8, nact->ags.text_decoration_color);
gfx_drawString(x +1, y, utf8, nact->ags.text_decoration_color, font);
adj.x = 0; adj.y = 0; adj.w = 1; adj.h = 0;
break;
case TEXT_DECORATION_DROP_SHADOW_BOTTOM_RIGHT:
gfx_drawString(x +1, y +1, utf8, nact->ags.text_decoration_color);
gfx_drawString(x +1, y +1, utf8, nact->ags.text_decoration_color, font);
adj.x = 0; adj.y = 0; adj.w = 1; adj.h = 1;
break;
case TEXT_DECORATION_OUTLINE:
gfx_drawString(x -1, y, utf8, nact->ags.text_decoration_color);
gfx_drawString(x +1, y, utf8, nact->ags.text_decoration_color);
gfx_drawString(x, y -1, utf8, nact->ags.text_decoration_color);
gfx_drawString(x, y +1, utf8, nact->ags.text_decoration_color);
gfx_drawString(x -1, y, utf8, nact->ags.text_decoration_color, font);
gfx_drawString(x +1, y, utf8, nact->ags.text_decoration_color, font);
gfx_drawString(x, y -1, utf8, nact->ags.text_decoration_color, font);
gfx_drawString(x, y +1, utf8, nact->ags.text_decoration_color, font);
adj.x = -1; adj.y = -1; adj.w = 2; adj.h = 2;
break;
case TEXT_DECORATION_BOLD_HORIZONTAL:
gfx_drawString(x +1, y, utf8, col);
gfx_drawString(x +1, y, utf8, col, font);
adj.x = 0; adj.y = 0; adj.w = 1; adj.h = 0;
break;
case TEXT_DECORATION_BOLD_VERTICAL:
gfx_drawString(x, y +1, utf8, col);
gfx_drawString(x, y +1, utf8, col, font);
adj.x = 0; adj.y = 0; adj.w = 0; adj.h = 1;
break;
case TEXT_DECORATION_BOLD_HORIZONTAL_VERTICAL:
gfx_drawString(x +1, y +1, utf8, col);
gfx_drawString(x +1, y +1, utf8, col, font);
adj.x = 0; adj.y = 0; adj.w = 1; adj.h = 1;
break;
case TEXT_DECORATION_DROP_SHADOW_OUTLINE:
gfx_drawString(x -1, y , utf8, nact->ags.text_decoration_color);
gfx_drawString(x +1, y , utf8, nact->ags.text_decoration_color);
gfx_drawString(x , y -1, utf8, nact->ags.text_decoration_color);
gfx_drawString(x , y +1, utf8, nact->ags.text_decoration_color);
gfx_drawString(x +2, y +2, utf8, nact->ags.text_decoration_color);
gfx_drawString(x -1, y , utf8, nact->ags.text_decoration_color, font);
gfx_drawString(x +1, y , utf8, nact->ags.text_decoration_color, font);
gfx_drawString(x , y -1, utf8, nact->ags.text_decoration_color, font);
gfx_drawString(x , y +1, utf8, nact->ags.text_decoration_color, font);
gfx_drawString(x +2, y +2, utf8, nact->ags.text_decoration_color, font);
adj.x = -1; adj.y = -1; adj.w = 3; adj.h = 3;
break;
}
SDL_Rect r = gfx_drawString(x, y, utf8, col);
SDL_Rect r = gfx_drawString(x, y, utf8, col, font);
if (rect_out) {
rect_out->x = r.x + adj.x;
rect_out->y = r.y + adj.y;
@@ -461,9 +463,10 @@ int ags_drawString(int x, int y, const char *src, int col, SDL_Rect *rect_out) {
return r.w;
}
SDL_Surface *ags_drawStringToSurface(const char *str, int r, int g, int b) {
SDL_Surface *ags_drawStringToSurface(const char *str, int r, int g, int b, FontSpec font) {
char *utf8 = toUTF8(str);
SDL_Surface *sf = font_get_glyph(utf8, r, g, b);
SDL_Color color = {r, g, b, 255};
SDL_Surface *sf = font_render_text(font, utf8, color);
free(utf8);
return sf;
}
@@ -684,14 +687,6 @@ void ags_whiteOut(int rate, bool flag) {
}
}
void ags_setFont(FontType type, int size) {
font_select(type, size, FONT_WEIGHT_NORMAL);
}
void ags_setFontWithWeight(FontType type, int size, int weight) {
font_select(type, size, weight);
}
void ags_setTextDecorationType(TextDecorationType type) {
nact->ags.text_decoration_type = type;
}
+3 -5
View File
@@ -123,7 +123,7 @@ struct _ags {
void (*eventcb)(agsevent_t *e); /* deliver event */
FontType font_type;
int font_weight;
FontWeight font_weight;
TextDecorationType text_decoration_type;
int text_decoration_color;
@@ -181,7 +181,7 @@ extern void ags_restoreRegion(void *region, int x, int y);
extern void ags_putRegion(void *region, int x, int y);
extern void ags_delRegion(void *region);
extern int ags_drawString(int x, int y, const char *src, int col, SDL_Rect *rect_out);
extern int ags_drawString(int x, int y, const char *src, int col, int size, SDL_Rect *rect_out);
extern void ags_drawCg(cgdata *cg, int x, int y, int brightness, int sprite_color, bool alpha_blend);
extern void ags_copyArea_shadow(int sx, int sy, int w, int h, int dx, int dy);
@@ -209,11 +209,9 @@ extern void ags_whiteIn(int rate, bool flg);
extern void ags_whiteOut(int rate, bool flg);
/* フォント関連 */
extern void ags_setFont(FontType type, int size);
extern void ags_setFontWithWeight(FontType type, int size, int weight);
extern void ags_setTextDecorationType(TextDecorationType type);
extern void ags_setTextDecorationColor(int color);
extern SDL_Surface *ags_drawStringToSurface(const char *str, int r, int g, int b);
extern SDL_Surface *ags_drawStringToSurface(const char *str, int r, int g, int b, FontSpec font);
/* カーソル関係 */
extern void ags_setCursorType(int type);
+1 -1
View File
@@ -107,7 +107,7 @@ void commandZB() {
int weight = getCaliValue();
if (nact->ags.enable_zb)
nact->ags.font_weight = weight;
nact->ags.font_weight = weight > 5 ? FONT_WEIGHT_BOLD : FONT_WEIGHT_NORMAL;
TRACE("ZB %d:", weight);
}
+4 -3
View File
@@ -54,14 +54,16 @@ static void redraw() {
.h = input->rect.h - YMARGIN * 2,
};
const FontSpec font = { .size = input->params->h };
if (*input->text) {
int w = gfx_drawString(r.x, r.y, input->text, fgcolor).w;
int w = gfx_drawString(r.x, r.y, input->text, fgcolor, font).w;
r.x += w;
r.w -= w;
}
if (*input->composingText) {
int w = gfx_drawString(r.x, r.y, input->composingText, fgcolor).w;
int w = gfx_drawString(r.x, r.y, input->composingText, fgcolor, font).w;
ags_fillRectangle(r.x, r.y + r.h, w, 2, fgcolor); // underline
}
@@ -152,7 +154,6 @@ bool edit_string(INPUTSTRING_PARAM *p) {
SDL_StartTextInput();
void *saved_region = ags_saveRegion(s.rect.x, s.rect.y, s.rect.w, s.rect.h);
ags_setFont(FONT_GOTHIC, p->h);
redraw();
event_custom_handler = handle_event;
+17 -14
View File
@@ -48,8 +48,6 @@ typedef struct {
static FontTable fonttbl[FONTTABLEMAX];
static int fontcnt = 0;
static FontTable *fontset;
static struct {
bool antialiase_on;
const char *name[FONTTYPEMAX];
@@ -79,10 +77,15 @@ static FontTable *font_lookup(int size, FontType type) {
return NULL;
}
void font_select(FontType type, int size, int weight) {
// Resolve a (type, size) pair to a TTF_Font, opening and caching it on first
// use, and apply the requested weight. Returns NULL for an invalid type.
static FontTable *font_resolve(FontSpec font) {
FontType type = font.type;
int size = font.size;
if (type >= FONTTYPEMAX) {
WARNING("Invalid font type %d", type);
return;
return NULL;
}
FontTable *tbl;
@@ -107,21 +110,20 @@ void font_select(FontType type, int size, int weight) {
#endif
if (!fs)
SYSERROR("Cannot open font %s", this.name[type]);
font_insert(size, type, fs);
fontset = &fonttbl[fontcnt - 1];
} else {
fontset = tbl;
tbl = &fonttbl[fontcnt - 1];
}
TTF_SetFontStyle(fontset->id, weight > 5 ? TTF_STYLE_BOLD : TTF_STYLE_NORMAL);
TTF_SetFontStyle(tbl->id, font.weight == FONT_WEIGHT_BOLD ? TTF_STYLE_BOLD : TTF_STYLE_NORMAL);
return tbl;
}
SDL_Surface *font_get_glyph(const char *str_utf8, int r, int g, int b) {
SDL_Surface *font_render_text(FontSpec font, const char *str_utf8, SDL_Color color) {
FontTable *fontset = font_resolve(font);
if (!fontset)
return NULL;
SDL_Surface *fs;
SDL_Color color = {r, g, b, 255};
fs = TTF_RenderUTF8_Blended(fontset->id, str_utf8, color);
if (!fs)
WARNING("Text rendering failed: %s", TTF_GetError());
@@ -167,16 +169,17 @@ static void gfx_drawAntiAlias_8bpp(int dstx, int dsty, SDL_Surface *src, uint8_t
}
}
SDL_Rect font_draw_glyph(int x, int y, const char *str_utf8, uint8_t cl) {
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.
+12 -5
View File
@@ -34,16 +34,23 @@ typedef enum {
} FontType;
#define FONTTYPEMAX 2
#define FONT_WEIGHT_NORMAL 4
#define FONT_WEIGHT_BOLD 7
typedef enum {
FONT_WEIGHT_NORMAL,
FONT_WEIGHT_BOLD,
} FontWeight;
typedef struct {
FontType type;
FontWeight weight;
int size;
} FontSpec;
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 void font_select(FontType type, int size, int weight);
extern struct SDL_Surface *font_get_glyph(const char *str_utf8, int r, int g, int b);
extern SDL_Rect font_draw_glyph(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);
extern SDL_Rect font_draw_text(FontSpec font, int x, int y, const char *str_utf8, uint8_t col);
#ifdef __EMSCRIPTEN__
extern bool load_mincho_font(void);
+1 -1
View File
@@ -56,7 +56,7 @@ void gfx_fillRectangleRGB(int x, int y, int w, int h, uint8_t r, uint8_t g, uint
void gfx_fillCircle(int left, int top, int diameter, uint8_t c);
void gfx_drawLine(int x1, int y1, int x2, int y2, uint8_t c);
SDL_Rect gfx_floodFill(int x, int y, int col);
SDL_Rect gfx_drawString(int x, int y, const char *str_utf8, uint8_t col);
SDL_Rect gfx_drawString(int x, int y, const char *str_utf8, uint8_t col, FontSpec font);
void gfx_copyArea(int sx,int sy, int w, int h, int dx, int dy);
void gfx_copyAreaSP(int sx, int sy, int w, int h, int dx, int dy, uint8_t sp);
void gfx_wrapColor(int sx, int sy, int w, int h, uint8_t cl, int rate);
+2 -2
View File
@@ -267,9 +267,9 @@ int gfx_nearest_color(int r, int g, int b) {
return col;
}
SDL_Rect gfx_drawString(int x, int y, const char *str_utf8, uint8_t col) {
SDL_Rect gfx_drawString(int x, int y, const char *str_utf8, uint8_t col, FontSpec font) {
gfx_pal_check();
return font_draw_glyph(x, y, str_utf8, col);
return font_draw_text(font, x, y, str_utf8, col);
}
/*
+2 -4
View File
@@ -123,10 +123,8 @@ void msg_putMessage(const char *m) {
// fprintf(stdout, "x=%d, y = %d, msg=%s\n", msgcur.x,msgcur.y,msg);
if (!msg.mg_dspMsg) return;
ags_setFontWithWeight(nact->ags.font_type, msg.MsgFontSize, nact->ags.font_weight);
SDL_Rect drawn;
msgcur.x += ags_drawString(msgcur.x, msgcur.y, m, msg.MsgFontColor, &drawn);
msgcur.x += ags_drawString(msgcur.x, msgcur.y, m, msg.MsgFontColor, msg.MsgFontSize, &drawn);
if (nact->messagewait_enable && nact->messagewait_time > 0 &&
!nact->messagewait_cancelled && !msgskip_isSkipping()) {
@@ -278,7 +276,7 @@ void msg_hitAnyKey() {
SDL_Rect r;
int x = msg.win->x + msg.win->width - msg.MsgFontSize;
int y = msg.win->y + msg.win->height - msg.MsgFontSize;
ags_drawString(x, y, prompt[nact->encoding], msg.HitAnyKeyMsgColor, &r);
ags_drawString(x, y, prompt[nact->encoding], msg.HitAnyKeyMsgColor, msg.MsgFontSize, &r);
ags_updateArea(r.x, r.y, r.w, r.h);
}
+3 -4
View File
@@ -301,10 +301,9 @@ static void init_selwindow() {
NOTICE("frameType is Default");
break;
}
ags_setFontWithWeight(nact->ags.font_type, sel.MsgFontSize, nact->ags.font_weight);
for (i = 0; i < regnum; i++) {
TRACE_MESSAGE("%d:%s\n", i +1, elm[i]);
ags_drawString(r.x +2, r.y + i * (sel.MsgFontSize +2) +1, elm[i], sel.MsgFontColor, NULL);
ags_drawString(r.x +2, r.y + i * (sel.MsgFontSize +2) +1, elm[i], sel.MsgFontColor, sel.MsgFontSize, NULL);
}
ags_updateArea(saveArea.x, saveArea.y, saveArea.w, saveArea.h);
@@ -390,7 +389,7 @@ static void encloseElement(int sw, int no) {
lineEncloseElement(r, sel.WinBackgroundColor, false); break;
case 2:
ags_fillRectangle(r->x, r->y, r->w +2, r->h +2, sel.WinBackgroundColor);
ags_drawString(r->x +2, r->y +1, elm[no], sel.MsgFontColor, NULL);
ags_drawString(r->x +2, r->y +1, elm[no], sel.MsgFontColor, sel.MsgFontSize, NULL);
ags_updateArea(r->x, r->y, r->w +2, r->h +2);
break;
default:
@@ -409,7 +408,7 @@ static void encloseElement(int sw, int no) {
lineEncloseElement(r, 255, false); break;
case 2:
ags_fillRectangle(r->x, r->y, r->w +2, r->h +2, sel.MsgFontColor);
ags_drawString(r->x +2, r->y +1, elm[no], sel.WinBackgroundColor, NULL);
ags_drawString(r->x +2, r->y +1, elm[no], sel.WinBackgroundColor, sel.MsgFontSize, NULL);
ags_updateArea(r->x, r->y, r->w +2, r->h +2);
break;
default: