Clean up number rounding. Now it is more obvious what code is doing. (#2862)
Add IM_ROUND() macro
Replace IM_FLOOR(n + 0.5f) and ImFloor(n + 0.5f) with IM_ROUND(n)
diff --git a/imgui.cpp b/imgui.cpp
index facc64d..56ac335 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -4747,8 +4747,8 @@
g.NextWindowData.SizeCallback(&data);
new_size = data.DesiredSize;
}
- new_size.x = ImFloor(new_size.x);
- new_size.y = ImFloor(new_size.y);
+ new_size.x = IM_FLOOR(new_size.x);
+ new_size.y = IM_FLOOR(new_size.y);
}
// Minimum size
@@ -6453,7 +6453,7 @@
if (size.x > 0.0f)
{
window->AutoFitFramesX = 0;
- window->SizeFull.x = ImFloor(size.x);
+ window->SizeFull.x = IM_FLOOR(size.x);
}
else
{
@@ -6463,7 +6463,7 @@
if (size.y > 0.0f)
{
window->AutoFitFramesY = 0;
- window->SizeFull.y = ImFloor(size.y);
+ window->SizeFull.y = IM_FLOOR(size.y);
}
else
{
@@ -8267,7 +8267,7 @@
{
// *Fallback* manual-scroll with Nav directional keys when window has no navigable item
ImGuiWindow* window = g.NavWindow;
- const float scroll_speed = ImFloor(window->CalcFontSize() * 100 * g.IO.DeltaTime + 0.5f); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported.
+ const float scroll_speed = IM_ROUND(window->CalcFontSize() * 100 * g.IO.DeltaTime); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported.
if (window->DC.NavLayerActiveMask == 0x00 && window->DC.NavHasScroll && g.NavMoveRequest)
{
if (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right)
diff --git a/imgui_draw.cpp b/imgui_draw.cpp
index e2b5ee8..544e9f3 100644
--- a/imgui_draw.cpp
+++ b/imgui_draw.cpp
@@ -2069,7 +2069,7 @@
const float descent = ImFloor(unscaled_descent * font_scale + ((unscaled_descent > 0.0f) ? +1 : -1));
ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
const float font_off_x = cfg.GlyphOffset.x;
- const float font_off_y = cfg.GlyphOffset.y + ImFloor(dst_font->Ascent + 0.5f);
+ const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
{
@@ -2591,7 +2591,7 @@
glyph.AdvanceX = advance_x + ConfigData->GlyphExtraSpacing.x; // Bake spacing into AdvanceX
if (ConfigData->PixelSnapH)
- glyph.AdvanceX = IM_FLOOR(glyph.AdvanceX + 0.5f);
+ glyph.AdvanceX = IM_ROUND(glyph.AdvanceX);
// Compute rough surface usage metrics (+1 to account for average padding, +0.99 to round)
DirtyLookupTables = true;
diff --git a/imgui_internal.h b/imgui_internal.h
index f669b18..26660ba 100644
--- a/imgui_internal.h
+++ b/imgui_internal.h
@@ -145,6 +145,7 @@
#define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose
#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255
#define IM_FLOOR(_VAL) ((float)(int)(_VAL)) // ImFloor() is not inlined in MSVC debug builds
+#define IM_ROUND(_VAL) ((float)(int)((_VAL) + 0.5f)) //
// Debug Logging
#ifndef IMGUI_DEBUG_LOG
@@ -262,8 +263,8 @@
static inline float ImLengthSqr(const ImVec2& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y; }
static inline float ImLengthSqr(const ImVec4& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y + lhs.z*lhs.z + lhs.w*lhs.w; }
static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = lhs.x*lhs.x + lhs.y*lhs.y; if (d > 0.0f) return 1.0f / ImSqrt(d); return fail_value; }
-static inline float ImFloor(float f) { return (float)(int)f; }
-static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)v.x, (float)(int)v.y); }
+static inline float ImFloor(float f) { return (float)(int)(f); }
+static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); }
static inline int ImModPositive(int a, int b) { return (a + b) % b; }
static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; }
static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); }
diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp
index 958a690..f31b013 100644
--- a/imgui_widgets.cpp
+++ b/imgui_widgets.cpp
@@ -852,7 +852,7 @@
// Apply scroll
// It is ok to modify Scroll here because we are being called in Begin() after the calculation of ContentSize and before setting up our starting position
const float scroll_v_norm = ImSaturate((clicked_v_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm * 0.5f) / (1.0f - grab_h_norm));
- *p_scroll_v = IM_FLOOR(0.5f + scroll_v_norm * scroll_max);//(win_size_contents_v - win_size_v));
+ *p_scroll_v = IM_ROUND(scroll_v_norm * scroll_max);//(win_size_contents_v - win_size_v));
// Update values for rendering
scroll_ratio = ImSaturate(*p_scroll_v / scroll_max);
@@ -1058,8 +1058,8 @@
return false;
ImVec2 center = check_bb.GetCenter();
- center.x = IM_FLOOR(center.x + 0.5f);
- center.y = IM_FLOOR(center.y + 0.5f);
+ center.x = IM_ROUND(center.x);
+ center.y = IM_ROUND(center.y);
const float radius = (square_sz - 1.0f) * 0.5f;
bool hovered, held;
@@ -4796,13 +4796,13 @@
draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size, sv_picker_size), col_white, hue_color32, hue_color32, col_white);
draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size, sv_picker_size), 0, 0, col_black, col_black);
RenderFrameBorder(picker_pos, picker_pos + ImVec2(sv_picker_size, sv_picker_size), 0.0f);
- sv_cursor_pos.x = ImClamp(IM_FLOOR(picker_pos.x + ImSaturate(S) * sv_picker_size + 0.5f), picker_pos.x + 2, picker_pos.x + sv_picker_size - 2); // Sneakily prevent the circle to stick out too much
- sv_cursor_pos.y = ImClamp(IM_FLOOR(picker_pos.y + ImSaturate(1 - V) * sv_picker_size + 0.5f), picker_pos.y + 2, picker_pos.y + sv_picker_size - 2);
+ sv_cursor_pos.x = ImClamp(IM_ROUND(picker_pos.x + ImSaturate(S) * sv_picker_size), picker_pos.x + 2, picker_pos.x + sv_picker_size - 2); // Sneakily prevent the circle to stick out too much
+ sv_cursor_pos.y = ImClamp(IM_ROUND(picker_pos.y + ImSaturate(1 - V) * sv_picker_size), picker_pos.y + 2, picker_pos.y + sv_picker_size - 2);
// Render Hue Bar
for (int i = 0; i < 6; ++i)
draw_list->AddRectFilledMultiColor(ImVec2(bar0_pos_x, picker_pos.y + i * (sv_picker_size / 6)), ImVec2(bar0_pos_x + bars_width, picker_pos.y + (i + 1) * (sv_picker_size / 6)), col_hues[i], col_hues[i], col_hues[i + 1], col_hues[i + 1]);
- float bar0_line_y = IM_FLOOR(picker_pos.y + H * sv_picker_size + 0.5f);
+ float bar0_line_y = IM_ROUND(picker_pos.y + H * sv_picker_size);
RenderFrameBorder(ImVec2(bar0_pos_x, picker_pos.y), ImVec2(bar0_pos_x + bars_width, picker_pos.y + sv_picker_size), 0.0f);
RenderArrowsForVerticalBar(draw_list, ImVec2(bar0_pos_x - 1, bar0_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f, style.Alpha);
}
@@ -4820,7 +4820,7 @@
ImRect bar1_bb(bar1_pos_x, picker_pos.y, bar1_pos_x + bars_width, picker_pos.y + sv_picker_size);
RenderColorRectWithAlphaCheckerboard(bar1_bb.Min, bar1_bb.Max, 0, bar1_bb.GetWidth() / 2.0f, ImVec2(0.0f, 0.0f));
draw_list->AddRectFilledMultiColor(bar1_bb.Min, bar1_bb.Max, user_col32_striped_of_alpha, user_col32_striped_of_alpha, user_col32_striped_of_alpha & ~IM_COL32_A_MASK, user_col32_striped_of_alpha & ~IM_COL32_A_MASK);
- float bar1_line_y = IM_FLOOR(picker_pos.y + (1.0f - alpha) * sv_picker_size + 0.5f);
+ float bar1_line_y = IM_ROUND(picker_pos.y + (1.0f - alpha) * sv_picker_size);
RenderFrameBorder(bar1_bb.Min, bar1_bb.Max, 0.0f);
RenderArrowsForVerticalBar(draw_list, ImVec2(bar1_pos_x - 1, bar1_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f, style.Alpha);
}
@@ -4877,7 +4877,7 @@
bb_inner.Expand(off);
if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col_rgb.w < 1.0f)
{
- float mid_x = IM_FLOOR((bb_inner.Min.x + bb_inner.Max.x) * 0.5f + 0.5f);
+ float mid_x = IM_ROUND((bb_inner.Min.x + bb_inner.Max.x) * 0.5f);
RenderColorRectWithAlphaCheckerboard(ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col_rgb), grid_step, ImVec2(-grid_step + off, off), rounding, ImDrawCornerFlags_TopRight| ImDrawCornerFlags_BotRight);
window->DrawList->AddRectFilled(bb_inner.Min, ImVec2(mid_x, bb_inner.Max.y), GetColorU32(col_rgb_without_alpha), rounding, ImDrawCornerFlags_TopLeft|ImDrawCornerFlags_BotLeft);
}
@@ -6014,7 +6014,7 @@
// We don't clip with current window clipping rectangle as it is already set to the area below. However we clip with window full rect.
// We remove 1 worth of rounding to Max.x to that text in long menus and small windows don't tend to display over the lower-right rounded area, which looks particularly glitchy.
ImRect bar_rect = window->MenuBarRect();
- ImRect clip_rect(ImFloor(bar_rect.Min.x + 0.5f), ImFloor(bar_rect.Min.y + window->WindowBorderSize + 0.5f), ImFloor(ImMax(bar_rect.Min.x, bar_rect.Max.x - window->WindowRounding) + 0.5f), ImFloor(bar_rect.Max.y + 0.5f));
+ ImRect clip_rect(IM_ROUND(bar_rect.Min.x), IM_ROUND(bar_rect.Min.y + window->WindowBorderSize), IM_ROUND(ImMax(bar_rect.Min.x, bar_rect.Max.x - window->WindowRounding)), IM_ROUND(bar_rect.Max.y));
clip_rect.ClipWith(window->OuterRectClipped);
PushClipRect(clip_rect.Min, clip_rect.Max, false);
@@ -6446,8 +6446,8 @@
const ImU32 col = GetColorU32((flags & ImGuiTabBarFlags_IsFocused) ? ImGuiCol_TabActive : ImGuiCol_TabUnfocusedActive);
const float y = tab_bar->BarRect.Max.y - 1.0f;
{
- const float separator_min_x = tab_bar->BarRect.Min.x - ImFloor(window->WindowPadding.x * 0.5f);
- const float separator_max_x = tab_bar->BarRect.Max.x + ImFloor(window->WindowPadding.x * 0.5f);
+ const float separator_min_x = tab_bar->BarRect.Min.x - IM_FLOOR(window->WindowPadding.x * 0.5f);
+ const float separator_max_x = tab_bar->BarRect.Max.x + IM_FLOOR(window->WindowPadding.x * 0.5f);
window->DrawList->AddLine(ImVec2(separator_min_x, y), ImVec2(separator_max_x, y), col, 1.0f);
}
return true;
@@ -7443,8 +7443,8 @@
{
// Compute clipping rectangle
ImGuiColumnData* column = &columns->Columns[n];
- float clip_x1 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(n));
- float clip_x2 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(n + 1) - 1.0f);
+ float clip_x1 = IM_ROUND(window->Pos.x + GetColumnOffset(n));
+ float clip_x2 = IM_ROUND(window->Pos.x + GetColumnOffset(n + 1) - 1.0f);
column->ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX);
column->ClipRect.ClipWith(window->ClipRect);
}
diff --git a/misc/freetype/imgui_freetype.cpp b/misc/freetype/imgui_freetype.cpp
index 3a89df5..6695fb6 100644
--- a/misc/freetype/imgui_freetype.cpp
+++ b/misc/freetype/imgui_freetype.cpp
@@ -545,7 +545,7 @@
const float descent = src_tmp.Font.Info.Descender;
ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
const float font_off_x = cfg.GlyphOffset.x;
- const float font_off_y = cfg.GlyphOffset.y + IM_FLOOR(dst_font->Ascent + 0.5f);
+ const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
const int padding = atlas->TexGlyphPadding;
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)