Skip to content

Commit

Permalink
lib/graphic: Support full width unifont glyphs in lfb
Browse files Browse the repository at this point in the history
  • Loading branch information
fruhland committed Jun 5, 2024
1 parent d36996f commit 3b00a0b
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 33 deletions.
40 changes: 33 additions & 7 deletions os/kernel/src/device/lfb_terminal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use alloc::format;
use crate::device::terminal::Terminal;
use graphic::ansi::COLOR_TABLE_256;
use graphic::buffered_lfb::BufferedLFB;
use graphic::color::Color;
use graphic::color::{Color, INVISIBLE};
use graphic::lfb::LFB;
use graphic::{color, lfb};
use stream::{InputStream, OutputStream};
Expand Down Expand Up @@ -114,7 +114,15 @@ 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::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 });
let draw_character = match self.visible {
true => match character.value {
'\0' => ' ',
value => value
}
false => 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, draw_character);
self.visible = !self.visible;

if sleep_counter >= 1000 {
Expand Down Expand Up @@ -214,11 +222,29 @@ impl LFBTerminal {
cursor.pos.0 = 0;
cursor.pos.1 += 1;
} else {
if LFBTerminal::print_char_at(&mut display, &mut color, c, cursor.pos) {
let char_width = LFBTerminal::print_char_at(&mut display, &mut color, c, cursor.pos);
if char_width > 0 {
let index = (cursor.pos.1 * display.size.0 + cursor.pos.0) as usize;
let char_columns = (char_width / lfb::DEFAULT_CHAR_WIDTH + (if char_width % lfb::DEFAULT_CHAR_WIDTH == 0 { 0 } else { 1 })) as u16;

// Set character in character buffer
display.char_buffer[index] = Character { value: c, fg_color: color.fg_color, bg_color: color.bg_color };

cursor.pos.0 += 1;
// Null out following, if glyph is larger than one column
for i in 1..char_columns {
if cursor.pos.0 + i >= display.size.0 {
break;
}

display.char_buffer[index + i as usize] = Character { value: '\0', fg_color: INVISIBLE, bg_color: INVISIBLE };
}

if cursor.pos.0 + char_columns >= display.size.0 {
let row = cursor.pos.1;
LFBTerminal::position(&mut display, &mut cursor, &mut color, (0, row + 1));
} else {
cursor.pos.0 += char_columns;
}
}
}

Expand All @@ -237,9 +263,9 @@ 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::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 print_char_at(display: &mut DisplayState, color: &mut ColorState, c: char, pos: (u16, u16)) -> u32 {
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) {
Expand Down
47 changes: 21 additions & 26 deletions os/library/graphic/src/lfb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,44 +93,39 @@ impl LFB {
}
}

pub fn draw_char(&self, x: u32, y: u32, fg_color: Color, bg_color: Color, c: char) -> bool {
pub fn draw_char(&self, x: u32, y: u32, fg_color: Color, bg_color: Color, c: char) -> u32 {
self.draw_char_scaled(x, y, 1, 1, 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 {
pub fn draw_char_scaled(&self, x: u32, y: u32, x_scale: u32, y_scale: u32, fg_color: Color, bg_color: Color, c: char) -> u32 {
return match get_glyph(c) {
Some(glyph) => {
if glyph.is_fullwidth() {
// TODO: Support full width glyphs
self.draw_char_scaled(x, y, x_scale, y_scale, fg_color, bg_color, ' ');
} else {
let mut x_offset = 0;
let mut y_offset = 0;

for row in 0..DEFAULT_CHAR_HEIGHT {
for col in 0..glyph.get_width() as u32 {
let color = match glyph.get_pixel(col as usize, row as usize) {
true => fg_color,
false => bg_color
};

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

for row in 0..DEFAULT_CHAR_HEIGHT {
for col in 0..glyph.get_width() as u32 {
let color = match glyph.get_pixel(col as usize, row as usize) {
true => fg_color,
false => bg_color
};

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 += y_scale;
x_offset += x_scale;
}

x_offset = 0;
y_offset += y_scale;
}

true
glyph.get_width() as u32
},
None => false
None => 0
}
}

Expand Down

0 comments on commit 3b00a0b

Please sign in to comment.