BREP_app 0.1.0

The BREP CAD application: an eframe (egui + wgpu) host that draws the brep-render 3D engine into an egui frame — native + wasm from one codebase.
Documentation
//! Font setup — a MONOSPACE UI font with broad symbol coverage.
//!
//! egui's bundled default font is essentially Latin-only (plus a small emoji
//! set), so the technical/geometric symbol glyphs this UI uses (`▣ ◎ ⬢ ├ → …`)
//! fall back to the missing-glyph rectangle ("tofu"). We make **DejaVu Sans
//! Mono** the primary font for BOTH families — the whole UI reads monospace (a
//! deliberate preference) — and append **DejaVu Sans** + **Noto Sans Symbols 2**
//! as per-glyph fallbacks so every symbol resolves; egui's default fonts (incl.
//! emoji) stay as the final fallbacks.
//!
//! Installed at app creation from each shell entry point (`lib.rs` wasm `start`,
//! `main.rs` native `run_native`) — NOT from `app.rs`, to stay out of the way of
//! concurrent panel work.

use eframe::egui;

const MONO: &[u8] = include_bytes!("../assets/fonts/DejaVuSansMono.ttf");
const SANS: &[u8] = include_bytes!("../assets/fonts/DejaVuSans.ttf");
const SYM2: &[u8] = include_bytes!("../assets/fonts/NotoSansSymbols2-Regular.ttf");
// GNU Unifont (SUPPLEMENTARY plane) — the universal LAST-RESORT catch-all for the
// emoji/pictograph range (U+1F000+ where 🔗 and friends live), which is where
// wrong-glyph / tofu problems actually occur. Placed at the very END of the
// fallback chain, so every glyph an earlier (nicer) font has is byte-identical —
// Unifont only draws what nothing else can (blocky; the price of total coverage).
// The BMP plane is deliberately NOT bundled: DejaVu Sans/Mono + NotoSansSymbols2
// already cover it comprehensively for this Latin UI, so bundling it too would add
// ~5 MB for no gain.
const UNIFONT_UPPER: &[u8] = include_bytes!("../assets/fonts/unifont_upper.otf");

/// Install the monospace + symbol fonts into `ctx`. Call once, at app creation.
pub fn install(ctx: &egui::Context) {
    let mut fonts = egui::FontDefinitions::default();
    fonts
        .font_data
        .insert("mono".to_owned(), egui::FontData::from_static(MONO).into());
    fonts
        .font_data
        .insert("sans_sym".to_owned(), egui::FontData::from_static(SANS).into());
    fonts
        .font_data
        .insert("sym2".to_owned(), egui::FontData::from_static(SYM2).into());
    fonts.font_data.insert(
        "unifont_upper".to_owned(),
        egui::FontData::from_static(UNIFONT_UPPER).into(),
    );

    // Primary = mono; then broad symbol fallbacks; then egui's existing defaults
    // (which include the emoji fonts). Order matters: egui resolves each glyph by
    // trying the family list front-to-back.
    for family in [egui::FontFamily::Proportional, egui::FontFamily::Monospace] {
        let list = fonts.families.entry(family).or_default();
        list.insert(0, "sym2".to_owned());
        list.insert(0, "sans_sym".to_owned());
        list.insert(0, "mono".to_owned());

        // Guarantee egui's bundled default emoji fonts stay in the fallback chain:
        // the toolbar glyphs 📄 (New), 💾 (Save) come from "NotoEmoji-Regular" and
        // ⛶ (Zoom-to-fit) from "emoji-icon-font". Both are
        // loaded into `font_data` by `FontDefinitions::default()` (feature
        // `default_fonts`, ON) and already trail these lists; append only if a key
        // exists but somehow dropped out, so no glyph tofus.
        //
        // Caveat: U+1F517 🔗 (LINK) is in NONE of the bundled/default fonts, so it
        // fell all the way through to emoji-icon-font and rendered as a stray PEN
        // glyph (that font's non-standard mapping). Icons that want "chain links"
        // use ⛓ U+26D3 (CHAINS), which IS in NotoSansSymbols2 and renders reliably.
        for emoji in ["NotoEmoji-Regular", "emoji-icon-font"] {
            if fonts.font_data.contains_key(emoji) && !list.iter().any(|f| f == emoji) {
                list.push(emoji.to_owned());
            }
        }

        // Universal catch-all LAST: any supplementary-plane glyph none of the
        // above provide (a stray emoji/pictograph) falls to GNU Unifont instead of
        // tofu.
        list.push("unifont_upper".to_owned());
    }
    ctx.set_fonts(fonts);
}