Skip to content

Commit

Permalink
Added TTF_StringToTag() and TTF_TagToString()
Browse files Browse the repository at this point in the history
Also clarified that the script used in the API is an ISO 15924 script code.

Fixes #505
  • Loading branch information
slouken committed Feb 6, 2025
1 parent e4caa3b commit aada768
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 15 deletions.
53 changes: 46 additions & 7 deletions include/SDL3_ttf/SDL_ttf.h
Original file line number Diff line number Diff line change
Expand Up @@ -941,48 +941,83 @@ extern SDL_DECLSPEC bool SDLCALL TTF_SetFontDirection(TTF_Font *font, TTF_Direct
*/
extern SDL_DECLSPEC TTF_Direction SDLCALL TTF_GetFontDirection(TTF_Font *font);

/**
* Convert from a 4 character string to a 32-bit tag.
*
* \param string the 4 character string to convert.
* \returns the 32-bit representation of the string.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL_ttf 3.0.0.
*
* \sa TTF_TagToString
*/
extern SDL_DECLSPEC Uint32 SDLCALL TTF_StringToTag(const char *string);

/**
* Convert from a 32-bit tag to a 4 character string.
*
* \param tag the 32-bit tag to convert.
* \param string a pointer filled in with the 4 character representation of the tag.
* \param size the size of the buffer pointed at by string, should be at least 4.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL_ttf 3.0.0.
*
* \sa TTF_TagToString
*/
extern SDL_DECLSPEC void SDLCALL TTF_TagToString(Uint32 tag, char *string, size_t size);

/**
* Set the script to be used for text shaping by a font.
*
* This returns false if SDL_ttf isn't build with HarfBuzz support.
* This returns false if SDL_ttf isn't built with HarfBuzz support.
*
* This updates any TTF_Text objects using this font.
*
* \param font the font to modify.
* \param script a script tag in the format used by HarfBuzz.
* \param script an [ISO 15924 code](https://unicode.org/iso15924/iso15924-codes.html).
* \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.
*
* \sa TTF_StringToTag
*/
extern SDL_DECLSPEC bool SDLCALL TTF_SetFontScript(TTF_Font *font, Uint32 script);

/**
* Get the script used for text shaping a font.
*
* \param font the font to query.
* \returns a script tag in the format used by HarfBuzz.
* \returns an [ISO 15924 code](https://unicode.org/iso15924/iso15924-codes.html) or 0 if a script hasn't been set.
*
* \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_TagToString
*/
extern SDL_DECLSPEC Uint32 SDLCALL TTF_GetFontScript(TTF_Font *font);

/**
* Get the script used by a 32-bit codepoint.
*
* \param ch the character code to check.
* \returns a script tag in the format used by HarfBuzz on success, or 0 on
* \returns an [ISO 15924 code](https://unicode.org/iso15924/iso15924-codes.html) on success, or 0 on
* failure; call SDL_GetError() for more information.
*
* \threadsafety This function is thread-safe.
*
* \since This function is available since SDL_ttf 3.0.0.
*
* \sa TTF_TagToString
*/
extern SDL_DECLSPEC Uint32 SDLCALL TTF_GetGlyphScript(Uint32 ch);

Expand Down Expand Up @@ -2110,17 +2145,19 @@ extern SDL_DECLSPEC TTF_Direction SDLCALL TTF_GetTextDirection(TTF_Text *text);
/**
* Set the script to be used for text shaping a text object.
*
* This returns false if SDL_ttf isn't build with HarfBuzz support.
* This returns false if SDL_ttf isn't built with HarfBuzz support.
*
* \param text the text to modify.
* \param script a script tag in the format used by HarfBuzz.
* \param script an [ISO 15924 code](https://unicode.org/iso15924/iso15924-codes.html).
* \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_StringToTag
*/
extern SDL_DECLSPEC bool SDLCALL TTF_SetTextScript(TTF_Text *text, Uint32 script);

Expand All @@ -2130,12 +2167,14 @@ extern SDL_DECLSPEC bool SDLCALL TTF_SetTextScript(TTF_Text *text, Uint32 script
* This defaults to the script of the font used by the text object.
*
* \param text the text to query.
* \returns a script tag in the format used by HarfBuzz.
* \returns an [ISO 15924 code](https://unicode.org/iso15924/iso15924-codes.html) or 0 if a script hasn't been set on either the text object or the font.
*
* \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_TagToString
*/
extern SDL_DECLSPEC Uint32 SDLCALL TTF_GetTextScript(TTF_Text *text);

Expand Down
45 changes: 37 additions & 8 deletions src/SDL_ttf.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ struct TTF_Font {
hb_font_t *hb_font;
hb_language_t hb_language;
#endif
Uint32 script;
Uint32 script; // ISO 15924 script tag
TTF_Direction direction;
bool render_sdf;

Expand Down Expand Up @@ -3352,7 +3352,7 @@ static bool CollectGlyphsFromFont(TTF_Font *font, const char *text, size_t lengt
// Set global configuration
hb_buffer_set_language(hb_buffer, font->hb_language);
hb_buffer_set_direction(hb_buffer, (hb_direction_t)direction);
hb_buffer_set_script(hb_buffer, script);
hb_buffer_set_script(hb_buffer, hb_script_from_iso15924_tag(script));

// Layout the text
hb_buffer_add_utf8(hb_buffer, text, (int)length, 0, -1);
Expand Down Expand Up @@ -4369,7 +4369,7 @@ SDL_Surface* TTF_RenderText_LCD_Wrapped(TTF_Font *font, const char *text, size_t
struct TTF_TextLayout
{
TTF_Direction direction;
Uint32 script;
Uint32 script; // ISO 15924 script tag
int font_height;
int wrap_length;
bool wrap_whitespace_visible;
Expand Down Expand Up @@ -4815,7 +4815,7 @@ Uint32 TTF_GetTextScript(TTF_Text *text)
{
TTF_CHECK_POINTER("text", text, 0);

if (text->internal->layout->script != 0) {
if (text->internal->layout->script) {
return text->internal->layout->script;
}
return TTF_GetFontScript(text->internal->font);
Expand Down Expand Up @@ -6001,6 +6001,38 @@ TTF_Direction TTF_GetFontDirection(TTF_Font *font)
return font->direction;
}

Uint32 TTF_StringToTag(const char *string)
{
Uint8 bytes[4] = { 0, 0, 0, 0 };

if (string) {
for (size_t i = 0; i < 4 && string[i]; ++i) {
bytes[i] = (Uint8)string[i];
}
}

Uint32 tag = ((Uint32)bytes[0] << 24) |
((Uint32)bytes[1] << 16) |
((Uint32)bytes[2] << 8) |
((Uint32)bytes[3] << 0);
return tag;
}

void TTF_TagToString(Uint32 tag, char *string, size_t size)
{
if (!string || !size) {
return;
}

for (size_t i = 0; i < 4 && i < size; ++i) {
string[i] = (char)(Uint8)(tag >> 24);
tag <<= 8;
}
if (size > 4) {
string[4] = '\0';
}
}

bool TTF_SetFontScript(TTF_Font *font, Uint32 script)
{
TTF_CHECK_FONT(font, false);
Expand Down Expand Up @@ -6045,10 +6077,7 @@ Uint32 TTF_GetGlyphScript(Uint32 ch)
hb_buffer_clear_contents(hb_buffer);
hb_buffer_set_content_type(hb_buffer, HB_BUFFER_CONTENT_TYPE_UNICODE);

script = hb_unicode_script(hb_unicode_functions, ch);
if (script == HB_SCRIPT_UNKNOWN) {
script = 0;
}
script = hb_script_to_iso15924_tag(hb_unicode_script(hb_unicode_functions, ch));

hb_buffer_destroy(hb_buffer);
#else
Expand Down
2 changes: 2 additions & 0 deletions src/SDL_ttf.sym
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ SDL3_ttf_0.0.0 {
TTF_SetTextString;
TTF_SetTextWrapWhitespaceVisible;
TTF_SetTextWrapWidth;
TTF_StringToTag;
TTF_TagToString;
TTF_TextWrapWhitespaceVisible;
TTF_UpdateText;
TTF_Version;
Expand Down

0 comments on commit aada768

Please sign in to comment.