Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
296 lines (239 sloc) 4.07 KB
#ifndef com_sleepless_gfont_cpp
#define com_sleepless_gfont_cpp
// Copyright 2002
// Sleepless Software Inc.
// All Rights Reserved
#include "font.cpp"
//extern "C" {
// void *o_getFont(const char *file) {
//};
struct GFont : Font
{
//#ifdef __APPLE__
// void *squidFont;
//#endif
Image *fimg;
int cy;
int ch;
#define NUM_PRINTABLE_CHARS (127 - 32)
int cx[NUM_PRINTABLE_CHARS];
int cw[NUM_PRINTABLE_CHARS];
bool fixed;
int maxw;
int avgw;
GFont()
{
fimg = 0;
cy = 0;
ch = 0;
height = 0;
fixed = 0;
maxw = 0;
avgw = 0;
//squidFont = 0;
}
GFont(int ht, int it, int un, int bo, const char *file)
{
//#ifdef __APPLE__
// squidsFont = o_getFont(file);
// return;
//#endif
fimg = new Image(file);
if(fimg == NULL)
return;
if(fimg->width < 1)
{
delete fimg;
fimg = 0;
return;
}
fixed = false;
maxw = 0;
#if __APPLE__
cy = 0;
ch = fimg->height / 16;
maxw = avgw = fimg->width / 8;
#else
unsigned long t = fimg->getPixel(0, 0);
int w = fimg->width;
int h = fimg->height;
int i = 1;
// Find top of font
for( ; i < h; i++ )
{
if(fimg->getPixel(0, i) != t)
break;
}
cy = i;
// Find height of font
for( ; i < h; i++ )
{
if(fimg->getPixel(0, i) == t)
break;
}
ch = i - cy;
height = ch; // XXX duplicate
int c;
i = 1;
int totw = 0;
// find character offsets and widths
for(c = 0; c < NUM_PRINTABLE_CHARS; c++)
{
// skip preceding space
for( ; i < w; i++)
{
if(fimg->getPixel(i, 0) != t)
break;
}
// find left edge of character
for( ; i < w; i++)
{
if(fimg->getPixel(i, 0) != t)
break;
}
cx[c] = i;
// skip intervening space
for( ; i < w; i++)
{
if(fimg->getPixel(i, 0) != t)
break;
}
// Find width of character
for( ; i < w; i++)
{
if(fimg->getPixel(i, 0) == t)
break;
}
cw[c] = i - cx[c];
if(cw[c] > maxw)
maxw = cw[c];
totw += cw[c];
}
maxw += 1;
avgw = (int)(((float)totw / (float)NUM_PRINTABLE_CHARS) * 1.4f);
// Enforce some sanity
if(cy >= h)
cy = 1;
if((cy + ch - 1) >= h)
ch = 1;
for(c = 0; c < NUM_PRINTABLE_CHARS; c++)
{
if(cx[c] >= w)
cx[c] = 1;
if((cx[c] + cw[c] - 1) >= w)
cw[c] = 1;
}
#endif
}
~GFont()
{
if(fimg)
delete fimg;
}
void textSize(const char *s, int len, int *pw, int *ph, int k, int lead)
{
*pw = *ph = 0;
if(fimg == NULL)
return;
#ifdef __APPLE__
int x = 0;
int maxx = 0;
int maxy = ch + lead;
for(int i = 0; i < len; i++)
{
int c = s[i];
if(c == '\n')
{
x = 0;
maxy += ch;
maxy += lead;
}
else
{
x += avgw;
x += k;
if(x > maxx)
maxx = x;
}
}
#else
int x = 0;
int maxx = 0;
int maxy = ch + lead;
if(fixed)
{
// XXX You know I don't think this is working right ...
// examine it more closely
*pw = len * maxw;
*ph = maxy;
}
//int len = strlen(s);
for(int i = 0; i < len; i++)
{
int c = s[i];
if(c == '\n')
{
x = 0;
maxy += ch;
maxy += lead;
}
else
{
c -= 32;
if((c < 0) || (c >= NUM_PRINTABLE_CHARS))
c = '?' - 32;
x += cw[c];
x += k;
if(x > maxx)
maxx = x;
}
}
#endif
*pw = maxx;
*ph = maxy;
}
// Render text in this font into an image
void draw(Image *img, const char *t, int x, int y, int clr, int lead, int kern, float a)
{
if(img->width < 1)
return;
if(img->height < 1)
return;
if(fimg == NULL)
return;
int left = x;
int len = strlen(t);
for(int i = 0; i < len; i++)
{
// Draw a char
int c = t[i];
if(c == '\n')
{
x = left;
y += ch;
y += lead;
}
else
{
c -= 32;
if((c < 0) || (c >= NUM_PRINTABLE_CHARS))
c = '?' - 32;
#ifdef __APPLE__
c += 32;
int chy = (c / 8) * ch;
int chx = (c % 8) * avgw;
img->gel_blit(fimg, chx, chy, avgw, ch, x, y, a, clr);
x += avgw;
#else
img->gel_blit(fimg, cx[c], cy, cw[c], ch, x, y, a, clr);
if(fixed)
x += avgw;
else
x += cw[c];
#endif
x += kern;
}
}
}
};
#endif // com_sleepless_gfont_cpp