Skip to main content

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//! This pass extends the init code with font registration
5
6use crate::embedded_resources::EmbeddedResourcesIdx;
7use crate::{
8    expression_tree::{BuiltinFunction, Expression, Unit},
9    object_tree::*,
10};
11use smol_str::SmolStr;
12use std::collections::{BTreeSet, HashMap};
13
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 mut path_to_id = HashMap::<SmolStr, EmbeddedResourcesIdx>::new();
32    let mut prepare_font_registration_argument: Box<dyn FnMut(&SmolStr) -> Expression> =
33        if embed_fonts {
34            Box::new(|font_path| {
35                let resource_id = *path_to_id.entry(font_path.clone()).or_insert_with(|| {
36                    doc.embedded_file_resources.borrow_mut().push_and_get_key(
37                        crate::embedded_resources::EmbeddedResources {
38                            path: Some(font_path.clone()),
39                            kind: crate::embedded_resources::EmbeddedResourcesKind::FileData,
40                        },
41                    )
42                });
43                Expression::NumberLiteral(resource_id.0 as _, Unit::None)
44            })
45        } else {
46            Box::new(|font_path| Expression::StringLiteral(font_path.clone()))
47        };
48
49    for c in doc.exported_roots() {
50        c.init_code.borrow_mut().font_registration_code.extend(all_fonts.iter().map(|font_path| {
51            Expression::FunctionCall {
52                function: registration_function.clone().into(),
53                arguments: vec![prepare_font_registration_argument(font_path)],
54                source_location: None,
55            }
56        }));
57    }
58}