From 1d75400a2d50e1eebea14ec009c3ae8e59accd57 Mon Sep 17 00:00:00 2001 From: Patrick Wuttke Date: Wed, 5 Mar 2025 22:02:30 +0100 Subject: [PATCH] Added more options to font loading. --- SModule | 2 +- private/raid/application.cpp | 63 +++++++++++++++++++++++++++--------- public/raid/raid.hpp | 23 ++++++++++++- 3 files changed, 71 insertions(+), 17 deletions(-) diff --git a/SModule b/SModule index 2d1be6d..77ef2e8 100644 --- a/SModule +++ b/SModule @@ -4,7 +4,7 @@ Import('env') public_dir = env.Dir('public') env.Append(CPPPATH = [public_dir]) if env['BUILD_TYPE'] == 'release': - cppdefines += ['RAID_RELEASE=1'] + env.Append(CPPDEFINES = ['RAID_RELEASE']) env = env.Module('private/raid/SModule') LIB_CONFIG = { diff --git a/private/raid/application.cpp b/private/raid/application.cpp index dd78e91..0983476 100644 --- a/private/raid/application.cpp +++ b/private/raid/application.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -125,29 +126,55 @@ int Application::run(int argc, char** argv) return 0; } -bool Application::loadFont(const fs::path& path) + +bool Application::loadFonts(std::span fonts) { ImGuiIO& imguiIO = ImGui::GetIO(); - std::unique_ptr fontFile; - if (const mijin::StreamError error = mFS.open(path, mijin::FileOpenMode::READ, fontFile); - error != mijin::StreamError::SUCCESS) - { - msgError("Error opening font file {}: {}.", path.generic_string(), mijin::errorName(error)); - return false; - } + std::vector buffers; + buffers.reserve(fonts.size()); - mijin::TypelessBuffer data; - if (const mijin::StreamError readError = fontFile->readRest(data); readError != mijin::StreamError::SUCCESS) + for (const FontConfig& font : fonts) { - msgError("Error reading font data from {}: {}.", path.generic_string(), mijin::errorName(readError)); - return false; + std::unique_ptr fontFile; + if (const mijin::StreamError error = mFS.open(font.path, mijin::FileOpenMode::READ, fontFile); + error != mijin::StreamError::SUCCESS) + { + msgError("Error opening font file {}: {}.", font.path.generic_string(), mijin::errorName(error)); + return false; + } + + mijin::TypelessBuffer& data = buffers.emplace_back(); + if (const mijin::StreamError readError = fontFile->readRest(data); readError != mijin::StreamError::SUCCESS) + { + msgError("Error reading font data from {}: {}.", font.path.generic_string(), mijin::errorName(readError)); + return false; + } } // by default ImGui takes ownership of the data, that's now what we want ImFontConfig config; config.FontDataOwnedByAtlas = false; - imguiIO.Fonts->AddFontFromMemoryTTF(data.data(), static_cast(data.byteSize()), 20, &config); + std::vector glyphRangesConverted; + for (const auto& [font, data] : mijin::zip(fonts, buffers)) + { + ImWchar* glyphRanges = nullptr; + if (!font.glyphRanges.empty()) + { + glyphRangesConverted.reserve(2 * font.glyphRanges.size() + 1); + glyphRangesConverted.clear(); + for (const std::pair& range : font.glyphRanges) + { + glyphRangesConverted.push_back(range.first); + glyphRangesConverted.push_back(range.second); + } + glyphRangesConverted.push_back(0); + glyphRanges = glyphRangesConverted.data(); + } + config.PixelSnapH = font.flags.pixelSnapH; + imguiIO.Fonts->AddFontFromMemoryTTF(data.data(), static_cast(data.byteSize()), font.size, &config, glyphRanges); + config.MergeMode = true; // for any more fonts + } // but in that case Build() has to be run before the data gets deleted imguiIO.Fonts->Build(); @@ -209,6 +236,13 @@ void Application::configureImgui() imguiIO.ConfigViewportsNoAutoMerge = true; } +std::vector Application::getDefaultFonts() +{ + return {{ + .path = "/data/fonts/NotoSans-Regular.ttf" + }}; +} + void Application::handleMessage(const Message& message) { switch (message.severity) @@ -452,8 +486,7 @@ bool Application::initImGui() // init font if (imguiIO.Fonts->Fonts.empty()) { - static const char* const DEFAULT_FONT = "/data/fonts/NotoSans-Regular.ttf"; - if (!loadFont(DEFAULT_FONT)) + if (!loadFonts(getDefaultFonts())) { imguiIO.Fonts->AddFontDefault(); } diff --git a/public/raid/raid.hpp b/public/raid/raid.hpp index 9c8d7ec..f6410ba 100644 --- a/public/raid/raid.hpp +++ b/public/raid/raid.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -34,6 +35,19 @@ struct Message const char* text; }; +struct FontFlags : mijin::BitFlags +{ + bool pixelSnapH : 1 = false; +}; + +struct FontConfig +{ + fs::path path; + std::vector> glyphRanges; + float size = 20.f; + FontFlags flags; +}; + class Application { private: @@ -90,7 +104,13 @@ public: int run(int argc, char* argv[]); [[nodiscard]] - bool loadFont(const fs::path& path); + bool loadFonts(std::span fonts); + + [[nodiscard]] + bool loadFont(const FontConfig& font) + { + return loadFonts({&font, 1}); + } [[nodiscard]] ImTextureID getOrLoadTexture(fs::path path); @@ -100,6 +120,7 @@ protected: virtual std::string getFolderName() = 0; virtual std::string getWindowTitle() = 0; virtual void configureImgui(); + virtual std::vector getDefaultFonts(); virtual void handleMessage(const Message& message); virtual void handleSDLEvent(const SDL_Event& event);