use std::{borrow::Cow, sync::Arc};
use gpui::App;
use usvg::fontdb;
#[derive(Clone)]
pub struct Database {
pub fonts: Arc<fontdb::Database>,
pub generation: u64,
}
pub fn add(cx: &App, fonts: Vec<Cow<'static, [u8]>>) -> gpui::Result<()> {
#[cfg(target_family = "wasm")]
web::add(&fonts);
cx.text_system().add_fonts(fonts)
}
pub fn database() -> Database {
#[cfg(not(target_family = "wasm"))]
{
static SYSTEM: std::sync::LazyLock<Database> = std::sync::LazyLock::new(|| {
let mut fonts = fontdb::Database::new();
fonts.load_system_fonts();
Database {
fonts: Arc::new(fonts),
generation: 0,
}
});
SYSTEM.clone()
}
#[cfg(target_family = "wasm")]
web::database()
}
#[cfg(target_family = "wasm")]
mod web {
use std::{
borrow::Cow,
sync::{Arc, Mutex, PoisonError},
};
use usvg::fontdb::{self, Source};
use super::Database;
static FONTS: Mutex<Option<Database>> = Mutex::new(None);
pub(super) fn add(added: &[Cow<'static, [u8]>]) {
let mut held = FONTS.lock().unwrap_or_else(PoisonError::into_inner);
let mut fonts = held
.as_ref()
.map_or_else(fontdb::Database::new, |db| (*db.fonts).clone());
for font in added {
fonts.load_font_source(Source::Binary(Arc::new(font.clone())));
}
let generation = held.as_ref().map_or(0, |db| db.generation) + 1;
*held = Some(Database {
fonts: Arc::new(fonts),
generation,
});
}
pub(super) fn database() -> Database {
FONTS
.lock()
.unwrap_or_else(PoisonError::into_inner)
.get_or_insert_with(|| Database {
fonts: Arc::new(fontdb::Database::new()),
generation: 0,
})
.clone()
}
}