From fe0d31204e3d530e68e47494b3d46ee3e1728660 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 1 Apr 2021 23:06:39 +0200 Subject: [PATCH] Small optimization of tesselate_text --- epaint/src/tessellator.rs | 14 +++++++++----- epaint/src/text/galley.rs | 16 +++++++++++++++- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/epaint/src/tessellator.rs b/epaint/src/tessellator.rs index b0c0daaf..f560ec6d 100644 --- a/epaint/src/tessellator.rs +++ b/epaint/src/tessellator.rs @@ -638,24 +638,28 @@ impl Tessellator { fake_italics: bool, out: &mut Mesh, ) { - if color == Color32::TRANSPARENT { + if color == Color32::TRANSPARENT || galley.is_empty() { return; } - galley.sanity_check(); + if cfg!(debug_assertions) { + galley.sanity_check(); + } - let num_chars = galley.text.chars().count(); + let num_chars = galley.char_count_excluding_newlines(); out.reserve_triangles(num_chars * 2); out.reserve_vertices(num_chars * 4); let inv_tex_w = 1.0 / tex_size[0] as f32; let inv_tex_h = 1.0 / tex_size[1] as f32; - let clip_rect = self.clip_rect.expand(2.0); // Some fudge to handle letters that are slightly larger than expected. + let clip_slack = 2.0; // Some fudge to handle letters that are slightly larger than expected. + let clip_rect_min_y = self.clip_rect.min.y - clip_slack; + let clip_rect_max_y = self.clip_rect.max.y + clip_slack; for row in &galley.rows { let row_min_y = pos.y + row.y_min; let row_max_y = pos.y + row.y_max; - let is_line_visible = row_max_y >= clip_rect.min.y && row_min_y <= clip_rect.max.y; + let is_line_visible = clip_rect_min_y <= row_max_y && row_min_y <= clip_rect_max_y; if self.options.coarse_tessellation_culling && !is_line_visible { // culling individual lines of text is important, since a single `Shape::Text` diff --git a/epaint/src/text/galley.rs b/epaint/src/text/galley.rs index 4ad62920..f901b912 100644 --- a/epaint/src/text/galley.rs +++ b/epaint/src/text/galley.rs @@ -138,13 +138,27 @@ impl Row { } impl Galley { + #[inline(always)] + pub fn is_empty(&self) -> bool { + self.text.is_empty() + } + + #[inline(always)] + pub(crate) fn char_count_excluding_newlines(&self) -> usize { + let mut char_count = 0; + for row in &self.rows { + char_count += row.char_count_excluding_newline(); + } + char_count + } + pub fn sanity_check(&self) { let mut char_count = 0; for row in &self.rows { row.sanity_check(); char_count += row.char_count_including_newline(); } - assert_eq!(char_count, self.text.chars().count()); + debug_assert_eq!(char_count, self.text.chars().count()); if let Some(last_row) = self.rows.last() { debug_assert!( !last_row.ends_with_newline,