Checkpoint

Antonio Scandurra created

Change summary

crates/gpui3/src/platform.rs                 |  4 +-
crates/gpui3/src/platform/mac/text_system.rs | 26 ++++++---------------
crates/gpui3/src/text_system.rs              | 15 +++++------
crates/gpui3/src/text_system/line_layout.rs  | 25 ++++++++------------
crates/gpui3/src/text_system/line_wrapper.rs | 11 +++++++-
5 files changed, 36 insertions(+), 45 deletions(-)

Detailed changes

crates/gpui3/src/platform.rs 🔗

@@ -5,7 +5,7 @@ mod mac;
 mod test;
 
 use crate::{
-    AnyWindowHandle, Bounds, DevicePixels, Event, Executor, Font, FontId, FontMetrics,
+    AnyWindowHandle, Bounds, DevicePixels, Event, Executor, Font, FontId, FontMetrics, FontRun,
     GlobalPixels, GlyphId, LineLayout, Pixels, Point, RenderGlyphParams, RenderImageParams,
     RenderSvgParams, Result, Scene, SharedString, Size,
 };
@@ -171,7 +171,7 @@ pub trait PlatformTextSystem: Send + Sync {
     fn glyph_for_char(&self, font_id: FontId, ch: char) -> Option<GlyphId>;
     fn glyph_raster_bounds(&self, params: &RenderGlyphParams) -> Result<Bounds<DevicePixels>>;
     fn rasterize_glyph(&self, params: &RenderGlyphParams) -> Result<(Size<DevicePixels>, Vec<u8>)>;
-    fn layout_line(&self, text: &str, font_size: Pixels, runs: &[(usize, FontId)]) -> LineLayout;
+    fn layout_line(&self, text: &str, font_size: Pixels, runs: &[FontRun]) -> LineLayout;
     fn wrap_line(
         &self,
         text: &str,

crates/gpui3/src/platform/mac/text_system.rs 🔗

@@ -1,7 +1,7 @@
 use crate::{
-    point, px, size, Bounds, DevicePixels, Font, FontFeatures, FontId, FontMetrics, FontStyle,
-    FontWeight, GlyphId, LineLayout, Pixels, PlatformTextSystem, Point, RenderGlyphParams, Result,
-    ShapedGlyph, ShapedRun, SharedString, Size, SUBPIXEL_VARIANTS,
+    point, px, size, Bounds, DevicePixels, Font, FontFeatures, FontId, FontMetrics, FontRun,
+    FontStyle, FontWeight, GlyphId, LineLayout, Pixels, PlatformTextSystem, Point,
+    RenderGlyphParams, Result, ShapedGlyph, ShapedRun, SharedString, Size, SUBPIXEL_VARIANTS,
 };
 use anyhow::anyhow;
 use cocoa::appkit::{CGFloat, CGPoint};
@@ -149,12 +149,7 @@ impl PlatformTextSystem for MacTextSystem {
         self.0.read().rasterize_glyph(glyph_id)
     }
 
-    fn layout_line(
-        &self,
-        text: &str,
-        font_size: Pixels,
-        font_runs: &[(usize, FontId)],
-    ) -> LineLayout {
+    fn layout_line(&self, text: &str, font_size: Pixels, font_runs: &[FontRun]) -> LineLayout {
         self.0.write().layout_line(text, font_size, font_runs)
     }
 
@@ -337,12 +332,7 @@ impl MacTextSystemState {
         }
     }
 
-    fn layout_line(
-        &mut self,
-        text: &str,
-        font_size: Pixels,
-        font_runs: &[(usize, FontId)],
-    ) -> LineLayout {
+    fn layout_line(&mut self, text: &str, font_size: Pixels, font_runs: &[FontRun]) -> LineLayout {
         // Construct the attributed string, converting UTF8 ranges to UTF16 ranges.
         let mut string = CFMutableAttributedString::new();
         {
@@ -350,8 +340,8 @@ impl MacTextSystemState {
             let utf16_line_len = string.char_len() as usize;
 
             let mut ix_converter = StringIndexConverter::new(text);
-            for (run_len, font_id) in font_runs {
-                let utf8_end = ix_converter.utf8_ix + run_len;
+            for run in font_runs {
+                let utf8_end = ix_converter.utf8_ix + run.len;
                 let utf16_start = ix_converter.utf16_ix;
 
                 if utf16_start >= utf16_line_len {
@@ -364,7 +354,7 @@ impl MacTextSystemState {
                 let cf_range =
                     CFRange::init(utf16_start as isize, (utf16_end - utf16_start) as isize);
 
-                let font: &FontKitFont = &self.fonts[font_id.0];
+                let font: &FontKitFont = &self.fonts[run.font_id.0];
                 unsafe {
                     string.set_attribute(
                         cf_range,

crates/gpui3/src/text_system.rs 🔗

@@ -40,7 +40,7 @@ pub struct TextSystem {
     font_ids_by_font: RwLock<HashMap<Font, FontId>>,
     font_metrics: RwLock<HashMap<FontId, FontMetrics>>,
     wrapper_pool: Mutex<HashMap<FontIdWithSize, Vec<LineWrapper>>>,
-    font_runs_pool: Mutex<Vec<Vec<(usize, FontId)>>>,
+    font_runs_pool: Mutex<Vec<Vec<FontRun>>>,
 }
 
 impl TextSystem {
@@ -153,8 +153,7 @@ impl TextSystem {
         wrap_width: Option<Pixels>,
     ) -> Result<SmallVec<[Line; 1]>> {
         let mut runs = runs.iter().cloned().peekable();
-        let mut font_runs: Vec<(usize, FontId)> =
-            self.font_runs_pool.lock().pop().unwrap_or_default();
+        let mut font_runs = self.font_runs_pool.lock().pop().unwrap_or_default();
 
         let mut lines = SmallVec::new();
         let mut line_start = 0;
@@ -173,13 +172,13 @@ impl TextSystem {
                 let run_len_within_line = cmp::min(line_end, run_start + run.len) - run_start;
 
                 if last_font == Some(run.font.clone()) {
-                    font_runs.last_mut().unwrap().0 += run_len_within_line;
+                    font_runs.last_mut().unwrap().len += run_len_within_line;
                 } else {
                     last_font = Some(run.font.clone());
-                    font_runs.push((
-                        run_len_within_line,
-                        self.platform_text_system.font_id(&run.font)?,
-                    ));
+                    font_runs.push(FontRun {
+                        len: run_len_within_line,
+                        font_id: self.platform_text_system.font_id(&run.font)?,
+                    });
                 }
 
                 if decoration_runs.last().map_or(false, |last_run| {

crates/gpui3/src/text_system/line_layout.rs 🔗

@@ -178,7 +178,7 @@ impl LineLayoutCache {
         &self,
         text: &SharedString,
         font_size: Pixels,
-        runs: &[(usize, FontId)],
+        runs: &[FontRun],
         wrap_width: Option<Pixels>,
     ) -> Arc<WrappedLineLayout> {
         let key = &CacheKeyRef {
@@ -219,6 +219,12 @@ impl LineLayoutCache {
     }
 }
 
+#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
+pub struct FontRun {
+    pub(crate) len: usize,
+    pub(crate) font_id: FontId,
+}
+
 trait AsCacheKeyRef {
     fn as_cache_key_ref(&self) -> CacheKeyRef;
 }
@@ -227,15 +233,15 @@ trait AsCacheKeyRef {
 struct CacheKey {
     text: SharedString,
     font_size: Pixels,
-    runs: SmallVec<[(usize, FontId); 1]>,
+    runs: SmallVec<[FontRun; 1]>,
     wrap_width: Option<Pixels>,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
 struct CacheKeyRef<'a> {
     text: &'a str,
     font_size: Pixels,
-    runs: &'a [(usize, FontId)],
+    runs: &'a [FontRun],
     wrap_width: Option<Pixels>,
 }
 
@@ -287,14 +293,3 @@ impl<'a> AsCacheKeyRef for CacheKeyRef<'a> {
         *self
     }
 }
-
-impl<'a> Hash for CacheKeyRef<'a> {
-    fn hash<H: Hasher>(&self, state: &mut H) {
-        self.text.hash(state);
-        self.font_size.hash(state);
-        for (len, font_id) in self.runs {
-            len.hash(state);
-            font_id.hash(state);
-        }
-    }
-}

crates/gpui3/src/text_system/line_wrapper.rs 🔗

@@ -1,4 +1,4 @@
-use crate::{px, FontId, Pixels, PlatformTextSystem};
+use crate::{px, FontId, FontRun, Pixels, PlatformTextSystem};
 use collections::HashMap;
 use std::{iter, sync::Arc};
 
@@ -112,7 +112,14 @@ impl LineWrapper {
         let mut buffer = [0; 4];
         let buffer = c.encode_utf8(&mut buffer);
         self.platform_text_system
-            .layout_line(buffer, self.font_size, &[(1, self.font_id)])
+            .layout_line(
+                buffer,
+                self.font_size,
+                &[FontRun {
+                    len: 1,
+                    font_id: self.font_id,
+                }],
+            )
             .width
     }
 }