From 247214253205e806f8851650cc225de617677532 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 17 Oct 2023 06:08:53 +0200 Subject: [PATCH] Checkpoint --- crates/gpui3/src/elements/text.rs | 15 ++++++++------- crates/gpui3/src/gpui3.rs | 3 ++- crates/gpui3/src/platform.rs | 7 ++++++- crates/gpui3/src/platform/mac/text_system.rs | 6 +++--- crates/gpui3/src/text_system.rs | 11 ++++++----- crates/gpui3/src/text_system/line.rs | 8 ++++---- crates/gpui3/src/text_system/line_wrapper.rs | 12 ++++++------ crates/gpui3/src/text_system/text_layout_cache.rs | 14 +++++++------- 8 files changed, 42 insertions(+), 34 deletions(-) diff --git a/crates/gpui3/src/elements/text.rs b/crates/gpui3/src/elements/text.rs index 2e1254c4ab..356b4c59d6 100644 --- a/crates/gpui3/src/elements/text.rs +++ b/crates/gpui3/src/elements/text.rs @@ -1,12 +1,13 @@ use crate::{ - size, AnyElement, Bounds, Element, IntoAnyElement, LayoutId, Line, Pixels, Size, ViewContext, + size, AnyElement, Bounds, Element, IntoAnyElement, LayoutId, Line, Pixels, SharedString, Size, + ViewContext, }; use parking_lot::Mutex; use smallvec::SmallVec; use std::{marker::PhantomData, sync::Arc}; -use util::{arc_cow::ArcCow, ResultExt}; +use util::ResultExt; -impl IntoAnyElement for ArcCow<'static, str> { +impl IntoAnyElement for SharedString { fn into_any(self) -> AnyElement { Text { text: self, @@ -19,7 +20,7 @@ impl IntoAnyElement for ArcCow<'static, str> { impl IntoAnyElement for &'static str { fn into_any(self) -> AnyElement { Text { - text: ArcCow::from(self), + text: self.into(), state_type: PhantomData, } .into_any() @@ -31,7 +32,7 @@ impl IntoAnyElement for &'static str { impl IntoAnyElement for String { fn into_any(self) -> AnyElement { Text { - text: ArcCow::from(self), + text: self.into(), state_type: PhantomData, } .into_any() @@ -39,7 +40,7 @@ impl IntoAnyElement for String { } pub struct Text { - text: ArcCow<'static, str>, + text: SharedString, state_type: PhantomData, } @@ -78,7 +79,7 @@ impl Element for Text { move |known_dimensions, _| { let Some(lines) = text_system .layout_text( - text.as_ref(), + &text, font_size, &[text_style.to_run(text.len())], known_dimensions.width, // Wrap if we know the width. diff --git a/crates/gpui3/src/gpui3.rs b/crates/gpui3/src/gpui3.rs index dbd14a9675..ea4a15f274 100644 --- a/crates/gpui3/src/gpui3.rs +++ b/crates/gpui3/src/gpui3.rs @@ -51,6 +51,7 @@ pub use util::arc_cow::ArcCow; pub use view::*; pub use window::*; +use derive_more::{Deref, DerefMut}; use std::{ any::{Any, TypeId}, mem, @@ -180,7 +181,7 @@ impl Flatten for Result { } } -#[derive(Clone, Eq, PartialEq, Hash)] +#[derive(Deref, DerefMut, Eq, PartialEq, Hash, Clone)] pub struct SharedString(ArcCow<'static, str>); impl Default for SharedString { diff --git a/crates/gpui3/src/platform.rs b/crates/gpui3/src/platform.rs index 7caf192404..87f88a9702 100644 --- a/crates/gpui3/src/platform.rs +++ b/crates/gpui3/src/platform.rs @@ -171,7 +171,12 @@ 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: &SharedString, + font_size: Pixels, + runs: &[(usize, FontId)], + ) -> 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 659be155f0..0dba74cc78 100644 --- a/crates/gpui3/src/platform/mac/text_system.rs +++ b/crates/gpui3/src/platform/mac/text_system.rs @@ -151,7 +151,7 @@ impl PlatformTextSystem for MacTextSystem { fn layout_line( &self, - text: &str, + text: &SharedString, font_size: Pixels, font_runs: &[(usize, FontId)], ) -> LineLayout { @@ -339,7 +339,7 @@ impl MacTextSystemState { fn layout_line( &mut self, - text: &str, + text: &SharedString, font_size: Pixels, font_runs: &[(usize, FontId)], ) -> LineLayout { @@ -416,12 +416,12 @@ impl MacTextSystemState { let typographic_bounds = line.get_typographic_bounds(); LineLayout { + text: text.clone(), width: typographic_bounds.width.into(), ascent: typographic_bounds.ascent.into(), descent: typographic_bounds.descent.into(), runs, font_size, - len: text.len(), } } diff --git a/crates/gpui3/src/text_system.rs b/crates/gpui3/src/text_system.rs index be6cdef129..331a5702c4 100644 --- a/crates/gpui3/src/text_system.rs +++ b/crates/gpui3/src/text_system.rs @@ -147,7 +147,7 @@ impl TextSystem { pub fn layout_text( &self, - text: &str, + text: &SharedString, font_size: Pixels, runs: &[TextRun], wrap_width: Option, @@ -158,8 +158,9 @@ impl TextSystem { let mut lines = SmallVec::new(); let mut line_start = 0; - for line in text.split('\n') { - let line_end = line_start + line.len(); + for line_text in text.split('\n') { + let line_text = SharedString::from(line_text.to_string()); + let line_end = line_start + line_text.len(); let mut last_font: Option = None; let mut decoration_runs = SmallVec::<[DecorationRun; 32]>::new(); @@ -204,7 +205,7 @@ impl TextSystem { let layout = self .text_layout_cache - .layout_line(line, font_size, &font_runs); + .layout_line(&line_text, font_size, &font_runs); lines.push(Arc::new(Line::new(layout, decoration_runs))); line_start = line_end + 1; // Skip `\n` character. @@ -391,12 +392,12 @@ impl From for GlyphId { #[derive(Default, Debug)] pub struct LineLayout { + pub text: SharedString, pub font_size: Pixels, pub width: Pixels, pub ascent: Pixels, pub descent: Pixels, pub runs: Vec, - pub len: usize, } #[derive(Debug)] diff --git a/crates/gpui3/src/text_system/line.rs b/crates/gpui3/src/text_system/line.rs index e5ccc38c12..0c7f05b2a1 100644 --- a/crates/gpui3/src/text_system/line.rs +++ b/crates/gpui3/src/text_system/line.rs @@ -63,11 +63,11 @@ impl Line { } pub fn len(&self) -> usize { - self.layout.len + self.layout.text.len() } pub fn is_empty(&self) -> bool { - self.layout.len == 0 + self.layout.text.is_empty() } pub fn index_for_x(&self, x: Pixels) -> Option { @@ -139,7 +139,7 @@ impl Line { run_end += style_run.len as usize; color = style_run.color; } else { - run_end = self.layout.len; + run_end = self.layout.text.len(); finished_underline = current_underline.take(); } } @@ -247,7 +247,7 @@ impl Line { )); } } else { - style_run_end = self.layout.len; + style_run_end = self.layout.text.len(); _color = black(); finished_underline = current_underline.take(); } diff --git a/crates/gpui3/src/text_system/line_wrapper.rs b/crates/gpui3/src/text_system/line_wrapper.rs index 2236a0144e..ad6623f8bc 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, Line, Pixels, PlatformTextSystem, ShapedBoundary}; +use crate::{px, FontId, Line, Pixels, PlatformTextSystem, ShapedBoundary, SharedString}; use collections::HashMap; use std::{iter, sync::Arc}; @@ -89,7 +89,7 @@ impl LineWrapper { pub fn wrap_shaped_line<'a>( &'a mut self, - str: &'a str, + str: &'a SharedString, line: &'a Line, wrap_width: Pixels, ) -> impl Iterator + 'a { @@ -183,7 +183,7 @@ impl LineWrapper { fn compute_width_for_char(&self, c: char) -> Pixels { self.platform_text_system - .layout_line(&c.to_string(), self.font_size, &[(1, self.font_id)]) + .layout_line(&c.to_string().into(), self.font_size, &[(1, self.font_id)]) .width } } @@ -295,10 +295,10 @@ mod tests { } } - let text = "aa bbb cccc ddddd eeee"; + let text = "aa bbb cccc ddddd eeee".into(); let lines = text_system .layout_text( - text, + &text, px(16.), &[ normal.with_len(4), @@ -319,7 +319,7 @@ mod tests { ); assert_eq!( wrapper - .wrap_shaped_line(text, &line, px(72.)) + .wrap_shaped_line(&text, &line, px(72.)) .collect::>(), &[ ShapedBoundary { diff --git a/crates/gpui3/src/text_system/text_layout_cache.rs b/crates/gpui3/src/text_system/text_layout_cache.rs index 47e6fa3b47..fe3d46e36c 100644 --- a/crates/gpui3/src/text_system/text_layout_cache.rs +++ b/crates/gpui3/src/text_system/text_layout_cache.rs @@ -1,4 +1,4 @@ -use crate::{FontId, LineLayout, Pixels, PlatformTextSystem, ShapedGlyph, ShapedRun}; +use crate::{FontId, LineLayout, Pixels, PlatformTextSystem, ShapedGlyph, ShapedRun, SharedString}; use parking_lot::{Mutex, RwLock, RwLockUpgradableReadGuard}; use smallvec::SmallVec; use std::{ @@ -30,9 +30,9 @@ impl TextLayoutCache { curr_frame.clear(); } - pub fn layout_line<'a>( - &'a self, - text: &'a str, + pub fn layout_line( + &self, + text: &SharedString, font_size: Pixels, runs: &[(usize, FontId)], ) -> Arc { @@ -53,7 +53,7 @@ impl TextLayoutCache { } else { let layout = Arc::new(self.platform_text_system.layout_line(text, font_size, runs)); let key = CacheKeyValue { - text: text.into(), + text: text.clone(), font_size, runs: SmallVec::from(runs), }; @@ -83,7 +83,7 @@ impl<'a> Hash for (dyn CacheKey + 'a) { #[derive(Eq)] struct CacheKeyValue { - text: String, + text: SharedString, font_size: Pixels, runs: SmallVec<[(usize, FontId); 1]>, } @@ -91,7 +91,7 @@ struct CacheKeyValue { impl CacheKey for CacheKeyValue { fn key(&self) -> CacheKeyRef { CacheKeyRef { - text: self.text.as_str(), + text: &self.text, font_size: self.font_size, runs: self.runs.as_slice(), }