浏览代码

Fonts: changing loader/backend or loader flags may be done without losing custom rects. Sharing more code.

ocornut 5 月之前
父节点
当前提交
fb5c537080
共有 3 个文件被更改,包括 60 次插入48 次删除
  1. 20 7
      imgui.cpp
  2. 38 39
      imgui_draw.cpp
  3. 2 2
      imgui_internal.h

+ 20 - 7
imgui.cpp

@@ -15695,9 +15695,16 @@ void ImGui::ShowFontAtlas(ImFontAtlas* atlas)
             ImFontAtlasBuildSetupFontLoader(atlas, loader_freetype);
             ImFontAtlasBuildSetupFontLoader(atlas, loader_freetype);
         if (loader_current == loader_freetype)
         if (loader_current == loader_freetype)
         {
         {
-            Text("Shared FreeType Loader Flags:");
-            if (ImGuiFreeType::DebugEditFontBuilderFlags(&atlas->FontBuilderFlags))
-                ImFontAtlasBuildReloadAll(atlas);
+            unsigned int loader_flags = atlas->FontBuilderFlags;
+            Text("Shared FreeType Loader Flags:  0x%08", loader_flags);
+            if (ImGuiFreeType::DebugEditFontBuilderFlags(&loader_flags))
+            {
+                for (ImFont* font : atlas->Fonts)
+                    ImFontAtlasBuildDestroyFontOutput(atlas, font);
+                atlas->FontBuilderFlags = loader_flags;
+                for (ImFont* font : atlas->Fonts)
+                    ImFontAtlasBuildInitFontOutput(atlas, font);
+            }
         }
         }
 #else
 #else
         BeginDisabled();
         BeginDisabled();
@@ -15724,8 +15731,9 @@ void ImGui::ShowFontAtlas(ImFontAtlas* atlas)
     if (Button("Grow"))
     if (Button("Grow"))
         ImFontAtlasBuildGrowTexture(atlas);
         ImFontAtlasBuildGrowTexture(atlas);
     SameLine();
     SameLine();
-    if (Button("Clear Output"))
+    if (Button("Clear All"))
         ImFontAtlasBuildClear(atlas);
         ImFontAtlasBuildClear(atlas);
