Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/sg/axis

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /externals/g4tools/include/tools/sg/axis (Version 11.3.0) and /externals/g4tools/include/tools/sg/axis (Version 10.1)


  1 // Copyright (C) 2010, Guy Barrand. All rights    
  2 // See the file tools.license for terms.          
  3                                                   
  4 #ifndef tools_sg_axis                             
  5 #define tools_sg_axis                             
  6                                                   
  7 #include "node"                                   
  8 #include "line_style"                             
  9 #include "text_style"                             
 10 #include "enums"                                  
 11 #include "noderef"                                
 12 #include "vertices"                               
 13 #include "draw_style"                             
 14 #include "rgba"                                   
 15 #include "normal"                                 
 16 #include "separator"                              
 17 #include "tools"                                  
 18 #include "nodekit"                                
 19                                                   
 20 #include "../lina/vec3f"                          
 21 #include "../mnmx"                                
 22 #include "../hplot"                               
 23                                                   
 24 #include <cstdio> //sprintf                       
 25 #include <cstring> //strcpy                       
 26                                                   
 27 namespace tools {                                 
 28 namespace sg {                                    
 29                                                   
 30 class axis : public node {                        
 31 public:                                           
 32   TOOLS_NODE(axis,tools::sg::axis,node)           
 33 public:                                           
 34   sf<float> width;                                
 35   sf<float> minimum_value;                        
 36   sf<float> maximum_value;                        
 37   sf<unsigned int> divisions;                     
 38   sf_string modeling; //hippo, hplot              
 39   sf<bool> is_log;                                
 40   // If modeling is hippo or hplot,               
 41   // labels_enforced true let labels be an inp    
 42   sf<bool> labels_enforced;                       
 43   sf<bool> tick_up;                               
 44   sf<float> tick_length;                          
 45                                                   
 46   // NOTE : if modeling is none,the below are     
 47   //        If modeling is hippo or hplot, the    
 48   //        (filled by compute_ticks).            
 49   sf<unsigned int> tick_number; //output          
 50   mf_string labels;       //output                
 51   mf<float> values;       //output //in [minim    
 52   mf<float> coords;       //output //in [0,wid    
 53   mf<float> sub_coords;   //output                
 54   sf<int> magnitude;      //output                
 55                                                   
 56   sf_string title;                                
 57   sf<float> title_to_axis;                        
 58   sf<float> title_height;                         
 59   sf_enum<hjust> title_hjust;                     
 60                                                   
 61   sf<float> label_to_axis;                        
 62   sf<float> label_height;                         
 63                                                   
 64   sf<bool>  labels_no_overlap_automated;          
 65   sf<float> labels_gap; //in percent of width.    
 66                                                   
 67   // time labels only in hplot modeling for th    
 68   sf<bool> time_labels;                           
 69   sf_string time_format;                          
 70   sf<double> time_offset;                         
 71   sf<bool> time_offset_is_GMT;                    
 72 public:                                           
 73   virtual const desc_fields& node_desc_fields(    
 74     TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::axi    
 75     static const desc_fields s_v(parent::node_    
 76       TOOLS_ARG_FIELD_DESC(width),                
 77       TOOLS_ARG_FIELD_DESC(minimum_value),        
 78       TOOLS_ARG_FIELD_DESC(maximum_value),        
 79       TOOLS_ARG_FIELD_DESC(divisions),            
 80       TOOLS_ARG_FIELD_DESC(modeling),             
 81       TOOLS_ARG_FIELD_DESC(is_log),               
 82       TOOLS_ARG_FIELD_DESC(labels_enforced),      
 83       TOOLS_ARG_FIELD_DESC(tick_up),              
 84       TOOLS_ARG_FIELD_DESC(tick_length),          
 85       TOOLS_ARG_FIELD_DESC(tick_number),          
 86       TOOLS_ARG_FIELD_DESC(labels),               
 87       TOOLS_ARG_FIELD_DESC(values),               
 88       TOOLS_ARG_FIELD_DESC(coords),               
 89       TOOLS_ARG_FIELD_DESC(sub_coords),           
 90       TOOLS_ARG_FIELD_DESC(magnitude),            
 91       TOOLS_ARG_FIELD_DESC(title),                
 92       TOOLS_ARG_FIELD_DESC(title_to_axis),        
 93       TOOLS_ARG_FIELD_DESC(title_height),         
 94       TOOLS_ARG_FIELD_DESC(title_hjust),          
 95       TOOLS_ARG_FIELD_DESC(label_to_axis),        
 96       TOOLS_ARG_FIELD_DESC(label_height),         
 97       TOOLS_ARG_FIELD_DESC(labels_no_overlap_a    
 98       TOOLS_ARG_FIELD_DESC(labels_gap),           
 99                                                   
100       TOOLS_ARG_FIELD_DESC(time_labels),          
101       TOOLS_ARG_FIELD_DESC(time_format),          
102       TOOLS_ARG_FIELD_DESC(time_offset),          
103       TOOLS_ARG_FIELD_DESC(time_offset_is_GMT)    
104     );                                            
105     return s_v;                                   
106   }                                               
107   virtual bool touched() {                        
108     if(parent::touched()) return true;            
109     if(line_style().touched()) return true;       
110     if(ticks_style().touched()) return true;      
111     if(labels_style().touched()) return true;     
112     if(mag_style().touched()) return true;        
113     if(title_style().touched()) return true;      
114     return false;                                 
115   }                                               
116   virtual void reset_touched() {                  
117     parent::reset_touched();                      
118     line_style().reset_touched();                 
119     ticks_style().reset_touched();                
120     labels_style().reset_touched();               
121     mag_style().reset_touched();                  
122     title_style().reset_touched();                
123   }                                               
124 private:                                          
125   void add_fields(){                              
126     // if adding a field, look for reset_style    
127     add_field(&width);                            
128     add_field(&minimum_value);                    
129     add_field(&maximum_value);                    
130     add_field(&divisions);                        
131     add_field(&modeling);                         
132     add_field(&is_log);                           
133     add_field(&labels_enforced);                  
134     add_field(&tick_up);                          
135     add_field(&tick_length);                      
136     add_field(&tick_number);                      
137     add_field(&labels);                           
138     add_field(&values);                           
139     add_field(&coords);                           
140     add_field(&sub_coords);                       
141     add_field(&magnitude);                        
142     add_field(&title);                            
143     add_field(&title_to_axis);                    
144     add_field(&title_height);                     
145     add_field(&title_hjust);                      
146     add_field(&label_to_axis);                    
147     add_field(&label_height);                     
148     add_field(&labels_no_overlap_automated);      
149     add_field(&labels_gap);                       
150                                                   
151     add_field(&time_labels);                      
152     add_field(&time_format);                      
153     add_field(&time_offset);                      
154     add_field(&time_offset_is_GMT);               
155   }                                               
156   void init_sg(){                                 
157     m_group.add(new noderef(m_line_sep));         
158     m_group.add(new noderef(m_ticks_sep));        
159     m_group.add(new noderef(m_labels_sep));       
160     m_group.add(new noderef(m_mag_sep));          
161     m_group.add(new noderef(m_title_sep));        
162   }                                               
163 public:                                           
164   virtual void render(render_action& a_action)    
165     if(touched()) {                               
166       update_sg(a_action.out());                  
167       reset_touched();                            
168     }                                             
169     m_group.render(a_action);                     
170   }                                               
171   virtual void pick(pick_action& a_action) {      
172     if(touched()) {                               
173       update_sg(a_action.out());                  
174       reset_touched();                            
175     }                                             
176     //m_group.pick(a_action);                     
177     nodekit_pick(a_action,m_group,this);          
178   }                                               
179   virtual void search(search_action& a_action)    
180     if(touched()) {                               
181       update_sg(a_action.out());                  
182       reset_touched();                            
183     }                                             
184     parent::search(a_action);                     
185     if(a_action.done()) return;                   
186     m_group.search(a_action);                     
187   }                                               
188   virtual void bbox(bbox_action& a_action) {      
189     if(touched()) {                               
190       update_sg(a_action.out());                  
191       reset_touched();                            
192     }                                             
193     m_group.bbox(a_action);                       
194   }                                               
195                                                   
196   virtual bool write(write_action& a_action) {    
197     //FIXME : this method should not be needed    
198     //        But m_[line,ticks,labels,mag,tit    
199                                                   
200     if(touched()) {                               
201       update_sg(a_action.out());                  
202       reset_touched();                            
203     }                                             
204     //if(!write_fields(a_action)) return false    
205     return m_group.write(a_action);               
206   }                                               
207 public:                                           
208   axis(const base_freetype& a_ttf)                
209   :parent()                                       
210   ,width(1)                                       
211   ,minimum_value(0)                               
212   ,maximum_value(1)                               
213   ,divisions(510)                                 
214   ,modeling(tick_modeling_hippo())                
215   ,is_log(false)                                  
216   ,labels_enforced(false)                         
217   ,tick_up(true)                                  
218   ,tick_length(0)                                 
219                                                   
220   ,tick_number(0)                                 
221   ,magnitude(0)                                   
222                                                   
223   ,title("")                                      
224   ,title_to_axis(0)   //inited below              
225   ,title_height(0)    //inited below              
226   ,title_hjust(right)                             
227                                                   
228   ,label_to_axis(0) //inited below                
229   ,label_height(0)  //inited below                
230                                                   
231   ,labels_no_overlap_automated(true)              
232   ,labels_gap(0.02f)                              
233                                                   
234   ,time_labels(false)                             
235   ,time_format("%H:%M:%S")                        
236   ,time_offset(0) //UTC_time_1970_01_01__00_00    
237   ,time_offset_is_GMT(false)                      
238                                                   
239   ,m_ttf(a_ttf)                                   
240   {                                               
241     add_fields();                                 
242                                                   
243     init_sg();                                    
244                                                   
245     reset_style(true);                            
246   }                                               
247   virtual ~axis(){}                               
248 public:                                           
249   axis(const axis& a_from)                        
250   :parent(a_from)                                 
251   ,width(a_from.width)                            
252   ,minimum_value(a_from.minimum_value)            
253   ,maximum_value(a_from.maximum_value)            
254   ,divisions(a_from.divisions)                    
255   ,modeling(a_from.modeling)                      
256   ,is_log(a_from.is_log)                          
257   ,labels_enforced(a_from.labels_enforced)        
258   ,tick_up(a_from.tick_up)                        
259   ,tick_length(a_from.tick_length)                
260                                                   
261   ,tick_number(a_from.tick_number)                
262   ,magnitude(a_from.magnitude)                    
263                                                   
264   ,title(a_from.title)                            
265   ,title_to_axis(a_from.title_to_axis)            
266   ,title_height(a_from.title_height)              
267   ,title_hjust(a_from.title_hjust)                
268                                                   
269   ,label_to_axis(a_from.label_to_axis)            
270   ,label_height(a_from.label_height)              
271                                                   
272   ,labels_no_overlap_automated(a_from.labels_n    
273   ,labels_gap(a_from.labels_gap)                  
274                                                   
275   ,time_labels(a_from.time_labels)                
276   ,time_format(a_from.time_format)                
277   ,time_offset(a_from.time_offset)                
278   ,time_offset_is_GMT(a_from.time_offset_is_GM    
279                                                   
280   ,m_ttf(a_from.m_ttf)                            
281                                                   
282   ,m_line_style(a_from.m_line_style)              
283   ,m_ticks_style(a_from.m_ticks_style)            
284   ,m_labels_style(a_from.m_labels_style)          
285   ,m_mag_style(a_from.m_mag_style)                
286   ,m_title_style(a_from.m_title_style)            
287   {                                               
288     add_fields();                                 
289     init_sg();                                    
290   }                                               
291   axis& operator=(const axis& a_from){            
292     parent::operator=(a_from);                    
293                                                   
294     width = a_from.width;                         
295     minimum_value = a_from.minimum_value;         
296     maximum_value = a_from.maximum_value;         
297     divisions = a_from.divisions;                 
298     modeling = a_from.modeling;                   
299     is_log = a_from.is_log;                       
300     labels_enforced = a_from.labels_enforced;     
301     tick_up = a_from.tick_up;                     
302     tick_length = a_from.tick_length;             
303                                                   
304     tick_number = a_from.tick_number;             
305     magnitude = a_from.magnitude;                 
306                                                   
307     title = a_from.title;                         
308     title_to_axis = a_from.title_to_axis;         
309     title_height = a_from.title_height;           
310     title_hjust = a_from.title_hjust;             
311                                                   
312     label_to_axis = a_from.label_to_axis;         
313     label_height = a_from.label_height;           
314                                                   
315     labels_no_overlap_automated = a_from.label    
316     labels_gap = a_from.labels_gap;               
317                                                   
318     time_labels = a_from.time_labels;             
319     time_format = a_from.time_format;             
320     time_offset = a_from.time_offset;             
321     time_offset_is_GMT = a_from.time_offset_is    
322                                                   
323     m_line_style = a_from.m_line_style;           
324     m_ticks_style = a_from.m_ticks_style;         
325     m_labels_style = a_from.m_labels_style;       
326     m_mag_style = a_from.m_mag_style;             
327     m_title_style = a_from.m_title_style;         
328                                                   
329     return *this;                                 
330   }                                               
331 public:                                           
332   sg::line_style& line_style() {return m_line_    
333   sg::line_style& ticks_style() {return m_tick    
334   text_style& labels_style() {return m_labels_    
335   text_style& title_style() {return m_title_st    
336   text_style& mag_style() {return m_mag_style;    
337                                                   
338   void set_color(const colorf& a_color){          
339     m_line_style.color = a_color;                 
340     m_ticks_style.color = a_color;                
341     m_labels_style.color = a_color;               
342     m_title_style.color = a_color;                
343     m_mag_style.color = a_color;                  
344   }                                               
345 public:                                           
346   void update_sg(std::ostream& a_out) {           
347     //a_out << "debug : tools::axis::update_sg    
348                                                   
349     if(width<=0) {                                
350       m_line_sep.clear();                         
351       m_ticks_sep.clear();                        
352       m_labels_sep.clear();                       
353       m_mag_sep.clear();                          
354       m_title_sep.clear();                        
355       return;                                     
356     }                                             
357                                                   
358     // line scene graph :                         
359     m_line_sep.clear();                           
360     if(m_line_style.visible) {                    
361       rgba* mat = new rgba();                     
362       mat->color = m_line_style.color;            
363       m_line_sep.add(mat);                        
364                                                   
365       draw_style* ds = new draw_style;            
366       ds->style = draw_lines;                     
367       ds->line_pattern = m_line_style.pattern;    
368       ds->line_width = m_line_style.width;        
369       m_line_sep.add(ds);                         
370                                                   
371       vertices* vtxs = new vertices;              
372       vtxs->mode = gl::line_strip();              
373       vtxs->add(0,0,0);                           
374       vtxs->add(width,0,0);                       
375       m_line_sep.add(vtxs);                       
376     }                                             
377                                                   
378     // ticks scene graph :                        
379     if(modeling==tick_modeling_none()) {          
380     } else if(modeling==tick_modeling_hplot())    
381       compute_ticks_HPLOT(a_out);                 
382     } else {                                      
383       compute_ticks_hippo();                      
384     }                                             
385                                                   
386     m_ticks_sep.clear();                          
387     if(m_ticks_style.visible) {                   
388                                                   
389       vertices* vtxs = new vertices;              
390       vtxs->mode = gl::lines();                   
391                                                   
392       if(modeling==tick_modeling_hplot()) {       
393                                                   
394         size_t num = m_sub_ticks.size()/4;        
395         size_t pos = 0;                           
396         for(size_t index=0;index<num;index++)     
397           float bx = m_sub_ticks[pos];pos++;      
398           float by = m_sub_ticks[pos];pos++;      
399           float ex = m_sub_ticks[pos];pos++;      
400           float ey = m_sub_ticks[pos];pos++;      
401           if(tick_up) {                           
402             vtxs->add(bx,by,0);                   
403             vtxs->add(ex,ey,0);                   
404           } else {                                
405             vtxs->add(bx,-by,0);                  
406             vtxs->add(ex,-ey,0);                  
407           }                                       
408         }                                         
409                                                   
410       } else {                                    
411                                                   
412         float yy = tick_up ? tick_length.value    
413         for(unsigned int index=0;index<tick_nu    
414           float xx = coords.values()[index];      
415           vtxs->add(xx,0,0);                      
416           vtxs->add(xx,yy,0);                     
417         }                                         
418       }                                           
419                                                   
420       if(vtxs->number()) {                        
421                                                   
422         rgba* mat = new rgba();                   
423         mat->color = m_ticks_style.color;         
424         m_ticks_sep.add(mat);                     
425                                                   
426         draw_style* ds = new draw_style;          
427         ds->style = draw_lines;                   
428         ds->line_pattern = m_ticks_style.patte    
429         ds->line_width = m_ticks_style.width;     
430         m_ticks_sep.add(ds);                      
431                                                   
432         m_ticks_sep.add(vtxs);                    
433       } else {                                    
434         delete vtxs;                              
435       }                                           
436                                                   
437     }                                             
438                                                   
439     // labels scene graph :                       
440     m_labels_sep.clear();                         
441     if(m_labels_style.visible && tick_number )    
442       m_labels_seps.clear();                      
443       m_labels_xs.clear();                        
444       m_labels_mtxs.clear();                      
445                                                   
446       rgba* mat = new rgba();                     
447       mat->color = m_labels_style.color;          
448       m_labels_sep.add(mat);                      
449                                                   
450       float text_size = label_height*m_labels_    
451       std::string font = m_labels_style.font.v    
452                                                   
453       if(font==font_hershey()) {                  
454         draw_style* ds = new draw_style;          
455         ds->style = draw_lines;                   
456         ds->line_pattern = m_labels_style.line    
457         ds->line_width = m_labels_style.line_w    
458         m_labels_sep.add(ds);                     
459       } else {                                    
460         m_labels_sep.add(new normal);             
461       }                                           
462                                                   
463       vec3f X = m_labels_style.x_orientation.v    
464       vec3f Y = m_labels_style.y_orientation.v    
465       X.normalize();                              
466       Y.normalize();                              
467       vec3f Z;X.cross(Y,Z);                       
468       Z.cross(X,Y);                               
469       mat4f scale_rot(X.v0(),Y.v0(),Z.v0(),0,     
470                       X.v1(),Y.v1(),Z.v1(),0,     
471                       X.v2(),Y.v2(),Z.v2(),0,     
472                       0,0,0,1);                   
473       scale_rot.mul_scale(text_size,text_size,    
474                                                   
475       bool bin_center = (m_labels_style.option    
476                                                   
477       vec3f vec;float xx;                         
478      {unsigned int number = tick_number;          
479       for(unsigned int index=0;index<number;in    
480                                                   
481         if(bin_center) { //label at the center    
482     if(index==(number-1)) continue;               
483           xx = 0.5f*(coords.values()[index]+co    
484   } else { // label on tick :                     
485           xx = coords.values()[index];            
486   }                                               
487                                                   
488         vec.set_value(xx,-label_to_axis,0);       
489         vec += m_labels_style.translation.valu    
490                                                   
491         separator* sep = new separator;           
492         m_labels_sep.add(sep);                    
493                                                   
494         matrix* _tsf =                            
495     add_string_opt(*sep,                          
496                          font,                    
497                          m_labels_style.font_m    
498                          m_labels_style.encodi    
499                          m_labels_style.smooth    
500                          labels.values()[index    
501                          vec[0],vec[1],vec[2],    
502                          scale_rot,               
503                          m_labels_style.hjust,    
504                          m_labels_style.vjust,    
505                          m_ttf);                  
506         if(_tsf) {                                
507           m_labels_seps.push_back(sep);           
508           m_labels_xs.push_back(xx);              
509           m_labels_mtxs.push_back(_tsf);          
510         }                                         
511       }}                                          
512                                                   
513       if(labels_no_overlap_automated.value())     
514       m_labels_seps.clear();                      
515       m_labels_xs.clear();                        
516       m_labels_mtxs.clear();                      
517     }                                             
518                                                   
519     m_mag_sep.clear();                            
520     if( magnitude.value() && m_mag_style.visib    
521       rgba* mat = new rgba();                     
522       mat->color = m_mag_style.color;             
523       m_mag_sep.add(mat);                         
524                                                   
525       char string[64];                            
526       if(magnitude>=0)                            
527         snpf(string,sizeof(string),"x10+%d",ma    
528       else                                        
529         snpf(string,sizeof(string),"x10-%d",::    
530                                                   
531       vec3f vec(width*1.03f,0,0);                 
532       vec += m_mag_style.translation.value();     
533                                                   
534       float text_size = label_height*0.8f * m_    
535       std::string font = m_mag_style.font.valu    
536                                                   
537       if(font==font_hershey()) {                  
538         draw_style* ds = new draw_style;          
539         ds->style = draw_lines;                   
540         ds->line_pattern = m_mag_style.line_pa    
541         ds->line_width = m_mag_style.line_widt    
542         m_mag_sep.add(ds);                        
543       }                                           
544                                                   
545       add_string(m_mag_sep,                       
546                          font,                    
547                          m_mag_style.font_mode    
548                          m_mag_style.encoding.    
549                          m_mag_style.smoothing    
550                          string,                  
551                          vec[0],vec[1],vec[2],    
552                          m_mag_style.x_orienta    
553                          m_mag_style.y_orienta    
554                          text_size,               
555                          m_mag_style.hjust,       
556                          m_mag_style.vjust,       
557                          m_ttf);                  
558     }                                             
559                                                   
560     // title scene graph :if(update_title) {      
561     m_title_sep.clear();                          
562     if(title.value().size() && m_title_style.v    
563       rgba* mat = new rgba();                     
564       mat->color = m_title_style.color;           
565       m_title_sep.add(mat);                       
566                                                   
567       float text_size = title_height*m_title_s    
568       std::string font = m_title_style.font.va    
569                                                   
570       if(font==font_hershey()) {                  
571         draw_style* ds = new draw_style;          
572         ds->style = draw_lines;                   
573         ds->line_pattern = m_title_style.line_    
574         ds->line_width = m_title_style.line_wi    
575         m_title_sep.add(ds);                      
576       } else {                                    
577         m_title_sep.add(new normal);              
578       }                                           
579                                                   
580       float xx = 0; //left                        
581       if(title_hjust==center) {                   
582          xx = width/2;                            
583       } else if(title_hjust==right) {             
584          xx = width;                              
585       }                                           
586                                                   
587       vec3f vec(xx,-title_to_axis,0);             
588       vec += m_title_style.translation.value()    
589                                                   
590       //std::cout << "debug : axis : update_ti    
591       //          << " pos : " << vec[0] << "     
592       //          << std::endl;                   
593                                                   
594       add_string(m_title_sep,                     
595                          font,                    
596                          m_title_style.font_mo    
597                          m_title_style.encodin    
598                          m_title_style.smoothi    
599                          title.value(),           
600                          vec[0],vec[1],vec[2],    
601                          m_title_style.x_orien    
602                          m_title_style.y_orien    
603                          text_size,               
604                          m_title_style.hjust,     
605                          m_title_style.vjust,     
606                          m_ttf);                  
607     }                                             
608                                                   
609   }                                               
610                                                   
611 public: //style                                   
612   void reset_style(bool a_geom = false) {         
613     //reset fields that are considered as part    
614                                                   
615     //////////////////////////////////////////    
616     // we do not touch :                          
617     //////////////////////////////////////////    
618     //width                                       
619     //minimum_value                               
620     //maximum_value                               
621     //labels_enforced                             
622     //tick_number                                 
623     //magnitude                                   
624     //time_labels                                 
625     //time_format                                 
626     //time_offset                                 
627     //time_offset_is_GMT                          
628     //labels                                      
629     //values                                      
630     //coords                                      
631     //sub_coords                                  
632                                                   
633     //////////////////////////////////////////    
634     divisions = 510;                              
635     modeling = tick_modeling_hippo();             
636     tick_up = true;                               
637     is_log = false;                               
638     title.value().clear();                        
639                                                   
640     labels_no_overlap_automated = true;           
641     labels_gap = 0.02f;                           
642                                                   
643     if(a_geom) {                                  
644     //////////////////////////////////////////    
645     // Take PAW default :                         
646     float YSIZ = 20; //page height                
647     float YMGL = 2;  //low y margin (to data f    
648     float YMGU = 2;  //up y margin (to data fr    
649     float VSIZ = 0.28F; //tick label character    
650     float YVAL = 0.4F;  //y distance of x tick    
651     float XTIC = 0.3F;  //y length of X axis t    
652     float YLAB = 0.8F; //y distance of x title    
653     float ASIZ = 0.28F; // axis title (label)     
654                                                   
655     float hData = YSIZ-YMGL-YMGU;                 
656                                                   
657     // To map data space to width :               
658     float to1 = width/hData;                      
659                                                   
660     float vsiz = VSIZ * to1; //0.0175F            
661     float yval = YVAL * to1; //0.025F             
662     float xtic = XTIC * to1; //0.01875F           
663     float ylab = YLAB * to1; //0.05F              
664     float asiz = ASIZ * to1; //0.0175F            
665                                                   
666     //sf                                          
667     tick_length = xtic;                           
668     label_to_axis = yval;                         
669     label_height = vsiz;                          
670                                                   
671     // The axis title is the PAW axis label.      
672     // It is right justified at the end of axi    
673     // (at end right for XY_X, at end top for     
674     title_to_axis = ylab;                         
675     title_height = asiz;                          
676     }                                             
677                                                   
678     title_hjust = right;                          
679                                                   
680     //////////////////////////////////////////    
681     // setup styles :                             
682     m_line_style = line_style();                  
683     m_ticks_style = line_style();                 
684     m_labels_style = text_style();                
685     m_mag_style = text_style();                   
686     m_title_style = text_style();                 
687                                                   
688     m_line_style.color = colorf_black();          
689     m_ticks_style.color = colorf_black();         
690                                                   
691     m_labels_style.color = colorf_black();        
692     m_labels_style.font = font_hershey();         
693     m_labels_style.encoding = encoding_PAW();     
694                                                   
695     m_mag_style.color = colorf_black();           
696     m_mag_style.font = font_hershey();            
697     m_mag_style.encoding = encoding_PAW();        
698                                                   
699     m_title_style.color = colorf_black();         
700     m_title_style.font = font_hershey();          
701     m_title_style.encoding = encoding_PAW();      
702   }                                               
703                                                   
704   typedef std::pair<std::string,std::string> s    
705   typedef std::vector<style_item_t> style_t;      
706   bool set_from_style(std::ostream& a_out,cons    
707     style_t::const_iterator it;                   
708     for(it=a_style.begin();it!=a_style.end();+    
709       const std::string& key = (*it).first;       
710       const std::string& sv = (*it).second;       
711       //::printf("debug : axis::set_from_style    
712       //if(key=="reset") {}                       
713                                                   
714       // not part of style :                      
715       //width                                     
716       //minimum_value                             
717       //maximum_value                             
718       //labels_enforced                           
719       //tick_number                               
720       //magnitude                                 
721       //title                                     
722       //time_labels                               
723       //time_format                               
724       //time_offset                               
725       //time_offset_is_GMT                        
726       //labels                                    
727       //values                                    
728       //coords                                    
729       //sub_coords                                
730                                                   
731       if(key=="divisions") {                      
732         unsigned int v;                           
733         if(!to(sv,v)) {style_failed(a_out,key,    
734         divisions = v;                            
735       } else if(key=="modeling") {                
736         modeling = sv;                            
737       } else if(key=="is_log") {                  
738         bool v;                                   
739         if(!to(sv,v)) {style_failed(a_out,key,    
740         is_log = v;                               
741                                                   
742       } else if(key=="tick_up") {                 
743         bool v;                                   
744         if(!to(sv,v)) {style_failed(a_out,key,    
745         tick_up = v;                              
746       } else if(key=="tick_length") {             
747         float v;                                  
748         if(!to(sv,v)) {style_failed(a_out,key,    
749         tick_length = v;                          
750                                                   
751       } else if(key=="title") {                   
752         title = sv;                               
753       } else if(key=="title_to_axis") {           
754         float v;                                  
755         if(!to(sv,v)) {style_failed(a_out,key,    
756         title_to_axis = v;                        
757       } else if(key=="title_height") {            
758         float v;                                  
759         if(!to(sv,v)) {style_failed(a_out,key,    
760         title_height = v;                         
761       } else if(key=="title_hjust") {             
762         hjust v;                                  
763         if(!shjust(sv,v))                         
764           {style_failed(a_out,key,sv);return f    
765         title_hjust = v;                          
766                                                   
767       } else if(key=="label_to_axis") {           
768         float v;                                  
769         if(!to(sv,v)) {style_failed(a_out,key,    
770         label_to_axis = v;                        
771       } else if(key=="label_height") {            
772         float v;                                  
773         if(!to(sv,v)) {style_failed(a_out,key,    
774         label_height = v;                         
775                                                   
776       } else if(key=="labels_no_overlap_automa    
777         bool v;                                   
778         if(!to(sv,v)) {style_failed(a_out,key,    
779         labels_no_overlap_automated = v;          
780       } else if(key=="labels_gap") {              
781         float v;                                  
782         if(!to(sv,v)) {style_failed(a_out,key,    
783         labels_gap = v;                           
784                                                   
785       } else {                                    
786         a_out << "axis::set_from_style :"         
787               << " unknown key " << key << "."    
788               << std::endl;                       
789       }                                           
790     }                                             
791     return true;                                  
792   }                                               
793                                                   
794   void set_encoding(const std::string& a_value    
795     labels_style().encoding = a_value;            
796     mag_style().encoding = a_value;               
797     title_style().encoding = a_value;             
798   }                                               
799 protected:                                        
800   float get_overlap(std::ostream& a_out,bool&     
801     a_overlap = false;                            
802     std::vector<float> x_mins;                    
803     std::vector<float> x_maxs;                    
804    {size_t index = 0;                             
805     bbox_action _action(a_out);                   
806     tools_vforcit(separator*,m_labels_seps,it)    
807       _action.reset();                            
808       (*it)->bbox(_action);                       
809       if(_action.end()) {                         
810         float dx,dy,dz;                           
811         if(_action.box().get_size(dx,dy,dz)) {    
812           if(dx>0) {                              
813             x_mins.push_back(m_labels_xs[index    
814             x_maxs.push_back(m_labels_xs[index    
815           }                                       
816         }                                         
817       }                                           
818       index++;                                    
819     }}                                            
820     float dx_overlap = 0;                         
821    {size_t number = x_mins.size();                
822     for(size_t index=1;index<number;index++) {    
823       float dx = x_mins[index]-x_maxs[index-1]    
824       if(dx<0) {                                  
825         a_overlap = true;                         
826   dx_overlap = mx(dx_overlap,-dx);                
827       }                                           
828     }}                                            
829     return dx_overlap;                            
830   }                                               
831   void avoid_labels_overlap(std::ostream& a_ou    
832     bool overlap;                                 
833     float first_scale = 1;                        
834     float first_overlap = get_overlap(a_out,ov    
835     if(overlap) {                                 
836       float second_scale = 1.1f; // greater th    
837      {tools_vforcit(matrix*,m_labels_mtxs,it)     
838         (*it)->mul_scale(second_scale,second_s    
839       }}                                          
840       float second_overlap = get_overlap(a_out    
841       if(overlap) {                               
842         // first_overlap  = a*first_scale+b       
843         // second_overlap = a*second_scale+b      
844   float a = (second_overlap-first_overlap)/(se    
845   float b = first_overlap-a*first_scale;          
846       //float wanted_scale = -b/a; //zero over    
847         float wanted_gap = width.value()*label    
848         float wanted_scale = (a==0.0f) ? 1 : (    
849         if(wanted_scale<=0) wanted_scale = 1;     
850         wanted_scale /= second_scale;             
851        {tools_vforcit(matrix*,m_labels_mtxs,it    
852           (*it)->mul_scale(wanted_scale,wanted    
853         }}                                        
854       } else { //it should not happen.            
855         tools_vforcit(matrix*,m_labels_mtxs,it    
856           (*it)->mul_scale(1.0f/second_scale,1    
857         }                                         
858       }                                           
859     }                                             
860   }                                               
861                                                   
862   static void style_failed(std::ostream& a_out    
863                            const std::string&     
864                            const std::string&     
865     a_out << "axis::set_from_style :"             
866           << " failed for key " << sout(a_key)    
867           << " and value " << sout(a_value) <<    
868           << std::endl;                           
869   }                                               
870 protected:                                        
871   ////////////////////////////////////////////    
872   /// Hippodraw tick modeling ////////////////    
873   ////////////////////////////////////////////    
874   void compute_ticks_hippo() {                    
875     //  input fields :                            
876     //    minimum_value                           
877     //    maximum_value                           
878     //    is_log                                  
879     //  output fields :                           
880     //    values                                  
881     //    coords                                  
882     //    sub_coords                              
883     //    labels (if labels_enforced is false)    
884     //    tick_number                             
885                                                   
886                                                   
887     float mn = minimum_value;                     
888     float mx = maximum_value;                     
889                                                   
890     bool a_is_log = is_log;                       
891     if(a_is_log) {                                
892       if((mn<=0) || (mx<=0) ) a_is_log = false    
893     }                                             
894                                                   
895     float magxxx,y,yr,startTick,tickSize;         
896     float pmag;                                   
897     char pstr[10] = "";                           
898     char tmp[10];                                 
899                                                   
900     unsigned int tick_num = 0;                    
901     std::vector<float> tick_values;               
902     std::vector<std::string> tick_labels;         
903                                                   
904     // need include <float.h> which does not e    
905     //NUM_FUZZ DBL_EPSILON*4                      
906     float NUM_FUZZ = 0.01f;                       
907                                                   
908     if (mn >= mx) {                               
909       if(tick_number) {                           
910         tick_number.value(0);                     
911         values.clear();                           
912         coords.clear();                           
913         sub_coords.clear();                       
914         labels.clear();                           
915       }                                           
916       if(magnitude.value()) magnitude.value(0)    
917       m_sub_ticks.clear();                        
918       return;                                     
919     }                                             
920                                                   
921     if (!a_is_log) {                              
922                                                   
923       tickSize  = calculate_ticks_hippo(mx-mn,    
924       startTick = fceil( mn / tickSize) * tick    
925                                                   
926       if (ffabs(magxxx) <= 3)                     
927         pmag = 0.0;                               
928       else                                        
929         pmag = startTick != 0.0 ? ffloor(flog1    
930                                                   
931       snpf(pstr,sizeof(pstr),"%%1.%df",(int)ma    
932                                                   
933       y = startTick;                              
934       while (y <= mx*(1.0+NUM_FUZZ)) {            
935                                                   
936         yr = ffloor(y/fpow(10,magxxx) + 0.5F);    
937                                                   
938         snpf(tmp,sizeof(tmp),pstr,yr*fpow(10,m    
939                                                   
940        {float val = yr * fpow(10.0,magxxx);       
941         if((val>=mn)&&(val<=mx)) { //G.Barrand    
942           tick_values.push_back(val);             
943           tick_labels.push_back(tmp);             
944           tick_num++;                             
945         }}                                        
946                                                   
947         y += tickSize;                            
948       }                                           
949       if (ffabs(magxxx) <= 3.0) magxxx = 0.0;     
950                                                   
951     }  else {                                     
952                                                   
953       if (mn <= 0) {                              
954         if(tick_number) {                         
955           tick_number.value(0);                   
956           values.clear();                         
957           coords.clear();                         
958           sub_coords.clear();                     
959           labels.clear();                         
960         }                                         
961         if(magnitude.value()) magnitude.value(    
962         m_sub_ticks.clear();                      
963         return;                                   
964       }                                           
965                                                   
966       int nLogTicks;                              
967       float logTicks[5];                          
968       float magStep;                              
969                                                   
970       float maghigh = fceil(flog10(mx));          
971       float maglow  = ffloor(flog10(mn));         
972       float magrng  = maghigh - maglow;           
973                                                   
974       if (magrng <=3) {                           
975         nLogTicks   = 3;                          
976         logTicks[0] = 1.0;                        
977         logTicks[1] = 2.0;                        
978         logTicks[2] = 5.0;                        
979         magStep     = 1.0;                        
980       } else {                                    
981         nLogTicks   = 1;                          
982         logTicks[0] = 1.0;                        
983         magStep     = magrng <= 7 ? 1.0F : 2.0    
984       }                                           
985                                                   
986       pmag = (nLogTicks == 3 && (ffabs(maglow)    
987         maglow : 0;                               
988                                                   
989       magxxx = maglow;                            
990       int i = 0;                                  
991       while ((y=logTicks[i]*fpow(10,magxxx)) <    
992         if (y >= mn) {                            
993                                                   
994           // be careful: there is a bug in the    
995           //   routine when you do, eg. printf    
996           if ((magxxx-pmag) > 4 || (magxxx-pma    
997             ::strcpy(pstr,"%1.0e");               
998           } else {                                
999             snpf(pstr,sizeof(pstr),               
1000                  "%%1.%df",(int)((magxxx-pmag    
1001           }                                      
1002           snpf(tmp,sizeof(tmp),pstr,y*fpow(10    
1003                                                  
1004          {float val = flog10(y);                 
1005           if((val>=flog10(mn))&&(val<=flog10(    
1006             tick_values.push_back(val);          
1007             tick_labels.push_back(tmp);          
1008             tick_num++;                          
1009           }}                                     
1010                                                  
1011         }                                        
1012                                                  
1013         i++;                                     
1014         if (i>=nLogTicks)        {               
1015           i = 0;                                 
1016           magxxx += magStep;                     
1017         }                                        
1018       }                                          
1019                                                  
1020       mn = flog10(mn);                           
1021       mx = flog10(mx);                           
1022     }                                            
1023                                                  
1024     float range = mx - mn;                       
1025                                                  
1026     // it is assumes that tick_values are ord    
1027     tick_number.value(tick_num);                 
1028     values.clear();                              
1029     coords.clear();                              
1030     for(unsigned int index=0;index<tick_num;i    
1031       float val = tick_values[index];            
1032       float coord = width * (val-mn)/range;      
1033       values.add(val);                           
1034       coords.add(coord);                         
1035     }                                            
1036                                                  
1037     if(labels_enforced) {                        
1038       size_t n = labels.size();                  
1039       if(tick_num>n) {                           
1040         for(size_t index=n;index<tick_num;ind    
1041       }                                          
1042     } else {                                     
1043       labels = tick_labels;                      
1044     }                                            
1045                                                  
1046     magnitude.value((int)pmag);                  
1047                                                  
1048     sub_coords.clear();                          
1049     m_sub_ticks.clear();                         
1050   }                                              
1051                                                  
1052   static float calculate_ticks_hippo(float aS    
1053     unsigned int MIN_TICKS = 4;                  
1054                                                  
1055     if (aSize <= 0.0) {                          
1056       //printf ("CalculateTicks : bad value \    
1057       aSize = ffabs(aSize);                      
1058       if (aSize == 0.0) aSize = 1.0;             
1059     }                                            
1060                                                  
1061     a_mag = ffloor(flog10(aSize));               
1062     if (aSize/fpow(10.0,a_mag) < MIN_TICKS) (    
1063                                                  
1064     // now fit the max number of ticks into t    
1065                                                  
1066     float  tickSize;                             
1067     int tickIndex;                               
1068     static const float goodTicks[] = {10.0, 5    
1069     for(tickIndex = 0;                           
1070        aSize/(tickSize=goodTicks[tickIndex]*f    
1071         tickIndex++){}                           
1072                                                  
1073     if (tickIndex == 0) a_mag++;                 
1074                                                  
1075     return tickSize;                             
1076   }                                              
1077                                                  
1078   ///////////////////////////////////////////    
1079   /// HPLOT tick modeling ///////////////////    
1080   ///////////////////////////////////////////    
1081   ///////////////////////////////////////////    
1082   void compute_ticks_HPLOT(std::ostream& a_ou    
1083     //  Controlled by fields :                   
1084     //    minimum_value                          
1085     //    maximum_value                          
1086     //    divisions                              
1087     //    is_log                                 
1088     //  Set value on fields :                    
1089     //    values                                 
1090     //    coords                                 
1091     //    labels (if labels_enforced is false    
1092     //    tick_number                            
1093                                                  
1094     float mn = minimum_value;                    
1095     float mx = maximum_value;                    
1096                                                  
1097     bool a_is_log = is_log;                      
1098     if(a_is_log) {                               
1099       if((mn<=0) || (mx<=0) ) a_is_log = fals    
1100     }                                            
1101                                                  
1102     // Use hplot::axis to get the ticks and s    
1103     // and the labels text.                      
1104                                                  
1105     double xmin = 0;                             
1106     double ymin = 0;                             
1107     double xmax = width;                         
1108     double ymax = 0;                             
1109                                                  
1110     double gridlength = 0;                       
1111     std::string chopt;                           
1112     if(a_is_log) chopt += "G";                   
1113                                                  
1114     std::vector<float> linesGrid;                
1115     std::vector<hplot::_text> texts;             
1116                                                  
1117     hplot::axis sbAxisHPLOT(a_out);              
1118                                                  
1119     chopt += "S";                                
1120     sbAxisHPLOT.set_tick_size(tick_length/wid    
1121                                                  
1122     if(time_labels.value()) {                    
1123       chopt += "t";                              
1124       sbAxisHPLOT.set_time_format(time_format    
1125       sbAxisHPLOT.set_time_offset(time_offset    
1126                                   time_offset    
1127     }                                            
1128                                                  
1129     // Get ticks :                               
1130    {double wmin = mn;                            
1131     double wmax = mx;                            
1132     int ndiv = divisions;                        
1133     sbAxisHPLOT.set_title("");                   
1134     sbAxisHPLOT.paint(xmin,ymin,xmax,ymax,       
1135                       wmin,wmax,ndiv, //Modif    
1136                       chopt,gridlength,false,    
1137                       m_sub_ticks,linesGrid,t    
1138                                                  
1139     if(a_is_log) {                               
1140       mn = flog10(mn);                           
1141       mx = flog10(mx);                           
1142     }                                            
1143                                                  
1144     float range = mx - mn;                       
1145                                                  
1146     size_t tick_num = texts.size();              
1147                                                  
1148     // HPLOT stores the magnitude on the last    
1149     magnitude.value(0);                          
1150     if(tick_num) {                               
1151       int pmag;                                  
1152       if(::sscanf(texts[tick_num-1].fString.c    
1153         magnitude.value(pmag);                   
1154         tick_num--;                              
1155       }                                          
1156     }                                            
1157                                                  
1158     tick_number.value(uint32(tick_num));         
1159     values.clear();                              
1160     coords.clear();                              
1161     for(size_t index=0;index<tick_num;index++    
1162       float coord = (float)texts[index].fX;      
1163       //NOTE : are we sure that val is in [mn    
1164       float val = (coord/width.value()) * ran    
1165       coords.add(coord);                         
1166       values.add(val);                           
1167     }                                            
1168                                                  
1169     if(labels_enforced) {                        
1170       size_t n = labels.size();                  
1171       if(tick_num>n) {                           
1172         for(size_t index=n;index<tick_num;ind    
1173       }                                          
1174     } else {                                     
1175       labels.clear();                            
1176       for(size_t index=0;index<tick_num;index    
1177         labels.add(texts[index].fString);        
1178       }                                          
1179     }                                            
1180                                                  
1181    {sub_coords.clear();                          
1182     size_t num = m_sub_ticks.size()/4;           
1183     size_t pos = 0;                              
1184     for(size_t index=0;index<num;index++) {      
1185       float coord = m_sub_ticks[pos];            
1186       pos += 4;                                  
1187       bool found = false;                        
1188       for(size_t i=0;i<tick_num;i++) {           
1189         if((float)texts[i].fX==coord) {          
1190           found = true;                          
1191           break;                                 
1192         }                                        
1193       }                                          
1194       if(!found) { //not a main tick             
1195         sub_coords.add(coord);                   
1196       }                                          
1197     }}                                           
1198   }                                              
1199                                                  
1200 protected:                                       
1201   const base_freetype& m_ttf;                    
1202                                                  
1203   group m_group;                                 
1204                                                  
1205   separator m_line_sep;                          
1206   separator m_ticks_sep;                         
1207   separator m_labels_sep;                        
1208   separator m_mag_sep;                           
1209   separator m_title_sep;                         
1210                                                  
1211   sg::line_style m_line_style;                   
1212   sg::line_style m_ticks_style;                  
1213   text_style m_labels_style;                     
1214   text_style m_mag_style;                        
1215   text_style m_title_style;                      
1216                                                  
1217   std::vector<float> m_sub_ticks; //n*(2+2)      
1218                                                  
1219   std::vector<separator*> m_labels_seps;         
1220   std::vector<float> m_labels_xs;                
1221   std::vector<matrix*> m_labels_mtxs;            
1222 };                                               
1223                                                  
1224 }}                                               
1225                                                  
1226 #endif