From bc447bc0a4b398f371867ceaa65f26e5c094484f Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Oct 2017 16:08:05 +0200 Subject: [PATCH 1/6] ImFontAtlas: Fixed memory leak if stbtt_InitFont() returned false. (#1391) --- imgui_draw.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index c3a5f3d5..8137f476 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1475,7 +1475,10 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo); IM_ASSERT(font_offset >= 0); if (!stbtt_InitFont(&tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset)) + { + ImGui::MemFree(tmp_array); return false; + } } // Allocate packing character data and flag packed characters buffer as non-packed (x0=y0=x1=y1=0) From 70cb427469de3da6e0d0db8b806c33b2899f08bf Mon Sep 17 00:00:00 2001 From: Patrick Doane Date: Tue, 24 Oct 2017 10:25:02 -0700 Subject: [PATCH 2/6] Add missing CloseClipboard call --- imgui.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index eedd3d86..62959854 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10661,7 +10661,10 @@ static void SetClipboardTextFn_DefaultImpl(void*, const char* text) const int wbuf_length = ImTextCountCharsFromUtf8(text, NULL) + 1; HGLOBAL wbuf_handle = GlobalAlloc(GMEM_MOVEABLE, (SIZE_T)wbuf_length * sizeof(ImWchar)); if (wbuf_handle == NULL) + { + CloseClipboard(); return; + } ImWchar* wbuf_global = (ImWchar*)GlobalLock(wbuf_handle); ImTextStrFromUtf8(wbuf_global, wbuf_length, text, NULL); GlobalUnlock(wbuf_handle); From 7d2cd0e6ff96f8e802a06c79e5946a083d76025c Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Oct 2017 20:19:32 +0200 Subject: [PATCH 3/6] Added IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS support in imconfig.h (#1038) --- imconfig.h | 9 ++++++--- imgui.cpp | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/imconfig.h b/imconfig.h index e557fa06..b175c9b2 100644 --- a/imconfig.h +++ b/imconfig.h @@ -13,6 +13,9 @@ //#define IMGUI_API __declspec( dllexport ) //#define IMGUI_API __declspec( dllimport ) +//---- Don't define obsolete functions names. Consider enabling from time to time or when updating to reduce like hood of using already obsolete function/names +//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS + //---- Include imgui_user.h at the end of imgui.h //#define IMGUI_INCLUDE_IMGUI_USER_H @@ -24,13 +27,13 @@ //---- It is very strongly recommended to NOT disable the test windows. Please read the comment at the top of imgui_demo.cpp to learn why. //#define IMGUI_DISABLE_TEST_WINDOWS -//---- Don't define obsolete functions names. Consider enabling from time to time or when updating to reduce like hood of using already obsolete function/names -//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS +//---- Don't implement ImFormatString(), ImFormatStringV() so you can reimplement them yourself. +//#define IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS //---- Pack colors to BGRA instead of RGBA (remove need to post process vertex buffer in back ends) //#define IMGUI_USE_BGRA_PACKED_COLOR -//---- Implement STB libraries in a namespace to avoid conflicts +//---- Implement STB libraries in a namespace to avoid linkage conflicts //#define IMGUI_STB_NAMESPACE ImGuiStb //---- Define constructor and implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4. diff --git a/imgui.cpp b/imgui.cpp index 62959854..0b56b635 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1011,6 +1011,7 @@ static const char* ImAtoi(const char* src, int* output) // MSVC version appears to return -1 on overflow, whereas glibc appears to return total count (which may be >= buf_size). // Ideally we would test for only one of those limits at runtime depending on the behavior the vsnprintf(), but trying to deduct it at compile time sounds like a pandora can of worm. +#ifndef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS int ImFormatString(char* buf, int buf_size, const char* fmt, ...) { IM_ASSERT(buf_size > 0); @@ -1033,6 +1034,7 @@ int ImFormatStringV(char* buf, int buf_size, const char* fmt, va_list args) buf[w] = 0; return w; } +#endif // #ifdef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS // Pass data_size==0 for zero-terminated strings // FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements. From 8fd5620277f3d89605ff8e2c286d744194f89e25 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Oct 2017 20:23:42 +0200 Subject: [PATCH 4/6] Renamed IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS to IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS for consistency. (ref #238, #520, #738) --- imconfig.h | 4 ++-- imgui.cpp | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/imconfig.h b/imconfig.h index b175c9b2..85eff5fd 100644 --- a/imconfig.h +++ b/imconfig.h @@ -20,8 +20,8 @@ //#define IMGUI_INCLUDE_IMGUI_USER_H //---- Don't implement default handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions) -//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS -//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS +//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS +//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS //---- Don't implement test window functionality (ShowTestWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty) //---- It is very strongly recommended to NOT disable the test windows. Please read the comment at the top of imgui_demo.cpp to learn why. diff --git a/imgui.cpp b/imgui.cpp index 0b56b635..fd1c44de 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -216,6 +216,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/10/24 (1.52) - renamed IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS to IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS for consistency. - 2017/10/20 (1.52) - changed IsWindowHovered() default parameters behavior to return false if an item is active in another window (e.g. click-dragging item from another window to this window). You can use the newly introduced IsWindowHovered() flags to requests this specific behavior if you need it. - 2017/10/20 (1.52) - marked IsItemHoveredRect()/IsMouseHoveringWindow() as obsolete, in favor of using the newly introduced flags for IsItemHovered() and IsWindowHovered(). See https://github.com/ocornut/imgui/issues/1382 for details. removed the IsItemRectHovered()/IsWindowRectHovered() names introduced in 1.51 since they were merely more consistent names for the two functions we are now obsoleting. @@ -10620,14 +10621,14 @@ void ImGui::Value(const char* prefix, float v, const char* float_format) // PLATFORM DEPENDENT HELPERS //----------------------------------------------------------------------------- -#if defined(_WIN32) && !defined(_WINDOWS_) && (!defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS) || !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS)) +#if defined(_WIN32) && !defined(_WINDOWS_) && (!defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS) || !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS)) #undef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #include #endif // Win32 API clipboard implementation -#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS) +#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS) #ifdef _MSC_VER #pragma comment(lib, "user32") @@ -10698,7 +10699,7 @@ static void SetClipboardTextFn_DefaultImpl(void*, const char* text) #endif // Win32 API IME support (for Asian languages, etc.) -#if defined(_WIN32) && !defined(__GNUC__) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS) +#if defined(_WIN32) && !defined(__GNUC__) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS) #include #ifdef _MSC_VER From 1f3372b7f1fbf73a2b701fafbeb0af086d0f508f Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Oct 2017 20:48:29 +0200 Subject: [PATCH 5/6] ImFormatString, ImFormatStringV(): clarifying specs so that passing a NULL buffer should return the desired length. (#1038) --- imgui.cpp | 13 ++++++++----- imgui_demo.cpp | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index fd1c44de..6d2ff61c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1010,16 +1010,18 @@ static const char* ImAtoi(const char* src, int* output) return src; } -// MSVC version appears to return -1 on overflow, whereas glibc appears to return total count (which may be >= buf_size). +// A) MSVC version appears to return -1 on overflow, whereas glibc appears to return total count (which may be >= buf_size). // Ideally we would test for only one of those limits at runtime depending on the behavior the vsnprintf(), but trying to deduct it at compile time sounds like a pandora can of worm. +// B) When buf==NULL vsnprintf() will return the output size. #ifndef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS int ImFormatString(char* buf, int buf_size, const char* fmt, ...) { - IM_ASSERT(buf_size > 0); va_list args; va_start(args, fmt); int w = vsnprintf(buf, buf_size, fmt, args); va_end(args); + if (buf == NULL) + return w; if (w == -1 || w >= buf_size) w = buf_size - 1; buf[w] = 0; @@ -1028,8 +1030,9 @@ int ImFormatString(char* buf, int buf_size, const char* fmt, ...) int ImFormatStringV(char* buf, int buf_size, const char* fmt, va_list args) { - IM_ASSERT(buf_size > 0); int w = vsnprintf(buf, buf_size, fmt, args); + if (buf == NULL) + return w; if (w == -1 || w >= buf_size) w = buf_size - 1; buf[w] = 0; @@ -1671,7 +1674,7 @@ void ImGuiTextBuffer::appendv(const char* fmt, va_list args) va_list args_copy; va_copy(args_copy, args); - int len = vsnprintf(NULL, 0, fmt, args); // FIXME-OPT: could do a first pass write attempt, likely successful on first pass. + int len = ImFormatStringV(NULL, 0, fmt, args); // FIXME-OPT: could do a first pass write attempt, likely successful on first pass. if (len <= 0) return; @@ -1684,7 +1687,7 @@ void ImGuiTextBuffer::appendv(const char* fmt, va_list args) } Buf.resize(needed_sz); - ImFormatStringV(&Buf[write_off] - 1, len+1, fmt, args_copy); + ImFormatStringV(&Buf[write_off - 1], len + 1, fmt, args_copy); } void ImGuiTextBuffer::append(const char* fmt, ...) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 35ee618b..5fe78dbe 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2359,6 +2359,7 @@ struct ExampleAppConsole void AddLog(const char* fmt, ...) IM_FMTARGS(2) { + // FIXME-OPT char buf[1024]; va_list args; va_start(args, fmt); From efcd53a0c31c9f2ae5b2f1d21ab74a18ac1b97f3 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Oct 2017 20:57:41 +0200 Subject: [PATCH 6/6] Removed direct dependency on sprintf() in imgui.cpp (#1038) (NB: imgui_demo stills uses it) --- imgui.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6d2ff61c..90a31c52 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9502,16 +9502,16 @@ void ImGui::ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags) { int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]); char buf[64]; - sprintf(buf, "(%.3ff, %.3ff, %.3ff, %.3ff)", col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]); + ImFormatString(buf, IM_ARRAYSIZE(buf), "(%.3ff, %.3ff, %.3ff, %.3ff)", col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]); if (Selectable(buf)) SetClipboardText(buf); - sprintf(buf, "(%d,%d,%d,%d)", cr, cg, cb, ca); + ImFormatString(buf, IM_ARRAYSIZE(buf), "(%d,%d,%d,%d)", cr, cg, cb, ca); if (Selectable(buf)) SetClipboardText(buf); if (flags & ImGuiColorEditFlags_NoAlpha) - sprintf(buf, "0x%02X%02X%02X", cr, cg, cb); + ImFormatString(buf, IM_ARRAYSIZE(buf), "0x%02X%02X%02X", cr, cg, cb); else - sprintf(buf, "0x%02X%02X%02X%02X", cr, cg, cb, ca); + ImFormatString(buf, IM_ARRAYSIZE(buf), "0x%02X%02X%02X%02X", cr, cg, cb, ca); if (Selectable(buf)) SetClipboardText(buf); EndPopup(); @@ -10789,13 +10789,14 @@ void ImGui::ShowMetricsWindow(bool* p_open) while (clipper.Step()) for (int prim = clipper.DisplayStart, vtx_i = elem_offset + clipper.DisplayStart*3; prim < clipper.DisplayEnd; prim++) { - char buf[300], *buf_p = buf; + char buf[300]; + char *buf_p = buf, *buf_end = buf + IM_ARRAYSIZE(buf); ImVec2 triangles_pos[3]; for (int n = 0; n < 3; n++, vtx_i++) { ImDrawVert& v = draw_list->VtxBuffer[idx_buffer ? idx_buffer[vtx_i] : vtx_i]; triangles_pos[n] = v.pos; - buf_p += sprintf(buf_p, "%s %04d { pos = (%8.2f,%8.2f), uv = (%.6f,%.6f), col = %08X }\n", (n == 0) ? "vtx" : " ", vtx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col); + buf_p += ImFormatString(buf_p, (int)(buf_end - buf_p), "%s %04d { pos = (%8.2f,%8.2f), uv = (%.6f,%.6f), col = %08X }\n", (n == 0) ? "vtx" : " ", vtx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col); } ImGui::Selectable(buf, false); if (ImGui::IsItemHovered())