1
- use bootloader_api:: info:: { FrameBufferInfo , PixelFormat } ;
1
+ use crate :: framebuffer:: FrameBufferWriter ;
2
+ use bootloader_api:: info:: FrameBufferInfo ;
3
+ use core:: fmt:: Write ;
2
4
use conquer_once:: spin:: OnceCell ;
3
- use core:: {
4
- fmt:: { self , Write } ,
5
- ptr,
6
- } ;
7
- use font_constants:: BACKUP_CHAR ;
8
- use noto_sans_mono_bitmap:: {
9
- get_raster, get_raster_width, FontWeight , RasterHeight , RasterizedChar ,
10
- } ;
11
5
use spinning_top:: Spinlock ;
12
6
13
7
/// The global logger instance used for the `log` crate.
14
8
pub static LOGGER : OnceCell < LockedLogger > = OnceCell :: uninit ( ) ;
15
9
16
- /// A [`Logger`] instance protected by a spinlock.
17
- pub struct LockedLogger ( Spinlock < Logger > ) ;
18
-
19
- /// Additional vertical space between lines
20
- const LINE_SPACING : usize = 2 ;
21
- /// Additional horizontal space between characters.
22
- const LETTER_SPACING : usize = 0 ;
23
-
24
- /// Padding from the border. Prevent that font is too close to border.
25
- const BORDER_PADDING : usize = 1 ;
26
-
27
- /// Constants for the usage of the [`noto_sans_mono_bitmap`] crate.
28
- mod font_constants {
29
- use super :: * ;
30
-
31
- /// Height of each char raster. The font size is ~0.84% of this. Thus, this is the line height that
32
- /// enables multiple characters to be side-by-side and appear optically in one line in a natural way.
33
- pub const CHAR_RASTER_HEIGHT : RasterHeight = RasterHeight :: Size16 ;
34
-
35
- /// The width of each single symbol of the mono space font.
36
- pub const CHAR_RASTER_WIDTH : usize = get_raster_width ( FontWeight :: Regular , CHAR_RASTER_HEIGHT ) ;
37
-
38
- /// Backup character if a desired symbol is not available by the font.
39
- /// The '�' character requires the feature "unicode-specials".
40
- pub const BACKUP_CHAR : char = '�' ;
41
-
42
- pub const FONT_WEIGHT : FontWeight = FontWeight :: Regular ;
43
- }
44
-
45
- /// Returns the raster of the given char or the raster of [`font_constants::BACKUP_CHAR`].
46
- fn get_char_raster ( c : char ) -> RasterizedChar {
47
- fn get ( c : char ) -> Option < RasterizedChar > {
48
- get_raster (
49
- c,
50
- font_constants:: FONT_WEIGHT ,
51
- font_constants:: CHAR_RASTER_HEIGHT ,
52
- )
53
- }
54
- get ( c) . unwrap_or_else ( || get ( BACKUP_CHAR ) . expect ( "Should get raster of backup char." ) )
55
- }
10
+ /// A [`FrameBufferWriter`] instance protected by a spinlock.
11
+ pub struct LockedLogger ( Spinlock < FrameBufferWriter > ) ;
56
12
57
13
impl LockedLogger {
58
14
/// Create a new instance that logs to the given framebuffer.
59
15
pub fn new ( framebuffer : & ' static mut [ u8 ] , info : FrameBufferInfo ) -> Self {
60
- LockedLogger ( Spinlock :: new ( Logger :: new ( framebuffer, info) ) )
16
+ LockedLogger ( Spinlock :: new ( FrameBufferWriter :: new ( framebuffer, info) ) )
61
17
}
62
18
63
19
/// Force-unlocks the logger to prevent a deadlock.
@@ -82,112 +38,3 @@ impl log::Log for LockedLogger {
82
38
fn flush ( & self ) { }
83
39
}
84
40
85
- /// Allows logging text to a pixel-based framebuffer.
86
- pub struct Logger {
87
- framebuffer : & ' static mut [ u8 ] ,
88
- info : FrameBufferInfo ,
89
- x_pos : usize ,
90
- y_pos : usize ,
91
- }
92
-
93
- impl Logger {
94
- /// Creates a new logger that uses the given framebuffer.
95
- pub fn new ( framebuffer : & ' static mut [ u8 ] , info : FrameBufferInfo ) -> Self {
96
- let mut logger = Self {
97
- framebuffer,
98
- info,
99
- x_pos : 0 ,
100
- y_pos : 0 ,
101
- } ;
102
- logger. clear ( ) ;
103
- logger
104
- }
105
-
106
- fn newline ( & mut self ) {
107
- self . y_pos += font_constants:: CHAR_RASTER_HEIGHT . val ( ) + LINE_SPACING ;
108
- self . carriage_return ( )
109
- }
110
-
111
- fn carriage_return ( & mut self ) {
112
- self . x_pos = BORDER_PADDING ;
113
- }
114
-
115
- /// Erases all text on the screen. Resets `self.x_pos` and `self.y_pos`.
116
- pub fn clear ( & mut self ) {
117
- self . x_pos = BORDER_PADDING ;
118
- self . y_pos = BORDER_PADDING ;
119
- self . framebuffer . fill ( 0 ) ;
120
- }
121
-
122
- fn width ( & self ) -> usize {
123
- self . info . width
124
- }
125
-
126
- fn height ( & self ) -> usize {
127
- self . info . height
128
- }
129
-
130
- /// Writes a single char to the framebuffer. Takes care of special control characters, such as
131
- /// newlines and carriage returns.
132
- fn write_char ( & mut self , c : char ) {
133
- match c {
134
- '\n' => self . newline ( ) ,
135
- '\r' => self . carriage_return ( ) ,
136
- c => {
137
- let new_xpos = self . x_pos + font_constants:: CHAR_RASTER_WIDTH ;
138
- if new_xpos >= self . width ( ) {
139
- self . newline ( ) ;
140
- }
141
- let new_ypos =
142
- self . y_pos + font_constants:: CHAR_RASTER_HEIGHT . val ( ) + BORDER_PADDING ;
143
- if new_ypos >= self . height ( ) {
144
- self . clear ( ) ;
145
- }
146
- self . write_rendered_char ( get_char_raster ( c) ) ;
147
- }
148
- }
149
- }
150
-
151
- /// Prints a rendered char into the framebuffer.
152
- /// Updates `self.x_pos`.
153
- fn write_rendered_char ( & mut self , rendered_char : RasterizedChar ) {
154
- for ( y, row) in rendered_char. raster ( ) . iter ( ) . enumerate ( ) {
155
- for ( x, byte) in row. iter ( ) . enumerate ( ) {
156
- self . write_pixel ( self . x_pos + x, self . y_pos + y, * byte) ;
157
- }
158
- }
159
- self . x_pos += rendered_char. width ( ) + LETTER_SPACING ;
160
- }
161
-
162
- fn write_pixel ( & mut self , x : usize , y : usize , intensity : u8 ) {
163
- let pixel_offset = y * self . info . stride + x;
164
- let color = match self . info . pixel_format {
165
- PixelFormat :: Rgb => [ intensity, intensity, intensity / 2 , 0 ] ,
166
- PixelFormat :: Bgr => [ intensity / 2 , intensity, intensity, 0 ] ,
167
- PixelFormat :: U8 => [ if intensity > 200 { 0xf } else { 0 } , 0 , 0 , 0 ] ,
168
- other => {
169
- // set a supported (but invalid) pixel format before panicking to avoid a double
170
- // panic; it might not be readable though
171
- self . info . pixel_format = PixelFormat :: Rgb ;
172
- panic ! ( "pixel format {:?} not supported in logger" , other)
173
- }
174
- } ;
175
- let bytes_per_pixel = self . info . bytes_per_pixel ;
176
- let byte_offset = pixel_offset * bytes_per_pixel;
177
- self . framebuffer [ byte_offset..( byte_offset + bytes_per_pixel) ]
178
- . copy_from_slice ( & color[ ..bytes_per_pixel] ) ;
179
- let _ = unsafe { ptr:: read_volatile ( & self . framebuffer [ byte_offset] ) } ;
180
- }
181
- }
182
-
183
- unsafe impl Send for Logger { }
184
- unsafe impl Sync for Logger { }
185
-
186
- impl fmt:: Write for Logger {
187
- fn write_str ( & mut self , s : & str ) -> fmt:: Result {
188
- for c in s. chars ( ) {
189
- self . write_char ( c) ;
190
- }
191
- Ok ( ( ) )
192
- }
193
- }
0 commit comments