source: trunk/GDE/PHYLIP/drawgram.c

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