Skip to content

Commit

Permalink
Add LoadFontDpiResponsive
Browse files Browse the repository at this point in the history
  • Loading branch information
pthom committed Apr 12, 2024
1 parent ce18809 commit 963b18c
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 34 deletions.
32 changes: 25 additions & 7 deletions src/hello_imgui/hello_imgui_font.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,35 @@ namespace HelloImGui
ImFontConfig fontConfigFontAwesome = ImFontConfig();
};

// When loading fonts, use HelloImGui::LoadFont(FontLoadingParams)
// ===============================================================
// instead of ImGui::GetIO().Fonts->AddFontFromFileTTF(), because it will
// automatically adjust the font size to account for HighDPI, and will spare
// you headaches when trying to get consistent font size across different OSes.
// see FontLoadingParams and ImFontConfig
// A font that will be automatically resized to account for changes in DPI
// (use LoadAdaptiveFont instead of LoadFont to get this behavior)
struct FontDpiResponsive
{
ImFont* font = nullptr;
std::string fontFilename;
float fontSize = 0.f;
FontLoadingParams fontLoadingParams;
};

// !!! When loading fonts, use
// HelloImGui::LoadFont(FontLoadingParams)
// or
// HelloImGui::LoadDpiResponsiveFont(FontLoadingParams)
//
// Use these functions instead of ImGui::GetIO().Fonts->AddFontFromFileTTF(),
// because they will automatically adjust the font size to account for HighDPI,
// and will spare you headaches when trying to get consistent font size across different OSes.

// Loads a font with the specified parameters (this font will not adapt to DPI changes after startup)
ImFont* LoadFont(const std::string & fontFilename, float fontSize,
const FontLoadingParams & params = {});

// @@md
// Loads a font with the specified parameters (this font will adapt to DPI changes after startup)
// (only fonts loaded with LoadAdaptiveFont will adapt to DPI changes. Avoid mixing LoadFont/LoadFontDpiResponsive)
FontDpiResponsive* LoadFontDpiResponsive(const std::string & fontFilename, float fontSize,
const FontLoadingParams & params = {});

// @@md

//
// Deprecated API below, kept for compatibility (uses LoadFont internally)
Expand Down
56 changes: 54 additions & 2 deletions src/hello_imgui/impl/hello_imgui_font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include "imgui_freetype.h"
#endif

#include <vector>

#ifdef IOS
#include "hello_imgui/internal/platform/getAppleBundleResourcePath.h"
#endif
Expand Down Expand Up @@ -132,7 +134,7 @@ namespace HelloImGui
}


ImFont* LoadFont(const std::string & fontFilename, float fontSize_, const FontLoadingParams& params_)
ImFont* _LoadFontImpl(const std::string & fontFilename, float fontSize_, const FontLoadingParams& params_)
{
gDidCallHelloImGuiLoadFontTTF = true;

Expand Down Expand Up @@ -209,7 +211,57 @@ namespace HelloImGui
return font;
}

ImFont* LoadFontTTF(const std::string & fontFilename, float fontSize, bool useFullGlyphRange, ImFontConfig config)
std::vector<FontDpiResponsive> gAllDpiResponsiveFonts;


ImFont* LoadFont(const std::string & fontFilename, float fontSize_, const FontLoadingParams& params_)
{
printf("LoadFont(%s, %f)\n", fontFilename.c_str(), fontSize_);
return _LoadFontImpl(fontFilename, fontSize_, params_);
}

FontDpiResponsive* LoadFontDpiResponsive(const std::string & fontFilename, float fontSize,
const FontLoadingParams & fontLoadingParams)
{
// Ensure that we have enough capacity, so that pointers remain valid
constexpr size_t maxFonts = 100;
if (gAllDpiResponsiveFonts.capacity() == 0)
gAllDpiResponsiveFonts.reserve(maxFonts);
// Whine if we are about to exceed the capacity
IM_ASSERT(gAllDpiResponsiveFonts.size() < maxFonts - 1 && "Too many fonts loaded");
// Insert a new element at the end of the vector
gAllDpiResponsiveFonts.push_back({ nullptr, fontFilename, fontSize, fontLoadingParams });

// Get the pointer to the newly inserted element (which we will return)
FontDpiResponsive* dpiResponsiveFont = &gAllDpiResponsiveFonts.back();

printf("LoadFontDpiResponsive(%s, %f)\n", fontFilename.c_str(), fontSize);
dpiResponsiveFont->font = _LoadFontImpl(fontFilename, fontSize, fontLoadingParams);
dpiResponsiveFont->fontSize = fontSize;
dpiResponsiveFont->fontFilename = fontFilename;
dpiResponsiveFont->fontLoadingParams = fontLoadingParams;
return dpiResponsiveFont;
}

