Browse Source

Fonts: ImFontFlags: ImFontFlags_NoLoadGlyphs + add ImFontFlags_LockBakedSizes

ocornut 6 months ago
parent
commit
dc1320df64
3 changed files with 30 additions and 9 deletions
  1. 13 3
      imgui.h
  2. 16 5
      imgui_draw.cpp
  3. 1 1
      imgui_widgets.cpp

+ 13 - 3
imgui.h

@@ -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

+ 16 - 5
imgui_draw.cpp

@@ -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)
-            ImFontAtlasBuildDiscardFontBaked(atlas, baked->ContainerFont, baked);
+        if (baked->LastUsedFrame + unused_frames > atlas->Builder->FrameCount)
+            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!

+ 1 - 1
imgui_widgets.cpp

@@ -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;