mirror of
https://github.com/ocornut/imgui.git
synced 2025-09-05 19:08:19 +00:00
Fonts: fixed support for multiple atlases.
Moved FontAtlasOwnedByContext to OwnerContext # Conflicts: # imgui.cpp # imgui_internal.h
This commit is contained in:
91
imgui.cpp
91
imgui.cpp
@@ -3962,13 +3962,13 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas)
|
|||||||
InputTextState.Ctx = this;
|
InputTextState.Ctx = this;
|
||||||
|
|
||||||
Initialized = false;
|
Initialized = false;
|
||||||
FontAtlasOwnedByContext = shared_font_atlas ? false : true;
|
|
||||||
Font = NULL;
|
Font = NULL;
|
||||||
FontBaked = NULL;
|
FontBaked = NULL;
|
||||||
FontSize = FontSizeBeforeScaling = FontScale = CurrentDpiScale = 0.0f;
|
FontSize = FontSizeBeforeScaling = FontScale = CurrentDpiScale = 0.0f;
|
||||||
FontRasterizerDensity = 1.0f;
|
FontRasterizerDensity = 1.0f;
|
||||||
IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)();
|
IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)();
|
||||||
IO.Fonts->RefCount++;
|
if (shared_font_atlas == NULL)
|
||||||
|
IO.Fonts->OwnerContext = this;
|
||||||
Time = 0.0f;
|
Time = 0.0f;
|
||||||
FrameCount = 0;
|
FrameCount = 0;
|
||||||
FrameCountEnded = FrameCountRendered = -1;
|
FrameCountEnded = FrameCountRendered = -1;
|
||||||
@@ -4226,8 +4226,9 @@ void ImGui::Initialize()
|
|||||||
|
|
||||||
// ImDrawList/ImFontAtlas are designed to function without ImGui, and 99% of it works without an ImGui context.
|
// ImDrawList/ImFontAtlas are designed to function without ImGui, and 99% of it works without an ImGui context.
|
||||||
// But this link allows us to facilitate/handle a few edge cases better.
|
// But this link allows us to facilitate/handle a few edge cases better.
|
||||||
|
ImFontAtlas* atlas = g.IO.Fonts;
|
||||||
g.DrawListSharedData.Context = &g;
|
g.DrawListSharedData.Context = &g;
|
||||||
ImFontAtlasAddDrawListSharedData(g.IO.Fonts, &g.DrawListSharedData);
|
RegisterFontAtlas(atlas);
|
||||||
|
|
||||||
g.Initialized = true;
|
g.Initialized = true;
|
||||||
}
|
}
|
||||||
@@ -4240,17 +4241,15 @@ void ImGui::Shutdown()
|
|||||||
IM_ASSERT_USER_ERROR(g.IO.BackendRendererUserData == NULL, "Forgot to shutdown Renderer backend?");
|
IM_ASSERT_USER_ERROR(g.IO.BackendRendererUserData == NULL, "Forgot to shutdown Renderer backend?");
|
||||||
|
|
||||||
// The fonts atlas can be used prior to calling NewFrame(), so we clear it even if g.Initialized is FALSE (which would happen if we never called NewFrame)
|
// The fonts atlas can be used prior to calling NewFrame(), so we clear it even if g.Initialized is FALSE (which would happen if we never called NewFrame)
|
||||||
if (ImFontAtlas* atlas = g.IO.Fonts)
|
for (ImFontAtlas* atlas : g.FontAtlases)
|
||||||
{
|
{
|
||||||
ImFontAtlasRemoveDrawListSharedData(atlas, &g.DrawListSharedData);
|
UnregisterFontAtlas(atlas);
|
||||||
atlas->RefCount--;
|
if (atlas->OwnerContext == &g)
|
||||||
if (g.FontAtlasOwnedByContext)
|
|
||||||
{
|
{
|
||||||
atlas->Locked = false;
|
atlas->Locked = false;
|
||||||
IM_DELETE(atlas);
|
IM_DELETE(atlas);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g.IO.Fonts = NULL;
|
|
||||||
g.DrawListSharedData.TempBuffer.clear();
|
g.DrawListSharedData.TempBuffer.clear();
|
||||||
|
|
||||||
// Cleanup of other data are conditional on actually having initialized Dear ImGui.
|
// Cleanup of other data are conditional on actually having initialized Dear ImGui.
|
||||||
@@ -4412,7 +4411,8 @@ void ImGui::GcCompactTransientMiscBuffers()
|
|||||||
g.MultiSelectTempDataStacked = 0;
|
g.MultiSelectTempDataStacked = 0;
|
||||||
g.MultiSelectTempData.clear_destruct();
|
g.MultiSelectTempData.clear_destruct();
|
||||||
TableGcCompactSettings();
|
TableGcCompactSettings();
|
||||||
g.IO.Fonts->CompactCache();
|
for (ImFontAtlas* atlas : g.FontAtlases)
|
||||||
|
atlas->CompactCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free up/compact internal window buffers, we can use this when a window becomes unused.
|
// Free up/compact internal window buffers, we can use this when a window becomes unused.
|
||||||
@@ -5210,29 +5210,27 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags(const ImVec2& mouse_pos)
|
|||||||
static void ImGui::UpdateTexturesNewFrame()
|
static void ImGui::UpdateTexturesNewFrame()
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImFontAtlas* atlas = g.IO.Fonts;
|
for (ImFontAtlas* atlas : g.FontAtlases)
|
||||||
if (g.FontAtlasOwnedByContext)
|
if (atlas->OwnerContext == &g)
|
||||||
{
|
{
|
||||||
atlas->RendererHasTextures = (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasTextures) != 0;
|
atlas->RendererHasTextures = (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasTextures) != 0;
|
||||||
ImFontAtlasUpdateNewFrame(atlas, g.FrameCount);
|
ImFontAtlasUpdateNewFrame(atlas, g.FrameCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build a single texture list
|
// Build a single texture list
|
||||||
// We want to avoid user reading from atlas->TexList[] in order to facilitate better support for multiple atlases.
|
|
||||||
static void ImGui::UpdateTexturesEndFrame()
|
static void ImGui::UpdateTexturesEndFrame()
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImFontAtlas* atlas = g.IO.Fonts;
|
|
||||||
g.PlatformIO.Textures.resize(0);
|
g.PlatformIO.Textures.resize(0);
|
||||||
g.PlatformIO.Textures.reserve(atlas->TexList.Size);
|
for (ImFontAtlas* atlas : g.FontAtlases)
|
||||||
for (ImTextureData* tex : atlas->TexList)
|
for (ImTextureData* tex : atlas->TexList)
|
||||||
{
|
{
|
||||||
// We provide this information so backends can decide whether to destroy textures.
|
// We provide this information so backends can decide whether to destroy textures.
|
||||||
// This means in practice that if N imgui contexts are created with a shared atlas, we assume all of them have a backend initialized.
|
// This means in practice that if N imgui contexts are created with a shared atlas, we assume all of them have a backend initialized.
|
||||||
tex->RefCount = (unsigned short)atlas->RefCount;
|
tex->RefCount = (unsigned short)atlas->RefCount;
|
||||||
g.PlatformIO.Textures.push_back(tex);
|
g.PlatformIO.Textures.push_back(tex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called once a frame. Followed by SetCurrentFont() which sets up the remaining data.
|
// Called once a frame. Followed by SetCurrentFont() which sets up the remaining data.
|
||||||
@@ -5810,8 +5808,8 @@ void ImGui::EndFrame()
|
|||||||
UpdateTexturesEndFrame();
|
UpdateTexturesEndFrame();
|
||||||
|
|
||||||
// Unlock font atlas
|
// Unlock font atlas
|
||||||
ImFontAtlas* atlas = g.IO.Fonts;
|
for (ImFontAtlas* atlas : g.FontAtlases)
|
||||||
atlas->Locked = false;
|
atlas->Locked = false;
|
||||||
|
|
||||||
// Clear Input data for next frame
|
// Clear Input data for next frame
|
||||||
g.IO.MousePosPrev = g.IO.MousePos;
|
g.IO.MousePosPrev = g.IO.MousePos;
|
||||||
@@ -5890,7 +5888,8 @@ void ImGui::Render()
|
|||||||
|
|
||||||
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
||||||
if (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasTextures)
|
if (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasTextures)
|
||||||
ImFontAtlasDebugLogTextureRequests(g.IO.Fonts);
|
for (ImFontAtlas* atlas : g.FontAtlases)
|
||||||
|
ImFontAtlasDebugLogTextureRequests(atlas);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CallContextHooks(&g, ImGuiContextHookType_RenderPost);
|
CallContextHooks(&g, ImGuiContextHookType_RenderPost);
|
||||||
@@ -8596,9 +8595,9 @@ bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max)
|
|||||||
void ImGui::UpdateFontsNewFrame()
|
void ImGui::UpdateFontsNewFrame()
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImFontAtlas* atlas = g.IO.Fonts;
|
|
||||||
if ((g.IO.BackendFlags & ImGuiBackendFlags_RendererHasTextures) == 0)
|
if ((g.IO.BackendFlags & ImGuiBackendFlags_RendererHasTextures) == 0)
|
||||||
atlas->Locked = true;
|
for (ImFontAtlas* atlas : g.FontAtlases)
|
||||||
|
atlas->Locked = true;
|
||||||
|
|
||||||
// We do this really unusual thing of calling *push_front()*, the reason behind that we want to support the PushFont()/NewFrame()/PopFont() idiom.
|
// We do this really unusual thing of calling *push_front()*, the reason behind that we want to support the PushFont()/NewFrame()/PopFont() idiom.
|
||||||
ImFontStackData font_stack_data = { ImGui::GetDefaultFont(), ImGui::GetDefaultFont()->DefaultSize };
|
ImFontStackData font_stack_data = { ImGui::GetDefaultFont(), ImGui::GetDefaultFont()->DefaultSize };
|
||||||
@@ -8614,6 +8613,25 @@ void ImGui::UpdateFontsEndFrame()
|
|||||||
PopFont();
|
PopFont();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImGui::RegisterFontAtlas(ImFontAtlas* atlas)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
if (g.FontAtlases.Size == 0)
|
||||||
|
IM_ASSERT(atlas == g.IO.Fonts);
|
||||||
|
atlas->RefCount++;
|
||||||
|
g.FontAtlases.push_back(atlas);
|
||||||
|
ImFontAtlasAddDrawListSharedData(atlas, &g.DrawListSharedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui::UnregisterFontAtlas(ImFontAtlas* atlas)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
IM_ASSERT(atlas->RefCount > 0);
|
||||||
|
ImFontAtlasRemoveDrawListSharedData(atlas, &g.DrawListSharedData);
|
||||||
|
g.FontAtlases.find_erase(atlas);
|
||||||
|
atlas->RefCount--;
|
||||||
|
}
|
||||||
|
|
||||||
// Use ImDrawList::_SetTexture(), making our shared g.FontStack[] authoritative against window-local ImDrawList.
|
// Use ImDrawList::_SetTexture(), making our shared g.FontStack[] authoritative against window-local ImDrawList.
|
||||||
// - Whereas ImDrawList::PushTexture()/PopTexture() is not to be used across Begin() calls.
|
// - Whereas ImDrawList::PushTexture()/PopTexture() is not to be used across Begin() calls.
|
||||||
// - Note that we don't propagate current texture id when e.g. Begin()-ing into a new window, we never really did...
|
// - Note that we don't propagate current texture id when e.g. Begin()-ing into a new window, we never really did...
|
||||||
@@ -8670,6 +8688,7 @@ void ImGui::UpdateCurrentFontSize()
|
|||||||
void ImGui::SetFontRasterizerDensity(float rasterizer_density)
|
void ImGui::SetFontRasterizerDensity(float rasterizer_density)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
IM_ASSERT(g.IO.BackendFlags & ImGuiBackendFlags_RendererHasTextures);
|
||||||
if (g.FontRasterizerDensity == rasterizer_density)
|
if (g.FontRasterizerDensity == rasterizer_density)
|
||||||
return;
|
return;
|
||||||
g.FontRasterizerDensity = rasterizer_density;
|
g.FontRasterizerDensity = rasterizer_density;
|
||||||
@@ -16104,12 +16123,12 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Details for Fonts
|
// Details for Fonts
|
||||||
ImFontAtlas* atlas = g.IO.Fonts;
|
for (ImFontAtlas* atlas : g.FontAtlases)
|
||||||
if (TreeNode("Fonts", "Fonts (%d), Textures (%d)", atlas->Fonts.Size, atlas->TexList.Size))
|
if (TreeNode((void*)atlas, "Fonts (%d), Textures (%d)", atlas->Fonts.Size, atlas->TexList.Size))
|
||||||
{
|
{
|
||||||
ShowFontAtlas(atlas);
|
ShowFontAtlas(atlas);
|
||||||
TreePop();
|
TreePop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Details for Popups
|
// Details for Popups
|
||||||
if (TreeNode("Popups", "Popups (%d)", g.OpenPopupStack.Size))
|
if (TreeNode("Popups", "Popups (%d)", g.OpenPopupStack.Size))
|
||||||
|
1
imgui.h
1
imgui.h
@@ -3684,6 +3684,7 @@ struct ImFontAtlas
|
|||||||
void* FontLoaderData; // Font backend opaque storage
|
void* FontLoaderData; // Font backend opaque storage
|
||||||
unsigned int FontBuilderFlags; // [FIXME: Should be called FontLoaderFlags] Shared flags (for all fonts) for font loader. THIS IS BUILD IMPLEMENTATION DEPENDENT (e.g. . Per-font override is also available in ImFontConfig.
|
unsigned int FontBuilderFlags; // [FIXME: Should be called FontLoaderFlags] Shared flags (for all fonts) for font loader. THIS IS BUILD IMPLEMENTATION DEPENDENT (e.g. . Per-font override is also available in ImFontConfig.
|
||||||
int RefCount; // Number of contexts using this atlas
|
int RefCount; // Number of contexts using this atlas
|
||||||
|
ImGuiContext* OwnerContext; // Context which own the atlas will be in charge of updating and destroying it.
|
||||||
|
|
||||||
// [Obsolete]
|
// [Obsolete]
|
||||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
|
@@ -2132,10 +2132,10 @@ struct ImGuiContextHook
|
|||||||
struct ImGuiContext
|
struct ImGuiContext
|
||||||
{
|
{
|
||||||
bool Initialized;
|
bool Initialized;
|
||||||
bool FontAtlasOwnedByContext; // IO.Fonts-> is owned by the ImGuiContext and will be destructed along with it.
|
|
||||||
ImGuiIO IO;
|
ImGuiIO IO;
|
||||||
ImGuiPlatformIO PlatformIO;
|
ImGuiPlatformIO PlatformIO;
|
||||||
ImGuiStyle Style;
|
ImGuiStyle Style;
|
||||||
|
ImVector<ImFontAtlas*> FontAtlases; // List of font atlases used by the context (generally only contains g.IO.Fonts aka the main font atlas)
|
||||||
ImFont* Font; // == FontStack.back().Font
|
ImFont* Font; // == FontStack.back().Font
|
||||||
ImFontBaked* FontBaked; // == Font->GetFontBaked(FontSize)
|
ImFontBaked* FontBaked; // == Font->GetFontBaked(FontSize)
|
||||||
float FontSize; // == FontSizeBeforeScaling * io.FontGlobalScale * font->Scale * g.CurrentWindow->FontWindowScale. Current text height.
|
float FontSize; // == FontSizeBeforeScaling * io.FontGlobalScale * font->Scale * g.CurrentWindow->FontWindowScale. Current text height.
|
||||||
@@ -3108,6 +3108,8 @@ namespace ImGui
|
|||||||
IMGUI_API void SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags flags);
|
IMGUI_API void SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags flags);
|
||||||
|
|
||||||
// Fonts, drawing
|
// Fonts, drawing
|
||||||
|
IMGUI_API void RegisterFontAtlas(ImFontAtlas* atlas);
|
||||||
|
IMGUI_API void UnregisterFontAtlas(ImFontAtlas* atlas);
|
||||||
IMGUI_API void SetCurrentFont(ImFont* font, float font_size);
|
IMGUI_API void SetCurrentFont(ImFont* font, float font_size);
|
||||||
IMGUI_API void SetFontRasterizerDensity(float rasterizer_density);
|
IMGUI_API void SetFontRasterizerDensity(float rasterizer_density);
|
||||||
inline float GetFontRasterizerDensity() { return GImGui->FontRasterizerDensity; }
|
inline float GetFontRasterizerDensity() { return GImGui->FontRasterizerDensity; }
|
||||||
|
Reference in New Issue
Block a user