klyff 0.1.3

Text rendering library for games with MSDF support
Documentation
use std::sync::Arc;

use super::Rect;

/// Raw bytes of the bundled PUA font.
///
/// The font contains a single empty glyph mapped to [`CUSTOM_GLYPH_CHAR`]. The glyph is
/// detected during encoding and surfaced via [`crate::MeshEncoder::custom_glyphs`].
const PUA_FONT: &[u8] = include_bytes!("puafont.ttf");

/// Family name of the bundled PUA font.
pub(crate) const CUSTOM_GLYPH_FAMILY: &str = "PUA Empty";

/// The Private Use Area codepoint that represents a custom glyph.
///
/// [`crate::StyledTextBuilder::push_custom_glyph`] inserts this character as a placeholder. The
/// empty glyph reserves layout space but is never drawn by klyff.
pub const CUSTOM_GLYPH_CHAR: char = '\u{E000}';

/// Handle to the loaded custom-glyph font.
///
/// Obtain one with [`setup_custom_glyph_font`], then register it on the renderer
/// ([`crate::TextRenderer::set_custom_glyph_font`]) or the low-level encoder
/// ([`crate::MeshEncoder::set_custom_glyph_font`]) so custom glyphs are detected during encoding.
#[derive(Debug, Clone, Copy)]
pub struct CustomGlyphFont {
    pub id: fontdb::ID,
}

/// A custom glyph detected during [`crate::MeshEncoder::encode`].
///
/// klyff does not render custom glyphs itself; it records each detected placeholder along with the
/// layout box it occupies so application code can draw whatever it wants in that position.
#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
pub struct CustomGlyph {
    /// The id supplied to [`crate::StyledTextBuilder::push_custom_glyph`].
    pub id: u64,
    /// Identifier of the [`crate::Text`] this glyph was produced from. Mirrors [`crate::Text::id`].
    pub text_id: u64,
    /// Screen-space box the glyph occupies. The box sits on the text baseline: its bottom edge is
    /// the baseline and it extends upward by the requested `height`, spanning the requested
    /// `width` horizontally (both multiplied by the text's scale).
    pub rect: Rect,
    /// The glyph's font size in screen-space pixels (`font_size * scale`).
    pub font_size_px: f32,
}

/// Load the bundled PUA font into `font_system` and return a handle identifying it.
///
/// Call this once during setup. The returned [`CustomGlyphFont`] must be registered with the
/// renderer or encoder that will detect custom glyphs (see [`CustomGlyphFont`]). After this,
/// [`crate::StyledTextBuilder::push_custom_glyph`] can insert custom glyphs into text.
pub fn setup_custom_glyph_font(font_system: &mut cosmic_text::FontSystem) -> CustomGlyphFont {
    let ids = font_system
        .db_mut()
        .load_font_source(fontdb::Source::Binary(Arc::new(PUA_FONT)));
    // The bundled font contains exactly one face.
    let id = ids
        .first()
        .copied()
        .expect("bundled PUA font must contain at least one face");
    CustomGlyphFont { id }
}