diff --git a/lib/libimhex/include/hex/api/imhex_api.hpp b/lib/libimhex/include/hex/api/imhex_api.hpp index fc3c58ed3..5bbea10a8 100644 --- a/lib/libimhex/include/hex/api/imhex_api.hpp +++ b/lib/libimhex/include/hex/api/imhex_api.hpp @@ -612,6 +612,7 @@ namespace hex { std::vector fontData; std::vector glyphRanges; Offset offset; + u32 flags; }; namespace impl { @@ -620,8 +621,13 @@ namespace hex { } - void loadFont(const std::fs::path &path, const std::vector &glyphRanges = {}, Offset offset = {}); - void loadFont(const std::string &name, const std::span &data, const std::vector &glyphRanges = {}, Offset offset = {}); + GlyphRange glyph(const char *glyph); + GlyphRange glyph(u32 codepoint); + GlyphRange range(const char *glyphBegin, const char *glyphEnd); + GlyphRange range(u32 codepointBegin, u32 codepointEnd); + + 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); } diff --git a/lib/libimhex/source/api/imhex_api.cpp b/lib/libimhex/source/api/imhex_api.cpp index f45b873f9..42551922a 100644 --- a/lib/libimhex/source/api/imhex_api.cpp +++ b/lib/libimhex/source/api/imhex_api.cpp @@ -13,6 +13,7 @@ #include #include +#include #include @@ -763,7 +764,40 @@ namespace hex { } - void loadFont(const std::fs::path &path, const std::vector &glyphRanges, Offset offset) { + GlyphRange glyph(const char *glyph) { + u32 codepoint; + ImTextCharFromUtf8(&codepoint, glyph, nullptr); + + return { + .begin = u16(codepoint), + .end = u16(codepoint) + }; + } + GlyphRange glyph(u32 codepoint) { + return { + .begin = u16(codepoint), + .end = u16(codepoint) + }; + } + GlyphRange range(const char *glyphBegin, const char *glyphEnd) { + u32 codepointBegin, codepointEnd; + ImTextCharFromUtf8(&codepointBegin, glyphBegin, nullptr); + ImTextCharFromUtf8(&codepointEnd, glyphEnd, nullptr); + + return { + .begin = u16(codepointBegin), + .end = u16(codepointEnd) + }; + } + + GlyphRange range(u32 codepointBegin, u32 codepointEnd) { + return { + .begin = u16(codepointBegin), + .end = u16(codepointEnd) + }; + } + + void loadFont(const std::fs::path &path, const std::vector &glyphRanges, Offset offset, u32 flags) { wolv::io::File fontFile(path, wolv::io::File::Mode::Read); if (!fontFile.isValid()) { log::error("Failed to load font from file '{}'", wolv::util::toUTF8String(path)); @@ -774,16 +808,18 @@ namespace hex { wolv::util::toUTF8String(path.filename()), fontFile.readVector(), glyphRanges, - offset + offset, + flags }); } - void loadFont(const std::string &name, const std::span &data, const std::vector &glyphRanges, Offset offset) { + void loadFont(const std::string &name, const std::span &data, const std::vector &glyphRanges, Offset offset, u32 flags) { impl::getFonts().emplace_back(Font { name, { data.begin(), data.end() }, glyphRanges, - offset + offset, + flags }); } } diff --git a/plugins/builtin/source/content/fonts.cpp b/plugins/builtin/source/content/fonts.cpp index c49d3d16f..c43501aab 100644 --- a/plugins/builtin/source/content/fonts.cpp +++ b/plugins/builtin/source/content/fonts.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -7,18 +8,34 @@ #include #include +#include + namespace hex::plugin::builtin { void loadFonts() { + using namespace ImHexApi::Fonts; + /** * !!IMPORTANT!! * Always load the font files in decreasing size of their glyphs. This will make the rasterize be more * efficient when packing the glyphs into the font atlas and therefor make the atlas much smaller. */ - ImHexApi::Fonts::loadFont("Font Awesome 5", romfs::get("fonts/fontawesome.otf").span(), { { ICON_MIN_FA, ICON_MAX_FA } }, { 0, 3_scaled }); - ImHexApi::Fonts::loadFont("VS Codicons", romfs::get("fonts/codicons.ttf").span(), { { ICON_MIN_VS, ICON_MAX_VS } }, { 0, 3_scaled }); - ImHexApi::Fonts::loadFont("Unifont", romfs::get("fonts/unifont.otf").span()); + ImHexApi::Fonts::loadFont("Font Awesome 5", romfs::get("fonts/fontawesome.otf").span(), + { + { glyph(ICON_FA_BACKSPACE), glyph(ICON_FA_INFINITY), glyph(ICON_FA_TACHOMETER_ALT), glyph(ICON_FA_MICROCHIP), glyph(ICON_FA_CODE_BRANCH) } + }, + { 0, 0 }, + ImGuiFreeTypeBuilderFlags_Monochrome | ImGuiFreeTypeBuilderFlags_MonoHinting); + + ImHexApi::Fonts::loadFont("VS Codicons", romfs::get("fonts/codicons.ttf").span(), + { + { ICON_MIN_VS, ICON_MAX_VS } + }, + { 0, 0 }, + ImGuiFreeTypeBuilderFlags_Monochrome | ImGuiFreeTypeBuilderFlags_MonoHinting); + + ImHexApi::Fonts::loadFont("Unifont", romfs::get("fonts/unifont.otf").span()); } } \ No newline at end of file diff --git a/plugins/builtin/source/content/init_tasks.cpp b/plugins/builtin/source/content/init_tasks.cpp index 0c1ce5967..447d9fe92 100644 --- a/plugins/builtin/source/content/init_tasks.cpp +++ b/plugins/builtin/source/content/init_tasks.cpp @@ -208,9 +208,10 @@ namespace hex::plugin::builtin { // 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(); - fonts->AddFontDefault(&cfg); + defaultFont = fonts->AddFontDefault(&cfg); } else { if (ContentRegistry::Settings::read("hex.builtin.setting.font", "hex.builtin.setting.font.font_bold", false)) cfg.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_Bold; @@ -219,24 +220,29 @@ namespace hex::plugin::builtin { if (!ContentRegistry::Settings::read("hex.builtin.setting.font", "hex.builtin.setting.font.font_antialias", false)) cfg.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_Monochrome | ImGuiFreeTypeBuilderFlags_MonoHinting; - auto font = fonts->AddFontFromFileTTF(wolv::util::toUTF8String(fontFile).c_str(), 0, &cfg, defaultGlyphRanges.Data); + defaultFont = fonts->AddFontFromFileTTF(wolv::util::toUTF8String(fontFile).c_str(), 0, &cfg, defaultGlyphRanges.Data); cfg.FontBuilderFlags = 0; - if (font == nullptr) { + 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(); - fonts->AddFontDefault(&cfg); + defaultFont = fonts->AddFontDefault(&cfg); } } + // Build default font to get its metrics + fonts->Build(); + // Merge all fonts into one big font atlas cfg.MergeMode = true; cfg.FontDataOwnedByAtlas = false; + // Add all other fonts to the atlas + auto startFlags = cfg.FontBuilderFlags; std::list> ranges; for (auto &font : ImHexApi::Fonts::impl::getFonts()) { ImVector fontRange; @@ -252,9 +258,11 @@ namespace hex::plugin::builtin { ranges.push_back(fontRange); + cfg.FontBuilderFlags = startFlags | font.flags; + std::memset(cfg.Name, 0x00, sizeof(cfg.Name)); std::strncpy(cfg.Name, font.name.c_str(), sizeof(cfg.Name) - 1); - cfg.GlyphOffset = { font.offset.x, font.offset.y }; + cfg.GlyphOffset = { font.offset.x, font.offset.y - defaultFont->Descent }; fonts->AddFontFromMemoryTTF(font.fontData.data(), int(font.fontData.size()), 0, &cfg, ranges.back().Data); }