diff --git a/.gitea/workflows/build_pc.yml b/.gitea/workflows/build_pc.yml index 5101ed2..b9369bd 100644 --- a/.gitea/workflows/build_pc.yml +++ b/.gitea/workflows/build_pc.yml @@ -32,8 +32,8 @@ jobs: - name: Install Dev Packages if: matrix.os == 'ubuntu-latest' run: > - sudo apt update && sudo apt install -y extra-cmake-modules libwayland-dev libxkbcommon-dev xorg-dev libarchive-dev libassimp-dev ninja-build glslang-tools glslang-dev unzip zip libcurl4-openssl-dev libfreetype-dev libjpeg-turbo8-dev nasm - && sudo wget https://sourceforge.net/projects/bin2c/files/1.1/bin2c-1.1.zip && sudo unzip bin2c-1.1.zip && cd bin2c && sudo gcc -o bin2c bin2c.c && sudo mv bin2c /usr/bin + sudo apt update && sudo apt install -y extra-cmake-modules libwayland-dev fonts-ubuntu libxkbcommon-dev xorg-dev libarchive-dev libassimp-dev ninja-build glslang-tools glslang-dev unzip zip libcurl4-openssl-dev libfreetype-dev libjpeg-turbo8-dev nasm + && sudo wget https://sourceforge.net/projects/bin2c/files/1.1/bin2c-1.1.zip && sudo unzip bin2c-1.1.zip && cd bin2c && sudo gcc -o bin2c bin2c.c && sudo mv bin2c /usr/bin && fc-cache -f -v - name: Get cmake checks from cache uses: actions/cache@v4 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/Base/Utils.hpp b/openVulkanoCpp/Base/Utils.hpp index 7654bc9..98b1640 100644 --- a/openVulkanoCpp/Base/Utils.hpp +++ b/openVulkanoCpp/Base/Utils.hpp @@ -157,6 +157,24 @@ namespace OpenVulkano return str.size() >= suffix.size() && 0 == str.compare(str.size()-suffix.size(), suffix.size(), suffix); } + static void ToLower(std::string& str) + { + std::transform(str.begin(), str.end(), str.begin(), [](char c) { return std::tolower(c); }); + } + + static void ToLower(const std::string& str, char* dest) + { + std::transform(str.begin(), str.end(), dest, [](char c) { return std::tolower(c); }); + } + + static std::string ToLower(const std::string& str) + { + std::string dest; + dest.resize(str.size()); + std::transform(str.begin(), str.end(), dest.begin(), [](char c) { return std::tolower(c); }); + return dest; + } + static std::pair SplitAtLastOccurrence(const std::string& str, char splitAt) { size_t pos = str.rfind(splitAt); diff --git a/openVulkanoCpp/Host/Linux/SystemFontResolver.cpp b/openVulkanoCpp/Host/Linux/SystemFontResolver.cpp new file mode 100644 index 0000000..43bb6d4 --- /dev/null +++ b/openVulkanoCpp/Host/Linux/SystemFontResolver.cpp @@ -0,0 +1,56 @@ +/* + * 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 "Base/Logger.hpp" +#include "Base/Utils.hpp" +#include +#include + +namespace OpenVulkano +{ + const std::string& SystemFontResolver::GetSystemFontPath(const std::string& fontName) + { + // fontName -> fontPath + static std::map fontFilesMapping = ReadSystemFonts(); + static std::string fallbackString; + auto it = fontFilesMapping.find(Utils::ToLower(fontName)); + return it == fontFilesMapping.end() ? fallbackString : it->second; + } + + std::map SystemFontResolver::ReadSystemFonts() + { + std::unique_ptr config(FcInitLoadConfigAndFonts(), &FcConfigDestroy); + std::unique_ptr pat(FcPatternCreate(), &FcPatternDestroy); + std::unique_ptr os(FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_LANG, FC_FILE, NULL), &FcObjectSetDestroy); + std::unique_ptr fs(FcFontList(config.get(), pat.get(), os.get()), &FcFontSetDestroy); + + if (!fs) + { + Logger::DATA->warn("Could not get system fonts"); + return {}; + } + + std::map fontFilesMapping; + for (int i = 0; i < fs->nfont; ++i) + { + FcPattern* font = fs->fonts[i]; + FcChar8* file; + FcChar8* style; + FcChar8* family; + if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch && + FcPatternGetString(font, FC_FAMILY, 0, &family) == FcResultMatch && + FcPatternGetString(font, FC_STYLE, 0, &style) == FcResultMatch) + { + std::string fontFull = std::string(reinterpret_cast(family)) + " " + + std::string(reinterpret_cast(style)); + Utils::ToLower(fontFull); + fontFilesMapping[std::move(fontFull)] = std::string(reinterpret_cast(file)); + } + } + return fontFilesMapping; + } +} diff --git a/openVulkanoCpp/Host/MacOS/SystemFontResolver.cpp b/openVulkanoCpp/Host/MacOS/SystemFontResolver.cpp new file mode 100644 index 0000000..617c36e --- /dev/null +++ b/openVulkanoCpp/Host/MacOS/SystemFontResolver.cpp @@ -0,0 +1,22 @@ +/* + * 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 + +namespace OpenVulkano +{ + const std::string& SystemFontResolver::GetSystemFontPath(const std::string& fontName) + { + static std::string fallbackString; + return fallbackString; + } + + std::map SystemFontResolver::ReadSystemFonts() + { + return {}; + } +} diff --git a/openVulkanoCpp/Host/MacOS/SystemInfo.mm b/openVulkanoCpp/Host/MacOS/SystemInfo.mm index ca295f6..d404d08 100644 --- a/openVulkanoCpp/Host/MacOS/SystemInfo.mm +++ b/openVulkanoCpp/Host/MacOS/SystemInfo.mm @@ -111,7 +111,7 @@ namespace OpenVulkano { NSOperatingSystemVersion sysVersion = [NSProcessInfo processInfo].operatingSystemVersion; osVersion = { static_cast(sysVersion.majorVersion), static_cast(sysVersion.minorVersion), - static_cast(sysVersion.patchVersion), 0 }; + static_cast(sysVersion.patchVersion), 0 }; } return osVersion; } diff --git a/openVulkanoCpp/Host/SystemFontResolver.hpp b/openVulkanoCpp/Host/SystemFontResolver.hpp new file mode 100644 index 0000000..83dac87 --- /dev/null +++ b/openVulkanoCpp/Host/SystemFontResolver.hpp @@ -0,0 +1,22 @@ +/* + * 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/. + */ + +#pragma once + +#include +#include + +namespace OpenVulkano +{ + class SystemFontResolver + { + public: + static const std::string& GetSystemFontPath(const std::string& fontName); + + private: + static std::map ReadSystemFonts(); + }; +} diff --git a/openVulkanoCpp/Host/Windows/SystemFontResolver.cpp b/openVulkanoCpp/Host/Windows/SystemFontResolver.cpp new file mode 100644 index 0000000..111cc00 --- /dev/null +++ b/openVulkanoCpp/Host/Windows/SystemFontResolver.cpp @@ -0,0 +1,142 @@ +/* + * 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 "Base/Utils.hpp" +#include "Base/Logger.hpp" +#include +#include +#include + +#define QFR_DESCRIPTION 1 + +#pragma comment(lib, "Dwrite.lib") + +namespace +{ + template + struct DirectWriteAutoReleasable final + { + DirectWriteAutoReleasable() : ptr(nullptr) {} + ~DirectWriteAutoReleasable() + { + if (ptr) + { + ptr->Release(); + } + } + + T* operator->() { return ptr; } + + T* ptr; + }; +} + +namespace OpenVulkano +{ + const std::string& SystemFontResolver::GetSystemFontPath(const std::string& fontName) + { + // font name -> filename + static std::map fontFileMapping = ReadSystemFonts(); + static std::string fallbackString; + auto it = fontFileMapping.find(Utils::ToLower(fontName)); + return it == fontFileMapping.end() ? fallbackString : it->second; + } + + std::map SystemFontResolver::ReadSystemFonts() + { + DirectWriteAutoReleasable dwrite; + HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory7), (IUnknown**) &dwrite); + if (!SUCCEEDED(hr)) + { + Logger::DATA->error("Could not read system fonts. DWriteCreateFactory has failed. Error code {}", hr); + return {}; + } + + DirectWriteAutoReleasable matchingFonts; + hr = dwrite->GetSystemFontSet(&matchingFonts.ptr); + if (!SUCCEEDED(hr)) + { + Logger::DATA->error("Could not read system fonts. GetSystemFontSet has failed. Error code {}", hr); + return {}; + } + + std::map fontFileMapping; + const UINT32 familyCount = matchingFonts->GetFontCount(); + // 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"); + + for (UINT32 i = 0; i < familyCount; ++i) + { + DirectWriteAutoReleasable faceRef; + hr = matchingFonts->GetFontFaceReference(i, &faceRef.ptr); + if (!SUCCEEDED(hr)) + { + continue; + } + + DirectWriteAutoReleasable file; + hr = faceRef->GetFontFile(&file.ptr); + if (!SUCCEEDED(hr)) + { + continue; + } + + DirectWriteAutoReleasable loader; + hr = file->GetLoader(&loader.ptr); + if (!SUCCEEDED(hr)) + { + continue; + } + + DirectWriteAutoReleasable localLoader; + hr = loader->QueryInterface(&localLoader.ptr); + if (!SUCCEEDED(hr)) + { + continue; + } + + const void* fileKey; + UINT32 fileKeySize; + hr = file->GetReferenceKey(&fileKey, &fileKeySize); + if (!SUCCEEDED(hr)) + { + continue; + } + + // Get font path + WCHAR filePath[MAX_PATH]; + hr = localLoader->GetFilePathFromKey(fileKey, fileKeySize, filePath, MAX_PATH); + if (!SUCCEEDED(hr)) + { + continue; + } + + // Get font name + unsigned long size = 0; + if (!GetFontResourceInfoW(filePath, &size, NULL, QFR_DESCRIPTION)) + { + continue; + } + + std::wstring fontName; + fontName.resize(size); + if (GetFontResourceInfoW(filePath, &size, fontName.data(), QFR_DESCRIPTION)) + { + // remove null-terminated characters since size is always bigger than needed + std::string fontNameCropped(fontName.begin(), fontName.end()); + const size_t realSize = strlen(fontNameCropped.data()); + fontNameCropped.resize(realSize); + Utils::ToLower(fontNameCropped); + fontFileMapping[std::move(fontNameCropped)] = std::string(filePath, filePath + wcslen(filePath)); + } + } + return fontFileMapping; + } + +} diff --git a/openVulkanoCpp/Host/iOS/SystemFontResolver.cpp b/openVulkanoCpp/Host/iOS/SystemFontResolver.cpp new file mode 100644 index 0000000..3aa69e1 --- /dev/null +++ b/openVulkanoCpp/Host/iOS/SystemFontResolver.cpp @@ -0,0 +1,22 @@ +/* + * 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 + +namespace OpenVulkano +{ + const std::string& SystemFontResolver::GetSystemFontPath(const std::string& fontName) + { + static std::string fallbackString; + return fallbackString; + } + + std::map SystemFontResolver::ReadSystemFonts() + { + return {}; + } +} diff --git a/openVulkanoCpp/Host/iOS/SystemInfo.mm b/openVulkanoCpp/Host/iOS/SystemInfo.mm index 3182ba2..f19455f 100644 --- a/openVulkanoCpp/Host/iOS/SystemInfo.mm +++ b/openVulkanoCpp/Host/iOS/SystemInfo.mm @@ -114,7 +114,7 @@ namespace OpenVulkano { NSOperatingSystemVersion osVersion = [NSProcessInfo processInfo].operatingSystemVersion; osv = { static_cast(osVersion.majorVersion), static_cast(osVersion.minorVersion), - static_cast(osVersion.patchVersion), 0 }; + static_cast(osVersion.patchVersion), 0 }; } return osv; } diff --git a/openVulkanoCpp/Scene/BitmapFontAtlasGenerator.cpp b/openVulkanoCpp/Scene/BitmapFontAtlasGenerator.cpp index d94d884..634600b 100644 --- a/openVulkanoCpp/Scene/BitmapFontAtlasGenerator.cpp +++ b/openVulkanoCpp/Scene/BitmapFontAtlasGenerator.cpp @@ -157,9 +157,8 @@ namespace OpenVulkano::Scene + glyph.firstGlyphByteInAtlas; for (int row = 0; row < slot->bitmap.rows; row++) { - std::memcpy(baseAddress + row * m_atlasData->GetTexture()->resolution.x, - &slot->bitmap.buffer[(slot->bitmap.rows - 1 - row) * slot->bitmap.pitch], - slot->bitmap.width); + std::memcpy(baseAddress - row * m_atlasData->GetTexture()->resolution.x, + &slot->bitmap.buffer[row * slot->bitmap.pitch], slot->bitmap.width); } } else diff --git a/openVulkanoCpp/Scene/Text/FontAtlas.hpp b/openVulkanoCpp/Scene/Text/FontAtlas.hpp index 9f04be8..5703512 100644 --- a/openVulkanoCpp/Scene/Text/FontAtlas.hpp +++ b/openVulkanoCpp/Scene/Text/FontAtlas.hpp @@ -45,6 +45,8 @@ namespace OpenVulkano::Scene void DeserializeMetadata(const std::span& data); public: + using Ptr = std::shared_ptr; + FontAtlas() = default; FontAtlas(const Math::Vector2ui textureResolution, const double lineHeight, const FontAtlasType atlasType, DataFormat dataFormat) diff --git a/openVulkanoCpp/Scene/Text/FontAtlasFactory.cpp b/openVulkanoCpp/Scene/Text/FontAtlasFactory.cpp new file mode 100644 index 0000000..d28c5d9 --- /dev/null +++ b/openVulkanoCpp/Scene/Text/FontAtlasFactory.cpp @@ -0,0 +1,106 @@ +/* + * 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 "FontAtlasFactory.hpp" +#include "Scene/SdfFontAtlasGenerator.hpp" +#include "Scene/BitmapFontAtlasGenerator.hpp" +#include "Host/SystemFontResolver.hpp" +#include "Base/Logger.hpp" +#include "Host/ResourceLoader.hpp" +#include + +namespace OpenVulkano::Scene +{ + FontAtlasFactory::FontIdentifier::FontIdentifier(const std::string& font_, const std::set& charset, + SubpixelLayout subpixelLayout_, float ptSize_, + FontAtlasType atlasType_) + : font(font_), subpixelLayout(subpixelLayout_), ptSize(ptSize_), atlasType(atlasType_) + { + std::for_each(charset.begin(), charset.end(), [&](uint32_t c) { charsetHash ^= c; }); + } + + bool FontAtlasFactory::FontIdentifier::FontIdentifier::operator<(const FontIdentifier& other) const + { + return std::tie(atlasType, charsetHash, ptSize, subpixelLayout, font) + < std::tie(other.atlasType, other.charsetHash, other.ptSize, other.subpixelLayout, other.font); + } + + FontAtlas::Ptr FontAtlasFactory::GetFontAtlasScalable(const std::string& fontIdentifier, bool msdf, + const std::set& charset) const + { + const auto& fontData = FindFont(fontIdentifier); + if (fontData.Empty()) + { + Logger::DATA->warn("Could not find font {}", fontIdentifier); + return nullptr; + } + + const std::set& setRef = (charset.empty() ? FontAtlasGeneratorBase::LoadAllGlyphs(fontData) : charset); + FontIdentifier id(fontIdentifier, setRef, SubpixelLayout::UNKNOWN, 0, + msdf ? FontAtlasType::MSDF : FontAtlasType::SDF); + + auto it = m_atlasesCache.find(id); + if (it != m_atlasesCache.end()) + { + return it->second; + } + + if (msdf) + { + MsdfFontAtlasGenerator msdfGen; + msdfGen.GenerateAtlas(fontData, setRef); + return m_atlasesCache.insert({ id, msdfGen.GetAtlas() }).first->second; + } + SdfFontAtlasGenerator sdfGen; + sdfGen.GenerateAtlas(fontData, setRef); + return m_atlasesCache.insert({ id, sdfGen.GetAtlas() }).first->second; + } + + FontAtlas::Ptr FontAtlasFactory::GetFontAtlas(const std::string& fontIdentifier, float ptSize, + SubpixelLayout subpixelLayout, + const std::set& charset) const + { + const auto& fontData = FindFont(fontIdentifier); + if (fontData.Empty()) + { + Logger::DATA->warn("Could not find font {}", fontIdentifier); + return nullptr; + } + + const std::set& setRef = (charset.empty() ? FontAtlasGeneratorBase::LoadAllGlyphs(fontData) : charset); + FontIdentifier id(fontIdentifier, setRef, subpixelLayout, ptSize, + subpixelLayout ? FontAtlasType::BITMAP_SUBPIXEL : FontAtlasType::BITMAP); + + auto it = m_atlasesCache.find(id); + if (it != m_atlasesCache.end()) + { + return it->second; + } + + FontPixelSizeConfig cfg(ptSize); + BitmapFontAtlasGenerator bitmapGen(cfg, subpixelLayout); + bitmapGen.GenerateAtlas(fontData, setRef); + return m_atlasesCache.insert({ id, bitmapGen.GetAtlas() }).first->second; + } + + Array FontAtlasFactory::FindFont(const std::string& fontIdentifier) const + { + Array resource = ResourceLoader::GetInstance().GetResource(fontIdentifier); + if (resource.Empty()) + { + if (!std::filesystem::exists(fontIdentifier)) + { + if (!m_allowSystemFonts) + { + return {}; + } + return Utils::ReadFile(SystemFontResolver::GetSystemFontPath(fontIdentifier), true); + } + return Utils::ReadFile(fontIdentifier); + } + return resource; + } +} diff --git a/openVulkanoCpp/Scene/Text/FontAtlasFactory.hpp b/openVulkanoCpp/Scene/Text/FontAtlasFactory.hpp new file mode 100644 index 0000000..3759c2c --- /dev/null +++ b/openVulkanoCpp/Scene/Text/FontAtlasFactory.hpp @@ -0,0 +1,44 @@ +/* + * 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/. + */ + +#pragma once + +#include "FontAtlas.hpp" +#include "Scene/SubpixelLayout.hpp" +#include "Data/Containers/Array.hpp" + +namespace OpenVulkano::Scene +{ + class FontAtlasFactory final + { + struct FontIdentifier + { + FontIdentifier(const std::string& font_, const std::set& charset, SubpixelLayout subpixelLayout_, + float ptSize_, FontAtlasType atlasType_); + bool operator<(const FontIdentifier& other) const; + + std::string font; + uint32_t charsetHash = 0; + SubpixelLayout subpixelLayout = SubpixelLayout::UNKNOWN; + float ptSize = 0; + FontAtlasType atlasType; + }; + public: + FontAtlasFactory(bool allowSystemFonts = true) : m_allowSystemFonts(allowSystemFonts) {} + [[nodiscard]] FontAtlas::Ptr GetFontAtlasScalable(const std::string& fontIdentifier, bool msdf = true, + const std::set& charset = {}) const; + [[nodiscard]] FontAtlas::Ptr GetFontAtlas(const std::string& fontIdentifier, float ptSize, + SubpixelLayout subpixelLayout = SubpixelLayout::UNKNOWN, + const std::set& charset = {}) const; + + private: + Array FindFont(const std::string& fontFile) const; + + private: + const bool m_allowSystemFonts; + mutable std::map m_atlasesCache; + }; +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 85c0c4f..29345f3 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -15,6 +15,17 @@ if (APPLE) list(FILTER SOURCES EXCLUDE REGEX "ExeAppendedZipResourceLoader") endif() +if (LINUX) + find_program(LSB_RELEASE_EXEC lsb_release) + execute_process(COMMAND ${LSB_RELEASE_EXEC} -is + OUTPUT_VARIABLE LSB_RELEASE_ID_SHORT + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if (NOT ${LSB_RELEASE_ID_SHORT} STREQUAL "Ubuntu") + list(FILTER SOURCES EXCLUDE REGEX "*Ubuntu*") + endif() +endif() + source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${SOURCES}) file(GLOB_RECURSE RESOURCES "${ROOT_FOLDER}/resources/*.rc" "${ROOT_FOLDER}/resources/*.h") list(APPEND SOURCES ${RESOURCES}) diff --git a/tests/Host/Linux/SystemFontsSearchTestsUbuntu.cpp b/tests/Host/Linux/SystemFontsSearchTestsUbuntu.cpp new file mode 100644 index 0000000..7db0018 --- /dev/null +++ b/tests/Host/Linux/SystemFontsSearchTestsUbuntu.cpp @@ -0,0 +1,33 @@ +/* + * 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 +#include "Host/SystemFontResolver.hpp" +#include "Base/Logger.hpp" +#include + +using namespace OpenVulkano; + +TEST_CASE("Search system fonts") +{ + Logger::SetupLogger("", "tests.log"); + + // assume these fonts are present since they are default + std::string path = SystemFontResolver::GetSystemFontPath("Ubuntu Regular"); + REQUIRE(path == "/usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf"); + + path = SystemFontResolver::GetSystemFontPath("ubuntu regular"); + REQUIRE(path == "/usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf"); + + path = SystemFontResolver::GetSystemFontPath("Ubuntu Mono Bold Italic"); + REQUIRE(path == "/usr/share/fonts/truetype/ubuntu/UbuntuMono-BI.ttf"); + + path = SystemFontResolver::GetSystemFontPath("ubuntu mono bold italic"); + REQUIRE(path == "/usr/share/fonts/truetype/ubuntu/UbuntuMono-BI.ttf"); + + path = SystemFontResolver::GetSystemFontPath("NON-EXISTING Font"); + REQUIRE(path.empty()); +} diff --git a/tests/Host/Windows/SystemFontsSearchTests.cpp b/tests/Host/Windows/SystemFontsSearchTests.cpp new file mode 100644 index 0000000..c97c2a2 --- /dev/null +++ b/tests/Host/Windows/SystemFontsSearchTests.cpp @@ -0,0 +1,33 @@ +/* + * 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 +#include "Base/Logger.hpp" +#include "Host/SystemFontResolver.hpp" +#include + +#include "Scene/Text/FontAtlasFactory.hpp" + +using namespace OpenVulkano; + +TEST_CASE("Search system fonts") +{ + Logger::SetupLogger("", "tests.log"); + + // assume these fonts are present since they are default + std::filesystem::path path = SystemFontResolver::GetSystemFontPath("Arial"); + REQUIRE(path.filename() == "ARIAL.TTF"); + + // assume these fonts are present since they are default + path = SystemFontResolver::GetSystemFontPath("Times New Roman"); + REQUIRE(path.filename() == "TIMES.TTF"); + + path = SystemFontResolver::GetSystemFontPath("Arial Bold Italic"); + REQUIRE(path.filename() == "ARIALBI.TTF"); + + path = SystemFontResolver::GetSystemFontPath("NON-EXISTING Font"); + REQUIRE(path.empty()); +}