From 230f826ef560eddecf86c47eec0eac04d1cbf249 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 21 Dec 2017 14:50:58 +0100 Subject: [PATCH 1/6] ImDrawList: Comments --- imgui.cpp | 2 +- imgui.h | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 3c9c1997..5fcd9ee5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -735,7 +735,7 @@ ImGuiStyle::ImGuiStyle() DisplaySafeAreaPadding = ImVec2(4,4); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. AntiAliasedLines = true; // Enable anti-aliasing on lines/borders. Disable if you are really short on CPU/GPU. AntiAliasedShapes = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) - CurveTessellationTol = 1.25f; // Tessellation tolerance. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. + CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. ImGui::StyleColorsClassic(this); } diff --git a/imgui.h b/imgui.h index 4e5203e2..55ac7b20 100644 --- a/imgui.h +++ b/imgui.h @@ -854,7 +854,7 @@ struct ImGuiStyle ImVec2 DisplaySafeAreaPadding; // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. bool AntiAliasedLines; // Enable anti-aliasing on lines/borders. Disable if you are really tight on CPU/GPU. bool AntiAliasedShapes; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) - float CurveTessellationTol; // Tessellation tolerance. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. + float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. ImVec4 Colors[ImGuiCol_COUNT]; IMGUI_API ImGuiStyle(); @@ -1372,15 +1372,14 @@ enum ImDrawCornerFlags_ // Draw command list // This is the low-level list of polygons that ImGui functions are filling. At the end of the frame, all command lists are passed to your ImGuiIO::RenderDrawListFn function for rendering. -// At the moment, each ImGui window contains its own ImDrawList but they could potentially be merged in the future. -// If you want to add custom rendering within a window, you can use ImGui::GetWindowDrawList() to access the current draw list and add your own primitives. +// Each ImGui window contains its own ImDrawList. You can use ImGui::GetWindowDrawList() to access the current window draw list and draw custom primitives. // You can interleave normal ImGui:: calls and adding primitives to the current draw list. // All positions are generally in pixel coordinates (top-left at (0,0), bottom-right at io.DisplaySize), however you are totally free to apply whatever transformation matrix to want to the data (if you apply such transformation you'll want to apply it to ClipRect as well) -// Primitives are always added to the list and not culled (culling is done at higher-level by ImGui:: functions). +// Important: Primitives are always added to the list and not culled (culling is done at higher-level by ImGui:: functions), if you use this API a lot consider coarse culling your drawn objects. struct ImDrawList { // This is what you have to render - ImVector CmdBuffer; // Commands. Typically 1 command = 1 GPU draw call. + ImVector CmdBuffer; // Draw commands. Typically 1 command = 1 GPU draw call, unless the command is a callback. ImVector IdxBuffer; // Index buffer. Each command consume ImDrawCmd::ElemCount of those ImVector VtxBuffer; // Vertex buffer. From 531c11d5c72890f324c9734ef5c860408b8a7f3d Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 21 Dec 2017 18:50:27 +0100 Subject: [PATCH 2/6] ImDrawList: Small refactor toward removing dependency on GImGui + PushClipRectFullscreen now correctly uses data provided by imgui which can takes account of DisplaySize + Removed static variable in PathArcToFast() which caused linking issues to some. --- imgui.cpp | 25 +++++++++++++------- imgui.h | 7 ++++-- imgui_draw.cpp | 59 ++++++++++++++++++++++++------------------------ imgui_internal.h | 23 +++++++++++++++---- 4 files changed, 71 insertions(+), 43 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5fcd9ee5..dbed5341 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1818,7 +1818,7 @@ bool ImGuiListClipper::Step() // ImGuiWindow //----------------------------------------------------------------------------- -ImGuiWindow::ImGuiWindow(const char* name) +ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) { Name = ImStrdup(name); ID = ImHash(name, 0); @@ -1859,7 +1859,7 @@ ImGuiWindow::ImGuiWindow(const char* name) FontWindowScale = 1.0f; DrawList = (ImDrawList*)ImGui::MemAlloc(sizeof(ImDrawList)); - IM_PLACEMENT_NEW(DrawList) ImDrawList(); + IM_PLACEMENT_NEW(DrawList) ImDrawList(&context->DrawListSharedData); DrawList->_OwnerName = Name; ParentWindow = NULL; RootWindow = NULL; @@ -2254,6 +2254,11 @@ ImDrawList* ImGui::GetOverlayDrawList() return &GImGui->OverlayDrawList; } +ImDrawListSharedData* ImGui::GetDrawListSharedData() +{ + return &GImGui->DrawListSharedData; +} + void ImGui::NewFrame() { ImGuiContext& g = *GImGui; @@ -2274,6 +2279,8 @@ void ImGui::NewFrame() SetCurrentFont(GetDefaultFont()); IM_ASSERT(g.Font->IsLoaded()); + g.DrawListSharedData.ClipRectFullscreen = ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y); + g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol; g.Time += g.IO.DeltaTime; g.FrameCount += 1; @@ -4145,7 +4152,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl // Create window the first time ImGuiWindow* window = (ImGuiWindow*)ImGui::MemAlloc(sizeof(ImGuiWindow)); - IM_PLACEMENT_NEW(window) ImGuiWindow(name); + IM_PLACEMENT_NEW(window) ImGuiWindow(&g, name); window->Flags = flags; g.WindowsById.SetVoidPtr(window->ID, window); @@ -5243,7 +5250,11 @@ static void SetCurrentFont(ImFont* font) g.Font = font; g.FontBaseSize = g.IO.FontGlobalScale * g.Font->FontSize * g.Font->Scale; g.FontSize = g.CurrentWindow ? g.CurrentWindow->CalcFontSize() : 0.0f; - g.FontTexUvWhitePixel = g.Font->ContainerAtlas->TexUvWhitePixel; + + ImFontAtlas* atlas = g.Font->ContainerAtlas; + g.DrawListSharedData.TexUvWhitePixel = atlas->TexUvWhitePixel; + g.DrawListSharedData.Font = g.Font; + g.DrawListSharedData.FontSize = g.FontSize; } void ImGui::PushFont(ImFont* font) @@ -5820,7 +5831,7 @@ float ImGui::GetFontSize() ImVec2 ImGui::GetFontTexUvWhitePixel() { - return GImGui->FontTexUvWhitePixel; + return GImGui->DrawListSharedData.TexUvWhitePixel; } void ImGui::SetWindowFontScale(float scale) @@ -10489,7 +10500,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl ImVec2 tra = wheel_center + ImRotate(triangle_pa, cos_hue_angle, sin_hue_angle); ImVec2 trb = wheel_center + ImRotate(triangle_pb, cos_hue_angle, sin_hue_angle); ImVec2 trc = wheel_center + ImRotate(triangle_pc, cos_hue_angle, sin_hue_angle); - ImVec2 uv_white = g.FontTexUvWhitePixel; + ImVec2 uv_white = GetFontTexUvWhitePixel(); draw_list->PrimReserve(6, 6); draw_list->PrimVtx(tra, uv_white, hue_color32); draw_list->PrimVtx(trb, uv_white, hue_color32); @@ -11609,7 +11620,6 @@ void ImGui::ShowMetricsWindow(bool* p_open) return; ImDrawList* overlay_draw_list = &GImGui->OverlayDrawList; // Render additional visuals into the top-most draw list - overlay_draw_list->PushClipRectFullScreen(); int elem_offset = 0; for (const ImDrawCmd* pcmd = draw_list->CmdBuffer.begin(); pcmd < draw_list->CmdBuffer.end(); elem_offset += pcmd->ElemCount, pcmd++) { @@ -11652,7 +11662,6 @@ void ImGui::ShowMetricsWindow(bool* p_open) } ImGui::TreePop(); } - overlay_draw_list->PopClipRect(); ImGui::TreePop(); } diff --git a/imgui.h b/imgui.h index 55ac7b20..c24a8603 100644 --- a/imgui.h +++ b/imgui.h @@ -50,6 +50,7 @@ struct ImDrawChannel; // Temporary storage for outputting drawing struct ImDrawCmd; // A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call) struct ImDrawData; // All draw command lists required to render the frame struct ImDrawList; // A single draw command list (generally one per window) +struct ImDrawListSharedData; // Data shared among multiple draw lists (typically owned by parent ImGui context, but you may create one yourself) struct ImDrawVert; // A single vertex (20 bytes by default, override layout with IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT) struct ImFont; // Runtime data for a single font within a parent ImFontAtlas struct ImFontAtlas; // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF/OTF font loader @@ -466,6 +467,7 @@ namespace ImGui IMGUI_API float GetTime(); IMGUI_API int GetFrameCount(); IMGUI_API ImDrawList* GetOverlayDrawList(); // this draw list will be the last rendered one, useful to quickly draw overlays shapes/text + IMGUI_API ImDrawListSharedData* GetDrawListSharedData(); IMGUI_API const char* GetStyleColorName(ImGuiCol idx); IMGUI_API ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = +0.0f); // utility to find the closest point the last item bounding rectangle edge. useful to visually link items IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f); @@ -1325,7 +1327,7 @@ struct ImDrawCmd ImDrawCallback UserCallback; // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally. void* UserCallbackData; // The draw callback code can access this. - ImDrawCmd() { ElemCount = 0; ClipRect.x = ClipRect.y = -8192.0f; ClipRect.z = ClipRect.w = +8192.0f; TextureId = NULL; UserCallback = NULL; UserCallbackData = NULL; } + ImDrawCmd() { ElemCount = 0; ClipRect.x = ClipRect.y = ClipRect.z = ClipRect.w = 0.0f; TextureId = NULL; UserCallback = NULL; UserCallbackData = NULL; } }; // Vertex index (override with '#define ImDrawIdx unsigned int' inside in imconfig.h) @@ -1384,6 +1386,7 @@ struct ImDrawList ImVector VtxBuffer; // Vertex buffer. // [Internal, used while building lists] + const ImDrawListSharedData* _Data; // Pointer to shared draw data (you can use ImGui::GetDrawListSharedData() to get the one from current ImGui context) const char* _OwnerName; // Pointer to owner window's name for debugging unsigned int _VtxCurrentIdx; // [Internal] == VtxBuffer.Size ImDrawVert* _VtxWritePtr; // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much) @@ -1395,7 +1398,7 @@ struct ImDrawList int _ChannelsCount; // [Internal] number of active channels (1+) ImVector _Channels; // [Internal] draw channels for columns API (not resized down so _ChannelsCount may be smaller than _Channels.Size) - ImDrawList() { _OwnerName = NULL; Clear(); } + ImDrawList(const ImDrawListSharedData* shared_data) { _Data = shared_data; _OwnerName = NULL; Clear(); } ~ImDrawList() { ClearFreeMemory(); } IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) IMGUI_API void PushClipRectFullScreen(); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 69e93689..03ff863c 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -277,10 +277,27 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst) } //----------------------------------------------------------------------------- -// ImDrawList +// ImDrawListData //----------------------------------------------------------------------------- -static const ImVec4 GNullClipRect(-8192.0f, -8192.0f, +8192.0f, +8192.0f); // Large values that are easy to encode in a few bits+shift +ImDrawListSharedData::ImDrawListSharedData() +{ + Font = NULL; + FontSize = 0.0f; + CurveTessellationTol = 0.0f; + ClipRectFullscreen = ImVec4(-8192.0f, -8192.0f, +8192.0f, +8192.0f); + + // Const data + for (int i = 0; i < IM_ARRAYSIZE(CircleVtx12); i++) + { + const float a = ((float)i * 2 * IM_PI) / (float)IM_ARRAYSIZE(CircleVtx12); + CircleVtx12[i] = ImVec2(cosf(a), sinf(a)); + } +} + +//----------------------------------------------------------------------------- +// ImDrawList +//----------------------------------------------------------------------------- void ImDrawList::Clear() { @@ -321,7 +338,7 @@ void ImDrawList::ClearFreeMemory() } // Using macros because C++ is a terrible language, we want guaranteed inline, no code in header, and no overhead in Debug builds -#define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : GNullClipRect) +#define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : _Data->ClipRectFullscreen) #define GetCurrentTextureId() (_TextureIdStack.Size ? _TextureIdStack.Data[_TextureIdStack.Size-1] : NULL) void ImDrawList::AddDrawCmd() @@ -412,8 +429,7 @@ void ImDrawList::PushClipRect(ImVec2 cr_min, ImVec2 cr_max, bool intersect_with_ void ImDrawList::PushClipRectFullScreen() { - PushClipRect(ImVec2(GNullClipRect.x, GNullClipRect.y), ImVec2(GNullClipRect.z, GNullClipRect.w)); - //PushClipRect(GetVisibleRect()); // FIXME-OPT: This would be more correct but we're not supposed to access ImGuiContext from here? + PushClipRect(ImVec2(_Data->ClipRectFullscreen.x, _Data->ClipRectFullscreen.y), ImVec2(_Data->ClipRectFullscreen.z, _Data->ClipRectFullscreen.w)); } void ImDrawList::PopClipRect() @@ -533,7 +549,7 @@ void ImDrawList::PrimReserve(int idx_count, int vtx_count) // Fully unrolled with inline call to keep our debug builds decently fast. void ImDrawList::PrimRect(const ImVec2& a, const ImVec2& c, ImU32 col) { - ImVec2 b(c.x, a.y), d(a.x, c.y), uv(GImGui->FontTexUvWhitePixel); + ImVec2 b(c.x, a.y), d(a.x, c.y), uv(_Data->TexUvWhitePixel); ImDrawIdx idx = (ImDrawIdx)_VtxCurrentIdx; _IdxWritePtr[0] = idx; _IdxWritePtr[1] = (ImDrawIdx)(idx+1); _IdxWritePtr[2] = (ImDrawIdx)(idx+2); _IdxWritePtr[3] = idx; _IdxWritePtr[4] = (ImDrawIdx)(idx+2); _IdxWritePtr[5] = (ImDrawIdx)(idx+3); @@ -581,7 +597,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 if (points_count < 2) return; - const ImVec2 uv = GImGui->FontTexUvWhitePixel; + const ImVec2 uv = _Data->TexUvWhitePixel; anti_aliased &= GImGui->Style.AntiAliasedLines; //if (ImGui::GetIO().KeyCtrl) anti_aliased = false; // Debug @@ -759,7 +775,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col, bool anti_aliased) { - const ImVec2 uv = GImGui->FontTexUvWhitePixel; + const ImVec2 uv = _Data->TexUvWhitePixel; anti_aliased &= GImGui->Style.AntiAliasedShapes; //if (ImGui::GetIO().KeyCtrl) anti_aliased = false; // Debug @@ -842,20 +858,6 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun void ImDrawList::PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12) { - static ImVec2 circle_vtx[12]; - static bool circle_vtx_builds = false; - const int circle_vtx_count = IM_ARRAYSIZE(circle_vtx); - if (!circle_vtx_builds) - { - for (int i = 0; i < circle_vtx_count; i++) - { - const float a = ((float)i / (float)circle_vtx_count) * 2*IM_PI; - circle_vtx[i].x = cosf(a); - circle_vtx[i].y = sinf(a); - } - circle_vtx_builds = true; - } - if (radius == 0.0f || a_min_of_12 > a_max_of_12) { _Path.push_back(centre); @@ -864,7 +866,7 @@ void ImDrawList::PathArcToFast(const ImVec2& centre, float radius, int a_min_of_ _Path.reserve(_Path.Size + (a_max_of_12 - a_min_of_12 + 1)); for (int a = a_min_of_12; a <= a_max_of_12; a++) { - const ImVec2& c = circle_vtx[a % circle_vtx_count]; + const ImVec2& c = _Data->CircleVtx12[a % IM_ARRAYSIZE(_Data->CircleVtx12)]; _Path.push_back(ImVec2(centre.x + c.x * radius, centre.y + c.y * radius)); } } @@ -916,7 +918,7 @@ void ImDrawList::PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImV if (num_segments == 0) { // Auto-tessellated - PathBezierToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, GImGui->Style.CurveTessellationTol, 0); + PathBezierToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->CurveTessellationTol, 0); } else { @@ -998,7 +1000,7 @@ void ImDrawList::AddRectFilledMultiColor(const ImVec2& a, const ImVec2& c, ImU32 if (((col_upr_left | col_upr_right | col_bot_right | col_bot_left) & IM_COL32_A_MASK) == 0) return; - const ImVec2 uv = GImGui->FontTexUvWhitePixel; + const ImVec2 uv = _Data->TexUvWhitePixel; PrimReserve(6, 4); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+1)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+2)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+2)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+3)); @@ -1094,12 +1096,11 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, if (text_begin == text_end) return; - // IMPORTANT: This is one of the few instance of breaking the encapsulation of ImDrawList, as we pull this from ImGui state, but it is just SO useful. - // Might just move Font/FontSize to ImDrawList? + // Pull default font/size from the shared ImDrawListSharedData instance if (font == NULL) - font = GImGui->Font; + font = _Data->Font; if (font_size == 0.0f) - font_size = GImGui->FontSize; + font_size = _Data->FontSize; IM_ASSERT(font->ContainerAtlas->TexID == _TextureIdStack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font. diff --git a/imgui_internal.h b/imgui_internal.h index ed19ba66..ca156367 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -453,6 +453,21 @@ struct ImGuiColumnsSet } }; +struct ImDrawListSharedData +{ + ImVec2 TexUvWhitePixel; // UV of white pixel in the atlas + ImFont* Font; // Current/default font (optional, for simplified AddText overload) + float FontSize; // Current/default font size (optional, for simplified AddText overload) + float CurveTessellationTol; + ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen() + + // Const data + // FIXME: Bake rounded corners fill/borders in atlas + ImVec2 CircleVtx12[12]; + + ImDrawListSharedData(); +}; + // Main state for ImGui struct ImGuiContext { @@ -462,7 +477,7 @@ struct ImGuiContext ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window. float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height. - ImVec2 FontTexUvWhitePixel; // (Shortcut) == Font->TexUvWhitePixel + ImDrawListSharedData DrawListSharedData; float Time; int FrameCount; @@ -574,12 +589,11 @@ struct ImGuiContext int WantTextInputNextFrame; char TempBuffer[1024*3+1]; // temporary text buffer - ImGuiContext() + ImGuiContext() : OverlayDrawList(NULL) { Initialized = false; Font = NULL; FontSize = FontBaseSize = 0.0f; - FontTexUvWhitePixel = ImVec2(0.0f, 0.0f); Time = 0.0f; FrameCount = 0; @@ -639,6 +653,7 @@ struct ImGuiContext OsImePosRequest = OsImePosSet = ImVec2(-1.0f, -1.0f); ModalWindowDarkeningRatio = 0.0f; + OverlayDrawList._Data = &DrawListSharedData; OverlayDrawList._OwnerName = "##Overlay"; // Give it a name for debugging MouseCursor = ImGuiMouseCursor_Arrow; memset(MouseCursorData, 0, sizeof(MouseCursorData)); @@ -805,7 +820,7 @@ struct IMGUI_API ImGuiWindow int FocusIdxTabRequestNext; // " public: - ImGuiWindow(const char* name); + ImGuiWindow(ImGuiContext* context, const char* name); ~ImGuiWindow(); ImGuiID GetID(const char* str, const char* str_end = NULL); From 14cb8177d0939fcdf59252192e7cd68162213c43 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 21 Dec 2017 19:01:53 +0100 Subject: [PATCH 3/6] ImDrawList: Removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Anti-aliasing is controlled via the regular style.AntiAliased flags. --- imgui.cpp | 9 ++++++++- imgui.h | 8 ++++---- imgui_draw.cpp | 8 ++++---- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index dbed5341..e3000c92 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -213,6 +213,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/12/21 (1.53) - removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Anti-aliasing is controlled via the regular style.AntiAliased flags. - 2017/12/14 (1.53) - using the ImGuiWindowFlags_NoScrollWithMouse flag on a child window forwards the mouse wheel event to the parent window, unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set. - 2017/12/13 (1.53) - renamed GetItemsLineHeightWithSpacing() to GetFrameHeightWithSpacing(). Kept redirection function (will obsolete). - 2017/12/13 (1.53) - obsoleted IsRootWindowFocused() in favor of using IsWindowFocused(ImGuiFocusedFlags_RootWindow). Kept redirection function (will obsolete). @@ -11658,7 +11659,13 @@ void ImGui::ShowMetricsWindow(bool* p_open) } ImGui::Selectable(buf, false); if (ImGui::IsItemHovered()) - overlay_draw_list->AddPolyline(triangles_pos, 3, IM_COL32(255,255,0,255), true, 1.0f, false); // Add triangle without AA, more readable for large-thin triangle + { + ImGuiStyle& style = ImGui::GetStyle(); + bool backup_aa_lines = style.AntiAliasedLines; + style.AntiAliasedLines = false; // Disable AA on triangle outlines at is more readable for very large and thin triangles. + overlay_draw_list->AddPolyline(triangles_pos, 3, IM_COL32(255,255,0,255), true, 1.0f); + style.AntiAliasedLines = backup_aa_lines; + } } ImGui::TreePop(); } diff --git a/imgui.h b/imgui.h index c24a8603..2185d066 100644 --- a/imgui.h +++ b/imgui.h @@ -1424,16 +1424,16 @@ struct ImDrawList IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,1), ImU32 col = 0xFFFFFFFF); IMGUI_API void AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,0), const ImVec2& uv_c = ImVec2(1,1), const ImVec2& uv_d = ImVec2(0,1), ImU32 col = 0xFFFFFFFF); IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, float rounding, int rounding_corners = ImDrawCornerFlags_All); - IMGUI_API void AddPolyline(const ImVec2* points, const int num_points, ImU32 col, bool closed, float thickness, bool anti_aliased); - IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col, bool anti_aliased); + IMGUI_API void AddPolyline(const ImVec2* points, const int num_points, ImU32 col, bool closed, float thickness); + IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col); IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0); // Stateful path API, add points then finish with PathFill() or PathStroke() inline void PathClear() { _Path.resize(0); } inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); } inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path[_Path.Size-1], &pos, 8) != 0) _Path.push_back(pos); } - inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col, true); PathClear(); } - inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness, true); PathClear(); } + inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col); PathClear(); } + inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness); PathClear(); } IMGUI_API void PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10); IMGUI_API void PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle IMGUI_API void PathBezierCurveTo(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, int num_segments = 0); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 03ff863c..1136e274 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -592,13 +592,13 @@ void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, c } // TODO: Thickness anti-aliased lines cap are missing their AA fringe. -void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, bool closed, float thickness, bool anti_aliased) +void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, bool closed, float thickness) { if (points_count < 2) return; const ImVec2 uv = _Data->TexUvWhitePixel; - anti_aliased &= GImGui->Style.AntiAliasedLines; + bool anti_aliased = GImGui->Style.AntiAliasedLines; //if (ImGui::GetIO().KeyCtrl) anti_aliased = false; // Debug int count = points_count; @@ -773,10 +773,10 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 } } -void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col, bool anti_aliased) +void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col) { const ImVec2 uv = _Data->TexUvWhitePixel; - anti_aliased &= GImGui->Style.AntiAliasedShapes; + bool anti_aliased = GImGui->Style.AntiAliasedShapes; //if (ImGui::GetIO().KeyCtrl) anti_aliased = false; // Debug if (anti_aliased) From d139bd088df3547377b2ad5e788547447fe18299 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 21 Dec 2017 19:27:06 +0100 Subject: [PATCH 4/6] Begin: Moved modal darkening draw block --- imgui.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e3000c92..1490d042 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4661,16 +4661,16 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window); window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); - // Modal window darkens what is behind them - if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostModalRootWindow()) - window->DrawList->AddRectFilled(fullscreen_rect.Min, fullscreen_rect.Max, GetColorU32(ImGuiCol_ModalWindowDarkening, g.ModalWindowDarkeningRatio)); - // Apply focus, new windows appears in front bool want_focus = false; if (window_just_activated_by_user && !(flags & ImGuiWindowFlags_NoFocusOnAppearing)) if (!(flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip)) || (flags & ImGuiWindowFlags_Popup)) want_focus = true; + // Draw modal window background (darkens what is behind them) + if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostModalRootWindow()) + window->DrawList->AddRectFilled(fullscreen_rect.Min, fullscreen_rect.Max, GetColorU32(ImGuiCol_ModalWindowDarkening, g.ModalWindowDarkeningRatio)); + // Draw window + handle manual resize ImRect title_bar_rect = window->TitleBarRect(); if (window->Collapsed) @@ -11644,6 +11644,8 @@ void ImGui::ShowMetricsWindow(bool* p_open) } if (!pcmd_node_open) continue; + + // Display individual triangles/vertices. Hover on to get the corresponding triangle highlighted. ImGuiListClipper clipper(pcmd->ElemCount/3); // Manually coarse clip our print out of individual vertices to save CPU, only items that may be visible. while (clipper.Step()) for (int prim = clipper.DisplayStart, vtx_i = elem_offset + clipper.DisplayStart*3; prim < clipper.DisplayEnd; prim++) From 996dfb21cf0a2be4b2e09356dc4df9c1ff47ce6c Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 21 Dec 2017 19:48:51 +0100 Subject: [PATCH 5/6] ImDrawList: Added ImDrawListFlags for AA settings. ImDrawList doesn't directly depends on GImGui anymore. --- TODO.txt | 4 +--- imgui.cpp | 16 +++++++++------- imgui.h | 10 +++++++++- imgui_demo.cpp | 2 +- imgui_draw.cpp | 9 +++------ 5 files changed, 23 insertions(+), 18 deletions(-) diff --git a/TODO.txt b/TODO.txt index 41270c4d..c052aeb5 100644 --- a/TODO.txt +++ b/TODO.txt @@ -30,12 +30,10 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i !- scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet. - scrolling/clipping: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y). (2017-08-20: can't repro) - - drawlist: move Font, FontSize, FontTexUvWhitePixel inside ImDrawList and make it self-contained (apart from drawing settings?) - - drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally - drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack. - drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). - - drawlist: avoid passing null (-9999,+9999) rectangle to end-user, instead perhaps pass rectangle based on io.DisplaySize? - drawlist: primtiives/helpers to manipulate vertices post submission, so e.g. a quad/rect can be resized to fit later submitted content, _without_ using the ChannelSplit api + - drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally - drawlist: non-AA strokes have gaps between points (#593, #288), especially RenderCheckmark(). - drawlist: would be good to be able to deep copy a draw list (ImVector= op?). - drawlist/opt: AddRect() axis aligned pixel aligned (no-aa) could use 8 triangles instead of 16 and no normal calculation. diff --git a/imgui.cpp b/imgui.cpp index 1490d042..ce3c09c0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -213,7 +213,8 @@ 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/12/21 (1.53) - removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Anti-aliasing is controlled via the regular style.AntiAliased flags. + - 2017/12/21 (1.53) - renamed style.AntiAliasedShapes to style.AntiAliasedFill for consistency and as a way to explicitly break code that manipulate those flag at runtime. You can now manipulate ImDrawList::Flags + - 2017/12/21 (1.53) - removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Prefer manipulating ImDrawList::Flags. - 2017/12/14 (1.53) - using the ImGuiWindowFlags_NoScrollWithMouse flag on a child window forwards the mouse wheel event to the parent window, unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set. - 2017/12/13 (1.53) - renamed GetItemsLineHeightWithSpacing() to GetFrameHeightWithSpacing(). Kept redirection function (will obsolete). - 2017/12/13 (1.53) - obsoleted IsRootWindowFocused() in favor of using IsWindowFocused(ImGuiFocusedFlags_RootWindow). Kept redirection function (will obsolete). @@ -735,7 +736,7 @@ ImGuiStyle::ImGuiStyle() DisplayWindowPadding = ImVec2(22,22); // Window positions are clamped to be visible within the display area by at least this amount. Only covers regular windows. DisplaySafeAreaPadding = ImVec2(4,4); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. AntiAliasedLines = true; // Enable anti-aliasing on lines/borders. Disable if you are really short on CPU/GPU. - AntiAliasedShapes = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) + AntiAliasedFill = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. ImGui::StyleColorsClassic(this); @@ -2290,6 +2291,7 @@ void ImGui::NewFrame() g.OverlayDrawList.Clear(); g.OverlayDrawList.PushTextureID(g.IO.Fonts->TexID); g.OverlayDrawList.PushClipRectFullScreen(); + g.OverlayDrawList.Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); // Mark rendering data as invalid to prevent user who may have a handle on it to use it g.RenderDrawData.Valid = false; @@ -4475,8 +4477,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->LastFrameActive = current_frame; window->IDStack.resize(1); - // Clear draw list, setup texture, outer clipping rectangle + // Setup draw list and outer clipping rectangle window->DrawList->Clear(); + window->DrawList->Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); ImRect fullscreen_rect(GetVisibleRect()); if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) @@ -11662,11 +11665,10 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGui::Selectable(buf, false); if (ImGui::IsItemHovered()) { - ImGuiStyle& style = ImGui::GetStyle(); - bool backup_aa_lines = style.AntiAliasedLines; - style.AntiAliasedLines = false; // Disable AA on triangle outlines at is more readable for very large and thin triangles. + ImDrawListFlags backup_flags = overlay_draw_list->Flags; + overlay_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines at is more readable for very large and thin triangles. overlay_draw_list->AddPolyline(triangles_pos, 3, IM_COL32(255,255,0,255), true, 1.0f); - style.AntiAliasedLines = backup_aa_lines; + overlay_draw_list->Flags = backup_flags; } } ImGui::TreePop(); diff --git a/imgui.h b/imgui.h index 2185d066..c313080a 100644 --- a/imgui.h +++ b/imgui.h @@ -79,6 +79,7 @@ typedef int ImGuiKey; // enum: a key identifier (ImGui-side enum) typedef int ImGuiMouseCursor; // enum: a mouse cursor identifier // enum ImGuiMouseCursor_ typedef int ImGuiStyleVar; // enum: a variable identifier for styling // enum ImGuiStyleVar_ typedef int ImDrawCornerFlags; // flags: for ImDrawList::AddRect*() etc. // enum ImDrawCornerFlags_ +typedef int ImDrawListFlags; // flags: for ImDrawList // enum ImDrawListFlags_ typedef int ImGuiColorEditFlags; // flags: for ColorEdit*(), ColorPicker*() // enum ImGuiColorEditFlags_ typedef int ImGuiColumnsFlags; // flags: for *Columns*() // enum ImGuiColumnsFlags_ typedef int ImGuiDragDropFlags; // flags: for *DragDrop*() // enum ImGuiDragDropFlags_ @@ -855,7 +856,7 @@ struct ImGuiStyle ImVec2 DisplayWindowPadding; // Window positions are clamped to be visible within the display area by at least this amount. Only covers regular windows. ImVec2 DisplaySafeAreaPadding; // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. bool AntiAliasedLines; // Enable anti-aliasing on lines/borders. Disable if you are really tight on CPU/GPU. - bool AntiAliasedShapes; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) + bool AntiAliasedFill; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. ImVec4 Colors[ImGuiCol_COUNT]; @@ -1372,6 +1373,12 @@ enum ImDrawCornerFlags_ ImDrawCornerFlags_All = 0xF // In your function calls you may use ~0 (= all bits sets) instead of ImDrawCornerFlags_All, as a convenience }; +enum ImDrawListFlags_ +{ + ImDrawListFlags_AntiAliasedLines = 1 << 0, + ImDrawListFlags_AntiAliasedFill = 1 << 1 +}; + // Draw command list // This is the low-level list of polygons that ImGui functions are filling. At the end of the frame, all command lists are passed to your ImGuiIO::RenderDrawListFn function for rendering. // Each ImGui window contains its own ImDrawList. You can use ImGui::GetWindowDrawList() to access the current window draw list and draw custom primitives. @@ -1386,6 +1393,7 @@ struct ImDrawList ImVector VtxBuffer; // Vertex buffer. // [Internal, used while building lists] + ImDrawListFlags Flags; // Flags, you may poke into these to adjust anti-aliasing settings per-primitive. const ImDrawListSharedData* _Data; // Pointer to shared draw data (you can use ImGui::GetDrawListSharedData() to get the one from current ImGui context) const char* _OwnerName; // Pointer to owner window's name for debugging unsigned int _VtxCurrentIdx; // [Internal] == VtxBuffer.Size diff --git a/imgui_demo.cpp b/imgui_demo.cpp index a2bf1be5..4f2705db 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1983,7 +1983,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) if (ImGui::TreeNode("Rendering")) { ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); ImGui::SameLine(); ShowHelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well."); - ImGui::Checkbox("Anti-aliased shapes", &style.AntiAliasedShapes); + ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill); ImGui::PushItemWidth(100); ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, FLT_MAX, NULL, 2.0f); if (style.CurveTessellationTol < 0.0f) style.CurveTessellationTol = 0.10f; diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 1136e274..2ce3c0bd 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -304,6 +304,7 @@ void ImDrawList::Clear() CmdBuffer.resize(0); IdxBuffer.resize(0); VtxBuffer.resize(0); + Flags = ImDrawListFlags_AntiAliasedLines | ImDrawListFlags_AntiAliasedFill; _VtxCurrentIdx = 0; _VtxWritePtr = NULL; _IdxWritePtr = NULL; @@ -598,15 +599,13 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 return; const ImVec2 uv = _Data->TexUvWhitePixel; - bool anti_aliased = GImGui->Style.AntiAliasedLines; - //if (ImGui::GetIO().KeyCtrl) anti_aliased = false; // Debug int count = points_count; if (!closed) count = points_count-1; const bool thick_line = thickness > 1.0f; - if (anti_aliased) + if (Flags & ImDrawListFlags_AntiAliasedLines) { // Anti-aliased stroke const float AA_SIZE = 1.0f; @@ -776,10 +775,8 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col) { const ImVec2 uv = _Data->TexUvWhitePixel; - bool anti_aliased = GImGui->Style.AntiAliasedShapes; - //if (ImGui::GetIO().KeyCtrl) anti_aliased = false; // Debug - if (anti_aliased) + if (Flags & ImDrawListFlags_AntiAliasedFill) { // Anti-aliased Fill const float AA_SIZE = 1.0f; From c8c872c75380f4094665bbebd22089c445fcf9ee Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 21 Dec 2017 13:43:09 +0100 Subject: [PATCH 6/6] Internals: String functions uses size_t in their signature --- imgui.cpp | 18 +++++++++--------- imgui_internal.h | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ce3c09c0..272859c3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -911,17 +911,17 @@ int ImStricmp(const char* str1, const char* str2) return d; } -int ImStrnicmp(const char* str1, const char* str2, int count) +int ImStrnicmp(const char* str1, const char* str2, size_t count) { int d = 0; while (count > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; count--; } return d; } -void ImStrncpy(char* dst, const char* src, int count) +void ImStrncpy(char* dst, const char* src, size_t count) { if (count < 1) return; - strncpy(dst, src, (size_t)count); + strncpy(dst, src, count); dst[count-1] = 0; } @@ -992,7 +992,7 @@ static const char* ImAtoi(const char* src, int* output) // 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, ...) +int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) { va_list args; va_start(args, fmt); @@ -1000,19 +1000,19 @@ int ImFormatString(char* buf, int buf_size, const char* fmt, ...) va_end(args); if (buf == NULL) return w; - if (w == -1 || w >= buf_size) - w = buf_size - 1; + if (w == -1 || w >= (int)buf_size) + w = (int)buf_size - 1; buf[w] = 0; return w; } -int ImFormatStringV(char* buf, int buf_size, const char* fmt, va_list args) +int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) { int w = vsnprintf(buf, buf_size, fmt, args); if (buf == NULL) return w; - if (w == -1 || w >= buf_size) - w = buf_size - 1; + if (w == -1 || w >= (int)buf_size) + w = (int)buf_size - 1; buf[w] = 0; return w; } diff --git a/imgui_internal.h b/imgui_internal.h index ca156367..060b2004 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -103,15 +103,15 @@ IMGUI_API void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec // Helpers: String IMGUI_API int ImStricmp(const char* str1, const char* str2); -IMGUI_API int ImStrnicmp(const char* str1, const char* str2, int count); -IMGUI_API void ImStrncpy(char* dst, const char* src, int count); +IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count); +IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count); IMGUI_API char* ImStrdup(const char* str); IMGUI_API char* ImStrchrRange(const char* str_begin, const char* str_end, char c); IMGUI_API int ImStrlenW(const ImWchar* str); IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end); -IMGUI_API int ImFormatString(char* buf, int buf_size, const char* fmt, ...) IM_FMTARGS(3); -IMGUI_API int ImFormatStringV(char* buf, int buf_size, const char* fmt, va_list args) IM_FMTLIST(3); +IMGUI_API int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) IM_FMTARGS(3); +IMGUI_API int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) IM_FMTLIST(3); // Helpers: Math // We are keeping those not leaking to the user by default, in the case the user has implicit cast operators between ImVec2 and its own types (when IM_VEC2_CLASS_EXTRA is defined)