1
0
Fork 0
mirror of https://github.com/ocornut/imgui.git synced 2026-01-11 00:04:24 +00:00

Fonts: changing loader/backend or loader flags may be done without losing custom rects. Sharing more code.

This commit is contained in:
ocornut 2025-04-03 19:10:16 +02:00
parent 526a5d0f8a
commit fb5c537080
3 changed files with 61 additions and 49 deletions

View file

@ -15695,9 +15695,16 @@ void ImGui::ShowFontAtlas(ImFontAtlas* atlas)
ImFontAtlasBuildSetupFontLoader(atlas, loader_freetype); ImFontAtlasBuildSetupFontLoader(atlas, loader_freetype);
if (loader_current == loader_freetype) if (loader_current == loader_freetype)
{ {
Text("Shared FreeType Loader Flags:"); unsigned int loader_flags = atlas->FontBuilderFlags;
if (ImGuiFreeType::DebugEditFontBuilderFlags(&atlas->FontBuilderFlags)) Text("Shared FreeType Loader Flags: 0x%08", loader_flags);
ImFontAtlasBuildReloadAll(atlas); if (ImGuiFreeType::DebugEditFontBuilderFlags(&loader_flags))
{
for (ImFont* font : atlas->Fonts)
ImFontAtlasBuildDestroyFontOutput(atlas, font);
atlas->FontBuilderFlags = loader_flags;
for (ImFont* font : atlas->Fonts)
ImFontAtlasBuildInitFontOutput(atlas, font);
}
} }
#else #else
BeginDisabled(); BeginDisabled();
@ -15724,8 +15731,9 @@ void ImGui::ShowFontAtlas(ImFontAtlas* atlas)
if (Button("Grow")) if (Button("Grow"))
ImFontAtlasBuildGrowTexture(atlas); ImFontAtlasBuildGrowTexture(atlas);
SameLine(); SameLine();
if (Button("Clear Output")) if (Button("Clear All"))
ImFontAtlasBuildClear(atlas); ImFontAtlasBuildClear(atlas);
SetItemTooltip("Destroy cache and custom rectangles.");
for (int tex_n = 0; tex_n < atlas->TexList.Size; tex_n++) for (int tex_n = 0; tex_n < atlas->TexList.Size; tex_n++)
{ {
@ -16613,9 +16621,14 @@ void ImGui::DebugNodeFont(ImFont* font)
#ifdef IMGUI_ENABLE_FREETYPE #ifdef IMGUI_ENABLE_FREETYPE
if (loader->Name != NULL && strcmp(loader->Name, "FreeType") == 0) if (loader->Name != NULL && strcmp(loader->Name, "FreeType") == 0)
{ {
Text("FreeType Loader Flags: 0x%08X", src->FontBuilderFlags); unsigned int loader_flags = src->FontBuilderFlags;
if (ImGuiFreeType::DebugEditFontBuilderFlags(&src->FontBuilderFlags)) Text("FreeType Loader Flags: 0x%08X", loader_flags);
ImFontAtlasBuildReloadFont(atlas, src); if (ImGuiFreeType::DebugEditFontBuilderFlags(&loader_flags))
{
ImFontAtlasBuildDestroyFontOutput(atlas, font);
src->FontBuilderFlags = loader_flags;
ImFontAtlasBuildInitFontOutput(atlas, font);
}
} }
#endif #endif
TreePop(); TreePop();

View file

@ -2649,14 +2649,11 @@ void ImFontAtlas::CompactCache()
void ImFontAtlas::ClearInputData() void ImFontAtlas::ClearInputData()
{ {
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!"); IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
for (ImFontConfig& font_cfg : Sources)
{
const ImFontLoader* loader = font_cfg.FontLoader ? font_cfg.FontLoader : FontLoader;
if (loader && loader->FontSrcDestroy != NULL)
loader->FontSrcDestroy(this, &font_cfg);
ImFontAtlasBuildDestroyFontSourceData(this, &font_cfg);
}
for (ImFont* font : Fonts)
ImFontAtlasBuildDestroyFontOutput(this, font);
for (ImFontConfig& font_cfg : Sources)
ImFontAtlasBuildDestroyFontSourceData(this, &font_cfg);
for (ImFont* font : Fonts) for (ImFont* font : Fonts)
{ {
// When clearing this we lose access to the font name and other information used to build the font. // When clearing this we lose access to the font name and other information used to build the font.
@ -3197,15 +3194,9 @@ void ImFontAtlas::RemoveFont(ImFont* font)
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!"); IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
font->ClearOutputData(); font->ClearOutputData();
ImFontAtlasBuildDestroyFontOutput(this, font);
for (int src_n = 0; src_n < font->SourcesCount; src_n++) for (int src_n = 0; src_n < font->SourcesCount; src_n++)
{ ImFontAtlasBuildDestroyFontSourceData(this, &font->Sources[src_n]);
ImFontConfig* src = (ImFontConfig*)(void*)&font->Sources[src_n];
const ImFontLoader* loader = src->FontLoader ? src->FontLoader : FontLoader;
if (loader && loader->FontSrcDestroy != NULL)
loader->FontSrcDestroy(this, src);
if (src->FontData != NULL && src->FontDataOwnedByAtlas)
IM_FREE(src->FontData);
}
bool removed = Fonts.find_erase(font); bool removed = Fonts.find_erase(font);
IM_ASSERT(removed); IM_ASSERT(removed);
@ -3376,15 +3367,19 @@ void ImFontAtlasBuildSetupFontLoader(ImFontAtlas* atlas, const ImFontLoader* fon
return; return;
IM_ASSERT(!atlas->Locked && "Cannot modify a locked ImFontAtlas!"); IM_ASSERT(!atlas->Locked && "Cannot modify a locked ImFontAtlas!");
// Note that texture size estimate is likely incorrect in this situation, as FreeType backend doesn't use oversampling. for (ImFont* font : atlas->Fonts)
ImVec2i new_tex_size = ImFontAtlasBuildGetTextureSizeEstimate(atlas); ImFontAtlasBuildDestroyFontOutput(atlas, font);
ImFontAtlasBuildDestroy(atlas); if (atlas->Builder && atlas->FontLoader && atlas->FontLoader->LoaderShutdown)
atlas->FontLoader->LoaderShutdown(atlas);
atlas->FontLoader = font_loader; atlas->FontLoader = font_loader;
atlas->FontLoaderName = font_loader ? font_loader->Name : "NULL"; atlas->FontLoaderName = font_loader ? font_loader->Name : "NULL";
IM_ASSERT(atlas->FontLoaderData == NULL);
ImFontAtlasBuildAddTexture(atlas, new_tex_size.x, new_tex_size.y); if (atlas->Builder && atlas->FontLoader && atlas->FontLoader->LoaderInit)
ImFontAtlasBuildInit(atlas); atlas->FontLoader->LoaderInit(atlas);
for (ImFont* font : atlas->Fonts)
ImFontAtlasBuildInitFontOutput(atlas, font);
} }
// Preload all glyph ranges for legacy backends. // Preload all glyph ranges for legacy backends.
@ -3562,18 +3557,31 @@ static void ImFontAtlasBuildUpdateLinesTexData(ImFontAtlas* atlas, bool add_and_
//----------------------------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------------------------
void ImFontAtlasBuildReloadAll(ImFontAtlas* atlas) bool ImFontAtlasBuildInitFontOutput(ImFontAtlas* atlas, ImFont* font)
{ {
const ImFontLoader* main_loader = atlas->FontLoader; bool ret = true;
ImFontAtlasBuildSetupFontLoader(atlas, NULL); for (int src_n = 0; src_n < font->SourcesCount; src_n++)
ImFontAtlasBuildSetupFontLoader(atlas, main_loader); {
ImFontConfig* src = &font->Sources[src_n];
const ImFontLoader* loader = src->FontLoader ? src->FontLoader : atlas->FontLoader;
if (loader && loader->FontSrcInit != NULL && !loader->FontSrcInit(atlas, src))
ret = false;
}
IM_ASSERT(ret); // Unclear how to react to this meaningfully. Assume that result will be same as initial AddFont() call.
return ret;
} }
void ImFontAtlasBuildReloadFont(ImFontAtlas* atlas, ImFontConfig* src) // Keep source/input FontData
void ImFontAtlasBuildDestroyFontOutput(ImFontAtlas* atlas, ImFont* font)
{ {
// FIXME-NEWATLAS: rebuild single font not supported yet. font->ClearOutputData();
IM_UNUSED(src); for (int src_n = 0; src_n < font->SourcesCount; src_n++)
ImFontAtlasBuildReloadAll(atlas); {
ImFontConfig* src = &font->Sources[src_n];
const ImFontLoader* loader = src->FontLoader ? src->FontLoader : atlas->FontLoader;
if (loader && loader->FontSrcDestroy != NULL)
loader->FontSrcDestroy(atlas, src);
}
} }
//----------------------------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------------------------
@ -4148,13 +4156,8 @@ void ImFontAtlasBuildInit(ImFontAtlas* atlas)
#else #else
IM_ASSERT(0); // Invalid Build function IM_ASSERT(0); // Invalid Build function
#endif #endif
return; // ImFontAtlasBuildSetupFontLoader() automatically call ImFontAtlasBuildInit()
} }
IM_ASSERT(atlas->FontLoaderData == NULL);
if (atlas->FontLoader->LoaderInit)
atlas->FontLoader->LoaderInit(atlas);
// Create initial texture size // Create initial texture size
if (atlas->TexData == NULL || atlas->TexData->Pixels == NULL) if (atlas->TexData == NULL || atlas->TexData->Pixels == NULL)
ImFontAtlasBuildAddTexture(atlas, ImUpperPowerOfTwo(atlas->TexMinWidth), ImUpperPowerOfTwo(atlas->TexMinHeight)); ImFontAtlasBuildAddTexture(atlas, ImUpperPowerOfTwo(atlas->TexMinWidth), ImUpperPowerOfTwo(atlas->TexMinHeight));
@ -4165,6 +4168,8 @@ void ImFontAtlasBuildInit(ImFontAtlas* atlas)
{ {
IM_ASSERT(atlas->Builder == NULL); IM_ASSERT(atlas->Builder == NULL);
builder = atlas->Builder = IM_NEW(ImFontAtlasBuilder)(); builder = atlas->Builder = IM_NEW(ImFontAtlasBuilder)();
if (atlas->FontLoader->LoaderInit)
atlas->FontLoader->LoaderInit(atlas);
} }
ImFontAtlasBuildUpdateRendererHasTexturesFromContext(atlas); ImFontAtlasBuildUpdateRendererHasTexturesFromContext(atlas);
@ -4193,13 +4198,7 @@ void ImFontAtlasBuildInit(ImFontAtlas* atlas)
void ImFontAtlasBuildDestroy(ImFontAtlas* atlas) void ImFontAtlasBuildDestroy(ImFontAtlas* atlas)
{ {
for (ImFont* font : atlas->Fonts) for (ImFont* font : atlas->Fonts)
font->ClearOutputData(); ImFontAtlasBuildDestroyFontOutput(atlas, font);
for (ImFontConfig& font_cfg : atlas->Sources)
{
const ImFontLoader* loader = font_cfg.FontLoader ? font_cfg.FontLoader : atlas->FontLoader;
if (loader && loader->FontSrcDestroy != NULL)
loader->FontSrcDestroy(atlas, &font_cfg);
}
if (atlas->Builder && atlas->FontLoader && atlas->FontLoader->LoaderShutdown) if (atlas->Builder && atlas->FontLoader && atlas->FontLoader->LoaderShutdown)
{ {
atlas->FontLoader->LoaderShutdown(atlas); atlas->FontLoader->LoaderShutdown(atlas);

View file

@ -3774,9 +3774,9 @@ IMGUI_API bool ImFontAtlasBuildAddFont(ImFontAtlas* atlas, ImFontCo
IMGUI_API void ImFontAtlasBuildSetupFontSpecialGlyphs(ImFontAtlas* atlas, ImFont* font, ImFontConfig* src); IMGUI_API void ImFontAtlasBuildSetupFontSpecialGlyphs(ImFontAtlas* atlas, ImFont* font, ImFontConfig* src);
IMGUI_API void ImFontAtlasBuildPreloadAllGlyphRanges(ImFontAtlas* atlas); // Legacy IMGUI_API void ImFontAtlasBuildPreloadAllGlyphRanges(ImFontAtlas* atlas); // Legacy
IMGUI_API void ImFontAtlasBuildGetOversampleFactors(ImFontConfig* src, float size, int* out_oversample_h, int* out_oversample_v); IMGUI_API void ImFontAtlasBuildGetOversampleFactors(ImFontConfig* src, float size, int* out_oversample_h, int* out_oversample_v);
IMGUI_API bool ImFontAtlasBuildInitFontOutput(ImFontAtlas* atlas, ImFont* font); // Using DestroyFontOutput/InitFontOutput sequence useful notably if font loader params have changed
IMGUI_API void ImFontAtlasBuildDestroyFontOutput(ImFontAtlas* atlas, ImFont* font);
IMGUI_API void ImFontAtlasBuildDestroyFontSourceData(ImFontAtlas* atlas, ImFontConfig* src); IMGUI_API void ImFontAtlasBuildDestroyFontSourceData(ImFontAtlas* atlas, ImFontConfig* src);
IMGUI_API void ImFontAtlasBuildReloadAll(ImFontAtlas* atlas); // Reinit/rebuild, notably if font loader params have changed.
IMGUI_API void ImFontAtlasBuildReloadFont(ImFontAtlas* atlas, ImFontConfig* src); // Reinit/rebuild, notably if font loader params have changed.
IMGUI_API ImFontBaked* ImFontAtlasBuildAddFontBaked(ImFontAtlas* atlas, ImFont* font, float font_size, ImGuiID baked_id); IMGUI_API ImFontBaked* ImFontAtlasBuildAddFontBaked(ImFontAtlas* atlas, ImFont* font, float font_size, ImGuiID baked_id);
IMGUI_API ImFontBaked* ImFontAtlasBuildGetClosestFontBakedMatch(ImFontAtlas* atlas, ImFont* font, float font_size); IMGUI_API ImFontBaked* ImFontAtlasBuildGetClosestFontBakedMatch(ImFontAtlas* atlas, ImFont* font, float font_size);