From 7670100d8122e257e920e5b8141a4fb2b6d137fc Mon Sep 17 00:00:00 2001 From: ohyzha Date: Sat, 18 Jan 2025 16:56:00 +0200 Subject: [PATCH] reimplement system fonts retrieval for Linux using fontconfig --- .vscode/settings.json | 96 +++++++++++++++++++ .../Host/Linux/SystemFontResolver.cpp | 43 ++++++++- .../Linux/SystemFontsSearchTestsUbuntu.cpp | 11 +-- 3 files changed, 142 insertions(+), 8 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..77a0b44 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,96 @@ +{ + "files.associations": { + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "csetjmp": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "*.ipp": "cpp", + "condition_variable": "cpp", + "thread": "cpp", + "*.inc": "cpp", + "any": "cpp", + "array": "cpp", + "atomic": "cpp", + "hash_map": "cpp", + "hash_set": "cpp", + "strstream": "cpp", + "barrier": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "bitset": "cpp", + "cfenv": "cpp", + "charconv": "cpp", + "chrono": "cpp", + "cinttypes": "cpp", + "codecvt": "cpp", + "compare": "cpp", + "complex": "cpp", + "concepts": "cpp", + "coroutine": "cpp", + "cstdint": "cpp", + "deque": "cpp", + "forward_list": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "regex": "cpp", + "source_location": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "rope": "cpp", + "slist": "cpp", + "fstream": "cpp", + "future": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "latch": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "ranges": "cpp", + "scoped_allocator": "cpp", + "semaphore": "cpp", + "shared_mutex": "cpp", + "span": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "syncstream": "cpp", + "typeindex": "cpp", + "typeinfo": "cpp", + "valarray": "cpp", + "variant": "cpp" + } +} \ No newline at end of file diff --git a/openVulkanoCpp/Host/Linux/SystemFontResolver.cpp b/openVulkanoCpp/Host/Linux/SystemFontResolver.cpp index f370d2c..c715e4c 100644 --- a/openVulkanoCpp/Host/Linux/SystemFontResolver.cpp +++ b/openVulkanoCpp/Host/Linux/SystemFontResolver.cpp @@ -5,17 +5,56 @@ */ #include "Host/SystemFontResolver.hpp" -#include +#include "Base/Logger.hpp" +#include namespace OpenVulkano { std::string SystemFontResolver::GetSystemFontPath(const std::string& fontName) { + // fontName -> fontPath + static std::map fontFilesMapping = ReadSystemFonts(); + auto it = fontFilesMapping.find(fontName); + if (it != fontFilesMapping.end()) + { + return it->second; + } return ""; } std::map SystemFontResolver::ReadSystemFonts() { - return {}; + FcConfig* config = FcInitLoadConfigAndFonts(); + FcPattern* pat = FcPatternCreate(); + FcObjectSet* os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_LANG, FC_FILE, NULL); + FcFontSet* fs = FcFontList(config, pat, os); + if (!fs) + { + Logger::DATA->warn("Could not get system fonts"); + FcFontSetDestroy(fs); + FcObjectSetDestroy(os); + FcPatternDestroy(pat); + return {}; + } + + std::map fontFilesMapping; + for (int i = 0; i < fs->nfont; ++i) + { + FcPattern* font = fs->fonts[i]; + FcChar8* file, *style, *family; + if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch && + FcPatternGetString(font, FC_FAMILY, 0, &family) == FcResultMatch && + FcPatternGetString(font, FC_STYLE, 0, &style) == FcResultMatch) + { + fontFilesMapping[std::string(reinterpret_cast(family)) + " " + + std::string(reinterpret_cast(style))] + = std::string(reinterpret_cast(file)); + } + } + FcFontSetDestroy(fs); + FcObjectSetDestroy(os); + FcPatternDestroy(pat); + FcConfigDestroy(config); + return fontFilesMapping; } } diff --git a/tests/Host/Linux/SystemFontsSearchTestsUbuntu.cpp b/tests/Host/Linux/SystemFontsSearchTestsUbuntu.cpp index 6c2e372..743631b 100644 --- a/tests/Host/Linux/SystemFontsSearchTestsUbuntu.cpp +++ b/tests/Host/Linux/SystemFontsSearchTestsUbuntu.cpp @@ -5,9 +5,8 @@ */ #include +#include "Host/SystemFontResolver.hpp" #include "Base/Logger.hpp" -#include "Host/SystemInfo.hpp" -#include "Scene/Text/FontAtlasFactory.hpp" #include using namespace OpenVulkano; @@ -17,12 +16,12 @@ TEST_CASE("Search system fonts") Logger::SetupLogger("", "tests.log"); // assume these fonts are present since they are default - std::filesystem::path path = SystemInfo::GetSystemFontPath("Ubuntu-R"); + std::string path = SystemFontResolver::GetSystemFontPath("Ubuntu Regular"); REQUIRE(path == "/usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf"); - path = SystemInfo::GetSystemFontPath("UbuntuMono-BI"); - REQUIRE(!path.empty()); + path = SystemFontResolver::GetSystemFontPath("Ubuntu Mono Bold Italic"); + REQUIRE(path == "/usr/share/fonts/truetype/ubuntu/UbuntuMono-BI.ttf"); - path = SystemInfo::GetSystemFontPath("NON-EXISTING Font"); + path = SystemFontResolver::GetSystemFontPath("NON-EXISTING Font"); REQUIRE(path.empty()); }