//////////////////////////////////////////////////////////// // softfont.cpp #ifdef __WATCOMC__ #include #else #include #endif #include #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; } } }