1 /* main.c	1.8	83/07/06
2  *
3  * Copyright -C- 1982 Barry S. Roitblat
4  *
5  *	This file contains the main and file system dependent routines
6  * for producing hard copy from gremlin files.  It is extensively modified
7  * from the vplot source.
8  */
9 
10 #include "gprint.h"
11 #include <signal.h>
12 #include <vfont.h>
13 
14 #define LPR "/usr/ucb/lpr"
15 
16 extern char *mktemp();
17 extern char *malloc();
18 extern char *rindex();
19 
20 /* imports */
21 extern HGtline(), HGArc(), HGPutText(), HGMove(), HGSetFont();
22 extern HGSetBrush(), HGInitFont(), HGPrintElt();
23 extern int style[], thick[];
24 extern char *tfont[], *tsize[];
25 
26 /* database imports */
27 
28 extern ELT *DBInit(), *DBRead();
29 extern POINT *PTInit(), *PTMakePoint();
30 
31 int	linethickness = 0;	/* brush styles */
32 int	linmod = SOLID;
33 char	*obuf;			/* output buffer NumOfLin x DevRange/8 */
34 int	bufsize;		/* output buffer size */
35 int	lastx;
36 int	lasty;
37 int	angle, startx, starty, endx, endy;
38 double	scale = 4.0;		/* Variables used to map gremlin screen */
39 double	orgx = 0.0;		/* x and y origin of gremlin picture */
40 double	orgy = 0.0;
41 
42 FILE	*pfp = stdout;		/* file descriptor of current picture */
43 char	picture[] = "/usr/tmp/rastAXXXXXX";
44 int	run = 13;		/* index of 'a' in picture[] */
45 int	DevRange = Vxlen;	/* plot dimensions in pixels */
46 int	DevRange8 = Vxlen/8;
47 int	BytPrLin = Vbytperlin;	/* Bytes per raster line. (not DevRange8) */
48 int	NumOfLin = Vylen;
49 
50 int	lparg = 6;		/* index into lpargs */
51 char	*lpargs[50] = { "lpr", "-Pvarian", "-v", "-s", "-r", "-J", };
52 
53 int	Orientation;		/* variables used to print from font file */
54 int	cfont = 0;
55 int	csize = 0;
56 struct	header header;
57 struct	dispatch dispatch[256];
58 char	*bits = NULL;
59 char	*fontdir = "/usr/lib/vfont/";
60 
main(argc,argv)61 main(argc, argv)
62 int argc;
63 char *argv[];
64 {
65 	FILE *fp, *fopen();
66 	ELT *PICTURE, *e;
67 	POINT *p1, pos;
68 	char *file[50], string[10], *arg;
69 	char c, string1[50], string2[50], string3[50], string4[50],
70 		string5[50], string6[50], string7[50], string8[50];
71 	extern int cleanup();
72 	float mult;
73 	int WriteRaster = FALSE;
74 	register char *cp1, *cp2;
75 	register int i, k;
76 	int brsh, gfil = 0;
77 
78 	/* Parse the command line. */
79 
80 	argc--;
81 	argv++;
82 	while (argc--) {
83 		if (*(arg = *argv++) != '-')
84 			file[gfil++] = arg;
85 		else switch (*++arg) {
86 		case 'W':	/* Print to wide (versatec) device */
87 			DevRange = Wxlen;
88 			DevRange8 = Wxlen/8;
89 			BytPrLin = Wbytperlin;
90 			NumOfLin = Wylen;
91 			lpargs[1] = "-Pversatec";
92 			break;
93 		case 'V':	/* Print to narrow (varian) device */
94 			DevRange = Vxlen;
95 			DevRange8 = Vxlen/8;
96 			BytPrLin = Vbytperlin;
97 			NumOfLin = Vylen;
98 			lpargs[1] = "-Pvarian";
99 			break;
100 		case '1':	/* select size 1 */
101 			if (*++arg == '\0' && argc--)
102 				arg = *argv++;
103 			tsize[0] = arg;
104 			break;
105 		case '2':	/* select size 2 */
106 			if (*++arg == '\0' && argc--)
107 				arg = *argv++;
108 			tsize[1] = arg;
109 			break;
110 		case '3':	/* select size 3 */
111 			if (*++arg == '\0' && argc--)
112 				arg = *argv++;
113 			tsize[2] = arg;
114 			break;
115 		case '4':	/* select size 4 */
116 			if (*++arg == '\0' && argc--)
117 				arg = *argv++;
118 			tsize[3] = arg;
119 			break;
120 		case 'R':	/* select Roman font */
121 			if (*++arg == '\0' && argc--)
122 				arg = *argv++;
123 			tfont[0] = arg;
124 			break;
125 		case 'I':	/* select italics font */
126 			if (*++arg == '\0' && argc--)
127 				arg = *argv++;
128 			tfont[1] = arg;
129 			break;
130 		case 'B':	/* select bold font */
131 			if (*++arg == '\0' && argc--)
132 				arg = *argv++;
133 			tfont[2] = arg;
134 			break;
135 		case 'S':	/* select special font */
136 			if (*++arg == '\0' && argc--)
137 				arg = *argv++;
138 			tfont[3] = arg;
139 			break;
140 		case 'N':	/* select narrow brush width */
141 			if (*++arg == '\0' && argc--)
142 				arg = *argv++;
143 			(void) sscanf(arg, "%d", &brsh);
144 			thick[0] = thick[1] = thick[3] = thick[4] = brsh;
145 			break;
146 		case 'T':	/* select thick brush width */
147 			if (*++arg == '\0' && argc--)
148 				arg = *argv++;
149 			(void) sscanf(arg, "%d", &brsh);
150 			thick[2] = brsh;
151 			break;
152 		case 'M':	/* select medium brush width */
153 			if (*++arg == '\0' && argc--)
154 				arg = *argv++;
155 			(void) sscanf(arg, "%d", &brsh);
156 			thick[5] = brsh;
157 			break;
158 		case 't':	/* send raster to standard output */
159 			WriteRaster = TRUE;
160 			break;
161 		case 'x':	/* select scale */
162 			if (*++arg == '\0' && argc--)
163 				arg = *argv++;
164 			sscanf(arg,"%f", &mult);
165 			scale *= mult;
166 			break;
167 		case 'p':	/* prompt for font and size parameters */
168 			printf("Roman font name? (%s): ", tfont[0]);
169 			gets(string1);
170 			if (*string1 != '\0') tfont[0] = string1;
171 			printf("Italic font name? (%s): ", tfont[1]);
172 			gets(string2);
173 			if (*string2 != '\0') tfont[1] = string2;
174 			printf("Bold font name? (%s): ", tfont[2]);
175 			gets(string3);
176 			if (*string3 != '\0') tfont[2] = string3;
177 			printf("Special font name? (%s): ", tfont[3]);
178 			gets(string4);
179 			if (*string4 != '\0') tfont[3] = string4;
180 			printf("font size 1? (%s): ", tsize[0]);
181 			gets(string5);
182 			if (*string5 != '\0') tsize[0] = string5;
183 			printf("font size 2? (%s): ", tsize[1]);
184 			gets(string6);
185 			if (*string6 != '\0') tsize[1] = string6;
186 			printf("font size 3? (%s): ", tsize[2]);
187 			gets(string7);
188 			if (*string7 != '\0') tsize[2] = string7;
189 			printf("font size 4? (%s): ", tsize[3]);
190 			gets(string8);
191 			if (*string8 != '\0') tsize[3] = string8;
192 			printf("narrow brush size? (%d): ", thick[0]);
193 			gets(string);
194 			if (*string != '\0') {
195 			    sscanf(string, "%d", &brsh);
196 			    thick[0] = thick[1] = thick[3] = thick[4] = brsh;
197 			}
198 			printf("medium brush size? (%d): ", thick[5]);
199 			gets(string);
200 			if (*string != '\0') {
201 			    sscanf(string, "%d", &brsh);
202 			    thick[5] = brsh;
203 			}
204 			printf("thick brush size? (%d): ", thick[2]);
205 			gets(string);
206 			if (*string != '\0') {
207 			    sscanf(string, "%d", &brsh);
208 			    thick[2] = brsh;
209 			}
210 			break;
211 		default:
212 			fprintf(stderr, "unknown switch: %c\n", *arg);
213 		}
214 	}
215 
216 	if (WriteRaster) {		/* over-ride dimension settings */
217 		DevRange = Vxlen;	/* if printing to file to be gdumped */
218 		DevRange8 = Vxlen/8;
219 		BytPrLin = DevRange8;
220 	}
221 
222 	signal(SIGTERM, cleanup);
223 	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
224 		signal(SIGINT, cleanup);
225 	mktemp(picture);
226 	if ((obuf = malloc(bufsize = NumOfLin * DevRange8)) == NULL) {
227 		fprintf(stderr,"gprint: ran out of memory for output buffer\n");
228 		exit(1);
229 	}
230 	if (gfil == 0) {	/* no filename, use standard input */
231 		file[0] = NULL;
232 		gfil++;
233 	}
234 	for (k=0; k<gfil; k++) {
235 		if (file[k] != NULL) {
236 			if ((fp = fopen(file[k], "r")) == NULL) {
237 			    fprintf(stderr, "gprint: can't open %s\n", file[k]);
238 			    continue;
239 			}
240 			if (k == 0) {
241 				if ((arg = rindex(file[k], '/')) == NULL)
242 					arg = file[k];
243 				else
244 					arg++;
245 				lpargs[lparg++] = arg;
246 			}
247 		} else {
248 			fp = stdin;
249 			lpargs[lparg++] = "gremlin";
250 		}
251 		/* read picture file */
252 		PICTURE = DBRead(fp, &Orientation, &pos);
253 		fclose(fp);
254 		if (DBNullelt(PICTURE))
255 			continue;
256 
257 		if (!WriteRaster) {
258 			umask(022);
259 			if ((pfp = fopen(picture, "w")) == NULL) {
260 			    fprintf(stderr,"gprint: can't create %s\n",picture);
261 			    cleanup();
262 			}
263 		}
264 		i = strlen(picture) + 1;
265 		if ((arg = malloc(i)) == NULL) {
266 			fprintf(stderr, "gprint: ran out of memory\n");
267 			cleanup();
268 		}
269 		strcpy(arg, picture);
270 		lpargs[lparg++] = arg;
271 		picture[run]++;
272 		cp2 = &obuf[bufsize];
273 		for (cp1 = obuf; cp1 < cp2; )
274 			*cp1++ = 0;
275 		e = PICTURE;
276 		while (!DBNullelt(e)) {
277 			HGPrintElt(e);	/* traverse picture;  print elements */
278 			e = DBNextElt(e);
279 		}
280 		if (WriteRaster)	/* if -t then cut image length */
281 		    while (!*--cp2);
282 		for (cp1 = obuf; cp1 < cp2; ) {			/* write file */
283 			for (i = DevRange8; i--; cp1++)
284 				putc(*cp1, pfp);
285 			for (i = BytPrLin - DevRange8; i--; )
286 				putc('\0', pfp);
287 		}
288 		if (!WriteRaster)
289 			fclose(pfp);
290 	}
291 	if (!WriteRaster) {
292 		lpargs[lparg] = 0;
293 		execv(LPR, lpargs);
294 		fprintf(stderr, "gprint: can't exec %s\n", LPR);
295 		cleanup();
296 	}
297 	exit(0);
298 }
299 
cleanup()300 cleanup()
301 {
302 	do
303 		unlink(picture);
304 	while (picture[run]-- != 'A');
305 	exit(1);
306 }
307 
308 /*
309  * Points should be in the range 0 <= x < DevRange, 0 <= y < NumOfLin.
310  * The origin is the top left-hand corner with increasing x towards the
311  * right and increasing y going down.
312  * The output array is NumOfLin x DevRange/8 pixels.
313  */
point(x,y)314 point(x, y)
315 register int x, y;
316 {
317 	register unsigned byte;
318 
319 	if ((unsigned) x < DevRange && (unsigned) y < NumOfLin) {
320 		byte = y * DevRange8 + (x >> 3);
321 		obuf[byte] |= 1 << (7 - (x & 07));
322 	}
323 }
324