Skip to content

Commit

Permalink
callbacks.LoadAdditionalFonts can be re-used during execution
Browse files Browse the repository at this point in the history
  • Loading branch information
pthom committed Mar 18, 2024
1 parent 910f93f commit 0e8fa03
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 18 deletions.
11 changes: 5 additions & 6 deletions src/hello_imgui/doc_params.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,11 +313,10 @@ struct RunnerCallbacks
void EnqueuePostInit(const VoidFunction& callback);
// `LoadAdditionalFonts`: default=_LoadDefaultFont_WithFontAwesome*.
// A function that is called once, when fonts are ready to be loaded.
// By default, _LoadDefaultFont_WithFontAwesome_ is called,
// but you can copy and customize it.
// (LoadDefaultFont_WithFontAwesome will load fonts from assets/fonts/
// but reverts to the ImGui embedded font if not found)
// A function that is called in order to load fonts.
// `LoadAdditionalFonts` will be called once, then *set to nullptr*.
// If you want to load additional fonts, during the app execution, you can
// set LoadAdditionalFonts to a function that will load the additional fonts.
VoidFunction LoadAdditionalFonts = (VoidFunction)ImGuiDefaultSettings::LoadDefaultFont_WithFontAwesomeIcons;
// If LoadAdditionalFonts==LoadDefaultFont_WithFontAwesomeIcons, this parameter control
// which icon font will be loaded by default.
Expand Down Expand Up @@ -361,7 +360,7 @@ struct RunnerCallbacks
// `PreNewFrame`: You can here add a function that will be called at each frame,
// and before the call to ImGui::NewFrame().
// It is a good place to dynamically add new fonts, or new dockable windows.
// It is a good place to add new dockable windows.
VoidFunction PreNewFrame = EmptyVoidFunction();
// `BeforeImGuiRender`: You can here add a function that will be called at each frame,
Expand Down
35 changes: 30 additions & 5 deletions src/hello_imgui/internal/backend_impls/abstract_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,18 @@
//



