From 9dfa2397deb17cf4fff5302c4ea6ee7eb41917fa Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 14 Feb 2024 11:02:24 +0100 Subject: [PATCH] Internals: Fixed ImFileOpen not working before context is created. (#7314, #7315) Amend daf49e9d8 --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index fc57af2d7..915d02d08 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -59,6 +59,8 @@ Other changes: a wrong viewport if none was initially set. - Backends: DirectX9: Using RGBA format when allowed by the driver to avoid CPU side 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] ----------------------------------------------------------------------- diff --git a/imgui.cpp b/imgui.cpp index 70d11d3ae..2eb615931 100644 --- a/imgui.cpp +++ b/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! const int filename_wsize = ::MultiByteToWideChar(CP_UTF8, 0, filename, -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 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 return fopen(filename, mode); #endif