Luna/kernel/src/render/TextRenderer.cpp

97 lines
2.6 KiB
C++

#define MODULE "text"
#include "render/TextRenderer.h"
#include "bootboot.h"
#include "font.h"
#include "init/InitRD.h"
#include "io/Serial.h"
#include "log/Log.h"
#include "render/Framebuffer.h"
#include "std/stdio.h"
#include "std/string.h"
extern BOOTBOOT bootboot;
static Color bgColor = Color::Black;
static Color fgColor = Color::White;
static uint32_t xpos = 0;
static uint32_t ypos = 0;
#define FONT_HEIGHT 16
#define FONT_WIDTH 8
void TextRenderer::reset()
{
xpos = 0;
ypos = 0;
}
#pragma GCC push_options
#pragma GCC optimize("O0")
static void putchar_at_offset(char c, [[maybe_unused]] uint32_t cx, [[maybe_unused]] uint32_t cy,
[[maybe_unused]] Color& fg, [[maybe_unused]] Color& bg)
{
uint8_t* glyph = &font[c * 16];
for (uint32_t y = 0; y < FONT_HEIGHT; y++)
{
for (uint32_t x = 0; x < FONT_WIDTH; x++)
{
volatile uint8_t mask = *glyph;
if ((mask & (0b10000000 >> x)) > 0) { framebuffer0.set_pixel(cx + x, cy + y, Color::White); }
else { framebuffer0.set_pixel(cx + x, cy + y, Color::Black); }
}
glyph++;
}
}
#pragma GCC pop_options
void TextRenderer::putchar(char chr)
{
switch (chr)
{
case '\n': {
ypos += FONT_HEIGHT;
if ((ypos + FONT_HEIGHT) >= bootboot.fb_height)
{
memcpy((void*)bootboot.fb_ptr, (char*)bootboot.fb_ptr + (bootboot.fb_scanline * FONT_HEIGHT),
bootboot.fb_size - (bootboot.fb_scanline * FONT_HEIGHT));
ypos -= FONT_HEIGHT;
framebuffer0.paint_rect(0, ypos, bootboot.fb_width, FONT_HEIGHT, Color::Black);
}
xpos = 0;
break;
}
case '\r': xpos = 0; break;
case '\b':
if (xpos != 0)
{
xpos -= FONT_WIDTH;
framebuffer0.paint_rect(xpos, ypos, FONT_WIDTH, FONT_HEIGHT, Color::Black);
}
break;
default: {
putchar_at_offset(chr, xpos, ypos, fgColor, bgColor);
xpos += FONT_WIDTH;
if ((xpos + FONT_WIDTH) > bootboot.fb_width)
{
xpos = 0;
ypos += FONT_HEIGHT;
if (ypos > bootboot.fb_height)
{
memcpy((void*)bootboot.fb_ptr, (char*)bootboot.fb_ptr + (bootboot.fb_scanline * FONT_HEIGHT),
bootboot.fb_size - (bootboot.fb_scanline * FONT_HEIGHT));
ypos -= FONT_HEIGHT;
framebuffer0.paint_rect(0, ypos, bootboot.fb_width, FONT_HEIGHT, Color::Black);
}
}
break;
}
}
}
void TextRenderer::write(const char* str, size_t size)
{
for (size_t i = 0; i < size; i++) { putchar(str[i]); }
}