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

Fonts: added ImGuiStyle::FontSizeBase. Ensuring PushFontSize() works before main loop and across NewFrame().

# Conflicts:
#	imgui.cpp
This commit is contained in:
ocornut 2025-05-26 20:24:06 +02:00
parent b029be6b6c
commit 1e118ab891
5 changed files with 125 additions and 56 deletions

106
imgui.cpp
View file

@ -1354,6 +1354,7 @@ static void* GImAllocatorUserData = NULL;
ImGuiStyle::ImGuiStyle()
{
FontSizeBase = 0.0f; // Will default to io.Fonts->Fonts[0] on first frame.
Alpha = 1.0f; // Global alpha applies to everything in Dear ImGui.
DisabledAlpha = 0.60f; // Additional alpha multiplier applied by BeginDisabled(). Multiply over current value of Alpha.
WindowPadding = ImVec2(8,8); // Padding within a window
@ -1415,6 +1416,10 @@ ImGuiStyle::ImGuiStyle()
HoverFlagsForTooltipMouse = ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_AllowWhenDisabled; // Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using mouse.
HoverFlagsForTooltipNav = ImGuiHoveredFlags_NoSharedDelay | ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_AllowWhenDisabled; // Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using keyboard/gamepad.
// [Internal]
_MainScale = 1.0f;
_NextFrameFontSizeBase = 0.0f;
// Default theme
ImGui::StyleColorsDark(this);
}
@ -1423,6 +1428,8 @@ ImGuiStyle::ImGuiStyle()
// Important: This operation is lossy because we round all sizes to integer. If you need to change your scale multiples, call this over a freshly initialized ImGuiStyle structure rather than scaling multiple times.
void ImGuiStyle::ScaleAllSizes(float scale_factor)
{
_MainScale *= scale_factor;
FontSizeBase = ImTrunc(FontSizeBase * scale_factor);
WindowPadding = ImTrunc(WindowPadding * scale_factor);
WindowRounding = ImTrunc(WindowRounding * scale_factor);
WindowMinSize = ImTrunc(WindowMinSize * scale_factor);
@ -4403,7 +4410,7 @@ static void SetCurrentWindow(ImGuiWindow* window)
ImGuiViewport* viewport = window->Viewport;
g.FontRasterizerDensity = (viewport->FramebufferScale.x != 0.0f) ? viewport->FramebufferScale.x : g.IO.DisplayFramebufferScale.x; // == SetFontRasterizerDensity()
}
ImGui::UpdateCurrentFontSize();
ImGui::UpdateCurrentFontSize(0.0f);
ImGui::NavUpdateCurrentWindowIsScrollPushableX();
}
}
@ -8450,7 +8457,7 @@ void ImGui::SetWindowFontScale(float scale)
IM_ASSERT(scale > 0.0f);
ImGuiWindow* window = GetCurrentWindow();
window->FontWindowScale = scale;
UpdateCurrentFontSize();
UpdateCurrentFontSize(0.0f);
}
void ImGui::PushFocusScope(ImGuiID id)
@ -8619,12 +8626,24 @@ void ImGui::UpdateFontsNewFrame()
for (ImFontAtlas* atlas : g.FontAtlases)
atlas->Locked = true;
// We do this really unusual thing of calling *push_front()*, the reason behind that we want to support the PushFont()/NewFrame()/PopFont() idiom.
ImFontStackData font_stack_data = { ImGui::GetDefaultFont(), ImGui::GetDefaultFont()->LegacySize };
g.FontStack.push_front(font_stack_data);
if (g.FontStack.Size == 1)
ImGui::SetCurrentFont(font_stack_data.Font, font_stack_data.FontSize);
if (g.Style._NextFrameFontSizeBase != 0.0f)
{
g.Style.FontSizeBase = g.Style._NextFrameFontSizeBase;
g.Style._NextFrameFontSizeBase = 0.0f;
}
// Apply default font size the first time
ImFont* font = ImGui::GetDefaultFont();
if (g.Style.FontSizeBase <= 0.0f)
g.Style.FontSizeBase = font->LegacySize * g.Style._MainScale;
// Set initial font
g.Font = font;
g.FontSizeBeforeScaling = g.Style.FontSizeBase;
g.FontSize = 0.0f;
ImFontStackData font_stack_data = { font, g.Style.FontSizeBase, g.Style.FontSizeBase }; // <--- Will restore FontSize
SetCurrentFont(font_stack_data.Font, font_stack_data.FontSizeBeforeScaling, 0.0f); // <--- but use 0.0f to enable scale
g.FontStack.push_back(font_stack_data);
IM_ASSERT(g.Font->IsLoaded());
}
@ -8633,6 +8652,15 @@ void ImGui::UpdateFontsEndFrame()
PopFont();
}
ImFont* ImGui::GetDefaultFont()
{
ImGuiContext& g = *GImGui;
ImFontAtlas* atlas = g.IO.Fonts;
if (atlas->Builder == NULL)
ImFontAtlasBuildMain(atlas);
return g.IO.FontDefault ? g.IO.FontDefault : atlas->Fonts[0];
}
void ImGui::RegisterUserTexture(ImTextureData* tex)
{
ImGuiContext& g = *GImGui;
@ -8673,12 +8701,12 @@ void ImGui::UnregisterFontAtlas(ImFontAtlas* atlas)
// the same way AddImage() does, but then all other primitives would also need to? I don't think we should tackle this problem
// because we have a concrete need and a test bed for multiple atlas textures.
// FIXME-NEWATLAS-V2: perhaps we can now leverage ImFontAtlasUpdateDrawListsTextures() ?
void ImGui::SetCurrentFont(ImFont* font, float font_size)
void ImGui::SetCurrentFont(ImFont* font, float font_size_before_scaling, float font_size_after_scaling)
{
ImGuiContext& g = *GImGui;
g.Font = font;
g.FontSizeBeforeScaling = font_size;
UpdateCurrentFontSize();
g.FontSizeBeforeScaling = font_size_before_scaling;
UpdateCurrentFontSize(font_size_after_scaling);
if (font != NULL)
{
@ -8693,20 +8721,27 @@ void ImGui::SetCurrentFont(ImFont* font, float font_size)
}
}
void ImGui::UpdateCurrentFontSize()
void ImGui::UpdateCurrentFontSize(float restore_font_size_after_scaling)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
g.Style.FontSizeBase = g.FontSizeBeforeScaling;
if (window != NULL && window->SkipItems)
return;
float final_size = g.FontSizeBeforeScaling * g.IO.FontGlobalScale;
// Restoring is pretty much only used by PopFont()/PopFontSize()
float final_size = (restore_font_size_after_scaling > 0.0f) ? restore_font_size_after_scaling : 0.0f;
if (final_size == 0.0f)
{
final_size = g.FontSizeBeforeScaling * g.IO.FontGlobalScale;
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
if (g.Font != NULL)
final_size *= g.Font->Scale;
if (g.Font != NULL)
final_size *= g.Font->Scale;
#endif
if (window != NULL)
final_size *= window->FontWindowScale;
if (window != NULL)
final_size *= window->FontWindowScale;
}
// Round font size
// - We started rounding in 1.90 WIP (18991) as our layout system currently doesn't support non-rounded font size well yet.
@ -8731,12 +8766,16 @@ void ImGui::SetFontRasterizerDensity(float rasterizer_density)
if (g.FontRasterizerDensity == rasterizer_density)
return;
g.FontRasterizerDensity = rasterizer_density;
UpdateCurrentFontSize();
UpdateCurrentFontSize(0.0f);
}
// If you want to scale an existing font size:
// - Use e.g. PushFontSize(style.FontSizeBase * factor) (= value before external scale factors applied).
// - Do NOT use PushFontSize(GetFontSize() * factor) (= value after external scale factors applied).
void ImGui::PushFont(ImFont* font, float font_size)
{
ImGuiContext& g = *GImGui;
g.FontStack.push_back({ g.Font, g.FontSizeBeforeScaling, g.FontSize });
if (font == NULL)
font = GetDefaultFont();
if (font_size <= 0.0f)
@ -8746,23 +8785,20 @@ void ImGui::PushFont(ImFont* font, float font_size)
else
font_size = g.FontSizeBeforeScaling; // Keep current font size
}
g.FontStack.push_back({ font, font_size });
SetCurrentFont(font, font_size);
SetCurrentFont(font, font_size, 0.0f);
}
void ImGui::PopFont()
{
ImGuiContext& g = *GImGui;
if (g.FontStack.Size <= 1 && g.WithinFrameScope)
if (g.FontStack.Size <= 0 && g.WithinFrameScope)
{
IM_ASSERT_USER_ERROR(0, "Calling PopFont() too many times!");
return;
}
ImFontStackData* font_stack_data = &g.FontStack.back();
SetCurrentFont(font_stack_data->Font, font_stack_data->FontSizeBeforeScaling, font_stack_data->FontSizeAfterScaling);
g.FontStack.pop_back();
if (ImFontStackData* font_stack_data = (g.FontStack.Size > 0) ? &g.FontStack.back() : NULL)
SetCurrentFont(font_stack_data->Font, font_stack_data->FontSize);
else
SetCurrentFont(NULL, 0.0f);
}
void ImGui::PushFontSize(float font_size)
@ -15751,10 +15787,11 @@ void ImGui::ShowFontAtlas(ImFontAtlas* atlas)
{
ImGuiContext& g = *GImGui;
ImGuiIO& io = g.IO;
ImGuiStyle& style = g.Style;
Text("Read "); SameLine(0, 0);
TextLinkOpenURL("https://www.dearimgui.com/faq/"); SameLine(0, 0);
Text(" for details on font loading.");
Text(" for details.");
SeparatorText("Backend Support for Dynamic Fonts");
BeginDisabled();
@ -15762,11 +15799,16 @@ void ImGui::ShowFontAtlas(ImFontAtlas* atlas)
EndDisabled();
BeginDisabled((io.BackendFlags & ImGuiBackendFlags_RendererHasTextures) == 0);
SetNextItemWidth(GetFontSize() * 5);
DragFloat("io.FontGlobalScale", &io.FontGlobalScale, 0.05f, 0.5f, 5.0f);
BulletText("This is scaling font only. General scaling will come later.");
BulletText("Load an actual font that's not the default for best result!");
BulletText("Please submit feedback:"); SameLine(); TextLinkOpenURL("https://github.com/ocornut/imgui/issues/8465");
SetNextItemWidth(GetFontSize() * 10);
if (DragFloat("FontSizeBase", &style.FontSizeBase, 0.20f, 5.0f, 100.0f, "%.0f"))
style._NextFrameFontSizeBase = style.FontSizeBase; // FIXME: Temporary hack until we finish remaining work.
SameLine(0.0f, 0.0f); Text(" (out %.2f)", GetFontSize());
SameLine(); MetricsHelpMarker("- This is scaling font only. General scaling will come later.");
SetNextItemWidth(GetFontSize() * 10);
DragFloat("io.FontGlobalScale", &io.FontGlobalScale, 0.05f, 0.5f, 5.0f); // <-- This works, but no need to make it too visible.
BulletText("Load a nice font for better results!");
BulletText("Please submit feedback:");
SameLine(); TextLinkOpenURL("#8465", "https://github.com/ocornut/imgui/issues/8465");
EndDisabled();
SeparatorText("Fonts");
@ -15786,7 +15828,7 @@ void ImGui::ShowFontAtlas(ImFontAtlas* atlas)
#else
BeginDisabled();
RadioButton("stb_truetype", false);
SetItemTooltip("Requires IMGUI_ENABLE_STB_TRUETYPE");
SetItemTooltip("Requires #define IMGUI_ENABLE_STB_TRUETYPE");
EndDisabled();
#endif
SameLine();
@ -15810,7 +15852,7 @@ void ImGui::ShowFontAtlas(ImFontAtlas* atlas)
#else
BeginDisabled();
RadioButton("FreeType", false);
SetItemTooltip("Requires IMGUI_ENABLE_FREETYPE + imgui_freetype.cpp.");
SetItemTooltip("Requires #define IMGUI_ENABLE_FREETYPE + imgui_freetype.cpp.");
EndDisabled();
#endif
EndDisabled();

20
imgui.h
View file

@ -498,8 +498,13 @@ namespace ImGui
// *IMPORTANT* before 1.92, fonts had a single size. They can now be dynamically be adjusted.
// - Before 1.92: PushFont() always used font default size.
// - Since 1.92: PushFont() preserve the current shared font size.
// - To use old behavior (single size font): use 'PushFont(font, font->LegacySize)' in call site, or set 'ImFontConfig::Flags |= ImFontFlags_DefaultToLegacySize' before calling AddFont().
IMGUI_API void PushFont(ImFont* font, float font_size = -1); // use NULL as a shortcut to push default font. Use <0.0f to keep current font size. Use font->LegacySize to revert to font size specified by AddFont().
// - To use old behavior (single size font, size specified in AddFontXXX() call:
// - Use 'PushFont(font, font->LegacySize)' at call site
// - Or set 'ImFontConfig::Flags |= ImFontFlags_DefaultToLegacySize' before calling AddFont(), and then 'PushFont(font)' will use this size.
// *IMPORTANT* If you want to scale an existing font size:
// - OK: PushFontSize(style.FontSizeBase * factor) (= value before external scale factors applied).
// - KO: PushFontSize(GetFontSize() * factor) (= value after external scale factors applied. external scale factors are io.FontGlobalScale and per-viewport scales.).
IMGUI_API void PushFont(ImFont* font, float font_size = -1); // use NULL as a shortcut to push default font. Use <0.0f to keep current font size.
IMGUI_API void PopFont();
IMGUI_API void PushFontSize(float font_size);
IMGUI_API void PopFontSize();
@ -2222,6 +2227,8 @@ IM_MSVC_RUNTIME_CHECKS_RESTORE
struct ImGuiStyle
{
float FontSizeBase; // Current base font size (scaling applied). Use PushFont()/PushFontSize() to modify. Use ImGui::GetFontSize() to obtain scaled value.
float Alpha; // Global alpha applies to everything in Dear ImGui.
float DisabledAlpha; // Additional alpha multiplier applied by BeginDisabled(). Multiply over current value of Alpha.
ImVec2 WindowPadding; // Padding within a window.
@ -2287,8 +2294,13 @@ struct ImGuiStyle
ImGuiHoveredFlags HoverFlagsForTooltipMouse;// Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using mouse.
ImGuiHoveredFlags HoverFlagsForTooltipNav; // Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using keyboard/gamepad.
IMGUI_API ImGuiStyle();
IMGUI_API void ScaleAllSizes(float scale_factor);
// [Internal]
float _MainScale; // FIXME-WIP: Reference scale, as applied by ScaleAllSizes().
float _NextFrameFontSizeBase; // FIXME: Temporary hack until we finish remaining work.
// Functions
IMGUI_API ImGuiStyle();
IMGUI_API void ScaleAllSizes(float scale_factor);
// Obsolete names
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS

View file

@ -430,16 +430,25 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::Text("dear imgui says hello! (%s) (%d)", IMGUI_VERSION, IMGUI_VERSION_NUM);
ImGui::Spacing();
ImGui::SeparatorText("dynamic_fonts branch");
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 5);
ImGui::DragFloat("io.FontGlobalScale", &ImGui::GetIO().FontGlobalScale, 0.05f, 0.5f, 5.0f);
ImGui::BulletText("This is scaling font only. General scaling will come later.");
ImGui::BulletText("Load an actual font that's not the default for best result!");
ImGui::BulletText("See 'Widgets->Fonts' below for more..");
ImGui::BulletText("Current font loader: '%s'", ImGui::GetIO().Fonts->FontLoaderName);
ImGui::BulletText("Please submit feedback:"); ImGui::SameLine();
ImGui::TextLinkOpenURL("https://github.com/ocornut/imgui/issues/8465");
ImGui::Spacing();
{
ImGui::SeparatorText("dynamic_fonts branch");
ImGuiStyle& style = ImGui::GetStyle();
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 20);
ImGui::ShowFontSelector("Font");
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 20);
if (ImGui::DragFloat("FontSizeBase", &style.FontSizeBase, 0.20f, 5.0f, 100.0f, "%.0f"))
style._NextFrameFontSizeBase = style.FontSizeBase; // FIXME: Temporary hack until we finish remaining work.
ImGui::SameLine(0.0f, 0.0f); Text(" (out %.2f)", ImGui::GetFontSize());
ImGui::SameLine(); HelpMarker("- This is scaling font only. General scaling will come later.");
//ImGui::SetNextItemWidth(ImGui::GetFontSize() * 20);
//ImGui::DragFloat("FontGlobalScale", &ImGui::GetIO().FontGlobalScale, 0.05f, 0.5f, 5.0f);
ImGui::BulletText("Load a nice font for better results!");
ImGui::BulletText("See 'Widgets->Fonts' below for more.");
//ImGui::BulletText("Current font loader: '%s'", ImGui::GetIO().Fonts->FontLoaderName);
ImGui::BulletText("Please submit feedback:"); ImGui::SameLine();
ImGui::TextLinkOpenURL("#8465", "https://github.com/ocornut/imgui/issues/8465");
ImGui::Spacing();
}
IMGUI_DEMO_MARKER("Help");
if (ImGui::CollapsingHeader("Help"))
@ -8207,11 +8216,16 @@ void ImGui::ShowFontSelector(const char* label)
ImGui::EndCombo();
}
ImGui::SameLine();
HelpMarker(
"- Load additional fonts with io.Fonts->AddFontFromFileTTF().\n"
"- The font atlas is built when calling io.Fonts->GetTexDataAsXXXX() or io.Fonts->Build().\n"
"- Read FAQ and docs/FONTS.md for more details.\n"
"- If you need to add/remove fonts at runtime (e.g. for DPI change), do it before calling NewFrame().");
if (io.BackendFlags & ImGuiBackendFlags_RendererHasTextures)
HelpMarker(
"- Load additional fonts with io.Fonts->AddFontXXX() functions.\n"
"- Read FAQ and docs/FONTS.md for more details.");
else
HelpMarker(
"- Load additional fonts with io.Fonts->AddFontXXX() functions.\n"
"- The font atlas is built when calling io.Fonts->GetTexDataAsXXXX() or io.Fonts->Build().\n"
"- Read FAQ and docs/FONTS.md for more details.\n"
"- If you need to add/remove fonts at runtime (e.g. for DPI change), do it before calling NewFrame().");
}
// Demo helper function to select among default colors. See ShowStyleEditor() for more advanced options.

