From 09904b77eb63f6305ca4d4eecaaaddf4030f4368 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Wed, 29 Nov 2023 23:47:37 +0100 Subject: [PATCH] feat: Add support for bold and italic fonts --- lib/libimhex/include/hex/api/imhex_api.hpp | 54 +++++++------ lib/libimhex/source/api/imhex_api.cpp | 75 ++++++++++-------- main/gui/source/init/tasks.cpp | 4 +- main/gui/source/window/window.cpp | 2 +- plugins/builtin/source/content/init_tasks.cpp | 77 +++++++++++-------- .../builtin/source/content/pl_visualizers.cpp | 2 +- 6 files changed, 124 insertions(+), 90 deletions(-) diff --git a/lib/libimhex/include/hex/api/imhex_api.hpp b/lib/libimhex/include/hex/api/imhex_api.hpp index 5bbea10a8..a21d014df 100644 --- a/lib/libimhex/include/hex/api/imhex_api.hpp +++ b/lib/libimhex/include/hex/api/imhex_api.hpp @@ -13,6 +13,7 @@ using ImGuiID = unsigned int; struct ImVec2; struct ImFontAtlas; +struct ImFont; namespace hex { @@ -358,10 +359,6 @@ namespace hex { void setBorderlessWindowMode(bool enabled); - void setCustomFontPath(const std::fs::path &path); - void setFontSize(float size); - void setFontAtlas(ImFontAtlas *fontAtlas); - void setGPUVendor(const std::string &vendor); void setPortableVersion(bool enabled); @@ -465,27 +462,6 @@ namespace hex { */ std::map &getInitArguments(); - constexpr static float DefaultFontSize = 13.0; - - /** - * @brief Gets the current custom font path - * @return The current custom font path - */ - std::filesystem::path &getCustomFontPath(); - - /** - * @brief Gets the current font size - * @return The current font size - */ - float getFontSize(); - - /** - * @brief Gets the current font atlas - * @return Current font atlas - */ - ImFontAtlas* getFontAtlas(); - - /** * @brief Sets if ImHex should follow the system theme * @param enabled Whether to follow the system theme @@ -619,6 +595,11 @@ namespace hex { std::vector& getFonts(); + void setCustomFontPath(const std::fs::path &path); + void setFontSize(float size); + void setFontAtlas(ImFontAtlas *fontAtlas); + + void setFonts(ImFont *bold, ImFont *italic); } GlyphRange glyph(const char *glyph); @@ -629,6 +610,29 @@ namespace hex { void loadFont(const std::fs::path &path, const std::vector &glyphRanges = {}, Offset offset = {}, u32 flags = 0); void loadFont(const std::string &name, const std::span &data, const std::vector &glyphRanges = {}, Offset offset = {}, u32 flags = 0); + constexpr static float DefaultFontSize = 13.0; + + ImFont* Bold(); + ImFont* Italic(); + + /** + * @brief Gets the current custom font path + * @return The current custom font path + */ + std::filesystem::path &getCustomFontPath(); + + /** + * @brief Gets the current font size + * @return The current font size + */ + float getFontSize(); + + /** + * @brief Gets the current font atlas + * @return Current font atlas + */ + ImFontAtlas* getFontAtlas(); + } } diff --git a/lib/libimhex/source/api/imhex_api.cpp b/lib/libimhex/source/api/imhex_api.cpp index 42551922a..e9ae89364 100644 --- a/lib/libimhex/source/api/imhex_api.cpp +++ b/lib/libimhex/source/api/imhex_api.cpp @@ -419,21 +419,6 @@ namespace hex { s_borderlessWindowMode = enabled; } - static std::fs::path s_customFontPath; - void setCustomFontPath(const std::fs::path &path) { - s_customFontPath = path; - } - - static float s_fontSize = DefaultFontSize; - void setFontSize(float size) { - s_fontSize = size; - } - - static ImFontAtlas *s_fontAtlas; - void setFontAtlas(ImFontAtlas* fontAtlas) { - s_fontAtlas = fontAtlas; - } - static std::string s_gpuVendor; void setGPUVendor(const std::string &vendor) { @@ -517,23 +502,8 @@ namespace hex { return initArgs; } - std::fs::path &getCustomFontPath() { - return impl::s_customFontPath; - } - - float getFontSize() { - return impl::s_fontSize; - } - - ImFontAtlas* getFontAtlas() { - return impl::s_fontAtlas; - } - - static bool s_systemThemeDetection; - - void enableSystemThemeDetection(bool enabled) { s_systemThemeDetection = enabled; @@ -762,6 +732,29 @@ namespace hex { return fonts; } + static std::fs::path s_customFontPath; + void setCustomFontPath(const std::fs::path &path) { + s_customFontPath = path; + } + + static float s_fontSize = DefaultFontSize; + void setFontSize(float size) { + s_fontSize = size; + } + + static std::unique_ptr s_fontAtlas; + void setFontAtlas(ImFontAtlas* fontAtlas) { + s_fontAtlas = std::unique_ptr(fontAtlas); + } + + static ImFont *s_boldFont = nullptr; + static ImFont *s_italicFont = nullptr; + void setFonts(ImFont *bold, ImFont *italic) { + s_boldFont = bold; + s_italicFont = italic; + } + + } GlyphRange glyph(const char *glyph) { @@ -822,6 +815,28 @@ namespace hex { flags }); } + + std::fs::path &getCustomFontPath() { + return impl::s_customFontPath; + } + + float getFontSize() { + return impl::s_fontSize; + } + + ImFontAtlas* getFontAtlas() { + return impl::s_fontAtlas.get(); + } + + ImFont* Bold() { + return impl::s_boldFont; + } + + ImFont* Italic() { + return impl::s_italicFont; + } + + } } diff --git a/main/gui/source/init/tasks.cpp b/main/gui/source/init/tasks.cpp index d81d35d1f..9d502faca 100644 --- a/main/gui/source/init/tasks.cpp +++ b/main/gui/source/init/tasks.cpp @@ -84,8 +84,8 @@ namespace hex::init { ImHexApi::HexEditor::impl::getTooltips().clear(); ImHexApi::HexEditor::impl::getTooltipFunctions().clear(); ImHexApi::System::getAdditionalFolderPaths().clear(); - ImHexApi::System::getCustomFontPath().clear(); ImHexApi::Messaging::impl::getHandlers().clear(); + ImHexApi::Fonts::getCustomFontPath().clear(); ImHexApi::Fonts::impl::getFonts().clear(); ContentRegistry::Settings::impl::getSettings().clear(); @@ -149,8 +149,6 @@ namespace hex::init { fs::setFileBrowserErrorCallback(nullptr); - IM_DELETE(ImHexApi::System::getFontAtlas()); - return true; } diff --git a/main/gui/source/window/window.cpp b/main/gui/source/window/window.cpp index debbcaec7..7504d1dae 100644 --- a/main/gui/source/window/window.cpp +++ b/main/gui/source/window/window.cpp @@ -1139,7 +1139,7 @@ namespace hex { void Window::initImGui() { IMGUI_CHECKVERSION(); - auto fonts = ImHexApi::System::getFontAtlas(); + auto fonts = ImHexApi::Fonts::getFontAtlas(); // Initialize ImGui and all other ImGui extensions GImGui = ImGui::CreateContext(fonts); diff --git a/plugins/builtin/source/content/init_tasks.cpp b/plugins/builtin/source/content/init_tasks.cpp index 73949d60d..6dd00a286 100644 --- a/plugins/builtin/source/content/init_tasks.cpp +++ b/plugins/builtin/source/content/init_tasks.cpp @@ -121,10 +121,10 @@ namespace hex::plugin::builtin { } bool loadFontsImpl(bool loadUnicode) { - const float defaultFontSize = ImHexApi::System::DefaultFontSize * std::round(ImHexApi::System::getGlobalScale()); + const float defaultFontSize = ImHexApi::Fonts::DefaultFontSize * std::round(ImHexApi::System::getGlobalScale()); // Reset used font size back to the default size - ImHexApi::System::impl::setFontSize(defaultFontSize); + ImHexApi::Fonts::impl::setFontSize(defaultFontSize); // Load custom font related settings if (ContentRegistry::Settings::read("hex.builtin.setting.font", "hex.builtin.setting.font.custom_font_enable", false).get()) { @@ -151,7 +151,7 @@ namespace hex::plugin::builtin { } } - ImHexApi::System::impl::setCustomFontPath(fontFile); + ImHexApi::Fonts::impl::setCustomFontPath(fontFile); // If a custom font has been loaded now, also load the font size float fontSize = defaultFontSize; @@ -159,12 +159,12 @@ namespace hex::plugin::builtin { fontSize = float(ContentRegistry::Settings::read("hex.builtin.setting.font", "hex.builtin.setting.font.font_size", 13).get()) * ImHexApi::System::getGlobalScale(); } - ImHexApi::System::impl::setFontSize(fontSize); + ImHexApi::Fonts::impl::setFontSize(fontSize); } - float fontSize = ImHexApi::System::getFontSize(); + float fontSize = ImHexApi::Fonts::getFontSize(); - const auto &fontFile = ImHexApi::System::getCustomFontPath(); + const auto &fontFile = ImHexApi::Fonts::getCustomFontPath(); // Setup basic font configuration auto fonts = IM_NEW(ImFontAtlas)(); @@ -206,32 +206,43 @@ namespace hex::plugin::builtin { glyphRangesBuilder.BuildRanges(&defaultGlyphRanges); } + if (fontFile.empty()) + fonts->Clear(); + + if (ContentRegistry::Settings::read("hex.builtin.setting.font", "hex.builtin.setting.font.font_bold", false)) + cfg.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_Bold; + if (ContentRegistry::Settings::read("hex.builtin.setting.font", "hex.builtin.setting.font.font_italic", false)) + cfg.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_Oblique; + if (!ContentRegistry::Settings::read("hex.builtin.setting.font", "hex.builtin.setting.font.font_antialias", false)) + cfg.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_Monochrome | ImGuiFreeTypeBuilderFlags_MonoHinting; + + auto loadDefaultFont = [&](const char *fontName, u32 flags = 0) { + ImFontConfig defaultConfig = cfg; + ImFont *defaultFont; + + defaultConfig.FontBuilderFlags |= flags; + + std::strncpy(defaultConfig.Name, fontName, sizeof(defaultConfig.Name) - 1); + + if (fontFile.empty()) { + defaultConfig.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_Monochrome | ImGuiFreeTypeBuilderFlags_MonoHinting; + defaultFont = fonts->AddFontDefault(&defaultConfig); + } else { + defaultFont = fonts->AddFontFromFileTTF(wolv::util::toUTF8String(fontFile).c_str(), 0, &defaultConfig, defaultGlyphRanges.Data); + } + + return defaultFont; + }; + // Load main font // If a custom font has been specified, load it, otherwise load the default ImGui font - ImFont *defaultFont; - if (fontFile.empty()) { - fonts->Clear(); + ImFont *defaultFont = loadDefaultFont("Default Font"); + if (defaultFont == nullptr) { + log::warn("Failed to load custom font! Falling back to default font."); + + ImHexApi::Fonts::impl::setFontSize(defaultFontSize); + cfg.SizePixels = defaultFontSize; defaultFont = fonts->AddFontDefault(&cfg); - } else { - if (ContentRegistry::Settings::read("hex.builtin.setting.font", "hex.builtin.setting.font.font_bold", false)) - cfg.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_Bold; - if (ContentRegistry::Settings::read("hex.builtin.setting.font", "hex.builtin.setting.font.font_italic", false)) - cfg.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_Oblique; - if (!ContentRegistry::Settings::read("hex.builtin.setting.font", "hex.builtin.setting.font.font_antialias", false)) - cfg.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_Monochrome | ImGuiFreeTypeBuilderFlags_MonoHinting; - - defaultFont = fonts->AddFontFromFileTTF(wolv::util::toUTF8String(fontFile).c_str(), 0, &cfg, defaultGlyphRanges.Data); - - cfg.FontBuilderFlags = 0; - - if (defaultFont == nullptr) { - log::warn("Failed to load custom font! Falling back to default font."); - - ImHexApi::System::impl::setFontSize(defaultFontSize); - cfg.SizePixels = defaultFontSize; - fonts->Clear(); - defaultFont = fonts->AddFontDefault(&cfg); - } } fonts->Build(); @@ -287,6 +298,12 @@ namespace hex::plugin::builtin { fonts->AddFontFromMemoryTTF(font.fontData.data(), int(font.fontData.size()), 0, &cfg, ranges.back().Data); } + // Create bold and italic font + cfg.MergeMode = false; + ImFont *boldFont = loadDefaultFont("Bold Font", ImGuiFreeTypeBuilderFlags_Bold); + ImFont *italicFont = loadDefaultFont("Italic Font", ImGuiFreeTypeBuilderFlags_Oblique); + ImHexApi::Fonts::impl::setFonts(boldFont, italicFont); + // Try to build the font atlas if (!fonts->Build()) { // The main reason the font atlas failed to build is that the font is too big for the GPU to handle @@ -310,7 +327,7 @@ namespace hex::plugin::builtin { } // Configure ImGui to use the font atlas - ImHexApi::System::impl::setFontAtlas(fonts); + ImHexApi::Fonts::impl::setFontAtlas(fonts); return true; } diff --git a/plugins/builtin/source/content/pl_visualizers.cpp b/plugins/builtin/source/content/pl_visualizers.cpp index 1f72ff56d..a0d1dd349 100644 --- a/plugins/builtin/source/content/pl_visualizers.cpp +++ b/plugins/builtin/source/content/pl_visualizers.cpp @@ -626,7 +626,7 @@ namespace hex::plugin::builtin { auto lastMonthDay = std::chrono::year_month_day_last(date.year(), date.month() / std::chrono::last); auto firstWeekDay = std::chrono::weekday(std::chrono::year_month_day(date.year(), date.month(), std::chrono::day(1))); - const auto scale = 1_scaled * (ImHexApi::System::getFontSize() / ImHexApi::System::DefaultFontSize); + const auto scale = 1_scaled * (ImHexApi::Fonts::getFontSize() / ImHexApi::Fonts::DefaultFontSize); // Draw calendar if (ImGui::BeginTable("##month_table", 2)) {