+    SetItemTooltip("Destroy cache and custom rectangles.");
 
 
     for (int tex_n = 0; tex_n < atlas->TexList.Size; tex_n++)
     for (int tex_n = 0; tex_n < atlas->TexList.Size; tex_n++)
     {
     {
@@ -16613,9 +16621,14 @@ void ImGui::DebugNodeFont(ImFont* font)
 #ifdef IMGUI_ENABLE_FREETYPE
 #ifdef IMGUI_ENABLE_FREETYPE
                 if (loader->Name != NULL && strcmp(loader->Name, "FreeType") == 0)
                 if (loader->Name != NULL && strcmp(loader->Name, "FreeType") == 0)
                 {
                 {
-                    Text("FreeType Loader Flags: 0x%08X", src->FontBuilderFlags);
-                    if (ImGuiFreeType::DebugEditFontBuilderFlags(&src->FontBuilderFlags))
-                        ImFontAtlasBuildReloadFont(atlas, src);
+                    unsigned int loader_flags = src->FontBuilderFlags;
+                    Text("FreeType Loader Flags: 0x%08X", loader_flags);
+                    if (ImGuiFreeType::DebugEditFontBuilderFlags(&loader_flags))
+                    {
+                        ImFontAtlasBuildDestroyFontOutput(atlas, font);
+                        src->FontBuilderFlags = loader_flags;
+                        ImFontAtlasBuildInitFontOutput(atlas, font);
+                    }
                 }
                 }
 #endif
 #endif
                 TreePop();
                 TreePop();

+ 38 - 39
imgui_draw.cpp

@@ -2649,14 +2649,11 @@ void ImFontAtlas::CompactCache()
 void ImFontAtlas::ClearInputData()
 void ImFontAtlas::ClearInputData()
 {
 {
     IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
     IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
+
+    for (ImFont* font : Fonts)
+        ImFontAtlasBuildDestroyFontOutput(this, font);
     for (ImFontConfig& font_cfg : Sources)
     for (ImFontConfig& font_cfg : Sources)
-    {
-        const ImFontLoader* loader = font_cfg.FontLoader ? font_cfg.FontLoader : FontLoader;
-        if (loader && loader->FontSrcDestroy != NULL)
-            loader->FontSrcDestroy(this, &font_cfg);
         ImFontAtlasBuildDestroyFontSourceData(this, &font_cfg);
         ImFontAtlasBuildDestroyFontSourceData(this, &font_cfg);
-    }
-
     for (ImFont* font : Fonts)
     for (ImFont* font : Fonts)
     {
     {
         // When clearing this we lose access to the font name and other information used to build the font.
         // When clearing this we lose access to the font name and other information used to build the font.
@@ -3197,15 +3194,9 @@ void ImFontAtlas::RemoveFont(ImFont* font)
     IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
     IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
     font->ClearOutputData();
     font->ClearOutputData();
 
 
+    ImFontAtlasBuildDestroyFontOutput(this, font);
     for (int src_n = 0; src_n < font->SourcesCount; src_n++)
     for (int src_n = 0; src_n < font->SourcesCount; src_n++)
-    {
-        ImFontConfig* src = (ImFontConfig*)(void*)&font->Sources[src_n];
-        const ImFontLoader* loader = src->FontLoader ? src->FontLoader : FontLoader;
-        if (loader && loader->FontSrcDestroy != NULL)
-            loader->FontSrcDestroy(this, src);
-        if (src->FontData != NULL && src->FontDataOwnedByAtlas)
-            IM_FREE(src->FontData);
-    }
+        ImFontAtlasBuildDestroyFontSourceData(this, &font->Sources[src_n]);
 
 
     bool removed = Fonts.find_erase(font);
     bool removed = Fonts.find_erase(font);
     IM_ASSERT(removed);
     IM_ASSERT(removed);
@@ -3376,15 +3367,19 @@ void ImFontAtlasBuildSetupFontLoader(ImFontAtlas* atlas, const ImFontLoader* fon
         return;
         return;
     IM_ASSERT(!atlas->Locked && "Cannot modify a locked ImFontAtlas!");
     IM_ASSERT(!atlas->Locked && "Cannot modify a locked ImFontAtlas!");
 
 
-    // Note that texture size estimate is likely incorrect in this situation, as FreeType backend doesn't use oversampling.
-    ImVec2i new_tex_size = ImFontAtlasBuildGetTextureSizeEstimate(atlas);
-    ImFontAtlasBuildDestroy(atlas);
+    for (ImFont* font : atlas->Fonts)
+        ImFontAtlasBuildDestroyFontOutput(atlas, font);
+    if (atlas->Builder && atlas->FontLoader && atlas->FontLoader->LoaderShutdown)
+        atlas->FontLoader->LoaderShutdown(atlas);
 
 
     atlas->FontLoader = font_loader;
     atlas->FontLoader = font_loader;
     atlas->FontLoaderName = font_loader ? font_loader->Name : "NULL";
     atlas->FontLoaderName = font_loader ? font_loader->Name : "NULL";
+    IM_ASSERT(atlas->FontLoaderData == NULL);
 
 
-    ImFontAtlasBuildAddTexture(atlas, new_tex_size.x, new_tex_size.y);
-    ImFontAtlasBuildInit(atlas);
+    if (atlas->Builder && atlas->FontLoader && atlas->FontLoader->LoaderInit)
+        atlas->FontLoader->LoaderInit(atlas);
+    for (ImFont* font : atlas->Fonts)
+        ImFontAtlasBuildInitFontOutput(atlas, font);
 }
 }
 
 
 // Preload all glyph ranges for legacy backends.
 // Preload all glyph ranges for legacy backends.
@@ -3562,18 +3557,31 @@ static void ImFontAtlasBuildUpdateLinesTexData(ImFontAtlas* atlas, bool add_and_
 
 
 //-----------------------------------------------------------------------------------------------------------------------------
 //-----------------------------------------------------------------------------------------------------------------------------
 
 
-void ImFontAtlasBuildReloadAll(ImFontAtlas* atlas)
+bool ImFontAtlasBuildInitFontOutput(ImFontAtlas* atlas, ImFont* font)
 {
 {
-    const ImFontLoader* main_loader = atlas->FontLoader;
-    ImFontAtlasBuildSetupFontLoader(atlas, NULL);
-    ImFontAtlasBuildSetupFontLoader(atlas, main_loader);
+    bool ret = true;
+    for (int src_n = 0; src_n < font->SourcesCount; src_n++)
+    {
+        ImFontConfig* src = &font->Sources[src_n];
+        const ImFontLoader* loader = src->FontLoader ? src->FontLoader : atlas->FontLoader;
+        if (loader && loader->FontSrcInit != NULL && !loader->FontSrcInit(atlas, src))
+            ret = false;
+    }
+    IM_ASSERT(ret); // Unclear how to react to this meaningfully. Assume that result will be same as initial AddFont() call.
+    return ret;
 }
 }
 
 
-void ImFontAtlasBuildReloadFont(ImFontAtlas* atlas, ImFontConfig* src)
+// Keep source/input FontData
+void ImFontAtlasBuildDestroyFontOutput(ImFontAtlas* atlas, ImFont* font)
 {
 {
-    // FIXME-NEWATLAS: rebuild single font not supported yet.
-    IM_UNUSED(src);
-    ImFontAtlasBuildReloadAll(atlas);
+    font->ClearOutputData();
+    for (int src_n = 0; src_n < font->SourcesCount; src_n++)
+    {
+        ImFontConfig* src = &font->Sources[src_n];
+        const ImFontLoader* loader = src->FontLoader ? src->FontLoader : atlas->FontLoader;
+        if (loader && loader->FontSrcDestroy != NULL)
+            loader->FontSrcDestroy(atlas, src);
+    }
 }
 }
 
 
 //-----------------------------------------------------------------------------------------------------------------------------
 //-----------------------------------------------------------------------------------------------------------------------------
@@ -4148,13 +4156,8 @@ void ImFontAtlasBuildInit(ImFontAtlas* atlas)
 #else
 #else
         IM_ASSERT(0); // Invalid Build function
         IM_ASSERT(0); // Invalid Build function
 #endif
 #endif
-        return; // ImFontAtlasBuildSetupFontLoader() automatically call ImFontAtlasBuildInit()
     }
     }
 
 
-    IM_ASSERT(atlas->FontLoaderData == NULL);
-    if (atlas->FontLoader->LoaderInit)
-        atlas->FontLoader->LoaderInit(atlas);
-
     // Create initial texture size
     // Create initial texture size
     if (atlas->TexData == NULL || atlas->TexData->Pixels == NULL)
     if (atlas->TexData == NULL || atlas->TexData->Pixels == NULL)
         ImFontAtlasBuildAddTexture(atlas, ImUpperPowerOfTwo(atlas->TexMinWidth), ImUpperPowerOfTwo(atlas->TexMinHeight));
         ImFontAtlasBuildAddTexture(atlas, ImUpperPowerOfTwo(atlas->TexMinWidth), ImUpperPowerOfTwo(atlas->TexMinHeight));
@@ -4165,6 +4168,8 @@ void ImFontAtlasBuildInit(ImFontAtlas* atlas)
     {
     {
         IM_ASSERT(atlas->Builder == NULL);
         IM_ASSERT(atlas->Builder == NULL);
         builder = atlas->Builder = IM_NEW(ImFontAtlasBuilder)();
         builder = atlas->Builder = IM_NEW(ImFontAtlasBuilder)();
+        if (atlas->FontLoader->LoaderInit)
+            atlas->FontLoader->LoaderInit(atlas);
     }
     }
 
 
     ImFontAtlasBuildUpdateRendererHasTexturesFromContext(atlas);
     ImFontAtlasBuildUpdateRendererHasTexturesFromContext(atlas);
@@ -4193,13 +4198,7 @@ void ImFontAtlasBuildInit(ImFontAtlas* atlas)
 void ImFontAtlasBuildDestroy(ImFontAtlas* atlas)
 void ImFontAtlasBuildDestroy(ImFontAtlas* atlas)
 {
 {
     for (ImFont* font : atlas->Fonts)
     for (ImFont* font : atlas->Fonts)
-        font->ClearOutputData();
-    for (ImFontConfig& font_cfg : atlas->Sources)
-    {
-        const ImFontLoader* loader = font_cfg.FontLoader ? font_cfg.FontLoader : atlas->FontLoader;
-        if (loader && loader->FontSrcDestroy != NULL)
-            loader->FontSrcDestroy(atlas, &font_cfg);
-    }
+        ImFontAtlasBuildDestroyFontOutput(atlas, font);
     if (atlas->Builder && atlas->FontLoader && atlas->FontLoader->LoaderShutdown)
     if (atlas->Builder && atlas->FontLoader && atlas->FontLoader->LoaderShutdown)
     {
     {
         atlas->FontLoader->LoaderShutdown(atlas);
         atlas->FontLoader->LoaderShutdown(atlas);

+ 2 - 2
imgui_internal.h

@@ -3774,9 +3774,9 @@ IMGUI_API bool              ImFontAtlasBuildAddFont(ImFontAtlas* atlas, ImFontCo
 IMGUI_API void              ImFontAtlasBuildSetupFontSpecialGlyphs(ImFontAtlas* atlas, ImFont* font, ImFontConfig* src);
 IMGUI_API void              ImFontAtlasBuildSetupFontSpecialGlyphs(ImFontAtlas* atlas, ImFont* font, ImFontConfig* src);
 IMGUI_API void              ImFontAtlasBuildPreloadAllGlyphRanges(ImFontAtlas* atlas); // Legacy
 IMGUI_API void              ImFontAtlasBuildPreloadAllGlyphRanges(ImFontAtlas* atlas); // Legacy
 IMGUI_API void              ImFontAtlasBuildGetOversampleFactors(ImFontConfig* src, float size, int* out_oversample_h, int* out_oversample_v);
 IMGUI_API void              ImFontAtlasBuildGetOversampleFactors(ImFontConfig* src, float size, int* out_oversample_h, int* out_oversample_v);
+IMGUI_API bool              ImFontAtlasBuildInitFontOutput(ImFontAtlas* atlas, ImFont* font); // Using DestroyFontOutput/InitFontOutput sequence useful notably if font loader params have changed
+IMGUI_API void              ImFontAtlasBuildDestroyFontOutput(ImFontAtlas* atlas, ImFont* font);
 IMGUI_API void              ImFontAtlasBuildDestroyFontSourceData(ImFontAtlas* atlas, ImFontConfig* src);
 IMGUI_API void              ImFontAtlasBuildDestroyFontSourceData(ImFontAtlas* atlas, ImFontConfig* src);
-IMGUI_API void              ImFontAtlasBuildReloadAll(ImFontAtlas* atlas);                     // Reinit/rebuild, notably if font loader params have changed.
-IMGUI_API void              ImFontAtlasBuildReloadFont(ImFontAtlas* atlas, ImFontConfig* src); // Reinit/rebuild, notably if font loader params have changed.
 
 
 IMGUI_API ImFontBaked*      ImFontAtlasBuildAddFontBaked(ImFontAtlas* atlas, ImFont* font, float font_size, ImGuiID baked_id);
 IMGUI_API ImFontBaked*      ImFontAtlasBuildAddFontBaked(ImFontAtlas* atlas, ImFont* font, float font_size, ImGuiID baked_id);
 IMGUI_API ImFontBaked*      ImFontAtlasBuildGetClosestFontBakedMatch(ImFontAtlas* atlas, ImFont* font, float font_size);
 IMGUI_API ImFontBaked*      ImFontAtlasBuildGetClosestFontBakedMatch(ImFontAtlas* atlas, ImFont* font, float font_size);