mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-09-22 22:48:08 +03:00
Improve rendering of fonts with descenders
- ags_drawString() returns a bounding box of the text so that callers can update the screen appropriately. - Use total font height (not only ascent) for vertical positioning.
This commit is contained in:
@@ -383,16 +383,14 @@ void ags_delRegion(void *region) {
|
||||
sdl_delRegion(region);
|
||||
}
|
||||
|
||||
int ags_drawString(int x, int y, const char *src, int col) {
|
||||
int w;
|
||||
|
||||
if (!check_param_xy(&x, &y)) return 0;
|
||||
MyRectangle ags_drawString(int x, int y, const char *src, int col) {
|
||||
if (!check_param_xy(&x, &y)) return (MyRectangle){};
|
||||
|
||||
char *utf8 = toUTF8(src);
|
||||
w = sdl_drawString(x, y, utf8, col);
|
||||
SDL_Rect r = sdl_drawString(x, y, utf8, col);
|
||||
free(utf8);
|
||||
|
||||
return w;
|
||||
return (MyRectangle){r.x, r.y, r.w, r.h};
|
||||
}
|
||||
|
||||
agsurface_t *ags_drawStringToSurface(const char *str) {
|
||||
|
||||
@@ -184,7 +184,7 @@ extern void ags_putRegion(void *region, int x, int y);
|
||||
extern void ags_copyRegion(void *region, int sx, int sy, int w,int h,int dx,int dy);
|
||||
extern void ags_delRegion(void *region);
|
||||
|
||||
extern int ags_drawString(int x, int y, const char *src, int col);
|
||||
extern MyRectangle ags_drawString(int x, int y, const char *src, int col);
|
||||
extern void ags_drawCg8bit(cgdata *cg, int x, int y);
|
||||
extern void ags_drawCg16bit(cgdata *cg, int x, int y);
|
||||
|
||||
|
||||
+15
-8
@@ -119,6 +119,8 @@ static void sdl_drawAntiAlias_8bpp(int dstx, int dsty, SDL_Surface *src, unsigne
|
||||
memset(cache, 0, 256);
|
||||
|
||||
for (int y = 0; y < src->h && dsty + y < sdl_dib->h; y++) {
|
||||
if (dsty + y < 0)
|
||||
continue;
|
||||
BYTE *sp = (BYTE*)src->pixels + y * src->pitch;
|
||||
BYTE *dp = (BYTE*)sdl_dib->pixels + (dsty + y) * sdl_dib->pitch + dstx;
|
||||
for (int x = 0; x < src->w && dstx + x < sdl_dib->w; x++) {
|
||||
@@ -149,15 +151,15 @@ static void sdl_drawAntiAlias_8bpp(int dstx, int dsty, SDL_Surface *src, unsigne
|
||||
SDL_UnlockSurface(sdl_dib);
|
||||
}
|
||||
|
||||
int font_draw_glyph(int x, int y, const char *str_utf8, int cl) {
|
||||
SDL_Rect font_draw_glyph(int x, int y, const char *str_utf8, int cl) {
|
||||
SDL_Surface *fs;
|
||||
SDL_Rect r_src, r_dst;
|
||||
SDL_Rect r_src, r_dst = {};
|
||||
int w, h;
|
||||
|
||||
if (!*str_utf8)
|
||||
return 0;
|
||||
return r_dst;
|
||||
if (!fontset)
|
||||
return 0;
|
||||
return r_dst;
|
||||
|
||||
if (this.antialiase_on) {
|
||||
fs = TTF_RenderUTF8_Blended(fontset->id, str_utf8, sdl_col[cl]);
|
||||
@@ -166,22 +168,27 @@ int font_draw_glyph(int x, int y, const char *str_utf8, int cl) {
|
||||
}
|
||||
if (!fs) {
|
||||
WARNING("Text rendering failed: %s\n", TTF_GetError());
|
||||
return 0;
|
||||
return r_dst;
|
||||
}
|
||||
|
||||
TTF_SizeUTF8(fontset->id, str_utf8, &w, &h);
|
||||
y = max(0, y - (TTF_FontAscent(fontset->id) - fontset->size * 0.9));
|
||||
// Center vertically to the box.
|
||||
y -= (TTF_FontHeight(fontset->id) - fontset->size) / 2;
|
||||
setRect(r_dst, x, y, w, h);
|
||||
|
||||
if (sdl_dib->format->BitsPerPixel == 8 && this.antialiase_on) {
|
||||
sdl_drawAntiAlias_8bpp(x, y, fs, cl);
|
||||
} else {
|
||||
setRect(r_src, 0, 0, w, h);
|
||||
setRect(r_dst, x, y, w, h);
|
||||
SDL_BlitSurface(fs, &r_src, sdl_dib, &r_dst);
|
||||
}
|
||||
|
||||
SDL_FreeSurface(fs);
|
||||
return w;
|
||||
if (r_dst.y < 0) {
|
||||
r_dst.h += r_dst.y;
|
||||
r_dst.y = 0;
|
||||
}
|
||||
return r_dst;
|
||||
}
|
||||
|
||||
void font_init(void) {
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ extern void font_set_antialias(boolean enable);
|
||||
extern boolean font_get_antialias(void);
|
||||
extern void font_select(int type, int size);
|
||||
extern struct SDL_Surface *font_get_glyph(const char *str_utf8);
|
||||
extern int font_draw_glyph(int x, int y, const char *str_utf8, int col);
|
||||
extern SDL_Rect font_draw_glyph(int x, int y, const char *str_utf8, int col);
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
extern int load_mincho_font(void);
|
||||
|
||||
+14
-17
@@ -111,7 +111,6 @@ void msg_setStringDecorationType(int type) {
|
||||
}
|
||||
|
||||
void msg_putMessage(const char *m) {
|
||||
int w;
|
||||
MyRectangle adj;
|
||||
|
||||
if (nextLineIsAfterKaigyou) {
|
||||
@@ -176,18 +175,21 @@ void msg_putMessage(const char *m) {
|
||||
break;
|
||||
}
|
||||
|
||||
w = ags_drawString(msgcur.x, msgcur.y, m, msg.MsgFontColor);
|
||||
MyRectangle drawn = ags_drawString(msgcur.x, msgcur.y, m, msg.MsgFontColor);
|
||||
msgcur.x += drawn.width;
|
||||
drawn.x += adj.x;
|
||||
drawn.y += adj.y;
|
||||
drawn.width += adj.width;
|
||||
drawn.height += adj.height;
|
||||
|
||||
if (nact->messagewait_enable && !nact->messagewait_cancelled && !msgskip_isSkipping()) {
|
||||
int x;
|
||||
for (x = 0; x < w + adj.width; x+=16) {
|
||||
ags_updateArea(msgcur.x + adj.x + x, msgcur.y + adj.y,
|
||||
16, msg.MsgFontSize + adj.height);
|
||||
for (x = 0; x < drawn.width; x+=16) {
|
||||
ags_updateArea(drawn.x + x, drawn.y, 16, drawn.height);
|
||||
if (nact->messagewait_cancel) {
|
||||
if (sys_getInputInfo()) {
|
||||
nact->messagewait_cancelled = TRUE;
|
||||
ags_updateArea(msgcur.x + adj.x, msgcur.y + adj.y,
|
||||
w + adj.width, msg.MsgFontSize + adj.height);
|
||||
ags_updateArea(drawn.x, drawn.y, drawn.width, drawn.height);
|
||||
break;
|
||||
}
|
||||
sdl_sleep(nact->messagewait_time * 10);
|
||||
@@ -195,10 +197,8 @@ void msg_putMessage(const char *m) {
|
||||
nact->callback();
|
||||
}
|
||||
} else {
|
||||
ags_updateArea(msgcur.x + adj.x, msgcur.y + adj.y,
|
||||
w + adj.width, msg.MsgFontSize + adj.height);
|
||||
ags_updateArea(drawn.x, drawn.y, drawn.width, drawn.height);
|
||||
}
|
||||
msgcur.x += w;
|
||||
}
|
||||
|
||||
void msg_nextLine() {
|
||||
@@ -327,18 +327,15 @@ void msg_getMessageLocation(MyPoint *loc) {
|
||||
}
|
||||
|
||||
void msg_hitAnyKey() {
|
||||
int w;
|
||||
const char *prompt[CHARACTER_ENCODING_MAX + 1] = {
|
||||
[SHIFT_JIS] = "\x81\xa5",
|
||||
[UTF8] = "▼",
|
||||
};
|
||||
|
||||
w = ags_drawString(msg.win->x + msg.win->width - msg.MsgFontSize,
|
||||
msg.win->y + msg.win->height - msg.MsgFontSize,
|
||||
prompt[nact->encoding], msg.HitAnyKeyMsgColor);
|
||||
ags_updateArea(msg.win->x + msg.win->width - msg.MsgFontSize,
|
||||
msg.win->y + msg.win->height - msg.MsgFontSize,
|
||||
w, msg.MsgFontSize);
|
||||
MyRectangle r = ags_drawString(msg.win->x + msg.win->width - msg.MsgFontSize,
|
||||
msg.win->y + msg.win->height - msg.MsgFontSize,
|
||||
prompt[nact->encoding], msg.HitAnyKeyMsgColor);
|
||||
ags_updateArea(r.x, r.y, r.width, r.height);
|
||||
}
|
||||
|
||||
static void drawLineFrame(Bcom_WindowInfo *i) {
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ extern void sdl_setPalette(Palette256 *pal, int src, int cnt);
|
||||
extern void sdl_drawRectangle(int x, int y, int w, int h, int cl);
|
||||
extern void sdl_fillRectangle(int x, int y, int w, int h, unsigned long c);
|
||||
extern void sdl_drawLine(int x1, int y1, int x2, int y2, unsigned long col);
|
||||
extern int sdl_drawString(int x, int y, const char *str_utf8, unsigned long col);
|
||||
extern SDL_Rect sdl_drawString(int x, int y, const char *str_utf8, unsigned long col);
|
||||
extern void sdl_copyArea(int sx,int sy, int w, int h, int dx, int dy);
|
||||
extern void sdl_drawTT(int x,int y,int w,int h,const char *bitmap,int ww, boolean antialiased);
|
||||
extern void sdl_copyAreaSP(int sx, int sy, int w, int h, int dx, int dy, int sp);
|
||||
|
||||
+1
-1
@@ -310,7 +310,7 @@ int sdl_nearest_color(int r, int g, int b) {
|
||||
return col;
|
||||
}
|
||||
|
||||
int sdl_drawString(int x, int y, const char *str_utf8, unsigned long col) {
|
||||
SDL_Rect sdl_drawString(int x, int y, const char *str_utf8, unsigned long col) {
|
||||
sdl_pal_check();
|
||||
return font_draw_glyph(x, y, str_utf8, col);
|
||||
}
|
||||
|
||||
+2
-2
@@ -53,13 +53,13 @@ static void redraw() {
|
||||
};
|
||||
|
||||
if (*input->text) {
|
||||
int w = sdl_drawString(r.x, r.y, input->text, fgcolor);
|
||||
int w = sdl_drawString(r.x, r.y, input->text, fgcolor).w;
|
||||
r.x += w;
|
||||
r.w -= w;
|
||||
}
|
||||
|
||||
if (*input->composingText) {
|
||||
int w = sdl_drawString(r.x, r.y, input->composingText, fgcolor);
|
||||
int w = sdl_drawString(r.x, r.y, input->composingText, fgcolor).w;
|
||||
ags_fillRectangle(r.x, r.y + r.h, w, 2, fgcolor); // underline
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -276,7 +276,7 @@ static void init_selwindow() {
|
||||
ags_setFont(FONT_GOTHIC, sel.MsgFontSize);
|
||||
for (i = 0; i < regnum; i++) {
|
||||
DEBUG_MESSAGE("%d:%s\n", i +1, elm[i]);
|
||||
ags_drawString(r.x +2, r.y + i * (sel.MsgFontSize +2) +2, elm[i], sel.MsgFontColor);
|
||||
ags_drawString(r.x +2, r.y + i * (sel.MsgFontSize +2) +1, elm[i], sel.MsgFontColor);
|
||||
}
|
||||
ags_updateArea(saveArea.x, saveArea.y, saveArea.width, saveArea.height);
|
||||
|
||||
@@ -364,7 +364,7 @@ static void encloseElement(int sw, int no) {
|
||||
lineEncloseElement(r, sel.WinBackgroundColor, FALSE); break;
|
||||
case 2:
|
||||
ags_fillRectangle(r->x, r->y, r->width +2, r->height +2, sel.WinBackgroundColor);
|
||||
ags_drawString(r->x +2, r->y +2, elm[no], sel.MsgFontColor);
|
||||
ags_drawString(r->x +2, r->y +1, elm[no], sel.MsgFontColor);
|
||||
ags_updateArea(r->x, r->y, r->width +2, r->height +2);
|
||||
break;
|
||||
default:
|
||||
@@ -383,7 +383,7 @@ static void encloseElement(int sw, int no) {
|
||||
lineEncloseElement(r, 255, FALSE); break;
|
||||
case 2:
|
||||
ags_fillRectangle(r->x, r->y, r->width +2, r->height +2, sel.MsgFontColor);
|
||||
ags_drawString(r->x +2, r->y +2, elm[no], sel.WinBackgroundColor);
|
||||
ags_drawString(r->x +2, r->y +1, elm[no], sel.WinBackgroundColor);
|
||||
ags_updateArea(r->x, r->y, r->width +2, r->height +2);
|
||||
break;
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user