BioInfWeb - TreeGraph / Version 1 / Show File - tgf-render.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-render.cc
Show File - tgf-render.cc  [show properties]
spinner
/*
 tgf-render.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-main.h"
36  #include "tgf-tree.h"
37  #include "tgf-render.h"
38  #include "tgf-utils.h"
39  #include "tgf-fonttable.h"
40  #include <cmath>
41 
42 
43  void writeInnerNodeTextLine(const fPoint& p,const fstring& s1,
44   const fstring& s2, const fstring& sepw,
45   float& h, gostream *of);
46 
47 
48  void tree::render(gostream *of) const
49  {
50   fRect paper,bbox;
51   paper.right=595.275591;
52   paper.bottom=841.889764;
53   bbox.right=dsc.picwidth;
54   bbox.bottom=dsc.picheight;
55 
56   of->write_head(paper,bbox,dsc.thickness);
57 
58   renderNode(this,of);
59 
60   renderRandklammern(of);
61 
62   if(dsc.uselength){
63    fPoint p;
64    p.x=dsc.Rand.left+4*millimeter;
65    p.y=dsc.picheight-10*millimeter;
66    float z=0.4*dsc.treewidth/dsc.lenscale;
67    z=std::pow((float)10.0,(int)std::floor(log10(z)));
68    //hoechstens 0.4mal Baumbreite als Lineal
69    float wd=dsc.treewidth;
70    of->write_rule(p,z,z*dsc.lenscale);
71   }
72 
73   of->write_foot();
74 
75  }
76 
77 
78  void tree::renderNode(const tnode *cp, gostream *of) const
79  {
80 
81   string ts1,ob,un;
82 
83   //Text schreiben
84   fPoint cc;
85   if(!cp->root()){
86    cc=cp->prev->pos;
87    cc.y=cp->pos.y;
88   } else {
89    //sonst x-Koordinate des Vorgaengers 0
90    cc=cp->pos;
91    cc.x=0;
92   }
93 
94   cc.x=0.5*(cc.x+cp->pos.x);
95 
96 
97 
98   float zh;
99   fPoint c2=cc;
100   c2.y-=0.33*(cp->u[0]).fontsize;
101   writeInnerNodeTextLine(c2,cp->u[0], cp->u[1], dsc.colsep, zh,of);
102   c2.y-=zh;
103   writeInnerNodeTextLine(c2,cp->u[2], cp->u[3], dsc.colsep, zh,of);
104   c2=cc;
105   c2.y+=1.2*(cp->d[0]).fontsize;
106   writeInnerNodeTextLine(c2,cp->d[0], cp->d[1], dsc.colsep, zh,of);
107   c2.y=cc.y+2.4*(cp->d[0]).fontsize;
108   writeInnerNodeTextLine(c2,cp->d[2], cp->d[3], dsc.colsep, zh,of);
109 
110 
111   if(dsc.shownumbers){
112    fPoint p1=cp->pos;
113    p1.x-=20;
114    p1.y+=7;
115    of->write_nodelabel(p1,cp->label());
116   }
117 
118   if(cp->terminal()){//Randtext
119    if(cp->r.length()==0){
120     return;
121    }
122    cc=cp->pos;
123    cc.x+=dsc.extrasep;
124    cc.y+=0.33*(cp->r).fontsize;
125    of->write_text(cp->r,cc);
126 
127    return;
128   }
129 
130   tnode *nx=cp->next;
131   float xx=cp->pos.x;
132 
133   int nch=cp->nchildren();
134   if(nch==1){ //nur ein Nachfolgeknoten
135    of->write_hline(xx, cp->pos.y, nx->pos.x-xx);
136   } else { //mindestens zwei Nachfolgeknoten
137    fPoint p=nx->pos;
138    float x1=p.x-xx,y1=p.y;
139    while(nx=nx->down) p=nx->pos;
140    if(dsc.roundness==0)
141     of->write_egabel(x1,y1,p.x-xx,p.y,xx);
142    else
143     of->write_rgabel(x1,y1,p.x-xx,p.y,xx,dsc.roundness*dsc.maxrund);
144 
145    nx=(cp->next)->down;//existiert n.V.
146    while(nx->down){
147     p=nx->pos;
148     of->write_hline(xx, p.y, p.x-xx);
149     nx=nx->down;
150    }
151 
152 
153   }
154 
155   //rekursiv weiter
156   nx=cp->next;
157   while(nx){
158    renderNode(nx,of);
159    nx=nx->down;
160   }
161 
162  }
163 
164 
165  void tree::renderRandklammern(gostream *of) const
166  {
167     for(list<klammer>::const_iterator it=kl.begin(); it!=kl.end(); ++it){
168    const tnode *x[2];
169    bool gut=true;
170    for(int i=0; i<2; i++){
171 
172     if((x[i]=lb.bfind_label((*it).lb[i].c_str()))==0){
173      cout << "\nLabel '" << (*it).lb[i] << "' undefined.\n";
174      gut=false;
175     }
176    }
177    if(gut){
178     if(x[0]->pos.y>x[1]->pos.y){
179      const tnode *tmp=x[0]; x[0]=x[1]; x[1]=tmp;
180     }
181     x[0]=x[0]->oberster_sichtbarer();
182     x[1]=x[1]->unterster_sichtbarer();
183     float xpos=dsc.picwidth-dsc.Rand.right-dsc.klammerrand+(*it).sp*klammer::breite;
184     of->write_klammer((*it).text,x[0]->pos.y,x[1]->pos.y,
185      xpos,0.35*dsc.rstyle.fontsize,it->style);
186    }
187   }
188 
189  }
190 
191 
192 
193  void writeInnerNodeTextLine(const fPoint& p,const fstring& s1,
194   const fstring& s2, const fstring& sepw,
195   float& h, gostream *of)
196  {
197   float x=p.x;
198   float w=0,wd[3];
199   h=0;
200   float h1;
201   int nc=0;
202 
203   if(s1.size()>0){
204    w=(wd[0]=helv_stringwidth(s1));
205    ++nc;
206    h=s1.fontsize*1.2;
207   }
208   if(s2.size()>0){
209    w+=(wd[2]=helv_stringwidth(s2));
210    ++nc;
211    h1=s2.fontsize*1.2;
212    if(h1>h) h=h1;
213   }
214   if(nc==2){
215    w+=(wd[1]=helv_stringwidth(sepw));
216    h1=sepw.fontsize*1.2;
217    if(h1>h) h=h1;
218   }
219   x-=w/2;
220 
221   fPoint p2=p;
222   p2.x=x;
223   if(s1.size()>0){
224    of->write_text(s1,p2);
225    p2.x+=wd[0];
226   }
227   if(s2.size()>0){
228     of->write_text(sepw,p2);
229    p2.x+=wd[1];
230     of->write_text(s2,p2);
231   }
232 
233 
234 
235 
236  }
237 
238 
239  float min_node_width(const tnode *p,const string& colsep)
240  {
241   float sepw=helv_stringwidth(colsep);
242   float m=0,m2;
243   for(int i=0; i<2; i++){
244   //oben, i-te Zeile
245    float m2=0;
246    int nc=0;
247    if(p->u[2*i].size()>0){
248     m2=helv_stringwidth(p->u[2*i]);
249     ++nc;
250    }
251    if(p->u[2*i+1].size()>0){
252     m2+=helv_stringwidth(p->u[2*i+1]);
253     ++nc;
254    }
255    if(nc==2) m2+=sepw;
256    if(m2>m) m=m2;
257   //unten, i-te Zeile
258    m2=0;
259    nc=0;
260    if(p->d[2*i].size()>0){
261     m2=helv_stringwidth(p->d[2*i]);
262     ++nc;
263    }
264    if(p->d[2*i+1].size()>0){
265     m2+=helv_stringwidth(p->d[2*i+1]);
266     ++nc;
267    }
268    if(nc==2) m2+=sepw;
269    if(m2>m) m=m2;
270   }
271 
272   const float extra=2.5*millimeter;
273   return m+extra;
274 
275  }
276 
277  float helv_stringwidth(const fstring& s)
278  {
279   float sz=0;
280   for(int i=0; i<s.length(); i++){
281    float x;
282    int c=s[i];
283    if(c<32 || c>126){//unbekannter Buchstabe
284     x=20.0;
285    } else {
286     c-=32;
287     if(s.face==fs_bold) c+=95;
288     else if(s.face==fs_italic) c+=190;
289     x=helv24[c];
290    }
291    sz+=x;
292   }
293   float ll=sz*(s.fontsize)/24.0;
294   return ll;
295  }


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