Fix performance and UX issues

This commit is contained in:
2026-03-07 23:11:00 +02:00
parent 0ef3893bce
commit 72c519bebc
6 changed files with 249 additions and 65 deletions

View File

@@ -75,16 +75,34 @@ pub fn apply_watermark(
}
}
/// Cache for font data to avoid repeated filesystem walks during preview updates
static FONT_CACHE: std::sync::Mutex<Option<FontCache>> = std::sync::Mutex::new(None);
static DEFAULT_FONT_CACHE: std::sync::OnceLock<Option<Vec<u8>>> = std::sync::OnceLock::new();
struct FontCache {
entries: std::collections::HashMap<String, Vec<u8>>,
}
fn find_system_font(family: Option<&str>) -> Result<Vec<u8>> {
// If a specific font family was requested, try to find it via fontconfig
// If a specific font family was requested, check the cache first
if let Some(name) = family {
if !name.is_empty() {
// Try common font paths with the family name
let name_lower = name.to_lowercase();
// Check cache
if let Ok(cache) = FONT_CACHE.lock() {
if let Some(ref c) = *cache {
if let Some(data) = c.entries.get(&name_lower) {
return Ok(data.clone());
}
}
}
// Cache miss - search filesystem
let search_dirs = [
"/usr/share/fonts",
"/usr/local/share/fonts",
];
let name_lower = name.to_lowercase();
for dir in &search_dirs {
if let Ok(entries) = walkdir(std::path::Path::new(dir)) {
for path in entries {
@@ -97,6 +115,13 @@ fn find_system_font(family: Option<&str>) -> Result<Vec<u8>> {
&& (file_name.contains("regular") || (!file_name.contains("bold") && !file_name.contains("italic")))
{
if let Ok(data) = std::fs::read(&path) {
// Store in cache
if let Ok(mut cache) = FONT_CACHE.lock() {
let c = cache.get_or_insert_with(|| FontCache {
entries: std::collections::HashMap::new(),
});
c.entries.insert(name_lower, data.clone());
}
return Ok(data);
}
}
@@ -106,26 +131,31 @@ fn find_system_font(family: Option<&str>) -> Result<Vec<u8>> {
}
}
// Fall back to default system fonts
let candidates = [
"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
"/usr/share/fonts/TTF/DejaVuSans.ttf",
"/usr/share/fonts/dejavu-sans-fonts/DejaVuSans.ttf",
"/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf",
"/usr/share/fonts/truetype/noto/NotoSans-Regular.ttf",
"/usr/share/fonts/noto/NotoSans-Regular.ttf",
];
for path in &candidates {
if let Ok(data) = std::fs::read(path) {
return Ok(data);
// Fall back to default system fonts (cached via OnceLock)
let default = DEFAULT_FONT_CACHE.get_or_init(|| {
let candidates = [
"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
"/usr/share/fonts/TTF/DejaVuSans.ttf",
"/usr/share/fonts/dejavu-sans-fonts/DejaVuSans.ttf",
"/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf",
"/usr/share/fonts/truetype/noto/NotoSans-Regular.ttf",
"/usr/share/fonts/noto/NotoSans-Regular.ttf",
];
for path in &candidates {
if let Ok(data) = std::fs::read(path) {
return Some(data);
}
}
}
None
});
Err(PixstripError::Processing {
operation: "watermark".into(),
reason: "No system font found for text watermark".into(),
})
match default {
Some(data) => Ok(data.clone()),
None => Err(PixstripError::Processing {
operation: "watermark".into(),
reason: "No system font found for text watermark".into(),
}),
}
}
/// Recursively walk a directory and collect file paths (max depth 5)