Annotation of loncom/cgi/mimeTeX/gfuntype.c, revision 1.1

1.1     ! albertel    1: /****************************************************************************
        !             2:  *
        !             3:  * Copyright (c) 2002, John Forkosh Associates, Inc.  All rights reserved.
        !             4:  * --------------------------------------------------------------------------
        !             5:  * This file is part of mimeTeX, which is free software. You may redistribute
        !             6:  * and/or modify it under the terms of the GNU General Public License,
        !             7:  * version 2 or later, as published by the Free Software Foundation.
        !             8:  *      MimeTeX is distributed in the hope that it will be useful, but
        !             9:  * WITHOUT ANY WARRANTY, not even the implied warranty of MERCHANTABILITY.
        !            10:  * See the GNU General Public License for specific details.
        !            11:  *      By using mimeTeX, you warrant that you have read, understood and
        !            12:  * agreed to these terms and conditions, and that you are at least 18 years
        !            13:  * of age and possess the legal right and ability to enter into this
        !            14:  * agreement and to use mimeTeX in accordance with it.
        !            15:  *      Your mimeTeX distribution should contain a copy of the GNU General
        !            16:  * Public License.  If not, write to the Free Software Foundation, Inc.,
        !            17:  * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
        !            18:  * --------------------------------------------------------------------------
        !            19:  *
        !            20:  * Program:	gfuntype  [-n fontname]  [-m msglevel]  [infile [outfile]]
        !            21:  *
        !            22:  * Purpose:	Parses output from  gftype -i
        !            23:  *		and writes pixel bitmap data of the characters
        !            24:  *		in a format suitable for a C header file, etc.
        !            25:  *
        !            26:  * --------------------------------------------------------------------------
        !            27:  *
        !            28:  * Command-line Arguments:
        !            29:  *		--- args can be in any order ---
        !            30:  *		infile		name of input file
        !            31:  *				(defaults to stdin if no filenames given)
        !            32:  *		outfile		name of output file
        !            33:  *				(defaults to stdout if <2 filenames given)
        !            34:  *		-m msglevel	verbose if msglevel>=9 (vv if >=99)
        !            35:  *		-n fontname	string used for fontname
        !            36:  *				(defaults to noname)
        !            37:  *
        !            38:  * Exits:	0=success,  1=some error
        !            39:  *
        !            40:  * Notes:     o	To compile
        !            41:  *		cc gfuntype.c mimetex.c -lm -o gfuntype
        !            42:  *		needs mimetex.c and mimetex.h
        !            43:  *
        !            44:  * Source:	gfuntype.c
        !            45:  *
        !            46:  * --------------------------------------------------------------------------
        !            47:  * Revision History:
        !            48:  * 09/22/02	J.Forkosh	Installation.
        !            49:  *
        !            50:  ****************************************************************************/
        !            51: 
        !            52: /* --------------------------------------------------------------------------
        !            53: standard headers, program parameters, global data and macros
        !            54: -------------------------------------------------------------------------- */
        !            55: /* --- standard headers --- */
        !            56: #include <stdio.h>
        !            57: #include <stdlib.h>
        !            58: #include <string.h>
        !            59: #include <ctype.h>
        !            60: /* --- application headers --- */
        !            61: /* #define SIGNEDCHAR */
        !            62: #include "mimetex.h"
        !            63: /* --- parameters either -D defined on cc line, or defaulted here --- */
        !            64: #ifndef	MSGLEVEL
        !            65: #define	MSGLEVEL 0
        !            66: #endif
        !            67: /* --- message level (verbose test) --- */
        !            68: static	int msglevel = MSGLEVEL;	/* verbose if msglevel >= 9 */
        !            69: static	FILE *msgfp;			/* verbose output goes here */
        !            70: /* --- miscellaneous other data --- */
        !            71: #define	CORNER_STUB ".<--"		/* start of upper,lower-left line */
        !            72: #define	TYPECAST    "(pixbyte *)"	/* typecast for pixmap string */
        !            73: 
        !            74: /* ==========================================================================
        !            75:  * Function:	main() for gfuntype.c
        !            76:  * Purpose:	interprets command-line args, etc
        !            77:  * --------------------------------------------------------------------------
        !            78:  * Command-Line Arguments:
        !            79:  *		See above
        !            80:  * --------------------------------------------------------------------------
        !            81:  * Returns:	0=success, 1=some error
        !            82:  * --------------------------------------------------------------------------
        !            83:  * Notes:     o
        !            84:  * ======================================================================= */
        !            85: /* --- entry point --- */
        !            86: int	main ( int argc, char *argv[] )
        !            87: {
        !            88: /* --------------------------------------------------------------------------
        !            89: Allocations and Declarations
        !            90: -------------------------------------------------------------------------- */
        !            91: int	argnum = 0;		/* argv[] index for command-line args */
        !            92: int	inarg=0, outarg=0;	/* argv[] indexes for infile, outfile */
        !            93: int	iserror = 1;		/* error signal */
        !            94: int	charnum,		/* character number (nextchar->charnum) */
        !            95: 	nchars = 0;		/* #chars in font */
        !            96: char	fontname[99] = "noname", /* font name */
        !            97: 	*getcharname();		/* get character name from its number */
        !            98: FILE	/* *fopen(),*/ *infp=stdin, *outfp=stdout; /* init file pointers */
        !            99: chardef	*getnextchar(), *nextchar, /* read and parse next char in infp */
        !           100: 	*fontdef[256];		/* chars stored using charnum as index */
        !           101: int	cstruct_chardef();	/* emit C struct for a character map */
        !           102: int	type_raster();		/* display debugging output */
        !           103: char	*copyright =		/* copyright, gnu/gpl notice */
        !           104:  "+-----------------------------------------------------------------------+\n"
        !           105:  "|gfuntype ver 1.00, Copyright(c) 2002-2003, John Forkosh Associates, Inc|\n"
        !           106:  "+-----------------------------------------------------------------------+\n"
        !           107:  "| gfuntype is free software licensed to you under terms of the GNU/GPL, |\n"
        !           108:  "|           and comes with absolutely no warranty whatsoever.           |\n"
        !           109:  "+-----------------------------------------------------------------------+";
        !           110: /* --------------------------------------------------------------------------
        !           111: interpret command-line arguments
        !           112: -------------------------------------------------------------------------- */
        !           113: while ( argc > ++argnum )	/* check for flags and filenames */
        !           114:     if ( *argv[argnum] == '-' )	/* got some '-' flag */
        !           115:       {
        !           116:       char flag = tolower(*(argv[argnum]+1)); /* char following '-' */
        !           117:       argnum++;			/* arg following flag is usually its value */
        !           118:       switch ( flag )		/* see what user wants to tell us */
        !           119: 	{
        !           120: 	/* --- no usage for clueless users yet --- */
        !           121: 	default:  exit(iserror); /* exit quietly for unrecognized input */
        !           122: 	/* --- adjustable program parameters (not checking input) --- */
        !           123: 	case 'm': msglevel   = atoi(argv[argnum]); break;
        !           124: 	case 'n': strcpy(fontname,argv[argnum]); break;
        !           125: 	} /* --- end-of-switch() --- */
        !           126:       } /* --- end-of-if(*argv[]=='-') --- */
        !           127:     else			/* this arg not a -flag, so it must be... */
        !           128:       if ( inarg == 0 )		/* no infile arg yet */
        !           129: 	inarg = argnum;		/* so use this one */
        !           130:       else			/* we already have an infile arg */
        !           131: 	if ( outarg == 0 )	/* but no outfile arg yet */
        !           132: 	  outarg = argnum;	/* so use this one */
        !           133: /* --- set verbose file ptr --- */
        !           134: msgfp = (outarg>0? stdout : stderr); /* use stdout or stderr */
        !           135: /* --- emit copyright, gnu/gpl notice --- */
        !           136: fprintf(msgfp,"%s\n",copyright); /* display copyright, gnu/gpl info */
        !           137: /* --- display input args if verbose output --- */
        !           138: if ( msglevel >= 9 )		/* verbose output requested */
        !           139:   fprintf(msgfp,"gfuntype> infile=%s, outfile=%s, fontname=%s\n",
        !           140:   (inarg>0?argv[inarg]:"stdin"), (outarg>0?argv[outarg]:"stdout"), fontname);
        !           141: /* --------------------------------------------------------------------------
        !           142: initialization
        !           143: -------------------------------------------------------------------------- */
        !           144: /* --- initialize font[] array --- */
        !           145: for ( charnum=0; charnum<256; charnum++ ) /*for each possible char in font*/
        !           146:   fontdef[charnum] = (chardef *)NULL;	/* char doesn't exist yet */
        !           147: /* --- open input file (if necessary) --- */
        !           148: if ( inarg > 0 )		/* input from file, not from stdin */
        !           149:   if ( (infp = fopen(argv[inarg],"r")) == NULL ) /*try to open input file*/
        !           150:     { fprintf(msgfp,"gfuntype> can't open %s for read\n",argv[inarg]);
        !           151:       goto end_of_job; }	/* report error and quit */
        !           152: /* --------------------------------------------------------------------------
        !           153: process input file
        !           154: -------------------------------------------------------------------------- */
        !           155: while ( (nextchar=getnextchar(infp)) != NULL ) /* get each char in file */
        !           156:   {
        !           157:   /* --- display character info --- */
        !           158:   if ( msglevel >= 9 )			/* verbose output requested */
        !           159:     fprintf(msgfp,"gfuntype> Char#%3d, loc %4d: ul=(%d,%d) ll=(%d,%d)\n",
        !           160:     nextchar->charnum, nextchar->location,
        !           161:     nextchar->topleftcol,nextchar->toprow,
        !           162:     nextchar->botleftcol,nextchar->botrow);
        !           163:   if ( msglevel >= 19 )			/* if a bit more verbose */
        !           164:     type_raster(&(nextchar->image),msgfp); /*display ascii image of raster*/
        !           165:   /* --- store character in font */
        !           166:   charnum = nextchar->charnum;		/* get char number of char in font */
        !           167:   if ( charnum>=0 && charnum<=255 )	/* check for valid range */
        !           168:     fontdef[charnum] = nextchar;	/* store char in font */
        !           169:   } /* --- end-of-while(charnum>0) --- */
        !           170: /* --------------------------------------------------------------------------
        !           171: generate output file
        !           172: -------------------------------------------------------------------------- */
        !           173: /* --- open output file (if necessary) --- */
        !           174: if ( outarg > 0 )		/* output to a file, not to stdout */
        !           175:   if ( (outfp = fopen(argv[outarg],"w")) == NULL ) /*try to open output file*/
        !           176:     { fprintf(msgfp,"gfuntype> can't open %s for write\n",argv[outarg]);
        !           177:       goto end_of_job; }	/* report error and quit */
        !           178: /* --- header lines --- */
        !           179: fprintf(outfp,"/%c --- fontdef for %s --- %c/\n", '*',fontname,'*');
        !           180: fprintf(outfp,"static\tchardef %c%s[] =\n   {\n", ' ',fontname);
        !           181: /* --- write characters comprising font --- */
        !           182: for ( charnum=0; charnum<256; charnum++ ) /*for each possible char in font*/
        !           183:   if ( fontdef[charnum] != (chardef *)NULL ) /*check if char exists in font*/
        !           184:     { if ( ++nchars > 1 )		/* bump count */
        !           185: 	fprintf(outfp,",\n");		/* and terminate preceding chardef */
        !           186:       fprintf(outfp,"      /%c --- pixel bitmap for %s char#%d %s --- %c/\n",
        !           187: 	'*',fontname,charnum,getcharname(fontname,charnum),'*');
        !           188:       cstruct_chardef(fontdef[charnum],outfp,6); } /*emit chardef as struct*/
        !           189:   else
        !           190:       if(0)fprintf(outfp,"NULL");	/* no character in this position */
        !           191: /* --- write trailer chardef and closing brace --- */
        !           192: fprintf(outfp,",\n");			/* finish up last map from loop */
        !           193: fprintf(outfp,"      /%c --- trailer  --- %c/\n",'*','*'); /* trailer... */
        !           194: fprintf(outfp,"      { -99, -999,  0,0,0,0, { 0,0,0, %s\"\\0\" }  }\n",
        !           195:      TYPECAST);
        !           196: fprintf(outfp,"   } ;\n");		/* terminating }; for fontdef */
        !           197: /* --------------------------------------------------------------------------
        !           198: end-of-job
        !           199: -------------------------------------------------------------------------- */
        !           200: /* --- reset error status for okay exit --- */
        !           201: iserror = 0;
        !           202: /* --- close files (if they're open and not stdin/out) --- */
        !           203: end_of_job:
        !           204:   if (  infp!=NULL &&  infp!=stdin  ) fclose( infp);
        !           205:   if ( outfp!=NULL && outfp!=stdout ) fclose(outfp);
        !           206: exit ( iserror );
        !           207: } /* --- end-of-function main() --- */
        !           208: 
        !           209: 
        !           210: /* ==========================================================================
        !           211:  * Function:	getnextchar ( fp )
        !           212:  * Purpose:	Reads and parses the next character definition on fp,
        !           213:  *		and returns a new chardef struct describing that character.
        !           214:  * --------------------------------------------------------------------------
        !           215:  * Arguments:	fp (I)		FILE *  to input file
        !           216:  *				(containing output from  gftype -i)
        !           217:  * Returns:	( chardef * )	ptr to chardef struct describing character,
        !           218:  *				or NULL for eof or any error
        !           219:  * --------------------------------------------------------------------------
        !           220:  * Notes:     o	fp is left so the next line read from it will be
        !           221:  *		the one following the final .<-- line.
        !           222:  * ======================================================================= */
        !           223: /* --- entry point --- */
        !           224: chardef	*getnextchar ( FILE *fp )
        !           225: {
        !           226: /* --------------------------------------------------------------------------
        !           227: Allocations and Declarations
        !           228: -------------------------------------------------------------------------- */
        !           229: chardef	*new_chardef(), *nextchar=(chardef *)NULL; /*ptr returned to caller*/
        !           230: int	delete_chardef();		/* free allocated memory if error */
        !           231: int	findnextchar(), charnum,location; /* get header line for next char */
        !           232: int	rasterizechar();		/* ascii image --> raster pixmap */
        !           233: int	parsecorner();			/* get col,row from ".<--" line */
        !           234: char	*readaline();			/* read next line from fp */
        !           235: /* --------------------------------------------------------------------------
        !           236: initialization
        !           237: -------------------------------------------------------------------------- */
        !           238: /* --- find and interpret header line for next character --- */
        !           239: charnum = findnextchar(fp,&location);	/* read and parse header line */
        !           240: if ( charnum < 0 ) goto error;		/* eof or error, no more chars */
        !           241: /* --- allocate a new chardef struct and begin populating it --- */
        !           242: if ( (nextchar=new_chardef())		/* allocate a new chardef */
        !           243: ==   (chardef *)NULL ) goto error;	/* and quit if we failed */
        !           244: nextchar->charnum = charnum;		/* store charnum in struct */
        !           245: nextchar->location = location;		/* and location */
        !           246: /* --- get upper-left corner line --- */
        !           247: if ( !parsecorner(readaline(fp),	/* parse corner line */
        !           248: &(nextchar->toprow),&(nextchar->topleftcol)) ) /* row and col from line */
        !           249:   goto error;				/* and quit if failed */
        !           250: /* --------------------------------------------------------------------------
        !           251: interpret character image (and parse terminating corner line)
        !           252: -------------------------------------------------------------------------- */
        !           253: /* --- read ascii character image and interpret as integer bitmap --- */
        !           254: if ( rasterizechar(fp,&nextchar->image) != 1 ) /* parse image of char */
        !           255:   goto error;				/* and quit if failed */
        !           256: /* --- get lower-left corner line --- */
        !           257: if ( !parsecorner(readaline(NULL),	/* reread and parse corner line */
        !           258: &(nextchar->botrow),&(nextchar->botleftcol)) ) /* row and col from line */
        !           259:   goto error;				/* and quit if failed */
        !           260: /* --------------------------------------------------------------------------
        !           261: done
        !           262: -------------------------------------------------------------------------- */
        !           263: goto end_of_job;			/* skip error return if successful */
        !           264: error:
        !           265:   if ( nextchar != (chardef *)NULL )	/* have an allocated chardef */
        !           266:     delete_chardef(nextchar);		/* so deallocate it */
        !           267:   nextchar = (chardef *)NULL;		/* and reset ptr to null for error */
        !           268: end_of_job:
        !           269:   return ( nextchar );			/* back with chardef or null */
        !           270: } /* --- end-of-function getnextchar() --- */
        !           271: 
        !           272: 
        !           273: /* ==========================================================================
        !           274:  * Function:	getcharname ( fontname, charnum )
        !           275:  * Purpose:	Looks up charnum for the family specified by fontname
        !           276:  *		and returns the corresponding charname.
        !           277:  * --------------------------------------------------------------------------
        !           278:  * Arguments:	fontname (I)	char * containing fontname for font family
        !           279:  *		charnum (I)	int containing the character number
        !           280:  *				whose corresponding name is wanted.
        !           281:  * Returns:	( char * )	ptr to character name
        !           282:  *				or NULL if charnum not found in table
        !           283:  * --------------------------------------------------------------------------
        !           284:  * Notes:     o
        !           285:  * ======================================================================= */
        !           286: /* --- entry point --- */
        !           287: char	*getcharname ( char *fontname, int charnum )
        !           288: {
        !           289: /* --------------------------------------------------------------------------
        !           290: Allocations and Declarations
        !           291: -------------------------------------------------------------------------- */
        !           292: /* --- recognized font family names and our corresponding numbers --- */
        !           293: static	char *fnames[] = { "cmr","cmmi","cmsy","cmex",NULL };
        !           294: static	int    fnums[] = { CMR10,CMMI10,CMSY10,CMEX10,  -1 };
        !           295: static	char *noname = "(noname)";  /* char name returned if lookup fails */
        !           296: /* --- other local declarations --- */
        !           297: char	*charname = noname;	/* character name returned to caller */
        !           298: char	flower[99] = "noname";	/* lowercase caller's fontname */
        !           299: int	ifamily = 0,		/* fnames[] (and fnums[]) index */
        !           300: 	ichar = 0;
        !           301: /* --------------------------------------------------------------------------
        !           302: lowercase caller's fontname and look it up in fnames[]
        !           303: -------------------------------------------------------------------------- */
        !           304: /* --- lowercase caller's fontname --- */
        !           305: for ( ichar=0; *fontname!='\000'; ichar++,fontname++ )/*lowercase each char*/
        !           306:   flower[ichar] = (isalpha(*fontname)? tolower(*fontname) : *fontname);
        !           307: flower[ichar] = '\000';		/* null-terminate lowercase fontname */
        !           308: if ( strlen(flower) < 2 ) goto end_of_job; /* no lookup match possible */
        !           309: /* --- look up lowercase fontname in our fnames[] table --- */
        !           310: for ( ifamily=0; ;ifamily++ )	/* check fnames[] for flower */
        !           311:   if ( fnames[ifamily] == NULL ) goto end_of_job; /* quit at end-of-table */
        !           312:   else if ( strstr(flower,fnames[ifamily]) != NULL ) break; /* found it */
        !           313: ifamily = fnums[ifamily];	/* xlate index to font family number */
        !           314: /* --------------------------------------------------------------------------
        !           315: now look up name for caller's charnum in ifamily, and return it to caller
        !           316: -------------------------------------------------------------------------- */
        !           317: /* --- search symtable[] for charnum in ifamily --- */
        !           318: for ( ichar=0; ;ichar++ )	/*search symtable[] for charnum in ifamily*/
        !           319:   if ( symtable[ichar].symbol == NULL ) goto end_of_job; /* end-of-table */
        !           320:   else
        !           321:     if ( symtable[ichar].family == ifamily /* found desired family */
        !           322:     &&   symtable[ichar].handler == NULL ) /* and char isn't a "dummy" */
        !           323:       if ( symtable[ichar].charnum == charnum ) break; /* found charnum */
        !           324: /* --- return corresponding charname to caller --- */
        !           325: charname = symtable[ichar].symbol; /* pointer to symbol name in table */
        !           326: end_of_job:
        !           327:   return ( charname );
        !           328: } /* --- end-of-function getcharname() --- */
        !           329: 
        !           330: 
        !           331: /* ==========================================================================
        !           332:  * Function:	findnextchar ( fp, location )
        !           333:  * Purpose:	Finds next "beginning of char" line in fp
        !           334:  *		and returns the character number,
        !           335:  *		and (optionally) location if arg provided.
        !           336:  * --------------------------------------------------------------------------
        !           337:  * Arguments:	fp (I)		FILE *  to input file
        !           338:  *				(containing output from  gftype -i)
        !           339:  *		location (O)	int *  returning "location" of character
        !           340:  *				(or pass NULL and it won't be returned)
        !           341:  * Returns:	( int )		character number,
        !           342:  *				or -1 for eof or any error
        !           343:  * --------------------------------------------------------------------------
        !           344:  * Notes:     o	fp is left so the next line read from it will be
        !           345:  *		the one following the "beginning of char" line
        !           346:  * ======================================================================= */
        !           347: /* --- entry point --- */
        !           348: int	findnextchar ( FILE *fp, int *location )
        !           349: {
        !           350: /* --------------------------------------------------------------------------
        !           351: Allocations and Declarations
        !           352: -------------------------------------------------------------------------- */
        !           353: static	char keyword[99]="beginning of char "; /*signals start of next char*/
        !           354: char	*readaline(), *line;	/* read next line from fp */
        !           355: char	*strstr(), *strchr(), *delim; /* search line for substring, char */
        !           356: char	token[99];		/* token extracted from line */
        !           357: int	charnum = (-1);		/* character number returned to caller */
        !           358: /* --------------------------------------------------------------------------
        !           359: keep reading lines until eof or keyword found
        !           360: -------------------------------------------------------------------------- */
        !           361: while ( (line=readaline(fp)) != NULL ) /* read lines until eof */
        !           362:   {
        !           363:   if ( msglevel >= 999 )	/* very, very verbose output requested */
        !           364:     fprintf(msgfp,"nextchar> line = %s\n",line);
        !           365:   if ( (delim=strstr(line,keyword)) != NULL ) /* found keyword on line */
        !           366:     {
        !           367:     /* --- get character number from line --- */
        !           368:     strcpy(token,delim+strlen(keyword)); /* char num follows keyword */
        !           369:     charnum = atoi(token);	/* interpret token as integer charnum */
        !           370:     /* --- get location at beginning of line --- */
        !           371:     if ( location != (int *)NULL )  /* caller wants location returned */
        !           372:       if ( (delim=strchr(line,':')) != NULL ) /* location precedes colon */
        !           373: 	{ *delim = '\000';	/* terminate line after location */
        !           374: 	  *location = atoi(line); } /* interpret location as integer */
        !           375:     break;			/* back to caller with charnum */
        !           376:     } /* --- end-of-if(delim!=NULL) --- */
        !           377:   } /* --- end-of-while(line!=NULL) --- */
        !           378: return ( charnum );		/* back to caller with char number or -1 */
        !           379: } /* --- end-of-function findnextchar() --- */
        !           380: 
        !           381: 
        !           382: /* ==========================================================================
        !           383:  * Function:	rasterizechar ( fp, rp )
        !           384:  * Purpose:	Reads and parses subsequent lines from fp
        !           385:  *		(until a terminating ".<--" line),
        !           386:  *		representing the ascii image of the character in fp,
        !           387:  *		and returns the results in raster struct rp
        !           388:  * --------------------------------------------------------------------------
        !           389:  * Arguments:	fp (I)		FILE *  to input file
        !           390:  *				(containing output from  gftype -i)
        !           391:  *				positioned immediately after top .<-- line,
        !           392:  *				ready to read first line of ascii image
        !           393:  *		rp (O)		raster *  returning the rasterized
        !           394:  *				character represented on fp as an ascii image
        !           395:  * Returns:	( int )		1=okay, or 0=eof or any error
        !           396:  * --------------------------------------------------------------------------
        !           397:  * Notes:     o	fp is left so the last line (already) read from it
        !           398:  *		contains the terminating .<-- corner information
        !           399:  *		(readaline(NULL) will reread this last line)
        !           400:  *	      o	char images on fp can be no wider than 31 pixels
        !           401:  * ======================================================================= */
        !           402: /* --- entry point --- */
        !           403: int	rasterizechar ( FILE *fp, raster *image )
        !           404: {
        !           405: /* --------------------------------------------------------------------------
        !           406: Allocations and Declarations
        !           407: -------------------------------------------------------------------------- */
        !           408: char	*readaline(), *line;	/* read next scan line for char from fp */
        !           409: unsigned char bitvec[512][64];	/* scan lines parsed (up to 512x512 bits) */
        !           410: int	height = 0,		/* #scan lines in fp comprising char */
        !           411: 	width = 0,		/* #chars on longest scan line */
        !           412: 	pixsz = 1;		/* default #bits per pixel, 1=bitmap */
        !           413: int	iscan, ipixel=0,	/* bitvec[] index, raster pixel map index */
        !           414: 	ibit;			/* bit along scan (i.e., 0...width-1) */
        !           415: int	isokay = 0;		/* returned status, init for failure */
        !           416: /* --------------------------------------------------------------------------
        !           417: read lines till ".<--" terminator, and construct one vector[] int per line
        !           418: -------------------------------------------------------------------------- */
        !           419: while ( (line=readaline(fp)) != NULL ) /* read lines until eof */
        !           420:   {
        !           421:   /* --- allocations and declarations --- */
        !           422:   int	icol, ncols=strlen(line); /* line[] column index, #cols in line[] */
        !           423:   /* --- check for end-of-char (when we encounter corner line) --- */
        !           424:   if ( memcmp(line,CORNER_STUB,strlen(CORNER_STUB)) == 0 ) /* corner line */
        !           425:     break;			/* so done with loop */
        !           426:   /* --- parse line (encode asterisks comprising character image) --- */
        !           427:   memset(bitvec[height],0,64);	/* first zero out all bits */
        !           428:   for ( icol=0; icol<ncols; icol++ ) /* now check line[] for asterisks */
        !           429:     if ( line[icol] == '*' )	/* we want to set this bit */
        !           430:       {	setlongbit(bitvec[height],icol); /* set bit */
        !           431: 	if ( icol >= width ) width=icol+1; } /* and check for new width */
        !           432:   height++;			/* bump character height */
        !           433:   } /* --- end-of-while(line!=NULL) --- */
        !           434: if ( height<1 || width<1 )	/* some problem parsing character */
        !           435:   goto end_of_job;		/* so quit */
        !           436: /* --------------------------------------------------------------------------
        !           437: allocate image raster pixmap for character
        !           438: -------------------------------------------------------------------------- */
        !           439: if ( image->pixmap != NULL )	/* hmm, somebody already allocated memory */
        !           440:   free((void *)image->pixmap);	/* just free it */
        !           441: image->width = width;		/* set image width within raster struct */
        !           442: image->height = height;		/* and height */
        !           443: image->pixsz = pixsz;		/* #bits per pixel, 1=bitmap or 8=bytemap */
        !           444: if ( (image->pixmap = (unsigned char *)malloc(pixmapsz(image)))
        !           445: == NULL ) goto end_of_job;	/* quit if failed to allocate pixmap */
        !           446: /* --------------------------------------------------------------------------
        !           447: copy each integer in bitvec[] to raster pixmap, bit by bit
        !           448: -------------------------------------------------------------------------- */
        !           449: for ( iscan=0; iscan<height; iscan++ )	/* for each integer in vector[] */
        !           450:   for ( ibit=0; ibit<width; ibit++ )	/* for all bits in this scan */
        !           451:     {
        !           452:     if ( getlongbit(bitvec[iscan],ibit) != 0 ) /* check current scan pixel */
        !           453:       { setlongbit(image->pixmap,ipixel); }
        !           454:     else				/*turn off corresponding raster bit*/
        !           455:       { unsetlongbit(image->pixmap,ipixel); }
        !           456:     ipixel++;				/* bump image raster pixel */
        !           457:     } /* --- end-of-for(iscan,ibit) --- */
        !           458: /* --------------------------------------------------------------------------
        !           459: done
        !           460: -------------------------------------------------------------------------- */
        !           461: isokay = 1;				/* reset flag for success */
        !           462:  end_of_job:
        !           463:   return ( isokay );			/* back with 1=success, 0=failure */
        !           464: } /* --- end-of-function rasterizechar() --- */
        !           465: 
        !           466: 
        !           467: /* ==========================================================================
        !           468:  * Function:	parsecorner ( line, row, col )
        !           469:  * Purpose:	Parses a "pixel corner" line (upper left or lower left)
        !           470:  *		and returns the (col,row) information on it as integers.
        !           471:  * --------------------------------------------------------------------------
        !           472:  * Arguments:	line (I)	char *  to input line containing
        !           473:  *				".<--This pixel's..." to be parsed
        !           474:  *		row (O)		int *  returning the (,row)
        !           475:  *		col (O)		int *  returning the (col,)
        !           476:  * Returns:	( int )		1 if successful, or 0 for any error
        !           477:  * --------------------------------------------------------------------------
        !           478:  * Notes:     o
        !           479:  * ======================================================================= */
        !           480: /* --- entry point --- */
        !           481: int	parsecorner ( char *line, int *row, int *col )
        !           482: {
        !           483: /* --------------------------------------------------------------------------
        !           484: Allocations and Declarations
        !           485: -------------------------------------------------------------------------- */
        !           486: int	isokay = 0;		/* success/fail flag, init for failure */
        !           487: char	field[99], *delim;	/*(col,row) field and ptr to various delims*/
        !           488: /* --------------------------------------------------------------------------
        !           489: extract (col,row) field from line, and interpret col and row as integers
        !           490: -------------------------------------------------------------------------- */
        !           491: /* --- first, check beginning of line --- */
        !           492: if ( line == (char *)NULL ) goto end_of_job; /* no line supplied by caller */
        !           493: if ( memcmp(line,CORNER_STUB,strlen(CORNER_STUB)) != 0 ) /*not valid corner*/
        !           494:   goto end_of_job;			/* so quit */
        !           495: /* --- extract  col,row  field from line --- */
        !           496: if ( (delim=strchr(line,'(')) == NULL ) goto end_of_job; /*find open paren*/
        !           497: strncpy(field,delim+1,10);		/* extract next 10 chars */
        !           498: field[10] = '\000';			/* and null-terminate field */
        !           499: if ( (delim=strchr(field,')')) == NULL ) goto end_of_job; /*find close paren*/
        !           500: *delim = '\000';			/* terminate field at close paren */
        !           501: /* --- interpret col,row as integers --- */
        !           502: if ( (delim=strchr(field,',')) == NULL ) goto end_of_job; /* find comma */
        !           503: *delim = '\000';			/* break field into col and row */
        !           504: if ( col != (int *)NULL )		/* caller gave us ptr for col */
        !           505:   *col = atoi(field);			/* so return it to him */
        !           506: if ( row != (int *)NULL )		/* caller gave us ptr for row */
        !           507:   *row = atoi(delim+1);			/* so return it to him */
        !           508: /* --------------------------------------------------------------------------
        !           509: done
        !           510: -------------------------------------------------------------------------- */
        !           511: isokay = 1;				/* reset flag for success */
        !           512:  end_of_job:
        !           513:   return ( isokay );			/* back with success/fail flag */
        !           514: } /* --- end-of-function parsecorner() --- */
        !           515: 
        !           516: 
        !           517: /* ==========================================================================
        !           518:  * Function:	readaline ( fp )
        !           519:  * Purpose:	Reads a line from fp, strips terminating newline,
        !           520:  *		and returns ptr to internal buffer
        !           521:  * --------------------------------------------------------------------------
        !           522:  * Arguments:	fp (I)		FILE *  to input file to be read.
        !           523:  *				If null, returns line previously read.
        !           524:  * Returns:	( char * )	internal buffer containing line read,
        !           525:  *				or NULL for eof or error.
        !           526:  * --------------------------------------------------------------------------
        !           527:  * Notes:     o	fp is left on the line following the returned line
        !           528:  * ======================================================================= */
        !           529: /* --- entry point --- */
        !           530: char	*readaline ( FILE *fp )
        !           531: {
        !           532: /* --------------------------------------------------------------------------
        !           533: Allocations and Declarations
        !           534: -------------------------------------------------------------------------- */
        !           535: static	char buffer[1024];	/* static buffer if caller supplies none */
        !           536: char	*fgets(), *bufptr=buffer; /* read line from fp */
        !           537: char	*strchr(), *delim;	/* remove terminating newline */
        !           538: /* --------------------------------------------------------------------------
        !           539: Read line and strip trailing newline
        !           540: -------------------------------------------------------------------------- */
        !           541: if ( fp != NULL )			/*if null, return previous line read*/
        !           542:   if ( (bufptr=fgets(buffer,1023,fp))	/* read next line from fp */
        !           543:   != NULL )				/* and check that we succeeded */
        !           544:     {
        !           545:     if ( (delim=strchr(bufptr,'\n'))	/* look for terminating newline */
        !           546:     != NULL )				/* and check that we found it */
        !           547:       *delim = '\000';			/* truncate line at newline */
        !           548:     } /* --- end-of-if(fgets()!=NULL) --- */
        !           549: return ( bufptr );			/*back to caller with buffer or null*/
        !           550: } /* --- end-of-function readaline() --- */
        !           551: /* --- end-of-file gfuntype.c --- */
        !           552: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>