source: trunk/GDE/PHYLIP/draw.c

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