Using _wfopen() under Windows+MSVC because fopen() doesn't support UTF-8 encoding. Wrapped as ImFileOpen(). (#917)

This commit is contained in:
ocornut 2016-11-27 16:43:36 +01:00
parent 9c6048f781
commit 104b381023
2 changed files with 20 additions and 3 deletions

View File

@ -1293,6 +1293,22 @@ void ImGui::ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float&
} }
} }
FILE* ImFileOpen(const char* filename, const char* mode)
{
#ifdef _MSC_VER
// We need a fopen() wrapper because MSVC/Windows fopen doesn't handle UTF-8 filenames. Converting both strings from UTF-8 to wchar format (using a single allocation, because we can)
const int filename_wsize = ImTextCountCharsFromUtf8(filename, NULL) + 1;
const int mode_wsize = ImTextCountCharsFromUtf8(mode, NULL) + 1;
ImVector<ImWchar> buf;
buf.resize(filename_wsize + mode_wsize);
ImTextStrFromUtf8(&buf[0], filename_wsize, filename, NULL);
ImTextStrFromUtf8(&buf[filename_wsize], mode_wsize, mode, NULL);
return _wfopen((wchar_t*)&buf[0], (wchar_t*)&buf[filename_wsize]);
#else
return fopen(filename, mode);
#endif
}
// Load file content into memory // Load file content into memory
// Memory allocated with ImGui::MemAlloc(), must be freed by user using ImGui::MemFree() // Memory allocated with ImGui::MemAlloc(), must be freed by user using ImGui::MemFree()
void* ImLoadFileToMemory(const char* filename, const char* file_open_mode, int* out_file_size, int padding_bytes) void* ImLoadFileToMemory(const char* filename, const char* file_open_mode, int* out_file_size, int padding_bytes)
@ -1302,7 +1318,7 @@ void* ImLoadFileToMemory(const char* filename, const char* file_open_mode, int*
*out_file_size = 0; *out_file_size = 0;
FILE* f; FILE* f;
if ((f = fopen(filename, file_open_mode)) == NULL) if ((f = ImFileOpen(filename, file_open_mode)) == NULL)
return NULL; return NULL;
long file_size_signed; long file_size_signed;
@ -2501,7 +2517,7 @@ static void SaveSettings()
// Write .ini file // Write .ini file
// If a window wasn't opened in this session we preserve its settings // If a window wasn't opened in this session we preserve its settings
FILE* f = fopen(filename, "wt"); FILE* f = ImFileOpen(filename, "wt");
if (!f) if (!f)
return; return;
for (int i = 0; i != g.Settings.Size; i++) for (int i = 0; i != g.Settings.Size; i++)
@ -5784,7 +5800,7 @@ void ImGui::LogToFile(int max_depth, const char* filename)
return; return;
} }
g.LogFile = fopen(filename, "ab"); g.LogFile = ImFileOpen(filename, "ab");
if (!g.LogFile) if (!g.LogFile)
{ {
IM_ASSERT(g.LogFile != NULL); // Consider this an error IM_ASSERT(g.LogFile != NULL); // Consider this an error

View File

@ -89,6 +89,7 @@ IMGUI_API int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, cons
// Helpers: Misc // Helpers: Misc
IMGUI_API ImU32 ImHash(const void* data, int data_size, ImU32 seed = 0); // Pass data_size==0 for zero-terminated strings IMGUI_API ImU32 ImHash(const void* data, int data_size, ImU32 seed = 0); // Pass data_size==0 for zero-terminated strings
IMGUI_API void* ImLoadFileToMemory(const char* filename, const char* file_open_mode, int* out_file_size = NULL, int padding_bytes = 0); IMGUI_API void* ImLoadFileToMemory(const char* filename, const char* file_open_mode, int* out_file_size = NULL, int padding_bytes = 0);
IMGUI_API FILE* ImOpenFile(const char* filename, const char* file_open_mode);
IMGUI_API bool ImIsPointInTriangle(const ImVec2& p, const ImVec2& a, const ImVec2& b, const ImVec2& c); IMGUI_API bool ImIsPointInTriangle(const ImVec2& p, const ImVec2& a, const ImVec2& b, const ImVec2& c);
static inline bool ImCharIsSpace(int c) { return c == ' ' || c == '\t' || c == 0x3000; } static inline bool ImCharIsSpace(int c) { return c == ' ' || c == '\t' || c == 0x3000; }
static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; }