tauri_plugin_system_fonts/
commands.rs

1use fontdb::{Database, Source, Style};
2use serde::{Deserialize, Serialize};
3use std::collections::HashSet;
4use tauri::command;
5
6#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
7pub enum SystemFontStyle {
8    Normal,
9    Italic,
10    Oblique,
11}
12
13#[derive(Clone, Serialize)]
14#[serde(rename_all = "camelCase")]
15pub struct SystemFont {
16    pub id: String,
17    pub name: String,
18    pub font_name: String,
19    pub path: String,
20    pub weight: u16,
21    pub style: SystemFontStyle,
22    pub monospaced: bool,
23}
24
25/// Get all fonts installed on the system.
26///
27/// # Example
28/// ```
29/// use tauri_plugin_system_fonts::get_system_fonts;
30///
31/// let fonts = get_system_fonts().await;
32/// ```
33#[command]
34pub async fn get_system_fonts() -> Vec<SystemFont> {
35    let mut db = Database::new();
36
37    db.load_system_fonts();
38
39    let mut seen = HashSet::new();
40
41    db.faces()
42        .filter_map(|font| match &font.source {
43            Source::File(path) => {
44                let name = font.families[0].0.clone();
45
46                if name.starts_with('.') {
47                    return None;
48                }
49
50                let style = match font.style {
51                    Style::Normal => SystemFontStyle::Normal,
52                    Style::Italic => SystemFontStyle::Italic,
53                    Style::Oblique => SystemFontStyle::Oblique,
54                };
55
56                let font = SystemFont {
57                    id: font.id.to_string(),
58                    name,
59                    font_name: font.post_script_name.clone(),
60                    path: path.to_string_lossy().to_string(),
61                    weight: font.weight.0,
62                    style,
63                    monospaced: font.monospaced,
64                };
65
66                if seen.insert((font.name.clone(), font.path.clone())) {
67                    Some(font)
68                } else {
69                    None
70                }
71            }
72            Source::Binary(_) => None,
73            Source::SharedFile(..) => None,
74        })
75        .collect()
76}