1*18122Sslatteng /* @(#)dterm.c 1.14 (Berkeley) 02/26/85"
214087Sslatteng *
314087Sslatteng * Converts ditroff output to text on a terminal. It is NOT meant to
414087Sslatteng * produce readable output, but is to show one how one's paper is (in
514087Sslatteng * general) formatted - what will go where on which page.
614087Sslatteng *
714087Sslatteng * options:
814087Sslatteng *
914087Sslatteng * -hn set horizontal resolution to n (in characters per inch;
1014087Sslatteng * default is 10.0).
1114087Sslatteng *
1214087Sslatteng * -vn set vertical resolution (default is 6.0).
1314087Sslatteng *
1414087Sslatteng * -ln set maximum output line-length to n (default is 79).
1514087Sslatteng *
1614087Sslatteng * -olist output page list - as in troff.
1714087Sslatteng *
1814087Sslatteng * -c continue at end of page. Default is to stop at the end
1914087Sslatteng * of each page, print "dterm:" and wait for a command.
2014087Sslatteng * Type ? to get a list of available commands.
2114087Sslatteng *
2215279Sslatteng * -m print margins. Default action is to cut printing area down
2315279Sslatteng * to only the part of the page with information on it.
2415279Sslatteng *
2516847Sslatteng * -a make the output readable - i.e. print like a "troff -a" with
2616847Sslatteng * no character overlap, and one space 'tween words
2716847Sslatteng *
2814822Sslatteng * -L put a form feed (^L) at the end of each page
2914645Sslatteng *
3015279Sslatteng * -w sets h = 20, v = 12, l = 131, also sets -c, -m and -L to allow
3114822Sslatteng * for extra-wide printouts on the printer.
3214822Sslatteng *
3314645Sslatteng * -fxxx get special character definition file "xxx". Default is
34*18122Sslatteng * FONTDIR/devter/specfile.
3514087Sslatteng */
3614087Sslatteng
3714087Sslatteng
3814087Sslatteng #include <stdio.h>
3914087Sslatteng #include <ctype.h>
4014087Sslatteng #include <math.h>
4114087Sslatteng
4214087Sslatteng
4314087Sslatteng #define FATAL 1
4414816Sslatteng #define PGWIDTH 266 /* WAY too big - for good measure */
4514816Sslatteng #define PGHEIGHT 220
4614087Sslatteng #define LINELEN 78
47*18122Sslatteng #define SPECFILE "devter/specfile"
48*18122Sslatteng #ifndef FONTDIR
49*18122Sslatteng #define FONTDIR "/usr/lib/font"
50*18122Sslatteng #endif
5114087Sslatteng
5214087Sslatteng #define hgoto(n) hpos = n
5314087Sslatteng #define vgoto(n) vpos = n
5414087Sslatteng #define hmot(n) hpos += n
5514087Sslatteng #define vmot(n) vpos += n
5614087Sslatteng
5714087Sslatteng #define sgn(n) ((n > 0) ? 1 : ((n < 0) ? -1 : 0))
5814087Sslatteng #define abs(n) ((n) >= 0 ? (n) : -(n))
5914087Sslatteng #define max(x,y) ((x) > (y) ? (x) : (y))
6014087Sslatteng #define min(x,y) ((x) < (y) ? (x) : (y))
6114087Sslatteng #define sqr(x) (long int)(x)*(x)
6214087Sslatteng
6314087Sslatteng
64*18122Sslatteng char SccsId [] = "@(#)dterm.c 1.14 (Berkeley) 02/26/85";
6514087Sslatteng
6614645Sslatteng char **spectab; /* here go the special characters */
67*18122Sslatteng char specfile[100] = FONTDIR;/* place to look up special characters */
6814645Sslatteng char *malloc();
6914822Sslatteng char *operand();
7014087Sslatteng
7114816Sslatteng int keepon = 0; /* flags: Don't stop at the end of each page? */
7214816Sslatteng int clearsc = 0; /* Put out form feed at each page? */
7314816Sslatteng int output = 0; /* Do we do output at all? */
7414816Sslatteng int nolist = 0; /* Output page list if > 0 */
7515279Sslatteng int margin = 0; /* Print blank margins? */
7616847Sslatteng int ascii = 0; /* make the output "readable"? */
7714645Sslatteng int olist[20]; /* pairs of page numbers */
7814087Sslatteng
7914645Sslatteng float hscale = 10.0; /* characters and lines per inch for output */
8014645Sslatteng float vscale = 6.0; /* device (defaults are for printer) */
8114645Sslatteng FILE *fp = stdin; /* input file pointer */
8214087Sslatteng
8314087Sslatteng char pagebuf[PGHEIGHT][PGWIDTH];
8414087Sslatteng int minh = PGWIDTH;
8514087Sslatteng int maxh = 0;
8614087Sslatteng int minv = PGHEIGHT;
8714087Sslatteng int maxv = 0;
8814087Sslatteng int linelen = LINELEN;
8914087Sslatteng
9014087Sslatteng int hpos; /* horizontal position to be next (left = 0) */
9114087Sslatteng int vpos; /* current vertical position (down positive) */
9214087Sslatteng
9314087Sslatteng int np; /* number of pages seen */
9414087Sslatteng int npmax; /* high-water mark of np */
9514087Sslatteng int pgnum[40]; /* their actual numbers */
9614087Sslatteng long pgadr[40]; /* their seek addresses */
9714087Sslatteng
9814645Sslatteng int DP; /* step size for drawing */
9914816Sslatteng int maxdots = 3200; /* maximum number of dots in an object */
10014087Sslatteng
10114087Sslatteng
10214087Sslatteng
main(argc,argv)10314087Sslatteng main(argc, argv)
10414087Sslatteng int argc;
10514087Sslatteng char **argv;
10614087Sslatteng {
107*18122Sslatteng strcat(specfile, "/");
108*18122Sslatteng strcat(specfile, SPECFILE);
10914822Sslatteng while (--argc > 0 && **++argv == '-') {
11014822Sslatteng switch ((*argv)[1]) {
11114645Sslatteng case 'f': /* special character filepath */
112*18122Sslatteng strncpy(specfile, operand(&argc, &argv), 100);
11314645Sslatteng break;
11414645Sslatteng case 'l': /* output line length */
11514822Sslatteng linelen = atoi(operand(&argc, &argv)) - 1;
11614087Sslatteng break;
11714645Sslatteng case 'h': /* horizontal scale (char/inch) */
11814822Sslatteng hscale = atof(operand(&argc, &argv));
11914087Sslatteng break;
12014645Sslatteng case 'v': /* vertical scale (char/inch) */
12114822Sslatteng vscale = atof(operand(&argc, &argv));
12214087Sslatteng break;
12314645Sslatteng case 'o': /* output list */
12414822Sslatteng outlist(operand(&argc, &argv));
12514087Sslatteng break;
12614816Sslatteng case 'c': /* continue at endofpage */
12714822Sslatteng keepon = !keepon;
12814087Sslatteng break;
12915279Sslatteng case 'm': /* print margins */
13015279Sslatteng margin = !margin;
13115279Sslatteng break;
13216847Sslatteng case 'a': /* readable mode */
13316847Sslatteng ascii = !ascii;
13416847Sslatteng break;
13514816Sslatteng case 'L': /* form feed after each page */
13614822Sslatteng clearsc = !clearsc;
13714816Sslatteng break;
13814816Sslatteng case 'w': /* "wide" printer format */
13914090Sslatteng hscale = 16.0;
14014090Sslatteng vscale = 9.6;
14114087Sslatteng linelen = 131;
14214087Sslatteng keepon = 1;
14314816Sslatteng clearsc = 1;
14414087Sslatteng break;
14514087Sslatteng }
14614087Sslatteng }
14714087Sslatteng
14814822Sslatteng if (argc < 1)
14914087Sslatteng conv(stdin);
15014087Sslatteng else
15114822Sslatteng while (argc--) {
15214087Sslatteng if (strcmp(*argv, "-") == 0)
15314087Sslatteng fp = stdin;
15414087Sslatteng else if ((fp = fopen(*argv, "r")) == NULL)
15514087Sslatteng error(FATAL, "can't open %s", *argv);
15614087Sslatteng conv(fp);
15714087Sslatteng fclose(fp);
15814087Sslatteng argv++;
15914087Sslatteng }
16014087Sslatteng done();
16114087Sslatteng }
16214087Sslatteng
16314087Sslatteng
16414822Sslatteng /*----------------------------------------------------------------------------*
16514822Sslatteng | Routine: char * operand (& argc, & argv)
16614822Sslatteng |
16714822Sslatteng | Results: returns address of the operand given with a command-line
16814822Sslatteng | option. It uses either "-Xoperand" or "-X operand", whichever
16914822Sslatteng | is present. The program is terminated if no option is present.
17014822Sslatteng |
17114822Sslatteng | Side Efct: argc and argv are updated as necessary.
17214822Sslatteng *----------------------------------------------------------------------------*/
17314822Sslatteng
operand(argcp,argvp)17414822Sslatteng char *operand(argcp, argvp)
17514822Sslatteng int * argcp;
17614822Sslatteng char ***argvp;
17714822Sslatteng {
17814822Sslatteng if ((**argvp)[2]) return(**argvp + 2); /* operand immediately follows */
17914822Sslatteng if ((--*argcp) <= 0) { /* operand next word */
18014822Sslatteng fprintf (stderr, "command-line option operand missing.\n");
18114822Sslatteng exit(1);
18214822Sslatteng }
18314822Sslatteng return(*(++(*argvp))); /* no operand */
18414822Sslatteng }
18514822Sslatteng
18614822Sslatteng
outlist(s)18714087Sslatteng outlist(s) /* process list of page numbers to be printed */
18814087Sslatteng char *s;
18914087Sslatteng {
19014087Sslatteng int n1, n2, i;
19114087Sslatteng
19214087Sslatteng nolist = 0;
19314087Sslatteng while (*s) {
19414087Sslatteng n1 = 0;
19514087Sslatteng if (isdigit(*s))
19614087Sslatteng do
19714087Sslatteng n1 = 10 * n1 + *s++ - '0';
19814087Sslatteng while (isdigit(*s));
19914087Sslatteng else
20014087Sslatteng n1 = -9999;
20114087Sslatteng n2 = n1;
20214087Sslatteng if (*s == '-') {
20314087Sslatteng s++;
20414087Sslatteng n2 = 0;
20514087Sslatteng if (isdigit(*s))
20614087Sslatteng do
20714087Sslatteng n2 = 10 * n2 + *s++ - '0';
20814087Sslatteng while (isdigit(*s));
20914087Sslatteng else
21014087Sslatteng n2 = 9999;
21114087Sslatteng }
21214087Sslatteng olist[nolist++] = n1;
21314087Sslatteng olist[nolist++] = n2;
21414087Sslatteng if (*s != '\0')
21514087Sslatteng s++;
21614087Sslatteng }
21714087Sslatteng olist[nolist] = 0;
21814087Sslatteng }
21914087Sslatteng
22014087Sslatteng
in_olist(n)22114087Sslatteng in_olist(n) /* is n in olist? */
22214087Sslatteng int n;
22314087Sslatteng {
22414087Sslatteng int i;
22514087Sslatteng
22614087Sslatteng if (nolist == 0)
22714087Sslatteng return(1); /* everything is included */
22814087Sslatteng for (i = 0; i < nolist; i += 2)
22914087Sslatteng if (n >= olist[i] && n <= olist[i+1])
23014087Sslatteng return(1);
23114087Sslatteng return(0);
23214087Sslatteng }
23314087Sslatteng
23414087Sslatteng
conv(fp)23514087Sslatteng conv(fp)
23614087Sslatteng register FILE *fp;
23714087Sslatteng {
23814087Sslatteng register int c;
23914087Sslatteng int m, n, i, n1, m1;
24014087Sslatteng char str[100], buf[300];
24114087Sslatteng
24214087Sslatteng while ((c = getc(fp)) != EOF) {
24314087Sslatteng switch (c) {
24414087Sslatteng case '\n': /* when input is text */
24514087Sslatteng case '\t':
24614087Sslatteng case ' ':
24714087Sslatteng case 0:
24814087Sslatteng break;
24914087Sslatteng
25014087Sslatteng case '0': case '1': case '2': case '3': case '4':
25114087Sslatteng case '5': case '6': case '7': case '8': case '9':
25214087Sslatteng /* two motion digits plus a character */
25316847Sslatteng if (ascii) {
25416847Sslatteng hmot((int)hscale);
25516847Sslatteng getc(fp);
25616847Sslatteng } else {
25716847Sslatteng hmot((c-'0')*10 + getc(fp)-'0');
25816847Sslatteng }
25914087Sslatteng put1(getc(fp));
26014087Sslatteng break;
26114087Sslatteng
26214087Sslatteng case 'c': /* single ascii character */
26314087Sslatteng put1(getc(fp));
26414087Sslatteng break;
26514087Sslatteng
26614087Sslatteng case 'C': /* funny character */
26714087Sslatteng fscanf(fp, "%s", str);
26814087Sslatteng put1s(str);
26914087Sslatteng break;
27014087Sslatteng
27114087Sslatteng case 't': /* straight text */
27214087Sslatteng fgets(buf, sizeof(buf), fp);
27314087Sslatteng t_text(buf);
27414087Sslatteng break;
27514087Sslatteng
27614087Sslatteng case 'D': /* draw function */
27714087Sslatteng fgets(buf, sizeof(buf), fp);
27814087Sslatteng switch (buf[0]) {
27914087Sslatteng case 'l': /* draw a line */
28014087Sslatteng sscanf(buf+1, "%d %d", &n, &m);
28116389Sslatteng drawline(n, m);
28214087Sslatteng break;
28314087Sslatteng case 'c': /* circle */
28414087Sslatteng sscanf(buf+1, "%d", &n);
28514087Sslatteng drawcirc(n);
28614087Sslatteng break;
28714087Sslatteng case 'e': /* ellipse */
28814087Sslatteng sscanf(buf+1, "%d %d", &m, &n);
28914087Sslatteng drawellip(m, n);
29014087Sslatteng break;
29114087Sslatteng case 'a': /* arc */
29214087Sslatteng sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1);
29314087Sslatteng drawarc(n, m, n1, m1);
29414087Sslatteng break;
29516505Sslatteng case 'q': /* versatec polygon - ignore */
29616505Sslatteng while (buf[strlen(buf) - 1] != '\n')
29716505Sslatteng if (fgets(buf, sizeof(buf), fp) == NULL)
29816505Sslatteng error(FATAL,"unexpected end of input");
29916505Sslatteng break;
30016505Sslatteng case 'P': /* unbordered */
30116389Sslatteng case 'p': /* polygon */
30216389Sslatteng sscanf(buf+1, "%d", &n);
30316389Sslatteng n = 1;
30416389Sslatteng while(buf[n++] == ' ');
30516389Sslatteng while(isdigit(buf[n])) n++;
30616389Sslatteng drawwig(buf+n, 1);
30716389Sslatteng break;
30814087Sslatteng case 'g': /* "gremlin" curve */
30914087Sslatteng case '~': /* wiggly line */
31016389Sslatteng drawwig(buf+1, 0);
31114087Sslatteng break;
31214087Sslatteng case 't': /* thickness - not important */
31314087Sslatteng case 's': /* style - not important */
31414087Sslatteng break;
31514087Sslatteng default:
31614087Sslatteng error(FATAL,"unknown drawing command %s\n",buf);
31714087Sslatteng break;
31814087Sslatteng }
31914087Sslatteng break;
32016389Sslatteng case 'i': /* stipple pattern request - ignored */
32114087Sslatteng case 's': /* point size - ignored */
32214087Sslatteng fscanf(fp, "%d", &n);
32314087Sslatteng break;
32414087Sslatteng
32514087Sslatteng case 'f': /* font request - ignored */
32614087Sslatteng fscanf(fp, "%s", str);
32714087Sslatteng break;
32814087Sslatteng
32914087Sslatteng case 'H': /* absolute horizontal motion */
33014087Sslatteng fscanf(fp, "%d", &n);
33114087Sslatteng hgoto(n);
33214087Sslatteng break;
33314087Sslatteng
33414087Sslatteng case 'h': /* relative horizontal motion */
33514087Sslatteng fscanf(fp, "%d", &n);
33614087Sslatteng hmot(n);
33714087Sslatteng break;
33814087Sslatteng
33914087Sslatteng case 'w': /* word space */
34016847Sslatteng if (ascii) {
34116847Sslatteng hmot((int)hscale);
34216847Sslatteng }
34314087Sslatteng break;
34414087Sslatteng
34514087Sslatteng case 'V': /* absolute vertical motion */
34614087Sslatteng fscanf(fp, "%d", &n);
34714087Sslatteng vgoto(n);
34814087Sslatteng break;
34914087Sslatteng
35014087Sslatteng case 'v': /* relative vertical motion */
35114087Sslatteng fscanf(fp, "%d", &n);
35214087Sslatteng vmot(n);
35314087Sslatteng break;
35414087Sslatteng
35514087Sslatteng case 'p': /* new page */
35614087Sslatteng fscanf(fp, "%d", &n);
35714087Sslatteng t_page(n);
35814087Sslatteng break;
35914087Sslatteng
36015279Sslatteng case 'P': /* new span (ignored) */
36115279Sslatteng fscanf(fp, "%d", &n);
36215279Sslatteng break;
36315279Sslatteng
36414087Sslatteng case 'n': /* end of line */
36514087Sslatteng hpos = 0;
36614087Sslatteng case '#': /* comment */
36714087Sslatteng while (getc(fp) != '\n')
36814087Sslatteng ;
36914087Sslatteng break;
37014087Sslatteng
37114087Sslatteng case 'x': /* device control */
37214087Sslatteng devcntrl(fp);
37314087Sslatteng break;
37414087Sslatteng
37514087Sslatteng default:
37614087Sslatteng error(!FATAL, "unknown input character %o %c\n", c, c);
37714087Sslatteng done();
37814087Sslatteng }
37914087Sslatteng }
38014087Sslatteng }
38114087Sslatteng
38214087Sslatteng
devcntrl(fp)38314087Sslatteng devcntrl(fp) /* interpret device control functions */
38414087Sslatteng FILE *fp;
38514087Sslatteng {
38614087Sslatteng int c, n;
38714087Sslatteng char str[20];
38814087Sslatteng
38914087Sslatteng fscanf(fp, "%s", str);
39014087Sslatteng switch (str[0]) { /* crude for now */
39114087Sslatteng case 'i': /* initialize */
39214087Sslatteng t_init(0);
39314087Sslatteng break;
39414087Sslatteng case 'r': /* resolution assumed when prepared */
39514087Sslatteng fscanf(fp, "%d", &n);
39614087Sslatteng hscale = (float) n / hscale;
39714087Sslatteng vscale = (float) n / vscale;
39814816Sslatteng DP = min (hscale, vscale); /* guess the drawing */
39914816Sslatteng DP = max (DP, 1); /* resolution */
40014816Sslatteng break;
40114087Sslatteng case 'f': /* font used */
40214087Sslatteng case 'T': /* device name */
40314087Sslatteng case 't': /* trailer */
40414087Sslatteng case 'p': /* pause -- can restart */
40514087Sslatteng case 's': /* stop */
40614087Sslatteng break;
40714087Sslatteng }
40814087Sslatteng while (getc(fp) != '\n') /* skip rest of input line */
40914087Sslatteng ;
41014087Sslatteng }
41114087Sslatteng
41214087Sslatteng /* error printing routine - first argument is a "fatal" flag */
error(f,s,a1,a2,a3,a4,a5,a6,a7)41314087Sslatteng error(f, s, a1, a2, a3, a4, a5, a6, a7) {
41414087Sslatteng fprintf(stderr, "dterm: ");
41514087Sslatteng fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
41614087Sslatteng fprintf(stderr, "\n");
41714087Sslatteng if (f) exit(1);
41814087Sslatteng }
41914087Sslatteng
42014087Sslatteng
t_init(reinit)42114087Sslatteng t_init(reinit) /* initialize device */
42214087Sslatteng int reinit;
42314087Sslatteng {
42414645Sslatteng register int i;
42514645Sslatteng register int j;
42614645Sslatteng register FILE *fp; /* file to look up special characters */
42714645Sslatteng register char *charptr; /* string pointer to step through specials */
42814645Sslatteng register char *tabptr; /* string pointer for spectab setting */
42914645Sslatteng char specials[5000]; /* intermediate input buffer (made bigger */
43014645Sslatteng /* than we'll EVER use... */
43114087Sslatteng
43214645Sslatteng
43314087Sslatteng fflush(stdout);
43414087Sslatteng hpos = vpos = 0;
43514087Sslatteng for (i = 0; i < PGHEIGHT; i++)
43614087Sslatteng for (j = 0; j < PGWIDTH; j++)
43714087Sslatteng pagebuf[i][j] = ' ';
43814087Sslatteng minh = PGWIDTH;
43914087Sslatteng maxh = 0;
44014087Sslatteng minv = PGHEIGHT;
44114087Sslatteng maxv = 0;
44214645Sslatteng
44314645Sslatteng if (reinit) return; /* if this is the first time, read */
44414645Sslatteng /* special character table file. */
44514645Sslatteng if ((fp = fopen (specfile, "r")) != NULL) {
44614645Sslatteng charptr = &specials[0];
44714923Sslatteng for (i = 2; fscanf(fp, "%s", charptr) != EOF; i++) {
44814645Sslatteng charptr += strlen(charptr) + 1;
44914645Sslatteng }
45014645Sslatteng fclose(fp);
45114645Sslatteng *charptr++ = '\0'; /* ending strings */
45214645Sslatteng *charptr++ = '\0';
45314645Sslatteng /* allocate table */
45414645Sslatteng spectab = (char **) malloc(i * sizeof(char*));
45514645Sslatteng spectab[0] = tabptr = malloc(j = (int) (charptr - &specials[0]));
45614645Sslatteng
45714645Sslatteng /* copy whole table */
45814645Sslatteng for (charptr = &specials[0]; j--; *tabptr++ = *charptr++);
45914645Sslatteng
46014923Sslatteng tabptr = spectab[0]; /* set up pointers to table */
46114645Sslatteng for (j = 0; i--; j++) {
46214645Sslatteng spectab[j] = tabptr;
46314645Sslatteng tabptr += strlen(tabptr) + 1;
46414645Sslatteng }
46514645Sslatteng
46614645Sslatteng } else { /* didn't find table - allocate a null one */
46714645Sslatteng
46814645Sslatteng error (!FATAL, "Can't open special character file: %s", specfile);
46914645Sslatteng spectab = (char **) malloc(2 * sizeof(char*));
47014645Sslatteng spectab[0] = malloc (2);
47114645Sslatteng spectab[1] = spectab[0] + 1;
47214645Sslatteng *spectab[0] = '\0';
47314645Sslatteng *spectab[1] = '\0';
47414645Sslatteng }
47514087Sslatteng }
47614087Sslatteng
47714087Sslatteng
47814087Sslatteng /* just got "p#" command. print the current page and */
t_page(n)47914087Sslatteng t_page(n) /* do whatever new page functions */
48014087Sslatteng {
48114087Sslatteng long ftell();
48214087Sslatteng int c, m, i;
48314087Sslatteng char buf[100], *bp;
48414087Sslatteng
48514087Sslatteng pgnum[np++] = n;
48614087Sslatteng pgadr[np] = ftell(fp);
48714087Sslatteng if (np > npmax)
48814087Sslatteng npmax = np;
48914087Sslatteng if (output == 0) {
49014087Sslatteng output = in_olist(n);
49114087Sslatteng t_init(1);
49214087Sslatteng return;
49314087Sslatteng }
49414087Sslatteng
49514087Sslatteng putpage();
49614087Sslatteng fflush(stdout);
49714087Sslatteng
49814816Sslatteng if (clearsc) putchar('');
49914087Sslatteng if (keepon) {
50014087Sslatteng t_init(1);
50114087Sslatteng return;
50214087Sslatteng }
50314087Sslatteng next:
50414087Sslatteng for (bp = buf; (*bp = readch()); )
50514087Sslatteng if (*bp++ == '\n')
50614087Sslatteng break;
50714087Sslatteng *bp = 0;
50814087Sslatteng switch (buf[0]) {
50914087Sslatteng case 0:
51014087Sslatteng done();
51114087Sslatteng break;
51214087Sslatteng case '\n':
51314087Sslatteng output = in_olist(n);
51414087Sslatteng t_init(1);
51514087Sslatteng return;
51614087Sslatteng case '-':
51714087Sslatteng case 'p':
51814087Sslatteng m = atoi(&buf[1]) + 1;
51914087Sslatteng if (fp == stdin) {
52014087Sslatteng fputs("you can't; it's not a file\n", stderr);
52114087Sslatteng break;
52214087Sslatteng }
52314087Sslatteng if (np - m <= 0) {
52414087Sslatteng fputs("too far back\n", stderr);
52514087Sslatteng break;
52614087Sslatteng }
52714087Sslatteng np -= m;
52814087Sslatteng fseek(fp, pgadr[np], 0);
52914087Sslatteng output = 1;
53014087Sslatteng t_init(1);
53114087Sslatteng return;
53214087Sslatteng case '0': case '1': case '2': case '3': case '4':
53314087Sslatteng case '5': case '6': case '7': case '8': case '9':
53414087Sslatteng m = atoi(&buf[0]);
53514087Sslatteng for (i = 0; i < npmax; i++)
53614087Sslatteng if (m == pgnum[i])
53714087Sslatteng break;
53814087Sslatteng if (i >= npmax || fp == stdin) {
53914087Sslatteng fputs("you can't\n", stderr);
54014087Sslatteng break;
54114087Sslatteng }
54214087Sslatteng np = i + 1;
54314087Sslatteng fseek(fp, pgadr[np], 0);
54414087Sslatteng output = 1;
54514087Sslatteng t_init(1);
54614087Sslatteng return;
54714087Sslatteng case 'o':
54814087Sslatteng outlist(&buf[1]);
54914087Sslatteng output = 0;
55014087Sslatteng t_init(1);
55114087Sslatteng return;
55214087Sslatteng case '?':
55314087Sslatteng fputs("p print this page again\n", stderr);
55414087Sslatteng fputs("-n go back n pages\n", stderr);
55514087Sslatteng fputs("n print page n (previously printed)\n", stderr);
55614087Sslatteng fputs("o... set the -o output list to ...\n", stderr);
55714087Sslatteng break;
55814087Sslatteng default:
55914087Sslatteng fputs("?\n", stderr);
56014087Sslatteng break;
56114087Sslatteng }
56214087Sslatteng goto next;
56314087Sslatteng }
56414087Sslatteng
56514087Sslatteng /* print the contents of the current page. puts out */
putpage()56614087Sslatteng putpage() /* only the part of the page that's been written on */
56715279Sslatteng { /* unless "margin" is set. */
56814087Sslatteng int i, j, k;
56914087Sslatteng
57014087Sslatteng fflush(stdout);
57115279Sslatteng if (margin) minv = minh = 0;
57214087Sslatteng for (i = minv; i <= maxv; i++) {
57314087Sslatteng for (k = maxh; pagebuf[i][k] == ' '; k--)
57414087Sslatteng ;
57514087Sslatteng if (k > minh + linelen)
57614087Sslatteng k = minh + linelen;
57714087Sslatteng for (j = minh; j <= k; j++)
57814087Sslatteng putchar(pagebuf[i][j]);
57914087Sslatteng putchar('\n');
58014087Sslatteng }
58114087Sslatteng fflush(stdout);
58214087Sslatteng }
58314087Sslatteng
58414087Sslatteng
t_text(s)58514087Sslatteng t_text(s) /* print string s as text */
58614087Sslatteng char *s;
58714087Sslatteng {
58814087Sslatteng int c;
58914087Sslatteng char str[100];
59014087Sslatteng
59114087Sslatteng if (!output)
59214087Sslatteng return;
59314087Sslatteng while ((c = *s++) != '\n') {
59414087Sslatteng if (c == '\\') {
59514087Sslatteng switch (c = *s++) {
59614087Sslatteng case '\\':
59714087Sslatteng case 'e':
59814087Sslatteng put1('\\');
59914087Sslatteng break;
60014087Sslatteng case '(':
60114087Sslatteng str[0] = *s++;
60214087Sslatteng str[1] = *s++;
60314087Sslatteng str[2] = '\0';
60414087Sslatteng put1s(str);
60514087Sslatteng break;
60614087Sslatteng }
60714087Sslatteng } else {
60814087Sslatteng put1(c);
60914087Sslatteng }
61016847Sslatteng hmot((int)hscale);
61114087Sslatteng }
61214087Sslatteng }
61314087Sslatteng
61414087Sslatteng
put1s(s)61514087Sslatteng put1s(s) /* s is a funny char name */
61614087Sslatteng char *s;
61714087Sslatteng {
61814087Sslatteng int i;
61914087Sslatteng char *p;
62014087Sslatteng static char prev[10] = "";
62114087Sslatteng static int previ;
62214087Sslatteng
62314087Sslatteng if (!output)
62414087Sslatteng return;
62514087Sslatteng if (strcmp(s, prev) != 0) {
62614087Sslatteng previ = -1;
62714645Sslatteng for (i = 0; *spectab[i] != '\0'; i += 2)
62814087Sslatteng if (strcmp(spectab[i], s) == 0) {
62914087Sslatteng strcpy(prev, s);
63014087Sslatteng previ = i;
63114087Sslatteng break;
63214087Sslatteng }
63314087Sslatteng }
63414087Sslatteng if (previ >= 0) {
63516847Sslatteng for (hmot((int)-hscale), p = spectab[previ+1]; *p; p++) {
63616847Sslatteng hmot((int)hscale);
63714087Sslatteng store(*p);
63816847Sslatteng }
63914087Sslatteng } else
64014645Sslatteng prev[0] = '\0';
64114087Sslatteng }
64214087Sslatteng
64314087Sslatteng
put1(c)64414087Sslatteng put1(c) /* output char c */
64514087Sslatteng int c;
64614087Sslatteng {
64714087Sslatteng if (!output)
64814087Sslatteng return;
64914087Sslatteng store(c);
65014087Sslatteng }
65114087Sslatteng
65214087Sslatteng
done()65314087Sslatteng done()
65414087Sslatteng {
65514087Sslatteng output = 1;
65614087Sslatteng putpage();
65714087Sslatteng fflush(stdout);
65814087Sslatteng exit(0);
65914087Sslatteng }
66014087Sslatteng
66114087Sslatteng
readch()66214087Sslatteng readch ()
66314087Sslatteng {
66414087Sslatteng int c;
66514087Sslatteng static FILE *rcf;
66614087Sslatteng static nbol; /* 0 if at beginning of a line */
66714087Sslatteng
66814087Sslatteng if (rcf == NULL) {
66914087Sslatteng rcf = fopen ("/dev/tty", "r");
67014087Sslatteng setbuf (rcf, NULL);
67114087Sslatteng }
67214087Sslatteng
67314087Sslatteng if (!nbol)
67414087Sslatteng fprintf (stderr, "dterm: "); /* issue prompt */
67514087Sslatteng if ((c = getc (rcf)) == EOF)
67614087Sslatteng return 0;
67714087Sslatteng nbol = (c != '\n');
67814087Sslatteng return c;
67914087Sslatteng }
68014087Sslatteng
68114087Sslatteng
store(c)68214087Sslatteng store(c) /* put 'c' in the page at (hpos, vpos) */
68314087Sslatteng {
68414087Sslatteng register int i;
68514087Sslatteng register int j;
68614087Sslatteng
68714087Sslatteng
68814087Sslatteng i = hpos / hscale; /* scale the position to page coordinates */
68914087Sslatteng j = vpos / vscale;
69014087Sslatteng
69114087Sslatteng if (i >= PGWIDTH) i = PGWIDTH - 1; /* don't go over the edge */
69214087Sslatteng else if (i < 0) i = 0;
69314087Sslatteng if (j >= PGHEIGHT) j = PGHEIGHT - 1;
69414087Sslatteng else if (j < 0) j = 0;
69514087Sslatteng
69614087Sslatteng pagebuf[j][i] = c; /* write the character */
69714087Sslatteng
69814087Sslatteng if (i > maxh) maxh = i; /* update the page bounds */
69914087Sslatteng if (i < minh) minh = i;
70014087Sslatteng if (j > maxv) maxv = j;
70114087Sslatteng if (j < minv) minv = j;
70214087Sslatteng }
70314087Sslatteng
70414087Sslatteng
drawline(dx,dy)70516389Sslatteng drawline(dx, dy) /* draw line from here to dx, dy using s */
70614087Sslatteng int dx, dy;
70714087Sslatteng {
70814087Sslatteng register int xd;
70914087Sslatteng register int yd;
71014087Sslatteng register int i;
71114087Sslatteng register int numdots;
71214087Sslatteng int dirmot, perp;
71314087Sslatteng int motincr, perpincr;
71414087Sslatteng int ohpos, ovpos;
71514087Sslatteng float val, slope;
71614087Sslatteng float incrway;
71714087Sslatteng
71814087Sslatteng ohpos = hpos;
71914087Sslatteng ovpos = vpos;
72014087Sslatteng xd = dx / DP;
72114087Sslatteng yd = dy / DP;
72214087Sslatteng if (xd == 0) {
72314087Sslatteng numdots = abs (yd);
72414087Sslatteng numdots = min(numdots, maxdots);
72514087Sslatteng motincr = DP * sgn (yd);
72616286Sslatteng put1('|');
72714087Sslatteng for (i = 0; i < numdots; i++) {
72814087Sslatteng vmot(motincr);
72916286Sslatteng put1('|');
73014087Sslatteng }
73114087Sslatteng } else
73214087Sslatteng if (yd == 0) {
73314087Sslatteng numdots = abs (xd);
73414816Sslatteng numdots = min(numdots, maxdots);
73514087Sslatteng motincr = DP * sgn (xd);
73616286Sslatteng put1('-');
73714087Sslatteng for (i = 0; i < numdots; i++) {
73814087Sslatteng hmot(motincr);
73916286Sslatteng put1('-');
74014087Sslatteng }
74114087Sslatteng } else {
74214087Sslatteng if (abs (xd) > abs (yd)) {
74314087Sslatteng val = slope = (float) xd/yd;
74414087Sslatteng numdots = abs (xd);
74514087Sslatteng dirmot = 'h';
74614087Sslatteng perp = 'v';
74714087Sslatteng motincr = DP * sgn (xd);
74814087Sslatteng perpincr = DP * sgn (yd);
74914087Sslatteng } else {
75014087Sslatteng val = slope = (float) yd/xd;
75114087Sslatteng numdots = abs (yd);
75214087Sslatteng dirmot = 'v';
75314087Sslatteng perp = 'h';
75414087Sslatteng motincr = DP * sgn (yd);
75514087Sslatteng perpincr = DP * sgn (xd);
75614087Sslatteng }
75714645Sslatteng numdots = min(numdots, maxdots);
75814087Sslatteng incrway = sgn ((int) slope);
75916286Sslatteng put1('*');
76014087Sslatteng for (i = 0; i < numdots; i++) {
76114087Sslatteng val -= incrway;
76214087Sslatteng if (dirmot == 'h')
76314087Sslatteng hmot(motincr);
76414087Sslatteng else
76514087Sslatteng vmot(motincr);
76614087Sslatteng if (val * slope < 0) {
76714087Sslatteng if (perp == 'h')
76814087Sslatteng hmot(perpincr);
76914087Sslatteng else
77014087Sslatteng vmot(perpincr);
77114087Sslatteng val += slope;
77214087Sslatteng }
77316286Sslatteng put1('*');
77414087Sslatteng }
77514087Sslatteng }
77614087Sslatteng hgoto(ohpos + dx);
77714087Sslatteng vgoto(ovpos + dy);
77814087Sslatteng }
77914087Sslatteng
78014087Sslatteng
drawwig(s,poly)78116389Sslatteng drawwig(s, poly) /* draw wiggly line or polygon, if "poly" set */
78214087Sslatteng char *s;
78316389Sslatteng int poly;
78414087Sslatteng {
78514087Sslatteng int x[50], y[50], xp, yp, pxp, pyp;
78614087Sslatteng float t1, t2, t3, w;
78714087Sslatteng int i, j, numdots, N;
78814087Sslatteng char temp[50], *p, *getstr();
78914087Sslatteng
79014087Sslatteng p = s;
79114087Sslatteng for (N = 2; (p=getstr(p,temp)) != NULL && N < sizeof(x)/sizeof(x[0]);) {
79214087Sslatteng x[N] = atoi(temp);
79314087Sslatteng p = getstr(p, temp);
79414087Sslatteng y[N++] = atoi(temp);
79514087Sslatteng }
79616389Sslatteng if (poly) {
79716389Sslatteng for (i = 2; i < N; i++)
79816389Sslatteng drawline(x[i], y[i]);
79916389Sslatteng return;
80016389Sslatteng }
80114087Sslatteng x[0] = x[1] = hpos;
80214087Sslatteng y[0] = y[1] = vpos;
80314087Sslatteng for (i = 1; i < N; i++) {
80414087Sslatteng x[i+1] += x[i];
80514087Sslatteng y[i+1] += y[i];
80614087Sslatteng }
80714087Sslatteng x[N] = x[N-1];
80814087Sslatteng y[N] = y[N-1];
80914087Sslatteng pxp = pyp = -9999;
81014087Sslatteng for (i = 0; i < N-1; i++) { /* interval */
81114087Sslatteng numdots = (dist(x[i], y[i], x[i+1], y[i+1])
81214087Sslatteng + dist(x[i+1], y[i+1], x[i+2], y[i+2])) / 2;
81314087Sslatteng numdots /= DP;
81414087Sslatteng numdots = min(numdots, maxdots);
81514087Sslatteng for (j = 0; j < numdots; j++) { /* points within */
81614087Sslatteng w = (float) j / numdots;
81714087Sslatteng t1 = 0.5 * w * w;
81814087Sslatteng w = w - 0.5;
81914087Sslatteng t2 = 0.75 - w * w;
82014087Sslatteng w = w - 0.5;
82114087Sslatteng t3 = 0.5 * w * w;
82214087Sslatteng xp = t1 * x[i+2] + t2 * x[i+1] + t3 * x[i] + 0.5;
82314087Sslatteng yp = t1 * y[i+2] + t2 * y[i+1] + t3 * y[i] + 0.5;
82414087Sslatteng if (xp != pxp || yp != pyp) {
82514087Sslatteng hgoto(xp);
82614087Sslatteng vgoto(yp);
82716286Sslatteng put1('*');
82814087Sslatteng pxp = xp;
82914087Sslatteng pyp = yp;
83014087Sslatteng }
83114087Sslatteng }
83214087Sslatteng }
83314087Sslatteng }
83414087Sslatteng
83514087Sslatteng
83614087Sslatteng /* copy next non-blank string from p to temp, update p */
83714087Sslatteng
getstr(p,temp)83814087Sslatteng char *getstr(p, temp)
83914087Sslatteng char *p, *temp;
84014087Sslatteng {
84114087Sslatteng while (*p == ' ' || *p == '\t' || *p == '\n')
84214087Sslatteng p++;
84314087Sslatteng if (*p == '\0') {
84414087Sslatteng temp[0] = 0;
84514087Sslatteng return(NULL);
84614087Sslatteng }
84714087Sslatteng while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0')
84814087Sslatteng *temp++ = *p++;
84914087Sslatteng *temp = '\0';
85014087Sslatteng return(p);
85114087Sslatteng }
85214087Sslatteng
85314087Sslatteng
drawcirc(d)85414087Sslatteng drawcirc(d)
85514087Sslatteng {
85614087Sslatteng int xc, yc;
85714087Sslatteng
85814087Sslatteng xc = hpos;
85914087Sslatteng yc = vpos;
86014087Sslatteng conicarc(hpos + d/2, -vpos, hpos, -vpos, hpos, -vpos, d/2, d/2);
86114087Sslatteng hgoto(xc + d); /* circle goes to right side */
86214087Sslatteng vgoto(yc);
86314087Sslatteng }
86414087Sslatteng
86514087Sslatteng
dist(x1,y1,x2,y2)86614087Sslatteng dist(x1, y1, x2, y2) /* integer distance from x1,y1 to x2,y2 */
86714087Sslatteng {
86814087Sslatteng float dx, dy;
86914087Sslatteng
87014087Sslatteng dx = x2 - x1;
87114087Sslatteng dy = y2 - y1;
87214087Sslatteng return sqrt(dx*dx + dy*dy) + 0.5;
87314087Sslatteng }
87414087Sslatteng
87514087Sslatteng
drawarc(dx1,dy1,dx2,dy2)87614087Sslatteng drawarc(dx1, dy1, dx2, dy2)
87714087Sslatteng {
87814087Sslatteng int x0, y0, x2, y2, r;
87914087Sslatteng
88014087Sslatteng x0 = hpos + dx1; /* center */
88114087Sslatteng y0 = vpos + dy1;
88214087Sslatteng x2 = x0 + dx2; /* "to" */
88314087Sslatteng y2 = y0 + dy2;
88414087Sslatteng r = sqrt((float) dx1 * dx1 + (float) dy1 * dy1) + 0.5;
88514087Sslatteng conicarc(x0, -y0, hpos, -vpos, x2, -y2, r, r);
88614087Sslatteng }
88714087Sslatteng
88814087Sslatteng
drawellip(a,b)88914087Sslatteng drawellip(a, b)
89014087Sslatteng {
89114087Sslatteng int xc, yc;
89214087Sslatteng
89314087Sslatteng xc = hpos;
89414087Sslatteng yc = vpos;
89514087Sslatteng conicarc(hpos + a/2, -vpos, hpos, -vpos, hpos, -vpos, a/2, b/2);
89614087Sslatteng hgoto(xc + a);
89714087Sslatteng vgoto(yc);
89814087Sslatteng }
89914087Sslatteng
90014087Sslatteng
conicarc(x,y,x0,y0,x1,y1,a,b)90114087Sslatteng conicarc(x, y, x0, y0, x1, y1, a, b)
90214087Sslatteng {
90314087Sslatteng /* based on Bresenham, CACM Feb 77, pp 102-3 by Chris Van Wyk */
90414087Sslatteng /* capitalized vars are an internal reference frame */
90514087Sslatteng long dotcount = 0;
90614087Sslatteng int xs, ys, xt, yt, Xs, Ys, qs, Xt, Yt, qt,
90714087Sslatteng M1x, M1y, M2x, M2y, M3x, M3y,
90814087Sslatteng Q, move, Xc, Yc;
90914087Sslatteng int ox1, oy1;
91014087Sslatteng long delta;
91114087Sslatteng float xc, yc;
91214087Sslatteng float radius, slope;
91314087Sslatteng float xstep, ystep;
91414087Sslatteng
91514087Sslatteng ox1 = x1;
91614087Sslatteng oy1 = y1;
91714087Sslatteng if (a != b) /* an arc of an ellipse; internally, think of circle */
91814087Sslatteng if (a > b) {
91914087Sslatteng xstep = (float)a / b;
92014087Sslatteng ystep = 1;
92114087Sslatteng radius = b;
92214087Sslatteng } else {
92314087Sslatteng xstep = 1;
92414087Sslatteng ystep = (float)b / a;
92514087Sslatteng radius = a;
92614087Sslatteng }
92714087Sslatteng else {
92814087Sslatteng /* a circular arc; radius computed from center and first point */
92914087Sslatteng xstep = ystep = 1;
93014087Sslatteng radius = sqrt((float)(sqr(x0 - x) + sqr(y0 - y)));
93114087Sslatteng }
93214087Sslatteng
93314087Sslatteng xc = x0;
93414087Sslatteng yc = y0;
93514087Sslatteng /* now, use start and end point locations to figure out
93614087Sslatteng the angle at which start and end happen; use these
93714087Sslatteng angles with known radius to figure out where start
93814087Sslatteng and end should be
93914087Sslatteng */
94014087Sslatteng slope = atan2((double)(y0 - y), (double)(x0 - x) );
94114087Sslatteng if (slope == 0.0 && x0 < x)
94214087Sslatteng slope = 3.14159265;
94314087Sslatteng x0 = x + radius * cos(slope) + 0.5;
94414087Sslatteng y0 = y + radius * sin(slope) + 0.5;
94514087Sslatteng slope = atan2((double)(y1 - y), (double)(x1 - x));
94614087Sslatteng if (slope == 0.0 && x1 < x)
94714087Sslatteng slope = 3.14159265;
94814087Sslatteng x1 = x + radius * cos(slope) + 0.5;
94914087Sslatteng y1 = y + radius * sin(slope) + 0.5;
95014087Sslatteng /* step 2: translate to zero-centered circle */
95114087Sslatteng xs = x0 - x;
95214087Sslatteng ys = y0 - y;
95314087Sslatteng xt = x1 - x;
95414087Sslatteng yt = y1 - y;
95514087Sslatteng /* step 3: normalize to first quadrant */
95614087Sslatteng if (xs < 0)
95714087Sslatteng if (ys < 0) {
95814087Sslatteng Xs = abs(ys);
95914087Sslatteng Ys = abs(xs);
96014087Sslatteng qs = 3;
96114087Sslatteng M1x = 0;
96214087Sslatteng M1y = -1;
96314087Sslatteng M2x = 1;
96414087Sslatteng M2y = -1;
96514087Sslatteng M3x = 1;
96614087Sslatteng M3y = 0;
96714087Sslatteng } else {
96814087Sslatteng Xs = abs(xs);
96914087Sslatteng Ys = abs(ys);
97014087Sslatteng qs = 2;
97114087Sslatteng M1x = -1;
97214087Sslatteng M1y = 0;
97314087Sslatteng M2x = -1;
97414087Sslatteng M2y = -1;
97514087Sslatteng M3x = 0;
97614087Sslatteng M3y = -1;
97714087Sslatteng }
97814087Sslatteng else if (ys < 0) {
97914087Sslatteng Xs = abs(xs);
98014087Sslatteng Ys = abs(ys);
98114087Sslatteng qs = 0;
98214087Sslatteng M1x = 1;
98314087Sslatteng M1y = 0;
98414087Sslatteng M2x = 1;
98514087Sslatteng M2y = 1;
98614087Sslatteng M3x = 0;
98714087Sslatteng M3y = 1;
98814087Sslatteng } else {
98914087Sslatteng Xs = abs(ys);
99014087Sslatteng Ys = abs(xs);
99114087Sslatteng qs = 1;
99214087Sslatteng M1x = 0;
99314087Sslatteng M1y = 1;
99414087Sslatteng M2x = -1;
99514087Sslatteng M2y = 1;
99614087Sslatteng M3x = -1;
99714087Sslatteng M3y = 0;
99814087Sslatteng }
99914087Sslatteng
100014087Sslatteng Xc = Xs;
100114087Sslatteng Yc = Ys;
100214087Sslatteng if (xt < 0)
100314087Sslatteng if (yt < 0) {
100414087Sslatteng Xt = abs(yt);
100514087Sslatteng Yt = abs(xt);
100614087Sslatteng qt = 3;
100714087Sslatteng } else {
100814087Sslatteng Xt = abs(xt);
100914087Sslatteng Yt = abs(yt);
101014087Sslatteng qt = 2;
101114087Sslatteng }
101214087Sslatteng else if (yt < 0) {
101314087Sslatteng Xt = abs(xt);
101414087Sslatteng Yt = abs(yt);
101514087Sslatteng qt = 0;
101614087Sslatteng } else {
101714087Sslatteng Xt = abs(yt);
101814087Sslatteng Yt = abs(xt);
101914087Sslatteng qt = 1;
102014087Sslatteng }
102114087Sslatteng
102214087Sslatteng /* step 4: calculate number of quadrant crossings */
102314087Sslatteng if (((4 + qt - qs) % 4 == 0) && (Xt <= Xs) && (Yt >= Ys))
102414087Sslatteng Q = 3;
102514087Sslatteng else
102614087Sslatteng Q = (4 + qt - qs) % 4 - 1;
102714087Sslatteng /* step 5: calculate initial decision difference */
102814087Sslatteng delta = sqr(Xs + 1) + sqr(Ys - 1) - sqr(xs) - sqr(ys);
102914087Sslatteng /* here begins the work of drawing. */
103014087Sslatteng while ((Q >= 0) || ((Q > -2) && ((Xt > Xc) && (Yt < Yc)))) {
103116286Sslatteng if (dotcount++ % DP == 0) {
103216286Sslatteng hgoto((int)xc);
103316286Sslatteng vmot(-vpos-((int)yc));
103416286Sslatteng put1('*');
103516286Sslatteng }
103614087Sslatteng if (Yc < 0.5) {
103714087Sslatteng /* reinitialize */
103814087Sslatteng Xs = Xc = 0;
103914087Sslatteng Ys = Yc = sqrt((float)(sqr(xs) + sqr(ys)));
104014087Sslatteng delta = sqr(Xs + 1) + sqr(Ys - 1) - sqr(xs) - sqr(ys);
104114087Sslatteng Q--;
104214087Sslatteng M1x = M3x;
104314087Sslatteng M1y = M3y;
104414087Sslatteng {
104514087Sslatteng int T;
104614087Sslatteng T = M2y;
104714087Sslatteng M2y = M2x;
104814087Sslatteng M2x = -T;
104914087Sslatteng T = M3y;
105014087Sslatteng M3y = M3x;
105114087Sslatteng M3x = -T;
105214087Sslatteng }
105314087Sslatteng } else {
105414087Sslatteng if (delta <= 0)
105514087Sslatteng if (2 * delta + 2 * Yc - 1 <= 0)
105614087Sslatteng move = 1;
105714087Sslatteng else
105814087Sslatteng move = 2;
105914087Sslatteng else if (2 * delta - 2 * Xc - 1 <= 0)
106014087Sslatteng move = 2;
106114087Sslatteng else
106214087Sslatteng move = 3;
106314087Sslatteng switch (move) {
106414087Sslatteng case 1:
106514087Sslatteng Xc++;
106614087Sslatteng delta += 2 * Xc + 1;
106714087Sslatteng xc += M1x * xstep;
106814087Sslatteng yc += M1y * ystep;
106914087Sslatteng break;
107014087Sslatteng case 2:
107114087Sslatteng Xc++;
107214087Sslatteng Yc--;
107314087Sslatteng delta += 2 * Xc - 2 * Yc + 2;
107414087Sslatteng xc += M2x * xstep;
107514087Sslatteng yc += M2y * ystep;
107614087Sslatteng break;
107714087Sslatteng case 3:
107814087Sslatteng Yc--;
107914087Sslatteng delta -= 2 * Yc + 1;
108014087Sslatteng xc += M3x * xstep;
108114087Sslatteng yc += M3y * ystep;
108214087Sslatteng break;
108314087Sslatteng }
108414087Sslatteng }
108514087Sslatteng }
108616389Sslatteng drawline((int)xc-ox1,(int)yc-oy1);
108714087Sslatteng }
1088