1
+ use crate :: binary:: logger:: font_constants:: BACKUP_CHAR ;
1
2
use crate :: boot_info:: { FrameBufferInfo , PixelFormat } ;
2
3
use conquer_once:: spin:: OnceCell ;
3
4
use core:: {
4
5
fmt:: { self , Write } ,
5
6
ptr,
6
7
} ;
7
- use noto_sans_mono_bitmap:: { get_bitmap, get_bitmap_width, BitmapChar , BitmapHeight , FontWeight } ;
8
+ use noto_sans_mono_bitmap:: {
9
+ get_raster, get_raster_width, FontWeight , RasterHeight , RasterizedChar ,
10
+ } ;
8
11
use spinning_top:: Spinlock ;
9
12
10
13
/// The global logger instance used for the `log` crate.
@@ -14,9 +17,41 @@ pub static LOGGER: OnceCell<LockedLogger> = OnceCell::uninit();
14
17
pub struct LockedLogger ( Spinlock < Logger > ) ;
15
18
16
19
/// Additional vertical space between lines
17
- const LINE_SPACING : usize = 0 ;
18
- /// Additional vertical space between separate log messages
19
- const LOG_SPACING : usize = 2 ;
20
+ const LINE_SPACING : usize = 2 ;
21
+
22
+ /// Constants for the usage of the [`noto_sans_mono_bitmap`] crate.
23
+ mod font_constants {
24
+ use super :: * ;
25
+
26
+ /// Height of each char raster. The font size is ~0.84% of this. Thus, this is the line height that
27
+ /// enables multiple characters to be side-by-side and appear optically in one line in a natural way.
28
+ pub const CHAR_RASTER_HEIGHT : RasterHeight = RasterHeight :: Size16 ;
29
+
30
+ /// The width of each single symbol of the mono space font.
31
+ pub const CHAR_RASTER_WIDTH : usize = get_raster_width ( FontWeight :: Regular , CHAR_RASTER_HEIGHT ) ;
32
+
33
+ /// Requires feature "unicode-specials"
34
+ pub const BACKUP_CHAR : char = '�' ;
35
+
36
+ pub const FONT_WEIGHT : FontWeight = FontWeight :: Regular ;
37
+ }
38
+
39
+ /// Returns the raster of the given char of the raster of [`font_constants::BACKUP_CHAR`].
40
+ fn get_char_raster ( c : char ) -> RasterizedChar {
41
+ get_raster (
42
+ c,
43
+ font_constants:: FONT_WEIGHT ,
44
+ font_constants:: CHAR_RASTER_HEIGHT ,
45
+ )
46
+ . unwrap_or (
47
+ get_raster (
48
+ BACKUP_CHAR ,
49
+ font_constants:: FONT_WEIGHT ,
50
+ font_constants:: CHAR_RASTER_HEIGHT ,
51
+ )
52
+ . unwrap ( ) ,
53
+ )
54
+ }
20
55
21
56
impl LockedLogger {
22
57
/// Create a new instance that logs to the given framebuffer.
@@ -40,7 +75,6 @@ impl log::Log for LockedLogger {
40
75
fn log ( & self , record : & log:: Record ) {
41
76
let mut logger = self . 0 . lock ( ) ;
42
77
writeln ! ( logger, "{}: {}" , record. level( ) , record. args( ) ) . unwrap ( ) ;
43
- logger. add_vspace ( LOG_SPACING ) ;
44
78
}
45
79
46
80
fn flush ( & self ) { }
@@ -68,19 +102,15 @@ impl Logger {
68
102
}
69
103
70
104
fn newline ( & mut self ) {
71
- self . y_pos += 14 + LINE_SPACING ;
105
+ self . y_pos += font_constants :: CHAR_RASTER_HEIGHT . val ( ) + LINE_SPACING ;
72
106
self . carriage_return ( )
73
107
}
74
108
75
- fn add_vspace ( & mut self , space : usize ) {
76
- self . y_pos += space;
77
- }
78
-
79
109
fn carriage_return ( & mut self ) {
80
110
self . x_pos = 0 ;
81
111
}
82
112
83
- /// Erases all text on the screen.
113
+ /// Erases all text on the screen. Resets `self.x_pos` and `self.y_pos` to zero.
84
114
pub fn clear ( & mut self ) {
85
115
self . x_pos = 0 ;
86
116
self . y_pos = 0 ;
@@ -95,27 +125,30 @@ impl Logger {
95
125
self . info . vertical_resolution
96
126
}
97
127
128
+ /// Writes a single char to the framebuffer. Takes care of special control characters, such as
129
+ /// newlines and carriage returns.
98
130
fn write_char ( & mut self , c : char ) {
99
131
match c {
100
132
'\n' => self . newline ( ) ,
101
133
'\r' => self . carriage_return ( ) ,
102
134
c => {
103
- if self . x_pos >= self . width ( ) {
135
+ let new_xpos = self . x_pos + font_constants:: CHAR_RASTER_WIDTH ;
136
+ if new_xpos >= self . width ( ) {
104
137
self . newline ( ) ;
105
138
}
106
- const BITMAP_LETTER_WIDTH : usize =
107
- get_bitmap_width ( FontWeight :: Regular , BitmapHeight :: Size14 ) ;
108
- if self . y_pos >= ( self . height ( ) - BITMAP_LETTER_WIDTH ) {
139
+ let new_ypos = self . y_pos + font_constants:: CHAR_RASTER_HEIGHT . val ( ) ;
140
+ if new_ypos >= self . height ( ) {
109
141
self . clear ( ) ;
110
142
}
111
- let bitmap_char = get_bitmap ( c, FontWeight :: Regular , BitmapHeight :: Size14 ) . unwrap ( ) ;
112
- self . write_rendered_char ( bitmap_char) ;
143
+ self . write_rendered_char ( get_char_raster ( c) ) ;
113
144
}
114
145
}
115
146
}
116
147
117
- fn write_rendered_char ( & mut self , rendered_char : BitmapChar ) {
118
- for ( y, row) in rendered_char. bitmap ( ) . iter ( ) . enumerate ( ) {
148
+ /// Prints a rendered char into the framebuffer.
149
+ /// Updates `self.x_pos`.
150
+ fn write_rendered_char ( & mut self , rendered_char : RasterizedChar ) {
151
+ for ( y, row) in rendered_char. raster ( ) . iter ( ) . enumerate ( ) {
119
152
for ( x, byte) in row. iter ( ) . enumerate ( ) {
120
153
self . write_pixel ( self . x_pos + x, self . y_pos + y, * byte) ;
121
154
}
0 commit comments