SHX fonts: list the ones in the user's font folders, for font lists

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RzTHYMZTCtkW9FExLCKj5V
This commit is contained in:
Claude
2026-11-04 22:43:42 +02:00
parent 2c979eb14b
commit 7ea06a86db
3 changed files with 32 additions and 2 deletions
+2 -2
View File
@@ -41,8 +41,8 @@ use cadcraft_geom::Vec2;
pub use compile::compile;
pub use table::{
FontProvider, add_drawing_dir, clear_registered, drawing_dirs, find, font_map, generation, register, search_path, set_font_dirs, set_font_map,
set_provider, set_search_path,
FontProvider, add_drawing_dir, clear_registered, drawing_dirs, find, font_map, generation, installed, register, search_path, set_font_dirs,
set_font_map, set_provider, set_search_path,
};
pub use text::ShxText;
pub(crate) use text::{shape, width};
+26
View File
@@ -238,6 +238,32 @@ pub fn find(name: &str) -> Option<Arc<ShxFont>> {
#[cfg(not(target_arch = "wasm32"))]
const MAX_DIR_ENTRIES: usize = 10_000;
/// The SHX fonts in the user's font folders ([`set_font_dirs`]) and the registered ones, by file
/// stem, sorted without repeats (for font lists). Not read: only their names are listed.
pub fn installed() -> Vec<String> {
let (dirs, mut out): (Vec<PathBuf>, Vec<String>) = {
let t = table();
(t.font_dirs.clone(), t.registered.keys().map(|k| k.trim_end_matches(".shx").to_string()).collect())
};
#[cfg(not(target_arch = "wasm32"))]
for d in &dirs {
let Ok(entries) = std::fs::read_dir(d) else { continue };
for e in entries.take(MAX_DIR_ENTRIES).filter_map(Result::ok) {
let p = e.path();
if p.extension().is_some_and(|x| x.eq_ignore_ascii_case("shx"))
&& let Some(stem) = p.file_stem().and_then(|s| s.to_str())
{
out.push(stem.to_string());
}
}
}
#[cfg(target_arch = "wasm32")]
let _ = dirs;
out.sort_by_key(|n| n.to_lowercase());
out.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
out
}
/// The file `name` (a lower-case key) in the first of `dirs` that has it, whatever the case of
/// its name: lower-case, upper-case, else any other case found in the directory (`Simplex.shx`
/// on a case-sensitive file system).
+4
View File
@@ -20,6 +20,9 @@ fn shx_fonts_in_the_users_font_folders_are_found() {
assert!(shx::find("cadcraft-top.shx").is_some_and(|f| f.has_shape(65)));
assert!(shx::find("CADCRAFT-DEEP").is_some(), "in a folder under the font folder");
assert!(ttf::available("cadcraft-deep.shx"));
// Font lists name them.
let names = shx::installed();
assert!(names.iter().any(|n| n == "cadcraft-top") && names.iter().any(|n| n == "cadcraft-deep"), "{names:?}");
// A file added later is found after Look for Fonts Again.
std::fs::write(dir.join("cadcraft-later.shx"), &bytes).unwrap();
@@ -28,5 +31,6 @@ fn shx_fonts_in_the_users_font_folders_are_found() {
ttf::set_font_dirs::<&str>(&[]);
assert!(shx::find("cadcraft-top.shx").is_none());
assert!(!shx::installed().iter().any(|n| n.starts_with("cadcraft-")));
let _ = std::fs::remove_dir_all(&dir);
}