From bdc35f03f2267f5cfa94cf7478d02a3649ede7d3 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 2 Sep 2021 14:14:05 +0200 Subject: [PATCH] Paint only glyphs that intersect the visible bounds in `Text` Co-Authored-By: Nathan Sobo --- gpui/src/elements/text.rs | 21 ++++++++++++++++----- gpui/src/text_layout.rs | 22 +++++++++++++++------- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/gpui/src/elements/text.rs b/gpui/src/elements/text.rs index 6284fc970473b3981e9b8bcb6b11dfcd3212ad46..400c9d599783f766ae9a894e00e709166ec503f6 100644 --- a/gpui/src/elements/text.rs +++ b/gpui/src/elements/text.rs @@ -82,13 +82,24 @@ impl Element for Text { ) -> Self::PaintState { let mut origin = bounds.origin(); for (line, wrap_boundaries) in &layout.lines { - line.paint_wrapped( + let wrapped_line_boundaries = RectF::new( origin, - layout.line_height, - wrap_boundaries.iter().copied(), - cx, + vec2f( + bounds.width(), + (wrap_boundaries.len() + 1) as f32 * layout.line_height, + ), ); - origin.set_y(origin.y() + (wrap_boundaries.len() + 1) as f32 * layout.line_height); + + if wrapped_line_boundaries.intersects(visible_bounds) { + line.paint_wrapped( + origin, + visible_bounds, + layout.line_height, + wrap_boundaries.iter().copied(), + cx, + ); + } + origin.set_y(wrapped_line_boundaries.max_y()); } } diff --git a/gpui/src/text_layout.rs b/gpui/src/text_layout.rs index 71db39947664c825864ac7e7f9bdbbf051061d3c..8a2bf23b1def73848f565f5522c1c9a1fc22defa 100644 --- a/gpui/src/text_layout.rs +++ b/gpui/src/text_layout.rs @@ -253,6 +253,7 @@ impl Line { pub fn paint_wrapped( &self, origin: Vector2F, + visible_bounds: RectF, line_height: f32, boundaries: impl IntoIterator, cx: &mut PaintContext, @@ -287,13 +288,20 @@ impl Line { } } - cx.scene.push_glyph(scene::Glyph { - font_id: run.font_id, - font_size: self.layout.font_size, - id: glyph.id, - origin: origin + glyph_origin, - color, - }); + let glyph_bounds = RectF::new( + origin + glyph_origin, + cx.font_cache + .bounding_box(run.font_id, self.layout.font_size), + ); + if glyph_bounds.intersects(visible_bounds) { + cx.scene.push_glyph(scene::Glyph { + font_id: run.font_id, + font_size: self.layout.font_size, + id: glyph.id, + origin: origin + glyph_origin, + color, + }); + } } } }