Browse Source

Fonts: fixed crashing password fields.

# Conflicts:
#	imgui_internal.h
ocornut 4 months ago
parent
commit
cc65015e4e
4 changed files with 30 additions and 22 deletions
  1. 1 1
      imgui.cpp
  2. 1 1
      imgui_draw.cpp
  3. 3 1
      imgui_internal.h
  4. 25 19
      imgui_widgets.cpp

+ 1 - 1
imgui.cpp

@@ -4086,6 +4086,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas)
     MouseCursor = ImGuiMouseCursor_Arrow;
     MouseStationaryTimer = 0.0f;
 
+    InputTextPasswordFontBackupFlags = ImFontFlags_None;
     TempInputId = 0;
     memset(&DataTypeZeroValue, 0, sizeof(DataTypeZeroValue));
     BeginMenuDepth = BeginComboDepth = 0;
@@ -4284,7 +4285,6 @@ void ImGui::Shutdown()
     g.MenusIdSubmittedThisFrame.clear();
     g.InputTextState.ClearFreeMemory();
     g.InputTextDeactivatedState.ClearFreeMemory();
-    g.InputTextPasswordFont.ContainerAtlas = NULL;
 
     g.SettingsWindows.clear();
     g.SettingsHandlers.clear();

+ 1 - 1
imgui_draw.cpp

@@ -4136,7 +4136,7 @@ void ImFontAtlasBuildInit(ImFontAtlas* atlas)
     }
 
     IM_ASSERT(atlas->FontLoaderData == NULL);
-    if (atlas->FontLoader && atlas->FontLoader->LoaderInit)
+    if (atlas->FontLoader->LoaderInit)
         atlas->FontLoader->LoaderInit(atlas);
 
     // Create initial texture size

+ 3 - 1
imgui_internal.h

@@ -2391,7 +2391,8 @@ struct ImGuiContext
     // Widget state
     ImGuiInputTextState     InputTextState;
     ImGuiInputTextDeactivatedState InputTextDeactivatedState;
-    ImFont                  InputTextPasswordFont;
+    ImFontBaked             InputTextPasswordFontBackupBaked;
+    ImFontFlags             InputTextPasswordFontBackupFlags;
     ImGuiID                 TempInputId;                        // Temporary text input when CTRL+clicking on a slider, etc.
     ImGuiDataTypeStorage    DataTypeZeroValue;                  // 0 for all data types
     int                     BeginMenuDepth;
@@ -3112,6 +3113,7 @@ namespace ImGui
     IMGUI_API void          UpdateCurrentFontSize();
     inline ImFont*          GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; }
     IMGUI_API void          PushPasswordFont();
+    IMGUI_API void          PopPasswordFont();
     inline ImDrawList*      GetForegroundDrawList(ImGuiWindow* window) { IM_UNUSED(window); return GetForegroundDrawList(); } // This seemingly unnecessary wrapper simplifies compatibility between the 'master' and 'docking' branches.
     IMGUI_API ImDrawList*   GetBackgroundDrawList(ImGuiViewport* viewport);                     // get background draw list for the given viewport. this draw list will be the first rendering one. Useful to quickly draw shapes/text behind dear imgui contents.
     IMGUI_API ImDrawList*   GetForegroundDrawList(ImGuiViewport* viewport);                     // get foreground draw list for the given viewport. this draw list will be the last rendered one. Useful to quickly draw shapes/text over dear imgui contents.

+ 25 - 19
imgui_widgets.cpp

@@ -4314,23 +4314,29 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
 void ImGui::PushPasswordFont()
 {
     ImGuiContext& g = *GImGui;
-    ImFont* in_font = g.Font;
-    ImFontBaked* in_baked = g.FontBaked;
-    ImFontGlyph glyph = *in_baked->FindGlyph('*');
-    glyph.PackId = -1;
-    ImFont* out_font = &g.InputTextPasswordFont;
-    out_font->Scale = in_font->Scale;
-    out_font->ContainerAtlas = in_font->ContainerAtlas;
-    out_font->Flags |= ImFontFlags_NoLoadGlyphs;
-    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);
-    out_baked->Ascent = in_baked->Ascent;
-    out_baked->Descent = in_baked->Descent;
-    out_baked->Glyphs.resize(0);
-    out_baked->Glyphs.push_back(glyph);
-    out_baked->FallbackGlyphIndex = 0;
-    out_baked->FallbackAdvanceX = glyph.AdvanceX;
-    PushFont(out_font);
+    ImFontBaked* backup = &g.InputTextPasswordFontBackupBaked;
+    IM_ASSERT(backup->IndexAdvanceX.Size == 0 && backup->IndexLookup.Size == 0);
+    ImFontGlyph* glyph = g.FontBaked->FindGlyph('*');
+    g.InputTextPasswordFontBackupFlags = g.Font->Flags;
+    backup->FallbackGlyphIndex = g.FontBaked->FallbackGlyphIndex;
+    backup->FallbackAdvanceX = g.FontBaked->FallbackAdvanceX;
+    backup->IndexLookup.swap(g.FontBaked->IndexLookup);
+    backup->IndexAdvanceX.swap(g.FontBaked->IndexAdvanceX);
+    g.Font->Flags |= ImFontFlags_NoLoadGlyphs;
+    g.FontBaked->FallbackGlyphIndex = g.FontBaked->Glyphs.index_from_ptr(glyph);
+    g.FontBaked->FallbackAdvanceX = glyph->AdvanceX;
+}
+
+void ImGui::PopPasswordFont()
+{
+    ImGuiContext& g = *GImGui;
+    ImFontBaked* backup = &g.InputTextPasswordFontBackupBaked;
+    g.Font->Flags = g.InputTextPasswordFontBackupFlags;
+    g.FontBaked->FallbackGlyphIndex = backup->FallbackGlyphIndex;
+    g.FontBaked->FallbackAdvanceX = backup->FallbackAdvanceX;
+    g.FontBaked->IndexLookup.swap(backup->IndexLookup);
+    g.FontBaked->IndexAdvanceX.swap(backup->IndexAdvanceX);
+    IM_ASSERT(backup->IndexAdvanceX.Size == 0 && backup->IndexLookup.Size == 0);
 }
 
 // Return false to discard a character.
@@ -5232,7 +5238,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
     if (new_is_displaying_hint != is_displaying_hint)
     {
         if (is_password && !is_displaying_hint)
-            PopFont();
+            PopPasswordFont();
         is_displaying_hint = new_is_displaying_hint;
         if (is_password && !is_displaying_hint)
             PushPasswordFont();
@@ -5423,7 +5429,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
     }
 
     if (is_password && !is_displaying_hint)
-        PopFont();
+        PopPasswordFont();
 
     if (is_multiline)
     {