BioInfWeb - TreeGraph / Version 1 / Show File - tgf-gostream.cc

TreeGraph subversion repository

sventon subversion web client - http://www.sventon.org
[show recent changes]
 
  Help
Rev: HEAD (2) - https://secure.bioinfweb.info/Code/svn/TreeGraph / trunk / main / tgf-gostream.cc
Show File - tgf-gostream.cc  [show properties]
spinner
/*
 tgf-gostream.cc, part of
 treegraph
 Tree formatting program
 Generates vector graphics (SVG,EPS) from .tgf-tree description files.
10   Copyright (c) 2003-04 by Joern Mueller
11 
12 
13   This program is free software; you can redistribute it and/or
14   modify it under the terms of the GNU General Public License
15   as published by the Free Software Foundation; either version 2
16   of the License, or (at your option) any later version.
17 
18   This program is distributed in the hope that it will be useful,
19   but WITHOUT ANY WARRANTY; without even the implied warranty of
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21   GNU General Public License for more details.
22 
23   You should have received a copy of the GNU General Public License
24   along with this program (GPL.html); if not, write to the Free Software
25   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26   (also: http://www.gnu.org)
27  */
28 
29 
30 
31 
32 
33 
34 
35  #include "tgf-gostream.h"
36  #include "tgf-tree.h"
37  #include "tgf-main.h"
38  #include <cstdio>
39 
40  /*
41  **
42  **
43  **
44  ** gostream
45  **
46  **
47  **
48  */
49 
50  void gostream::write_nodelabel(const fPoint& pos, const std::string& str)
51  {
52 
53   fontstyle tmp;
54   tmp.fontsize=12;
55   tmp.face=fs_bold;
56   write_text(fstring(str,tmp),pos);
57  }
58 
59 
60  /*
61  **
62  **
63  **
64  ** svg_ostream
65  **
66  **
67  **
68  */
69 
70  const float PiOver2=asin(1.0);
71 
72 
73  void svg_ostream::moveto(float x,float y)
74  {
75   s << 'M'<< x << ' ' << y;
76 
77  }
78 
79 
80  void svg_ostream::lineto(float x,float y)
81  {
82   s << 'L' << x << ' ' << y;
83 
84  }
85 
86  void svg_ostream::curveto(float x1,float y1, float x2,float y2, float x3,float y3)
87  {
88   s<< 'C' << x1 <<' ' << y1 << ' '<< x2 <<' ' << y2 << ' '<< x3 <<' ' << y3;
89  }
90 
91  void svg_ostream::write_head(const fRect& paper, const fRect& bbox, float lthick)
92  {
93   s << "<?xml version=\"1.0\" standalone=\"no\"?>\n";
94   s << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\"\n";
95   s << "\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n";
96   //hier noch richtige Strichbreite einsetzen:
97   s << "<svg style=\"fill:none;stroke:#000000;stroke-linecap:round;stroke-width:"<<lthick;
98   s << ";font-family:Helvetica; font-style:normal; font-weight:normal; fill-opacity:1; fill-rule:evenodd; stroke-opacity:1; \"\n";
99   s << "width=\""<<paper.right<<"\"\n";
100   s << "height=\""<<paper.bottom<<"\"\n";
101   s << "transform=\"translate("<<0.5*(paper.right-bbox.right) <<","<< 0.5*(paper.bottom-bbox.bottom)<< ")\"\n";
102    s << ">\n";
103 
104 
105  }
106 
107  void svg_ostream::write_foot(void)
108  {
109   s << "\n</svg>\n";
110   s.flush();
111  }
112 
113  void svg_ostream::write_text(const fstring& str, const fPoint& p, float angle)
114  {
115   s << "<text style=\"fill:#000000;stroke:none;font-size:"<<str.fontsize<<"px";
116   if(str.face==fs_italic)
117    s << ";font-weight:normal;font-style:italic";
118   else if(str.face==fs_bold)
119    s << ";font-weight:bold;font-style:normal";
120  // else aus << "font-weight:normal;font-style:normal";//Standard: plain
121   s << "\"\nx=\"0\" y=\"0\"";
122   s << "\ntransform=\"matrix(";
123   float c1=cos(angle),s1=sin(angle);
124   s<<c1<<","<< s1<<","<<-s1<<","<<c1<<",";
125   s<<p.x<<","<<p.y<<")\"";
126   s <<">";
127   s << str;
128   s << "</text>\n";
129  }
130 
131  void svg_ostream::write_rgabel(float l1,float y1 ,float l2,float y2,float xx,float maxr)
132  {
133   float hdmt=0.5*maxr;
134 
135   s << "<path d=\"";
136   s << "M" << xx+l1 << " " << y1;
137   s << "H" << xx+maxr;
138   s << "C" << xx+hdmt << " " << y1 << " " << xx << " " << y1+hdmt;
139   s << " " << xx << " " << y1+maxr;
140   s << "V" << y2-maxr;
141   s << "C" << xx << " " << y2-hdmt << " " << xx+hdmt << " " << y2;
142   s << " " << xx+maxr << " " << y2;
143   s << "H" << xx+l2;
144   s << "\" />\n";//path
145 
146  }
147 
148  void svg_ostream::write_egabel(float l1,float y1,float l2,float y2,float xx)
149  {
150   s << "<path d=\"";
151   s << "M" << xx+l1 << " " << y1;
152   s << "H" << xx;
153   s << "V" << y2;
154   s << "H" << xx+l2;
155   s << "\" />\n";//path
156  }
157 
158  void svg_ostream::write_hline(float x1,float y1,float l)
159  {
160   s << "<line x1=\"" << x1 << "\" y1=\"" << y1 << "\" ";
161   s << "x2=\"" << x1+l << "\" y2=\"" << y1 << "\" />\n";
162 
163  }
164 
165  void svg_ostream::write_klammer(const fstring& txt,float y1,
166   float y2,float x,float ext, int style)
167  {
168 
169   y1-=ext;
170   y2+=ext;
171 
172   if(!(style&klammer::eckig)){
173 
174   s << "<path style=\"stroke-linejoin:round;stroke-linecap:round;stroke-width:0.8\"\n";
175 
176   float ll=0.5*fabs(y2-y1);
177   if(ll>20.0) ll=20.0;
178   float frc=0.035*ll;
179 
180   float md=0.5*(y1+y2);
181   s << "d=\"";
182 
183   moveto(x,y2);
184   curveto(x+3,y2-4*frc, x+3,y2-4*frc, x+3,y2-8*frc);
185   lineto(x+3,md+7*frc);
186   curveto(x+3,md+5*frc, x+3,md+2*frc, x+6,md);
187 
188   moveto(x+6,md);
189   curveto(x+3.5,md+3*frc, x+3.5,md+5*frc, x+3.5,md+7*frc);
190   lineto(x+3.5,y2-8*frc);
191   curveto(x+3.5,y2-5*frc, x+3.5,y2-3*frc, x,y2);
192 
193   moveto(x,y1);
194   curveto(x+3,y1+4*frc, x+3,y1+4*frc, x+3,y1+8*frc);
195   lineto(x+3,md-7*frc);
196   curveto(x+3,md-5*frc, x+3,md-2*frc, x+6,md);
197 
198   moveto(x+6,md);
199   curveto(x+3.5,md-3*frc, x+3.5,md-5*frc, x+3.5,md-7*frc);
200   lineto(x+3.5,y1+8*frc);
201   curveto(x+3.5,y1+5*frc, x+3.5,y1+3*frc, x,y1);
202   s<<"\"\n/>";
203 
204   } else {
205   s<< "<g>";
206   s << "<path style=\"stroke-linejoin:round;stroke-linecap:butt;stroke-width:0.8\" ";
207   s << "d=\"M"<<x<<' '<<y1;
208   s << " H"<<x+4.0<<"V"<<y2<<"H"<<x<<"\" />\n";
209   s << "<path style=\"stroke-linecap:butt;stroke-width:1\" ";
210   s << "d=\"M"<<x+4.0-0.7<<' '<<y1<<"V"<<y2<<"\" />\n";
211   s<<"</g>";
212   }
213 
214 
215 
216 
217   fPoint m;
218   if(style&klammer::gedreht){
219    m.x=x+8.0;
220    m.y=(y1+y2)/2+0.33*txt.fontsize;
221   } else {
222    m.x=x+8.0+txt.fontsize;
223    m.y=(y1+y2)/2+0.5*helv_stringwidth(txt);
224   }
225   write_text(txt,m,(style&klammer::gedreht)?0:-PiOver2);
226 
227 
228  }
229 
230 
231 
232  void svg_ostream::write_rule(const fPoint& pos, float z,float wd)
233  {
234   s<<"<g style=\"stroke-linecap:butt;stroke-width:1\">\n";
235   write_hline(pos.x,pos.y,wd);
236   s<<"<g style=\"stroke-width:0.3\">\n";
237 
238   int i;
239   float x1,l;
240   for(int i=0; i<=10; i++){
241    x1=pos.x+i*0.1*wd;
242    l=2.0;
243    if(i==0 || i==10)
244     l=3.0;
245    else if(i==5)
246     l=2.5;
247    s << "<line x1=\"" << x1 << "\" y1=\"" << pos.y-l << "\" ";
248    s << "x2=\"" << x1 << "\" y2=\"" << pos.y+l << "\" />\n";
249   }
250   s<< "</g></g>\n";
251 
252   fontstyle tmp;
253   tmp.fontsize=12;
254   tmp.face=fs_bold;
255   char st[10];
256   sprintf(st,"%.5g",z);
257   fstring ft(st,tmp);
258   fPoint m;
259   m.x=pos.x+wd/2-0.5*helv_stringwidth(ft);
260   m.y=pos.y+16;
261   write_text(ft,m);
262 
263  }
264 
265  void svg_ostream::write_arrow(const fPoint& pos, float angle_deg)
266  {
267  cout << "Arrow geht noch nicht.\n";
268   const float htief=9,hhbr=3.4,kerb=2.4;
269   s<<"<g transform=\"translate("<<pos.x<<","<<pos.y<<")\">\n";
270   s<<"<g transform=\"rotate("<<angle_deg<<")\">\n";
271   s << "<path style=\"stroke-linejoin:round;stroke-width:0.8\" ";
272   s << "d=\"M0 0L"<<htief<<" "<<hhbr;
273  // s << " H"<<x+4.0<<"V"<<y2+ext<<"H"<<x<<"\" />\n";
274 
275   s<<"</g></g>";
276  }
277 
278  void svg_ostream::write_nodelabel(const fPoint& pos, const std::string& str)
279  {
280   s<<"<g style=\"fill:#FF0000\">";
281   gostream::write_nodelabel(pos,str);
282   s << "</g>\n";
283 
284  }
285 
286 
287 
288  /*
289  **
290  **
291  **
292  ** ps_ostream
293  **
294  **
295  **
296  */
297  ps_ostream::ps_ostream(std::ostream& s1) : gostream(s1)
298  {
299   finited=false;
300 
301  }
302 
303  void ps_ostream::setfont(const fontstyle& f)
304  //Reduces number of calls to scalefont/Makefont
305  {
306   bool ch=(!finited||(f.face!=laststyle.face)||(f.fontsize!=laststyle.fontsize));
307   if(ch){
308    const float& q=f.fontsize;
309    if(f.face==fs_italic){
310    s << "/Helvetica findfont ["<<q<<" 0 "<<0.25*q<<" "<<q<< " 0 0] makefont setfont\n";
311    } else if(f.face==fs_bold)
312    s << "/Helvetica-Bold findfont "<<q<<" scalefont setfont\n";
313    else
314    s << "/Helvetica findfont "<<q<<" scalefont setfont\n";
315    laststyle=f;
316    finited=true;
317   }
318  }
319 
320 
321  void ps_ostream::moveto(float x,float y)
322  {
323   s << x << ' ' << ty(y) << " M ";
324 
325  }
326 
327 
328  void ps_ostream::lineto(float x,float y)
329  {
330   s << x << ' ' << ty(y) << " L ";
331 
332  }
333 
334  void ps_ostream::curveto(float x1,float y1, float x2,float y2, float x3,float y3)
335  {
336   s<< x1 <<' ' << ty(y1) << ' '<< x2 <<' ' << ty(y2) << ' '<< x3 <<' ' << ty(y3) << " C ";
337  }
338 
339 
340 
341  void ps_ostream::write_head(const fRect& paper, const fRect& bbox, float lthick)
342  {
343 
344  //bbox auf paper zentrieren.
345   yh=bbox.bottom; //fuer rhd.-Koordinaten unter PostScript
346   fPoint st(0.5*(paper.right-bbox.right),0.5*(paper.bottom-bbox.bottom));
347   s << "%!PS-Adobe-3.0 EPSF-3.0\n";
348   s << "%%Creator: treegraph " TGFVERSION "\n";
349   s << "%%BoundingBox: " << int(st.x) << ' ' << int(st.y) << ' ';
350   s << int(st.x+bbox.right+1.0) << ' ' << int(st.y+bbox.bottom+1.0) <<endl;
351   s << "%%DocumentNeededFonts: Helvetica Helvetica-Bold\n";//Italic wird aus Plain konstruiert
352   s << "%%EndComments\n";
353   s << "%%BeginProlog\n";
354  // s << "150 dict begin ";
355   s << "/M {moveto} bind def /L {lineto} bind def /C {curveto} bind def\n";
356   s << "/N {newpath} bind def /SW {show} bind def /S {stroke} bind def\n";
357   s << "/LS {lineto stroke} bind def\n";
358   s << "/SF {setfont} bind def /GS {gsave} bind def /GR {grestore} bind def\n";
359   s << st.x <<' '<< st.y<< " translate\n";
360   s << lthick << " setlinewidth 1 setlinecap\n";
361    s << "\n%%EndProlog\n";
362 
363  }
364 
365  void ps_ostream::write_foot(void)
366  {
367   s << "\n%%EOF\n";
368   s.flush();
369  //Hier noch was wegen dict
370  }
371 
372  void ps_ostream::write_text(const fstring& str, const fPoint& p, float angle)
373  {
374   setfont(str);
375   s << p.x << " " << ty(p.y) << " M\n";
376 
377   if(angle!=0.0){
378    s << "GS " << -angle*90/PiOver2 << " rotate ";
379   }
380 
381   s << "("<<str<<") SW\n";
382   if(angle!=0.0){
383    s << "GR\n";
384   }
385 
386  }
387 
388  void ps_ostream::write_rgabel(float l1,float y1 ,float l2,float y2,float xx,float maxr)
389  {
390   float hdmt=0.5*maxr;
391  // s << "N ";
392   moveto(xx+l1,y1);
393   lineto(xx+maxr,y1);
394   curveto(xx+hdmt,y1,xx,y1+hdmt,xx,y1+maxr);
395   s<<endl;
396   lineto(xx,y2-maxr);
397   curveto(xx,y2-hdmt,xx+hdmt,y2,xx+maxr,y2);
398   lineto(xx+l2,y2);
399   s << "S\n";
400 
401 
402  }
403 
404  void ps_ostream::write_egabel(float l1,float y1,float l2,float y2,float xx)
405  {
406  // s << "N ";
407   moveto(xx+l1,y1);
408   lineto(xx,y1);
409   lineto(xx,y2);
410   lineto(xx+l2,y2);
411   s << "S\n";
412  }
413 
414  void ps_ostream::write_hline(float x1,float y1,float l)
415  {
416  // s << "N ";
417   moveto(x1,y1);
418   lineto(x1+l,y1);
419   s << "S\n";
420  }
421 
422  void ps_ostream::write_klammer(const fstring& txt,float y1,
423   float y2,float x,float ext, int style)
424  {
425 
426   y1-=ext;
427   y2+=ext;
428 
429   s << "GS\n";
430 
431   if(!(style&klammer::eckig)){
432 
433   float ll=0.5*fabs(y2-y1);
434   if(ll>20.0) ll=20.0;
435   float frc=0.035*ll;
436 
437   float md=0.5*(y1+y2);
438   s << "0.8 setlinewidth 2 setlinejoin 1 setlinecap N\n";
439 
440   moveto(x,y2);
441   curveto(x+3,y2-4*frc, x+3,y2-4*frc, x+3,y2-8*frc);
442   lineto(x+3,md+7*frc);
443   curveto(x+3,md+5*frc, x+3,md+2*frc, x+6,md);
444   s << endl;
445 
446   moveto(x+6,md);
447   curveto(x+3.5,md+3*frc, x+3.5,md+5*frc, x+3.5,md+7*frc);
448   lineto(x+3.5,y2-8*frc);
449   curveto(x+3.5,y2-5*frc, x+3.5,y2-3*frc, x,y2);
450   s<<endl;
451 
452   moveto(x,y1);
453   curveto(x+3,y1+4*frc, x+3,y1+4*frc, x+3,y1+8*frc);
454   lineto(x+3,md-7*frc);
455   curveto(x+3,md-5*frc, x+3,md-2*frc, x+6,md);
456   s << endl;
457 
458   moveto(x+6,md);
459   curveto(x+3.5,md-3*frc, x+3.5,md-5*frc, x+3.5,md-7*frc);
460   lineto(x+3.5,y1+8*frc);
461   curveto(x+3.5,y1+5*frc, x+3.5,y1+3*frc, x,y1);
462 
463   } else {
464 
465   s << "0.8 setlinewidth 2 setlinejoin 0 setlinecap N\n";
466   moveto(x,y1);
467   lineto(x+4.0,y1);
468   lineto(x+4.0,y2);
469   lineto(x,y2);
470   s << "S\n";
471   s << "1 setlinewidth\n";
472   moveto(x+4.0-0.7,y1);
473   lineto(x+4.0-0.7,y2);
474 
475   }
476 
477 
478   s << "S GR\n";
479 
480   fPoint m;
481   if(style&klammer::gedreht){
482    m.x=x+8.0;
483    m.y=(y1+y2)/2+0.33*txt.fontsize;
484   } else {
485    m.x=x+8.0+txt.fontsize;
486    m.y=(y1+y2)/2+0.5*helv_stringwidth(txt);
487   }
488   write_text(txt,m,(style&klammer::gedreht)?0:-PiOver2);
489 
490  }
491 
492 
493 
494  void ps_ostream::write_rule(const fPoint& pos, float z,float wd)
495  {
496 
497   s<<"GS 0 setlinecap 1 setlinewidth\n";
498   write_hline(pos.x,pos.y,wd);
499   s<<"0.3 setlinewidth\n";
500 
501   int i;
502   float x1,l;
503   for(int i=0; i<=10; i++){
504    x1=pos.x+i*0.1*wd;
505    l=2.0;
506    if(i==0 || i==10)
507     l=3.0;
508    else if(i==5)
509     l=2.5;
510   // s << "N ";
511    moveto(x1,pos.y-l);
512    lineto(x1,pos.y+l);
513    s<<"S\n";
514   }
515   s<< "GR\n";
516 
517   fontstyle tmp;
518   tmp.fontsize=12;
519   tmp.face=fs_bold;
520   char st[10];
521   sprintf(st,"%.5g",z);
522   fstring ft(st,tmp);
523   fPoint m;
524   m.x=pos.x+wd/2-0.5*helv_stringwidth(ft);
525   m.y=pos.y+16;
526   write_text(ft,m);
527 
528 
529  }
530 
531  void ps_ostream::write_arrow(const fPoint& pos, float angle_deg)
532  {
533  /*
534   const float htief=9,hhbr=3.4,kerb=2.4;
535   s<<"<g transform=\"translate("<<pos.x<<","<<pos.y<<")\">\n";
536   s<<"<g transform=\"rotate("<<angle_deg<<")\">\n";
537   s << "<path style=\"stroke-linejoin:round;stroke-width:0.8\"";
538   s << "d=\"M0 0L"<<htief<<" "<<hhbr;
539  // s << " H"<<x+4.0<<"V"<<y2+ext<<"H"<<x<<"\" />\n";
540 
541   s<<"</g></g>";
542  */
543  }
544 
545  void ps_ostream::write_nodelabel(const fPoint& pos, const std::string& str)
546  {
547   s<<"1 0 0 setrgbcolor ";
548   gostream::write_nodelabel(pos,str);
549   s << "0 0 0 setrgbcolor \n";
550 
551  }


feed icon

sventon 2.5.1

Valid XHTML 1.0 Strict   CSS ist valide!
TreeGraph icon
bioinfweb RSS feed TreeGraph 2 on ResearchGate bioinfweb on twitter TreeGraph 2 on GitHub
bioinfweb - Biology & Informatics Website