View file

@ -3190,7 +3190,7 @@ static void ImFontAtlasBuildNotifySetFont(ImFontAtlas* atlas, ImFont* old_font,
bool need_bind_ctx = ctx != curr_ctx;
if (need_bind_ctx)
ImGui::SetCurrentContext(ctx);
ImGui::SetCurrentFont(new_font, ctx->FontSize);
ImGui::SetCurrentFont(new_font, ctx->FontSizeBeforeScaling, ctx->FontSize);
if (need_bind_ctx)
ImGui::SetCurrentContext(curr_ctx);
}

View file

@ -871,7 +871,8 @@ struct ImDrawDataBuilder
struct ImFontStackData
{
ImFont* Font;
float FontSize;
float FontSizeBeforeScaling;
float FontSizeAfterScaling;
};
//-----------------------------------------------------------------------------
@ -3116,12 +3117,12 @@ namespace ImGui
IMGUI_API void UnregisterUserTexture(ImTextureData* tex);
IMGUI_API void RegisterFontAtlas(ImFontAtlas* atlas);
IMGUI_API void UnregisterFontAtlas(ImFontAtlas* atlas);
IMGUI_API void SetCurrentFont(ImFont* font, float font_size);
IMGUI_API void SetCurrentFont(ImFont* font, float font_size_before_scaling, float font_size_after_scaling);
IMGUI_API void UpdateCurrentFontSize(float restore_font_size_after_scaling);
IMGUI_API void SetFontRasterizerDensity(float rasterizer_density);
inline float GetFontRasterizerDensity() { return GImGui->FontRasterizerDensity; }
IMGUI_API void UpdateCurrentFontSize();
inline float GetRoundedFontSize(float size) { return IM_ROUND(size); }
inline ImFont* GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; }
IMGUI_API ImFont* GetDefaultFont();
IMGUI_API void PushPasswordFont();
IMGUI_API void PopPasswordFont();
inline ImDrawList* GetForegroundDrawList(ImGuiWindow* window) { IM_UNUSED(window); return GetForegroundDrawList(); } // This seemingly unnecessary wrapper simplifies compatibility between the 'master' and 'docking' branches.