Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 2 // See the file tools.license for terms. 3 4 #ifndef tools_sg_valop2sg 5 #define tools_sg_valop2sg 6 7 #include "bbox_action" 8 #include "strings" 9 #include "separator" 10 #include "matrix" 11 #include "vertices" 12 #include "base_freetype" 13 #include "mnmx" 14 15 #include "../valop" 16 #include "../smath" 17 18 namespace tools { 19 20 class valop2sg : public virtual valop_visitor 21 public: 22 virtual bool binary(unsigned int a_type,cons 23 sg::separator* sep = new sg::separator; 24 25 sg::separator* sep1 = new sg::separator; 26 sep->add(sep1); 27 sg::matrix* tsf1 = new sg::matrix; 28 sep1->add(tsf1); 29 vec3f mn1,mx1; 30 {valop2sg v(m_out,*sep1,m_ttf); 31 if(!v.visit(a_1)) { 32 delete sep; 33 return false; 34 } 35 mnmx(m_out,*sep1,mn1,mx1);} 36 37 sg::separator* op_sep = new sg::separator; 38 sep->add(op_sep); 39 sg::matrix* op_tsf = new sg::matrix; 40 op_sep->add(op_tsf); 41 42 sg::separator* sep2 = new sg::separator; 43 sep->add(sep2); 44 sg::matrix* tsf2 = new sg::matrix; 45 sep2->add(tsf2); 46 vec3f mn2,mx2; 47 {valop2sg v(m_out,*sep2,m_ttf); 48 if(!v.visit(a_2)) { 49 delete sep; 50 return false; 51 } 52 mnmx(m_out,*sep2,mn2,mx2);} 53 54 if((a_type==valop::ADD) || 55 (a_type==valop::SUB) || 56 (a_type==valop::MUL) || 57 (a_type==valop::EQUAL) ){ 58 59 sg::base_freetype* tft = sg::base_freety 60 61 if(a_type==valop::ADD) unichar2sg 62 //else if(a_type==valop::SUB) unichar2sg 63 else if(a_type==valop::SUB) unichar2sg 64 //else if(a_type==valop::MUL) unichar2sg 65 //else if(a_type==valop::MUL) unichar2sg 66 else if(a_type==valop::MUL) unichar2sg 67 else if(a_type==valop::EQUAL) unichar2sg 68 op_sep->add(tft); 69 70 vec3f omn,omx; 71 mnmx(m_out,*tft,omn,omx); 72 73 float odx = omx[0]-omn[0]; 74 float xmargin = odx*0.1f; 75 76 op_tsf->mul_translate(-omn[0]+mx1[0]+xma 77 78 tsf2->mul_translate(-mn2[0]+mx1[0]+xmarg 79 80 } else if( (a_type==valop::ASIDE) || 81 (a_type==valop::NVMUL) ){ 82 83 float xspace = (mx1[0]-mn1[0])*0.1f; 84 85 tsf2->mul_translate(-mn2[0]+mx1[0]+xspac 86 87 } else if(a_type==valop::DIV) { 88 89 // the bar : 90 sg::vertices* vtcs = new sg::vertices; 91 op_sep->add(vtcs); 92 float w2 = 0.5f; 93 float h = 0.101f; 94 vtcs->add(-w2,0,0); 95 vtcs->add( w2,0,0); 96 vtcs->add( w2,h,0); 97 vtcs->add(-w2,h,0); 98 if(m_wf) { 99 vtcs->mode = gl::line_strip(); 100 vtcs->add(-w2,0,0); 101 } else { 102 vtcs->mode = gl::triangle_fan(); 103 } 104 105 float ymargin = h; 106 107 float osx = mx(mx1[0]-mn1[0],mx2[0]-mn2[ 108 osx *= 1.1f; 109 110 op_tsf->mul_scale(osx,1,1); 111 112 //put a_1 symbol in the middle of the ba 113 //put a_1 symbol on top of the bar (with 114 float dx1 = -(mn1[0]+mx1[0])*0.5f; 115 float dy1 = -mn1[1]+h+ymargin; 116 tsf1->mul_translate(dx1,dy1,0); 117 118 //put a_2 symbol in the middle of the ba 119 //put a_2 symbol under the bar (with an 120 float dx2 = -(mn2[0]+mx2[0])*0.5f; 121 float dy2 = -mx2[1]-ymargin; 122 tsf2->mul_translate(dx2,dy2,0); 123 124 } else if(a_type==valop::SUPS) { 125 126 if(mx2[0]==mn2[0]) { 127 delete sep; 128 return false; 129 } 130 131 float s2 = 0.5f*(mx1[0]-mn1[0])/(mx2[0]- 132 tsf2->set_scale(s2,s2,1); 133 mnmx(m_out,*sep2,mn2,mx2); 134 135 float xshift = (mx1[0]-mn1[0])*0.1f; 136 float dx2 = -mn2[0]+mx1[0]+xshift; 137 138 float yshift = (mx1[1]-mn1[1])*0.3f; 139 float dy2 = -mn2[1]+mx1[1]-yshift; 140 141 tsf2->set_translate(dx2,dy2,0); 142 tsf2->mul_scale(s2,s2,1); //applied firs 143 144 } else if(a_type==valop::SUBS) { 145 146 if(mx2[0]==mn2[0]) { 147 delete sep; 148 return false; 149 } 150 151 float s2 = 0.5f*(mx1[0]-mn1[0])/(mx2[0]- 152 tsf2->set_scale(s2,s2,1); 153 mnmx(m_out,*sep2,mn2,mx2); 154 155 float xshift = (mx1[0]-mn1[0])*0.1f; 156 float dx2 = -mn2[0]+mx1[0]+xshift; 157 158 float yshift = (mx1[1]-mn1[1])*0.3f; 159 float dy2 = -mn2[1]-yshift; 160 161 tsf2->set_translate(dx2,dy2,0); 162 tsf2->mul_scale(s2,s2,1); //applied firs 163 164 } else { 165 delete sep; 166 return false; 167 } 168 169 m_group.add(sep); 170 171 return true; 172 } 173 174 virtual bool unary(unsigned int a_type,const 175 if(a_type==valop::MINUS) { 176 sg::separator* sep = new sg::separator; 177 178 sg::separator* sep1 = new sg::separator; 179 sep->add(sep1); 180 sg::matrix* tsf1 = new sg::matrix; 181 sep1->add(tsf1); 182 vec3f mn1,mx1; 183 {valop2sg v(m_out,*sep1,m_ttf); 184 if(!v.visit(a_1)) { 185 delete sep; 186 return false; 187 } 188 mnmx(m_out,*sep1,mn1,mx1);} 189 190 m_group.add(sep); 191 192 //////////////////////////////////////// 193 /// minus symbol /////////////////////// 194 //////////////////////////////////////// 195 sg::separator* op_sep = new sg::separato 196 sep->add(op_sep); 197 //sg::matrix* op_tsf = new sg::matrix; 198 //op_sep->add(op_tsf); 199 200 sg::base_freetype* tft = sg::base_freety 201 //TTNODE* tft = new TTNODE(); 202 unichar2sg(0x0002D,*tft); 203 op_sep->add(tft); 204 vec3f omn,omx; 205 mnmx(m_out,*tft,omn,omx); 206 207 float odx = omx[0]-omn[0]; 208 float xmargin = odx*0.1f; 209 210 //push a_1 at right of minus symbol 211 tsf1->mul_translate(-mn1[0]+omx[0]+xmarg 212 213 return true; 214 215 } else { 216 return false; 217 } 218 } 219 220 virtual bool variable(unsigned int a_type,co 221 222 sg::base_freetype* tft = sg::base_freetype 223 //TTNODE* tft = new TTNODE(); 224 225 if(a_type==valop::SYMBOL) { 226 if(rcmp(a_var.get_string(),s_psi())) { 227 unichar2sg(0x003C8,*tft); 228 m_group.add(tft); 229 return true; 230 } else if(rcmp(a_var.get_string(),s_gamm 231 unichar2sg(0x003B3,*tft); 232 m_group.add(tft); 233 return true; 234 } else if(rcmp(a_var.get_string(),s_mu() 235 unichar2sg(0x003BC,*tft); 236 m_group.add(tft); 237 return true; 238 } else if(rcmp(a_var.get_string(),s_uppe 239 unichar2sg(0x02206,*tft); 240 m_group.add(tft); 241 return true; 242 } else if(rcmp(a_var.get_string(),s_part 243 unichar2sg(0x02202,*tft); //d ronde 244 m_group.add(tft); 245 return true; 246 } else if(rcmp(a_var.get_string(),s_h_ba 247 unichar2sg(0x0210F,*tft); 248 m_group.add(tft); 249 return true; 250 } 251 252 } else if(a_type==valop::REAL){ 253 s2sg(value::to_string(a_var),*tft); 254 m_group.add(tft); 255 return true; 256 257 } else if(a_type==valop::STRING){ 258 if(a_var.type()==value::STRING){ 259 s2sg(a_var.get_string(),*tft); 260 m_group.add(tft); 261 return true; 262 } else { 263 m_out << "valop2sg::variable :" 264 << " expected a value::STRING." 265 << " Got " << a_var.stype() << " 266 << std::endl; 267 } 268 } 269 270 delete tft; 271 return false; 272 } 273 274 virtual bool option(const valop& a_node) { 275 sg::base_freetype* tft = sg::base_freetype 276 //TTNODE* tft = new TTNODE(); 277 s2sg(a_node.m_name,*tft); 278 m_group.add(tft); 279 return true; 280 } 281 282 virtual bool func_1(const valop& a_f,const v 283 if(rcmp(a_f.m_function->name(),s_sqrt())) 284 285 sg::separator* sep = new sg::separator; 286 287 sg::separator* sep1 = new sg::separator; 288 sep->add(sep1); 289 vec3f mn1,mx1; 290 {valop2sg v(m_out,*sep1,m_ttf); 291 if(!v.visit(a_1)) { 292 delete sep; 293 return false; 294 } 295 mnmx(m_out,*sep1,mn1,mx1);} 296 297 m_group.add(sep); 298 299 //////////////////////////////////////// 300 /// sqrt symbol //////////////////////// 301 //////////////////////////////////////// 302 sg::separator* op_sep = new sg::separato 303 sep->add(op_sep); 304 sg::matrix* op_tsf = new sg::matrix; 305 op_sep->add(op_tsf); 306 307 sg::base_freetype* tft = sg::base_freety 308 //TTNODE* tft = new TTNODE(); 309 unichar2sg(0x0221A,*tft); 310 op_sep->add(tft); 311 vec3f omn,omx; 312 mnmx(m_out,*tft,omn,omx); 313 314 // upper bar : 315 sg::vertices* vtcs = new sg::vertices; 316 op_sep->add(vtcs); 317 float dx = 0.05f; //to cover the top of 318 float w = mx1[0]-mn1[0]; 319 w *= 1.05f; 320 float h = 0.09f; 321 vtcs->add(omx[0]-dx ,omx[1]-h,0); 322 vtcs->add(omx[0]+w ,omx[1]-h,0); 323 vtcs->add(omx[0]+w ,omx[1] ,0); 324 vtcs->add(omx[0]-dx ,omx[1] ,0); 325 if(m_wf) { 326 vtcs->mode = gl::line_strip(); 327 vtcs->add(omx[0]-dx ,omx[1]-h,0); 328 } else { 329 vtcs->mode = gl::triangle_fan(); 330 } 331 332 //float odx = omx[0]-omn[0]; 333 //float xmargin = odx*0.1f; 334 float xmargin = 0; 335 336 //push sqrt-symbol at left of a_1 337 //scale sqrt-symbol to match a_1 y heigh 338 //y translate sqrt-symbol so that a_1 is 339 340 float osy = (mx1[1]-mn1[1])/(omx[1]-omn[ 341 float ody = -omn[1]*osy + mn1[1]; 342 343 osy *= 1.2f; 344 345 op_tsf->mul_translate(-omx[0]+mn1[0]-xma 346 op_tsf->mul_scale(1,osy,1); 347 348 return true; 349 } else { 350 // generic case : <func_name>(rep of a_1 351 352 sg::separator* sep = new sg::separator; 353 354 sg::separator* sep1 = new sg::separator; 355 sep->add(sep1); 356 vec3f mn1,mx1; 357 {valop2sg v(m_out,*sep1,m_ttf); 358 if(!v.visit(a_1)) { 359 delete sep; 360 return false; 361 } 362 mnmx(m_out,*sep1,mn1,mx1);} 363 364 m_group.add(sep); 365 366 //////////////////////////////////////// 367 /// left func symbol : <func_name> ( 368 //////////////////////////////////////// 369 {sg::separator* op_sep = new sg::separato 370 sep->add(op_sep); 371 sg::matrix* op_tsf = new sg::matrix; 372 op_sep->add(op_tsf); 373 374 sg::base_freetype* tft = sg::base_freety 375 //TTNODE* tft = new TTNODE(); 376 s2sg(a_f.m_function->name(),*tft); 377 tft->unitext[0].push_back(0x00028); // ( 378 op_sep->add(tft); 379 380 vec3f omn,omx; 381 mnmx(m_out,*tft,omn,omx); 382 383 //push func-symbol at left of a_1 : 384 //float odx = omx[0]-omn[0]; 385 //float xmargin = odx*0.1f; 386 float xmargin = 0; 387 op_tsf->mul_translate(-omx[0]+mn1[0]-xma 388 } //end left op 389 390 //////////////////////////////////////// 391 /// right func symbol : ) 392 //////////////////////////////////////// 393 {sg::separator* op_sep = new sg::separato 394 sep->add(op_sep); 395 sg::matrix* op_tsf = new sg::matrix; 396 op_sep->add(op_tsf); 397 398 sg::base_freetype* tft = sg::base_freety 399 //TTNODE* tft = new TTNODE(); 400 unichar2sg(0x00029,*tft); 401 op_sep->add(tft); 402 vec3f omn,omx; 403 mnmx(m_out,*tft,omn,omx); 404 405 //push func-symbol at right of a_1 : 406 //float odx = omx[0]-omn[0]; 407 //float xmargin = odx*0.1f; 408 float xmargin = 0; 409 op_tsf->mul_translate(-omn[0]+mx1[0]+xma 410 } //end right op 411 412 return true; 413 } 414 } 415 virtual bool func_2(const valop& a_f,const v 416 if(rcmp(a_f.m_function->name(),s_pow())) { 417 418 sg::separator* sep = new sg::separator; 419 420 sg::separator* sep1 = new sg::separator; 421 sep->add(sep1); 422 sg::matrix* tsf1 = new sg::matrix; 423 sep1->add(tsf1); 424 vec3f mn1,mx1; 425 {valop2sg v(m_out,*sep1,m_ttf); 426 if(!v.visit(a_1)) { 427 delete sep; 428 return false; 429 } 430 mnmx(m_out,*sep1,mn1,mx1);} 431 432 //sg::separator* op_sep = new sg::separa 433 //sep->add(op_sep); 434 //sg::matrix* op_tsf = new sg::matrix; 435 //op_sep->add(op_tsf); 436 437 sg::separator* sep2 = new sg::separator; 438 sep->add(sep2); 439 sg::matrix* tsf2 = new sg::matrix; 440 sep2->add(tsf2); 441 vec3f mn2,mx2; 442 {valop2sg v(m_out,*sep2,m_ttf); 443 if(!v.visit(a_2)) { 444 delete sep; 445 return false; 446 } 447 mnmx(m_out,*sep2,mn2,mx2);} 448 449 float s2 = 0.5f*(mx1[0]-mn1[0])/(mx2[0]- 450 if(mx2[0]==mn2[0]) { 451 delete sep; 452 return false; 453 } 454 tsf2->set_scale(s2,s2,1); 455 mnmx(m_out,*sep2,mn2,mx2); 456 457 float xshift = (mx1[0]-mn1[0])*0.1f; 458 float dx2 = -mn2[0]+mx1[0]+xshift; 459 460 float yshift = (mx1[1]-mn1[1])*0.3f; 461 float dy2 = -mn2[1]+mx1[1]-yshift; 462 463 tsf2->set_identity(); 464 tsf2->mul_translate(dx2,dy2,0); 465 tsf2->mul_scale(s2,s2,1); //applied firs 466 467 m_group.add(sep); 468 469 return true; 470 471 } else { 472 // generic case : <func_name>(rep of a_1 473 474 sg::separator* sep = new sg::separator; 475 476 sg::separator* sep1 = new sg::separator; 477 sep->add(sep1); 478 vec3f mn1,mx1; 479 {valop2sg v(m_out,*sep1,m_ttf); 480 if(!v.visit(a_1)) { 481 delete sep; 482 return false; 483 } 484 mnmx(m_out,*sep1,mn1,mx1);} 485 486 sg::separator* sep2 = new sg::separator; 487 sep->add(sep2); 488 sg::matrix* tsf2 = new sg::matrix; 489 sep2->add(tsf2); 490 vec3f mn2,mx2; 491 {valop2sg v(m_out,*sep2,m_ttf); 492 if(!v.visit(a_2)) { 493 delete sep; 494 return false; 495 } 496 mnmx(m_out,*sep2,mn2,mx2);} 497 498 m_group.add(sep); 499 500 //////////////////////////////////////// 501 /// left func symbol : <func_name> ( 502 //////////////////////////////////////// 503 {sg::separator* op_sep = new sg::separato 504 sep->add(op_sep); 505 sg::matrix* op_tsf = new sg::matrix; 506 op_sep->add(op_tsf); 507 508 sg::base_freetype* tft = sg::base_freety 509 //TTNODE* tft = new TTNODE(); 510 s2sg(a_f.m_function->name(),*tft); 511 tft->unitext[0].push_back(0x00028); // ( 512 op_sep->add(tft); 513 514 vec3f omn,omx; 515 mnmx(m_out,*tft,omn,omx); 516 517 //push func-symbol at left of a_1 : 518 //float odx = omx[0]-omn[0]; 519 //float xmargin = odx*0.1f; 520 float xmargin = 0; 521 op_tsf->mul_translate(-omx[0]+mn1[0]-xma 522 } //end left op 523 524 //////////////////////////////////////// 525 /// , 526 //////////////////////////////////////// 527 float xend2 = 0; 528 {sg::separator* op_sep = new sg::separato 529 sep->add(op_sep); 530 sg::matrix* op_tsf = new sg::matrix; 531 op_sep->add(op_tsf); 532 533 sg::base_freetype* tft = sg::base_freety 534 //TTNODE* tft = new TTNODE(); 535 unichar2sg(0x0002C,*tft); // , 536 op_sep->add(tft); 537 vec3f omn,omx; 538 mnmx(m_out,*tft,omn,omx); 539 540 //push comma-symbol at right of a_1 : 541 float odx = omx[0]-omn[0]; 542 float xmargin = odx*0.1f; 543 op_tsf->mul_translate(-omn[0]+mx1[0]+xma 544 545 float xendcomma = mx1[0]+xmargin+(omx[0] 546 547 tsf2->mul_translate(-mn2[0]+xendcomma+xm 548 549 xend2 = xendcomma+(mx2[0]-mn2[0]); 550 } //end comma 551 552 //////////////////////////////////////// 553 /// right func symbol : ) 554 //////////////////////////////////////// 555 {sg::separator* op_sep = new sg::separato 556 sep->add(op_sep); 557 sg::matrix* op_tsf = new sg::matrix; 558 op_sep->add(op_tsf); 559 560 sg::base_freetype* tft = sg::base_freety 561 //TTNODE* tft = new TTNODE(); 562 unichar2sg(0x00029,*tft); 563 op_sep->add(tft); 564 vec3f omn,omx; 565 mnmx(m_out,*tft,omn,omx); 566 567 //push ")" at right of a_2 : 568 //float odx = omx[0]-omn[0]; 569 //float xmargin = odx*0.1f; 570 float xmargin = 0; 571 op_tsf->mul_translate(-omn[0]+xend2+xmar 572 } //end right op 573 574 return true; 575 } 576 } 577 virtual bool func_3(const valop&,const valop 578 return false; 579 } 580 virtual bool func_4(const valop&,const valop 581 return false; 582 } 583 virtual bool func_5(const valop&,const valop 584 return false; 585 } 586 virtual bool func_6(const valop&,const valop 587 return false; 588 } 589 public: 590 valop2sg(std::ostream& a_out, 591 sg::group& a_group, 592 const sg::base_freetype& a_ttf) 593 :m_out(a_out) 594 ,m_group(a_group) 595 //,m_wf(true) 596 ,m_wf(false) 597 ,m_ttf(a_ttf) 598 {} 599 virtual ~valop2sg() {} 600 public: 601 valop2sg(const valop2sg& a_from) 602 :valop_visitor(a_from) 603 ,m_out(a_from.m_out) 604 ,m_group(a_from.m_group) 605 ,m_wf(a_from.m_wf) 606 ,m_ttf(a_from.m_ttf) 607 {} 608 valop2sg& operator=(const valop2sg& a_from){ 609 m_wf = a_from.m_wf; 610 return *this; 611 } 612 protected: 613 typedef unsigned int unichar; 614 615 unichar char2stix(char a_c) { 616 if(a_c=='-') return 0x0002D; 617 if(a_c=='.') return 0x0002E; 618 619 if(a_c=='0') return 0x00030; 620 if(a_c=='1') return 0x00031; 621 if(a_c=='2') return 0x00032; 622 if(a_c=='3') return 0x00033; 623 if(a_c=='4') return 0x00034; 624 if(a_c=='5') return 0x00035; 625 if(a_c=='6') return 0x00036; 626 if(a_c=='7') return 0x00037; 627 if(a_c=='8') return 0x00038; 628 if(a_c=='9') return 0x00039; 629 630 if(a_c=='A') return 0x00041; 631 if(a_c=='B') return 0x00042; 632 if(a_c=='C') return 0x00043; 633 if(a_c=='D') return 0x00044; 634 if(a_c=='E') return 0x00045; 635 if(a_c=='F') return 0x00046; 636 if(a_c=='G') return 0x00047; 637 if(a_c=='H') return 0x00048; 638 if(a_c=='I') return 0x00049; 639 if(a_c=='J') return 0x0004A; 640 if(a_c=='K') return 0x0004B; 641 if(a_c=='L') return 0x0004C; 642 if(a_c=='M') return 0x0004D; 643 if(a_c=='N') return 0x0004E; 644 if(a_c=='O') return 0x0004F; 645 if(a_c=='P') return 0x00050; 646 if(a_c=='Q') return 0x00051; 647 if(a_c=='R') return 0x00052; 648 if(a_c=='S') return 0x00053; 649 if(a_c=='T') return 0x00054; 650 if(a_c=='U') return 0x00055; 651 if(a_c=='V') return 0x00056; 652 if(a_c=='W') return 0x00057; 653 if(a_c=='X') return 0x00058; 654 if(a_c=='Y') return 0x00059; 655 if(a_c=='Z') return 0x0005A; 656 657 if(a_c=='a') return 0x00061; 658 if(a_c=='b') return 0x00062; 659 if(a_c=='c') return 0x00063; 660 if(a_c=='d') return 0x00064; 661 if(a_c=='e') return 0x00065; 662 if(a_c=='f') return 0x00066; 663 if(a_c=='g') return 0x00067; 664 if(a_c=='h') return 0x00068; 665 if(a_c=='i') return 0x00069; 666 if(a_c=='j') return 0x0006A; 667 if(a_c=='k') return 0x0006B; 668 if(a_c=='l') return 0x0006C; 669 if(a_c=='m') return 0x0006D; 670 if(a_c=='n') return 0x0006E; 671 if(a_c=='o') return 0x0006F; 672 if(a_c=='p') return 0x00070; 673 if(a_c=='q') return 0x00071; 674 if(a_c=='r') return 0x00072; 675 if(a_c=='s') return 0x00073; 676 if(a_c=='t') return 0x00074; 677 if(a_c=='u') return 0x00075; 678 if(a_c=='v') return 0x00076; 679 if(a_c=='w') return 0x00077; 680 if(a_c=='x') return 0x00078; 681 if(a_c=='y') return 0x00079; 682 if(a_c=='z') return 0x0007A; 683 684 if(a_c=='_') return 0x0005F; 685 686 return 0x0003F; //? 687 } 688 689 void unichar2sg(unichar a_unichar,sg::base_f 690 if(m_wf) a_node.modeling = sg::font_outlin 691 692 a_node.font = sg::font_stixgeneral_otf(); 693 694 std::vector<unichar> line; 695 line.push_back(a_unichar); 696 697 a_node.unitext.add(line); 698 } 699 700 void s2sg(const std::string& a_s,sg::base_fr 701 if(m_wf) a_node.modeling = sg::font_outlin 702 703 a_node.font = sg::font_stixgeneral_otf(); 704 705 std::vector<unichar> line; 706 tools_sforcit(a_s,it) line.push_back(char2 707 708 a_node.unitext.add(line); 709 } 710 711 protected: 712 std::ostream& m_out; 713 sg::group& m_group; 714 bool m_wf; 715 const sg::base_freetype& m_ttf; 716 }; 717 718 } 719 720 #endif