namespace HelloImGui
{
// Encapsulated inside hello_imgui_screenshot.cpp
void setFinalAppWindowScreenshotRgbBuffer(const ImageBuffer& b);


// Only used with OpenGL if the font loading failed at first frame
// (used by ReloadFontIfFailed_OpenGL(), which should ideally by suppressed)
VoidFunction gInitialFontLoadingFunction = nullptr;


AbstractRunner::AbstractRunner(RunnerParams &params_)
: params(params_) {}

Expand All @@ -76,19 +82,19 @@ AbstractRunner::AbstractRunner(RunnerParams &params_)
// size for a crisper rendering) and try to reload the fonts.
// This only works if the user provided callback LoadAdditionalFonts() uses DpiFontLoadingFactor()
// to multiply its font size.
void AbstractRunner::ReloadFontIfFailed() const
void AbstractRunner::ReloadFontIfFailed_OpenGL() const
{
fprintf(stderr, "Detected a potential font loading error! You might try to reduce the number of loaded fonts and/or their size!\n");
#ifdef HELLOIMGUI_HAS_OPENGL
if (ImGui::GetIO().FontGlobalScale < 1.f)
if (ImGui::GetIO().FontGlobalScale < 1.f && gInitialFontLoadingFunction)
{
fprintf(stderr,
"Trying to solve the font loading error by changing ImGui::GetIO().FontGlobalScale from %f to 1.f! Font rendering might be less crisp...\n",
ImGui::GetIO().FontGlobalScale
);
ImGui::GetIO().FontGlobalScale = 1.f;
ImGui::GetIO().Fonts->Clear();
params.callbacks.LoadAdditionalFonts();
gInitialFontLoadingFunction();
ImGui::GetIO().Fonts->Build();
ImGui_ImplOpenGL3_CreateFontsTexture();
}
Expand Down Expand Up @@ -662,10 +668,13 @@ void AbstractRunner::Setup()
//
// load fonts & set ImGui::GetIO().FontGlobalScale
//
ImGui::GetIO().Fonts->Clear();

// LoadAdditionalFonts will load fonts and resize them by 1./FontGlobalScale
// (if and only if it uses HelloImGui::LoadFontTTF instead of ImGui's font loading functions)
ImGui::GetIO().Fonts->Clear();
gInitialFontLoadingFunction = params.callbacks.LoadAdditionalFonts;
params.callbacks.LoadAdditionalFonts();
params.callbacks.LoadAdditionalFonts = nullptr;
bool buildSuccess = ImGui::GetIO().Fonts->Build();
IM_ASSERT(buildSuccess && "ImGui::GetIO().Fonts->Build() failed!");
{
Expand Down Expand Up @@ -905,6 +914,19 @@ void AbstractRunner::CreateFramesAndRender()
#endif
} // SCOPED_RELEASE_GIL_ON_MAIN_THREAD end

if (true_gil) // Load additional fonts during execution
{
if (params.callbacks.LoadAdditionalFonts != nullptr)
{
params.callbacks.LoadAdditionalFonts();
ImGui::GetIO().Fonts->Build();
// cf https://github.com/ocornut/imgui/issues/6547
// We need to recreate the rendering backend device objects
mRenderingBackendCallbacks->Impl_DestroyFontTexture();
mRenderingBackendCallbacks->Impl_CreateFontTexture();
params.callbacks.LoadAdditionalFonts = nullptr;
}
}

//
// Rendering logic
Expand Down Expand Up @@ -950,7 +972,10 @@ void AbstractRunner::CreateFramesAndRender()
{
auto error = glGetError();
if (error != 0)
{
fprintf(stderr, "OpenGL error detected on first frame: %d. Will try to reload font without scaling\n", error);
foundPotentialFontLoadingError = true;
}
}
}
#endif
Expand Down Expand Up @@ -997,7 +1022,7 @@ void AbstractRunner::CreateFramesAndRender()
#endif

if (foundPotentialFontLoadingError)
ReloadFontIfFailed();
ReloadFontIfFailed_OpenGL();

mIdxFrame += 1;
}
Expand Down
2 changes: 1 addition & 1 deletion src/hello_imgui/internal/backend_impls/abstract_runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class AbstractRunner
void SetupDpiAwareParams();
void PrepareWindowGeometry();
void HandleDpiOnSecondFrame();
void ReloadFontIfFailed() const;
void ReloadFontIfFailed_OpenGL() const;
void MakeWindowSizeRelativeTo96Ppi_IfRequired();
bool ShallSizeWindowRelativeTo96Ppi();
bool WantAutoSize();
Expand Down
3 changes: 3 additions & 0 deletions src/hello_imgui/internal/backend_impls/rendering_callbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ namespace HelloImGui
VoidFunction Impl_Shutdown_3D = [] { HIMG_ERROR("Empty function"); };
std::function<ImageBuffer()> Impl_ScreenshotRgb_3D = [] { return ImageBuffer{}; };
std::function<ScreenSize()> Impl_GetFrameBufferSize; //= [] { return ScreenSize{0, 0}; };

VoidFunction Impl_DestroyFontTexture = [] { HIMG_ERROR("Empty function"); };
VoidFunction Impl_CreateFontTexture = [] { HIMG_ERROR("Empty function"); };
};

using RenderingCallbacksPtr = std::shared_ptr<RenderingCallbacks>;
Expand Down
3 changes: 3 additions & 0 deletions src/hello_imgui/internal/backend_impls/rendering_dx11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ namespace HelloImGui

// callbacks->Impl_GetFrameBufferSize; //= [] { return ScreenSize{0, 0}; };

callbacks->Impl_CreateFontTexture = ImGui_ImplDX11_CreateFontsTexture;
callbacks->Impl_DestroyFontTexture = ImGui_ImplDX11_DestroyFontsTexture;

return callbacks;
}

