Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 2 // See the file tools.license for terms. 3 3 4 #ifndef tools_sg_text_hershey 4 #ifndef tools_sg_text_hershey 5 #define tools_sg_text_hershey 5 #define tools_sg_text_hershey 6 6 7 #include "base_text" 7 #include "base_text" 8 #include "enums" 8 #include "enums" 9 #include "strings" 9 #include "strings" 10 #include "render_action" 10 #include "render_action" 11 #include "pick_action" 11 #include "pick_action" 12 #include "bbox_action" 12 #include "bbox_action" 13 #include "gstos" 13 #include "gstos" 14 #include "sf_string" 14 #include "sf_string" 15 15 16 #include "../hershey" 16 #include "../hershey" 17 #include "../lina/box_3f" 17 #include "../lina/box_3f" 18 #include "../mnmx" 18 #include "../mnmx" 19 19 20 namespace tools { 20 namespace tools { 21 namespace sg { 21 namespace sg { 22 22 23 class hchar { 23 class hchar { 24 #ifdef TOOLS_MEM 24 #ifdef TOOLS_MEM 25 TOOLS_SCLASS(tools::sg::hchar) 25 TOOLS_SCLASS(tools::sg::hchar) 26 #endif 26 #endif 27 public: 27 public: 28 hchar() 28 hchar() 29 :m_char(0) 29 :m_char(0) 30 ,m_font(sg::latin) 30 ,m_font(sg::latin) 31 ,m_y_move(none) 31 ,m_y_move(none) 32 ,m_back(false) 32 ,m_back(false) 33 ,m_bar(false) 33 ,m_bar(false) 34 ,m_cr(false) 34 ,m_cr(false) 35 { 35 { 36 #ifdef TOOLS_MEM 36 #ifdef TOOLS_MEM 37 mem::increment(s_class().c_str()); 37 mem::increment(s_class().c_str()); 38 #endif 38 #endif 39 } 39 } 40 virtual ~hchar(){ 40 virtual ~hchar(){ 41 #ifdef TOOLS_MEM 41 #ifdef TOOLS_MEM 42 mem::decrement(s_class().c_str()); 42 mem::decrement(s_class().c_str()); 43 #endif 43 #endif 44 } 44 } 45 public: 45 public: 46 hchar(const hchar& aFrom) 46 hchar(const hchar& aFrom) 47 :m_char(aFrom.m_char) 47 :m_char(aFrom.m_char) 48 ,m_font(aFrom.m_font) 48 ,m_font(aFrom.m_font) 49 ,m_y_move(aFrom.m_y_move) 49 ,m_y_move(aFrom.m_y_move) 50 ,m_back(aFrom.m_back) 50 ,m_back(aFrom.m_back) 51 ,m_bar(aFrom.m_bar) 51 ,m_bar(aFrom.m_bar) 52 ,m_cr(aFrom.m_cr) 52 ,m_cr(aFrom.m_cr) 53 { 53 { 54 #ifdef TOOLS_MEM 54 #ifdef TOOLS_MEM 55 mem::increment(s_class().c_str()); 55 mem::increment(s_class().c_str()); 56 #endif 56 #endif 57 } 57 } 58 hchar& operator=(const hchar& aFrom) { 58 hchar& operator=(const hchar& aFrom) { 59 m_char = aFrom.m_char; 59 m_char = aFrom.m_char; 60 m_font = aFrom.m_font; 60 m_font = aFrom.m_font; 61 m_y_move = aFrom.m_y_move; 61 m_y_move = aFrom.m_y_move; 62 m_back = aFrom.m_back; 62 m_back = aFrom.m_back; 63 m_bar = aFrom.m_bar; 63 m_bar = aFrom.m_bar; 64 m_cr = aFrom.m_cr; 64 m_cr = aFrom.m_cr; 65 return *this; 65 return *this; 66 } 66 } 67 public: 67 public: 68 enum e_move { 68 enum e_move { 69 none, 69 none, 70 up, 70 up, 71 down 71 down 72 }; 72 }; 73 public: 73 public: 74 char m_char; 74 char m_char; 75 font_type m_font; 75 font_type m_font; 76 e_move m_y_move; 76 e_move m_y_move; 77 bool m_back; 77 bool m_back; 78 bool m_bar; 78 bool m_bar; 79 bool m_cr; 79 bool m_cr; 80 }; 80 }; 81 81 82 class text_hershey : public base_text, public 82 class text_hershey : public base_text, public gstos { 83 public: 83 public: 84 TOOLS_NODE(text_hershey,tools::sg::text_hers 84 TOOLS_NODE(text_hershey,tools::sg::text_hershey,base_text) 85 public: 85 public: 86 sf_string encoding; 86 sf_string encoding; 87 sf_enum<font_type> font; 87 sf_enum<font_type> font; 88 public: 88 public: 89 virtual const desc_fields& node_desc_fields( 89 virtual const desc_fields& node_desc_fields() const { 90 TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::tex 90 TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::text_hershey) 91 static const desc_fields s_v(parent::node_ 91 static const desc_fields s_v(parent::node_desc_fields(),2, //WARNING : take care of count. 92 TOOLS_ARG_FIELD_DESC(encoding), 92 TOOLS_ARG_FIELD_DESC(encoding), 93 TOOLS_ARG_FIELD_DESC(font) 93 TOOLS_ARG_FIELD_DESC(font) 94 ); 94 ); 95 return s_v; 95 return s_v; 96 } 96 } 97 private: 97 private: 98 void add_fields(){ 98 void add_fields(){ 99 add_field(&encoding); 99 add_field(&encoding); 100 add_field(&font); 100 add_field(&font); 101 } 101 } 102 protected: //gstos 102 protected: //gstos 103 virtual unsigned int create_gsto(std::ostrea 103 virtual unsigned int create_gsto(std::ostream&,sg::render_manager& a_mgr) { 104 std::vector<float> gsto_data; 104 std::vector<float> gsto_data; 105 105 106 {size_t npts = m_segs.size()/2; //2 coords 106 {size_t npts = m_segs.size()/2; //2 coords 107 size_t ngsto = npts*3; //3 coords. 107 size_t ngsto = npts*3; //3 coords. 108 size_t sz = gsto_data.size(); 108 size_t sz = gsto_data.size(); 109 gsto_data.resize(sz+ngsto); 109 gsto_data.resize(sz+ngsto); 110 float* pxyz = vec_data<float>(gsto_data)+s 110 float* pxyz = vec_data<float>(gsto_data)+sz; 111 const float* data = vec_data<float>(m_segs 111 const float* data = vec_data<float>(m_segs); 112 gl::cvt_2to3(npts,data,pxyz);} 112 gl::cvt_2to3(npts,data,pxyz);} 113 113 114 m_gsto_sz = gsto_data.size(); 114 m_gsto_sz = gsto_data.size(); 115 115 116 if(gsto_data.empty()) return 0; 116 if(gsto_data.empty()) return 0; 117 117 118 return a_mgr.create_gsto_from_data(gsto_da 118 return a_mgr.create_gsto_from_data(gsto_data); 119 } 119 } 120 public: 120 public: 121 virtual void render(render_action& a_action) 121 virtual void render(render_action& a_action) { 122 if(touched()) { 122 if(touched()) { 123 update_sg(); 123 update_sg(); 124 reset_touched(); 124 reset_touched(); 125 } 125 } 126 const state& state = a_action.state(); 126 const state& state = a_action.state(); 127 if(state.m_use_gsto) { 127 if(state.m_use_gsto) { 128 unsigned int _id = get_gsto_id(a_action. 128 unsigned int _id = get_gsto_id(a_action.out(),a_action.render_manager()); 129 if(_id) { 129 if(_id) { 130 a_action.begin_gsto(_id); 130 a_action.begin_gsto(_id); 131 a_action.draw_gsto_v(gl::lines(),m_gst 131 a_action.draw_gsto_v(gl::lines(),m_gsto_sz/3,0); 132 a_action.end_gsto(); 132 a_action.end_gsto(); 133 return; 133 return; 134 134 135 } else { //!_id 135 } else { //!_id 136 // use immediate rendering. 136 // use immediate rendering. 137 } 137 } 138 138 139 } else { 139 } else { 140 clean_gstos(&a_action.render_manager()); 140 clean_gstos(&a_action.render_manager()); 141 } 141 } 142 142 143 // immediate rendering : 143 // immediate rendering : 144 a_action.draw_vertex_array_xy(gl::lines(), 144 a_action.draw_vertex_array_xy(gl::lines(),m_segs); 145 } 145 } 146 146 147 virtual void pick(pick_action& a_action) { 147 virtual void pick(pick_action& a_action) { 148 if(touched()) { 148 if(touched()) { 149 update_sg(); 149 update_sg(); 150 reset_touched(); 150 reset_touched(); 151 } 151 } 152 a_action.add__lines_xy(*this,m_segs,true); 152 a_action.add__lines_xy(*this,m_segs,true); 153 } 153 } 154 154 155 virtual void bbox(bbox_action& a_action) { 155 virtual void bbox(bbox_action& a_action) { 156 if(touched()) { 156 if(touched()) { 157 update_sg(); 157 update_sg(); 158 reset_touched(); 158 reset_touched(); 159 } 159 } 160 160 161 float x,y; 161 float x,y; 162 std::vector<float>::const_iterator it; 162 std::vector<float>::const_iterator it; 163 for(it=m_segs.begin();it!=m_segs.end();) { 163 for(it=m_segs.begin();it!=m_segs.end();) { 164 x = *it;it++; 164 x = *it;it++; 165 y = *it;it++; 165 y = *it;it++; 166 a_action.add_one_point(x,y,0); 166 a_action.add_one_point(x,y,0); 167 } 167 } 168 } 168 } 169 169 170 public: 170 public: 171 text_hershey() 171 text_hershey() 172 :parent() 172 :parent() 173 ,encoding(encoding_none()) 173 ,encoding(encoding_none()) 174 ,font(sg::latin) 174 ,font(sg::latin) 175 ,m_gsto_sz(0) 175 ,m_gsto_sz(0) 176 { 176 { 177 add_fields(); 177 add_fields(); 178 } 178 } 179 virtual ~text_hershey(){} 179 virtual ~text_hershey(){} 180 public: 180 public: 181 text_hershey(const text_hershey& a_from) 181 text_hershey(const text_hershey& a_from) 182 :parent(a_from) 182 :parent(a_from) 183 ,gstos(a_from) 183 ,gstos(a_from) 184 ,encoding(a_from.encoding) 184 ,encoding(a_from.encoding) 185 ,font(a_from.font) 185 ,font(a_from.font) 186 ,m_gsto_sz(0) 186 ,m_gsto_sz(0) 187 { 187 { 188 add_fields(); 188 add_fields(); 189 } 189 } 190 text_hershey& operator=(const text_hershey& 190 text_hershey& operator=(const text_hershey& a_from){ 191 parent::operator=(a_from); 191 parent::operator=(a_from); 192 gstos::operator=(a_from); 192 gstos::operator=(a_from); 193 encoding = a_from.encoding; 193 encoding = a_from.encoding; 194 font = a_from.font; 194 font = a_from.font; 195 return *this; 195 return *this; 196 } 196 } 197 public: //sg::base_text : 197 public: //sg::base_text : 198 virtual void get_bounds(float a_height, 198 virtual void get_bounds(float a_height, 199 float& a_mn_x,float& 199 float& a_mn_x,float& a_mn_y,float& a_mn_z, 200 float& a_mx_x,float& 200 float& a_mx_x,float& a_mx_y,float& a_mx_z) const { 201 get_bounds(a_height,encoding.value(),font. 201 get_bounds(a_height,encoding.value(),font.value(), 202 strings.values(), 202 strings.values(), 203 a_mn_x,a_mn_y,a_mn_z, 203 a_mn_x,a_mn_y,a_mn_z, 204 a_mx_x,a_mx_y,a_mx_z); 204 a_mx_x,a_mx_y,a_mx_z); 205 } 205 } 206 virtual float ascent(float a_height) const { 206 virtual float ascent(float a_height) const { 207 // '/' seems to be the char with the max a 207 // '/' seems to be the char with the max ascent. 208 // NOTE : If 'A', the ascent = height.valu 208 // NOTE : If 'A', the ascent = height.value(). 209 float mn_x,mn_y,mn_z; 209 float mn_x,mn_y,mn_z; 210 float mx_x,mx_y,mx_z; 210 float mx_x,mx_y,mx_z; 211 get_char_bound('/',sg::latin,a_height,fals 211 get_char_bound('/',sg::latin,a_height,false, 212 mn_x,mn_y,mn_z, 212 mn_x,mn_y,mn_z, 213 mx_x,mx_y,mx_z); 213 mx_x,mx_y,mx_z); 214 return mx_y; 214 return mx_y; 215 } 215 } 216 virtual float y_advance(float a_height) cons 216 virtual float y_advance(float a_height) const { 217 float HEIGHT = a_height; 217 float HEIGHT = a_height; 218 return 2 * HEIGHT; //Y_ADVANCE 218 return 2 * HEIGHT; //Y_ADVANCE 219 } 219 } 220 220 221 public: 221 public: 222 virtual float descent(float a_height) const 222 virtual float descent(float a_height) const {return _descent(a_height);} 223 223 224 virtual bool truncate(const std::string& a_s 224 virtual bool truncate(const std::string& a_string,float a_height,float a_cut_width,std::string& a_out) const { 225 return _truncate(a_string,a_height,font.va 225 return _truncate(a_string,a_height,font.value(),a_cut_width,a_out); 226 } 226 } 227 227 228 public: 228 public: 229 static void get_bounds(float a_height, 229 static void get_bounds(float a_height, 230 const std::string& a_ 230 const std::string& a_encoding, 231 font_type a_font, 231 font_type a_font, 232 const std::vector<std 232 const std::vector<std::string>& a_ss, 233 float& a_mn_x,float& 233 float& a_mn_x,float& a_mn_y,float& a_mn_z, 234 float& a_mx_x,float& 234 float& a_mx_x,float& a_mx_y,float& a_mx_z){ 235 if(a_ss.size()) { 235 if(a_ss.size()) { 236 float HEIGHT = a_height; 236 float HEIGHT = a_height; 237 float Y_ADVANCE = 2 * HEIGHT; 237 float Y_ADVANCE = 2 * HEIGHT; 238 float width = 0; 238 float width = 0; 239 float Y = 0; 239 float Y = 0; 240 std::vector<float> dummy; 240 std::vector<float> dummy; 241 tools_vforcit(std::string,a_ss,it) { 241 tools_vforcit(std::string,a_ss,it) { 242 float XL = 0; 242 float XL = 0; 243 string_segs(false,*it,a_height,a_encod 243 string_segs(false,*it,a_height,a_encoding,a_font,XL,Y,dummy,false); 244 Y -= Y_ADVANCE; 244 Y -= Y_ADVANCE; 245 width = mx<float>(width,XL); 245 width = mx<float>(width,XL); 246 } 246 } 247 247 248 a_mn_x = 0; 248 a_mn_x = 0; 249 a_mn_y = -Y_ADVANCE*(a_ss.size()-1)-_des 249 a_mn_y = -Y_ADVANCE*(a_ss.size()-1)-_descent(a_height); 250 a_mn_z = 0; 250 a_mn_z = 0; 251 a_mx_x = width; 251 a_mx_x = width; 252 a_mx_y = HEIGHT; 252 a_mx_y = HEIGHT; 253 a_mx_z = 0; 253 a_mx_z = 0; 254 } else { 254 } else { 255 box_3f_make_empty(a_mn_x,a_mn_y,a_mn_z,a 255 box_3f_make_empty(a_mn_x,a_mn_y,a_mn_z,a_mx_x,a_mx_y,a_mx_z); 256 } 256 } 257 } 257 } 258 258 259 static void get_bounds(float a_height, 259 static void get_bounds(float a_height, 260 const std::string& a_ 260 const std::string& a_encoding, 261 font_type a_font, 261 font_type a_font, 262 const std::string& a_ 262 const std::string& a_s, 263 float& a_mn_x,float& 263 float& a_mn_x,float& a_mn_y,float& a_mn_z, 264 float& a_mx_x,float& 264 float& a_mx_x,float& a_mx_y,float& a_mx_z){ 265 float HEIGHT = a_height; 265 float HEIGHT = a_height; 266 float Y_ADVANCE = 2 * HEIGHT; 266 float Y_ADVANCE = 2 * HEIGHT; 267 float width = 0; 267 float width = 0; 268 float Y = 0; 268 float Y = 0; 269 std::vector<float> dummy; 269 std::vector<float> dummy; 270 float XL = 0; 270 float XL = 0; 271 string_segs(false,a_s,a_height,a_encoding, 271 string_segs(false,a_s,a_height,a_encoding,a_font,XL,Y,dummy,false); 272 Y -= Y_ADVANCE; 272 Y -= Y_ADVANCE; 273 width = mx<float>(width,XL); 273 width = mx<float>(width,XL); 274 274 275 a_mn_x = 0; 275 a_mn_x = 0; 276 a_mn_y = -_descent(a_height); 276 a_mn_y = -_descent(a_height); 277 a_mn_z = 0; 277 a_mn_z = 0; 278 a_mx_x = width; 278 a_mx_x = width; 279 a_mx_y = HEIGHT; 279 a_mx_y = HEIGHT; 280 a_mx_z = 0; 280 a_mx_z = 0; 281 } 281 } 282 282 283 protected: 283 protected: 284 void update_sg() { 284 void update_sg() { 285 clean_gstos(); 285 clean_gstos(); 286 m_segs.clear(); 286 m_segs.clear(); 287 get_segments(m_segs); 287 get_segments(m_segs); 288 } 288 } 289 289 290 void get_segments(std::vector<float>& a_segs 290 void get_segments(std::vector<float>& a_segs) const { 291 291 292 float Y = 0; 292 float Y = 0; 293 if( (vjust.value()==sg::middle) || 293 if( (vjust.value()==sg::middle) || 294 (vjust.value()==sg::top) ){ 294 (vjust.value()==sg::top) ){ 295 float mn_x,mn_y,mn_z; 295 float mn_x,mn_y,mn_z; 296 float mx_x,mx_y,mx_z; 296 float mx_x,mx_y,mx_z; 297 get_bounds(height.value(),mn_x,mn_y,mn_z 297 get_bounds(height.value(),mn_x,mn_y,mn_z,mx_x,mx_y,mx_z); 298 float szy = mx_y - mn_y; 298 float szy = mx_y - mn_y; 299 299 300 if(vjust.value()==sg::middle) { 300 if(vjust.value()==sg::middle) { 301 Y -= 0.5F * szy; 301 Y -= 0.5F * szy; 302 } else if(vjust.value()==sg::top) { 302 } else if(vjust.value()==sg::top) { 303 Y -= szy; 303 Y -= szy; 304 } 304 } 305 } 305 } 306 306 307 float HEIGHT = height.value(); 307 float HEIGHT = height.value(); 308 float Y_ADVANCE = 2 * HEIGHT; 308 float Y_ADVANCE = 2 * HEIGHT; 309 309 310 const std::string& encod = encoding.value( 310 const std::string& encod = encoding.value(); 311 311 312 const std::vector<std::string>& ss = strin 312 const std::vector<std::string>& ss = strings.values(); 313 tools_vforcit(std::string,ss,it) { 313 tools_vforcit(std::string,ss,it) { 314 314 315 float X = 0; 315 float X = 0; 316 if( (hjust.value()==sg::center) || 316 if( (hjust.value()==sg::center) || 317 (hjust.value()==sg::right) ){ 317 (hjust.value()==sg::right) ){ 318 float mn_x,mn_y,mn_z; 318 float mn_x,mn_y,mn_z; 319 float mx_x,mx_y,mx_z; 319 float mx_x,mx_y,mx_z; 320 get_bounds(height,encoding.value(),fon 320 get_bounds(height,encoding.value(),font,*it, 321 mn_x,mn_y,mn_z,mx_x,mx_y,mx 321 mn_x,mn_y,mn_z,mx_x,mx_y,mx_z); 322 float szx = mx_x - mn_x; 322 float szx = mx_x - mn_x; 323 323 324 if(hjust.value()==sg::center) { 324 if(hjust.value()==sg::center) { 325 X -= 0.5F * szx; 325 X -= 0.5F * szx; 326 } else if(hjust.value()==sg::right) { 326 } else if(hjust.value()==sg::right) { 327 X -= szx; 327 X -= szx; 328 } 328 } 329 } 329 } 330 330 331 string_segs(true,*it,HEIGHT,encod,font.v 331 string_segs(true,*it,HEIGHT,encod,font.value(),X,Y,a_segs,true); 332 Y -= Y_ADVANCE; 332 Y -= Y_ADVANCE; 333 } 333 } 334 } 334 } 335 protected: 335 protected: 336 static float _descent(float a_height) { 336 static float _descent(float a_height) { 337 // '/' seems to be the char with the max d 337 // '/' seems to be the char with the max descent. 338 float mn_x,mn_y,mn_z; 338 float mn_x,mn_y,mn_z; 339 float mx_x,mx_y,mx_z; 339 float mx_x,mx_y,mx_z; 340 get_char_bound('/',sg::latin,a_height,fals 340 get_char_bound('/',sg::latin,a_height,false, 341 mn_x,mn_y,mn_z, 341 mn_x,mn_y,mn_z, 342 mx_x,mx_y,mx_z); 342 mx_x,mx_y,mx_z); 343 return -mn_y; //return then a positive num 343 return -mn_y; //return then a positive number. 344 } 344 } 345 345 346 static bool _truncate(const std::string& a_s 346 static bool _truncate(const std::string& a_string, 347 float a_height, 347 float a_height, 348 font_type a_font,float 348 font_type a_font,float a_cut_width, 349 std::string& a_out) { 349 std::string& a_out) { 350 //It does not take into account encoding. 350 //It does not take into account encoding. 351 351 352 a_out.clear(); 352 a_out.clear(); 353 353 354 float width = 0; 354 float width = 0; 355 355 356 const unsigned int mx_poly = 4; 356 const unsigned int mx_poly = 4; 357 const unsigned int mx_point = 160; 357 const unsigned int mx_point = 160; 358 358 359 int max_point[mx_poly]; 359 int max_point[mx_poly]; 360 float xp[mx_point]; 360 float xp[mx_point]; 361 float yp[mx_point]; 361 float yp[mx_point]; 362 362 363 tools_sforcit(a_string,it) { 363 tools_sforcit(a_string,it) { 364 364 365 float cwidth; 365 float cwidth; 366 int number; 366 int number; 367 if (a_font==sg::greek) { 367 if (a_font==sg::greek) { 368 hershey::greek_char_points(*it,a_heigh 368 hershey::greek_char_points(*it,a_height,number,max_point,xp,yp,cwidth); 369 } else if (a_font==sg::special) { 369 } else if (a_font==sg::special) { 370 hershey::special_char_points(*it,a_hei 370 hershey::special_char_points(*it,a_height,number,max_point,xp,yp,cwidth); 371 } else { 371 } else { 372 hershey::latin_char_points(*it,a_heigh 372 hershey::latin_char_points(*it,a_height,number,max_point,xp,yp,cwidth); 373 } 373 } 374 374 375 float advance = cwidth + a_height * 0.01 375 float advance = cwidth + a_height * 0.01F; 376 376 377 if((width+cwidth)>=a_cut_width) return t 377 if((width+cwidth)>=a_cut_width) return true; 378 a_out += *it; 378 a_out += *it; 379 width += advance; 379 width += advance; 380 } 380 } 381 381 382 return true; 382 return true; 383 } 383 } 384 384 385 static void get_char_bound(char a_char, 385 static void get_char_bound(char a_char, 386 font_type a_font, 386 font_type a_font, 387 float a_scale,boo 387 float a_scale,bool a_bar, 388 float& a_mn_x,flo 388 float& a_mn_x,float& a_mn_y,float& a_mn_z, 389 float& a_mx_x,flo 389 float& a_mx_x,float& a_mx_y,float& a_mx_z){ 390 box_3f_make_empty(a_mn_x,a_mn_y,a_mn_z,a_m 390 box_3f_make_empty(a_mn_x,a_mn_y,a_mn_z,a_mx_x,a_mx_y,a_mx_z); 391 391 392 const unsigned int mx_poly = 4; 392 const unsigned int mx_poly = 4; 393 const unsigned int mx_point = 160; 393 const unsigned int mx_point = 160; 394 394 395 int max_point[mx_poly]; 395 int max_point[mx_poly]; 396 float xp[mx_point]; 396 float xp[mx_point]; 397 float yp[mx_point]; 397 float yp[mx_point]; 398 398 399 int number; 399 int number; 400 float width; 400 float width; 401 if (a_font==sg::greek) { 401 if (a_font==sg::greek) { 402 hershey::greek_char_points(a_char,a_scal 402 hershey::greek_char_points(a_char,a_scale,number,max_point,xp,yp,width); 403 } else if (a_font==sg::special) { 403 } else if (a_font==sg::special) { 404 hershey::special_char_points(a_char,a_sc 404 hershey::special_char_points(a_char,a_scale,number,max_point,xp,yp,width); 405 } else { 405 } else { 406 hershey::latin_char_points(a_char,a_scal 406 hershey::latin_char_points(a_char,a_scale,number,max_point,xp,yp,width); 407 } 407 } 408 408 409 float ymax = 0; 409 float ymax = 0; 410 410 411 int ipoint = 0; 411 int ipoint = 0; 412 for (int ipoly=0;ipoly<number;ipoly++) { 412 for (int ipoly=0;ipoly<number;ipoly++) { 413 int pointn = max_point[ipoly]; 413 int pointn = max_point[ipoly]; 414 if(pointn>0) { 414 if(pointn>0) { 415 for(int count=0;count<pointn-1;count++ 415 for(int count=0;count<pointn-1;count++) { 416 ymax = mx<float>(ymax,yp[ipoint]); 416 ymax = mx<float>(ymax,yp[ipoint]); 417 box_3f_extend_by(a_mn_x,a_mn_y,a_mn_ 417 box_3f_extend_by(a_mn_x,a_mn_y,a_mn_z,a_mx_x,a_mx_y,a_mx_z,xp[ipoint],yp[ipoint],0); 418 418 419 ymax = mx<float>(ymax,yp[ipoint+1]); 419 ymax = mx<float>(ymax,yp[ipoint+1]); 420 box_3f_extend_by(a_mn_x,a_mn_y,a_mn_ 420 box_3f_extend_by(a_mn_x,a_mn_y,a_mn_z,a_mx_x,a_mx_y,a_mx_z,xp[ipoint+1],yp[ipoint+1],0); 421 421 422 ipoint ++; 422 ipoint ++; 423 } 423 } 424 ipoint ++; 424 ipoint ++; 425 } 425 } 426 } 426 } 427 427 428 if(a_bar) { //Draw a bar on top of the cha 428 if(a_bar) { //Draw a bar on top of the character. 429 float xbar = 0; 429 float xbar = 0; 430 float ybar = ymax * 1.3F; 430 float ybar = ymax * 1.3F; 431 box_3f_extend_by(a_mn_x,a_mn_y,a_mn_z,a_ 431 box_3f_extend_by(a_mn_x,a_mn_y,a_mn_z,a_mx_x,a_mx_y,a_mx_z,xbar,ybar,0); 432 box_3f_extend_by(a_mn_x,a_mn_y,a_mn_z,a_ 432 box_3f_extend_by(a_mn_x,a_mn_y,a_mn_z,a_mx_x,a_mx_y,a_mx_z,xbar+width,ybar,0); 433 } 433 } 434 } 434 } 435 435 436 static void string_segs( 436 static void string_segs( 437 bool aGEN_POINTS // false = advance only. 437 bool aGEN_POINTS // false = advance only. 438 ,const std::string& a_string 438 ,const std::string& a_string 439 ,float a_height 439 ,float a_height 440 ,const std::string& a_encoding 440 ,const std::string& a_encoding 441 ,font_type a_font 441 ,font_type a_font 442 ,float& aX 442 ,float& aX 443 ,float& aY 443 ,float& aY 444 ,std::vector<float>& a_segs 444 ,std::vector<float>& a_segs 445 ,bool a_fill_segs 445 ,bool a_fill_segs 446 ){ 446 ){ 447 float oldX = 0; 447 float oldX = 0; 448 float HEIGHT = a_height; 448 float HEIGHT = a_height; 449 449 450 bool encod_PAW = (a_encoding==encoding_PAW 450 bool encod_PAW = (a_encoding==encoding_PAW()?true:false); 451 451 452 sencoded sed; 452 sencoded sed; 453 if(encod_PAW) decode_PAW(a_string,sed); 453 if(encod_PAW) decode_PAW(a_string,sed); 454 else decode_plain(a_string,sed); 454 else decode_plain(a_string,sed); 455 455 456 tools_vforcit(hchar,sed,it) { 456 tools_vforcit(hchar,sed,it) { 457 const hchar& hc = *it; 457 const hchar& hc = *it; 458 458 459 font_type hershey_font = hc.m_font; 459 font_type hershey_font = hc.m_font; 460 if(encod_PAW) { 460 if(encod_PAW) { 461 hershey_font = hc.m_font; 461 hershey_font = hc.m_font; 462 } else { 462 } else { 463 hershey_font = a_font; 463 hershey_font = a_font; 464 } 464 } 465 465 466 float scale = HEIGHT; 466 float scale = HEIGHT; 467 float ymove = 0; 467 float ymove = 0; 468 if(hc.m_y_move==hchar::up) { 468 if(hc.m_y_move==hchar::up) { 469 scale = HEIGHT*0.6F; 469 scale = HEIGHT*0.6F; 470 ymove = HEIGHT*0.6F; 470 ymove = HEIGHT*0.6F; 471 } else if(hc.m_y_move==hchar::down) { 471 } else if(hc.m_y_move==hchar::down) { 472 scale = HEIGHT*0.6F; 472 scale = HEIGHT*0.6F; 473 ymove = -HEIGHT*0.6F; 473 ymove = -HEIGHT*0.6F; 474 } 474 } 475 if(hc.m_back) aX = oldX; 475 if(hc.m_back) aX = oldX; 476 oldX = aX; 476 oldX = aX; 477 //FIXME : bar 477 //FIXME : bar 478 aY += ymove; 478 aY += ymove; 479 479 480 float advance = char_segs(aGEN_POINTS,hc 480 float advance = char_segs(aGEN_POINTS,hc.m_char,hershey_font,scale,hc.m_bar,aX,aY,a_segs,a_fill_segs) + HEIGHT * 0.01F; 481 481 482 aX += advance; 482 aX += advance; 483 483 484 aY -= ymove; 484 aY -= ymove; 485 } 485 } 486 } 486 } 487 487 488 static float char_segs( 488 static float char_segs( 489 bool aGEN_POINTS // false = advance only. 489 bool aGEN_POINTS // false = advance only. 490 ,char a_char 490 ,char a_char 491 ,font_type a_font 491 ,font_type a_font 492 ,float a_scale 492 ,float a_scale 493 ,bool aBar 493 ,bool aBar 494 ,float aX 494 ,float aX 495 ,float aY 495 ,float aY 496 ,std::vector<float>& a_segs 496 ,std::vector<float>& a_segs 497 ,bool a_fill_segs 497 ,bool a_fill_segs 498 ){ 498 ){ 499 const unsigned int mx_poly = 8; 499 const unsigned int mx_poly = 8; 500 const unsigned int mx_point = 160; 500 const unsigned int mx_point = 160; 501 501 502 int max_point[mx_poly]; 502 int max_point[mx_poly]; 503 float xp[mx_point]; 503 float xp[mx_point]; 504 float yp[mx_point]; 504 float yp[mx_point]; 505 505 506 int number; 506 int number; 507 float width; 507 float width; 508 if (a_font==sg::greek) { 508 if (a_font==sg::greek) { 509 hershey::greek_char_points(a_char,a_scal 509 hershey::greek_char_points(a_char,a_scale,number,max_point,xp,yp,width); 510 } else if (a_font==sg::special) { 510 } else if (a_font==sg::special) { 511 hershey::special_char_points(a_char,a_sc 511 hershey::special_char_points(a_char,a_scale,number,max_point,xp,yp,width); 512 } else { 512 } else { 513 hershey::latin_char_points(a_char,a_scal 513 hershey::latin_char_points(a_char,a_scale,number,max_point,xp,yp,width); 514 } 514 } 515 if(!aGEN_POINTS) return width; 515 if(!aGEN_POINTS) return width; 516 516 517 float ymax = 0; 517 float ymax = 0; 518 518 519 int ipoint = 0; 519 int ipoint = 0; 520 int pointn; 520 int pointn; 521 for (int ipoly=0;ipoly<number;ipoly++) { 521 for (int ipoly=0;ipoly<number;ipoly++) { 522 pointn = max_point[ipoly]; 522 pointn = max_point[ipoly]; 523 if(pointn>0) { 523 if(pointn>0) { 524 for(int count=0;count<pointn-1;count++ 524 for(int count=0;count<pointn-1;count++) { 525 ymax = mx<float>(ymax,yp[ipoint]); 525 ymax = mx<float>(ymax,yp[ipoint]); 526 if(a_fill_segs) { 526 if(a_fill_segs) { 527 a_segs.push_back(aX+xp[ipoint]); 527 a_segs.push_back(aX+xp[ipoint]); 528 a_segs.push_back(aY+yp[ipoint]); 528 a_segs.push_back(aY+yp[ipoint]); 529 } 529 } 530 ymax = mx<float>(ymax,yp[ipoint+1]); 530 ymax = mx<float>(ymax,yp[ipoint+1]); 531 if(a_fill_segs) { 531 if(a_fill_segs) { 532 a_segs.push_back(aX+xp[ipoint+1]); 532 a_segs.push_back(aX+xp[ipoint+1]); 533 a_segs.push_back(aY+yp[ipoint+1]); 533 a_segs.push_back(aY+yp[ipoint+1]); 534 } 534 } 535 ipoint ++; 535 ipoint ++; 536 } 536 } 537 ipoint ++; 537 ipoint ++; 538 } 538 } 539 } 539 } 540 540 541 if(aBar) { //Draw a bar on top of the char 541 if(aBar) { //Draw a bar on top of the character. 542 float xbar = 0; 542 float xbar = 0; 543 float ybar = ymax * 1.3F; 543 float ybar = ymax * 1.3F; 544 544 545 if(a_fill_segs) { 545 if(a_fill_segs) { 546 a_segs.push_back(aX+xbar); 546 a_segs.push_back(aX+xbar); 547 a_segs.push_back(aY+ybar); 547 a_segs.push_back(aY+ybar); 548 548 549 a_segs.push_back(aX+xbar+width); 549 a_segs.push_back(aX+xbar+width); 550 a_segs.push_back(aY+ybar); 550 a_segs.push_back(aY+ybar); 551 } 551 } 552 } 552 } 553 553 554 return width; 554 return width; 555 } 555 } 556 556 557 typedef std::vector<hchar> sencoded; 557 typedef std::vector<hchar> sencoded; 558 558 559 static void decode_plain(const std::string& 559 static void decode_plain(const std::string& a_s,sencoded& a_sed){ 560 a_sed.clear(); 560 a_sed.clear(); 561 tools_sforcit(a_s,it) { 561 tools_sforcit(a_s,it) { 562 hchar hc; 562 hchar hc; 563 hc.m_char = *it; 563 hc.m_char = *it; 564 a_sed.push_back(hc); 564 a_sed.push_back(hc); 565 } 565 } 566 if(a_sed.size()) a_sed[a_sed.size()-1].m_c 566 if(a_sed.size()) a_sed[a_sed.size()-1].m_cr = true; 567 } 567 } 568 //////////////////////////////////////////// 568 /////////////////////////////////////////////////////////////////////////// 569 /// PAW encoding /////////////////////////// 569 /// PAW encoding ////////////////////////////////////////////////////////// 570 //////////////////////////////////////////// 570 /////////////////////////////////////////////////////////////////////////// 571 // PAW control characters : 571 // PAW control characters : 572 // [ go to greek (roman = default) 572 // [ go to greek (roman = default) 573 // ] end of greek 573 // ] end of greek 574 // " go to special 574 // " go to special 575 // # end of special 575 // # end of special 576 // ! go to normal level of script 576 // ! go to normal level of script 577 // ^ go to superscript 577 // ^ go to superscript 578 // ? go to subscript 578 // ? go to subscript 579 // & backscpace one charachter 579 // & backscpace one charachter 580 // < go to lower case 580 // < go to lower case 581 // > go to upper case (default) 581 // > go to upper case (default) 582 // Extension : 582 // Extension : 583 // | draw a bar over one character 583 // | draw a bar over one character 584 // Found in PAW manual Version 1.14 (July 19 584 // Found in PAW manual Version 1.14 (July 1992), page 178, 180. 585 //////////////////////////////////////////// 585 /////////////////////////////////////////////////////////////////////////// 586 static void decode_PAW(const std::string& a_ 586 static void decode_PAW(const std::string& a_s,sencoded& a_sed){ 587 a_sed.clear(); 587 a_sed.clear(); 588 588 589 font_type hershey_font = sg::latin; 589 font_type hershey_font = sg::latin; 590 hchar::e_move move = hchar::none; 590 hchar::e_move move = hchar::none; 591 bool back = false; 591 bool back = false; 592 bool bar = false; 592 bool bar = false; 593 //bool upper = true; //to be done. 593 //bool upper = true; //to be done. 594 594 595 tools_sforcit(a_s,it) { 595 tools_sforcit(a_s,it) { 596 char c = *it; 596 char c = *it; 597 // Control characters : 597 // Control characters : 598 if(c=='[') { 598 if(c=='[') { 599 hershey_font = sg::greek; 599 hershey_font = sg::greek; 600 continue; 600 continue; 601 } else if(c==']') { 601 } else if(c==']') { 602 hershey_font = sg::latin; 602 hershey_font = sg::latin; 603 continue; 603 continue; 604 } else if(c=='"') { 604 } else if(c=='"') { 605 hershey_font = sg::special; 605 hershey_font = sg::special; 606 continue; 606 continue; 607 } else if(c=='#') { 607 } else if(c=='#') { 608 hershey_font = sg::latin; 608 hershey_font = sg::latin; 609 continue; 609 continue; 610 } else if(c=='!') { 610 } else if(c=='!') { 611 move = hchar::none; 611 move = hchar::none; 612 continue; 612 continue; 613 } else if(c=='^') { 613 } else if(c=='^') { 614 move = hchar::up; 614 move = hchar::up; 615 continue; 615 continue; 616 } else if(c=='?') { 616 } else if(c=='?') { 617 move = hchar::down; 617 move = hchar::down; 618 continue; 618 continue; 619 } else if(c=='&') { 619 } else if(c=='&') { 620 back = true; 620 back = true; 621 continue; 621 continue; 622 } else if(c=='<') { 622 } else if(c=='<') { 623 //upper = false; 623 //upper = false; 624 continue; 624 continue; 625 } else if(c=='>') { 625 } else if(c=='>') { 626 //upper = true; 626 //upper = true; 627 continue; 627 continue; 628 } 628 } 629 629 630 hchar hc; 630 hchar hc; 631 hc.m_y_move = move; 631 hc.m_y_move = move; 632 hc.m_back = back; 632 hc.m_back = back; 633 hc.m_bar = bar; 633 hc.m_bar = bar; 634 hc.m_font = hershey_font; 634 hc.m_font = hershey_font; 635 hc.m_char = c; 635 hc.m_char = c; 636 636 637 a_sed.push_back(hc); 637 a_sed.push_back(hc); 638 638 639 back = false; 639 back = false; 640 bar = false; 640 bar = false; 641 } 641 } 642 642 643 if(a_sed.size()) a_sed[a_sed.size()-1].m_c 643 if(a_sed.size()) a_sed[a_sed.size()-1].m_cr = true; 644 } 644 } 645 645 646 protected: 646 protected: 647 std::vector<float> m_segs; //list of [begin, 647 std::vector<float> m_segs; //list of [begin,end] 648 size_t m_gsto_sz; 648 size_t m_gsto_sz; 649 }; 649 }; 650 650 651 }} 651 }} 652 652 653 #endif 653 #endif