From e8029178b6ca21a6fde6a738ba1d98def1da50d0 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Mon, 16 Dec 2024 16:28:15 +0100 Subject: [PATCH] Reduce aliasing when painting thin box outlines (#5484) * Part of https://github.com/emilk/egui/issues/5164 --- crates/epaint/src/tessellator.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/crates/epaint/src/tessellator.rs b/crates/epaint/src/tessellator.rs index 9821e402..0594c8a2 100644 --- a/crates/epaint/src/tessellator.rs +++ b/crates/epaint/src/tessellator.rs @@ -1277,6 +1277,11 @@ impl Tessellator { ((point * self.pixels_per_point - 0.5).round() + 0.5) / self.pixels_per_point } + #[inline(always)] + pub fn round_pos_to_pixel(&self, pos: Pos2) -> Pos2 { + pos2(self.round_to_pixel(pos.x), self.round_to_pixel(pos.y)) + } + #[inline(always)] pub fn round_pos_to_pixel_center(&self, pos: Pos2) -> Pos2 { pos2( @@ -1702,6 +1707,20 @@ impl Tessellator { self.tessellate_line(line, stroke, out); // …and forth } } else { + let rect = if !stroke.is_empty() && stroke.width < self.feathering { + // Very thin rectangle strokes create extreme aliasing when they move around. + // We can fix that by rounding the rectangle corners to pixel centers. + // TODO(#5164): maybe do this for all shapes and stroke sizes + // TODO(emilk): since we use StrokeKind::Outside, we should probably round the + // corners after offsetting them with half the stroke width (see `translate_stroke_point`). + Rect { + min: self.round_pos_to_pixel_center(rect.min), + max: self.round_pos_to_pixel_center(rect.max), + } + } else { + rect + }; + let path = &mut self.scratchpad_path; path.clear(); path::rounded_rectangle(&mut self.scratchpad_points, rect, rounding);