diff --git a/lib/third_party/imgui/backend/source/imgui_impl_opengl3.cpp b/lib/third_party/imgui/backend/source/imgui_impl_opengl3.cpp index 23170c585..9a8e1aec2 100644 --- a/lib/third_party/imgui/backend/source/imgui_impl_opengl3.cpp +++ b/lib/third_party/imgui/backend/source/imgui_impl_opengl3.cpp @@ -423,10 +423,10 @@ void ImGui_ImplOpenGL3_NewFrame() bool useFontShaders = false; void FontShadersOn(const ImDrawList *parent_list, const ImDrawCmd *cmd) { - useFontShaders = !useFontShaders; + useFontShaders = true; } void FontShadersOff(const ImDrawList *parent_list, const ImDrawCmd *cmd) { - useFontShaders = !useFontShaders; + useFontShaders = false; } ImDrawCallback ImGui_ImplOpenGL3_TurnFontShadersOn = &FontShadersOn; ImDrawCallback ImGui_ImplOpenGL3_TurnFontShadersOff = &FontShadersOff; diff --git a/lib/third_party/imgui/imgui/source/imgui_draw.cpp b/lib/third_party/imgui/imgui/source/imgui_draw.cpp index 81c166e4e..4ef332140 100644 --- a/lib/third_party/imgui/imgui/source/imgui_draw.cpp +++ b/lib/third_party/imgui/imgui/source/imgui_draw.cpp @@ -1716,6 +1716,15 @@ void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32 font_size = _Data->FontSize; IM_ASSERT(font->ContainerAtlas->TexID == _CmdHeader.TextureId); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font. + ImVec4 clip_rect = _CmdHeader.ClipRect; + if (cpu_fine_clip_rect) + { + clip_rect.x = ImMax(clip_rect.x, cpu_fine_clip_rect->x); + clip_rect.y = ImMax(clip_rect.y, cpu_fine_clip_rect->y); + clip_rect.z = ImMin(clip_rect.z, cpu_fine_clip_rect->z); + clip_rect.w = ImMin(clip_rect.w, cpu_fine_clip_rect->w); + } + // IMHEX PATCH BEGIN int flags; bool is_subpixel = false; @@ -1726,15 +1735,9 @@ void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32 if (is_subpixel) AddCallback(ImGui_ImplOpenGL3_TurnFontShadersOn, NULL); // IMHEX PATCH END - ImVec4 clip_rect = _CmdHeader.ClipRect; - if (cpu_fine_clip_rect) - { - clip_rect.x = ImMax(clip_rect.x, cpu_fine_clip_rect->x); - clip_rect.y = ImMax(clip_rect.y, cpu_fine_clip_rect->y); - clip_rect.z = ImMin(clip_rect.z, cpu_fine_clip_rect->z); - clip_rect.w = ImMin(clip_rect.w, cpu_fine_clip_rect->w); - } + font->RenderText(this, font_size, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip_rect != NULL); + // IMHEX PATCH BEGIN if (is_subpixel) AddCallback(ImGui_ImplOpenGL3_TurnFontShadersOff, NULL); @@ -3329,15 +3332,8 @@ void ImFontAtlas::GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_wid TexPixelsRGBA32 = (unsigned int*)IM_ALLOC((size_t)TexWidth * (size_t)TexHeight * 4); const unsigned char* src = pixels; unsigned int* dst = TexPixelsRGBA32; - // IMHEX PATCH BEGIN - if (FontBuilderFlags & ImGuiFreeTypeBuilderFlags_SubPixel) { - for (int n = TexWidth * TexHeight; n > 0; n--,src++) - *dst++ = IM_COL32(*src, *src, *src, *src); - } else { - for (int n = TexWidth * TexHeight; n > 0; n--) - *dst++ = IM_COL32(255, 255, 255, (unsigned int)(*src++)); - } - // IMHEX PATCH END + for (int n = TexWidth * TexHeight; n > 0; n--) + *dst++ = IM_COL32(255, 255, 255, (unsigned int)(*src++)); } } diff --git a/plugins/fonts/include/font_atlas.hpp b/plugins/fonts/include/font_atlas.hpp index d98327464..2a0893191 100644 --- a/plugins/fonts/include/font_atlas.hpp +++ b/plugins/fonts/include/font_atlas.hpp @@ -29,7 +29,6 @@ namespace hex::fonts { } float calculateFontDescend(FT_Library ft, float fontSize) const { - if (ft == nullptr) { log::fatal("FreeType not initialized"); return 0.0f; @@ -46,14 +45,17 @@ namespace hex::fonts { if (m_font->FontSize > 0.0F) size = m_font->FontSize * std::max(1.0F, std::floor(ImHexApi::System::getGlobalScale())); else - size = std::max(1.0F, std::floor(size / ImHexApi::Fonts::DefaultFontSize)) * ImHexApi::Fonts::DefaultFontSize; + size = std::max(1.0F, std::floor(size / ImHexApi::Fonts::DefaultFontSize)) * ImHexApi::Fonts::DefaultFontSize * std::floor(ImHexApi::System::getGlobalScale()); - if (FT_Set_Pixel_Sizes(face, size, size) != 0) { - log::fatal("Failed to set pixel size"); - return 0.0f; - } + FT_Size_RequestRec req; + req.type = FT_SIZE_REQUEST_TYPE_REAL_DIM; + req.width = 0; + req.height = (uint32_t)(IM_ROUND(size) * 64.0F); + req.horiResolution = 0; + req.vertResolution = 0; + FT_Request_Size(face, &req); - return face->size->metrics.descender / 64.0F; + return face->size->metrics.ascender / 64.0F; } ImFont* getFont() { return m_font; } @@ -249,18 +251,13 @@ namespace hex::fonts { log::fatal("Failed to load face"); return 0.0f; } - - // Calculate the expected font size - auto size = fontSize; - if (font.defaultSize.has_value()) - size = font.defaultSize.value() * std::max(1.0F, std::floor(ImHexApi::System::getGlobalScale())); - else - size = std::max(1.0F, std::floor(size / ImHexApi::Fonts::DefaultFontSize)) * ImHexApi::Fonts::DefaultFontSize; - - if (FT_Set_Pixel_Sizes(face, size, size) != 0) { - log::fatal("Failed to set pixel size"); - return false; - } + FT_Size_RequestRec req; + req.type = FT_SIZE_REQUEST_TYPE_REAL_DIM; + req.width = 0; + req.height = (uint32_t)(IM_ROUND(fontSize) * 64.0F); + req.horiResolution = 0; + req.vertResolution = 0; + FT_Request_Size(face, &req); return face->size->metrics.descender / 64.0F; } diff --git a/plugins/fonts/source/font_loader.cpp b/plugins/fonts/source/font_loader.cpp index 4e6ca8415..9437f5fb8 100644 --- a/plugins/fonts/source/font_loader.cpp +++ b/plugins/fonts/source/font_loader.cpp @@ -22,7 +22,7 @@ namespace hex::fonts { - bool BuildSubPixelAtlas(FontAtlas *fontAtlas, float fontSize) { + bool BuildSubPixelAtlas(FontAtlas *fontAtlas) { FT_Library ft = nullptr; if (FT_Init_FreeType(&ft) != 0) { log::fatal("Failed to initialize FreeType"); @@ -41,10 +41,10 @@ namespace hex::fonts { std::map bitmapLCD; ImU32 fontCount = io.Fonts->ConfigData.Size; for (ImU32 i = 0; i < fontCount; i++) { - std::string fontName = io.Fonts->ConfigData[i].Name; + const auto config = io.Fonts->ConfigData[i]; + const auto &fontName = config.Name; - std::ranges::transform(fontName.begin(), fontName.end(), fontName.begin(), [](unsigned char c) { return std::tolower(c); }); - if (fontName == "nonscalable") { + if (hex::equalsIgnoreCase(fontName, "nonscalable")) { continue; } @@ -53,25 +53,20 @@ namespace hex::fonts { return false; } - float actualFontSize; - if (fontName.find("icon") != std::string::npos) - actualFontSize = ImHexApi::Fonts::pointsToPixels(fontSize); - else - actualFontSize = fontSize; - - if (FT_Set_Pixel_Sizes(face, actualFontSize, actualFontSize) != 0) { - log::fatal("Failed to set pixel size"); - return false; - } + FT_Size_RequestRec req; + req.type = FT_SIZE_REQUEST_TYPE_REAL_DIM; + req.width = 0; + req.height = (uint32_t)(IM_ROUND(config.SizePixels) * 64.0F); + req.horiResolution = 0; + req.vertResolution = 0; + FT_Request_Size(face, &req); FT_UInt gIndex; FT_ULong charCode = FT_Get_First_Char(face, &gIndex); while (gIndex != 0) { - - FT_UInt glyph_index = FT_Get_Char_Index(face, charCode); - if (FT_Load_Glyph(face, glyph_index, FT_LOAD_TARGET_LCD | FT_LOAD_TARGET_LIGHT | FT_LOAD_RENDER) != 0) { + if (FT_Load_Glyph(face, glyph_index, FT_LOAD_TARGET_LCD | FT_LOAD_TARGET_LIGHT | FT_LOAD_RENDER) != 0) { IM_ASSERT(true && "Failed to load glyph"); return false; } @@ -82,17 +77,15 @@ namespace hex::fonts { continue; } - auto width = bitmap_lcd.getWidth() / 3; + auto width = bitmap_lcd.getWidth() / 3.0F; auto height = bitmap_lcd.getHeight(); FT_GlyphSlot slot = face->glyph; FT_Size size = face->size; - ImVec2 offset = ImVec2((slot->metrics.horiBearingX / 64.0f), (size->metrics.ascender - slot->metrics.horiBearingY) / 64.0f); - if (fontName.find("codicon") != std::string::npos) - offset.x -= 1.0f; - ImS32 advance = (float) slot->advance.x / 64.0f; - if (offset.x+width > advance && advance >= (int) width) - offset.x = advance - width; + ImVec2 offset = ImVec2(face->glyph->bitmap_left, -face->glyph->bitmap_top); + offset.x += config.GlyphOffset.x; + offset.y += size->metrics.ascender / 64.0F; + ImS32 advance = (float) slot->advance.x / 64.0F; ImS32 rect_id = io.Fonts->AddCustomRectFontGlyph(io.Fonts->Fonts[0], charCode, width, height, advance, offset); rect_ids.push_back(rect_id); @@ -154,6 +147,7 @@ namespace hex::fonts { u32 fontIndex = 0; auto io = ImGui::GetIO(); io.Fonts = fontAtlas->getAtlas(); + // Check if Unicode support is enabled in the settings and that the user doesn't use the No GPU version on Windows // The Mesa3D software renderer on Windows identifies itself as "VMware, Inc." bool shouldLoadUnicode = ContentRegistry::Settings::read("hex.fonts.setting.font", "hex.fonts.setting.font.load_all_unicode_chars", false) && ImHexApi::System::getGPUVendor() != "VMware, Inc."; @@ -221,13 +215,16 @@ namespace hex::fonts { glyphRanges.push_back(glyphRange); // Calculate the glyph offset for the font - const ImVec2 offset = { font.offset.x, font.offset.y - (defaultFont->calculateFontDescend(ft, realFontSize) - fontAtlas->calculateFontDescend(ft, font, realFontSize)) }; // Load the font float size = realFontSize; if (font.defaultSize.has_value()) size = font.defaultSize.value() * ImHexApi::System::getBackingScaleFactor(); + + const ImVec2 offset = { font.offset.x, font.offset.y + ImCeil(4_scaled) }; + fontAtlas->addFontFromMemory(font.fontData, size, !font.defaultSize.has_value(), offset, glyphRanges.back()); + if (!font.scalable.value_or(true)) { std::string fontName = "NonScalable"; auto nameSize = fontName.size(); @@ -252,6 +249,6 @@ namespace hex::fonts { } return true; } else - return BuildSubPixelAtlas(fontAtlas,fontSize); + return BuildSubPixelAtlas(fontAtlas); } } \ No newline at end of file