home *** CD-ROM | disk | FTP | other *** search
- //-------------------------------------------------------------//
- // File: HpFont.Cpp //
- // Desc: Font implementation for HP Soft Font //
- // Author: Marv Luse, Autumn Hill Software //
- //-------------------------------------------------------------//
-
- #include "stdlib.h"
- #include "stdio.h"
- #include "ctype.h"
- #include "HpFont.Hpp"
-
- #define BUF_SIZ 128
-
- static int cur_ch = 0;
- static int hp_stat;
-
- //............................... Skip next n bytes from a file
-
- static int skip_inp( FILE *inp, int nbytes )
- {
- int n;
- char buf[BUF_SIZ];
-
- while( nbytes > 0 )
- {
- n = nbytes > BUF_SIZ ? BUF_SIZ : nbytes;
- if( fread(buf, n, 1, inp) != 1 )
- return 0;
- nbytes -= n;
- }
- return 1;
- }
-
- //......................... Determine char range from font type
-
- static void char_range( int font_type, int& min_ch, int& max_ch )
- {
- switch( font_type )
- {
- case 0 : // 7-bit, 32-127
- min_ch = 32;
- max_ch = 127;
- break;
-
- case 1 : // 8-bit, 32-127 and 160-255
- min_ch = 32;
- max_ch = 255;
- break;
-
- default: // 8-bit, everything
- min_ch = 0;
- max_ch = 255;
- break;
- }
- }
-
- //................. Determine esq type and its numeric argument
-
- static void get_esq_values( char esq_buf[], int& type, int& parm )
- {
- int i;
- char c1, c2, clast;
-
- /* extract group char and terminating char */
- c1 = esq_buf[1];
- c2 = esq_buf[2];
- i = 0;
- while( esq_buf[i] ) i++;
- clast = esq_buf[i-1];
-
- /* determine type */
- if( (c1==')') && (c2=='s') && (clast=='W') )
- type = eFONTDESC;
- else if( (c1=='(') && (c2=='s') && (clast=='W') )
- type = eCHARDESC;
- else if( (c1=='*') && (c2=='c') && (clast=='E') )
- type = eCHARCODE;
- else
- type = eUNKNOWN;
-
- /* get the sequence's value field */
- parm = 0;
- i = 0;
- while( (esq_buf[i]) && (! isdigit(esq_buf[i])) ) i++;
- if( isdigit(esq_buf[i]) )
- parm = atoi( esq_buf+i );
- }
-
-
- //.................... Read the next esc seq from the font file
-
- static int get_esq( FILE *inp, char esq_buf[], int buf_len )
- {
- int i, nbytes;
-
- nbytes = 0;
-
- while( (i=fgetc( inp )) != EOF )
- {
- if( nbytes == buf_len )
- {
- hp_stat = hpOVRFLOW;
- return 0;
- }
- esq_buf[nbytes++] = (char) i;
- // check for end of sequence
- if( isupper( i ) ) break;
- }
-
- // validity check - first char should be decimal 27
- if( (nbytes > 0) && (esq_buf[0] != 27) )
- {
- hp_stat = hpBADFMT;
- return 0;
- }
-
- // add a terminating null
- esq_buf[nbytes] = 0;
-
- return( nbytes );
- }
-
- //.................................... set font-related metrics
-
- void HpFont::SetFontMetrics( font_desc& fd )
- {
- cell_w = REV_WRD( fd.cell_width );
- cell_h = REV_WRD( fd.cell_height );
- ascent = REV_WRD( fd.bl_dist );
- descent = cell_h - ascent;
- pitch = REV_WRD( fd.pitch ) >> 2;
- }
-
- //.................................... set char-related metrics
-
- void HpFont::SetCharMetrics( Character& c, char_desc& cd )
- {
- c.left_ofs = REV_WRD( cd.left_ofs );
- c.top_ofs = REV_WRD( cd.top_ofs );
- c.width = REV_WRD( cd.char_width );
- c.height = REV_WRD( cd.char_height );
- c.rowbytes = (c.width + 7) / 8;
- c.delta_x = (REV_WRD( cd.delta_x ) + 3) >> 2;
- }
-
- //........................ default destructor
-
- HpFont::~HpFont( )
- {
- }
-
- //........................ instantiate a font from HP Soft Font
-
- HpFont::HpFont( char *path ) : Font( )
- {
- FILE *inp;
- char esq_buf[BUF_SIZ];
- font_desc fd;
- char_desc cd;
- int n, esq_type, esq_parm;
-
- // open file
- if( (inp = fopen( path, "rb" )) == NULL )
- {
- hpstatus = hpNOTFOUND;
- fstatus = fntFAILED;
- return;
- }
-
- // initialize static globals
- cur_ch = 0;
- hp_stat = hpNOINIT;
-
- // scan the file and process
- while( (get_esq( inp, esq_buf, BUF_SIZ ) > 0) &&
- (hp_stat == hpNOINIT) )
- {
-
- // get the escape sequence type and its
- // numeric value field...
- get_esq_values( esq_buf, esq_type, esq_parm );
-
- // process the sequence.....
- switch( esq_type )
- {
-
- case eFONTDESC: //............... font descriptor
- // read the descriptor
- if( fread( &fd, sizeof(font_desc), 1, inp ) != 1 )
- {
- hp_stat = hpIOERROR;
- break;
- }
- // allocate the Character array, init font stuff
- char_range( (int) fd.font_type, min_ch, max_ch );
- ch_cnt = max_ch - min_ch + 1;
- ch = new Character[ch_cnt];
- if( ch == 0 )
- {
- hp_stat = hpNOMEM;
- break;
- }
- SetFontMetrics( fd );
- // skip any trailing info
- if( esq_parm > sizeof(font_desc) )
- skip_inp( inp, esq_parm-sizeof(font_desc) );
- break;
-
- case eCHARDESC: //............... char descriptor
- // read the descriptor
- if( fread( &cd, sizeof(char_desc), 1, inp ) != 1 )
- {
- hp_stat = hpIOERROR;
- break;
- }
- // is this a char we discard?
- if( (cur_ch < min_ch) || (cur_ch > max_ch) )
- {
- skip_inp( inp, esq_parm-sizeof(char_desc) );
- break;
- }
- // set char table entry
- Character *c = &ch[cur_ch-min_ch];
- SetCharMetrics( *c, cd );
- // allocate this char's bitmap
- int i = c->rowbytes * c->height;
- if( i )
- {
- c->mask = new char[i];
- if( c->mask == 0 )
- {
- hp_stat = hpNOMEM;
- break;
- }
- }
- else
- c->mask = 0;
- // get the bitmap which follows
- if( esq_parm > sizeof(char_desc) )
- {
- n = esq_parm - sizeof(char_desc);
- if( fread( c->mask, n, 1, inp ) != 1 )
- {
- hp_stat = hpIOERROR;
- break;
- }
- }
- break;
-
- case eCHARCODE: //........ specify character code
- // save char code for later use
- cur_ch = esq_parm;
- break;
-
- case eUNKNOWN: //........ unknown seq - ignore it
- break;
- }
-
- }
-
- fclose( inp );
-
- // update Font and HpFont status members
- if( hp_stat != hpNOINIT )
- {
- hpstatus = hp_stat;
- fstatus = fntFAILED;
- return;
- }
- hpstatus = hpOKAY;
- fstatus = fntOKAY;
-
- // set width of blank-- may not have been a definition
- Character *b = &ch[32-min_ch];
- if( b->delta_x == 0 )
- b->delta_x = pitch;
- }
-