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