From f11afa43114be00434d9cfee6beff19ab47ba8dc Mon Sep 17 00:00:00 2001 From: Samuel Date: Mon, 20 Jan 2025 19:25:02 -0300 Subject: [PATCH] Improve cache of font data to use less memory --- CHANGELOG.md | 1 + crates/zng-ext-font/src/lib.rs | 1 + crates/zng-ext-font/src/query_util.rs | 22 +++++++++++++++++++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e7717287..1cd52fe92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Unreleased +* Improve cache of font data to use less memory. # 0.13.7 diff --git a/crates/zng-ext-font/src/lib.rs b/crates/zng-ext-font/src/lib.rs index 8af193ddf..defc818dd 100644 --- a/crates/zng-ext-font/src/lib.rs +++ b/crates/zng-ext-font/src/lib.rs @@ -1785,6 +1785,7 @@ impl> std::ops::Index for FontList { struct FontFaceLoader { custom_fonts: HashMap>, unregister_requests: Vec<(FontName, ResponderVar)>, + system_fonts_cache: HashMap>, list_cache: HashMap, Vec>, } diff --git a/crates/zng-ext-font/src/query_util.rs b/crates/zng-ext-font/src/query_util.rs index 8b90fc359..921d472ec 100644 --- a/crates/zng-ext-font/src/query_util.rs +++ b/crates/zng-ext-font/src/query_util.rs @@ -1,16 +1,22 @@ +use std::path::PathBuf; + #[cfg(not(any(target_arch = "wasm32", target_os = "android")))] pub use desktop::*; +use parking_lot::Mutex; #[cfg(target_arch = "wasm32")] pub use wasm::*; #[cfg(target_os = "android")] pub use android::*; +static DATA_CACHE: Mutex>)>> = Mutex::new(vec![]); + #[cfg(not(any(target_arch = "wasm32", target_os = "android")))] mod desktop { use std::{borrow::Cow, path::Path, sync::Arc}; + use zng_layout::unit::ByteUnits; use zng_var::ResponseVar; use crate::{FontDataRef, FontLoadingError, FontName, FontStretch, FontStyle, FontWeight, GlyphLoadingError}; @@ -166,9 +172,23 @@ mod desktop { } } + for (k, data) in super::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 = super::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)), }