////////////////////////////////////////////////////////////
// softfont.cpp
#ifdef __WATCOMC__
#include <mem.h>
#else
#include <memory.h>
#endif
#include <stdlib.h>
#include "rasterop.h"
#include "softfont.h"
#include "util.h"
#define SWAB(w) ((w) = (((w)&0x00FF)<<8) | ((w)>>8)&0x00FF)
static void font_deletechars( FONTNODE *pf );
static FONTLIST fontlist;
FONTNODE *font_find( int id )
{
for( FONTNODE *pf = fontlist; pf; pf = pf->next )
if( pf->id == id )
return pf;
return NULL;
}
FONTNODE *font_new( int id, char *pdata, int cdata )
{
FONTNODE *pf = font_find( id );
if( pf )
{
font_deletechars( pf );
}
else
{
pf = new FONTNODE;
if( !pf )
return NULL;
pf->next = fontlist;
pf->id = id;
memset( pf->cd, 0, sizeof(pf->cd) );
fontlist = pf;
}
if( cdata >= sizeof(FONTDESC) )
{
memcpy( &pf->fd, pdata, sizeof(FONTDESC) );
}
else
{
memcpy( &pf->fd, pdata, cdata );
memset( (char *)&pf->fd + cdata, 0, sizeof(FONTDESC) - cdata );
}
SWAB( pf->fd.fdsize );
SWAB( pf->fd.baseline );
SWAB( pf->fd.cellwidth );
SWAB( pf->fd.cellheight );
SWAB( pf->fd.symbolset );
SWAB( pf->fd.pitch );
SWAB( pf->fd.height );
SWAB( pf->fd.xheight );
SWAB( pf->fd.textheight );
SWAB( pf->fd.textwidth );
SWAB( pf->fd.firstcode );
SWAB( pf->fd.lastcode );
SWAB( pf->fd.capheight );
swap( unsigned char, pf->fd.fontno[0], pf->fd.fontno[3] );
swap( unsigned char, pf->fd.fontno[1], pf->fd.fontno[2] );
SWAB( pf->fd.copyrightlen );
return pf;
}
CHARDESC *font_newchar( int id, int charcode, char *pdata, int cdata )
{
FONTNODE *pf = font_find( id );
if( pf && charcode >= 0 && charcode <= 255 && cdata >= sizeof(CHARDESC) )
{
unsigned short w, h;
swab( pdata + 10, (char *)&w, sizeof(unsigned short) );
swab( pdata + 12, (char *)&h, sizeof(unsigned short) );
if( pf->cd[charcode] )
{
free( pf->cd[charcode] );
pf->cd[charcode] = NULL;
}
int n = sizeof(CHARDESC) + (w+7)/8 * h;
pf->cd[charcode] = (CHARDESC *)new unsigned char[n];
if( pf->cd[charcode] )
{
if( cdata >= n )
{
memcpy( pf->cd[charcode], pdata, n );
}
else
{
memcpy( pf->cd[charcode], pdata, cdata );
memset( (char *)pf->cd[charcode] + cdata, 0, n - cdata );
}
SWAB( pf->cd[charcode]->leftoffset );
SWAB( pf->cd[charcode]->topoffset );
SWAB( pf->cd[charcode]->width );
SWAB( pf->cd[charcode]->height );
SWAB( pf->cd[charcode]->deltax );
}
return pf->cd[charcode];
}
return NULL;
}
int font_drawchar( unsigned char bits[3300][300], int x, int y, FONTNODE *pf, int charcode )
{
if( pf && charcode >= 0 && charcode <= 255 && pf->cd[charcode] )
{
bit_blt( bits, x + pf->cd[charcode]->leftoffset, y - pf->cd[charcode]->topoffset,
(unsigned char *)(pf->cd[charcode] + 1), pf->cd[charcode]->width, pf->cd[charcode]->height );
return pf->cd[charcode]->deltax;
}
return 0;
}
//////////////////////////////////////////////////////////////
void font_deletechars( FONTNODE *pf )
{
for( int i=0; i<256; i++ )
{
if( pf->cd[i] )
{
free( pf->cd[i] );
pf->cd[i] = NULL;
}
}
}