i_slint_compiler/passes/
collect_custom_fonts.rs

1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
3
4//! Passes that fills the root component used_global
5
6use crate::{
7    expression_tree::{BuiltinFunction, Expression, Unit},
8    object_tree::*,
9};
10use smol_str::SmolStr;
11use std::collections::BTreeSet;
12
13/// Fill the root_component's used_globals
14pub fn collect_custom_fonts<'a>(
15    doc: &Document,
16    all_docs: impl Iterator<Item = &'a Document> + 'a,
17    embed_fonts: bool,
18) {
19    let mut all_fonts = BTreeSet::new();
20
21    for doc in all_docs {
22        all_fonts.extend(doc.custom_fonts.iter().map(|(path, _)| path))
23    }
24
25    let registration_function = if embed_fonts {
26        BuiltinFunction::RegisterCustomFontByMemory
27    } else {
28        BuiltinFunction::RegisterCustomFontByPath
29    };
30
31    let prepare_font_registration_argument: Box<dyn Fn(&SmolStr) -> Expression> = if embed_fonts {
32        Box::new(|font_path| {
33            Expression::NumberLiteral(
34                {
35                    let mut resources = doc.embedded_file_resources.borrow_mut();
36                    let resource_id = match resources.get(font_path) {
37                        Some(r) => r.id,
38                        None => {
39                            let id = resources.len();
40                            resources.insert(
41                                font_path.clone(),
42                                crate::embedded_resources::EmbeddedResources {
43                                    id,
44                                    kind: crate::embedded_resources::EmbeddedResourcesKind::RawData,
45                                },
46                            );
47                            id
48                        }
49                    };
50                    resource_id as _
51                },
52                Unit::None,
53            )
54        })
55    } else {
56        Box::new(|font_path| Expression::StringLiteral(font_path.clone()))
57    };
58
59    for c in doc.exported_roots() {
60        c.init_code.borrow_mut().font_registration_code.extend(all_fonts.iter().map(|font_path| {
61            Expression::FunctionCall {
62                function: registration_function.clone().into(),
63                arguments: vec![prepare_font_registration_argument(font_path)],
64                source_location: None,
65            }
66        }));
67    }
68}