makepad_draw/text/
font_face.rs

1use {
2    makepad_rustybuzz as rustybuzz,
3    rustybuzz::ttf_parser,
4    std::{fmt, marker::PhantomPinned, mem, pin::Pin, rc::Rc},
5};
6
7#[derive(Debug)]
8pub struct FontFace(Pin<Box<FontFaceInner>>);
9
10impl FontFace {
11    pub fn from_data_and_index(data: Rc<Vec<u8>>, index: u32) -> Option<Self> {
12        let mut inner = Box::pin(FontFaceInner {
13            data,
14            ttf_parser_face: None,
15            rustybuzz_face: None,
16            _pinned: PhantomPinned,
17        });
18        unsafe {
19            let data: &'static [u8] = mem::transmute(&**inner.data);
20            let ttf_parser_face = ttf_parser::Face::parse(data, index).ok()?;
21            let rustybuzz_face = rustybuzz::Face::from_face(ttf_parser_face.clone());
22            let inner_ref = Pin::as_mut(&mut inner).get_unchecked_mut();
23            inner_ref.ttf_parser_face = Some(ttf_parser_face);
24            inner_ref.rustybuzz_face = Some(rustybuzz_face);
25        }
26        Some(Self(inner))
27    }
28
29    pub fn as_ttf_parser_face(&self) -> &ttf_parser::Face<'_> {
30        self.0.ttf_parser_face.as_ref().unwrap()
31    }
32
33    pub fn as_rustybuzz_face(&self) -> &rustybuzz::Face<'_> {
34        self.0.rustybuzz_face.as_ref().unwrap()
35    }
36}
37
38struct FontFaceInner {
39    data: Rc<Vec<u8>>,
40    ttf_parser_face: Option<ttf_parser::Face<'static>>,
41    rustybuzz_face: Option<rustybuzz::Face<'static>>,
42    _pinned: PhantomPinned,
43}
44
45impl fmt::Debug for FontFaceInner {
46    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47        f.debug_struct("FontFaceInner").finish_non_exhaustive()
48    }
49}