From 9055c9ed222f16fdd0147453b5fb8596c76278d0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 22 Dec 2025 17:51:24 +0100 Subject: [PATCH] imgui_freetype: fixed overwriting ImFontConfig::PixelSnapH when hinting is enabled. Fix/amend 99f6b305c1. --- docs/CHANGELOG.txt | 4 ++++ imgui_draw.cpp | 1 + misc/freetype/imgui_freetype.cpp | 10 +++------- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index f9ee3a143..a9dd06ba1 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -67,6 +67,10 @@ Other Changes: - Fonts: - Fixed an issue related to EllipsisChar handling, while changing font loader or font loader flags dynamically in Style->Fonts menus. + - imgui_freetype: fixed overwriting ImFontConfig::PixelSnapH when hinting + is enabled, creating side-effects when later disabling hinting or + dynamically switching to stb_truetype rasterizer. + which would prevent - Textures: - Fixed a building issue when ImTextureID is defined as a struct. - Fixed displaying texture # in Metrics/Debugger window. diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 7e1b8a290..553730344 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -3392,6 +3392,7 @@ void ImFontAtlasBuildMain(ImFontAtlas* atlas) void ImFontAtlasBuildGetOversampleFactors(ImFontConfig* src, ImFontBaked* baked, int* out_oversample_h, int* out_oversample_v) { + // (Only used by stb_truetype builder) // Automatically disable horizontal oversampling over size 36 const float raster_size = baked->Size * baked->RasterizerDensity * src->RasterizerDensity; *out_oversample_h = (src->OversampleH != 0) ? src->OversampleH : (raster_size > 36.0f || src->PixelSnapH) ? 1 : 2; diff --git a/misc/freetype/imgui_freetype.cpp b/misc/freetype/imgui_freetype.cpp index 26a087017..d3d0a60ef 100644 --- a/misc/freetype/imgui_freetype.cpp +++ b/misc/freetype/imgui_freetype.cpp @@ -153,7 +153,7 @@ struct ImGui_ImplFreeType_Data struct ImGui_ImplFreeType_FontSrcData { // Initialize from an external data buffer. Doesn't copy data, and you must ensure it stays valid up to this object lifetime. - bool InitFont(FT_Library ft_library, ImFontConfig* src, ImGuiFreeTypeLoaderFlags extra_user_flags); + bool InitFont(FT_Library ft_library, const ImFontConfig* src, ImGuiFreeTypeLoaderFlags extra_user_flags); void CloseFont(); ImGui_ImplFreeType_FontSrcData() { memset((void*)this, 0, sizeof(*this)); } ~ImGui_ImplFreeType_FontSrcData() { CloseFont(); } @@ -172,7 +172,7 @@ struct ImGui_ImplFreeType_FontSrcBakedData ImGui_ImplFreeType_FontSrcBakedData() { memset((void*)this, 0, sizeof(*this)); } }; -bool ImGui_ImplFreeType_FontSrcData::InitFont(FT_Library ft_library, ImFontConfig* src, ImGuiFreeTypeLoaderFlags extra_font_loader_flags) +bool ImGui_ImplFreeType_FontSrcData::InitFont(FT_Library ft_library, const ImFontConfig* src, ImGuiFreeTypeLoaderFlags extra_font_loader_flags) { FT_Error error = FT_New_Memory_Face(ft_library, (const FT_Byte*)src->FontData, (FT_Long)src->FontDataSize, (FT_Long)src->FontNo, &FtFace); if (error != 0) @@ -187,12 +187,8 @@ bool ImGui_ImplFreeType_FontSrcData::InitFont(FT_Library ft_library, ImFontConfi LoadFlags = 0; if ((UserFlags & ImGuiFreeTypeLoaderFlags_Bitmap) == 0) LoadFlags |= FT_LOAD_NO_BITMAP; - if (UserFlags & ImGuiFreeTypeLoaderFlags_NoHinting) LoadFlags |= FT_LOAD_NO_HINTING; - else - src->PixelSnapH = true; // FIXME: A bit weird to do this this way. - if (UserFlags & ImGuiFreeTypeLoaderFlags_NoAutoHint) LoadFlags |= FT_LOAD_NO_AUTOHINT; if (UserFlags & ImGuiFreeTypeLoaderFlags_ForceAutoHint) @@ -543,7 +539,7 @@ static bool ImGui_ImplFreeType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontConf const float offsets_scale = (ref_size != 0.0f) ? (baked->Size / ref_size) : 1.0f; float font_off_x = (src->GlyphOffset.x * offsets_scale); float font_off_y = (src->GlyphOffset.y * offsets_scale) + baked->Ascent; - if (src->PixelSnapH) // Snap scaled offset. This is to mitigate backward compatibility issues for GlyphOffset, but a better design would be welcome. + if (src->PixelSnapH || (bd_font_data->UserFlags & ImGuiFreeTypeLoaderFlags_NoHinting) == 0) // Snap scaled offset. This is to mitigate backward compatibility issues for GlyphOffset, but a better design would be welcome. font_off_x = IM_ROUND(font_off_x); if (src->PixelSnapV) font_off_y = IM_ROUND(font_off_y);