From a0ed8b647fcbd88832213e928e624c24ed117a68 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 24 Oct 2024 09:09:05 -0700
Subject: [PATCH] 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] <font>.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] <font>.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_Fon
(Patch may be truncated, please check the link at the top of this post.)