diff --git a/modules/SACT/sactlog.c b/modules/SACT/sactlog.c index 6391c62..02156a1 100644 --- a/modules/SACT/sactlog.c +++ b/modules/SACT/sactlog.c @@ -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--; diff --git a/modules/lib/drawtext.c b/modules/lib/drawtext.c index de87d23..e3ea50b 100644 --- a/modules/lib/drawtext.c +++ b/modules/lib/drawtext.c @@ -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}; diff --git a/modules/lib/sactcg.c b/modules/lib/sactcg.c index e5d7f8b..76f1539 100644 --- a/modules/lib/sactcg.c +++ b/modules/lib/sactcg.c @@ -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); diff --git a/src/ags.c b/src/ags.c index 1b7c452..457776f 100644 --- a/src/ags.c +++ b/src/ags.c @@ -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; } diff --git a/src/ags.h b/src/ags.h index 2ab8035..abac5d4 100644 --- a/src/ags.h +++ b/src/ags.h @@ -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); diff --git a/src/cmdz.c b/src/cmdz.c index 67c66bd..489f14b 100644 --- a/src/cmdz.c +++ b/src/cmdz.c @@ -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); } diff --git a/src/editor.c b/src/editor.c index e0b1d5d..5a7c1b5 100644 --- a/src/editor.c +++ b/src/editor.c @@ -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; diff --git a/src/font.c b/src/font.c index a2fb6c7..81ce15b 100644 --- a/src/font.c +++ b/src/font.c @@ -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. diff --git a/src/font.h b/src/font.h index ddd5de6..c6c21d3 100644 --- a/src/font.h +++ b/src/font.h @@ -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); diff --git a/src/gfx.h b/src/gfx.h index c5c6e69..825850a 100644 --- a/src/gfx.h +++ b/src/gfx.h @@ -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); diff --git a/src/gfx_draw.c b/src/gfx_draw.c index 243c0af..298320d 100644 --- a/src/gfx_draw.c +++ b/src/gfx_draw.c @@ -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); } /* diff --git a/src/message.c b/src/message.c index f4334d7..9bffdd7 100644 --- a/src/message.c +++ b/src/message.c @@ -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); } diff --git a/src/selection.c b/src/selection.c index 4f022ea..ea1b39d 100644 --- a/src/selection.c +++ b/src/selection.c @@ -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: