Clean up system font drawing
Refactor font reading to fewer places
This commit is contained in:
parent
1dd19faaeb
commit
c2a7eed9d8
6 changed files with 51 additions and 124 deletions
|
@ -492,6 +492,16 @@ struct font
|
|||
bool wide; //If set, 16 wide instead of 8.
|
||||
uint32_t* data; //Glyph data. Bitpacked with element padding between rows.
|
||||
size_t offset; //Glyph offset.
|
||||
uint32_t get_width() const throw() { return wide ? 16 : 8; }
|
||||
uint32_t get_height() const throw() { return 16; }
|
||||
bool read_pixel(uint32_t x, uint32_t y) const throw()
|
||||
{
|
||||
if(wide) {
|
||||
return ((data[y >> 1] >> (31 - (((y & 1) << 4) + x))) & 1) != 0;
|
||||
} else {
|
||||
return ((data[y >> 2] >> (31 - (((y & 3) << 3) + x))) & 1) != 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -53,12 +53,9 @@ namespace
|
|||
{
|
||||
while(rlist->scale) {
|
||||
auto g = main_font.get_glyph(rlist->codepoint);
|
||||
for(uint32_t j = 0; j < 16; j++) {
|
||||
for(uint32_t i = 0; i < (g.wide ? 16 : 8); i++) {
|
||||
uint32_t slice = g.data[j / (g.wide ? 2 : 4)];
|
||||
uint32_t bit = 31 - ((j % (g.wide ? 2 : 4)) * (g.wide ? 16 : 8) + i);
|
||||
uint32_t value = (slice >> bit) & 1;
|
||||
if(value) {
|
||||
for(uint32_t j = 0; j < g.get_height(); j++) {
|
||||
for(uint32_t i = 0; i < g.get_width(); i++) {
|
||||
if(g.read_pixel(i, j)) {
|
||||
uint32_t basex = rlist->x + rlist->scale * i;
|
||||
uint32_t basey = rlist->y + rlist->scale * j;
|
||||
for(uint32_t j2 = 0; j2 < rlist->scale; j2++)
|
||||
|
|
|
@ -965,17 +965,11 @@ failed:
|
|||
main_font.for_each_glyph(str, 0, false, false, [size, &fg, &bg, bmp](uint32_t ix, uint32_t iy,
|
||||
const framebuffer::font::glyph& g, bool hdbl, bool vdbl) {
|
||||
T* _bmp = bmp + (iy * size.first + ix);
|
||||
size_t w = g.wide ? 16 : 8;
|
||||
size_t w = g.get_width();
|
||||
size_t skip = size.first - w;
|
||||
for(size_t _y = 0; _y < 16; _y++) {
|
||||
uint32_t d = g.data[_y >> (g.wide ? 1 : 2)];
|
||||
if(g.wide)
|
||||
d >>= 16 - ((_y & 1) << 4);
|
||||
else
|
||||
d >>= 24 - ((_y & 3) << 3);
|
||||
for(size_t _x = 0; _x < w; _x++, _bmp++) {
|
||||
uint32_t b = w - _x - 1;
|
||||
*_bmp = ((d >> b) & 1) ? fg : bg;
|
||||
for(size_t _y = 0; _y < g.get_height(); _y++) {
|
||||
for(size_t _x = 0; _x < g.get_width(); _x++, _bmp++) {
|
||||
*_bmp = g.read_pixel(_x, _y) ? fg : bg;
|
||||
}
|
||||
_bmp = _bmp + skip;
|
||||
}
|
||||
|
|
|
@ -19,43 +19,20 @@ namespace
|
|||
if(x >= w || y >= h)
|
||||
return;
|
||||
const framebuffer::font::glyph& g = main_font.get_glyph(ch);
|
||||
unsigned maxw = min((size_t)(g.wide ? 16 : 8), (size_t)(w - x));
|
||||
unsigned maxh = min((size_t)16, (size_t)(h - y));
|
||||
unsigned maxw = min((size_t)g.get_width(), (size_t)(w - x));
|
||||
unsigned maxh = min((size_t)g.get_height(), (size_t)(h - y));
|
||||
unsigned char* cellbase = reinterpret_cast<unsigned char*>(fb) + y * istride + pstride * x;
|
||||
if(g.wide) {
|
||||
//Wide character.
|
||||
for(size_t y2 = 0; y2 < maxh; y2++) {
|
||||
uint32_t d = g.data[y2 >> 1];
|
||||
d >>= 16 - ((y2 & 1) << 4);
|
||||
for(size_t j = 0; j < maxw; j++) {
|
||||
uint32_t b = 15 - j;
|
||||
if(((d >> b) & 1) != 0) {
|
||||
for(unsigned k = 0; k < pstride; k++)
|
||||
cellbase[pstride * j + k] = _fg[k];
|
||||
} else {
|
||||
for(unsigned k = 0; k < pstride; k++)
|
||||
cellbase[pstride * j + k] = _bg[k];
|
||||
}
|
||||
for(size_t y2 = 0; y2 < maxh; y2++) {
|
||||
for(size_t j = 0; j < maxw; j++) {
|
||||
if(g.read_pixel(j, y2)) {
|
||||
for(unsigned k = 0; k < pstride; k++)
|
||||
cellbase[pstride * j + k] = _fg[k];
|
||||
} else {
|
||||
for(unsigned k = 0; k < pstride; k++)
|
||||
cellbase[pstride * j + k] = _bg[k];
|
||||
}
|
||||
cellbase += istride;
|
||||
}
|
||||
} else {
|
||||
//Narrow character.
|
||||
for(size_t y2 = 0; y2 < maxh; y2++) {
|
||||
uint32_t d = g.data[y2 >> 2];
|
||||
d >>= 24 - ((y2 & 3) << 3);
|
||||
for(size_t j = 0; j < maxw; j++) {
|
||||
uint32_t b = 7 - j;
|
||||
if(((d >> b) & 1) != 0) {
|
||||
for(unsigned k = 0; k < pstride; k++)
|
||||
cellbase[pstride * j + k] = _fg[k];
|
||||
} else {
|
||||
for(unsigned k = 0; k < pstride; k++)
|
||||
cellbase[pstride * j + k] = _bg[k];
|
||||
}
|
||||
}
|
||||
cellbase += istride;
|
||||
}
|
||||
cellbase += istride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +68,7 @@ void cover_next_position(uint32_t ch, unsigned& x, unsigned& y)
|
|||
y = y + 16;
|
||||
} else {
|
||||
const framebuffer::font::glyph& g = main_font.get_glyph(ch);
|
||||
x = x + (g.wide ? 16 : 8);
|
||||
x = x + g.get_width();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -240,31 +240,25 @@ font2::font2(const std::string& file)
|
|||
font2::font2(struct font& bfont)
|
||||
{
|
||||
auto s = bfont.get_glyphs_set();
|
||||
rowadvance = 0;
|
||||
for(auto i = s.begin();;i++) {
|
||||
const font::glyph& j = (i != s.end()) ? bfont.get_glyph(*i) : bfont.get_bad_glyph();
|
||||
glyph k;
|
||||
k.width = j.wide ? 16 : 8;
|
||||
k.height = 16;
|
||||
k.width = j.get_width();
|
||||
k.height = j.get_height();
|
||||
k.stride = 1;
|
||||
k.fglyph.resize(16);
|
||||
for(size_t y = 0; y < 16; y++) {
|
||||
k.fglyph[y] = 0;
|
||||
uint32_t r = j.data[y / (j.wide ? 2 : 4)];
|
||||
if(j.wide)
|
||||
r >>= 16 - ((y & 1) << 4);
|
||||
else
|
||||
r >>= 24 - ((y & 3) << 3);
|
||||
for(size_t y = 0; y < k.height; y++) {
|
||||
for(size_t x = 0; x < k.width; x++) {
|
||||
uint32_t b = (j.wide ? 15 : 7) - x;
|
||||
if(((r >> b) & 1) != 0)
|
||||
if(j.read_pixel(x, y))
|
||||
k.fglyph[y] |= 1UL << (31 - x);
|
||||
}
|
||||
}
|
||||
rowadvance = std::max((size_t)rowadvance, (size_t)j.get_height());
|
||||
std::u32string key = (i != s.end()) ? std::u32string(1, *i) : std::u32string();
|
||||
glyphs[key] = k;
|
||||
if(i == s.end()) break;
|
||||
}
|
||||
rowadvance = 16;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const std::u32string& lkey)
|
||||
|
|
|
@ -50,7 +50,6 @@ std::pair<size_t, size_t> text_framebuffer::get_pixels()
|
|||
|
||||
void text_framebuffer::render(char* tbuffer)
|
||||
{
|
||||
uint32_t dummy[8] = {0};
|
||||
size_t stride = 24 * width;
|
||||
size_t cellstride = 24;
|
||||
for(size_t y = 0; y < height; y++) {
|
||||
|
@ -67,68 +66,24 @@ void text_framebuffer::render(char* tbuffer)
|
|||
char fgb = (e.fg >> 16);
|
||||
char fgg = (e.fg >> 8);
|
||||
char fgr = (e.fg >> 0);
|
||||
const uint32_t* data = (g.data ? g.data : dummy);
|
||||
if(g.wide && xp < width - 1) {
|
||||
//Wide character, can draw full width.
|
||||
for(size_t y2 = 0; y2 < 16; y2++) {
|
||||
uint32_t d = data[y2 >> 1];
|
||||
d >>= 16 - ((y2 & 1) << 4);
|
||||
for(size_t j = 0; j < 16; j++) {
|
||||
uint32_t b = 15 - j;
|
||||
if(((d >> b) & 1) != 0) {
|
||||
cellbase[3 * j + 0] = fgr;
|
||||
cellbase[3 * j + 1] = fgg;
|
||||
cellbase[3 * j + 2] = fgb;
|
||||
} else {
|
||||
cellbase[3 * j + 0] = bgr;
|
||||
cellbase[3 * j + 1] = bgg;
|
||||
cellbase[3 * j + 2] = bgb;
|
||||
}
|
||||
|
||||
uint32_t cells = g.get_width() / 8;
|
||||
uint32_t drawc = 8 * std::min(cells, (uint32_t)((xp < width - 1) ? 2 : 1));
|
||||
for(size_t y2 = 0; y2 < g.get_height(); y2++) {
|
||||
for(size_t j = 0; j < drawc; j++) {
|
||||
if(g.read_pixel(j, y2)) {
|
||||
cellbase[3 * j + 0] = fgr;
|
||||
cellbase[3 * j + 1] = fgg;
|
||||
cellbase[3 * j + 2] = fgb;
|
||||
} else {
|
||||
cellbase[3 * j + 0] = bgr;
|
||||
cellbase[3 * j + 1] = bgg;
|
||||
cellbase[3 * j + 2] = bgb;
|
||||
}
|
||||
cellbase += stride;
|
||||
}
|
||||
xp += 2;
|
||||
} else if(g.wide) {
|
||||
//Wide character, can only draw half.
|
||||
for(size_t y2 = 0; y2 < 16; y2++) {
|
||||
uint32_t d = data[y2 >> 1];
|
||||
d >>= 16 - ((y2 & 1) << 4);
|
||||
for(size_t j = 0; j < 8; j++) {
|
||||
uint32_t b = 15 - j;
|
||||
if(((d >> b) & 1) != 0) {
|
||||
cellbase[3 * j + 0] = fgr;
|
||||
cellbase[3 * j + 1] = fgg;
|
||||
cellbase[3 * j + 2] = fgb;
|
||||
} else {
|
||||
cellbase[3 * j + 0] = bgr;
|
||||
cellbase[3 * j + 1] = bgg;
|
||||
cellbase[3 * j + 2] = bgb;
|
||||
}
|
||||
}
|
||||
cellbase += stride;
|
||||
}
|
||||
xp += 2;
|
||||
} else {
|
||||
//Narrow character.
|
||||
for(size_t y2 = 0; y2 < 16; y2++) {
|
||||
uint32_t d = data[y2 >> 2];
|
||||
d >>= 24 - ((y2 & 3) << 3);
|
||||
for(size_t j = 0; j < 8; j++) {
|
||||
uint32_t b = 7 - j;
|
||||
if(((d >> b) & 1) != 0) {
|
||||
cellbase[3 * j + 0] = fgr;
|
||||
cellbase[3 * j + 1] = fgg;
|
||||
cellbase[3 * j + 2] = fgb;
|
||||
} else {
|
||||
cellbase[3 * j + 0] = bgr;
|
||||
cellbase[3 * j + 1] = bgg;
|
||||
cellbase[3 * j + 2] = bgb;
|
||||
}
|
||||
}
|
||||
cellbase += stride;
|
||||
}
|
||||
xp += 1;
|
||||
cellbase += stride;
|
||||
}
|
||||
xp += cells;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -170,7 +125,7 @@ size_t text_framebuffer::write(const std::u32string& str, size_t w, size_t x, si
|
|||
e.fg = fg;
|
||||
e.bg = bg;
|
||||
}
|
||||
pused += (g.wide ? 2 : 1);
|
||||
pused += g.get_width() / 8;
|
||||
}
|
||||
while(pused < w) {
|
||||
//Pad with spaces.
|
||||
|
|
Loading…
Add table
Reference in a new issue