diff --git a/Makefile.common b/Makefile.common index 365fab1041..44e7ec0e25 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1079,6 +1079,10 @@ ifeq ($(HAVE_FREETYPE), 1) OBJ += gfx/drivers_font_renderer/freetype.o LIBS += $(FREETYPE_LIBS) DEF_FLAGS += $(FREETYPE_CFLAGS) + ifeq ($(HAVE_FREETYPE), 1) + LIBS += $(FONTCONFIG_LIBS) + DEF_FLAGS += $(FONTCONFIG_CFLAGS) + endif endif ifeq ($(HAVE_THREADS), 1) diff --git a/gfx/drivers_font_renderer/freetype.c b/gfx/drivers_font_renderer/freetype.c index aa6782a856..24a2b80c2d 100644 --- a/gfx/drivers_font_renderer/freetype.c +++ b/gfx/drivers_font_renderer/freetype.c @@ -27,6 +27,11 @@ #include #include +#ifdef HAVE_FONTCONFIG +#include +#include "../../msg_hash.h" +#endif + #ifdef WIIU #include #endif @@ -240,6 +245,43 @@ static void *font_renderer_ft_init(const char *font_path, float font_size) err = FT_New_Memory_Face(handle->lib, font_data, font_size, 0, &handle->face); } else +#elif HAVE_FONTCONFIG + /* if fallback font is requested, instead of loading it, we find the full font in the system */ + if (!*font_path || strstr(font_path, "fallback")) + { + FcConfig* config = FcInitLoadConfigAndFonts(); + FcResult result = FcResultNoMatch; + FcChar8* font_path = NULL; + int face_index = 0; + /* select Sans fonts */ + FcPattern* pattern = FcNameParse((const FcChar8*)"Sans"); + /* since fontconfig uses LL-TT style, we need to normalize locale names */ + FcChar8* locale = FcLangNormalize((const FcChar8*)get_user_language_iso639_1(false)); + /* box the locale data in a FcValue container */ + FcValue locale_boxed = {.type = FcTypeString, {locale}}; + /* configure fontconfig substitute policies, this will increase the search scope */ + FcConfigSubstitute(config, pattern, FcMatchPattern); + /* pull in system-wide defaults, so the font selection respects system (or user) configurations */ + FcDefaultSubstitute(pattern); + /* override locale settins, since we are not using the system locale */ + FcPatternAdd(pattern, FC_LANG, locale_boxed, false); + /* let's find the best matching font given our search criteria */ + FcPattern* found = FcFontMatch(config, pattern, &result); + /* uh-oh, for some reason, we can't find any font */ + if (result != FcResultMatch) + goto error; + if (FcPatternGetString(found, FC_FILE, 0, &font_path) != FcResultMatch) + goto error; + if (FcPatternGetInteger(found, FC_INDEX, 0, &face_index) != FcResultMatch) + goto error; + /* initialize font renderer */ + err = FT_New_Face(handle->lib, (const char*)font_path, face_index, &handle->face); + /* free up fontconfig internal structures */ + FcPatternDestroy(pattern); + FcPatternDestroy(found); + FcStrFree(locale); + FcConfigDestroy(config); + } else #endif { if (!path_is_valid(font_path)) @@ -304,7 +346,9 @@ static const char *font_paths[] = { /* Highly OS/platform dependent. */ static const char *font_renderer_ft_get_default_font(void) { -#ifdef WIIU +/* Since fontconfig will return parameters more than a simple path + we will process these in the init function */ +#if defined(WIIU) || defined(HAVE_FONTCONFIG) return ""; #else size_t i; diff --git a/msg_hash.c b/msg_hash.c index 72875c7222..22e88a4cca 100644 --- a/msg_hash.c +++ b/msg_hash.c @@ -146,9 +146,13 @@ const char *get_user_language_iso639_1(bool limit) case RETRO_LANGUAGE_VIETNAMESE: return "vi"; case RETRO_LANGUAGE_CHINESE_SIMPLIFIED: - return "zh"; + if (limit) + return "zh"; + return "zh_cn"; case RETRO_LANGUAGE_CHINESE_TRADITIONAL: - return "zh"; + if (limit) + return "zh"; + return "zh_tw"; case RETRO_LANGUAGE_ARABIC: return "ar"; case RETRO_LANGUAGE_GREEK: diff --git a/qb/config.libs.sh b/qb/config.libs.sh index 1e16cdd0d7..c9aa28eb1a 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -498,6 +498,7 @@ check_pkgconf DBUS dbus-1 check_val '' UDEV "-ludev" '' libudev '' '' false check_val '' V4L2 -lv4l2 '' libv4l2 '' '' false check_val '' FREETYPE -lfreetype freetype2 freetype2 '' '' false +check_val '' FONTCONFIG -lfontconfig fontconfig fontconfig '' '' false check_val '' X11 -lX11 '' x11 '' '' false if [ "$HAVE_X11" != 'no' ]; then