From 7ddfa88c30a1ac18cde6f400343d3fe9fba64fb2 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 24 Oct 2024 09:09:05 -0700 Subject: [PATCH 1/2] Re-added solid text rendering It turns out this is useful for pixel fonts Fixes https://github.com/libsdl-org/SDL_ttf/issues/423 --- docs/README-migration.md | 8 +- examples/showfont.c | 13 ++- examples/testapp.c | 40 +++++---- include/SDL3_ttf/SDL_ttf.h | 138 +++++++++++++++++++++++++++++++ src/SDL_ttf.c | 163 ++++++++++++++++++++++++++++++------- src/SDL_ttf.sym | 3 + 6 files changed, 314 insertions(+), 51 deletions(-) diff --git a/docs/README-migration.md b/docs/README-migration.md index f56e3ece..bb609986 100644 --- a/docs/README-migration.md +++ b/docs/README-migration.md @@ -36,8 +36,6 @@ Several functions have been renamed. We have provided a handy semantic patch to In general we have switched to using UTF8 in the API. Functions which had 3 variants, for Latin-1, UTF-8, and UCS2, now accept UTF-8 text. In addition, those functions now have an optional length parameter which allows you to render substrings. -The solid color rendering functions have been removed in favor of the higher quality shaded and blended functions. - The alpha in background colors is now transparent if it's equal to 0. The following functions have been renamed: @@ -58,12 +56,15 @@ The following functions have been renamed: * TTF_RenderGlyph32_Blended() => TTF_RenderGlyph_Blended() * TTF_RenderGlyph32_LCD() => TTF_RenderGlyph_LCD() * TTF_RenderGlyph32_Shaded() => TTF_RenderGlyph_Shaded() +* TTF_RenderGlyph32_Solid() => TTF_RenderGlyph_Solid() * TTF_RenderUTF8_Blended() => TTF_RenderText_Blended() * TTF_RenderUTF8_Blended_Wrapped() => TTF_RenderText_Blended_Wrapped() * TTF_RenderUTF8_LCD() => TTF_RenderText_LCD() * TTF_RenderUTF8_LCD_Wrapped() => TTF_RenderText_LCD_Wrapped() * TTF_RenderUTF8_Shaded() => TTF_RenderText_Shaded() * TTF_RenderUTF8_Shaded_Wrapped() => TTF_RenderText_Shaded_Wrapped() +* TTF_RenderUTF8_Solid() => TTF_RenderText_Solid() +* TTF_RenderUTF8_Solid_Wrapped() => TTF_RenderText_Solid_Wrapped() * TTF_SetFontScriptName() => TTF_SetFontScript() * TTF_SetFontWrappedAlign() => TTF_SetFontWrapAlignment() * TTF_SizeText() => TTF_GetTextSize() @@ -81,7 +82,6 @@ The following functions have been removed: * TTF_OpenFontIndexDPI() - replaced with TTF_OpenFontWithProperties() * TTF_OpenFontIndexDPIIO() - replaced with TTF_OpenFontWithProperties() * TTF_OpenFontIndexIO() - replaced with TTF_OpenFontWithProperties() -* TTF_RenderGlyph32_Solid() * TTF_RenderGlyph_Solid() * TTF_RenderText_Solid() * TTF_RenderText_Solid_Wrapped() @@ -93,8 +93,6 @@ The following functions have been removed: * TTF_RenderUNICODE_Shaded_Wrapped() * TTF_RenderUNICODE_Solid() * TTF_RenderUNICODE_Solid_Wrapped() -* TTF_RenderUTF8_Solid() -* TTF_RenderUTF8_Solid_Wrapped() * TTF_SizeUNICODE() The following symbols have been renamed: diff --git a/examples/showfont.c b/examples/showfont.c index 244abad1..a9284579 100644 --- a/examples/showfont.c +++ b/examples/showfont.c @@ -40,7 +40,7 @@ #define TTF_SHOWFONT_USAGE \ -"Usage: %s [-textengine surface|renderer] [-shaded] [-blended] [-wrapped] [-b] [-i] [-u] [-s] [-outline size] [-hintlight|-hintmono|-hintnone] [-nokerning] [-wrap] [-align left|center|right] [-fgcol r,g,b,a] [-bgcol r,g,b,a] [-editbox] .ttf [ptsize] [text]\n" +"Usage: %s [-textengine surface|renderer] [-solid] [-shaded] [-blended] [-wrapped] [-b] [-i] [-u] [-s] [-outline size] [-hintlight|-hintmono|-hintnone] [-nokerning] [-wrap] [-align left|center|right] [-fgcol r,g,b,a] [-bgcol r,g,b,a] [-editbox] .ttf [ptsize] [text]\n" typedef enum { @@ -51,6 +51,7 @@ typedef enum typedef enum { + TextRenderSolid, TextRenderShaded, TextRenderBlended } TextRenderMethod; @@ -311,6 +312,9 @@ int main(int argc, char *argv[]) return(1); } } else + if (SDL_strcmp(argv[i], "-solid") == 0) { + rendermethod = TextRenderSolid; + } else if (SDL_strcmp(argv[i], "-shaded") == 0) { rendermethod = TextRenderShaded; } else @@ -511,6 +515,13 @@ int main(int argc, char *argv[]) message = DEFAULT_TEXT; } switch (rendermethod) { + case TextRenderSolid: + if (wrap) { + text = TTF_RenderText_Solid_Wrapped(font, message, 0, *forecol, 0); + } else { + text = TTF_RenderText_Solid(font, message, 0, *forecol); + } + break; case TextRenderShaded: if (wrap) { text = TTF_RenderText_Shaded_Wrapped(font, message, 0, *forecol, *backcol, 0); diff --git a/examples/testapp.c b/examples/testapp.c index 57cd4590..8c364a2c 100644 --- a/examples/testapp.c +++ b/examples/testapp.c @@ -112,7 +112,7 @@ static void help(void) SDL_Log("t : ticks elapsed for 50 rendering"); SDL_Log("d : display normal texture, no screen update, stream texture "); SDL_Log("r : start/stop random test"); - SDL_Log("m : render mode Blended/Shaded"); + SDL_Log("m : render mode Solid/Blended/Shaded"); SDL_Log("x : text engine None/Surface/Renderer"); SDL_Log("n : change direction"); SDL_Log("9/0 : -/+ alpha color fg"); @@ -191,10 +191,10 @@ static int print_elapsed_ticks = 0; static int update_screen_mode = 0; static int save_to_bmp = 0; -/* RENDER_BLENDED = 0, RENDER_SHADED = 1, RENDER_LCD = 2 */ +/* RENDER_SOLID = 0, RENDER_BLENDED = 1, RENDER_SHADED = 2, RENDER_LCD = 3 } */ static int render_mode = -1; static int render_mode_overwrite; -static const char *render_mode_desc[] = { "Blended", "Shaded", "LCD" }; +static const char *render_mode_desc[] = { "Solid", "Blended", "Shaded", "LCD" }; static const int render_mode_count = SDL_arraysize(render_mode_desc); static int textengine_mode = 0; @@ -698,6 +698,10 @@ int main(void) seed=1641805930; replay=1; font_style=9; kerning=1; sdf=1; wrap=0; wrap_size=661; w_align=2; outline=0; curr_size=20; render_mode=3; curr_str=14; curr_font=1777; hinting=1; fg_alpha=65; // light LCD #endif + //seed=1673390190; replay=1; font_style=12; kerning=0; sdf=1; wrap=0; wrap_size=91; w_align=0; outline=0; curr_size=16; render_mode=0; curr_str=14; curr_font=1288; hinting=0; fg_alpha=77; // none Solid + + //seed=1673390190; replay=1; font_style=12; kerning=0; sdf=0; wrap=0; wrap_size=91; w_align=0; outline=0; curr_size=30; render_mode=1; curr_str=14; curr_font=1288; hinting=0; fg_alpha=77; // none Solid + //seed=1673390190; replay=1; font_style=9; kerning=1; sdf=0; wrap=1; wrap_size=94; w_align=2; outline=7; curr_size=42; render_mode=1; curr_str=75; curr_font=1997; hinting=1; fg_alpha=90; // light Blended if (replay) { @@ -957,15 +961,17 @@ int main(void) if (textengine_mode == 0) { - switch (render_mode) - { + switch (render_mode) { case 0: - text_surface = TTF_RenderText_Blended(font, text, 0, textcol); + text_surface = TTF_RenderText_Solid(font, text, 0, textcol); break; case 1: - text_surface = TTF_RenderText_Shaded(font, text, 0, textcol, boardcol); + text_surface = TTF_RenderText_Blended(font, text, 0, textcol); break; case 2: + text_surface = TTF_RenderText_Shaded(font, text, 0, textcol, boardcol); + break; + case 3: #if defined(HAVE_LCD) text_surface = TTF_RenderText_LCD(font, text, 0, textcol, boardcol); #else @@ -996,15 +1002,17 @@ int main(void) } if (textengine_mode == 0) { - switch (render_mode) - { + switch (render_mode) { case 0: - text_surface = TTF_RenderText_Blended(font, text, 0, textcol); + text_surface = TTF_RenderText_Solid(font, text, 0, textcol); break; case 1: - text_surface = TTF_RenderText_Shaded(font, text, 0, textcol, boardcol); + text_surface = TTF_RenderText_Blended(font, text, 0, textcol); break; case 2: + text_surface = TTF_RenderText_Shaded(font, text, 0, textcol, boardcol); + break; + case 3: #if defined(HAVE_LCD) text_surface = TTF_RenderText_LCD(font, text, 0, textcol, boardcol); #else @@ -1047,15 +1055,17 @@ int main(void) } if (textengine_mode == 0) { - switch (render_mode) - { + switch (render_mode) { case 0: - text_surface = TTF_RenderText_Blended_Wrapped(font, text, 0, textcol, wrap_size); + text_surface = TTF_RenderText_Solid_Wrapped(font, text, 0, textcol, wrap_size); break; case 1: - text_surface = TTF_RenderText_Shaded_Wrapped(font, text, 0, textcol, boardcol, wrap_size); + text_surface = TTF_RenderText_Blended_Wrapped(font, text, 0, textcol, wrap_size); break; case 2: + text_surface = TTF_RenderText_Shaded_Wrapped(font, text, 0, textcol, boardcol, wrap_size); + break; + case 3: #if defined(HAVE_LCD) text_surface = TTF_RenderText_LCD_Wrapped(font, text, 0, textcol, boardcol, wrap_size); #else diff --git a/include/SDL3_ttf/SDL_ttf.h b/include/SDL3_ttf/SDL_ttf.h index ab7c492b..9e00cf75 100644 --- a/include/SDL3_ttf/SDL_ttf.h +++ b/include/SDL3_ttf/SDL_ttf.h @@ -757,6 +757,108 @@ typedef enum TTF_Direction TTF_DIRECTION_BTT /* Bottom to Top */ } TTF_Direction; +/** + * Render UTF-8 text at fast quality to a new 8-bit surface. + * + * This function will allocate a new 8-bit, palettized surface. The surface's + * 0 pixel will be the colorkey, giving a transparent background. The 1 pixel + * will be set to the text color. + * + * This will not word-wrap the string; you'll get a surface with a single line + * of text, as long as the string requires. You can use + * TTF_RenderText_Solid_Wrapped() instead if you need to wrap the output to + * multiple lines. + * + * This will not wrap on newline characters. + * + * You can render at other quality levels with TTF_RenderText_Shaded, + * TTF_RenderText_Blended, and TTF_RenderText_LCD. + * + * \param font the font to render with. + * \param text text to render, in UTF-8 encoding. + * \param length the length of the text, in bytes, or 0 for null terminated + * text. + * \param fg the foreground color for the text. + * \returns a new 8-bit, palettized surface, or NULL if there was an error. + * + * \threadsafety This function should be called on the thread that created the + * font. + * + * \since This function is available since SDL_ttf 3.0.0. + * + * \sa TTF_RenderText_Blended + * \sa TTF_RenderText_LCD + * \sa TTF_RenderText_Shaded + * \sa TTF_RenderText_Solid + * \sa TTF_RenderText_Solid_Wrapped + */ +extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Solid(TTF_Font *font, const char *text, size_t length, SDL_Color fg); + +/** + * Render word-wrapped UTF-8 text at fast quality to a new 8-bit surface. + * + * This function will allocate a new 8-bit, palettized surface. The surface's + * 0 pixel will be the colorkey, giving a transparent background. The 1 pixel + * will be set to the text color. + * + * Text is wrapped to multiple lines on line endings and on word boundaries if + * it extends beyond `wrapLength` in pixels. + * + * If wrapLength is 0, this function will only wrap on newline characters. + * + * You can render at other quality levels with TTF_RenderText_Shaded_Wrapped, + * TTF_RenderText_Blended_Wrapped, and TTF_RenderText_LCD_Wrapped. + * + * \param font the font to render with. + * \param text text to render, in UTF-8 encoding. + * \param length the length of the text, in bytes, or 0 for null terminated + * text. + * \param fg the foreground color for the text. + * \param wrapLength the maximum width of the text surface or 0 to wrap on + * newline characters. + * \returns a new 8-bit, palettized surface, or NULL if there was an error. + * + * \threadsafety This function should be called on the thread that created the + * font. + * + * \since This function is available since SDL_ttf 3.0.0. + * + * \sa TTF_RenderText_Blended_Wrapped + * \sa TTF_RenderText_LCD_Wrapped + * \sa TTF_RenderText_Shaded_Wrapped + * \sa TTF_RenderText_Solid + */ +extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Solid_Wrapped(TTF_Font *font, const char *text, size_t length, SDL_Color fg, int wrapLength); + +/** + * Render a single 32-bit glyph at fast quality to a new 8-bit surface. + * + * This function will allocate a new 8-bit, palettized surface. The surface's + * 0 pixel will be the colorkey, giving a transparent background. The 1 pixel + * will be set to the text color. + * + * The glyph is rendered without any padding or centering in the X direction, + * and aligned normally in the Y direction. + * + * You can render at other quality levels with TTF_RenderGlyph_Shaded, + * TTF_RenderGlyph_Blended, and TTF_RenderGlyph_LCD. + * + * \param font the font to render with. + * \param ch the character to render. + * \param fg the foreground color for the text. + * \returns a new 8-bit, palettized surface, or NULL if there was an error. + * + * \threadsafety This function should be called on the thread that created the + * font. + * + * \since This function is available since SDL_ttf 3.0.0. + * + * \sa TTF_RenderGlyph_Blended + * \sa TTF_RenderGlyph_LCD + * \sa TTF_RenderGlyph_Shaded + */ +extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Solid(TTF_Font *font, Uint32 ch, SDL_Color fg); + /** * Set direction to be used for text shaping by a font. * @@ -1057,6 +1159,9 @@ extern SDL_DECLSPEC bool SDLCALL TTF_MeasureString(TTF_Font *font, const char *t * * This will not wrap on newline characters. * + * You can render at other quality levels with TTF_RenderText_Solid, + * TTF_RenderText_Blended, and TTF_RenderText_LCD. + * * \param font the font to render with. * \param text text to render, in UTF-8 encoding. * \param length the length of the text, in bytes, or 0 for null terminated @@ -1073,6 +1178,7 @@ extern SDL_DECLSPEC bool SDLCALL TTF_MeasureString(TTF_Font *font, const char *t * \sa TTF_RenderText_Blended * \sa TTF_RenderText_LCD * \sa TTF_RenderText_Shaded_Wrapped + * \sa TTF_RenderText_Solid */ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Shaded(TTF_Font *font, const char *text, size_t length, SDL_Color fg, SDL_Color bg); @@ -1089,6 +1195,9 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Shaded(TTF_Font *font, * * If wrap_width is 0, this function will only wrap on newline characters. * + * You can render at other quality levels with TTF_RenderText_Solid_Wrapped, + * TTF_RenderText_Blended_Wrapped, and TTF_RenderText_LCD_Wrapped. + * * \param font the font to render with. * \param text text to render, in UTF-8 encoding. * \param length the length of the text, in bytes, or 0 for null terminated @@ -1107,6 +1216,7 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Shaded(TTF_Font *font, * \sa TTF_RenderText_Blended_Wrapped * \sa TTF_RenderText_LCD_Wrapped * \sa TTF_RenderText_Shaded + * \sa TTF_RenderText_Solid_Wrapped */ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Shaded_Wrapped(TTF_Font *font, const char *text, size_t length, SDL_Color fg, SDL_Color bg, int wrap_width); @@ -1121,6 +1231,9 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Shaded_Wrapped(TTF_Font * The glyph is rendered without any padding or centering in the X direction, * and aligned normally in the Y direction. * + * You can render at other quality levels with TTF_RenderGlyph_Solid, + * TTF_RenderGlyph_Blended, and TTF_RenderGlyph_LCD. + * * \param font the font to render with. * \param ch the codepoint to render. * \param fg the foreground color for the text. @@ -1134,6 +1247,7 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Shaded_Wrapped(TTF_Font * * \sa TTF_RenderGlyph_Blended * \sa TTF_RenderGlyph_LCD + * \sa TTF_RenderGlyph_Solid */ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Shaded(TTF_Font *font, Uint32 ch, SDL_Color fg, SDL_Color bg); @@ -1151,6 +1265,9 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Shaded(TTF_Font *font, * * This will not wrap on newline characters. * + * You can render at other quality levels with TTF_RenderText_Solid, + * TTF_RenderText_Shaded, and TTF_RenderText_LCD. + * * \param font the font to render with. * \param text text to render, in UTF-8 encoding. * \param length the length of the text, in bytes, or 0 for null terminated @@ -1166,6 +1283,7 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Shaded(TTF_Font *font, * \sa TTF_RenderText_Blended_Wrapped * \sa TTF_RenderText_LCD * \sa TTF_RenderText_Shaded + * \sa TTF_RenderText_Solid */ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Blended(TTF_Font *font, const char *text, size_t length, SDL_Color fg); @@ -1181,6 +1299,9 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Blended(TTF_Font *font, * * If wrap_width is 0, this function will only wrap on newline characters. * + * You can render at other quality levels with TTF_RenderText_Solid_Wrapped, + * TTF_RenderText_Shaded_Wrapped, and TTF_RenderText_LCD_Wrapped. + * * \param font the font to render with. * \param text text to render, in UTF-8 encoding. * \param length the length of the text, in bytes, or 0 for null terminated @@ -1198,6 +1319,7 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Blended(TTF_Font *font, * \sa TTF_RenderText_Blended * \sa TTF_RenderText_LCD_Wrapped * \sa TTF_RenderText_Shaded_Wrapped + * \sa TTF_RenderText_Solid_Wrapped */ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Blended_Wrapped(TTF_Font *font, const char *text, size_t length, SDL_Color fg, int wrap_width); @@ -1211,6 +1333,9 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Blended_Wrapped(TTF_Fon * The glyph is rendered without any padding or centering in the X direction, * and aligned normally in the Y direction. * + * You can render at other quality levels with TTF_RenderGlyph_Solid, + * TTF_RenderGlyph_Shaded, and TTF_RenderGlyph_LCD. + * * \param font the font to render with. * \param ch the codepoint to render. * \param fg the foreground color for the text. @@ -1223,6 +1348,7 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Blended_Wrapped(TTF_Fon * * \sa TTF_RenderGlyph_LCD * \sa TTF_RenderGlyph_Shaded + * \sa TTF_RenderGlyph_Solid */ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Blended(TTF_Font *font, Uint32 ch, SDL_Color fg); @@ -1240,6 +1366,9 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Blended(TTF_Font *font * * This will not wrap on newline characters. * + * You can render at other quality levels with TTF_RenderText_Solid, + * TTF_RenderText_Shaded, and TTF_RenderText_Blended. + * * \param font the font to render with. * \param text text to render, in UTF-8 encoding. * \param length the length of the text, in bytes, or 0 for null terminated @@ -1256,6 +1385,7 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Blended(TTF_Font *font * \sa TTF_RenderText_Blended * \sa TTF_RenderText_LCD_Wrapped * \sa TTF_RenderText_Shaded + * \sa TTF_RenderText_Solid */ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_LCD(TTF_Font *font, const char *text, size_t length, SDL_Color fg, SDL_Color bg); @@ -1272,6 +1402,9 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_LCD(TTF_Font *font, con * * If wrap_width is 0, this function will only wrap on newline characters. * + * You can render at other quality levels with TTF_RenderText_Solid_Wrapped, + * TTF_RenderText_Shaded_Wrapped, and TTF_RenderText_Blended_Wrapped. + * * \param font the font to render with. * \param text text to render, in UTF-8 encoding. * \param length the length of the text, in bytes, or 0 for null terminated @@ -1290,6 +1423,7 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_LCD(TTF_Font *font, con * \sa TTF_RenderText_Blended_Wrapped * \sa TTF_RenderText_LCD * \sa TTF_RenderText_Shaded_Wrapped + * \sa TTF_RenderText_Solid_Wrapped */ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_LCD_Wrapped(TTF_Font *font, const char *text, size_t length, SDL_Color fg, SDL_Color bg, int wrap_width); @@ -1304,6 +1438,9 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_LCD_Wrapped(TTF_Font *f * The glyph is rendered without any padding or centering in the X direction, * and aligned normally in the Y direction. * + * You can render at other quality levels with TTF_RenderGlyph_Solid, + * TTF_RenderGlyph_Shaded, and TTF_RenderGlyph_Blended. + * * \param font the font to render with. * \param ch the codepoint to render. * \param fg the foreground color for the text. @@ -1317,6 +1454,7 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_LCD_Wrapped(TTF_Font *f * * \sa TTF_RenderGlyph_Blended * \sa TTF_RenderGlyph_Shaded + * \sa TTF_RenderGlyph_Solid */ extern SDL_DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_LCD(TTF_Font *font, Uint32 ch, SDL_Color fg, SDL_Color bg); diff --git a/src/SDL_ttf.c b/src/SDL_ttf.c index 6908a729..4951c04e 100644 --- a/src/SDL_ttf.c +++ b/src/SDL_ttf.c @@ -170,12 +170,13 @@ static SDL_INLINE int hasNEON(void) #define DIVIDE_BY_255(x) DIVIDE_BY_255_SIGNED(x, 1) -#define CACHED_METRICS 0x10 +#define CACHED_METRICS 0x20 -#define CACHED_PIXMAP 0x01 -#define CACHED_COLOR 0x02 -#define CACHED_LCD 0x04 -#define CACHED_SUBPIX 0x08 +#define CACHED_BITMAP 0x01 +#define CACHED_PIXMAP 0x02 +#define CACHED_COLOR 0x04 +#define CACHED_LCD 0x08 +#define CACHED_SUBPIX 0x10 typedef struct { @@ -192,6 +193,7 @@ typedef struct { typedef struct cached_glyph { int stored; FT_UInt index; + TTF_Image bitmap; TTF_Image pixmap; int sz_left; int sz_top; @@ -338,6 +340,7 @@ static struct TTF_CHECK_POINTER("font", font, errval) typedef enum { + RENDER_SOLID = 0, RENDER_SHADED, RENDER_BLENDED, RENDER_LCD @@ -347,7 +350,7 @@ typedef enum { false, 0, NULL, NULL -static bool Find_GlyphByIndex(TTF_Font *font, FT_UInt idx, int want_pixmap, int want_color, int want_lcd, int want_subpixel, int translation, c_glyph **out_glyph, TTF_Image **out_image); +static bool Find_GlyphByIndex(TTF_Font *font, FT_UInt idx, int want_bitmap, int want_pixmap, int want_color, int want_lcd, int want_subpixel, int translation, c_glyph **out_glyph, TTF_Image **out_image); #if defined(USE_DUFFS_LOOP) @@ -1160,7 +1163,7 @@ static int Get_Alignment(void) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-value" #endif -#define BUILD_RENDER_LINE(NAME, IS_BLENDED, IS_BLENDED_OPAQUE, IS_LCD, WP_WC, WS, BLIT_GLYPH_BLENDED_OPAQUE_OPTIM, BLIT_GLYPH_BLENDED_OPTIM, BLIT_GLYPH_OPTIM) \ +#define BUILD_RENDER_LINE(NAME, IS_BLENDED, IS_BLENDED_OPAQUE, IS_LCD, WB_WP_WC, WS, BLIT_GLYPH_BLENDED_OPAQUE_OPTIM, BLIT_GLYPH_BLENDED_OPTIM, BLIT_GLYPH_OPTIM) \ \ static bool Render_Line_##NAME(TTF_Font *font, SDL_Surface *textbuf, int xstart, int ystart, SDL_Color *fg) \ { \ @@ -1174,7 +1177,7 @@ static bool Render_Line_##NAME(TTF_Font *font, SDL_Surface *textbuf, int xstart, int y = font->pos_buf[i].y; \ TTF_Image *image; \ \ - if (Find_GlyphByIndex(font, idx, WP_WC, WS, x & 63, NULL, &image)) { \ + if (Find_GlyphByIndex(font, idx, WB_WP_WC, WS, x & 63, NULL, &image)) { \ int above_w, above_h; \ Uint32 dstskip; \ Sint32 srcskip; /* Can be negative */ \ @@ -1270,18 +1273,20 @@ static bool Render_Line_##NAME(TTF_Font *font, SDL_Surface *textbuf, int xstart, } \ \ -#define PIXMAP CACHED_PIXMAP, 0, 0 -#define COLOR 0, CACHED_COLOR, 0 -#define LCD 0, 0, CACHED_LCD +#define BITMAP CACHED_BITMAP, 0, 0, 0 +#define PIXMAP 0, CACHED_PIXMAP, 0, 0 +#define COLOR 0, 0, CACHED_COLOR, 0 +#define LCD 0, 0, 0, CACHED_LCD #define SUBPIX CACHED_SUBPIX -// BUILD_RENDER_LINE(NAME, IS_BLENDED, IS_BLENDED_OPAQUE, WANT_PIXMAP_COLOR_LCD, WANT_SUBPIXEL, BLIT_GLYPH_BLENDED_OPAQUE_OPTIM, BLIT_GLYPH_BLENDED_OPTIM, BLIT_GLYPH_OPTIM) +// BUILD_RENDER_LINE(NAME, IS_BLENDED, IS_BLENDED_OPAQUE, WANT_BITMAP_PIXMAP_COLOR_LCD, WANT_SUBPIXEL, BLIT_GLYPH_BLENDED_OPAQUE_OPTIM, BLIT_GLYPH_BLENDED_OPTIM, BLIT_GLYPH_OPTIM) #if defined(HAVE_SSE2_INTRINSICS) BUILD_RENDER_LINE(SSE_Shaded , 0, 0, 0, PIXMAP, 0 , , , BG_SSE ) BUILD_RENDER_LINE(SSE_Blended , 1, 0, 0, COLOR, 0 , , BG_Blended_SSE , ) BUILD_RENDER_LINE(SSE_Blended_Opaque , 1, 1, 0, COLOR, 0 , BG_Blended_Opaque_SSE , , ) +BUILD_RENDER_LINE(SSE_Solid , 0, 0, 0, BITMAP, 0 , , , BG_SSE ) BUILD_RENDER_LINE(SSE_Shaded_SP , 0, 0, 0, PIXMAP, SUBPIX, , , BG_SSE ) BUILD_RENDER_LINE(SSE_Blended_SP , 1, 0, 0, COLOR, SUBPIX, , BG_Blended_SSE , ) BUILD_RENDER_LINE(SSE_Blended_Opaque_SP , 1, 1, 0, COLOR, SUBPIX, BG_Blended_Opaque_SSE , , ) @@ -1293,6 +1298,7 @@ BUILD_RENDER_LINE(SSE_LCD_SP , 0, 0, 1, LCD, SUBPIX, BUILD_RENDER_LINE(NEON_Shaded , 0, 0, 0, PIXMAP, 0 , , , BG_NEON ) BUILD_RENDER_LINE(NEON_Blended , 1, 0, 0, COLOR, 0 , , BG_Blended_NEON, ) BUILD_RENDER_LINE(NEON_Blended_Opaque , 1, 1, 0, COLOR, 0 , BG_Blended_Opaque_NEON, , ) +BUILD_RENDER_LINE(NEON_Solid , 0, 0, 0, BITMAP, 0 , , , BG_NEON ) BUILD_RENDER_LINE(NEON_Shaded_SP , 0, 0, 0, PIXMAP, SUBPIX, , , BG_NEON ) BUILD_RENDER_LINE(NEON_Blended_SP , 1, 0, 0, COLOR, SUBPIX, , BG_Blended_NEON, ) BUILD_RENDER_LINE(NEON_Blended_Opaque_SP, 1, 1, 0, COLOR, SUBPIX, BG_Blended_Opaque_NEON, , ) @@ -1304,6 +1310,7 @@ BUILD_RENDER_LINE(NEON_LCD_SP , 0, 0, 1, LCD, SUBPIX, BUILD_RENDER_LINE(64_Shaded , 0, 0, 0, PIXMAP, 0 , , , BG_64 ) BUILD_RENDER_LINE(64_Blended , 1, 0, 0, COLOR, 0 , , BG_Blended_32 , ) BUILD_RENDER_LINE(64_Blended_Opaque , 1, 1, 0, COLOR, 0 , BG_Blended_Opaque_32 , , ) +BUILD_RENDER_LINE(64_Solid , 0, 0, 0, BITMAP, 0 , , , BG_64 ) BUILD_RENDER_LINE(64_Shaded_SP , 0, 0, 0, PIXMAP, SUBPIX, , , BG_64 ) BUILD_RENDER_LINE(64_Blended_SP , 1, 0, 0, COLOR, SUBPIX, , BG_Blended_32 , ) BUILD_RENDER_LINE(64_Blended_Opaque_SP , 1, 1, 0, COLOR, SUBPIX, BG_Blended_Opaque_32 , , ) @@ -1313,6 +1320,7 @@ BUILD_RENDER_LINE(64_LCD_SP , 0, 0, 1, LCD, SUBPIX, BUILD_RENDER_LINE(32_Shaded , 0, 0, 0, PIXMAP, 0 , , , BG_32 ) BUILD_RENDER_LINE(32_Blended , 1, 0, 0, COLOR, 0 , , BG_Blended_32 , ) BUILD_RENDER_LINE(32_Blended_Opaque , 1, 1, 0, COLOR, 0 , BG_Blended_Opaque_32 , , ) +BUILD_RENDER_LINE(32_Solid , 0, 0, 0, BITMAP, 0 , , , BG_32 ) BUILD_RENDER_LINE(32_Shaded_SP , 0, 0, 0, PIXMAP, SUBPIX, , , BG_32 ) BUILD_RENDER_LINE(32_Blended_SP , 1, 0, 0, COLOR, SUBPIX, , BG_Blended_32 , ) BUILD_RENDER_LINE(32_Blended_Opaque_SP , 1, 1, 0, COLOR, SUBPIX, BG_Blended_Opaque_32 , , ) @@ -1322,6 +1330,7 @@ BUILD_RENDER_LINE(32_LCD_SP , 0, 0, 1, LCD, SUBPIX, BUILD_RENDER_LINE(8_Shaded , 0, 0, 0, PIXMAP, 0 , , , BG ) BUILD_RENDER_LINE(8_Blended , 1, 0, 0, COLOR, 0 , , BG_Blended , ) BUILD_RENDER_LINE(8_Blended_Opaque , 1, 1, 0, COLOR, 0 , BG_Blended_Opaque , , ) +BUILD_RENDER_LINE(8_Solid , 0, 0, 0, BITMAP, 0 , , , BG ) BUILD_RENDER_LINE(8_Shaded_SP , 0, 0, 0, PIXMAP, SUBPIX, , , BG ) BUILD_RENDER_LINE(8_Blended_SP , 1, 0, 0, COLOR, SUBPIX, , BG_Blended , ) BUILD_RENDER_LINE(8_Blended_Opaque_SP , 1, 1, 0, COLOR, SUBPIX, BG_Blended_Opaque , , ) @@ -1334,6 +1343,7 @@ BUILD_RENDER_LINE(8_LCD_SP , 0, 0, 1, LCD, SUBPIX, static int (*Render_Line_SDF_Shaded)(TTF_Font *font, SDL_Surface *textbuf, int xstart, int ystart, SDL_Color *fg) = NULL; BUILD_RENDER_LINE(SDF_Blended , 1, 0, 0, COLOR, 0 , , BG_Blended_SDF , ) BUILD_RENDER_LINE(SDF_Blended_Opaque , 1, 1, 0, COLOR, 0 , BG_Blended_Opaque_SDF , , ) +static int (*Render_Line_SDF_Solid)(TTF_Font *font, SDL_Surface *textbuf, int xstart, int ystart, SDL_Color *fg) = NULL; static int (*Render_Line_SDF_Shaded_SP)(TTF_Font *font, SDL_Surface *textbuf, int xstart, int ystart, SDL_Color *fg) = NULL; BUILD_RENDER_LINE(SDF_Blended_SP , 1, 0, 0, COLOR, SUBPIX, , BG_Blended_SDF , ) BUILD_RENDER_LINE(SDF_Blended_Opaque_SP , 1, 1, 0, COLOR, SUBPIX, BG_Blended_Opaque_SDF , , ) @@ -1349,6 +1359,8 @@ static bool Render_Line(const render_mode_t render_mode, int subpixel, TTF_Font { // Render line (pos_buf) to textbuf at (xstart, ystart) + // Subpixel with RENDER_SOLID doesn't make sense. + // (and 'cached->subpixel.translation' would need to distinguish bitmap/pixmap). int is_opaque = (fg.a == SDL_ALPHA_OPAQUE); #define Call_Specific_Render_Line(NAME) \ @@ -1372,12 +1384,14 @@ static bool Render_Line(const render_mode_t render_mode, int subpixel, TTF_Font return Render_Line_##NAME##_Blended_SP(font, textbuf, xstart, ystart, &fg); \ } \ } \ - } else /*if (render_mode == RENDER_LCD)*/ { \ + } else if (render_mode == RENDER_LCD) { \ if (subpixel == 0) { \ return Render_Line_##NAME##_LCD(font, textbuf, xstart, ystart, &fg); \ } else { \ return Render_Line_##NAME##_LCD_SP(font, textbuf, xstart, ystart, &fg); \ } \ + } else { \ + return Render_Line_##NAME##_Solid(font, textbuf, xstart, ystart, NULL); \ } #if TTF_USE_SDF @@ -1426,7 +1440,7 @@ static bool Render_Line_TextEngine(TTF_Font *font, int xstart, int ystart, int w int offset = font->pos_buf[i].offset; c_glyph *glyph; - if (Find_GlyphByIndex(font, idx, 0, 0, 0, 0, 0, &glyph, NULL)) { + if (Find_GlyphByIndex(font, idx, 0, 0, 0, 0, 0, 0, &glyph, NULL)) { int above_w, above_h; int glyph_x = 0; int glyph_y = 0; @@ -1532,9 +1546,9 @@ static SDL_Surface *AllocateAlignedPixels(size_t width, size_t height, SDL_Pixel * Considerer also for instance, that when we read 1 block of 16 bytes from source, for the blended * format (bbp == 4), it writes(and reads) 4 blocks of 16 in the dest, like BG_Blended_SSE()). * - * Remark: for Shaded, block ratio read/write is 1:1. + * Remark: for Solid/Shaded, block ratio read/write is 1:1. * For Color / LCD / SDF, it is byte vs byte or int. They are also fallback for - * Shaded/Blend, when it isn't contained in textbuf, see clip_glyph() + * Solid/Shaded/Blend, when it isn't contained in textbuf, see clip_glyph() * * So the pitch must contain "width * bytes_per_pixel", plus in the * worst case, writing at last pixel (1 * bytes_per_pixel), an extra "alignment * bytes_per_pixel". @@ -1607,6 +1621,33 @@ static SDL_Surface *AllocateAlignedPixels(size_t width, size_t height, SDL_Pixel return textbuf; } +static SDL_Surface* Create_Surface_Solid(int width, int height, SDL_Color fg, Uint32 *color) +{ + SDL_Surface *textbuf = AllocateAlignedPixels(width, height, SDL_PIXELFORMAT_INDEX8, 0); + if (textbuf == NULL) { + return NULL; + } + + // Underline/Strikethrough color style + *color = 1; + + // Fill the palette: 1 is foreground + { + SDL_Palette *palette = SDL_GetSurfacePalette(textbuf); + palette->colors[0].r = 255 - fg.r; + palette->colors[0].g = 255 - fg.g; + palette->colors[0].b = 255 - fg.b; + palette->colors[1].r = fg.r; + palette->colors[1].g = fg.g; + palette->colors[1].b = fg.b; + palette->colors[1].a = fg.a; + } + + SDL_SetSurfaceColorKey(textbuf, true, 0); + + return textbuf; +} + static SDL_Surface* Create_Surface_Shaded(int width, int height, SDL_Color fg, SDL_Color bg, Uint32 *color) { SDL_Surface *textbuf = AllocateAlignedPixels(width, height, SDL_PIXELFORMAT_INDEX8, 0); @@ -2180,6 +2221,7 @@ static void Flush_Glyph(c_glyph *glyph) glyph->stored = 0; glyph->index = 0; Flush_Glyph_Image(&glyph->pixmap); + Flush_Glyph_Image(&glyph->bitmap); } static void Flush_Cache(TTF_Font *font) @@ -2296,17 +2338,21 @@ static bool Load_Glyph(TTF_Font *font, c_glyph *cached, int want, int translatio cached->stored |= CACHED_METRICS; } - if (((want & CACHED_PIXMAP) && !(cached->stored & CACHED_PIXMAP)) || + if (((want & CACHED_BITMAP) && !(cached->stored & CACHED_BITMAP)) || + ((want & CACHED_PIXMAP) && !(cached->stored & CACHED_PIXMAP)) || ((want & CACHED_COLOR) && !(cached->stored & CACHED_COLOR)) || ((want & CACHED_LCD) && !(cached->stored & CACHED_LCD)) || (want & CACHED_SUBPIX) ) { - TTF_Image *dst = &cached->pixmap; + const int mono = (want & CACHED_BITMAP); + TTF_Image *dst = (mono ? &cached->bitmap : &cached->pixmap); FT_Glyph glyph = NULL; FT_Bitmap *src; FT_Render_Mode ft_render_mode; - { + if (mono) { + ft_render_mode = FT_RENDER_MODE_MONO; + } else { ft_render_mode = FT_RENDER_MODE_NORMAL; #if TTF_USE_SDF if ((want & CACHED_COLOR) && font->render_sdf) { @@ -2533,7 +2579,29 @@ static bool Load_Glyph(TTF_Font *font, c_glyph *cached, int want, int translatio } \ } - if (src->pixel_mode == FT_PIXEL_MODE_MONO) { + if (mono) { + if (src->pixel_mode == FT_PIXEL_MODE_MONO) { + while (quotient--) { + MONO_MONO(8); + } + MONO_MONO(remainder); + } else if (src->pixel_mode == FT_PIXEL_MODE_GRAY2) { + while (quotient--) { + MONO_GRAY2(4); + } + MONO_GRAY2(remainder); + } else if (src->pixel_mode == FT_PIXEL_MODE_GRAY4) { + while (quotient--) { + MONO_GRAY4(2); + } + MONO_GRAY4(remainder); + } else { + while (quotient--) { + unsigned char c = *srcp++; + *dstp++ = (c >= 0x80) ? 1 : 0; + } + } + } else if (src->pixel_mode == FT_PIXEL_MODE_MONO) { /* This special case wouldn't be here if the FT_Render_Glyph() * function wasn't buggy when it tried to render a .fon font with 256 * shades of gray. Instead, it returns a black and white surface @@ -2610,7 +2678,9 @@ static bool Load_Glyph(TTF_Font *font, c_glyph *cached, int want, int translatio // SDL_memset(pixmap + dst->width - font->glyph_overhang, 0, font->glyph_overhang); for (offset = 1; offset <= font->glyph_overhang; ++offset) { for (col = dst->width - 1; col > 0; --col) { - { + if (mono) { + pixmap[col] |= pixmap[col-1]; + } else { int pixel = (pixmap[col] + pixmap[col-1]); if (pixel > NUM_GRAYS - 1) { pixel = NUM_GRAYS - 1; @@ -2638,7 +2708,9 @@ static bool Load_Glyph(TTF_Font *font, c_glyph *cached, int want, int translatio #endif // Mark that we rendered this format - if (src->pixel_mode == FT_PIXEL_MODE_LCD) { + if (mono) { + cached->stored |= CACHED_BITMAP; + } else if (src->pixel_mode == FT_PIXEL_MODE_LCD) { cached->stored |= CACHED_LCD; } else { #if TTF_USE_COLOR @@ -2672,7 +2744,7 @@ static bool Load_Glyph(TTF_Font *font, c_glyph *cached, int want, int translatio } static bool Find_GlyphByIndex(TTF_Font *font, FT_UInt idx, - int want_pixmap, int want_color, int want_lcd, int want_subpixel, + int want_bitmap, int want_pixmap, int want_color, int want_lcd, int want_subpixel, int translation, c_glyph **out_glyph, TTF_Image **out_image) { // cache size is 256, get key by masking @@ -2686,10 +2758,14 @@ static bool Find_GlyphByIndex(TTF_Font *font, FT_UInt idx, *out_image = &glyph->pixmap; } + if (want_bitmap) { + *out_image = &glyph->bitmap; + } + if (want_subpixel) { /* Not a real cache, but if it always advances by integer pixels (eg translation 0 or same as previous), * this allows to render as fast as normal mode. */ - int want = CACHED_METRICS | want_pixmap | want_color | want_lcd | want_subpixel; + int want = CACHED_METRICS | want_bitmap | want_pixmap | want_color | want_lcd | want_subpixel; if (glyph->stored && glyph->index != idx) { Flush_Glyph(glyph); @@ -2712,13 +2788,17 @@ static bool Find_GlyphByIndex(TTF_Font *font, FT_UInt idx, glyph->index = idx; return Load_Glyph(font, glyph, want, translation); } else { - const int want = CACHED_METRICS | want_pixmap | want_color | want_lcd; + const int want = CACHED_METRICS | want_bitmap | want_pixmap | want_color | want_lcd; // Faster check as it gets inlined if (want_pixmap) { if ((glyph->stored & CACHED_PIXMAP) && glyph->index == idx) { return true; } + } else if (want_bitmap) { + if ((glyph->stored & CACHED_BITMAP) && glyph->index == idx) { + return true; + } } else if (want_color) { if ((glyph->stored & CACHED_COLOR) && glyph->index == idx) { return true; @@ -2774,7 +2854,7 @@ static bool Find_GlyphMetrics(TTF_Font *font, Uint32 ch, c_glyph **out_glyph) TTF_CHECK_FONT(font, false); FT_UInt idx = get_char_index(font, ch); - return Find_GlyphByIndex(font, idx, 0, 0, 0, 0, 0, out_glyph, NULL); + return Find_GlyphByIndex(font, idx, 0, 0, 0, 0, 0, 0, out_glyph, NULL); } bool TTF_FontHasGlyph(TTF_Font *font, Uint32 ch) @@ -2808,7 +2888,7 @@ SDL_Surface *TTF_GetGlyphImageForIndex(TTF_Font *font, Uint32 glyph_index) TTF_CHECK_FONT(font, NULL); - if (!Find_GlyphByIndex(font, glyph_index, 1, 0, 0, 0, 0, NULL, &image)) { + if (!Find_GlyphByIndex(font, glyph_index, 0, CACHED_PIXMAP, 0, 0, 0, 0, NULL, &image)) { return NULL; } @@ -3036,7 +3116,7 @@ static bool TTF_Size_Internal(TTF_Font *font, const char *text, size_t length, i continue; } #endif - if (!Find_GlyphByIndex(font, idx, 0, 0, 0, 0, 0, &glyph, NULL)) { + if (!Find_GlyphByIndex(font, idx, 0, 0, 0, 0, 0, 0, &glyph, NULL)) { goto failure; } @@ -3233,7 +3313,9 @@ static SDL_Surface* TTF_Render_Internal(TTF_Font *font, const char *text, size_t if (fg.a == SDL_ALPHA_TRANSPARENT) { fg.a = SDL_ALPHA_OPAQUE; } - if (render_mode == RENDER_SHADED) { + if (render_mode == RENDER_SOLID) { + textbuf = Create_Surface_Solid(width, height, fg, &color); + } else if (render_mode == RENDER_SHADED) { textbuf = Create_Surface_Shaded(width, height, fg, bg, &color); } else if (render_mode == RENDER_BLENDED) { textbuf = Create_Surface_Blended(width, height, fg, &color); @@ -3267,6 +3349,20 @@ static SDL_Surface* TTF_Render_Internal(TTF_Font *font, const char *text, size_t return NULL; } +SDL_Surface* TTF_RenderText_Solid(TTF_Font *font, const char *text, size_t length, SDL_Color fg) +{ + return TTF_Render_Internal(font, text, length, fg, fg /* unused */, RENDER_SOLID); +} + +SDL_Surface* TTF_RenderGlyph_Solid(TTF_Font *font, Uint32 ch, SDL_Color fg) +{ + char utf8[4], *end; + + end = SDL_UCS4ToUTF8(ch, utf8); + + return TTF_RenderText_Solid(font, utf8, (end - utf8), fg); +} + SDL_Surface* TTF_RenderText_Shaded(TTF_Font *font, const char *text, size_t length, SDL_Color fg, SDL_Color bg) { return TTF_Render_Internal(font, text, length, fg, bg, RENDER_SHADED); @@ -3564,7 +3660,9 @@ static SDL_Surface* TTF_Render_Wrapped_Internal(TTF_Font *font, const char *text if (fg.a == SDL_ALPHA_TRANSPARENT) { fg.a = SDL_ALPHA_OPAQUE; } - if (render_mode == RENDER_SHADED) { + if (render_mode == RENDER_SOLID) { + textbuf = Create_Surface_Solid(width, height, fg, &color); + } else if (render_mode == RENDER_SHADED) { textbuf = Create_Surface_Shaded(width, height, fg, bg, &color); } else if (render_mode == RENDER_BLENDED) { textbuf = Create_Surface_Blended(width, height, fg, &color); @@ -3628,6 +3726,11 @@ static SDL_Surface* TTF_Render_Wrapped_Internal(TTF_Font *font, const char *text return NULL; } +SDL_Surface* TTF_RenderText_Solid_Wrapped(TTF_Font *font, const char *text, size_t length, SDL_Color fg, int wrap_width) +{ + return TTF_Render_Wrapped_Internal(font, text, length, fg, fg /* unused */, wrap_width, RENDER_SOLID); +} + SDL_Surface* TTF_RenderText_Shaded_Wrapped(TTF_Font *font, const char *text, size_t length, SDL_Color fg, SDL_Color bg, int wrap_width) { return TTF_Render_Wrapped_Internal(font, text, length, fg, bg, wrap_width, RENDER_SHADED); diff --git a/src/SDL_ttf.sym b/src/SDL_ttf.sym index a0e2d867..a91bf474 100644 --- a/src/SDL_ttf.sym +++ b/src/SDL_ttf.sym @@ -63,12 +63,15 @@ SDL3_ttf_0.0.0 { TTF_RenderGlyph_Blended; TTF_RenderGlyph_LCD; TTF_RenderGlyph_Shaded; + TTF_RenderGlyph_Solid; TTF_RenderText_Blended; TTF_RenderText_Blended_Wrapped; TTF_RenderText_LCD; TTF_RenderText_LCD_Wrapped; TTF_RenderText_Shaded; TTF_RenderText_Shaded_Wrapped; + TTF_RenderText_Solid; + TTF_RenderText_Solid_Wrapped; TTF_SetFontDirection; TTF_SetFontHinting; TTF_SetFontKerning; From f8e117627183bd59c7e8c693a092136a0c23b6bd Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 24 Oct 2024 09:10:07 -0700 Subject: [PATCH 2/2] Fixed caption placement with the surface text engine --- examples/showfont.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/showfont.c b/examples/showfont.c index a9284579..332bfc06 100644 --- a/examples/showfont.c +++ b/examples/showfont.c @@ -101,7 +101,7 @@ static void DrawScene(Scene *scene) case TextEngineSurface: /* Flush the renderer so we can draw directly to the window surface */ SDL_FlushRenderer(renderer); - TTF_DrawSurfaceText(scene->caption, scene->captionRect.w, scene->captionRect.h, scene->window_surface); + TTF_DrawSurfaceText(scene->caption, scene->captionRect.x, scene->captionRect.y, scene->window_surface); break; case TextEngineRenderer: TTF_DrawRendererText(scene->caption, (float)scene->captionRect.x, (float)scene->captionRect.y);