source: tags/arb-6.0/GDE/PHYLIP/drawgram.c

Last change on this file was 2175, checked in by westram, 20 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: 44.8 KB
Line 
1
2#include "draw.h"
3/* Version 3.6.  Copyright (c) 1986-2002 by Joseph Felsenstein and
4  Christopher A. Meacham.  Additional code written by Hisashi Horino,
5  Sean Lamont, Andrew Keefe, Daniel Fineman, and Akiko Fuseki.
6  Permission is granted to copy, distribute, and modify this
7  program provided that (1) this copyright message is not removed
8  and (2) no fee is charged for this program. */
9
10
11#define gap 0.5    /* distance in character heights between the end
12                      of a branch and the start of the name */
13FILE *plotfile;
14char pltfilename[FNMLNGTH];
15char trefilename[FNMLNGTH];
16char *progname;
17
18long nextnode,  strpwide, strpdeep, strpdiv,
19        strptop, strpbottom, payge, numlines, hpresolution, iteration;
20boolean preview, previewing, dotmatrix,
21         haslengths, uselengths, empty, rescaled, firstscreens,
22         pictbold, pictitalic, pictshadow, pictoutline, multiplot, finished;
23double xmargin, ymargin, topoflabels, bottomoflabels, rightoflabels,
24       leftoflabels, tipspacing,maxheight, scale, xscale, yscale,
25       xoffset, yoffset, nodespace, stemlength, treedepth, xnow, ynow,
26       xunitspercm, yunitspercm,
27       xsize, ysize, xcorner, ycorner, labelheight,labelrotation,expand, rootx,
28       rooty, bscale, xx0, yy0, fontheight, maxx, minx, maxy, miny;
29double pagex, pagey, paperx, papery, hpmargin, vpmargin;
30
31double *textlength, *firstlet;
32striptype stripe;
33plottertype plotter, oldplotter, previewer;
34growth grows;
35treestyle style;
36node *root;
37pointarray nodep;
38pointarray treenode;
39fonttype font;
40long filesize;
41Char ch, resopts;
42double trweight;   /* starting here, needed to make sccs version happy */
43boolean goteof;
44node *grbg;
45long *zeros;     /* ... down to here */
46
47       enum {yes, no} penchange, oldpenchange;
48static enum {weighted, intermediate, centered, inner, vshaped} nodeposition;
49winactiontype winaction;
50
51#ifdef X
52String res[]= {
53        "*.input: True",
54        "*.menubar.orientation: horizontal",
55        "*.menubar.borderWidth: 0",
56        "*.drawing_area.background: #CCFFFF",
57        "*.drawing_area.foreground: #000000",
58        "*.menubar.right: ChainLeft",
59        "*.menubar.bottom: ChainTop",
60        "*.menubar.top: ChainTop",
61        "*.menubar.left: ChainLeft",
62        "*.drawing_area.fromVert: menubar",
63        "*.drawing_area.top: ChainTop",
64        "*.drawing_area.bottom: ChainBottom",
65        "*.drawing_area.left: ChainLeft",
66        "*.drawing_area.right: ChainRight",
67        "*.dialog.label: Drawgram -- Rooted tree plotting program\\n\\n\\nPHYLIP version 3.6. (c) Copyright 1993-2002 by The University of Washington.\\nWritten by Joseph Felsenstein, Andrew Keeffe, Akiko Fuseki, Sean Lamont\\nand Dan Fineman\\nPermission is granted to copy and use this program provided no fee is\\ncharged for it and provided that this copyright notice is not removed.",
68        NULL
69};
70#endif
71
72
73#ifndef OLDC
74/* function prototypes */
75void   initdrawgramnode(node **, node **, node *, long, long, long *,
76                long *, initops, pointarray, pointarray, Char *, Char *, FILE *);
77void   initialparms(void);
78char   showparms(void);
79void   getparms(char);
80void   calctraverse(node *, double, double *);
81void   calculate(void);
82void   rescale(void);
83void   setup_environment(Char *argv[], boolean *);
84void   user_loop(boolean *);
85/* function prototypes */
86#endif
87
88void initdrawgramnode(node **p, node **grbg, node *q, long len,
89                long nodei, long *ntips, long *parens, initops whichinit,
90                pointarray treenode, pointarray nodep, Char *str, Char *ch,
91                FILE *intree)
92{
93  /* initializes a node */
94  long i;
95  boolean minusread;
96  double valyew, divisor;
97
98  switch (whichinit) {
99  case bottom:
100    gnu(grbg, p);
101    (*p)->index = nodei;
102    (*p)->tip = false;
103    for (i=0;i<MAXNCH;i++)
104      (*p)->nayme[i] = '\0';
105    nodep[(*p)->index - 1] = (*p);
106    break;
107  case nonbottom:
108    gnu(grbg, p);
109    (*p)->index = nodei;
110    break;
111  case tip:
112    (*ntips)++;
113    gnu(grbg, p);
114    nodep[(*ntips) - 1] = *p;
115    setupnode(*p, *ntips);
116    (*p)->tip = true;
117    (*p)->naymlength = len ;
118    strncpy ((*p)->nayme, str, MAXNCH);
119    break;
120  case length:
121    processlength(&valyew, &divisor, ch, &minusread, intree, parens);
122    if (!minusread)
123      (*p)->oldlen = valyew / divisor;
124    else
125      (*p)->oldlen = 0.0;
126    break;
127  case hsnolength:
128    haslengths = false;
129    break;
130  default:        /* cases hslength,treewt,unittrwt,iter        */
131    break;        /* should never occur                        */
132  }
133} /* initdrawgramnode */
134
135
136void initialparms()
137{
138  /* initialize parameters */
139  plotter = DEFPLOTTER;
140  previewer = DEFPREV;
141  paperx=20.6375;
142  pagex=20.6375;
143  papery=26.9875;
144  pagey=26.9875;
145  strcpy(fontname,"Times-Roman");
146  plotrparms(spp);   /* initial, possibly bogus, parameters */
147  style = phenogram;
148  grows = horizontal;
149  labelrotation = 90.0;
150  nodespace = 3.0;
151  stemlength = 0.05;
152  treedepth = 0.5 / 0.95;
153  rescaled = true;
154  bscale = 1.0;
155  uselengths = haslengths;
156  if (uselengths)
157    nodeposition = weighted;
158  else
159    nodeposition = centered;
160  xmargin = 0.08 * xsize;
161  ymargin = 0.08 * ysize;
162  preview = true;
163  hpmargin = 0.02*pagex;
164  vpmargin = 0.02*pagey;
165}  /* initialparms */
166
167
168char showparms()
169{
170  char input[32];
171  Char ch;
172  char cstr[32];
173
174  if (!firstscreens)
175    clearit();
176  printf("\nRooted tree plotting program version %s\n\n", VERSION);
177  printf("Here are the settings: \n");
178  printf(" 0  Screen type (IBM PC, ANSI):  %s\n",
179           ibmpc ? "IBM PC" : ansi  ? "ANSI"  : "(none)");
180  printf(" P       Final plotting device: ");
181  switch (plotter) {
182    case lw:
183      printf(" Postscript printer\n");
184      break;
185    case pcl:
186      printf(" HP Laserjet compatible printer (%d DPI)\n", (int) hpresolution);
187      break;
188    case epson:
189      printf(" Epson dot-matrix printer\n");
190      break;
191    case pcx:
192      printf(" PCX file for PC Paintbrush drawing program (%s)\n",
193             (resopts == 1) ? "EGA 640x350" : 
194             (resopts == 2) ? "VGA 800x600" : "VGA 1024x768");
195      break;
196    case pict:
197      printf(" Macintosh PICT file for drawing program\n");
198      break;
199    case idraw:
200      printf(" Idraw drawing program\n");
201      break;
202    case fig:
203      printf(" Xfig drawing program\n");
204      break;
205    case hp:
206      printf(" HPGL graphics language for HP plotters\n");
207      break;
208    case xbm:
209      printf(" X Bitmap file format (%d by %d resolution)\n",(int)xsize,(int)ysize);
210      break;
211    case bmp:
212      printf(" MS-Windows Bitmap (%d by %d resolution)\n",(int)xsize,(int)ysize);
213      break;
214    case gif:
215      printf(" Compuserve GIF format (%d by %d)\n",(int)xsize,(int)ysize);
216      break;
217    case ibm:
218      printf(" IBM PC graphics (CGA, EGA, or VGA)\n");
219      break;
220    case tek:
221      printf(" Tektronix graphics screen\n");
222      break;
223    case decregis:
224      printf(" DEC ReGIS graphics (VT240 or DECTerm)\n");
225      break;
226    case houston:
227      printf(" Houston Instruments plotter\n");
228      break;
229    case toshiba:
230      printf(" Toshiba 24-pin dot matrix printer\n");
231      break;
232    case citoh:
233      printf(" Imagewriter or C.Itoh/TEC/NEC 9-pin dot matrix printer\n");
234      break;
235    case oki:
236      printf(" old Okidata 9-pin dot matrix printer\n");
237      break;
238    case ray:
239      printf(" Rayshade ray-tracing program file format\n");
240      break;
241    case pov:
242      printf(" POV ray-tracing program file format\n");
243      break;
244    case vrml:
245      printf(" VRML, Virtual Reality Markup Language\n");
246      break;
247    case mac:
248    case other:
249      printf(" (Current output device unannounced)\n");
250      break;
251    default:        /*case xpreview not handled */
252      break;
253  }
254  printf(" V           Previewing device: ");
255  if (!preview)
256    printf(" (none)\n");
257  else {
258    switch (previewer) {
259      case ibm:
260        printf(" IBM PC graphics (CGA, EGA, or VGA)\n");
261        break;
262      case xpreview:
263        printf(" X Windows display\n");
264        break;
265      case tek:
266        printf(" Tektronix graphics screen\n");
267        break;
268      case mac:
269        printf(" Macintosh graphics screen\n");
270        break;
271      case decregis:
272        printf(" DEC ReGIS graphics (VT240 or DECTerm)\n");
273        break;
274      case winpreview:
275        printf(" MS Windows display\n");
276        break;
277      case other:
278        printf(" (Current previewing device unannounced)\n");
279        break;
280      default:   /* all other cases */
281        break;
282    }
283  }
284  printf(" H                  Tree grows:  ");
285  printf((grows == vertical) ? "Vertically\n" : "Horizontally\n");
286  printf(" S                  Tree style:  %s\n",
287         (style == cladogram) ? "Cladogram" :
288         (style == phenogram)  ? "Phenogram" :
289         (style == curvogram) ? "Curvogram" :
290         (style == eurogram)  ? "Eurogram"  : 
291         (style == swoopogram) ? "Swoopogram" : "Circular");
292  printf(" B          Use branch lengths:  ");
293  if (haslengths) {
294    if (uselengths)
295      printf("Yes\n");
296    else
297      printf("No\n");
298  } else
299    printf("(no branch lengths available)\n");
300  if (style != circular) {
301    printf(" L             Angle of labels:");
302    if (labelrotation < 10.0)
303      printf("%5.1f\n", labelrotation);
304    else
305      printf("%6.1f\n", labelrotation);
306  }
307  printf(" R      Scale of branch length:");
308  if (rescaled)
309    printf("  Automatically rescaled\n");
310  else
311    printf("  Fixed:%6.2f cm per unit branch length\n", bscale);
312  printf(" D       Depth/Breadth of tree:%6.2f\n", treedepth);
313  printf(" T      Stem-length/tree-depth:%6.2f\n", stemlength);
314  printf(" C    Character ht / tip space:%8.4f\n", 1.0 / nodespace);
315  printf(" A             Ancestral nodes:  %s\n",
316         (nodeposition == weighted)     ? "Weighted"     :
317         (nodeposition == intermediate) ? "Intermediate" :
318         (nodeposition == centered)     ? "Centered"     :
319         (nodeposition == inner)        ? "Inner"        :
320         "So tree is V-shaped");
321  if (plotter == lw || plotter == idraw || 
322      (plotter == fig && (labelrotation == 90.0 || labelrotation == 180.0 || 
323                          labelrotation == 270.0 || labelrotation == 0.0)) ||
324  (plotter == pict && ((grows == vertical && labelrotation == 0.0) ||
325                      (grows == horizontal && labelrotation == 90.0))))
326    printf(" F                        Font:  %s\n",fontname);
327  if ((plotter == pict && ((grows == vertical && labelrotation == 0.0) ||
328                      (grows == horizontal && labelrotation == 90.0)))
329                   && (strcmp(fontname,"Hershey") != 0))
330    printf(" Q        Pict Font Attributes:  %s, %s, %s, %s\n",
331        (pictbold   ? "Bold"   : "Medium"),
332        (pictitalic ? "Italic" : "Regular"),
333        (pictshadow ? "Shadowed": "Unshadowed"),
334        (pictoutline ? "Outlined" : "Unoutlined"));
335  if (plotter == ray) {
336    printf(" M          Horizontal margins:%6.2f pixels\n", xmargin);
337    printf(" M            Vertical margins:%6.2f pixels\n", ymargin);
338  } else {
339    printf(" M          Horizontal margins:%6.2f cm\n", xmargin);
340    printf(" M            Vertical margins:%6.2f cm\n", ymargin);
341  }
342  printf(" #              Pages per tree:  ");
343  /* Add 0.5 to clear up truncation problems. */
344  if (((int) ((pagex / paperx) + 0.5) == 1) && 
345      ((int) ((pagey / papery) + 0.5) == 1))
346    /* If we're only using one page per tree, */
347    printf ("one page per tree\n") ;   
348  else
349    printf ("%.0f by %.0f pages per tree\n",
350             (pagey-vpmargin) / (papery-vpmargin),
351             (pagex-hpmargin) / (paperx-hpmargin)) ;
352
353  for (;;) {
354    printf("\n Y to accept these or type the letter for one to change\n");
355#ifdef WIN32
356    phyFillScreenColor();
357#endif
358    getstryng(input);
359    uppercase(&input[0]);
360    ch=input[0];
361    if (plotter == idraw || plotter == lw)
362       strcpy(cstr,"#Y0PVHSBLMRDTCAF");
363    else if (((plotter == fig) && (labelrotation == 0.0))
364             || (labelrotation == 90.0 )
365             || (labelrotation == 180.0) || (labelrotation == 270.0))
366      strcpy(cstr,"#Y0PVHSBLMRDTCAFQ");
367    else if (plotter == pict){
368        if (((grows == vertical && labelrotation == 0.0) ||
369            (grows == horizontal && labelrotation == 90.0)))
370                strcpy(cstr,"#Y0PVHSBLMRDTCAFQ");
371           else
372              strcpy(cstr,"#Y0PVHSBLMRDTCA"); }
373    else
374      strcpy(cstr,"#Y0PVHSBLMRDTCA");
375                     
376    if  (strchr(cstr,ch))
377      break;
378    printf(" That letter is not one of the menu choices.  Type\n");
379  }
380 return ch;
381}  /* showparms */
382
383
384void getparms(char numtochange)
385{
386  /* get from user the relevant parameters for the plotter and diagram */
387  long loopcount;
388  Char ch;
389  char input[100];
390  boolean ok;
391  int i, m, n;
392     
393  n = (int)((pagex-hpmargin-0.01)/(paperx-hpmargin)+1.0);
394  m = (int)((pagey-vpmargin-0.01)/(papery-vpmargin)+1.0);
395  switch (numtochange) {
396
397  case '0':
398    initterminal(&ibmpc, &ansi);
399    break;
400
401  case 'P':
402    getplotter();
403    break;
404
405  case 'V':
406    getpreview();
407    break;
408
409  case 'H':
410    if (grows == vertical)
411      grows = horizontal;
412    else
413      grows = vertical;
414    break;
415
416  case 'S':
417    clearit() ; 
418    printf("What style tree is this to be (currently set to %s):\n",
419           (style == cladogram) ? "Cladogram" :
420           (style == phenogram)  ? "Phenogram" :
421           (style == curvogram) ? "Curvogram" :
422           (style == eurogram)  ? "Eurogram"  : 
423           (style == swoopogram) ? "Swoopogram" : "Circular") ;
424    printf(" C    Cladogram -- v-shaped \n") ;
425    printf(" P    Phenogram -- branches are square\n") ;
426    printf(" V    Curvogram -- branches are 1/4 of an ellipse\n") ;
427    printf(" E    Eurogram -- branches angle outward, then up\n");
428    printf(" S    Swoopogram -- branches curve outward then reverse\n") ;
429    printf(" O    Circular tree\n");
430    do {
431      printf("\n Type letter of style to change to (C, P, V, E, S or O):\n");
432#ifdef WIN32
433      phyFillScreenColor();
434#endif
435      scanf("%c%*[^\n]", &ch);
436      getchar();
437      uppercase(&ch);
438    } while (ch != 'C' && ch != 'P' && ch != 'V'
439          && ch != 'E' && ch != 'S' && ch != 'O');
440    switch (ch) {
441
442    case 'C':
443      style = cladogram;
444      break;
445
446    case 'P':
447      style = phenogram;
448      break;
449
450    case 'E':
451      style = eurogram;
452      break;
453
454    case 'S':
455      style = swoopogram;
456      break;
457
458    case 'V':
459      style = curvogram;
460      break;
461
462    case 'O':
463      style = circular;
464      treedepth = 1.0;
465      break;
466    }
467    break;
468
469  case 'B':
470    if (haslengths) {
471      uselengths = !uselengths;
472      if (!uselengths)
473        nodeposition = weighted;
474      else
475        nodeposition = intermediate;
476    } else {
477      printf("Cannot use lengths since not all of them exist\n");
478      uselengths = false;
479    }
480    break;
481
482  case 'L':
483    clearit();
484    printf("\n(Considering the tree as if it \"grew\" vertically:)\n");
485    printf("Are the labels to be plotted vertically (90),\n");
486    printf(" horizontally (0), or at a 45-degree angle?\n");
487    loopcount = 0;
488    do {
489      printf(" Choose an angle in degrees from 90 to 0:\n");
490#ifdef WIN32
491      phyFillScreenColor();
492#endif
493      scanf("%lf%*[^\n]", &labelrotation);
494      getchar();
495      uppercase(&ch);
496      countup(&loopcount, 10);
497    } while (labelrotation < 0.0 && labelrotation > 90.0);
498    break;
499
500  case 'M':
501    clearit();
502    printf("\nThe tree will be drawn to fit in a rectangle which has \n");
503    printf(" margins in the horizontal and vertical directions of:\n");
504    if (plotter == ray) {
505      printf(
506       "%6.2f pixels (horizontal margin) and%6.2f pixels (vertical margin)\n",
507               xmargin, ymargin);
508      }
509    else {
510        printf("%6.2f cm (horizontal margin) and%6.2f cm (vertical margin)\n",
511               xmargin, ymargin);
512      }
513    putchar('\n');
514    loopcount = 0;
515    do {
516      if (plotter == ray)
517        printf(" New value (in pixels) of horizontal margin?\n");
518      else
519        printf(" New value (in cm) of horizontal margin?\n");
520#ifdef WIN32
521      phyFillScreenColor();
522#endif
523      scanf("%lf%*[^\n]", &xmargin);
524      getchar();
525      ok = ((unsigned)xmargin < xsize / 2.0);
526      if (!ok)
527        printf(" Impossible value.  Please retype it.\n");
528      countup(&loopcount, 10);
529    } while (!ok);
530    loopcount = 0;
531    do {
532      if (plotter == ray)
533        printf(" New value (in pixels) of vertical margin?\n");
534      else
535        printf(" New value (in cm) of vertical margin?\n");
536#ifdef WIN32
537      phyFillScreenColor();
538#endif
539      scanf("%lf%*[^\n]", &ymargin);
540      getchar();
541      ok = ((unsigned)ymargin < ysize / 2.0);
542      if (!ok)
543        printf(" Impossible value.  Please retype it.\n");
544      countup(&loopcount, 10);
545    } while (!ok);
546
547    break;
548
549  case 'R':
550    rescaled = !rescaled;
551    if (!rescaled) {
552      printf("Centimeters per unit branch length?\n");
553#ifdef WIN32
554      phyFillScreenColor();
555#endif
556      scanf("%lf%*[^\n]", &bscale);
557      getchar();
558    }
559    break;
560
561  case 'D':
562    printf("New value of depth of tree as fraction of its breadth?\n");
563#ifdef WIN32
564    phyFillScreenColor();
565#endif
566    scanf("%lf%*[^\n]", &treedepth);
567    getchar();
568    break;
569
570  case 'T':
571    loopcount = 0;
572    do {
573      printf("New value of stem length as fraction of tree depth?\n");
574#ifdef WIN32
575      phyFillScreenColor();
576#endif
577      scanf("%lf%*[^\n]", &stemlength);
578      getchar();
579      countup(&loopcount, 10);
580    } while ((unsigned)stemlength >= 0.9);
581    break;
582
583  case 'C':
584    printf("New value of character height as fraction of tip spacing?\n");
585#ifdef WIN32
586    phyFillScreenColor();
587#endif
588    scanf("%lf%*[^\n]", &nodespace);
589    getchar();
590    nodespace = 1.0 / nodespace;
591    break;
592
593  case '#':
594    loopcount = 0;
595    for (;;){
596      clearit();
597      printf("  Page Specifications Submenu\n\n");
598      printf(" L   Output size in pages: %.0f down by %.0f across\n",
599             (pagey / papery), (pagex / paperx));
600      printf(" P   Physical paper size: %1.5f by %1.5f cm\n",paperx,papery);
601      printf(" O   Overlap Region: %1.5f %1.5f cm\n",hpmargin,vpmargin);
602      printf(" M   main menu\n");
603      getstryng(input);
604      ch = input[0];
605      uppercase(&ch);
606      switch (ch){
607      case 'L':
608        printf("Number of pages in height:\n");
609#ifdef WIN32
610        phyFillScreenColor();
611#endif
612        getstryng(input);
613        m = atoi(input);
614        printf("Number of pages in width:\n");
615        getstryng(input);
616        n = atoi(input);
617        break;
618      case 'P':
619        printf("Paper Width (in cm):\n");
620#ifdef WIN32
621        phyFillScreenColor();
622#endif
623        getstryng(input);
624        paperx = atof(input);
625        printf("Paper Height (in cm):\n");
626        getstryng(input);
627        papery = atof(input);   
628        break;
629      case 'O':
630        printf("Horizontal Overlap (in cm):");
631#ifdef WIN32
632        phyFillScreenColor();
633#endif
634        getstryng(input);
635        hpmargin = atof(input);   
636        printf("Vertical Overlap (in cm):");
637#ifdef WIN32
638        phyFillScreenColor();
639#endif
640        getstryng(input);
641        vpmargin = atof(input);   
642      case 'M':
643        break;
644      default:
645        printf("Please enter L, P, O , or M.\n");
646        break;
647      }
648      pagex = ((double)n * (paperx-hpmargin)+hpmargin);
649      pagey = ((double)m * (papery-vpmargin)+vpmargin);
650      if (ch == 'M')
651        break;
652      countup(&loopcount, 10);
653    }
654    break;
655
656  case 'A':
657    clearit();
658    printf("Should interior node positions:\n");
659    printf(" be Intermediate between their immediate descendants,\n");
660    printf("    Weighted average of tip positions\n");
661    printf("    Centered among their ultimate descendants\n");
662    printf("    iNnermost of immediate descendants\n");
663    printf(" or so that tree is V-shaped\n");
664    loopcount = 0;
665    do {
666      printf(" (type I, W, C, N or V):\n");
667#ifdef WIN32
668      phyFillScreenColor();
669#endif
670      scanf("%c%*[^\n]", &ch);
671      getchar();
672      uppercase(&ch);
673      countup(&loopcount, 10);
674    } while (ch != 'I' && ch != 'W' && ch != 'C' && ch != 'N' && ch != 'V');
675    switch (ch) {
676
677      case 'W':
678        nodeposition = weighted;
679        break;
680
681      case 'I':
682        nodeposition = intermediate;
683        break;
684
685      case 'C':
686        nodeposition = centered;
687        break;
688
689      case 'N':
690        nodeposition = inner;
691        break;
692
693      case 'V':
694        nodeposition = vshaped;
695        break;
696    }
697    break;
698
699  case 'F':
700    if (plotter == fig){
701        for (i=0;i<34;++i)
702          printf("%s\n",figfontname(i));
703      loopcount = 0;
704      for (;;){
705        printf("Fontname:"); 
706#ifdef WIN32
707        phyFillScreenColor();
708#endif
709        getstryng(fontname);
710        if (isfigfont(fontname))
711          break;
712        printf("Invalid font name for fig.\n");
713        printf("Enter one of the following fonts or \"Hershey\" for default font\n");
714        countup(&loopcount, 10);
715      }
716    }
717      else {
718        printf("Enter font name or \"Hershey\" for the default font\n");
719#ifdef WIN32
720        phyFillScreenColor();
721#endif
722        getstryng(fontname);
723      }
724    break;
725
726  case 'Q':
727    clearit();
728    loopcount = 0;
729    do {
730      printf("Italic? (Y/N)\n"); 
731#ifdef WIN32
732      phyFillScreenColor();
733#endif
734      getstryng(input);
735      input[0] = toupper(input[0]);
736      countup(&loopcount, 10);
737    } while (input[0] != 'Y' && input[0] != 'N');
738    pictitalic = (input[0] == 'Y');
739    loopcount = 0;
740    do {
741      printf("Bold? (Y/N)\n"); 
742#ifdef WIN32
743    phyFillScreenColor();
744#endif
745      getstryng(input);
746      input[0] = toupper(input[0]);
747      countup(&loopcount, 10);
748    } while (input[0] != 'Y' && input[0] != 'N');
749    pictbold = (input[0] == 'Y');
750    loopcount = 0;
751    do {
752      printf("Shadow? (Y/N)\n"); 
753#ifdef WIN32
754      phyFillScreenColor();
755#endif
756      getstryng(input);
757      input[0] = toupper(input[0]);
758      countup(&loopcount, 10);
759    } while (input[0] != 'Y' && input[0] != 'N');
760    pictshadow = (input[0] == 'Y');
761    loopcount = 0;
762    do {
763      printf("Outline? (Y/N)\n"); 
764#ifdef WIN32
765      phyFillScreenColor();
766#endif
767      getstryng(input);
768      input[0] = toupper(input[0]);
769      countup(&loopcount, 10);
770    } while (input[0] != 'Y' && input[0] != 'N');
771    pictoutline = (input[0] == 'Y');break;
772  }
773}  /* getparms */
774
775
776void calctraverse(node *p, double lengthsum, double *tipx)
777{
778  /* traverse to establish initial node coordinates */
779  double x1, y1, x2, y2, x3, x4, x5, w1, w2, sumwx, sumw, nodeheight;
780  node *pp, *plast, *panc;
781
782  if (p == root)
783    nodeheight = 0.0;
784  else if (uselengths)
785      nodeheight = lengthsum + fabs(p->oldlen);
786    else
787      nodeheight = 1.0;
788  if (nodeheight > maxheight)
789    maxheight = nodeheight;
790  if (p->tip) {
791    p->xcoord = *tipx;
792    p->tipsabove = 1;
793    if (uselengths)
794      p->ycoord = nodeheight;
795    else
796      p->ycoord = 1.0;
797    *tipx += tipspacing;
798    return;
799  }
800  sumwx = 0.0;
801  sumw = 0.0;
802  p->tipsabove = 0;
803  pp = p->next;
804  x3 = 0.0;
805  do {
806    calctraverse(pp->back, nodeheight, tipx);
807    p->tipsabove += pp->back->tipsabove;
808    sumw += pp->back->tipsabove;
809    sumwx += pp->back->tipsabove * pp->back->xcoord;
810    if (fabs(pp->back->xcoord - 0.5) < fabs(x3 - 0.5))
811      x3 = pp->back->xcoord;
812    plast = pp;
813    pp = pp->next;
814  } while (pp != p);
815  x1 = p->next->back->xcoord;
816  x2 = plast->back->xcoord;
817  y1 = p->next->back->ycoord;
818  y2 = plast->back->ycoord;
819
820  switch (nodeposition) {
821
822  case weighted:
823    w1 = y1 - p->ycoord;
824    w2 = y2 - p->ycoord;
825    if (w1 + w2 <= 0.0)
826      p->xcoord = (x1 + x2) / 2.0;
827    else
828      p->xcoord = (w2 * x1 + w1 * x2) / (w1 + w2);
829    break;
830
831  case intermediate:
832    p->xcoord = (x1 + x2) / 2.0;
833    break;
834
835  case centered:
836    p->xcoord = sumwx / sumw;
837    break;
838
839  case inner:
840    p->xcoord = x3;
841    break;
842
843  case vshaped:
844    if (iteration > 1) {
845      if (!(p == root)) {
846        panc = nodep[p->back->index-1];
847        w1 = p->ycoord - panc->ycoord;
848        w2 = y1 - p->ycoord;
849        if (w1+w2 < 0.000001)
850          x4 = (x1+panc->xcoord)/2.0;
851        else
852          x4 = (w1*x1+w2*panc->xcoord)/(w1+w2);
853        w2 = y2 - p->ycoord;
854        if (w1+w2 < 0.000001)
855          x5 = (x2+panc->xcoord)/2.0;
856        else
857          x5 = (w1*x2+w2*panc->xcoord)/(w1+w2);
858        if (panc->xcoord < p->xcoord)
859          p->xcoord = x5;
860        else
861          p->xcoord = x4;
862/* debug
863        if (p->xcoord < x1)
864          p->xcoord = x1;
865        else if (p->xcoord > x2)
866            p->xcoord = x2;               
867debug */
868      }
869      else {
870        if ((y1-2*p->ycoord+y2) < 0.000001)
871          p->xcoord = (x1+x2)/2;
872        else
873          p->xcoord = ((y2-p->ycoord)*x1+(y1-p->ycoord))/(y1-2*p->ycoord+y2);
874        }
875    }
876    break;
877  }
878  if (uselengths) {
879    p->ycoord = nodeheight;
880    return;
881  }
882  if (nodeposition != inner) {
883    p->ycoord = (y1 + y2 - sqrt((y1 + y2) * (y1 + y2) - 4 * (y1 * y2 -
884                           (x2 - p->xcoord) * (p->xcoord - x1)))) / 2.0;
885   /* this formula comes from the requirement that the vector from
886   (x,y) to (x1,y1) be at right angles to that from (x,y) to (x2,y2) */
887    return;
888  }
889  if (fabs(x1 - 0.5) > fabs(x2 - 0.5)) {
890    p->ycoord = y1 + x1 - x2;
891    w1 = y2 - p->ycoord;
892  } else {
893    p->ycoord = y2 + x1 - x2;
894    w1 = y1 - p->ycoord;
895  }
896  if (w1 < epsilon)
897    p->ycoord -= fabs(x1 - x2);
898}  /* calctraverse */
899
900
901void calculate()
902{
903  /* compute coordinates for tree */
904  double tipx;
905  double sum, temp, maxtextlength, maxfirst=0, leftfirst, angle;
906  double lef = 0.0, rig = 0.0, top = 0.0, bot = 0.0;
907  double *firstlet, *textlength;
908  long i;
909
910  firstlet = (double *)Malloc(nextnode*sizeof(double));
911  textlength = (double *)Malloc(nextnode*sizeof(double));
912  for (i = 0; i < nextnode; i++) {
913    nodep[i]->xcoord = 0.0;
914    nodep[i]->ycoord = 0.0;
915    if (nodep[i]->naymlength > 0)
916      firstlet[i] = lengthtext(nodep[i]->nayme, 1L,fontname,font);
917    else
918      firstlet[i] = 0.0;
919  }
920  i = 0;
921  do
922    i++;
923  while (!nodep[i]->tip);
924  leftfirst = firstlet[i];
925  maxheight = 0.0;
926  maxtextlength = 0.0;
927  for (i = 0; i < nextnode; i++) {
928   if (nodep[i]->tip) {
929      textlength[i] = lengthtext(nodep[i]->nayme, nodep[i]->naymlength,
930                                fontname, font);
931      if (textlength[i]-0.5*firstlet[i] > maxtextlength) {
932        maxtextlength = textlength[i]-0.5*firstlet[i];
933        maxfirst = firstlet[i];
934      }
935    }
936  }
937  maxtextlength = maxtextlength + 0.5*maxfirst;
938  fontheight = heighttext(font,fontname);
939  if (style == circular) {
940    if (grows == vertical)
941      angle = pi / 2.0;
942    else
943      angle = 2.0*pi;
944  } else
945     angle = pi * labelrotation / 180.0;
946  maxtextlength /= fontheight;
947  maxfirst /= fontheight;
948  leftfirst /= fontheight;
949  for (i = 0; i < nextnode; i++) {
950    if (nodep[i]->tip) {
951      textlength[i] /= fontheight;
952      firstlet[i] /= fontheight;
953    }
954  }
955  if (spp > 1)
956    labelheight = 1.0 / (nodespace * (spp - 1));
957  else
958    labelheight = 1.0 / nodespace;
959/*  if (style == circular)
960    labelheight = pi * labelheight;    debug */
961  if (angle < pi / 6.0)
962    tipspacing = (nodespace
963        + cos(angle) * (maxtextlength - 0.5*maxfirst)) * labelheight;
964  else if (spp > 1) {
965      if (style == circular) {
966        tipspacing = 1.0 / spp;
967      } else
968        tipspacing = 1.0 / (spp - 1.0);
969    } else
970      tipspacing = 1.0;
971  finished = false;
972  iteration = 1;
973  do {
974    if (style == circular)
975      tipx = 1.0/(2.0*(double)spp);
976    else
977      tipx = 0.0;
978    sum = 0.0;
979    calctraverse(root, sum, &tipx);
980    iteration++;
981  }
982  while ((nodeposition == vshaped) && (iteration < 4*spp));
983  rooty = root->ycoord;
984  labelheight *= 1.0 - stemlength;
985  for (i = 0; i < nextnode; i++) {
986    if (rescaled) {
987      if (style != circular)
988        nodep[i]->xcoord *= 1.0 - stemlength;
989      nodep[i]->ycoord = stemlength * treedepth + (1.0 - stemlength) *
990            treedepth * (nodep[i]->ycoord - rooty) / (maxheight - rooty);
991      nodep[i]->oldtheta = angle;
992    } else {
993      nodep[i]->xcoord = nodep[i]->xcoord * (maxheight - rooty) / treedepth;
994      nodep[i]->ycoord = stemlength / (1 - stemlength) * (maxheight - rooty) +
995                         nodep[i]->ycoord;
996      nodep[i]->oldtheta = angle;
997    }
998  }
999  topoflabels = 0.0;
1000  bottomoflabels = 0.0;
1001  leftoflabels = 0.0;
1002  rightoflabels = 0.0;
1003  if  (style == circular) {
1004    for (i = 0; i < nextnode; i++) {
1005      temp = nodep[i]->xcoord;
1006      if (grows == vertical) {
1007        nodep[i]->xcoord = (1.0+nodep[i]->ycoord
1008                                * cos((1.5-2.0*temp)*pi)/treedepth)/2.0;
1009        nodep[i]->ycoord = (1.0+nodep[i]->ycoord
1010                                * sin((1.5-2.0*temp)*pi)/treedepth)/2.0;
1011        nodep[i]->oldtheta = (1.5-2.0*temp)*pi;
1012      } else {
1013        nodep[i]->xcoord = (1.0+nodep[i]->ycoord
1014                                * cos((1.0-2.0*temp)*pi)/treedepth)/2.0;
1015        nodep[i]->ycoord = (1.0+nodep[i]->ycoord
1016                                * sin((1.0-2.0*temp)*pi)/treedepth)/2.0;
1017        nodep[i]->oldtheta = (1.0-2.0*temp)*pi;
1018      }
1019    }
1020    tipspacing *= 2.0*pi;
1021  }
1022  maxx = nodep[0]->xcoord;
1023  maxy = nodep[0]->ycoord;
1024  minx = nodep[0]->xcoord;
1025  if (style == circular)
1026    miny = nodep[0]->ycoord;
1027  else
1028    miny = 0.0;
1029  for (i = 1; i < nextnode; i++) {
1030    if (nodep[i]->xcoord > maxx)
1031      maxx = nodep[i]->xcoord;
1032    if (nodep[i]->ycoord > maxy)
1033      maxy = nodep[i]->ycoord;
1034    if (nodep[i]->xcoord < minx)
1035      minx = nodep[i]->xcoord;
1036    if (nodep[i]->ycoord < miny)
1037      miny = nodep[i]->ycoord;
1038  }
1039  if  (style == circular) {
1040    for (i = 0; i < nextnode; i++) {
1041      if (nodep[i]->tip) {
1042        angle = nodep[i]->oldtheta;
1043        if (cos(angle) < 0.0)
1044          angle -= pi;
1045        top = (nodep[i]->ycoord - maxy) / labelheight + sin(nodep[i]->oldtheta);
1046        rig = (nodep[i]->xcoord - maxx) / labelheight + cos(nodep[i]->oldtheta);
1047        bot = (miny - nodep[i]->ycoord) / labelheight - sin(nodep[i]->oldtheta);
1048        lef = (minx - nodep[i]->xcoord) / labelheight - cos(nodep[i]->oldtheta);
1049        if (cos(nodep[i]->oldtheta) > 0) {
1050          if (sin(angle) > 0.0)
1051            top += sin(angle) * textlength[i];
1052          top += sin(angle - 1.25 * pi) * gap * firstlet[i];
1053          if (sin(angle) < 0.0)
1054            bot -= sin(angle) * textlength[i];
1055          bot -= sin(angle - 0.75 * pi) * gap * firstlet[i];
1056          if (sin(angle) > 0.0)
1057            rig += cos(angle - 0.75 * pi) * gap * firstlet[i];
1058          else
1059            rig += cos(angle - 1.25 * pi) * gap * firstlet[i];
1060          rig += cos(angle) * textlength[i];
1061          if (sin(angle) > 0.0)
1062            lef -= cos(angle - 1.25 * pi) * gap * firstlet[i];
1063          else
1064            lef -= cos(angle - 0.75 * pi) * gap * firstlet[i];
1065        } else {
1066          if (sin(angle) < 0.0)
1067            top -= sin(angle) * textlength[i];
1068          top += sin(angle + 0.25 * pi) * gap * firstlet[i];
1069          if (sin(angle) > 0.0)
1070            bot += sin(angle) * textlength[i];
1071          bot -= sin(angle - 0.25 * pi) * gap * firstlet[i];
1072          if (sin(angle) > 0.0)
1073            rig += cos(angle - 0.25 * pi) * gap * firstlet[i];
1074          else
1075            rig += cos(angle + 0.25 * pi) * gap * firstlet[i];
1076          if (sin(angle) < 0.0)
1077            rig += cos(angle) * textlength[i];
1078          if (sin(angle) > 0.0)
1079            lef -= cos(angle + 0.25 * pi) * gap * firstlet[i];
1080          else
1081            lef -= cos(angle - 0.25 * pi) * gap * firstlet[i];
1082          lef += cos(angle) * textlength[i];
1083        }
1084      }
1085      if (top > topoflabels)
1086        topoflabels = top;
1087      if (bot > bottomoflabels)
1088        bottomoflabels = bot;
1089      if (rig > rightoflabels)
1090        rightoflabels = rig;
1091      if (lef > leftoflabels)
1092        leftoflabels = lef;
1093    }
1094    topoflabels *= labelheight;
1095    bottomoflabels *= labelheight;
1096    leftoflabels *= labelheight;
1097    rightoflabels *= labelheight;
1098  }
1099  if (style != circular) {
1100    topoflabels = labelheight *
1101              (1.0 + sin(angle) * (maxtextlength - 0.5 * maxfirst)
1102                   + cos(angle) * 0.5 * maxfirst);
1103    rightoflabels = labelheight *
1104                    (cos(angle) * (textlength[nextnode-1] - 0.5 * maxfirst)
1105                   + sin(angle) * 0.5);
1106    leftoflabels = labelheight * (cos(angle) * leftfirst * 0.5
1107                                    + sin(angle) * 0.5);
1108  }
1109  rooty = miny;
1110  free(firstlet);
1111  free(textlength);
1112}  /* calculate */
1113
1114
1115void rescale()
1116{
1117  /* compute coordinates of tree for plot or preview device */
1118  long i;
1119  double treeheight, treewidth, extrax, extray, temp;
1120  treeheight = maxy - miny;
1121  treewidth = maxx - minx;
1122  if (style == circular) {
1123    treewidth = 1.0;
1124    treeheight = 1.0;
1125    if (!rescaled) {
1126      if (uselengths) {
1127        labelheight *= (maxheight - rooty) / treedepth;
1128        topoflabels *= (maxheight - rooty) / treedepth;
1129        bottomoflabels *= (maxheight - rooty) / treedepth;
1130        leftoflabels *= (maxheight - rooty) / treedepth;
1131        rightoflabels *= (maxheight - rooty) / treedepth;
1132        treewidth *= (maxheight - rooty) / treedepth;
1133      }
1134    }
1135  }
1136  treewidth += rightoflabels + leftoflabels;
1137  treeheight += topoflabels + bottomoflabels;
1138  if (grows == vertical) {
1139    if (!rescaled)
1140      expand = bscale;
1141    else {
1142      expand = (xsize - 2 * xmargin) / treewidth;
1143      if ((ysize - 2 * ymargin) / treeheight < expand)
1144        expand = (ysize - 2 * ymargin) / treeheight;
1145    }
1146    extrax = (xsize - 2 * xmargin - treewidth * expand) / 2.0;
1147    extray = (ysize - 2 * ymargin - treeheight * expand) / 2.0;
1148  } else {
1149    if (!rescaled)
1150      expand = bscale;
1151    else {
1152      expand = (ysize - 2 * ymargin) / treewidth;
1153      if ((xsize - 2 * xmargin) / treeheight < expand)
1154        expand = (xsize - 2 * xmargin) / treeheight;
1155    }
1156    extrax = (xsize - 2 * xmargin - treeheight * expand) / 2.0;
1157    extray = (ysize - 2 * ymargin - treewidth * expand) / 2.0;
1158  }
1159  for (i = 0; i < nextnode; i++) {
1160    nodep[i]->xcoord = expand * (nodep[i]->xcoord + leftoflabels);
1161    nodep[i]->ycoord = expand * (nodep[i]->ycoord + bottomoflabels);
1162    if ((style != circular) && (grows == horizontal)) {
1163      temp = nodep[i]->ycoord;
1164      nodep[i]->ycoord = expand * treewidth - nodep[i]->xcoord;
1165      nodep[i]->xcoord = temp;
1166    }
1167    nodep[i]->xcoord += xmargin + extrax;
1168    nodep[i]->ycoord += ymargin + extray;
1169  }
1170  if (style == circular) {
1171    xx0 = xmargin+extrax+expand*(leftoflabels + 0.5);
1172    yy0 = ymargin+extray+expand*(bottomoflabels + 0.5);
1173  }
1174  else if (grows == vertical)
1175      rooty = ymargin + extray;
1176    else
1177      rootx = xmargin + extrax;
1178}  /* rescale */
1179
1180
1181void plottree(node *p, node *q)
1182{
1183  /* plot part or all of tree on the plotting device */
1184  long i;
1185  double x00=0, y00=0, x1, y1, x2, y2, x3, y3, x4, y4,
1186           cc, ss, f, g, fract=0, minny, miny;
1187  node *pp;
1188
1189  x2 = xscale * (xoffset + p->xcoord);
1190  y2 = yscale * (yoffset + p->ycoord);
1191  if (style == circular) {
1192    x00 = xscale * (xx0 + xoffset);
1193    y00 = yscale * (yy0 + yoffset);
1194  }
1195  if (p != root) {
1196    x1 = xscale * (xoffset + q->xcoord);
1197    y1 = yscale * (yoffset + q->ycoord);
1198
1199    switch (style) {
1200
1201    case cladogram:
1202      plot(penup, x1, y1);
1203      plot(pendown, x2, y2);
1204      break;
1205
1206    case phenogram:
1207      plot(penup, x1, y1);
1208      if (grows == vertical)
1209        plot(pendown, x2, y1);
1210      else
1211        plot(pendown, x1, y2);
1212      plot(pendown, x2, y2);
1213      break;
1214
1215    case curvogram:
1216      plot(penup, x1, y1) ;
1217      curvespline(x1,y1,x2,y2,(boolean)(grows == vertical),20);
1218      break;
1219
1220    case eurogram:
1221      plot(penup, x1, y1);
1222      if (grows == vertical)
1223        plot(pendown, x2, (2 * y1 + y2) / 3);
1224      else
1225        plot(pendown, (2 * x1 + x2) / 3, y2);
1226      plot(pendown, x2, y2);
1227      break;
1228
1229    case swoopogram:
1230      plot(penup, x1, y1);
1231      if ((grows == vertical && fabs(y1 - y2) >= epsilon) ||
1232          (grows == horizontal && fabs(x1 - x2) >= epsilon)) {
1233        if (grows == vertical)
1234          miny = p->ycoord;
1235        else
1236          miny = p->xcoord;
1237        pp = q->next;
1238        while (pp != q) {
1239          if (grows == vertical)
1240            minny = pp->back->ycoord;
1241          else
1242            minny = pp->back->xcoord;
1243          if (minny < miny)
1244            miny = minny;
1245          pp = pp->next;
1246        }
1247        if (grows == vertical)
1248          miny = yscale * (yoffset + miny);
1249        else
1250          miny = xscale * (xoffset + miny);
1251        if (grows == vertical)
1252          fract = 0.3333 * (miny - y1) / (y2 - y1);
1253        else
1254          fract = 0.3333 * (miny - x1) / (x2 - x1);
1255      } if ((grows == vertical && fabs(y1 - y2) >= epsilon) ||
1256          (grows == horizontal && fabs(x1 - x2) >= epsilon)) {
1257        if (grows == vertical)
1258          miny = p->ycoord;
1259        else
1260          miny = p->xcoord;
1261        pp = q->next;
1262        while (pp != q) {
1263          if (grows == vertical)
1264            minny = pp->back->ycoord;
1265          else
1266            minny = pp->back->xcoord;
1267          if (minny < miny)
1268            miny = minny;
1269          pp = pp->next;
1270        }
1271        if (grows == vertical)
1272          miny = yscale * (yoffset + miny);
1273        else
1274          miny = xscale * (xoffset + miny);
1275        if (grows == vertical)
1276          fract = 0.3333 * (miny - y1) / (y2 - y1);
1277        else
1278          fract = 0.3333 * (miny - x1) / (x2 - x1);
1279      }
1280      swoopspline(x1,y1,x1+fract*(x2-x1),y1+fract*(y2-y1),
1281                  x2,y2,(boolean)(grows != vertical),segments);       
1282      break;
1283
1284  case circular:
1285      plot(penup, x1, y1);
1286      if (fabs(x1-x00)+fabs(y1-y00) > 0.00001) {
1287        g = ((x1-x00)*(x2-x00)+(y1-y00)*(y2-y00))
1288                       /sqrt(((x1-x00)*(x1-x00)+(y1-y00)*(y1-y00))
1289                             *((x2-x00)*(x2-x00)+(y2-y00)*(y2-y00)));
1290        if (g > 1.0) 
1291          g = 1.0;
1292        if (g < -1.0)
1293          g = -1.0;
1294        f = acos(g);
1295        if ((x2-x00)*(y1-y00)>(x1-x00)*(y2-y00))
1296          f = -f;
1297        if (fabs(g-1.0) > 0.0001) {
1298          cc = cos(f/segments);
1299          ss = sin(f/segments);
1300          x3 = x1;
1301          y3 = y1;
1302          for (i = 1; i <= segments; i++) {
1303            x4 = x00 + cc*(x3-x00) - ss*(y3-y00);
1304            y4 = y00 + ss*(x3-x00) + cc*(y3-y00);
1305            x3 = x4;
1306            y3 = y4;
1307            plot(pendown, x3, y3);
1308            }
1309          }
1310        }
1311      plot(pendown, x2, y2);
1312      break;
1313
1314    }
1315  } else {
1316    if (style == circular) {
1317      x1 = x00;
1318      y1 = y00;
1319    } else {
1320      if (grows == vertical) {
1321        x1 =  xscale *  (xoffset + p->xcoord);
1322        y1 =  yscale *  (yoffset + rooty);
1323      } else {
1324        x1 =  xscale *  (xoffset + rootx);
1325        y1 =  yscale *  (yoffset + p->ycoord);
1326      }
1327    }
1328    plot(penup, x1, y1);
1329    plot(pendown, x2, y2);
1330  }
1331  if (p->tip)
1332    return;
1333  pp = p->next;
1334  while (pp != p) {
1335    plottree(pp->back, p);
1336    pp = pp->next;
1337  }
1338}  /* plottree */
1339
1340
1341void plotlabels(char *fontname)
1342{
1343  long i;
1344  double compr, dx = 0, dy = 0, labangle, cosl, sinl, cosv, sinv, vec;
1345  boolean left, right;
1346  node *lp;
1347  double *firstlet;
1348
1349  firstlet = (double *)Malloc(nextnode*sizeof(double));
1350  textlength = (double *)Malloc(nextnode*sizeof(double));
1351  compr = xunitspercm / yunitspercm;
1352  if (penchange == yes)
1353    changepen(labelpen);
1354  for (i = 0; i < nextnode; i++) {
1355    if (nodep[i]->tip) {
1356      lp = nodep[i];
1357      firstlet[i] = lengthtext(nodep[i]->nayme,1L,fontname,font)
1358                              /fontheight;
1359      textlength[i] = lengthtext(nodep[i]->nayme, nodep[i]->naymlength,
1360                                fontname, font)/fontheight;
1361      labangle = nodep[i]->oldtheta;
1362      if (cos(labangle) < 0.0)
1363        labangle += pi;
1364      cosl = cos(labangle);
1365      sinl = sin(labangle);
1366      vec = sqrt(1.0+firstlet[i]*firstlet[i]);
1367      cosv = firstlet[i]/vec;
1368      sinv = 1.0/vec;
1369      if (style == circular) {
1370        right = cos(nodep[i]->oldtheta) > 0.0;
1371        left = !right;
1372        if (right) {
1373          dx = labelheight * expand * cos(nodep[i]->oldtheta);
1374          dy = labelheight * expand * sin(nodep[i]->oldtheta);
1375          dx -= labelheight * expand * 0.5 * vec * (cosl*sinv-sinl*cosv);
1376          dy -= labelheight * expand * 0.5 * vec * (sinl*sinv+cosl*cosv);
1377        }
1378        if (left) {
1379          dx = labelheight * expand * cos(nodep[i]->oldtheta);
1380          dy = labelheight * expand * sin(nodep[i]->oldtheta);
1381          dx -= labelheight * expand * textlength[i] * cosl;
1382          dy -= labelheight * expand * textlength[i] * sinl;
1383          dx += labelheight * expand * 0.5 * vec * (cosl*cosv+sinl*sinv);
1384          dy -= labelheight * expand * 0.5 * vec * (-sinl*cosv+cosl*sinv);
1385        }
1386      } else {
1387          dx = labelheight * expand * cos(nodep[i]->oldtheta);
1388          dy = labelheight * expand * sin(nodep[i]->oldtheta);
1389          dx += labelheight * expand * 0.5 * vec * (cosl*cosv+sinl*sinv);
1390          dy += labelheight * expand * 0.5 * vec * (-sinl*cosv+cosl*sinv);
1391        }
1392      if (style == circular) {
1393        plottext(lp->nayme, lp->naymlength,
1394             labelheight * expand * xscale / compr, compr,
1395             xscale * (lp->xcoord + dx + xoffset),
1396             yscale * (lp->ycoord + dy + yoffset), 180 * (-labangle) / pi,
1397             font,fontname);
1398      } else {
1399        if (grows == vertical)
1400          plottext(lp->nayme, lp->naymlength,
1401                   labelheight * expand * xscale / compr, compr,
1402                   xscale * (lp->xcoord + dx + xoffset),
1403                   yscale * (lp->ycoord + dy + yoffset),
1404                   -labelrotation, font,fontname);
1405        else
1406          plottext(lp->nayme, lp->naymlength, labelheight * expand * yscale,
1407                   compr, xscale * (lp->xcoord + dy + xoffset),
1408                   yscale * (lp->ycoord - dx + yoffset), 90.0 - labelrotation,
1409                   font,fontname);
1410      }
1411    }
1412  }
1413  if (penchange == yes)
1414    changepen(treepen);
1415  free(firstlet);
1416  free(textlength);
1417}  /* plotlabels */
1418
1419
1420void setup_environment(Char *argv[], boolean *canbeplotted)
1421{
1422  boolean firsttree;
1423  /* Set up all kinds of fun stuff */
1424#ifdef MAC
1425  OSErr retcode;
1426  FInfo  fndrinfo;
1427  macsetup("Drawgram","Preview");
1428#endif
1429#ifdef TURBOC
1430  if ((registerbgidriver(EGAVGA_driver) <0) ||
1431      (registerbgidriver(Herc_driver) <0)   ||
1432      (registerbgidriver(CGA_driver) <0)){
1433    printf("Graphics error: %s ",grapherrormsg(graphresult()));
1434    exit(-1);}
1435#endif
1436
1437 
1438
1439  openfile(&plotfile,PLOTFILE,"plot file", "w",argv[0],pltfilename);
1440  openfile(&intree,INTREE,"input tree file", "r",argv[0],trefilename);
1441 
1442  printf("DRAWGRAM from PHYLIP version %s\n",VERSION);
1443  printf("Reading tree ... \n");
1444  firsttree = true;
1445  allocate_nodep(&nodep, &intree, &spp);
1446  treeread (intree, &root, treenode, &goteof, &firsttree,
1447            nodep, &nextnode, &haslengths,
1448            &grbg, initdrawgramnode);
1449  root->oldlen = 0.0;
1450  printf("Tree has been read.\n");
1451  printf("Loading the font .... \n");
1452  loadfont(font,argv[0]);
1453  printf("Font loaded.\n");
1454  previewing = false;
1455  ansi = ANSICRT;
1456  ibmpc = IBMCRT;
1457  firstscreens = true;
1458  initialparms();
1459  (*canbeplotted) = false;
1460}  /* setup_environment */
1461
1462     
1463void user_loop(boolean *canbeplotted)
1464{
1465  char     input_char;
1466  long stripedepth;
1467 
1468  while (!(*canbeplotted)) {
1469    do {
1470      input_char=showparms();
1471      firstscreens = false;
1472      if (input_char != 'Y')
1473        getparms(input_char);
1474    } while (input_char != 'Y');
1475    if (dotmatrix) {
1476      stripedepth = allocstripe(stripe,(strpwide/8),
1477                                ((long)(yunitspercm * ysize)));
1478      strpdeep = stripedepth;
1479      strpdiv  = stripedepth;
1480    }
1481    plotrparms(spp); 
1482    numlines = dotmatrix ? 
1483      ((long)floor(yunitspercm * ysize + 0.5) / strpdeep) :1;
1484    xscale = xunitspercm;
1485    yscale = yunitspercm;
1486    calculate();
1487    rescale();
1488    (*canbeplotted) = true;
1489    if (preview) {
1490      previewing = true;
1491      (*canbeplotted) = plotpreview(fontname,&xoffset,&yoffset,
1492                                  &scale,spp,root);
1493    } else {
1494      /*(*canbeplotted) = plot_without_preview(fontname,&xoffset,&yoffset,
1495                                           &scale,spp,root);*/
1496      (*canbeplotted)=true;
1497    }
1498    if ((previewer == winpreview || previewer == xpreview || previewer == mac) && (winaction == quitnow)) {
1499      (*canbeplotted) = true;
1500    }
1501  }
1502} /* user_loop */
1503
1504int main(int argc, Char *argv[])
1505{
1506  boolean canbeplotted;
1507#ifdef MAC
1508  OSErr retcode;
1509  FInfo  fndrinfo;
1510 
1511  SIOUXSetTitle("\pPHYLIP:  Drawtree");
1512  argv[0] = "Drawgram";
1513#endif
1514
1515  grbg = NULL;
1516  progname = argv[0];
1517
1518#ifdef X
1519  nargc=argc;
1520  nargv=argv;
1521#endif
1522 
1523  init(argc, argv);
1524
1525  setup_environment(argv, &canbeplotted);
1526
1527  user_loop(&canbeplotted);
1528  if (!((previewer == winpreview || previewer == xpreview || previewer == mac) && (winaction == quitnow))) {
1529    previewing = false;
1530    initplotter(spp,fontname);
1531    numlines = dotmatrix ? ((long)floor(yunitspercm * ysize + 0.5)/strpdeep) : 1;
1532    if (plotter != ibm)
1533      printf("\nWriting plot file ...\n");
1534    drawit(fontname,&xoffset,&yoffset,numlines,root);
1535    finishplotter();
1536  }
1537  printf("\nPlot written to file \"%s\"\n\n", pltfilename);
1538  FClose(plotfile);
1539  FClose(intree);
1540#ifdef MAC
1541  if (plotter == pict){
1542    retcode=GetFInfo(CtoPstr(PLOTFILE),0,&fndrinfo);
1543    fndrinfo.fdType='PICT';
1544    fndrinfo.fdCreator='MDRW';
1545    retcode=SetFInfo(CtoPstr(PLOTFILE),0,&fndrinfo);}
1546  if (plotter == lw){
1547    retcode=GetFInfo(CtoPstr(PLOTFILE),0,&fndrinfo);
1548    fndrinfo.fdType='TEXT';
1549    retcode=SetFInfo(CtoPstr(PLOTFILE),0,&fndrinfo);}
1550#endif
1551  printf("Done.\n\n");
1552
1553#ifdef WIN32
1554  phyRestoreConsoleAttributes();
1555#endif
1556
1557  exit(0);
1558}
1559
1560
Note: See TracBrowser for help on using the repository browser.