source: branches/profile/GDE/PHYLIP/draw.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: 99.0 KB
Line 
1#ifdef WIN32
2#include <windows.h>
3#endif
4
5#include "draw.h"
6#ifdef QUICKC
7struct videoconfig myscreen;
8void   setupgraphics();
9#endif
10
11#ifdef WIN32
12extern HDC hdc;
13extern HPEN hPenTree;
14extern HPEN hPenLabel;
15extern void winplotpreview();
16
17struct winpreviewparms_t {
18  char * fn;
19  double *xo, *yo, *scale;
20  long nt;
21  node *root;
22};
23
24struct winpreviewparms_t winpreviewparms;
25
26#endif
27#ifdef X
28struct {
29        char* fn;
30        double *xo, *yo, *scale;
31        long nt;
32        node *root;
33} xpreviewparms;
34 
35Atom wm_delete_window;
36Atom wm_delete_window2;
37
38Widget dialog;
39Widget shell=NULL;
40Window mainwin=0;
41
42void init_x(void);
43void  redraw(Widget w,XtPointer client, XExposeEvent *ev);
44void plot_callback(Widget w,XtPointer client, XtPointer call);
45void change_callback(Widget w,XtPointer client, XtPointer call);
46void about_callback(Widget w,XtPointer client, XtPointer call);
47void quit_callback(Widget w,XtPointer client, XtPointer call);
48void close_x(void);
49void do_dialog(void);
50void delete_callback(Widget w, XEvent* event, String *params, int *num_params); 
51void dismiss_dialog(void);
52#endif
53
54
55long winheight;
56long winwidth;
57
58extern winactiontype winaction;
59
60colortype colors[7] = {
61  {"White    ",1.0,1.0,1.0},
62  {"Red      ",1.0,0.3,0.3},
63  {"Orange   ",1.0,0.6,0.6},
64  {"Yellow   ",1.0,0.9,0.4},
65  {"Green    ",0.3,0.8,0.3},
66  {"Blue     ",0.5,0.5,1.0},
67  {"Violet   ",0.6,0.4,0.8},
68};
69
70vrmllighttype vrmllights[3] = {
71  {1.0, -100.0, 100.0, 100.0},
72  {0.5, 100.0, -100.0, -100.0},
73  {0.3, 0.0, -100.0, 100.0},
74};
75
76long        vrmltreecolor, vrmlnamecolor, vrmlskycolornear,        vrmlskycolorfar,
77        vrmlgroundcolornear, vrmlgroundcolorfar, vrmlplotcolor;
78
79char fontname[LARGE_BUF_LENGTH];
80
81/* format of matrix: capheight,  length[32],length[33],..length[256]*/
82
83byte *full_pic ;
84int increment = 0 ;
85int total_bytes = 0 ;
86
87short unknown_metric[256];
88
89static short helvetica_metric[] = { 718,
90278,278,355,556,556,889,667,222,333,333,389,584,278,333,278,278,556,556,556,
91556,556,556,556,556,556,556,278,278,584,584,584,556,1015,667,667,722,722,667,
92611,778,722,278,500,667,556,833,722,778,667,778,722,667,611,722,667,944,667,
93667,611,278,278,278,469,556,222,556,556,500,556,556,278,556,556,222,222,500,
94222,833,556,556,556,556,333,500,278,556,500,722,500,500,500,334,260,334,584,
950,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,333,556,
96556,167,556,556,556,556,191,333,556,333,333,500,500,0,556,556,556,278,0,537,
97350,222,333,333,556,1000,1000,0,611,0,333,333,333,333,333,333,333,333,0,333,
98333,0,333,333,333,1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,370,0,0,0,0,556,
99778,1000,365,0,0,0,0,0,889,0,0,0,278,0,0,222,611,944,611,0,0,0};
100static short helveticabold_metric[] = {718, /* height */ 
101278,333,474,556,556,889,722,278,333,333,389,584,278,333,278,278,556,556,556,
102556,556,556,556,556,556,556,333,333,584,584,584,611,975,722,722,722,722,667,
103611,778,722,278,556,722,611,833,722,778,667,778,722,667,611,722,667,944,667,
104667,611,333,278,333,584,556,278,556,611,556,611,556,333,611,611,278,278,556,
105278,889,611,611,611,611,389,556,333,611,556,778,556,556,500,389,280,389,584,
1060,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,333,556,
107556,167,556,556,556,556,238,500,556,333,333,611,611,0,556,556,556,278,0,556,
108350,278,500,500,556,1000,1000,0,611,0,333,333,333,333,333,333,333,333,0,333,
109333,0,333,333,333,1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,370,0,0,0,0,611,
110778,1000,365,0,0,0,0,0,889,0,0,0,278,0,0,278,611,944,611,0,0,0};
111static short timesroman_metric[] = {662,
112250,333,408,500,500,833,778,333,333,333,500,564,250,333,250,278,500,500,500,
113500,500,500,500,500,500,500,278,278,564,564,564,444,921,722,667,667,722,611,
114556,722,722,333,389,722,611,889,722,722,556,722,667,556,611,722,722,944,722,
115722,611,333,278,333,469,500,333,444,500,444,500,444,333,500,500,278,278,500,
116278,778,500,500,500,500,333,389,278,500,500,722,500,500,444,480,200,480,541,
1170,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,333,500,
118500,167,500,500,500,500,180,444,500,333,333,556,556,0,500,500,500,250,0,453,
119350,333,444,444,500,1000,1000,0,444,0,333,333,333,333,333,333,333,333,0,333,
120333,0,333,333,333,1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,889,0,276,0,0,0,0,611,
121722,889,310,0,0,0,0,0,667,0,0,0,278,0,0,278,500,722,500,0,0,0};
122static short timesitalic_metric[] = {660, /* height */ 
123250,333,420,500,500,833,778,333,333,333,500,675,250,333,250,278,500,500,500,
124500,500,500,500,500,500,500,333,333,675,675,675,500,920,611,611,667,722,611,
125611,722,722,333,444,667,556,833,667,722,611,722,611,500,556,722,611,833,611,
126556,556,389,278,389,422,500,333,500,500,444,500,444,278,500,500,278,278,444,
127278,722,500,500,500,500,389,389,278,500,444,667,444,444,389,400,275,400,541,
1280,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,389,500,
129500,167,500,500,500,500,214,556,500,333,333,500,500,0,500,500,500,250,0,523,
130350,333,556,556,500,889,1000,0,500,0,333,333,333,333,333,333,333,333,0,333,
131333,0,333,333,333,889,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,889,0,276,0,0,0,0,556,
132722,944,310,0,0,0,0,0,667,0,0,0,278,0,0,278,500,667,500,0,0,0};
133static short timesbold_metric[] = {681, /* height */ 
134250,333,555,500,500,1000,833,333,333,333,500,570,250,333,250,278,500,500,500,
135500,500,500,500,500,500,500,333,333,570,570,570,500,930,722,667,722,722,667,
136611,778,778,389,500,778,667,944,722,778,611,778,722,556,667,722,722,1000,722,
137722,667,333,278,333,581,500,333,500,556,444,556,444,333,500,556,278,333,556,
138278,833,556,500,556,556,444,389,333,556,500,722,500,500,444,394,220,394,520,0,
1390,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,333,500,500,
140167,500,500,500,500,278,500,500,333,333,556,556,0,500,500,500,250,0,540,350,
141333,500,500,500,1000,1000,0,500,0,333,333,333,333,333,333,333,333,0,333,333,
1420,333,333,333,1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,0,300,0,0,0,0,667,778,
1431000,330,0,0,0,0,0,722,0,0,0,278,0,0,278,500,722,556,0,0,0};
144static short timesbolditalic_metric[] = {662, /* height */ 
145250,389,555,500,500,833,778,333,333,333,500,570,250,333,250,278,500,500,500,
146500,500,500,500,500,500,500,333,333,570,570,570,500,832,667,667,667,722,667,
147667,722,778,389,500,667,611,889,722,722,611,722,667,556,611,722,667,889,667,
148611,611,333,278,333,570,500,333,500,500,444,500,444,333,500,556,278,278,500,
149278,778,556,500,500,500,389,389,278,556,444,667,500,444,389,348,220,348,570,
1500,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,389,500,
151500,167,500,500,500,500,278,500,500,333,333,556,556,0,500,500,500,250,0,500,
152350,333,500,500,500,1000,1000,0,500,0,333,333,333,333,333,333,333,333,0,333,
153333,0,333,333,333,1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,944,0,266,0,0,0,0,611
154,722,944,300,0,0,0,0,0,722,0,0,0,278,0,0,278,500,722,500,0,0,0};
155static const char *figfonts[] = {"Times-Roman","Times-Italic","Times-Bold","Times-BoldItalic",
156 "AvantGarde-Book","AvantGarde-BookOblique","AvantGarde-Demi","AvantGarde-DemiOblique",
157"Bookman-Light","Bookman-LightItalic","Bookman-Demi","Bookman-DemiItalic",
158"Courier","Courier-Italic","Courier-Bold","Courier-BoldItalic",
159"Helvetica","Helvetica-Oblique","Helvetica-Bold","Helvetica-BoldOblique",
160"Helvetica-Narrow","Helvetica-Narrow-Oblique","Helvetica-Narrow-Bold","Helvetica-Narrow-BoldOblique",
161"NewCenturySchlbk-Roman","NewCenturySchlbk-Italic","NewCenturySchlbk-Bold","NewCenturySchlbk-BoldItalic",
162"Palatino-Roman","Palatino-Italic","Palatino-Bold","Palatino-BoldItalic",
163"Symbol","ZapfChancery-MediumItalic","ZapfDingbats"};                               
164                               
165double oldx, oldy;
166
167boolean didloadmetric;
168long   nmoves,oldpictint,pagecount;
169double labelline,linewidth,oldxhigh,oldxlow,oldyhigh,oldylow,
170       vrmllinewidth, raylinewidth,treeline,oldxsize,oldysize,oldxunitspercm,
171       oldyunitspercm,oldxcorner,oldycorner,oldxmargin,oldymargin,
172       oldhpmargin,oldvpmargin,clipx0,clipx1,clipy0,clipy1,userxsize,userysize;
173long rootmatrix[51][51];
174long  HiMode,GraphDriver,GraphMode,LoMode,bytewrite;
175
176/* externals should move to .h file later. */
177extern long          strpbottom,strptop,strpwide,strpdeep,strpdiv,hpresolution;
178extern boolean       dotmatrix,empty,preview,previewing,pictbold,pictitalic,
179                     pictshadow,pictoutline;
180extern double        expand,xcorner,xnow,xsize,xscale,xunitspercm,
181                     ycorner,ynow,ysize,yscale,yunitspercm,labelrotation,
182                     labelheight,xmargin,ymargin,pagex,pagey,paperx,papery,
183                     hpmargin,vpmargin;
184extern long          filesize;
185extern growth        grows;
186extern enum {yes,no} penchange,oldpenchange;
187extern FILE          *plotfile;
188extern plottertype   plotter,oldplotter,previewer;
189extern striptype     stripe;
190extern char             resopts;
191pentype                     lastpen;
192extern char pltfilename[FNMLNGTH];
193extern char progname[FNMLNGTH];
194
195#define NO_PLANE 666    /* To make POVRay happy */
196
197#ifndef OLDC
198/* function prototypes */
199int    pointinrect(double, double, double, double, double, double);
200int    rectintersects(double, double, double, double,
201                double, double, double, double);
202long   upbyte(long);
203long   lobyte(long);
204
205void   pictoutint(FILE *, long);
206Local long SFactor(void);
207long   DigitsInt(long);
208Local boolean IsColumnEmpty(striparray *, long, long);
209void   Skip(long Amount);
210Local long FirstBlack(striparray *, long, long);
211Local long FirstWhite(striparray *, long, long);
212Local boolean IsBlankStrip(striparray *mystripe, long deep);
213
214void   striprint(long, long);
215long showvrmlparms(long vrmltreecolor, long vrmlnamecolor, 
216                long vrmlskycolornear, long vrmlskycolorfar, 
217                long vrmlgroundcolornear);
218void getvrmlparms(long *vrmltreecolor, long *vrmlnamecolor, 
219                long *vrmlskycolornear,long *vrmlskycolorfar, 
220                long *vrmlgroundcolornear,long *vrmlgroundcolorfar, 
221                long numtochange);
222
223#ifdef QUICKC
224void   setupgraphics(void);
225#endif
226
227
228long   showrayparms(long, long, long, long, long, long);
229void   getrayparms(long *, long *, long *, long *, long *,long *, long);
230
231int    readafmfile(char *, short *);
232
233void   metricforfont(char *, short *);
234void   plotchar(long *, struct LOC_plottext *);
235void   swap_charptr(char **, char **);
236void   plotpb(void);
237char  *findXfont(char *, double, double *, int *);
238int    macfontid(char *);
239int figfontid(char *fontname);
240                       
241void   makebox(char *, double *, double *, double *, long);
242/* function prototypes */
243#endif
244
245
246int pointinrect(double x,double y,double x0,double y0,double x1,double y1)
247{
248  double tmp;
249  if (x0 > x1)
250    tmp = x0,
251      x0  = x1,
252      x1  = tmp;
253  if (y0 > y1)
254    tmp = y0,
255      y0  = y1,
256      y1  = tmp;
257 
258  return ((x >= x0 && x <= x1) && (y >= y0 && y <= y1));
259}  /* pointinrect */
260
261int rectintersects(double xmin1,double ymin1,double xmax1,double ymax1,
262                double xmin2,double ymin2,double xmax2,double ymax2)
263{
264  double temp;
265 
266  /* check if any of the corners of either square are contained within the  *
267   * other one. This catches MOST cases, the last one (two) is two thin     *
268   * bands crossing each other (like a '+' )                                */
269 
270  if (xmin1 > xmax1){
271    temp  = xmin1;  xmin1 = xmax1;  xmax1 = temp;}
272  if (xmin2 > xmax2){
273    temp  = xmin2;  xmin2 = xmax2;  xmax2 = temp;}
274  if (ymin1 > ymax1){
275    temp  = ymin1;  ymin1 = ymax1;  ymax1 = temp;}
276  if (ymin2 > ymax2){
277    temp  = ymin2;  ymin2 = ymax2;  ymax2 = temp;}
278 
279  return (pointinrect(xmin1,ymin1,xmin2,ymin2,xmax2,ymax2) ||
280          pointinrect(xmax1,ymin1,xmin2,ymin2,xmax2,ymax2) ||
281          pointinrect(xmin1,ymax1,xmin2,ymin2,xmax2,ymax2) ||
282          pointinrect(xmax1,ymax1,xmin2,ymin2,xmax2,ymax2) ||
283          pointinrect(xmin2,ymin2,xmin1,ymin1,xmax1,ymax1) ||
284          pointinrect(xmax2,ymin2,xmin1,ymin1,xmax1,ymax1) ||
285          pointinrect(xmin2,ymax2,xmin1,ymin1,xmax1,ymax1) ||
286          pointinrect(xmax2,ymax2,xmin1,ymin1,xmax1,ymax1) || 
287          (xmin1 >= xmin2 && xmax1 <= xmax2 &&
288           ymin2 >= ymin1 && ymax2 <= ymax1)                ||
289          (xmin2 >= xmin1 && xmax2 <= xmax1 &&
290           ymin1 >= ymin2 && ymax1 <= ymax2)); 
291}  /* rectintersects */
292
293void clearit()
294{
295  long i;
296 
297  if (previewer == tek)
298    printf("%c\f", escape);
299  else if (ansi || ibmpc)
300    printf("\033[2J\033[H");
301  else {
302    for (i = 1; i <= 24; i++)
303      putchar('\n');
304  }
305#ifdef WIN32
306  phyClearScreen();
307#endif
308}  /* clearit */
309
310
311boolean isfigfont(char *fontname)
312{
313  int i;
314  if (strcmp(fontname,"Hershey") == 0)
315    return 1;
316  for (i=0;i<34;++i)
317    if (strcmp(fontname,figfonts[i]) == 0)
318      break;
319  return (i < 34);
320}  /* isfigfont */
321
322
323int figfontid(char *fontname)
324{
325  int i;
326  for (i=0;i<34;++i)
327    if (strcmp(fontname,figfonts[i]) == 0)
328      return i;
329  return -1;
330}  /* figfontid */
331
332
333const char *figfontname(int id)
334{
335  return figfonts[id];
336}  /* figfontname */
337
338
339void getpreview()
340{
341  long loopcount;
342  Char ch;
343
344  clearit();
345  printf("\nWhich type of screen will it be previewed on?\n\n");
346  printf("   type:       to choose one compatible with:\n\n");
347  printf("        N         will not be previewed\n");
348#ifdef DOS
349  printf("        I         MSDOS graphics screens\n");
350#endif
351#ifdef MAC
352  printf("        M         Macintosh screens\n");
353#endif
354#ifdef X
355  printf("        X         X Windows display\n");
356#endif
357#ifdef WIN32
358  printf("        W         MS Windows display\n");
359#endif
360  printf("        K         TeKtronix 4010 graphics terminal\n");
361  printf("        D         DEC ReGIS graphics (VT240 terminal)\n");
362  printf("        U         other: one you have inserted code for\n");
363  loopcount = 0;
364  do {
365    printf(" Choose one: \n");
366#ifdef WIN32
367    phyFillScreenColor();
368#endif
369    scanf("%c%*[^\n]", &ch);
370    getchar();
371    uppercase(&ch);
372    countup(&loopcount, 10);
373  }
374#undef FOO
375#ifdef DOS
376#define FOO
377  while (strchr("NIKDU",ch) == NULL);
378#endif
379#ifdef MAC
380#define FOO
381  while (strchr("NMKDU",ch) == NULL);
382#endif
383#ifdef X
384#define FOO
385  while (strchr("NXKDU",ch) == NULL);
386#endif
387#ifdef WIN32
388#define FOO
389  while (strchr("NWKDU",ch) == NULL);
390#endif
391#ifndef FOO
392  while (strchr("NKDU",ch) == NULL);
393#endif
394  preview = true;
395  switch (ch) {
396
397  case 'N':
398    preview = false;
399    previewer = other;   /* Added by Dan F. */
400    break;
401
402  case 'I':
403    previewer = ibm;
404    break;
405
406  case 'M':
407    previewer = mac;
408    break;
409
410  case 'X':
411    previewer = xpreview;
412    break;
413
414  case 'W':
415    previewer = winpreview;
416    break;
417
418  case 'K':
419    previewer = tek;
420    break;
421
422  case 'D':
423    previewer = decregis;
424    break;
425
426  case 'U':
427    previewer = other;
428    break;
429  }
430  printf("\n\n\n");
431}  /* getpreview */
432
433
434void pout(long n)
435{
436#ifdef MAC
437  if (previewing)
438    printf("%*ld", (int)((long)(0.434295 * log((double)n) + 0.0001)), n);
439  else
440    fprintf(plotfile, "%*ld",
441            (int)((long)(0.434295 * log((double)n) + 0.0001)), n);
442#endif
443#ifndef MAC
444  if (previewing)
445    printf("%*ld", (int)((long)(0.434295 * log((double)n) + 0.0001)), n);
446  else
447    fprintf(plotfile, "%*ld",
448            (int)((long)(0.434295 * log((double)n) + 0.0001)), n);
449#endif
450}  /* pout */
451
452
453long upbyte(long num)
454{
455  /* get upper nibble of byte */
456  long Result = 0, i, j, bytenum, nibcount;
457  boolean done;
458
459  bytenum = 0;
460  done = false;
461  nibcount = 0;
462  i = num / 16;
463  i /= 16;
464  j = 1;
465  while (!done) {
466    bytenum += (i & 15) * j;
467    nibcount++;
468    if (nibcount == 2) {
469      Result = bytenum;
470      done = true;
471    } else {
472      j *= 16;
473      i /= 16;
474    }
475  }
476  return Result;
477}  /* upbyte */
478
479
480long lobyte(long num)
481{
482  /* get low order nibble of byte */
483  long Result = 0, i, j, bytenum, nibcount;
484  boolean done;
485
486  bytenum = 0;
487  done = false;
488  nibcount = 0;
489  i = num;
490  j = 1;
491  while (!done) {
492    bytenum += (i & 15) * j;
493    nibcount++;
494    if (nibcount == 2) {
495      Result = bytenum;
496      done = true;
497    } else {
498      j *= 16;
499      i /= 16;
500    }
501  }
502  return Result;
503}  /* lobyte */
504
505
506void pictoutint(FILE *file, long pictint)
507{
508char picthi, pictlo;
509
510picthi = (char)(pictint / 256);
511pictlo = (char)(pictint % 256);
512fprintf(file, "%c%c", picthi, pictlo);
513}
514
515
516void initplotter(long ntips, char *fontname)
517{
518  long i,j, hres, vres;
519  Char picthi, pictlo;
520  long pictint;
521  int padded_width, byte_width;
522  unsigned int dummy1, dummy2;
523 
524  treeline = 0.18 * labelheight * yscale * expand;
525  labelline = 0.06 * labelheight * yscale * expand;
526  linewidth = treeline;
527  if (dotmatrix ) {
528    for (i = 0; i <= 50; i++) {   /* for fast circle calculations */
529     for (j = 0; j <= 50; j++){
530       rootmatrix[i][j] =
531           (long)floor(sqrt((double)(i * i + j * j)) + 0.5);}
532   }
533  }
534 switch (plotter) {
535
536  case xpreview:
537#ifdef X
538                XGetGeometry(display,mainwin,
539        &DefaultRootWindow(display),&x,&y,&width,&height,&dummy1,&dummy2);
540    XClearWindow(display,mainwin);
541#endif
542    break;
543
544  case tek:
545    oldxhigh = -1.0;
546    oldxlow = -1.0;
547    oldyhigh = -1.0;
548    oldylow = -1.0;
549    nmoves = 0;       /* DLS/JMH -- See function  PLOT                  */
550    if (previewing)   /* DLS/JMH                                        */
551      printf("%c\f", escape);   /* DLS/JMH */
552    else
553      fprintf(plotfile, "%c\f", escape);
554    break;
555
556  case hp:
557    fprintf(plotfile, "IN;SP1;VS10.0;\n");
558    break;
559
560  case ray:
561    treeline = 0.27 * labelheight * yscale * expand;
562    linewidth = treeline;
563    raylinewidth = treeline;
564    if (grows == vertical)
565      fprintf(plotfile, "plane backcolor 0 0 %2.4f 0 0 1\n", ymargin);
566    else
567      fprintf(plotfile, "plane backcolor 0 0 %2.4f 0 0 1\n",
568              ymargin - ysize / (ntips - 1));
569
570    fprintf(plotfile, "\nname tree\n");
571    fprintf(plotfile, "grid 22 22 22\n");
572    break;
573
574  case pov:
575    treeline = 0.27 * labelheight * yscale * expand;
576    linewidth = treeline;
577    raylinewidth = treeline;
578    fprintf(plotfile, "\n// First, the tree\n\n");
579    break;
580
581  case vrml:
582    vrmllinewidth = treeline;
583    break;
584
585  case pict:
586    plotfile = freopen(pltfilename,"wb",plotfile);
587    for (i=0;i<512;++i)
588      putc('\000',plotfile);
589    pictoutint(plotfile,1000); /* size...replaced later with seek */
590    pictoutint(plotfile,1);    /* bbx0   */
591    pictoutint(plotfile,1);    /* bby0   */
592    pictoutint(plotfile,612);  /* bbx1   */
593    pictoutint(plotfile,792);  /* bby1   */
594    fprintf(plotfile,"%c%c",0x11,0x01); /* version "1" (B&W) pict */
595    fprintf(plotfile,"%c%c%c",0xa0,0x00,0x82);
596    fprintf(plotfile,"%c",1);    /* clip rect */
597    pictoutint(plotfile,10);  /* region size, bytes. */
598    pictoutint(plotfile,1);   /* clip x0             */
599    pictoutint(plotfile,1);   /* clip y0             */
600    pictoutint(plotfile,612); /* clip x1             */
601    pictoutint(plotfile,792); /* clip y1             */
602   
603    bytewrite+=543;
604
605    oldpictint = 0;
606    pictint = (long)(linewidth + 0.5);
607    if (pictint == 0)
608      pictint = 1;
609    picthi = (Char)(pictint / 256);
610    pictlo = (Char)(pictint % 256);
611    fprintf(plotfile, "\007%c%c%c%c", picthi, pictlo, picthi, pictlo);
612    /* Set pen size for drawing tree. */
613    break;
614
615  case bmp:
616    plotfile = freopen(pltfilename,"wb",plotfile);
617    write_bmp_header(plotfile, (int)(xsize*xunitspercm), (int)(ysize*yunitspercm));
618    byte_width   = (int) ceil (xsize / 8.0);
619    padded_width = ((byte_width + 3) / 4) * 4 ;
620    full_pic     = (byte *) Malloc ((padded_width *2) * (int) ysize) ;
621    break ;
622
623  case xbm:  /* what a completely verbose data representation format! */
624
625    fprintf(plotfile, "#define drawgram_width %5ld\n",
626            (long)(xunitspercm * xsize));
627    fprintf(plotfile, "#define drawgram_height %5ld\n",
628            (long)(yunitspercm * ysize));
629    fprintf(plotfile, "static char drawgram_bits[] = {\n");
630    /*filesize := 53;  */
631    break;
632
633  case lw:     /* write conforming postscript */
634    fprintf(plotfile,"%%!PS-Adobe-2.0\n");
635    fprintf(plotfile,"%%%%Title: Phylip Tree Output\n");
636    fprintf(plotfile,"%%%%DocumentFonts: (atend)\n");
637    fprintf(plotfile,"%%%%Pages: %d 1\n",
638           ((int)((pagex-hpmargin-0.01)/(paperx-hpmargin))+1)*
639               ((int)((pagey-vpmargin-0.01)/papery-vpmargin)+1));
640    fprintf(plotfile,"%%%%BoundingBox: 0 0 612 792\n");
641    fprintf(plotfile,"%%%%DocumentPaperSizes: Letter\n"); /* this may not be right */
642    fprintf(plotfile,"%%%%Orientation: Portrait\n"); 
643    fprintf(plotfile,"%%%%EndComments\n");
644    fprintf(plotfile,"/l {newpath moveto lineto stroke} def\n");
645    fprintf(plotfile,"%%%%EndProlog\n%%%%\n");
646    fprintf(plotfile,"%%%%Page: 1 1\n");
647    fprintf(plotfile,"%%%%PageBoundingBox: 0 0 %d %d\n",
648            (int)(xunitspercm*paperx),(int)(yunitspercm*papery));
649    fprintf(plotfile,"%%%%PageFonts: (atend)\n%%%%BeginPageSetup\n");
650    fprintf(plotfile,"%%%%PaperSize: Letter\n");
651    fprintf(plotfile," 1 setlinecap \n 1 setlinejoin  \n");
652    fprintf(plotfile, "%8.2f setlinewidth newpath \n", treeline);
653    break;
654
655  case idraw:
656    fprintf(plotfile, "%%I Idraw 9 Grid 8 \n\n");
657    fprintf(plotfile,"%%%%Page: 1 1\n\n");
658    fprintf(plotfile,"Begin\n");
659    fprintf(plotfile,"%%I b u\n");
660    fprintf(plotfile,"%%I cfg u\n");
661    fprintf(plotfile,"%%I cbg u\n");
662    fprintf(plotfile,"%%I f u\n");
663    fprintf(plotfile,"%%I p u\n");
664    fprintf(plotfile,"%%I t\n");
665    fprintf(plotfile,"[ 0.679245 0 0 0.679245 0 0 ] concat\n"); 
666
667    fprintf(plotfile,"/originalCTM matrix currentmatrix def\n\n");
668    break;
669
670  case ibm:
671#ifdef TURBOC
672    initgraph(&GraphDriver,&HiMode,"");
673#endif
674#ifdef QUICKC
675    setupgraphics();
676#endif
677    break;
678
679  case mac:
680#ifdef MAC
681    gfxmode();
682    pictint=(long)(linewidth + 0.5);
683#endif
684    break;
685
686  case houston:
687    break;
688
689  case decregis:
690    oldx = (double) 300;
691    oldy = (double) 1;
692    nmoves = 0;
693    if (previewing)
694          printf("%c[2J%cPpW(I3);S(A[0,0][799,479]);S(I(W))S(E);S(C0);W(I(D))\n",
695                 escape,escape);
696     else
697       fprintf(plotfile,
698               "%c[2J%cPpW(I3);S(A[0,0][799,479]);S(I(W))S(E);S(C0);W(I(D))\n",
699               escape,escape);
700    break;
701
702  case epson:
703    plotfile = freopen(pltfilename,"wb",plotfile);
704    fprintf(plotfile, "\0333\030");
705    break;
706
707  case oki:
708    plotfile = freopen(pltfilename,"wb",plotfile);
709    fprintf(plotfile, "\033%%9\020");
710    break;
711
712  case citoh:
713    plotfile = freopen(pltfilename,"wb",plotfile);
714    fprintf(plotfile, "\033T16");
715    break;
716
717  case toshiba: /* reopen in binary since we always need \n\r on the file */
718                /* and dos in text mode puts it, but unix does not        */
719    plotfile = freopen(pltfilename,"wb",plotfile);
720    fprintf(plotfile, "\033\032I\n\r\n\r");
721    fprintf(plotfile, "\033L06\n\r");
722    break;
723
724  case pcl:
725    plotfile = freopen(pltfilename,"wb",plotfile);
726/* debug  omit next statement for Deskjet?   Push current cursor
727    fprintf(plotfile, "\033&f0S");
728 debug */
729    if (hpresolution == 150 || hpresolution == 300)
730      fprintf(plotfile, "\033*t%3ldR", hpresolution);
731    else if (hpresolution == 75)
732      fprintf(plotfile, "\033*t75R");
733    break;
734
735  case pcx:
736    plotfile = freopen(pltfilename,"wb",plotfile);
737    fprintf(plotfile,"\012\003\001\001%c%c%c%c",0,0,0,0);
738  /* Manufacturer version (1 byte) version (1 byte), encoding (1 byte),
739     bits per pixel (1 byte), xmin (2 bytes) ymin (2 bytes),
740     Version */
741    hres = strpwide;
742    vres = (long)floor(yunitspercm * ysize + 0.5);
743    fprintf(plotfile, "%c%c", (unsigned char)lobyte(hres - 1),
744            (unsigned char)upbyte(hres - 1)); /* Xmax */
745    fprintf(plotfile, "%c%c", (unsigned char)lobyte(vres - 1),
746            (unsigned char)upbyte(vres - 1)); /* Ymax */
747    fprintf(plotfile, "%c%c", (unsigned char)lobyte(hres),
748            (unsigned char)upbyte(hres));
749    /* Horizontal resolution */
750    fprintf(plotfile, "%c%c", (unsigned char)lobyte(vres),
751            (unsigned char)upbyte(vres));
752    /* Vertical resolution */
753    for (i = 1; i <= 48; i++)   /* Color Map */
754      putc('\000', plotfile);
755    putc('\000', plotfile);
756    putc('\001', plotfile);   /* Num Planes */
757    putc(hres / 8, plotfile);   /* Bytes per line */
758    putc('\000',plotfile);
759    for (i = 1; i <= 60; i++)   /* Filler */
760      putc('\000',plotfile);
761    break;
762
763  case fig:
764    fprintf(plotfile, "#FIG 2.0\n");
765    fprintf(plotfile, "80 2\n");
766    break;
767
768 case gif:
769 case other:
770    break;
771 default:        /* case vrml not handled        */
772    break;
773    /* initialization code for a new plotter goes here */
774  }
775}  /* initplotter */
776
777
778void finishplotter()
779{
780  int padded_width, byte_width; /* For bmp code */
781
782  switch (plotter) {
783
784  case xpreview:
785#ifdef X
786         plotter=oldplotter;
787         redraw(NULL,NULL,NULL);
788         XtAppMainLoop(appcontext);
789
790#endif
791    break;
792
793  case tek:
794    if (previewing) {
795      scanf("%*c%*[^\n]");
796      getchar();
797      printf("%c\f", escape);
798    } else {
799      putc('\n', plotfile);
800      plot(penup, 1.0, 1.0);
801    }
802    break;
803
804  case hp:
805    plot(penup, 1.0, 1.0);
806    fprintf(plotfile, "SP;\n");
807    break;
808
809  case ray:
810    fprintf(plotfile,"end\n\nobject treecolor tree\n");
811    fprintf(plotfile,"object namecolor species_names\n");
812    break;
813
814  case pov:
815    break;
816
817  case pict:
818    fprintf(plotfile,"%c%c%c%c%c",0xa0,0x00,0x82,0xff,0x00);
819    bytewrite+=5;
820    fseek(plotfile,512L,SEEK_SET);
821    pictoutint(plotfile,bytewrite);
822    break;
823
824  case lw:
825    fprintf(plotfile, "stroke showpage \n\n");
826    fprintf(plotfile,"%%%%PageTrailer\n");
827    fprintf(plotfile,"%%%%PageFonts: %s\n",
828            (strcmp(fontname,"Hershey") == 0) ? "" : fontname);
829    fprintf(plotfile,"%%%%Trailer\n");
830    fprintf(plotfile,"%%%%DocumentFonts: %s\n",
831            (strcmp(fontname,"Hershey") == 0) ? "" : fontname);
832    break;
833
834  case idraw:
835    fprintf(plotfile, "\nEnd %%I eop\n\n");
836    fprintf(plotfile, "showpage\n\n");
837    fprintf(plotfile, "%%%%Trailer\n\n");
838    fprintf(plotfile, "end\n");
839    break;
840
841  case ibm:
842#ifdef TURBOC
843    getchar();
844    restorecrtmode();
845#endif
846#ifdef QUICKC
847    getchar();
848    _clearscreen(_GCLEARSCREEN);
849    _setvideomode(_DEFAULTMODE);
850#endif
851    break;
852
853  case mac:
854#ifdef MAC
855    plotter=oldplotter;
856    eventloop();
857#endif
858    break;
859
860  case houston:
861    break;
862
863  case decregis:
864    plot(penup, 1.0, 1.0);
865    if (previewing)
866      printf("%c\\", escape);
867    else
868      fprintf(plotfile, "%c\\", escape);
869    if (previewing) {
870      getchar();
871      printf("%c[2J",escape);
872    }
873    break;
874
875  case epson:
876    fprintf(plotfile, "\0333$");
877    break;
878
879  case oki:
880    /* blank case */
881    break;
882
883  case citoh:
884    fprintf(plotfile, "\033A");
885    break;
886
887  case toshiba:
888    fprintf(plotfile, "\033\032I\n\r");
889    break;
890
891  case pcl:
892/* debug  omit next statement for Deskjet?    pop cursor
893    fprintf(plotfile, "\033&f1S"); 
894 debug */
895    fprintf(plotfile, "\033*rB");    /* Exit graphics mode */
896    putc('\f', plotfile);            /* just to make sure? */
897    break;
898
899  case pcx:
900    /* blank case */
901    break;
902
903  case bmp:
904    byte_width = (int) ceil (xsize / 8.0);
905    padded_width = ((byte_width + 3) / 4) * 4 ;
906    turn_rows (full_pic, padded_width, (int) ysize);
907    write_full_pic(full_pic, total_bytes);
908    free (full_pic) ;
909    break;
910
911  case xbm:
912    fprintf(plotfile, "}\n");
913    break;
914
915  case fig:
916    /* blank case */
917    break;
918
919  case gif:
920  case other:
921    break;
922  default:        /* case vrml not handled        */
923    break;
924    /* termination code for a new plotter goes here */
925  }
926}  /* finishplotter */
927
928
929Local long SFactor()
930{
931  /* the dot-skip is resolution-independent. */
932  /* this makes all the point-skip instructions skip the same # of dots. */
933  long Result = 0;
934
935  if (hpresolution == 150)
936    Result = 2;
937  if (hpresolution == 300)
938    Result = 1;
939  if (hpresolution == 75)
940    return 4;
941  return Result;
942}  /* SFactor */
943
944
945long DigitsInt(long x)
946{
947  if (x < 10)
948    return 1;
949  else if (x >= 10 && x < 100)
950    return 2;
951  else
952    return 3;
953}  /* DigistInt */
954
955
956Local boolean IsColumnEmpty(striparray *mystripe, long pos, long deep)
957{
958  long j;
959  boolean ok;
960
961  ok = true;
962  j = 1;
963  while (ok && j <= deep) {
964    ok = (ok && mystripe[j - 1][pos - 1] == null);
965    j++;
966  }
967  return ok;
968}  /* IsColumnEmpty */
969
970
971void Skip(long Amount)
972{
973  /* assume we're not in gfx mode. */
974  fprintf(plotfile, "\033&f1S");   /* Pop the graphics cursor    */
975#ifdef MAC
976  fprintf(plotfile, "\033*p+%*ldX",
977          (int)DigitsInt(Amount * SFactor()), Amount * SFactor());
978#endif
979#ifndef MAC
980  fprintf(plotfile, "\033*p+%*ldX",
981          (int)DigitsInt(Amount * SFactor()), Amount * SFactor());
982#endif
983  fprintf(plotfile, "\033&f0S");   /* Push the cursor to new location */
984  filesize += 15 + DigitsInt(Amount * SFactor());
985}  /* Skip */
986
987
988Local long FirstBlack(striparray *mystripe, long startpos, long deep)
989{
990  /* returns, given a strip and a position, next x with some y's nonzero */
991  long i;
992  boolean columnempty;
993
994  i = startpos;
995  columnempty = true;
996  while (columnempty && i < strpwide / 8) {
997    columnempty = (columnempty && IsColumnEmpty(mystripe, i,deep));
998    if (columnempty)
999      i++;
1000  }
1001  return i;
1002}  /* FirstBlack */
1003
1004
1005Local long FirstWhite(striparray *mystripe, long startpos, long deep)
1006{
1007  /* returns, given a strip and a position, the next x with all y's zero */
1008  long i;
1009  boolean columnempty;
1010
1011  i = startpos;
1012  columnempty = false;
1013  while (!columnempty && i < strpwide / 8) {
1014    columnempty = IsColumnEmpty(mystripe, i,deep);
1015    if (!columnempty)
1016      i++;
1017  }
1018  return i;
1019}  /* FirstWhite */
1020
1021
1022Local boolean IsBlankStrip(striparray *mystripe, long deep)
1023{
1024  long i, j;
1025  boolean ok;
1026
1027  ok = true;
1028  i = 1;
1029  while (ok && i <= strpwide / 8) {
1030    for (j = 0; j < (deep); j++)
1031      ok = (ok && mystripe[j][i - 1] == '\0');
1032    i++;
1033  }
1034  return ok;
1035}  /* IsBlankStrip */
1036
1037
1038void striprint(long div, long deep)
1039{
1040  long i, j, t, x, theend, width;
1041  unsigned char counter;
1042  boolean done;
1043  done = false;
1044  width = strpwide;
1045  if (plotter != pcx && plotter != pcl &&
1046      plotter != bmp && plotter != xbm) {
1047    while (!done) {
1048      for (i = 0; i < div; i++)
1049        done = done || (stripe[i] && (stripe[i][width - 1] != null));
1050      if (!done)
1051        width--;
1052      done = (done || width == 0);
1053    }
1054  }
1055  switch (plotter) {
1056
1057  case epson:
1058    if (!empty) {
1059      fprintf(plotfile, "\033L%c%c", (char) width & 255, (char) width / 256);
1060      for (i = 0; i < width; i++)
1061        putc(stripe[0][i], plotfile);
1062      filesize += width + 4;
1063    }
1064    putc('\n', plotfile);
1065    putc('\r', plotfile);
1066    break;
1067
1068  case oki:
1069    if (!empty) {
1070      fprintf(plotfile, "\033%%1%c%c", (char) width / 128, (char) width & 127);
1071      for (i = 0; i < width; i++)
1072        putc(stripe[0][i], plotfile);
1073      filesize += width + 5;
1074    }
1075    putc('\n', plotfile);
1076    putc('\r', plotfile);
1077    break;
1078
1079  case citoh:
1080    if (!empty) {
1081      fprintf(plotfile, "\033S%04ld",width);
1082      for (i = 0; i < width; i++)
1083        putc(stripe[0][i], plotfile);
1084      filesize += width + 6;
1085    }
1086
1087    putc('\n', plotfile);
1088    putc('\r', plotfile);
1089    break;
1090
1091  case toshiba:
1092    if (!empty) {
1093      for (i = 0; i < width; i++) {
1094        for (j = 0; j <= 3; j++)
1095          stripe[j][i] += 64;
1096      }
1097      fprintf(plotfile, "\033;%04ld",width);
1098
1099      for (i = 0; i < width; i++)
1100        fprintf(plotfile, "%c%c%c%c",
1101                stripe[0][i], stripe[1][i], stripe[2][i], stripe[3][i]);
1102      filesize += width * 4 + 6;
1103    }
1104    putc('\n', plotfile);
1105    putc('\r', plotfile);
1106    break;
1107
1108  case pcx:
1109    width = strpwide / 8;
1110    for (j = 0; j < div; j++) {
1111      t = 1;
1112      while (1) {
1113        i = 0; /* i == RLE count ???? */
1114        while ((stripe[j][t + i - 1]) == (stripe[j][t + i])
1115               && t + i < width && i < 63)
1116          i++;
1117        if (i > 0) {
1118          counter = 192;
1119          counter += i;
1120          putc(counter, plotfile);
1121          putc(255 - stripe[j][t - 1], plotfile);
1122          t += i;
1123          filesize += 2;
1124        } else {
1125          if (255 - (stripe[j][t - 1] & 255) >= 192) {
1126            putc(193, plotfile);
1127            filesize++;
1128          }
1129          putc(255 - stripe[j][t - 1], plotfile);
1130          t++;
1131          filesize++;
1132
1133        }
1134        if (t >width) break;
1135      }
1136    }
1137    break;
1138
1139  case pcl:
1140    width = strpwide / 8;
1141    if (IsBlankStrip(stripe,deep)) {
1142#ifdef MAC
1143      fprintf(plotfile, "\033&f1S\033*p0X\033*p+%*ldY\033&f0S",
1144              (int)DigitsInt(deep * SFactor()), deep * SFactor());
1145#endif
1146#ifndef MAC
1147      fprintf(plotfile, "\033&f1S\033*p0X\033*p+%*dY\033&f0S",
1148              (int)DigitsInt(deep * SFactor()), (int) (deep * SFactor()));
1149#endif
1150      filesize += DEFAULT_STRIPE_HEIGHT + DigitsInt(deep * SFactor());
1151    } else {  /* plotting the actual strip as bitmap data */
1152      x = 1;
1153      theend = 1;
1154      while (x < width) {
1155        x = FirstBlack(stripe, x,deep);    /* all-black strip is now    */
1156        Skip((x - theend - 1) * 8);        /* x..theend                 */
1157        theend = FirstWhite(stripe, x,deep) - 1;/* like lastblack            */
1158        fprintf(plotfile, "\033*r1A");     /* enter gfx mode            */
1159        for (j = 0; j < div; j++) {
1160#ifdef MAC
1161          fprintf(plotfile, "\033*b%*ldW",
1162                  (int)DigitsInt(theend - x + 1), theend - x + 1);
1163#endif
1164#ifndef MAC
1165          fprintf(plotfile, "\033*b%*dW",
1166                  (int)DigitsInt(theend - x + 1), (int) (theend - x + 1));
1167#endif
1168              /* dump theend-x+1 bytes */
1169          for (t = x - 1; t < theend; t++)
1170            putc(stripe[j][t], plotfile);
1171          filesize += theend - x + DigitsInt(theend - x + 1) + 5;
1172        }
1173        fprintf(plotfile, "\033*rB");   /* end gfx mode */
1174        Skip((theend - x + 1) * 8);
1175        filesize += 9;
1176        x = theend + 1;
1177      }
1178      fprintf(plotfile, "\033&f1S");   /* Pop cursor  */
1179#ifdef MAC
1180      fprintf(plotfile, "\033*p0X\033*p+%*ldY",
1181              (int)DigitsInt(deep * SFactor()), deep * SFactor());
1182#endif
1183#ifndef MAC
1184      fprintf(plotfile, "\033*p0X\033*p+%*dY",
1185              (int)DigitsInt(deep * SFactor()), (int) (deep * SFactor()));
1186#endif
1187      filesize += DEFAULT_STRIPE_HEIGHT + DigitsInt(deep * SFactor());
1188      fprintf(plotfile, "\033&f0S");   /* Push cursor  */
1189    }
1190    break;
1191    /* case for hpcl code */
1192
1193
1194  case bmp:
1195    width = ((strpwide -1) / 8) +1;
1196    translate_stripe_to_bmp (&stripe, full_pic, increment++,
1197                             width, div, &total_bytes) ;
1198    break;
1199    /* case for bmp code */
1200
1201  case xbm:
1202    x = 0;   /* count up # of bytes so we can put returns. */
1203    width = ((strpwide -1) / 8) +1;
1204    for (j = 0; j <  div; j++) {
1205      for (i = 0; i < width; i++) {
1206        fprintf(plotfile, "0x%02x,",(unsigned char)stripe[j][i]);
1207        filesize += 5;
1208        x++;
1209        if ((x % 15) == 0) {
1210          putc('\n', plotfile);
1211          filesize++;
1212        }
1213      }
1214    }
1215   putc('\n',plotfile);
1216   break;
1217
1218  case lw:
1219  case hp:
1220  case xpreview:
1221  case winpreview:
1222  case tek:
1223  case ibm:
1224  case mac:
1225  case houston:
1226  case decregis:
1227  case fig:
1228  case pict:
1229  case ray:
1230  case pov:
1231  case gif:
1232  case idraw:
1233  case other:
1234    break;
1235  default:      /* case vrml not handled        */
1236    break;
1237    /* graphics print code for a new printer goes here */
1238  }
1239}  /* striprint */
1240
1241
1242#ifdef QUICKC
1243void setupgraphics()
1244{
1245_getvideoconfig(&myscreen);
1246#ifndef WATCOM
1247switch(myscreen.adapter){
1248  case _CGA:
1249  case _OCGA:
1250   _setvideomode(_HRESBW);
1251    break;
1252  case _EGA:
1253  case _OEGA:
1254    _setvideomode(_ERESNOCOLOR);
1255  case _VGA:
1256  case _OVGA:
1257  case _MCGA:
1258    _setvideomode(_VRES2COLOR);
1259     break;
1260  case _HGC:
1261    _setvideomode(_HERCMONO);
1262     break;
1263  default:
1264     printf("Your display hardware is unsupported by this program.\n");
1265      break;
1266}
1267#endif
1268#ifdef WATCOM
1269switch(myscreen.adapter){
1270  case _VGA:
1271  case _SVGA:
1272      _setvideomode(_VRES16COLOR);
1273      break;
1274  case _MCGA:
1275      _setvideomode(_MRES256COLOR);
1276      break;
1277  case _EGA:
1278     _setvideomode(_ERESNOCOLOR);
1279     break;
1280  case _CGA:
1281     _setvideomode(_MRES4COLOR);
1282     break;
1283  case _HERCULES:
1284     _setvideomode(_HERCMONO);
1285     break;
1286  default:
1287     printf("Your display hardware is unsupported by this program.\n");
1288     exxit(-1);
1289     break;
1290   }
1291#endif
1292_getvideoconfig(&myscreen);
1293_setlinestyle(0xffff);
1294xunitspercm=myscreen.numxpixels / 25;
1295yunitspercm=myscreen.numypixels / 17.5;
1296xsize = 25.0;
1297ysize = 17.5;
1298}  /* setupgraphics */
1299#endif
1300
1301
1302void loadfont(short *font, char *application)
1303{
1304
1305  FILE *fontfile;
1306  long i, charstart = 0, dummy;
1307  Char ch = 'A';
1308
1309  i=0;
1310  openfile(&fontfile,FONTFILE,"font file","r",application,NULL);
1311
1312  while (!(eoff(fontfile) || ch == ' ')) {
1313    charstart = i + 1;
1314    fscanf(fontfile, "%c%c%ld%hd%hd", &ch, &ch, &dummy, &font[charstart + 1],
1315           &font[charstart + 2]);
1316    font[charstart] = ch;
1317    i = charstart + 3;
1318    do {
1319      if ((i - charstart - 3) % 10 == 0) 
1320        scan_eoln(fontfile);
1321      i++;
1322      fscanf(fontfile, "%hd", &font[i - 1]);
1323    } while (abs(font[i - 1]) < 10000);
1324    scan_eoln(fontfile);
1325    font[charstart - 1] = i + 1;
1326  }
1327  font[charstart - 1] = 0;
1328 FClose(fontfile);
1329}  /* loadfont */
1330
1331
1332long showrayparms(long treecolor, long namecolor, long backcolor,
1333                        long bottomcolor, long rx, long ry)
1334{
1335  long i, loopcount;
1336  Char ch,input[32];
1337  long numtochange;
1338
1339  if (previewer == tek)
1340    printf("%c\f", escape);
1341  else {
1342    for (i = 1; i <= 24; i++)
1343      putchar('\n');
1344  }
1345  if (plotter == ray) {
1346    printf("Settings for Rayshade file: \n\n");
1347    printf(" (1)               Tree color:  %.10s\n",colors[treecolor-1].name);
1348    printf(" (2)      Species names color:  %.10s\n",colors[namecolor-1].name);
1349    printf(" (3)         Background color:  %.10s\n",colors[backcolor-1].name);
1350    printf(" (4)               Resolution:  %2ld X %2ld\n\n",rx,ry);
1351  } else if (plotter == pov) {
1352    printf("Settings for POVray file: \n\n");
1353    printf(" (1)               Tree color:  %.10s\n",colors[treecolor-1].name);
1354    printf(" (2)      Species names color:  %.10s\n",colors[namecolor-1].name);
1355    printf(" (3)         Background color:  %.10s\n",colors[backcolor-1].name);
1356    printf(" (4)             Bottom plane:  %.10s\n",
1357           bottomcolor == NO_PLANE ?
1358           "(none)\0" : colors[bottomcolor-1].name);
1359  }
1360   
1361  printf(" Do you want to accept these? (Yes or No)\n");
1362  loopcount = 0;
1363  for (;;) {
1364    printf(" Type Y or N or the number (1-4) of the one to change: \n");
1365#ifdef WIN32
1366    phyFillScreenColor();
1367#endif
1368    getstryng(input);
1369    numtochange=atoi(input);
1370    uppercase(&input[0]);
1371    ch=input[0];
1372    if (ch == 'Y' || ch == 'N' || (numtochange >= 1 && numtochange <= 4))
1373      break;
1374    countup(&loopcount, 10);
1375  }
1376 return (ch == 'Y') ? -1 : numtochange;
1377}  /* showrayparms */
1378
1379
1380void getrayparms(long *treecolor, long *namecolor, long *backcolor,
1381                        long *bottomcolor, long *rx,long *ry, long numtochange)
1382{
1383  Char ch;
1384  long i, loopcount;
1385
1386  if (numtochange == 0) {
1387    loopcount = 0;
1388    do {
1389      printf(" Type the number of one that you want to change (1-4):\n");
1390#ifdef WIN32
1391      phyFillScreenColor();
1392#endif
1393      scanf("%ld%*[^\n]", &numtochange);
1394      getchar();
1395      countup(&loopcount, 10);
1396    } while (numtochange < 1 || numtochange > 10);
1397  }
1398  switch (numtochange) {
1399
1400  case 1:
1401    printf("\nWhich of these colors will the tree be?:\n");
1402    printf("   White, Red, Orange, Yellow, Green, Blue, or Violet\n");
1403    printf(" (W, R, O, Y, G, B, or V)\n");
1404    loopcount = 0;
1405    do {
1406      printf(" Choose one: \n");
1407#ifdef WIN32
1408      phyFillScreenColor();
1409#endif
1410      scanf("%c%*[^\n]", &ch);
1411      getchar();
1412      if (ch == '\n')
1413        ch = ' ';
1414      uppercase(&ch);
1415      (*treecolor) = 0;
1416      for (i = 1; i <= 7; i++) {
1417        if (ch == colors[i - 1].name[0]) {
1418          (*treecolor) = i;
1419          return;
1420        }
1421      }
1422      countup(&loopcount, 10);
1423    } while ((*treecolor) == 0);
1424    break;
1425   
1426  case 2:
1427    printf("\nWhich of these colors will the species names be?:\n");
1428    printf("   White, Red, Orange, Yellow, Green, Blue, or Violet\n");
1429    printf(" (W, R, O, Y, G, B, or V)\n");
1430    loopcount = 0;
1431    do {
1432      printf(" Choose one: \n");
1433#ifdef WIN32
1434      phyFillScreenColor();
1435#endif
1436      scanf("%c%*[^\n]", &ch);
1437      getchar();
1438      if (ch == '\n')
1439        ch = ' ';
1440      uppercase(&ch);
1441      (*namecolor) = 0;
1442      for (i = 1; i <= 7; i++) {
1443        if (ch == colors[i - 1].name[0]) {
1444          (*namecolor) = i;
1445          return;
1446        }
1447      }
1448      countup(&loopcount, 10);
1449    } while ((*namecolor) == 0);
1450    break;
1451
1452  case 3:
1453    printf("\nWhich of these colors will the background be?:\n");
1454    printf("   White, Red, Orange, Yellow, Green, Blue, or Violet\n");
1455    printf(" (W, R, O, Y, G, B, or V)\n");
1456    loopcount = 0;
1457    do {
1458      printf(" Choose one: \n");
1459#ifdef WIN32
1460      phyFillScreenColor();
1461#endif
1462      scanf("%c%*[^\n]", &ch);
1463      getchar();
1464      if (ch == '\n')
1465        ch = ' ';
1466      uppercase(&ch);
1467      (*backcolor) = 0;
1468      for (i = 1; i <= 7; i++) {
1469        if (ch == colors[i - 1].name[0]) {
1470          (*backcolor) = i;
1471          return;
1472        }
1473      }
1474      countup(&loopcount, 10);
1475    } while ((*backcolor) == 0);
1476    break;
1477
1478  case 4:
1479    /* Dimensions for rayshade, bottom plane for povray */
1480    if (plotter == pov) {
1481      printf("\nWhich of these colors will the bottom plane be?:\n");
1482      printf("   White, Red, Orange, Yellow, Green, Blue, Violet, or None (no plane)\n");
1483      printf(" (W, R, O, Y, G, B, V, or N)\n");
1484      loopcount = 0;
1485      do {
1486        printf(" Choose one: \n");
1487#ifdef WIN32
1488        phyFillScreenColor();
1489#endif
1490        scanf("%c%*[^\n]", &ch);
1491        getchar();
1492        if (ch == '\n')
1493          ch = ' ';
1494        uppercase(&ch);
1495        /* If the user doesn't want a bottom plane. . . */
1496        if (ch == 'N') {
1497          (*bottomcolor) = NO_PLANE;
1498          return;
1499        } else {
1500          (*bottomcolor) = 0;
1501          for (i = 1; i <= 7; i++) {
1502            if (ch == colors[i - 1].name[0]) {
1503              (*bottomcolor) = i;
1504              return;
1505            }
1506          }
1507        }
1508      countup(&loopcount, 10);
1509      } while ((*bottomcolor) == 0);
1510
1511    } else if (plotter == ray) {
1512      printf("\nEnter the X resolution:\n");
1513#ifdef WIN32
1514      phyFillScreenColor();
1515#endif
1516      scanf("%ld%*[^\n]", rx);
1517      getchar();
1518      printf("Enter the Y resolution:\n");
1519#ifdef WIN32
1520      phyFillScreenColor();
1521#endif
1522    scanf("%ld%*[^\n]",ry);
1523      getchar();
1524    }
1525    break;
1526  }
1527}  /* getrayparms */
1528
1529
1530long showvrmlparms(long vrmltreecolor, long vrmlnamecolor, long vrmlskycolornear,
1531                        long vrmlskycolorfar, long vrmlgroundcolornear)
1532{
1533  long i, loopcount;
1534  Char ch,input[32];
1535  long numtochange;
1536
1537  if (previewer == tek)
1538    printf("%c\f", escape);
1539  else {
1540    for (i = 1; i <= 24; i++)
1541      putchar('\n');
1542  }
1543  printf("Settings for VRML file: \n\n");
1544  printf(" (1)               Tree color:  %.10s\n",colors[vrmltreecolor-1].name);
1545  printf(" (2)      Species names color:  %.10s\n",colors[vrmlnamecolor-1].name);
1546  printf(" (3)            Horizon color:  %.10s\n",colors[vrmlskycolorfar-1].name);
1547  printf(" (4)             Zenith color:  %.10s\n",colors[vrmlskycolornear-1].name);
1548  printf(" (5)             Ground color:  %.10s\n",colors[vrmlgroundcolornear-1].name);
1549   
1550  printf(" Do you want to accept these? (Yes or No)\n");
1551  loopcount = 0;
1552  for (;;) {
1553    printf(" Type Y or N or the number (1-5) of the one to change: \n");
1554#ifdef WIN32
1555    phyFillScreenColor();
1556#endif
1557    getstryng(input);
1558    numtochange=atoi(input);
1559    uppercase(&input[0]);
1560    ch=input[0];
1561    if (ch == 'Y' || ch == 'N' || (numtochange >= 1 && numtochange <= 5))
1562      break;
1563    countup(&loopcount, 10);
1564  }
1565 return (ch == 'Y') ? -1 : numtochange;
1566}  /* showvrmlparms */
1567
1568
1569void getvrmlparms(long *vrmltreecolor, long *vrmlnamecolor, long *vrmlskycolornear,
1570                        long *vrmlskycolorfar, long *vrmlgroundcolornear,
1571                        long *vrmlgroundcolorfar, long numtochange)
1572{
1573  Char ch;
1574  long i, loopcount;
1575
1576  if (numtochange == 0) {
1577    loopcount = 0;
1578    do {
1579      printf(" Type the number of one that you want to change (1-4):\n");
1580#ifdef WIN32
1581      phyFillScreenColor();
1582#endif
1583      scanf("%ld%*[^\n]", &numtochange);
1584      getchar();
1585      countup(&loopcount, 10);
1586    } while (numtochange < 1 || numtochange > 10);
1587  }
1588  switch (numtochange) {
1589
1590  case 1:
1591    printf("\nWhich of these colors will the tree be?:\n");
1592    printf("   White, Red, Orange, Yellow, Green, Blue, or Violet\n");
1593    printf(" (W, R, O, Y, G, B, or V)\n");
1594    loopcount = 0;
1595    do {
1596      printf(" Choose one: \n");
1597#ifdef WIN32
1598      phyFillScreenColor();
1599#endif
1600      scanf("%c%*[^\n]", &ch);
1601      getchar();
1602      if (ch == '\n')
1603        ch = ' ';
1604      uppercase(&ch);
1605      (*vrmltreecolor) = 0;
1606      for (i = 1; i <= 7; i++) {
1607        if (ch == colors[i - 1].name[0]) {
1608          (*vrmltreecolor) = i;
1609          return;
1610        }
1611      }
1612      countup(&loopcount, 10);
1613    } while ((*vrmltreecolor) == 0);
1614    break;
1615   
1616  case 2:
1617    printf("\nWhich of these colors will the species names be?:\n");
1618    printf("   White, Red, Orange, Yellow, Green, Blue, or Violet\n");
1619    printf(" (W, R, O, Y, G, B, or V)\n");
1620    loopcount = 0;
1621    do {
1622      printf(" Choose one: \n");
1623#ifdef WIN32
1624      phyFillScreenColor();
1625#endif
1626      scanf("%c%*[^\n]", &ch);
1627      getchar();
1628      if (ch == '\n')
1629        ch = ' ';
1630      uppercase(&ch);
1631      (*vrmlnamecolor) = 0;
1632      for (i = 1; i <= 7; i++) {
1633        if (ch == colors[i - 1].name[0]) {
1634          (*vrmlnamecolor) = i;
1635          return;
1636        }
1637      }
1638      countup(&loopcount, 10);
1639    } while ((*vrmlnamecolor) == 0);
1640    break;
1641
1642  case 3:
1643    printf("\nWhich of these colors will the horizon be?:\n");
1644    printf("   White, Red, Orange, Yellow, Green, Blue, or Violet\n");
1645    printf(" (W, R, O, Y, G, B, or V)\n");
1646    loopcount = 0;
1647    do {
1648      printf(" Choose one: \n");
1649#ifdef WIN32
1650      phyFillScreenColor();
1651#endif
1652      scanf("%c%*[^\n]", &ch);
1653      getchar();
1654      if (ch == '\n')
1655        ch = ' ';
1656      uppercase(&ch);
1657      (*vrmlskycolorfar) = 0;
1658      for (i = 1; i <= 7; i++) {
1659        if (ch == colors[i - 1].name[0]) {
1660          (*vrmlskycolorfar) = i;
1661          return;
1662        }
1663      }
1664      countup(&loopcount, 10);
1665    } while ((*vrmlskycolorfar) == 0);
1666    break;
1667
1668  case 4:
1669    printf("\nWhich of these colors will the zenith be?:\n");
1670    printf("   White, Red, Orange, Yellow, Green, Blue, or Violet\n");
1671    printf(" (W, R, O, Y, G, B, or V)\n");
1672    loopcount = 0;
1673    do {
1674      printf(" Choose one: \n");
1675#ifdef WIN32
1676      phyFillScreenColor();
1677#endif
1678      scanf("%c%*[^\n]", &ch);
1679      getchar();
1680      if (ch == '\n')
1681        ch = ' ';
1682      uppercase(&ch);
1683      (*vrmlskycolornear) = 0;
1684      for (i = 1; i <= 7; i++) {
1685        if (ch == colors[i - 1].name[0]) {
1686          (*vrmlskycolornear) = i;
1687          return;
1688        }
1689      }
1690      countup(&loopcount, 10);
1691    } while ((*vrmlskycolornear) == 0);
1692    break;
1693
1694  case 5:
1695    printf("\nWhich of these colors will the ground be?:\n");
1696    printf("   White, Red, Orange, Yellow, Green, Blue, or Violet\n");
1697    printf(" (W, R, O, Y, G, B, or V)\n");
1698    loopcount = 0;
1699    do {
1700      printf(" Choose one: \n");
1701#ifdef WIN32
1702      phyFillScreenColor();
1703#endif
1704      scanf("%c%*[^\n]", &ch);
1705      getchar();
1706      if (ch == '\n')
1707        ch = ' ';
1708      uppercase(&ch);
1709      (*vrmlgroundcolornear) = 0;
1710      for (i = 1; i <= 7; i++) {
1711        if (ch == colors[i - 1].name[0]) {
1712          (*vrmlgroundcolornear) = i;
1713          (*vrmlgroundcolorfar) = i;
1714          return;
1715        }
1716      }
1717      countup(&loopcount, 10);
1718    } while ((*vrmlgroundcolornear) == 0);
1719    break;
1720
1721  }
1722}  /* gevrmlparms */
1723
1724
1725void plotrparms(long ntips)
1726{
1727  /* set up initial characteristics of plotter or printer */
1728  long treecolor, namecolor, backcolor, bottomcolor, rayresx, rayresy;
1729  double viewangle;
1730  long n, loopcount;
1731  double xsizehold, ysizehold;
1732
1733  xsizehold = xsize;
1734  ysizehold = ysize;
1735  penchange = no;
1736  xcorner = 0.0;
1737  ycorner = 0.0;
1738  if (dotmatrix && (!previewing))
1739    strpdiv = 1;
1740  switch (plotter) {
1741
1742  case ray:
1743    penchange = yes;
1744    xunitspercm = 1.0;
1745    yunitspercm = 1.0;
1746    xsize = 10.0;
1747    ysize = 10.0;
1748    rayresx = 512;
1749    rayresy = 512;
1750    treecolor = 6;
1751    namecolor = 4;
1752    backcolor = 1;
1753    /* MSVC gave warning that bottomcolor was uninitialized.  Unsure what
1754       this should be */
1755    bottomcolor = 1;
1756    loopcount = 0;
1757    do {
1758      n=showrayparms(treecolor,namecolor,backcolor,bottomcolor,rayresx,rayresy);
1759      if (n != -1)
1760        getrayparms(&treecolor,&namecolor,&backcolor,&bottomcolor,&rayresx,&rayresy,n);
1761      countup(&loopcount, 10);
1762    } while (n != -1);
1763    xsize = rayresx;
1764    ysize = rayresy;
1765
1766    fprintf(plotfile, "report verbose\n");
1767
1768    fprintf(plotfile, "screen %ld %ld\n", rayresx, rayresy);
1769    if (ysize >= xsize) {
1770      viewangle = 2 * atan(ysize / (2 * 1.21 * xsize)) * 180 / pi;
1771      fprintf(plotfile, "fov 45 %3.1f\n", viewangle);
1772      fprintf(plotfile, "light 1 point 0 %6.2f %6.2f\n",
1773              -xsize * 1.8, xsize * 1.5);
1774      fprintf(plotfile, "eyep %6.2f %6.2f %6.2f\n",
1775              xsize * 0.5, -xsize * 1.21, ysize * 0.55);
1776    } else {
1777      viewangle = 2 * atan(xsize / (2 * 1.21 * ysize)) * 180 / pi;
1778      fprintf(plotfile, "fov %3.1f 45\n", viewangle);
1779      fprintf(plotfile, "light 1 point 0 %6.2f %6.2f\n",
1780              -ysize * 1.8, ysize * 1.5);
1781      fprintf(plotfile, "eyep %6.2f %6.2f %6.2f\n",
1782              xsize * 0.5, -ysize * 1.21, ysize * 0.55);
1783    }
1784
1785    fprintf(plotfile, "lookp %6.2f 0 %6.2f\n", xsize * 0.5, ysize * 0.5);
1786    fprintf(plotfile, "/* %.10s */\n", colors[treecolor - 1].name);
1787    fprintf(plotfile,
1788            "surface treecolor diffuse %5.2f%5.2f%5.2f specular 1 1 1 specpow 30\n",
1789            colors[treecolor - 1].red, colors[treecolor - 1].green,
1790            colors[treecolor - 1].blue);
1791    fprintf(plotfile, "/* %.10s */\n", colors[namecolor - 1].name);
1792    fprintf(plotfile,
1793            "surface namecolor diffuse %5.2f%5.2f%5.2f specular 1 1 1 specpow 30\n",
1794            colors[namecolor - 1].red, colors[namecolor - 1].green,
1795            colors[namecolor - 1].blue);
1796    fprintf(plotfile, "/* %.10s */\n", colors[backcolor - 1].name);
1797    fprintf(plotfile, "surface backcolor diffuse %5.2f%5.2f%5.2f\n\n",
1798            colors[backcolor - 1].red, colors[backcolor - 1].green,
1799            colors[backcolor - 1].blue);
1800    break;
1801
1802  case pov:
1803    penchange = yes;
1804    xunitspercm = 1.0;
1805    yunitspercm = 1.0;
1806    xsize = 10.0;
1807    ysize = 10.0;
1808    rayresx = 512;
1809    rayresy = 512;
1810    treecolor = 6;
1811    namecolor = 4;
1812    backcolor = 1;
1813    bottomcolor = 1;
1814    loopcount = 0;
1815    do {
1816      n=showrayparms(treecolor,namecolor,backcolor,bottomcolor,rayresx,rayresy);
1817      if (n != -1)
1818        getrayparms(&treecolor,&namecolor,&backcolor,&bottomcolor,&rayresx,&rayresy,n);
1819      countup(&loopcount, 10);
1820    } while (n != -1);
1821    xsize = rayresx;
1822    ysize = rayresy;
1823
1824    fprintf(plotfile, "// Declare the colors\n\n");
1825
1826    fprintf(plotfile, "#declare C_Tree        = color rgb<%6.2f, %6.2f, %6.2f>\n",
1827            colors[treecolor-1].red,
1828            colors[treecolor-1].green,
1829            colors[treecolor-1].blue);
1830
1831    fprintf(plotfile, "#declare C_Name        = color rgb<%6.2f, %6.2f, %6.2f>\n\n",
1832            colors[namecolor-1].red,
1833            colors[namecolor-1].green,
1834            colors[namecolor-1].blue);
1835
1836    fprintf(plotfile, "// Declare the textures\n\n");
1837
1838    fprintf(plotfile, "#declare %s = texture { pigment { C_Tree }\n", TREE_TEXTURE);
1839    fprintf(plotfile, "\t\tfinish { phong 1 phong_size 100 }}\n");
1840
1841    fprintf(plotfile, "#declare %s = texture { pigment { C_Name }\n", NAME_TEXTURE);
1842    fprintf(plotfile, "\t\tfinish { phong 1 phong_size 100 }}\n");
1843
1844    fprintf(plotfile, "\n#global_settings { assumed_gamma 2.2 }\n\n");
1845   
1846    fprintf(plotfile, "light_source { <0, %6.2f, %6.2f> color <1,1,1> }\n\n",
1847            xsize * 1.8, xsize * 1.5);
1848
1849    /* The camera location */
1850    fprintf(plotfile, "camera {\n");
1851
1852    if (ysize >= xsize) {
1853      fprintf(plotfile, "\tlocation <%6.2f, %6.2f, %6.2f>\n",
1854              -xsize * 0.5, -xsize * 1.21, ysize * 0.55);
1855    } else {
1856      fprintf(plotfile, "\tlocation <%6.2f, %6.2f, %6.2f>\n",
1857              -xsize * 0.5, -ysize * 1.21, ysize * 0.55);
1858    }
1859     
1860    fprintf(plotfile, "\tlook_at <%6.2f, 0, %6.2f>\n",
1861            -xsize * 0.5, ysize * 0.5);
1862
1863    /* Handily, we can rotate since the rayshade paradigm ain't
1864       exactly congruent to the povray paradigm */
1865    fprintf(plotfile, "\trotate z*180\n");
1866    fprintf(plotfile, "}\n\n");
1867
1868    fprintf(plotfile, "#background { color rgb <%6.2f, %6.2f, %6.2f> }\n\n",
1869            colors[backcolor-1].red,
1870            colors[backcolor-1].green,
1871            colors[backcolor-1].blue);
1872
1873    if (bottomcolor != NO_PLANE) {
1874      /* The user wants a plane on the bottom... */
1875      if (grows == vertical) 
1876        fprintf(plotfile, "plane { z, %2.4f\n", 0.0 /*ymargin*/);
1877      else
1878        fprintf(plotfile, "plane { z, %2.4f\n",
1879                ymargin - ysize / (ntips - 1));
1880     
1881      fprintf(plotfile, "\tpigment {color rgb <%6.2f, %6.2f, %6.2f> }}\n\n",
1882              colors[bottomcolor-1].red,
1883              colors[bottomcolor-1].green,
1884              colors[bottomcolor-1].blue);
1885    }
1886     
1887    break;
1888
1889  case vrml:
1890#ifndef MAC
1891    penchange = yes;
1892    xunitspercm = 1.0;
1893    yunitspercm = 1.0;
1894    xsize = 10.0;
1895    ysize = 10.0;
1896    vrmltreecolor = 6;
1897    vrmlnamecolor = 4;
1898    vrmlskycolornear = 7;
1899    vrmlskycolorfar = 2;
1900    vrmlgroundcolornear = 1;
1901    vrmlgroundcolorfar = 1;
1902    vrmlplotcolor = vrmltreecolor;
1903    loopcount = 0;
1904    do {
1905      n=showvrmlparms(vrmltreecolor, vrmlnamecolor, vrmlskycolornear,
1906                        vrmlskycolorfar, vrmlgroundcolornear);
1907      if (n != -1)
1908        getvrmlparms(&vrmltreecolor, &vrmlnamecolor, &vrmlskycolornear,
1909               &vrmlskycolorfar, &vrmlgroundcolornear, &vrmlgroundcolorfar, n);
1910      countup(&loopcount, 10);
1911    } while (n != -1);
1912    break;
1913#endif
1914  case pict:
1915    strcpy(fontname,"Times");
1916    penchange = yes;
1917    xunitspercm = 28.346456693;
1918    yunitspercm = 28.346456693;
1919    /*7.5 x 10 inch default PICT page size*/
1920    xsize = 19.05;
1921    ysize = 25.40;
1922    break;
1923
1924  case lw:
1925    penchange = yes;
1926    xunitspercm = 28.346456693;
1927    yunitspercm = 28.346456693;
1928    xsize = pagex;
1929    ysize = pagey;
1930    break;
1931
1932  case idraw:
1933    penchange = yes;
1934    xunitspercm = 28.346456693;
1935    yunitspercm = 28.346456693;
1936    xsize = 21.59;
1937    ysize = 27.94;
1938    break;
1939
1940  case hp:
1941    penchange = no;
1942    xunitspercm = 400.0;
1943    yunitspercm = 400.0;
1944    xsize = 24.0;
1945    ysize = 18.0;
1946    break;
1947
1948#ifdef X
1949  case xpreview:
1950    xunitspercm = 39.37;
1951    yunitspercm = 39.37;
1952    xsize = width * 0.0254;
1953    ysize = height * 0.0254;
1954    break;
1955#endif
1956
1957#ifdef WIN32
1958  case winpreview:
1959    penchange = yes;
1960    xunitspercm = 28.346456693;
1961    yunitspercm = 28.346456693;
1962    xsize = winwidth / xunitspercm;
1963    ysize = winheight / yunitspercm;
1964    break;
1965#endif
1966
1967  case tek:
1968    xunitspercm = 50.0;
1969    yunitspercm = 50.0;
1970    xsize = 20.46;
1971    ysize = 15.6;
1972    break;
1973
1974  case ibm:
1975#ifdef TURBOC
1976    GraphDriver = 0;
1977    detectgraph(&GraphDriver,&GraphMode);
1978    getmoderange(GraphDriver,&LoMode,&HiMode);
1979    initgraph(&GraphDriver,&HiMode,"");
1980    xunitspercm = getmaxx()/25;
1981    yunitspercm = getmaxy() / 17.5;
1982    restorecrtmode();
1983    xsize = 25.0;
1984    ysize = 17.5;
1985#endif
1986#ifdef QUICKC
1987    setupgraphics();
1988#endif
1989    break;
1990
1991  case mac:
1992    penchange = yes;
1993    penchange = yes;
1994    xunitspercm = 28.346456693;
1995    yunitspercm = 28.346456693;
1996    xsize = winwidth / xunitspercm;
1997    ysize = winheight / yunitspercm;
1998    break;
1999
2000  case houston:
2001    penchange = yes;
2002    xunitspercm = 100.0;
2003    yunitspercm = 100.0;
2004    xsize = 24.5;
2005    ysize = 17.5;
2006    break;
2007
2008  case decregis:
2009    xunitspercm = 30.0;
2010    yunitspercm = 30.0;
2011    xsize = 25.0;
2012    ysize = 15.0;
2013    break;
2014
2015  case epson:
2016    penchange = yes;
2017    xunitspercm = 47.244;
2018    yunitspercm = 28.346;
2019    xsize = 18.70;
2020    ysize = 22.0;
2021    strpwide = 960;
2022    strpdeep = 8;
2023    strpdiv = 1;
2024    break;
2025
2026  case oki:
2027    penchange = yes;
2028    xunitspercm = 56.692;
2029    yunitspercm = 28.346;
2030    xsize = 19.0;
2031    ysize = 22.0;
2032    strpwide = 1100;
2033    strpdeep = 8;
2034    strpdiv = 1;
2035    break;
2036
2037  case citoh:
2038    penchange = yes;
2039    xunitspercm = 28.346;
2040    yunitspercm = 28.346;
2041    xsize = 22.3;
2042    ysize = 26.0;
2043    strpwide = 640;
2044    strpdeep = 8;
2045    strpdiv = 1;
2046    break;
2047
2048  case toshiba:
2049    penchange = yes;
2050    xunitspercm = 70.866;
2051    yunitspercm = 70.866;
2052    xsize = 19.0;
2053    ysize = 25.0;
2054    strpwide = 1350;
2055    strpdeep = 24;
2056    strpdiv = 4;
2057    break;
2058
2059  case pcl:
2060    penchange = yes;
2061    xsize = 21.59;
2062    ysize = 27.94;
2063    xunitspercm = 118.11023622;   /* 300 DPI = 118.1 DPC                    */
2064    yunitspercm = 118.11023622;
2065    strpwide = 2550;   /* 8.5 * 300 DPI                                     */
2066    strpdeep = DEFAULT_STRIPE_HEIGHT;     /* height of the strip            */
2067    strpdiv = DEFAULT_STRIPE_HEIGHT;      /* in this case == strpdeep       */
2068                       /* this is information for 300 DPI resolution        */
2069    switch (hpresolution) {
2070
2071    case 75:
2072      strpwide    /= 4;
2073      xunitspercm /= 4.0;
2074      yunitspercm /= 4.0;
2075      break;
2076
2077    case 150:
2078      strpwide     /= 2;
2079      xunitspercm /= 2.0;
2080      yunitspercm /= 2.0;
2081      break;
2082
2083    case 300:
2084      break;
2085    }
2086    break;
2087
2088  case bmp:            /* since it's resolution dependent, make 1x1 pixels  */
2089    penchange = yes;   /* per square cm for easier math.                    */
2090    xunitspercm = 1.0;
2091    yunitspercm = 1.0;
2092    xsize = userxsize / xunitspercm; 
2093    ysize = userysize / yunitspercm;
2094    strpdeep = DEFAULT_STRIPE_HEIGHT;
2095    strpdiv = DEFAULT_STRIPE_HEIGHT;
2096    strpwide = (long)(xsize * xunitspercm);
2097    break;
2098
2099  case xbm:            /* since it's resolution dependent, make 1x1 pixels  */
2100    penchange = yes;   /* per square cm for easier math.                    */
2101    xunitspercm = 1.0;
2102    yunitspercm = 1.0;
2103    xsize = userxsize / xunitspercm;
2104    ysize = userysize / yunitspercm;
2105    strpdeep = 10;
2106    strpdiv = 10;
2107    strpwide = (long)(xsize*xunitspercm);
2108    break;
2109
2110  case pcx:
2111    penchange = yes;
2112    xsize = 21.16;
2113    ysize = 15.88;
2114    strpdeep = 10;
2115    strpdiv = 10;
2116    xunitspercm = strpwide / xsize;
2117
2118    switch (resopts) {
2119
2120    case 1:
2121      strpwide = 640;
2122      yunitspercm = 350 / ysize;
2123      break;
2124
2125    case 2:
2126      strpwide = 800;
2127      yunitspercm = 600 / ysize;
2128      break;
2129     
2130    case 3:
2131      strpwide = 1024;
2132      yunitspercm = 768 / ysize;
2133      break;
2134    }
2135    break;
2136
2137  case fig:
2138    penchange = yes;
2139    xunitspercm = 31.011;
2140    yunitspercm = 29.78;
2141    xsize = 25.4;
2142    ysize = 20.32;
2143    break;
2144
2145  case gif:
2146  case other:
2147    break;
2148  default:
2149    break;
2150    /* initial parameter settings for a new plotter go here */
2151  }
2152
2153  if (xsizehold != 0.0 && ysizehold != 0.0) {
2154    xmargin = xmargin * xsize / xsizehold;
2155    ymargin = ymargin * ysize / ysizehold;
2156  }
2157 
2158  if (previewing)
2159    return;
2160}  /* plotrparms */
2161
2162
2163void getplotter()
2164{
2165  long loopcount;
2166  Char ch,input[100];
2167
2168  clearit() ;
2169  printf("\nWhich plotter or printer will the tree be drawn on?\n");
2170  printf("(many other brands or models are compatible with these)\n\n");
2171  printf("   type:       to choose one compatible with:\n\n");
2172  printf("        L         Postscript printer file format\n");
2173  printf("        M         PICT format (for drawing programs)\n");
2174  printf("        J         HP Laserjet PCL file format\n");
2175  printf("        W         MS-Windows Bitmap\n");
2176#ifdef DOS
2177  printf("        I         IBM PC graphics screens\n");
2178#endif
2179  printf("        F         FIG 2.0 drawing program format          \n");
2180  printf("        A         Idraw drawing program format            \n");
2181  printf("        Z         VRML Virtual Reality Markup Language file\n");
2182  printf("        P         PCX file format (for drawing programs)\n");
2183  printf("        K         TeKtronix 4010 graphics terminal\n");
2184  printf("        X         X Bitmap format\n");
2185  printf("        V         POVRAY 3D rendering program file\n");
2186  printf("        R         Rayshade 3D rendering program file\n");
2187  printf("        H         Hewlett-Packard pen plotter (HPGL file format)\n");
2188  printf("        D         DEC ReGIS graphics (VT240 terminal)\n");
2189  printf("        E         Epson MX-80 dot-matrix printer\n");
2190  printf("        C         Prowriter/Imagewriter dot-matrix printer\n");
2191  printf("        T         Toshiba 24-pin dot-matrix printer\n");
2192  printf("        O         Okidata dot-matrix printer\n");
2193  printf("        B         Houston Instruments plotter\n");
2194  printf("        U         other: one you have inserted code for\n");
2195  loopcount = 0;
2196  do {
2197    printf(" Choose one: \n");
2198#ifdef WIN32
2199    phyFillScreenColor();
2200#endif
2201    scanf("%c%*[^\n]", &ch);
2202    getchar();
2203    uppercase(&ch);
2204    countup(&loopcount, 10);
2205  }
2206#ifdef DOS
2207while (strchr("LJKHIDBECOTUAZPXRMFWV",ch) == NULL);   
2208#endif
2209#ifndef DOS
2210while (strchr("LJKHDBECOTAZUPXRMFWV",ch) == NULL);
2211#endif
2212  switch (ch) {
2213
2214  case 'L':
2215    plotter = lw;
2216    strcpy(fontname, "Times-Roman");
2217    break;
2218
2219  case 'A':
2220    plotter = idraw;
2221    strcpy(fontname, "Times-Bold");
2222    break;
2223
2224  case 'M':
2225    plotter = pict;
2226    strcpy(fontname, "Times");
2227    break;
2228
2229  case 'R':
2230    plotter = ray;
2231    strcpy(fontname, "Hershey");
2232    break;
2233
2234  case 'V':
2235    plotter = pov;
2236    strcpy(fontname, "Hershey");
2237    break;
2238
2239  case 'Z':
2240    plotter = vrml;
2241    strcpy(fontname, "Hershey");
2242    break;
2243
2244  case 'J':
2245    plotter = pcl;
2246    strcpy(fontname, "Hershey");
2247    printf("Please select Laserjet resolution\n\n");
2248    printf("1:  75 DPI\n2:  150 DPI\n3:  300 DPI\n\n");
2249    loopcount = 0;
2250    do {
2251#ifdef WIN32
2252      phyFillScreenColor();
2253#endif
2254      getstryng(input);
2255      ch = atoi(input);
2256      countup(&loopcount, 10);
2257    } while (ch != 1 && ch != 2 && ch != 3);
2258    hpresolution = 75*(1<<(ch-1));
2259    /* following pcl init code copied here from plotrparms                  */
2260    xunitspercm = 118.11023622;   /* 300 DPI = 118.1 DPC                    */
2261    yunitspercm = 118.11023622;
2262    strpwide = 2550;   /* 8.5 * 300 DPI                                     */
2263    strpdeep = DEFAULT_STRIPE_HEIGHT;     /* height of the strip            */
2264    strpdiv = DEFAULT_STRIPE_HEIGHT;      /* in this case == strpdeep       */
2265                       /* this is information for 300 DPI resolution        */
2266    switch (hpresolution) {
2267
2268    case 75:
2269      strpwide    /= 4;
2270      xunitspercm /= 4.0;
2271      yunitspercm /= 4.0;
2272      break;
2273
2274    case 150:
2275      strpwide     /= 2;
2276      xunitspercm /= 2.0;
2277      yunitspercm /= 2.0;
2278      break;
2279
2280    case 300:
2281      break;
2282    }
2283
2284    break;
2285
2286  case 'K':
2287    plotter = tek;
2288    strcpy(fontname, "Hershey");
2289    break;
2290
2291  case 'H':
2292    plotter = hp;
2293    strcpy(fontname, "Hershey");
2294    break;
2295
2296  case 'I':
2297    plotter = ibm;
2298    strcpy(fontname, "Hershey");
2299    break;
2300
2301  case 'D':
2302    plotter = decregis;
2303    strcpy(fontname, "Hershey");
2304    break;
2305
2306  case 'B':
2307    plotter = houston;
2308    strcpy(fontname, "Hershey");
2309    break;
2310
2311  case 'E':
2312    plotter = epson;
2313    strcpy(fontname, "Hershey");
2314    break;
2315
2316  case 'C':
2317    plotter = citoh;
2318    strcpy(fontname, "Hershey");
2319    break;
2320
2321  case 'O':
2322    plotter = oki;
2323    strcpy(fontname, "Hershey");
2324    break;
2325
2326  case 'T':
2327    plotter = toshiba;
2328    strcpy(fontname, "Hershey");
2329    break;
2330
2331  case 'P':
2332    plotter = pcx;
2333    strcpy(fontname, "Hershey");
2334    printf("Please select the PCX file resolution\n\n");
2335    printf("1: EGA 640  X 350\n");
2336    printf("2: VGA 800  X 600\n");
2337    printf("3: VGA 1024 X 768\n\n");
2338    loopcount = 0;
2339    do {
2340#ifdef WIN32
2341      phyFillScreenColor();
2342#endif
2343      getstryng(input);
2344      ch = (char)atoi(input);
2345      uppercase(&ch);
2346      countup(&loopcount, 10);
2347    } while (ch != 1 && ch != 2 && ch != 3);
2348    switch (ch) {
2349     
2350    case 1:
2351      strpwide = 640;
2352      yunitspercm = 350 / ysize;
2353      resopts = 1;
2354      break;
2355     
2356    case 2:
2357      strpwide = 800;
2358      yunitspercm = 600 / ysize;
2359      resopts = 2;
2360      break;
2361     
2362    case 3:
2363      strpwide = 1024;
2364      yunitspercm = 768 / ysize;
2365      resopts = 3;
2366      break;
2367    }
2368    break;
2369
2370  case 'W':
2371    plotter = bmp;
2372    strcpy(fontname, "Hershey");
2373    printf("Please select the MS-Windows bitmap file resolution\n");
2374    printf("X resolution?\n");
2375#ifdef WIN32
2376    phyFillScreenColor();
2377#endif
2378    scanf("%lf%*[^\n]", &userxsize);
2379    getchar();
2380    printf("Y resolution?\n");
2381#ifdef WIN32
2382    phyFillScreenColor();
2383#endif
2384    scanf("%lf%*[^\n]", &userysize);
2385    getchar();
2386    xunitspercm = 1.0;
2387    yunitspercm = 1.0;
2388    /* Assuming existing reasonable margin values, set the margins
2389       to be the same as those in the previous output mode/resolution.
2390       This corrects the problem of the tree being hard up against the border
2391       when large resolutions are entered. */
2392    xmargin = userxsize / xsize * xmargin;
2393    ymargin = userysize / ysize * ymargin;
2394
2395    xsize = userxsize;
2396    ysize = userysize;
2397
2398    strpdeep = DEFAULT_STRIPE_HEIGHT;
2399    strpdiv = DEFAULT_STRIPE_HEIGHT;
2400    strpwide = (long)xsize;
2401    break;
2402
2403  case 'X':
2404    plotter = xbm;
2405    strcpy(fontname, "Hershey");
2406    printf("Please select the X-bitmap file resolution\n");
2407    printf("X resolution?\n");
2408#ifdef WIN32
2409    phyFillScreenColor();
2410#endif
2411    scanf("%lf%*[^\n]", &userxsize);
2412    getchar();
2413    printf("Y resolution?\n");
2414#ifdef WIN32
2415    phyFillScreenColor();
2416#endif
2417    scanf("%lf%*[^\n]", &userysize);
2418    getchar();
2419    xunitspercm = 1.0;
2420    yunitspercm = 1.0;
2421    /* Assuming existing reasonable margin values, set the margins
2422       to be the same as those in the previous output mode/resolution.
2423       This corrects the problem of the tree being hard up against the border
2424       when large resolutions are entered. */
2425    xmargin = userxsize / xsize * xmargin;
2426    ymargin = userysize / ysize * ymargin;
2427
2428    xsize = userxsize;
2429    ysize = userysize;
2430    strpdeep = DEFAULT_STRIPE_HEIGHT;
2431    strpdiv = DEFAULT_STRIPE_HEIGHT;
2432    strpwide = (long)xsize;
2433    break;
2434
2435  case 'F':
2436    plotter = fig;
2437    strcpy(fontname, "Times-Roman");
2438    break;
2439
2440  case 'U':
2441    plotter = other;
2442    break;
2443  }
2444  dotmatrix = (plotter == epson || plotter == oki || plotter == citoh ||
2445               plotter == toshiba || plotter == pcx || plotter == pcl ||
2446               plotter == xbm || plotter == bmp);
2447}  /* getplotter */
2448
2449
2450void changepen(pentype pen)
2451{
2452  Char picthi, pictlo;
2453  long  pictint;
2454  lastpen = pen;
2455
2456 switch (pen) {
2457
2458  case treepen:
2459    linewidth = treeline;
2460    if (plotter == hp)
2461      fprintf(plotfile, "SP1;\n");
2462    if (plotter == lw) {
2463      fprintf(plotfile, "stroke %8.2f setlinewidth \n", treeline);
2464      fprintf(plotfile, " 1 setlinecap 1 setlinejoin \n");
2465    }
2466#ifdef WIN32
2467    if (plotter == winpreview)
2468      SelectObject(hdc, hPenTree); 
2469#endif
2470    break;
2471
2472  case labelpen:
2473    linewidth = labelline;
2474    if (plotter == hp)
2475      fprintf(plotfile, "SP2;\n");
2476    if (plotter == lw) {
2477      fprintf(plotfile, " stroke%8.2f setlinewidth \n", labelline);
2478      fprintf(plotfile, "1 setlinecap 1 setlinejoin \n");
2479    }
2480#ifdef WIN32
2481    if (plotter == winpreview)
2482      SelectObject(hdc, hPenLabel); 
2483#endif
2484    break;
2485  }
2486#ifdef MAC
2487if (plotter == mac){
2488      pictint = ( long)(linewidth + 0.5);
2489      if (pictint ==0)
2490           pictint = 1;
2491}
2492#endif
2493
2494  if (plotter != pict)
2495    return;
2496  pictint = ( long)(linewidth + 0.5);
2497  if (pictint == 0)
2498    pictint = 1;
2499  picthi = (Char)(pictint / 256);
2500  pictlo = (Char)(pictint & 255);
2501  fprintf(plotfile, "\007%c%c%c%c", picthi, pictlo, picthi, pictlo);
2502  bytewrite += 5;
2503}  /* changepen */
2504
2505
2506int readafmfile(char *filename, short *metric)
2507{
2508char line[256], word1[100], word2[100];
2509int scanned, nmetrics=0, inmetrics, charnum, charlen, i, capheight=0;
2510FILE *fp;
2511
2512fp = fopen(filename,"r");
2513if (!fp)
2514  return 0;
2515inmetrics = 0;
2516
2517for (i=0;i<256;metric[i++]=(short)0);
2518
2519for (;;){
2520  scanned = fscanf(fp,"%[^\n]\n",line);
2521  if (scanned != 1 )
2522    break;
2523  scanned=sscanf(line,"%s %s",word1,word2);
2524  if (scanned == 2 && strcmp(word1,"CapHeight") == 0)
2525    capheight = atoi(word2);
2526
2527  if (inmetrics){
2528    sscanf(line,"%*s %s %*s %*s %s",word1,word2);
2529    charnum = atoi(word1);
2530    charlen = atoi(word2);
2531    nmetrics--;
2532    if (nmetrics == 0)
2533      break;
2534
2535    if (charnum != -1 && charnum >= 32)
2536      metric[charnum-31] = charlen;
2537  }
2538  else
2539    if (scanned == 2 && strcmp(word1,"StartCharMetrics") == 0)
2540      nmetrics = atoi(word2),
2541      inmetrics = 1;
2542
2543  if ((strcmp(word1,"EndCharMetrics") == 0) || (feof(fp)))
2544    break;
2545}
2546FClose(fp);
2547metric[0] = capheight;
2548return 1;
2549}  /* readafmfile */
2550
2551
2552void metricforfont(char *fontname, short *fontmetric)
2553{
2554  int i;
2555  long loopcount;
2556  char afmfile[FNMLNGTH];
2557 
2558  if ((strcmp(fontname,"Helvetica") == 0) ||
2559      (strcmp(fontname,"Helvetica-Oblique") == 0))
2560    for (i=31;i<256;++i)
2561      fontmetric[i-31] = helvetica_metric[i-31];
2562  else if ((strcmp(fontname,"Helvetica-Bold") == 0) ||
2563      (strcmp(fontname,"Helvetica-BoldOblique") == 0))
2564    for (i=31;i<256;++i)
2565      fontmetric[i-31] = helveticabold_metric[i-31];
2566  else if (strcmp(fontname,"Times-Roman") == 0)
2567    for (i=31;i<256;++i)
2568      fontmetric[i-31] = timesroman_metric[i-31];
2569  else if (strcmp(fontname,"Times") == 0)
2570    for (i=31;i<256;++i)
2571      fontmetric[i-31] = timesroman_metric[i-31];
2572  else if (strcmp(fontname,"Times-Italic") == 0)
2573    for (i=31;i<256;++i)
2574      fontmetric[i-31] = timesitalic_metric[i-31];
2575  else if (strcmp(fontname,"Times-Bold") == 0)
2576    for (i=31;i<256;++i)
2577      fontmetric[i-31] = timesbold_metric[i-31];
2578  else if (strcmp(fontname,"Times-BoldItalic") == 0)
2579    for (i=31;i<256;++i)
2580      fontmetric[i-31] = timesbolditalic_metric[i-31];
2581 
2582  else if (strncmp(fontname,"Courier",7) == 0){
2583    fontmetric[0] = 562; 
2584    for (i=32;i<256;++i)
2585      fontmetric[i-31] = (short)600;
2586  }
2587  else {
2588    if (didloadmetric){
2589      for (i=31;i<256;++i)
2590        fontmetric[i-31] = unknown_metric[i-31];}
2591    else {
2592      didloadmetric = 1;
2593      sprintf(afmfile,"%s.afm",fontname);    /* search current dir */
2594      if (readafmfile(afmfile,unknown_metric)){
2595        for (i=31;i<256;++i)
2596          fontmetric[i-31] = unknown_metric[i-31];
2597        return;}
2598      sprintf(afmfile,"%s%s.afm",AFMDIR,fontname); /* search afm dir */
2599      if (readafmfile(afmfile,unknown_metric)){
2600      for (i=31;i<256;++i)
2601        fontmetric[i-31] = unknown_metric[i-31];
2602      return;}
2603#ifdef NeXT
2604      sprintf(afmfile,"%s/Library/Fonts/%s.font/%s.afm",getenv("HOME"),
2605              fontname,fontname);
2606      if (readafmfile(afmfile,unknown_metric)){
2607      for (i=31;i<256;++i)
2608        fontmetric[i-31] = unknown_metric[i-31];
2609      return;}
2610      sprintf(afmfile,"/LocalLibrary/Fonts/%s.font/%s.afm",fontname,fontname);
2611      if (readafmfile(afmfile,unknown_metric)){
2612      for (i=31;i<256;++i)
2613        fontmetric[i-31] = unknown_metric[i-31];
2614      return;}
2615#endif
2616      loopcount = 0;
2617      for (;;){
2618        printf("Enter the path of the %s.afm file, or \"none\" for best guess:",
2619                fontname);
2620        getstryng(afmfile);
2621        if (strcmp(afmfile,"none") == 0){
2622          for (i=31;i<256;++i)
2623            fontmetric[i-31] = timesroman_metric[i-31],
2624            unknown_metric[i-31] = timesroman_metric[i-31],
2625            didloadmetric =1;
2626          return;
2627        }
2628        else {
2629          if (readafmfile(afmfile,unknown_metric)){
2630            for (i=31;i<256;++i)
2631              fontmetric[i-31] = unknown_metric[i-31];
2632            return;}
2633          else
2634            printf("Can't read that file. Please re-enter.\n");
2635        }
2636        countup(&loopcount, 10);
2637      }
2638    }
2639  }
2640}  /* metricforfont */
2641
2642
2643double heighttext(fonttype font, char *fontname)
2644{
2645  short          afmetric[256];
2646#ifdef MAC
2647  FontInfo       info;
2648#endif
2649
2650  if (strcmp(fontname,"Hershey") == 0)
2651    return (double)font[2];
2652#ifdef MAC
2653  else if (((plotter == pict || plotter == mac)  &&
2654            (((grows == vertical && labelrotation == 0.0) ||
2655             (grows == horizontal && labelrotation == 90.0))))){
2656    TextFont(macfontid(fontname)); 
2657    TextSize((int)(1000));
2658    TextFace((int)((pictbold ? 1: 0) | (pictitalic ? 2 : 0)|
2659        (pictoutline ? 8 : 0)|(pictshadow ? 16 : 0)));
2660    GetFontInfo(&info);   
2661    TextFont(macfontid("courier"));
2662    TextSize(10);
2663    TextFace(0);
2664    return (double)info.ascent;
2665       }
2666#endif
2667  else if (strcmp(fontname,"Hershey") == 0)
2668    return (double)font[2];
2669  else{
2670      metricforfont(fontname,afmetric); 
2671      return (double)afmetric[0];}
2672}  /* heighttext */
2673
2674
2675double lengthtext(char *pstring, long nchars, char *fontname,
2676                        fonttype font)
2677{  /* lengthext */
2678  long i, j, code;
2679  static double  sumlength;
2680  long                  sumbigunits;
2681  short          afmetric[256];
2682
2683  sumlength = 0.0;
2684  if (strcmp(fontname,"Hershey") == 0) {
2685    for (i = 0; i < nchars; i++) {
2686      code = pstring[i];
2687      j = 1;
2688      while (font[j] != code && font[j - 1] != 0)
2689        j = font[j - 1];
2690      if (font[j] == code)
2691        sumlength += font[j + 2];
2692    }
2693    return sumlength;
2694  }
2695#ifdef MAC
2696  else   if  (((plotter == pict || plotter == mac) && 
2697          (((grows == vertical && labelrotation == 0.0) ||
2698          (grows == horizontal && labelrotation == 90.0))))){
2699  TextFont(macfontid(fontname)); 
2700  TextSize((int)(1000));
2701  TextFace((int)((pictbold ? 1: 0) | (pictitalic ? 2 : 0)|
2702      (pictoutline ? 8 : 0)|(pictshadow ? 16 : 0)));
2703   sumbigunits = 0;
2704    for (i = 0; i < nchars; i++) 
2705      sumbigunits += (long)CharWidth(pstring[i]);
2706      TextFace(0);
2707      TextSize(10);
2708      TextFont(macfontid("courier"));
2709      return (double)sumbigunits;
2710          }
2711#endif
2712      else {
2713       metricforfont(fontname,afmetric);
2714       sumbigunits = 0;
2715       for (i = 0; i < nchars; i++) 
2716         sumbigunits += afmetric[(int)(1+(unsigned char)pstring[i] - 32)];
2717   
2718       sumlength = (double)sumbigunits;
2719          }
2720      return sumlength;
2721}  /* lengthtext */
2722
2723
2724void plotchar(long *place, struct LOC_plottext *text)
2725{
2726  text->heightfont = text->font[*place + 1];
2727  text->yfactor = text->height / text->heightfont;
2728  text->xfactor = text->yfactor;
2729  *place += 3;
2730  do {
2731    (*place)++;
2732    text->coord = text->font[*place - 1];
2733    if (text->coord > 0)
2734      text->penstatus = pendown;
2735    else
2736      text->penstatus = penup;
2737    text->coord = abs(text->coord);
2738    text->coord %= 10000;
2739    text->xfont = (text->coord / 100 - xstart) * text->xfactor;
2740    text->yfont = (text->coord % 100 - ystart) * text->yfactor;
2741    text->xplot = text->xx + (text->xfont * text->cosslope +
2742                              text->yfont * text->sinslope) * text->compress;
2743    text->yplot = text->yy - text->xfont * text->sinslope +
2744      text->yfont * text->cosslope;
2745    plot(text->penstatus, text->xplot, text->yplot);
2746  } while (abs(text->font[*place - 1]) < 10000);
2747  text->xx = text->xplot;
2748  text->yy = text->yplot;
2749}  /* plotchar */
2750
2751
2752void swap_charptr(char **one, char **two)
2753{
2754  char *tmp = (*one);
2755  (*one)= (*two);
2756  (*two) = tmp;
2757}  /* swap */
2758
2759
2760void plotpb()
2761{
2762  pagecount++;
2763  fprintf(plotfile,"\n showpage \n%%%%PageTrailer\n");
2764  fprintf(plotfile,"%%%%DocumentFonts: %s\n",
2765              (strcmp(fontname,"Hershey") == 0) ? "" : fontname);
2766  fprintf(plotfile,"%%%%\n%%%%Page: %ld %ld\n",pagecount,pagecount);
2767  fprintf(plotfile,"%%%%PageBoundingBox: 0 0 %d %d\n",
2768          (int)(xunitspercm*paperx),(int)(yunitspercm*papery));
2769  fprintf(plotfile,"%%%%PageFonts: (atend)\n%%%%BeginPageSetup\n%%%%PaperSize: Letter\n");
2770  fprintf(plotfile,"0 0 moveto\n"); /* hack to make changepen work w/o errors */
2771  changepen(lastpen);
2772}  /* plotpb */
2773
2774
2775void drawit(char *fontname, double *xoffset, double *yoffset,
2776                        long numlines, node *root)
2777{
2778  long i, j, line, xpag, ypag;
2779
2780  long test_long ;  /* To get a division out of a loop */
2781
2782  (*xoffset) = 0.0;
2783  (*yoffset) = 0.0;
2784
2785  xpag = (int)((pagex-hpmargin-0.01)/(paperx - hpmargin))+1;
2786  ypag = (int)((pagey-vpmargin-0.01)/(papery - vpmargin))+1;
2787  if (dotmatrix){
2788    strptop    = (long)(ysize * yunitspercm);
2789    strpbottom = numlines*strpdeep + 1;
2790  }
2791  else {
2792    pagecount = 1;
2793    for (j=0; j<ypag; ++j)
2794      for (i=0; i<xpag; ++i){
2795        clipx0 = (double)i*(paperx -  hpmargin);
2796        clipx1 = (double)(i*(paperx -  hpmargin))+(paperx - hpmargin);
2797        clipy0 = (double)(j*(papery -  vpmargin));
2798        clipy1 = (double)(j*(papery-hpmargin))+(papery+vpmargin);
2799        plottree(root,root);
2800        plotlabels(fontname);
2801        if (!(i == xpag - 1 && j == ypag - 1))
2802          plotpb(); /* page break */
2803      }
2804  }
2805
2806  if (dotmatrix){
2807    striprint(( long)((ysize * yunitspercm)- (numlines * strpdeep)),
2808              ( long)((ysize * yunitspercm)- (numlines * strpdeep)));
2809    strptop = numlines * strpdeep;
2810    strpbottom = strptop - strpdeep + 1;
2811    printf(" writing %3ld lines ...\n", numlines);
2812    printf("  Line     Output file size\n");
2813    printf("  ----     ------ ---- ----\n");
2814#ifdef WIN32
2815    phyFillScreenColor();
2816#endif
2817    test_long = strpwide / 8 ;        /* A fix for below */
2818
2819    for (line = 1; line <= numlines ; line++) {
2820      for (i = 0; i <= strpdeep ; i++) {
2821        for (j=0; j<=test_long;++j)   /* Don't do a divide every time! */
2822          stripe[i][j] = 0;
2823      }
2824      empty = true;
2825      xnow = strpwide / 2.0;
2826      ynow = 0.0;
2827      plottree(root, root);
2828      plotlabels(fontname);
2829      strptop     = strpbottom - 1;
2830      strpbottom -= strpdeep;
2831
2832      if (strpdeep > DEFAULT_STRIPE_HEIGHT){
2833        /* large stripe, do in DEFAULT_STRIPE_HEIGHT (20)-line     */
2834        for (i=0;i<strpdeep;++i){
2835          swap_charptr(&stripe[i%DEFAULT_STRIPE_HEIGHT],
2836               &stripe[i]);
2837          if ((i%DEFAULT_STRIPE_HEIGHT) ==
2838              (DEFAULT_STRIPE_HEIGHT -1)){
2839            striprint(DEFAULT_STRIPE_HEIGHT,
2840                      DEFAULT_STRIPE_HEIGHT);}
2841        }
2842        striprint(strpdeep%DEFAULT_STRIPE_HEIGHT,
2843                  strpdeep%DEFAULT_STRIPE_HEIGHT);
2844      }
2845      else{                          /* small stripe, do it all now.     */
2846        striprint(strpdiv,strpdeep);
2847        if (line % 5 == 0)
2848          printf("%5ld%16ld\n", line, filesize);
2849#ifdef WIN32
2850          phyFillScreenColor();
2851#endif
2852
2853      }
2854    }
2855  }
2856}  /* drawit */
2857
2858
2859char *findXfont(char *fontname, double pointsize, double *scale,
2860                        int *epointsize)
2861{
2862  static char returnval[64];
2863
2864  if (strcmp(fontname,"Helvetica") == 0)
2865    strcpy(returnval,"*-helvetica-medium-r-*-120-75-75-*"),
2866    (*scale) = pointsize / 12.0,
2867    (*epointsize) = 12;
2868  else if (strcmp(fontname,"Helvetica-Oblique") == 0)
2869    strcpy(returnval,"*-helvetica-medium-o-*-140-75-75-*"),
2870    (*scale) = pointsize / 14.0,
2871    (*epointsize) = 14;
2872  else if (strcmp(fontname,"Helvetica-Bold") == 0)
2873    strcpy(returnval,"*-helvetica-bold-r-*-140-75-75-*"),
2874    (*scale) = pointsize / 14.0,
2875    (*epointsize) = 14;
2876  else if (strcmp(fontname,"Helvetica-BoldOblique") == 0)
2877    strcpy(returnval,"*-helvetica-medium-o-*-140-75-75-*"),
2878    (*scale) = pointsize / 14.0,
2879    (*epointsize) = 14;
2880  else if (strcmp(fontname,"Times-Roman") == 0)
2881    strcpy(returnval,"*-times-medium-r-*-140-75-75-*"),
2882    (*scale) = pointsize / 14.0,
2883    (*epointsize) = 14;
2884  else if (strcmp(fontname,"Times-Italic") == 0)
2885    strcpy(returnval,"*-times-medium-i-*-140-75-75-*"),
2886    (*scale) = pointsize / 14.0,
2887    (*epointsize) = 14;
2888  else if (strcmp(fontname,"Times-Bold") == 0)
2889    strcpy(returnval,"*-times-medium-i-*-140-75-75-*"),
2890    (*scale) = pointsize / 14.0,
2891    (*epointsize) = 14;
2892  else if (strcmp(fontname,"Times-BoldItalic") == 0)
2893    strcpy(returnval,"*-times-medium-i-*-140-75-75-*"),
2894    (*scale) = pointsize / 14.0,
2895    (*epointsize) = 14;
2896  else if (strcmp(fontname,"Courier") == 0)
2897    sprintf(returnval,"*-courier-medium-r-*-100-75-75-*"),
2898    (*scale) = pointsize / 12.0,
2899    (*epointsize) = 12;
2900  else if (strcmp(fontname,"Courier-Italic") == 0)
2901    strcpy(returnval,"*-courier-medium-r-*-120-75-75-*"),
2902    (*scale) = pointsize / 12.0,
2903    (*epointsize) = 12;
2904  else if (strcmp(fontname,"Courier-Bold") == 0)
2905    strcpy(returnval,"*-courier-bold-r-*-120-75-75-*"),
2906    (*scale) = pointsize / 12.0,
2907    (*epointsize) = 12;
2908  else if (strcmp(fontname,"Courier-BoldItalic") == 0)
2909    strcpy(returnval,"*-courier-bold-r-*-120-75-75-*"),
2910    (*scale) = pointsize / 12.0,
2911    (*epointsize) = 12;
2912  else
2913    sprintf(returnval,"*-times-medium-r-*-120-75-75-*"),
2914    (*scale) = pointsize / 12.0,
2915    (*epointsize) = 12;
2916  return returnval;
2917}  /* findXfont */
2918
2919
2920int macfontid(char *fontname)
2921{
2922char fontnam[256];
2923int  i;
2924
2925  strcpy(fontnam,fontname);
2926  for (i=0;i<strlen(fontnam);++i)
2927    fontnam[i] = toupper(fontnam[i]);
2928  if (strcmp(fontnam,"NEW YORK") == 0)
2929    return 2;
2930  else if (strcmp(fontnam,"GENEVA") == 0)
2931    return 3;
2932  else if (strcmp(fontnam,"MONACO") == 0)
2933    return 4;
2934  else if (strcmp(fontnam,"VENICE") == 0)
2935    return 5;
2936  else if (strcmp(fontnam,"LONDON") == 0)
2937    return 6; 
2938  else if (strcmp(fontnam,"ATHENS") == 0)
2939    return 7;   
2940  else if (strcmp(fontnam,"SAN FRANCISCO") == 0)
2941    return 8; 
2942  else if (strcmp(fontnam,"TORONTO") == 0)
2943    return 9; 
2944  else if (strcmp(fontnam,"CAIRO") == 0)
2945    return 11; 
2946  else if (strcmp(fontnam,"LOS ANGELES") == 0)
2947    return 12; 
2948  else if (strcmp(fontnam,"TIMES") == 0)
2949    return 20; 
2950  else if (strcmp(fontnam,"TIMES-ROMAN") == 0)
2951    return 20; 
2952  else if (strcmp(fontnam,"HELVETICA") == 0)
2953    return 21;   
2954  else if (strcmp(fontnam,"COURIER") == 0)
2955    return 22;   
2956  else if (strcmp(fontnam,"SYMBOL") == 0)
2957    return 23; 
2958  else if (strcmp(fontnam,"TALIESIN") == 0)
2959    return 24;   
2960  else
2961    return 0; 
2962 }  /* macfontid */
2963
2964
2965void plottext(Char *pstring,long nchars,double height_,double cmpress2,
2966                        double x,double y,double slope,short *font_,char *fontname)
2967{
2968#ifdef max
2969#undef max
2970#endif
2971#define max(a,b) ((a > b) ? a : b)
2972#ifdef min
2973#undef min
2974#endif
2975#define min(a,b) ((a > b) ? b : a)
2976#define max4(a,b,c,d) (max(max(a,b),max(c,d)))
2977#define min4(a,b,c,d) (min(min(a,b),min(c,d)))
2978  struct LOC_plottext text;
2979  long i, j, code;
2980  double pointsize;
2981  int    epointsize;   /* effective pointsize before scale in idraw matrix */
2982  double iscale;
2983  double textlen;
2984  double px0,py0,px1,py1; /* square bounding box of text */
2985 
2986  text.heightfont = font_[2];
2987  pointsize = (((height_ / xunitspercm) / 2.54) * 72.0);
2988 
2989  if (strcmp(fontname,"Hershey") !=0)
2990        pointsize *= ((double)1000.0 / heighttext(font_,fontname));
2991
2992  text.height = height_;
2993  text.compress = cmpress2;
2994  text.font = font_;
2995  text.xx = x;
2996  text.yy = y;
2997  text.sinslope = sin(pi * slope / 180.0);
2998  text.cosslope = cos(pi * slope / 180.0);
2999
3000  if ((strcmp(fontname,"Hershey") == 0)||
3001      (previewing && (!(((plotter == pict) || (plotter == mac))
3002                        && (((grows == vertical) && (labelrotation == 0.0)) ||
3003                            ((grows == horizontal) && (labelrotation == 90.0))
3004                            ))))){
3005    for (i = 0; i < nchars; i++) {
3006      code = pstring[i];
3007      j = 1;
3008      while (text.font[j] != code && text.font[j - 1] != 0)
3009        j = text.font[j - 1];
3010      plotchar(&j,  &text);
3011    }
3012  }
3013 /* print native font.  idraw, PS, pict, and fig. */
3014
3015  else if (plotter == fig) {
3016    fprintf(plotfile,"4 0 %d %d 0 -1 0 %1.5f 4 19 163 %d %d %s\001\n",
3017            figfontid(fontname), /* font ID    */
3018            (int)pointsize,      /* font size  */
3019            (double)0.0,         /* font rotation */
3020            (int)x,              /* x position    */
3021            (int)(606.0 - y),    /* y position    */
3022            pstring);
3023  }
3024  else if (plotter == lw)  {
3025    /* If there's NO possibility that the line intersects the square bounding
3026     * box of the font, leave it out. Otherwise, let postscript clip to region.
3027     * Compute text boundary, be REAL generous. */
3028    textlen = (lengthtext(pstring,nchars,fontname,font_)/1000)*pointsize;
3029    px0 = min4(x + (text.cosslope * pointsize),
3030               x - (text.cosslope * pointsize),
3031               x + (text.cosslope * pointsize) + (text.sinslope * textlen),
3032               x - (text.cosslope * pointsize) + (text.sinslope * textlen))
3033      /28.346;
3034    px1 = max4(x + (text.cosslope * pointsize),
3035               x - (text.cosslope * pointsize),
3036               x + (text.cosslope * pointsize) + (text.sinslope * textlen),
3037               x - (text.cosslope * pointsize) + (text.sinslope * textlen))
3038      /28.346;
3039    py0 = min4(y + (text.sinslope * pointsize),
3040               y - (text.sinslope * pointsize),
3041               y + (text.sinslope * pointsize) + (text.cosslope * textlen),
3042               y - (text.sinslope * pointsize) + (text.cosslope * textlen))
3043      /28.346;
3044    py1 = max4(y + (text.sinslope * pointsize),
3045               y - (text.sinslope * pointsize),
3046               y + (text.sinslope * pointsize) + (text.cosslope * textlen),
3047               y - (text.sinslope * pointsize) + (text.cosslope * textlen))
3048      /28.346;
3049
3050    /* if rectangles intersect, print it. */
3051    if (rectintersects(px0,py0,px1,py1,clipx0,clipy0,clipx1,clipy1)) {
3052      fprintf(plotfile,"gsave\n");
3053      fprintf(plotfile,"/%s findfont %f scalefont setfont\n",fontname,
3054              pointsize);
3055      fprintf(plotfile,"%f %f translate %f rotate\n",
3056                x-(clipx0*xunitspercm),y-(clipy0*xunitspercm),-slope);
3057      fprintf(plotfile,"0 0 moveto\n");
3058      fprintf(plotfile,"(%s) show\n",pstring);
3059      fprintf(plotfile,"grestore\n");
3060    }
3061  }
3062else if (plotter == idraw) {
3063   iscale = pointsize / 12.0;
3064   y += text.height * text.cosslope;
3065   x += text.height * text.sinslope;
3066        fprintf(plotfile, "Begin %%I Text\n");
3067   fprintf(plotfile, "%%I cfg Black\n");
3068   fprintf(plotfile, "0 0 0 SetCFg\n");
3069   fprintf(plotfile, "%%I f %s\n",
3070             findXfont(fontname,pointsize,&iscale,&epointsize));
3071   fprintf(plotfile,"%s %d SetF\n",fontname,epointsize);
3072   fprintf(plotfile, "%%I t\n");
3073   fprintf(plotfile, "[ %f %f %f %f %f %f ] concat\n",
3074           text.cosslope*iscale, -text.sinslope*iscale,
3075           text.sinslope*iscale, text.cosslope*iscale,
3076           x+216.0 ,y+285.0);
3077   fprintf(plotfile, "%%I\n");
3078   fprintf(plotfile, "[\n(%s)\n] Text\nEnd\n\n",pstring); 
3079   
3080 }
3081else if (plotter == pict || plotter == mac) {
3082   if (previewing){
3083#ifdef MAC
3084   TextFont(macfontid(fontname)); 
3085   TextSize((int)(pointsize+0.5));
3086   TextFace((int)((pictbold ? 1: 0) | (pictitalic ? 2 : 0)|
3087      (pictoutline ? 8 : 0)|(pictshadow ? 16 : 0)));
3088      MoveTo((int)floor((double)x + 0.5),
3089              winheight - (long)floor((double)y + 0.5)+MAC_OFFSET); 
3090      putstring(pstring);
3091    TextFont(macfontid("courier"));
3092    TextSize(10);
3093    TextFace(0);
3094#endif
3095   }
3096   else {
3097   /* txfont: */
3098    fprintf(plotfile,"%c",(unsigned char)3);
3099    pictoutint(plotfile,macfontid(fontname));
3100    /* txsize: */
3101    fprintf(plotfile,"%c",13);
3102    pictoutint(plotfile,(int)(pointsize+0.5));
3103    /* txface: */
3104    fprintf(plotfile,"%c%c",4,
3105      (int)((pictbold ? 1: 0) | (pictitalic ? 2 : 0)|
3106      (pictoutline ? 8 : 0)|(pictshadow ? 16 : 0)));
3107    /* txfloc: */   
3108    fprintf(plotfile,"%c",40);
3109    pictoutint(plotfile,(int)floor(ysize * yunitspercm - y + 0.5));
3110    pictoutint(plotfile,(int)(x+0.5));
3111    fprintf(plotfile,"%c%s",(char)strlen(pstring),pstring);
3112    bytewrite+=(14+strlen(pstring)); 
3113   }
3114 }
3115}  /* plottext */
3116
3117
3118void makebox(char *fn,double *xo,double *yo,double *scale,long ntips)
3119/* fn--fontname| xo,yo--x and y offsets */
3120{
3121  /* draw the box on screen which represents plotting area.        */
3122  char ch;
3123  long xpag,ypag,i,j;
3124  double xpagecorrection, ypagecorrection;
3125
3126  if (previewer != winpreview && previewer != mac && previewer != xpreview) {
3127    printf("\nWe now will preview the tree.  The box that will be\n");
3128    printf("plotted on the screen represents the boundary of the\n");
3129    printf("final plotting surface.  To see the preview, press on\n");
3130    printf("the ENTER or RETURN key (you may need to do it twice).\n");
3131    printf("When finished viewing it, press on that key again.\n");
3132  }
3133  oldpenchange   = penchange;
3134  oldxsize       = xsize;
3135  oldysize       = ysize;
3136  oldxunitspercm = xunitspercm;
3137  oldyunitspercm = yunitspercm;
3138  oldxcorner     = xcorner;
3139  oldycorner     = ycorner;
3140  oldxmargin     = xmargin;
3141  oldymargin     = ymargin;
3142  oldhpmargin    = hpmargin;
3143  oldvpmargin    = vpmargin;
3144  oldplotter     = plotter;
3145  plotter        = previewer;
3146  if (previewer != winpreview && previewer != mac && previewer != xpreview) {
3147#ifdef WIN32
3148    phyFillScreenColor();
3149#endif
3150    scanf("%c%*[^\n]", &ch);
3151    (void)getchar();
3152    if (ch == '\n')
3153      ch = ' ';
3154  }
3155  plotrparms(ntips);
3156  initplotter(ntips,fn);
3157  xcorner += 0.05 * xsize;
3158  ycorner += 0.05 * ysize;
3159  xsize *= 0.9;
3160  ysize *= 0.9;
3161  (*scale) = ysize / oldysize;
3162  if (xsize / oldxsize < (*scale))
3163    (*scale) = xsize / oldxsize;
3164  xpagecorrection = oldxsize / pagex;
3165  ypagecorrection = oldysize / pagey;
3166  (*xo) = (xcorner + (xsize - oldxsize * (*scale)) / 2.0) / (*scale);
3167  (*yo) = (ycorner   + (ysize - oldysize * (*scale)) / 2.0) / (*scale);
3168
3169  xscale = (*scale) * xunitspercm;
3170  yscale = (*scale) * yunitspercm;
3171  xmargin *= (*scale);
3172  ymargin *= (*scale);
3173  hpmargin *= (*scale);
3174  vpmargin *= (*scale);
3175  xpag = (int)((pagex-hpmargin-0.01)/(paperx - hpmargin))+1;
3176  ypag = (int)((pagey-vpmargin-0.01)/(papery - vpmargin))+1;
3177  /* draw the outer borders */
3178
3179  plot(penup, xscale * (*xo), yscale * (*yo));
3180  plot(pendown, xscale * (*xo), yscale * ((*yo) + pagey * ypagecorrection));
3181  plot(pendown, xscale * ((*xo) + pagex * xpagecorrection), 
3182    yscale * ((*yo) + pagey * ypagecorrection));
3183  plot(pendown, xscale * ((*xo) + pagex * xpagecorrection), yscale * (*yo));
3184  plot(pendown, xscale * (*xo), yscale * (*yo));
3185  /* we've done the extent, now draw the dividing lines: */
3186  for (i=0; i<xpag; ++i){
3187      plot(penup,(xscale * (*xo))+xscale*i*(paperx - hpmargin)*xpagecorrection,
3188                  ((*yo)*yscale));
3189      plot(pendown,(xscale * (*xo))+xscale*i*(paperx - hpmargin)*xpagecorrection,
3190                  ((*yo)*yscale)+yscale*pagey*ypagecorrection);
3191      if (i != 0) {
3192        plot(penup,(xscale * (*xo))
3193             +xscale*i*(paperx - hpmargin)*xpagecorrection+xscale*hpmargin,((*yo)*yscale));
3194        plot(pendown,(xscale * (*xo))
3195             +xscale*i*(paperx - hpmargin)*xpagecorrection+xscale*hpmargin,
3196             ((*yo)*yscale)+yscale*pagey*ypagecorrection);
3197      }
3198  }
3199  for (j=0;j<ypag;++j){
3200      plot(penup,(xscale * (*xo)),
3201           ((*yo)*yscale)+yscale*j*(papery-vpmargin)*ypagecorrection);
3202      plot(pendown,(xscale * (*xo))+xscale*pagex*xpagecorrection,
3203           ((*yo)*yscale)+yscale*j*(papery-hpmargin)*ypagecorrection);
3204      if (j != 0) {
3205        plot(penup,(xscale * (*xo)),
3206             ((*yo)*yscale)+yscale*j*(papery-vpmargin)*ypagecorrection+yscale*vpmargin);
3207        plot(pendown,(xscale * (*xo))+xscale*pagex*xpagecorrection,
3208             ((*yo)*yscale)+yscale*j*(papery-hpmargin)*ypagecorrection+yscale*vpmargin);
3209      }
3210  }
3211}  /* makebox */
3212
3213
3214boolean plotpreview(char *fn, double *xo, double *yo, double *scale,
3215                        long nt, node *root)
3216{
3217  long loopcount;
3218  boolean canbeplotted;
3219  Char ch;
3220
3221  previewing = true;
3222#ifdef WIN32
3223  if (previewer == winpreview) {
3224    winpreviewparms.fn    = fn;
3225    winpreviewparms.xo    = xo;
3226    winpreviewparms.yo    = yo;
3227    winpreviewparms.scale = scale;
3228    winpreviewparms.nt    = nt;
3229    winpreviewparms.root  = root;
3230    winplotpreview();
3231  }
3232  else {
3233    makebox(fn,xo,yo,scale,nt);
3234    plottree(root, root);
3235    plotlabels(fn);
3236    finishplotter();
3237  }
3238#endif
3239#ifdef MAC
3240  if (previewer == mac ){
3241        macpreviewparms.fn    = fn;
3242        macpreviewparms.xo    = xo;
3243        macpreviewparms.yo    = yo;
3244        macpreviewparms.scale = scale;
3245        macpreviewparms.nt    = nt;
3246        macpreviewparms.root  = root;
3247
3248        /*oldplotter=plotter;
3249        plotter = previewer;
3250        initplotter(nt,fn);*/
3251        gfxmode();
3252        paint_gfx_window();
3253        oldplotter=plotter;
3254        plotter=mac;
3255        finishplotter();
3256    } else  {
3257        makebox(fn,xo,yo,scale,nt);
3258        plottree(root, root);
3259        plotlabels(fn);
3260        finishplotter();
3261    }
3262#endif
3263#ifdef X
3264    if (previewer == xpreview ){
3265        xpreviewparms.fn    = fn;
3266        xpreviewparms.xo    = xo;
3267        xpreviewparms.yo    = yo;
3268        xpreviewparms.scale = scale;
3269        xpreviewparms.nt    = nt;
3270        xpreviewparms.root  = root;
3271
3272        init_x();
3273        oldplotter=plotter;
3274        plotter=xpreview;
3275        finishplotter();
3276    } else  {
3277        makebox(fn,xo,yo,scale,nt);
3278        plottree(root, root);
3279        plotlabels(fn);
3280        finishplotter();
3281    }
3282
3283#endif
3284#ifndef MAC
3285#ifndef WIN32
3286#ifndef X
3287  makebox(fn,xo,yo,scale,nt);
3288  plottree(root, root);
3289  plotlabels(fn);
3290  finishplotter();
3291#endif
3292#endif
3293#endif
3294  penchange = oldpenchange;
3295  xsize = oldxsize;
3296  ysize = oldysize;
3297  xunitspercm = oldxunitspercm;
3298  yunitspercm = oldyunitspercm;
3299  xscale = xunitspercm;
3300  yscale = yunitspercm;
3301  plotter = oldplotter;
3302  xcorner = oldxcorner;
3303  ycorner = oldycorner;
3304  xmargin = oldxmargin;
3305  ymargin = oldymargin;
3306  hpmargin = oldhpmargin;
3307  vpmargin = oldvpmargin;
3308  if (previewer == winpreview || previewer == xpreview || previewer == mac) {
3309    canbeplotted = (winaction == plotnow);
3310  } else {
3311    printf(" Is the tree ready to be plotted? (Answer Y or N)\n");
3312    loopcount = 0;
3313    do {
3314      printf("Type Y or N:\n");
3315#ifdef WIN32
3316      phyFillScreenColor();
3317#endif
3318      scanf("%c%*[^\n]", &ch);
3319      (void)getchar();
3320      if (ch == '\n')
3321        ch = ' ';
3322      uppercase(&ch);
3323      countup(&loopcount, 10);
3324    } while (ch != 'Y' && ch != 'N');
3325    canbeplotted = (ch == 'Y');
3326  }
3327  if (previewer == xpreview) {
3328  }
3329  return canbeplotted;
3330}  /* plotpreview */
3331
3332
3333#ifdef WIN32
3334winplotpreviewcore(int windowwidth, int windowheight)
3335{
3336  winheight = windowheight;
3337  winwidth = windowwidth;
3338  makebox(winpreviewparms.fn,
3339          winpreviewparms.xo,
3340          winpreviewparms.yo,
3341          winpreviewparms.scale,
3342          winpreviewparms.nt);
3343  plottree(winpreviewparms.root, winpreviewparms.root);
3344  plotlabels(winpreviewparms.fn);
3345  finishplotter();
3346  penchange = oldpenchange;
3347  xsize = oldxsize;
3348  ysize = oldysize;
3349  xunitspercm = oldxunitspercm;
3350  yunitspercm = oldyunitspercm;
3351  xscale = xunitspercm;
3352  yscale = yunitspercm;
3353  plotter = oldplotter;
3354  xcorner = oldxcorner;
3355  ycorner = oldycorner;
3356  xmargin = oldxmargin;
3357  ymargin = oldymargin;
3358  hpmargin = oldhpmargin;
3359  vpmargin = oldvpmargin;
3360}
3361#endif
3362
3363
3364long allocstripe(striptype stripe, long x, long y)
3365{
3366  long i;
3367  for (i=0 ; i<=y; ++i){
3368    stripe[i] = (MALLOCRETURN *)Malloc((x+1)*sizeof(Char));
3369    if (!stripe[i])
3370      break;
3371  }
3372  return i-1; 
3373} /* allocstripe */
3374
3375
3376#ifdef X
3377
3378void  redraw(Widget w,XtPointer client, XExposeEvent *ev) {
3379        XGCValues values;
3380        values.line_width=3;
3381        XChangeGC(display,gc1,GCLineWidth,&values);
3382        makebox(xpreviewparms.fn,
3383             xpreviewparms.xo,
3384             xpreviewparms.yo,
3385             xpreviewparms.scale,
3386                xpreviewparms.nt);
3387        values.line_width=1;
3388        XChangeGC(display,gc1,GCLineWidth,&values);
3389        plottree(xpreviewparms.root, xpreviewparms.root);
3390        plotlabels(xpreviewparms.fn);
3391
3392        penchange = oldpenchange;
3393        xsize = oldxsize;
3394        ysize = oldysize;
3395        xunitspercm = oldxunitspercm;
3396        yunitspercm = oldyunitspercm;
3397        xscale = xunitspercm;
3398        yscale = yunitspercm;
3399        plotter = oldplotter;
3400        xcorner = oldxcorner;
3401        ycorner = oldycorner;
3402        xmargin = oldxmargin;
3403        ymargin = oldymargin;
3404        hpmargin = oldhpmargin;
3405        vpmargin = oldvpmargin;
3406
3407
3408}
3409
3410void plot_callback(Widget w,XtPointer client, XtPointer call) {
3411        winaction=plotnow;
3412        close_x();
3413}
3414
3415
3416void change_callback(Widget w,XtPointer client, XtPointer call) {
3417        winaction=changeparms;
3418        close_x();
3419}
3420
3421void quit_callback(Widget w,XtPointer client, XtPointer call) {
3422        winaction=quitnow;
3423        close_x();
3424}
3425
3426void about_callback(Widget w,XtPointer client, XtPointer call) {
3427        do_dialog();
3428}
3429 
3430void delete_callback(Widget w, XEvent* event, String *params, int *num_params) {
3431        if (event->type != ClientMessage || event->xclient.data.l[0] !=
3432                        wm_delete_window) 
3433                return;
3434        winaction=changeparms;
3435        close_x();
3436
3437}
3438
3439void close_x() {
3440        shell=NULL;
3441        XtAppSetExitFlag(appcontext);
3442        XtUnrealizeWidget(toplevel);
3443        XtDestroyWidget(toplevel);
3444        XtCloseDisplay(display);
3445}
3446
3447
3448void dismiss_dialog()
3449{
3450        XtDestroyWidget(shell);       
3451        shell=NULL;
3452}
3453
3454void do_dialog() {
3455        if (shell != NULL)
3456                return;       
3457        shell=XtCreatePopupShell("About",transientShellWidgetClass,
3458                        toplevel,NULL,0);
3459        dialog=XtCreateManagedWidget("dialog",dialogWidgetClass,shell,NULL,0);
3460        XawDialogAddButton(dialog,"Dismiss",(XtCallbackProc)dismiss_dialog
3461                        ,NULL);
3462        XtRealizeWidget(shell);
3463          wm_delete_window2 = XInternAtom(XtDisplay(shell),
3464                  "WM_DELETE_WINDOW",0);
3465        XSetWMProtocols(XtDisplay(shell),XtWindow(shell),
3466                          &wm_delete_window2,1);
3467        XtMapWidget(shell);
3468}
3469
3470static XtActionsRec draw_actions[] = {
3471        { "quit", (XtActionProc)delete_callback },
3472};
3473
3474void init_x() {
3475  Widget paned;
3476  Widget menubar;
3477  Widget menuButton;
3478  Widget menu;
3479  Widget entry;
3480  Widget drawing_area; 
3481  XSetWindowAttributes winAttr;
3482  Arg wargs[7];
3483  unsigned int dummy1,dummy2;
3484  Window dummy3;
3485  XGCValues values;
3486
3487  toplevel=XtAppInitialize(&appcontext,"phylip",NULL,0,&nargc,nargv,res,
3488                  NULL,0); 
3489 
3490  /* make the top level window*/
3491                /* this is for closing the window*/
3492  XtAppAddActions(appcontext,draw_actions,1);
3493  XtOverrideTranslations(toplevel,
3494          XtParseTranslationTable ("<Message>WM_PROTOCOLS: quit()"));
3495
3496  /* create a form add it to toplevel */
3497  paned = XtCreateManagedWidget("paned",formWidgetClass,toplevel,NULL,0);
3498 
3499  /* create a menubar add it to the form*/
3500  menubar = XtCreateManagedWidget("menubar",boxWidgetClass,paned,NULL,0);
3501 
3502 
3503  /* create an area to draw in  with a size relative to the size of the screen*/
3504  XGetGeometry(XtDisplay(toplevel),XDefaultRootWindow(XtDisplay(toplevel)),
3505                  &dummy3,&x,&y,&width,&height,&dummy1,&dummy2);
3506
3507  height *= 0.7;
3508  width = 0.75 * height;
3509 
3510  XtSetArg(wargs[0],XtNwidth,width);
3511  XtSetArg(wargs[1],XtNheight,height); 
3512                 
3513  drawing_area = XtCreateManagedWidget("drawing_area",coreWidgetClass,
3514                  paned,wargs,2);
3515
3516  /* create a menubuton add it to the menubar*/
3517  menuButton = XtCreateManagedWidget ("File",menuButtonWidgetClass,
3518                   menubar,NULL,0);
3519
3520  /* create a menu add it to the menubutton */
3521  menu = XtCreatePopupShell("menu",simpleMenuWidgetClass,menuButton,NULL,0);
3522
3523  entry=XtCreateManagedWidget("Plot",smeBSBObjectClass,menu,NULL,0);
3524  XtAddCallback(entry,XtNcallback,plot_callback,NULL);
3525         
3526  entry=XtCreateManagedWidget("Change Parameters",smeBSBObjectClass,
3527                menu,NULL,0);
3528  XtAddCallback(entry,XtNcallback,change_callback,NULL);
3529         
3530  entry=XtCreateManagedWidget("Quit",smeBSBObjectClass,menu,NULL,0);
3531  XtAddCallback(entry,XtNcallback,quit_callback,NULL);
3532         
3533  menuButton = XtCreateManagedWidget("Help",menuButtonWidgetClass,
3534                  menubar,NULL,0);
3535 
3536  menu = XtCreatePopupShell("menu",simpleMenuWidgetClass,menuButton,NULL,0);
3537 
3538  entry=XtCreateManagedWidget("About",smeBSBObjectClass,menu,NULL,0);
3539  XtAddCallback(entry,XtNcallback,about_callback,NULL);
3540 
3541
3542  /* realize the widgets */ 
3543  XtRealizeWidget(toplevel);
3544 
3545  wm_delete_window = XInternAtom(XtDisplay(toplevel),
3546                  "WM_DELETE_WINDOW",0);
3547  XSetWMProtocols(XtDisplay(toplevel),XtWindow(toplevel),
3548                  &wm_delete_window,1);
3549 
3550  values.foreground=BlackPixel(XtDisplay(toplevel),0); 
3551  gc1=XCreateGC (XtDisplay (toplevel), XtWindow (drawing_area),
3552                  GCForeground,&values);
3553 
3554  mainwin=XtWindow(drawing_area);                       
3555         
3556  XtAddEventHandler(drawing_area,ExposureMask ,FALSE,
3557                  (XtEventHandler)redraw,NULL);
3558 
3559  XtAddEventHandler(toplevel,StructureNotifyMask,FALSE,
3560                  (XtEventHandler)redraw,NULL);
3561 
3562  display=XtDisplay(toplevel);
3563
3564
3565
3566  winAttr.backing_store = Always;
3567  winAttr.save_under=1;
3568  XChangeWindowAttributes(display,mainwin,CWBackingStore|CWSaveUnder,&winAttr);
3569 
3570  XGetGeometry(display,mainwin,&DefaultRootWindow(display),
3571                  &x,&y,&width,&height,&dummy1,&dummy2);
3572
3573}
3574#endif
3575
Note: See TracBrowser for help on using the repository browser.