1use alloc::{vec, vec::Vec};
7
8use spin::Mutex;
9
10use crate::error::KernelError;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum FontSize {
15 Small = 8,
16 Medium = 12,
17 Large = 16,
18 ExtraLarge = 24,
19}
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23pub enum FontStyle {
24 Regular,
25 Bold,
26 Italic,
27 BoldItalic,
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32pub enum FontWeight {
33 Thin = 100,
34 Light = 300,
35 Regular = 400,
36 Medium = 500,
37 Bold = 700,
38 Black = 900,
39}
40
41#[derive(Debug, Clone)]
43pub struct Glyph {
44 pub character: char,
46
47 pub bitmap: Vec<u8>,
49
50 pub width: u8,
52
53 pub height: u8,
55
56 pub x_offset: i8,
58
59 pub y_offset: i8,
61
62 pub advance: u8,
64}
65
66impl Glyph {
67 pub fn new(character: char, width: u8, height: u8) -> Self {
69 let bitmap_size = (width as usize * height as usize).div_ceil(8);
70 Self {
71 character,
72 bitmap: vec![0; bitmap_size],
73 width,
74 height,
75 x_offset: 0,
76 y_offset: 0,
77 advance: width,
78 }
79 }
80
81 pub fn get_pixel(&self, x: u8, y: u8) -> bool {
83 if x >= self.width || y >= self.height {
84 return false;
85 }
86
87 let bit_index = y as usize * self.width as usize + x as usize;
88 let byte_index = bit_index / 8;
89 let bit_offset = bit_index % 8;
90
91 if byte_index >= self.bitmap.len() {
92 return false;
93 }
94
95 (self.bitmap[byte_index] & (1 << bit_offset)) != 0
96 }
97
98 pub fn set_pixel(&mut self, x: u8, y: u8, value: bool) {
100 if x >= self.width || y >= self.height {
101 return;
102 }
103
104 let bit_index = y as usize * self.width as usize + x as usize;
105 let byte_index = bit_index / 8;
106 let bit_offset = bit_index % 8;
107
108 if byte_index >= self.bitmap.len() {
109 return;
110 }
111
112 if value {
113 self.bitmap[byte_index] |= 1 << bit_offset;
114 } else {
115 self.bitmap[byte_index] &= !(1 << bit_offset);
116 }
117 }
118}
119
120pub struct Font {
122 pub name: &'static str,
124
125 pub size: FontSize,
127
128 pub style: FontStyle,
130
131 glyphs: Vec<Glyph>,
133
134 pub line_height: u8,
136
137 pub baseline: u8,
139}
140
141impl Font {
142 pub fn new(name: &'static str, size: FontSize, style: FontStyle) -> Self {
144 let height = size as u8;
145 let line_height = height + 2;
146 let baseline = height - 2;
147
148 let mut font = Self {
149 name,
150 size,
151 style,
152 glyphs: Vec::new(),
153 line_height,
154 baseline,
155 };
156
157 font.initialize_ascii_glyphs();
159
160 font
161 }
162
163 fn initialize_ascii_glyphs(&mut self) {
165 for ch in 32u8..=126 {
167 let character = ch as char;
168 let width = (self.size as u8 * 2) / 3; let glyph = Glyph::new(character, width, self.size as u8);
170 self.glyphs.push(glyph);
171 }
172 }
173
174 pub fn get_glyph(&self, ch: char) -> Option<&Glyph> {
176 let code = ch as u32;
177 if (32..=126).contains(&code) {
178 Some(&self.glyphs[(code - 32) as usize])
179 } else {
180 None
181 }
182 }
183
184 pub fn measure_text(&self, text: &str) -> u32 {
186 let mut width = 0u32;
187 for ch in text.chars() {
188 if let Some(glyph) = self.get_glyph(ch) {
189 width += glyph.advance as u32;
190 }
191 }
192 width
193 }
194
195 pub fn render_text(
197 &self,
198 text: &str,
199 buffer: &mut [u8],
200 buffer_width: usize,
201 buffer_height: usize,
202 x: i32,
203 y: i32,
204 ) -> Result<(), KernelError> {
205 let mut cursor_x = x;
206 let cursor_y = y;
207
208 for ch in text.chars() {
209 if let Some(glyph) = self.get_glyph(ch) {
210 for gy in 0..glyph.height {
212 for gx in 0..glyph.width {
213 if glyph.get_pixel(gx, gy) {
214 let px = cursor_x + gx as i32 + glyph.x_offset as i32;
215 let py = cursor_y + gy as i32 + glyph.y_offset as i32;
216
217 if px >= 0
218 && py >= 0
219 && (px as usize) < buffer_width
220 && (py as usize) < buffer_height
221 {
222 let pixel_index = py as usize * buffer_width + px as usize;
223 if pixel_index < buffer.len() {
224 buffer[pixel_index] = 255; }
226 }
227 }
228 }
229 }
230
231 cursor_x += glyph.advance as i32;
232 }
233 }
234
235 Ok(())
236 }
237}
238
239pub struct FontManager {
241 fonts: Vec<Font>,
243
244 default_font: usize,
246}
247
248impl FontManager {
249 pub fn new() -> Self {
251 let mut manager = Self {
252 fonts: Vec::new(),
253 default_font: 0,
254 };
255
256 manager.load_default_fonts();
258
259 manager
260 }
261
262 fn load_default_fonts(&mut self) {
264 self.fonts
266 .push(Font::new("Monospace", FontSize::Small, FontStyle::Regular));
267 self.fonts
268 .push(Font::new("Monospace", FontSize::Medium, FontStyle::Regular));
269 self.fonts
270 .push(Font::new("Monospace", FontSize::Large, FontStyle::Regular));
271 self.fonts
272 .push(Font::new("Monospace", FontSize::Medium, FontStyle::Bold));
273
274 println!("[FONT] Loaded {} default fonts", self.fonts.len());
275 }
276
277 pub fn get_default_font(&self) -> &Font {
279 &self.fonts[self.default_font]
280 }
281
282 pub fn get_font(&self, size: FontSize, style: FontStyle) -> Option<&Font> {
284 self.fonts
285 .iter()
286 .find(|f| f.size == size && f.style == style)
287 }
288
289 pub fn add_font(&mut self, font: Font) {
291 self.fonts.push(font);
292 }
293}
294
295impl Default for FontManager {
296 fn default() -> Self {
297 Self::new()
298 }
299}
300
301static FONT_MANAGER: Mutex<Option<FontManager>> = Mutex::new(None);
303
304pub fn init() -> Result<(), KernelError> {
306 let mut lock = FONT_MANAGER.lock();
307 if lock.is_some() {
308 return Err(KernelError::InvalidState {
309 expected: "uninitialized",
310 actual: "initialized",
311 });
312 }
313
314 *lock = Some(FontManager::new());
315
316 println!("[FONT] Font rendering system initialized");
317 Ok(())
318}
319
320pub fn with_font_manager<R, F: FnOnce(&mut FontManager) -> R>(f: F) -> Result<R, KernelError> {
322 FONT_MANAGER
323 .lock()
324 .as_mut()
325 .map(f)
326 .ok_or(KernelError::InvalidState {
327 expected: "initialized",
328 actual: "uninitialized",
329 })
330}
331
332#[cfg(test)]
333mod tests {
334 use super::*;
335
336 #[test]
337 fn test_font_creation() {
338 let font = Font::new("Test", FontSize::Medium, FontStyle::Regular);
339 assert_eq!(font.name, "Test");
340 assert_eq!(font.size, FontSize::Medium);
341 }
342
343 #[test]
344 fn test_glyph_pixel_operations() {
345 let mut glyph = Glyph::new('A', 8, 12);
346 assert!(!glyph.get_pixel(0, 0));
347
348 glyph.set_pixel(0, 0, true);
349 assert!(glyph.get_pixel(0, 0));
350
351 glyph.set_pixel(0, 0, false);
352 assert!(!glyph.get_pixel(0, 0));
353 }
354
355 #[test]
356 fn test_text_measurement() {
357 let font = Font::new("Test", FontSize::Medium, FontStyle::Regular);
358 let width = font.measure_text("Hello");
359 assert!(width > 0);
360 }
361}