1*27071Sslatteng /* main.c 1.24 (Berkeley) 86/04/14
214057Sslatteng *
314057Sslatteng * This file contains the main and file system dependent routines
414057Sslatteng * for processing gremlin files into troff input. The program watches
514057Sslatteng * input go by to standard output, only interpretting things between .GS
615367Sslatteng * and .GE lines. Default values (font, size, scale, thickness) may be
715367Sslatteng * overridden with a "default" command and are further overridden by
815367Sslatteng * commands in the input. A description of the command-line options are
915367Sslatteng * listed below. A space is NOT required for the operand of an option.
1014057Sslatteng *
1114057Sslatteng * command options are:
1214057Sslatteng *
1315367Sslatteng * -L dir set the library directory to dir. If a file is not found
1415367Sslatteng * in the current directory, it is looked for in dir (default
1515367Sslatteng * is /usr/lib/gremlib).
1614057Sslatteng *
1714817Sslatteng * -T dev Prepare output for "dev" printer. Default is for the varian
1815367Sslatteng * -P dev and versatec printers. Devices acceptable are: ver, var, ip.
1914057Sslatteng *
2015367Sslatteng * Inside the GS and GE, commands are accepted to reconfigure
2115367Sslatteng * the picture. At most one command may reside on each line, and
2215367Sslatteng * each command is followed by a parameter separated by white space.
2315367Sslatteng * The commands are as follows, and may be abbreviated down to one
2416546Sslatteng * character (with exception of "scale" and "stipple" down to "sc"
2516546Sslatteng * and "st") and may be upper or lower case.
2615031Sslatteng *
2715367Sslatteng * default - make all settings in the current
2815367Sslatteng * .GS/.GE the global defaults.
2915367Sslatteng * Height, width and file are NOT saved.
3015031Sslatteng * 1, 2, 3, 4 - set size 1, 2, 3, or 4 (followed
3115367Sslatteng * by an integer point size).
3215031Sslatteng * roman, italics, bold, special - set gremlin's fonts to any other
3315031Sslatteng * troff font (one or two characters)
3416546Sslatteng * stipple, l - use a stipple font for polygons. Arg
3516546Sslatteng * is troff font name. No Default. Can
3616546Sslatteng * use only one stipple font per picture.
3717240Sralph * (see below for stipple font index)
3815031Sslatteng * scale, x - scale is IN ADDITION to the global
3915367Sslatteng * scale factor from the default.
4015367Sslatteng * pointscale - turn on scaling point sizes to
4115367Sslatteng * match "scale" commands. (optional
4215367Sslatteng * operand "off" to turn it off)
4315031Sslatteng * narrow, medium, thick - set pixel widths of lines.
4415031Sslatteng * file - set the file name to read the
4515367Sslatteng * gremlin picture from. If the file
4615367Sslatteng * isn't in the current directory, the
4715367Sslatteng * gremlin library is tried.
4815031Sslatteng * width, height - these two commands override any
4915031Sslatteng * scaling factor that is in effect,
5015031Sslatteng * and forces the picture to fit into
5115031Sslatteng * either the height or width specified,
5215031Sslatteng * whichever makes the picture smaller.
5315031Sslatteng * The operand for these two commands is
5415031Sslatteng * a floating-point number in units of
5515031Sslatteng * inches
56*27071Sslatteng * oldstipplemap - use the old-style stipple mapping.
57*27071Sslatteng * THE FOLLOWING COMMANDS ARE IGNORED
58*27071Sslatteng * UNLESS OLDSTIPPLEMAP IS SPECIFIED.
5917240Sralph * l1, l2, l3, l4, l5, l6, l7, l8 - set association between stipples
6017240Sralph * (1 - 8) and the stipple font file
6117240Sralph * index. Valid cifplot indices are
6217240Sralph * 1 - 32 (although 24 is not defined)
6317240Sralph * and valid unigrafix indices are
6417240Sralph * 1 - 64. Nonetheless, any number
6517240Sralph * between 0 and 255 is accepted since
6617240Sralph * new stipple fonts may be added.
6717240Sralph * An integer operand is required.
6815031Sslatteng *
6915031Sslatteng * Troff number registers used: g1 through g9. g1 is the width of the
7015185Sslatteng * picture, and g2 is the height. g3, and g4, save information, g8
7115185Sslatteng * and g9 are used for text processing and g5-g7 are reserved.
7214057Sslatteng */
7314057Sslatteng
7414057Sslatteng
7514585Sslatteng #include <ctype.h>
7614057Sslatteng #include "gprint.h"
7714057Sslatteng #include "dev.h"
7814057Sslatteng
7915031Sslatteng extern char *malloc();
8014057Sslatteng extern char *rindex();
8114057Sslatteng
8214057Sslatteng /* database imports */
8314057Sslatteng
8414057Sslatteng extern HGPrintElt();
8514057Sslatteng extern ELT *DBInit(), *DBRead();
8614057Sslatteng extern POINT *PTInit(), *PTMakePoint();
8714057Sslatteng
8814057Sslatteng
8923936Sslatteng #ifndef GREMLIB
9014062Sslatteng #define GREMLIB "/usr/local/gremlib/"
9117240Sralph #endif
9217240Sralph
9317595Sopcode #define SUN_SCALEFACTOR 0.70
9417595Sopcode
9515873Sslatteng #ifndef DEVDIR
9615185Sslatteng #define DEVDIR "/usr/lib/font"
9715873Sslatteng #endif
9815185Sslatteng #define DEFAULTDEV "va"
9917595Sopcode #define DEFSTIPPLE "cf"
10014057Sslatteng
10114057Sslatteng #define MAXINLINE 100 /* input line length */
10214057Sslatteng #define DEFTHICK 3 /* default thicknes */
10314057Sslatteng #define DEFSTYLE SOLID /* default line style */
10414057Sslatteng
10517595Sopcode #ifdef oldversion
10614057Sslatteng #define SCREENtoINCH 0.02 /* scaling factor, screen to inches */
10717595Sopcode #endif
10817595Sopcode
10917595Sopcode double SCREENtoINCH; /* scaling factor, screen to inches */
11017595Sopcode
11115367Sslatteng #define BIG 999999999999.0 /* unweildly large floating number */
11214057Sslatteng
11314057Sslatteng
114*27071Sslatteng static char sccsid[] = "@(#) (Berkeley) 04/14/86";
11514057Sslatteng
11614057Sslatteng char *printer = DEFAULTDEV; /* device to look up resolution of */
11715367Sslatteng char *gremlib = GREMLIB; /* place to find files after current dir. */
11814057Sslatteng double res; /* that printer's resolution goes here */
11914057Sslatteng
12014057Sslatteng int linethickness; /* brush styles */
12114057Sslatteng int linmod;
12214057Sslatteng int lastx; /* point registers for printing elements */
12314057Sslatteng int lasty;
12414057Sslatteng int lastyline; /* a line's vertical position is NOT the same */
12514057Sslatteng /* after that line is over, so for a line of */
12614057Sslatteng /* drawing commands, vertical spacing is kept */
12714057Sslatteng /* in lastyline */
12814057Sslatteng
12915367Sslatteng /* these are the default fonts, sizes, line styles, */
13015367Sslatteng /* and thicknesses. These can be modified from a */
13115367Sslatteng /* "default" command and are reset each time the */
13215367Sslatteng /* start of a picture (.GS) is found. */
13314057Sslatteng
13415367Sslatteng char * deffont[] = { "R", "I", "B", "S" };
13515367Sslatteng int defsize[] = { 10, 16, 24, 36 };
13615367Sslatteng int defthick[STYLES] = { 1, 1, 5, 1, 1, 3 };
13717240Sralph int defstipple_index[NSTIPPLES] = { 1, 3, 12, 14, 16, 19, 21, 23 };
13815367Sslatteng int style[STYLES] = { DOTTED, DOTDASHED, SOLID, DASHED, SOLID, SOLID };
13915367Sslatteng double scale = 1.0; /* no scaling, default */
14015367Sslatteng int defpoint = 0; /* flag for pointsize scaling */
14116546Sslatteng char * defstipple = (char *) 0;
14214057Sslatteng
14314057Sslatteng int thick[STYLES]; /* thicknesses set by defaults, then by commands */
14415367Sslatteng char *tfont[FONTS]; /* fonts originally set to deffont values, then */
14515367Sslatteng int tsize[SIZES]; /* optionally changed by commands inside grn */
14617240Sralph int stipple_index[NSTIPPLES]; /* stipple font file indices */
14716546Sslatteng char * stipple;
14814057Sslatteng
14914585Sslatteng double xscale; /* scaling factor from individual pictures */
15014057Sslatteng double troffscale; /* scaling factor at output time */
15114057Sslatteng double width; /* user-request maximum width for picture (in inches) */
15214057Sslatteng double height; /* user-request height */
15315367Sslatteng int pointscale; /* flag for pointsize scaling */
15415367Sslatteng int setdefault; /* flag for a .GS/.GE to remember all settings */
15514057Sslatteng
15614057Sslatteng double toppoint; /* remember the picture */
15714057Sslatteng double bottompoint; /* bounds in these variables */
15814057Sslatteng double leftpoint;
15914057Sslatteng double rightpoint;
16014057Sslatteng
16114057Sslatteng int ytop; /* these are integer versions of the above */
16214057Sslatteng int ybottom; /* so not to convert each time they're used */
16314057Sslatteng int xleft;
16414057Sslatteng int xright;
16514057Sslatteng
16614057Sslatteng int linenum = 0; /* line number of input file */
16714057Sslatteng char inputline[MAXINLINE]; /* spot to filter through the file */
16814057Sslatteng char *c1 = inputline; /* c1, c2, and c3 will be used to */
16914057Sslatteng char *c2 = inputline + 1; /* hunt for lines that begin with */
17014057Sslatteng char *c3 = inputline + 2; /* ".GS" by looking individually */
17114057Sslatteng char GScommand[MAXINLINE]; /* put user's ".GS" command line here */
17215873Sslatteng char gremlinfile[MAXINLINE]; /* filename to use for a picture */
17317240Sralph int SUNFILE = FALSE; /* TRUE if SUN gremlin file */
174*27071Sslatteng int oldstipmap = FALSE; /* TRUE if old-style stipple mapping */
17514057Sslatteng
17614817Sslatteng char *doinput();
17714057Sslatteng
17814817Sslatteng
17914057Sslatteng /*----------------------------------------------------------------------------*
18014057Sslatteng | Routine: main (argument_count, argument_pointer)
18114057Sslatteng |
18214057Sslatteng | Results: parses the command line, accumulating input file names, then
18314057Sslatteng | reads the inputs, passing it directly to output until a ".GS"
18414057Sslatteng | line is read. Main then passes control to "conv" to do the
18514057Sslatteng | gremlin file conversions.
18614057Sslatteng *----------------------------------------------------------------------------*/
18714057Sslatteng
main(argc,argv)18814057Sslatteng main(argc, argv)
18914057Sslatteng int argc;
19014057Sslatteng char **argv;
19114057Sslatteng {
19223741Sslatteng register FILE *fp;
19314057Sslatteng register int k;
19414057Sslatteng register char c;
19515367Sslatteng register gfil = 0;
19615367Sslatteng char *file[50];
19714057Sslatteng
19814817Sslatteng char *operand();
19923741Sslatteng char *getenv();
20014057Sslatteng
20114057Sslatteng
20223741Sslatteng if (fp = (FILE *) getenv("PRINTER")) printer = (char *) fp;
20323741Sslatteng if (fp = (FILE *) getenv("TYPESETTER")) printer = (char *) fp;
20414817Sslatteng while (--argc) {
20514817Sslatteng if (**++argv != '-')
20614817Sslatteng file[gfil++] = *argv;
20714817Sslatteng else
20814817Sslatteng switch (c = (*argv)[1]) {
20914817Sslatteng
21023741Sslatteng case 0:
21123741Sslatteng file[gfil++] = NULL;
21223741Sslatteng break;
21323741Sslatteng
21415185Sslatteng case 'P':
21514057Sslatteng case 'T': /* final output typesetter name */
21614817Sslatteng printer = operand(&argc, &argv);
21714057Sslatteng break;
21815367Sslatteng
21915367Sslatteng case 'L': /* set library directory */
22015367Sslatteng gremlib = operand(&argc, &argv);
22114057Sslatteng break;
22215367Sslatteng
22314057Sslatteng default:
22415367Sslatteng error("unknown switch: %c", c);
22514057Sslatteng }
22614057Sslatteng }
22714057Sslatteng /* set the resolution for an output device */
22814057Sslatteng getres(printer); /* named in "printer" */
22914057Sslatteng
23014057Sslatteng if (gfil == 0) { /* no filename, use standard input */
23114057Sslatteng file[0] = NULL;
23214057Sslatteng gfil++;
23314057Sslatteng }
23414817Sslatteng
23514057Sslatteng for (k=0; k<gfil; k++) {
23614057Sslatteng if (file[k] != NULL) {
23714057Sslatteng if ((fp = fopen(file[k], "r")) == NULL) {
23815367Sslatteng error("can't open %s", file[k]);
23916188Sslatteng exit(1);
24014057Sslatteng }
24114057Sslatteng } else {
24214057Sslatteng fp = stdin;
24314057Sslatteng }
24414057Sslatteng
24514057Sslatteng while (doinput(fp) != NULL) {
24614057Sslatteng if (*c1 == '.' && *c2 == 'G' && *c3 == 'S') {
24714057Sslatteng conv(fp, linenum);
24814057Sslatteng } else {
24914057Sslatteng fputs(inputline, stdout);
25014057Sslatteng }
25114057Sslatteng }
25214057Sslatteng }
25314057Sslatteng }
25414057Sslatteng
25514057Sslatteng
25614057Sslatteng /*----------------------------------------------------------------------------*
25715367Sslatteng | Routine: error (control_string, args, . . . )
25815367Sslatteng |
25915367Sslatteng | Results: prints ("grn: ", the control_string + args, "\n") to stderr
26015367Sslatteng *----------------------------------------------------------------------------*/
26115367Sslatteng
26215367Sslatteng /* VARARGS1 */
error(s,a1,a2,a3,a4)26315367Sslatteng error(s, a1, a2, a3, a4)
26415367Sslatteng char * s;
26515367Sslatteng {
26615367Sslatteng fprintf(stderr, "grn: ");
26715367Sslatteng fprintf(stderr, s, a1, a2, a3, a4);
26815367Sslatteng fprintf(stderr, "\n");
26915367Sslatteng }
27015367Sslatteng
27115367Sslatteng
27215367Sslatteng /*----------------------------------------------------------------------------*
27314817Sslatteng | Routine: char * operand (& argc, & argv)
27414817Sslatteng |
27514817Sslatteng | Results: returns address of the operand given with a command-line
27614817Sslatteng | option. It uses either "-Xoperand" or "-X operand", whichever
27714817Sslatteng | is present. The program is terminated if no option is present.
27814817Sslatteng |
27914817Sslatteng | Side Efct: argc and argv are updated as necessary.
28014817Sslatteng *----------------------------------------------------------------------------*/
28114817Sslatteng
operand(argcp,argvp)28214817Sslatteng char *operand(argcp, argvp)
28314817Sslatteng int * argcp;
28414817Sslatteng char ***argvp;
28514817Sslatteng {
28614817Sslatteng if ((**argvp)[2]) return(**argvp + 2); /* operand immediately follows */
28714817Sslatteng if ((--*argcp) <= 0) { /* no operand */
28815367Sslatteng error("command-line option operand missing.");
28916188Sslatteng exit(8);
29014817Sslatteng }
29114817Sslatteng return(*(++(*argvp))); /* operand is next word */
29214817Sslatteng }
29314817Sslatteng
29414817Sslatteng
29514817Sslatteng /*----------------------------------------------------------------------------*
29614057Sslatteng | Routine: getres (device_name)
29714057Sslatteng |
29814057Sslatteng | Results: sets "res" to the resolution of the output device specified
29914057Sslatteng | by the string dev.
30014057Sslatteng *----------------------------------------------------------------------------*/
30114057Sslatteng
getres(name)30214057Sslatteng getres(name)
30314057Sslatteng char *name;
30414057Sslatteng {
30514057Sslatteng int fin;
30614057Sslatteng struct dev device;
30714057Sslatteng char temp[60];
30814057Sslatteng
30915185Sslatteng sprintf(temp, "%s/dev%s/DESC.out", DEVDIR, name);
31014057Sslatteng if ((fin = open(temp, 0)) < 0) {
31115367Sslatteng error("can't open tables for %s", temp);
31214057Sslatteng exit(1);
31314057Sslatteng }
31414057Sslatteng read(fin, &device, sizeof(struct dev));
31514057Sslatteng res = (double) device.res;
31614057Sslatteng close(fin);
31714057Sslatteng }
31814057Sslatteng
31914057Sslatteng
32014057Sslatteng /*----------------------------------------------------------------------------*
32114057Sslatteng | Routine: char * doinput (file_pointer)
32214057Sslatteng |
32314057Sslatteng | Results: a line of input is read into "inputline".
32414057Sslatteng |
32514057Sslatteng | Side Efct: "linenum" is incremented.
32614057Sslatteng |
32714057Sslatteng | Bugs: lines longer than MAXINLINE are NOT checked, except for
32814057Sslatteng | updating "linenum"
32914057Sslatteng *----------------------------------------------------------------------------*/
33014057Sslatteng
doinput(fp)33114057Sslatteng char *doinput(fp)
33214057Sslatteng FILE *fp;
33314057Sslatteng {
33415367Sslatteng char *k;
33514057Sslatteng
33614057Sslatteng
33714057Sslatteng if ((k = fgets(inputline, MAXINLINE, fp)) == NULL)
33814057Sslatteng return k;
33914057Sslatteng if (index (inputline, '\n')) /* ++ only if it's a complete line */
34014057Sslatteng linenum++;
34114057Sslatteng return (char*) !NULL;
34214057Sslatteng }
34314057Sslatteng
34414057Sslatteng
34514057Sslatteng /*----------------------------------------------------------------------------*
34614057Sslatteng | Routine: initpic ( )
34714057Sslatteng |
34814057Sslatteng | Results: sets all parameters to the normal defaults, possibly overridden
34915367Sslatteng | by a setdefault command. Initilaize the picture variables,
35014057Sslatteng | and output the startup commands to troff to begin the picture.
35114057Sslatteng *----------------------------------------------------------------------------*/
35214057Sslatteng
initpic()35314057Sslatteng initpic()
35414057Sslatteng {
35514057Sslatteng register int i;
35614057Sslatteng
35714057Sslatteng for (i = 0; i < STYLES; i++) { /* line thickness defaults */
35814057Sslatteng thick[i] = defthick[i];
35914057Sslatteng }
36014057Sslatteng for (i = 0; i < FONTS; i++) { /* font name defaults */
36115367Sslatteng tfont[i] = deffont[i];
36214057Sslatteng }
36314057Sslatteng for (i = 0; i < SIZES; i++) { /* font size defaults */
36415367Sslatteng tsize[i] = defsize[i];
36514057Sslatteng }
36617240Sralph for (i = 0; i < NSTIPPLES; i++) { /* stipple font file default indices */
36717240Sralph stipple_index[i] = defstipple_index[i];
36817240Sralph }
36916546Sslatteng stipple = defstipple;
37014057Sslatteng
37114057Sslatteng gremlinfile[0] = 0; /* filename is "null" */
37215367Sslatteng setdefault = 0; /* this is not the default settings (yet) */
37314057Sslatteng
37414057Sslatteng toppoint = BIG; /* set the picture bounds out */
37524157Sslatteng bottompoint = -BIG; /* of range so they'll be set */
37614057Sslatteng leftpoint = BIG; /* by "savebounds" on input */
37724157Sslatteng rightpoint = -BIG;
37814057Sslatteng
37915367Sslatteng pointscale = defpoint; /* Flag for scaling point sizes default. */
38014585Sslatteng xscale = scale; /* default scale of individual pictures */
38114057Sslatteng width = 0.0; /* size specifications input by user */
38214057Sslatteng height = 0.0;
38314057Sslatteng
38414057Sslatteng linethickness = DEFTHICK; /* brush styles */
38514057Sslatteng linmod = DEFSTYLE;
38614057Sslatteng }
38714057Sslatteng
38814057Sslatteng
38914057Sslatteng /*----------------------------------------------------------------------------*
39014057Sslatteng | Routine: conv (file_pointer, starting_line)
39114057Sslatteng |
39214057Sslatteng | Results: at this point, we just passed a ".GS" line in the input file.
39314057Sslatteng | conv reads the input and calls "interpret" to process commands,
39414057Sslatteng | gathering up information until a ".GE" line is found. It then
39514057Sslatteng | calls "HGPrint" to do the translation of the gremlin file to
39614057Sslatteng | troff commands.
39714057Sslatteng *----------------------------------------------------------------------------*/
39814057Sslatteng
conv(fp,baseline)39914057Sslatteng conv(fp, baseline)
40014057Sslatteng register FILE *fp;
40114057Sslatteng int baseline;
40214057Sslatteng {
40316188Sslatteng register FILE *gfp = NULL; /* input file pointer */
40416188Sslatteng register int done = 0; /* flag to remember if finished */
40516188Sslatteng register ELT *e; /* current element pointer */
40616188Sslatteng ELT *PICTURE; /* whole picture data base pointer */
40716188Sslatteng double temp; /* temporary calculating area */
40816188Sslatteng POINT ptr; /* coordinates of a point to pass to "mov" routine */
40916188Sslatteng int flyback; /* flag "want to end up at the top of the picture?" */
41014057Sslatteng
41114057Sslatteng
41214585Sslatteng initpic(); /* set defaults, ranges, etc. */
41314585Sslatteng strcpy (GScommand, inputline); /* save ".GS" line for later */
41414057Sslatteng do {
41514057Sslatteng done = (doinput(fp) == NULL); /* test for EOF */
41616188Sslatteng flyback = *c3 == 'F'; /* and .GE or .GF */
41716188Sslatteng done |= (*c1 == '.' && *c2 == 'G' && (*c3 == 'E' || flyback));
41814057Sslatteng
41914057Sslatteng if (done) {
42015367Sslatteng if (setdefault) savestate();
42115367Sslatteng
42214057Sslatteng if (!gremlinfile[0]) {
42316188Sslatteng if(!setdefault)
42416188Sslatteng error("at line %d: no picture filename.\n", baseline);
42514057Sslatteng return;
42614057Sslatteng }
42714057Sslatteng if ((gfp = fopen(gremlinfile, "r")) == NULL) {
42815873Sslatteng char name[MAXINLINE]; /* if the file isn't in the current */
42914061Sslatteng /* directory, try the gremlin library */
43015367Sslatteng sprintf(name, "%s%s", gremlib, gremlinfile);
43114061Sslatteng if ((gfp = fopen(name, "r")) == NULL) {
43215367Sslatteng error("can't open %s", gremlinfile);
43314061Sslatteng return;
43414061Sslatteng }
43514057Sslatteng }
43614057Sslatteng PICTURE = DBRead(gfp); /* read picture file */
43714057Sslatteng fclose(gfp);
43814057Sslatteng if (DBNullelt(PICTURE))
43915031Sslatteng return; /* if a request is made to make the */
44014057Sslatteng /* picture fit into a specific area, */
44114057Sslatteng /* set the scale to do that. */
44217595Sopcode
44317595Sopcode SCREENtoINCH = (SUNFILE) ? 0.014 : 0.02;
44417595Sopcode
44517595Sopcode if (stipple == (char *) NULL) /* if user forgot stipple */
44617595Sopcode if (has_polygon(PICTURE)) /* and picture has a polygon */
44717595Sopcode stipple = DEFSTIPPLE; /* then set the default */
44817595Sopcode
44915031Sslatteng if ((temp = bottompoint - toppoint) < 0.1) temp = 0.1;
45015625Sslatteng temp = (height != 0.0) ? height / (temp * SCREENtoINCH) : BIG;
45115031Sslatteng if ((troffscale = rightpoint - leftpoint) < 0.1) troffscale=0.1;
45215625Sslatteng troffscale = (width != 0.0) ?
45315625Sslatteng width / (troffscale * SCREENtoINCH) : BIG;
45414057Sslatteng if (temp == BIG && troffscale == BIG) {
45514585Sslatteng troffscale = xscale;
45614057Sslatteng } else {
45714057Sslatteng if (temp < troffscale) troffscale = temp;
45815367Sslatteng } /* here, troffscale is the */
45915367Sslatteng /* picture's scaling factor */
46015367Sslatteng if (pointscale) {
46115367Sslatteng register int i; /* do pointscaling here, when */
46215367Sslatteng /* scale is known, before output */
46317595Sopcode
46415367Sslatteng for (i = 0; i < SIZES; i++)
46515367Sslatteng tsize[i] = (int) (troffscale * (double) tsize[i] + 0.5);
46617595Sopcode
46714057Sslatteng }
46815367Sslatteng /* change to device units */
46915367Sslatteng troffscale *= SCREENtoINCH * res; /* from screen units */
47014057Sslatteng
47114057Sslatteng ytop = toppoint * troffscale; /* calculate integer */
47214057Sslatteng ybottom = bottompoint * troffscale; /* versions of the */
47314057Sslatteng xleft = leftpoint * troffscale; /* picture limits */
47414057Sslatteng xright = rightpoint * troffscale;
47514057Sslatteng /* save stuff in number registers, */
47615031Sslatteng /* register g1 = picture width and */
47715031Sslatteng /* register g2 = picture height, */
47814057Sslatteng /* set vertical spacing, no fill, */
47914057Sslatteng /* and break (to make sure picture */
48014057Sslatteng /* starts on left), and put out the */
48114057Sslatteng /* user's ".GS" line. */
48216188Sslatteng printf(
48316405Sslatteng ".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",
48416188Sslatteng xright-xleft, ybottom-ytop, GScommand);
48514057Sslatteng
48616546Sslatteng if (stipple) { /* stipple requested for this picture */
48716546Sslatteng printf(".st %s\n", stipple);
48816546Sslatteng }
48916546Sslatteng
49014057Sslatteng lastx = xleft; /* note where we are, (upper left */
49114057Sslatteng lastyline = lasty = ytop; /* corner of the picture) */
49214057Sslatteng
49314057Sslatteng e = PICTURE;
49416546Sslatteng while (!DBNullelt(e)) { /* traverse picture; print elements */
49516546Sslatteng HGPrintElt(e, baseline);
49614057Sslatteng e = DBNextElt(e);
49714057Sslatteng }
49816188Sslatteng /* decide where to end picture */
49916188Sslatteng if (flyback) { /* end piture at upper left */
50016188Sslatteng ptr.x = leftpoint;
50116188Sslatteng ptr.y = toppoint;
50216188Sslatteng } else { /* end picture at lower left */
50316188Sslatteng ptr.x = leftpoint;
50416188Sslatteng ptr.y = bottompoint;
50516188Sslatteng }
50614061Sslatteng tmove(&ptr); /* restore default line parameters, */
50716188Sslatteng /* restore everything to the way */
50816188Sslatteng /* it was before the .GS, then put */
50916188Sslatteng /* out the ".GE" line from user */
51016600Sslatteng printf("\\D't %du'\\D's %du'\n", DEFTHICK, DEFSTYLE);
51116600Sslatteng if (flyback) { /* make sure we end up at top of */
51216600Sslatteng printf(".sp -1\n"); /* picture if "flying back" */
51316600Sslatteng }
51416546Sslatteng if (stipple) { /* restore stipple to previous */
51516546Sslatteng printf(".st\n");
51616546Sslatteng }
51715224Sslatteng printf(".br\n.ft \\n(g3\n.ps \\n(g4\n%s", inputline);
51814057Sslatteng } else {
51914057Sslatteng interpret(inputline); /* take commands from the input file */
52014057Sslatteng }
52114057Sslatteng } while (!done);
52214057Sslatteng }
52314057Sslatteng
52414057Sslatteng
52514057Sslatteng /*----------------------------------------------------------------------------*
52615367Sslatteng | Routine: savestate ( )
52715367Sslatteng |
52815367Sslatteng | Results: all the current scaling / font size / font name / thickness /
52915367Sslatteng | pointscale settings are saved to be the defaults. Scaled
53015367Sslatteng | point sizes are NOT saved. The scaling is done each time a
53115367Sslatteng | new picture is started.
53215367Sslatteng |
53316546Sslatteng | Side Efct: scale, and def* are modified.
53415367Sslatteng *----------------------------------------------------------------------------*/
53515367Sslatteng
savestate()53615367Sslatteng savestate()
53715367Sslatteng {
53815367Sslatteng register int i;
53915367Sslatteng
54015367Sslatteng for (i = 0; i < STYLES; i++) { /* line thickness defaults */
54115367Sslatteng defthick[i] = thick[i];
54215367Sslatteng }
54315367Sslatteng for (i = 0; i < FONTS; i++) { /* font name defaults */
54415367Sslatteng deffont[i] = tfont[i];
54515367Sslatteng }
54615367Sslatteng for (i = 0; i < SIZES; i++) { /* font size defaults */
54715367Sslatteng defsize[i] = tsize[i];
54815367Sslatteng }
54917240Sralph for (i = 0; i < NSTIPPLES; i++) { /* stipple font file default indices */
55017240Sralph defstipple_index[i] = stipple_index[i];
55117240Sralph }
55216546Sslatteng defstipple = stipple; /* if stipple has been set, it's remembered */
55315367Sslatteng
55415367Sslatteng scale *= xscale; /* default scale of individual pictures */
55515367Sslatteng defpoint = pointscale; /* flag for scaling pointsizes from x factors */
55615367Sslatteng }
55715367Sslatteng
55815367Sslatteng
55915367Sslatteng /*----------------------------------------------------------------------------*
56014057Sslatteng | Routine: savebounds (x_coordinate, y_coordinate)
56114057Sslatteng |
56214057Sslatteng | Results: keeps track of the maximum and minimum extent of a picture
56314057Sslatteng | in the global variables: left-, right-, top- and bottompoint.
56414057Sslatteng | "savebounds" assumes that the points have been oriented to
56514057Sslatteng | the correct direction. No scaling has taken place, though.
56614057Sslatteng *----------------------------------------------------------------------------*/
56714057Sslatteng
savebounds(x,y)56814057Sslatteng savebounds(x, y)
56914057Sslatteng float x;
57014057Sslatteng float y;
57114057Sslatteng {
57215054Sslatteng if (x < leftpoint) leftpoint = x;
57315054Sslatteng if (x > rightpoint) rightpoint = x;
57415054Sslatteng if (y < toppoint) toppoint = y;
57515054Sslatteng if (y > bottompoint) bottompoint = y;
57614057Sslatteng }
57714057Sslatteng
57814057Sslatteng
57914057Sslatteng /*----------------------------------------------------------------------------*
58014057Sslatteng | Routine: interpret (character_string)
58114057Sslatteng |
58214057Sslatteng | Results: commands are taken from the input string and performed.
58314585Sslatteng | Commands are separated by the endofline, and are of the
58414585Sslatteng | format:
58514585Sslatteng | string1 string2
58614057Sslatteng |
58714585Sslatteng | where string1 is the command and string2 is the argument.
58814585Sslatteng |
58914057Sslatteng | Side Efct: font and size strings, plus the gremlin file name and the
59014057Sslatteng | width and height variables are set by this routine.
59114057Sslatteng *----------------------------------------------------------------------------*/
59214057Sslatteng
interpret(line)59314057Sslatteng interpret (line)
59414585Sslatteng char *line;
59514057Sslatteng {
59614585Sslatteng char str1[MAXINLINE];
59714585Sslatteng char str2[MAXINLINE];
59814585Sslatteng register char *chr;
59915367Sslatteng register int i;
60015367Sslatteng double par;
60114585Sslatteng
60215367Sslatteng str2[0] = '\0';
60315031Sslatteng sscanf(line, "%80s%80s", &str1[0], &str2[0]);
60414585Sslatteng for (chr = &str1[0]; *chr; chr++) /* convert command to */
60514586Sslatteng if(isupper(*chr)) *chr = tolower(*chr); /* lower case */
60614585Sslatteng switch (str1[0]) {
60714585Sslatteng
60814585Sslatteng case '1':
60914585Sslatteng case '2': /* font sizes */
61014585Sslatteng case '3':
61114585Sslatteng case '4':
61215367Sslatteng i = atoi(str2);
61315367Sslatteng if (i > 0 && i < 1000)
61415367Sslatteng tsize[str1[0] - '1'] = i;
61515367Sslatteng else
61615367Sslatteng error("bad font size value at line %d", linenum);
61714585Sslatteng break;
61814585Sslatteng
61914585Sslatteng case 'r': /* roman */
62015367Sslatteng if(str2[0] < '0') goto nofont;
62115031Sslatteng tfont[0] = malloc(strlen(str2) + 1);
62214585Sslatteng strcpy(tfont[0], str2);
62314585Sslatteng break;
62414585Sslatteng
62514585Sslatteng case 'i': /* italics */
62615367Sslatteng if(str2[0] < '0') goto nofont;
62715031Sslatteng tfont[1] = malloc(strlen(str2) + 1);
62814585Sslatteng strcpy(tfont[1], str2);
62914585Sslatteng break;
63014585Sslatteng
63114585Sslatteng case 'b': /* bold */
63215367Sslatteng if(str2[0] < '0') goto nofont;
63315031Sslatteng tfont[2] = malloc(strlen(str2) + 1);
63414585Sslatteng strcpy(tfont[2], str2);
63514585Sslatteng break;
63614585Sslatteng
63714585Sslatteng case 's': /* special */
63815367Sslatteng if (str1[1] == 'c') goto scalecommand; /* or scale */
63915367Sslatteng
64015367Sslatteng if(str2[0] < '0') {
64115367Sslatteng nofont: error("no fontname specified in line %d", linenum);
64215367Sslatteng break;
64315367Sslatteng }
64416546Sslatteng if (str1[1] == 't') goto stipplecommand; /* or stipple */
64516546Sslatteng
64615031Sslatteng tfont[3] = malloc(strlen(str2) + 1);
64714585Sslatteng strcpy(tfont[3], str2);
64814585Sslatteng break;
64914585Sslatteng
65016546Sslatteng case 'l': /* l */
65117240Sralph if ((str1[1] < '1') || (str1[1] > '8'))
65217240Sralph goto stipplecommand;
65317240Sralph
65417240Sralph /* else set stipple index */
65517240Sralph i = atoi(str2);
65617240Sralph if (i >= 0 && i < 256)
65717240Sralph stipple_index[str1[1] - '1'] = i;
65817240Sralph else
65917240Sralph error("bad stipple index value at line %d", linenum);
66017240Sralph break;
66117240Sralph
66216546Sslatteng stipplecommand: /* stipple */
66316546Sslatteng stipple = malloc(strlen(str2) + 1);
66416546Sslatteng strcpy(stipple, str2);
66516546Sslatteng break;
66616546Sslatteng
667*27071Sslatteng case 'o': /* oldstipplemap */
668*27071Sslatteng oldstipmap = TRUE;
669*27071Sslatteng break;
670*27071Sslatteng
67114585Sslatteng case 't': /* thick */
67214585Sslatteng thick[2] = atoi(str2);
67314585Sslatteng break;
67414585Sslatteng
67514585Sslatteng case 'm': /* medium */
67614585Sslatteng thick[5] = atoi(str2);
67714585Sslatteng break;
67814585Sslatteng
67914585Sslatteng case 'n': /* narrow */
68014585Sslatteng thick[0] = thick[1] = thick[3] = thick[4] = atoi(str2);
68114585Sslatteng break;
68214585Sslatteng
68314585Sslatteng case 'x': /* x */
68414585Sslatteng scalecommand: /* scale */
68515367Sslatteng par = atof(str2);
68615367Sslatteng if (par > 0.0)
68715367Sslatteng xscale *= par;
68815367Sslatteng else
68915367Sslatteng error("illegal scale value on line %d", linenum);
69014585Sslatteng break;
69114585Sslatteng
69214585Sslatteng case 'f': /* file */
69314585Sslatteng strcpy(gremlinfile, str2);
69414585Sslatteng break;
69514585Sslatteng
69614585Sslatteng case 'w': /* width */
69714585Sslatteng width = atof(str2);
69814585Sslatteng if (width < 0.0) width = -width;
69914585Sslatteng break;
70014585Sslatteng
70114585Sslatteng case 'h': /* height */
70214585Sslatteng height = atof(str2);
70314585Sslatteng if (height < 0.0) height = -height;
70414585Sslatteng break;
70514585Sslatteng
70615367Sslatteng case 'd': /* defaults */
70715367Sslatteng setdefault = 1;
70815367Sslatteng break;
70915367Sslatteng
71015367Sslatteng case 'p': /* pointscale */
71115367Sslatteng if (strcmp("off", str2))
71215367Sslatteng pointscale = 1;
71315367Sslatteng else
71415367Sslatteng pointscale = 0;
71515367Sslatteng break;
71615367Sslatteng
71714585Sslatteng default:
71816188Sslatteng error("unknown command, %s, on line %d", str1, linenum);
71916188Sslatteng exit(8);
72014585Sslatteng break;
72114585Sslatteng };
72214057Sslatteng }
72317595Sopcode
72417595Sopcode
72517595Sopcode /*
72617595Sopcode * return TRUE if picture contains a polygon
72717595Sopcode * otherwise FALSE
72817595Sopcode */
has_polygon(elist)72917595Sopcode has_polygon(elist)
73017595Sopcode register ELT *elist;
73117595Sopcode {
73217595Sopcode while (!DBNullelt(elist)) {
73317595Sopcode if (elist->type == POLYGON)
73417595Sopcode return(1);
73517595Sopcode elist = DBNextElt(elist);
73617595Sopcode }
73717595Sopcode
73817595Sopcode return(0);
73917595Sopcode }
740