1
0
Fork 0
mirror of https://github.com/ocornut/imgui.git synced 2026-01-09 23:54:20 +00:00

(Breaking) Fonts: remove ImFontConfig::PixelSnapV. Post-rescale GlyphOffset is always rounded.

Amend 99f6b305c, 99bca397d8.
This commit is contained in:
ocornut 2025-12-23 14:30:16 +01:00
parent 55ad3b4abd
commit 73dd0e869d
5 changed files with 30 additions and 32 deletions

View file

@ -50,17 +50,21 @@ Breaking Changes:
- This will invalidate hashes (stored in .ini data) for Tables and Windows - This will invalidate hashes (stored in .ini data) for Tables and Windows
that are using the "###" operators. (#713, #1698) that are using the "###" operators. (#713, #1698)
- Renamed helper macro IM_ARRAYSIZE() -> IM_COUNTOF(). Kept redirection/legacy name. - Renamed helper macro IM_ARRAYSIZE() -> IM_COUNTOF(). Kept redirection/legacy name.
- Fonts: Fixed handling of `ImFontConfig::FontDataOwnedByAtlas = false` which - Fonts:
- Fixed handling of `ImFontConfig::FontDataOwnedByAtlas = false` which
did erroneously make a copy of the font data, essentially defeating the purpose did erroneously make a copy of the font data, essentially defeating the purpose
of this flag and wasting memory (undetected since July 2015 and now spotted of this flag and wasting memory (undetected since July 2015 and now spotted
by @TellowKrinkle, this is perhaps the oldest bug in Dear ImGui history, by @TellowKrinkle, this is perhaps the oldest bug in Dear ImGui history,
albeit for a rarely used feature!) (#9086, #8465) albeit for a rarely used feature!) (#9086, #8465)
HOWEVER, fixing this bug is likely to surface bugs in user/app code: HOWEVER, fixing this bug is likely to surface bugs in user/app code:
- Prior to 1.92, font data only needs to be available during the atlas->AddFontXXX() call. - Prior to 1.92, font data only needs to be available during the atlas->AddFontXXX() call.
- Since 1.92, font data needs to available until atlas->RemoveFont(), or more typically Since 1.92, font data needs to available until atlas->RemoveFont(), or more typically
until a shutdown of the owning context or font atlas. until a shutdown of the owning context or font atlas.
- The fact that handling of `FontDataOwnedByAtlas = false` was broken - The fact that handling of `FontDataOwnedByAtlas = false` was broken bypassed
bypassed the issue altogether. the issue altogether.
- Removed ImFontConfig::PixelSnapV added in 1.92 which turns out is unnecessary
(and misdocumented). Post-rescale GlyphOffset is always rounded.
Other Changes: Other Changes:
@ -70,7 +74,7 @@ Other Changes:
- imgui_freetype: fixed overwriting ImFontConfig::PixelSnapH when hinting - imgui_freetype: fixed overwriting ImFontConfig::PixelSnapH when hinting
is enabled, creating side-effects when later disabling hinting or is enabled, creating side-effects when later disabling hinting or
dynamically switching to stb_truetype rasterizer. dynamically switching to stb_truetype rasterizer.
which would prevent - Post rescale GlyphOffset is always rounded.
- Textures: - Textures:
- Fixed a building issue when ImTextureID is defined as a struct. - Fixed a building issue when ImTextureID is defined as a struct.
- Fixed displaying texture # in Metrics/Debugger window. - Fixed displaying texture # in Metrics/Debugger window.

View file

@ -394,13 +394,13 @@ IMPLEMENTING SUPPORT for ImGuiBackendFlags_RendererHasTextures:
When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
You can read releases logs https://github.com/ocornut/imgui/releases for more details. You can read releases logs https://github.com/ocornut/imgui/releases for more details.
- 2025/12/23 (1.92.6) - Fonts: removed ImFontConfig::PixelSnapV added in 1.92 which turns out is unnecessary (and misdocumented). Post-rescale GlyphOffset is always rounded.
- 2025/12/17 (1.92.6) - Renamed helper macro IM_ARRAYSIZE() -> IM_COUNTOF(). Kept redirection/legacy name for now. - 2025/12/17 (1.92.6) - Renamed helper macro IM_ARRAYSIZE() -> IM_COUNTOF(). Kept redirection/legacy name for now.
- 2025/12/11 (1.92.6) - Hashing: handling of "###" operator to reset to seed within a string identifier doesn't include the "###" characters in the output hash anymore. - 2025/12/11 (1.92.6) - Hashing: handling of "###" operator to reset to seed within a string identifier doesn't include the "###" characters in the output hash anymore.
- Before: GetID("Hello###World") == GetID("###World") != GetID("World"); - Before: GetID("Hello###World") == GetID("###World") != GetID("World");
- Now: GetID("Hello###World") == GetID("###World") == GetID("World"); - Now: GetID("Hello###World") == GetID("###World") == GetID("World");
- This has the property of facilitating concatenating and manipulating identifiers using "###", and will allow fixing other dangling issues. - This has the property of facilitating concatenating and manipulating identifiers using "###", and will allow fixing other dangling issues.
- This will invalidate hashes (stored in .ini data) for Tables and Windows! - This will invalidate hashes (stored in .ini data) for Tables and Windows that are using the "###" operators. (#713, #1698)
that are using the "###" operators. (#713, #1698)
- 2025/11/24 (1.92.6) - Fonts: Fixed handling of `ImFontConfig::FontDataOwnedByAtlas = false` which did erroneously make a copy of the font data, essentially defeating the purpose of this flag and wasting memory. - 2025/11/24 (1.92.6) - Fonts: Fixed handling of `ImFontConfig::FontDataOwnedByAtlas = false` which did erroneously make a copy of the font data, essentially defeating the purpose of this flag and wasting memory.
(trivia: undetected since July 2015, this is perhaps the oldest bug in Dear ImGui history, albeit for a rarely used feature, see #9086) (trivia: undetected since July 2015, this is perhaps the oldest bug in Dear ImGui history, albeit for a rarely used feature, see #9086)
HOWEVER, fixing this bug is likely to surface bugs in user code using `FontDataOwnedByAtlas = false`. HOWEVER, fixing this bug is likely to surface bugs in user code using `FontDataOwnedByAtlas = false`.
@ -1265,7 +1265,7 @@ IMPLEMENTING SUPPORT for ImGuiBackendFlags_RendererHasTextures:
#define IMGUI_DEBUG_NAV_RECTS 0 // Display the reference navigation rectangle for each window #define IMGUI_DEBUG_NAV_RECTS 0 // Display the reference navigation rectangle for each window
// Default font size if unspecified in both style.FontSizeBase and AddFontXXX() calls. // Default font size if unspecified in both style.FontSizeBase and AddFontXXX() calls.
static const float FONT_DEFAULT_SIZE = 20.0f; static const float FONT_DEFAULT_SIZE_BASE = 20.0f;
// When using Ctrl+Tab (or Gamepad Square+L/R) we delay the visual a little in order to reduce visual noise doing a fast switch. // When using Ctrl+Tab (or Gamepad Square+L/R) we delay the visual a little in order to reduce visual noise doing a fast switch.
static const float NAV_WINDOWING_HIGHLIGHT_DELAY = 0.20f; // Time before the highlight and screen dimming starts fading in static const float NAV_WINDOWING_HIGHLIGHT_DELAY = 0.20f; // Time before the highlight and screen dimming starts fading in
@ -8903,7 +8903,7 @@ void ImGui::UpdateFontsNewFrame()
// Apply default font size the first time // Apply default font size the first time
ImFont* font = ImGui::GetDefaultFont(); ImFont* font = ImGui::GetDefaultFont();
if (g.Style.FontSizeBase <= 0.0f) if (g.Style.FontSizeBase <= 0.0f)
g.Style.FontSizeBase = (font->LegacySize > 0.0f ? font->LegacySize : FONT_DEFAULT_SIZE); g.Style.FontSizeBase = (font->LegacySize > 0.0f ? font->LegacySize : FONT_DEFAULT_SIZE_BASE);
// Set initial font // Set initial font
g.Font = font; g.Font = font;

View file

@ -30,7 +30,7 @@
// Library Version // Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
#define IMGUI_VERSION "1.92.6 WIP" #define IMGUI_VERSION "1.92.6 WIP"
#define IMGUI_VERSION_NUM 19257 #define IMGUI_VERSION_NUM 19258
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000 #define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198 #define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
@ -3528,7 +3528,6 @@ struct ImFontConfig
// Options // Options
bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights. bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights.
bool PixelSnapH; // false // Align every glyph AdvanceX to pixel boundaries. Prevents fractional font size from working correctly! Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1. bool PixelSnapH; // false // Align every glyph AdvanceX to pixel boundaries. Prevents fractional font size from working correctly! Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1.
bool PixelSnapV; // false // Align Scaled GlyphOffset.y to pixel boundaries. Prevents fractional font size from working correctly!.
ImS8 OversampleH; // 0 (2) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1 or 2 depending on size. Note the difference between 2 and 3 is minimal. You can reduce this to 1 for large glyphs save memory. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details. ImS8 OversampleH; // 0 (2) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1 or 2 depending on size. Note the difference between 2 and 3 is minimal. You can reduce this to 1 for large glyphs save memory. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details.
ImS8 OversampleV; // 0 (1) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1. This is not really useful as we don't use sub-pixel positions on the Y axis. ImS8 OversampleV; // 0 (1) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1. This is not really useful as we don't use sub-pixel positions on the Y axis.
ImWchar EllipsisChar; // 0 // Explicitly specify Unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used. ImWchar EllipsisChar; // 0 // Explicitly specify Unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used.
@ -3553,6 +3552,9 @@ struct ImFontConfig
const ImFontLoader* FontLoader; // Custom font backend for this source (default source is the one stored in ImFontAtlas) const ImFontLoader* FontLoader; // Custom font backend for this source (default source is the one stored in ImFontAtlas)
void* FontLoaderData; // Font loader opaque storage (per font config) void* FontLoaderData; // Font loader opaque storage (per font config)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
bool PixelSnapV; // true // [Obsoleted in 1.91.6] Align Scaled GlyphOffset.y to pixel boundaries.
#endif
IMGUI_API ImFontConfig(); IMGUI_API ImFontConfig();
}; };

View file

@ -3121,11 +3121,11 @@ ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template)
font_cfg.PixelSnapH = true; font_cfg.PixelSnapH = true;
} }
if (font_cfg.SizePixels <= 0.0f) if (font_cfg.SizePixels <= 0.0f)
font_cfg.SizePixels = 13.0f * 1.0f; font_cfg.SizePixels = 13.0f; // This only serves (1) as a reference for GlyphOffset.y setting and (2) as a default for pre-1.92 backend.
if (font_cfg.Name[0] == '\0') if (font_cfg.Name[0] == '\0')
ImFormatString(font_cfg.Name, IM_COUNTOF(font_cfg.Name), "ProggyClean.ttf"); ImFormatString(font_cfg.Name, IM_COUNTOF(font_cfg.Name), "ProggyClean.ttf");
font_cfg.EllipsisChar = (ImWchar)0x0085; font_cfg.EllipsisChar = (ImWchar)0x0085;
font_cfg.GlyphOffset.y += 1.0f * IM_TRUNC(font_cfg.SizePixels / 13.0f); // Add +1 offset per 13 units font_cfg.GlyphOffset.y += 1.0f * (font_cfg.SizePixels / 13.0f); // Add +1 offset per 13 units
int ttf_compressed_size = 0; int ttf_compressed_size = 0;
const char* ttf_compressed = GetDefaultCompressedFontDataTTF(&ttf_compressed_size); const char* ttf_compressed = GetDefaultCompressedFontDataTTF(&ttf_compressed_size);
@ -4721,12 +4721,8 @@ static bool ImGui_ImplStbTrueType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontC
const float ref_size = baked->OwnerFont->Sources[0]->SizePixels; const float ref_size = baked->OwnerFont->Sources[0]->SizePixels;
const float offsets_scale = (ref_size != 0.0f) ? (baked->Size / ref_size) : 1.0f; 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_x = ImFloor(src->GlyphOffset.x * offsets_scale + 0.5f); // Snap scaled offset.
float font_off_y = (src->GlyphOffset.y * offsets_scale); float font_off_y = ImFloor(src->GlyphOffset.y * offsets_scale + 0.5f);
if (src->PixelSnapH) // 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);
font_off_x += sub_x; font_off_x += sub_x;
font_off_y += sub_y + IM_ROUND(baked->Ascent); font_off_y += sub_y + IM_ROUND(baked->Ascent);
float recip_h = 1.0f / (oversample_h * rasterizer_density); float recip_h = 1.0f / (oversample_h * rasterizer_density);

View file

@ -538,12 +538,8 @@ static bool ImGui_ImplFreeType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontConf
const float ref_size = baked->OwnerFont->Sources[0]->SizePixels; const float ref_size = baked->OwnerFont->Sources[0]->SizePixels;
const float offsets_scale = (ref_size != 0.0f) ? (baked->Size / ref_size) : 1.0f; 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_x = ImFloor(src->GlyphOffset.x * offsets_scale + 0.5f); // Snap scaled offset.
float font_off_y = (src->GlyphOffset.y * offsets_scale) + baked->Ascent; float font_off_y = ImFloor(src->GlyphOffset.y * offsets_scale + 0.5f) + baked->Ascent;
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);
float recip_h = 1.0f / rasterizer_density; float recip_h = 1.0f / rasterizer_density;
float recip_v = 1.0f / rasterizer_density; float recip_v = 1.0f / rasterizer_density;