WIP - Comments, remove ImFontAtlas facing BuildGrowTexture(), BuildCompactTexture(). Make IsBuilt() obsolete.

This commit is contained in:
ocornut 2025-01-13 20:03:09 +01:00
parent e3625d0fcd
commit 70b4e9150f
4 changed files with 58 additions and 76 deletions

View file

@ -5337,7 +5337,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags(const ImVec2& mouse_pos)
static void ImGui::UpdateTexturesNewFrame()
{
// FIXME-NEWATLAS: How to reach/target all atlas?
// FIXME-NEWATLAS-V2: If we aim to support multiple atlases used by same context: how to reach/target all atlases?
ImGuiContext& g = *GImGui;
ImFontAtlas* atlas = g.IO.Fonts;
if (g.FontAtlasOwnedByContext)
@ -8501,7 +8501,7 @@ void ImGui::SetCurrentFont(ImFont* font)
// - The right-ish solution may be to remove _SetTextureID() and make AddText/RenderText lazily call PushTextureID()/PopTextureID()
// the same way AddImage() does, but then all other primitives would also need to? I don't think we should tackle this problem
// because we have a concrete need and a test bed for multiple atlas textures.
// FIXME-NEWATLAS: perhaps we can now leverage ImFontAtlasUpdateDrawListsTextures() ?
// FIXME-NEWATLAS-V2: perhaps we can now leverage ImFontAtlasUpdateDrawListsTextures() ?
void ImGui::PushFont(ImFont* font)
{
ImGuiContext& g = *GImGui;

View file

@ -3436,6 +3436,7 @@ struct ImDrawData
//-----------------------------------------------------------------------------
// We intentionally support a limited amount of texture formats to limit burden on CPU-side code and extension.
// Most standard backends only support RGBA32 but we provide a single channel option for low-resource/embedded systems.
enum ImTextureFormat
{
ImTextureFormat_RGBA32, // 4 components per pixel, each is unsigned 8-bit. Total size = TexWidth * TexHeight * 4
@ -3620,16 +3621,14 @@ struct ImFontAtlas
IMGUI_API ImFont* AddFontFromMemoryCompressedBase85TTF(const char* compressed_font_data_base85, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data_base85' still owned by caller. Compress with binary_to_compressed_c.cpp with -base85 parameter.
IMGUI_API void RemoveFont(ImFont* font);
// FIXME-NEWATLAS: Clarify meaning/purpose
IMGUI_API void Clear(); // Clear everything (input fonts, output glyphs/textures)
IMGUI_API void ClearCache(); // Clear cached glyphs and textures.
// As we are transitioning toward a new font system, we expect to obsolete those soon:
IMGUI_API void ClearInputData(); // [OBSOLETE] Clear input data (all ImFontConfig structures including sizes, TTF data, glyph ranges, etc.) = all the data used to build the texture and fonts.
IMGUI_API void ClearFonts(); // [OBSOLETE] Clear input+output font data (same as ClearInputData() + glyphs storage, UV coordinates).
IMGUI_API void ClearTexData(); // [OBSOLETE] Clear output texture data (CPU side). Saves RAM once the texture has been copied to graphics memory.
IMGUI_API void BuildGrowTexture();
IMGUI_API void BuildCompactTexture();
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// Build atlas, retrieve pixel data.
// User is in charge of copying the pixels into graphics memory (e.g. create a texture with your engine). Then store your texture handle with SetTexID().
@ -3641,8 +3640,8 @@ struct ImFontAtlas
IMGUI_API void GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 4 bytes-per-pixel
void SetTexID(ImTextureID id) { TexRef._TexData = NULL; TexRef._TexID = id; } // Called by legacy backends.
void SetTexID(ImTextureRef id) { TexRef = id; } // Called by legacy backends.
bool IsBuilt() const { return Fonts.Size > 0 && TexIsBuilt; } // Bit ambiguous: used to detect when user didn't build texture but effectively we should check TexID != 0 except that would be backend dependent...
#endif
bool IsBuilt() const { return Fonts.Size > 0 && TexIsBuilt; } // Bit ambiguous: used to detect when user didn't build texture but effectively we should check TexID != 0 except that would be backend dependent...
//-------------------------------------------
// Glyph Ranges
@ -3786,7 +3785,7 @@ struct ImFont
IMGUI_API void BuildClearGlyphs();
};
// FIXME-NEWATLAS: Added indirection to avoid patching ImDrawCmd after texture updates.
// Added indirection to avoid patching ImDrawCmd after texture updates.
inline ImTextureID ImDrawCmd::GetTexID() const
{
ImTextureID tex_id = TexRef._TexData ? TexRef._TexData->TexID : TexRef._TexID;

View file

@ -2453,16 +2453,14 @@ void ImTextureData::DestroyPixels()
// [SECTION] ImFontAtlas, ImFontAtlasBuilder
//-----------------------------------------------------------------------------
// - Default texture data encoded in ASCII
// - ImFontAtlasBuilder
// - ImFontAtlas()
// - ImFontAtlas::Clear()
// - ImFontAtlas::ClearCache()
// - ImFontAtlas::ClearInputData()
// - ImFontAtlas::ClearTexData()
// - ImFontAtlas::ClearFonts()
// - ImFontAtlas::Clear()
// - ImFontAtlas::ClearCache()
// - ImFontAtlas::BuildGrowTexture()
// - ImFontAtlas::BuildCompactTexture()
// - ImFontAtlasUpdateTextures()
//-----------------------------------------------------------------------------
// - ImFontAtlasUpdateNewFrame()
// - ImFontAtlasTextureBlockConvert()
// - ImFontAtlasTextureBlockPostProcess()
// - ImFontAtlasTextureBlockPostProcessMultiply()
@ -2470,9 +2468,9 @@ void ImTextureData::DestroyPixels()
// - ImFontAtlasTextureBlockCopy()
// - ImFontAtlasTextureBlockQueueUpload()
//-----------------------------------------------------------------------------
// - ImFontAtlas::Build() [legacy]
// - ImFontAtlas::GetTexDataAsAlpha8() [legacy]
// - ImFontAtlas::GetTexDataAsRGBA32() [legacy]
// - ImFontAtlas::Build() [legacy]
//-----------------------------------------------------------------------------
// - ImFontAtlas::AddFont()
// - ImFontAtlas::AddFontDefault()
@ -2485,6 +2483,7 @@ void ImTextureData::DestroyPixels()
//-----------------------------------------------------------------------------
// - ImFontAtlas::AddCustomRectRegular()
// - ImFontAtlas::AddCustomRectFontGlyph()
// - ImFontAtlas::GetCustomRectByIndex()
// - ImFontAtlas::CalcCustomRectUV()
// - ImFontAtlasGetMouseCursorTexData()
//-----------------------------------------------------------------------------
@ -2497,6 +2496,8 @@ void ImTextureData::DestroyPixels()
// - ImFontAtlasBuildAddFont()
// - ImFontAtlasBuildSetupFontCreateEllipsisFromDot()
// - ImFontAtlasBuildSetupFontSpecialGlyphs()
// - ImFontAtlasBuildDiscardFontGlyph()
// - ImFontAtlasBuildDiscardFontGlyphs()
// - ImFontAtlasBuildReloadFont()
//-----------------------------------------------------------------------------
// - ImFontAtlasAddDrawListSharedData()
@ -2509,11 +2510,15 @@ void ImTextureData::DestroyPixels()
// - ImFontAtlasBuildMakeSpace()
// - ImFontAtlasBuildRepackTexture()
// - ImFontAtlasBuildGrowTexture()
// - ImFontAtlasBuildRepackOrGrowTexture()
// - ImFontAtlasBuildGetTextureSizeEstimate()
// - ImFontAtlasBuildCompactTexture()
// - ImFontAtlasBuildInit()
// - ImFontAtlasBuildDestroy()
//-----------------------------------------------------------------------------
// - ImFontAtlasPackInit()
// - ImFontAtlasPackAllocRectEntry()
// - ImFontAtlasPackDiscardRect()
// - ImFontAtlasPackAddRect()
// - ImFontAtlasPackGetRect()
//-----------------------------------------------------------------------------
@ -2601,6 +2606,21 @@ ImFontAtlas::~ImFontAtlas()
Clear();
}
void ImFontAtlas::Clear()
{
ClearInputData();
ClearTexData();
ClearFonts();
}
void ImFontAtlas::ClearCache()
{
ImVec2i new_tex_size = ImFontAtlasBuildGetTextureSizeEstimate(this);
ImFontAtlasBuildDestroy(this);
ImFontAtlasBuildAddTexture(this, new_tex_size.x, new_tex_size.y);
ImFontAtlasBuildInit(this);
}
void ImFontAtlas::ClearInputData()
{
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
@ -2626,8 +2646,6 @@ void ImFontAtlas::ClearInputData()
font->LockDisableLoading = true;
}
Sources.clear();
//CustomRects.clear();
// Important: we leave TexReady untouched
}
void ImFontAtlas::ClearTexData()
@ -2636,7 +2654,6 @@ void ImFontAtlas::ClearTexData()
TexList.clear();
IM_DELETE(TexData);
TexData = NULL;
// Important: we leave TexReady untouched
}
void ImFontAtlas::ClearFonts()
@ -2654,36 +2671,6 @@ void ImFontAtlas::ClearFonts()
}
}
void ImFontAtlas::Clear()
{
//IM_DELETE(Builder); // FIXME-NEW-ATLAS: Clarify ClearXXX functions
//const ImFontLoader* font_loader = FontLoader;
//ImFontAtlasBuildSetupFontLoader(this, NULL);
ClearInputData();
ClearTexData();
ClearFonts();
//ImFontAtlasBuildSetupFontLoader(this, font_loader);
}
// FIXME-NEWATLAS: Too widespread purpose. Clarify each call site in current WIP demo.
void ImFontAtlas::ClearCache()
{
ImVec2i new_tex_size = ImFontAtlasBuildGetTextureSizeEstimate(this);
ImFontAtlasBuildDestroy(this);
ImFontAtlasBuildAddTexture(this, new_tex_size.x, new_tex_size.y);
ImFontAtlasBuildInit(this);
}
void ImFontAtlas::BuildGrowTexture()
{
ImFontAtlasBuildGrowTexture(this, TexData->Width, TexData->Height);
}
void ImFontAtlas::BuildCompactTexture()
{
ImFontAtlasBuildCompactTexture(this);
}
static void ImFontAtlasBuildUpdateRendererHasTexturesFromContext(ImFontAtlas* atlas)
{
// [LEGACY] Copy back the ImGuiBackendFlags_RendererHasTextures flag from ImGui context.
@ -2756,15 +2743,6 @@ void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas)
}
}
// Source buffer may be written to (used for in-place mods).
// Post-process hooks may eventually be added here.
void ImFontAtlasTextureBlockPostProcess(ImFontAtlasPostProcessData* data)
{
// Multiply operator (legacy)
if (data->FontSrc->RasterizerMultiply != 1.0f)
ImFontAtlasTextureBlockPostProcessMultiply(data, data->FontSrc->RasterizerMultiply);
}
void ImFontAtlasTextureBlockConvert(const unsigned char* src_pixels, ImTextureFormat src_fmt, int src_pitch, unsigned char* dst_pixels, ImTextureFormat dst_fmt, int dst_pitch, int w, int h)
{
IM_ASSERT(src_pixels != NULL && dst_pixels != NULL);
@ -2800,6 +2778,15 @@ void ImFontAtlasTextureBlockConvert(const unsigned char* src_pixels, ImTextureFo
}
}
// Source buffer may be written to (used for in-place mods).
// Post-process hooks may eventually be added here.
void ImFontAtlasTextureBlockPostProcess(ImFontAtlasPostProcessData* data)
{
// Multiply operator (legacy)
if (data->FontSrc->RasterizerMultiply != 1.0f)
ImFontAtlasTextureBlockPostProcessMultiply(data, data->FontSrc->RasterizerMultiply);
}
void ImFontAtlasTextureBlockPostProcessMultiply(ImFontAtlasPostProcessData* data, float multiply_factor)
{
unsigned char* pixels = data->Pixels;
@ -3756,10 +3743,9 @@ void ImFontAtlasBuildRepackTexture(ImFontAtlas* atlas, int w, int h)
new_tex->UseColors = old_tex->UseColors;
IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: resize+repack %dx%d => Texture #%03d: %dx%d\n", old_tex->UniqueID, old_tex->Width, old_tex->Height, new_tex->UniqueID, new_tex->Width, new_tex->Height);
// FIXME-NEWATLAS-TESTS: Test calling RepackTexture with size too small to fits existing rects.
// Repack, lose discarded rectangle, copy pixels
// FIXME-NEWATLAS-V2: Repacking in batch would be beneficial to packing heuristic.
// FIXME-NEWATLAS-TESTS: Test calling RepackTexture with size too small to fits existing rects.
ImFontAtlasPackInit(atlas);
ImVector<ImFontAtlasRect> old_rects;
ImVector<ImFontAtlasRectEntry> old_index = builder->RectsIndex;
@ -3822,7 +3808,7 @@ void ImFontAtlasBuildGrowTexture(ImFontAtlas* atlas, int old_tex_w, int old_tex_
old_tex_h = atlas->TexData->Height;
// FIXME-NEWATLAS-V2: What to do when reaching limits exposed by backend?
// FIXME-NEWATLAS-V2: does ImFontAtlasFlags_NoPowerOfTwoHeight makes sense now? Allow 'lock' and 'compact' operations?
// FIXME-NEWATLAS-V2: Does ImFontAtlasFlags_NoPowerOfTwoHeight makes sense now? Allow 'lock' and 'compact' operations? Could we expose e.g. tex->UsedRect.
IM_ASSERT(ImIsPowerOfTwo(old_tex_w) && ImIsPowerOfTwo(old_tex_h));
IM_ASSERT(ImIsPowerOfTwo(atlas->TexMinWidth) && ImIsPowerOfTwo(atlas->TexMaxWidth) && ImIsPowerOfTwo(atlas->TexMinHeight) && ImIsPowerOfTwo(atlas->TexMaxHeight));
@ -4021,7 +4007,7 @@ void ImFontAtlasPackDiscardRect(ImFontAtlas* atlas, ImFontAtlasRectId id)
}
// Important: Calling this may recreate a new texture and therefore change atlas->TexData
// FIXME-NEWATLAS-V2: Expose other glyph padding settings for custom alteration (e.g. drop shadows). See #7962
// FIXME-NEWFONTS: Expose other glyph padding settings for custom alteration (e.g. drop shadows). See #7962
ImFontAtlasRectId ImFontAtlasPackAddRect(ImFontAtlas* atlas, int w, int h, ImFontAtlasRectEntry* overwrite_entry)
{
IM_ASSERT(w > 0 && w <= 0xFFFF);
@ -4193,9 +4179,10 @@ static bool ImGui_ImplStbTrueType_FontSrcInit(ImFontAtlas* atlas, ImFontConfig*
}
src->FontLoaderData = bd_font_data;
// FIXME-NEWATLAS-V2: reevaluate sizing metrics
// FIXME-NEWFONTS: reevaluate sizing metrics
int oversample_h, oversample_v;
ImFontAtlasBuildGetOversampleFactors(src, &oversample_h, &oversample_v);
if (src->SizePixels > 0.0f)
{
bd_font_data->ScaleForRasterX = stbtt_ScaleForPixelHeight(&bd_font_data->FontInfo, src->SizePixels * src->RasterizerDensity) * oversample_h;
@ -4209,7 +4196,7 @@ static bool ImGui_ImplStbTrueType_FontSrcInit(ImFontAtlas* atlas, ImFontConfig*
bd_font_data->ScaleForLayout = stbtt_ScaleForMappingEmToPixels(&bd_font_data->FontInfo, -src->SizePixels);
}
// FIXME-NEWATLAS-V2: make use of line gap value
// FIXME-NEWFONTS: make use of line gap value
int unscaled_ascent, unscaled_descent, unscaled_line_gap;
stbtt_GetFontVMetrics(&bd_font_data->FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap);

View file

@ -141,10 +141,10 @@ struct ImGuiTextIndex; // Maintain a line index for a text buffer.
// ImDrawList/ImFontAtlas
struct ImDrawDataBuilder; // Helper to build a ImDrawData instance
struct ImDrawListSharedData; // Data shared between all ImDrawList instances
struct ImFontAtlasBuilder; // Internal storage for incrementally packing and building a ImFontAtlas
struct ImFontAtlasPostProcessData; // Data available to potential texture post-processing functions
struct ImFontAtlasRect; // Packed rectangle (same as ImTextureRect)
struct ImFontAtlasRectEntry; // Packed rectangle lookup entry
struct ImFontAtlasBuilder; // Internal storage for incrementally packing and building a ImFontAtlas
struct ImFontAtlasPostProcessData; // Data available to potential post-process functions
// ImGui
struct ImGuiBoxSelectState; // Box-selection state (currently used by multi-selection, could potentially be used by others)
@ -3944,7 +3944,7 @@ struct ImFontAtlasRectEntry
unsigned int Used : 1;
};
// Data available to potential post-process functions
// Data available to potential texture post-processing functions
struct ImFontAtlasPostProcessData
{
ImFontAtlas* FontAtlas;
@ -3987,15 +3987,13 @@ struct ImFontAtlasBuilder
ImFontAtlasBuilder() { memset(this, 0, sizeof(*this)); RectsIndexFreeListStart = -1; PackIdMouseCursors = PackIdLinesTexData = -1; }
};
// FIXME-NEWATLAS: Cleanup
IMGUI_API void ImFontAtlasBuildInit(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildDestroy(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildMain(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildSetupFontLoader(ImFontAtlas* atlas, const ImFontLoader* font_loader);
IMGUI_API void ImFontAtlasBuildUpdatePointers(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildRenderBitmapFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char);
IMGUI_API void ImFontAtlasBuildMain(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildInit(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildDestroy(ImFontAtlas* atlas);
IMGUI_API ImTextureData* ImFontAtlasBuildAddTexture(ImFontAtlas* atlas, int w, int h);
IMGUI_API void ImFontAtlasBuildMakeSpace(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildRepackTexture(ImFontAtlas* atlas, int w, int h);
@ -4004,26 +4002,24 @@ IMGUI_API void ImFontAtlasBuildCompactTexture(ImFontAtlas* atlas);
IMGUI_API ImVec2i ImFontAtlasBuildGetTextureSizeEstimate(ImFontAtlas* atlas);
IMGUI_API bool ImFontAtlasBuildAddFont(ImFontAtlas* atlas, ImFontConfig* src);
IMGUI_API ImFontGlyph* ImFontAtlasBuildAddFontGlyph(ImFontAtlas* atlas, ImFont* font, ImFontConfig* src, const ImFontGlyph* in_glyph);
IMGUI_API void ImFontAtlasBuildSetupFontSpecialGlyphs(ImFontAtlas* atlas, ImFontConfig* src);
IMGUI_API void ImFontAtlasBuildDiscardFontGlyphs(ImFontAtlas* atlas, ImFont* font);
IMGUI_API void ImFontAtlasBuildReloadFont(ImFontAtlas* atlas, ImFont* font);
IMGUI_API void ImFontAtlasBuildReloadFont(ImFontAtlas* atlas, ImFont* font); // <--- Your future new best friend!
IMGUI_API void ImFontAtlasBuildPreloadAllGlyphRanges(ImFontAtlas* atlas); // Legacy
IMGUI_API void ImFontAtlasBuildGetOversampleFactors(ImFontConfig* src, int* out_oversample_h, int* out_oversample_v);
IMGUI_API ImFontGlyph* ImFontAtlasBuildAddFontGlyph(ImFontAtlas* atlas, ImFont* font, ImFontConfig* cfg, const ImFontGlyph* in_glyph);
IMGUI_API void ImFontAtlasPackInit(ImFontAtlas* atlas);
IMGUI_API ImFontAtlasRectId ImFontAtlasPackAddRect(ImFontAtlas* atlas, int w, int h, ImFontAtlasRectEntry* overwrite_entry = NULL);
IMGUI_API void ImFontAtlasPackDiscardRect(ImFontAtlas* atlas, ImFontAtlasRectId id);
IMGUI_API ImFontAtlasRect* ImFontAtlasPackGetRect(ImFontAtlas* atlas, ImFontAtlasRectId id);
IMGUI_API void ImFontAtlasPackDiscardRect(ImFontAtlas* atlas, ImFontAtlasRectId id);
IMGUI_API void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasAddDrawListSharedData(ImFontAtlas* atlas, ImDrawListSharedData* data);
IMGUI_API void ImFontAtlasRemoveDrawListSharedData(ImFontAtlas* atlas, ImDrawListSharedData* data);
IMGUI_API void ImFontAtlasUpdateDrawListsTextures(ImFontAtlas* atlas, ImTextureRef old_tex, ImTextureRef new_tex);
IMGUI_API void ImFontAtlasUpdateDrawListsSharedData(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasTextureBlockConvert(const unsigned char* src_pixels, ImTextureFormat src_fmt, int src_pitch, unsigned char* dst_pixels, ImTextureFormat dst_fmt, int dst_pitch, int w, int h);
IMGUI_API void ImFontAtlasTextureBlockPostProcess(ImFontAtlasPostProcessData* data);
IMGUI_API void ImFontAtlasTextureBlockPostProcessMultiply(ImFontAtlasPostProcessData* data, float multiply_factor);