diff --git a/imgui.h b/imgui.h index aa706eb2f..671d25862 100644 --- a/imgui.h +++ b/imgui.h @@ -3444,6 +3444,7 @@ enum ImDrawFlags_ // Stroke options ImDrawFlags_Closed = 1 << 9, // PathStroke(), AddPolyline(): specify that shape should be closed. ImDrawFlags_MiterOnly = 1 << 10, // PathStroke(), AddPolyline(): use miter corners only. This assumes that the input polyline does not have corners sharper than 90 degrees. Slightly faster. + ImDrawFlags_SquareCap = 1 << 11, // PathStroke(), AddPolyline(): use square cap line ends. // Stroke position relative to the shape outline ImDrawFlags_StrokeInside = 1 << 16, // Draw stroke inside of the shape outline (Default) @@ -3540,8 +3541,8 @@ struct ImDrawList IMGUI_API void AddEllipseFilled(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot = 0.0f, int num_segments = 0); IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL); IMGUI_API void AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL); - IMGUI_API void AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0); // Cubic Bezier (4 control points) - IMGUI_API void AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments = 0); // Quadratic Bezier (3 control points) + IMGUI_API void AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0, ImDrawFlags flags = 0); // Cubic Bezier (4 control points) + IMGUI_API void AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments = 0, ImDrawFlags flags = 0); // Quadratic Bezier (3 control points) // General polygon // - Only simple polygons are supported by filling functions (no self-intersections, no holes). diff --git a/imgui_demo.cpp b/imgui_demo.cpp index dd7a11f0d..f5fa6c443 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -10418,6 +10418,7 @@ static void ShowExampleAppCustomRendering(bool* p_open) static bool curve_segments_override = false; static int curve_segments_override_v = 8; static ImVec4 colf = ImVec4(1.0f, 1.0f, 0.4f, 1.0f); + static bool square_caps = false; ImGui::DragFloat("Size", &sz, 0.2f, 0.2f, 100.0f, "%.0f"); ImGui::DragFloat("Thickness", &thickness, 0.05f, 0.0f, 32.0f, "%.02f"); ImGui::SliderInt("N-gon sides", &ngon_sides, 3, 12); @@ -10428,6 +10429,7 @@ static void ShowExampleAppCustomRendering(bool* p_open) ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); curve_segments_override |= ImGui::SliderInt("Curves segments override", &curve_segments_override_v, 3, 40); ImGui::ColorEdit4("Color", &colf.x); + ImGui::Checkbox("Square caps", &square_caps); static ImDrawFlags flags = ImDrawFlags_None; ImGui::AlignTextToFramePadding(); @@ -10443,6 +10445,7 @@ static void ShowExampleAppCustomRendering(bool* p_open) const ImU32 col = ImColor(colf); const float spacing = 10.0f; const ImDrawFlags corners_tl_br = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersBottomRight; + const ImDrawFlags stroke_flags = square_caps ? ImDrawFlags_SquareCap : ImDrawFlags_None; const float rounding = sz / 5.0f; const int circle_segments = circle_segments_override ? circle_segments_override_v : 0; const int curve_segments = curve_segments_override ? curve_segments_override_v : 0; @@ -10467,7 +10470,6 @@ static void ShowExampleAppCustomRendering(bool* p_open) //draw_list->AddPolyline(concave_shape, IM_COUNTOF(concave_shape), col, ImDrawFlags_Closed, th); draw_list->AddLineH(x, x + sz, y, col, th, flags); x += sz + spacing; // Horizontal line (note: drawing a filled rectangle will be faster!) draw_list->AddLineV(x, y, y + sz, col, th, flags); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!) - draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y), col, th, flags); x += sz + spacing; draw_list->AddLine(ImVec2(x, y + sz), ImVec2(x, y), col, th, flags); x += spacing; @@ -10479,11 +10481,11 @@ static void ShowExampleAppCustomRendering(bool* p_open) x += sz + spacing; // Quadratic Bezier Curve (3 control points) - draw_list->AddBezierQuadratic(ImVec2(x + cp3[0].x, y + cp3[0].y), ImVec2(x + cp3[1].x, y + cp3[1].y), ImVec2(x + cp3[2].x, y + cp3[2].y), col, th, curve_segments); + draw_list->AddBezierQuadratic(ImVec2(x + cp3[0].x, y + cp3[0].y), ImVec2(x + cp3[1].x, y + cp3[1].y), ImVec2(x + cp3[2].x, y + cp3[2].y), col, th, curve_segments, stroke_flags); x += sz + spacing; // Cubic Bezier Curve (4 control points) - draw_list->AddBezierCubic(ImVec2(x + cp4[0].x, y + cp4[0].y), ImVec2(x + cp4[1].x, y + cp4[1].y), ImVec2(x + cp4[2].x, y + cp4[2].y), ImVec2(x + cp4[3].x, y + cp4[3].y), col, th, curve_segments); + draw_list->AddBezierCubic(ImVec2(x + cp4[0].x, y + cp4[0].y), ImVec2(x + cp4[1].x, y + cp4[1].y), ImVec2(x + cp4[2].x, y + cp4[2].y), ImVec2(x + cp4[3].x, y + cp4[3].y), col, th, curve_segments, stroke_flags); x = p.x + 4; y += sz + spacing; diff --git a/imgui_draw.cpp b/imgui_draw.cpp index d81ff87a7..6ba00fbf7 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -934,6 +934,8 @@ void ImDrawList::_AddPolylineThin(const ImVec2* points, ImVec2* normals, float* len_sqr1 = sqr_lengths[0]; const ImVec2 dir(n1.y, -n1.x); + if (flags & ImDrawFlags_SquareCap) + p1 -= dir * (half_thickness - half_aa); // At this point half_thickness has half fringe width baked in. const ImVec2 pa = p1 - dir * half_aa; const ImVec2 pb = p1 + dir * half_aa; @@ -1153,6 +1155,8 @@ void ImDrawList::_AddPolylineThin(const ImVec2* points, ImVec2* normals, float* // End cap const ImVec2 dir(n1.y, -n1.x); + if (flags & ImDrawFlags_SquareCap) + p1 += dir * (half_thickness - half_aa); // At this point half_thickness has half fringe width baked in. const ImVec2 pa = p1 - dir * half_aa; const ImVec2 pb = p1 + dir * half_aa; @@ -1247,6 +1251,8 @@ void ImDrawList::_AddPolylineThick(const ImVec2* points, ImVec2* normals, float* // Start cap const ImVec2 dir(n1.y, -n1.x); + if (flags & ImDrawFlags_SquareCap) + p1 -= dir * (half_thickness - half_aa); // At this point half_thickness has half fringe width baked in. const ImVec2 pa = p1 - dir * half_aa; const ImVec2 pb = p1 + dir * half_aa; @@ -1464,6 +1470,8 @@ void ImDrawList::_AddPolylineThick(const ImVec2* points, ImVec2* normals, float* // End cap const ImVec2 dir(n1.y, -n1.x); + if (flags & ImDrawFlags_SquareCap) + p1 += dir * (half_thickness - half_aa); // At this point half_thickness has half fringe width baked in. const ImVec2 pa = p1 - dir * half_aa; const ImVec2 pb = p1 + dir * half_aa; @@ -1857,7 +1865,7 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun _VtxWritePtr += points_count; _VtxCurrentIdx += points_count; - unsigned int prev_outer_idx = (unsigned int )-1; // We dont know oueter vert could yet, will need to patch once we're done. + unsigned int prev_outer_idx = 0; // We dont know outer vert could yet, will need to patch once we're done. const float miter_distance_limit = half_aa * IM_POLYLINE_MITER_LIMIT; const float miter_distance_limit_sqr = miter_distance_limit * miter_distance_limit; @@ -2395,7 +2403,7 @@ void ImDrawList::AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float th if (g_LEGACY_STROKES || stroke_pos == ImDrawFlags_StrokeLegacy) { const ImVec2 points[2] = { ImVec2(p1.x + 0.5f, p1.y + 0.5f), ImVec2(p2.x + 0.5f, p2.y + 0.5f) }; - AddPolyline(points, 2, col, thickness); + AddPolyline(points, 2, col, thickness, ImDrawFlags_StrokeLegacy); return; } @@ -2429,7 +2437,7 @@ void ImDrawList::AddLineH(float min_x, float max_x, float y, ImU32 col, float th if (g_LEGACY_STROKES || stroke_pos == ImDrawFlags_StrokeLegacy) { const ImVec2 points[2] = { ImVec2(min_x + 0.5f, y + 0.5f), ImVec2(max_x + 0.5f, y + 0.5f) }; // Same as AddLine() above. - AddPolyline(points, 2, col, thickness); + AddPolyline(points, 2, col, thickness, ImDrawFlags_StrokeLegacy); return; } @@ -2460,7 +2468,7 @@ void ImDrawList::AddLineV(float x, float min_y, float max_y, ImU32 col, float th if (g_LEGACY_STROKES || stroke_pos == ImDrawFlags_StrokeLegacy) { const ImVec2 points[2] = { ImVec2(x + 0.5f, max_y + 0.5f), ImVec2(x + 0.5f, min_y + 0.5f) }; // Same as AddLine() above. - AddPolyline(points, 2, col, thickness); + AddPolyline(points, 2, col, thickness, ImDrawFlags_StrokeLegacy); return; } @@ -3308,25 +3316,25 @@ void ImDrawList::AddEllipseFilled(const ImVec2& center, const ImVec2& radius, Im } // Cubic Bezier takes 4 controls points -void ImDrawList::AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments) +void ImDrawList::AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments, ImDrawFlags flags) { if ((col & IM_COL32_A_MASK) == 0) return; PathLineTo(p1); PathBezierCubicCurveTo(p2, p3, p4, num_segments); - PathStroke(col, thickness); + PathStroke(col, thickness, flags); } // Quadratic Bezier takes 3 controls points -void ImDrawList::AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments) +void ImDrawList::AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments, ImDrawFlags flags) { if ((col & IM_COL32_A_MASK) == 0) return; PathLineTo(p1); PathBezierQuadraticCurveTo(p2, p3, num_segments); - PathStroke(col, thickness); + PathStroke(col, thickness, flags); } void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect)