diff --git a/crates/gpui3/src/platform.rs b/crates/gpui3/src/platform.rs index 7caf192404..8bfdfbccfa 100644 --- a/crates/gpui3/src/platform.rs +++ b/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; fn glyph_raster_bounds(&self, params: &RenderGlyphParams) -> Result>; fn rasterize_glyph(&self, params: &RenderGlyphParams) -> Result<(Size, Vec)>; - 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, diff --git a/crates/gpui3/src/platform/mac/text_system.rs b/crates/gpui3/src/platform/mac/text_system.rs index 13c6e815fa..a4c56c3523 100644 --- a/crates/gpui3/src/platform/mac/text_system.rs +++ b/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, diff --git a/crates/gpui3/src/text_system.rs b/crates/gpui3/src/text_system.rs index f3a12f0767..5315e4e357 100644 --- a/crates/gpui3/src/text_system.rs +++ b/crates/gpui3/src/text_system.rs @@ -40,7 +40,7 @@ pub struct TextSystem { font_ids_by_font: RwLock>, font_metrics: RwLock>, wrapper_pool: Mutex>>, - font_runs_pool: Mutex>>, + font_runs_pool: Mutex>>, } impl TextSystem { @@ -153,8 +153,7 @@ impl TextSystem { wrap_width: Option, ) -> Result> { 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| { diff --git a/crates/gpui3/src/text_system/line_layout.rs b/crates/gpui3/src/text_system/line_layout.rs index 97e0272f27..5d83bd69f6 100644 --- a/crates/gpui3/src/text_system/line_layout.rs +++ b/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, ) -> Arc { 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, } -#[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, } @@ -287,14 +293,3 @@ impl<'a> AsCacheKeyRef for CacheKeyRef<'a> { *self } } - -impl<'a> Hash for CacheKeyRef<'a> { - fn hash(&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); - } - } -} diff --git a/crates/gpui3/src/text_system/line_wrapper.rs b/crates/gpui3/src/text_system/line_wrapper.rs index aa2af39a81..3dceec0572 100644 --- a/crates/gpui3/src/text_system/line_wrapper.rs +++ b/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 } }