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 "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<psf2_header const *>(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<uint8_t const *>(data) + psf2->header_size;
return font{
psf2->height,
psf2->width,
psf2->length,
font_data};
}
int
font_draw(
struct font *f,
struct screen *s,
font::font() :
m_height(0),
m_width(0),
m_count(0),
m_data(nullptr)
{}
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,
uint32_t color,
uint32_t x,
uint32_t y)
screen::pixel_t color,
screen::coord_t x,
screen::coord_t y) const
{
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);
unsigned bwidth = (m_width+7)/8;
uint8_t const *data = m_data + (glyph * glyph_bytes());
for (int dy = 0; dy < f->height; ++dy) {
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;
}

View File

@@ -1,22 +1,33 @@
#pragma once
#include <stdint.h>
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);

View File

@@ -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(
font f = font::load(header->font);
screen s{
header->frame_buffer,
header->hres,
header->vres,
header->rmask,
header->gmask,
header->bmask,
&screen);
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<sizeof(message); ++i) {
font_draw(
&font,
&screen,
message[i],
color,
(i % perline) * font.width + 10,
(i / perline) * font.height + 10);
f.draw_glyph(s, message[i], color,
(i % perline) * f.width() + 10,
(i / perline) * f.height() + 10);
}
do_the_set_registers(header);

View File

@@ -1,42 +1,28 @@
#include "font.h"
#include "screen.h"
int
screen_fill(struct screen *s, uint32_t color)
screen::color_masks::color_masks(pixel_t r, pixel_t g, pixel_t b) : r(r), g(g), b(b) {}
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)
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<uint32_t *>(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;
}

View File

@@ -2,29 +2,37 @@
#include <stddef.h>
#include <stdint.h>
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);
};
int screen_init(
void *frame_buffer,
uint32_t hres,
uint32_t vres,
uint32_t rmask,
uint32_t gmask,
uint32_t bmask,
struct screen *s);
struct resolution {
coord_t w, h;
resolution(coord_t w, coord_t h);
coord_t size() const { return w * h; }
};
int screen_fill(struct screen *s, uint32_t color);
int screen_pixel(
struct screen *s,
uint32_t x,
uint32_t y,
uint32_t color);
private:
pixel_t *m_framebuffer;
color_masks m_masks;
resolution m_resolution;
};