void _ReloadAllDpiResponsiveFonts()
{
printf("_ReloadAllDpiResponsiveFonts\n");
auto& imguiFonts = ImGui::GetIO().Fonts;
imguiFonts->Clear();
for (auto & dpiResponsiveFont : gAllDpiResponsiveFonts)
{
float fontSize = dpiResponsiveFont.fontSize;
const std::string & fontFilename = dpiResponsiveFont.fontFilename;
const FontLoadingParams & fontLoadingParams = dpiResponsiveFont.fontLoadingParams;
ImFont* newFont = _LoadFontImpl(fontFilename, fontSize, fontLoadingParams);
dpiResponsiveFont.font = newFont;
}
bool buildSuccess = imguiFonts->Build();
IM_ASSERT(buildSuccess && "_ReloadAllDpiResponsiveFonts: Failed to build fonts");
}


ImFont* LoadFontTTF(const std::string & fontFilename, float fontSize, bool useFullGlyphRange, ImFontConfig config)
{
FontLoadingParams fontLoadingParams;
if (useFullGlyphRange)
Expand Down
4 changes: 2 additions & 2 deletions src/hello_imgui/impl/imgui_default_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ void LoadDefaultFont_WithFontAwesomeIcons()
return;
}

ImFont* font = LoadFont(fontFilename, fontSize);
auto font = LoadFontDpiResponsive(fontFilename, fontSize);
if (defaultIconFont == HelloImGui::DefaultIconFont::NoIcons)
return;

Expand All @@ -43,7 +43,7 @@ void LoadDefaultFont_WithFontAwesomeIcons()
HelloImGui::FontLoadingParams fontParams;
fontParams.mergeToLastFont = true;
fontParams.useFullGlyphRange = true;
font = LoadFont(iconFontFile, fontSize, fontParams);
font = LoadFontDpiResponsive(iconFontFile, fontSize, fontParams);
(void) font;
}

Expand Down
73 changes: 50 additions & 23 deletions src/hello_imgui/internal/backend_impls/abstract_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ class NetImGuiWrapper
}
}

void sendFonts()
{
_sendFonts_Impl();
}

private:
void InitiateConnection()
{
Expand All @@ -175,7 +180,7 @@ class NetImGuiWrapper
NetImgui::ConnectToApp(clientName().c_str(), remoteParams().serverHost.c_str(), remoteParams().serverPort);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
++ mNbConnectionsTentatives;
sendFonts();
_sendFonts_Impl();
}

std::string clientName()
Expand All @@ -192,9 +197,8 @@ class NetImGuiWrapper
HelloImGui::NetImGuiParams& remoteParams() { return HelloImGui::GetRunnerParams()->remoteParams; }
HelloImGui::RunnerParams& runnerParams() { return *HelloImGui::GetRunnerParams(); }

