Detailed changes
@@ -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<S: 'static + Send + Sync> IntoAnyElement<S> for ArcCow<'static, str> {
+impl<S: 'static + Send + Sync> IntoAnyElement<S> for SharedString {
fn into_any(self) -> AnyElement<S> {
Text {
text: self,
@@ -19,7 +20,7 @@ impl<S: 'static + Send + Sync> IntoAnyElement<S> for ArcCow<'static, str> {
impl<V: 'static + Send + Sync> IntoAnyElement<V> for &'static str {
fn into_any(self) -> AnyElement<V> {
Text {
- text: ArcCow::from(self),
+ text: self.into(),
state_type: PhantomData,
}
.into_any()
@@ -31,7 +32,7 @@ impl<V: 'static + Send + Sync> IntoAnyElement<V> for &'static str {
impl<S: 'static + Send + Sync> IntoAnyElement<S> for String {
fn into_any(self) -> AnyElement<S> {
Text {
- text: ArcCow::from(self),
+ text: self.into(),
state_type: PhantomData,
}
.into_any()
@@ -39,7 +40,7 @@ impl<S: 'static + Send + Sync> IntoAnyElement<S> for String {
}
pub struct Text<S> {
- text: ArcCow<'static, str>,
+ text: SharedString,
state_type: PhantomData<S>,
}
@@ -78,7 +79,7 @@ impl<S: 'static + Send + Sync> Element for Text<S> {
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.
@@ -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<T> Flatten<T> for Result<T> {
}
}
-#[derive(Clone, Eq, PartialEq, Hash)]
+#[derive(Deref, DerefMut, Eq, PartialEq, Hash, Clone)]
pub struct SharedString(ArcCow<'static, str>);
impl Default for SharedString {
@@ -171,7 +171,12 @@ 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: &SharedString,
+ font_size: Pixels,
+ runs: &[(usize, FontId)],
+ ) -> LineLayout;
fn wrap_line(
&self,
text: &str,
@@ -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(),
}
}
@@ -147,7 +147,7 @@ impl TextSystem {
pub fn layout_text(
&self,
- text: &str,
+ text: &SharedString,
font_size: Pixels,
runs: &[TextRun],
wrap_width: Option<Pixels>,
@@ -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<Font> = 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<u32> 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<ShapedRun>,
- pub len: usize,
}
#[derive(Debug)]
@@ -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<usize> {
@@ -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();
}
@@ -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<Item = ShapedBoundary> + '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::<Vec<_>>(),
&[
ShapedBoundary {
@@ -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<LineLayout> {
@@ -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(),
}