Skip to main content

headless_lms_server/programs/seed/
certificate_fonts_data.rs

1//! Single source of truth for the certificate fonts seeded into local/test/dev environments.
2
3/// Certificate fonts as `(display_name, file_path, bytes)`. `seed_certificate_fonts` registers
4/// the DB rows and `seed_file_storage` uploads the bytes, both iterating this list.
5///
6/// Inter Variable is the default (see `certificates::TextToRender`) and covers Latin, Cyrillic and
7/// Greek. The Noto Sans fonts extend coverage to scripts Inter lacks; the renderer resolves each
8/// text to the single loaded font that covers it (see `certificates::resolve_font_family`) rather
9/// than relying on usvg's per-glyph fallback.
10pub const CERTIFICATE_FONTS: &[(&str, &str, &[u8])] = &[
11    (
12        "Inter Variable",
13        "fonts/inter-variable.ttf",
14        include_bytes!("./data/InterVariable.ttf"),
15    ),
16    (
17        "Noto Sans CJK SC",
18        "fonts/noto-sans-cjk-sc.otf",
19        include_bytes!("./data/NotoSansCJKsc-Regular.otf"),
20    ),
21    (
22        "Noto Sans Arabic",
23        "fonts/noto-sans-arabic.ttf",
24        include_bytes!("./data/NotoSansArabic.ttf"),
25    ),
26    (
27        "Noto Sans Hebrew",
28        "fonts/noto-sans-hebrew.ttf",
29        include_bytes!("./data/NotoSansHebrew.ttf"),
30    ),
31    (
32        "Noto Sans Thai",
33        "fonts/noto-sans-thai.ttf",
34        include_bytes!("./data/NotoSansThai.ttf"),
35    ),
36    (
37        "Noto Sans Devanagari",
38        "fonts/noto-sans-devanagari.ttf",
39        include_bytes!("./data/NotoSansDevanagari.ttf"),
40    ),
41    (
42        "Noto Sans Bengali",
43        "fonts/noto-sans-bengali.ttf",
44        include_bytes!("./data/NotoSansBengali.ttf"),
45    ),
46    (
47        "Noto Sans Tamil",
48        "fonts/noto-sans-tamil.ttf",
49        include_bytes!("./data/NotoSansTamil.ttf"),
50    ),
51    (
52        "Noto Sans Telugu",
53        "fonts/noto-sans-telugu.ttf",
54        include_bytes!("./data/NotoSansTelugu.ttf"),
55    ),
56    (
57        "Noto Sans Kannada",
58        "fonts/noto-sans-kannada.ttf",
59        include_bytes!("./data/NotoSansKannada.ttf"),
60    ),
61    (
62        "Noto Sans Malayalam",
63        "fonts/noto-sans-malayalam.ttf",
64        include_bytes!("./data/NotoSansMalayalam.ttf"),
65    ),
66    (
67        "Noto Sans Gujarati",
68        "fonts/noto-sans-gujarati.ttf",
69        include_bytes!("./data/NotoSansGujarati.ttf"),
70    ),
71    (
72        "Noto Sans Gurmukhi",
73        "fonts/noto-sans-gurmukhi.ttf",
74        include_bytes!("./data/NotoSansGurmukhi.ttf"),
75    ),
76    (
77        "Noto Sans Oriya",
78        "fonts/noto-sans-oriya.ttf",
79        include_bytes!("./data/NotoSansOriya.ttf"),
80    ),
81    (
82        "Noto Sans Sinhala",
83        "fonts/noto-sans-sinhala.ttf",
84        include_bytes!("./data/NotoSansSinhala.ttf"),
85    ),
86    (
87        "Noto Sans Armenian",
88        "fonts/noto-sans-armenian.ttf",
89        include_bytes!("./data/NotoSansArmenian.ttf"),
90    ),
91    (
92        "Noto Sans Georgian",
93        "fonts/noto-sans-georgian.ttf",
94        include_bytes!("./data/NotoSansGeorgian.ttf"),
95    ),
96    (
97        "Noto Sans Ethiopic",
98        "fonts/noto-sans-ethiopic.ttf",
99        include_bytes!("./data/NotoSansEthiopic.ttf"),
100    ),
101    (
102        "Noto Sans Khmer",
103        "fonts/noto-sans-khmer.ttf",
104        include_bytes!("./data/NotoSansKhmer.ttf"),
105    ),
106    (
107        "Noto Sans Lao",
108        "fonts/noto-sans-lao.ttf",
109        include_bytes!("./data/NotoSansLao.ttf"),
110    ),
111    (
112        "Noto Sans Myanmar",
113        "fonts/noto-sans-myanmar.ttf",
114        include_bytes!("./data/NotoSansMyanmar.ttf"),
115    ),
116];
117
118// Build fails on unhydrated git-lfs pointers, which include_bytes! would embed silently.
119const _: () = {
120    let mut i = 0;
121    while i < CERTIFICATE_FONTS.len() {
122        assert!(
123            matches!(
124                CERTIFICATE_FONTS[i].2,
125                [0x00, 0x01, 0x00, 0x00, ..] | [b'O', b'T', b'T', b'O', ..]
126            ),
127            "certificate font is not a valid font file (likely an unhydrated git-lfs pointer); run: git lfs pull --include=\"services/headless-lms/server/src/programs/seed/data\""
128        );
129        i += 1;
130    }
131};
132
133#[cfg(test)]
134mod tests {
135    use super::CERTIFICATE_FONTS;
136
137    /// Every font file in the seed data dir must be in CERTIFICATE_FONTS: the certificates
138    /// crate's coverage tests load fonts by globbing that dir, so a stray unseeded font would
139    /// pass those tests without ever reaching seeded environments.
140    #[test]
141    fn every_font_file_in_data_dir_is_seeded() {
142        let dir = concat!(env!("CARGO_MANIFEST_DIR"), "/src/programs/seed/data");
143        let font_file_count = std::fs::read_dir(dir)
144            .expect("seed data dir must exist")
145            .filter(|entry| {
146                let path = entry.as_ref().expect("readable seed dir entry").path();
147                matches!(
148                    path.extension().and_then(|e| e.to_str()),
149                    Some("ttf" | "otf")
150                )
151            })
152            .count();
153        assert_eq!(
154            font_file_count,
155            CERTIFICATE_FONTS.len(),
156            "font files in src/programs/seed/data and CERTIFICATE_FONTS entries must match 1:1"
157        );
158    }
159}