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