makepad_draw/text/
fonts.rs

1use {
2    super::{
3        font::FontId,
4        font_family::FontFamilyId,
5        layouter::{self, LaidoutText, LayoutParams, Layouter},
6        loader::{FontDefinition, FontFamilyDefinition},
7        rasterizer::Rasterizer,
8    },
9    makepad_platform::*,
10    std::{cell::RefCell, mem, rc::Rc},
11};
12
13#[derive(Debug)]
14pub struct Fonts {
15    layouter: Layouter,
16    needs_prepare_atlases: bool,
17    grayscale_texture: Texture,
18    color_texture: Texture,
19}
20
21impl Fonts {
22    pub fn new(cx: &mut Cx, settings: layouter::Settings) -> Self {
23        let layouter = Layouter::new(settings);
24        let rasterizer = layouter.rasterizer().borrow();
25        let grayscale_atlas_size = rasterizer.grayscale_atlas().size();
26        let color_atlas_size = rasterizer.color_atlas().size();
27        drop(rasterizer);
28        Self {
29            layouter,
30            needs_prepare_atlases: false,
31            grayscale_texture: Texture::new_with_format(
32                cx,
33                TextureFormat::VecRu8 {
34                    width: grayscale_atlas_size.width,
35                    height: grayscale_atlas_size.height,
36                    data: None,
37                    unpack_row_length: None,
38                    updated: TextureUpdated::Empty,
39                },
40            ),
41            color_texture: Texture::new_with_format(
42                cx,
43                TextureFormat::VecBGRAu8_32 {
44                    width: color_atlas_size.width,
45                    height: color_atlas_size.height,
46                    data: None,
47                    updated: TextureUpdated::Empty,
48                },
49            ),
50        }
51    }
52
53    pub fn rasterizer(&self) -> &Rc<RefCell<Rasterizer>> {
54        self.layouter.rasterizer()
55    }
56
57    pub fn grayscale_texture(&self) -> &Texture {
58        &self.grayscale_texture
59    }
60
61    pub fn color_texture(&self) -> &Texture {
62        &self.color_texture
63    }
64
65    pub fn is_font_family_known(&self, id: FontFamilyId) -> bool {
66        self.layouter.is_font_family_known(id)
67    }
68
69    pub fn is_font_known(&self, id: FontId) -> bool {
70        self.layouter.is_font_known(id)
71    }
72
73    pub fn define_font_family(&mut self, id: FontFamilyId, definition: FontFamilyDefinition) {
74        self.layouter.define_font_family(id, definition);
75    }
76
77    pub fn define_font(&mut self, id: FontId, definition: FontDefinition) {
78        self.layouter.define_font(id, definition);
79    }
80
81    pub fn get_or_layout(&mut self, params: impl LayoutParams) -> Rc<LaidoutText> {
82        self.layouter.get_or_layout(params)
83    }
84
85    pub fn prepare_textures(&mut self, cx: &mut Cx) -> bool {
86        assert!(!self.needs_prepare_atlases);
87        let mut rasterizer = self.layouter.rasterizer().borrow_mut();
88        if rasterizer.grayscale_atlas_mut().reset_if_needed() {
89            return false;
90        }
91        if rasterizer.color_atlas_mut().reset_if_needed() {
92            return false;
93        }
94        drop(rasterizer);
95        self.prepare_grayscale_texture(cx);
96        self.prepare_color_texture(cx);
97        self.needs_prepare_atlases = true;
98        true
99    }
100
101    fn prepare_grayscale_texture(&mut self, cx: &mut Cx) {
102        let mut rasterizer = self.layouter.rasterizer().borrow_mut();
103        let dirty_rect = rasterizer.grayscale_atlas_mut().take_dirty_image().bounds();
104        let pixels: Vec<u8> = unsafe {
105            mem::transmute(rasterizer.grayscale_atlas_mut().replace_pixels(Vec::new()))
106        };
107        self.grayscale_texture.put_back_vec_u8(
108            cx,
109            pixels,
110            Some(RectUsize::new(
111                PointUsize::new(dirty_rect.origin.x, dirty_rect.origin.y),
112                SizeUsize::new(dirty_rect.size.width, dirty_rect.size.height),
113            )),
114        );
115    }
116
117    fn prepare_color_texture(&mut self, cx: &mut Cx) {
118        let mut rasterizer = self.layouter.rasterizer().borrow_mut();
119        let dirty_rect = rasterizer.color_atlas_mut().take_dirty_image().bounds();
120        let pixels: Vec<u32> = unsafe {
121            mem::transmute(rasterizer.color_atlas_mut().replace_pixels(Vec::new()))
122        };
123        self.color_texture.put_back_vec_u32(
124            cx,
125            pixels,
126            Some(RectUsize::new(
127                PointUsize::new(dirty_rect.origin.x, dirty_rect.origin.y),
128                SizeUsize::new(dirty_rect.size.width, dirty_rect.size.height),
129            )),
130        )
131    }
132
133    pub fn prepare_atlases_if_needed(&mut self, cx: &mut Cx) {
134        if !self.needs_prepare_atlases {
135            return;
136        }
137        self.prepare_grayscale_atlas(cx);
138        self.prepare_color_atlas(cx);
139        self.needs_prepare_atlases = false;
140    }
141
142    fn prepare_grayscale_atlas(&mut self, cx: &mut Cx) {
143        let mut rasterizer = self.layouter.rasterizer().borrow_mut();
144        let pixels = self.grayscale_texture.take_vec_u8(cx);
145        unsafe {
146            rasterizer.grayscale_atlas_mut().replace_pixels(mem::transmute(pixels))
147        };
148    }
149
150    fn prepare_color_atlas(&mut self, cx: &mut Cx) {
151        let mut rasterizer = self.layouter.rasterizer().borrow_mut();
152        let pixels = self.color_texture.take_vec_u32(cx);
153        unsafe {
154            rasterizer.color_atlas_mut().replace_pixels(mem::transmute(pixels))
155        };
156    }
157}