DrawList: added _GetStrokePos() helper indirection, made flags=0 select default at runtime.

This commit is contained in:
ocornut
2026-05-19 17:40:16 +02:00
parent e3a5cb7278
commit 753cb8474d
4 changed files with 27 additions and 13 deletions

11
imgui.h
View File

@@ -3445,11 +3445,11 @@ enum ImDrawFlags_
//ImDrawFlags_Closed = 1, // Prior to 1.92.8 (May 2026), ImDrawFlags_Closed was guaranteed to be == 1<<0 == 1 for legacy compatibility reason. Hardcoded use of 1 or true should be replaced.
// Stroke position relative to the shape outline
ImDrawFlags_StrokeInside = 0 << 16, // Draw stroke inside of the shape outline (Default)
ImDrawFlags_StrokeCenter = 1 << 16, // Draw stroke at the center of the shape outline
ImDrawFlags_StrokeCenterPixelAligned = 2 << 16, // Draw stroke at the center of the shape outline, so that half thickness (rounded down) will be outside, and rest inside the shape outline.
ImDrawFlags_StrokeOutside = 3 << 16, // Draw stroke outside of the shape outline
ImDrawFlags_StrokeLegacy = 4 << 16, // Use legacy position
ImDrawFlags_StrokeInside = 1 << 16, // Draw stroke inside of the shape outline (Default)
ImDrawFlags_StrokeCenter = 2 << 16, // Draw stroke at the center of the shape outline
ImDrawFlags_StrokeCenterPixelAligned = 3 << 16, // Draw stroke at the center of the shape outline, so that half thickness (rounded down) will be outside, and rest inside the shape outline.
ImDrawFlags_StrokeOutside = 4 << 16, // Draw stroke outside of the shape outline
ImDrawFlags_StrokeLegacy = 5 << 16, // Use legacy position
ImDrawFlags_StrokeMask_ = 0x07 << 16,
ImDrawFlags_InvalidMask_ = ~0x7FFFFFF0, // == 0x8000000F,
@@ -3640,6 +3640,7 @@ struct ImDrawList
IMGUI_API void _OnChangedTexture();
IMGUI_API void _OnChangedVtxOffset();
IMGUI_API void _SetTexture(ImTextureRef tex_ref);
IMGUI_API ImDrawFlags _GetStrokePos(ImDrawFlags flags, ImDrawFlags default_stroke_pos);
IMGUI_API int _CalcCircleAutoSegmentCount(float radius) const;
IMGUI_API void _PathArcToFastEx(const ImVec2& center, float radius, int a_min_sample, int a_max_sample, int a_step);
IMGUI_API void _PathArcToN(const ImVec2& center, float radius, float a_min, float a_max, int num_segments);

View File

@@ -10429,9 +10429,10 @@ static void ShowExampleAppCustomRendering(bool* p_open)
curve_segments_override |= ImGui::SliderInt("Curves segments override", &curve_segments_override_v, 3, 40);
ImGui::ColorEdit4("Color", &colf.x);
static ImDrawFlags flags = 0;
static ImDrawFlags flags = ImDrawFlags_None;
ImGui::AlignTextToFramePadding();
ImGui::Text("Stroke:");
ImGui::SameLine(); ImGui::RadioButton("Default", &flags, ImDrawFlags_None);
ImGui::SameLine(); ImGui::RadioButton("Inside", &flags, ImDrawFlags_StrokeInside);
ImGui::SameLine(); ImGui::RadioButton("Center", &flags, ImDrawFlags_StrokeCenter);
ImGui::SameLine(); ImGui::RadioButton("CenterPixelAligned", &flags, ImDrawFlags_StrokeCenterPixelAligned);

View File

