diff options
Diffstat (limited to 'modules/text_server_fb/text_server_fb.cpp')
-rw-r--r-- | modules/text_server_fb/text_server_fb.cpp | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 4c0ed084d8..c3f62d7324 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -71,8 +71,10 @@ using namespace godot; #endif #endif -#ifdef MODULE_SVG_ENABLED #ifdef MODULE_FREETYPE_ENABLED +#include FT_SFNT_NAMES_H +#include FT_TRUETYPE_IDS_H +#ifdef MODULE_SVG_ENABLED #include "thorvg_svg_in_ot.h" #endif #endif @@ -669,7 +671,7 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_glyph(FontFallback *p_font_data, } if (p_font_data->embolden != 0.f) { - FT_Pos strength = p_font_data->embolden * p_size.x * 4; // 26.6 fractional units (1 / 64). + FT_Pos strength = p_font_data->embolden * p_size.x * fd->oversampling * 4; // 26.6 fractional units (1 / 64). FT_Outline_Embolden(&fd->face->glyph->outline, strength); } @@ -857,8 +859,37 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontFallback *p_f fd->underline_thickness = (FT_MulFix(fd->face->underline_thickness, fd->face->size->metrics.y_scale) / 64.0) / fd->oversampling * fd->scale; if (!p_font_data->face_init) { - // Get style flags and name. - if (fd->face->family_name != nullptr) { + // When a font does not provide a `family_name`, FreeType tries to synthesize one based on other names. + // FreeType automatically converts non-ASCII characters to "?" in the synthesized name. + // To avoid that behavior, use the format-specific name directly if available. + if (FT_IS_SFNT(fd->face)) { + int name_count = FT_Get_Sfnt_Name_Count(fd->face); + for (int i = 0; i < name_count; i++) { + FT_SfntName sfnt_name; + if (FT_Get_Sfnt_Name(fd->face, i, &sfnt_name) != 0) { + continue; + } + if (sfnt_name.name_id != TT_NAME_ID_FONT_FAMILY && sfnt_name.name_id != TT_NAME_ID_TYPOGRAPHIC_FAMILY) { + continue; + } + if (!p_font_data->font_name.is_empty() && sfnt_name.language_id != TT_MS_LANGID_ENGLISH_UNITED_STATES) { + continue; + } + + switch (sfnt_name.platform_id) { + case TT_PLATFORM_APPLE_UNICODE: { + p_font_data->font_name.parse_utf16((const char16_t *)sfnt_name.string, sfnt_name.string_len / 2, false); + } break; + + case TT_PLATFORM_MICROSOFT: { + if (sfnt_name.encoding_id == TT_MS_ID_UNICODE_CS || sfnt_name.encoding_id == TT_MS_ID_UCS_4) { + p_font_data->font_name.parse_utf16((const char16_t *)sfnt_name.string, sfnt_name.string_len / 2, false); + } + } break; + } + } + } + if (p_font_data->font_name.is_empty() && fd->face->family_name != nullptr) { p_font_data->font_name = String::utf8((const char *)fd->face->family_name); } if (fd->face->style_name != nullptr) { @@ -4439,6 +4470,10 @@ String TextServerFallback::_string_to_lower(const String &p_string, const String return p_string.to_lower(); } +String TextServerFallback::_string_to_title(const String &p_string, const String &p_language) const { + return p_string.capitalize(); +} + PackedInt32Array TextServerFallback::_string_get_word_breaks(const String &p_string, const String &p_language, int64_t p_chars_per_line) const { PackedInt32Array ret; |