1*13811Sslatteng /* main.c	1.8	83/07/06
211377Sralph  *
311377Sralph  * Copyright -C- 1982 Barry S. Roitblat
411377Sralph  *
511381Sralph  *	This file contains the main and file system dependent routines
611377Sralph  * for producing hard copy from gremlin files.  It is extensively modified
711377Sralph  * from the vplot source.
811377Sralph  */
911377Sralph 
1011377Sralph #include "gprint.h"
1111377Sralph #include <signal.h>
1211377Sralph #include <vfont.h>
1311377Sralph 
1411381Sralph #define LPR "/usr/ucb/lpr"
1511377Sralph 
1611377Sralph extern char *mktemp();
1711381Sralph extern char *malloc();
1811381Sralph extern char *rindex();
1911377Sralph 
2011377Sralph /* imports */
2111377Sralph extern HGtline(), HGArc(), HGPutText(), HGMove(), HGSetFont();
2211377Sralph extern HGSetBrush(), HGInitFont(), HGPrintElt();
2311377Sralph extern int style[], thick[];
2411377Sralph extern char *tfont[], *tsize[];
2511377Sralph 
2611377Sralph /* database imports */
2711377Sralph 
2811377Sralph extern ELT *DBInit(), *DBRead();
2911377Sralph extern POINT *PTInit(), *PTMakePoint();
3011377Sralph 
3111381Sralph int	linethickness = 0;	/* brush styles */
3211577Sralph int	linmod = SOLID;
3312435Sslatteng char	*obuf;			/* output buffer NumOfLin x DevRange/8 */
3411793Sralph int	bufsize;		/* output buffer size */
3511381Sralph int	lastx;
3611381Sralph int	lasty;
3711381Sralph int	angle, startx, starty, endx, endy;
3812435Sslatteng double	scale = 4.0;		/* Variables used to map gremlin screen */
3911793Sralph double	orgx = 0.0;		/* x and y origin of gremlin picture */
4011793Sralph double	orgy = 0.0;
4111377Sralph 
4211577Sralph FILE	*pfp = stdout;		/* file descriptor of current picture */
4311381Sralph char	picture[] = "/usr/tmp/rastAXXXXXX";
4411381Sralph int	run = 13;		/* index of 'a' in picture[] */
4512435Sslatteng int	DevRange = Vxlen;	/* plot dimensions in pixels */
4612435Sslatteng int	DevRange8 = Vxlen/8;
4712435Sslatteng int	BytPrLin = Vbytperlin;	/* Bytes per raster line. (not DevRange8) */
4812435Sslatteng int	NumOfLin = Vylen;
4912435Sslatteng 
5011381Sralph int	lparg = 6;		/* index into lpargs */
5111381Sralph char	*lpargs[50] = { "lpr", "-Pvarian", "-v", "-s", "-r", "-J", };
5211377Sralph 
5312435Sslatteng int	Orientation;		/* variables used to print from font file */
5411381Sralph int	cfont = 0;
5511381Sralph int	csize = 0;
5611381Sralph struct	header header;
5711381Sralph struct	dispatch dispatch[256];
5811381Sralph char	*bits = NULL;
5911381Sralph char	*fontdir = "/usr/lib/vfont/";
6011377Sralph 
main(argc,argv)6111377Sralph main(argc, argv)
6211377Sralph int argc;
6311377Sralph char *argv[];
6411377Sralph {
6511381Sralph 	FILE *fp, *fopen();
6611381Sralph 	ELT *PICTURE, *e;
6711381Sralph 	POINT *p1, pos;
6811381Sralph 	char *file[50], string[10], *arg;
6911381Sralph 	char c, string1[50], string2[50], string3[50], string4[50],
7011381Sralph 		string5[50], string6[50], string7[50], string8[50];
7111381Sralph 	extern int cleanup();
7211381Sralph 	float mult;
7311381Sralph 	int WriteRaster = FALSE;
7411577Sralph 	register char *cp1, *cp2;
7511577Sralph 	register int i, k;
7611381Sralph 	int brsh, gfil = 0;
7711377Sralph 
7811381Sralph 	/* Parse the command line. */
7911377Sralph 
8011381Sralph 	argc--;
8111381Sralph 	argv++;
8211381Sralph 	while (argc--) {
8311381Sralph 		if (*(arg = *argv++) != '-')
8411381Sralph 			file[gfil++] = arg;
8511381Sralph 		else switch (*++arg) {
8611381Sralph 		case 'W':	/* Print to wide (versatec) device */
8712435Sslatteng 			DevRange = Wxlen;
8812435Sslatteng 			DevRange8 = Wxlen/8;
8912435Sslatteng 			BytPrLin = Wbytperlin;
9012435Sslatteng 			NumOfLin = Wylen;
9111381Sralph 			lpargs[1] = "-Pversatec";
9211381Sralph 			break;
9311381Sralph 		case 'V':	/* Print to narrow (varian) device */
9412435Sslatteng 			DevRange = Vxlen;
9512435Sslatteng 			DevRange8 = Vxlen/8;
9612435Sslatteng 			BytPrLin = Vbytperlin;
9712435Sslatteng 			NumOfLin = Vylen;
9811381Sralph 			lpargs[1] = "-Pvarian";
9911381Sralph 			break;
10011381Sralph 		case '1':	/* select size 1 */
10111381Sralph 			if (*++arg == '\0' && argc--)
10211381Sralph 				arg = *argv++;
10311381Sralph 			tsize[0] = arg;
10411381Sralph 			break;
10511381Sralph 		case '2':	/* select size 2 */
10611381Sralph 			if (*++arg == '\0' && argc--)
10711381Sralph 				arg = *argv++;
10811381Sralph 			tsize[1] = arg;
10911381Sralph 			break;
11011381Sralph 		case '3':	/* select size 3 */
11111381Sralph 			if (*++arg == '\0' && argc--)
11211381Sralph 				arg = *argv++;
11311381Sralph 			tsize[2] = arg;
11411381Sralph 			break;
11511381Sralph 		case '4':	/* select size 4 */
11611381Sralph 			if (*++arg == '\0' && argc--)
11711381Sralph 				arg = *argv++;
11811381Sralph 			tsize[3] = arg;
11911381Sralph 			break;
12011381Sralph 		case 'R':	/* select Roman font */
12111381Sralph 			if (*++arg == '\0' && argc--)
12211381Sralph 				arg = *argv++;
12311381Sralph 			tfont[0] = arg;
12411381Sralph 			break;
12511381Sralph 		case 'I':	/* select italics font */
12611381Sralph 			if (*++arg == '\0' && argc--)
12711381Sralph 				arg = *argv++;
12811381Sralph 			tfont[1] = arg;
12911381Sralph 			break;
13011381Sralph 		case 'B':	/* select bold font */
13111381Sralph 			if (*++arg == '\0' && argc--)
13211381Sralph 				arg = *argv++;
13311381Sralph 			tfont[2] = arg;
13411381Sralph 			break;
13511381Sralph 		case 'S':	/* select special font */
13611381Sralph 			if (*++arg == '\0' && argc--)
13711381Sralph 				arg = *argv++;
13811381Sralph 			tfont[3] = arg;
13911381Sralph 			break;
14011381Sralph 		case 'N':	/* select narrow brush width */
14111381Sralph 			if (*++arg == '\0' && argc--)
14211381Sralph 				arg = *argv++;
14311381Sralph 			(void) sscanf(arg, "%d", &brsh);
14411381Sralph 			thick[0] = thick[1] = thick[3] = thick[4] = brsh;
14511381Sralph 			break;
14611381Sralph 		case 'T':	/* select thick brush width */
14711381Sralph 			if (*++arg == '\0' && argc--)
14811381Sralph 				arg = *argv++;
14911381Sralph 			(void) sscanf(arg, "%d", &brsh);
15011381Sralph 			thick[2] = brsh;
15111381Sralph 			break;
15211381Sralph 		case 'M':	/* select medium brush width */
15311381Sralph 			if (*++arg == '\0' && argc--)
15411381Sralph 				arg = *argv++;
15511381Sralph 			(void) sscanf(arg, "%d", &brsh);
15611381Sralph 			thick[5] = brsh;
15711381Sralph 			break;
15811381Sralph 		case 't':	/* send raster to standard output */
15911381Sralph 			WriteRaster = TRUE;
16011381Sralph 			break;
16111381Sralph 		case 'x':	/* select scale */
16211381Sralph 			if (*++arg == '\0' && argc--)
16311381Sralph 				arg = *argv++;
16411381Sralph 			sscanf(arg,"%f", &mult);
16511381Sralph 			scale *= mult;
16611381Sralph 			break;
16711381Sralph 		case 'p':	/* prompt for font and size parameters */
16811381Sralph 			printf("Roman font name? (%s): ", tfont[0]);
16911381Sralph 			gets(string1);
17011381Sralph 			if (*string1 != '\0') tfont[0] = string1;
17111381Sralph 			printf("Italic font name? (%s): ", tfont[1]);
17211381Sralph 			gets(string2);
17311381Sralph 			if (*string2 != '\0') tfont[1] = string2;
17411381Sralph 			printf("Bold font name? (%s): ", tfont[2]);
17511381Sralph 			gets(string3);
17611381Sralph 			if (*string3 != '\0') tfont[2] = string3;
17711381Sralph 			printf("Special font name? (%s): ", tfont[3]);
17811381Sralph 			gets(string4);
17911381Sralph 			if (*string4 != '\0') tfont[3] = string4;
18011381Sralph 			printf("font size 1? (%s): ", tsize[0]);
18111381Sralph 			gets(string5);
18211381Sralph 			if (*string5 != '\0') tsize[0] = string5;
18311381Sralph 			printf("font size 2? (%s): ", tsize[1]);
18411381Sralph 			gets(string6);
18511381Sralph 			if (*string6 != '\0') tsize[1] = string6;
18611381Sralph 			printf("font size 3? (%s): ", tsize[2]);
18711381Sralph 			gets(string7);
18811381Sralph 			if (*string7 != '\0') tsize[2] = string7;
18911381Sralph 			printf("font size 4? (%s): ", tsize[3]);
19011381Sralph 			gets(string8);
19111381Sralph 			if (*string8 != '\0') tsize[3] = string8;
19211381Sralph 			printf("narrow brush size? (%d): ", thick[0]);
19311381Sralph 			gets(string);
19411381Sralph 			if (*string != '\0') {
19513172Sslatteng 			    sscanf(string, "%d", &brsh);
19613172Sslatteng 			    thick[0] = thick[1] = thick[3] = thick[4] = brsh;
19711381Sralph 			}
19811381Sralph 			printf("medium brush size? (%d): ", thick[5]);
19911381Sralph 			gets(string);
20011381Sralph 			if (*string != '\0') {
20113172Sslatteng 			    sscanf(string, "%d", &brsh);
20213172Sslatteng 			    thick[5] = brsh;
20311381Sralph 			}
20411381Sralph 			printf("thick brush size? (%d): ", thick[2]);
20511381Sralph 			gets(string);
20611381Sralph 			if (*string != '\0') {
20713172Sslatteng 			    sscanf(string, "%d", &brsh);
20813172Sslatteng 			    thick[2] = brsh;
20911381Sralph 			}
21011381Sralph 			break;
21111381Sralph 		default:
21212435Sslatteng 			fprintf(stderr, "unknown switch: %c\n", *arg);
21311381Sralph 		}
21411381Sralph 	}
21511377Sralph 
21613172Sslatteng 	if (WriteRaster) {		/* over-ride dimension settings */
21713172Sslatteng 		DevRange = Vxlen;	/* if printing to file to be gdumped */
21813172Sslatteng 		DevRange8 = Vxlen/8;
21913268Sslatteng 		BytPrLin = DevRange8;
22013172Sslatteng 	}
22113172Sslatteng 
22211381Sralph 	signal(SIGTERM, cleanup);
22311381Sralph 	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
22411381Sralph 		signal(SIGINT, cleanup);
22511381Sralph 	mktemp(picture);
22612435Sslatteng 	if ((obuf = malloc(bufsize = NumOfLin * DevRange8)) == NULL) {
22713172Sslatteng 		fprintf(stderr,"gprint: ran out of memory for output buffer\n");
22811577Sralph 		exit(1);
22911577Sralph 	}
23011381Sralph 	if (gfil == 0) {	/* no filename, use standard input */
23111381Sralph 		file[0] = NULL;
23211381Sralph 		gfil++;
23311381Sralph 	}
23411381Sralph 	for (k=0; k<gfil; k++) {
23511381Sralph 		if (file[k] != NULL) {
23611381Sralph 			if ((fp = fopen(file[k], "r")) == NULL) {
23713172Sslatteng 			    fprintf(stderr, "gprint: can't open %s\n", file[k]);
23813172Sslatteng 			    continue;
23911381Sralph 			}
24011381Sralph 			if (k == 0) {
24111381Sralph 				if ((arg = rindex(file[k], '/')) == NULL)
24211381Sralph 					arg = file[k];
24311381Sralph 				else
24411381Sralph 					arg++;
24511381Sralph 				lpargs[lparg++] = arg;
24611381Sralph 			}
24711381Sralph 		} else {
24811381Sralph 			fp = stdin;
24911381Sralph 			lpargs[lparg++] = "gremlin";
25011381Sralph 		}
25111381Sralph 		/* read picture file */
25211381Sralph 		PICTURE = DBRead(fp, &Orientation, &pos);
25311577Sralph 		fclose(fp);
25411381Sralph 		if (DBNullelt(PICTURE))
25511381Sralph 			continue;
25611377Sralph 
25711577Sralph 		if (!WriteRaster) {
25811793Sralph 			umask(022);
25911577Sralph 			if ((pfp = fopen(picture, "w")) == NULL) {
26013172Sslatteng 			    fprintf(stderr,"gprint: can't create %s\n",picture);
26113172Sslatteng 			    cleanup();
26211577Sralph 			}
26311381Sralph 		}
26411381Sralph 		i = strlen(picture) + 1;
26511381Sralph 		if ((arg = malloc(i)) == NULL) {
26611381Sralph 			fprintf(stderr, "gprint: ran out of memory\n");
26711381Sralph 			cleanup();
26811381Sralph 		}
26911381Sralph 		strcpy(arg, picture);
27011381Sralph 		lpargs[lparg++] = arg;
27111381Sralph 		picture[run]++;
27211577Sralph 		cp2 = &obuf[bufsize];
27311577Sralph 		for (cp1 = obuf; cp1 < cp2; )
27411577Sralph 			*cp1++ = 0;
27511381Sralph 		e = PICTURE;
27611381Sralph 		while (!DBNullelt(e)) {
27713172Sslatteng 			HGPrintElt(e);	/* traverse picture;  print elements */
27811381Sralph 			e = DBNextElt(e);
27911381Sralph 		}
28013268Sslatteng 		if (WriteRaster)	/* if -t then cut image length */
28113268Sslatteng 		    while (!*--cp2);
28213268Sslatteng 		for (cp1 = obuf; cp1 < cp2; ) {			/* write file */
28311793Sralph 			for (i = DevRange8; i--; cp1++)
28411793Sralph 				putc(*cp1, pfp);
28512435Sslatteng 			for (i = BytPrLin - DevRange8; i--; )
28611793Sralph 				putc('\0', pfp);
28711381Sralph 		}
28811577Sralph 		if (!WriteRaster)
28911577Sralph 			fclose(pfp);
29011381Sralph 	}
29111381Sralph 	if (!WriteRaster) {
29211381Sralph 		lpargs[lparg] = 0;
29311381Sralph 		execv(LPR, lpargs);
29411381Sralph 		fprintf(stderr, "gprint: can't exec %s\n", LPR);
29511381Sralph 		cleanup();
29611381Sralph 	}
29711381Sralph 	exit(0);
29811377Sralph }
29911377Sralph 
cleanup()30011381Sralph cleanup()
30111377Sralph {
30211793Sralph 	do
30311381Sralph 		unlink(picture);
30411793Sralph 	while (picture[run]-- != 'A');
30511381Sralph 	exit(1);
30611377Sralph }
30711377Sralph 
30811381Sralph /*
30912435Sslatteng  * Points should be in the range 0 <= x < DevRange, 0 <= y < NumOfLin.
31011381Sralph  * The origin is the top left-hand corner with increasing x towards the
31111381Sralph  * right and increasing y going down.
31212435Sslatteng  * The output array is NumOfLin x DevRange/8 pixels.
31311381Sralph  */
point(x,y)31411377Sralph point(x, y)
31511381Sralph register int x, y;
31611377Sralph {
31711577Sralph 	register unsigned byte;
31811377Sralph 
31912435Sslatteng 	if ((unsigned) x < DevRange && (unsigned) y < NumOfLin) {
32011793Sralph 		byte = y * DevRange8 + (x >> 3);
32111577Sralph 		obuf[byte] |= 1 << (7 - (x & 07));
32212435Sslatteng 	}
32311377Sralph }
324