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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use std::mem::replace;
use bytemuck::cast_slice;
use image::{EncodableLayout, GenericImageView, ImageFormat};
use crate::{Error, Result};
pub struct Builder {
pub(crate) inner_size: (usize, usize),
pub(crate) title: String,
pub(crate) font: Font,
}
pub(crate) enum Font {
Default,
Custom(FontData),
}
pub struct FontData {
pub data: Vec<u32>,
pub width: u32,
pub height: u32,
}
impl Builder {
pub fn new() -> Self {
Builder {
inner_size: (800, 600),
title: "mterm".to_string(),
font: Font::Default,
}
}
pub fn with_inner_size(&mut self, width: usize, height: usize) -> &mut Self {
self.inner_size = (width, height);
self
}
pub fn with_title(&mut self, title: &str) -> &mut Self {
self.title = String::from(title);
self
}
pub fn with_font(&mut self, font: FontData) -> &mut Self {
self.font = Font::Custom(font);
self
}
pub fn build(&mut self) -> Self {
Builder {
inner_size: self.inner_size,
font: replace(&mut self.font, Font::Default),
title: self.title.clone(),
}
}
}
pub fn load_font_image(data: &[u8], format: ImageFormat) -> Result<FontData> {
let font_image =
image::load_from_memory_with_format(data, format).map_err(|_| Error::BadFont)?;
let dimensions = font_image.dimensions();
let font_rgba = font_image.to_rgba8();
let font_data = font_rgba.as_bytes();
let data_u32: &[u32] = cast_slice(font_data);
let char_width = dimensions.0 / 16;
let char_height = dimensions.1 / 16;
if char_width == 0 || char_height == 0 {
return Err(Error::BadFont);
}
Ok(FontData {
width: char_width,
height: char_height,
data: Vec::from(data_u32),
})
}