1 /* main.c 1.24 (Berkeley) 86/04/14 2 * 3 * This file contains the main and file system dependent routines 4 * for processing gremlin files into troff input. The program watches 5 * input go by to standard output, only interpretting things between .GS 6 * and .GE lines. Default values (font, size, scale, thickness) may be 7 * overridden with a "default" command and are further overridden by 8 * commands in the input. A description of the command-line options are 9 * listed below. A space is NOT required for the operand of an option. 10 * 11 * command options are: 12 * 13 * -L dir set the library directory to dir. If a file is not found 14 * in the current directory, it is looked for in dir (default 15 * is /usr/lib/gremlib). 16 * 17 * -T dev Prepare output for "dev" printer. Default is for the varian 18 * -P dev and versatec printers. Devices acceptable are: ver, var, ip. 19 * 20 * Inside the GS and GE, commands are accepted to reconfigure 21 * the picture. At most one command may reside on each line, and 22 * each command is followed by a parameter separated by white space. 23 * The commands are as follows, and may be abbreviated down to one 24 * character (with exception of "scale" and "stipple" down to "sc" 25 * and "st") and may be upper or lower case. 26 * 27 * default - make all settings in the current 28 * .GS/.GE the global defaults. 29 * Height, width and file are NOT saved. 30 * 1, 2, 3, 4 - set size 1, 2, 3, or 4 (followed 31 * by an integer point size). 32 * roman, italics, bold, special - set gremlin's fonts to any other 33 * troff font (one or two characters) 34 * stipple, l - use a stipple font for polygons. Arg 35 * is troff font name. No Default. Can 36 * use only one stipple font per picture. 37 * (see below for stipple font index) 38 * scale, x - scale is IN ADDITION to the global 39 * scale factor from the default. 40 * pointscale - turn on scaling point sizes to 41 * match "scale" commands. (optional 42 * operand "off" to turn it off) 43 * narrow, medium, thick - set pixel widths of lines. 44 * file - set the file name to read the 45 * gremlin picture from. If the file 46 * isn't in the current directory, the 47 * gremlin library is tried. 48 * width, height - these two commands override any 49 * scaling factor that is in effect, 50 * and forces the picture to fit into 51 * either the height or width specified, 52 * whichever makes the picture smaller. 53 * The operand for these two commands is 54 * a floating-point number in units of 55 * inches 56 * oldstipplemap - use the old-style stipple mapping. 57 * THE FOLLOWING COMMANDS ARE IGNORED 58 * UNLESS OLDSTIPPLEMAP IS SPECIFIED. 59 * l1, l2, l3, l4, l5, l6, l7, l8 - set association between stipples 60 * (1 - 8) and the stipple font file 61 * index. Valid cifplot indices are 62 * 1 - 32 (although 24 is not defined) 63 * and valid unigrafix indices are 64 * 1 - 64. Nonetheless, any number 65 * between 0 and 255 is accepted since 66 * new stipple fonts may be added. 67 * An integer operand is required. 68 * 69 * Troff number registers used: g1 through g9. g1 is the width of the 70 * picture, and g2 is the height. g3, and g4, save information, g8 71 * and g9 are used for text processing and g5-g7 are reserved. 72 */ 73 74 75 #include <ctype.h> 76 #include "gprint.h" 77 #include "dev.h" 78 79 extern char *malloc(); 80 extern char *rindex(); 81 82 /* database imports */ 83 84 extern HGPrintElt(); 85 extern ELT *DBInit(), *DBRead(); 86 extern POINT *PTInit(), *PTMakePoint(); 87 88 89 #ifndef GREMLIB 90 #define GREMLIB "/usr/local/gremlib/" 91 #endif 92 93 #define SUN_SCALEFACTOR 0.70 94 95 #ifndef DEVDIR 96 #define DEVDIR "/usr/lib/font" 97 #endif 98 #define DEFAULTDEV "va" 99 #define DEFSTIPPLE "cf" 100 101 #define MAXINLINE 100 /* input line length */ 102 #define DEFTHICK 3 /* default thicknes */ 103 #define DEFSTYLE SOLID /* default line style */ 104 105 #ifdef oldversion 106 #define SCREENtoINCH 0.02 /* scaling factor, screen to inches */ 107 #endif 108 109 double SCREENtoINCH; /* scaling factor, screen to inches */ 110 111 #define BIG 999999999999.0 /* unweildly large floating number */ 112 113 114 static char sccsid[] = "@(#) (Berkeley) 04/14/86"; 115 116 char *printer = DEFAULTDEV; /* device to look up resolution of */ 117 char *gremlib = GREMLIB; /* place to find files after current dir. */ 118 double res; /* that printer's resolution goes here */ 119 120 int linethickness; /* brush styles */ 121 int linmod; 122 int lastx; /* point registers for printing elements */ 123 int lasty; 124 int lastyline; /* a line's vertical position is NOT the same */ 125 /* after that line is over, so for a line of */ 126 /* drawing commands, vertical spacing is kept */ 127 /* in lastyline */ 128 129 /* these are the default fonts, sizes, line styles, */ 130 /* and thicknesses. These can be modified from a */ 131 /* "default" command and are reset each time the */ 132 /* start of a picture (.GS) is found. */ 133 134 char * deffont[] = { "R", "I", "B", "S" }; 135 int defsize[] = { 10, 16, 24, 36 }; 136 int defthick[STYLES] = { 1, 1, 5, 1, 1, 3 }; 137 int defstipple_index[NSTIPPLES] = { 1, 3, 12, 14, 16, 19, 21, 23 }; 138 int style[STYLES] = { DOTTED, DOTDASHED, SOLID, DASHED, SOLID, SOLID }; 139 double scale = 1.0; /* no scaling, default */ 140 int defpoint = 0; /* flag for pointsize scaling */ 141 char * defstipple = (char *) 0; 142 143 int thick[STYLES]; /* thicknesses set by defaults, then by commands */ 144 char *tfont[FONTS]; /* fonts originally set to deffont values, then */ 145 int tsize[SIZES]; /* optionally changed by commands inside grn */ 146 int stipple_index[NSTIPPLES]; /* stipple font file indices */ 147 char * stipple; 148 149 double xscale; /* scaling factor from individual pictures */ 150 double troffscale; /* scaling factor at output time */ 151 double width; /* user-request maximum width for picture (in inches) */ 152 double height; /* user-request height */ 153 int pointscale; /* flag for pointsize scaling */ 154 int setdefault; /* flag for a .GS/.GE to remember all settings */ 155 156 double toppoint; /* remember the picture */ 157 double bottompoint; /* bounds in these variables */ 158 double leftpoint; 159 double rightpoint; 160 161 int ytop; /* these are integer versions of the above */ 162 int ybottom; /* so not to convert each time they're used */ 163 int xleft; 164 int xright; 165 166 int linenum = 0; /* line number of input file */ 167 char inputline[MAXINLINE]; /* spot to filter through the file */ 168 char *c1 = inputline; /* c1, c2, and c3 will be used to */ 169 char *c2 = inputline + 1; /* hunt for lines that begin with */ 170 char *c3 = inputline + 2; /* ".GS" by looking individually */ 171 char GScommand[MAXINLINE]; /* put user's ".GS" command line here */ 172 char gremlinfile[MAXINLINE]; /* filename to use for a picture */ 173 int SUNFILE = FALSE; /* TRUE if SUN gremlin file */ 174 int oldstipmap = FALSE; /* TRUE if old-style stipple mapping */ 175 176 char *doinput(); 177 178 179 /*----------------------------------------------------------------------------* 180 | Routine: main (argument_count, argument_pointer) 181 | 182 | Results: parses the command line, accumulating input file names, then 183 | reads the inputs, passing it directly to output until a ".GS" 184 | line is read. Main then passes control to "conv" to do the 185 | gremlin file conversions. 186 *----------------------------------------------------------------------------*/ 187 188 main(argc, argv) 189 int argc; 190 char **argv; 191 { 192 register FILE *fp; 193 register int k; 194 register char c; 195 register gfil = 0; 196 char *file[50]; 197 198 char *operand(); 199 char *getenv(); 200 201 202 if (fp = (FILE *) getenv("PRINTER")) printer = (char *) fp; 203 if (fp = (FILE *) getenv("TYPESETTER")) printer = (char *) fp; 204 while (--argc) { 205 if (**++argv != '-') 206 file[gfil++] = *argv; 207 else 208 switch (c = (*argv)[1]) { 209 210 case 0: 211 file[gfil++] = NULL; 212 break; 213 214 case 'P': 215 case 'T': /* final output typesetter name */ 216 printer = operand(&argc, &argv); 217 break; 218 219 case 'L': /* set library directory */ 220 gremlib = operand(&argc, &argv); 221 break; 222 223 default: 224 error("unknown switch: %c", c); 225 } 226 } 227 /* set the resolution for an output device */ 228 getres(printer); /* named in "printer" */ 229 230 if (gfil == 0) { /* no filename, use standard input */ 231 file[0] = NULL; 232 gfil++; 233 } 234 235 for (k=0; k<gfil; k++) { 236 if (file[k] != NULL) { 237 if ((fp = fopen(file[k], "r")) == NULL) { 238 error("can't open %s", file[k]); 239 exit(1); 240 } 241 } else { 242 fp = stdin; 243 } 244 245 while (doinput(fp) != NULL) { 246 if (*c1 == '.' && *c2 == 'G' && *c3 == 'S') { 247 conv(fp, linenum); 248 } else { 249 fputs(inputline, stdout); 250 } 251 } 252 } 253 } 254 255 256 /*----------------------------------------------------------------------------* 257 | Routine: error (control_string, args, . . . ) 258 | 259 | Results: prints ("grn: ", the control_string + args, "\n") to stderr 260 *----------------------------------------------------------------------------*/ 261 262 /* VARARGS1 */ 263 error(s, a1, a2, a3, a4) 264 char * s; 265 { 266 fprintf(stderr, "grn: "); 267 fprintf(stderr, s, a1, a2, a3, a4); 268 fprintf(stderr, "\n"); 269 } 270 271 272 /*----------------------------------------------------------------------------* 273 | Routine: char * operand (& argc, & argv) 274 | 275 | Results: returns address of the operand given with a command-line 276 | option. It uses either "-Xoperand" or "-X operand", whichever 277 | is present. The program is terminated if no option is present. 278 | 279 | Side Efct: argc and argv are updated as necessary. 280 *----------------------------------------------------------------------------*/ 281 282 char *operand(argcp, argvp) 283 int * argcp; 284 char ***argvp; 285 { 286 if ((**argvp)[2]) return(**argvp + 2); /* operand immediately follows */ 287 if ((--*argcp) <= 0) { /* no operand */ 288 error("command-line option operand missing."); 289 exit(8); 290 } 291 return(*(++(*argvp))); /* operand is next word */ 292 } 293 294 295 /*----------------------------------------------------------------------------* 296 | Routine: getres (device_name) 297 | 298 | Results: sets "res" to the resolution of the output device specified 299 | by the string dev. 300 *----------------------------------------------------------------------------*/ 301 302 getres(name) 303 char *name; 304 { 305 int fin; 306 struct dev device; 307 char temp[60]; 308 309 sprintf(temp, "%s/dev%s/DESC.out", DEVDIR, name); 310 if ((fin = open(temp, 0)) < 0) { 311 error("can't open tables for %s", temp); 312 exit(1); 313 } 314 read(fin, &device, sizeof(struct dev)); 315 res = (double) device.res; 316 close(fin); 317 } 318 319 320 /*----------------------------------------------------------------------------* 321 | Routine: char * doinput (file_pointer) 322 | 323 | Results: a line of input is read into "inputline". 324 | 325 | Side Efct: "linenum" is incremented. 326 | 327 | Bugs: lines longer than MAXINLINE are NOT checked, except for 328 | updating "linenum" 329 *----------------------------------------------------------------------------*/ 330 331 char *doinput(fp) 332 FILE *fp; 333 { 334 char *k; 335 336 337 if ((k = fgets(inputline, MAXINLINE, fp)) == NULL) 338 return k; 339 if (index (inputline, '\n')) /* ++ only if it's a complete line */ 340 linenum++; 341 return (char*) !NULL; 342 } 343 344 345 /*----------------------------------------------------------------------------* 346 | Routine: initpic ( ) 347 | 348 | Results: sets all parameters to the normal defaults, possibly overridden 349 | by a setdefault command. Initilaize the picture variables, 350 | and output the startup commands to troff to begin the picture. 351 *----------------------------------------------------------------------------*/ 352 353 initpic() 354 { 355 register int i; 356 357 for (i = 0; i < STYLES; i++) { /* line thickness defaults */ 358 thick[i] = defthick[i]; 359 } 360 for (i = 0; i < FONTS; i++) { /* font name defaults */ 361 tfont[i] = deffont[i]; 362 } 363 for (i = 0; i < SIZES; i++) { /* font size defaults */ 364 tsize[i] = defsize[i]; 365 } 366 for (i = 0; i < NSTIPPLES; i++) { /* stipple font file default indices */ 367 stipple_index[i] = defstipple_index[i]; 368 } 369 stipple = defstipple; 370 371 gremlinfile[0] = 0; /* filename is "null" */ 372 setdefault = 0; /* this is not the default settings (yet) */ 373 374 toppoint = BIG; /* set the picture bounds out */ 375 bottompoint = -BIG; /* of range so they'll be set */ 376 leftpoint = BIG; /* by "savebounds" on input */ 377 rightpoint = -BIG; 378 379 pointscale = defpoint; /* Flag for scaling point sizes default. */ 380 xscale = scale; /* default scale of individual pictures */ 381 width = 0.0; /* size specifications input by user */ 382 height = 0.0; 383 384 linethickness = DEFTHICK; /* brush styles */ 385 linmod = DEFSTYLE; 386 } 387 388 389 /*----------------------------------------------------------------------------* 390 | Routine: conv (file_pointer, starting_line) 391 | 392 | Results: at this point, we just passed a ".GS" line in the input file. 393 | conv reads the input and calls "interpret" to process commands, 394 | gathering up information until a ".GE" line is found. It then 395 | calls "HGPrint" to do the translation of the gremlin file to 396 | troff commands. 397 *----------------------------------------------------------------------------*/ 398 399 conv(fp, baseline) 400 register FILE *fp; 401 int baseline; 402 { 403 register FILE *gfp = NULL; /* input file pointer */ 404 register int done = 0; /* flag to remember if finished */ 405 register ELT *e; /* current element pointer */ 406 ELT *PICTURE; /* whole picture data base pointer */ 407 double temp; /* temporary calculating area */ 408 POINT ptr; /* coordinates of a point to pass to "mov" routine */ 409 int flyback; /* flag "want to end up at the top of the picture?" */ 410 411 412 initpic(); /* set defaults, ranges, etc. */ 413 strcpy (GScommand, inputline); /* save ".GS" line for later */ 414 do { 415 done = (doinput(fp) == NULL); /* test for EOF */ 416 flyback = *c3 == 'F'; /* and .GE or .GF */ 417 done |= (*c1 == '.' && *c2 == 'G' && (*c3 == 'E' || flyback)); 418 419 if (done) { 420 if (setdefault) savestate(); 421 422 if (!gremlinfile[0]) { 423 if(!setdefault) 424 error("at line %d: no picture filename.\n", baseline); 425 return; 426 } 427 if ((gfp = fopen(gremlinfile, "r")) == NULL) { 428 char name[MAXINLINE]; /* if the file isn't in the current */ 429 /* directory, try the gremlin library */ 430 sprintf(name, "%s%s", gremlib, gremlinfile); 431 if ((gfp = fopen(name, "r")) == NULL) { 432 error("can't open %s", gremlinfile); 433 return; 434 } 435 } 436 PICTURE = DBRead(gfp); /* read picture file */ 437 fclose(gfp); 438 if (DBNullelt(PICTURE)) 439 return; /* if a request is made to make the */ 440 /* picture fit into a specific area, */ 441 /* set the scale to do that. */ 442 443 SCREENtoINCH = (SUNFILE) ? 0.014 : 0.02; 444 445 if (stipple == (char *) NULL) /* if user forgot stipple */ 446 if (has_polygon(PICTURE)) /* and picture has a polygon */ 447 stipple = DEFSTIPPLE; /* then set the default */ 448 449 if ((temp = bottompoint - toppoint) < 0.1) temp = 0.1; 450 temp = (height != 0.0) ? height / (temp * SCREENtoINCH) : BIG; 451 if ((troffscale = rightpoint - leftpoint) < 0.1) troffscale=0.1; 452 troffscale = (width != 0.0) ? 453 width / (troffscale * SCREENtoINCH) : BIG; 454 if (temp == BIG && troffscale == BIG) { 455 troffscale = xscale; 456 } else { 457 if (temp < troffscale) troffscale = temp; 458 } /* here, troffscale is the */ 459 /* picture's scaling factor */ 460 if (pointscale) { 461 register int i; /* do pointscaling here, when */ 462 /* scale is known, before output */ 463 464 for (i = 0; i < SIZES; i++) 465 tsize[i] = (int) (troffscale * (double) tsize[i] + 0.5); 466 467 } 468 /* change to device units */ 469 troffscale *= SCREENtoINCH * res; /* from screen units */ 470 471 ytop = toppoint * troffscale; /* calculate integer */ 472 ybottom = bottompoint * troffscale; /* versions of the */ 473 xleft = leftpoint * troffscale; /* picture limits */ 474 xright = rightpoint * troffscale; 475 /* save stuff in number registers, */ 476 /* register g1 = picture width and */ 477 /* register g2 = picture height, */ 478 /* set vertical spacing, no fill, */ 479 /* and break (to make sure picture */ 480 /* starts on left), and put out the */ 481 /* user's ".GS" line. */ 482 printf( 483 ".br\n.nr g1 %du\n.nr g2 %du\n%s.nr g3 \\n(.f\n.nr g4 \\n(.s\n\\0\n.sp -1\n", 484 xright-xleft, ybottom-ytop, GScommand); 485 486 if (stipple) { /* stipple requested for this picture */ 487 printf(".st %s\n", stipple); 488 } 489 490 lastx = xleft; /* note where we are, (upper left */ 491 lastyline = lasty = ytop; /* corner of the picture) */ 492 493 e = PICTURE; 494 while (!DBNullelt(e)) { /* traverse picture; print elements */ 495 HGPrintElt(e, baseline); 496 e = DBNextElt(e); 497 } 498 /* decide where to end picture */ 499 if (flyback) { /* end piture at upper left */ 500 ptr.x = leftpoint; 501 ptr.y = toppoint; 502 } else { /* end picture at lower left */ 503 ptr.x = leftpoint; 504 ptr.y = bottompoint; 505 } 506 tmove(&ptr); /* restore default line parameters, */ 507 /* restore everything to the way */ 508 /* it was before the .GS, then put */ 509 /* out the ".GE" line from user */ 510 printf("\\D't %du'\\D's %du'\n", DEFTHICK, DEFSTYLE); 511 if (flyback) { /* make sure we end up at top of */ 512 printf(".sp -1\n"); /* picture if "flying back" */ 513 } 514 if (stipple) { /* restore stipple to previous */ 515 printf(".st\n"); 516 } 517 printf(".br\n.ft \\n(g3\n.ps \\n(g4\n%s", inputline); 518 } else { 519 interpret(inputline); /* take commands from the input file */ 520 } 521 } while (!done); 522 } 523 524 525 /*----------------------------------------------------------------------------* 526 | Routine: savestate ( ) 527 | 528 | Results: all the current scaling / font size / font name / thickness / 529 | pointscale settings are saved to be the defaults. Scaled 530 | point sizes are NOT saved. The scaling is done each time a 531 | new picture is started. 532 | 533 | Side Efct: scale, and def* are modified. 534 *----------------------------------------------------------------------------*/ 535 536 savestate() 537 { 538 register int i; 539 540 for (i = 0; i < STYLES; i++) { /* line thickness defaults */ 541 defthick[i] = thick[i]; 542 } 543 for (i = 0; i < FONTS; i++) { /* font name defaults */ 544 deffont[i] = tfont[i]; 545 } 546 for (i = 0; i < SIZES; i++) { /* font size defaults */ 547 defsize[i] = tsize[i]; 548 } 549 for (i = 0; i < NSTIPPLES; i++) { /* stipple font file default indices */ 550 defstipple_index[i] = stipple_index[i]; 551 } 552 defstipple = stipple; /* if stipple has been set, it's remembered */ 553 554 scale *= xscale; /* default scale of individual pictures */ 555 defpoint = pointscale; /* flag for scaling pointsizes from x factors */ 556 } 557 558 559 /*----------------------------------------------------------------------------* 560 | Routine: savebounds (x_coordinate, y_coordinate) 561 | 562 | Results: keeps track of the maximum and minimum extent of a picture 563 | in the global variables: left-, right-, top- and bottompoint. 564 | "savebounds" assumes that the points have been oriented to 565 | the correct direction. No scaling has taken place, though. 566 *----------------------------------------------------------------------------*/ 567 568 savebounds(x, y) 569 float x; 570 float y; 571 { 572 if (x < leftpoint) leftpoint = x; 573 if (x > rightpoint) rightpoint = x; 574 if (y < toppoint) toppoint = y; 575 if (y > bottompoint) bottompoint = y; 576 } 577 578 579 /*----------------------------------------------------------------------------* 580 | Routine: interpret (character_string) 581 | 582 | Results: commands are taken from the input string and performed. 583 | Commands are separated by the endofline, and are of the 584 | format: 585 | string1 string2 586 | 587 | where string1 is the command and string2 is the argument. 588 | 589 | Side Efct: font and size strings, plus the gremlin file name and the 590 | width and height variables are set by this routine. 591 *----------------------------------------------------------------------------*/ 592 593 interpret (line) 594 char *line; 595 { 596 char str1[MAXINLINE]; 597 char str2[MAXINLINE]; 598 register char *chr; 599 register int i; 600 double par; 601 602 str2[0] = '\0'; 603 sscanf(line, "%80s%80s", &str1[0], &str2[0]); 604 for (chr = &str1[0]; *chr; chr++) /* convert command to */ 605 if(isupper(*chr)) *chr = tolower(*chr); /* lower case */ 606 switch (str1[0]) { 607 608 case '1': 609 case '2': /* font sizes */ 610 case '3': 611 case '4': 612 i = atoi(str2); 613 if (i > 0 && i < 1000) 614 tsize[str1[0] - '1'] = i; 615 else 616 error("bad font size value at line %d", linenum); 617 break; 618 619 case 'r': /* roman */ 620 if(str2[0] < '0') goto nofont; 621 tfont[0] = malloc(strlen(str2) + 1); 622 strcpy(tfont[0], str2); 623 break; 624 625 case 'i': /* italics */ 626 if(str2[0] < '0') goto nofont; 627 tfont[1] = malloc(strlen(str2) + 1); 628 strcpy(tfont[1], str2); 629 break; 630 631 case 'b': /* bold */ 632 if(str2[0] < '0') goto nofont; 633 tfont[2] = malloc(strlen(str2) + 1); 634 strcpy(tfont[2], str2); 635 break; 636 637 case 's': /* special */ 638 if (str1[1] == 'c') goto scalecommand; /* or scale */ 639 640 if(str2[0] < '0') { 641 nofont: error("no fontname specified in line %d", linenum); 642 break; 643 } 644 if (str1[1] == 't') goto stipplecommand; /* or stipple */ 645 646 tfont[3] = malloc(strlen(str2) + 1); 647 strcpy(tfont[3], str2); 648 break; 649 650 case 'l': /* l */ 651 if ((str1[1] < '1') || (str1[1] > '8')) 652 goto stipplecommand; 653 654 /* else set stipple index */ 655 i = atoi(str2); 656 if (i >= 0 && i < 256) 657 stipple_index[str1[1] - '1'] = i; 658 else 659 error("bad stipple index value at line %d", linenum); 660 break; 661 662 stipplecommand: /* stipple */ 663 stipple = malloc(strlen(str2) + 1); 664 strcpy(stipple, str2); 665 break; 666 667 case 'o': /* oldstipplemap */ 668 oldstipmap = TRUE; 669 break; 670 671 case 't': /* thick */ 672 thick[2] = atoi(str2); 673 break; 674 675 case 'm': /* medium */ 676 thick[5] = atoi(str2); 677 break; 678 679 case 'n': /* narrow */ 680 thick[0] = thick[1] = thick[3] = thick[4] = atoi(str2); 681 break; 682 683 case 'x': /* x */ 684 scalecommand: /* scale */ 685 par = atof(str2); 686 if (par > 0.0) 687 xscale *= par; 688 else 689 error("illegal scale value on line %d", linenum); 690 break; 691 692 case 'f': /* file */ 693 strcpy(gremlinfile, str2); 694 break; 695 696 case 'w': /* width */ 697 width = atof(str2); 698 if (width < 0.0) width = -width; 699 break; 700 701 case 'h': /* height */ 702 height = atof(str2); 703 if (height < 0.0) height = -height; 704 break; 705 706 case 'd': /* defaults */ 707 setdefault = 1; 708 break; 709 710 case 'p': /* pointscale */ 711 if (strcmp("off", str2)) 712 pointscale = 1; 713 else 714 pointscale = 0; 715 break; 716 717 default: 718 error("unknown command, %s, on line %d", str1, linenum); 719 exit(8); 720 break; 721 }; 722 } 723 724 725 /* 726 * return TRUE if picture contains a polygon 727 * otherwise FALSE 728 */ 729 has_polygon(elist) 730 register ELT *elist; 731 { 732 while (!DBNullelt(elist)) { 733 if (elist->type == POLYGON) 734 return(1); 735 elist = DBNextElt(elist); 736 } 737 738 return(0); 739 } 740