/*
Copyright (c) 2007-2013, John Ryland
*/
#include <oslayer.h>
#include <font.h>
// XXX quick fix to get it working
// fsMap should be a drop in replacement for mmap but seems to not be working now
//#define fsMmap mmap
Font openFont(const char *mapableFont)
{
int fd = fsOpen(mapableFont, O_RDONLY);
unsigned int *d = (unsigned int *)fsMmap(0, 16, PROT_READ, MAP_PRIVATE, fd, 0);
unsigned char *c;
Font data;
data.fd = fd;
data.bits_per_pixel = d[0];
data.pixel_size = d[1];
data.map_size = d[2];
/*
strPrint("data.bits_per_pixel: ");
strPrint(strInteger(data.bits_per_pixel, 10));
strPrint("\ndata.pixel_size: ");
strPrint(strInteger(data.pixel_size, 10));
strPrint("\ndata.map_size: ");
strPrint(strInteger(data.map_size, 10));
strPrint("\n");
*/
fsMunmap(d, 16);
c = (unsigned char *)fsMmap(0, data.map_size, PROT_READ, MAP_PRIVATE, fd, 0);
data.glyphs = (Glyph *)(c + 16);
data.pixel_data = (unsigned char *)(c + 16 + sizeof(Glyph)*256);
return data;
}
void closeFont(Font font)
{
fsClose(font.fd);
}
void drawChar(Image *image, int x, int y, unsigned char *data, int w, int h)
{
int i, j;
unsigned int col = 0xFFFF;
for (j = 0; j < h; j++) {
if ( (y + j >= 0) && (y + j < image->height) ) {
unsigned short *row = (unsigned short *)&image->pixel_data[((y+j)*image->width+x)*2];
for (i = 0; i < w; i++) {
if ( (x + i >= 0) && (x + i < image->width) ) {
int alpha = data[j*w+i];
if (alpha == 0) {
// nothing
} else if (alpha == 255) {
row[i] = col;
} else {
unsigned int r, g, b;
alpha = 255 - alpha;
r = alpha * ((row[i] >> 11) & 0x1F);
g = alpha * ((row[i] >> 5) & 0x3F);
b = alpha * ((row[i] >> 0) & 0x1F);
alpha = 255 - alpha;
r += alpha * ((col >> 11) & 0x1F);
g += alpha * ((col >> 5) & 0x3F);
b += alpha * ((col >> 0) & 0x1F);
r >>= 8;
g >>= 8;
b >>= 8;
row[i] = ((r & 0x1F) << 11) | ((g & 0x3F) << 5) | (b & 0x1F);
}
}
}
}
}
}
void drawText(Image *image, int x1, int y1, Font font, const char *text)
{
int i = 0;
int x = x1;
int ch;
while ((ch = text[i]) != 0) {
int xPos = x;
/* don't add bitmap_left on first char */
if ( i != 0 )
xPos += font.glyphs[ch].left;
drawChar(image, xPos, y1 + 16 - font.glyphs[ch].top,
font.pixel_data + font.glyphs[ch].pixel_data_offset,
font.glyphs[ch].width, font.glyphs[ch].height);
/* correct for not adding bitmap_left on first char */
if ( i == 0 )
x -= font.glyphs[ch].left;
x += font.glyphs[ch].horiAdvance;
i++;
}
}