From cb0e12a6157556aad7e2aa229e9e8bc6bd386700 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 19 Oct 2024 20:32:57 -0700
Subject: [PATCH] Added TTF_SetTextColor() and TTF_GetTextColor()
People expected there to be an API function to set the text color. Voila!
---
examples/editbox.c | 4 +-
examples/showfont.c | 5 +-
include/SDL3_ttf/SDL_textengine.h | 1 +
include/SDL3_ttf/SDL_ttf.h | 125 +++++++++++++++++++++++++++++-
src/SDL_renderer_textengine.c | 2 +-
src/SDL_surface_textengine.c | 10 +--
src/SDL_ttf.c | 100 +++++++++++++++++++++++-
src/SDL_ttf.sym | 4 +
8 files changed, 235 insertions(+), 16 deletions(-)
diff --git a/examples/editbox.c b/examples/editbox.c
index 8cd239e9..f5f701a9 100644
--- a/examples/editbox.c
+++ b/examples/editbox.c
@@ -221,7 +221,9 @@ static void SaveCandidates(EditBox *edit, const SDL_Event *event)
edit->candidates = TTF_CreateText(TTF_GetTextEngine(edit->text), edit->font, candidate_text, 0);
SDL_free(candidate_text);
if (edit->candidates) {
- SDL_copyp(&edit->candidates->color, &edit->text->color);
+ float r, g, b, a;
+ TTF_GetTextColorFloat(edit->text, &r, &g, &b, &a);
+ TTF_SetTextColorFloat(edit->candidates, r, g, b, a);
} else {
ClearCandidates(edit);
}
diff --git a/examples/showfont.c b/examples/showfont.c
index fda33db4..9ff9c6d0 100644
--- a/examples/showfont.c
+++ b/examples/showfont.c
@@ -550,10 +550,7 @@ int main(int argc, char *argv[])
editRect.w -= 8.0f;
scene.edit = EditBox_Create(scene.window, scene.renderer, engine, font, &editRect);
if (scene.edit) {
- scene.edit->text->color.r = forecol->r / 255.0f;
- scene.edit->text->color.g = forecol->g / 255.0f;
- scene.edit->text->color.b = forecol->b / 255.0f;
- scene.edit->text->color.a = forecol->a / 255.0f;
+ TTF_SetTextColor(scene.edit->text, forecol->r, forecol->g, forecol->b, forecol->a);
EditBox_Insert(scene.edit, message);
}
diff --git a/include/SDL3_ttf/SDL_textengine.h b/include/SDL3_ttf/SDL_textengine.h
index 99222e95..0bf12399 100644
--- a/include/SDL3_ttf/SDL_textengine.h
+++ b/include/SDL3_ttf/SDL_textengine.h
@@ -106,6 +106,7 @@ typedef struct TTF_TextLayout TTF_TextLayout;
struct TTF_TextData
{
TTF_Font *font; /**< The font used by this text, read-only. */
+ SDL_FColor color; /**< The color of the text, read-only. */
bool needs_layout_update; /**< True if the layout needs to be updated */
TTF_TextLayout *layout; /**< Cached layout information, read-only. */
diff --git a/include/SDL3_ttf/SDL_ttf.h b/include/SDL3_ttf/SDL_ttf.h
index f78f22fb..3dcce873 100644
--- a/include/SDL3_ttf/SDL_ttf.h
+++ b/include/SDL3_ttf/SDL_ttf.h
@@ -1341,7 +1341,6 @@ typedef struct TTF_TextData TTF_TextData;
typedef struct TTF_Text
{
char *text; /**< A copy of the text used to create this text object, useful for layout and debugging. This will be freed automatically when the object is destroyed. */
- SDL_FColor color; /**< The color of the text, read-write. You can change this anytime. */
int num_lines; /**< The number of lines in the text, 0 if it's empty */
int refcount; /**< Application reference count, used when freeing surface */
@@ -1549,6 +1548,8 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL TTF_GetTextProperties(TTF_Text *tex
* text.
*
* \since This function is available since SDL_ttf 3.0.0.
+ *
+ * \sa TTF_GetTextEngine
*/
extern SDL_DECLSPEC bool SDLCALL TTF_SetTextEngine(TTF_Text *text, TTF_TextEngine *engine);
@@ -1563,6 +1564,8 @@ extern SDL_DECLSPEC bool SDLCALL TTF_SetTextEngine(TTF_Text *text, TTF_TextEngin
* text.
*
* \since This function is available since SDL_ttf 3.0.0.
+ *
+ * \sa TTF_SetTextEngine
*/
extern SDL_DECLSPEC TTF_TextEngine * SDLCALL TTF_GetTextEngine(TTF_Text *text);
@@ -1580,6 +1583,8 @@ extern SDL_DECLSPEC TTF_TextEngine * SDLCALL TTF_GetTextEngine(TTF_Text *text);
* text.
*
* \since This function is available since SDL_ttf 3.0.0.
+ *
+ * \sa TTF_GetTextFont
*/
extern SDL_DECLSPEC bool SDLCALL TTF_SetTextFont(TTF_Text *text, TTF_Font *font);
@@ -1594,9 +1599,99 @@ extern SDL_DECLSPEC bool SDLCALL TTF_SetTextFont(TTF_Text *text, TTF_Font *font)
* text.
*
* \since This function is available since SDL_ttf 3.0.0.
+ *
+ * \sa TTF_SetTextFont
*/
extern SDL_DECLSPEC TTF_Font * SDLCALL TTF_GetTextFont(TTF_Text *text);
+/**
+ * Set the color of a text object.
+ *
+ * The default text color is white (255, 255, 255, 255).
+ *
+ * \param text the TTF_Text to modify.
+ * \param r the red color value in the range of 0-255.
+ * \param g the green color value in the range of 0-255.
+ * \param b the blue color value in the range of 0-255.
+ * \param a the alpha value in the range of 0-255.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety This function should be called on the thread that created the
+ * text.
+ *
+ * \since This function is available since SDL_ttf 3.0.0.
+ *
+ * \sa TTF_GetTextColor
+ * \sa TTF_SetTextColorFloat
+ */
+extern SDL_DECLSPEC bool SDLCALL TTF_SetTextColor(TTF_Text *text, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
+
+/**
+ * Set the color of a text object.
+ *
+ * The default text color is white (1.0f, 1.0f, 1.0f, 1.0f).
+ *
+ * \param text the TTF_Text to modify.
+ * \param r the red color value, normally in the range of 0-1.
+ * \param g the green color value, normally in the range of 0-1.
+ * \param b the blue color value, normally in the range of 0-1.
+ * \param a the alpha value in the range of 0-1.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety This function should be called on the thread that created the
+ * text.
+ *
+ * \since This function is available since SDL_ttf 3.0.0.
+ *
+ * \sa TTF_GetTextColorFloat
+ * \sa TTF_SetTextColor
+ */
+extern SDL_DECLSPEC bool SDLCALL TTF_SetTextColorFloat(TTF_Text *text, float r, float g, float b, float a);
+
+/**
+ * Get the color of a text object.
+ *
+ * \param text the TTF_Text to query.
+ * \param r a pointer filled in with the red color value in the range of 0-255, may be NULL.
+ * \param g a pointer filled in with the green color value in the range of 0-255, may be NULL.
+ * \param b a pointer filled in with the blue color value in the range of 0-255, may be NULL.
+ * \param a a pointer filled in with the alpha value in the range of 0-255, may be NULL.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety This function should be called on the thread that created the
+ * text.
+ *
+ * \since This function is available since SDL_ttf 3.0.0.
+ *
+ * \sa TTF_GetTextColorFloat
+ * \sa TTF_SetTextColor
+ */
+extern SDL_DECLSPEC bool SDLCALL TTF_GetTextColor(TTF_Text *text, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a);
+
+/**
+ * Get the color of a text object.
+ *
+ * \param text the TTF_Text to query.
+ * \param r a pointer filled in with the red color value, normally in the range of 0-1, may be NULL.
+ * \param g a pointer filled in with the green color value, normally in the range of 0-1, may be NULL.
+ * \param b a pointer filled in with the blue color value, normally in the range of 0-1, may be NULL.
+ * \param a a pointer filled in with the alpha value in the range of 0-1, may be NULL.
+ * \returns true on success or false on failure; call SDL_GetError() for more
+ * information.
+ *
+ * \threadsafety This function should be called on the thread that created the
+ * text.
+ *
+ * \since This function is available since SDL_ttf 3.0.0.
+ *
+ * \sa TTF_GetTextColor
+ * \sa TTF_SetTextColorFloat
+ */
+extern SDL_DECLSPEC bool SDLCALL TTF_GetTextColorFloat(TTF_Text *text, float *r, float *g, float *b, float *a);
+
/**
* Set the position of a text object.
*
@@ -1611,6 +1706,8 @@ extern SDL_DECLSPEC TTF_Font * SDLCALL TTF_GetTextFont(TTF_Text *text);
* text.
*
* \since This function is available since SDL_ttf 3.0.0.
+ *
+ * \sa TTF_GetTextPosition
*/
extern SDL_DECLSPEC bool SDLCALL TTF_SetTextPosition(TTF_Text *text, int x, int y);
@@ -1627,6 +1724,8 @@ extern SDL_DECLSPEC bool SDLCALL TTF_SetTextPosition(TTF_Text *text, int x, int
* text.
*
* \since This function is available since SDL_ttf 3.0.0.
+ *
+ * \sa TTF_SetTextPosition
*/
extern SDL_DECLSPEC bool SDLCALL TTF_GetTextPosition(TTF_Text *text, int *x, int *y);
@@ -1644,6 +1743,10 @@ extern SDL_DECLSPEC bool SDLCALL TTF_GetTextPosition(TTF_Text *text, int *x, int
* text.
*
* \since This function is available since SDL_ttf 3.0.0.
+ *
+ * \sa TTF_AppendTextString
+ * \sa TTF_DeleteTextString
+ * \sa TTF_InsertTextString
*/
extern SDL_DECLSPEC bool SDLCALL TTF_SetTextString(TTF_Text *text, const char *string, size_t length);
@@ -1665,6 +1768,10 @@ extern SDL_DECLSPEC bool SDLCALL TTF_SetTextString(TTF_Text *text, const char *s
* text.
*
* \since This function is available since SDL_ttf 3.0.0.
+ *
+ * \sa TTF_AppendTextString
+ * \sa TTF_DeleteTextString
+ * \sa TTF_SetTextString
*/
extern SDL_DECLSPEC bool SDLCALL TTF_InsertTextString(TTF_Text *text, int offset, const char *string, size_t length);
@@ -1682,6 +1789,10 @@ extern SDL_DECLSPEC bool SDLCALL TTF_InsertTextString(TTF_Text *text, int offset
* text.
*
* \since This function is available since SDL_ttf 3.0.0.
+ *
+ * \sa TTF_DeleteTextString
+ * \sa TTF_InsertTextString
+ * \sa TTF_SetTextString
*/
extern SDL_DECLSPEC bool SDLCALL TTF_AppendTextString(TTF_Text *text, const char *string, size_t length);
@@ -1702,6 +1813,10 @@ extern SDL_DECLSPEC bool SDLCALL TTF_AppendTextString(TTF_Text *text, const char
* text.
*
* \since This function is available since SDL_ttf 3.0.0.
+ *
+ * \sa TTF_AppendTextString
+ * \sa TTF_InsertTextString
+ * \sa TTF_SetTextString
*/
extern SDL_DECLSPEC bool SDLCALL TTF_DeleteTextString(TTF_Text *text, int offset, int length);
@@ -1718,6 +1833,8 @@ extern SDL_DECLSPEC bool SDLCALL TTF_DeleteTextString(TTF_Text *text, int offset
* text.
*
* \since This function is available since SDL_ttf 3.0.0.
+ *
+ * \sa TTF_GetTextWrapping
*/
extern SDL_DECLSPEC bool SDLCALL TTF_SetTextWrapping(TTF_Text *text, int wrapLength);
@@ -1734,6 +1851,8 @@ extern SDL_DECLSPEC bool SDLCALL TTF_SetTextWrapping(TTF_Text *text, int wrapLen
* text.
*
* \since This function is available since SDL_ttf 3.0.0.
+ *
+ * \sa TTF_SetTextWrapping
*/
extern SDL_DECLSPEC bool SDLCALL TTF_GetTextWrapping(TTF_Text *text, int *wrapLength);
@@ -1751,6 +1870,8 @@ extern SDL_DECLSPEC bool SDLCALL TTF_GetTextWrapping(TTF_Text *text, int *wrapLe
* text.
*
* \since This function is available since SDL_ttf 3.0.0.
+ *
+ * \sa TTF_TextWrapWhitespaceVisible
*/
extern SDL_DECLSPEC bool SDLCALL TTF_SetTextWrapWhitespaceVisible(TTF_Text *text, bool visible);
@@ -1764,6 +1885,8 @@ extern SDL_DECLSPEC bool SDLCALL TTF_SetTextWrapWhitespaceVisible(TTF_Text *text
* text.
*
* \since This function is available since SDL_ttf 3.0.0.
+ *
+ * \sa TTF_SetTextWrapWhitespaceVisible
*/
extern SDL_DECLSPEC bool SDLCALL TTF_TextWrapWhitespaceVisible(TTF_Text *text);
diff --git a/src/SDL_renderer_textengine.c b/src/SDL_renderer_textengine.c
index 386597dc..d8e53663 100644
--- a/src/SDL_renderer_textengine.c
+++ b/src/SDL_renderer_textengine.c
@@ -887,7 +887,7 @@ bool TTF_DrawRendererText(TTF_Text *text, float x, float y)
SDL_RenderGeometryRaw(renderer,
sequence->texture,
sequence->positions, 2 * sizeof(float),
- &text->color, 0,
+ &text->internal->color, 0,
sequence->texcoords, 2 * sizeof(float),
sequence->num_rects * 4,
sequence->indices, sequence->num_rects * 6, sizeof(*sequence->indices));
diff --git a/src/SDL_surface_textengine.c b/src/SDL_surface_textengine.c
index f8a70754..8730a276 100644
--- a/src/SDL_surface_textengine.c
+++ b/src/SDL_surface_textengine.c
@@ -344,11 +344,11 @@ bool TTF_DrawSurfaceText(TTF_Text *text, int x, int y, SDL_Surface *surface)
return true;
}
- if (text->color.r != data->fcolor.r ||
- text->color.g != data->fcolor.g ||
- text->color.b != data->fcolor.b ||
- text->color.a != data->fcolor.a) {
- UpdateColor(data, &text->color);
+ if (text->internal->color.r != data->fcolor.r ||
+ text->internal->color.g != data->fcolor.g ||
+ text->internal->color.b != data->fcolor.b ||
+ text->internal->color.a != data->fcolor.a) {
+ UpdateColor(data, &text->internal->color);
}
for (int i = 0; i < data->num_ops; ++i) {
diff --git a/src/SDL_ttf.c b/src/SDL_ttf.c
index ec342eec..37b04bb3 100644
--- a/src/SDL_ttf.c
+++ b/src/SDL_ttf.c
@@ -3702,10 +3702,10 @@ static TTF_Text *CreateText(TTF_TextEngine *engine, TTF_Font *font, const char *
result->internal = &mem->internal;
result->internal->layout = &mem->layout;
result->internal->font = font;
- result->color.r = 1.0f;
- result->color.g = 1.0f;
- result->color.b = 1.0f;
- result->color.a = 1.0f;
+ result->internal->color.r = 1.0f;
+ result->internal->color.g = 1.0f;
+ result->internal->color.b = 1.0f;
+ result->internal->color.a = 1.0f;
result->internal->needs_layout_update = true;
result->internal->engine = engine;
result->internal->layout->wrap_length = wrapLength;
@@ -4064,6 +4064,98 @@ TTF_Font *TTF_GetTextFont(TTF_Text *text)
return text->internal->font;
}
+bool TTF_SetTextColor(TTF_Text *text, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+ const float fR = (float)r / 255.0f;
+ const float fG = (float)g / 255.0f;
+ const float fB = (float)b / 255.0f;
+ const float fA = (float)a / 255.0f;
+
+ return TTF_SetTextColorFloat(text, fR, fG, fB, fA);
+}
+
+bool TTF_SetTextColorFloat(TTF_Text *text, float r, float g, float b, float a)
+{
+ TTF_CHECK_POINTER("text", text, false);
+
+ text->internal->color.r = r;
+ text->internal->color.g = g;
+ text->internal->color.b = b;
+ text->internal->color.a = a;
+ return true;
+}
+
+bool TTF_GetTextColor(TTF_Text *text, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
+{
+ float fR = 1.0f, fG = 1.0f, fB = 1.0f, fA = 1.0f;
+
+ if (!TTF_GetTextColorFloat(text, &fR, &fG, &fB, &fA)) {
+ if (r) {
+ *r = 255;
+ }
+ if (g) {
+ *g = 255;
+ }
+ if (b) {
+ *b = 255;
+ }
+ if (b) {
+ *b = 255;
+ }
+ return false;
+ }
+
+ if (r) {
+ *r = (Uint8)SDL_roundf(SDL_clamp(fR, 0.0f, 1.0f) * 255.0f);
+ }
+ if (g) {
+ *g = (Uint8)SDL_roundf(SDL_clamp(fG, 0.0f, 1.0f) * 255.0f);
+ }
+ if (b) {
+ *b = (Uint8)SDL_roundf(SDL_clamp(fB, 0.0f, 1.0f) * 255.0f);
+ }
+ if (a) {
+ *a = (Uint8)SDL_roundf(SDL_clamp(fA, 0.0f, 1.0f) * 255.0f);
+ }
+ return true;
+}
+
+bool TTF_GetTextColorFloat(TTF_Text *text, float *r, float *g, float *b, float *a)
+{
+ SDL_FColor color;
+
+ if (r) {
+ *r = 1.0f;
+ }
+ if (g) {
+ *g = 1.0f;
+ }
+ if (b) {
+ *b = 1.0f;
+ }
+ if (a) {
+ *a = 1.0f;
+ }
+
+ TTF_CHECK_POINTER("text", text, false);
+
+ color = text->internal->color;
+
+ if (r) {
+ *r = color.r;
+ }
+ if (g) {
+ *g = color.g;
+ }
+ if (b) {
+ *b = color.b;
+ }
+ if (a) {
+ *a = color.a;
+ }
+ return true;
+}
+
bool TTF_SetTextPosition(TTF_Text *text, int x, int y)
{
TTF_CHECK_POINTER("text", text, false);
diff --git a/src/SDL_ttf.sym b/src/SDL_ttf.sym
index c5bb0e1b..4aab9e0f 100644
--- a/src/SDL_ttf.sym
+++ b/src/SDL_ttf.sym
@@ -43,6 +43,8 @@ SDL3_ttf_0.0.0 {
TTF_GetPreviousTextSubString;
TTF_GetStringSize;
TTF_GetStringSizeWrapped;
+ TTF_GetTextColor;
+ TTF_GetTextColorFloat;
TTF_GetTextEngine;
TTF_GetTextFont;
TTF_GetTextPosition;
@@ -80,6 +82,8 @@ SDL3_ttf_0.0.0 {
TTF_SetFontSizeDPI;
TTF_SetFontStyle;
TTF_SetFontWrapAlignment;
+ TTF_SetTextColor;
+ TTF_SetTextColorFloat;
TTF_SetTextEngine;
TTF_SetTextFont;
TTF_SetTextPosition;