Proper way to handle fonts which rasterize smaller than expected.
Version/Branch of Dear ImGui:
Version 1.91.0, Branch: docking
Back-ends:
Custom
Compiler, OS:
Clang 19, Linux
Full config/build information:
N/A
Details:
Hi,
While migrating an application to the new 1.91.0+ font system (which is amazing by the way) I encountered a point of confusion when dealing with fonts which rasterize to a actual size much smaller then the expected base height (SizePixels). I am using the freetype backend but the same effect happens with the truetype backend.
For example, I have a file Cantarell-Regular.ttf, which when baked to a size of 18.0f (eg style.FontSizeBase=18.0f) ends up with the ascii glyphs appearing about the same height as ProggyClean.ttf (an H is 9 pixels tall in the former and 8 in the latter). Because the glyphs themselves appear to be font size 13.0f, for things to look nice I would ideally want FontSizeBase to be 13.0f so that spacing of widgets is consistent. However, because the baked font size seems to be tied 1-to-1 to the logical font size, I am forced to either use FontSizeBase = 13.0f and end up with far too small text or use FontSizeBase = 18.0f and end up with widgets appearing too large for the small baked font.
To get around this issue I added a field float RasterizerScale to the ImFontConfig structure and in ImGui_ImplFreeType_FontBakedInit instead of using the exact baked size I use float size = baked->Size * src->RasterizerScale; so that for any FontSizeBase the relative scale is consistent with the rest of the UI.
Then, when calling AddFontFromFileTTF I set config.RasterizerScale = 18.0f/13.0f; so that for a requested font size of 13.0f freetype rasterizes at 18.0f, producing the correct sized glyphs.
This issue seems like it could be a somewhat common one to have with fonts and so I just wanted to check if there is a way to achieve this result without modifying ImGui itself or if there are plans to add support for this in the future. Or maybe I am missing a feature of the new fonts API completely!
I attached some pictures below to help show what I am describing.
Thanks!
Screenshots/Video:
Font Size 13.0f: (Text is too small!)
Font Size 18.0f: (Arrows and spacing are too large)
config.RasterizerScale = 18.0f/13.0f; (my intended result)
Freetype is given 18.0f, Imgui lays out as if 13.0f.
Compare to ProggyClean.ttf 13.0f: (Glyphs are similar height to Cantarell at 18.0f)
Minimal, Complete and Verifiable Example code:
N/A
Could it be related to #8857 ?
Oh yes that PR seems to be addressing the same issue but in a much better way then my hacky RasterizerScale setting. For large fonts (like Cantarell, Noto, etc) which contain both ascii glyphs and potentially large unicode glyphs it makes a lot more sense for ImGui to use the per glyph em square to determine the rendered size like described in that pr.
Since it looks like #8857 is making good progress I'll stick with my little hack in the meantime until people smarter than me solve it in a proper way. Thanks!