Kernel: Fonts can now be parsed from the filesystem and set to terminal

We currently dont have a fallback font if we cannot get to filesystem
initialization, but that will come later. I can't test on real hardware
for this reason.
This commit is contained in:
Bananymous
2023-02-22 22:29:31 +02:00
parent 0e668738dc
commit a4980acc88
16 changed files with 78 additions and 58344 deletions

View File

@@ -324,6 +324,21 @@ argument_done:
TTY_PRINTLN("{}", BAN::StringView((const char*)data.data(), data.size()));
}
else if (arguments.front() == "loadfont")
{
if (!VirtualFileSystem::is_initialized())
return TTY_PRINTLN("VFS not initialized :(");
if (arguments.size() != 2)
return TTY_PRINTLN("usage: 'loadfont font_path'");
auto font_or_error = Font::load(arguments[1]);
if (font_or_error.is_error())
return TTY_PRINTLN("{}", font_or_error.error());
auto font = font_or_error.release_value();
m_tty->set_font(font);
}
else
{
TTY_PRINTLN("unrecognized command '{}'", arguments.front());

View File

@@ -52,6 +52,14 @@ void TTY::set_cursor_position(uint32_t x, uint32_t y)
last_y = m_row = y;
}
void TTY::set_font(const Kernel::Font& font)
{
m_terminal_driver->set_font(font);
for (uint32_t y = 0; y < m_height; y++)
for (uint32_t x = 0; x < m_width; x++)
render_from_buffer(x, y);
}
static uint16_t handle_unicode(uint8_t ch)
{
static uint8_t unicode_left = 0;

View File

@@ -4,9 +4,7 @@
#include <kernel/multiboot.h>
#include <kernel/VesaTerminalDriver.h>
extern const struct bitmap_font font;
VesaTerminalDriver* VesaTerminalDriver::create()
VesaTerminalDriver* VesaTerminalDriver::create(const Kernel::Font& font)
{
if (!(g_multiboot_info->flags & MULTIBOOT_FLAGS_FRAMEBUFFER))
{
@@ -73,29 +71,19 @@ void VesaTerminalDriver::set_pixel(uint32_t offset, Color color)
void VesaTerminalDriver::putchar_at(uint16_t ch, uint32_t x, uint32_t y, Color fg, Color bg)
{
uint32_t glyph_index = 0;
for (uint32_t i = 0; i < m_font.Chars; i++)
{
if (m_font.Index[i] == ch)
{
glyph_index = i;
break;
}
}
const uint8_t* glyph = font().has_glyph(ch) ? font().glyph(ch) : font().glyph('?');
const uint8_t* glyph = m_font.Bitmap + glyph_index * m_font.Height;
x *= m_font.Width;
y *= m_font.Height;
x *= font().width();
y *= font().height();
uint32_t row_offset = y * m_pitch + x * m_bpp / 8;
for (uint32_t dy = 0; dy < m_font.Height && y + dy < m_height; dy++)
for (uint32_t dy = 0; dy < font().height() && y + dy < m_height; dy++)
{
uint32_t pixel_offset = row_offset;
for (uint32_t dx = 0; dx < m_font.Width && x + dx < m_width; dx++)
for (uint32_t dx = 0; dx < font().width() && x + dx < m_width; dx++)
{
uint8_t bitmask = 1 << (font.Width - dx - 1);
set_pixel(pixel_offset, glyph[dy] & bitmask ? fg : bg);
uint8_t bitmask = 1 << (font().width() - dx - 1);
set_pixel(pixel_offset, glyph[dy * font().pitch()] & bitmask ? fg : bg);
pixel_offset += m_bpp / 8;
}
row_offset += m_pitch;
@@ -128,38 +116,19 @@ void VesaTerminalDriver::clear(Color color)
void VesaTerminalDriver::set_cursor_position(uint32_t x, uint32_t y)
{
ASSERT(m_font.Height == 16 && m_font.Width == 8);
constexpr uint8_t cursor[] = {
________,
________,
________,
________,
________,
________,
________,
________,
________,
________,
________,
________,
________,
XXXXXXXX,
XXXXXXXX,
________,
};
uint32_t cursor_h = font().height() / 8;
uint32_t cursor_top = font().height() * 13 / 16;
x *= m_font.Width;
y *= m_font.Height;
x *= font().width();
y *= font().height();
uint32_t row_offset = y * m_pitch + x * m_bpp / 8;
for (uint32_t dy = 0; dy < m_font.Height && y + dy < m_height; dy++)
uint32_t row_offset = (y + cursor_top) * m_pitch + x * m_bpp / 8;
for (uint32_t dy = 0; dy < cursor_h; dy++)
{
uint32_t pixel_offset = row_offset;
for (uint32_t dx = 0; dx < m_font.Width && x + dx < m_width; dx++)
for (uint32_t dx = 0; dx < font().width(); dx++)
{
uint8_t bitmask = 1 << (font.Width - dx - 1);
if (cursor[dy] & bitmask)
set_pixel(pixel_offset, s_cursor_color);
set_pixel(pixel_offset, s_cursor_color);
pixel_offset += m_bpp / 8;
}
row_offset += m_pitch;

File diff suppressed because it is too large Load Diff

View File

@@ -76,29 +76,40 @@ extern "C" void kernel_main()
dprintln("kmalloc initialized");
IDT::initialize();
dprintln("IDT initialized");
dprintln("IDT initialized");
MMU::intialize();
dprintln("MMU initialized");
TerminalDriver* terminal_driver = VesaTerminalDriver::create();
ASSERT(terminal_driver);
dprintln("VESA initialized");
TTY* tty1 = new TTY(terminal_driver);
//TerminalDriver* terminal_driver = VesaTerminalDriver::create();
//ASSERT(terminal_driver);
//dprintln("VESA initialized");
//TTY* tty1 = new TTY(terminal_driver);
InterruptController::initialize(cmdline.force_pic);
dprintln("Interrupt controller initialized");
PIT::initialize();
dprintln("PIT initialized");
if (!Input::initialize())
return;
dprintln("8042 initialized");
Scheduler::initialize();
Scheduler& scheduler = Scheduler::get();
MUST(scheduler.add_thread(BAN::Function<void()>([] { DiskIO::initialize(); })));
MUST(scheduler.add_thread(BAN::Function<void()>([tty1] { Shell(tty1).run(); })));
MUST(scheduler.add_thread(BAN::Function<void()>(
[]
{
DiskIO::initialize();
dprintln("Disk IO initialized");
auto font = MUST(Font::load("/usr/share/fonts/zap-ext-vga16.psf"));
dprintln("Font loaded");
Shell(new TTY(VesaTerminalDriver::create(font))).run();
}
)));
scheduler.start();
ASSERT(false);
}