From 2cde9125d6286c878c5e00d4a9ff9c85e108aa8d Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 17 Jan 2025 18:06:25 +0100 Subject: [PATCH] Fonts: Selecting font config source list done by shared code. --- imgui.h | 10 +++++----- imgui_draw.cpp | 24 +++++++++++++++--------- imgui_internal.h | 2 +- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/imgui.h b/imgui.h index 0420b4358..753fffe92 100644 --- a/imgui.h +++ b/imgui.h @@ -3631,19 +3631,19 @@ struct ImFont float FallbackAdvanceX; // 4 // out // FindGlyph(FallbackChar)->AdvanceX float FontSize; // 4 // in // Height of characters/line, set during loading (don't change after loading) - // [Internal] Members: Hot ~28/40 bytes (for RenderText loop) + // [Internal] Members: Hot ~28/36 bytes (for RenderText loop) ImVector IndexLookup; // 12-16 // out // Sparse. Index glyphs by Unicode code-point. ImVector Glyphs; // 12-16 // out // All glyphs. int FallbackGlyphIndex; // 4 // out // Index of FontFallbackChar - // [Internal] Members: Cold ~32/40 bytes + // [Internal] Members: Cold ~32/40/60 bytes // Conceptually Sources[] is the list of font sources merged to create this font. - ImFontAtlas* ContainerAtlas; // 4-8 // out // What we has been loaded into - ImFontConfig* Sources; // 4-8 // in // Pointer within ContainerAtlas->Sources[], to SourcesCount instances short SourcesCount; // 2 // in // Number of ImFontConfig involved in creating this font. Usually 1, or >1 when merging multiple font sources into one ImFont. short EllipsisCharCount; // 1 // out // 1 or 3 ImWchar EllipsisChar; // 2-4 // out // Character used for ellipsis rendering ('...'). ImWchar FallbackChar; // 2-4 // out // Character used if a glyph isn't found (U+FFFD, '?') + ImFontConfig* Sources; // 4-8 // in // Pointer within ContainerAtlas->Sources[], to SourcesCount instances + ImFontAtlas* ContainerAtlas; // 4-8 // out // What we has been loaded into float EllipsisWidth; // 4 // out // Total ellipsis Width float EllipsisCharStep; // 4 // out // Step between characters when EllipsisCount > 0 float Scale; // 4 // in // Base font scale (~1.0f), multiplied by the per-window font scale which you can adjust with SetWindowFontScale() @@ -3651,7 +3651,7 @@ struct ImFont int MetricsTotalSurface;// 4 // out // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs) ImU8 Used8kPagesMap[(IM_UNICODE_CODEPOINT_MAX+1)/8192/8]; // 1 bytes if ImWchar=ImWchar16, 16 bytes if ImWchar==ImWchar32. Store 1-bit for each block of 4K codepoints that has one active glyph. This is mainly used to facilitate iterations across all used codepoints. bool LockDisableLoading; - ImFontConfig* LockSingleSrcConfig; + short LockSingleSrcConfigIdx; // Methods IMGUI_API ImFont(); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index b1cf15ff4..a497663b9 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -3394,10 +3394,12 @@ bool ImFontAtlasBuildAddFont(ImFontAtlas* atlas, ImFontConfig* src) void ImFontAtlasBuildSetupFontSpecialGlyphs(ImFontAtlas* atlas, ImFontConfig* src) { ImFont* font = src->DstFont; + const int cfg_idx_in_font = (int)(src - font->Sources); + IM_ASSERT(cfg_idx_in_font >= 0 && cfg_idx_in_font < font->SourcesCount); IM_UNUSED(atlas); // While manipulating glyphs during init we want to restrict all searches for one source font. - font->LockSingleSrcConfig = src; + font->LockSingleSrcConfigIdx = (short)cfg_idx_in_font; // Setup Fallback character // FIXME-NEWATLAS: could we use a scheme where this is lazily loaded? @@ -3448,8 +3450,7 @@ void ImFontAtlasBuildSetupFontSpecialGlyphs(ImFontAtlas* atlas, ImFontConfig* sr font->EllipsisWidth = ImMax(dot_glyph->AdvanceX, dot_glyph->X0 + font->EllipsisCharStep * 3.0f - 1.0f); // FIXME: Slightly odd for normally mono-space fonts but since this is used for trailing contents. } } - - font->LockSingleSrcConfig = NULL; + font->LockSingleSrcConfigIdx = -1; } // Those functions are designed to facilitate changing the underlying structures for ImFontAtlas to store an array of ImDrawListSharedData* @@ -3809,10 +3810,15 @@ ImFontGlyph* ImFont::BuildLoadGlyph(ImWchar codepoint) //char utf8_buf[5]; //IMGUI_DEBUG_LOG("[font] BuildAddGlyph U+%04X (%s)\n", (unsigned int)codepoint, ImTextCharToUtf8(utf8_buf, (unsigned int)codepoint)); - ImFontAtlas* atlas = ContainerAtlas; + + // Load from single source or all sources? + int srcs_count = (LockSingleSrcConfigIdx != -1) ? 1 : SourcesCount; + ImFontConfig* srcs = (LockSingleSrcConfigIdx != -1) ? &Sources[LockSingleSrcConfigIdx] : Sources; + + // Call backend const ImFontLoader* font_loader = atlas->FontLoader; - if (!font_loader->FontAddGlyph(atlas, this, codepoint)) + if (!font_loader->FontAddGlyph(atlas, this, srcs, srcs_count, codepoint)) { // Mark index as not found, so we don't attempt the search twice BuildGrowIndex(codepoint + 1); @@ -3937,16 +3943,15 @@ static bool ImGui_ImplStbTrueType_FontSrcContainsGlyph(ImFontAtlas* atlas, ImFon return glyph_index != 0; } -static bool ImGui_ImplStbTrueType_FontAddGlyph(ImFontAtlas* atlas, ImFont* font, ImWchar codepoint) +static bool ImGui_ImplStbTrueType_FontAddGlyph(ImFontAtlas* atlas, ImFont* font, ImFontConfig* srcs, int srcs_count, ImWchar codepoint) { // Search for first font which has the glyph ImGui_ImplStbTrueType_FontSrcData* bd_font_data = NULL; ImFontConfig* src = NULL; int glyph_index = 0; - int scan_count = (font->LockSingleSrcConfig != NULL) ? 1 : font->SourcesCount; - for (int src_n = 0; src_n < scan_count; src_n++, bd_font_data++) + for (int src_n = 0; src_n < srcs_count; src_n++) { - src = font->LockSingleSrcConfig ? font->LockSingleSrcConfig : &font->Sources[src_n]; + src = &srcs[src_n]; bd_font_data = (ImGui_ImplStbTrueType_FontSrcData*)src->FontLoaderData; glyph_index = stbtt_FindGlyphIndex(&bd_font_data->FontInfo, (int)codepoint); if (glyph_index != 0) @@ -4369,6 +4374,7 @@ ImFont::ImFont() { memset(this, 0, sizeof(*this)); Scale = 1.0f; + LockSingleSrcConfigIdx = -1; } ImFont::~ImFont() diff --git a/imgui_internal.h b/imgui_internal.h index 3b650c9d5..27d1ca8e1 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -3626,7 +3626,7 @@ struct ImFontLoader bool (*FontSrcInit)(ImFontAtlas* atlas, ImFontConfig* src); void (*FontSrcDestroy)(ImFontAtlas* atlas, ImFontConfig* src); bool (*FontSrcContainsGlyph)(ImFontAtlas* atlas, ImFontConfig* src, ImWchar codepoint); - bool (*FontAddGlyph)(ImFontAtlas* atlas, ImFont* font, ImWchar codepoint); + bool (*FontAddGlyph)(ImFontAtlas* atlas, ImFont* font, ImFontConfig* srcs, int srcs_count, ImWchar codepoint); ImFontLoader() { memset(this, 0, sizeof(*this)); } };