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::{
7    expression_tree::{BuiltinFunction, Expression, Unit},
8    object_tree::*,
9};
10use smol_str::SmolStr;
11use std::collections::BTreeSet;
12
13pub fn collect_custom_fonts<'a>(
14    doc: &Document,
15    all_docs: impl Iterator<Item = &'a Document> + 'a,
16    embed_fonts: bool,
17) {
18    let mut all_fonts = BTreeSet::new();
19
20    for doc in all_docs {
21        all_fonts.extend(doc.custom_fonts.iter().map(|(path, _)| path))
22    }
23
24    let registration_function = if embed_fonts {
25        BuiltinFunction::RegisterCustomFontByMemory
26    } else {
27        BuiltinFunction::RegisterCustomFontByPath
28    };
29
30    let prepare_font_registration_argument: Box<dyn Fn(&SmolStr) -> Expression> = if embed_fonts {
31        Box::new(|font_path| {
32            Expression::NumberLiteral(
33                {
34                    let mut resources = doc.embedded_file_resources.borrow_mut();
35                    let resource_id = match resources.get(font_path) {
36                        Some(r) => r.id,
37                        None => {
38                            let id = resources.len();
39                            resources.insert(
40                                font_path.clone(),
41                                crate::embedded_resources::EmbeddedResources {
42                                    id,
43                                    kind: crate::embedded_resources::EmbeddedResourcesKind::RawData,
44                                },
45                            );
46                            id
47                        }
48                    };
49                    resource_id as _
50                },
51                Unit::None,
52            )
53        })
54    } else {
55        Box::new(|font_path| Expression::StringLiteral(font_path.clone()))
56    };
57
58    for c in doc.exported_roots() {
59        c.init_code.borrow_mut().font_registration_code.extend(all_fonts.iter().map(|font_path| {
60            Expression::FunctionCall {
61                function: registration_function.clone().into(),
62                arguments: vec![prepare_font_registration_argument(font_path)],
63                source_location: None,
64            }
65        }));
66    }
67}