From 23dc46c4f8bf6aaf83d70f54441916404bf1aba5 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 31 Mar 2025 19:24:59 +0200 Subject: [PATCH] Fonts: added RemoveCustomRect(). + internally add ImFontAtlasPackReuseRectEntry() --- imgui.h | 1 + imgui_draw.cpp | 29 +++++++++++++++++++---------- imgui_internal.h | 4 ++-- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/imgui.h b/imgui.h index ce5decfa4..a3d70bb98 100644 --- a/imgui.h +++ b/imgui.h @@ -3634,6 +3634,7 @@ struct ImFontAtlas // - AddCustomRectFontGlyph() --> Prefer using custom ImFontLoader inside ImFontConfig // - ImFontAtlasCustomRect --> Renamed to ImFontAtlasRect IMGUI_API ImFontAtlasRectId AddCustomRect(int width, int height); // Register a rectangle. Return -1 (ImFontAtlasRectId_Invalid) on error. + IMGUI_API void RemoveCustomRect(ImFontAtlasRectId id); // Unregister a rectangle. Existing pixels will stay in texture until resized / garbage collected. IMGUI_API bool GetCustomRect(ImFontAtlasRectId id, ImFontAtlasRect* out_r) const; // Get rectangle coordinates for current texture. Valid immediately, never store this (read above)! //------------------------------------------- diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 83db3576b..7cc1351fb 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -2499,8 +2499,10 @@ void ImTextureData::DestroyPixels() // - ImFontAtlasBuildNotifySetFont() //----------------------------------------------------------------------------- // - ImFontAtlas::AddCustomRect() -// - ImFontAtlas::AddCustomRectFontGlyph() +// - ImFontAtlas::RemoveCustomRect() // - ImFontAtlas::GetCustomRect() +// - ImFontAtlas::AddCustomRectFontGlyph() [legacy] +// - ImFontAtlas::AddCustomRectFontGlyphForSize() [legacy] // - ImFontAtlasGetMouseCursorTexData() //----------------------------------------------------------------------------- // - ImFontAtlasBuildMain() @@ -2538,6 +2540,7 @@ void ImTextureData::DestroyPixels() //----------------------------------------------------------------------------- // - ImFontAtlasPackInit() // - ImFontAtlasPackAllocRectEntry() +// - ImFontAtlasPackReuseRectEntry() // - ImFontAtlasPackDiscardRect() // - ImFontAtlasPackAddRect() // - ImFontAtlasPackGetRect() @@ -3239,6 +3242,12 @@ ImFontAtlasRectId ImFontAtlas::AddCustomRect(int width, int height) return r_id; } +void ImFontAtlas::RemoveCustomRect(ImFontAtlasRectId id) +{ + IM_ASSERT(id != ImFontAtlasRectId_Invalid); + ImFontAtlasPackDiscardRect(this, id); +} + #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS // This API does not make sense anymore with scalable fonts. // - Prefer adding a font source (ImFontConfig) using a custom/procedural loader. @@ -4095,7 +4104,7 @@ ImVec2i ImFontAtlasBuildGetTextureSizeEstimate(ImFontAtlas* atlas) return ImVec2i(new_tex_w, new_tex_h); } -// Clear all output. Invalidates all AddCustomRectXXX return values. +// Clear all output. Invalidates all AddCustomRect() return values! void ImFontAtlasBuildClear(ImFontAtlas* atlas) { ImVec2i new_tex_size = ImFontAtlasBuildGetTextureSizeEstimate(atlas); @@ -4237,6 +4246,13 @@ static ImFontAtlasRectId ImFontAtlasPackAllocRectEntry(ImFontAtlas* atlas, int r return (ImFontAtlasRectId)index_idx; } +static ImFontAtlasRectId ImFontAtlasPackReuseRectEntry(ImFontAtlas* atlas, ImFontAtlasRectEntry* overwrite_entry) +{ + IM_ASSERT(overwrite_entry->Used); + overwrite_entry->TargetIndex = atlas->Builder->Rects.Size - 1; + return atlas->Builder->RectsIndex.index_from_ptr(overwrite_entry); +} + // This is expected to be called in batches and followed by a repack void ImFontAtlasPackDiscardRect(ImFontAtlas* atlas, ImFontAtlasRectId id) { @@ -4300,16 +4316,9 @@ ImFontAtlasRectId ImFontAtlasPackAddRect(ImFontAtlas* atlas, int w, int h, ImFon builder->Rects.push_back(r); if (overwrite_entry != NULL) - { - // Write into an existing entry instead of adding one (used during repack) - IM_ASSERT(overwrite_entry->Used); - overwrite_entry->TargetIndex = builder->Rects.Size - 1; - return builder->RectsIndex.index_from_ptr(overwrite_entry); - } + return ImFontAtlasPackReuseRectEntry(atlas, overwrite_entry); // Write into an existing entry instead of adding one (used during repack) else - { return ImFontAtlasPackAllocRectEntry(atlas, builder->Rects.Size - 1); - } } // Important: don'return pointer valid until next call to AddRect(), e.g. FindGlyph(), CalcTextSize() can all potentially invalidate previous pointers. diff --git a/imgui_internal.h b/imgui_internal.h index 7389c0216..0a9961a45 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -3701,8 +3701,8 @@ IMGUI_API const ImFontLoader* ImFontAtlasGetFontLoaderForStbTruetype(); // Having this also makes it easier to e.g. sort rectangles during repack. struct ImFontAtlasRectEntry { - int TargetIndex : 31; // When Used: ImFontAtlasRectId -> into Rects[]. When unused: index to next unused RectsIndex[] slot to consume free-list. - unsigned int Used : 1; + int TargetIndex : 31; // When Used: ImFontAtlasRectId -> into Rects[]. When unused: index to next unused RectsIndex[] slot to consume free-list. + unsigned int Used : 1; }; // Data available to potential texture post-processing functions