Skip to content
Permalink
main
Go to file
 
 
Cannot retrieve contributors at this time
604 lines (549 sloc) 19.2 KB
#include "print_funcs.h"
/* font.c
*
* bitmap font data
* designed by Henrik Theiling for Liquid Rendering, 2009
*
*
* adapted for aleph project by monome 2012
*/
// ordering is column-first for easier variable spacing
/* (0,0) = top left
* pixel(x,y) = (bool)(font_data[x].data & (1 << y)) */
//#include "compiler.h"
#include "types.h"
#include "font.h"
// #include "fonts/ume_tgo5_18.h"
// maxiumum string size to attempt rendering
#define MAX_RENDER_STRING 32
// glyph table to use
/// FIXME: implement this, it would be a little faster
// column-first buffer indexing
// #define COL_FIRST
// glyph.last is the inset from right hand edge of glyph box...
const glyph_t font_data[]= {
{ /* 0x00020UL, 0, 2UL, */ 2, 1, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ /* 0x00021UL, 0, 0UL, */ 3, 2, { 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00 } },
{ /* 0x00022UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x06, 0x00, 0x06, 0x00 } },
{ /* 0x00023UL, 0, 0UL, */ 1, 0, { 0x00, 0x24, 0x7e, 0x24, 0x7e, 0x24 } },
{ /* 0x00024UL, 0, 0UL, */ 1, 0, { 0x00, 0x48, 0x54, 0xfe, 0x54, 0x24 } },
{ /* 0x00025UL, 0, 0UL, */ 1, 1, { 0x00, 0x48, 0x20, 0x10, 0x48, 0x00 } },
{ /* 0x00026UL, 0, 0UL, */ 1, 0, { 0x00, 0x34, 0x4a, 0x54, 0x20, 0x50 } },
{ /* 0x00027UL, 0, 0UL, */ 3, 2, { 0x00, 0x00, 0x00, 0x06, 0x00, 0x00 } },
{ /* 0x00028UL, 0, 0UL, */ 2, 2, { 0x00, 0x00, 0x3c, 0x42, 0x00, 0x00 } },
{ /* 0x00029UL, 0, 0UL, */ 2, 2, { 0x00, 0x00, 0x42, 0x3c, 0x00, 0x00 } },
{ /* 0x0002aUL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x54, 0x38, 0x54, 0x00 } },
{ /* 0x0002bUL, 0, 2UL, */ 2, 1, { 0x00, 0x00, 0x10, 0x38, 0x10, 0x00 } },
{ /* 0x0002cUL, 0, 0UL, */ 2, 2, { 0x00, 0x00, 0x80, 0x60, 0x00, 0x00 } },
{ /* 0x0002dUL, 0, 0UL, */ 2, 2, { 0x00, 0x00, 0x10, 0x10, 0x00, 0x00 } },
{ /* 0x0002eUL, 0, 0UL, */ 3, 2, { 0x00, 0x00, 0x00, 0x40, 0x00, 0x00 } },
{ /* 0x0002fUL, 0, 0UL, */ 1, 2, { 0x00, 0x60, 0x18, 0x06, 0x00, 0x00 } },
{ /* 0x00030UL, 0, 2UL, */ 2, 1, { 0x00, 0x00, 0x3c, 0x5A, 0x3c, 0x00 } },
{ /* 0x00031UL, 0, 2UL, */ 2, 1, { 0x00, 0x00, 0x04, 0x7e, 0x00, 0x00 } },
{ /* 0x00032UL, 0, 2UL, */ 2, 1, { 0x00, 0x00, 0x62, 0x52, 0x4c, 0x00 } },
{ /* 0x00033UL, 0, 2UL, */ 2, 1, { 0x00, 0x00, 0x42, 0x4a, 0x36, 0x00 } },
{ /* 0x00034UL, 0, 2UL, */ 2, 1, { 0x00, 0x00, 0x1c, 0x10, 0x7e, 0x00 } },
{ /* 0x00035UL, 0, 2UL, */ 2, 1, { 0x00, 0x00, 0x4e, 0x4a, 0x32, 0x00 } },
{ /* 0x00036UL, 0, 2UL, */ 2, 1, { 0x00, 0x00, 0x3c, 0x4a, 0x32, 0x00 } },
{ /* 0x00037UL, 0, 2UL, */ 2, 1, { 0x00, 0x00, 0x02, 0x72, 0x0e, 0x00 } },
{ /* 0x00038UL, 0, 2UL, */ 2, 1, { 0x00, 0x00, 0x34, 0x4a, 0x34, 0x00 } },
{ /* 0x00039UL, 0, 2UL, */ 2, 1, { 0x00, 0x00, 0x4c, 0x52, 0x3c, 0x00 } },
{ /* 0x0003aUL, 0, 0UL, */ 3, 2, { 0x00, 0x00, 0x00, 0x48, 0x00, 0x00 } },
{ /* 0x0003bUL, 0, 0UL, */ 2, 2, { 0x00, 0x00, 0x80, 0x64, 0x00, 0x00 } },
{ /* 0x0003cUL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x10, 0x28, 0x44, 0x00 } },
{ /* 0x0003dUL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x28, 0x28, 0x28, 0x00 } },
{ /* 0x0003eUL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x44, 0x28, 0x10, 0x00 } },
{ /* 0x0003fUL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x52, 0x0a, 0x04, 0x00 } },
{ /* 0x00040UL, 0, 0UL, */ 1, 0, { 0x00, 0x7c, 0x82, 0x92, 0xaa, 0x3c } },
{ /* 0x00041UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x7c, 0x12, 0x7c, 0x00 } },
{ /* 0x00042UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x7e, 0x4a, 0x34, 0x00 } },
{ /* 0x00043UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x3c, 0x42, 0x42, 0x00 } },
{ /* 0x00044UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x7e, 0x42, 0x3c, 0x00 } },
{ /* 0x00045UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x7e, 0x4a, 0x42, 0x00 } },
{ /* 0x00046UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x7e, 0x0a, 0x02, 0x00 } },
{ /* 0x00047UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x3c, 0x42, 0x72, 0x00 } },
{ /* 0x00048UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x7e, 0x08, 0x7e, 0x00 } },
// { /* 0x00049UL, 0, 0UL, */ 3, 2, { 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00 } },
// there are 2 uppercase I's... this one has serifs
{ /* 0x00049UL, 0, 3UL, */ 2, 1, { 0x00, 0x00, 0x42, 0x7e, 0x42, 0x00 } },
{ /* 0x0004aUL, 0, 0UL, */ 2, 2, { 0x00, 0x00, 0x80, 0x7e, 0x00, 0x00 } },
{ /* 0x0004bUL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x7e, 0x08, 0x76, 0x00 } },
{ /* 0x0004cUL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x7e, 0x40, 0x40, 0x00 } },
{ /* 0x0004dUL, 0, 0UL, */ 1, 0, { 0x00, 0x7e, 0x04, 0x08, 0x04, 0x7e } },
{ /* 0x0004eUL, 0, 0UL, */ 1, 1, { 0x00, 0x7e, 0x04, 0x08, 0x7e, 0x00 } },
{ /* 0x0004fUL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x3c, 0x42, 0x3c, 0x00 } },
{ /* 0x00050UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x7e, 0x12, 0x0c, 0x00 } },
{ /* 0x00051UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x3c, 0xc2, 0xbc, 0x00 } },
{ /* 0x00052UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x7e, 0x12, 0x6c, 0x00 } },
{ /* 0x00053UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x44, 0x4a, 0x32, 0x00 } },
{ /* 0x00054UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x02, 0x7e, 0x02, 0x00 } },
{ /* 0x00055UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x3e, 0x40, 0x7e, 0x00 } },
{ /* 0x00056UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x7e, 0x20, 0x1e, 0x00 } },
{ /* 0x00057UL, 0, 0UL, */ 1, 0, { 0x00, 0x3e, 0x40, 0x30, 0x40, 0x3e } },
{ /* 0x00058UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x66, 0x18, 0x66, 0x00 } },
{ /* 0x00059UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x0e, 0x70, 0x0e, 0x00 } },
{ /* 0x0005aUL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x62, 0x5a, 0x46, 0x00 } },
{ /* 0x0005bUL, 0, 0UL, */ 2, 2, { 0x00, 0x00, 0x7e, 0x42, 0x00, 0x00 } },
{ /* 0x0005cUL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x06, 0x18, 0x60, 0x00 } },
{ /* 0x0005dUL, 0, 0UL, */ 2, 2, { 0x00, 0x00, 0x42, 0x7e, 0x00, 0x00 } },
{ /* 0x0005eUL, 0, 0UL, */ 1, 0, { 0x00, 0x08, 0x04, 0x7e, 0x04, 0x08 } },
{ /* 0x0005fUL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x80, 0x80, 0x80, 0x00 } },
{ /* 0x00060UL, 0, 0UL, */ 1, 1, { 0x00, 0x48, 0x7c, 0x4a, 0x42, 0x00 } },
{ /* 0x00061UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x20, 0x54, 0x78, 0x00 } },
{ /* 0x00062UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x7e, 0x44, 0x38, 0x00 } },
{ /* 0x00063UL, 0, 0UL, */ 2, 2, { 0x00, 0x00, 0x38, 0x44, 0x00, 0x00 } },
{ /* 0x00064UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x38, 0x44, 0x7e, 0x00 } },
{ /* 0x00065UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x38, 0x54, 0x4c, 0x00 } },
{ /* 0x00066UL, 0, 0UL, */ 2, 2, { 0x00, 0x00, 0x7c, 0x0a, 0x00, 0x00 } },
{ /* 0x00067UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x98, 0xa4, 0x7c, 0x00 } },
{ /* 0x00068UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x7e, 0x04, 0x78, 0x00 } },
{ /* 0x00069UL, 0, 0UL, */ 3, 2, { 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00 } },
{ /* 0x0006aUL, 0, 0UL, */ 2, 2, { 0x00, 0x00, 0x80, 0x7a, 0x00, 0x00 } },
{ /* 0x0006bUL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x7e, 0x18, 0x64, 0x00 } },
{ /* 0x0006cUL, 0, 0UL, */ 3, 2, { 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00 } },
{ /* 0x0006dUL, 0, 0UL, */ 1, 0, { 0x00, 0x7c, 0x04, 0x7c, 0x04, 0x78 } },
{ /* 0x0006eUL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x7c, 0x04, 0x78, 0x00 } },
{ /* 0x0006fUL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x38, 0x44, 0x38, 0x00 } },
{ /* 0x00070UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0xfc, 0x44, 0x78, 0x00 } },
{ /* 0x00071UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x38, 0x24, 0xfc, 0x00 } },
{ /* 0x00072UL, 0, 0UL, */ 2, 2, { 0x00, 0x00, 0x78, 0x04, 0x00, 0x00 } },
{ /* 0x00073UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x48, 0x54, 0x24, 0x00 } },
{ /* 0x00074UL, 0, 0UL, */ 2, 2, { 0x00, 0x00, 0x3e, 0x44, 0x00, 0x00 } },
{ /* 0x00075UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x3c, 0x40, 0x7c, 0x00 } },
{ /* 0x00076UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x7c, 0x20, 0x1c, 0x00 } },
{ /* 0x00077UL, 0, 0UL, */ 1, 0, { 0x00, 0x3c, 0x40, 0x38, 0x40, 0x3c } },
{ /* 0x00078UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x6c, 0x10, 0x6c, 0x00 } },
{ /* 0x00079UL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x1c, 0xa0, 0x7c, 0x00 } },
{ /* 0x0007aUL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x64, 0x54, 0x4c, 0x00 } },
{ /* 0x0007bUL, 0, 0UL, */ 2, 1, { 0x00, 0x00, 0x08, 0x76, 0x42, 0x00 } },
{ /* 0x0007cUL, 0, 0UL, */ 3, 2, { 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00 } },
{ /* 0x0007dUL, 0, 0UL, */ 1, 2, { 0x00, 0x42, 0x76, 0x08, 0x00, 0x00 } },
{ /* 0x0007eUL, 0, 0UL, */ 1, 1, { 0x00, 0x04, 0x02, 0x04, 0x02, 0x00 } },
};
const U32 font_nglyphs = sizeof(font_data)/sizeof(glyph_t) - 1;
//------------------------------------------
//----- functions
// render single glyph to a flat buffer (1byte = 1px)
// given pointer to buffer, pixel offset, row length,
// foreground and background colors
// return columns used
extern u8 font_glyph(char ch, u8* buf, u8 w, u8 a, u8 b) {
u8 i=0;
u8 j;
u8 * p = buf;
const glyph_t* gl = &(font_data[ch - FONT_ASCII_OFFSET]);
// columns to draw
u8 cols = FONT_CHARW - gl->first - gl->last;
while(i < cols) {
for(j=0; j<FONT_CHARH; j++) {
*p = gl->data[i + gl->first] & (1 << j) ? a : b;
// if(*buf) { print_dbg("#"); } else { print_dbg("_"); }
// point at next row
p += w;
}
// increment column count
i++;
// reset pointer to row
p = buf + i;
}
return cols;
}
// fixed_width variant
extern u8 font_glyph_fixed(char ch, u8* buf, u8 w, u8 a, u8 b) {
u8 i=0;
u8 j;
u8 * p = buf;
const glyph_t* gl = &(font_data[ch - FONT_ASCII_OFFSET]);
// columns to draw
while(i < FONT_CHARW) {
for(j=0; j<FONT_CHARH; j++) {
*p = gl->data[i + gl->first] & (1 << j) ? a : b;
// point at next row
p += w;
}
// increment column count
i++;
// reset pointer to row
p = buf + i;
}
return FONT_CHARW;
}
// same as font_glyph, double size
extern u8* font_glyph_big(char ch, u8* buf, u8 w, u8 a, u8 b) {
u8 i=0, j, val;
u8* p = buf;
const glyph_t* gl = &(font_data[ch - FONT_ASCII_OFFSET]);
// columns to draw
u8 cols = (FONT_CHARW - gl->first - gl->last);
while(i < cols) {
for(j=0; j<FONT_CHARH; j++) {
val = gl->data[i + gl->first] & (1 << j) ? a : b;
*p = val;
*(p +1) = val;
// point at next row
p += w;
// fill the next row as well
*p = val;
*(p +1) = val;
// point at next row
p += w;
}
// move pointer back the size of one column
// buf -= colOffset;
// increment for next row
// buf += 2;
// increment column count
i++;
// set pointer to next (pixel*2) in first row
p = buf + (i*2);
}
return p;
}
// same as font_glyph,m 4x size
extern u8* font_glyph_bigbig(char ch, u8* buf, u8 w, u8 a, u8 b) {
u8 i=0, j, val;
u8* p = buf;
const glyph_t* gl = &(font_data[ch - FONT_ASCII_OFFSET]);
// columns to draw
u8 cols = (FONT_CHARW - gl->first - gl->last);
while(i < cols) {
for(j=0; j<FONT_CHARH; j++) {
val = gl->data[i + gl->first] & (1 << j) ? a : b;
*p = val;
*(p +1) = val;
*(p +2) = val;
*(p +3) = val;
// point at next row
p += w;
// fill the next row as well
*p = val;
*(p +1) = val;
*(p +2) = val;
*(p +3) = val;
// point at next row
p += w;
// fill the next row as well
*p = val;
*(p +1) = val;
*(p +2) = val;
*(p +3) = val;
// point at next row
p += w;
// fill the next row as well
*p = val;
*(p +1) = val;
*(p +2) = val;
*(p +3) = val;
// point at next row
p += w;
}
// move pointer back the size of one column
// buf -= colOffset;
// increment for next row
// buf += 2;
// increment column count
i++;
// set pointer to next (pixel*2) in first row
p = buf + (i << 2);
}
return p;
}
u8 font_string_position(const char* str, u8 pos) {
u8 i = 0,n = 0;
while(i<pos) {
n+= FONT_CHARW - font_data[str[i] - FONT_ASCII_OFFSET].first - font_data[str[i] - FONT_ASCII_OFFSET].last;
n++;
i++;
}
return n;
}
u8 font_string_pixels(const char* str) {
u8 i = 0,n = 0;
while(str[i]) {
n+= FONT_CHARW - font_data[str[i] - FONT_ASCII_OFFSET].first - font_data[str[i] - FONT_ASCII_OFFSET].last;
n++;
i++;
}
return n;
}
// render a string of packed glyphs to a buffer
u8* font_string(const char* str, u8* buf, u32 size, u8 w, u8 a, u8 b) {
u8* max = buf + size - 8; // pad 1 character width on right edge
// u32 x = 0;
// u8 dx = 0;
while(buf < max) {
// while (x < w) {
if (*str == 0) {
// end of string
break;
}
// dx = font_glyph(*str, buf, w, a, b);
// buf = +=dx;
buf += font_glyph(*str, buf, w, a, b);
// x += dx;
// 1-column space between chars
++buf;
// ++x;
++str;
}
return buf;
}
// render a font string to a region.
// this allows for smarter bounds handling
void font_string_region_wrap(region* reg, const char* str, u8 xoff, u8 yoff, u8 fg, u8 bg) {
u8* buf = reg->data + xoff + (u32)(reg->w) * (u32)yoff;
u8* max = reg->data + reg->len;
u32 xmax = reg->w - 7; // padding
u8 dx = 0;
while(buf < max) {
// break on end of string
if(*str == 0) { break; }
dx = font_glyph(*str, buf, reg->w, fg, bg) + 1;
buf += dx;
xoff += dx;
++str;
// wrap lines
if(xoff > xmax) {
xoff = 0;
buf += (reg->w - xoff);
print_dbg("\r\n font_string_region: wrapped line");
}
}
}
// clipping variant
void font_string_region_clip(region* reg, const char* str, u8 xoff, u8 yoff, u8 fg, u8 bg) {
u8* buf = reg->data + xoff + (u32)(reg->w) * (u32)yoff;
u8* max = reg->data + reg->len;
u32 xmax = reg->w - 7; // padding
u8 dx = 0;
while(buf < max) {
// break on end of string
if(*str == 0) { break; }
dx = font_glyph(*str, buf, reg->w, fg, bg) + 1;
buf += dx;
xoff += dx;
++str;
// wrap lines
if(xoff > xmax) {
return;
}
}
}
// clipping variant
#define TAB_POSITION 48
void font_string_region_clip_tab(region* reg, const char* str, u8 xoff, u8 yoff, u8 fg, u8 bg) {
u8* buf = reg->data + xoff + (u32)(reg->w) * (u32)yoff;
u8* max = reg->data + reg->len;
u32 xmax = reg->w - 7; // padding
u8 dx = 0;
while(buf < max) {
// break on end of string
if(*str == 0) { break; }
if(*str == '|') {
buf = reg->data + TAB_POSITION + (u32)(reg->w) * (u32)yoff;
}
else {
dx = font_glyph(*str, buf, reg->w, fg, bg) + 1;
buf += dx;
xoff += dx;
}
++str;
// wrap lines
if(xoff > xmax) {
return;
}
}
}
void font_string_region_clip_right(region* reg, const char* str, u8 xoff, u8 yoff, u8 fg, u8 bg) {
int8_t x = xoff - font_string_pixels(str);
if(x < 0) x = 0;
u8* buf = reg->data + x + (u32)(reg->w) * (u32)yoff;
u8* max = reg->data + reg->len;
u32 xmax = reg->w - 6; // padding changed from 7 to 6 (only using 4 wide nums anyway)
u8 dx = 0;
while(buf < max) {
// break on end of string
if(*str == 0) { break; }
dx = font_glyph(*str, buf, reg->w, fg, bg) + 1;
buf += dx;
x += dx;
++str;
// wrap lines
if(x > xmax) {
return;
}
}
}
// clipping variant with hilight
void font_string_region_clip_hi(region* reg, const char* str, u8 xoff, u8 yoff, u8 fg, u8 bg, u8 hi) {
font_string_region_clip_hid(reg, str, xoff, yoff, fg, bg, hi, 1);
}
// clipping variant with hilight
void font_string_region_clip_hid(region* reg, const char* str, u8 xoff, u8 yoff, u8 fg, u8 bg, u8 hi, u8 hid) {
u8* buf = reg->data + xoff + (u32)(reg->w) * (u32)yoff;
u8* max = reg->data + reg->len;
u32 xmax = reg->w - 7;
u8 dx = 0;
u8 i = 0;
while(buf < max) {
// break on end of string
if(*str == 0) { break; }
if(i == hi) bg += hid;
dx = font_glyph(*str, buf, reg->w, fg, bg) + 1;
if(i == hi) bg -= hid;
buf += dx;
xoff += dx;
++str;
// wrap lines
if(xoff > xmax) {
return;
}
i++;
}
}
// same as font_string, double size
u8* font_string_big(const char* str, u8* buf, u32 size, u8 w, u8 a, u8 b) {
u8* max = buf + size;
while (buf < max) {
if (*str == 0) {
// end of string
break;
}
buf = font_glyph_big(*str, buf, w, a, b);
/* // 1-column space between chars */
/* buf++; */
/* str++; */
// 2-column space between chars
buf += 2;
++str;
}
return buf;
}
// same as font_string, 4x size
u8* font_string_bigbig(const char* str, u8* buf, u32 size, u8 w, u8 a, u8 b) {
u8* max = buf + size;
while (buf < max) {
if (*str == 0) {
// end of string
break;
}
buf = font_glyph_bigbig(*str, buf, w, a, b);
// 1-column space between chars
// buf++;
// 3-column space
buf += 3;
str++;
}
return buf;
}
/*
//-------------
//----- anti-aliased fonts (bitmaps)
// render an anti-aliased (4-bit) glyph to a buffer
// arguments are character, buffer, target row size, invert flag
extern u8* font_glyph_aa(char ch, u8* buf, u8 w, u8 inv) {
//#if 0
const char* gl; // glyph data
// u8 gw, gh; // glyph width and height
u8 i, j;
// how many bytes to move buf pointer for 1st column of next row
u32 nextRowBytes;
// buf pointer;
char* p;
// pointer to copy function
// void (*fp)(const char* src, char* dst);
// fixme: wtf why
// if(inv) { fp = &copyPxInv; } else { fp = &copyPx; }
#if 0
/// FIXME: might want only numerals
//// hackish
if( (ch > 45) && (ch < 58)) { // dot + numerals
gl = FONT_AA[ch - 46].glyph.data;
// print_dbg("\r\n printing numeral ");
// print_dbg_char(ch);
// print_dbg(" , glyphidx: ");
// print_dbg_ulong(ch - 46);
} else {
return buf;
}
#else
// gl = FONT_AA[ch - FONT_ASCII_OFFSET].glyph.data;
/// flaarggg
// print_dbg("\r\n render glyph: ");
// print_dbg_char(ch);
// print_dbg(" ( 0x");
// print_dbg_hex((u32)ch);
////////
/// FIXME: font is missing ` or _ or something
if(ch > 95) { ch--; }
////////
gl = FONT_AA[ch - FONT_ASCII_OFFSET].glyph.data;
#endif
/// copy glyph to buffer...
p = (char*)buf;
nextRowBytes = w - FONT_AA_CHARW;
// print_dbg("\r\n");
// print_dbg("\r\n");
if(inv) {
// loop over rows
for(i=0; i<FONT_AA_CHARH; i++) {
// loop over columns
for(j=0; j<FONT_AA_CHARW; j++) {
// print_dbg_char(*gl + 0x20);
// print_dbg(dbgStr[(u32)(*gl)]);
// print_dbg(" ");
// copy/invert pixel and advance pointers
*p++ = 0xf - *gl++;
}
// print_dbg("\r\n");
// reset column and advance row
p += nextRowBytes;
}
// return original buf pointer plus glyph width
} else {
// loop over rows
for(i=0; i<FONT_AA_CHARH; i++) {
// loop over columns
for(j=0; j<FONT_AA_CHARW; j++) {
// print_dbg_char(*gl + 0x20);
// print_dbg(dbgStr[(u32)(*gl)]);
// print_dbg(" ");
// copy pixel and advance pointers
*p++ = *gl++;
}
// print_dbg("\r\n");
// reset column and advance row
p += nextRowBytes;
}
}
// return original buf pointer plus glyph width
return buf + FONT_AA_CHARW;
//#endif
}
// render a string of packed glyphs to a buffer
extern u8* font_string_aa(const char* str, u8* buf, u32 size, u8 w, u8 inv) {
u8* max = buf + size;
// print_dbg("\r\n antialiased string \"");
// print_dbg(str);
// print_dbg("\" font w, h: (");
// print_dbg_ulong(FONT_AA_CHARW);
// print_dbg(" , ");
// print_dbg_ulong(FONT_AA_CHARH);
// print_dbg(" ) , buf w: ");
// print_dbg_ulong(w);
/// FIXME: this bounds check looks wrong
while (buf < max) {
if (*str == 0) {
// end of string
break;
}
buf = font_glyph_aa(*str, buf, w, inv);
// 1-column space between chars
// buf++;
//// cutting the fonts with space included
//// so that background doesn't bleed through here
str++;
}
return buf;
}
*/