makepad-draw 1.0.0

Makepad 2d drawing API
Documentation
use {
    makepad_rustybuzz as rustybuzz,
    rustybuzz::ttf_parser,
    std::{fmt, marker::PhantomPinned, mem, pin::Pin, rc::Rc},
};

#[derive(Debug)]
pub struct FontFace(Pin<Box<FontFaceInner>>);

impl FontFace {
    pub fn from_data_and_index(data: Rc<Vec<u8>>, index: u32) -> Option<Self> {
        let mut inner = Box::pin(FontFaceInner {
            data,
            ttf_parser_face: None,
            rustybuzz_face: None,
            _pinned: PhantomPinned,
        });
        unsafe {
            let data: &'static [u8] = mem::transmute(&**inner.data);
            let ttf_parser_face = ttf_parser::Face::parse(data, index).ok()?;
            let rustybuzz_face = rustybuzz::Face::from_face(ttf_parser_face.clone());
            let inner_ref = Pin::as_mut(&mut inner).get_unchecked_mut();
            inner_ref.ttf_parser_face = Some(ttf_parser_face);
            inner_ref.rustybuzz_face = Some(rustybuzz_face);
        }
        Some(Self(inner))
    }

    pub fn as_ttf_parser_face(&self) -> &ttf_parser::Face<'_> {
        self.0.ttf_parser_face.as_ref().unwrap()
    }

    pub fn as_rustybuzz_face(&self) -> &rustybuzz::Face<'_> {
        self.0.rustybuzz_face.as_ref().unwrap()
    }
}

struct FontFaceInner {
    data: Rc<Vec<u8>>,
    ttf_parser_face: Option<ttf_parser::Face<'static>>,
    rustybuzz_face: Option<rustybuzz::Face<'static>>,
    _pinned: PhantomPinned,
}

impl fmt::Debug for FontFaceInner {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("FontFaceInner").finish_non_exhaustive()
    }
}