azul_layout/font/
loading.rs

1#![cfg(feature = "std")]
2#![cfg(feature = "font_loading")]
3#![cfg_attr(not(feature = "std"), no_std)]
4
5use std::io::Error as IoError;
6
7use azul_core::app_resources::LoadedFontSource;
8use azul_css::{AzString, FontRef, StringVec, StyleFontFamily, U8Vec};
9use rust_fontconfig::FcFontCache;
10
11const DEFAULT_FONT_INDEX: i32 = 0;
12
13#[cfg(not(miri))]
14pub fn build_font_cache() -> FcFontCache {
15    FcFontCache::build()
16}
17
18#[cfg(miri)]
19pub fn build_font_cache() -> FcFontCache {
20    FcFontCache::default()
21}
22
23#[derive(Debug)]
24pub enum FontReloadError {
25    Io(IoError, AzString),
26    FontNotFound(AzString),
27    FontLoadingNotActive(AzString),
28}
29
30impl Clone for FontReloadError {
31    fn clone(&self) -> Self {
32        use self::FontReloadError::*;
33        match self {
34            Io(err, path) => Io(IoError::new(err.kind(), "Io Error"), path.clone()),
35            FontNotFound(id) => FontNotFound(id.clone()),
36            FontLoadingNotActive(id) => FontLoadingNotActive(id.clone()),
37        }
38    }
39}
40
41azul_core::impl_display!(FontReloadError, {
42    Io(err, path_buf) => format!("Could not load \"{}\" - IO error: {}", path_buf.as_str(), err),
43    FontNotFound(id) => format!("Could not locate system font: \"{:?}\" found", id),
44    FontLoadingNotActive(id) => format!("Could not load system font: \"{:?}\": crate was not compiled with --features=\"font_loading\"", id)
45});
46
47/// Returns the bytes of the font (loads the font from the system in case it is a
48/// `FontSource::System` font). Also returns the index into the font (in case the font is a font
49/// collection).
50pub fn font_source_get_bytes(
51    font_family: &StyleFontFamily,
52    fc_cache: &FcFontCache,
53) -> Option<LoadedFontSource> {
54    use azul_css::StyleFontFamily::*;
55
56    let (font_bytes, font_index) = match font_family {
57        System(id) => {
58            #[cfg(feature = "font_loading")]
59            {
60                crate::font::load_system_font(id.as_str(), fc_cache)
61                    .map(|(font_bytes, font_index)| (font_bytes, font_index))
62                    .ok_or(FontReloadError::FontNotFound(id.clone()))
63            }
64            #[cfg(not(feature = "font_loading"))]
65            {
66                Err(FontReloadError::FontLoadingNotActive(id.clone()))
67            }
68        }
69        File(path) => std::fs::read(path.as_str())
70            .map_err(|e| FontReloadError::Io(e, path.clone()))
71            .map(|font_bytes| (font_bytes.into(), DEFAULT_FONT_INDEX)),
72        Ref(r) => {
73            // NOTE: this path should never execute
74            Ok((r.get_data().bytes.clone(), DEFAULT_FONT_INDEX))
75        }
76    }
77    .ok()?;
78
79    Some(LoadedFontSource {
80        data: font_bytes,
81        index: font_index.max(0) as u32,
82        // only fonts added via FontRef can load glyph outlines!
83        load_outlines: false,
84    })
85}