diff --git a/src/modules/main/font.cpp b/src/modules/main/font.cpp index 44a8fce..2248ee0 100644 --- a/src/modules/main/font.cpp +++ b/src/modules/main/font.cpp @@ -1,5 +1,4 @@ #include "font.h" -#include "screen.h" /* PSF2 header format * Taken from the Linux KBD documentation @@ -7,19 +6,16 @@ */ const static uint8_t magic[] = {0x72, 0xb5, 0x4a, 0x86}; +const static uint32_t max_version = 0; + +const static uint8_t unicode_sep = 0xff; +const static uint8_t unicode_start = 0xfe; /* bits used in flags */ enum psf2_flags { psf2_has_unicode = 0x00000001 }; -/* max version recognized so far */ -#define PSF2_MAXVERSION 0 - -/* UTF8 separators */ -#define PSF2_SEPARATOR 0xFF -#define PSF2_STARTSEQ 0xFE - struct psf2_header { uint8_t magic[4]; uint32_t version; @@ -30,52 +26,59 @@ struct psf2_header { uint32_t height, width; // max dimensions of glyphs }; -int -font_init(void *header, struct font *font) +font +font::load(void const *data) { - struct psf2_header *psf2 = (struct psf2_header *)header; + psf2_header const *psf2 = static_cast(data); for (int i = 0; i < sizeof(magic); ++i) { if (psf2->magic[i] != magic[i]) { - return 1; + return font{}; } } - if (font == 0) - return 2; - - font->height = psf2->height; - font->width = psf2->width; - font->charsize = psf2->charsize; - font->count = psf2->length; - font->data = (uint8_t *)header + psf2->header_size; - return 0; + uint8_t const *font_data = static_cast(data) + psf2->header_size; + return font{ + psf2->height, + psf2->width, + psf2->length, + font_data}; } -int -font_draw( - struct font *f, - struct screen *s, - uint32_t glyph, - uint32_t color, - uint32_t x, - uint32_t y) -{ - const uint32_t height = f->height; - const uint32_t width = f->width; - const uint32_t bwidth = (width+7)/8; - uint8_t *data = f->data + (glyph * f->charsize); +font::font() : + m_height(0), + m_width(0), + m_count(0), + m_data(nullptr) +{} - for (int dy = 0; dy < f->height; ++dy) { +font::font(unsigned height, unsigned width, unsigned count, uint8_t const *data) : + m_height(height), + m_width(width), + m_count(count), + m_data(data) +{} + +void +font::draw_glyph( + screen &s, + uint32_t glyph, + screen::pixel_t color, + screen::coord_t x, + screen::coord_t y) const +{ + unsigned bwidth = (m_width+7)/8; + uint8_t const *data = m_data + (glyph * glyph_bytes()); + + for (int dy = 0; dy < m_height; ++dy) { for (int dx = 0; dx < bwidth; ++dx) { uint8_t byte = data[dy * bwidth + dx]; for (int i = 0; i < 8; ++i) { - if (dx*8 + i >= width) continue; + if (dx*8 + i >= m_width) continue; const uint8_t mask = 1 << (7-i); uint32_t c = (byte & mask) ? color : 0; - screen_pixel(s, x + dx*8 + i, y + dy, c); + s.draw_pixel(x + dx*8 + i, y + dy, c); } } } - return 0; } diff --git a/src/modules/main/font.h b/src/modules/main/font.h index 00fb8c8..44129ca 100644 --- a/src/modules/main/font.h +++ b/src/modules/main/font.h @@ -1,22 +1,33 @@ #pragma once #include -struct screen; +#include "screen.h" -struct font { - uint16_t height; - uint16_t width; - uint16_t charsize; - uint16_t count; - uint8_t *data; +class font +{ +public: + static font load(void const *data); + + unsigned glyph_bytes() const { return m_height * ((m_width + 7) / 8); } + unsigned count() const { return m_count; } + unsigned width() const { return m_width; } + unsigned height() const { return m_height; } + bool valid() const { return m_count > 0; } + + void draw_glyph( + screen &s, + uint32_t glyph, + screen::pixel_t color, + screen::coord_t x, + screen::coord_t y) const; + +private: + font(); + font(unsigned height, unsigned width, unsigned count, uint8_t const *data); + + unsigned m_height; + unsigned m_width; + unsigned m_count; + uint8_t const *m_data; }; -int font_init(void *header, struct font *font); - -int font_draw( - struct font *f, - struct screen *s, - uint32_t glyph, - uint32_t color, - uint32_t x, - uint32_t y); diff --git a/src/modules/main/main.cpp b/src/modules/main/main.cpp index 532c191..cad5d67 100644 --- a/src/modules/main/main.cpp +++ b/src/modules/main/main.cpp @@ -13,32 +13,22 @@ extern "C" { void kernel_main(popcorn_data *header) { - struct screen screen; - struct font font; - int status = 0; - - status = font_init(header->font, &font); - - status = screen_init( - header->frame_buffer, - header->hres, - header->vres, - header->rmask, - header->gmask, - header->bmask, - &screen); + font f = font::load(header->font); + screen s{ + header->frame_buffer, + header->hres, + header->vres, + header->rmask, + header->gmask, + header->bmask}; uint32_t color = header->gmask; - uint32_t perline = header->hres / font.width; + uint32_t perline = header->hres / f.width(); const char message[] = "Hello, I am text rendered by the kernel! :-D "; for (int i=0; i(framebuffer)), + m_masks(rmask, gmask, bmask), + m_resolution(hres, vres) { - const size_t len = s->hres * s->vres; +} + +void +screen::fill(pixel_t color) +{ + const size_t len = m_resolution.size(); for (size_t i = 0; i < len; ++i) - s->data[i] = 0; - return 0; + m_framebuffer[i] = color; } -int -screen_init( - void *frame_buffer, - uint32_t hres, - uint32_t vres, - uint32_t rmask, - uint32_t gmask, - uint32_t bmask, - struct screen *s) +void +screen::draw_pixel(coord_t x, coord_t y, pixel_t color) { - s->data = static_cast(frame_buffer); - s->hres = hres; - s->vres = vres; - s->rmask = rmask; - s->gmask = gmask; - s->bmask = bmask; - - return screen_fill(s, 0); -} - -int -screen_pixel( - struct screen *s, - uint32_t x, - uint32_t y, - uint32_t color) -{ - s->data[x + y*s->hres] = color; - return 0; + m_framebuffer[x + y * m_resolution.w] = color; } diff --git a/src/modules/main/screen.h b/src/modules/main/screen.h index e5708f1..f25eeeb 100644 --- a/src/modules/main/screen.h +++ b/src/modules/main/screen.h @@ -2,29 +2,37 @@ #include #include -struct screen { - uint32_t *data; - uint32_t hres; - uint32_t vres; - uint32_t rmask; - uint32_t gmask; - uint32_t bmask; +class screen +{ +public: + using coord_t = uint32_t; + using pixel_t = uint32_t; + + screen( + void *framebuffer, + coord_t hres, coord_t vres, + pixel_t rmask, pixel_t gmask, pixel_t bmask); + + void fill(pixel_t color); + void draw_pixel(coord_t x, coord_t y, pixel_t color); + + screen() = delete; + screen(const screen &) = delete; + + struct color_masks { + pixel_t r, g, b; + color_masks(pixel_t r, pixel_t g, pixel_t b); + }; + + struct resolution { + coord_t w, h; + resolution(coord_t w, coord_t h); + coord_t size() const { return w * h; } + }; + +private: + pixel_t *m_framebuffer; + color_masks m_masks; + resolution m_resolution; }; -int screen_init( - void *frame_buffer, - uint32_t hres, - uint32_t vres, - uint32_t rmask, - uint32_t gmask, - uint32_t bmask, - struct screen *s); - -int screen_fill(struct screen *s, uint32_t color); - -int screen_pixel( - struct screen *s, - uint32_t x, - uint32_t y, - uint32_t color); -