forked from Bananymous/banan-os
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:
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
58006
kernel/kernel/font.c
58006
kernel/kernel/font.c
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user