diff options
| author | quarrel07 <178681861+quarrel07@users.noreply.github.com> | 2026-07-19 07:12:17 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-07-19 16:12:17 +0200 |
| commit | 582900a1b9198bc941d139b0374b92a178c27efe (patch) | |
| tree | a58962f31b1a7c55a63c0de2bff12be9131d3777 | |
| parent | 6ed9a8ad288aebd6438af924e2de9f4061f99fb9 (diff) | |
macOS: sharp ImGui menu text on Retina at every menu scale (#714)
* macOS: sharp ImGui menu text on Retina at every menu scale
On a HiDPI display the ImGui overlay renders into a 2x framebuffer, but
the glyph atlas is rasterized at the logical point size and stretched up
by DisplayFramebufferScale, so all menu text looks fuzzy.
Set ImFontConfig::RasterizerDensity on the game fonts and the merged
FontAwesome icons: glyphs rasterize at higher resolution without
changing logical size or layout. Baked at retinaScale (2.0) times the
Menu Scale slider's maximum (2.0) so the runtime FontGlobalScale only
ever downsamples a high-res atlas instead of stretching a low-res one,
keeping text crisp at every Menu Scale setting. Standard-DPI displays
just get a supersampled atlas (identical layout, slightly sharper).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Shorten the RasterizerDensity comment
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
| -rw-r--r-- | src/port/Engine.cpp | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index 5120c82a2..3d516130e 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -587,11 +587,21 @@ uint8_t GameEngine::GetBankIdByName(const std::string& name) { ImFont* GameEngine::CreateFontWithSize(float size, std::string fontPath) { auto mImGuiIo = &ImGui::GetIO(); ImFont* font; + // Rasterize the glyph atlas at higher density so menu text stays sharp on HiDPI/Retina + // displays. Bake at retinaScale * maxMenuScale so the runtime Menu Scale setting + // (FontGlobalScale) only ever downsamples the atlas rather than stretching it blurry. + float rasterDensity = 1.0f; +#if defined(__APPLE__) + constexpr float kRetinaScale = 2.0f; // Retina backing scale + constexpr float kMaxMenuScale = 2.0f; // keep in sync with the gSettings.Menu.Scale slider Max + rasterDensity = kRetinaScale * kMaxMenuScale; +#endif if (fontPath == "") { ImFontConfig fontCfg = ImFontConfig(); fontCfg.OversampleH = fontCfg.OversampleV = 1; fontCfg.PixelSnapH = true; fontCfg.SizePixels = size; + fontCfg.RasterizerDensity = rasterDensity; font = mImGuiIo->Fonts->AddFontDefault(&fontCfg); } else { auto initData = std::make_shared<Ship::ResourceInitData>(); @@ -603,7 +613,9 @@ ImFont* GameEngine::CreateFontWithSize(float size, std::string fontPath) { Ship::Context::GetInstance()->GetResourceManager()->LoadResource(fontPath, false, initData)); char* fontDataPtr = (char*) malloc(fontData->DataSize); memcpy(fontDataPtr, fontData->Data, fontData->DataSize); - font = mImGuiIo->Fonts->AddFontFromMemoryTTF(fontDataPtr, fontData->DataSize, size); + ImFontConfig fontCfg = ImFontConfig(); + fontCfg.RasterizerDensity = rasterDensity; + font = mImGuiIo->Fonts->AddFontFromMemoryTTF(fontDataPtr, fontData->DataSize, size, &fontCfg); } // FontAwesome fonts need to have their sizes reduced by 2.0f/3.0f in order to align correctly float iconFontSize = size * 2.0f / 3.0f; @@ -612,6 +624,7 @@ ImFont* GameEngine::CreateFontWithSize(float size, std::string fontPath) { iconsConfig.MergeMode = true; iconsConfig.PixelSnapH = true; iconsConfig.GlyphMinAdvanceX = iconFontSize; + iconsConfig.RasterizerDensity = rasterDensity; mImGuiIo->Fonts->AddFontFromMemoryCompressedBase85TTF(fontawesome_compressed_data_base85, iconFontSize, &iconsConfig, sIconsRanges); return font; |
