feat: Enumerate fonts on Linux using Fontconfig when available (#1821)

### Problem description

The fonts list on Linux does not show all system fonts, and does not
show font names at all.

### Implementation description

Use Fontconfig to make the list less bad if Fontconfig headers are
available.

### Additional things

I like fonts.

---------

Co-authored-by: Nik <werwolv98@gmail.com>
This commit is contained in:
Colin Snover
2024-07-21 13:28:37 -05:00
committed by GitHub
parent 09b6c2ab5b
commit c1c51e0baf
11 changed files with 58 additions and 2 deletions

View File

@@ -63,6 +63,15 @@ if (WIN32)
target_link_libraries(main PRIVATE usp10 wsock32 ws2_32 Dwmapi.lib Winmm.lib)
else ()
target_link_libraries(main PRIVATE pthread)
if (NOT APPLE)
find_package(Fontconfig)
if (TARGET Fontconfig::Fontconfig)
message(STATUS "Using Fontconfig version: ${Fontconfig_VERSION}")
target_link_libraries(main PRIVATE Fontconfig::Fontconfig)
target_compile_definitions(main PRIVATE IMHEX_HAS_FONTCONFIG)
endif ()
endif ()
endif ()
precompileHeaders(main ${CMAKE_CURRENT_SOURCE_DIR}/include)

View File

@@ -22,6 +22,10 @@
#include <string.h>
#include <ranges>
#if defined(IMHEX_HAS_FONTCONFIG)
#include <fontconfig/fontconfig.h>
#endif
namespace hex {
bool isFileInPath(const std::fs::path &filename) {
@@ -48,7 +52,43 @@ namespace hex {
} // Hopefully one of these commands is installed
}
#if defined(IMHEX_HAS_FONTCONFIG)
static bool enumerateFontConfig() {
if (!FcInit())
return false;
ON_SCOPE_EXIT { FcFini(); };
auto fonts = FcConfigGetFonts(nullptr, FcSetSystem);
if (fonts == nullptr)
return false;
for (int i = 0; i < fonts->nfont; ++i) {
auto font = fonts->fonts[i];
FcChar8 *file, *fullName;
if (FcPatternGetString(font, FC_FILE, 0, &file) != FcResultMatch) {
continue;
}
if (FcPatternGetString(font, FC_FULLNAME, 0, &fullName) != FcResultMatch
&& FcPatternGetString(font, FC_FAMILY, 0, &fullName) != FcResultMatch) {
continue;
}
registerFont(reinterpret_cast<const char *>(fullName), reinterpret_cast<const char *>(file));
}
return true;
}
#endif
void enumerateFonts() {
#if defined(IMHEX_HAS_FONTCONFIG)
if (enumerateFontConfig())
return;
#endif
const std::array FontDirectories = {
"/usr/share/fonts",
"/usr/local/share/fonts",