Checkpoint
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
use crate::{px, Font, Line, Pixels, PlatformTextSystem, RunStyle, ShapedBoundary};
|
||||
use crate::{px, FontId, Line, Pixels, PlatformTextSystem, ShapedBoundary};
|
||||
use collections::HashMap;
|
||||
use std::{iter, sync::Arc};
|
||||
|
||||
pub struct LineWrapper {
|
||||
text_system: Arc<dyn PlatformTextSystem>,
|
||||
pub(crate) font: Font,
|
||||
platform_text_system: Arc<dyn PlatformTextSystem>,
|
||||
pub(crate) font_id: FontId,
|
||||
pub(crate) font_size: Pixels,
|
||||
cached_ascii_char_widths: [Option<Pixels>; 128],
|
||||
cached_other_char_widths: HashMap<char, Pixels>,
|
||||
@@ -13,10 +13,14 @@ pub struct LineWrapper {
|
||||
impl LineWrapper {
|
||||
pub const MAX_INDENT: u32 = 256;
|
||||
|
||||
pub fn new(font: Font, font_size: Pixels, text_system: Arc<dyn PlatformTextSystem>) -> Self {
|
||||
pub fn new(
|
||||
font_id: FontId,
|
||||
font_size: Pixels,
|
||||
text_system: Arc<dyn PlatformTextSystem>,
|
||||
) -> Self {
|
||||
Self {
|
||||
text_system,
|
||||
font,
|
||||
platform_text_system: text_system,
|
||||
font_id,
|
||||
font_size,
|
||||
cached_ascii_char_widths: [None; 128],
|
||||
cached_other_char_widths: HashMap::default(),
|
||||
@@ -178,19 +182,8 @@ impl LineWrapper {
|
||||
}
|
||||
|
||||
fn compute_width_for_char(&self, c: char) -> Pixels {
|
||||
self.text_system
|
||||
.layout_line(
|
||||
&c.to_string(),
|
||||
self.font_size,
|
||||
&[(
|
||||
1,
|
||||
RunStyle {
|
||||
font: self.font.clone(),
|
||||
color: Default::default(),
|
||||
underline: Default::default(),
|
||||
},
|
||||
)],
|
||||
)
|
||||
self.platform_text_system
|
||||
.layout_line(&c.to_string(), self.font_size, &[(1, self.font_id)])
|
||||
.width
|
||||
}
|
||||
}
|
||||
@@ -210,14 +203,14 @@ impl Boundary {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{font, App};
|
||||
use crate::{font, App, RunStyle};
|
||||
|
||||
#[test]
|
||||
fn test_wrap_line() {
|
||||
App::test().run(|cx| {
|
||||
let text_system = cx.text_system().clone();
|
||||
let mut wrapper = LineWrapper::new(
|
||||
font("Courier"),
|
||||
text_system.font_id(&font("Courier")).unwrap(),
|
||||
px(16.),
|
||||
text_system.platform_text_system.clone(),
|
||||
);
|
||||
@@ -293,20 +286,22 @@ mod tests {
|
||||
};
|
||||
|
||||
let text = "aa bbb cccc ddddd eeee";
|
||||
let line = text_system.layout_str(
|
||||
text,
|
||||
px(16.),
|
||||
&[
|
||||
(4, normal.clone()),
|
||||
(5, bold.clone()),
|
||||
(6, normal.clone()),
|
||||
(1, bold.clone()),
|
||||
(7, normal.clone()),
|
||||
],
|
||||
);
|
||||
let line = text_system
|
||||
.layout_line(
|
||||
text,
|
||||
px(16.),
|
||||
&[
|
||||
(4, normal.clone()),
|
||||
(5, bold.clone()),
|
||||
(6, normal.clone()),
|
||||
(1, bold.clone()),
|
||||
(7, normal.clone()),
|
||||
],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut wrapper = LineWrapper::new(
|
||||
normal.font,
|
||||
text_system.font_id(&normal.font).unwrap(),
|
||||
px(16.),
|
||||
text_system.platform_text_system.clone(),
|
||||
);
|
||||
|
||||
@@ -15,7 +15,7 @@ use std::{
|
||||
pub(crate) struct TextLayoutCache {
|
||||
prev_frame: Mutex<HashMap<CacheKeyValue, Arc<LineLayout>>>,
|
||||
curr_frame: RwLock<HashMap<CacheKeyValue, Arc<LineLayout>>>,
|
||||
fonts: Arc<dyn PlatformTextSystem>,
|
||||
platform_text_system: Arc<dyn PlatformTextSystem>,
|
||||
}
|
||||
|
||||
impl TextLayoutCache {
|
||||
@@ -23,7 +23,7 @@ impl TextLayoutCache {
|
||||
Self {
|
||||
prev_frame: Mutex::new(HashMap::new()),
|
||||
curr_frame: RwLock::new(HashMap::new()),
|
||||
fonts,
|
||||
platform_text_system: fonts,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,12 +34,12 @@ impl TextLayoutCache {
|
||||
curr_frame.clear();
|
||||
}
|
||||
|
||||
pub fn layout_str<'a>(
|
||||
pub fn layout_line<'a>(
|
||||
&'a self,
|
||||
text: &'a str,
|
||||
font_size: Pixels,
|
||||
runs: &'a [(usize, RunStyle)],
|
||||
) -> Line {
|
||||
runs: &[(usize, FontId)],
|
||||
) -> Arc<LineLayout> {
|
||||
let key = &CacheKeyRef {
|
||||
text,
|
||||
font_size,
|
||||
@@ -47,22 +47,22 @@ impl TextLayoutCache {
|
||||
} as &dyn CacheKey;
|
||||
let curr_frame = self.curr_frame.upgradable_read();
|
||||
if let Some(layout) = curr_frame.get(key) {
|
||||
return Line::new(layout.clone(), runs);
|
||||
return layout.clone();
|
||||
}
|
||||
|
||||
let mut curr_frame = RwLockUpgradableReadGuard::upgrade(curr_frame);
|
||||
if let Some((key, layout)) = self.prev_frame.lock().remove_entry(key) {
|
||||
curr_frame.insert(key, layout.clone());
|
||||
Line::new(layout, runs)
|
||||
layout
|
||||
} else {
|
||||
let layout = Arc::new(self.fonts.layout_line(text, font_size, runs));
|
||||
let layout = Arc::new(self.platform_text_system.layout_line(text, font_size, runs));
|
||||
let key = CacheKeyValue {
|
||||
text: text.into(),
|
||||
font_size,
|
||||
runs: SmallVec::from(runs),
|
||||
};
|
||||
curr_frame.insert(key, layout.clone());
|
||||
Line::new(layout, runs)
|
||||
layout
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,7 +89,7 @@ impl<'a> Hash for (dyn CacheKey + 'a) {
|
||||
struct CacheKeyValue {
|
||||
text: String,
|
||||
font_size: Pixels,
|
||||
runs: SmallVec<[(usize, RunStyle); 1]>,
|
||||
runs: SmallVec<[(usize, FontId); 1]>,
|
||||
}
|
||||
|
||||
impl CacheKey for CacheKeyValue {
|
||||
@@ -120,11 +120,11 @@ impl<'a> Borrow<dyn CacheKey + 'a> for CacheKeyValue {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
struct CacheKeyRef<'a> {
|
||||
text: &'a str,
|
||||
font_size: Pixels,
|
||||
runs: &'a [(usize, RunStyle)],
|
||||
runs: &'a [(usize, FontId)],
|
||||
}
|
||||
|
||||
impl<'a> CacheKey for CacheKeyRef<'a> {
|
||||
@@ -133,26 +133,13 @@ impl<'a> CacheKey for CacheKeyRef<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PartialEq for CacheKeyRef<'a> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.text == other.text
|
||||
&& self.font_size == other.font_size
|
||||
&& self.runs.len() == other.runs.len()
|
||||
&& self.runs.iter().zip(other.runs.iter()).all(
|
||||
|((len_a, style_a), (len_b, style_b))| {
|
||||
len_a == len_b && style_a.font == style_b.font
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
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, style_id) in self.runs {
|
||||
for (len, font_id) in self.runs {
|
||||
len.hash(state);
|
||||
style_id.font.hash(state);
|
||||
font_id.hash(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user