From 8d501a2dc31f3bef6d5a7f6b0d060c8915082011 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Fri, 10 Mar 2023 09:10:12 +0200 Subject: [PATCH] [TextServer] Add invalid font scaling check, restrict Linux/BSD system fonts lookup to TrueType/CFF only. --- modules/text_server_adv/text_server_adv.cpp | 4 +- modules/text_server_fb/text_server_fb.cpp | 4 +- platform/linuxbsd/os_linuxbsd.cpp | 133 +++++++++++--------- 3 files changed, 77 insertions(+), 64 deletions(-) diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 79c007ace65b..3cf6288fef2e 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -1391,7 +1391,9 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f FT_Select_Size(fd->face, best_match); } else { FT_Set_Pixel_Sizes(fd->face, 0, double(fd->size.x * fd->oversampling)); - fd->scale = ((double)fd->size.x * fd->oversampling) / (double)fd->face->size->metrics.y_ppem; + if (fd->face->size->metrics.y_ppem != 0) { + fd->scale = ((double)fd->size.x * fd->oversampling) / (double)fd->face->size->metrics.y_ppem; + } } fd->hb_handle = hb_ft_font_create(fd->face, nullptr); diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 9a9dcb3a31c0..868772628762 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -830,7 +830,9 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontFallback *p_f FT_Select_Size(fd->face, best_match); } else { FT_Set_Pixel_Sizes(fd->face, 0, Math::round(fd->size.x * fd->oversampling)); - fd->scale = ((double)fd->size.x * fd->oversampling) / (double)fd->face->size->metrics.y_ppem; + if (fd->face->size->metrics.y_ppem != 0) { + fd->scale = ((double)fd->size.x * fd->oversampling) / (double)fd->face->size->metrics.y_ppem; + } } fd->ascent = (fd->face->size->metrics.ascender / 64.0) / fd->oversampling * fd->scale; diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index 54bb34ef73f8..88c3d2cc14a1 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -677,40 +677,45 @@ Vector OS_LinuxBSD::get_system_font_path_for_text(const String &p_font_n } Vector ret; - FcPattern *pattern = FcPatternCreate(); - if (pattern) { - FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast(p_font_name.utf8().get_data())); - FcPatternAddInteger(pattern, FC_WEIGHT, _weight_to_fc(p_weight)); - FcPatternAddInteger(pattern, FC_WIDTH, _stretch_to_fc(p_stretch)); - FcPatternAddInteger(pattern, FC_SLANT, p_italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); + static const char *allowed_formats[] = { "TrueType", "CFF" }; + for (size_t i = 0; i < sizeof(allowed_formats) / sizeof(const char *); i++) { + FcPattern *pattern = FcPatternCreate(); + if (pattern) { + FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); + FcPatternAddString(pattern, FC_FONTFORMAT, reinterpret_cast(allowed_formats[i])); + FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast(p_font_name.utf8().get_data())); + FcPatternAddInteger(pattern, FC_WEIGHT, _weight_to_fc(p_weight)); + FcPatternAddInteger(pattern, FC_WIDTH, _stretch_to_fc(p_stretch)); + FcPatternAddInteger(pattern, FC_SLANT, p_italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); - FcCharSet *char_set = FcCharSetCreate(); - for (int i = 0; i < p_text.size(); i++) { - FcCharSetAddChar(char_set, p_text[i]); - } - FcPatternAddCharSet(pattern, FC_CHARSET, char_set); - - FcLangSet *lang_set = FcLangSetCreate(); - FcLangSetAdd(lang_set, reinterpret_cast(p_locale.utf8().get_data())); - FcPatternAddLangSet(pattern, FC_LANG, lang_set); - - FcConfigSubstitute(0, pattern, FcMatchPattern); - FcDefaultSubstitute(pattern); - - FcResult result; - FcPattern *match = FcFontMatch(0, pattern, &result); - if (match) { - char *file_name = nullptr; - if (FcPatternGetString(match, FC_FILE, 0, reinterpret_cast(&file_name)) == FcResultMatch) { - if (file_name) { - ret.push_back(String::utf8(file_name)); - } + FcCharSet *char_set = FcCharSetCreate(); + for (int j = 0; j < p_text.size(); j++) { + FcCharSetAddChar(char_set, p_text[j]); } - FcPatternDestroy(match); + FcPatternAddCharSet(pattern, FC_CHARSET, char_set); + + FcLangSet *lang_set = FcLangSetCreate(); + FcLangSetAdd(lang_set, reinterpret_cast(p_locale.utf8().get_data())); + FcPatternAddLangSet(pattern, FC_LANG, lang_set); + + FcConfigSubstitute(0, pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + + FcResult result; + FcPattern *match = FcFontMatch(0, pattern, &result); + if (match) { + char *file_name = nullptr; + if (FcPatternGetString(match, FC_FILE, 0, reinterpret_cast(&file_name)) == FcResultMatch) { + if (file_name) { + ret.push_back(String::utf8(file_name)); + } + } + FcPatternDestroy(match); + } + FcPatternDestroy(pattern); + FcCharSetDestroy(char_set); + FcLangSetDestroy(lang_set); } - FcPatternDestroy(pattern); - FcCharSetDestroy(char_set); - FcLangSetDestroy(lang_set); } return ret; @@ -725,47 +730,51 @@ String OS_LinuxBSD::get_system_font_path(const String &p_font_name, int p_weight ERR_FAIL_V_MSG(String(), "Unable to load fontconfig, system font support is disabled."); } - String ret; - FcPattern *pattern = FcPatternCreate(); - if (pattern) { - bool allow_substitutes = (p_font_name.to_lower() == "sans-serif") || (p_font_name.to_lower() == "serif") || (p_font_name.to_lower() == "monospace") || (p_font_name.to_lower() == "cursive") || (p_font_name.to_lower() == "fantasy"); + static const char *allowed_formats[] = { "TrueType", "CFF" }; + for (size_t i = 0; i < sizeof(allowed_formats) / sizeof(const char *); i++) { + FcPattern *pattern = FcPatternCreate(); + if (pattern) { + bool allow_substitutes = (p_font_name.to_lower() == "sans-serif") || (p_font_name.to_lower() == "serif") || (p_font_name.to_lower() == "monospace") || (p_font_name.to_lower() == "cursive") || (p_font_name.to_lower() == "fantasy"); - FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); - FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast(p_font_name.utf8().get_data())); - FcPatternAddInteger(pattern, FC_WEIGHT, _weight_to_fc(p_weight)); - FcPatternAddInteger(pattern, FC_WIDTH, _stretch_to_fc(p_stretch)); - FcPatternAddInteger(pattern, FC_SLANT, p_italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); + FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); + FcPatternAddString(pattern, FC_FONTFORMAT, reinterpret_cast(allowed_formats[i])); + FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast(p_font_name.utf8().get_data())); + FcPatternAddInteger(pattern, FC_WEIGHT, _weight_to_fc(p_weight)); + FcPatternAddInteger(pattern, FC_WIDTH, _stretch_to_fc(p_stretch)); + FcPatternAddInteger(pattern, FC_SLANT, p_italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); - FcConfigSubstitute(0, pattern, FcMatchPattern); - FcDefaultSubstitute(pattern); + FcConfigSubstitute(0, pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); - FcResult result; - FcPattern *match = FcFontMatch(0, pattern, &result); - if (match) { - if (!allow_substitutes) { - char *family_name = nullptr; - if (FcPatternGetString(match, FC_FAMILY, 0, reinterpret_cast(&family_name)) == FcResultMatch) { - if (family_name && String::utf8(family_name).to_lower() != p_font_name.to_lower()) { - FcPatternDestroy(match); - FcPatternDestroy(pattern); - - return String(); + FcResult result; + FcPattern *match = FcFontMatch(0, pattern, &result); + if (match) { + if (!allow_substitutes) { + char *family_name = nullptr; + if (FcPatternGetString(match, FC_FAMILY, 0, reinterpret_cast(&family_name)) == FcResultMatch) { + if (family_name && String::utf8(family_name).to_lower() != p_font_name.to_lower()) { + FcPatternDestroy(match); + FcPatternDestroy(pattern); + continue; + } } } - } - char *file_name = nullptr; - if (FcPatternGetString(match, FC_FILE, 0, reinterpret_cast(&file_name)) == FcResultMatch) { - if (file_name) { - ret = String::utf8(file_name); + char *file_name = nullptr; + if (FcPatternGetString(match, FC_FILE, 0, reinterpret_cast(&file_name)) == FcResultMatch) { + if (file_name) { + String ret = String::utf8(file_name); + FcPatternDestroy(match); + FcPatternDestroy(pattern); + return ret; + } } + FcPatternDestroy(match); } - - FcPatternDestroy(match); + FcPatternDestroy(pattern); } - FcPatternDestroy(pattern); } - return ret; + return String(); #else ERR_FAIL_V_MSG(String(), "Godot was compiled without fontconfig, system font support is disabled."); #endif