DrawList: consistently support scope flags (ImDrawFlags::Flags) + primitive flags. ImDrawFlags_AAEnds and ImDrawFlags_StrokeLegacy ok. (the most important ones). ImDrawFlags_UseTexForRoundCorners ok. ImDrawFlags_AAFill, ImDrawFlags_AAStrokes: for primitives: only for selected ones taking flags params. Haven't added the flag to all functions because it feels like a fringe use case. ImDrawFlags_TextNoPixelSnap supported in RenderText(), per-prim (9417)
diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index a4b7682..aef92b4 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt
@@ -151,6 +151,7 @@ Unifying them allows easily using them for both per-primitives and scope alterations. - (Breaking) Enabling ImFontAtlasFlags_NoBakedLines in the font atlas will disable support for anti-aliased lines. +- `ImDrawFlags_TextNoPixelSnap` may be passed to low-level RenderText() primitive. (#9417) - Tweaked line rendering in various locations to avoid blurryness: - Windows: title-bar and menu-bar border (when thickness>1.0f). - Tables: borders (when thickness>1.0f).
diff --git a/imgui.h b/imgui.h index fd38c30..1548b69 100644 --- a/imgui.h +++ b/imgui.h
@@ -3373,7 +3373,7 @@ ImVector<ImDrawCmd> CmdBuffer; // Draw commands. Typically 1 command = 1 GPU draw call, unless the command is a callback. ImVector<ImDrawIdx> IdxBuffer; // Index buffer. Each command consume ImDrawCmd::ElemCount of those ImVector<ImDrawVert> VtxBuffer; // Vertex buffer. - ImDrawFlags Flags; // Flags, you may poke into these to adjust anti-aliasing settings per-primitive. + ImDrawFlags Flags; // Current flags for drawing primitives. You may poke into these to adjust anti-aliasing settings per-primitive. Will be exposed as PushDrawFlags(). // [Internal, used while building lists] unsigned int _VtxCurrentIdx; // [Internal] generally == VtxBuffer.Size unless we are past 64K vertices, in which case this gets reset to 0.
diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 1f16f5a..05db80d 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp
@@ -964,7 +964,8 @@ ImVec4 tex_uvs; float fringe; - if (Flags & ImDrawFlags_AALines) + flags |= Flags; + if (flags & ImDrawFlags_AALines) { _SelectFringeTexture(screen_thickness, &tex_uvs, &fringe); } @@ -1306,7 +1307,8 @@ // Read more details near AddRect() + see "API BREAKING CHANGES" section for 1.82, 1.90 and 1.92.8. IM_ASSERT_USER_ERROR_RET((flags & ImDrawFlags_InvalidMask_) == 0, "Incorrect parameter. Did you swap 'thickness' and 'flags'?"); - if (Flags & ImDrawFlags_AALines) + flags |= Flags; + if (flags & ImDrawFlags_AALines) { // Anti-aliased stroke const float AA_SIZE = _FringeScale; @@ -1320,7 +1322,7 @@ // Do we want to draw this line using a texture? // - For now, only draw integer-width lines using textures to avoid issues with the way scaling occurs, could be improved. // - If AA_SIZE is not 1.0f we cannot use the texture path. - const bool use_texture = (Flags & ImDrawFlags_UseTexForStrokeLegacy) && (integer_thickness < IM_DRAWLIST_TEX_LINES_WIDTH_MAX) && (fractional_thickness <= 0.00001f) && (AA_SIZE == 1.0f); + const bool use_texture = (flags & ImDrawFlags_UseTexForStrokeLegacy) && (integer_thickness < IM_DRAWLIST_TEX_LINES_WIDTH_MAX) && (fractional_thickness <= 0.00001f) && (AA_SIZE == 1.0f); // We should never hit this, because NewFrame() doesn't set ImDrawFlags_UseTexForStrokeLegacy unless ImFontAtlasFlags_NoBakedLines is off IM_ASSERT_PARANOID(!use_texture || !(_Data->Font->OwnerAtlas->Flags & ImFontAtlasFlags_NoBakedLines)); @@ -1566,7 +1568,8 @@ }*/ const ImVec2 uv = _Data->TexUvWhitePixel; - if (Flags & ImDrawFlags_AAFill) + flags |= Flags; + if (flags & ImDrawFlags_AAFill) { const float half_aa = _FringeScale * 0.5f; ImU32 col_trans = col & ~IM_COL32_A_MASK; @@ -2173,7 +2176,7 @@ { if (flags & ImDrawFlags_StrokeMask_) return (flags & ImDrawFlags_StrokeMask_); - return _Data->OverrideStrokePos ? _Data->OverrideStrokePos : default_stroke_pos; + return default_stroke_pos; } IM_MSVC_RUNTIME_CHECKS_RESTORE @@ -2201,7 +2204,8 @@ ImVec4 tex_uvs; float fringe; - if (Flags & ImDrawFlags_AALines) + flags |= Flags; + if (flags & ImDrawFlags_AALines) { _SelectFringeTexture(screen_thickness, &tex_uvs, &fringe); } @@ -2339,6 +2343,7 @@ if ((col & IM_COL32_A_MASK) == 0) return; + flags |= Flags; ImDrawFlags stroke_pos = _GetStrokePos(flags, ImDrawFlags_StrokeCenter); if (g_LEGACY_STROKES || stroke_pos == ImDrawFlags_StrokeLegacy) { @@ -2354,6 +2359,7 @@ if ((col & IM_COL32_A_MASK) == 0) return; + flags |= Flags; ImDrawFlags stroke_pos = _GetStrokePos(flags, ImDrawFlags_StrokeInside); if (g_LEGACY_STROKES || stroke_pos == ImDrawFlags_StrokeLegacy) { @@ -2399,6 +2405,7 @@ if ((col & IM_COL32_A_MASK) == 0) return; + flags |= Flags; ImDrawFlags stroke_pos = _GetStrokePos(flags, ImDrawFlags_StrokeInside); if (g_LEGACY_STROKES || stroke_pos == ImDrawFlags_StrokeLegacy) { @@ -2575,7 +2582,8 @@ ImVec4 tex_uvs; float fringe; - if (Flags & ImDrawFlags_AALines) + flags |= Flags; + if (flags & ImDrawFlags_AALines) { _SelectFringeTexture(screen_thickness, &tex_uvs, &fringe); } @@ -2709,6 +2717,7 @@ if ((col & IM_COL32_A_MASK) == 0) return; + flags |= Flags; ImDrawFlags stroke_pos = _GetStrokePos(flags, ImDrawFlags_StrokeInside); if (g_LEGACY_STROKES || stroke_pos == ImDrawFlags_StrokeLegacy) IM_UNLIKELY @@ -2799,7 +2808,7 @@ return; } // Textured corners are baked with AA, do not use them if no-AA is requested. - const bool allow_tex_corners = (Flags & (ImDrawFlags_AALines | ImDrawFlags_UseTexForRoundCorners)) == (ImDrawFlags_AALines | ImDrawFlags_UseTexForRoundCorners); + const bool allow_tex_corners = (flags & (ImDrawFlags_AALines | ImDrawFlags_UseTexForRoundCorners)) == (ImDrawFlags_AALines | ImDrawFlags_UseTexForRoundCorners); if (allow_tex_corners && s_thickness < IM_DRAWLIST_TEX_CORNERS_THICKNESS_MAX && s_rounding <= IM_DRAWLIST_TEX_CORNERS_ROUNDING_MAX) { // Pixel aligned rect with round corners rendered using baked textures. @@ -2897,6 +2906,7 @@ float width = p_max.x - p_min.x; float height = p_max.y - p_min.y; const float min_dim = ImMin(width, height); + flags |= Flags; // The rect is smaller than pixel in one dimension. if (min_dim < _FringeScale) IM_UNLIKELY @@ -2945,7 +2955,7 @@ return; } // Textured corners are baked with AA, do not use them if no-AA is requested. - const bool allow_tex_corners = (Flags & (ImDrawFlags_AAFill | ImDrawFlags_UseTexForRoundCorners)) == (ImDrawFlags_AAFill | ImDrawFlags_UseTexForRoundCorners); + const bool allow_tex_corners = (flags & (ImDrawFlags_AAFill | ImDrawFlags_UseTexForRoundCorners)) == (ImDrawFlags_AAFill | ImDrawFlags_UseTexForRoundCorners); if (allow_tex_corners && s_rounding <= IM_DRAWLIST_TEX_CORNERS_ROUNDING_MAX) { IM_ASSERT_PARANOID(!(_Data->Font->OwnerAtlas->Flags & ImFontAtlasFlags_NoBakedRoundCorners)); @@ -3033,6 +3043,7 @@ if ((col & IM_COL32_A_MASK) == 0) return; + flags |= Flags; ImDrawFlags stroke_pos = _GetStrokePos(flags, ImDrawFlags_StrokeInside); if (g_LEGACY_STROKES || stroke_pos == ImDrawFlags_StrokeLegacy) IM_UNLIKELY { @@ -3117,6 +3128,7 @@ if ((col & IM_COL32_A_MASK) == 0 || num_segments <= 2) return; + flags |= Flags; ImDrawFlags stroke_pos = _GetStrokePos(flags, ImDrawFlags_StrokeInside); if (g_LEGACY_STROKES || stroke_pos == ImDrawFlags_StrokeLegacy) IM_UNLIKELY { @@ -7724,7 +7736,8 @@ float y = pos.y; if (y > clip_rect.w) return; - if ((draw_list->Flags & ImDrawFlags_TextNoPixelSnap) == 0) + flags |= draw_list->Flags; + if ((flags & ImDrawFlags_TextNoPixelSnap) == 0) { x = IM_TRUNC(x); y = IM_TRUNC(y);
diff --git a/imgui_internal.h b/imgui_internal.h index 8466c20..2a246cd 100644 --- a/imgui_internal.h +++ b/imgui_internal.h
@@ -953,7 +953,6 @@ ImFont* Font; // Current font (used for simplified AddText overload) float FontSize; // Current font size (used 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 ImDrawFlags InitialDrawFlags; // Initial flags at the beginning of the frame (it is possible to alter flags on a per-drawlist basis afterwards)