Skip to content

Commit b1f442b

Browse files
authored
Merge pull request #267 from phip1611/fb-logger-noto-sans-mono-bitmap-bump
fb/logger: bump noto-sans-mono-bitmap + improvements
2 parents 515a7ec + ecd9e39 commit b1f442b

File tree

3 files changed

+73
-32
lines changed

3 files changed

+73
-32
lines changed

Cargo.lock

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+12-6
Original file line numberDiff line numberDiff line change
@@ -56,17 +56,23 @@ rand = { version = "0.8.4", optional = true, default-features = false }
5656
rand_chacha = { version = "0.3.1", optional = true, default-features = false }
5757

5858
[dependencies.noto-sans-mono-bitmap]
59-
version = "0.1.2"
59+
version = "0.2.0"
6060
default-features = false
61-
features = ["regular", "size_14"]
61+
features = [
62+
"regular",
63+
"size_16",
64+
"unicode-basic-latin",
65+
# required for the fallback char '�'
66+
"unicode-specials"
67+
]
6268
optional = true
6369

6470
[build-dependencies]
6571
llvm-tools-build = { version = "0.1", optional = true, package = "llvm-tools" }
6672
toml = { version = "0.5.1", optional = true }
67-
serde = { version = "1.0", features = ["derive"], optional = true}
68-
quote = { version = "1.0", optional = true}
69-
proc-macro2 = { version = "1.0", optional = true}
73+
serde = { version = "1.0", features = ["derive"], optional = true }
74+
quote = { version = "1.0", optional = true }
75+
proc-macro2 = { version = "1.0", optional = true }
7076

7177
[features]
7278
default = []
@@ -94,6 +100,6 @@ default-target = "x86_64-unknown-linux-gnu"
94100
[package.metadata.release]
95101
dev-version = false
96102
pre-release-replacements = [
97-
{ file="Changelog.md", search="# Unreleased", replace="# Unreleased\n\n# {{version}} – {{date}}", exactly=1 },
103+
{ file = "Changelog.md", search = "# Unreleased", replace = "# Unreleased\n\n# {{version}} – {{date}}", exactly = 1 },
98104
]
99105
pre-release-commit-message = "Release version {{version}}"

src/binary/logger.rs

+59-24
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
use crate::binary::logger::font_constants::BACKUP_CHAR;
12
use crate::boot_info::{FrameBufferInfo, PixelFormat};
23
use conquer_once::spin::OnceCell;
34
use core::{
45
fmt::{self, Write},
56
ptr,
67
};
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+
};
811
use spinning_top::Spinlock;
912

1013
/// The global logger instance used for the `log` crate.
@@ -14,9 +17,42 @@ pub static LOGGER: OnceCell<LockedLogger> = OnceCell::uninit();
1417
pub struct LockedLogger(Spinlock<Logger>);
1518

1619
/// 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+
/// 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(get(BACKUP_CHAR).expect("Should get raster of backup char."))
55+
}
2056

2157
impl LockedLogger {
2258
/// Create a new instance that logs to the given framebuffer.
@@ -39,8 +75,7 @@ impl log::Log for LockedLogger {
3975

4076
fn log(&self, record: &log::Record) {
4177
let mut logger = self.0.lock();
42-
writeln!(logger, "{}: {}", record.level(), record.args()).unwrap();
43-
logger.add_vspace(LOG_SPACING);
78+
writeln!(logger, "{:5}: {}", record.level(), record.args()).unwrap();
4479
}
4580

4681
fn flush(&self) {}
@@ -68,22 +103,18 @@ impl Logger {
68103
}
69104

70105
fn newline(&mut self) {
71-
self.y_pos += 14 + LINE_SPACING;
106+
self.y_pos += font_constants::CHAR_RASTER_HEIGHT.val() + LINE_SPACING;
72107
self.carriage_return()
73108
}
74109

75-
fn add_vspace(&mut self, space: usize) {
76-
self.y_pos += space;
77-
}
78-
79110
fn carriage_return(&mut self) {
80-
self.x_pos = 0;
111+
self.x_pos = BORDER_PADDING;
81112
}
82113

83-
/// Erases all text on the screen.
114+
/// Erases all text on the screen. Resets `self.x_pos` and `self.y_pos`.
84115
pub fn clear(&mut self) {
85-
self.x_pos = 0;
86-
self.y_pos = 0;
116+
self.x_pos = BORDER_PADDING;
117+
self.y_pos = BORDER_PADDING;
87118
self.framebuffer.fill(0);
88119
}
89120

@@ -95,32 +126,36 @@ impl Logger {
95126
self.info.vertical_resolution
96127
}
97128

129+
/// Writes a single char to the framebuffer. Takes care of special control characters, such as
130+
/// newlines and carriage returns.
98131
fn write_char(&mut self, c: char) {
99132
match c {
100133
'\n' => self.newline(),
101134
'\r' => self.carriage_return(),
102135
c => {
103-
if self.x_pos >= self.width() {
136+
let new_xpos = self.x_pos + font_constants::CHAR_RASTER_WIDTH;
137+
if new_xpos >= self.width() {
104138
self.newline();
105139
}
106-
const BITMAP_LETTER_WIDTH: usize =
107-
get_bitmap_width(FontWeight::Regular, BitmapHeight::Size14);
108-
if self.y_pos >= (self.height() - BITMAP_LETTER_WIDTH) {
140+
let new_ypos =
141+
self.y_pos + font_constants::CHAR_RASTER_HEIGHT.val() + BORDER_PADDING;
142+
if new_ypos >= self.height() {
109143
self.clear();
110144
}
111-
let bitmap_char = get_bitmap(c, FontWeight::Regular, BitmapHeight::Size14).unwrap();
112-
self.write_rendered_char(bitmap_char);
145+
self.write_rendered_char(get_char_raster(c));
113146
}
114147
}
115148
}
116149

117-
fn write_rendered_char(&mut self, rendered_char: BitmapChar) {
118-
for (y, row) in rendered_char.bitmap().iter().enumerate() {
150+
/// Prints a rendered char into the framebuffer.
151+
/// Updates `self.x_pos`.
152+
fn write_rendered_char(&mut self, rendered_char: RasterizedChar) {
153+
for (y, row) in rendered_char.raster().iter().enumerate() {
119154
for (x, byte) in row.iter().enumerate() {
120155
self.write_pixel(self.x_pos + x, self.y_pos + y, *byte);
121156
}
122157
}
123-
self.x_pos += rendered_char.width();
158+
self.x_pos += rendered_char.width() + LETTER_SPACING;
124159
}
125160

126161
fn write_pixel(&mut self, x: usize, y: usize, intensity: u8) {

0 commit comments

Comments
 (0)