Fix extraction of font runs from text runs (#40840)

Max Brunsfeld and Mikayla Maki created

Fixes a bug in https://github.com/zed-industries/zed/pull/39928

The bug caused all completions to appear in bold-face

Release Notes:

- Fixed a bug where bold-face font was applied to the wrong characters
in items in the autocomplete menu

Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>

Change summary

crates/gpui/examples/text_layout.rs | 10 ++++++++--
crates/gpui/src/text_system.rs      |  6 ++----
2 files changed, 10 insertions(+), 6 deletions(-)

Detailed changes

crates/gpui/examples/text_layout.rs 🔗

@@ -1,6 +1,6 @@
 use gpui::{
-    App, Application, Bounds, Context, Window, WindowBounds, WindowOptions, div, prelude::*, px,
-    size,
+    App, Application, Bounds, Context, FontStyle, FontWeight, StyledText, Window, WindowBounds,
+    WindowOptions, div, prelude::*, px, size,
 };
 
 struct HelloWorld {}
@@ -71,6 +71,12 @@ impl Render for HelloWorld {
                             .child("100%"),
                     ),
             )
+            .child(div().flex().gap_2().justify_between().child(
+                StyledText::new("ABCD").with_highlights([
+                    (0..1, FontWeight::EXTRA_BOLD.into()),
+                    (2..3, FontStyle::Italic.into()),
+                ]),
+            ))
     }
 }
 

crates/gpui/src/text_system.rs 🔗

@@ -426,7 +426,6 @@ impl WindowTextSystem {
             font_runs.clear();
             let line_end = line_start + line_text.len();
 
-            let mut last_font: Option<FontId> = None;
             let mut decoration_runs = SmallVec::<[DecorationRun; 32]>::new();
             let mut run_start = line_start;
             while run_start < line_end {
@@ -455,14 +454,13 @@ impl WindowTextSystem {
                     true
                 };
 
+                let font_id = self.resolve_font(&run.font);
                 if let Some(font_run) = font_runs.last_mut()
-                    && Some(font_run.font_id) == last_font
+                    && font_id == font_run.font_id
                     && !decoration_changed
                 {
                     font_run.len += run_len_within_line;
                 } else {
-                    let font_id = self.resolve_font(&run.font);
-                    last_font = Some(font_id);
                     font_runs.push(FontRun {
                         len: run_len_within_line,
                         font_id,