From c863c1f6a1eb2aba0c017168e105025fe1fda422 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Tue, 29 Oct 2019 17:04:13 +0100 Subject: [PATCH] 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) --- imgui.cpp | 10 +++++----- imgui_draw.cpp | 4 ++-- imgui_internal.h | 5 +++-- imgui_widgets.cpp | 26 +++++++++++++------------- misc/freetype/imgui_freetype.cpp | 2 +- 5 files changed, 24 insertions(+), 23 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index facc64d4..56ac3357 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4747,8 +4747,8 @@ static ImVec2 CalcWindowSizeAfterConstraint(ImGuiWindow* window, ImVec2 new_size 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 @@ void ImGui::SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond con 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 @@ void ImGui::SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond con 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 @@ static void ImGui::NavUpdate() { // *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 e2b5ee86..544e9f3b 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -2069,7 +2069,7 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) 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 @@ void ImFont::AddGlyph(ImWchar codepoint, float x0, float y0, float x1, float y1, 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 f669b18e..26660ba3 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -145,6 +145,7 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer #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 ImSaturate(float f) 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 958a6904..f31b0138 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -852,7 +852,7 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, floa // 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 @@ bool ImGui::RadioButton(const char* label, bool active) 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 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl 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 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl 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 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl 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 @@ bool ImGui::BeginMenuBar() // 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 @@ bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImG 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 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag { // 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 3a89df59..6695fb65 100644 --- a/misc/freetype/imgui_freetype.cpp +++ b/misc/freetype/imgui_freetype.cpp @@ -545,7 +545,7 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns 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++)