source: branches/stable/GDE/PHYLIP/draw2.c

Last change on this file was 2175, checked in by westram, 21 years ago

upgrade to PHYLIP 3.6

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 54.7 KB
Line 
1
2#include <stdio.h> /* Metrowerks for windows defines WIN32 here */
3#define swap_m(x,y) temp = y,y=x,x=temp;
4
5extern long winheight;
6extern long winwidth;
7
8#ifdef WIN32
9#include <windows.h>
10HDC hdc;
11
12/******* Menu Defines *******/
13
14#define IDM_ABOUT      1000
15#define IDM_PLOT       1001
16#define IDM_CHANGE     1002
17#define IDM_QUIT       1003
18
19#define XWINPERCENT    0.66
20#define YWINPERCENT    0.66
21#endif
22
23
24#ifdef QUICKC
25extern struct videoconfig myscreen;
26#endif
27
28#include "draw.h"
29
30static long eb[]={
31  0 , 1 ,2 ,3 ,55,45,46,47,22,5,37,11,12,13,14,15,16,17,18,19,60,61,50,38,
32  24, 25,63,39,28,29,30,31,64,90,127,123,91,108,80,125,77,93,92,78,107,96,
33  75,97,240,241,242,243,244,245,246,247,248,249,122,94,76,126,110,111, 124,
34  193,194,195,196,197,198,199,200,201,209,210,211, 212,213,214,215,216,217,
35  226,227,228,229,230,231,232,233,173,224,189, 95,109,121,129,130,131,132,
36  133,134,135,136,137,145,146,147,148,149,150, 151, 152,153,162,163,164,165,
37  166,167,168,169,192,79,208,161,7};
38
39double oldxreal, oldyreal;
40boolean didenter, didexit, curvetrue;
41extern long vrmlplotcolor;
42
43extern double oldx, oldy ;
44/*xx only here for debugging */ extern node *root;
45extern long    nmoves, oldpictint ;
46extern long    rootmatrix[51][51];
47extern long    strpbottom,strptop,strpwide,strpdeep;
48extern boolean dotmatrix, empty, previewing;
49extern double  ynow, ysize, xsize, yunitspercm;
50extern FILE          *plotfile;
51extern plottertype   plotter;
52extern striptype     stripe;
53
54extern long vrmltreecolor, vrmlnamecolor, vrmlskycolorfar, vrmlskycolornear,
55  vrmlgroundcolorfar, vrmlgroundcolornear;
56extern colortype colors[7];
57extern vrmllighttype vrmllights[3];
58extern double pie;
59double pie = 3.141592654;
60
61
62/* Added by Dan F. for the new previewing paradigm */
63extern double labelline,linewidth,oldxhigh,oldxlow,oldyhigh,oldylow,
64  vrmllinewidth, raylinewidth,treeline,oldxsize,oldysize,oldxunitspercm,
65  oldyunitspercm,oldxcorner,oldycorner,clipx0,clipx1,clipy0,clipy1;
66
67/* func. protocol added for vrml - danieyek 981111 */
68
69extern long          strpdiv,hpresolution;
70extern boolean       preview,pictbold,pictitalic,
71  pictshadow,pictoutline;
72extern double        expand,xcorner,xnow,xscale,xunitspercm,
73  ycorner,yscale,labelrotation,
74  labelheight,ymargin,pagex,pagey,paperx,papery,hpmargin,vpmargin;
75
76extern long          filesize;
77extern growth        grows;
78extern enum {yes,no} penchange,oldpenchange;
79extern plottertype   oldplotter,previewer;
80extern char             resopts;
81extern winactiontype winaction;
82
83#ifndef OLDC
84/* function prototypes */
85void   plotdot(long, long);
86void   circlepoints(int, int, int, int);
87void   drawpen(long, long, long);
88void   drawfatline(long, long, long, long, long);
89void   idellipse(double, double); 
90void   splyne(double,double,double,double,boolean,long,boolean,boolean);
91static void   putshort(FILE *, int);
92
93static void   putint(FILE *, int);
94void   reverse_bits (byte *, int); 
95void   makebox_no_interaction(char *, double *, double *, double *, long);
96void   void_func(void);
97/* function prototypes */
98#endif
99
100
101void plotdot(long ix, long iy)
102{
103  /* plot one dot at ix, iy */
104  long ix0, iy0, iy1 = 0, iy2 = 0;
105
106  iy0 = strptop - iy;
107  if ((unsigned)iy0 > strpdeep || ix <= 0 || ix > strpwide)
108    return;
109  empty = false;
110  ix0 = ix;
111  switch (plotter) {
112
113  case citoh:
114    iy1 = 1;
115    iy2 = iy0;
116    break;
117
118  case epson:
119    iy1 = 1;
120    iy2 = 7 - iy0;
121    break;
122
123  case oki:
124    iy1 = 1;
125    iy2 = 7 - iy0;
126    break;
127
128  case toshiba:
129    iy1 = iy0 / 6 + 1;
130    iy2 = 5 - iy0 % 6;
131    break;
132
133  case pcx:
134    iy1 = iy0 + 1;
135    ix0 = (ix - 1) / 8 + 1;
136    iy2 = 7 - ((ix - 1) & 7);
137    break;
138
139  case pcl:
140    iy1 = iy0 + 1;
141    ix0 = (ix - 1) / 8 + 1;
142    iy2 = 7 - ((ix - 1) & 7);
143    break;
144
145  case bmp: 
146    iy1 = iy0 + 1;
147    ix0 = (ix - 1) / 8 + 1;
148    iy2 = 7 - ((ix - 1) & 7);
149  case xbm:
150  case gif:
151    iy1 = iy0 + 1;
152    ix0 = (ix - 1) / 8 + 1;
153    iy2 = (ix - 1) & 7;
154    break;
155
156  case lw:
157  case hp:
158  case tek:
159  case mac:
160  case houston:
161  case decregis:
162  case fig:
163  case pict:
164  case ray:
165  case pov:
166  case idraw:
167  case ibm:
168  case other:
169    break;
170  default:        /* cases xpreview and vrml not handled        */
171    break;
172    /* code for making dot array for a new printer
173      goes here */
174  }
175  stripe[iy1 - 1][ix0 - 1] |= (unsigned char)1<<iy2;
176}  /* plotdot */
177
178
179void circlepoints(int x, int y, int x0, int y0)
180{
181  /* circlepoints is consecutively passed a circle center and x,y coordinates *
182   * for 1 octant of a circle. Since the circle is symmetrical, we can use    *
183   * this to plot a complete circle with adjacent pixels (to avoid holes      *
184   * often associated with diagonal stairstepping.                            */
185 
186  plotdot(x0+x,y0+y);
187  plotdot(x0+x,y0+y-1);
188  plotdot(x0+y,y0+x);
189  plotdot(x0+y-1,y0+x);
190 
191  plotdot(x0-x,y0+y);
192  plotdot(x0-x,y0+y-1);
193  plotdot(x0-y,y0+x);
194  plotdot(x0-y+1,y0+x);
195 
196  plotdot(x0+x,y0-y);
197  plotdot(x0+x,y0-y+1);
198  plotdot(x0+y,y0-x);
199  plotdot(x0+y-1,y0-x);
200 
201  plotdot(x0-x,y0-y);
202  plotdot(x0-x,y0-y+1);
203  plotdot(x0-y,y0-x);
204  plotdot(x0-y+1,y0-x);
205}  /* circlepoints */
206
207
208void drawpen(long x0, long y0, long radius)
209{
210 int x,y,d,deltaE,deltaSE;
211
212  x = 0;
213  y = radius;
214  d = 1-radius;
215  deltaE = 3;
216  deltaSE = -2 * radius + 5;
217  circlepoints(x,y,x0,y0);
218
219  while (y > x){
220    if (d < 0) {
221      d = d + deltaE;
222      deltaE += 2;
223      deltaSE += 2;
224      x++;
225    }
226    else {
227      d+=deltaSE;
228      deltaE += 2;
229      deltaSE += 4;
230      x++;
231      y--;
232    }
233    circlepoints(x,y,x0,y0);
234  }
235} /* drawpen */
236
237
238void drawfatline(long ixabs, long iyabs, long ixnow, long iynow,
239                        long penwide)
240{
241  long temp, xdiff, ydiff, err, x1, y1;
242
243  didenter = false;
244  didexit = false;
245
246  if (ixabs < ixnow) {
247    temp = ixnow;
248    ixnow = ixabs;
249    ixabs = temp;
250    temp = iynow;
251    iynow = iyabs;
252    iyabs = temp;
253  }
254  xdiff = ixabs - ixnow;
255  ydiff = iyabs - iynow;
256  if (ydiff >= 0) {
257    if (xdiff >= ydiff) {
258      err = -(xdiff / 2);
259      x1 = ixnow;
260      while (x1 <= ixabs && !(didenter && didexit)) {
261        drawpen(x1, iynow, penwide);
262        err += ydiff;
263        if (err > 0) {
264          iynow++;
265          err -= xdiff;
266        }
267        x1++;
268      }
269      return;
270    }
271    err = -(ydiff / 2);
272    y1 = iynow;
273    while (y1 < iyabs && !(didenter && didexit)) {
274      drawpen(ixnow, y1, penwide);
275      err += xdiff;
276      if (err > 0) {
277        ixnow++;
278        err -= ydiff;
279      }
280      y1++;
281    }
282    return;
283  }
284  if (xdiff < -ydiff) {
285    err = ydiff / 2;
286    y1 = iynow;
287    while (y1 >= iyabs && !(didenter && didexit)) {
288      drawpen(ixnow, y1, penwide);
289      err += xdiff;
290      if (err > 0) {
291        ixnow++;
292        err += ydiff;
293      }
294      y1--;
295    }
296    return;
297  }
298  err = -(xdiff / 2);
299  x1 = ixnow;
300  while (x1 <= ixabs && !(didenter && didexit)) {
301    drawpen(x1, iynow, penwide);
302    err -= ydiff;
303    if (err > 0) {
304      iynow--;
305      err -= xdiff;
306    }
307    x1++;
308  }
309}  /* drawfatline */
310
311
312void plot(pensttstype pen, double xabs, double yabs)
313{
314  long xhigh, yhigh, xlow, ylow, ixnow, iynow, ixabs, iyabs,
315       cdx, cdy, temp, i;
316  long pictint;
317  double newx, newy, dx, dy, lscale, dxreal, dyreal;
318  Char picthi, pictlo;
319
320  /* added to give every line a name in vrml! - danieyek 981110 */
321  static long lineCount = 0;
322  /* Record the first node as the coordinate for viewpoint! */
323  static int firstNodeP=1;
324  double distance, angle;
325  double episilon = 1.0e-10;
326
327  /* For povray, added by Dan F. */
328  char texture_string[7];
329
330/* remember to respect & translate for clipping region, clip{x,y}{0,1} */
331
332  if (!dotmatrix || previewing) {
333    switch (plotter) {
334
335    case xpreview:
336      if (pen == pendown) {
337#ifdef X
338        XDrawLine(display,mainwin,gc1,(long)oldx,(long)(height-oldy),
339                                      (long)xabs,(long)(height-yabs));
340#endif
341      }
342      oldx = xabs;
343      oldy = yabs;
344      break;
345
346    case winpreview:
347#ifdef WIN32
348      if (pen == pendown) {
349        LineTo(hdc, (int) xabs, (int)(winheight-yabs)); 
350      }
351      else {
352        MoveToEx(hdc, (int) xabs, (int) (winheight-yabs), (LPPOINT) NULL); 
353      }
354#endif
355      break;
356
357    case tek:
358      if (pen == penup) {
359        if (previewing)
360          putchar('\035');
361        else
362          putc('\035', plotfile);
363      }
364      ixnow = (long)floor(xabs + 0.5);
365      iynow = (long)floor(yabs + 0.5);
366      xhigh = ixnow / 32;
367      yhigh = iynow / 32;
368      xlow = ixnow & 31;
369      ylow = iynow & 31;
370      if (!ebcdic) {
371        if (yhigh != oldyhigh) {
372          if (previewing)
373            putchar(yhigh + 32);
374          else
375            putc(yhigh + 32, plotfile);
376        }
377        if (ylow != oldylow || xhigh != oldxhigh) {
378          if (previewing)
379            putchar(ylow + 96);
380          else
381            putc(ylow + 96, plotfile);
382        }
383        if (xhigh != oldxhigh) {
384          if (previewing)
385            putchar(xhigh + 32);
386          else
387            putc(xhigh + 32, plotfile);
388        }
389        if (previewing)
390          putchar(xlow + 64);
391        else
392          putc(xlow + 64, plotfile);
393      } else {  /* DLS/JMH -- for systems that use EBCDIC coding */
394        if (yhigh != oldyhigh) {
395          if (previewing)
396            putchar(eb[yhigh + 32]);
397          else
398            putc(eb[yhigh + 32], plotfile);
399        }
400        if (ylow != oldylow || xhigh != oldxhigh) {
401          if (previewing)
402            putchar(eb[ylow + 96]);
403          else
404            putc(eb[ylow + 96], plotfile);
405        }
406        if (xhigh != oldxhigh) {
407          if (previewing)
408            putchar(eb[xhigh + 32]);
409          else
410            putc(eb[xhigh + 32], plotfile);
411        }
412        if (previewing)
413          putchar(eb[xlow + 64]);
414        else
415          putc(eb[xlow + 64], plotfile);
416      }
417
418      oldxhigh = xhigh;
419      oldxlow = xlow;
420      oldyhigh = yhigh;
421      oldylow = ylow;
422      break;
423
424    case hp:
425      if (pen == pendown)
426        fprintf(plotfile, "PD");
427      else
428        fprintf(plotfile, "PU");
429      pout((long)floor(xabs + 0.5));
430      putc(',', plotfile);
431      pout((long)floor(yabs + 0.5));
432      fprintf(plotfile, ";\n");
433      break;
434
435    case pict:
436      newx = floor(xabs + 0.5);
437      newy = floor(ysize * yunitspercm - yabs + 0.5);
438      if (pen == pendown) {
439        if (linewidth > 5) {
440          dxreal = xabs - oldxreal;
441          dyreal = yabs - oldyreal;
442          lscale = sqrt(dxreal * dxreal + dyreal * dyreal) /
443            (fabs(dxreal) + fabs(dyreal));
444          pictint = (long)(lscale * linewidth + 0.5);
445
446          if (pictint == 0)
447            pictint = 1;
448          if (pictint != oldpictint) {
449            picthi = (Char)(pictint / 256);
450            pictlo = (Char)(pictint & 255);
451            fprintf(plotfile, "\007%c%c%c%c", picthi, pictlo, picthi, pictlo);
452          }
453          oldpictint = pictint;
454        }
455        fprintf(plotfile, " %c%c%c%c",
456                (Char)((long) oldy / 256), (Char)((long) oldy & 255), (Char)((long) oldx / 256),
457                (Char)((long) oldx & 255));
458        fprintf(plotfile, "%c%c%c%c",
459                (Char)((long)newy / 256), (Char)((long)newy & 255), (Char)((long)newx / 256),
460                (Char)((long)newx & 255));
461        }
462      oldxreal = xabs;
463      oldyreal = yabs;
464      oldx = newx;
465      oldy = newy;
466      break;
467
468    case ray:
469      if (pen == pendown) {
470        if (linewidth != treeline) {
471          if (raylinewidth > labelline) {
472            raylinewidth = labelline;
473            fprintf(plotfile, "end\n\n");
474            fprintf(plotfile, "name species_names\n");
475            fprintf(plotfile, "grid 22 22 22\n");
476          }
477        }
478
479        if (oldxreal != xabs || oldyreal != yabs) {
480          raylinewidth *= 0.99999;
481          fprintf(plotfile, "cylinder %8.7f %6.3f 0 %6.3f %6.3f 0 %6.3f\n",
482                  raylinewidth, oldxreal, oldyreal, xabs, yabs);
483          fprintf(plotfile, "sphere %8.7f %6.3f 0 %6.3f\n",
484                  raylinewidth, xabs, yabs);
485        }
486      }
487      oldxreal = xabs;
488      oldyreal = yabs;
489      break;
490
491    case pov:
492      /* Default to writing out tree texture... */
493      strcpy (texture_string, TREE_TEXTURE);
494
495      if (pen == pendown) {
496        if (linewidth != treeline) {
497          /* Change the texture to name texture */
498          strcpy (texture_string, NAME_TEXTURE);
499
500          if (raylinewidth > labelline) {
501            raylinewidth = labelline;
502            fprintf(plotfile, "\n// Now, the species names:\n\n");
503          }
504        }
505
506        if (oldxreal != xabs || oldyreal != yabs) {
507          raylinewidth *= 0.99999;
508          fprintf(plotfile,
509                  "cylinder { <%6.3f, 0, %6.3f,>, <%6.3f, 0, %6.3f>, %8.7f \n",
510                  oldxreal, oldyreal, xabs, yabs, raylinewidth);
511          fprintf(plotfile, "\ttexture { %s } }\n", texture_string);
512
513          fprintf(plotfile, "sphere { <%6.3f, 0, %6.3f>, %8.7f \n",
514                  xabs, yabs, raylinewidth);
515          fprintf(plotfile, "\ttexture { %s } }\n", texture_string);
516
517        }
518      }
519      oldxreal = xabs;
520      oldyreal = yabs;
521      break;
522
523    case lw:
524      if (pen == pendown){
525        /* If there's NO possibility that the line interesects the page,
526         * leave it out. Otherwise, let postscript clip it to the page. */
527          if (!((xabs > clipx1*xunitspercm &&  oldx > clipx1*xunitspercm) ||
528              (xabs < clipx0*xunitspercm &&  oldx < clipx0*xunitspercm) ||
529              (yabs > clipy1*yunitspercm &&  oldy > clipy1*yunitspercm) ||
530              (yabs < clipy0*yunitspercm &&  oldy < clipy0*yunitspercm)))
531            fprintf(plotfile, "%8.2f %8.2f %8.2f %8.2f l\n",
532                    oldx-(clipx0*xunitspercm), oldy-(clipy0*yunitspercm),
533                    xabs-(clipx0*xunitspercm), yabs-(clipy0*yunitspercm));
534        }
535        oldx     = xabs,
536        oldy     = yabs;
537      break;
538
539    case idraw:
540      if (pen == pendown) {
541        fprintf(plotfile, "Begin %%I Line\n");
542        fprintf(plotfile, "%%I b 65535\n");
543        fprintf(plotfile, "%d 0 0 [] 0 SetB\n",
544                ((linewidth>=1.0) ? (int)linewidth : 1));
545        fprintf(plotfile, "%%I cfg Black\n");
546        fprintf(plotfile, "0 0 0 SetCFg\n");
547        fprintf(plotfile, "%%I cbg White\n");
548        fprintf(plotfile, "1 1 1 SetCBg\n");
549        fprintf(plotfile, "%%I p\n");
550        fprintf(plotfile, "0 SetP\n");
551        fprintf(plotfile, "%%I t\n");
552        fprintf(plotfile, "[ 0.01 0 0 0.01 216 285 ] concat\n");
553        fprintf(plotfile, "%%I\n");
554        fprintf(plotfile, "%ld %ld %ld %ld Line\n",
555                (long)(100.0 * (oldxreal+0.5)),
556                (long)(100.0 * (oldyreal+0.5)),
557                (long)(100.0 * (xabs+0.5)),
558                (long)(100.0 * (yabs+0.5)));
559        fprintf(plotfile, "End\n\n");
560
561        if (linewidth >= 4.0) {
562            fprintf(plotfile, "Begin %%I Elli\n");
563            fprintf(plotfile, "%%I b 65535\n");
564            fprintf(plotfile, "1 0 0 [] 0 SetB\n");
565            fprintf(plotfile, "%%I cfg Black\n");
566            fprintf(plotfile, "0 0 0 SetCFg\n");
567            fprintf(plotfile, "%%I cbg White\n");
568            fprintf(plotfile, "1 1 1 SetCBg\n");
569            fprintf(plotfile, "%%I p\n");
570            fprintf(plotfile, "0 SetP\n");
571            fprintf(plotfile, "%%I t\n");
572            fprintf(plotfile, "[ 0.01 0 0 0.01 216 285 ] concat\n");
573            fprintf(plotfile, "%%I\n");
574            fprintf(plotfile, "%ld %ld %ld %ld Elli\n",
575                    (long)(100.0 * (oldxreal+0.5)),
576                    (long)(100.0 * (oldyreal+0.5)),
577                    (long)(100.0 * (linewidth/2)) - 100,
578                    (long)(100.0 * (linewidth/2)) - 100);
579            fprintf(plotfile, "End\n");
580           
581            fprintf(plotfile, "Begin %%I Elli\n");
582            fprintf(plotfile, "%%I b 65535\n");
583            fprintf(plotfile, "1 0 0 [] 0 SetB\n");
584            fprintf(plotfile, "%%I cfg Black\n");
585            fprintf(plotfile, "0 0 0 SetCFg\n");
586            fprintf(plotfile, "%%I cbg White\n");
587            fprintf(plotfile, "1 1 1 SetCBg\n");
588            fprintf(plotfile, "%%I p\n");
589            fprintf(plotfile, "0 SetP\n");
590            fprintf(plotfile, "%%I t\n");
591            fprintf(plotfile, "[ 0.01 0 0 0.01 216 285 ] concat\n");
592            fprintf(plotfile, "%%I\n");
593            fprintf(plotfile, "%ld %ld %ld %ld Elli\n",
594                    (long)(100.0 * (xabs+0.5)),
595                    (long)(100.0 * (yabs+0.5)),
596                    (long)(100.0 * (linewidth/2)) - 100,
597                    (long)(100.0 * (linewidth/2)) - 100);
598            fprintf(plotfile, "End\n");
599        }
600      }
601      oldxreal = xabs;
602      oldyreal = yabs;
603      break;
604
605    case ibm:
606#ifdef TURBOC
607    newx = floor(xabs + 0.5);
608    newy = fabs(floor(yabs) - getmaxy());
609    if (pen == pendown)
610      line((long)oldx,(long)oldy,(long)newx,(long)newy);
611    oldx = newx;
612    oldy = newy;
613#endif
614#ifdef QUICKC
615    newx = floor(xabs + 0.5);
616    newy = fabs(floor(yabs) - myscreen.numypixels);
617
618    if (pen == pendown)
619        _lineto((long)newx,(long)newy);
620    else
621        _moveto((long)newx,(long)newy);
622    oldx = newx;
623    oldy = newy;
624
625#endif
626    break;
627     case mac:
628#ifdef MAC
629      if (pen == pendown){
630        LineTo((int)floor((double)xabs + 0.5),
631               winheight - (long)floor((double)yabs + 0.5)+MAC_OFFSET);}
632      else{
633        MoveTo((int)floor((double)xabs + 0.5),
634               winheight - (long)floor((double)yabs + 0.5)+MAC_OFFSET);}
635#endif
636
637      break;
638
639    case houston:
640      if (pen == pendown)
641        fprintf(plotfile, "D ");
642      else
643        fprintf(plotfile, "U ");
644      pout((long)((long)floor(xabs + 0.5)));
645      putc(',', plotfile);
646      pout((long)((long)floor(yabs + 0.5)));
647      putc('\n', plotfile);
648      break;
649
650    case decregis:
651      newx = floor(xabs + 0.5);
652      newy = fabs(floor(yabs + 0.5) - 479);
653      if (pen == pendown) {
654        if (previewing) {
655          printf("P[");
656          pout((long)oldx);
657          putchar(',');
658          pout((long)oldy);
659          printf("]V[");
660          pout((long)newx);
661          putchar(',');
662          pout((long)newy);
663          putchar(']');
664        } else {
665          fprintf(plotfile, "P[");
666          pout((long)oldx);
667          putc(',', plotfile);
668          pout((long)oldy);
669          fprintf(plotfile, "]V[");
670          pout((long)newx);
671          putc(',', plotfile);
672          pout((long)newy);
673          putc(']', plotfile);
674        }
675        nmoves++;
676        if (nmoves == 3) {
677          nmoves = 0;
678          if (previewing)
679            putchar('\n');
680          else
681            putc('\n', plotfile);
682        }
683      }
684      oldx = newx;
685      oldy = newy;
686      break;
687
688    case fig:
689      newx = floor(xabs + 0.5);
690      newy = floor(yabs + 0.5);
691      if (pen == pendown) {
692        fprintf(plotfile, "2 1 0 %5ld 0 0 0 0 0.000 0 0\n",
693                (long)floor(linewidth + 0.5) + 1);
694        fprintf(plotfile, "%5ld%5ld%5ld%5ld 9999 9999\n",
695                (long)oldx, 606 - (long) oldy, (long)newx, 606 - (long)newy);
696        fprintf(plotfile,
697          "1 3 0  1 0 0 0 21 0.00 1 0.0 %5ld%5ld%5ld %5ld %5ld%5ld%5ld 349\n",
698                (long)oldx, 
699                606 - (long) oldy, 
700                (long)floor(linewidth / 2 + 0.5),
701                (long)floor(linewidth / 2 + 0.5), 
702                (long)oldx, 606 - (long)oldy, 
703                606 - (long)oldy);
704        fprintf(plotfile,
705          "1 3 0  1 0 0 0 21 0.00 1 0.0 %5ld%5ld%5ld %5ld %5ld%5ld%5ld 349\n",
706                (long)newx, 
707                606 - (long)newy, 
708                (long)floor(linewidth / 2 + 0.5),
709                (long)floor(linewidth / 2 + 0.5), 
710                (long)newx, 
711                606 - (long)newy, 
712                606 - (long)newy);
713      }
714      oldx = newx;
715      oldy = newy;
716      break;
717
718    case vrml:
719
720      newx = xabs;
721      newy = yabs;
722      /* if this is the root node,
723         use the coordinates to define the view point */
724      if (firstNodeP-- == 1)
725      {
726        fprintf(plotfile, "#VRML V2.0 utf8\n");
727        fprintf(plotfile, "    NavigationInfo {\n");
728        fprintf(plotfile, "      headlight FALSE\n");
729        fprintf(plotfile, "    }\n");
730        fprintf(plotfile, "    Viewpoint\n");
731        fprintf(plotfile, "    {\n");
732        fprintf(plotfile, "      position %f %f %f\n", xsize/2, ysize/2, ysize*1.2);
733        fprintf(plotfile, "      description \"Entry View\"\n");
734        fprintf(plotfile, "    }\n");
735
736        for (i=0; i<3; i++) {
737          fprintf(plotfile, "    PointLight {\n");
738          fprintf(plotfile, "      on TRUE\n");
739          fprintf(plotfile, "      intensity %f\n",
740               vrmllights[i].intensity);
741          fprintf(plotfile, "      ambientIntensity 0.0\n");
742          fprintf(plotfile, "      color 1.0 1.0 1.0\n");
743          fprintf(plotfile, "      location %f %f %f\n",
744               vrmllights[i].x,
745               vrmllights[i].y,
746               vrmllights[i].z);
747          fprintf(plotfile, "      attenuation 0.0 0.0 0.0\n");
748          fprintf(plotfile, "      radius 200.0\n");
749          fprintf(plotfile, "    }\n");
750        }
751
752        fprintf(plotfile, "    Background\n");
753        fprintf(plotfile, "    {\n");
754        fprintf(plotfile, "      skyAngle [1.75]\n");
755        fprintf(plotfile, "      skyColor [%f %f %f, %f %f %f]\n",
756                  colors[vrmlskycolornear-1].red, 
757                  colors[vrmlskycolornear-1].green, 
758                  colors[vrmlskycolornear-1].blue,
759                  colors[vrmlskycolorfar-1].red, 
760                  colors[vrmlskycolorfar-1].green, 
761                  colors[vrmlskycolorfar-1].blue);
762        fprintf(plotfile, "      groundAngle[0 1.57 3.14]\n");
763        fprintf(plotfile,
764            "      groundColor [0.9 0.9 0.9, 0.7 0.7 0.7, %f %f %f]\n",
765                  colors[vrmlgroundcolorfar-1].red,
766                  colors[vrmlgroundcolorfar-1].green, 
767                  colors[vrmlgroundcolorfar-1].blue);
768        fprintf(plotfile, "    }\n");
769      }
770
771      if (pen == penup)
772      {/* pen down = beginning of a new path */
773      }
774      else if (pen == pendown)
775      {/* pen up = continue, line may not end yet. */
776
777        if (linewidth != treeline) {
778          if (vrmllinewidth > labelline) {
779            vrmllinewidth = labelline;
780            vrmlplotcolor = vrmlnamecolor;
781          }
782        }
783
784        distance = sqrt((newy - oldy)*(newy - oldy) + (newx - oldx)*(newx - oldx));
785        angle = computeAngle(oldx, oldy, newx, newy);
786
787        if (distance >= episilon)
788        {
789          fprintf(plotfile, "    DEF Line%ld Transform\n", lineCount++);
790          fprintf(plotfile, "    {\n");
791          fprintf(plotfile, "      rotation 0 0 1 %f\n", angle);
792          fprintf(plotfile, "      translation %f %f 0\n", oldx, oldy);
793          fprintf(plotfile, "      children\n");
794          fprintf(plotfile, "      [\n");
795          fprintf(plotfile, "        Shape\n");
796          fprintf(plotfile, "        {\n");
797          fprintf(plotfile, "          appearance Appearance\n");
798          fprintf(plotfile, "          {\n");
799          fprintf(plotfile, "            material Material { diffuseColor %f %f %f}\n",
800                  colors[vrmlplotcolor-1].red, 
801                  colors[vrmlplotcolor-1].green, 
802                  colors[vrmlplotcolor-1].blue);
803          fprintf(plotfile, "          }\n");
804          fprintf(plotfile, "          geometry Sphere\n");
805          fprintf(plotfile, "          {\n");
806/*          vrmllinewidth *= 0.99999; */
807          fprintf(plotfile, "            radius %f\n", vrmllinewidth);
808          fprintf(plotfile, "          }\n");
809          fprintf(plotfile, "        }\n");
810          fprintf(plotfile, "        Transform\n");
811          fprintf(plotfile, "        {\n");
812          fprintf(plotfile, "          rotation 0 0 1 -1.570796327\n" );
813          fprintf(plotfile, "          translation %f 0 0\n", distance/2);
814          fprintf(plotfile, "          children\n");
815          fprintf(plotfile, "          [\n");
816          fprintf(plotfile, "            Shape\n");
817          fprintf(plotfile, "            {\n");
818          fprintf(plotfile, "              appearance Appearance\n");
819          fprintf(plotfile, "              {\n");
820          fprintf(plotfile, "                material Material { diffuseColor %f %f %f}\n",
821                  colors[vrmlplotcolor-1].red, 
822                  colors[vrmlplotcolor-1].green, 
823                  colors[vrmlplotcolor-1].blue );
824          fprintf(plotfile, "              }\n");
825          fprintf(plotfile, "              geometry Cylinder\n");
826          fprintf(plotfile, "              {\n");
827          /* line radius affects end sphere's size */
828/*          vrmllinewidth *= 0.99999; */
829          fprintf(plotfile, "                radius %f\n", vrmllinewidth);
830          fprintf(plotfile, "                height %f\n", distance);
831          fprintf(plotfile, "              }\n");
832          fprintf(plotfile, "            }\n");
833          fprintf(plotfile, "          ]\n");
834          fprintf(plotfile, "        }\n");
835          fprintf(plotfile, "        Transform\n");
836          fprintf(plotfile, "        {\n");
837          fprintf(plotfile, "          translation %f 0 0\n", distance);
838          fprintf(plotfile, "          children\n");
839          fprintf(plotfile, "          [\n");
840          fprintf(plotfile, "            Shape\n");
841          fprintf(plotfile, "            {\n");
842          fprintf(plotfile, "              appearance Appearance\n");
843          fprintf(plotfile, "              {\n");
844          fprintf(plotfile, "                material Material { diffuseColor %f %f %f}\n",
845                  colors[vrmlplotcolor-1].red, 
846                  colors[vrmlplotcolor-1].green, 
847                  colors[vrmlplotcolor-1].blue );
848          fprintf(plotfile, "              }\n");
849          fprintf(plotfile, "              geometry Sphere\n");
850          fprintf(plotfile, "              {\n");
851          /* radius affects line size */
852/*          vrmllinewidth *= 0.99999; */
853          fprintf(plotfile, "                radius %f\n", vrmllinewidth);
854          fprintf(plotfile, "              }\n");
855          fprintf(plotfile, "            }\n");
856          fprintf(plotfile, "          ]\n");
857          fprintf(plotfile, "        }\n");
858          fprintf(plotfile, "      ]\n");
859          fprintf(plotfile, "    }\n");
860        }
861      }
862      else
863      {
864        fprintf(stderr, "ERROR: Programming error in plot().");
865      }
866
867      oldx = newx;
868      oldy = newy;
869      break;
870
871    case epson:
872    case oki:
873    case citoh:
874    case toshiba:
875    case pcx:
876    case pcl:
877    case bmp:
878    case xbm:
879    case gif:
880    case other:
881      break;
882      /* code for a pen move on a new plotter goes here */
883    }
884    return;
885  }
886  if (pen == pendown) {
887    ixabs = (long)floor(xabs + 0.5);
888    iyabs = (long)floor(yabs + 0.5);
889    ixnow = (long)floor(xnow + 0.5);
890    iynow = (long)floor(ynow + 0.5);
891    if (ixnow > ixabs) {
892      temp = ixnow;
893      ixnow = ixabs;
894      ixabs = temp;
895      temp = iynow;
896      iynow = iyabs;
897      iyabs = temp;
898    }
899    dx = ixabs - ixnow;
900    dy = iyabs - iynow;
901   /* if (dx + fabs(dy) <= 0.0)
902      c = 0.0;
903    else
904      c = 0.5 * linewidth / sqrt(dx * dx + dy * dy); */
905    cdx = (long)floor(linewidth + 0.5);
906    cdy = (long)floor(linewidth + 0.5);
907    if ((iyabs + cdx >= strpbottom || iynow + cdx >= strpbottom) &&
908        (iyabs - cdx <= strptop || iynow - cdx <= strptop)) {
909      drawfatline(ixnow,iynow,ixabs,iyabs,(long)floor(linewidth+0.5));
910    }
911  }
912
913  xnow = xabs;
914  ynow = yabs;
915
916  /* Bitmap Code to plot (xnow,ynow) to (xabs,yabs)                 */
917} /* plot                                                           */
918
919
920void idellipse(double x, double y) 
921{
922  fprintf(plotfile, "Begin %%I Elli\n");
923  fprintf(plotfile, "%%I b 65535\n");
924  fprintf(plotfile, "1 0 0 [] 0 SetB\n");
925  fprintf(plotfile, "%%I cfg Black\n");
926  fprintf(plotfile, "0 0 0 SetCFg\n");
927  fprintf(plotfile, "%%I cbg White\n");
928  fprintf(plotfile, "1 1 1 SetCBg\n");
929  fprintf(plotfile, "%%I p\n");
930  fprintf(plotfile, "0 SetP\n");
931  fprintf(plotfile, "%%I t\n");
932  fprintf(plotfile, "[ 0.01 0 0 0.01 216 285 ] concat\n");
933  fprintf(plotfile, "%%I\n");
934  fprintf(plotfile, "%ld %ld %ld %ld Elli\n",
935          (long)(100.0 * (x+0.5)),(long)(100.0 * (y+0.5)),
936          (long)(100.0 * (linewidth/2)) - 100,
937          (long)(100.0 * (linewidth/2)) - 100);
938  fprintf(plotfile, "End\n");
939}  /* idellipse */
940
941
942void splyne(double x1, double y1, double x2, double y2, boolean sense,
943                        long segs, boolean head, boolean tail)
944{
945/* sense is true if line departing from x1,y1 is tangential to x,
946   false if tangential to y */
947
948   
949  long i,fromx,fromy,tox,toy;
950  double f, g, h, x3, y3;
951  long ptop, pleft, pbottom, pright, startangle, arcangle;
952  double dtheta;
953  double sintheta,costheta,sindtheta,cosdtheta,newsintheta,newcostheta;
954  double rx,ry; /* axes of ellipse   */
955  double ox,oy; /* center of ellipse */
956  double prevx,prevy;
957  long pictint;
958 
959  x1 = x1 - (clipx0 * xunitspercm);
960  x2 = x2 - (clipx0 * xunitspercm);
961  y1 = y1 - (clipy0 * yunitspercm);
962  y2 = y2 - (clipy0 * yunitspercm); /* adjust by clipping region */
963
964  switch (plotter) {
965
966  case lw:
967    fprintf(plotfile,"stroke %8.2f %8.2f moveto\n",x1,y1);
968    if (sense)
969      fprintf(plotfile,"%8.2f %8.2f %8.2f %8.2f %8.2f %8.2f curveto\n",
970              (x1+(0.55*(x2-x1))), y1, x2, (y1+(0.45*(y2-y1))),
971              x2, y2);
972    else
973      fprintf(plotfile,"%8.2f %8.2f %8.2f %8.2f %8.2f %8.2f curveto\n",
974              x1, (y1+(0.55*(y2-y1))), (x1+(0.45*(x2-x1))), y2,
975              x2, y2);
976    break;
977
978  case pict:
979    {
980      double dtop, dleft, dbottom, dright,temp;
981      if (x1 == x2 || y1 == y2) {
982        plot(penup, x1, y1);
983        plot(pendown, x2, y2);
984      } else {
985    if (x2 > x1 && y2 < y1){ swap_m(x2,x1); swap_m(y2,y1); sense = !sense; } 
986       
987        y1 = (ysize * yunitspercm) - y1;
988        y2 = (ysize * yunitspercm) - y2; 
989
990        if (sense) {
991          if (x2 > x1) {
992            dtop = y2 - y1 + y2;
993            dleft = x1 - x2 + x1;
994            dbottom = y1;
995            dright = x2;
996            startangle = 90;
997          } else {
998
999            dtop = y2 - y1 + y2;
1000            dleft = x2;
1001            dbottom = y1;
1002            dright = x1 + (x1 - x2);
1003            startangle = 180;
1004          }
1005        }
1006         else {
1007          if (x2 > x1) {
1008            dtop = y1 + (y1 - y2);
1009            dleft = x1;
1010            dbottom = y2;
1011            dright = x2 + (x2 - x1);
1012            startangle = 270;
1013          } else {
1014            dtop = y2;
1015            dleft = x1;
1016            dbottom = y1 + y1 - y2;;
1017                dright = x2 + (x2 - x1);
1018            startangle = 0;
1019          }
1020        }
1021        arcangle = 90;
1022         if (dbottom < dtop) {swap_m(dbottom,dtop);}
1023    if (dleft> dright) {swap_m(dleft,dright);}
1024 
1025        ptop    = (long)floor((dtop - 0) + 0.5);
1026        pleft   = (long)floor(dleft  + 0.5);
1027        pbottom = (long)floor(dbottom + 0.5) + (long)floor(linewidth + 0.5);
1028        pright  = (long)floor(dright  + 0.5) + (long)floor(linewidth + 0.5);
1029
1030    if (!sense)
1031        pbottom++;
1032     else
1033        if (x2 < x1)
1034            pright++;
1035         else
1036            pleft--;
1037        pictint = 1;   
1038
1039        fprintf(plotfile,"\140%c%c%c%c%c%c%c%c%c%c%c%c",
1040                (Char)(ptop / 256), (Char)(ptop % 256),
1041                (Char)(pleft / 256), (Char)(pleft % 256),
1042                (Char)(pbottom / 256), (Char)(pbottom % 256),
1043                (Char)(pright / 256), (Char)(pright % 256),
1044                (Char)(startangle / 256), (Char)(startangle % 256),
1045                (Char)(arcangle / 256), (Char)(arcangle % 256));
1046      }
1047    }
1048    break;
1049
1050  case fig:
1051   fromx = (long)floor(x1 + 0.5);
1052   fromy = (long)floor(y1 + 0.5);
1053   tox = (long)floor(x2 + 0.5);
1054   toy = (long)floor(y2 + 0.5);
1055   
1056    fprintf(plotfile, "3 0 0 %5ld 0 0 0 0 0.000 0 0\n",
1057            (long)floor(linewidth + 0.5) + 1);
1058    if (sense)
1059      fprintf(plotfile, "%5ld%5ld%5ld%5ld%5ld%5ld%5ld%5ld 9999 9999\n",
1060              fromx, 606 - fromy,
1061              (long)floor((x1+(0.55*(x2-x1))) + 0.5), 606 - fromy,
1062              tox, 606 - (long)floor((y1+(0.45*(y2-y1))) + 0.5),
1063              tox, 606 - toy);
1064    else
1065      fprintf(plotfile, "%5ld%5ld%5ld%5ld%5ld%5ld%5ld%5ld 9999 9999\n",
1066              fromx, 606 - fromy,
1067              fromx, 606 - (long)floor((y1+(0.55*(y2-y1))) + 0.5),
1068              (long)floor((x1+(0.45*(x2-x1))) + 0.5), 606 - toy,
1069              tox, 606 - toy);
1070    fprintf(plotfile, "1 3 0  1 0 0 0 21 0.00 1 0.0 ");
1071    fprintf(plotfile, "%5ld%5ld%5ld %5ld %5ld%5ld%5ld 349\n",
1072            fromx, 606 - fromy, (long)floor(linewidth / 2 + 0.5),
1073            (long)floor(linewidth / 2 + 0.5), fromx,
1074            606 - fromy, 606 - fromy);
1075    fprintf(plotfile, "1 3 0  1 0 0 0 21 0.00 1 0.0 ");
1076    fprintf(plotfile, "%5ld%5ld%5ld %5ld %5ld%5ld%5ld 349\n",
1077            tox, 606 - toy, (long)floor(linewidth / 2 + 0.5),
1078            (long)floor(linewidth / 2 + 0.5), tox,
1079            606 - toy, 606 - toy);
1080    break;
1081
1082  case idraw:
1083   
1084    if (head){
1085      fprintf(plotfile,"Begin %%I Pict\n%%I b u\n%%I cfg u\n%%I cbg u\n");
1086      fprintf(plotfile,"%%I f u\n%%I p u \n%%I t u\n\n");
1087      idellipse(x1,y1);
1088      fprintf(plotfile, "Begin %%I BSpl\n");
1089      fprintf(plotfile, "%%I b 65535\n");
1090      fprintf(plotfile, "%ld 0 0 [] 0 SetB\n",
1091              ((linewidth>=1.0) ? (long)linewidth : 1));
1092      fprintf(plotfile, "%%I cfg Black\n");
1093      fprintf(plotfile, "0 0 0 SetCFg\n");
1094      fprintf(plotfile, "%%I cbg White\n");
1095      fprintf(plotfile, "1 1 1 SetCBg\n");
1096      fprintf(plotfile, "none SetP %%I p n\n");
1097      fprintf(plotfile, "%%I t\n");
1098      fprintf(plotfile, "[ 0.01 0 0 0.01 216 285 ] concat\n");
1099      if (tail)
1100        fprintf(plotfile,"%%I %ld\n",segs+1);
1101      else
1102        fprintf(plotfile,"%%I %ld\n",(segs*2)+1);
1103      fprintf(plotfile, "%ld %ld\n", (long)(100.0 * (x1+0.5)), 
1104              (long)(100.0 * (y1+0.5))); 
1105    }
1106    rx = (fabs(x2 - x1));
1107    ry = (fabs(y2 - y1));
1108
1109    if (!sense){
1110      if (x2 < x1)
1111        sintheta  = 0.0,
1112        costheta  = 1.0,
1113        dtheta = 90.0 / ((double)segs),
1114        ox = x2,
1115        oy = y1;
1116      else
1117        sintheta  = 0.0,
1118        costheta  = -1.0,
1119        dtheta = -90.0 / ((double)segs),
1120        ox = x2,
1121        oy = y1;
1122    }
1123    else{
1124      if (x2 < x1)
1125        sintheta  = -1.0,
1126        costheta  = 0.0,
1127        dtheta = -90.0 / ((double)segs),
1128        ox = x1,
1129        oy = y2;
1130      else
1131        sintheta  = -1.0,
1132        costheta  = 0.0,
1133        dtheta = 90.0 / ((double)segs),
1134        ox = x1,
1135        oy = y2;
1136        }
1137    x3        = x1;
1138    y3        = y1;
1139    sindtheta = sin(dtheta * (3.1415926535897932384626433 / 180.0));
1140    cosdtheta = cos(dtheta * (3.1415926535897932384626433 / 180.0));
1141   
1142    for (i = 1; i <= segs; i++) {
1143      prevx = x3;
1144      prevy = y3;
1145      newsintheta = (sintheta * cosdtheta) + (costheta * sindtheta);
1146      newcostheta = (costheta * cosdtheta) - (sintheta * sindtheta);
1147      sintheta = newsintheta;
1148      costheta = newcostheta;
1149      x3 = ox + (costheta * rx);
1150      y3 = oy + (sintheta * ry);
1151
1152      /* adjust spline for better aesthetics: */
1153      if (i == 1){
1154        if (sense)
1155          y3 = (y3 + prevy)  / 2.0;
1156        else
1157          x3 = (x3 + prevx) / 2.0;}
1158      else if (i == segs - 1){
1159        if (sense)
1160          x3 = (x3 + x2) / 2.0;
1161        else
1162          y3 = (y2 + y3) / 2.0;
1163      }
1164      fprintf(plotfile, "%ld %ld\n", (long)(100.0 * (x3+0.5)), 
1165              (long)(100.0 * (y3+0.5))); 
1166  }
1167    if (head && tail) 
1168      fprintf(plotfile," BSpl\nEnd\n\n"); /* changed for gcc */
1169      /*fprintf(plotfile,"%ld BSpl\nEnd\n\n"); This is the original */
1170    else if (tail) 
1171             fprintf(plotfile," BSpl \nEnd\n\n");  /* changed for gcc */
1172        /*fprintf(plotfile,"%ld BSpl\nEnd\n\n"); This is the original */
1173    if (tail)
1174      idellipse(x2,y2),
1175      fprintf(plotfile,"\nEnd %%I eop\n\n");
1176    break;
1177
1178  case hp:
1179    plot(penup,x1,y1);   
1180    if (sense){
1181      if (x2 > x1)
1182        fprintf(plotfile,"PD;AA%ld,%ld,90,1;\n",(long)x1,(long)y2);
1183      else
1184        fprintf(plotfile,"PD;AA%ld,%ld,-90,1;\n",(long)x1,(long)y2);
1185    }
1186    else {
1187      if (x2 > x1)
1188        fprintf(plotfile,"PD;AA%ld,%ld,-90,1;\n",(long)x2,(long)y1);
1189      else
1190        fprintf(plotfile,"PD;AA%ld,%ld,90,1;\n",(long)x2,(long)y1);
1191    }
1192    plot(penup,x2,y2); fprintf(plotfile,"PD;PU;");
1193
1194/*    else
1195      fprintf(plotfile,"PD;AA%ld,%ld,90,1;\n",(long)x2,(int)y1); */
1196    plot(penup,x2,y2);
1197    break;
1198  default:
1199    for (i = 1; i <= 2*segs; i++) {
1200      f = (double)i / (2*segs);
1201      g = (double)i / (2*segs);
1202      h = 1.0 - sqrt(1.0 - g * g);
1203      if (sense) {
1204        x3 = x1 * (1.0 - f) + x2 * f;
1205        y3 = y1 + (y2 - y1) * h;
1206      } else {
1207        x3 = x1 + (x2 - x1) * h;
1208        y3 = y1 * (1.0 - f) + y2 * f;
1209      }
1210      plot(pendown, x3, y3);
1211    }
1212    break;
1213  }
1214}  /* splyne */
1215
1216
1217void swoopspline(double x1, double y1, double x2, double y2, double x3,
1218                        double y3, boolean sense, long segs)
1219{
1220  splyne(x1,y1,x2,y2,sense,segs/4,true,false); 
1221  splyne(x2,y2,x3,y3,(boolean)(!sense),segs/4,false,true); 
1222}  /* swoopspline */
1223
1224
1225void curvespline(double x1, double y1, double x2, double y2,
1226                        boolean sense, long segs)
1227{
1228  splyne(x1,y1,x2,y2,sense,segs/2,true,true); 
1229}  /* curvespline */
1230
1231
1232/*******************************************/
1233static void putshort(FILE *fp, int i)
1234{
1235  int c, c1;
1236
1237  c = ((unsigned int ) i) & 0xff;  c1 = (((unsigned int) i)>>8) & 0xff;
1238  putc(c, fp);   putc(c1,fp);
1239}  /* putshort */
1240/*******************************************/
1241
1242
1243static void putint(FILE *fp, int i)
1244{
1245  int c, c1, c2, c3;
1246  c  = ((unsigned int ) i)      & 0xff; 
1247  c1 = (((unsigned int) i)>>8)  & 0xff;
1248  c2 = (((unsigned int) i)>>16) & 0xff;
1249  c3 = (((unsigned int) i)>>24) & 0xff;
1250
1251  putc(c, fp);   putc(c1,fp);  putc(c2,fp);  putc(c3,fp);
1252}  /* ptint */
1253
1254
1255void write_bmp_header (FILE *plotfile,int width,int height)
1256{
1257  /*
1258   *  write a 1-bit image header
1259   *
1260   */
1261
1262  byte r1[2],g1[2],b1[2] ;
1263
1264  int i, bperlin;
1265
1266  r1[0] = (long) 255;   /* Black */
1267  g1[0] = (long) 255;
1268  b1[0] = (long) 255;
1269
1270  r1[1] = 0;
1271  g1[1] = 0;
1272  b1[1] = 0;
1273
1274  bperlin = ((width + 31) / 32) * 4;   /* # bytes written per line */
1275
1276  putc('B', plotfile); 
1277  putc('M', plotfile);        /* BMP file magic number */
1278
1279  /* compute filesize and write it */
1280  i = 14 +                    /* size of bitmap file header */
1281      40 +                    /* size of bitmap info header */
1282      8 +                     /* size of colormap */
1283      bperlin * height;       /* size of image data */
1284
1285  putint(plotfile, i);
1286  putshort(plotfile, 0);          /* reserved1 */
1287  putshort(plotfile, 0);          /* reserved2 */
1288  putint(plotfile, 
1289         14 + 40 + 8);            /* offset from BOfile to BObitmap */
1290  putint(plotfile, 40);           /* biSize: size of bitmap info header */
1291  putint(plotfile, width);        /* Width */
1292  putint(plotfile, height);       /* Height */
1293  putshort(plotfile, 1);          /* Planes:  must be '1' */
1294  putshort(plotfile, 1);          /* BitCount: 1 */
1295  putint(plotfile, 0);            /* Compression:  BI_RGB = 0 */
1296  putint(plotfile, bperlin*height);/* SizeImage:  size of raw image data */
1297  putint(plotfile, 75 * 39);      /* XPelsPerMeter: (75dpi * 39 in. per meter) */
1298  putint(plotfile, 75 * 39);      /* YPelsPerMeter: (75dpi * 39 in. per meter) */
1299  putint(plotfile, 2);            /* ClrUsed: # of colors used in cmap */
1300  putint(plotfile, 2);            /* ClrImportant: same as above */
1301
1302  /* write out the colormap */
1303  for (i = 0 ; i < 2 ; i++) {
1304    putc(b1[i],plotfile);
1305    putc(g1[i],plotfile);
1306    putc(r1[i],plotfile);
1307    putc(0,    plotfile);
1308  }
1309}  /* write_bmp_header */
1310
1311
1312void reverse_bits (byte *full_pic, int location) 
1313{
1314  /* Reverse all the bits at location */
1315  int i, loop_end ; 
1316  byte orig, reversed;
1317
1318  /* initialize...*/
1319  orig = full_pic[location] ;
1320  reversed = (byte) '\0'; 
1321  loop_end = sizeof (byte) * 8 ;
1322
1323  if (orig == (byte) '\0') {
1324    /* No need to do anything for 0 bytes, */
1325    return ;
1326  } else {
1327    for (i = 0 ; i < loop_end ; i++) {
1328      reversed = (reversed << 1) | (orig & 1) ;
1329      orig   >>= 1 ;
1330    }
1331    full_pic[location] = reversed ;
1332  }
1333}  /* reverse_bits */
1334
1335
1336void turn_rows (byte *full_pic, int padded_width, int height)
1337{
1338  int i, j;
1339  int midpoint = padded_width / 2 ;
1340  byte temp ; /* For the swap call */
1341
1342  for (j = 0 ; j < height ; j++) {
1343    for (i = 0 ; i < midpoint ; i++) {
1344
1345      reverse_bits (full_pic, (j * padded_width) + i);
1346      reverse_bits (full_pic, (j * padded_width) + (padded_width - i));
1347      swap_m (full_pic[(j * padded_width) + i],
1348            full_pic[(j * padded_width) + (padded_width - i)]) ;
1349    }
1350    /* Then do the midpoint */
1351    reverse_bits (full_pic, (j * padded_width) + midpoint);
1352  }
1353}  /* turn_rows */
1354
1355
1356void translate_stripe_to_bmp(striptype *stripe, byte *full_pic,
1357                        int increment, int width, int div, int *total_bytes) 
1358{
1359  int padded_width, i, j, offset, pad_size,
1360    total_stripes, last_stripe_offset, truncated_stripe_height ;
1361  if (div == 0)
1362    /* For some reason this is called once without valid data */
1363    return ;
1364  else if (div == DEFAULT_STRIPE_HEIGHT) {
1365    /* For a non-last-stripe, figure out if the last stripe is going
1366       to be shorter than the others, to know how far from the bottom
1367       things should be offset. */
1368
1369    truncated_stripe_height = (int) ysize % DEFAULT_STRIPE_HEIGHT;
1370   
1371    if (truncated_stripe_height != 0)
1372      /* The last stripe isn't default height */
1373      last_stripe_offset = DEFAULT_STRIPE_HEIGHT - ((int) ysize %
1374                                                    DEFAULT_STRIPE_HEIGHT) ;
1375    else
1376      /* Stripes are all default height */
1377      last_stripe_offset = 0 ;
1378
1379  } else {
1380    /* For the last stripe, */
1381    last_stripe_offset = 0 ; 
1382  }
1383
1384  /* just for debugging... */
1385 
1386  total_stripes        = (int) ceil (ysize / (double) DEFAULT_STRIPE_HEIGHT);
1387
1388  /* width, padded to be a multiple of 32 bits, or 4 bytes */
1389  padded_width = ((width + 3)/4) * 4; 
1390  pad_size     = padded_width - width;
1391
1392  /* Include pad_size here, as it'll be turned horizontally later */
1393  offset       = ((total_stripes - increment) *
1394                  (padded_width * DEFAULT_STRIPE_HEIGHT))
1395    - (padded_width * last_stripe_offset)
1396    + pad_size ;
1397
1398  for (j = div; j >= 0; j--) {
1399    for (i = 0; i < width; i++) {
1400      full_pic[offset +       
1401              (((div-j) * padded_width) 
1402               + (width-i))] = (byte) (*stripe)[j][i];
1403      (*total_bytes)++ ;
1404    }
1405
1406    /* Take into account the padding */
1407    (*total_bytes) += pad_size ;
1408  }
1409}  /* translate_stripe_to_bmp */
1410
1411
1412void write_full_pic(byte *full_pic, int total_bytes)
1413{
1414  int i ;
1415  for (i = 0; i < total_bytes; i++) {
1416    putc (full_pic[i], plotfile);
1417  }
1418}  /* write_full_pic */
1419
1420
1421void makebox_no_interaction(char *fn, double *xo, double *yo,
1422                        double *scale, long ntips)
1423/* fn--fontname        xo,yo--x and y offsets */
1424{
1425  /* draw the box on screen which represents plotting area.        */
1426
1427  long xpag,ypag,i,j;
1428
1429  oldpenchange   = penchange;
1430  oldxsize       = xsize;
1431  oldysize       = ysize;
1432  oldxunitspercm = xunitspercm;
1433  oldyunitspercm = yunitspercm;
1434  oldxcorner     = xcorner;
1435  oldycorner     = ycorner;
1436  oldplotter     = plotter;
1437
1438  plotrparms(ntips);
1439  xcorner += 0.05 * xsize;
1440  ycorner += 0.05 * ysize;
1441  xsize *= 0.9;
1442  ysize *= 0.9;
1443  (*scale) = ysize / oldysize;
1444  if (xsize / oldxsize < (*scale))
1445    (*scale) = xsize / oldxsize;
1446  (*xo) = (xcorner + (xsize - oldxsize * (*scale)) / 2.0) / (*scale);
1447  (*yo) = (ycorner   + (ysize - oldysize * (*scale)) / 2.0) / (*scale);
1448
1449  xscale = (*scale) * xunitspercm;
1450  yscale = (*scale) * yunitspercm;
1451  initplotter(ntips,fn);
1452  plot(penup, xscale * (*xo), yscale * (*yo));
1453  plot(pendown, xscale * (*xo), yscale * ((*yo) + oldysize));
1454  plot(pendown, xscale * ((*xo) + oldxsize), yscale * ((*yo) + oldysize));
1455  plot(pendown, xscale * ((*xo) + oldxsize), yscale * (*yo));
1456  plot(pendown, xscale * (*xo), yscale * (*yo));
1457  /* we've done the extent, now draw the dividing lines: */
1458  xpag = (int)((pagex-hpmargin-0.01)/(paperx - hpmargin))+1;
1459  ypag = (int)((pagey-vpmargin-0.01)/(papery - vpmargin))+1;
1460  for (i=0;i<xpag;++i){
1461    plot(penup,(xscale * (*xo))+xscale*i*(paperx - hpmargin),((*yo)*yscale)+0);
1462    plot(pendown,(xscale * (*xo))+xscale*i*(paperx - hpmargin),((*yo)*yscale)+yscale*pagey);
1463    }
1464  for (j=0;j<ypag;++j){
1465    plot(penup,(xscale * (*xo)),((*yo)*yscale)+yscale*j*(papery-vpmargin));
1466    plot(pendown,(xscale * (*xo))+xscale*pagex,((*yo)*yscale)+yscale*j*(papery-hpmargin));
1467    }
1468}  /* makebox_no_interaction */
1469
1470
1471boolean plot_without_preview(char *fn, double *xo, double *yo,
1472                        double *scale, long nt, node *root)
1473{
1474
1475  previewing = false;
1476  makebox_no_interaction(fn,xo,yo,scale,nt);
1477  penchange = oldpenchange;
1478  xsize = oldxsize;
1479  ysize = oldysize;
1480  xunitspercm = oldxunitspercm;
1481  yunitspercm = oldyunitspercm;
1482  xscale = xunitspercm;
1483  yscale = yunitspercm;
1484  plotter = oldplotter;
1485  xcorner = oldxcorner;
1486  ycorner = oldycorner;
1487  return 1;
1488}  /* plot_without_preview */
1489
1490
1491void void_func()
1492{
1493    fprintf(plotfile, "// Declare the colors\n\n");
1494    fprintf(plotfile, "#declare C_White       = color rgb<1, 1, 1>\n");
1495
1496    fprintf(plotfile, "#declare C_White_trans = color rgbt<1, 1, 1, 0.7>\n");
1497
1498    fprintf(plotfile, "#declare C_Red         = color rgb<1, 0, 0>\n");
1499   
1500    fprintf(plotfile, "#declare C_Yellow      = color rgb<1, 1, 0>\n");
1501   
1502    fprintf(plotfile, "#declare C_Green       = color rgb<0, 1, 0>\n");
1503   
1504    fprintf(plotfile, "#declare C_Black       = color rgb<0, 0, 0>\n");
1505   
1506    fprintf(plotfile, "#declare C_Blue        = color rgb<0, 0, 1>\n");
1507   
1508    fprintf(plotfile, "\n// Declare the textures\n\n");
1509    fprintf(plotfile, "#declare T_White = texture { pigment { C_White }}\n");
1510    fprintf(plotfile, "#declare T_White_trans = texture { pigment { C_White_trans }}\n");
1511    fprintf(plotfile, "#declare T_Red = texture { pigment { C_Red }\n");
1512    fprintf(plotfile, "\tfinish { phong 1 phong_size 100 }}\n");
1513    fprintf(plotfile, "#declare T_Red_trans = texture { pigment { C_Red filter 0.7 }\n");
1514    fprintf(plotfile, "\tfinish { phong 1 phong_size 100 }}\n");
1515    fprintf(plotfile, "#declare T_Green = texture { pigment { C_Green }\n");
1516    fprintf(plotfile, "\tfinish { phong 1 phong_size 100 }}\n");
1517
1518    fprintf(plotfile, "#declare T_Green_trans = texture { \n");
1519    fprintf(plotfile, "\tpigment { C_Green filter 0.7 }\n");
1520    fprintf(plotfile, "\tfinish { phong 1 phong_size 100 }}\n");
1521
1522    fprintf(plotfile, "#declare T_Blue = texture { pigment { C_Blue }\n");
1523    fprintf(plotfile, "\tfinish { phong 1 phong_size 100 }}\n");
1524
1525    fprintf(plotfile, "#background { color rgb<1, 1, 1> }\n");
1526}  /* void_func */
1527
1528
1529/* added for vrml - danieyek 981111 */
1530/* Returned angle in radian */
1531/* A related function is "double angleBetVectors(Xu, Yu, Xv, Yv)"
1532   in drawtree.c */
1533double computeAngle(double oldx, double oldy, double newx, double newy)
1534{
1535  double angle;
1536
1537  if ((newx-oldx) == 0 )
1538  {
1539    /* pi/2 or -pi/2! */
1540    if (newy > oldy) angle = pie/2;
1541    else if (newy < oldy) angle = -pie/2;
1542    else 
1543    {
1544      /* added - danieyek 990130 */
1545      /* newx = oldx; newy = oldy; one point on top of the other!
1546         If new and old correspond to 2 points, changes are that the 2 coordinates
1547         are not identical under double precision value. */
1548      fprintf(stderr, 
1549      "ERROR: Angle can't be computed, 2 points on top of each other in computeAngle()!\n");
1550      angle = 0;
1551    }
1552  }
1553  else
1554  {
1555    angle = atan( (newy-oldy)/(newx-oldx) );
1556
1557    if (newy >= oldy && newx >= oldx)
1558    {
1559      /* First quardrant - no adjustment */
1560    }
1561    else if (newx <= oldx)
1562    {
1563      /* Second (angle = negative) and
1564         third (angle = positive) quardrant */
1565      angle = pie + angle;
1566    }
1567    else if (newy <= oldy && newx >= oldx)
1568    {
1569      /* Fourth quardrant; "angle" is negative! */
1570      angle = 2*pie + angle;
1571    }
1572    else
1573    {
1574      /* Should never get here. */
1575      fprintf(stderr, "ERROR: Programming error in computeAngle()!\n");
1576    }
1577  }
1578  return angle;
1579}  /* computeAngle */
1580
1581#ifdef WIN32
1582#include <windows.h>
1583
1584/*********************  Prototypes  ***********************/
1585
1586LRESULT WINAPI MainWndProc( HWND, UINT, WPARAM, LPARAM );
1587LRESULT WINAPI AboutDlgProc( HWND, UINT, WPARAM, LPARAM );
1588
1589/*******************  Global Variables ********************/
1590extern void winplotpreviewcore();
1591HANDLE ghInstance;
1592HPEN hPenTree, hPenLabel, hPenBackground, hPenOld; 
1593
1594/********************************************************************\
1595*  Comments: Register window class, create and display the main      *
1596*            window, and enter message loop.                         *
1597\********************************************************************/
1598
1599winplotpreview()
1600{
1601   WNDCLASS wc;
1602   MSG msg;
1603   HWND hWnd;
1604   int screenXres, screenYres, winXres, winYres;
1605
1606   winaction = quitnow;
1607
1608   wc.lpszClassName = "GenericAppClass";
1609   wc.lpfnWndProc = MainWndProc;
1610   wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
1611   wc.hInstance = NULL;
1612   wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
1613   wc.hCursor = LoadCursor( NULL, IDC_ARROW );
1614   wc.hbrBackground = (HBRUSH)( COLOR_WINDOW+1 );
1615   wc.lpszMenuName = "GenericAppMenu";
1616   wc.cbClsExtra = 0;
1617   wc.cbWndExtra = 0;
1618
1619   RegisterClass( &wc );
1620
1621   ghInstance = NULL;
1622
1623   screenXres = GetSystemMetrics(SM_CXSCREEN);
1624   winXres = (int)((float)(screenXres)*XWINPERCENT);
1625   screenYres = GetSystemMetrics(SM_CYSCREEN);
1626   winYres = (int)((float)(screenYres)*YWINPERCENT);
1627
1628   hWnd = CreateWindow( "GenericAppClass",
1629      "Tree Preview",
1630      WS_OVERLAPPEDWINDOW,
1631      0,
1632      0,
1633      winXres,
1634      winYres,
1635      NULL,
1636      NULL,
1637      NULL,
1638      NULL
1639   );
1640
1641   ShowWindow( hWnd, SW_SHOWNORMAL );
1642
1643   while( GetMessage( &msg, NULL, 0, 0 ) ) {
1644      TranslateMessage( &msg );
1645      DispatchMessage( &msg );
1646   }
1647
1648   return msg.wParam;
1649}
1650
1651/*********************     *
1652*                                                                    *
1653* Comments: The following messages are processed                     *
1654*                                                                    *
1655*           WM_PAINT                                                 *
1656*           WM_COMMAND                                               *
1657*           WM_DESTROY                                               *
1658*                                                                    *
1659*                                                                    *
1660\********************************************************************/
1661
1662LRESULT CALLBACK MainWndProc( HWND hWnd, UINT msg, WPARAM wParam,
1663   LPARAM lParam )
1664{
1665   PAINTSTRUCT ps;
1666   LOGBRUSH lb;
1667   HBRUSH bgbrush; 
1668   RECT lpRect;
1669   int windowwidth, windowheight;
1670
1671   switch( msg ) {
1672/**************************************************************\
1673*     WM_ACTIVATE:                                             *
1674\**************************************************************/
1675
1676      case WM_ACTIVATE:
1677         if (wParam != WA_INACTIVE)
1678            BringWindowToTop(hWnd);
1679      break;
1680
1681/**************************************************************\
1682*     WM_PAINT:                                                *
1683\**************************************************************/
1684
1685      case WM_PAINT:
1686         hdc = BeginPaint( hWnd, &ps );
1687         /* Initialize the pen's brush. */
1688         lb.lbStyle = BS_SOLID; 
1689         lb.lbColor = RGB(0,0,0); 
1690         lb.lbHatch = 0;
1691         /* 2 pixel pen for the tree */
1692         hPenTree = ExtCreatePen(PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_ROUND,
1693                            (DWORD)2, &lb, 0, NULL); 
1694         /* 1 pixel pen for labels */
1695         hPenLabel = ExtCreatePen(PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_ROUND,
1696                            (DWORD)1, &lb, 0, NULL); 
1697         /* light blue pen for outline of background rectangle */
1698         lb.lbColor = RGB(204,255,255);
1699         hPenBackground = ExtCreatePen(PS_GEOMETRIC | PS_SOLID,
1700                            (DWORD)1, &lb, 0, NULL); 
1701         /* light blue brush for interior of background rectangle */
1702         bgbrush = CreateSolidBrush(RGB(204,255,255));
1703         /* GetClientRect returns the size of that part of the window
1704            that is actually ours to draw in.
1705          */
1706         GetClientRect(hWnd, &lpRect);
1707         windowwidth = lpRect.right;
1708         windowheight = lpRect.bottom;
1709         /* select background pen and brush */ 
1710         SelectObject(hdc, hPenBackground);
1711         SelectObject(hdc, bgbrush);
1712         /* fill background */
1713         Rectangle(hdc, 0, 0, windowwidth, windowheight);
1714         /* select tree pen */
1715         hPenOld = SelectObject(hdc, hPenTree); 
1716         /* winplotpreviewcore calls makebox, plottree, plotlabels and
1717            finishplotter
1718          */
1719         winplotpreviewcore(windowwidth, windowheight);
1720         /* delete pens to recover memory */
1721         DeleteObject(hPenTree); 
1722         DeleteObject(hPenLabel);
1723         DeleteObject(hPenBackground);
1724         DeleteObject(bgbrush);
1725         EndPaint( hWnd, &ps );
1726         break;
1727
1728/**************************************************************\
1729*     WM_COMMAND:                                              *
1730\**************************************************************/
1731
1732      case WM_COMMAND:
1733         switch( wParam ) {
1734            case IDM_ABOUT:
1735               DialogBox( ghInstance, "AboutDlg", hWnd, (DLGPROC)
1736                          AboutDlgProc );
1737            break;
1738            case IDM_PLOT: // "Plot" menu item
1739               winaction = plotnow;
1740               DestroyWindow(hWnd);
1741            break;
1742            case IDM_CHANGE: // "Change Parameters" menu item
1743               winaction = changeparms;
1744               DestroyWindow(hWnd);
1745            break;
1746            case IDM_QUIT: // "Quit" menu item
1747               winaction = quitnow;
1748               DestroyWindow(hWnd);
1749            break;
1750         }
1751      break;
1752
1753/**************************************************************\
1754*     WM_DESTROY: PostQuitMessage() is called                  *
1755\**************************************************************/
1756
1757      case WM_DESTROY:
1758         PostQuitMessage( 0 );
1759         break;
1760
1761/**************************************************************\
1762*     Let the default window proc handle all other messages    *
1763\**************************************************************/
1764
1765      default:
1766         return( DefWindowProc( hWnd, msg, wParam, lParam ));
1767   }
1768
1769   return 0;
1770}
1771
1772/********************************************************************\
1773* Function: LRESULT CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM)*
1774*                                                                    *
1775*  Purpose: Processes "About" Dialog Box Messages                    *
1776*                                                                    *
1777* Comments: The About dialog box is displayed when the user clicks   *
1778*           About from the Help menu.                                *
1779*                                                                    *
1780\********************************************************************/
1781
1782LRESULT CALLBACK AboutDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
1783{
1784   switch( uMsg ) {
1785      case WM_INITDIALOG:
1786         return TRUE;
1787      case WM_COMMAND:
1788         switch( wParam ) {
1789            case IDOK:
1790               EndDialog( hDlg, TRUE );
1791               return TRUE;
1792         }
1793      break;
1794   }
1795
1796   return FALSE;
1797}
1798
1799
1800#endif
Note: See TracBrowser for help on using the repository browser.