use ass_core::parser::Script;
use fontdb::Database as FontDatabase;
#[cfg(not(feature = "nostd"))]
pub fn shared_system_fonts() -> std::sync::Arc<FontDatabase> {
use std::sync::{Arc, OnceLock};
static CACHE: OnceLock<Arc<FontDatabase>> = OnceLock::new();
CACHE
.get_or_init(|| {
let mut db = FontDatabase::new();
db.load_system_fonts();
let dirs = [
"/usr/share/fonts",
"/usr/local/share/fonts",
"/System/Library/Fonts",
"/System/Library/Fonts/Supplemental",
"/Library/Fonts",
];
for dir in dirs {
if std::path::Path::new(dir).exists() {
db.load_fonts_dir(dir);
}
}
if let Ok(home) = std::env::var("HOME") {
let user_fonts = format!("{home}/.fonts");
if std::path::Path::new(&user_fonts).exists() {
db.load_fonts_dir(&user_fonts);
}
}
Arc::new(db)
})
.clone()
}
pub fn load_embedded_fonts(script: &Script, font_database: &mut FontDatabase) {
if let Some(fonts) = script.sections().iter().find_map(|section| {
if let ass_core::parser::ast::Section::Fonts(fonts) = section {
Some(fonts)
} else {
None
}
}) {
for font in fonts {
match font.decode_data() {
Ok(font_data) => {
font_database.load_font_data(font_data);
}
Err(_e) => {}
}
}
}
}
pub fn load_font_files(
script: &Script,
#[cfg_attr(feature = "nostd", allow(unused_variables))] font_database: &mut FontDatabase,
) {
if let Some(script_info) = script.sections().iter().find_map(|section| {
if let ass_core::parser::ast::Section::ScriptInfo(info) = section {
Some(info)
} else {
None
}
}) {
for (key, value) in &script_info.fields {
if key.to_lowercase().contains("font") {
let _font_path = value.trim();
#[cfg(not(feature = "nostd"))]
{
let path = std::path::Path::new(_font_path);
if path.exists() && path.is_file() {
let _ = font_database.load_font_file(path);
}
}
}
}
}
}
pub fn load_script_fonts(script: &Script, font_database: &mut FontDatabase) {
load_embedded_fonts(script, font_database);
load_font_files(script, font_database);
}