tirbofish/dropbear
main / crates / kino-ui / src / rendering / text.rs · 3109 bytes
crates/kino-ui/src/rendering/text.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use glam::Vec2;
use glyphon::{
Buffer, Cache, Color, FontSystem, Resolution, SwashCache, TextArea, TextAtlas, TextBounds,
TextRenderer, Viewport,
};
pub struct TextEntry {
pub buffer: Buffer,
pub position: Vec2,
pub size: Vec2,
}
pub struct KinoTextRenderer {
pub font_system: FontSystem,
pub swash_cache: SwashCache,
pub atlas: TextAtlas,
pub renderer: TextRenderer,
pub viewport: Viewport,
pub entries: Vec<TextEntry>,
}
impl KinoTextRenderer {
pub(crate) fn new(
device: &wgpu::Device,
queue: &wgpu::Queue,
format: wgpu::TextureFormat,
) -> Self {
log::debug!("Creating KinoTextRenderer");
log::debug!("Loading system fonts");
let mut font_system = FontSystem::new();
font_system.db_mut().load_system_fonts();
log::debug!("Loaded system fonts");
log::debug!("Loading \"Roboto-Regular.ttf\" as fallback");
font_system.db_mut().load_font_data(
include_bytes!("../../../../resources/fonts/Roboto-Regular.ttf").to_vec(),
);
log::debug!("Loaded fallback");
let swash_cache = SwashCache::new();
let cache = Cache::new(device);
let viewport = Viewport::new(device, &cache);
let mut atlas = TextAtlas::new(device, queue, &cache, format);
let renderer = TextRenderer::new(&mut atlas, device, Default::default(), None);
log::debug!("Created new KinoTextRenderer");
Self {
font_system,
swash_cache,
atlas,
renderer,
viewport,
entries: Vec::new(),
}
}
/// Prepare the text renderer for drawing
pub fn prepare(&mut self, device: &wgpu::Device, queue: &wgpu::Queue, width: u32, height: u32) {
self.viewport.update(queue, Resolution { width, height });
let text_areas: Vec<TextArea> = self
.entries
.iter()
.map(|entry| TextArea {
buffer: &entry.buffer,
left: entry.position.x,
top: entry.position.y,
bounds: TextBounds {
right: width as i32,
bottom: height as i32,
..Default::default()
},
scale: 1.0,
default_color: Color::rgb(255, 255, 255),
custom_glyphs: &[],
})
.collect();
self.renderer
.prepare(
device,
queue,
&mut self.font_system,
&mut self.atlas,
&self.viewport,
text_areas,
&mut self.swash_cache,
)
.unwrap();
self.entries.clear();
}
pub fn render<'a>(&'a self, pass: &mut wgpu::RenderPass<'a>) {
self.renderer
.render(&self.atlas, &self.viewport, pass)
.unwrap();
}
pub fn resize(&mut self, width: u32, height: u32, queue: &wgpu::Queue) {
self.viewport.update(queue, Resolution { width, height });
}
}