Move screen and font to proper classes

This commit is contained in:
Justin C. Miller
2018-04-09 13:56:14 -07:00
parent 77cc1fe757
commit eaa9d2ba53
5 changed files with 132 additions and 134 deletions

View File

@@ -1,5 +1,4 @@
#include "font.h" #include "font.h"
#include "screen.h"
/* PSF2 header format /* PSF2 header format
* Taken from the Linux KBD documentation * Taken from the Linux KBD documentation
@@ -7,19 +6,16 @@
*/ */
const static uint8_t magic[] = {0x72, 0xb5, 0x4a, 0x86}; 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 */ /* bits used in flags */
enum psf2_flags { enum psf2_flags {
psf2_has_unicode = 0x00000001 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 { struct psf2_header {
uint8_t magic[4]; uint8_t magic[4];
uint32_t version; uint32_t version;
@@ -30,52 +26,59 @@ struct psf2_header {
uint32_t height, width; // max dimensions of glyphs uint32_t height, width; // max dimensions of glyphs
}; };
int font
font_init(void *header, struct font *font) font::load(void const *data)
{ {
struct psf2_header *psf2 = (struct psf2_header *)header; psf2_header const *psf2 = static_cast<psf2_header const *>(data);
for (int i = 0; i < sizeof(magic); ++i) { for (int i = 0; i < sizeof(magic); ++i) {
if (psf2->magic[i] != magic[i]) { if (psf2->magic[i] != magic[i]) {
return 1; return font{};
} }
} }
if (font == 0) uint8_t const *font_data = static_cast<uint8_t const *>(data) + psf2->header_size;
return 2; return font{
psf2->height,
font->height = psf2->height; psf2->width,
font->width = psf2->width; psf2->length,
font->charsize = psf2->charsize; font_data};
font->count = psf2->length;
font->data = (uint8_t *)header + psf2->header_size;
return 0;
} }
int font::font() :
font_draw( m_height(0),
struct font *f, m_width(0),
struct screen *s, m_count(0),
uint32_t glyph, m_data(nullptr)
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);
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) { for (int dx = 0; dx < bwidth; ++dx) {
uint8_t byte = data[dy * bwidth + dx]; uint8_t byte = data[dy * bwidth + dx];
for (int i = 0; i < 8; ++i) { 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); const uint8_t mask = 1 << (7-i);
uint32_t c = (byte & mask) ? color : 0; 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;
} }

View File

@@ -1,22 +1,33 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
struct screen; #include "screen.h"
struct font { class font
uint16_t height; {
uint16_t width; public:
uint16_t charsize; static font load(void const *data);
uint16_t count;
uint8_t *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);

View File

@@ -13,32 +13,22 @@ extern "C" {
void void
kernel_main(popcorn_data *header) kernel_main(popcorn_data *header)
{ {
struct screen screen; font f = font::load(header->font);
struct font font; screen s{
int status = 0; header->frame_buffer,
header->hres,
status = font_init(header->font, &font); header->vres,
header->rmask,
status = screen_init( header->gmask,
header->frame_buffer, header->bmask};
header->hres,
header->vres,
header->rmask,
header->gmask,
header->bmask,
&screen);
uint32_t color = header->gmask; 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 "; const char message[] = "Hello, I am text rendered by the kernel! :-D ";
for (int i=0; i<sizeof(message); ++i) { for (int i=0; i<sizeof(message); ++i) {
font_draw( f.draw_glyph(s, message[i], color,
&font, (i % perline) * f.width() + 10,
&screen, (i / perline) * f.height() + 10);
message[i],
color,
(i % perline) * font.width + 10,
(i / perline) * font.height + 10);
} }
do_the_set_registers(header); do_the_set_registers(header);

View File

@@ -1,42 +1,28 @@
#include "font.h"
#include "screen.h" #include "screen.h"
int screen::color_masks::color_masks(pixel_t r, pixel_t g, pixel_t b) : r(r), g(g), b(b) {}
screen_fill(struct screen *s, uint32_t color) screen::resolution::resolution(coord_t w, coord_t h) : w(w), h(h) {}
screen::screen(
void *framebuffer,
coord_t hres, coord_t vres,
pixel_t rmask, pixel_t gmask, pixel_t bmask) :
m_framebuffer(static_cast<pixel_t *>(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) for (size_t i = 0; i < len; ++i)
s->data[i] = 0; m_framebuffer[i] = color;
return 0;
} }
int void
screen_init( screen::draw_pixel(coord_t x, coord_t y, pixel_t color)
void *frame_buffer,
uint32_t hres,
uint32_t vres,
uint32_t rmask,
uint32_t gmask,
uint32_t bmask,
struct screen *s)
{ {
s->data = static_cast<uint32_t *>(frame_buffer); m_framebuffer[x + y * m_resolution.w] = color;
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;
} }

View File

@@ -2,29 +2,37 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
struct screen { class screen
uint32_t *data; {
uint32_t hres; public:
uint32_t vres; using coord_t = uint32_t;
uint32_t rmask; using pixel_t = uint32_t;
uint32_t gmask;
uint32_t bmask; 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);