From 2efc6fc1489fba89fbf62367600aefd0c2ac816f Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 26 Sep 2024 18:54:22 -0700
Subject: [PATCH] TTF_GetGlyphKerning() returns bool
The actual kerning distance is stored in an output parameter, since -1 is a valid kerning distance.
Fixes https://github.com/libsdl-org/SDL_ttf/issues/55
---
build-scripts/SDL_migration.cocci | 5 --
docs/README-migration.md | 3 +-
include/SDL3_ttf/SDL_ttf.h | 6 ++-
src/SDL_ttf.c | 83 ++++++++++++++-----------------
src/SDL_ttf.sym | 2 +-
5 files changed, 44 insertions(+), 55 deletions(-)
diff --git a/build-scripts/SDL_migration.cocci b/build-scripts/SDL_migration.cocci
index 3d3e066b..6f4f67ea 100644
--- a/build-scripts/SDL_migration.cocci
+++ b/build-scripts/SDL_migration.cocci
@@ -83,8 +83,3 @@
- TTF_RenderGlyph32_LCD
+ TTF_RenderGlyph_LCD
(...)
-@@
-@@
-- TTF_GetFontKerningSizeGlyphs32
-+ TTF_GetFontKerningSizeGlyphs
- (...)
diff --git a/docs/README-migration.md b/docs/README-migration.md
index 966e4d61..c3397373 100644
--- a/docs/README-migration.md
+++ b/docs/README-migration.md
@@ -37,7 +37,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 following functions have been renamed:
-* TTF_GetFontKerningSizeGlyphs32() => TTF_GetFontKerningSizeGlyphs()
* TTF_GlyphIsProvided32() => TTF_GlyphIsProvided()
* TTF_GlyphMetrics32() => TTF_GlyphMetrics()
* TTF_MeasureUTF8() => TTF_MeasureText()
@@ -57,6 +56,8 @@ The following functions have been renamed:
The following functions have been removed:
* TTF_ByteSwappedUNICODE()
+* TTF_GetFontKerningSizeGlyphs() - replaced with TTF_GetGlyphKerning()
+* TTF_GetFontKerningSizeGlyphs32() - replaced with TTF_GetGlyphKerning()
* TTF_MeasureUNICODE()
* TTF_OpenFontDPI() - replaced with TTF_OpenFontWithProperties()
* TTF_OpenFontDPIIO() - replaced with TTF_OpenFontWithProperties()
diff --git a/include/SDL3_ttf/SDL_ttf.h b/include/SDL3_ttf/SDL_ttf.h
index c983240e..2346aecd 100644
--- a/include/SDL3_ttf/SDL_ttf.h
+++ b/include/SDL3_ttf/SDL_ttf.h
@@ -1181,13 +1181,15 @@ extern SDL_DECLSPEC int SDLCALL TTF_WasInit(void);
* \param font the font to query.
* \param previous_ch the previous character's code, 32 bits.
* \param ch the current character's code, 32 bits.
- * \returns The kerning size between the two specified characters, in pixels, or -1 on failure; call SDL_GetError() for more information.
+ * \param kerning a pointer filled in with the kerning size between the two specified characters, in pixels, 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 font.
*
* \since This function is available since SDL_ttf 3.0.0.
*/
-extern SDL_DECLSPEC int TTF_GetFontKerningSizeGlyphs(TTF_Font *font, Uint32 previous_ch, Uint32 ch);
+extern SDL_DECLSPEC bool TTF_GetGlyphKerning(TTF_Font *font, Uint32 previous_ch, Uint32 ch, int *kerning);
/**
* Enable Signed Distance Field rendering for a font.
diff --git a/src/SDL_ttf.c b/src/SDL_ttf.c
index 5606dab7..08b9fd2d 100644
--- a/src/SDL_ttf.c
+++ b/src/SDL_ttf.c
@@ -333,7 +333,7 @@ static SDL_Surface* TTF_Render_Internal(TTF_Font *font, const char *text, size_t
static SDL_Surface* TTF_Render_Wrapped_Internal(TTF_Font *font, const char *text, size_t length, SDL_Color fg, SDL_Color bg, int wrapLength, render_mode_t render_mode);
-static int 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);
+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);
static void Flush_Cache(TTF_Font *font);
@@ -1122,7 +1122,7 @@ static int 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, WB_WP_WC, WS, x & 63, NULL, &image) == 0) { \
+ 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 */ \
@@ -2100,7 +2100,7 @@ static void Flush_Cache(TTF_Font *font)
}
}
-static FT_Error Load_Glyph(TTF_Font *font, c_glyph *cached, int want, int translation)
+static bool Load_Glyph(TTF_Font *font, c_glyph *cached, int want, int translation)
{
const int alignment = Get_Alignment() - 1;
FT_GlyphSlot slot;
@@ -2124,8 +2124,7 @@ static FT_Error Load_Glyph(TTF_Font *font, c_glyph *cached, int want, int transl
if (want & CACHED_LCD) {
if (slot->format == FT_GLYPH_FORMAT_BITMAP) {
- SDL_SetError("LCD mode not possible with bitmap font");
- return -1;
+ return SDL_SetError("LCD mode not possible with bitmap font");
}
}
@@ -2602,14 +2601,13 @@ static FT_Error Load_Glyph(TTF_Font *font, c_glyph *cached, int want, int transl
}
/* We're done, this glyph is cached since 'stored' is not 0 */
- return 0;
+ return true;
ft_failure:
- TTF_SetFTError("Couldn't find glyph", error);
- return -1;
+ return TTF_SetFTError("Couldn't find glyph", error);
}
-static int Find_GlyphByIndex(TTF_Font *font, FT_UInt idx,
+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)
{
@@ -2632,7 +2630,6 @@ static int Find_GlyphByIndex(TTF_Font *font, FT_UInt idx,
{
/* No 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 retval;
int want = CACHED_METRICS | want_bitmap | want_pixmap | want_color | want_lcd | want_subpixel;
if (glyph->stored && glyph->index != idx) {
@@ -2644,7 +2641,7 @@ static int Find_GlyphByIndex(TTF_Font *font, FT_UInt idx,
}
if ((glyph->stored & want) == want) {
- return 0;
+ return true;
}
if (want_color || want_pixmap || want_lcd) {
@@ -2654,39 +2651,31 @@ static int Find_GlyphByIndex(TTF_Font *font, FT_UInt idx,
}
glyph->index = idx;
- retval = Load_Glyph(font, glyph, want, translation);
- if (retval == 0) {
- return 0;
- } else {
- return -1;
- }
- }
- else
- {
- int retval;
+ return Load_Glyph(font, glyph, want, translation);
+ } else {
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 0;
+ return true;
}
} else if (want_bitmap) {
if ((glyph->stored & CACHED_BITMAP) && glyph->index == idx) {
- return 0;
+ return true;
}
} else if (want_color) {
if ((glyph->stored & CACHED_COLOR) && glyph->index == idx) {
- return 0;
+ return true;
}
} else if (want_lcd) {
if ((glyph->stored & CACHED_LCD) && glyph->index == idx) {
- return 0;
+ return true;
}
} else {
/* Get metrics */
if (glyph->stored && glyph->index == idx) {
- return 0;
+ return true;
}
}
@@ -2703,12 +2692,7 @@ static int Find_GlyphByIndex(TTF_Font *font, FT_UInt idx,
}
glyph->index = idx;
- retval = Load_Glyph(font, glyph, want, 0);
- if (retval == 0) {
- return 0;
- } else {
- return -1;
- }
+ return Load_Glyph(font, glyph, want, 0);
}
}
@@ -2730,7 +2714,7 @@ static FT_UInt get_char_index(TTF_Font *font, Uint32 ch)
}
-static int Find_GlyphMetrics(TTF_Font *font, Uint32 ch, c_glyph **out_glyph)
+static bool Find_GlyphMetrics(TTF_Font *font, Uint32 ch, c_glyph **out_glyph)
{
FT_UInt idx = get_char_index(font, ch);
return Find_GlyphByIndex(font, idx, 0, 0, 0, 0, 0, 0, out_glyph, NULL);
@@ -2850,7 +2834,7 @@ bool TTF_GlyphMetrics(TTF_Font *font, Uint32 ch, int *minx, int *maxx, int *miny
TTF_CHECK_FONT(font, false);
- if (Find_GlyphMetrics(font, ch, &glyph) < 0) {
+ if (!Find_GlyphMetrics(font, ch, &glyph)) {
return false;
}
@@ -3045,7 +3029,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, 0, &glyph, NULL) < 0) {
+ if (!Find_GlyphByIndex(font, idx, 0, 0, 0, 0, 0, 0, &glyph, NULL)) {
goto failure;
}
@@ -3855,36 +3839,43 @@ int TTF_WasInit(void)
return SDL_GetAtomicInt(&TTF_state.refcount);
}
-int TTF_GetFontKerningSizeGlyphs(TTF_Font *font, Uint32 previous_ch, Uint32 ch)
+bool TTF_GetGlyphKerning(TTF_Font *font, Uint32 previous_ch, Uint32 ch, int *kerning)
{
FT_Error error;
c_glyph *prev_glyph, *glyph;
FT_Vector delta;
- TTF_CHECK_FONT(font, -1);
+ if (kerning) {
+ *kerning = 0;
+ }
+
+ TTF_CHECK_FONT(font, false);
if (ch == UNICODE_BOM_NATIVE || ch == UNICODE_BOM_SWAPPED) {
- return 0;
+ return true;
}
if (previous_ch == UNICODE_BOM_NATIVE || previous_ch == UNICODE_BOM_SWAPPED) {
- return 0;
+ return true;
}
- if (Find_GlyphMetrics(font, ch, &glyph) < 0) {
- return -1;
+ if (!Find_GlyphMetrics(font, ch, &glyph)) {
+ return false;
}
- if (Find_GlyphMetrics(font, previous_ch, &prev_glyph) < 0) {
- return -1;
+ if (!Find_GlyphMetrics(font, previous_ch, &prev_glyph)) {
+ return false;
}
error = FT_Get_Kerning(font->face, prev_glyph->index, glyph->index, FT_KERNING_DEFAULT, &delta);
if (error) {
- TTF_SetFTError("Couldn't get glyph kerning", error);
- return -1;
+ return TTF_SetFTError("Couldn't get glyph kerning", error);
}
- return (int)(delta.x >> 6);
+
+ if (kerning) {
+ *kerning = (int)(delta.x >> 6);
+ }
+ return true;
}
bool TTF_IsFontScalable(const TTF_Font *font)
diff --git a/src/SDL_ttf.sym b/src/SDL_ttf.sym
index 85750db6..06e57b9e 100644
--- a/src/SDL_ttf.sym
+++ b/src/SDL_ttf.sym
@@ -11,12 +11,12 @@ SDL3_ttf_0.0.0 {
TTF_FontLineSkip;
TTF_GetFontHinting;
TTF_GetFontKerning;
- TTF_GetFontKerningSizeGlyphs;
TTF_GetFontOutline;
TTF_GetFontSDF;
TTF_GetFontStyle;
TTF_GetFontWrappedAlign;
TTF_GetFreeTypeVersion;
+ TTF_GetGlyphKerning;
TTF_GetHarfBuzzVersion;
TTF_GlyphIsProvided;
TTF_GlyphMetrics;