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 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 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 */ 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