diff --git a/imgui.h b/imgui.h index 9bf4db914..8cf3f7ff4 100644 --- a/imgui.h +++ b/imgui.h @@ -177,6 +177,7 @@ struct ImFontBaked; // Baked data for a ImFont at a given size. struct ImFontConfig; // Configuration data when adding a font or merging fonts struct ImFontGlyph; // A single font glyph (code point + coordinates within in ImFontAtlas + offset) struct ImFontGlyphRangesBuilder; // Helper to build glyph ranges from text/string data +struct ImFontHooks; // Opaque interface to font hooks struct ImFontLoader; // Opaque interface to a font loading backend (stb_truetype, FreeType etc.). struct ImTextureData; // Specs and pixel storage for a texture used by Dear ImGui. struct ImTextureRect; // Coordinates of a rectangle within a texture. @@ -3682,6 +3683,7 @@ struct ImFontAtlas const ImFontLoader* FontLoader; // Font loader opaque interface (default to stb_truetype, can be changed to use FreeType by defining IMGUI_ENABLE_FREETYPE). Don't set directly! const char* FontLoaderName; // Font loader name (for display e.g. in About box) == FontLoader->Name void* FontLoaderData; // Font backend opaque storage + const ImFontHooks* FontHooks; // Shared font hooks for all fonts. unsigned int FontBuilderFlags; // [FIXME: Should be called FontLoaderFlags] Shared flags (for all fonts) for font loader. THIS IS BUILD IMPLEMENTATION DEPENDENT (e.g. . Per-font override is also available in ImFontConfig. int RefCount; // Number of contexts using this atlas @@ -3769,6 +3771,7 @@ struct ImFont float Scale; // 4 // in // Base font scale (~1.0f), multiplied by the per-window font scale which you can adjust with SetWindowFontScale() 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 EllipsisAutoBake; // 1 // // Mark when the "..." glyph needs to be generated. + const ImFontHooks* FontHooks; // 8 // in // Custom font hooks for the font. // Methods IMGUI_API ImFont(); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 968dc47d4..8661de762 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -4365,6 +4365,14 @@ static void ImFontBaked_BuildGrowIndex(ImFontBaked* baked, int new_size) baked->IndexLookup.resize(new_size, IM_FONTGLYPH_INDEX_UNUSED); } +static void ImFont_FontHookRemapCodepoint(ImFontAtlas* atlas, ImFont* font, ImWchar* c) +{ + if (font->FontHooks && font->FontHooks->FontHookRemapCodepoint != NULL) + font->FontHooks->FontHookRemapCodepoint(atlas, font, c); + else if (atlas->FontHooks && atlas->FontHooks->FontHookRemapCodepoint != NULL) + atlas->FontHooks->FontHookRemapCodepoint(atlas, font, c); +} + static ImFontGlyph* ImFontBaked_BuildLoadGlyph(ImFontBaked* baked, ImWchar codepoint) { ImFont* font = baked->ContainerFont; @@ -4377,6 +4385,10 @@ static ImFontGlyph* ImFontBaked_BuildLoadGlyph(ImFontBaked* baked, ImWchar codep return NULL; } + // User remapping hooks + ImWchar src_codepoint = codepoint; + ImFont_FontHookRemapCodepoint(atlas, font, &codepoint); + //char utf8_buf[5]; //IMGUI_DEBUG_LOG("[font] BuildLoadGlyph U+%04X (%s)\n", (unsigned int)codepoint, ImTextCharToUtf8(utf8_buf, (unsigned int)codepoint)); @@ -4398,6 +4410,7 @@ static ImFontGlyph* ImFontBaked_BuildLoadGlyph(ImFontBaked* baked, ImWchar codep if (loader->FontBakedLoadGlyph(atlas, src, baked, loader_user_data_p, codepoint, &glyph_buf)) { // FIXME: Add hooks for e.g. #7962 + glyph_buf.Codepoint = src_codepoint; glyph_buf.SourceIdx = src_n; return ImFontAtlasBakedAddFontGlyph(atlas, baked, src, &glyph_buf); } @@ -5079,7 +5092,7 @@ void ImFontAtlasBakedSetFontGlyphBitmap(ImFontAtlas* atlas, ImFontBaked* baked, ImFontAtlasTextureBlockQueueUpload(atlas, tex, r->x, r->y, r->w, r->h); } -// FIXME-NEWATLAS: Implement AddRemapChar() which was removed since transitioning to baked logic. +// FIXME: Use ImFontHooks::FontHookRemapCodepoint() hooks. void ImFont::AddRemapChar(ImWchar from_codepoint, ImWchar to_codepoint, bool overwrite_dst) { IM_UNUSED(from_codepoint); @@ -5149,6 +5162,7 @@ bool ImFontBaked::IsGlyphLoaded(ImWchar c) bool ImFont::IsGlyphInFont(ImWchar c) { ImFontAtlas* atlas = ContainerAtlas; + ImFont_FontHookRemapCodepoint(atlas, this, &c); for (ImFontConfig* src : Sources) { const ImFontLoader* loader = src->FontLoader ? src->FontLoader : atlas->FontLoader; diff --git a/imgui_internal.h b/imgui_internal.h index 00cb159d2..b486430ad 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -37,7 +37,7 @@ Index of this file: // [SECTION] Tab bar, Tab item support // [SECTION] Table support // [SECTION] ImGui internal API -// [SECTION] ImFontLoader +// [SECTION] ImFontLoader, ImFontHooks // [SECTION] ImFontAtlas internal API // [SECTION] Test Engine specific hooks (imgui_test_engine) @@ -3664,7 +3664,7 @@ namespace ImGui //----------------------------------------------------------------------------- -// [SECTION] ImFontLoader +// [SECTION] ImFontLoader, ImFontHooks //----------------------------------------------------------------------------- // Hooks and storage for a given font backend. @@ -3693,6 +3693,14 @@ struct ImFontLoader IMGUI_API const ImFontLoader* ImFontAtlasGetFontLoaderForStbTruetype(); #endif +// User hooks +// Conceptually this could be public, but API is still going to be evolve. +struct ImFontHooks +{ + // Modify codepoint to map to another value. + void (*FontHookRemapCodepoint)(ImFontAtlas* atlas, ImFont* font, ImWchar* io_codepoint); +}; + //----------------------------------------------------------------------------- // [SECTION] ImFontAtlas internal API //-----------------------------------------------------------------------------