/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #include "Host/SystemFontResolver.hpp" #include #include #define QFR_DESCRIPTION 1 namespace OpenVulkano { std::string SystemFontResolver::GetSystemFontPath(const std::string& fontName) { // font name -> filename static std::map fontFileMapping = ReadSystemFonts(); // maybe check everything in lower case ? so that we can use Arial/arial as input parameter auto it = fontFileMapping.find(fontName); return it == fontFileMapping.end() ? "" : it->second; } std::map SystemFontResolver::ReadSystemFonts() { std::map fontFileMapping; // thank you Microsoft for function that is not even documented, but exists and it's the only function that // can return real font name from font filename (e.g. font filename is times.ttf that corresponds to Times New Roman) int(WINAPI* GetFontResourceInfoW)(wchar_t*, unsigned long*, void*, unsigned long); *(FARPROC*) &GetFontResourceInfoW = GetProcAddress(GetModuleHandleA("gdi32"), "GetFontResourceInfoW"); std::wstring winDir; winDir.resize(MAX_PATH); UINT len = GetWindowsDirectoryW(winDir.data(), MAX_PATH); winDir.resize(len); std::filesystem::path fontsDir = std::filesystem::path(winDir) / "Fonts"; for (const auto& fontFilename : std::filesystem::directory_iterator(fontsDir)) { unsigned long size = 0; std::wstring ws = fontFilename.path().wstring(); if (!GetFontResourceInfoW(ws.data(), &size, NULL, QFR_DESCRIPTION)) { continue; } std::wstring fontName; fontName.resize(size); if (GetFontResourceInfoW(ws.data(), &size, fontName.data(), QFR_DESCRIPTION)) { // remove null-terminated characters since size is always bigger than needed std::string fontNameCropped(fontName.begin(), fontName.end()); size_t realSize = 0; for (; realSize < fontNameCropped.size(); realSize++) { if (fontNameCropped[realSize] == '\0') { break; } } fontNameCropped.resize(realSize); fontFileMapping[std::move(fontNameCropped)] = fontFilename.path().string(); } } return fontFileMapping; } }