Expand Down
3 changes: 3 additions & 0 deletions src/hello_imgui/internal/backend_impls/rendering_dx12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,9 @@ namespace HelloImGui
// callbacks->Impl_ScreenshotRgb_3D = [] { return ImageBuffer{}; };
// callbacks->Impl_GetFrameBufferSize; //= [] { return ScreenSize{0, 0}; };

callbacks->Impl_CreateFontTexture = ImGui_ImplDX12_CreateFontsTexture;
callbacks->Impl_DestroyFontTexture = ImGui_ImplDX12_DestroyFontsTexture;


return callbacks;
}
Expand Down
7 changes: 7 additions & 0 deletions src/hello_imgui/internal/backend_impls/rendering_metal.mm
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ RenderingCallbacksPtr PrepareBackendCallbacksCommon()
ImGui_ImplMetal_Shutdown();
};

callbacks->Impl_CreateFontTexture = []
{
auto& gMetalGlobals = GetMetalGlobals();
ImGui_ImplMetal_CreateFontsTexture(gMetalGlobals.mtlDevice);
};
callbacks->Impl_DestroyFontTexture = ImGui_ImplMetal_DestroyFontsTexture;

return callbacks;
}

Expand Down
3 changes: 3 additions & 0 deletions src/hello_imgui/internal/backend_impls/rendering_opengl3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ namespace HelloImGui
ImGui_ImplOpenGL3_Shutdown();
};

callbacks->Impl_CreateFontTexture = ImGui_ImplOpenGL3_CreateFontsTexture;
callbacks->Impl_DestroyFontTexture = ImGui_ImplOpenGL3_DestroyFontsTexture;

return callbacks;
}

Expand Down
3 changes: 3 additions & 0 deletions src/hello_imgui/internal/backend_impls/rendering_vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ namespace HelloImGui
// callbacks->Impl_ScreenshotRgb_3D = [] { return ImageBuffer{}; };
// callbacks->Impl_GetFrameBufferSize; //= [] { return ScreenSize{0, 0}; };

callbacks->Impl_CreateFontTexture = ImGui_ImplVulkan_CreateFontsTexture;
callbacks->Impl_DestroyFontTexture = ImGui_ImplVulkan_DestroyFontsTexture;


return callbacks;
}
Expand Down
11 changes: 5 additions & 6 deletions src/hello_imgui/runner_callbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,10 @@ struct RunnerCallbacks
void EnqueuePostInit(const VoidFunction& callback);

// `LoadAdditionalFonts`: default=_LoadDefaultFont_WithFontAwesome*.
// A function that is called once, when fonts are ready to be loaded.
// By default, _LoadDefaultFont_WithFontAwesome_ is called,
// but you can copy and customize it.
// (LoadDefaultFont_WithFontAwesome will load fonts from assets/fonts/
// but reverts to the ImGui embedded font if not found)
// A function that is called in order to load fonts.
// `LoadAdditionalFonts` will be called once, then *set to nullptr*.
// If you want to load additional fonts, during the app execution, you can
// set LoadAdditionalFonts to a function that will load the additional fonts.
VoidFunction LoadAdditionalFonts = (VoidFunction)ImGuiDefaultSettings::LoadDefaultFont_WithFontAwesomeIcons;
// If LoadAdditionalFonts==LoadDefaultFont_WithFontAwesomeIcons, this parameter control
// which icon font will be loaded by default.
Expand Down Expand Up @@ -231,7 +230,7 @@ struct RunnerCallbacks

// `PreNewFrame`: You can here add a function that will be called at each frame,
// and before the call to ImGui::NewFrame().
// It is a good place to dynamically add new fonts, or new dockable windows.
// It is a good place to add new dockable windows.
VoidFunction PreNewFrame = EmptyVoidFunction();

// `BeforeImGuiRender`: You can here add a function that will be called at each frame,
Expand Down

0 comments on commit 0e8fa03

Please sign in to comment.