caching?
bendn 2 months ago
parent 1c761ed · commit 3c13f54
-rw-r--r--src/lib.rs63
1 files changed, 43 insertions, 20 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 4b59d01..9b9ef96 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -39,6 +39,7 @@ pub struct Fonts<'a, 'b, 'c, 'd> {
pub bold_italic: F<'d>,
cache: LruCache<(u8, FF32, u16), swash::scale::image::Image>,
+ shape_cache: LruCache<(u8, FF32, String), (u16, Vec<(u16, f32)>)>,
scx: ShapeContext,
}
#[derive(Clone, Copy)]
@@ -91,6 +92,7 @@ impl<'a, 'b, 'c, 'd> Fonts<'a, 'b, 'c, 'd> {
italic: italic.into(),
bold_italic: bold_italic.into(),
cache: LruCache::new(3000),
+ shape_cache: LruCache::new(2000),
scx: ShapeContext::new(),
}
}
@@ -173,7 +175,7 @@ pub unsafe fn render(
};
}
}
- let mut characters: Vec<Glyph> = vec![Glyph::default(); c];
+ let mut characters: Vec<(u16, f32)> = vec![(0, 0.); c];
for (col, k) in cells.chunks_exact(c as _).zip(0..) {
let tokenized = col.iter().enumerate().map(|(i, cell)| {
@@ -190,9 +192,10 @@ pub unsafe fn render(
)
});
let scx = &mut fonts.scx;
+ let sch = &mut fonts.shape_cache;
let mut cluster = CharCluster::new();
macro_rules! input {
- ($rule:expr, $font:expr) => {
+ ($rule:expr, $font:expr, $k: literal) => {
tokenized
.clone()
.chunk_by($rule)
@@ -200,6 +203,21 @@ pub unsafe fn render(
.filter(|x| x.0)
.for_each(|(_, y)| {
let x = y.map(|x| x.0).collect::<Vec<_>>();
+ let key = (
+ $k,
+ FF32::new(ppem),
+ x.iter().map(|x| x.ch).collect::<String>(),
+ );
+ /*if let Some((s, d)) = sch.get_mut(&key) {
+ for (a, b) in d
+ .iter()
+ .zip(&mut characters[*s as usize..])
+ {
+ //characters[*c as usize] = (*a, *b);
+ *b = *a;
+ }
+ return;
+ }*/
let mut shaper = scx
.builder($font)
.size(ppem)
@@ -218,20 +236,31 @@ pub unsafe fn render(
cluster.map(|ch| $font.charmap().map(ch));
shaper.add_cluster(&cluster);
}
+ let mut s = None;
+ let mut l = vec![];
shaper.shape_with(|x| {
+ s = s.or(Some(x.glyphs[0].data));
+ l.extend(
+ x.glyphs.into_iter().map(|x| (x.id, x.x)),
+ );
+
+ // println!("-");
x.glyphs.into_iter().for_each(|x| {
- characters[x.data as usize] = *x;
+ // dbg!(x.data);
+ characters[x.data as usize] = (x.id, x.x);
})
});
+ sch.insert(key.clone(), (s.unwrap() as _, l));
});
};
}
- input!(|x| x.1 & Style::ITALIC == 0, *fonts.regular);
- input!(|x| x.1 & Style::ITALIC != 0, *fonts.italic);
- for (&cell, glyph) in
- characters.iter().map(|x| (&col[x.data as usize], x))
+ input!(|x| x.1 & Style::ITALIC == 0, *fonts.regular, 0);
+ input!(|x| x.1 & Style::ITALIC != 0, *fonts.italic, 1);
+ for (&cell, id, glyx, j) in characters
+ .iter()
+ .zip(0..)
+ .map(|(&(id, x), index)| (&col[index], id, x, index))
{
- let j = glyph.data as usize;
let mut color = cell.style.color;
if (cell.style.flags & Style::DIM) != 0 {
color = color.map(|x| x / 2);
@@ -271,7 +300,7 @@ pub unsafe fn render(
f if f & Style::ITALIC != 0 => (1, fonts.italic),
_ => (0, fonts.regular),
};
- let id = glyph.id;
+
let key = (key, FF32::new(ppem), id);
if !fonts.cache.contains_key(&key) {
let mut scbd = ScaleContext::new();
@@ -296,7 +325,7 @@ pub unsafe fn render(
continue;
}
// println!("{:?} {:?}", glyph, x.placement);
- let x_ = (((j as f32 * fw + glyph.x + 0.125)
+ let x_ = (((j as f32 * fw + glyx + 0.125)
+ x.placement.left as f32)
.round() as i32
+ offset_x as i32)
@@ -438,7 +467,7 @@ pub unsafe fn fill_in(
}
let from = y1 * iw + x1;
let p = image.buffer_mut().as_mut_ptr();
- let n = w as usize *3;
+ let n = w as usize * 3;
let from = p.add(from as usize * 3);
for y in y1 + 1..(y1 + h).min(image.height()) {
@@ -509,14 +538,8 @@ fn x() {
letter: Some(']'),
},
];
- render_owned(
- &z,
- (5, 1),
- 20.0,
- &mut Fonts::new(*FONT, *FONT, *FONT, *FONT),
- 2.0,
- true,
- )
- .show();
+ let mut f = Fonts::new(*FONT, *FONT, *FONT, *FONT);
+ render_owned(&z, (5, 1), 20.0, &mut f, 2.0, true);
+ render_owned(&z, (5, 1), 20.0, &mut f, 2.0, true).show();
}
}