@@ -1512,11 +1512,22 @@ void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, ImDr
extern bool g_LEGACY_STROKES;
// We intently don't turn g_LEGACY_STROKES into ImDrawFlags_StrokeLegacy here.
// The earlier should use verbatim legacy code but will be removed before release once we confirm that both matches.
ImDrawFlags ImDrawList::_GetStrokePos(ImDrawFlags flags, ImDrawFlags default_stroke_pos)
{
if (flags & ImDrawFlags_StrokeMask_)
return (flags & ImDrawFlags_StrokeMask_);
return _Data->OverrideStrokePos ? _Data->OverrideStrokePos : default_stroke_pos;
}
void ImDrawList::AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness, ImDrawFlags flags)
{
if ((col & IM_COL32_A_MASK) == 0)
return;
if (g_LEGACY_STROKES || (flags & ImDrawFlags_StrokeMask_) == ImDrawFlags_StrokeLegacy)
ImDrawFlags stroke_pos = _GetStrokePos(flags, ImDrawFlags_StrokeCenter); // WIP: only Legacy is used.
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);
@@ -1539,7 +1550,7 @@ void ImDrawList::AddLineH(float min_x, float max_x, float y, ImU32 col, float th
return;
}
ImDrawFlags stroke_pos = (flags & ImDrawFlags_StrokeMask_);
ImDrawFlags stroke_pos = _GetStrokePos(flags, ImDrawFlags_StrokeInside);
if (stroke_pos == ImDrawFlags_StrokeCenter)
y -= thickness * 0.5f;
else if (stroke_pos == ImDrawFlags_StrokeCenterPixelAligned)
@@ -1570,7 +1581,7 @@ void ImDrawList::AddLineV(float x, float min_y, float max_y, ImU32 col, float th
return;
}
ImDrawFlags stroke_pos = (flags & ImDrawFlags_StrokeMask_);
ImDrawFlags stroke_pos = _GetStrokePos(flags, ImDrawFlags_StrokeInside);
if (stroke_pos == ImDrawFlags_StrokeCenter)
x -= thickness * 0.5f;
else if (stroke_pos == ImDrawFlags_StrokeCenterPixelAligned)
@@ -1736,7 +1747,7 @@ void ImDrawList::AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, fl
}
const bool is_truncated = _FringeScaleIsInteger && ImIsTruncated4(p_min.x, p_min.y, p_max.x, p_max.y) && ImIsTruncated4(rounding, thickness, 0.0f, 0.0f);
ImDrawFlags stroke_pos = (flags & ImDrawFlags_StrokeMask_);
ImDrawFlags stroke_pos = _GetStrokePos(flags, ImDrawFlags_StrokeInside);
if ((stroke_pos == ImDrawFlags_StrokeInside || stroke_pos == ImDrawFlags_StrokeOutside || stroke_pos == ImDrawFlags_StrokeCenterPixelAligned) && is_truncated)
{
if ((flags & ImDrawFlags_RoundCornersMask_) == 0)
@@ -2011,7 +2022,7 @@ void ImDrawList::AddCircle(const ImVec2& center, float radius, ImU32 col, int nu
}
else
{
const ImDrawFlags stroke_pos = (flags & ImDrawFlags_StrokeMask_);
ImDrawFlags stroke_pos = _GetStrokePos(flags, ImDrawFlags_StrokeInside);
if (stroke_pos == ImDrawFlags_StrokeInside)
radius -= thickness * 0.5f;
else if (stroke_pos == ImDrawFlags_StrokeCenterPixelAligned)
@@ -2077,7 +2088,7 @@ void ImDrawList::AddNgon(const ImVec2& center, float radius, ImU32 col, int num_
}
else
{
const ImDrawFlags stroke_pos = (flags & ImDrawFlags_StrokeMask_);
ImDrawFlags stroke_pos = _GetStrokePos(flags, ImDrawFlags_StrokeInside);
if (stroke_pos == ImDrawFlags_StrokeInside)
radius -= thickness * 0.5f;
else if (stroke_pos == ImDrawFlags_StrokeCenterPixelAligned)
@@ -2120,7 +2131,7 @@ void ImDrawList::AddEllipse(const ImVec2& center, const ImVec2& radius, ImU32 co
else
{
r = radius;
ImDrawFlags stroke_pos = (flags & ImDrawFlags_StrokeMask_);
ImDrawFlags stroke_pos = _GetStrokePos(flags, ImDrawFlags_StrokeInside);
if (stroke_pos == ImDrawFlags_StrokeInside)
r -= ImVec2(thickness * 0.5f, thickness * 0.5f);
else if (stroke_pos == ImDrawFlags_StrokeCenterPixelAligned)

View File

@@ -925,6 +925,7 @@ struct IMGUI_API ImDrawListSharedData
ImFont* Font; // Current font (used for simplified AddText overload)
float FontSize; // Current font size (used for for simplified AddText overload)
float FontScale; // Current font scale (== FontSize / Font->FontSize)
ImDrawFlags OverrideStrokePos; // Override default StrokePos when not specified by an individual primitive. == 0 or ImDrawFlags_StrokeLegacy only.
float CurveTessellationMaxError; // Tessellation tolerance when using PathBezierCurveTo()
float CircleTessellationMaxError; // Number of circle segments to use per pixel of radius for AddCircle() etc
ImDrawListFlags InitialFlags; // Initial flags at the beginning of the frame (it is possible to alter flags on a per-drawlist basis afterwards)