Skip to content

Commit

Permalink
Improve cache of font data to use less memory (#598)
Browse files Browse the repository at this point in the history
  • Loading branch information
SamRodri authored Jan 21, 2025
1 parent b0f4dcb commit f5f7efc
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Unreleased

* Improve cache of font data to use less memory.

# 0.13.7

Expand Down
1 change: 1 addition & 0 deletions crates/zng-ext-font/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1785,6 +1785,7 @@ impl<I: SliceIndex<[Font]>> std::ops::Index<I> for FontList {
struct FontFaceLoader {
custom_fonts: HashMap<FontName, Vec<FontFace>>,
unregister_requests: Vec<(FontName, ResponderVar<bool>)>,

system_fonts_cache: HashMap<FontName, Vec<SystemFontFace>>,
list_cache: HashMap<Box<[FontName]>, Vec<FontFaceListQuery>>,
}
Expand Down
28 changes: 25 additions & 3 deletions crates/zng-ext-font/src/query_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,20 @@ pub use android::*;

#[cfg(not(any(target_arch = "wasm32", target_os = "android")))]
mod desktop {
use std::{borrow::Cow, path::Path, sync::Arc};

use std::{
borrow::Cow,
path::{Path, PathBuf},
sync::Arc,
};

use parking_lot::Mutex;
use zng_layout::unit::ByteUnits;
use zng_var::ResponseVar;

use crate::{FontDataRef, FontLoadingError, FontName, FontStretch, FontStyle, FontWeight, GlyphLoadingError};

static DATA_CACHE: Mutex<Vec<(PathBuf, std::sync::Weak<Vec<u8>>)>> = Mutex::new(vec![]);

pub fn system_all() -> ResponseVar<Vec<FontName>> {
zng_task::wait_respond(|| {
font_kit::source::SystemSource::new()
Expand Down Expand Up @@ -166,9 +174,23 @@ mod desktop {
}
}

for (k, data) in DATA_CACHE.lock().iter() {
if *k == *path {
if let Some(data) = data.upgrade() {
return Ok((FontDataRef(data), *font_index));
}
}
}

let bytes = std::fs::read(&*path)?;
tracing::debug!("read font `{}:{}`, using {}", path.display(), font_index, bytes.capacity().bytes());

let data = Arc::new(bytes);
let mut cache = DATA_CACHE.lock();
cache.retain(|(_, v)| v.strong_count() > 0);
cache.push((path.to_path_buf(), Arc::downgrade(&data)));

Ok((FontDataRef(Arc::new(bytes)), *font_index))
Ok((FontDataRef(data), *font_index))
}
font_kit::handle::Handle::Memory { bytes, font_index } => Ok((FontDataRef(bytes.clone()), *font_index)),
}
Expand Down

0 comments on commit f5f7efc

Please sign in to comment.