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