2.8 KiB · text History 487bb12
//! Fonts for rasterising: the house B612 family, compiled in so the PNG
//! renderer never depends on what the host or container has installed.
//! B612 is OFL-1.1; see `fonts/OFL.txt`.
use std::sync::{Arc, LazyLock};

use base64::Engine;
use resvg::usvg::fontdb;

static MONO_REGULAR: &[u8] = include_bytes!("../../fonts/B612Mono-Regular.ttf");
static MONO_BOLD: &[u8] = include_bytes!("../../fonts/B612Mono-Bold.ttf");
static MONO_ITALIC: &[u8] = include_bytes!("../../fonts/B612Mono-Italic.ttf");
static MONO_BOLD_ITALIC: &[u8] = include_bytes!("../../fonts/B612Mono-BoldItalic.ttf");
static SANS_BOLD: &[u8] = include_bytes!("../../fonts/B612-Bold.ttf");

pub const MONO_FAMILY: &str = "B612 Mono";

pub static FONTDB: LazyLock<Arc<fontdb::Database>> = LazyLock::new(|| {
    let mut db = fontdb::Database::new();
    for data in [MONO_REGULAR, MONO_BOLD, MONO_ITALIC, MONO_BOLD_ITALIC, SANS_BOLD] {
        db.load_font_data(data.to_vec());
    }
    db.set_monospace_family(MONO_FAMILY);
    db.set_sans_serif_family("B612");
    Arc::new(db)
});

/// Horizontal advance of one monospace cell, as a fraction of the font size.
pub fn mono_advance() -> f32 {
    static ADV: LazyLock<f32> = LazyLock::new(|| {
        let face = ttf_parser::Face::parse(MONO_REGULAR, 0).expect("B612 Mono parses");
        let gid = face.glyph_index('M').expect("B612 Mono has M");
        face.glyph_hor_advance(gid).expect("advance") as f32 / face.units_per_em() as f32
    });
    *ADV
}

/// `@font-face` rules carrying the latin web subsets inline, so a downloaded
/// SVG renders in the house font wherever it is opened.
pub fn embedded_font_css() -> &'static str {
    static CSS: LazyLock<String> = LazyLock::new(|| {
        let b64 = |d: &[u8]| base64::engine::general_purpose::STANDARD.encode(d);
        let faces: [(&str, &str, &str, &[u8]); 5] = [
            ("B612 Mono", "normal", "normal", include_bytes!("../../assets/f/css/files/b612-mono-latin-400-normal.woff2")),
            ("B612 Mono", "bold", "normal", include_bytes!("../../assets/f/css/files/b612-mono-latin-700-normal.woff2")),
            ("B612 Mono", "normal", "italic", include_bytes!("../../assets/f/css/files/b612-mono-latin-400-italic.woff2")),
            ("B612 Mono", "bold", "italic", include_bytes!("../../assets/f/css/files/b612-mono-latin-700-italic.woff2")),
            ("B612", "bold", "normal", include_bytes!("../../assets/f/css/files/b612-latin-700-normal.woff2")),
        ];
        faces
            .iter()
            .map(|(fam, weight, style, data)| {
                format!(
                    "@font-face{{font-family:'{fam}';font-weight:{weight};font-style:{style};src:url(data:font/woff2;base64,{})format('woff2')}}",
                    b64(data)
                )
            })
            .collect()
    });
    &CSS
}