makepad_draw/text/
font_face.rs1use {
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}