void sendFonts()
void _sendFonts_Impl()
{
printf("NetImGuiWrapper: sendFonts\n");
const ImFontAtlas* pFonts = ImGui::GetIO().Fonts;
if( pFonts->TexPixelsAlpha8) // && (pFonts->TexPixelsAlpha8 != client.mpFontTextureData || client.mFontTextureID != pFonts->TexID ))
{
Expand Down Expand Up @@ -439,30 +443,24 @@ void ReadDpiAwareParams(const std::string& appIniSettingLocation, DpiAwareParams
}


void _LogDpiParams(const HelloImGui::DpiAwareParams& dpiAwareParams)
void _LogDpiParams(const std::string& origin, const HelloImGui::DpiAwareParams& dpiAwareParams)
{
auto &io = ImGui::GetIO();
std::stringstream msg;
PoorManLog("dpiAwareParams: dpiWindowSizeFactor=%f\n", dpiAwareParams.dpiWindowSizeFactor);
PoorManLog("dpiAwareParams: fontRenderingScale=%f\n", dpiAwareParams.fontRenderingScale);
PoorManLog("dpiAwareParams: DpiFontLoadingFactor()=%f\n", dpiAwareParams.DpiFontLoadingFactor());
PoorManLog(" ImGui FontGlobalScale: %f\n", io.FontGlobalScale);
PoorManLog(" ImGui DisplayFramebufferScale=%f, %f\n", io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y);
PoorManLog("DpiAwareParams: %s\n", origin.c_str());
PoorManLog(" dpiWindowSizeFactor=%f\n", dpiAwareParams.dpiWindowSizeFactor);
PoorManLog(" fontRenderingScale=%f\n", dpiAwareParams.fontRenderingScale);
PoorManLog(" DpiFontLoadingFactor()=%f\n", dpiAwareParams.DpiFontLoadingFactor());
PoorManLog(" (ImGui FontGlobalScale: %f)\n", io.FontGlobalScale);
PoorManLog(" (ImGui DisplayFramebufferScale=%f, %f)\n", io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y);
}


void _CheckDpiAwareParamsChanges(HelloImGui::RunnerParams& params)
bool _CheckDpiAwareParamsChanges(HelloImGui::RunnerParams& params)
{
auto& dpiAwareParams = params.dpiAwareParams;
auto& io = ImGui::GetIO();

static bool isFirstTime = true;
if (isFirstTime)
{
_LogDpiParams(dpiAwareParams);
isFirstTime = false;
}

// Check changes
bool didFontGlobalScaleChange = dpiAwareParams.fontRenderingScale != io.FontGlobalScale;
if (didFontGlobalScaleChange)
Expand All @@ -488,8 +486,11 @@ void _CheckDpiAwareParamsChanges(HelloImGui::RunnerParams& params)
if (didDpiWindowSizeFactorChange || didFontGlobalScaleChange)
{
printf("New DpiAwareParams:\n");
_LogDpiParams(dpiAwareParams);
_LogDpiParams("_CheckDpiAwareParamsChanges (changed!)", dpiAwareParams);
return true;
}
else
return false;
}


Expand Down Expand Up @@ -545,7 +546,7 @@ void AbstractRunner::SetupDpiAwareParams()
}
ImGui::GetIO().FontGlobalScale = params.dpiAwareParams.fontRenderingScale;

_CheckDpiAwareParamsChanges(params);
_LogDpiParams("SetupDpiAwareParams", params.dpiAwareParams);
}


Expand Down Expand Up @@ -856,8 +857,8 @@ void AbstractRunner::Setup()

// This should be done before Impl_LinkPlatformAndRenderBackends()
// because, in the case of glfw ImGui_ImplGlfw_InstallCallbacks
// will chain the user callbacks with ImGui callbacks; and PostInit()
// is a good place for the user to install callbacks
// will chain the user callbacks with ImGui callbacks;
// and PostInit() is a good place for the user to install callbacks
if (params.callbacks.PostInit_AddPlatformBackendCallbacks)
params.callbacks.PostInit_AddPlatformBackendCallbacks();

Expand Down Expand Up @@ -911,7 +912,10 @@ void AbstractRunner::Setup()

#ifdef HELLOIMGUI_WITH_NETIMGUI
if (params.remoteParams.enableRemoting)
gNetImGuiWrapper = std::make_unique<NetImGuiWrapper>();
{
gNetImGuiWrapper = std::make_unique<NetImGuiWrapper>();
gNetImGuiWrapper->sendFonts();
}
#endif
}

Expand Down Expand Up @@ -1153,6 +1157,13 @@ void AbstractRunner::CreateFramesAndRender()
mRenderingBackendCallbacks->Impl_DestroyFontTexture();
mRenderingBackendCallbacks->Impl_CreateFontTexture();
params.callbacks.LoadAdditionalFonts = nullptr;
#ifdef HELLOIMGUI_WITH_NETIMGUI
if (params.remoteParams.enableRemoting)
{
gNetImGuiWrapper = std::make_unique<NetImGuiWrapper>();
gNetImGuiWrapper->sendFonts();
}
#endif
}
}

Expand Down Expand Up @@ -1245,7 +1256,23 @@ void AbstractRunner::CreateFramesAndRender()

mIdxFrame += 1;

_CheckDpiAwareParamsChanges(params);
if (_CheckDpiAwareParamsChanges(params))
{
// Import _ReloadAllDpiResponsiveFonts from hello_imgui_font.cpp
void _ReloadAllDpiResponsiveFonts();

mRenderingBackendCallbacks->Impl_DestroyFontTexture();
_ReloadAllDpiResponsiveFonts();
// cf https://github.com/ocornut/imgui/issues/6547: we need to recreate the rendering backend device objects
mRenderingBackendCallbacks->Impl_CreateFontTexture();
#ifdef HELLOIMGUI_WITH_NETIMGUI
if (params.remoteParams.enableRemoting)
{
gNetImGuiWrapper = std::make_unique<NetImGuiWrapper>();
gNetImGuiWrapper->sendFonts();
}
#endif
}
}

// Idling for non emscripten, where HelloImGui is responsible for the main loop.
Expand Down

0 comments on commit 963b18c

Please sign in to comment.