Skip to main content

blockworx_text/
cache.rs

1//! The layout cache. Every label on a sheet is laid out on every frame, and
2//! the text it is laid out from rarely changes, so a run is shaped once.
3
4use std::collections::HashMap;
5
6use blockworx_geom::WorldPx;
7use blockworx_paint::Font;
8use blockworx_paint::text::Layout;
9
10/// How many runs to remember before starting over. A sheet's labels are a few
11/// hundred; the rest is what editing them left behind.
12const RUNS: usize = 4096;
13
14#[derive(Default)]
15pub(crate) struct LayoutCache {
16    laid_out: HashMap<Key, Layout>,
17}
18
19impl LayoutCache {
20    pub(crate) fn get(&self, text: &str, font: &Font, wrap: WorldPx) -> Option<&Layout> {
21        self.laid_out.get(&Key::of(text, font, wrap))
22    }
23
24    pub(crate) fn put(&mut self, text: &str, font: &Font, wrap: WorldPx, laid_out: Layout) {
25        if self.laid_out.len() >= RUNS {
26            self.laid_out.clear();
27        }
28        self.laid_out.insert(Key::of(text, font, wrap), laid_out);
29    }
30}
31
32/// What a laid-out run is filed under. The two lengths are keyed by their
33/// bits: they are exactly as equal as the layouts they produce, and a font
34/// states its size as a float.
35#[derive(PartialEq, Eq, Hash)]
36struct Key {
37    text: String,
38    size: u32,
39    wrap: u32,
40}
41
42impl Key {
43    fn of(text: &str, font: &Font, wrap: WorldPx) -> Self {
44        Self {
45            text: text.to_owned(),
46            size: font.size.to_bits(),
47            wrap: wrap.get().to_bits(),
48        }
49    }
50}