diff --git a/imgui.cpp b/imgui.cpp index a4fc5ecce..8f56e8956 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -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; diff --git a/imgui.h b/imgui.h index a10cc1011..69b66700d 100644 --- a/imgui.h +++ b/imgui.h @@ -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; diff --git a/imgui_draw.cpp b/imgui_draw.cpp index c4405aba6..bc820980a 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -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 old_rects; ImVector 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); diff --git a/imgui_internal.h b/imgui_internal.h index 27f245d42..bd922909a 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -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);