📄 gfuntype.c
字号:
* or NULL for eof or any error
* --------------------------------------------------------------------------
* Notes: o fp is left so the next line read from it will be
* the one following the final .<-- line.
* ======================================================================= */
/* --- entry point --- */
chardef *getnextchar ( FILE *fp )
{
/* --------------------------------------------------------------------------
Allocations and Declarations
-------------------------------------------------------------------------- */
chardef *new_chardef(), *nextchar=(chardef *)NULL; /*ptr returned to caller*/
int delete_chardef(); /* free allocated memory if error */
int findnextchar(), charnum,location; /* get header line for next char */
int rasterizechar(); /* ascii image --> raster pixmap */
int parsestat=(-999), parsecorner(); /* get col,row from ".<--" line */
char *readaline(); /* read next line from fp */
/* --------------------------------------------------------------------------
initialization
-------------------------------------------------------------------------- */
while ( parsestat == (-999) ) { /* flush entirely blank characters */
/* --- find and interpret header line for next character --- */
charnum = findnextchar(fp,&location); /* read and parse header line */
if ( charnum < 0 ) goto error; /* eof or error, no more chars */
/* --- allocate a new chardef struct and begin populating it --- */
if ( nextchar == (chardef *)NULL ) /* haven't allocated chardef yet */
if ( (nextchar=new_chardef()) /* allocate a new chardef */
== (chardef *)NULL ) goto error; /* and quit if we failed */
nextchar->charnum = charnum; /* store charnum in struct */
nextchar->location = location; /* and location */
/* --- get upper-left corner line --- */
parsestat = parsecorner(readaline(fp), /* parse corner line */
&(nextchar->toprow),&(nextchar->topleftcol)); /* row and col from line */
} /* --- end-of-while(parsestat) --- */
if ( !parsestat ) goto error; /* quit if parsecorner() failed */
/* --------------------------------------------------------------------------
interpret character image (and parse terminating corner line)
-------------------------------------------------------------------------- */
/* --- read ascii character image and interpret as integer bitmap --- */
if ( rasterizechar(fp,&nextchar->image) != 1 ) /* parse image of char */
goto error; /* and quit if failed */
/* --- get lower-left corner line --- */
if ( !parsecorner(readaline(NULL), /* reread and parse corner line */
&(nextchar->botrow),&(nextchar->botleftcol)) ) /* row and col from line */
goto error; /* and quit if failed */
/* --------------------------------------------------------------------------
done
-------------------------------------------------------------------------- */
goto end_of_job; /* skip error return if successful */
error:
if ( nextchar != (chardef *)NULL ) /* have an allocated chardef */
delete_chardef(nextchar); /* so deallocate it */
nextchar = (chardef *)NULL; /* and reset ptr to null for error */
end_of_job:
return ( nextchar ); /* back with chardef or null */
} /* --- end-of-function getnextchar() --- */
/* ==========================================================================
* Function: getcharname ( fontname, charnum )
* Purpose: Looks up charnum for the family specified by fontname
* and returns the corresponding charname.
* --------------------------------------------------------------------------
* Arguments: fontname (I) char * containing fontname for font family
* (from -n switch on command line)
* charnum (I) int containing the character number
* whose corresponding name is wanted.
* Returns: ( char * ) ptr to character name
* or NULL if charnum not found in table
* --------------------------------------------------------------------------
* Notes: o
* ======================================================================= */
/* --- entry point --- */
char *getcharname ( char *fontname, int charnum )
{
/* --------------------------------------------------------------------------
Allocations and Declarations
-------------------------------------------------------------------------- */
/* --- recognized font family names and our corresponding numbers --- */
static char *fnames[] = /*font name from -n switch on command line*/
{ "cmr","cmmib","cmmi","cmsy","cmex","bbold","rsfs","stmary", NULL };
static int fnums[] = /* corresponding mimetex fontfamily number*/
{ CMR10,CMMIB10,CMMI10,CMSY10,CMEX10,BBOLD10,RSFS10,STMARY10, -1 };
static int offsets[] = /* symtable[ichar].charnum = charnum-offset*/
{ 0, 0, 0, 0, 0, 0, 65, 0, -1 };
/* --- other local declarations --- */
char *charname = NULL; /* character name returned to caller */
char flower[99] = "noname"; /* lowercase caller's fontname */
int ifamily = 0, /* fnames[] (and fnums[],offsets[]) index */
offset = 0, /* offsets[ifamily] */
ichar = 0; /* loop index */
/* --------------------------------------------------------------------------
lowercase caller's fontname and look it up in fnames[]
-------------------------------------------------------------------------- */
/* --- lowercase caller's fontname --- */
for ( ichar=0; *fontname!='\000'; ichar++,fontname++ )/*lowercase each char*/
flower[ichar] = (isalpha(*fontname)? tolower(*fontname) : *fontname);
flower[ichar] = '\000'; /* null-terminate lowercase fontname */
if ( strlen(flower) < 2 ) goto end_of_job; /* no lookup match possible */
/* --- look up lowercase fontname in our fnames[] table --- */
for ( ifamily=0; ;ifamily++ ) /* check fnames[] for flower */
if ( fnames[ifamily] == NULL ) goto end_of_job; /* quit at end-of-table */
else if ( strstr(flower,fnames[ifamily]) != NULL ) break; /* found it */
offset = offsets[ifamily]; /* symtable[ichar].charnum = charnum-offset*/
ifamily = fnums[ifamily]; /* xlate index to font family number */
/* --------------------------------------------------------------------------
now look up name for caller's charnum in ifamily, and return it to caller
-------------------------------------------------------------------------- */
/* --- search symtable[] for charnum in ifamily --- */
for ( ichar=0; ;ichar++ ) /*search symtable[] for charnum in ifamily*/
if ( symtable[ichar].symbol == NULL ) goto end_of_job; /* end-of-table */
else
if ( symtable[ichar].family == ifamily /* found desired family */
&& symtable[ichar].handler == NULL ) /* and char isn't a "dummy" */
if ( symtable[ichar].charnum == charnum-offset ) break; /*got charnum*/
/* --- return corresponding charname to caller --- */
charname = symtable[ichar].symbol; /* pointer to symbol name in table */
end_of_job:
if ( charname==NULL && isnoname ) /* want unnamed/undefined chars */
charname = noname; /* so replace null return with noname */
return ( charname );
} /* --- end-of-function getcharname() --- */
/* ==========================================================================
* Function: findnextchar ( fp, location )
* Purpose: Finds next "beginning of char" line in fp
* and returns the character number,
* and (optionally) location if arg provided.
* --------------------------------------------------------------------------
* Arguments: fp (I) FILE * to input file
* (containing output from gftype -i)
* location (O) int * returning "location" of character
* (or pass NULL and it won't be returned)
* Returns: ( int ) character number,
* or -1 for eof or any error
* --------------------------------------------------------------------------
* Notes: o fp is left so the next line read from it will be
* the one following the "beginning of char" line
* ======================================================================= */
/* --- entry point --- */
int findnextchar ( FILE *fp, int *location )
{
/* --------------------------------------------------------------------------
Allocations and Declarations
-------------------------------------------------------------------------- */
static char keyword[99]="beginning of char "; /*signals start of next char*/
char *readaline(), *line; /* read next line from fp */
char *strstr(), *strchr(), *delim; /* search line for substring, char */
char token[99]; /* token extracted from line */
int charnum = (-1); /* character number returned to caller */
/* --------------------------------------------------------------------------
keep reading lines until eof or keyword found
-------------------------------------------------------------------------- */
while ( (line=readaline(fp)) != NULL ) /* read lines until eof */
{
if ( msglevel >= 999 ) /* very, very verbose output requested */
fprintf(msgfp,"nextchar> line = %s\n",line);
if ( (delim=strstr(line,keyword)) != NULL ) /* found keyword on line */
{
/* --- get character number from line --- */
strcpy(token,delim+strlen(keyword)); /* char num follows keyword */
charnum = atoi(token); /* interpret token as integer charnum */
/* --- get location at beginning of line --- */
if ( location != (int *)NULL ) /* caller wants location returned */
if ( (delim=strchr(line,':')) != NULL ) /* location precedes colon */
{ *delim = '\000'; /* terminate line after location */
*location = atoi(line); } /* interpret location as integer */
break; /* back to caller with charnum */
} /* --- end-of-if(delim!=NULL) --- */
} /* --- end-of-while(line!=NULL) --- */
return ( charnum ); /* back to caller with char number or -1 */
} /* --- end-of-function findnextchar() --- */
/* ==========================================================================
* Function: rasterizechar ( fp, rp )
* Purpose: Reads and parses subsequent lines from fp
* (until a terminating ".<--" line),
* representing the ascii image of the character in fp,
* and returns the results in raster struct rp
* --------------------------------------------------------------------------
* Arguments: fp (I) FILE * to input file
* (containing output from gftype -i)
* positioned immediately after top .<-- line,
* ready to read first line of ascii image
* rp (O) raster * returning the rasterized
* character represented on fp as an ascii image
* Returns: ( int ) 1=okay, or 0=eof or any error
* --------------------------------------------------------------------------
* Notes: o fp is left so the last line (already) read from it
* contains the terminating .<-- corner information
* (readaline(NULL) will reread this last line)
* o char images on fp can be no wider than 31 pixels
* ======================================================================= */
/* --- entry point --- */
int rasterizechar ( FILE *fp, raster *image )
{
/* --------------------------------------------------------------------------
Allocations and Declarations
-------------------------------------------------------------------------- */
char *readaline(), *line; /* read next scan line for char from fp */
unsigned char bitvec[1024][128]; /* scan lines parsed up to 1024x1024 bits */
int bitcmp(); /* compare bit strings */
int height = 0, /* #scan lines in fp comprising char */
width = 0; /* #chars on longest scan line */
int iscan, /* bitvec[] index */
ibit; /* bit along scan (i.e., 0...width-1) */
int isokay = 0; /* returned status, init for failure */
/* --- bitmap and .gf-formatted image info (we'll choose smallest) --- */
int iformat = gformat; /*0=best, 1=bitmap, 2=8-bit.gf, 3=4-bit.gf*/
unsigned char gfpixcount[2][65536]; /* .gf black/white flips (max=64K) */
int npixcounts[2] = {9999999,9999999}; /* #counts for 8-bit,4-bit .gf */
int nbytes1=9999999,nbytes2=9999999,nbytes3=9999999;/*#bytes for format*/
/* --------------------------------------------------------------------------
read lines till ".<--" terminator, and construct one vector[] int per line
-------------------------------------------------------------------------- */
memset(bitvec,0,128*1024); /* zero-fill bitvec[] */
while ( (line=readaline(fp)) != NULL ) /* read lines until eof */
{
/* --- allocations and declarations --- */
int icol, ncols=strlen(line); /* line[] column index, #cols in line[] */
/* --- check for end-of-char (when we encounter corner line) --- */
if ( memcmp(line,CORNER_STUB,strlen(CORNER_STUB)) == 0 ) /* corner line */
break; /* so done with loop */
/* --- parse line (encode asterisks comprising character image) --- */
memset(bitvec[height],0,128); /* first zero out all bits */
for ( icol=0; icol<ncols; icol++ ) /* now check line[] for asterisks */
if ( line[icol] == '*' ) /* we want to set this bit */
{ setlongbit(bitvec[height],icol); /* set bit */
if ( icol >= width ) width=icol+1; } /* and check for new width */
height++; /* bump character height */
} /* --- end-of-while(line!=NULL) --- */
if ( height<1 || width<1 ) /* some problem parsing character */
goto end_of_job; /* so quit */
/* --------------------------------------------------------------------------
init image values
-------------------------------------------------------------------------- */
if ( image->pixmap != NULL ) /* hmm, somebody already allocated memory */
free((void *)image->pixmap); /* so just free it */
image->width = width; /* set image width within raster struct */
image->height = height; /* and height */
image->format = gformat; /* set format (will be reset below) */
image->pixsz = 1; /* #bits per pixel (or #counts in .gf fmt) */
if ( gformat==0 || gformat==1 ) /* bitmap representation allowed */
{ nbytes1 = pixmapsz(image); /* #bytes needed for bitmap */
iformat = 1; } /* default to bitmap format */
/* --------------------------------------------------------------------------
perform .gf-like compression on image in bitvec
-------------------------------------------------------------------------- */
if ( gformat == 0 /* choose optimal/smallest respresentation */
|| gformat==2 || gformat==3 ) /* .gf-like compressed representation */
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -