source: tags/initial/GDE/PHYLIP/drawgraphics.c

Last change on this file was 2, checked in by oldcode, 24 years ago

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 53.3 KB
Line 
1#include "drawgraphics.h"
2
3#ifdef QUICKC
4struct videoconfig myscreen;
5void   setupgraphics();
6#endif
7
8Static colortype colors[7] = {
9  {"White    ",0.9,0.9,0.9},
10  {"Red      ",1.0,0.3,0.3},
11  {"Orange   ",1.0,0.6,0.6},
12  {"Yellow   ",1.0,0.9,0.4},
13  {"Green    ",0.3,0.8,0.3},
14  {"Blue     ",0.5,0.5,1.0},
15  {"Violet   ",0.6,0.4,0.8},
16};
17
18/*
19 * Used ONLY here: */
20
21static long eb[]={
22  0 , 1 ,2 ,3 ,55,45,46,47,22,5,37,11,12,13,14,15,16,17,18,19,60,61,50,38,
23  24, 25,63,39,28,29,30,31,64,90,127,123,91,108,80,125,77,93,92,78,107,96,
24  75,97,240,241,242,243,244,245,246,247,248,249,122,94,76,126,110,111, 124,
25  193,194,195,196,197,198,199,200,201,209,210,211, 212,213,214,215,216,217,
26  226,227,228,229,230,231,232,233,173,224,189, 95,109,121,129,130,131,132,
27  133,134,135,136,137,145,146,147,148,149,150, 151, 152,153,162,163,164,165,
28  166,167,168,169,192,79,208,161,7};
29
30long   hpresolution,nmoves,oldpictint,oldx,oldy,bytewrite;
31double  labelline,linewidth,oldxhigh,oldxlow,oldyhigh,oldylow,oldxreal,
32        oldyreal,raylinewidth,treeline,oldxsize,oldysize,oldxunitspercm,
33        oldyunitspercm,oldxcorner,oldycorner;
34long rootmatrix[51][51];
35long  HiMode,GraphDriver,GraphMode,LoMode;
36boolean didenter,didexit,didcompute;
37
38/* externals will move to .h file later. */
39extern long         strpbottom,strptop,strpwide,strpdeep,strpdiv;
40extern boolean       dotmatrix,empty,preview,previewing;
41extern double        expand,xcorner,xnow,xsize,xscale,xunitspercm,
42                                      ycorner,ynow,ysize,yscale,yunitspercm,
43                                      labelheight,ymargin;
44extern long          filesize,bytewrite;
45extern growth        grows;
46extern enum {yes,no} penchange,oldpenchange;
47extern FILE          *plotfile;
48extern plottertype   plotter,oldplotter,previewer;
49extern striptype     stripe;
50
51extern char pltfilename[100];
52
53void pout(n)
54long n;
55{
56#ifdef MAC
57  if (previewing)
58    printf("%*ld", (int)((long)(0.434295 * log((double)n) + 0.0001)), n);
59  else
60    fprintf(plotfile, "%*ld",
61            (int)((long)(0.434295 * log((double)n) + 0.0001)), n);
62#else
63  if (previewing)
64    printf("%*d", (int)((long)(0.434295 * log((double)n) + 0.0001)), n);
65  else
66    fprintf(plotfile, "%*d",
67            (int)((long)(0.434295 * log((double)n) + 0.0001)), n);
68#endif
69}  /* pout */
70
71
72long upbyte(num)
73long num;
74{
75  /* get upper nibble of byte */
76  long Result, i, j, bytenum, nibcount;
77  boolean done;
78
79  bytenum = 0;
80  done = false;
81  nibcount = 0;
82  i = num / 16;
83  i /= 16;
84  j = 1;
85  while (!done) {
86    bytenum += (i & 15) * j;
87    nibcount++;
88    if (nibcount == 2) {
89      Result = bytenum;
90      done = true;
91    } else {
92      j *= 16;
93      i /= 16;
94    }
95  }
96  return Result;
97}  /* upbyte */
98
99
100
101Local long lobyte(num)
102long num;
103{
104  /* get low order nibble of byte */
105  long Result, i, j, bytenum, nibcount;
106  boolean done;
107
108  bytenum = 0;
109  done = false;
110  nibcount = 0;
111  i = num;
112  j = 1;
113  while (!done) {
114    bytenum += (i & 15) * j;
115    nibcount++;
116    if (nibcount == 2) {
117      Result = bytenum;
118      done = true;
119    } else {
120      j *= 16;
121      i /= 16;
122    }
123  }
124  return Result;
125}  /* lobyte */
126
127
128void plotdot(ix, iy)
129long ix, iy;
130{
131  /* plot one dot at ix, iy */
132  long ix0, iy0, iy1, iy2;
133
134  iy0 = strptop - iy;
135  if ((unsigned)iy0 > strpdeep || ix <= 0 || ix > strpwide)
136    return;
137  empty = false;
138  ix0 = ix;
139  switch (plotter) {
140
141  case citoh:
142    iy1 = 1;
143    iy2 = iy0;
144    break;
145
146  case epson:
147    iy1 = 1;
148    iy2 = 7 - iy0;
149    break;
150
151  case oki:
152    iy1 = 1;
153    iy2 = 7 - iy0;
154    break;
155
156  case toshiba:
157    iy1 = iy0 / 6 + 1;
158    iy2 = 5 - iy0 % 6;
159    break;
160
161  case pcx:
162    iy1 = iy0 + 1;
163    ix0 = (ix - 1) / 8 + 1;
164    iy2 = 7 - ((ix - 1) & 7);
165    break;
166
167  case pcl:
168    iy1 = iy0 + 1;
169    ix0 = (ix - 1) / 8 + 1;
170    iy2 = 7 - ((ix - 1) & 7);
171    break;
172
173  case xbm:
174    iy1 = iy0 + 1;
175    ix0 = (ix - 1) / 8 + 1;
176    iy2 = (ix - 1) & 7;
177    break;
178
179  case other:
180    break;
181    /* code for making dot array for a new printer
182      goes here */
183  }
184  stripe[iy1 - 1][ix0 - 1] |= (unsigned char)1<<iy2;
185}  /* plotdot */
186
187
188
189void drawpen(x, y, width)
190long x, y, width;
191{
192  long i, j, radius, low, hi;
193
194  radius = (long)floor(width / 2.0 + 0.5);
195  low = (long)floor(0.5 - width / 2.0);
196  hi = width - low;
197  if (y + hi < strpbottom || y + low > strptop) {
198    if (didenter)
199      didexit = true;
200    return;
201  }
202  if (!didenter)
203    didenter = true;
204  for (i = low; i <= hi; i++) {
205    for (j = low; j <= hi; j++) {
206      if (rootmatrix[abs(i)][abs(j)] <= radius){
207        plotdot(x + i, y + j);
208        plotdot(x + i, y - j);
209        plotdot(x - i, y + j);
210        plotdot(x - 1, y - j);}
211    }
212  }
213}  /* drawpen */
214
215
216
217
218void drawfatline(ixabs, iyabs, ixnow, iynow, penwide)
219long ixabs, iyabs, ixnow, iynow, penwide;
220{
221  long temp, xdiff, ydiff, err, x1, y1;
222
223  didenter = false;
224  didexit = false;
225
226  if (ixabs < ixnow) {
227    temp = ixnow;
228    ixnow = ixabs;
229    ixabs = temp;
230    temp = iynow;
231    iynow = iyabs;
232    iyabs = temp;
233  }
234  xdiff = ixabs - ixnow;
235  ydiff = iyabs - iynow;
236  if (ydiff >= 0) {
237    if (xdiff >= ydiff) {
238      err = -(xdiff / 2);
239      x1 = ixnow;
240      while (x1 <= ixabs && !(didenter && didexit)) {
241        drawpen(x1, iynow, penwide);
242        err += ydiff;
243        if (err > 0) {
244          iynow++;
245          err -= xdiff;
246        }
247        x1++;
248      }
249      return;
250    }
251    err = -(ydiff / 2);
252    y1 = iynow;
253    while (y1 < iyabs && !(didenter && didexit)) {
254      drawpen(ixnow, y1, penwide);
255      err += xdiff;
256      if (err > 0) {
257        ixnow++;
258        err -= ydiff;
259      }
260      y1++;
261    }
262    return;
263  }
264  if (xdiff < -ydiff) {
265    err = ydiff / 2;
266    y1 = iynow;
267    while (y1 >= iyabs && !(didenter && didexit)) {
268      drawpen(ixnow, y1, penwide);
269      err += xdiff;
270      if (err > 0) {
271        ixnow++;
272        err += ydiff;
273      }
274      y1--;
275    }
276    return;
277  }
278  err = -(xdiff / 2);
279  x1 = ixnow;
280  while (x1 <= ixabs && !(didenter && didexit)) {
281    drawpen(x1, iynow, penwide);
282    err -= ydiff;
283    if (err > 0) {
284      iynow--;
285      err -= xdiff;
286    }
287    x1++;
288  }
289}  /* drawfatline */
290
291
292void plot(pen, xabs, yabs)
293pensttstype pen;
294double xabs, yabs;
295{
296  long xhigh, yhigh, xlow, ylow, newx, newy, ixnow, iynow, ixabs, iyabs,
297       ixleft, iyleft, ixbot, iybot, ixtop, iytop, cdx, cdy, temp;
298  long pictint;
299  double c, dx, dy, lscale, dxreal, dyreal;
300  Char picthi, pictlo;
301#ifdef MAC
302  queryevent();
303#endif
304  if (!dotmatrix || previewing) {
305    switch (plotter) {
306
307    case tek:
308      if (pen == penup) {
309        if (previewing)
310          putchar('\035');
311        else
312          putc('\035', plotfile);
313      }
314      ixnow = (long)floor(xabs + 0.5);
315      iynow = (long)floor(yabs + 0.5);
316      xhigh = ixnow / 32;
317      yhigh = iynow / 32;
318      xlow = ixnow & 31;
319      ylow = iynow & 31;
320      if (!ebcdic) {
321        if (yhigh != oldyhigh) {
322          if (previewing)
323            putchar(yhigh + 32);
324          else
325            putc(yhigh + 32, plotfile);
326        }
327        if (ylow != oldylow || xhigh != oldxhigh) {
328          if (previewing)
329            putchar(ylow + 96);
330          else
331            putc(ylow + 96, plotfile);
332        }
333        if (xhigh != oldxhigh) {
334          if (previewing)
335            putchar(xhigh + 32);
336          else
337            putc(xhigh + 32, plotfile);
338        }
339        if (previewing)
340          putchar(xlow + 64);
341        else
342          putc(xlow + 64, plotfile);
343      } else {  /* DLS/JMH -- for systems that use EBCDIC coding */
344        if (yhigh != oldyhigh) {
345          if (previewing)
346            putchar(eb[yhigh + 32]);
347          else
348            putc(eb[yhigh + 32], plotfile);
349        }
350        if (ylow != oldylow || xhigh != oldxhigh) {
351          if (previewing)
352            putchar(eb[ylow + 96]);
353          else
354            putc(eb[ylow + 96], plotfile);
355        }
356        if (xhigh != oldxhigh) {
357          if (previewing)
358            putchar(eb[xhigh + 32]);
359          else
360            putc(eb[xhigh + 32], plotfile);
361        }
362        if (previewing)
363          putchar(eb[xlow + 64]);
364        else
365          putc(eb[xlow + 64], plotfile);
366      }
367
368      oldxhigh = xhigh;
369      oldxlow = xlow;
370      oldyhigh = yhigh;
371      oldylow = ylow;
372      break;
373
374    case hp:
375      if (pen == pendown)
376        fprintf(plotfile, "PD");
377      else
378        fprintf(plotfile, "PU");
379      pout((long)floor(xabs + 0.5));
380      putc(',', plotfile);
381      pout((long)floor(yabs + 0.5));
382      fprintf(plotfile, ";\n");
383      break;
384
385    case pict:
386      newx = (long)floor(xabs + 0.5);
387      newy = (long)floor(ysize * yunitspercm - yabs + 0.5);
388      if (pen == pendown) {
389        if (linewidth > 5) {
390          dxreal = xabs - oldxreal;
391          dyreal = yabs - oldyreal;
392          lscale = sqrt(dxreal * dxreal + dyreal * dyreal) /
393            (fabs(dxreal) + fabs(dyreal));
394          pictint = (long)(lscale * linewidth + 0.5);
395
396          if (pictint == 0)
397            pictint = 1;
398          if (pictint != oldpictint) {
399            picthi = (Char)(pictint / 256);
400            pictlo = (Char)(pictint & 255);
401            fprintf(plotfile, "\007%c%c%c%c", picthi, pictlo, picthi, pictlo);
402          }
403          oldpictint = pictint;
404        }
405        fprintf(plotfile, " %c%c%c%c",
406                (Char)(oldy / 256), (Char)(oldy & 255), (Char)(oldx / 256),
407                (Char)(oldx & 255));
408        fprintf(plotfile, "%c%c%c%c",
409                (Char)(newy / 256), (Char)(newy & 255), (Char)(newx / 256),
410                (Char)(newx & 255));
411        }
412      oldxreal = xabs;
413      oldyreal = yabs;
414      oldx = newx;
415      oldy = newy;
416
417      break;
418#ifndef MAC
419    case ray:
420      if (pen == pendown) {
421        if (linewidth != treeline) {
422          if (raylinewidth > labelline) {
423            raylinewidth = labelline;
424            fprintf(plotfile, "end\n\n");
425            fprintf(plotfile, "name species_names\n");
426            fprintf(plotfile, "grid 22 22 22\n");
427          }
428        }
429
430        if (oldxreal != xabs || oldyreal != yabs) {
431          raylinewidth *= 0.99999;
432          fprintf(plotfile, "cylinder %8.7f %6.3f 0 %6.3f %6.3f 0 %6.3f\n",
433                  raylinewidth, oldxreal, oldyreal, xabs, yabs);
434          fprintf(plotfile, "sphere %8.7f %6.3f 0 %6.3f\n",
435                  raylinewidth, xabs, yabs);
436        }
437      }
438      oldxreal = xabs;
439      oldyreal = yabs;
440      break;
441#endif /* ifndef MAC */
442    case lw:
443      if (pen == pendown)
444        fprintf(plotfile, "%8.2f%8.2f lineto\n", xabs, yabs);
445      else
446        fprintf(plotfile, "stroke %8.2f%8.2f moveto\n", xabs, yabs);
447      break;
448
449    case ibmpc:
450#ifdef TURBOC
451    newx =  (long)(floor(xabs + 0.5));
452    newy = abs((long)(floor(yabs)) - getmaxy());
453    if (pen == pendown)
454        line(oldx,oldy,newx,newy);
455    oldx=newx;
456    oldy=newy;
457#endif
458#ifdef QUICKC
459    newx =  (long)(floor(xabs + 0.5));
460    newy = abs((long)(floor(yabs)) - myscreen.numypixels);
461
462    if (pen == pendown)
463        _lineto((long)newx,(long)newy);
464    else
465        _moveto((long)newx,(long)newy);
466    oldx=newx;
467    oldy=newy;
468
469#endif
470    break;
471     case mac:
472#ifdef MAC
473      if (pen == pendown){
474        LineTo((int)floor((double)xabs + 0.5),
475               342 - (long)floor((double)yabs + 0.5));}
476      else{
477        MoveTo((int)floor((double)xabs + 0.5),
478               342 - (long)floor((double)yabs + 0.5));}
479#endif
480
481      break;
482
483    case houston:
484      if (pen == pendown)
485        fprintf(plotfile, "D ");
486      else
487        fprintf(plotfile, "U ");
488      pout((long)((long)floor(xabs + 0.5)));
489      putc(',', plotfile);
490      pout((long)((long)floor(yabs + 0.5)));
491      putc('\n', plotfile);
492      break;
493
494    case decregis:
495      newx = (long)floor(xabs + 0.5);
496      newy = (long)abs((long)floor(yabs + 0.5) - 479);
497      if (pen == pendown) {
498        if (previewing) {
499          printf("P[");
500          pout(oldx);
501          putchar(',');
502          pout(oldy);
503          printf("]V[");
504          pout(newx);
505          putchar(',');
506          pout(newy);
507          putchar(']');
508        } else {
509          fprintf(plotfile, "P[");
510          pout(oldx);
511          putc(',', plotfile);
512          pout(oldy);
513          fprintf(plotfile, "]V[");
514          pout(newx);
515          putc(',', plotfile);
516          pout(newy);
517          putc(']', plotfile);
518        }
519        nmoves++;
520        if (nmoves == 3) {
521          nmoves = 0;
522          if (previewing)
523            putchar('\n');
524          else
525            putc('\n', plotfile);
526        }
527      }
528      oldx = newx;
529      oldy = newy;
530      break;
531
532    case fig:
533      newx = (long)floor(xabs + 0.5);
534      newy = (long)floor(yabs + 0.5);
535      if (pen == pendown) {
536        fprintf(plotfile, "2 1 0 %5ld 0 0 0 0 0.000 0 0\n",
537                (long)floor(linewidth + 0.5) + 1);
538        fprintf(plotfile, "%5ld%5ld%5ld%5ld 9999 9999\n",
539                oldx, 606 - oldy, newx, 606 - newy);
540
541        fprintf(plotfile,
542          "1 3 0  1 0 0 0 21 0.00 1 0.0 %5ld%5ld%5ld %5ld %5ld%5ld%5ld 349\n",
543          oldx, 606 - oldy, (long)floor(linewidth / 2 + 0.5),
544          (long)floor(linewidth / 2 + 0.5), oldx, 606 - oldy, 606 - oldy);
545        fprintf(plotfile,
546          "1 3 0  1 0 0 0 21 0.00 1 0.0 %5ld%5ld%5ld %5ld %5ld%5ld%5ld 349\n",
547          newx, 606 - newy, (long)floor(linewidth / 2 + 0.5),
548          (long)floor(linewidth / 2 + 0.5), newx, 606 - newy, 606 - newy);
549
550      }
551      oldx = newx;
552      oldy = newy;
553      break;
554    case other:
555      break;
556      /* code for a pen move on a new plotter goes here */
557    }
558    return;
559  }
560  if (pen == pendown) {
561    ixabs = (long)floor(xabs + 0.5);
562    iyabs = (long)floor(yabs + 0.5);
563    ixnow = (long)floor(xnow + 0.5);
564    iynow = (long)floor(ynow + 0.5);
565    if (ixnow > ixabs) {
566      temp = ixnow;
567      ixnow = ixabs;
568      ixabs = temp;
569      temp = iynow;
570      iynow = iyabs;
571      iyabs = temp;
572    }
573    dx = ixabs - ixnow;
574    dy = iyabs - iynow;
575   /* if (dx + fabs(dy) <= 0.0)
576      c = 0.0;
577    else
578      c = 0.5 * linewidth / sqrt(dx * dx + dy * dy); */
579    cdx = (long)floor(linewidth + 0.5);
580    cdy = (long)floor(linewidth + 0.5);
581    if ((iyabs + cdx >= strpbottom || iynow + cdx >= strpbottom) &&
582        (iyabs - cdx <= strptop || iynow - cdx <= strptop)) {
583      drawfatline(ixnow,iynow,ixabs,iyabs,(long)floor(linewidth+0.5));}
584  }
585
586  xnow = xabs;
587  ynow = yabs;
588
589  /* Bitmap Code to plot (xnow,ynow) to (xabs,yabs)                 */
590} /* plot                                                           */
591
592
593void pictoutint(file,pictint)
594FILE *file;
595long  pictint;
596{
597char picthi, pictlo;
598
599picthi = (char)(pictint / 256);
600pictlo = (char)(pictint % 256);
601fprintf(file, "%c%c", picthi, pictlo);
602}
603
604void initplotter(ntips,fontname)
605long ntips;
606char *fontname;
607{
608  long i,j, hres, vres;
609  Char picthi, pictlo;
610  long pictint;
611
612  treeline = 0.18 * labelheight * yscale * expand;
613  labelline = 0.06 * labelheight * yscale * expand;
614  linewidth = treeline;
615  if (dotmatrix ) {
616    for (i = 0; i <= 50; i++) {   /* for fast circle calculations */
617     for (j = 0; j <= 50; j++){
618       rootmatrix[i][j] =
619           (long)floor(sqrt((double)(i * i + j * j)) + 0.5);}
620   }
621  }
622 switch (plotter) {
623
624  case tek:
625    oldxhigh = -1.0;
626    oldxlow = -1.0;
627    oldyhigh = -1.0;
628    oldylow = -1.0;
629    nmoves = 0;       /* DLS/JMH -- See function  PLOT                  */
630    if (previewing)   /* DLS/JMH                                        */
631      printf("%c\f", escape);   /* DLS/JMH */
632    else
633      fprintf(plotfile, "%c\f", escape);
634    break;
635
636  case hp:
637    fprintf(plotfile, "IN;SP1;VS10.0;\n");
638    break;
639#ifndef MAC
640  case ray:
641    treeline = 0.27 * labelheight * yscale * expand;
642    linewidth = treeline;
643    raylinewidth = treeline;
644    if (grows == vertical)
645      fprintf(plotfile, "plane backcolor 0 0 %2.4f 0 0 1\n", ymargin);
646    else
647      fprintf(plotfile, "plane backcolor 0 0 %2.4f 0 0 1\n",
648              ymargin - ysize / (ntips - 1));
649
650    fprintf(plotfile, "\nname tree\n");
651    fprintf(plotfile, "grid 22 22 22\n");
652    break;
653#endif /* ifndef mac */
654   case pict:
655    plotfile = freopen(pltfilename,"wb",plotfile);
656    for (i=0;i<512;++i)
657      putc('\000',plotfile);
658    pictoutint(plotfile,1000); /* size...replaced later with seek */
659    pictoutint(plotfile,1);    /* bbx0   */
660    pictoutint(plotfile,1);    /* bby0   */
661    pictoutint(plotfile,612);  /* bbx1   */
662    pictoutint(plotfile,792);  /* bby1   */
663    fprintf(plotfile,"%c%c",0x11,0x01); /* version "1" (B&W) pict */
664    fprintf(plotfile,"%c%c%c",0xa0,0x00,0x82);
665    fprintf(plotfile,"%c",1);    /* clip rect */
666    pictoutint(plotfile,10);  /* region size, bytes. */
667    pictoutint(plotfile,1);   /* clip x0             */
668    pictoutint(plotfile,1);   /* clip y0             */
669    pictoutint(plotfile,612); /* clip x1             */
670    pictoutint(plotfile,792); /* clip y1             */
671   
672    bytewrite=543;
673
674    oldpictint = 0;
675    pictint = (long)(linewidth + 0.5);
676    if (pictint == 0)
677      pictint = 1;
678    picthi = (Char)(pictint / 256);
679    pictlo = (Char)(pictint % 256);
680    fprintf(plotfile, "\007%c%c%c%c", picthi, pictlo, picthi, pictlo);
681    /* Set pen size for drawing tree. */
682    break;
683
684  case xbm:  /* what a completely verbose data representation format.*/
685
686    fprintf(plotfile, "#define drawgram_width %5ld\n",
687            (long)(xunitspercm * xsize));
688    fprintf(plotfile, "#define drawgram_height %5ld\n",
689            (long)(yunitspercm * ysize));
690    fprintf(plotfile, "static char drawgram_bits[] = {\n");
691    /*filesize := 53;  */
692    break;
693  case lw:     /* write conforming encapsulated postscript */
694    fprintf(plotfile, "%%!PS-Adobe-2.0 EPSF-2.0\n");
695    fprintf(plotfile,"%%%%Creator: Phylip\n");
696    fprintf(plotfile,"%%%%Title:  phylip.ps\n%%%%Pages: 1\n");
697    fprintf(plotfile,"%%%%BoundingBox: 0 0 612 792\n");
698    fprintf(plotfile,"%%%%EndComments\n%%%%EndProlog\n%%%%Page: 1 1\n\n");
699    fprintf(plotfile," 1 setlinecap \n 1 setlinejoin  \n");
700    fprintf(plotfile, "%8.2f setlinewidth newpath \n", treeline);
701    break;
702
703  case ibmpc:
704#ifdef TURBOC
705    initgraph(&GraphDriver,&HiMode,"");
706#endif
707#ifdef QUICKC
708    setupgraphics();
709#endif
710    break;
711
712  case mac:
713#ifdef MAC
714    gfxmode();
715    pictint=(long)(linewidth + 0.5);
716    if (pictint == 0)
717         pictint=1;
718    PenSize((int)pictint,(int)pictint);
719#endif
720    break;
721
722  case houston:
723    break;
724
725  case decregis:
726    oldx = 300;
727    oldy = 1;
728    nmoves = 0;
729    if (previewing)
730          printf("%c[2J%cPpW(I3);SA[0,0][799,479];S(I(W))S(E);S(C00;W(I(D))\n",
731                 escape,escape);
732     else
733       fprintf(plotfile,
734               "%c[2J%cPpW(I3);S(A[0,0][799,479]);S(I(W))S(E);S(C0);W(I(D))\n",
735               escape,escape);
736    break;
737
738  case epson:
739    plotfile = freopen(pltfilename,"wb",plotfile);
740    fprintf(plotfile, "\0333\030");
741    break;
742
743  case oki:
744    plotfile = freopen(pltfilename,"wb",plotfile);
745    fprintf(plotfile, "\033%%9\020");
746    break;
747
748  case citoh:
749    plotfile = freopen(pltfilename,"wb",plotfile);
750    fprintf(plotfile, "\033T16");
751    break;
752
753  case toshiba: /* reopen in binary since we always need \n\r on the file */
754                /* and dos in text mode puts it, but unix does not        */
755    plotfile = freopen(pltfilename,"wb",plotfile);
756    fprintf(plotfile, "\033\032I\n\r\n\r");
757    fprintf(plotfile, "\033L06\n\r");
758    break;
759
760  case pcl:
761    plotfile = freopen(pltfilename,"wb",plotfile);
762    fprintf(plotfile, "\033&f0S");   /* Push current cursor */
763    if (hpresolution == 150 || hpresolution == 300)
764      fprintf(plotfile, "\033*t%3ldR", hpresolution);
765    else if (hpresolution == 75)
766      fprintf(plotfile, "\033*t75R");
767    break;
768
769  case pcx:
770    plotfile = freopen(pltfilename,"wb",plotfile);
771    fprintf(plotfile,"\012\003\001\001%c%c%c%c",0,0,0,0);
772  /* Manufacturer version (1 byte) version (1 byte), encoding (1 byte),
773     bits per pixel (1 byte), xmin (2 bytes) ymin (2 bytes),
774     Version */
775    hres = strpwide;
776    vres = (long)floor(yunitspercm * ysize + 0.5);
777    fprintf(plotfile, "%c%c", (unsigned char)lobyte(hres - 1),
778            (unsigned char)upbyte(hres - 1)); /* Xmax */
779    fprintf(plotfile, "%c%c", (unsigned char)lobyte(vres - 1),
780            (unsigned char)upbyte(vres - 1)); /* Ymax */
781    fprintf(plotfile, "%c%c", (unsigned char)lobyte(hres),
782            (unsigned char)upbyte(hres));
783    /* Horizontal resolution */
784    fprintf(plotfile, "%c%c", (unsigned char)lobyte(vres),
785            (unsigned char)upbyte(vres));
786    /* Vertical resolution */
787    for (i = 1; i <= 48; i++)  /* fill color map with 0 */
788      putc('\000', plotfile);
789    putc('\000', plotfile);
790    putc('\001', plotfile);   /* Num Planes */
791    putc(hres / 8, plotfile);   /* Bytes per line */
792    putc('\000',plotfile);
793    for (i = 1; i <= 60; i++)   /* Filler */
794      putc('\000',plotfile);
795    break;
796  case fig:
797    fprintf(plotfile, "#FIG 2.0\n");
798    fprintf(plotfile, "80 2\n");
799    break;
800  case other:
801    break;
802    /* initialization code for a new plotter goes here */
803  }
804}  /* initplotter */
805
806
807
808
809void finishplotter()
810{
811char trash;
812  switch (plotter) {
813
814  case tek:
815    if (previewing) {
816      scanf("%c%*[^\n]", &trash);
817      trash=getchar();
818      printf("%c\f", escape);
819    } else {
820      putc('\n', plotfile);
821      plot(penup, 1.0, 1.0);
822    }
823    break;
824
825  case hp:
826    plot(penup, 1.0, 1.0);
827    fprintf(plotfile, "SP;\n");
828    break;
829
830#ifndef MAC
831  case ray:
832    fprintf(plotfile,"end\n\nobject treecolor tree\n");
833    fprintf(plotfile,"object namecolor species_names\n");
834    break;
835#endif
836
837  case pict:
838    fprintf(plotfile,"%c%c%c%c%c",0xa0,0x00,0x82,0xff,0x00);
839    bytewrite+=5;
840#ifndef SEEK_SET
841#define SEEK_SET 0
842#endif
843    fseek(plotfile,512L,SEEK_SET);
844    pictoutint(plotfile,bytewrite);
845    break;
846
847
848  case lw:
849    fprintf(plotfile, "stroke showpage \n\n");
850    break;
851
852  case ibmpc:
853#ifdef TURBOC
854    trash=getchar();
855    restorecrtmode();
856#endif
857#ifdef QUICKC
858    trash=getchar();
859    _clearscreen(_GCLEARSCREEN);
860    _setvideomode(_DEFAULTMODE);
861#endif
862    break;
863
864  case mac:
865#ifdef MAC
866    if (previewing) {
867      scanf("%c%*[^\n]", &trash);
868      trash=getchar();
869      textmode();}
870#endif
871    break;
872
873  case houston:
874    break;
875
876  case decregis:
877    plot(penup, 1.0, 1.0);
878    if (previewing)
879      printf("%c\\", escape);
880    else
881      fprintf(plotfile, "%c\\", escape);
882    if (previewing) {
883      trash = getchar();
884      printf("%c[2J",escape);
885    }
886   
887    break;
888
889  case epson:
890    fprintf(plotfile, "\0333$");
891    break;
892
893  case oki:
894    /* blank case */
895    break;
896
897  case citoh:
898    fprintf(plotfile, "\033A");
899    break;
900
901  case toshiba:
902    fprintf(plotfile, "\033\032I\n\r");
903    break;
904
905  case pcl:
906    fprintf(plotfile, "\033&f1S");   /* pop cursor         */
907    fprintf(plotfile, "\033*rB");    /* Exit graphics mode */
908    putc('\f', plotfile);            /* just to make sure? */
909    break;
910
911  case pcx:
912    /* blank case */
913    break;
914
915  case xbm:
916    fprintf(plotfile, "}\n");
917    break;
918
919  case fig:
920    /* blank case */
921    break;
922  case other:
923    break;
924    /* termination code for a new plotter goes here */
925  }
926}  /* finishplotter */
927
928
929Local long SFactor()
930{
931  /* the dot-skip is resolution-independent. */
932  /* this makes all the point-skip instructions skip the same # of dots. */
933  long Result;
934
935  if (hpresolution == 150)
936    Result = 2;
937  if (hpresolution == 300)
938    Result = 1;
939  if (hpresolution == 75)
940    return 4;
941  return Result;
942}  /* SFactor */
943
944long DigitsInt(x)
945long x;
946{
947  if (x < 10)
948    return 1;
949  else if (x >= 10 && x < 100)
950    return 2;
951  else
952    return 3;
953}  /* DigistInt */
954
955Local boolean IsColumnEmpty(mystripe, pos,deep)
956striparray *mystripe;
957 long pos,deep;
958{
959  long j;
960  boolean ok;
961
962  ok = true;
963  j = 1;
964  while (ok && j <= deep) {
965    ok = (ok && mystripe[j - 1][pos - 1] == null);
966    j++;
967  }
968  return ok;
969}  /* IsColumnEmpty */
970
971void Skip(Amount)
972 long Amount;
973{
974  /* assume we're not in gfx mode. */
975  fprintf(plotfile, "\033&f1S");   /* Pop the graphics cursor    */
976#ifdef MAC
977  fprintf(plotfile, "\033*p+%*ldX",
978          (int)DigitsInt(Amount * SFactor()), Amount * SFactor());
979#else
980  fprintf(plotfile, "\033*p+%*dX",
981          (int)DigitsInt(Amount * SFactor()), Amount * SFactor());
982#endif
983  fprintf(plotfile, "\033&f0S");   /* Push the cursor to new location */
984  filesize += 15 + DigitsInt(Amount * SFactor());
985}  /* Skip */
986
987Local long FirstBlack(mystripe, startpos,deep)
988striparray *mystripe;
989 long startpos,deep;
990{
991  /* returns, given a strip and a position, next x with some y's nonzero */
992  long i;
993  boolean columnempty;
994
995  i = startpos;
996  columnempty = true;
997  while (columnempty && i < strpwide / 8) {
998    columnempty = (columnempty && IsColumnEmpty(mystripe, i,deep));
999    if (columnempty)
1000      i++;
1001  }
1002  return i;
1003}  /* FirstBlack */
1004
1005Local long FirstWhite(mystripe, startpos,deep)
1006striparray *mystripe;
1007 long startpos,deep;
1008{
1009  /* returns, given a strip and a position, the next x with all y's zero */
1010  long i;
1011  boolean columnempty;
1012
1013  i = startpos;
1014  columnempty = false;
1015  while (!columnempty && i < strpwide / 8) {
1016    columnempty = IsColumnEmpty(mystripe, i,deep);
1017    if (!columnempty)
1018      i++;
1019  }
1020  return i;
1021}  /* FirstWhite */
1022
1023Local boolean IsBlankStrip(mystripe,deep)
1024striparray *mystripe;
1025 long deep;
1026{
1027  long i, j;
1028  boolean ok;
1029
1030  ok = true;
1031  i = 1;
1032  while (ok && i <= strpwide / 8) {
1033    for (j = 0; j < (deep); j++)
1034      ok = (ok && mystripe[j][i - 1] == '\0');
1035    i++;
1036  }
1037  return ok;
1038}  /* IsBlankStrip */
1039
1040
1041void striprint(div,deep)
1042 long div,deep;
1043{
1044  long i, j, t, x, theend, width;
1045  Char counter;
1046  boolean done;
1047  done = false;
1048  width = strpwide;
1049  if (plotter != pcx && plotter != pcl) {
1050    while (!done) {
1051      for (i = 0; i < div; i++)
1052        done = (done || (stripe[i] && stripe[i][width - 1] != null));
1053      if (!done)
1054        width--;
1055      done = (done || width == 0);
1056    }
1057  }
1058  switch (plotter) {
1059
1060  case epson:
1061    if (!empty) {
1062      fprintf(plotfile, "\033L%c%c", width & 255, width / 256);
1063      for (i = 0; i < width; i++)
1064        putc(stripe[0][i], plotfile);
1065      filesize += width + 4;
1066    }
1067    putc('\n', plotfile);
1068    putc('\r', plotfile);
1069    break;
1070
1071  case oki:
1072    if (!empty) {
1073      fprintf(plotfile, "\033%%1%c%c", width / 128, width & 127);
1074      for (i = 0; i < width; i++)
1075        putc(stripe[0][i], plotfile);
1076      filesize += width + 5;
1077    }
1078    putc('\n', plotfile);
1079    putc('\r', plotfile);
1080    break;
1081
1082  case citoh:
1083    if (!empty) {
1084      fprintf(plotfile, "\033S%04ld",width);
1085      for (i = 0; i < width; i++)
1086        putc(stripe[0][i], plotfile);
1087      filesize += width + 6;
1088    }
1089
1090    putc('\n', plotfile);
1091    putc('\r', plotfile);
1092    break;
1093
1094  case toshiba:
1095    if (!empty) {
1096      for (i = 0; i < width; i++) {
1097        for (j = 0; j <= 3; j++)
1098          stripe[j][i] += 64;
1099      }
1100      fprintf(plotfile, "\033;%04ld",width);
1101
1102      for (i = 0; i < width; i++)
1103        fprintf(plotfile, "%c%c%c%c",
1104                stripe[0][i], stripe[1][i], stripe[2][i], stripe[3][i]);
1105      filesize += width * 4 + 6;
1106    }
1107    putc('\n', plotfile);
1108    putc('\r', plotfile);
1109    break;
1110
1111  case pcx:
1112    width = strpwide / 8;
1113    for (j = 0; j < div; j++) {
1114      t = 1;
1115      while (1) {
1116        i = 0; /* i == RLE count ???? */
1117        while ((stripe[j][t + i - 1]) == (stripe[j][t + i])
1118               && t + i < width && i < 63)
1119          i++;
1120        if (i > 0) {
1121          counter = 192;
1122          counter += i;
1123          putc(counter, plotfile);
1124          putc(255 - stripe[j][t - 1], plotfile);
1125          t += i;
1126          filesize += 2;
1127        } else {
1128          if (255 - (stripe[j][t - 1] & 255) >= 192) {
1129            putc(193, plotfile);
1130            filesize++;
1131          }
1132          putc(255 - stripe[j][t - 1], plotfile);
1133          t++;
1134          filesize++;
1135
1136        }
1137        if (t >width) break;
1138      }
1139    }
1140    break;
1141
1142  case pcl:
1143    width = strpwide / 8;
1144    if (IsBlankStrip(stripe,deep)) {
1145#ifdef MAC
1146      fprintf(plotfile, "\033&f1S\033*p0X\033*p+%*ldY\033&f0S",
1147              (int)DigitsInt(deep * SFactor()), deep * SFactor());
1148#else
1149      fprintf(plotfile, "\033&f1S\033*p0X\033*p+%*dY\033&f0S",
1150              (int)DigitsInt(deep * SFactor()), deep * SFactor());
1151#endif
1152      filesize += 20 + DigitsInt(deep * SFactor());
1153    } else {  /* plotting the actual strip as bitmap data */
1154      x = 1;
1155      theend = 1;
1156      while (x < width) {
1157        x = FirstBlack(stripe, x,deep);    /* all-black strip is now    */
1158        Skip((x - theend - 1) * 8);        /* x..theend                 */
1159        theend = FirstWhite(stripe, x,deep) - 1;/* like lastblack            */
1160        fprintf(plotfile, "\033*r1A");     /* enter gfx mode            */
1161        for (j = 0; j < div; j++) {
1162#ifdef MAC
1163          fprintf(plotfile, "\033*b%*ldW",
1164                  (int)DigitsInt(theend - x + 1), theend - x + 1);
1165#else
1166          fprintf(plotfile, "\033*b%*dW",
1167                  (int)DigitsInt(theend - x + 1), theend - x + 1);
1168#endif
1169              /* dump theend-x+1 bytes */
1170          for (t = x - 1; t < theend; t++)
1171            putc(stripe[j][t], plotfile);
1172          filesize += theend - x + DigitsInt(theend - x + 1) + 5;
1173        }
1174        fprintf(plotfile, "\033*rB");   /* end gfx mode */
1175        Skip((theend - x + 1) * 8);
1176        filesize += 9;
1177        x = theend + 1;
1178      }
1179      fprintf(plotfile, "\033&f1S");   /* Pop cursor  */
1180#ifdef MAC
1181      fprintf(plotfile, "\033*p0X\033*p+%*ldY",
1182              (int)DigitsInt(deep * SFactor()), deep * SFactor());
1183#else
1184      fprintf(plotfile, "\033*p0X\033*p+%*dY",
1185              (int)DigitsInt(deep * SFactor()), deep * SFactor());
1186#endif
1187      filesize += 20 + DigitsInt(deep * SFactor());
1188      fprintf(plotfile, "\033&f0S");   /* Push cursor  */
1189    }
1190    break;
1191    /* case for hpcl code */
1192  case xbm:
1193    x = 0;   /* count up # of bytes so we can put returns. */
1194    width = ((strpwide -1) / 8) +1;
1195    for (j = 0; j <  div; j++) {
1196      for (i = 0; i < width; i++) {
1197        fprintf(plotfile, "0x%02x,",(unsigned char)stripe[j][i]);
1198        filesize += 5;
1199        x++;
1200        if ((x % 15) == 0) {
1201          putc('\n', plotfile);
1202          filesize++;
1203        }
1204      }
1205    }
1206   putc('\n',plotfile);
1207   break;
1208
1209  case other:
1210    break;
1211    /* graphics print code for a new printer goes here */
1212  }
1213 }  /* striprint */
1214
1215#ifdef QUICKC
1216void setupgraphics()
1217{
1218_getvideoconfig(&myscreen);
1219#ifndef WATCOM
1220switch(myscreen.adapter){
1221  case _CGA:
1222  case _OCGA:
1223   _setvideomode(_HRESBW);
1224    break;
1225  case _EGA:
1226  case _OEGA:
1227    _setvideomode(_ERESNOCOLOR);
1228  case _VGA:
1229  case _OVGA:
1230  case _MCGA:
1231    _setvideomode(_VRES2COLOR);
1232     break;
1233  case _HGC:
1234    _setvideomode(_HERCMONO);
1235     break;
1236  default:
1237     printf("Your display hardware is unsupported by this program.\n");
1238      break;
1239}
1240#else
1241switch(myscreen.adapter){
1242  case _VGA:
1243  case _SVGA:
1244      _setvideomode(_VRES16COLOR);
1245      break;
1246  case _MCGA:
1247      _setvideomode(_MRES256COLOR);
1248      break;
1249  case _EGA:
1250     _setvideomode(_ERESNOCOLOR);
1251     break;
1252  case _CGA:
1253     _setvideomode(_MRES4COLOR);
1254     break;
1255  case _HERCULES:
1256     _setvideomode(_HERCMONO);
1257     break;
1258  default:
1259     printf("Your display hardware is unsupported by this program.\n");
1260     exit(-1);
1261     break;
1262   }
1263#endif
1264_getvideoconfig(&myscreen);
1265_setlinestyle(0xffff);
1266xunitspercm=myscreen.numxpixels / 25;
1267yunitspercm=myscreen.numypixels / 17.5;
1268xsize = 25.0;
1269ysize = 17.5;
1270}
1271#endif
1272
1273void loadfont(font,application)
1274short *font;
1275char *application;
1276{
1277
1278FILE *fontfile;
1279 long i, charstart, dummy;
1280Char trash,ch = 'A';
1281  i=0;
1282  openfile(&fontfile,FONTFILE,"r",application,NULL);
1283
1284  while (!(eof(fontfile) || ch == ' ')) {
1285    charstart = i + 1;
1286    fscanf(fontfile, "%c%c%hd%hd%hd", &ch, &ch, &dummy, &font[charstart + 1],
1287           &font[charstart + 2]);
1288    font[charstart] = ch;
1289    i = charstart + 3;
1290    do {
1291      if ((i - charstart - 3) % 10 == 0) {
1292        fscanf(fontfile, "%*[^\n]");
1293        getc(fontfile);
1294      }
1295      i++;
1296      fscanf(fontfile, "%hd", &font[i - 1]);
1297    } while (abs(font[i - 1]) < 10000);
1298    fscanf(fontfile, "%*[^\n]");
1299#ifdef MAC
1300    queryevent();
1301#endif
1302    getc(fontfile);
1303    font[charstart - 1] = i + 1;
1304  }
1305  font[charstart - 1] = 0;
1306 FClose(fontfile);
1307}  /* loadfont */
1308
1309#ifndef MAC
1310
1311 long  showrayparms(treecolor,namecolor,backcolor,rx,ry)
1312 long treecolor,namecolor,backcolor,rx,ry;
1313{
1314  long i;
1315  Char ch,input[32];
1316  long numtochange;
1317
1318  if (previewer == tek)
1319    printf("%c\f", escape);
1320  else {
1321    for (i = 1; i <= 24; i++)
1322      putchar('\n');
1323  }
1324  printf("Settings for Rayshade file: \n\n");
1325  printf(" (1)               Tree color:  %.10s\n",colors[treecolor-1].name);
1326  printf(" (2)      Species names color:  %.10s\n",colors[namecolor-1].name);
1327  printf(" (3)         Background color:  %.10s\n",colors[backcolor-1].name);
1328  printf(" (4)               Resolution:  %2ld X %2ld\n\n",rx,ry);
1329
1330  printf(" Do you want to accept these? (Yes or No)\n");
1331  for (;;) {
1332    printf(" Type Y or N or the number (1-4) of the one to change: \n");
1333    gets(input);
1334    numtochange=atoi(input);
1335    uppercase(&input[0]);
1336    ch=input[0];
1337    if (ch == 'Y' || ch == 'N' || (numtochange >= 1 && numtochange <= 4))
1338      break;
1339  }
1340 return (ch == 'Y') ? -1 : numtochange;
1341}  /* showrayparms */
1342
1343
1344void getrayparms(treecolor,namecolor,backcolor,rx,ry,numtochange)
1345 long *treecolor,*namecolor,*backcolor,*rx,*ry;
1346 long numtochange;
1347{
1348  Char ch;
1349  long i;
1350
1351  if (numtochange == 0) {
1352    do {
1353      printf(" Type the number of one that you want to change (1-4):\n");
1354      scanf("%ld%*[^\n]", &numtochange);
1355      getchar();
1356    } while (numtochange < 1 || numtochange > 10);
1357  }
1358  switch (numtochange) {
1359
1360  case 1:
1361    printf("\nWhich of these colors will the tree be?:\n");
1362    printf("   White, Red, Orange, Yellow, Green, Blue, or Violet\n");
1363    printf(" (W, R, O, Y, G, B, or V)\n");
1364    do {
1365      printf(" Choose one: \n");
1366      scanf("%c%*[^\n]", &ch);
1367      getchar();
1368      if (ch == '\n')
1369        ch = ' ';
1370      uppercase(&ch);
1371      (*treecolor) = 0;
1372      for (i = 1; i <= 7; i++) {
1373        if (ch == colors[i - 1].name[0]) {
1374          (*treecolor) = i;
1375          return;
1376        }
1377      }
1378    } while ((*treecolor) == 0);
1379    break;
1380
1381  case 2:
1382    printf("\nWhich of these colors will the species names be?:\n");
1383    printf("   White, Red, Orange, Yellow, Green, Blue, or Violet\n");
1384    printf(" (W, R, O, Y, G, B, or V)\n");
1385    do {
1386      printf(" Choose one: \n");
1387      scanf("%c%*[^\n]", &ch);
1388      getchar();
1389      if (ch == '\n')
1390        ch = ' ';
1391      uppercase(&ch);
1392      (*namecolor) = 0;
1393      for (i = 1; i <= 7; i++) {
1394        if (ch == colors[i - 1].name[0]) {
1395          (*namecolor) = i;
1396          return;
1397        }
1398      }
1399    } while ((*namecolor) == 0);
1400    break;
1401
1402  case 3:
1403    printf("\nWhich of these colors will the background be?:\n");
1404    printf("   White, Red, Orange, Yellow, Green, Blue, or Violet\n");
1405    printf(" (W, R, O, Y, G, B, or V)\n");
1406    do {
1407      printf(" Choose one: \n");
1408      scanf("%c%*[^\n]", &ch);
1409      getchar();
1410      if (ch == '\n')
1411        ch = ' ';
1412      uppercase(&ch);
1413      (*backcolor) = 0;
1414      for (i = 1; i <= 7; i++) {
1415        if (ch == colors[i - 1].name[0]) {
1416          (*backcolor) = i;
1417          return;
1418        }
1419      }
1420    } while ((*backcolor) == 0);
1421    break;
1422
1423  case 4:
1424    printf("\nEnter the X resolution:\n");
1425    scanf("%ld%*[^\n]", rx);
1426    getchar();
1427    printf("Enter the Y resolution:\n");
1428    scanf("%ld%*[^\n]",ry);
1429    getchar();
1430    break;
1431  }
1432}  /* getrayparms */
1433
1434#endif
1435
1436void plotrparms()
1437{
1438  /* set up initial characteristics of plotter or printer */
1439  Char trash,ch;                       /* colors is declared globally */
1440  long treecolor, namecolor, backcolor, i, rayresx, rayresy;
1441  double viewangle;
1442  long n;
1443
1444  penchange = no;
1445  xcorner = 0.0;
1446  ycorner = 0.0;
1447  if (dotmatrix && (!previewing))
1448    strpdiv = 1;
1449  switch (plotter) {
1450#ifndef MAC
1451  case ray:
1452    penchange = yes;
1453    xunitspercm = 1.0;
1454    yunitspercm = 1.0;
1455    xsize = 10.0;
1456    ysize = 10.0;
1457    rayresx = 512;
1458    rayresy = 512;
1459    treecolor = 6;
1460    namecolor = 4;
1461    backcolor = 1;
1462    do {
1463      n=showrayparms(treecolor,namecolor,backcolor,rayresx,rayresy);
1464      if (n != -1)
1465        getrayparms(&treecolor,&namecolor,&backcolor,&rayresx,&rayresy,n);
1466    } while (n != -1);
1467    xsize = rayresx;
1468    ysize = rayresy;
1469
1470    fprintf(plotfile, "report verbose\n");
1471
1472    fprintf(plotfile, "screen %ld %ld\n", rayresx, rayresy);
1473    if (ysize >= xsize) {
1474      viewangle = 2 * atan(ysize / (2 * 1.21 * xsize)) * 180 / pi;
1475      fprintf(plotfile, "fov 45 %3.1f\n", viewangle);
1476      fprintf(plotfile, "light 1 point 0 %6.2f %6.2f\n",
1477              -xsize * 1.8, xsize * 1.5);
1478      fprintf(plotfile, "eyep %6.2f %6.2f %6.2f\n",
1479              xsize * 0.5, -xsize * 1.21, ysize * 0.55);
1480    } else {
1481      viewangle = 2 * atan(xsize / (2 * 1.21 * ysize)) * 180 / pi;
1482      fprintf(plotfile, "fov %3.1f 45\n", viewangle);
1483      fprintf(plotfile, "light 1 point 0 %6.2f %6.2f\n",
1484              -ysize * 1.8, ysize * 1.5);
1485      fprintf(plotfile, "eyep %6.2f %6.2f %6.2f\n",
1486              xsize * 0.5, -ysize * 1.21, ysize * 0.55);
1487    }
1488
1489    fprintf(plotfile, "lookp %6.2f 0 %6.2f\n", xsize * 0.5, ysize * 0.5);
1490    fprintf(plotfile, "/* %.10s */\n", colors[treecolor - 1].name);
1491    fprintf(plotfile,
1492            "surface treecolor diffuse %5.2f%5.2f%5.2f specular 1 1 1 specpow 30\n",
1493            colors[treecolor - 1].red, colors[treecolor - 1].green,
1494            colors[treecolor - 1].blue);
1495    fprintf(plotfile, "/* %.10s */\n", colors[namecolor - 1].name);
1496    fprintf(plotfile,
1497            "surface namecolor diffuse %5.2f%5.2f%5.2f specular 1 1 1 specpow 30\n",
1498            colors[namecolor - 1].red, colors[namecolor - 1].green,
1499            colors[namecolor - 1].blue);
1500    fprintf(plotfile, "/* %.10s */\n", colors[backcolor - 1].name);
1501    fprintf(plotfile, "surface backcolor diffuse %5.2f%5.2f%5.2f\n\n",
1502            colors[backcolor - 1].red, colors[backcolor - 1].green,
1503            colors[backcolor - 1].blue);
1504    break;
1505#endif /* ifndef mac */
1506  case pict:
1507    penchange = yes;
1508    xunitspercm = 28.346456693;
1509    yunitspercm = 28.346456693;
1510    /*7.5 x 10 inch default PICT page size*/
1511    xsize = 19.05;
1512    ysize = 25.40;
1513    break;
1514
1515  case lw:
1516    penchange = yes;
1517    xunitspercm = 28.346456693;
1518    yunitspercm = 28.346456693;
1519    xsize = 21.59;
1520    ysize = 27.94;
1521    break;
1522
1523  case hp:
1524    penchange = yes;
1525    xunitspercm = 400.0;
1526    yunitspercm = 400.0;
1527    xsize = 24.0;
1528    ysize = 18.0;
1529    break;
1530
1531  case tek:
1532    xunitspercm = 50.0;
1533    yunitspercm = 50.0;
1534    xsize = 20.46;
1535    ysize = 15.6;
1536    break;
1537
1538  case ibmpc:
1539#ifdef TURBOC
1540  GraphDriver = 0;
1541  detectgraph(&GraphDriver,&GraphMode);
1542  getmoderange(GraphDriver,&LoMode,&HiMode);
1543  initgraph(&GraphDriver,&HiMode,"");
1544  xunitspercm = getmaxx()/25;
1545  yunitspercm = getmaxy() / 17.5;
1546  restorecrtmode();
1547  xsize = 25.0;
1548  ysize = 17.5;
1549#endif
1550#ifdef QUICKC
1551setupgraphics();
1552
1553#endif
1554  break;
1555
1556  case mac:
1557    penchange = yes;
1558    xunitspercm = 33.5958;
1559    yunitspercm = 33.6624;
1560    xsize = 15.24;
1561    ysize = 10.00;
1562    break;
1563
1564  case houston:
1565    penchange = yes;
1566    xunitspercm = 100.0;
1567    yunitspercm = 100.0;
1568    xsize = 24.5;
1569    ysize = 17.5;
1570    break;
1571
1572  case decregis:
1573    xunitspercm = 30.0;
1574    yunitspercm = 30.0;
1575    xsize = 25.0;
1576    ysize = 15.0;
1577    break;
1578
1579  case epson:
1580    penchange = yes;
1581    xunitspercm = 47.244;
1582    yunitspercm = 28.346;
1583    xsize = 18.70;
1584    ysize = 22.0;
1585    strpwide = 960;
1586    strpdeep = 8;
1587    strpdiv = 1;
1588    break;
1589
1590  case oki:
1591    penchange = yes;
1592    xunitspercm = 56.692;
1593    yunitspercm = 28.346;
1594    xsize = 19.0;
1595    ysize = 22.0;
1596    strpwide = 1100;
1597    strpdeep = 8;
1598    strpdiv = 1;
1599    break;
1600
1601  case citoh:
1602    penchange = yes;
1603    xunitspercm = 28.346;
1604    yunitspercm = 28.346;
1605    xsize = 22.3;
1606    ysize = 26.0;
1607    strpwide = 640;
1608    strpdeep = 8;
1609    strpdiv = 1;
1610    break;
1611
1612  case toshiba:
1613    penchange = yes;
1614    xunitspercm = 70.866;
1615    yunitspercm = 70.866;
1616    xsize = 19.0;
1617    ysize = 25.0;
1618    strpwide = 1350;
1619    strpdeep = 24;
1620    strpdiv = 4;
1621    break;
1622
1623  case pcl:
1624    penchange = yes;
1625    xsize = 21.59;
1626    ysize = 27.94;
1627    xunitspercm = 118.11023622;   /* 300 DPI = 118.1 DPC                    */
1628    yunitspercm = 118.11023622;
1629    strpwide = 2550;   /* 8.5 * 300 DPI                                     */
1630    strpdeep = 20;     /* height of the strip                               */
1631    strpdiv = 20;      /* in this case == strpdeep                          */
1632                       /* this is information for 300 DPI resolution        */
1633    printf("Please select Laserjet resolution\n\n");
1634    printf("1:  75 DPI\n2:  150 DPI\n3:  300 DPI\n\n");
1635    do {
1636      scanf("%c%*[^\n]", &ch);
1637      trash=getchar();
1638      uppercase(&ch);
1639    } while (ch != '1' && ch != '2' && ch != '3');
1640    switch (ch) {
1641
1642    case '1':
1643      strpwide /= 4;
1644      xunitspercm /= 4.0;
1645      yunitspercm /= 4.0;
1646      hpresolution = 75;
1647      break;
1648
1649    case '2':
1650      strpwide /= 2;
1651      xunitspercm /= 2.0;
1652      yunitspercm /= 2.0;
1653      hpresolution = 150;
1654      break;
1655
1656    case '3':
1657      hpresolution = 300;
1658      break;
1659    }
1660    break;
1661  case xbm:            /* since it's resolution dependent, make 1x1 pixels  */
1662    penchange = yes;   /* per square cm for easier math.                    */
1663    xunitspercm = 1.0;
1664    yunitspercm = 1.0;
1665    strpdeep = 10;
1666    strpdiv = 10;
1667    printf("Please select the X-bitmap file resolution\n");
1668    printf("X resolution?\n");
1669    scanf("%lf%*[^\n]", &xsize);
1670    getchar();
1671    printf("Y resolution?\n");
1672    scanf("%lf%*[^\n]", &ysize);
1673    getchar();
1674    strpwide = (long)xsize;
1675    xsize /= xunitspercm;
1676    ysize /= yunitspercm;
1677
1678    break;
1679
1680  case pcx:
1681    penchange = yes;
1682    xsize = 21.16;
1683    ysize = 15.88;
1684    strpdeep = 10;
1685    strpdiv = 10;
1686    printf("Please select the PCX file resolution\n\n");
1687    printf("1: EGA 640  X 350\n");
1688    printf("2: VGA 800  X 600\n");
1689    printf("3: VGA 1024 X 768\n\n");
1690    do {
1691      scanf("%c%*[^\n]", &ch);
1692      trash=getchar();
1693      uppercase(&ch);
1694    } while (ch != '1' && ch != '2' && ch != '3');
1695    switch (ch) {
1696
1697    case '1':
1698      strpwide = 640;
1699      yunitspercm = 350 / ysize;
1700      break;
1701
1702    case '2':
1703      strpwide = 800;
1704      yunitspercm = 600 / ysize;
1705      break;
1706
1707    case '3':
1708      strpwide = 1024;
1709      yunitspercm = 768 / ysize;
1710      break;
1711    }
1712    xunitspercm = strpwide / xsize;
1713    break;
1714  case fig:
1715    penchange = yes;
1716    xunitspercm = 31.011;
1717    yunitspercm = 29.78;
1718    xsize = 25.4;
1719    ysize = 20.32;
1720    break;
1721  case other:
1722    break;
1723    /* initial parameter settings for a new plotter go here */
1724  }
1725  if (previewing)
1726    return;
1727}  /* plotrparms */
1728
1729
1730void getplotter()
1731{
1732  Char ch,trash;
1733
1734  printf("\nWhich plotter or printer will the tree be drawn on?\n");
1735  printf("(many other brands or models are compatible with these)\n\n");
1736  printf("   type:       to choose one compatible with:\n\n");
1737  printf("        L         Apple Laserwriter (with Postscript)\n");
1738  printf("        M         MacDraw PICT format\n");
1739#ifndef MAC
1740  printf("        R         Rayshade 3D rendering program file\n");
1741#endif
1742  printf("        J         Hewlett-Packard Laserjet\n");
1743  printf("        K         TeKtronix 4010 graphics terminal\n");
1744  printf("        H         Hewlett-Packard 7470 plotter\n");
1745#ifdef DOS
1746  printf("        I         IBM PC graphics screens\n");
1747#endif
1748  printf("        D         DEC ReGIS graphics (VT240 terminal)\n");
1749  printf("        B         Houston Instruments plotter\n");
1750  printf("        E         Epson MX-80 dot-matrix printer\n");
1751  printf("        C         Prowriter/Imagewriter dot-matrix printer\n");
1752  printf("        O         Okidata dot-matrix printer\n");
1753  printf("        T         Toshiba 24-pin dot-matrix printer\n");
1754  printf("        P         PC Paintbrush monochrome PCX file format\n");
1755  printf("        X         X Bitmap format                         \n");
1756  printf("        F         FIG 2.0 format                          \n");
1757  printf("        U         other: one you have inserted code for\n");
1758  do {
1759    printf(" Choose one: \n");
1760    scanf("%c%*[^\n]", &ch);
1761    trash=getchar();
1762    uppercase(&ch);
1763  }
1764#ifdef DOS
1765while (strchr("LJKHIDBECOTUPXRMF",ch) == NULL);
1766#else
1767while (strchr("LJKHDBECOTUPXRMF",ch) == NULL);
1768#endif
1769  switch (ch) {
1770
1771  case 'L':
1772    plotter = lw;
1773    break;
1774
1775  case 'M':
1776    plotter = pict;
1777    break;
1778
1779 case 'R':
1780    plotter = ray;
1781    break;
1782
1783  case 'J':
1784    plotter = pcl;
1785    break;
1786
1787  case 'K':
1788    plotter = tek;
1789    break;
1790
1791  case 'H':
1792    plotter = hp;
1793    break;
1794
1795  case 'I':
1796    plotter = ibmpc;
1797    break;
1798
1799  case 'D':
1800    plotter = decregis;
1801    break;
1802
1803  case 'B':
1804    plotter = houston;
1805    break;
1806
1807  case 'E':
1808    plotter = epson;
1809    break;
1810
1811  case 'C':
1812    plotter = citoh;
1813    break;
1814
1815  case 'O':
1816    plotter = oki;
1817    break;
1818
1819  case 'T':
1820    plotter = toshiba;
1821    break;
1822
1823  case 'P':
1824    plotter = pcx;
1825    break;
1826
1827  case 'X':
1828    plotter = xbm;
1829    break;
1830
1831  case 'F':
1832    plotter = fig;
1833    break;
1834
1835  case 'U':
1836    plotter = other;
1837    break;
1838  }
1839  dotmatrix = (plotter == epson || plotter == oki || plotter == citoh ||
1840               plotter == toshiba || plotter == pcx || plotter == pcl ||
1841               plotter == xbm);
1842  printf("\nWhich type of screen will it be previewed on?\n\n");
1843  printf("   type:       to choose one compatible with:\n\n");
1844  printf("        N         will not be previewed\n");
1845#ifdef DOS
1846  printf("        I         IBM PC graphics screens\n");
1847#else
1848# ifdef MAC
1849  printf("        M         Macintosh screens\n");
1850# else
1851  printf("        K         TeKtronix 4010 graphics terminal\n");
1852  printf("        D         DEC ReGIS graphics (VT240 terminal)\n");
1853  printf("        U         other: one you have inserted code for\n");
1854# endif
1855#endif
1856  do {
1857    printf(" Choose one: \n");
1858    scanf("%c%*[^\n]", &ch);
1859    trash=getchar();
1860    uppercase(&ch);
1861  }
1862#ifdef DOS
1863  while (strchr("NIKDU",ch) == NULL);
1864#else
1865# ifdef MAC
1866  while (strchr("NMKDU",ch) == NULL);
1867#  else
1868  while (strchr("NKDU",ch) == NULL);
1869#  endif
1870#endif
1871  preview = true;
1872  switch (ch) {
1873
1874  case 'N':
1875    preview = false;
1876    break;
1877
1878  case 'I':
1879    previewer = ibmpc;
1880    break;
1881
1882  case 'M':
1883    previewer = mac;
1884    break;
1885
1886  case 'K':
1887    previewer = tek;
1888    break;
1889
1890  case 'D':
1891    previewer = decregis;
1892    break;
1893
1894  case 'U':
1895    previewer = other;
1896    break;
1897  }
1898  printf("\n\n\n");
1899}  /* getplotter */
1900
1901
1902void changepen(pen)
1903pentype pen;
1904{
1905  Char picthi, pictlo;
1906  long  pictint;
1907
1908 switch (pen) {
1909
1910  case treepen:
1911    linewidth = treeline;
1912    if (plotter == hp)
1913      fprintf(plotfile, "SP1;\n");
1914    if (plotter == lw) {
1915      fprintf(plotfile, "stroke %8.2f setlinewidth \n", treeline);
1916      fprintf(plotfile, " 1 setlinecap 1 setlinejoin \n");
1917    }
1918    break;
1919
1920  case labelpen:
1921    linewidth = labelline;
1922    if (plotter == hp)
1923      fprintf(plotfile, "SP2;\n");
1924    if (plotter == lw) {
1925      fprintf(plotfile, " stroke%8.2f setlinewidth \n", labelline);
1926      fprintf(plotfile, "1 setlinecap 1 setlinejoin \n");
1927    }
1928    break;
1929  }
1930#ifdef MAC
1931if (plotter == mac){
1932      pictint = ( long)(linewidth + 0.5);
1933      if (pictint ==0)
1934           pictint = 1;
1935      PenSize((int)pictint,(int)pictint);}
1936#endif
1937
1938  if (plotter != pict)
1939    return;
1940  pictint = ( long)(linewidth + 0.5);
1941  if (pictint == 0)
1942    pictint = 1;
1943  picthi = (Char)(pictint / 256);
1944  pictlo = (Char)(pictint & 255);
1945  fprintf(plotfile, "\007%c%c%c%c", picthi, pictlo, picthi, pictlo);
1946}  /* changepen */
1947
1948
1949double lengthtext(pstring, nchars,font)
1950Char *pstring;
1951 long nchars;
1952fonttype font;
1953{  /* lengthext */
1954  long i, j, code;
1955  static double sumlength;
1956  sumlength = 0.0;
1957  for (i = 0; i < nchars; i++) {
1958    code = pstring[i];
1959    j = 1;
1960    while (font[j] != code && font[j - 1] != 0)
1961      j = font[j - 1];
1962    if (font[j] == code)
1963      sumlength += font[j + 2];
1964  }
1965  return sumlength;
1966}  /* lengthtext */
1967
1968
1969void plotchar(place,text)
1970 long *place;
1971struct LOC_plottext *text;         /* variables passed from plottext */
1972{
1973  text->heightfont = text->font[*place + 1];
1974  text->yfactor = text->height / text->heightfont;
1975  text->xfactor = text->yfactor;
1976  *place += 3;
1977  do {
1978    (*place)++;
1979    text->coord = text->font[*place - 1];
1980    if (text->coord > 0)
1981      text->penstatus = pendown;
1982    else
1983      text->penstatus = penup;
1984    text->coord = abs(text->coord);
1985    text->coord %= 10000;
1986    text->xfont = (text->coord / 100 - xstart) * text->xfactor;
1987    text->yfont = (text->coord % 100 - ystart) * text->yfactor;
1988    text->xplot = text->xx + (text->xfont * text->cosslope +
1989                              text->yfont * text->sinslope) * text->compress;
1990    text->yplot = text->yy - text->xfont * text->sinslope +
1991      text->yfont * text->cosslope;
1992    plot(text->penstatus, text->xplot, text->yplot);
1993  } while (abs(text->font[*place - 1]) < 10000);
1994  text->xx = text->xplot;
1995  text->yy = text->yplot;
1996}  /* plotchar */
1997
1998swap(one,two)
1999char **one,**two;
2000{
2001char *tmp = (*one);
2002(*one)= (*two);
2003(*two) = tmp;
2004return;
2005}
2006
2007void drawit(fontname,xoffset,yoffset,numlines,root)
2008char *fontname;
2009double *xoffset,*yoffset;
2010 long  numlines;
2011node *root;
2012{
2013  long i, j, line;
2014  long deep,iterations;
2015  (*xoffset) = 0.0;
2016  (*yoffset) = 0.0;
2017  if (dotmatrix){
2018    strptop    = ( long)(ysize * yunitspercm);
2019    strpbottom = numlines*strpdeep + 1;
2020  }
2021  else {
2022    plottree(root,root);
2023    plotlabels(fontname);
2024  }
2025  if (dotmatrix){
2026    striprint(( long)((ysize * yunitspercm)- (numlines * strpdeep)),
2027              ( long)((ysize * yunitspercm)- (numlines * strpdeep)));
2028    strptop = numlines * strpdeep;
2029    strpbottom = strptop - strpdeep + 1;
2030    printf(" writing%3ld lines ...\n", numlines);
2031    printf("  Line     Output file size\n");
2032    printf("  ----     ------ ---- ----\n");
2033    for (line = 1; line <= numlines ; line++) {
2034      for (i = 0; i <= strpdeep ; i++){
2035        for (j=0; j<=(strpwide/8);++j)
2036          stripe[i][j] = 0;}
2037      empty = true;
2038      xnow = strpwide / 2.0;
2039      ynow = 0.0;
2040      plottree(root, root);
2041      plotlabels(fontname);
2042      strptop = strpbottom - 1;
2043      strpbottom -= strpdeep;
2044      deep=20;
2045      if (strpdeep > deep){              /* large stripe, do in 20-line     */
2046        for (i=0;i<strpdeep;++i){
2047          swap(&stripe[i%deep],&stripe[i]);
2048          if ((i%deep) == (deep -1)){
2049            striprint(deep,deep);}
2050        }
2051        striprint(strpdeep%deep,strpdeep%deep);
2052      }
2053      else{                          /* small stripe, do it all now.     */
2054        striprint(strpdiv,strpdeep);
2055        if (line % 5 == 0)
2056          printf("%5ld%16ld\n", line, filesize);
2057      }
2058    }
2059  }
2060}  /* drawit */
2061
2062
2063void plottext(pstring, nchars, height_, cmpress2, x, y, slope, font_,fontname)
2064Char *pstring;
2065 long nchars;
2066double height_, cmpress2, x, y, slope;
2067short *font_;
2068char *fontname;
2069{
2070  struct LOC_plottext text;
2071  long i, j, code;
2072  double pointsize;
2073  text.heightfont = font_[2];
2074
2075  pointsize = (1.2*(height_/text.heightfont)*cmpress2 / 2.54) * 72.0;
2076  text.height = height_;
2077  text.compress = cmpress2;
2078  text.font = font_;
2079  text.xx = x;
2080  text.yy = y;
2081  text.sinslope = sin(pi * slope / 180.0);
2082  text.cosslope = cos(pi * slope / 180.0);
2083  if (previewing || (strcmp(fontname,"Hershey") == 0)){
2084    for (i = 0; i < nchars; i++) {
2085      code = pstring[i];
2086      j = 1;
2087      while (text.font[j] != code && text.font[j - 1] != 0)
2088        j = text.font[j - 1];
2089      plotchar(&j,  &text);
2090    }
2091  }
2092
2093  else if (plotter == lw)  {
2094 /* print alternate font.  Right now, only postscript. */
2095    fprintf(plotfile,"gsave\n");
2096    fprintf(plotfile,"/%s findfont %f scalefont setfont\n",fontname,
2097            pointsize);
2098    fprintf(plotfile,"%f %f translate %f rotate\n",x,y,-slope);
2099    fprintf(plotfile,"0 0 moveto\n");
2100    fprintf(plotfile,"(%s) show\n",pstring);
2101    fprintf(plotfile,"grestore\n");
2102  }
2103}  /* plottext */
2104
2105
2106void makebox(fn,xo,yo,scale,ntips)
2107char *fn;                          /* fontname                       */
2108double *xo,*yo;                    /* x and y offsets                 */
2109double *scale;
2110 long ntips;
2111{
2112  /* draw the box on screen which represents plotting area.        */
2113  char ch;
2114
2115  printf("\nWe now will preview the tree.  The box that will be\n");
2116  printf("plotted on the screen represents the boundary of the\n");
2117  printf("final plotting surface.  To see the preview, press on\n");
2118  printf("the ENTER or RETURN key (you may need to do it twice).\n");
2119  printf("When finished viewing it, press on that key again.\n");
2120  oldpenchange   = penchange;
2121  oldxsize       = xsize;
2122  oldysize       = ysize;
2123  oldxunitspercm = xunitspercm;
2124  oldyunitspercm = yunitspercm;
2125  oldxcorner     = xcorner;
2126  oldycorner     = ycorner;
2127  oldplotter     = plotter;
2128  plotter        = previewer;
2129  scanf("%c%*[^\n]", &ch);
2130  (void)getchar();
2131  if (ch == '\n')
2132    ch = ' ';
2133  plotrparms();
2134  xcorner += 0.05 * xsize;
2135  ycorner += 0.05 * ysize;
2136  xsize *= 0.9;
2137  ysize *= 0.9;
2138  (*scale) = ysize / oldysize;
2139  if (xsize / oldxsize < (*scale))
2140    (*scale) = xsize / oldxsize;
2141  (*xo) = (xcorner + (xsize - oldxsize * (*scale)) / 2.0) / (*scale);
2142  (*yo) = (ycorner   + (ysize - oldysize * (*scale)) / 2.0) / (*scale);
2143  xscale = (*scale) * xunitspercm;
2144  yscale = (*scale) * yunitspercm;
2145  initplotter(ntips,fn);
2146  plot(penup, xscale * (*xo), yscale * (*yo));
2147  plot(pendown, xscale * (*xo), yscale * ((*yo) + oldysize));
2148  plot(pendown, xscale * ((*xo) + oldxsize), yscale * ((*yo) + oldysize));
2149  plot(pendown, xscale * ((*xo) + oldxsize), yscale * (*yo));
2150  plot(pendown, xscale * (*xo), yscale * (*yo));
2151}  /* makebox */
2152
2153
2154boolean plotpreview(fn,xo,yo,scale,nt,root)
2155char *fn;        /* font name                                              */
2156double *xo,*yo;
2157double *scale;
2158 long nt;        /* ntips                                                  */
2159node *root;
2160{
2161  boolean canbeplotted;
2162  Char ch;
2163
2164  previewing = true;
2165  makebox(fn,xo,yo,scale,nt);
2166  plottree(root, root);
2167  plotlabels(fn);
2168  finishplotter();
2169  penchange = oldpenchange;
2170  xsize = oldxsize;
2171  ysize = oldysize;
2172  xunitspercm = oldxunitspercm;
2173  yunitspercm = oldyunitspercm;
2174  xscale = xunitspercm;
2175  yscale = yunitspercm;
2176  plotter = oldplotter;
2177  xcorner = oldxcorner;
2178  ycorner = oldycorner;
2179  printf(" Is the tree ready to be plotted? (Answer Y or N)\n");
2180  do {
2181    printf("Type Y or N:\n");
2182    scanf("%c%*[^\n]", &ch);
2183    (void)getchar();
2184    if (ch == '\n')
2185      ch = ' ';
2186    uppercase(&ch);
2187  } while (ch != 'Y' && ch != 'N');
2188  canbeplotted = (ch == 'Y');
2189  return canbeplotted;
2190}  /* plotpreview */
2191
2192
2193long allocstripe(stripe,x,y)
2194striptype stripe;
2195long x,y;
2196{
2197  long i,stripedepth;
2198  for (i=0 ; i<=y;++i){
2199    stripe[i] = (MALLOCRETURN *)malloc((x+1)*sizeof(Char));
2200    if (!stripe[i])
2201      break;
2202   }
2203return i-1;
2204}
2205
Note: See TracBrowser for help on using the repository browser.