mirror of
https://github.com/godotengine/godot
synced 2024-10-14 21:57:35 +00:00
[TextServer] Add invalid font scaling check, restrict Linux/BSD system fonts lookup to TrueType/CFF only.
This commit is contained in:
parent
c1128e911c
commit
8d501a2dc3
|
@ -1391,7 +1391,9 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f
|
||||||
FT_Select_Size(fd->face, best_match);
|
FT_Select_Size(fd->face, best_match);
|
||||||
} else {
|
} else {
|
||||||
FT_Set_Pixel_Sizes(fd->face, 0, double(fd->size.x * fd->oversampling));
|
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);
|
fd->hb_handle = hb_ft_font_create(fd->face, nullptr);
|
||||||
|
|
|
@ -830,7 +830,9 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontFallback *p_f
|
||||||
FT_Select_Size(fd->face, best_match);
|
FT_Select_Size(fd->face, best_match);
|
||||||
} else {
|
} else {
|
||||||
FT_Set_Pixel_Sizes(fd->face, 0, Math::round(fd->size.x * fd->oversampling));
|
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;
|
fd->ascent = (fd->face->size->metrics.ascender / 64.0) / fd->oversampling * fd->scale;
|
||||||
|
|
|
@ -677,40 +677,45 @@ Vector<String> OS_LinuxBSD::get_system_font_path_for_text(const String &p_font_n
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<String> ret;
|
Vector<String> ret;
|
||||||
FcPattern *pattern = FcPatternCreate();
|
static const char *allowed_formats[] = { "TrueType", "CFF" };
|
||||||
if (pattern) {
|
for (size_t i = 0; i < sizeof(allowed_formats) / sizeof(const char *); i++) {
|
||||||
FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8 *>(p_font_name.utf8().get_data()));
|
FcPattern *pattern = FcPatternCreate();
|
||||||
FcPatternAddInteger(pattern, FC_WEIGHT, _weight_to_fc(p_weight));
|
if (pattern) {
|
||||||
FcPatternAddInteger(pattern, FC_WIDTH, _stretch_to_fc(p_stretch));
|
FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
|
||||||
FcPatternAddInteger(pattern, FC_SLANT, p_italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN);
|
FcPatternAddString(pattern, FC_FONTFORMAT, reinterpret_cast<const FcChar8 *>(allowed_formats[i]));
|
||||||
|
FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8 *>(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();
|
FcCharSet *char_set = FcCharSetCreate();
|
||||||
for (int i = 0; i < p_text.size(); i++) {
|
for (int j = 0; j < p_text.size(); j++) {
|
||||||
FcCharSetAddChar(char_set, p_text[i]);
|
FcCharSetAddChar(char_set, p_text[j]);
|
||||||
}
|
|
||||||
FcPatternAddCharSet(pattern, FC_CHARSET, char_set);
|
|
||||||
|
|
||||||
FcLangSet *lang_set = FcLangSetCreate();
|
|
||||||
FcLangSetAdd(lang_set, reinterpret_cast<const FcChar8 *>(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<FcChar8 **>(&file_name)) == FcResultMatch) {
|
|
||||||
if (file_name) {
|
|
||||||
ret.push_back(String::utf8(file_name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
FcPatternDestroy(match);
|
FcPatternAddCharSet(pattern, FC_CHARSET, char_set);
|
||||||
|
|
||||||
|
FcLangSet *lang_set = FcLangSetCreate();
|
||||||
|
FcLangSetAdd(lang_set, reinterpret_cast<const FcChar8 *>(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<FcChar8 **>(&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;
|
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.");
|
ERR_FAIL_V_MSG(String(), "Unable to load fontconfig, system font support is disabled.");
|
||||||
}
|
}
|
||||||
|
|
||||||
String ret;
|
static const char *allowed_formats[] = { "TrueType", "CFF" };
|
||||||
FcPattern *pattern = FcPatternCreate();
|
for (size_t i = 0; i < sizeof(allowed_formats) / sizeof(const char *); i++) {
|
||||||
if (pattern) {
|
FcPattern *pattern = FcPatternCreate();
|
||||||
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");
|
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);
|
FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
|
||||||
FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8 *>(p_font_name.utf8().get_data()));
|
FcPatternAddString(pattern, FC_FONTFORMAT, reinterpret_cast<const FcChar8 *>(allowed_formats[i]));
|
||||||
FcPatternAddInteger(pattern, FC_WEIGHT, _weight_to_fc(p_weight));
|
FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8 *>(p_font_name.utf8().get_data()));
|
||||||
FcPatternAddInteger(pattern, FC_WIDTH, _stretch_to_fc(p_stretch));
|
FcPatternAddInteger(pattern, FC_WEIGHT, _weight_to_fc(p_weight));
|
||||||
FcPatternAddInteger(pattern, FC_SLANT, p_italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN);
|
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);
|
FcConfigSubstitute(0, pattern, FcMatchPattern);
|
||||||
FcDefaultSubstitute(pattern);
|
FcDefaultSubstitute(pattern);
|
||||||
|
|
||||||
FcResult result;
|
FcResult result;
|
||||||
FcPattern *match = FcFontMatch(0, pattern, &result);
|
FcPattern *match = FcFontMatch(0, pattern, &result);
|
||||||
if (match) {
|
if (match) {
|
||||||
if (!allow_substitutes) {
|
if (!allow_substitutes) {
|
||||||
char *family_name = nullptr;
|
char *family_name = nullptr;
|
||||||
if (FcPatternGetString(match, FC_FAMILY, 0, reinterpret_cast<FcChar8 **>(&family_name)) == FcResultMatch) {
|
if (FcPatternGetString(match, FC_FAMILY, 0, reinterpret_cast<FcChar8 **>(&family_name)) == FcResultMatch) {
|
||||||
if (family_name && String::utf8(family_name).to_lower() != p_font_name.to_lower()) {
|
if (family_name && String::utf8(family_name).to_lower() != p_font_name.to_lower()) {
|
||||||
FcPatternDestroy(match);
|
FcPatternDestroy(match);
|
||||||
FcPatternDestroy(pattern);
|
FcPatternDestroy(pattern);
|
||||||
|
continue;
|
||||||
return String();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
char *file_name = nullptr;
|
||||||
char *file_name = nullptr;
|
if (FcPatternGetString(match, FC_FILE, 0, reinterpret_cast<FcChar8 **>(&file_name)) == FcResultMatch) {
|
||||||
if (FcPatternGetString(match, FC_FILE, 0, reinterpret_cast<FcChar8 **>(&file_name)) == FcResultMatch) {
|
if (file_name) {
|
||||||
if (file_name) {
|
String ret = String::utf8(file_name);
|
||||||
ret = String::utf8(file_name);
|
FcPatternDestroy(match);
|
||||||
|
FcPatternDestroy(pattern);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
FcPatternDestroy(match);
|
||||||
}
|
}
|
||||||
|
FcPatternDestroy(pattern);
|
||||||
FcPatternDestroy(match);
|
|
||||||
}
|
}
|
||||||
FcPatternDestroy(pattern);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return String();
|
||||||
#else
|
#else
|
||||||
ERR_FAIL_V_MSG(String(), "Godot was compiled without fontconfig, system font support is disabled.");
|
ERR_FAIL_V_MSG(String(), "Godot was compiled without fontconfig, system font support is disabled.");
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue