Fonts: ImFontFlags: ImFontFlags_NoLoadGlyphs + add ImFontFlags_LockBakedSizes

This commit is contained in:
ocornut
2025-02-06 11:57:30 +01:00
parent 8a8d8a7b38
commit dc1320df64
3 changed files with 30 additions and 9 deletions

16
imgui.h
View File

@@ -230,7 +230,8 @@ typedef int ImGuiTableBgTarget; // -> enum ImGuiTableBgTarget_ // Enum: A
// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments. // - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments.
typedef int ImDrawFlags; // -> enum ImDrawFlags_ // Flags: for ImDrawList functions typedef int ImDrawFlags; // -> enum ImDrawFlags_ // Flags: for ImDrawList functions
typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList instance typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList instance
typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas build typedef int ImFontFlags; // -> enum ImFontFlags_ // Flags: for ImFont
typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas
typedef int ImGuiBackendFlags; // -> enum ImGuiBackendFlags_ // Flags: for io.BackendFlags typedef int ImGuiBackendFlags; // -> enum ImGuiBackendFlags_ // Flags: for io.BackendFlags
typedef int ImGuiButtonFlags; // -> enum ImGuiButtonFlags_ // Flags: for InvisibleButton() typedef int ImGuiButtonFlags; // -> enum ImGuiButtonFlags_ // Flags: for InvisibleButton()
typedef int ImGuiChildFlags; // -> enum ImGuiChildFlags_ // Flags: for BeginChild() typedef int ImGuiChildFlags; // -> enum ImGuiChildFlags_ // Flags: for BeginChild()
@@ -3666,6 +3667,15 @@ struct ImFontBaked
IMGUI_API void BuildGrowIndex(int new_size); IMGUI_API void BuildGrowIndex(int new_size);
}; };
// Font flags
// (in future versions as we redesign font loading API, this will become more important and better documented. for now please consider this as internal/advanced use)
enum ImFontFlags_
{
ImFontFlags_None = 0,
ImFontFlags_LockBakedSizes = 1 << 0, // Disable loading new baked sizes, disable garbage collecting current ones. e.g. if you want to lock a font to a single size.
ImFontFlags_NoLoadGlyphs = 1 << 1, // Disable loading new glyphs.
};
// Font runtime data and rendering // Font runtime data and rendering
// - ImFontAtlas automatically loads a default embedded font for you if you didn't load one manually. // - ImFontAtlas automatically loads a default embedded font for you if you didn't load one manually.
// - Since 1.92.X a font may be rendered as any size! Therefore a font doesn't have one specific size. // - Since 1.92.X a font may be rendered as any size! Therefore a font doesn't have one specific size.
@@ -3673,9 +3683,10 @@ struct ImFontBaked
// - If you used g.Font + g.FontSize (which is frequent from the ImGui layer), you can use g.FontBaked as a shortcut, as g.FontBaked == g.Font->GetFontBaked(g.FontSize). // - If you used g.Font + g.FontSize (which is frequent from the ImGui layer), you can use g.FontBaked as a shortcut, as g.FontBaked == g.Font->GetFontBaked(g.FontSize).
struct ImFont struct ImFont
{ {
// [Internal] Members: Hot ~8-16 bytes // [Internal] Members: Hot ~12-20 bytes
ImFontBaked* LastBaked; // 4-8 // Cache last bound baked. DO NOT USE. Use GetFontBaked(). ImFontBaked* LastBaked; // 4-8 // Cache last bound baked. DO NOT USE. Use GetFontBaked().
ImFontAtlas* ContainerAtlas; // 4-8 // What we has been loaded into ImFontAtlas* ContainerAtlas; // 4-8 // What we has been loaded into
ImFontFlags Flags; // 4 // Font flags
// [Internal] Members: Cold ~24-52 bytes // [Internal] Members: Cold ~24-52 bytes
// Conceptually Sources[] is the list of font sources merged to create this font. // Conceptually Sources[] is the list of font sources merged to create this font.
@@ -3686,7 +3697,6 @@ struct ImFont
ImWchar FallbackChar; // 2-4 // out // Character used if a glyph isn't found (U+FFFD, '?') ImWchar FallbackChar; // 2-4 // out // Character used if a glyph isn't found (U+FFFD, '?')
float Scale; // 4 // in // Base font scale (~1.0f), multiplied by the per-window font scale which you can adjust with SetWindowFontScale() 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. 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;
short LockSingleSrcConfigIdx; short LockSingleSrcConfigIdx;
// Methods // Methods

View File

@@ -2647,7 +2647,7 @@ void ImFontAtlas::ClearInputData()
font->Sources = NULL; font->Sources = NULL;
font->SourcesCount = 0; font->SourcesCount = 0;
} }
font->LockDisableLoading = true; font->Flags |= ImFontFlags_NoLoadGlyphs;
} }
Sources.clear(); Sources.clear();
} }
@@ -3688,8 +3688,11 @@ void ImFontAtlasBuildDiscardBakes(ImFontAtlas* atlas, int unused_frames)
for (int baked_n = 0; baked_n < builder->BakedPool.Size; baked_n++) for (int baked_n = 0; baked_n < builder->BakedPool.Size; baked_n++)
{ {
ImFontBaked* baked = &builder->BakedPool[baked_n]; ImFontBaked* baked = &builder->BakedPool[baked_n];
if (baked->LastUsedFrame + unused_frames <= atlas->Builder->FrameCount && !baked->WantDestroy) if (baked->LastUsedFrame + unused_frames > atlas->Builder->FrameCount)
ImFontAtlasBuildDiscardFontBaked(atlas, baked->ContainerFont, baked); continue;
if (baked->WantDestroy || (baked->ContainerFont->Flags & ImFontFlags_LockBakedSizes))
continue;
ImFontAtlasBuildDiscardFontBaked(atlas, baked->ContainerFont, baked);
} }
} }
@@ -3816,7 +3819,8 @@ void ImFontAtlasBuildRepackTexture(ImFontAtlas* atlas, int w, int h)
//ImFontAtlasDebugWriteTexToDisk(old_tex, "Before Pack"); //ImFontAtlasDebugWriteTexToDisk(old_tex, "Before Pack");
// Repack, lose discarded rectangle, copy pixels // Repack, lose discarded rectangle, copy pixels
// FIXME-NEWATLAS-V2: Repacking in batch would be beneficial to packing heuristic. // FIXME-NEWATLAS: This is unstable because packing order is based on RectsIndex
// FIXME-NEWATLAS-V2: Repacking in batch would be beneficial to packing heuristic, and fix stability.
// FIXME-NEWATLAS-TESTS: Test calling RepackTexture with size too small to fits existing rects. // FIXME-NEWATLAS-TESTS: Test calling RepackTexture with size too small to fits existing rects.
ImFontAtlasPackInit(atlas); ImFontAtlasPackInit(atlas);
ImVector<ImFontAtlasRect> old_rects; ImVector<ImFontAtlasRect> old_rects;
@@ -4172,7 +4176,7 @@ ImFontGlyph* ImFontBaked::BuildLoadGlyph(ImWchar codepoint)
ImFont* font = ContainerFont; ImFont* font = ContainerFont;
ImFontBaked* baked = this; ImFontBaked* baked = this;
ImFontAtlas* atlas = font->ContainerAtlas; ImFontAtlas* atlas = font->ContainerAtlas;
if (font->LockDisableLoading || atlas->Locked) if (atlas->Locked || (font->Flags & ImFontFlags_NoLoadGlyphs))
return NULL; return NULL;
//char utf8_buf[5]; //char utf8_buf[5];
@@ -5008,6 +5012,13 @@ ImFontBaked* ImFont::GetFontBaked(float size)
return baked; return baked;
} }
// FIXME-BAKED: If loading is locked, find closest match
if (Flags & ImFontFlags_LockBakedSizes)
{
IM_ASSERT(LastBaked);
return LastBaked;
}
// FIXME-BAKED: If atlas is locked, find closest match // FIXME-BAKED: If atlas is locked, find closest match
if (atlas->Locked) if (atlas->Locked)
IM_ASSERT(!atlas->Locked && "Cannot use dynamic font size with a locked ImFontAtlas!"); // Locked because rendering backend does not support ImGuiBackendFlags_RendererHasTextures! IM_ASSERT(!atlas->Locked && "Cannot use dynamic font size with a locked ImFontAtlas!"); // Locked because rendering backend does not support ImGuiBackendFlags_RendererHasTextures!

View File

@@ -4321,7 +4321,7 @@ void ImGui::PushPasswordFont()
ImFont* out_font = &g.InputTextPasswordFont; ImFont* out_font = &g.InputTextPasswordFont;
out_font->Scale = in_font->Scale; out_font->Scale = in_font->Scale;
out_font->ContainerAtlas = in_font->ContainerAtlas; out_font->ContainerAtlas = in_font->ContainerAtlas;
out_font->LockDisableLoading = true; out_font->Flags |= ImFontFlags_NoLoadGlyphs;
ImFontBaked* out_baked = out_font->GetFontBaked(in_baked->Size); ImFontBaked* out_baked = out_font->GetFontBaked(in_baked->Size);
IM_ASSERT(out_baked->Glyphs.Size <= 1 && out_baked->IndexAdvanceX.Size == 0 && out_baked->IndexLookup.Size == 0); IM_ASSERT(out_baked->Glyphs.Size <= 1 && out_baked->IndexAdvanceX.Size == 0 && out_baked->IndexLookup.Size == 0);
out_baked->Ascent = in_baked->Ascent; out_baked->Ascent = in_baked->Ascent;