wgpu-font-renderer 0.1.0

GPU-Centered Font Rendering crate
Documentation
use owned_ttf_parser::{AsFaceRef, GlyphId};
use swash::{shape::ShapeContext, text::Script, CacheKey};

use crate::{loader::Glyph, FontStore};

pub struct Paragraph {
    pub glyphs: Vec<(GlyphId, f32)>,
    pub position: [f32; 2],
    pub width: f32,
    pub size: u16,
    pub font_key: CacheKey,
    pub color: [f32; 4],
}

impl Paragraph {
    pub fn new(position: [f32; 2], size: u16, color: [f32; 4], font_key: CacheKey) -> Self {
        Self {
            glyphs: Vec::new(),
            position,
            width: 0.,
            size,
            font_key,
            color,
        }
    }

    pub fn append(&mut self, glyph_id: GlyphId, left: f32) {
        self.width += left;
        self.glyphs.push((glyph_id, left));
    }


}

pub struct TypeWriter {
    context: ShapeContext,
}

impl TypeWriter {

    pub fn new() -> Self {
        Self {
            context: ShapeContext::new()
        }
    }

    pub fn shape_text(&mut self, font_store: &FontStore, font_key: CacheKey, position: [f32; 2], size: u16, color: [f32; 4], text: &str) -> Option<Paragraph> {
        if let Some(font) = font_store.get(font_key) {
            let mut shaper = self.context.builder(font.as_ref())
                .script(Script::Latin)
                .size(size as f32)
                .build();

            let face = font.face.as_face_ref();

            let mut paragraph = Paragraph::new(position, size, color, font_key);

            shaper.add_str(text);
            shaper.shape_with(|cluster| {
                let glyph_id = GlyphId(cluster.glyphs[0].id);
                paragraph.append(glyph_id, cluster.glyphs[0].advance)
            });

            Some(paragraph)
        } else {
            None
        }
    } 
}