2022-09-10 22:17:18 +02:00
|
|
|
#define MODULE "text"
|
|
|
|
|
2022-09-05 16:13:51 +02:00
|
|
|
#include "render/TextRenderer.h"
|
|
|
|
#include "bootboot.h"
|
|
|
|
#include "init/InitRD.h"
|
|
|
|
#include "io/Serial.h"
|
2022-09-10 22:17:18 +02:00
|
|
|
#include "log/Log.h"
|
2022-09-19 20:17:37 +02:00
|
|
|
#include "psf1.h"
|
2022-09-10 18:44:14 +02:00
|
|
|
#include "render/Framebuffer.h"
|
2022-09-05 16:13:51 +02:00
|
|
|
#include "std/stdio.h"
|
|
|
|
#include "std/string.h"
|
|
|
|
|
|
|
|
extern BOOTBOOT bootboot;
|
|
|
|
|
2022-09-19 20:17:37 +02:00
|
|
|
static psf1_t* font;
|
2022-09-05 16:13:51 +02:00
|
|
|
static Color bgColor = Color::Black;
|
|
|
|
static Color fgColor = Color::White;
|
|
|
|
static uint32_t xpos = 0;
|
|
|
|
static uint32_t ypos = 0;
|
|
|
|
|
2022-09-19 20:17:37 +02:00
|
|
|
#define FONT_HEIGHT font->charsize
|
|
|
|
#define FONT_WIDTH 8
|
|
|
|
|
2022-09-05 16:13:51 +02:00
|
|
|
bool TextRenderer::try_initialize()
|
|
|
|
{
|
2022-09-10 22:17:18 +02:00
|
|
|
InitRD::File font_file = InitRD::open("boot/font.psf");
|
2022-09-05 16:13:51 +02:00
|
|
|
if (!font_file.addr)
|
|
|
|
{
|
2022-09-10 22:17:18 +02:00
|
|
|
kerrorln("Failed to load boot/font.psf from initrd");
|
2022-09-05 16:13:51 +02:00
|
|
|
return false;
|
|
|
|
}
|
2022-09-19 20:17:37 +02:00
|
|
|
font = (psf1_t*)font_file.addr;
|
|
|
|
if (font->magic[0] != psf1_magic[0] || font->magic[1] != psf1_magic[1])
|
2022-09-05 16:13:51 +02:00
|
|
|
{
|
2022-09-19 20:17:37 +02:00
|
|
|
kerrorln("Font magic does not match PSF font magic: 0x%x 0x%x", font->magic[0], font->magic[1]);
|
2022-09-05 16:13:51 +02:00
|
|
|
return false;
|
|
|
|
}
|
2022-09-19 20:17:37 +02:00
|
|
|
kdbgln("Loaded font %s, height %d, address %lx, mode %d", font_file.name, font->charsize,
|
|
|
|
(uintptr_t)&font->glyphs[0], font->mode);
|
2022-09-05 16:13:51 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TextRenderer::is_initialized()
|
|
|
|
{
|
|
|
|
return font; // if font is NULL, not initialized, else yes
|
|
|
|
}
|
|
|
|
|
2022-09-19 20:17:37 +02:00
|
|
|
static void putchar_at_offset(char c, uint32_t cx, uint32_t cy, Color& fg, Color& bg)
|
2022-09-05 16:13:51 +02:00
|
|
|
{
|
2022-09-19 20:17:37 +02:00
|
|
|
volatile uint8_t* glyph = (uint8_t*)font->glyphs + (c * font->charsize);
|
|
|
|
for (uint32_t y = 0; y < FONT_HEIGHT; y++)
|
2022-09-05 16:13:51 +02:00
|
|
|
{
|
2022-09-19 20:17:37 +02:00
|
|
|
for (uint32_t x = 0; x < FONT_WIDTH; x++)
|
2022-09-05 16:13:51 +02:00
|
|
|
{
|
2022-09-19 20:17:37 +02:00
|
|
|
if (((*glyph & (0b10000000 >> x)) > 0)) { framebuffer0.set_pixel(cx + x, cy + y, fg); }
|
|
|
|
else { framebuffer0.set_pixel(cx + x, cy + y, bg); }
|
2022-09-05 16:13:51 +02:00
|
|
|
}
|
2022-09-19 20:17:37 +02:00
|
|
|
glyph++;
|
2022-09-05 16:13:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextRenderer::putchar(char chr)
|
|
|
|
{
|
|
|
|
switch (chr)
|
|
|
|
{
|
|
|
|
case '\n':
|
2022-09-19 20:17:37 +02:00
|
|
|
ypos += FONT_HEIGHT;
|
|
|
|
if ((ypos + FONT_HEIGHT) >= bootboot.fb_height)
|
2022-09-05 16:13:51 +02:00
|
|
|
{
|
2022-09-19 20:17:37 +02:00
|
|
|
memcpy((void*)bootboot.fb_ptr, (uint32_t*)bootboot.fb_ptr + (bootboot.fb_scanline * FONT_HEIGHT),
|
|
|
|
bootboot.fb_size - (sizeof(uint32_t) * bootboot.fb_scanline * FONT_HEIGHT));
|
|
|
|
ypos -= FONT_HEIGHT;
|
|
|
|
framebuffer0.paint_rect(0, ypos, bootboot.fb_width, FONT_HEIGHT, Color::Black);
|
2022-09-05 16:13:51 +02:00
|
|
|
}
|
|
|
|
xpos = 0;
|
|
|
|
break;
|
|
|
|
case '\r': xpos = 0; break;
|
|
|
|
case '\b':
|
|
|
|
if (xpos != 0)
|
|
|
|
{
|
2022-09-19 20:17:37 +02:00
|
|
|
xpos -= FONT_WIDTH;
|
|
|
|
framebuffer0.paint_rect(xpos, ypos, FONT_WIDTH, FONT_HEIGHT, Color::Black);
|
2022-09-05 16:13:51 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
putchar_at_offset(chr, xpos, ypos, fgColor, bgColor);
|
2022-09-19 20:17:37 +02:00
|
|
|
xpos += FONT_WIDTH;
|
|
|
|
if ((xpos + FONT_WIDTH) > bootboot.fb_width)
|
2022-09-05 16:13:51 +02:00
|
|
|
{
|
|
|
|
xpos = 0;
|
2022-09-19 20:17:37 +02:00
|
|
|
ypos += FONT_HEIGHT;
|
2022-09-05 16:13:51 +02:00
|
|
|
if (ypos > bootboot.fb_height)
|
|
|
|
{
|
2022-09-19 20:17:37 +02:00
|
|
|
memcpy((void*)bootboot.fb_ptr, (uint32_t*)bootboot.fb_ptr + (bootboot.fb_scanline * FONT_HEIGHT),
|
|
|
|
bootboot.fb_size - (sizeof(uint32_t) * bootboot.fb_scanline * FONT_HEIGHT));
|
|
|
|
ypos -= FONT_HEIGHT;
|
|
|
|
framebuffer0.paint_rect(0, ypos, bootboot.fb_width, FONT_HEIGHT, Color::Black);
|
2022-09-05 16:13:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextRenderer::write(const char* str, size_t size)
|
|
|
|
{
|
|
|
|
for (size_t i = 0; i < size; i++) { putchar(str[i]); }
|
|
|
|
}
|