Skip to content

Dynamic font scaling issue #9513

Description

@itsRythem

Version/Branch of Dear ImGui:

Version 1.93.0 WIP, Branch: Master

Back-ends:

imgui_impl_win32.cpp + imgui_impl_dx11.cpp

Compiler, OS:

Windows 11 + MSVC 2026

Full config/build information:

Dear ImGui 1.93.0 WIP (19292)
--------------------------------
sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=199711
define: _WIN32
define: _WIN64
define: _MSC_VER=1951
define: _MSVC_LANG=202002
IM_ASSERT: runs expression: OK. expand size: OK
--------------------------------
io.BackendPlatformName: imgui_impl_win32
io.BackendRendererName: imgui_impl_dx11
io.ConfigFlags: 0x00000000
io.ConfigNavCaptureKeyboard
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigMemoryCompactTimer = 60.0
io.BackendFlags: 0x0000003E
 HasMouseCursors
 HasSetMousePos
 RendererHasVtxOffset
 RendererHasTextures
--------------------------------
io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,256
io.Fonts->FontLoaderName: FreeType (2.14.3; 2.14.3)
io.DisplaySize: 1424.00,789.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------
style.WindowPadding: 8.00,8.00
style.WindowBorderSize: 1.00
style.FramePadding: 4.00,3.00
style.FrameRounding: 0.00
style.FrameBorderSize: 0.00
style.ItemSpacing: 8.00,4.00
style.ItemInnerSpacing: 4.00,4.00

Details:

I am implementing an SDF/MSDF font-rendering system in my own build of ImGui, and I have run into an issue with how baked font sizes are selected.

For SDF/MSDF fonts, the atlas ideally only needs to contain a small number of baked sizes. For example:

  • 1–64px → bake at 64px
  • 65–128px → bake at 128px
  • 129–192px → bake at 192px
  • etc.

The font can then be raster-scaled and rendered at arbitrary sizes using a shader that evaluates the distance field, rather than requiring a new baked font for every requested size.

Currently, however, ImFont::GetFontBaked() uses the requested/scaled font size when determining which baked font to use. This means that scaling an SDF/MSDF font can cause ImGui to generate additional baked fonts at runtime. SDF/MSDF generation is considerably more expensive than normal rasterization, so this can result in significant stalls when the font is scaled; in my testing, generating a new SDF can cause roughly a 1 FPS-level hitch.

Using ImFontFlags_LockBakedSizes avoids this behavior by forcing ImGui to perform a lookup for the closest existing baked size, but this introduces a relatively heavy lookup path and does not seem ideal as a general solution.

My temporary workaround is to hard-code the size passed from GetFontBaked() to ImFontAtlasBakedGetOrAdd(), effectively forcing all requests to use my desired baked size. However, this is obviously not a good solution because it changes the behavior globally and can break fonts that are not using SDF/MSDF rendering.

I think there may be value in introducing an intermediate API between callers of GetFontBaked() and GetFontBaked() itself. This could allow a font to specify how its requested size should be mapped to a baked size.

For example, something along the lines of:

ImFontBaked* ImFont::GetFontBaked(float size)
{
    size = GetPreferredBakedSize(size);
    ...
}

Where GetPreferredBakedSize() could either be controlled by a font flag or provided as a callback.

This would allow SDF/MSDF implementations to define a policy such as rounding the requested size up to the nearest 64px interval, while normal fonts would retain the existing behavior:

float GetPreferredBakedSize(float requested_size)
{
    return ceilf(requested_size / 64.0f) * 64.0f;
}

Another possibility would be an ImFont/ImFontConfig option such as PreferBakedSize, or a callback that receives the requested size and returns the size that should actually be baked/looked up.

The important distinction is that this would not force all fonts into fixed baked sizes. It would simply give specialized font implementations, such as SDF/MSDF, a way to control baked-size selection without modifying the backend or globally enabling ImFontFlags_LockBakedSizes.

Would an API along these lines make sense for ImGui, or is there already a better extension point for implementing this behavior?

Screenshots/Video:

No response

Minimal, Complete and Verifiable Example code:

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions