1use std::{borrow::Cow, sync::Arc};
9
10use gpui::App;
11use usvg::fontdb;
12
13#[derive(Clone)]
18pub struct Database {
19 pub fonts: Arc<fontdb::Database>,
20 pub generation: u64,
21}
22
23pub fn add(cx: &App, fonts: Vec<Cow<'static, [u8]>>) -> gpui::Result<()> {
25 #[cfg(target_family = "wasm")]
26 web::add(&fonts);
27 cx.text_system().add_fonts(fonts)
28}
29
30pub fn database() -> Database {
33 #[cfg(not(target_family = "wasm"))]
34 {
35 static SYSTEM: std::sync::LazyLock<Database> = std::sync::LazyLock::new(|| {
36 let mut fonts = fontdb::Database::new();
37 fonts.load_system_fonts();
38 Database {
39 fonts: Arc::new(fonts),
40 generation: 0,
41 }
42 });
43 SYSTEM.clone()
44 }
45 #[cfg(target_family = "wasm")]
46 web::database()
47}
48
49#[cfg(target_family = "wasm")]
50mod web {
51 use std::{
52 borrow::Cow,
53 sync::{Arc, Mutex, PoisonError},
54 };
55
56 use usvg::fontdb::{self, Source};
57
58 use super::Database;
59
60 static FONTS: Mutex<Option<Database>> = Mutex::new(None);
61
62 pub(super) fn add(added: &[Cow<'static, [u8]>]) {
63 let mut held = FONTS.lock().unwrap_or_else(PoisonError::into_inner);
64 let mut fonts = held
65 .as_ref()
66 .map_or_else(fontdb::Database::new, |db| (*db.fonts).clone());
67 for font in added {
68 fonts.load_font_source(Source::Binary(Arc::new(font.clone())));
69 }
70 let generation = held.as_ref().map_or(0, |db| db.generation) + 1;
71 *held = Some(Database {
72 fonts: Arc::new(fonts),
73 generation,
74 });
75 }
76
77 pub(super) fn database() -> Database {
78 FONTS
79 .lock()
80 .unwrap_or_else(PoisonError::into_inner)
81 .get_or_insert_with(|| Database {
82 fonts: Arc::new(fontdb::Database::new()),
83 generation: 0,
84 })
85 .clone()
86 }
87}