Skip to content

Commit

Permalink
library/graphic: Implement scalable character drawing in LFB
Browse files Browse the repository at this point in the history
  • Loading branch information
fruhland committed Jun 4, 2024
1 parent 4463893 commit 7f3f91e
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 26 deletions.
2 changes: 1 addition & 1 deletion os/kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ uefi = { version = "0.28.0", features = ["alloc"] }
log = "0.4.20"
goblin = { version = "0.8.2", default-features = false, features = ["elf32", "elf64", "endian_fd"]}
tar-no-std = "0.3.1"
pci_types = "0.6.1"
pci_types = "0.7.0"

[build-dependencies]
built = { version = "0.7.2", features = ["chrono", "git2"] }
36 changes: 18 additions & 18 deletions os/kernel/src/device/lfb_terminal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ impl DisplayState {
pub fn new(buffer: *mut u8, pitch: u32, width: u32, height: u32, bpp: u8) -> Self {
let raw_lfb = LFB::new(buffer, pitch, width, height, bpp);
let mut lfb = BufferedLFB::new(raw_lfb);
let size = ((width / lfb::CHAR_WIDTH) as u16, (height / lfb::CHAR_HEIGHT) as u16);
let size = ((width / lfb::DEFAULT_CHAR_WIDTH) as u16, (height / lfb::DEFAULT_CHAR_HEIGHT) as u16);

let mut char_buffer = Vec::with_capacity(size.0 as usize * size.1 as usize * size_of::<Character>());
for _ in 0..char_buffer.capacity() {
Expand Down Expand Up @@ -114,7 +114,7 @@ impl CursorThread {
let cursor = self.terminal.cursor.lock();
let character = display.char_buffer[(cursor.pos.1 * display.size.0 + cursor.pos.0) as usize];

display.lfb.direct_lfb().draw_char(cursor.pos.0 as u32 * lfb::CHAR_WIDTH, cursor.pos.1 as u32 * lfb::CHAR_HEIGHT, character.fg_color, character.bg_color, if self.visible { character.value } else { CURSOR });
display.lfb.direct_lfb().draw_char(cursor.pos.0 as u32 * lfb::DEFAULT_CHAR_WIDTH, cursor.pos.1 as u32 * lfb::DEFAULT_CHAR_HEIGHT, character.fg_color, character.bg_color, if self.visible { character.value } else { CURSOR });
self.visible = !self.visible;

if sleep_counter >= 1000 {
Expand Down Expand Up @@ -238,14 +238,14 @@ impl LFBTerminal {
}

fn print_char_at(display: &mut DisplayState, color: &mut ColorState, c: char, pos: (u16, u16)) -> bool {
display.lfb.lfb().draw_char(pos.0 as u32 * lfb::CHAR_WIDTH, pos.1 as u32 * lfb::CHAR_HEIGHT, color.fg_color, color.bg_color, c)
&& display.lfb.direct_lfb().draw_char(pos.0 as u32 * lfb::CHAR_WIDTH, pos.1 as u32 * lfb::CHAR_HEIGHT, color.fg_color, color.bg_color, c)
display.lfb.lfb().draw_char(pos.0 as u32 * lfb::DEFAULT_CHAR_WIDTH, pos.1 as u32 * lfb::DEFAULT_CHAR_HEIGHT, color.fg_color, color.bg_color, c)
&& display.lfb.direct_lfb().draw_char(pos.0 as u32 * lfb::DEFAULT_CHAR_WIDTH, pos.1 as u32 * lfb::DEFAULT_CHAR_HEIGHT, color.fg_color, color.bg_color, c)
}

fn draw_status_bar(display: &mut DisplayState) {
// Draw background
for i in 0..display.size.0 as u32 * lfb::CHAR_WIDTH {
for j in 0..lfb::CHAR_HEIGHT {
for i in 0..display.size.0 as u32 * lfb::DEFAULT_CHAR_WIDTH {
for j in 0..lfb::DEFAULT_CHAR_HEIGHT {
display.lfb.lfb().draw_pixel(i, j, color::HHU_GREEN);
}
}
Expand All @@ -271,11 +271,11 @@ impl LFBTerminal {

if let Ok(date) = runtime_services.get_time() {
let date_str = format!("{}-{:0>2}-{:0>2} {:0>2}:{:0>2}:{:0>2}", date.year(), date.month(), date.day(), date.hour(), date.minute(), date.second());
display.lfb.lfb().draw_string((display.size.0 as u32 - date_str.len() as u32) * lfb::CHAR_WIDTH, 0, color::HHU_BLUE, color::INVISIBLE, &date_str);
display.lfb.lfb().draw_string((display.size.0 as u32 - date_str.len() as u32) * lfb::DEFAULT_CHAR_WIDTH, 0, color::HHU_BLUE, color::INVISIBLE, &date_str);
}
}

display.lfb.flush_lines(0, lfb::CHAR_HEIGHT);
display.lfb.flush_lines(0, lfb::DEFAULT_CHAR_HEIGHT);
}

fn scroll_up(display: &mut DisplayState, color: &mut ColorState) {
Expand All @@ -293,8 +293,8 @@ impl LFBTerminal {
});

let size = display.size;
display.lfb.lfb().scroll_up(lfb::CHAR_HEIGHT);
display.lfb.lfb().fill_rect(0, (size.1 - 1) as u32 * lfb::CHAR_HEIGHT, size.0 as u32 * lfb::CHAR_WIDTH, lfb::CHAR_HEIGHT, color.bg_color);
display.lfb.lfb().scroll_up(lfb::DEFAULT_CHAR_HEIGHT);
display.lfb.lfb().fill_rect(0, (size.1 - 1) as u32 * lfb::DEFAULT_CHAR_HEIGHT, size.0 as u32 * lfb::DEFAULT_CHAR_WIDTH, lfb::DEFAULT_CHAR_HEIGHT, color.bg_color);

LFBTerminal::draw_status_bar(display);
display.lfb.flush();
Expand Down Expand Up @@ -330,7 +330,7 @@ impl LFBTerminal {
fn clear_screen(display: &mut DisplayState, color: &mut ColorState) {
// Clear screen
let size = display.size;
display.lfb.lfb().fill_rect(0, 0, size.0 as u32 * lfb::CHAR_WIDTH, size.1 as u32 * lfb::CHAR_HEIGHT, color.bg_color);
display.lfb.lfb().fill_rect(0, 0, size.0 as u32 * lfb::DEFAULT_CHAR_WIDTH, size.1 as u32 * lfb::DEFAULT_CHAR_HEIGHT, color.bg_color);

// Clear character buffer
display.char_buffer.iter_mut().for_each(|item| {
Expand All @@ -348,10 +348,10 @@ impl LFBTerminal {
let size = display.size;

// Clear from start of line to cursor
display.lfb.lfb().fill_rect(0, pos.1 as u32 * lfb::CHAR_HEIGHT, pos.0 as u32 * lfb::CHAR_WIDTH, lfb::CHAR_HEIGHT, color.bg_color);
display.lfb.lfb().fill_rect(0, pos.1 as u32 * lfb::DEFAULT_CHAR_HEIGHT, pos.0 as u32 * lfb::DEFAULT_CHAR_WIDTH, lfb::DEFAULT_CHAR_HEIGHT, color.bg_color);

// Clear from start of screen to line before cursor
display.lfb.lfb().fill_rect(0, 0, size.0 as u32 * lfb::CHAR_WIDTH, pos.1 as u32 * lfb::CHAR_HEIGHT, color.bg_color);
display.lfb.lfb().fill_rect(0, 0, size.0 as u32 * lfb::DEFAULT_CHAR_WIDTH, pos.1 as u32 * lfb::DEFAULT_CHAR_HEIGHT, color.bg_color);

// Clear character buffer from beginning of screen to cursor
display.char_buffer.iter_mut().enumerate()
Expand All @@ -371,10 +371,10 @@ impl LFBTerminal {
let size = display.size;

// Clear from cursor to end of line
display.lfb.lfb().fill_rect(pos.0 as u32 * lfb::CHAR_WIDTH, pos.1 as u32 * lfb::CHAR_HEIGHT, (size.0 - pos.0) as u32 * lfb::CHAR_WIDTH, lfb::CHAR_HEIGHT, color.bg_color);
display.lfb.lfb().fill_rect(pos.0 as u32 * lfb::DEFAULT_CHAR_WIDTH, pos.1 as u32 * lfb::DEFAULT_CHAR_HEIGHT, (size.0 - pos.0) as u32 * lfb::DEFAULT_CHAR_WIDTH, lfb::DEFAULT_CHAR_HEIGHT, color.bg_color);

// Clear from next line to end of screen
display.lfb.lfb().fill_rect(0, (pos.1 + 1) as u32 * lfb::CHAR_HEIGHT, size.0 as u32 * lfb::CHAR_WIDTH, (size.1 - pos.1 - 1) as u32 * lfb::CHAR_HEIGHT, color.bg_color);
display.lfb.lfb().fill_rect(0, (pos.1 + 1) as u32 * lfb::DEFAULT_CHAR_HEIGHT, size.0 as u32 * lfb::DEFAULT_CHAR_WIDTH, (size.1 - pos.1 - 1) as u32 * lfb::DEFAULT_CHAR_HEIGHT, color.bg_color);

// Clear character buffer from cursor to end of screen
display.char_buffer.iter_mut().skip((pos.1 * size.0 + pos.0) as usize)
Expand All @@ -393,7 +393,7 @@ impl LFBTerminal {
let size = display.size;

// Clear line in lfb
display.lfb.lfb().fill_rect(0, pos.1 as u32 * lfb::CHAR_HEIGHT, size.0 as u32 * lfb::CHAR_WIDTH, lfb::CHAR_HEIGHT, color.bg_color);
display.lfb.lfb().fill_rect(0, pos.1 as u32 * lfb::DEFAULT_CHAR_HEIGHT, size.0 as u32 * lfb::DEFAULT_CHAR_WIDTH, lfb::DEFAULT_CHAR_HEIGHT, color.bg_color);
// Clear line in character buffer
display.char_buffer.iter_mut().skip((pos.1 * size.0) as usize).enumerate()
.filter(|item| item.0 < size.0 as usize)
Expand All @@ -414,7 +414,7 @@ impl LFBTerminal {
let size = display.size;

// Clear line in lfb
display.lfb.lfb().fill_rect(0, pos.1 as u32 * lfb::CHAR_HEIGHT, pos.0 as u32 * lfb::CHAR_WIDTH, lfb::CHAR_HEIGHT, color.bg_color);
display.lfb.lfb().fill_rect(0, pos.1 as u32 * lfb::DEFAULT_CHAR_HEIGHT, pos.0 as u32 * lfb::DEFAULT_CHAR_WIDTH, lfb::DEFAULT_CHAR_HEIGHT, color.bg_color);

// Clear line in character buffer
display.char_buffer.iter_mut().skip((pos.1 * size.0) as usize).enumerate()
Expand All @@ -436,7 +436,7 @@ impl LFBTerminal {
let size = display.size;

// Clear line in lfb
display.lfb.lfb().fill_rect(pos.0 as u32 * lfb::CHAR_WIDTH, pos.1 as u32 * lfb::CHAR_HEIGHT, (size.0 - pos.0) as u32 * lfb::CHAR_WIDTH, lfb::CHAR_HEIGHT, color.bg_color);
display.lfb.lfb().fill_rect(pos.0 as u32 * lfb::DEFAULT_CHAR_WIDTH, pos.1 as u32 * lfb::DEFAULT_CHAR_HEIGHT, (size.0 - pos.0) as u32 * lfb::DEFAULT_CHAR_WIDTH, lfb::DEFAULT_CHAR_HEIGHT, color.bg_color);

// Clear line in character buffer
display.char_buffer.iter_mut().skip((pos.1 * size.0 + pos.0) as usize).enumerate()
Expand Down
26 changes: 19 additions & 7 deletions os/library/graphic/src/lfb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ pub struct LFB {
unsafe impl Send for LFB {}
unsafe impl Sync for LFB {}

pub const CHAR_HEIGHT: u32 = 16;
pub const CHAR_WIDTH: u32 = 8;
pub const DEFAULT_CHAR_WIDTH: u32 = 8;
pub const DEFAULT_CHAR_HEIGHT: u32 = 16;

impl LFB {
pub const fn new(buffer: *mut u8, pitch: u32, width: u32, height: u32, bpp: u8) -> Self {
Expand Down Expand Up @@ -97,6 +97,10 @@ impl LFB {
}

pub fn draw_char(&self, x: u32, y: u32, fg_color: Color, bg_color: Color, c: char) -> bool {
self.draw_char_scaled(x, y, 1, 2, fg_color, bg_color, c)
}

pub fn draw_char_scaled(&self, x: u32, y: u32, x_scale: u32, y_scale: u32, fg_color: Color, bg_color: Color, c: char) -> bool {
let mut glyph = BASIC_FONTS.get(c);
if glyph.is_none() {
glyph = LATIN_FONTS.get(c);
Expand Down Expand Up @@ -131,13 +135,17 @@ impl LFB {
_ => fg_color,
};

self.draw_pixel(x + x_offset, y + y_offset, color);
self.draw_pixel(x + x_offset, y + y_offset + 1, color);
x_offset += 1;
for i in 0..x_scale {
for j in 0..y_scale {
self.draw_pixel(x + x_offset + i, y + y_offset + j, color);
}
}

x_offset += x_scale;
}

x_offset = 0;
y_offset += 2;
y_offset += y_scale;
}

return true;
Expand All @@ -147,8 +155,12 @@ impl LFB {
}

pub fn draw_string(&self, x: u32, y: u32, fg_color: Color, bg_color: Color, string: &str) {
self.draw_string_scaled(x, y, 1, 2, fg_color, bg_color, string);
}

pub fn draw_string_scaled(&self, x: u32, y: u32, x_scale: u32, y_scale: u32, fg_color: Color, bg_color: Color, string: &str) {
for c in string.chars().enumerate() {
self.draw_char(x + (c.0 as u32 * CHAR_WIDTH), y, fg_color, bg_color, c.1);
self.draw_char_scaled(x + (c.0 as u32 * (8 * x_scale)), y, x_scale, y_scale, fg_color, bg_color, c.1);
}
}

Expand Down

0 comments on commit 7f3f91e

Please sign in to comment.