From 6e4a9777f8f5b61668446924cc51bcfb1412fd1f Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 26 Sep 2024 20:04:28 -0700 Subject: [PATCH] Added TTF_GetGlyphScript() Fixes https://github.com/libsdl-org/SDL_ttf/issues/351 Closes https://github.com/libsdl-org/SDL_ttf/pull/312 --- build-scripts/SDL_migration.cocci | 5 ++++ docs/README-migration.md | 1 + include/SDL3_ttf/SDL_ttf.h | 28 ++++++++++++++++++--- src/SDL_ttf.c | 42 ++++++++++++++++++++++++++++++- src/SDL_ttf.sym | 3 ++- 5 files changed, 73 insertions(+), 6 deletions(-) diff --git a/build-scripts/SDL_migration.cocci b/build-scripts/SDL_migration.cocci index 81b3788f..9a7c931d 100644 --- a/build-scripts/SDL_migration.cocci +++ b/build-scripts/SDL_migration.cocci @@ -155,3 +155,8 @@ - TTF_IsFontScalable + TTF_FontIsScalable (...) +@@ +@@ +- TTF_SetFontScriptName ++ TTF_SetFontScript + (...) diff --git a/docs/README-migration.md b/docs/README-migration.md index 422011fc..bebaa9b7 100644 --- a/docs/README-migration.md +++ b/docs/README-migration.md @@ -63,6 +63,7 @@ The following functions have been renamed: * TTF_RenderUTF8_Shaded_Wrapped() => TTF_RenderText_Shaded_Wrapped() * TTF_RenderUTF8_Solid() => SDL_RenderText_Solid() * TTF_RenderUTF8_Solid_Wrapped() => TTF_RenderText_Solid_Wrapped() +* TTF_SetFontScriptName() => TTF_SetFontScript() * TTF_SetFontWrappedAlign() => TTF_SetFontWrapAlignment() * TTF_SizeUTF8() => TTF_SizeText() diff --git a/include/SDL3_ttf/SDL_ttf.h b/include/SDL3_ttf/SDL_ttf.h index 31b376c6..cebe9e1c 100644 --- a/include/SDL3_ttf/SDL_ttf.h +++ b/include/SDL3_ttf/SDL_ttf.h @@ -1280,7 +1280,7 @@ typedef enum TTF_Direction * - `TTF_DIRECTION_TTB` (Top to Bottom) * - `TTF_DIRECTION_BTT` (Bottom to Top) * - * If SDL_ttf was not built with HarfBuzz support, this function returns -1. + * If SDL_ttf was not built with HarfBuzz support, this function returns false. * * \param font the font to specify a direction for. * \param direction the new direction for text to flow. @@ -1299,23 +1299,43 @@ extern SDL_DECLSPEC bool SDLCALL TTF_SetFontDirection(TTF_Font *font, TTF_Direct * The supplied script value must be a null-terminated string of exactly four * characters. * - * If SDL_ttf was not built with HarfBuzz support, this function returns -1. + * If SDL_ttf was not built with HarfBuzz support, this function returns false. * * \param font the font to specify a script name for. * \param script null-terminated string of exactly 4 characters. * \returns true on success or false on failure; call SDL_GetError() for more * information. * + * \threadsafety This function is not thread-safe. + * + * \since This function is available since SDL_ttf 3.0.0. + */ +extern SDL_DECLSPEC bool SDLCALL TTF_SetFontScript(TTF_Font *font, const char *script); + +/** + * Get the script used by a 32-bit codepoint. + * + * The supplied script value will be a null-terminated string of exactly four + * characters. + * + * If SDL_ttf was not built with HarfBuzz support, this function returns false. + * + * \param ch the character code to check. + * \param script a pointer filled in with the script used by `ch`. + * \param script_size the size of the script buffer, which must be at least 5 characters. + * \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 bool SDLCALL TTF_SetFontScriptName(TTF_Font *font, const char *script); +extern SDL_DECLSPEC bool SDLCALL TTF_GetGlyphScript(Uint32 ch, char *script, size_t script_size); /** * Set language to be used for text shaping by a font. * - * If SDL_ttf was not built with HarfBuzz support, this function returns -1. + * If SDL_ttf was not built with HarfBuzz support, this function returns false. * * \param font the font to specify a language for. * \param language_bcp47 a null-terminated string containing the desired language's BCP47 code. Or null to reset the value. diff --git a/src/SDL_ttf.c b/src/SDL_ttf.c index 384286ce..1e9e9152 100644 --- a/src/SDL_ttf.c +++ b/src/SDL_ttf.c @@ -2903,7 +2903,7 @@ bool TTF_SetFontDirection(TTF_Font *font, TTF_Direction direction) #endif } -bool TTF_SetFontScriptName(TTF_Font *font, const char *script) +bool TTF_SetFontScript(TTF_Font *font, const char *script) { TTF_CHECK_FONT(font, false); @@ -2928,6 +2928,46 @@ bool TTF_SetFontScriptName(TTF_Font *font, const char *script) #endif } +bool TTF_GetGlyphScript(Uint32 ch, char *script, size_t script_size) +{ +#if TTF_USE_HARFBUZZ + TTF_CHECK_POINTER("script", script, false); + + if (script_size < 5) { + return SDL_SetError("Insufficient script buffer size"); + } + + hb_buffer_t *hb_buffer = hb_buffer_create(); + + if (hb_buffer == NULL) { + return SDL_SetError("Cannot create harfbuzz buffer"); + } + + hb_unicode_funcs_t* hb_unicode_functions = hb_buffer_get_unicode_funcs(hb_buffer); + + if (hb_unicode_functions == NULL) { + hb_buffer_destroy(hb_buffer); + return SDL_SetError("Cannot get harfbuzz unicode functions"); + } + + hb_buffer_clear_contents(hb_buffer); + hb_buffer_set_content_type(hb_buffer, HB_BUFFER_CONTENT_TYPE_UNICODE); + + uint8_t untagged_script[4] = { HB_UNTAG(hb_unicode_script(hb_unicode_functions, ch)) }; + script[0] = (char)untagged_script[0]; + script[1] = (char)untagged_script[1]; + script[2] = (char)untagged_script[2]; + script[3] = (char)untagged_script[3]; + script[4] = '\0'; + + hb_buffer_destroy(hb_buffer); + return true; + +#else + return SDL_SetError("Unsupported"); +#endif +} + bool TTF_SetFontLanguage(TTF_Font *font, const char *language_bcp47) { TTF_CHECK_FONT(font, false); diff --git a/src/SDL_ttf.sym b/src/SDL_ttf.sym index c6891704..b8bfb910 100644 --- a/src/SDL_ttf.sym +++ b/src/SDL_ttf.sym @@ -20,6 +20,7 @@ SDL3_ttf_0.0.0 { TTF_GetFreeTypeVersion; TTF_GetGlyphKerning; TTF_GetGlyphMetrics; + TTF_GetGlyphScript; TTF_GetHarfBuzzVersion; TTF_Init; TTF_MeasureText; @@ -46,7 +47,7 @@ SDL3_ttf_0.0.0 { TTF_SetFontLineSkip; TTF_SetFontOutline; TTF_SetFontSDF; - TTF_SetFontScriptName; + TTF_SetFontScript; TTF_SetFontSize; TTF_SetFontSizeDPI; TTF_SetFontStyle;