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