Browse Source

Internals: Fixed ImFileOpen not working before context is created. (#7314, #7315)

Amend daf49e9d8
ocornut 1 year ago
parent
commit
9dfa2397de
2 changed files with 14 additions and 6 deletions
  1. 2 0
      docs/CHANGELOG.txt
  2. 12 6
      imgui.cpp

+ 2 - 0
docs/CHANGELOG.txt

@@ -59,6 +59,8 @@ Other changes:
   a wrong viewport if none was initially set.
   a wrong viewport if none was initially set.
 - Backends: DirectX9: Using RGBA format when allowed by the driver to avoid CPU side
 - Backends: DirectX9: Using RGBA format when allowed by the driver to avoid CPU side
   conversion. (#6575) [@Demonese]
   conversion. (#6575) [@Demonese]
+- Internals: Fixed ImFileOpen not working before context is created, preventing creation
+  of a font atlas before main context creation. (#7314, #7315) [@PathogenDavid, @ocornut]
 
 
 
 
 -----------------------------------------------------------------------
 -----------------------------------------------------------------------

+ 12 - 6
imgui.cpp

@@ -2063,12 +2063,18 @@ ImFileHandle ImFileOpen(const char* filename, const char* mode)
     // Previously we used ImTextCountCharsFromUtf8/ImTextStrFromUtf8 here but we now need to support ImWchar16 and ImWchar32!
     // Previously we used ImTextCountCharsFromUtf8/ImTextStrFromUtf8 here but we now need to support ImWchar16 and ImWchar32!
     const int filename_wsize = ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0);
     const int filename_wsize = ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0);
     const int mode_wsize = ::MultiByteToWideChar(CP_UTF8, 0, mode, -1, NULL, 0);
     const int mode_wsize = ::MultiByteToWideChar(CP_UTF8, 0, mode, -1, NULL, 0);
-    ImGuiContext& g = *GImGui;
-    g.TempBuffer.reserve((filename_wsize + mode_wsize) * sizeof(wchar_t));
-    wchar_t* buf = (wchar_t*)(void*)g.TempBuffer.Data;
-    ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, (wchar_t*)&buf[0], filename_wsize);
-    ::MultiByteToWideChar(CP_UTF8, 0, mode, -1, (wchar_t*)&buf[filename_wsize], mode_wsize);
-    return ::_wfopen((const wchar_t*)&buf[0], (const wchar_t*)&buf[filename_wsize]);
+
+    // Use stack buffer if possible, otherwise heap buffer. Sizes include zero terminator.
+    // We don't rely on current ImGuiContext as this is implied to be a helper function which doesn't depend on it (see #7314).
+    wchar_t local_temp_stack[FILENAME_MAX];
+    ImVector<wchar_t> local_temp_heap;
+    if (filename_wsize + mode_wsize > IM_ARRAYSIZE(local_temp_stack))
+        local_temp_heap.resize(filename_wsize + mode_wsize);
+    wchar_t* filename_wbuf = local_temp_heap.Data ? local_temp_heap.Data : local_temp_stack;
+    wchar_t* mode_wbuf = filename_wbuf + filename_wsize;
+    ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, filename_wbuf, filename_wsize);
+    ::MultiByteToWideChar(CP_UTF8, 0, mode, -1, mode_wbuf, mode_wsize);
+    return ::_wfopen(filename_wbuf, mode_wbuf);
 #else
 #else
     return fopen(filename, mode);
     return fopen(filename, mode);
 #endif
 #endif