From f9f9f0670fb81eb0c9e31ccc68d1104dcaad4883 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Mon, 11 Mar 2024 16:46:20 +0100 Subject: [PATCH] editor: Rearrange float operations in layout (#9176) We were seeing weird layouts with large files, where - starting with some verylargelineindex - lines were rendered at weird y offsets. It turned out that in some cases we're doing operations on Pixel values of different magnitude, which then led to wrong results in calculations. This commit addresses some of these problems, visible at glance when working with large plaintext files. I *did not* dig into things like inlay hints or diagnostics to see if they are subject to the same potential precision loss. Fixes #5371 Release Notes: - Fixed editor layout for large files, where the lines might have been laid out with incorrect Y offset from the top. --- crates/editor/src/element.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index b3fbdf2525..187a23537e 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -856,7 +856,8 @@ impl EditorElement { }; let x = cursor_character_x - scroll_pixel_position.x; - let y = cursor_position.row() as f32 * line_height - scroll_pixel_position.y; + let y = (cursor_position.row() as f32 - scroll_pixel_position.y / line_height) + * line_height; if selection.is_newest { editor.pixel_position_of_newest_cursor = Some(point( text_hitbox.origin.x + x + block_width / 2., @@ -1692,8 +1693,7 @@ impl EditorElement { fn paint_background(&self, layout: &EditorLayout, cx: &mut ElementContext) { cx.paint_layer(layout.hitbox.bounds, |cx| { - let scroll_top = - layout.position_map.snapshot.scroll_position().y * layout.position_map.line_height; + let scroll_top = layout.position_map.snapshot.scroll_position().y; let gutter_bg = cx.theme().colors().editor_gutter_background; cx.paint_quad(fill(layout.gutter_hitbox.bounds, gutter_bg)); cx.paint_quad(fill(layout.text_hitbox.bounds, self.style.background)); @@ -1713,8 +1713,8 @@ impl EditorElement { let origin = point( layout.hitbox.origin.x, layout.hitbox.origin.y - + (layout.position_map.line_height * *start_row as f32) - - scroll_top, + + (*start_row as f32 - scroll_top) + * layout.position_map.line_height, ); let size = size( layout.hitbox.size.width, @@ -1730,8 +1730,8 @@ impl EditorElement { let origin = point( layout.hitbox.origin.x, layout.hitbox.origin.y - + (layout.position_map.line_height * highlight_row_start as f32) - - scroll_top, + + (highlight_row_start as f32 - scroll_top) + * layout.position_map.line_height, ); let size = size( layout.hitbox.size.width, @@ -2779,7 +2779,8 @@ impl LineWithInvisibles { cx: &mut ElementContext, ) { let line_height = layout.position_map.line_height; - let line_y = line_height * row as f32 - layout.position_map.scroll_pixel_position.y; + let line_y = + line_height * (row as f32 - layout.position_map.scroll_pixel_position.y / line_height); self.line .paint(