00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "Riostream.h"
00013 #include "TROOT.h"
00014 #include "TClass.h"
00015 #include "TLatex.h"
00016 #include "TMath.h"
00017 #include "TVirtualPad.h"
00018 #include "TVirtualPS.h"
00019
00020 #ifdef R__SUNCCBUG
00021 const Double_t kPI = 3.14159265358979323846;
00022 #else
00023 const Double_t kPI = TMath::Pi();
00024 #endif
00025 const Int_t kLatex = BIT(10);
00026 const Int_t kPrintingPS = BIT(11);
00027
00028 ClassImp(TLatex)
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 TLatex::TLatex()
00306 {
00307
00308
00309 fFactorSize = 1.5;
00310 fFactorPos = 0.6;
00311 fLimitFactorSize = 3;
00312 fError = 0;
00313 fShow = kFALSE;
00314 fPos=fTabMax = 0;
00315 fOriginSize = 0.04;
00316 fTabSize = 0;
00317 fItalic = kFALSE;
00318 SetLineWidth(2);
00319 }
00320
00321
00322
00323 TLatex::TLatex(Double_t x, Double_t y, const char *text)
00324 :TText(x,y,text)
00325 {
00326
00327
00328 fFactorSize = 1.5;
00329 fFactorPos = 0.6;
00330 fError = 0;
00331 fShow = kFALSE;
00332 fPos = 0;
00333 fTabMax = 0;
00334 fOriginSize = 0.04;
00335 fTabSize = 0;
00336 fItalic = kFALSE;
00337 fLimitFactorSize = 3;
00338 SetLineWidth(2);
00339 }
00340
00341
00342
00343 TLatex::~TLatex()
00344 {
00345
00346 }
00347
00348
00349
00350 TLatex::TLatex(const TLatex &text) : TText(text), TAttLine(text)
00351 {
00352
00353
00354 fFactorSize = 1.5;
00355 fFactorPos = 0.6;
00356 fShow = kFALSE;
00357 fPos = 0;
00358 fTabMax = 0;
00359 fOriginSize = 0.04;
00360 fItalic = kFALSE;
00361 fLimitFactorSize = 3;
00362 ((TLatex&)text).Copy(*this);
00363 }
00364
00365
00366 TLatex& TLatex::operator=(const TLatex& lt)
00367 {
00368
00369 if(this!=<) {
00370 TText::operator=(lt);
00371 TAttLine::operator=(lt);
00372 fFactorSize=lt.fFactorSize;
00373 fFactorPos=lt.fFactorPos;
00374 fLimitFactorSize=lt.fLimitFactorSize;
00375 fError=lt.fError;
00376 fShow=lt.fShow;
00377 fTabSize=lt.fTabSize;
00378 fOriginSize=lt.fOriginSize;
00379 fTabSize=lt.fTabSize;
00380 fTabSize=lt.fTabSize;
00381 fItalic=lt.fItalic;
00382 }
00383 return *this;
00384 }
00385
00386
00387 void TLatex::Copy(TObject &obj) const
00388 {
00389
00390
00391 ((TLatex&)obj).fFactorSize = fFactorSize;
00392 ((TLatex&)obj).fFactorPos = fFactorPos;
00393 ((TLatex&)obj).fLimitFactorSize = fLimitFactorSize;
00394 ((TLatex&)obj).fError = fError;
00395 ((TLatex&)obj).fShow = fShow;
00396 ((TLatex&)obj).fTabSize = 0;
00397 ((TLatex&)obj).fOriginSize = fOriginSize;
00398 ((TLatex&)obj).fTabMax = fTabMax;
00399 ((TLatex&)obj).fPos = fPos;
00400 ((TLatex&)obj).fItalic = fItalic;
00401 TText::Copy(obj);
00402 TAttLine::Copy(((TAttLine&)obj));
00403 }
00404
00405
00406
00407 TLatexFormSize TLatex::Anal1(TextSpec_t spec, const Char_t* t, Int_t length)
00408 {
00409
00410
00411 return Analyse(0,0,spec,t,length);
00412 }
00413
00414
00415
00416 TLatexFormSize TLatex::Analyse(Double_t x, Double_t y, TextSpec_t spec, const Char_t* t, Int_t length)
00417 {
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440 const char *tab[] = { "alpha","beta","chi","delta","varepsilon","phi","gamma","eta","iota","varphi","kappa","lambda",
00441 "mu","nu","omicron","pi","theta","rho","sigma","tau","upsilon","varomega","omega","xi","psi","zeta",
00442 "Alpha","Beta","Chi","Delta","Epsilon","Phi","Gamma","Eta","Iota","vartheta",
00443 "Kappa","Lambda","Mu","Nu","Omicron","Pi","Theta","Rho","Sigma","Tau",
00444 "Upsilon","varsigma","Omega","Xi","Psi","Zeta","varUpsilon","epsilon"};
00445
00446 const char *tab2[] = { "leq","/","infty","voidb","club","diamond","heart",
00447 "spade","leftrightarrow","leftarrow","uparrow","rightarrow",
00448 "downarrow","circ","pm","doublequote","geq","times","propto",
00449 "partial","bullet","divide","neq","equiv","approx","3dots",
00450 "cbar","topbar","downleftarrow","aleph","Jgothic","Rgothic","voidn",
00451 "otimes","oplus","oslash","cap","cup","supset","supseteq",
00452 "notsubset","subset","subseteq","in","notin","angle","nabla",
00453 "oright","ocopyright","trademark","prod","surd","upoint","corner","wedge",
00454 "vee","Leftrightarrow","Leftarrow","Uparrow","Rightarrow",
00455 "Downarrow","diamond","LT","void1","copyright","void3","sum",
00456 "arctop","lbar","arcbottom","topbar","void8", "bottombar","arcbar",
00457 "ltbar","AA","aa","void06","GT","int","forall","exists" };
00458
00459 const char *tab3[] = { "bar","vec","dot","hat","ddot","acute","grave","check","tilde","slash"};
00460
00461 if (fError != 0) return TLatexFormSize(0,0,0);
00462
00463 Int_t nBlancDeb=0,nBlancFin=0,l_nBlancDeb=0,l_nBlancFin=0;
00464 Int_t i,k;
00465 Int_t min=0, max=0;
00466 Bool_t cont = kTRUE;
00467 while(cont) {
00468
00469
00470
00471 if (nBlancDeb==length) return TLatexFormSize(0,0,0);
00472
00473
00474
00475
00476 if (nBlancDeb==l_nBlancDeb && nBlancFin==l_nBlancFin) cont = kFALSE;
00477
00478
00479 if (t[nBlancDeb]=='{' && t[length-nBlancFin-1]=='}') {
00480 Int_t nBrackets = 0;
00481 Bool_t sameBrackets = kTRUE;
00482 for(i=nBlancDeb;i<length-nBlancFin;i++) {
00483 if (t[i] == '{' && !(i>0 && t[i-1] == '@')) nBrackets++;
00484 if (t[i] == '}' && t[i-1]!= '@') nBrackets--;
00485 if (nBrackets==0 && i<length-nBlancFin-2) {
00486 sameBrackets=kFALSE;
00487 break;
00488 }
00489 }
00490
00491 if (sameBrackets) {
00492
00493 nBlancDeb++;
00494 nBlancFin++;
00495 if (nBlancDeb+nBlancFin==length) return TLatexFormSize(0,0,0);
00496 cont = kTRUE;
00497 }
00498
00499 }
00500
00501 l_nBlancDeb = nBlancDeb;
00502 l_nBlancFin = nBlancFin;
00503 }
00504
00505
00506
00507 length -= nBlancFin+nBlancDeb;
00508 Char_t* text = new Char_t[length+1];
00509 strncpy(text,t+nBlancDeb,length);
00510 text[length] = 0;
00511
00512
00513 Double_t indiceSize = spec.fSize/fFactorSize;
00514 if(indiceSize<fOriginSize/TMath::Exp(fLimitFactorSize*TMath::Log(fFactorSize))-0.001f)
00515 indiceSize = spec.fSize;
00516
00517 TextSpec_t specNewSize = spec;
00518 specNewSize.fSize = indiceSize;
00519
00520
00521 Int_t opPower = -1;
00522 Int_t opUnder = -1;
00523 Int_t opFrac = -1;
00524 Int_t opSqrt = -1;
00525 Int_t nBrackets = 0;
00526 Int_t nCroch = 0;
00527 Int_t opCurlyCurly = -1;
00528 Int_t opSquareCurly = -1;
00529 Int_t opCloseCurly = -2;
00530 Int_t opColor = -1;
00531 Int_t opFont = -1;
00532 Int_t opScale = -1;
00533 Int_t opGreek = -1;
00534 Int_t opSpec = -1;
00535 Int_t opAbove = -1;
00536 Int_t opSquareBracket = 0 ;
00537 Int_t opBigCurly = 0 ;
00538 Int_t opAbs = 0 ;
00539 Int_t opParen = 0 ;
00540 Int_t abovePlace = 0 ;
00541 Int_t opBox = 0 ;
00542 Int_t opPerp = 0;
00543 Int_t opOdot = 0;
00544 Int_t opHbar = 0;
00545 Int_t opParallel = 0;
00546 Int_t opSplitLine = -1;
00547 Int_t opKern = -1;
00548 Int_t opLower = -1;
00549 Int_t opBf = -1;
00550 Int_t opIt = -1;
00551 Bool_t opFound = kFALSE;
00552 Bool_t quote1 = kFALSE, quote2 = kFALSE ;
00553
00554 for(i=0;i<length;i++) {
00555 switch (text[i]) {
00556 case '\'' : quote1 = !quote1 ; break ;
00557 case '"' : quote2 = !quote2 ; break ;
00558 }
00559
00560 switch (text[i]) {
00561 case '{':
00562 if (nCroch==0) {
00563 if (!(i>0 && text[i-1] == '@')) nBrackets++;
00564 }
00565 break;
00566 case '}':
00567 if (nCroch==0) {
00568 if (!(i>0 && text[i-1] == '@')) nBrackets--;
00569 if (nBrackets==0) {
00570 if (i<length-1) if (text[i+1]=='{' && opCurlyCurly==-1) opCurlyCurly=i;
00571 if (i<length-2) {
00572 if (text[i+1]!='{' && !(text[i+2]=='{' && (text[i+1]=='^' || text[i+1]=='_'))
00573 && opCloseCurly==-2) opCloseCurly=i;
00574 }
00575 else if (i<length-1) {
00576 if (text[i+1]!='{' && opCloseCurly==-2) opCloseCurly=i;
00577 }
00578 else if (opCloseCurly==-2) opCloseCurly=i;
00579 }
00580 }
00581 break;
00582 case '[':
00583 if (nBrackets==0) {
00584 if (!(i>0 && text[i-1] == '@')) nCroch++;
00585 }
00586 break;
00587 case ']':
00588 if (nBrackets==0) {
00589 if (!(i>0 && text[i-1] == '@')) nCroch--;
00590 if (nCroch<0) {
00591
00592 fError = "Missing \"[\"";
00593 delete [] text;
00594 return TLatexFormSize(0,0,0);
00595 }
00596 }
00597 break;
00598 }
00599 if (length>i+1) {
00600 Char_t buf[3];
00601 strncpy(buf,&text[i],2);
00602 if (strncmp(buf,"^{",2)==0) {
00603 if (opPower==-1 && nBrackets==0 && nCroch==0) opPower=i;
00604 if (i>3) {
00605 Char_t buf1[5];
00606 strncpy(buf1,&text[i-4],4);
00607 if (strncmp(buf1,"#int",4)==0) {
00608 abovePlace = 1;
00609 if (i>4 && opCloseCurly==-2) opCloseCurly=i-5;
00610 }
00611 if (strncmp(buf1,"#sum",4)==0) {
00612 abovePlace = 2;
00613 if (i>4 && opCloseCurly==-2) opCloseCurly=i-5;
00614 }
00615 }
00616 }
00617 if (strncmp(buf,"_{",2)==0) {
00618 if (opUnder==-1 && nBrackets==0 && nCroch==0) opUnder=i;
00619 if (i>3) {
00620 Char_t buf2[5];
00621 strncpy(buf2,&text[i-4],4);
00622 if (strncmp(buf2,"#int",4)==0) {
00623 abovePlace = 1;
00624 if (i>4 && opCloseCurly==-2) opCloseCurly=i-5;
00625 }
00626 if (strncmp(buf2,"#sum",4)==0) {
00627 abovePlace = 2;
00628 if (i>4 && opCloseCurly==-2) opCloseCurly=i-5;
00629 }
00630 }
00631 }
00632 if (strncmp(buf,"]{",2)==0)
00633 if (opSquareCurly==-1 && nBrackets==0 && nCroch==0) opSquareCurly=i;
00634 }
00635
00636 if (text[i]=='\\' || (text[i]=='#' && !opFound && nBrackets==0 && nCroch==0)) {
00637
00638 if (length>i+10 ) {
00639 Char_t buf[11];
00640 strncpy(buf,&text[i+1],10);
00641 if (strncmp(buf,"splitline{",10)==0) {
00642 opSplitLine=i; opFound = kTRUE;
00643 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00644 continue;
00645 }
00646 }
00647 if (length>i+8 ) {
00648 Char_t buf[9];
00649 strncpy(buf,&text[i+1],8);
00650 if (!opParallel && strncmp(buf,"parallel",8)==0) {
00651 opParallel=1; opFound = kTRUE;
00652 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00653 continue;
00654 }
00655 }
00656 if (length>i+6) {
00657 Char_t buf[7];
00658 strncpy(buf,&text[i+1],6);
00659 if (strncmp(buf,"lower[",6)==0 || strncmp(buf,"lower{",6)==0) {
00660 opLower=i; opFound = kTRUE;
00661 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00662 continue ;
00663 }
00664 if (strncmp(buf,"scale[",6)==0 || strncmp(buf,"scale{",6)==0) {
00665 opScale=i; opFound = kTRUE;
00666 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00667 continue ;
00668 }
00669 if (strncmp(buf,"color[",6)==0 || strncmp(buf,"color{",6)==0) {
00670 opColor=i; opFound = kTRUE;
00671 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00672 continue ;
00673 }
00674 }
00675 if (length>i+5 ) {
00676 Char_t buf[6];
00677 strncpy(buf,&text[i+1],5);
00678 if (strncmp(buf,"frac{",5)==0) {
00679 opFrac=i; opFound = kTRUE;
00680 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00681 continue;
00682 }
00683 if (strncmp(buf,"sqrt{",5)==0 || strncmp(buf,"sqrt[",5)==0) {
00684 opSqrt=i; opFound = kTRUE;
00685 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00686 continue;
00687 }
00688 if (strncmp(buf,"font{",5)==0 || strncmp(buf,"font[",5)==0) {
00689 opFont=i; opFound = kTRUE;
00690 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00691 continue;
00692 }
00693 if (strncmp(buf,"kern[",5)==0 || strncmp(buf,"kern{",5)==0) {
00694 opKern=i; opFound = kTRUE;
00695 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00696 continue ;
00697 }
00698 }
00699 if (length>i+4 ) {
00700 Char_t buf[5];
00701 strncpy(buf,&text[i+1],4);
00702 if (!opOdot && strncmp(buf,"odot",4)==0) {
00703 opOdot=1; opFound = kTRUE;
00704 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00705 continue;
00706 }
00707 if (!opHbar && strncmp(buf,"hbar",4)==0) {
00708 opHbar=1; opFound = kTRUE;
00709 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00710 continue;
00711 }
00712 if (!opPerp && strncmp(buf,"perp",4)==0) {
00713 opPerp=1; opFound = kTRUE;
00714 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00715 continue;
00716 }
00717 }
00718 if (length>i+3) {
00719 Char_t buf[4];
00720 strncpy(buf,&text[i+1],3);
00721 buf[3] = 0;
00722 if (strncmp(buf,"[]{",3)==0) {
00723 opSquareBracket=1; opFound = kTRUE;
00724 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00725 continue;
00726 }
00727 if (strncmp(buf,"{}{",3)==0 ) {
00728 opBigCurly=1; opFound = kTRUE;
00729 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00730 continue;
00731 }
00732 if (strncmp(buf,"||{",3)==0) {
00733 opAbs=1; opFound = kTRUE;
00734 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00735 continue;
00736 }
00737 if (strncmp(buf,"(){",3)==0) {
00738 opParen=1; opFound = kTRUE;
00739 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00740 continue;
00741 }
00742 if (!opBox && strncmp(buf,"Box",3)==0) {
00743 opBox=1; opFound = kTRUE;
00744 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00745 continue;
00746 }
00747 if (strncmp(buf,"bf[",3)==0 || strncmp(buf,"bf{",3)==0) {
00748 opBf=i; opFound = kTRUE;
00749 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00750 continue ;
00751 }
00752 if (strncmp(buf,"it[",3)==0 || strncmp(buf,"it{",3)==0) {
00753 opIt=i; opFound = kTRUE;
00754 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00755 continue ;
00756 }
00757 }
00758 for(k=0;k<54;k++) {
00759 if (!opFound && UInt_t(length)>i+strlen(tab[k])) {
00760 if (strncmp(&text[i+1],tab[k],strlen(tab[k]))==0) {
00761 opGreek=k;
00762 opFound = kTRUE;
00763 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00764 }
00765 }
00766 }
00767 for(k=0;k<10;k++) {
00768 if (!opFound && UInt_t(length)>i+strlen(tab3[k])) {
00769 if (strncmp(&text[i+1],tab3[k],strlen(tab3[k]))==0) {
00770 opAbove=k;
00771 opFound = kTRUE;
00772 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00773 }
00774 }
00775 }
00776 UInt_t lastsize = 0;
00777 if (!opFound)
00778 for(k=0;k<82;k++) {
00779 if ((opSpec==-1 || strlen(tab2[k])>lastsize) && UInt_t(length)>i+strlen(tab2[k])) {
00780 if (strncmp(&text[i+1],tab2[k],strlen(tab2[k]))==0) {
00781 lastsize = strlen(tab2[k]);
00782 opSpec=k;
00783 opFound = kTRUE;
00784 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
00785 }
00786 }
00787 }
00788 }
00789 }
00790
00791 TLatexFormSize fs1;
00792 TLatexFormSize fs2;
00793 TLatexFormSize fs3;
00794 TLatexFormSize result;
00795
00796
00797 if (opCloseCurly>-1 && opCloseCurly<length-1) {
00798 if(!fShow) {
00799 fs1 = Anal1(spec,text,opCloseCurly+1);
00800 fs2 = Anal1(spec,text+opCloseCurly+1,length-opCloseCurly-1);
00801 Savefs(&fs1);
00802 } else {
00803 fs1 = Readfs();
00804 Analyse(x+fs1.Width(),y,spec,text+opCloseCurly+1,length-opCloseCurly-1);
00805 Analyse(x,y,spec,text,opCloseCurly+1);
00806 }
00807 result = fs1+fs2;
00808 }
00809
00810 else if (opPower>-1 && opUnder>-1) {
00811 min = TMath::Min(opPower,opUnder);
00812 max = TMath::Max(opPower,opUnder);
00813 Double_t xfpos = 0. ;
00814 Double_t prop=1, propU=1;
00815 switch (abovePlace) {
00816 case 1 :
00817 prop = .8 ; propU = 1.75 ;
00818 break;
00819 case 2:
00820 prop = .9 ; propU = 1.75 ;
00821 break;
00822 }
00823
00824
00825
00826
00827 if (!fShow) {
00828 Int_t ltext = min ;
00829 if (min >= 2 && strncmp(&text[min-2],"{}",2)==0) {
00830
00831
00832 snprintf(&text[ltext-2],length-(ltext-2),"I ") ;
00833 ltext-- ;
00834 }
00835 fs1 = Anal1(spec,text,ltext);
00836 fs2 = Anal1(specNewSize,text+min+1,max-min-1);
00837 fs3 = Anal1(specNewSize,text+max+1,length-max-1);
00838 Savefs(&fs1);
00839 Savefs(&fs2);
00840 Savefs(&fs3);
00841 } else {
00842 fs3 = Readfs();
00843 fs2 = Readfs();
00844 fs1 = Readfs();
00845 Double_t pos = 0;
00846 if (!abovePlace) {
00847 Double_t addW = fs1.Width()+xfpos, addH1, addH2;
00848 if (opPower<opUnder) {
00849 addH1 = -fs1.Over()*(fFactorPos)-fs2.Under();
00850 addH2 = fs1.Under()+fs3.Over()*(fFactorPos);
00851 } else {
00852 addH1 = fs1.Under()+fs2.Over()*(fFactorPos);
00853 addH2 = -fs1.Over()*(fFactorPos)-fs3.Under();
00854 }
00855 Analyse(x+addW,y+addH2,specNewSize,text+max+1,length-max-1);
00856 Analyse(x+addW,y+addH1,specNewSize,text+min+1,max-min-1);
00857 } else {
00858 Double_t addW1, addW2, addH1, addH2;
00859 Double_t m = TMath::Max(fs1.Width(),TMath::Max(fs2.Width(),fs3.Width()));
00860 pos = (m-fs1.Width())/2;
00861 if (opPower<opUnder) {
00862 addH1 = -fs1.Over()*propU-fs2.Under();
00863 addW1 = (m-fs2.Width())/2;
00864 addH2 = fs1.Under()*prop+fs3.Over();
00865 addW2 = (m-fs3.Width())/2;
00866 } else {
00867 addH1 = fs1.Under()*prop+fs2.Over();
00868 addW1 = (m-fs2.Width())/2;
00869 addH2 = -fs1.Over()*propU-fs3.Under();
00870 addW2 = (m-fs3.Width())/2;
00871 }
00872
00873 Analyse(x+addW2,y+addH2,specNewSize,text+max+1,length-max-1);
00874 Analyse(x+addW1,y+addH1,specNewSize,text+min+1,max-min-1);
00875 }
00876
00877 if (min >= 2 && strncmp(&text[min-2],"{}",2)==0) {
00878 snprintf(&text[min-2],length-(min-2)," ") ;
00879 Analyse(x+pos,y,spec,text,min-1);
00880 } else {
00881 Analyse(x+pos,y,spec,text,min);
00882 }
00883 }
00884
00885 if (!abovePlace) {
00886 if (opPower<opUnder) {
00887 result.Set(fs1.Width()+xfpos+TMath::Max(fs2.Width(),fs3.Width()),
00888 fs1.Over()*fFactorPos+fs2.Height(),
00889 fs1.Under()+fs3.Height()-fs3.Over()*(1-fFactorPos));
00890 } else {
00891 result.Set(fs1.Width()+xfpos+TMath::Max(fs2.Width(),fs3.Width()),
00892 fs1.Over()*fFactorPos+fs3.Height(),
00893 fs1.Under()+fs2.Height()-fs2.Over()*(1-fFactorPos));
00894 }
00895 } else {
00896 if (opPower<opUnder) {
00897 result.Set(TMath::Max(fs1.Width(),TMath::Max(fs2.Width(),fs3.Width())),
00898 fs1.Over()*propU+fs2.Height(),fs1.Under()*prop+fs3.Height());
00899 } else {
00900 result.Set(TMath::Max(fs1.Width(),TMath::Max(fs2.Width(),fs3.Width())),
00901 fs1.Over()*propU+fs3.Height(),fs1.Under()*prop+fs2.Height());
00902 }
00903 }
00904 }
00905 else if (opPower>-1) {
00906 Double_t prop=1;
00907 Double_t xfpos = 0. ;
00908 switch (abovePlace) {
00909 case 1 :
00910 prop = 1.75 ; break ;
00911 case 2 :
00912 prop = 1.75; break ;
00913 }
00914
00915 if (!fShow) {
00916 Int_t ltext = opPower ;
00917 if (ltext >= 2 && strncmp(&text[ltext-2],"{}",2)==0) {
00918
00919
00920 snprintf(&text[ltext-2],length-(ltext-2),"I ") ;
00921 ltext-- ;
00922 }
00923 fs1 = Anal1(spec,text,ltext);
00924 fs2 = Anal1(specNewSize,text+opPower+1,length-opPower-1);
00925 Savefs(&fs1);
00926 Savefs(&fs2);
00927 } else {
00928 fs2 = Readfs();
00929 fs1 = Readfs();
00930 Int_t pos = 0;
00931 if (!abovePlace){
00932 Double_t over = fs1.Over();
00933 if (over <= 0) over = 1.5*fs2.Over();
00934 Analyse(x+fs1.Width()+xfpos,y-over*fFactorPos-fs2.Under(),specNewSize,text+opPower+1,length-opPower-1);
00935 } else {
00936 Int_t pos2=0;
00937 if (fs2.Width()>fs1.Width())
00938 pos=Int_t((fs2.Width()-fs1.Width())/2);
00939 else
00940 pos2=Int_t((fs1.Width()-fs2.Width())/2);
00941
00942 Analyse(x+pos2,y-fs1.Over()*prop-fs2.Under(),specNewSize,text+opPower+1,length-opPower-1);
00943 }
00944 if (opPower >= 2 && strncmp(&text[opPower-2],"{}",2)==0) {
00945 snprintf(&text[opPower-2],length-(opPower-2)," ") ;
00946 Analyse(x+pos,y,spec,text,opPower-1);
00947 } else {
00948 Analyse(x+pos,y,spec,text,opPower);
00949 }
00950 }
00951
00952 if (!abovePlace)
00953 result.Set(fs1.Width()+xfpos+fs2.Width(),
00954 fs1.Over()*fFactorPos+fs2.Over(),fs1.Under());
00955 else
00956 result.Set(TMath::Max(fs1.Width(),fs2.Width()),fs1.Over()*prop+fs2.Height(),fs1.Under());
00957
00958 }
00959 else if (opUnder>-1) {
00960 Double_t prop = .9;
00961 Double_t xfpos = 0.;
00962 Double_t fpos = fFactorPos ;
00963
00964 if(!fShow) {
00965 Int_t ltext = opUnder ;
00966 if (ltext >= 2 && strncmp(&text[ltext-2],"{}",2)==0) {
00967
00968
00969 snprintf(&text[ltext-2],length-(ltext-2),"I ") ;
00970 ltext-- ;
00971 }
00972 fs1 = Anal1(spec,text,ltext);
00973 fs2 = Anal1(specNewSize,text+opUnder+1,length-opUnder-1);
00974 Savefs(&fs1);
00975 Savefs(&fs2);
00976 } else {
00977 fs2 = Readfs();
00978 fs1 = Readfs();
00979 Int_t pos = 0;
00980 if (!abovePlace)
00981 Analyse(x+fs1.Width()+xfpos,y+fs1.Under()+fs2.Over()*fpos,specNewSize,text+opUnder+1,length-opUnder-1);
00982 else {
00983 Int_t pos2=0;
00984 if (fs2.Width()>fs1.Width())
00985 pos=Int_t((fs2.Width()-fs1.Width())/2);
00986 else
00987 pos2=Int_t((fs1.Width()-fs2.Width())/2);
00988
00989 Analyse(x+pos2,y+fs1.Under()*prop+fs2.Over(),specNewSize,text+opUnder+1,length-opUnder-1);
00990 }
00991 if (opUnder >= 2 && strncmp(&text[opUnder-2],"{}",2)==0) {
00992 snprintf(&text[opUnder-2],length-(opUnder-2)," ") ;
00993 Analyse(x+pos,y,spec,text,opUnder-1);
00994 } else {
00995 Analyse(x+pos,y,spec,text,opUnder);
00996 }
00997 }
00998 if (!abovePlace)
00999 result.Set(fs1.Width()+xfpos+fs2.Width(),fs1.Over(),
01000 fs1.Under()+fs2.Under()+fs2.Over()*fpos);
01001 else
01002 result.Set(TMath::Max(fs1.Width(),fs2.Width()),fs1.Over(),fs1.Under()*prop+fs2.Height());
01003 }
01004 else if (opBox) {
01005 Double_t square = GetHeight()*spec.fSize/2;
01006 if (!fShow) {
01007 fs1 = Anal1(spec,text+4,length-4);
01008 } else {
01009 fs1 = Analyse(x+square,y,spec,text+4,length-4);
01010 Double_t adjust = GetHeight()*spec.fSize/20;
01011 Double_t x1 = x+adjust ;
01012 Double_t x2 = x-adjust+square ;
01013 Double_t y1 = y;
01014 Double_t y2 = y-square+adjust;
01015 DrawLine(x1,y1,x2,y1,spec);
01016 DrawLine(x2,y1,x2,y2,spec);
01017 DrawLine(x2,y2,x1,y2,spec);
01018 DrawLine(x1,y2,x1,y1,spec);
01019 }
01020 result = fs1 + TLatexFormSize(square,square,0);
01021 }
01022 else if (opOdot) {
01023 Double_t square = GetHeight()*spec.fSize/2;
01024 if (!fShow) {
01025 fs1 = Anal1(spec,text+5,length-5);
01026 } else {
01027 fs1 = Analyse(x+1.3*square,y,spec,text+5,length-5);
01028 Double_t adjust = GetHeight()*spec.fSize/20;
01029 Double_t r1 = 0.62*square;
01030 Double_t y1 = y-0.3*square-adjust;
01031 DrawCircle(x+0.6*square,y1,r1,spec) ;
01032 DrawCircle(x+0.6*square,y1,r1/100,spec) ;
01033 }
01034 result = fs1 + TLatexFormSize(square,square,0);
01035 }
01036 else if (opHbar) {
01037 Double_t square = GetHeight()*spec.fSize/2;
01038 if (!fShow) {
01039 fs1 = Anal1(spec,text+5,length-5);
01040 } else {
01041 fs1 = Analyse(x+square,y,spec,text+5,length-5);
01042 TText hbar;
01043 hbar.SetTextFont(12);
01044 hbar.SetTextColor(fTextColor);
01045 hbar.SetTextSize(spec.fSize);
01046 hbar.SetTextAngle(fTextAngle);
01047 Double_t xOrigin = (Double_t)gPad->XtoAbsPixel(fX);
01048 Double_t yOrigin = (Double_t)gPad->YtoAbsPixel(fY);
01049 Double_t angle = kPI*spec.fAngle/180.;
01050 Double_t xx = gPad->AbsPixeltoX(Int_t((x-xOrigin)*TMath::Cos(angle)+(y-yOrigin)*TMath::Sin(angle)+xOrigin));
01051 Double_t yy = gPad->AbsPixeltoY(Int_t((x-xOrigin)*TMath::Sin(-angle)+(y-yOrigin)*TMath::Cos(angle)+yOrigin));
01052 hbar.PaintText(xx,yy,"h");
01053 DrawLine(x,y-0.8*square,x+0.75*square,y-square,spec);
01054 }
01055 result = fs1 + TLatexFormSize(square,square,0);
01056 }
01057 else if (opPerp) {
01058 Double_t square = GetHeight()*spec.fSize/1.4;
01059 if (!fShow) {
01060 fs1 = Anal1(spec,text+5,length-5);
01061 } else {
01062 fs1 = Analyse(x+0.5*square,y,spec,text+5,length-5);
01063 Double_t x0 = x + 0.50*square;
01064 Double_t x1 = x0 - 0.48*square;
01065 Double_t x2 = x0 + 0.48*square;
01066 Double_t y1 = y + 0.6*square;
01067 Double_t y2 = y1 - 1.3*square;
01068 DrawLine(x1,y1,x2,y1,spec);
01069 DrawLine(x0,y1,x0,y2,spec);
01070 }
01071 result = fs1;
01072 }
01073 else if (opParallel) {
01074 Double_t square = GetHeight()*spec.fSize/1.4;
01075 if (!fShow) {
01076 fs1 = Anal1(spec,text+9,length-9);
01077 } else {
01078 fs1 = Analyse(x+0.5*square,y,spec,text+9,length-9);
01079 Double_t x1 = x + 0.15*square;
01080 Double_t x2 = x + 0.45*square;
01081 Double_t y1 = y + 0.3*square;
01082 Double_t y2 = y1- 1.3*square;
01083 DrawLine(x1,y1,x1,y2,spec);
01084 DrawLine(x2,y1,x2,y2,spec);
01085 }
01086 result = fs1 + TLatexFormSize(square,square,0);
01087 }
01088 else if (opGreek>-1) {
01089 TextSpec_t newSpec = spec;
01090 newSpec.fFont = fItalic ? 152 : 122;
01091 char letter = 97 + opGreek;
01092 Double_t yoffset = 0.;
01093 if (opGreek>25) letter -= 58;
01094 if (opGreek == 52) letter = '\241';
01095 if (opGreek == 53) letter = '\316';
01096 if (!fShow) {
01097 fs1 = Anal1(newSpec,&letter,1);
01098 fs2 = Anal1(spec,text+strlen(tab[opGreek])+1,length-strlen(tab[opGreek])-1);
01099 Savefs(&fs1);
01100 } else {
01101 fs1 = Readfs();
01102 Analyse(x+fs1.Width(),y,spec,text+strlen(tab[opGreek])+1,length-strlen(tab[opGreek])-1);
01103 Analyse(x,y-yoffset,newSpec,&letter,1);
01104 }
01105 fs1.AddOver(TLatexFormSize(0,yoffset,0)) ;
01106 result = fs1+fs2;
01107 }
01108
01109 else if (opSpec>-1) {
01110 TextSpec_t newSpec = spec;
01111 newSpec.fFont = fItalic ? 152 : 122;
01112 char letter = '\243' + opSpec;
01113 if(opSpec == 75 || opSpec == 76) {
01114 newSpec.fFont = GetTextFont();
01115 if (opSpec == 75) letter = '\305';
01116 if (opSpec == 76) letter = '\345';
01117 }
01118 if(opSpec == 80 || opSpec == 81) {
01119 if (opSpec == 80) letter = '\042';
01120 if (opSpec == 81) letter = '\044';
01121 }
01122 Double_t props, propi;
01123 props = 1.8 ;
01124 propi = 2.3 ;
01125
01126 if (opSpec==66 ) {
01127 newSpec.fSize = spec.fSize*props;
01128 } else if (opSpec==79) {
01129 newSpec.fSize = spec.fSize*propi;
01130 }
01131 if (!fShow) {
01132 fs1 = Anal1(newSpec,&letter,1);
01133 if (opSpec == 79 || opSpec == 66)
01134 fs1.Set(fs1.Width(),fs1.Over()*0.45,fs1.Over()*0.45);
01135
01136 fs2 = Anal1(spec,text+strlen(tab2[opSpec])+1,length-strlen(tab2[opSpec])-1);
01137 Savefs(&fs1);
01138 } else {
01139 fs1 = Readfs();
01140 Analyse(x+fs1.Width(),y,spec,text+strlen(tab2[opSpec])+1,length-strlen(tab2[opSpec])-1);
01141 if (opSpec!=66 && opSpec!=79)
01142 Analyse(x,y,newSpec,&letter,1);
01143 else {
01144 Analyse(x,y+fs1.Under()/2.,newSpec,&letter,1);
01145 }
01146 }
01147 result = fs1+fs2;
01148 }
01149 else if (opAbove>-1) {
01150 if (!fShow) {
01151 fs1 = Anal1(spec,text+strlen(tab3[opAbove])+1,length-strlen(tab3[opAbove])-1);
01152 Savefs(&fs1);
01153 } else {
01154 fs1 = Readfs();
01155 Analyse(x,y,spec,text+strlen(tab3[opAbove])+1,length-strlen(tab3[opAbove])-1);
01156 Double_t sub = GetHeight()*spec.fSize/14;
01157 Double_t x1 , y1 , x2, y2, x3, x4;
01158 switch(opAbove) {
01159 case 0:
01160 Double_t ypos ;
01161 ypos = y-fs1.Over()-sub ;
01162 DrawLine(x,ypos,x+fs1.Width(),ypos,spec);
01163 break;
01164 case 1:
01165 Double_t y0 ;
01166 y0 = y-sub-fs1.Over() ;
01167 y1 = y0-GetHeight()*spec.fSize/8 ;
01168 x1 = x+fs1.Width() ;
01169 DrawLine(x,y1,x1,y1,spec);
01170 DrawLine(x1,y1,x1-GetHeight()*spec.fSize/4,y0-GetHeight()*spec.fSize/4,spec);
01171 DrawLine(x1,y1,x1-GetHeight()*spec.fSize/4,y0,spec);
01172 break;
01173 case 2:
01174 x1 = x+fs1.Width()/2-3*sub/4 ;
01175 x2 = x+fs1.Width()/2+3*sub/4 ;
01176 y1 = y-sub-fs1.Over() ;
01177 DrawLine(x1,y1,x2,y1,spec);
01178 break;
01179 case 3:
01180 x2 = x+fs1.Width()/2 ;
01181 y1 = y -9*sub;
01182 y2 = y1-2*sub;
01183 x1 = x2-fs1.Width()/3 ;
01184 x3 = x2+fs1.Width()/3 ;
01185 DrawLine(x1,y1,x2,y2,spec);
01186 DrawLine(x2,y2,x3,y1,spec);
01187 break;
01188 case 4:
01189 x1 = x+fs1.Width()/2-9*sub/4 ;
01190 x2 = x+fs1.Width()/2-3*sub/4 ;
01191 x3 = x+fs1.Width()/2+9*sub/4 ;
01192 x4 = x+fs1.Width()/2+3*sub/4 ;
01193 y1 = y-sub-fs1.Over() ;
01194 DrawLine(x1,y1,x2,y1,spec);
01195 DrawLine(x3,y1,x4,y1,spec);
01196 break;
01197 case 5:
01198 x1 = x+fs1.Width()/2;
01199 y1 = y +sub -fs1.Over() ;
01200 x2 = x1 +3*sub;
01201 y2 = y1 -2.5*sub;
01202 DrawLine(x1,y1,x2,y2,spec);
01203 break;
01204 case 6:
01205 x1 = x+fs1.Width()/2-sub;
01206 y1 = y-sub-fs1.Over() ;
01207 x2 = x1 +2*sub;
01208 y2 = y1 +2*sub;
01209 DrawLine(x1,y1,x2,y2,spec);
01210 break;
01211 case 7:
01212 x1 = x+fs1.Width()/2 ;
01213 x2 = x1 -2*sub ;
01214 x3 = x1 +2*sub ;
01215 y1 = y-sub-fs1.Over() ;
01216 DrawLine(x2,y-3*sub-fs1.Over(),x1,y1,spec);
01217 DrawLine(x3,y-3*sub-fs1.Over(),x1,y1,spec);
01218 break;
01219 case 8:
01220 x2 = x+fs1.Width()/2 ;
01221 y2 = y -fs1.Over() ;
01222 {
01223
01224
01225 TVirtualPS *saveps = gVirtualPS;
01226 if (gVirtualPS) gVirtualPS = 0;
01227 Double_t sinang = TMath::Sin(spec.fAngle/180*kPI);
01228 Double_t cosang = TMath::Cos(spec.fAngle/180*kPI);
01229 Double_t xOrigin = (Double_t)gPad->XtoAbsPixel(fX);
01230 Double_t yOrigin = (Double_t)gPad->YtoAbsPixel(fY);
01231 Double_t xx = gPad->AbsPixeltoX(Int_t((x2-xOrigin)*cosang+(y2-yOrigin)*sinang+xOrigin));
01232 Double_t yy = gPad->AbsPixeltoY(Int_t((x2-xOrigin)*-sinang+(y2-yOrigin)*cosang+yOrigin));
01233 TText tilde;
01234 tilde.SetTextFont(fTextFont);
01235 tilde.SetTextColor(fTextColor);
01236 tilde.SetTextSize(0.9*spec.fSize);
01237 tilde.SetTextAlign(22);
01238 tilde.SetTextAngle(fTextAngle);
01239 tilde.PaintText(xx,yy,"~");
01240 if (saveps) {
01241 y2 -= 4*sub;
01242 xx = gPad->AbsPixeltoX(Int_t((x2-xOrigin)*cosang+(y2-yOrigin)*sinang+xOrigin));
01243 yy = gPad->AbsPixeltoY(Int_t((x2-xOrigin)*-sinang+(y2-yOrigin)*cosang+yOrigin));
01244 gVirtualPS = saveps;
01245 gVirtualPS->SetTextAlign(22);
01246 gVirtualPS->Text(xx, yy, "~");
01247 }
01248 }
01249 break;
01250 case 9:
01251 x1 = x + 0.8*fs1.Width();
01252 y1 = y -fs1.Over() ;
01253 x2 = x + 0.3*fs1.Width();
01254 y2 = y1 + 1.2*fs1.Height();
01255 DrawLine(x1,y1,x2,y2,spec);
01256 break;
01257 }
01258 }
01259 Double_t div = 3;
01260 if (opAbove==1) div=4;
01261 result.Set(fs1.Width(),fs1.Over()+GetHeight()*spec.fSize/div,fs1.Under());
01262 }
01263 else if (opSquareBracket) {
01264 Double_t l = GetHeight()*spec.fSize/4;
01265 Double_t l2 = l/2 ;
01266 if (!fShow) {
01267 fs1 = Anal1(spec,text+3,length-3);
01268 Savefs(&fs1);
01269 } else {
01270 fs1 = Readfs();
01271 Analyse(x+l2+l,y,spec,text+3,length-3);
01272 DrawLine(x+l2,y-fs1.Over(),x+l2,y+fs1.Under(),spec);
01273 DrawLine(x+l2,y-fs1.Over(),x+l2+l,y-fs1.Over(),spec);
01274 DrawLine(x+l2,y+fs1.Under(),x+l2+l,y+fs1.Under(),spec);
01275 DrawLine(x+l2+fs1.Width()+2*l,y-fs1.Over(),x+l2+fs1.Width()+2*l,y+fs1.Under(),spec);
01276 DrawLine(x+l2+fs1.Width()+2*l,y-fs1.Over(),x+l2+fs1.Width()+l,y-fs1.Over(),spec);
01277 DrawLine(x+l2+fs1.Width()+2*l,y+fs1.Under(),x+l2+fs1.Width()+l,y+fs1.Under(),spec);
01278 }
01279 result.Set(fs1.Width()+3*l,fs1.Over(),fs1.Under());
01280 }
01281 else if (opParen) {
01282 Double_t l = GetHeight()*spec.fSize/4;
01283 Double_t radius2,radius1 , dw, l2 = l/2 ;
01284 Double_t angle = 35 ;
01285 if (!fShow) {
01286 fs1 = Anal1(spec,text+3,length-3);
01287 Savefs(&fs1);
01288 radius2 = fs1.Height() ;
01289 radius1 = radius2 * 2 / 3;
01290 dw = radius1*(1 - TMath::Cos(kPI*angle/180)) ;
01291 } else {
01292 fs1 = Readfs();
01293 radius2 = fs1.Height();
01294 radius1 = radius2 * 2 / 3;
01295 dw = radius1*(1 - TMath::Cos(kPI*angle/180)) ;
01296 Double_t x1 = x+l2+radius1 ;
01297 Double_t x2 = x+5*l2+2*dw+fs1.Width()-radius1 ;
01298 Double_t y1 = y - (fs1.Over() - fs1.Under())/2. ;
01299 DrawParenthesis(x1,y1,radius1,radius2,180-angle,180+angle,spec) ;
01300 DrawParenthesis(x2,y1,radius1,radius2,360-angle,360+angle,spec) ;
01301 Analyse(x+3*l2+dw,y,spec,text+3,length-3);
01302 }
01303
01304 result.Set(fs1.Width()+3*l+2*dw,fs1.Over(),fs1.Under());
01305 }
01306 else if (opAbs) {
01307 Double_t l = GetHeight()*spec.fSize/4;
01308 Double_t l2 = l/2 ;
01309 if (!fShow) {
01310 fs1 = Anal1(spec,text+3,length-3);
01311 Savefs(&fs1);
01312 } else {
01313 fs1 = Readfs();
01314 Analyse(x+l2+l,y,spec,text+3,length-3);
01315 DrawLine(x+l2,y-fs1.Over(),x+l2,y+fs1.Under(),spec);
01316 DrawLine(x+l2+fs1.Width()+2*l,y-fs1.Over(),x+l2+fs1.Width()+2*l,y+fs1.Under(),spec);
01317 }
01318 result.Set(fs1.Width()+3*l,fs1.Over(),fs1.Under());
01319 }
01320 else if (opBigCurly) {
01321 Double_t l = GetHeight()*spec.fSize/4;
01322 Double_t l2 = l/2 ;
01323 Double_t l8 , ltip;
01324
01325 if (!fShow) {
01326 fs1 = Anal1(spec,text+3,length-3);
01327 l8 = fs1.Height()/8 ;
01328 ltip = TMath::Min(l8,l) ;
01329 l = ltip ;
01330 Savefs(&fs1);
01331 } else {
01332 fs1 = Readfs();
01333 Double_t y2 = y + (fs1.Under()-fs1.Over())/2 ;
01334 l8 = fs1.Height()/8 ;
01335 ltip = TMath::Min(l8,l) ;
01336 l = ltip ;
01337 Analyse(x+l+ltip+l2,y,spec,text+3,length-3);
01338
01339
01340 DrawLine(x+l2+ltip,y-fs1.Over(),x+l2+ltip,y2-ltip,spec);
01341 DrawLine(x+l2+ltip,y2+ltip,x+l2+ltip,y+fs1.Under(),spec);
01342
01343 DrawLine(x+l2+ltip,y-fs1.Over(),x+l2+ltip+l,y-fs1.Over(),spec);
01344 DrawLine(x+l2+ltip,y+fs1.Under(),x+l2+ltip+l,y+fs1.Under(),spec);
01345
01346 DrawLine(x+l2,y2,x+l2+ltip,y2-ltip,spec);
01347 DrawLine(x+l2,y2,x+l2+ltip,y2+ltip,spec);
01348
01349
01350
01351 DrawLine(x+l2+ltip+fs1.Width()+2*l,y-fs1.Over(),x+l2+ltip+fs1.Width()+2*l,y2-ltip,spec);
01352 DrawLine(x+l2+ltip+fs1.Width()+2*l,y2+ltip,x+l2+ltip+fs1.Width()+2*l,y+fs1.Under(),spec);
01353
01354 DrawLine(x+l2+fs1.Width()+l+ltip,y-fs1.Over(),x+l2+ltip+fs1.Width()+2*l,y-fs1.Over(),spec);
01355 DrawLine(x+l2+fs1.Width()+l+ltip,y+fs1.Under(),x+l2+ltip+fs1.Width()+2*l,y+fs1.Under(),spec);
01356
01357 DrawLine(x+l2+ltip+2*l+fs1.Width(),y2-ltip,x+l2+2*l+2*ltip+fs1.Width(),y2,spec);
01358 DrawLine(x+l2+ltip+2*l+fs1.Width(),y2+ltip,x+l2+2*l+2*ltip+fs1.Width(),y2,spec);
01359 }
01360 result.Set(fs1.Width()+3*l+2*ltip,fs1.Over(),fs1.Under()) ;;
01361 }
01362 else if (opFrac>-1) {
01363 if (opCurlyCurly==-1) {
01364
01365 fError = "Missing denominator for #frac";
01366 return TLatexFormSize(0,0,0);
01367 }
01368 Double_t height = GetHeight()*spec.fSize/8;
01369 if (!fShow) {
01370 fs1 = Anal1(spec,text+opFrac+6,opCurlyCurly-opFrac-6);
01371 fs2 = Anal1(spec,text+opCurlyCurly+2,length-opCurlyCurly-3);
01372 Savefs(&fs1);
01373 Savefs(&fs2);
01374 } else {
01375 fs2 = Readfs();
01376 fs1 = Readfs();
01377 Double_t addW1,addW2;
01378 if (fs1.Width()<fs2.Width()) {
01379 addW1 = (fs2.Width()-fs1.Width())/2;
01380 addW2 = 0;
01381 } else {
01382 addW1 = 0;
01383 addW2 = (fs1.Width()-fs2.Width())/2;
01384 }
01385 Analyse(x+addW2,y+fs2.Over()-height,spec,text+opCurlyCurly+2,length-opCurlyCurly-3);
01386 Analyse(x+addW1,y-fs1.Under()-3*height,spec,text+opFrac+6,opCurlyCurly-opFrac-6);
01387
01388 DrawLine(x,y-2*height,x+TMath::Max(fs1.Width(),fs2.Width()),y-2*height,spec);
01389 }
01390
01391 result.Set(TMath::Max(fs1.Width(),fs2.Width()),fs1.Height()+3*height,fs2.Height()-height);
01392
01393 }
01394 else if (opSplitLine>-1) {
01395 if (opCurlyCurly==-1) {
01396
01397 fError = "Missing second line for #splitline";
01398 return TLatexFormSize(0,0,0);
01399 }
01400 Double_t height = GetHeight()*spec.fSize/8;
01401 if (!fShow) {
01402 fs1 = Anal1(spec,text+opSplitLine+11,opCurlyCurly-opSplitLine-11);
01403 fs2 = Anal1(spec,text+opCurlyCurly+2,length-opCurlyCurly-3);
01404 Savefs(&fs1);
01405 Savefs(&fs2);
01406 } else {
01407 fs2 = Readfs();
01408 fs1 = Readfs();
01409 Analyse(x,y+fs2.Over()-height,spec,text+opCurlyCurly+2,length-opCurlyCurly-3);
01410 Analyse(x,y-fs1.Under()-3*height,spec,text+opSplitLine+11,opCurlyCurly-opSplitLine-11);
01411 }
01412
01413 result.Set(TMath::Max(fs1.Width(),fs2.Width()),fs1.Height()+3*height,fs2.Height()-height);
01414
01415 }
01416 else if (opSqrt>-1) {
01417 if (!fShow) {
01418 if (opSquareCurly>-1) {
01419
01420 fs1 = Anal1(specNewSize,text+opSqrt+6,opSquareCurly-opSqrt-6);
01421 fs2 = Anal1(spec,text+opSquareCurly+1,length-opSquareCurly-1);
01422 Savefs(&fs1);
01423 Savefs(&fs2);
01424 result.Set(fs2.Width()+ GetHeight()*spec.fSize/10+TMath::Max(GetHeight()*spec.fSize/2,(Double_t)fs1.Width()),
01425 fs2.Over()+fs1.Height()+GetHeight()*spec.fSize/4,fs2.Under());
01426 } else {
01427 fs1 = Anal1(spec,text+opSqrt+5,length-opSqrt-5);
01428 Savefs(&fs1);
01429 result.Set(fs1.Width()+GetHeight()*spec.fSize/2,fs1.Over()+GetHeight()*spec.fSize/4,fs1.Under());
01430 }
01431 } else {
01432 if (opSquareCurly>-1) {
01433 fs2 = Readfs();
01434 fs1 = Readfs();
01435 Double_t pas = TMath::Max(GetHeight()*spec.fSize/2,(Double_t)fs1.Width());
01436 Double_t pas2 = pas + GetHeight()*spec.fSize/10;
01437 Double_t y1 = y-fs2.Over() ;
01438 Double_t y2 = y+fs2.Under() ;
01439 Double_t y3 = y1-GetHeight()*spec.fSize/4;
01440 Analyse(x+pas2,y,spec,text+opSquareCurly+1,length-opSquareCurly-1);
01441 Analyse(x,y-fs2.Over()-fs1.Under(),specNewSize,text+opSqrt+6,opSquareCurly-opSqrt-6);
01442 DrawLine(x,y1,x+pas,y2,spec);
01443 DrawLine(x+pas,y2,x+pas,y3,spec);
01444 DrawLine(x+pas,y3,x+pas2+fs2.Width(),y3,spec);
01445 } else {
01446 fs1 = Readfs();
01447 Double_t x1 = x+GetHeight()*spec.fSize*2/5 ;
01448 Double_t x2 = x+GetHeight()*spec.fSize/2+fs1.Width() ;
01449 Double_t y1 = y-fs1.Over() ;
01450 Double_t y2 = y+fs1.Under() ;
01451 Double_t y3 = y1-GetHeight()*spec.fSize/4;
01452
01453 Analyse(x+GetHeight()*spec.fSize/2,y,spec,text+opSqrt+6,length-opSqrt-7);
01454
01455 Short_t lineW = GetLineWidth();
01456 Double_t dx = (y2-y3)/8;
01457 SetLineWidth(TMath::Max(2,(Int_t)(dx/2)));
01458 DrawLine(x-dx,y1,x1-dx,y2,spec);
01459 SetLineWidth((Int_t)(dx/4));
01460 DrawLine(x1-dx,y2,x1,y3,spec);
01461 DrawLine(x1,y3,x2,y3,spec);
01462 SetLineWidth(lineW);
01463 }
01464 }
01465 }
01466 else if (opColor>-1) {
01467 if (opSquareCurly==-1) {
01468
01469 fError = "Missing color number. Syntax is #color[(Int_t)nb]{ ... }";
01470 return TLatexFormSize(0,0,0);
01471 }
01472 TextSpec_t newSpec = spec;
01473 Char_t *nb = new Char_t[opSquareCurly-opColor-6];
01474 strncpy(nb,text+opColor+7,opSquareCurly-opColor-7);
01475 nb[opSquareCurly-opColor-7] = 0;
01476 if (sscanf(nb,"%d",&newSpec.fColor) < 1) {
01477 delete[] nb;
01478
01479 fError = "Invalid color number. Syntax is #color[(Int_t)nb]{ ... }";
01480 return TLatexFormSize(0,0,0);
01481 }
01482 delete[] nb;
01483 if (!fShow) {
01484 result = Anal1(newSpec,text+opSquareCurly+1,length-opSquareCurly-1);
01485 } else {
01486 Analyse(x,y,newSpec,text+opSquareCurly+1,length-opSquareCurly-1);
01487 }
01488 }
01489 else if (opFont>-1) {
01490 if (opSquareCurly==-1) {
01491
01492 fError = "Missing font number. Syntax is #font[nb]{ ... }";
01493 return TLatexFormSize(0,0,0);
01494 }
01495 TextSpec_t newSpec = spec;
01496 Char_t *nb = new Char_t[opSquareCurly-opFont-5];
01497 strncpy(nb,text+opFont+6,opSquareCurly-opFont-6);
01498 nb[opSquareCurly-opFont-6] = 0;
01499 if (sscanf(nb,"%d",&newSpec.fFont) < 1) {
01500 delete[] nb;
01501
01502 fError = "Invalid font number. Syntax is #font[(Int_t)nb]{ ... }";
01503 return TLatexFormSize(0,0,0);
01504 }
01505 delete[] nb;
01506 if (!fShow) {
01507 result = Anal1(newSpec,text+opSquareCurly+1,length-opSquareCurly-1);
01508 } else {
01509 Analyse(x,y,newSpec,text+opSquareCurly+1,length-opSquareCurly-1);
01510 }
01511 }
01512 else if (opKern>-1) {
01513 if (opSquareCurly==-1) {
01514
01515 fError = "Missing horizontal shift number. Syntax is #kern[dx]{ ... }";
01516 return TLatexFormSize(0,0,0);
01517 }
01518 Char_t *dxc = new Char_t[opSquareCurly-opKern-5];
01519 strncpy(dxc,text+opKern+6,opSquareCurly-opKern-6);
01520 dxc[opSquareCurly-opKern-6] = 0;
01521 Float_t dx = 0;
01522 if (sscanf(dxc,"%f",&dx) < 1) {
01523 delete[] dxc;
01524
01525 fError = "Invalid horizontal shift number. Syntax is #kern[(Float_t)dx]{ ... }";
01526 return TLatexFormSize(0,0,0);
01527 }
01528 delete[] dxc;
01529 if (!fShow) {
01530 fs1 = Anal1(spec,text+opSquareCurly+1,length-opSquareCurly-1);
01531 Savefs(&fs1);
01532 Double_t ddx = dx * fs1.Width();
01533 result = TLatexFormSize(fs1.Width() + ddx, fs1.Over(), fs1.Under());
01534 } else {
01535 fs1 = Readfs();
01536 Double_t ddx = dx * fs1.Width();
01537 Analyse(x + ddx,y,spec,text+opSquareCurly+1,length-opSquareCurly-1);
01538 }
01539 }
01540 else if (opLower>-1) {
01541 if (opSquareCurly==-1) {
01542
01543 fError = "Missing vertical shift number. Syntax is #lower[dy]{ ... }";
01544 return TLatexFormSize(0,0,0);
01545 }
01546 Char_t *dyc = new Char_t[opSquareCurly-opLower-6];
01547 strncpy(dyc,text+opLower+7,opSquareCurly-opLower-7);
01548 dyc[opSquareCurly-opLower-7] = 0;
01549 Float_t dy = 0;
01550 if (sscanf(dyc,"%f",&dy) < 1) {
01551 delete[] dyc;
01552
01553 fError = "Invalid vertical shift number. Syntax is #lower[(Float_t)dy]{ ... }";
01554 return TLatexFormSize(0,0,0);
01555 }
01556 delete[] dyc;
01557 if (!fShow) {
01558 fs1 = Anal1(spec,text+opSquareCurly+1,length-opSquareCurly-1);
01559 Savefs(&fs1);
01560 Double_t ddy = dy * (fs1.Over() + fs1.Under());
01561 result = TLatexFormSize(fs1.Width(), fs1.Over() + ddy, fs1.Under() + ddy);
01562 } else {
01563 fs1 = Readfs();
01564 Double_t ddy = dy * (fs1.Over() + fs1.Under());
01565 Analyse(x,y + ddy,spec,text+opSquareCurly+1,length-opSquareCurly-1);
01566 }
01567 }
01568 else if (opScale>-1) {
01569 if (opSquareCurly==-1) {
01570
01571 fError = "Missing scale factor. Syntax is #scale[(Double_t)nb]{ ... }";
01572 return TLatexFormSize(0,0,0);
01573 }
01574 TextSpec_t newSpec = spec;
01575 Char_t *nb = new Char_t[opSquareCurly-opScale-6];
01576 strncpy(nb,text+opScale+7,opSquareCurly-opScale-7);
01577 nb[opSquareCurly-opScale-7] = 0;
01578 if (sscanf(nb,"%lf",&newSpec.fSize) < 1) {
01579 delete[] nb;
01580
01581 fError = "Invalid scale factor. Syntax is #factor[(Double_t)nb]{ ... }";
01582 return TLatexFormSize(0,0,0);
01583 }
01584 newSpec.fSize *= spec.fSize;
01585 delete[] nb;
01586 if (!fShow) {
01587 result = Anal1(newSpec,text+opSquareCurly+1,length-opSquareCurly-1);
01588 } else {
01589 Analyse(x,y,newSpec,text+opSquareCurly+1,length-opSquareCurly-1);
01590 }
01591 }
01592 else if (opBf>-1) {
01593 TextSpec_t newSpec = spec;
01594 Int_t lut[] = {3, 13, 1, 6, 7, 4, 5, 10, 11, 8, 9, 12, 2, 14, 15};
01595 Int_t fontId = (newSpec.fFont/10);
01596 if ((fontId >= 1) && (fontId <= (Int_t)(sizeof(lut)/sizeof(lut[0])))) fontId = lut[fontId-1];
01597 newSpec.fFont = fontId*10 + newSpec.fFont%10;
01598 if (!fShow) {
01599 fs1 = Anal1(newSpec,text+3,length-3);
01600 Savefs(&fs1);
01601 } else {
01602 fs1 = Readfs();
01603 Analyse(x,y,newSpec,text+3,length-3);
01604 }
01605 result = fs1;
01606 }
01607 else if (opIt>-1) {
01608 TextSpec_t newSpec = spec;
01609 Int_t lut[] = {13, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 15, 1, 14, 12};
01610 Int_t fontId = (newSpec.fFont/10);
01611 if ((fontId >= 1) && (fontId <= (Int_t)(sizeof(lut)/sizeof(lut[0])))) fontId = lut[fontId-1];
01612 newSpec.fFont = fontId*10 + newSpec.fFont%10;
01613 fItalic = !fItalic;
01614 if (!fShow) {
01615 fs1 = Anal1(newSpec,text+3,length-3);
01616 Savefs(&fs1);
01617 } else {
01618 fs1 = Readfs();
01619 Analyse(x,y,newSpec,text+3,length-3);
01620 }
01621 fItalic = !fItalic;
01622 result = fs1;
01623 }
01624 else {
01625 SetTextSize(spec.fSize);
01626 SetTextAngle(spec.fAngle);
01627 SetTextColor(spec.fColor);
01628 SetTextFont(spec.fFont);
01629 SetTextAlign(11);
01630 TAttText::Modify();
01631 UInt_t w=0,h=0;
01632
01633 Int_t leng = strlen(text) ;
01634
01635 quote1 = quote2 = kFALSE ;
01636 Char_t *p ;
01637 for (i=0 ; i<leng ; i++) {
01638 switch (text[i]) {
01639 case '\'' : quote1 = !quote1 ; break ;
01640 case '"' : quote2 = !quote2 ; break ;
01641 }
01642
01643 if (text[i] == '@') {
01644 p = &text[i] ;
01645 if ( *(p+1) == '{' || *(p+1) == '}' || *(p+1) == '[' || *(p+1) == ']') {
01646 while (*p != 0) {
01647 *p = *(p+1) ; p++ ;
01648 }
01649 leng-- ;
01650 }
01651 }
01652 }
01653 text[leng] = 0 ;
01654
01655 if (fShow) {
01656
01657 Double_t xOrigin = (Double_t)gPad->XtoAbsPixel(fX);
01658 Double_t yOrigin = (Double_t)gPad->YtoAbsPixel(fY);
01659 Double_t angle = kPI*spec.fAngle/180.;
01660 Double_t xx = gPad->AbsPixeltoX(Int_t((x-xOrigin)*TMath::Cos(angle)+(y-yOrigin)*TMath::Sin(angle)+xOrigin));
01661 Double_t yy = gPad->AbsPixeltoY(Int_t((x-xOrigin)*TMath::Sin(-angle)+(y-yOrigin)*TMath::Cos(angle)+yOrigin));
01662 gPad->PaintText(xx,yy,text);
01663 } else {
01664 GetTextExtent(w,h,text);
01665 Double_t width = w;
01666 UInt_t a,d;
01667 GetTextAscentDescent(a, d, text);
01668 fs1.Set(width,a,d);
01669 }
01670
01671 result = fs1;
01672 }
01673
01674 delete[] text;
01675
01676 return result;
01677 }
01678
01679
01680
01681 TLatex *TLatex::DrawLatex(Double_t x, Double_t y, const char *text)
01682 {
01683
01684
01685
01686 TLatex *newtext = new TLatex(x, y, text);
01687 TAttText::Copy(*newtext);
01688 newtext->SetBit(kCanDelete);
01689 if (TestBit(kTextNDC)) newtext->SetNDC();
01690 newtext->AppendPad();
01691 return newtext;
01692 }
01693
01694
01695
01696 void TLatex::DrawLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2, TextSpec_t spec)
01697 {
01698
01699
01700 Double_t sinang = TMath::Sin(spec.fAngle/180*kPI);
01701 Double_t cosang = TMath::Cos(spec.fAngle/180*kPI);
01702 Double_t xOrigin = (Double_t)gPad->XtoAbsPixel(fX);
01703 Double_t yOrigin = (Double_t)gPad->YtoAbsPixel(fY);
01704 Double_t xx = gPad->AbsPixeltoX(Int_t((x1-xOrigin)*cosang+(y1-yOrigin)*sinang+xOrigin));
01705 Double_t yy = gPad->AbsPixeltoY(Int_t((x1-xOrigin)*-sinang+(y1-yOrigin)*cosang+yOrigin));
01706
01707 Double_t xx2 = gPad->AbsPixeltoX(Int_t((x2-xOrigin)*cosang+(y2-yOrigin)*sinang+xOrigin));
01708 Double_t yy2 = gPad->AbsPixeltoY(Int_t((x2-xOrigin)*-sinang+(y2-yOrigin)*cosang+yOrigin));
01709
01710 SetLineColor(spec.fColor);
01711 TAttLine::Modify();
01712 gPad->PaintLine(xx,yy,xx2,yy2);
01713 }
01714
01715
01716
01717 void TLatex::DrawCircle(Double_t x1, Double_t y1, Double_t r, TextSpec_t spec )
01718 {
01719
01720
01721 if (r < 1) r = 1;
01722 Double_t sinang = TMath::Sin(spec.fAngle/180*kPI);
01723 Double_t cosang = TMath::Cos(spec.fAngle/180*kPI);
01724 Double_t xOrigin = (Double_t)gPad->XtoAbsPixel(fX);
01725 Double_t yOrigin = (Double_t)gPad->YtoAbsPixel(fY);
01726
01727 const Int_t np = 40;
01728 Double_t dphi = 2*kPI/np;
01729 Double_t x[np+3], y[np+3];
01730 Double_t angle,dx,dy;
01731
01732 SetLineColor(spec.fColor);
01733 TAttLine::Modify();
01734
01735 for (Int_t i=0;i<=np;i++) {
01736 angle = Double_t(i)*dphi;
01737 dx = r*TMath::Cos(angle) +x1 -xOrigin;
01738 dy = r*TMath::Sin(angle) +y1 -yOrigin;
01739 x[i] = gPad->AbsPixeltoX(Int_t( dx*cosang+ dy*sinang +xOrigin));
01740 y[i] = gPad->AbsPixeltoY(Int_t(-dx*sinang+ dy*cosang +yOrigin));
01741 }
01742 gPad->PaintPolyLine(np+1,x,y);
01743 }
01744
01745
01746
01747 void TLatex::DrawParenthesis(Double_t x1, Double_t y1, Double_t r1, Double_t r2,
01748 Double_t phimin, Double_t phimax, TextSpec_t spec )
01749 {
01750
01751
01752 if (r1 < 1) r1 = 1;
01753 if (r2 < 1) r2 = 1;
01754 Double_t sinang = TMath::Sin(spec.fAngle/180*kPI);
01755 Double_t cosang = TMath::Cos(spec.fAngle/180*kPI);
01756 Double_t xOrigin = (Double_t)gPad->XtoAbsPixel(fX);
01757 Double_t yOrigin = (Double_t)gPad->YtoAbsPixel(fY);
01758
01759 const Int_t np = 40;
01760 Double_t dphi = (phimax-phimin)*kPI/(180*np);
01761 Double_t x[np+3], y[np+3];
01762 Double_t angle,dx,dy ;
01763
01764 SetLineColor(spec.fColor);
01765 TAttLine::Modify();
01766
01767 for (Int_t i=0;i<=np;i++) {
01768 angle = phimin*kPI/180 + Double_t(i)*dphi;
01769 dx = r1*TMath::Cos(angle) +x1 -xOrigin;
01770 dy = r2*TMath::Sin(angle) +y1 -yOrigin;
01771 x[i] = gPad->AbsPixeltoX(Int_t( dx*cosang+dy*sinang +xOrigin));
01772 y[i] = gPad->AbsPixeltoY(Int_t(-dx*sinang+dy*cosang +yOrigin));
01773 }
01774 gPad->PaintPolyLine(np+1,x,y);
01775 }
01776
01777
01778
01779 void TLatex::Paint(Option_t *)
01780 {
01781
01782
01783 Double_t xsave = fX;
01784 Double_t ysave = fY;
01785 if (TestBit(kTextNDC)) {
01786 fX = gPad->GetX1() + xsave*(gPad->GetX2() - gPad->GetX1());
01787 fY = gPad->GetY1() + ysave*(gPad->GetY2() - gPad->GetY1());
01788 PaintLatex(fX,fY,GetTextAngle(),GetTextSize(),GetTitle());
01789 } else {
01790 PaintLatex(gPad->XtoPad(fX),gPad->YtoPad(fY),GetTextAngle(),GetTextSize(),GetTitle());
01791 }
01792 fX = xsave;
01793 fY = ysave;
01794 }
01795
01796
01797
01798 void TLatex::PaintLatex(Double_t x, Double_t y, Double_t angle, Double_t size, const Char_t *text1)
01799 {
01800
01801
01802
01803
01804
01805 TAttText::Modify();
01806
01807
01808 if (fTextFont%10 < 2) {
01809 if (gVirtualX) gVirtualX->SetTextAngle(angle);
01810 if (gVirtualPS) gVirtualPS->SetTextAngle(angle);
01811 gPad->PaintText(x,y,text1);
01812 return;
01813 }
01814
01815 TString newText = text1;
01816 if( newText.Length() == 0) return;
01817
01818 Double_t saveSize = size;
01819 Int_t saveFont = fTextFont;
01820 if (fTextFont%10 > 2) {
01821 UInt_t w = TMath::Abs(gPad->XtoAbsPixel(gPad->GetX2()) -
01822 gPad->XtoAbsPixel(gPad->GetX1()));
01823 UInt_t h = TMath::Abs(gPad->YtoAbsPixel(gPad->GetY2()) -
01824 gPad->YtoAbsPixel(gPad->GetY1()));
01825 if (w < h)
01826 size = size/w;
01827 else
01828 size = size/h;
01829 SetTextFont(10*(saveFont/10) + 2);
01830 }
01831 if (gVirtualPS) gVirtualPS->SetBit(kLatex);
01832
01833 fError = 0 ;
01834 if (CheckLatexSyntax(newText)) {
01835 cout<<"\n*ERROR<TLatex>: "<<fError<<endl;
01836 cout<<"==> "<<text1<<endl;
01837 return ;
01838 }
01839 fError = 0 ;
01840
01841 Int_t length = newText.Length() ;
01842 const Char_t *text = newText.Data() ;
01843
01844 fX=x;
01845 fY=y;
01846 x = gPad->XtoAbsPixel(x);
01847 y = gPad->YtoAbsPixel(y);
01848 fShow = kFALSE ;
01849 TLatexFormSize fs = FirstParse(angle,size,text);
01850
01851 fOriginSize = size;
01852
01853
01854 Short_t lineW = GetLineWidth();
01855 Int_t lineC = GetLineColor();
01856
01857 TextSpec_t spec;
01858 spec.fAngle = angle;
01859 spec.fSize = size;
01860 spec.fColor = GetTextColor();
01861 spec.fFont = GetTextFont();
01862 Short_t halign = fTextAlign/10;
01863 Short_t valign = fTextAlign - 10*halign;
01864 TextSpec_t newSpec = spec;
01865 if (fError != 0) {
01866 cout<<"*ERROR<TLatex>: "<<fError<<endl;
01867 cout<<"==> "<<text<<endl;
01868 } else {
01869 fShow = kTRUE;
01870 newSpec.fSize = size;
01871
01872 switch (valign) {
01873 case 0: y -= fs.Under() ; break;
01874 case 1: break;
01875 case 2: y += fs.Height()*0.5-fs.Under(); y++; break;
01876 case 3: y += fs.Over() ; break;
01877 }
01878 switch (halign) {
01879 case 2: x -= fs.Width()/2 ; break;
01880 case 3: x -= fs.Width() ; break;
01881 }
01882 Analyse(x,y,newSpec,text,length);
01883 }
01884
01885 SetTextSize(saveSize);
01886 SetTextAngle(angle);
01887 SetTextFont(saveFont);
01888 SetTextColor(spec.fColor);
01889 SetTextAlign(valign+10*halign);
01890 SetLineWidth(lineW);
01891 SetLineColor(lineC);
01892 delete[] fTabSize;
01893
01894 if (gVirtualPS) gVirtualPS->ResetBit(kLatex);
01895 }
01896
01897
01898
01899 Int_t TLatex::CheckLatexSyntax(TString &text)
01900 {
01901
01902
01903 const Char_t *kWord1[] = {"{}^{","{}_{","^{","_{","#scale{","#color{","#font{","#sqrt{","#[]{","#{}{","#||{",
01904 "#bar{","#vec{","#dot{","#hat{","#ddot{","#acute{","#grave{","#check{","#tilde{","#slash{","#bf{","#it{",
01905 "\\scale{","\\color{","\\font{","\\sqrt{","\\[]{","\\{}{","\\||{","#(){","\\(){",
01906 "\\bar{","\\vec{","\\dot{","\\hat{","\\ddot{","\\acute{","\\grave{","\\check{","\\bf{","\\it{"};
01907 const Char_t *kWord2[] = {"#scale[","#color[","#font[","#sqrt[","#kern[","#lower[","\\scale[","\\color[","\\font[","\\sqrt[","\\kern[","\\lower["};
01908 const Char_t *kWord3[] = {"#frac{","\\frac{","#splitline{","\\splitline{"};
01909 const Char_t *kLeft1[] = {"#left[","\\left[","#left{","\\left{","#left|","\\left|","#left(","\\left("};
01910 const Char_t *kLeft2[] = {"#[]{","#[]{","#{}{","#{}{","#||{","#||{","#(){","#(){"};
01911 const Char_t *kRight[] = {"#right]","\\right]","#right}","\\right}","#right|","\\right|","#right)","\\right)"};
01912 const Int_t lkWord1[] = {4,4,2,2,7,7,6,6,4,4,4,5,5,5,5,6,7,7,7,7,7,4,4,7,7,6,6,4,4,4,4,4,5,5,5,5,6,7,7,7,4,4};
01913 const Int_t lkWord2[] = {7,7,6,6,6,7,7,7,6,6,6,7} ;
01914 const Int_t lkWord3[] = {6,6,11,11} ;
01915 Int_t nkWord1 = 42, nkWord2 = 12, nkWord3 = 4;
01916 Int_t i,k ;
01917 Int_t nLeft1 , nRight , nOfLeft, nOfRight;
01918 Int_t lLeft1 = 6 ;
01919 Int_t lLeft2 = 4 ;
01920 Int_t lRight = 7 ;
01921 nLeft1 = nRight = 8 ;
01922 nOfLeft = nOfRight = 0 ;
01923
01924 Char_t buf[11] ; for (i=0;i<11;i++) buf[i]=0;
01925 Bool_t opFound ;
01926 Int_t opFrac = 0;
01927 Int_t length = text.Length() ;
01928
01929 Int_t nOfCurlyBracket, nOfKW1, nOfKW2, nOfKW3, nOfSquareCurly, nOfCurlyCurly ;
01930 Int_t nOfExtraCurly = 0 , nOfExtraSquare = 0;
01931 Int_t nOfSquareBracket = 0 ;
01932 Int_t error = 0 ;
01933 Bool_t quote1 = kFALSE , quote2 = kFALSE;
01934
01935
01936
01937 i = 0 ;
01938 while (i < length) {
01939
01940
01941 strncpy(buf,&text[i],TMath::Min(7,length-i));
01942 opFound = kFALSE ;
01943 for (k = 0 ; k < nLeft1 ; k++) {
01944 if (strncmp(buf,kLeft1[k],lLeft1)==0) {
01945 nOfLeft++ ;
01946 i+=lLeft1 ;
01947 opFound = kTRUE ;
01948 break ;
01949 }
01950 }
01951 if (opFound) continue ;
01952
01953 for(k=0;k<nRight;k++) {
01954 if (strncmp(buf,kRight[k],lRight)==0) {
01955 nOfRight++ ;
01956 i+=lRight ;
01957 opFound = kTRUE ;
01958 break ;
01959 }
01960 }
01961 if (!opFound) i++ ;
01962 }
01963 if (nOfLeft != nOfRight) {
01964 printf(" nOfLeft = %d, nOfRight = %d\n",nOfLeft,nOfRight) ;
01965 error = 1 ;
01966 fError = "Operators \"#left\" and \"#right\" don't match !" ;
01967 goto ERROR_END ;
01968 }
01969
01970 for (k = 0 ; k < nLeft1 ; k++) {
01971 text.ReplaceAll(kLeft1[k],lLeft1,kLeft2[k],lLeft2) ;
01972 }
01973 for (k = 0 ; k < nRight ; k++) {
01974 text.ReplaceAll(kRight[k],lRight,"}",1) ;
01975 }
01976 length = text.Length() ;
01977
01978 i = nOfCurlyBracket = nOfKW1 = nOfKW2 = nOfKW3 = nOfSquareCurly = nOfCurlyCurly =0 ;
01979 while (i< length){
01980 switch (text[i]) {
01981 case '"' : quote1 = !quote1 ; break ;
01982 case '\'': quote2 = !quote2 ; break ;
01983 }
01984
01985
01986 strncpy(buf,&text[i],TMath::Min(11,length-i));
01987 opFound = kFALSE ;
01988
01989 for(k=0;k<nkWord1;k++) {
01990 if (strncmp(buf,kWord1[k],lkWord1[k])==0) {
01991 nOfKW1++ ;
01992 i+=lkWord1[k] ;
01993 opFound = kTRUE ;
01994 nOfCurlyBracket++ ;
01995 break ;
01996 }
01997 }
01998 if (opFound) continue ;
01999
02000 for(k=0;k<nkWord2;k++) {
02001 if (strncmp(buf,kWord2[k],lkWord2[k])==0) {
02002 nOfKW2++ ;
02003 i+=lkWord2[k] ;
02004 opFound = kTRUE ;
02005 nOfSquareBracket++;
02006 break ;
02007 }
02008 }
02009 if (opFound) continue ;
02010
02011 for(k=0;k<nkWord3;k++) {
02012 if (strncmp(buf,kWord3[k],lkWord3[k])==0) {
02013 nOfKW3++ ;
02014 i+=lkWord3[k] ;
02015 opFound = kTRUE ;
02016 opFrac++ ;
02017 nOfCurlyBracket++ ;
02018 break ;
02019 }
02020 }
02021 if (opFound) continue ;
02022 if (strncmp(buf,"}{",2) == 0 && opFrac) {
02023 opFrac-- ;
02024 nOfCurlyCurly++ ;
02025 i+= 2;
02026 }
02027 else if (strncmp(buf,"]{",2) == 0 && nOfSquareBracket) {
02028 nOfSquareCurly++ ;
02029 i+= 2 ;
02030 nOfCurlyBracket++ ;
02031 nOfSquareBracket-- ;
02032 }
02033 else if (strncmp(buf,"@{",2) == 0 || strncmp(buf,"@}",2) == 0) {
02034 i+= 2 ;
02035 }
02036 else if (strncmp(buf,"@[",2) == 0 || strncmp(buf,"@]",2) == 0) {
02037 i+= 2 ;
02038 }
02039 else if (text[i] == ']' ) {
02040 text.Insert(i,"@") ;
02041 length++ ;
02042 i+=2 ;
02043 nOfExtraSquare-- ;
02044 }
02045 else if (text[i] == '[' ) {
02046 text.Insert(i,"@") ;
02047 length++ ;
02048 i+=2 ;
02049 nOfExtraSquare++ ;
02050 }
02051 else if (text[i] == '{' ) {
02052 text.Insert(i,"@") ;
02053 length++ ;
02054 i+=2 ;
02055 nOfExtraCurly++ ;
02056 }
02057 else if (text[i] == '}' ) {
02058 if ( nOfCurlyBracket) {
02059 nOfCurlyBracket-- ;
02060 i++ ;
02061 } else {
02062 text.Insert(i,"@") ;
02063 length++ ;
02064 i+=2 ;
02065 nOfExtraCurly-- ;
02066 }
02067 } else {
02068 i++ ;
02069 buf[1] = 0 ;
02070 }
02071 }
02072
02073 if (nOfKW2 != nOfSquareCurly) {
02074 error = 1 ;
02075 fError = "Invalid number of \"]{\"" ;
02076 }
02077 else if (nOfKW3 != nOfCurlyCurly) {
02078 error = 1 ;
02079 fError = "Error in syntax of \"#frac\"" ;
02080 }
02081 else if (nOfCurlyBracket < 0) {
02082 error = 1 ;
02083 fError = "Missing \"{\"" ;
02084 }
02085 else if (nOfCurlyBracket > 0) {
02086 error = 1 ;
02087 fError = "Missing \"}\"" ;
02088 }
02089 else if (nOfSquareBracket < 0) {
02090 error = 1 ;
02091 fError = "Missing \"[\"" ;
02092 }
02093 else if (nOfSquareBracket > 0) {
02094 error = 1 ;
02095 fError = "Missing \"]\"" ;
02096 }
02097
02098 ERROR_END:
02099 return error ;
02100 }
02101
02102
02103
02104 TLatexFormSize TLatex::FirstParse(Double_t angle, Double_t size, const Char_t *text)
02105 {
02106
02107
02108 fError = 0;
02109 fTabMax = 100;
02110 fTabSize = new FormSize_t[fTabMax];
02111
02112
02113 fPos = 0;
02114 fShow = kFALSE;
02115 fOriginSize = size;
02116
02117
02118 Short_t lineW = GetLineWidth();
02119 Int_t lineC = GetLineColor();
02120
02121 TextSpec_t spec;
02122 spec.fAngle = angle;
02123 if (fTextFont%10 == 3) {
02124 Double_t hw = TMath::Max((Double_t)gPad->XtoPixel(gPad->GetX2()),
02125 (Double_t)gPad->YtoPixel(gPad->GetY1()));
02126 spec.fSize = size/hw;
02127 } else {
02128 spec.fSize = size;
02129 }
02130 spec.fColor = GetTextColor();
02131 spec.fFont = GetTextFont();
02132 Short_t halign = fTextAlign/10;
02133 Short_t valign = fTextAlign - 10*halign;
02134
02135 TLatexFormSize fs = Anal1(spec,text,strlen(text));
02136
02137 SetTextSize(size);
02138 SetTextAngle(angle);
02139 SetTextFont(spec.fFont);
02140 SetTextColor(spec.fColor);
02141 SetTextAlign(valign+10*halign);
02142 SetLineWidth(lineW);
02143 SetLineColor(lineC);
02144 return fs;
02145 }
02146
02147
02148
02149 Double_t TLatex::GetHeight() const
02150 {
02151
02152
02153 Double_t w = gPad->GetAbsWNDC()*Double_t(gPad->GetWw());
02154 Double_t h = gPad->GetAbsHNDC()*Double_t(gPad->GetWh());
02155 if (w < h)
02156 return w;
02157 else
02158 return h;
02159 }
02160
02161
02162
02163 Double_t TLatex::GetXsize()
02164 {
02165
02166
02167 if (!gPad) return 0;
02168 TString newText = GetTitle();
02169 if( newText.Length() == 0) return 0;
02170 fError = 0 ;
02171 if (CheckLatexSyntax(newText)) {
02172 cout<<"\n*ERROR<TLatex>: "<<fError<<endl;
02173 cout<<"==> "<<GetTitle()<<endl;
02174 return 0;
02175 }
02176 fError = 0 ;
02177
02178 const Char_t *text = newText.Data() ;
02179 Double_t angle_old = GetTextAngle();
02180 TLatexFormSize fs = FirstParse(0,GetTextSize(),text);
02181 SetTextAngle(angle_old);
02182 delete[] fTabSize;
02183 return TMath::Abs(gPad->AbsPixeltoX(Int_t(fs.Width())) - gPad->AbsPixeltoX(0));
02184 }
02185
02186
02187
02188 void TLatex::GetBoundingBox(UInt_t &w, UInt_t &h, Bool_t angle)
02189 {
02190
02191
02192 if (!gPad) return;
02193 TString newText = GetTitle();
02194 if( newText.Length() == 0) return;
02195 fError = 0 ;
02196 if (CheckLatexSyntax(newText)) {
02197 cout<<"\n*ERROR<TLatex>: "<<fError<<endl;
02198 cout<<"==> "<<GetTitle()<<endl;
02199 return;
02200 }
02201 fError = 0 ;
02202
02203 if (angle) {
02204 Int_t cBoxX[4], cBoxY[4];
02205 Int_t ptx, pty;
02206 if (TestBit(kTextNDC)) {
02207 ptx = gPad->UtoPixel(fX);
02208 pty = gPad->VtoPixel(fY);
02209 } else {
02210 ptx = gPad->XtoAbsPixel(gPad->XtoPad(fX));
02211 pty = gPad->YtoAbsPixel(gPad->YtoPad(fY));
02212 }
02213 GetControlBox(ptx, pty, fTextAngle, cBoxX, cBoxY);
02214 Int_t x1 = cBoxX[0];
02215 Int_t x2 = cBoxX[0];
02216 Int_t y1 = cBoxY[0];
02217 Int_t y2 = cBoxY[0];
02218 for (Int_t i=1; i<4; i++) {
02219 if (cBoxX[i] < x1) x1 = cBoxX[i];
02220 if (cBoxX[i] > x2) x2 = cBoxX[i];
02221 if (cBoxY[i] < y1) y1 = cBoxY[i];
02222 if (cBoxY[i] > y2) y2 = cBoxY[i];
02223 }
02224 w = x2-x1;
02225 h = y2-y1;
02226 } else {
02227 const Char_t *text = newText.Data() ;
02228 TLatexFormSize fs = FirstParse(GetTextAngle(),GetTextSize(),text);
02229 delete[] fTabSize;
02230 w = (UInt_t)fs.Width();
02231 h = (UInt_t)fs.Height();
02232 }
02233 }
02234
02235
02236
02237 Double_t TLatex::GetYsize()
02238 {
02239
02240
02241 if (!gPad) return 0;
02242 TString newText = GetTitle();
02243 if( newText.Length() == 0) return 0;
02244 fError = 0 ;
02245 if (CheckLatexSyntax(newText)) {
02246 cout<<"\n*ERROR<TLatex>: "<<fError<<endl;
02247 cout<<"==> "<<GetTitle()<<endl;
02248 return 0;
02249 }
02250 fError = 0 ;
02251
02252 const Char_t *text = newText.Data() ;
02253 TLatexFormSize fs = FirstParse(0,GetTextSize(),text);
02254 delete[] fTabSize;
02255 return TMath::Abs(gPad->AbsPixeltoY(Int_t(fs.Height())) - gPad->AbsPixeltoY(0));
02256 }
02257
02258
02259
02260 TLatexFormSize TLatex::Readfs()
02261 {
02262
02263
02264 fPos--;
02265 TLatexFormSize result(fTabSize[fPos].fWidth,fTabSize[fPos].fOver,fTabSize[fPos].fUnder);
02266 return result;
02267 }
02268
02269
02270
02271 void TLatex::Savefs(TLatexFormSize *fs)
02272 {
02273
02274
02275 fTabSize[fPos].fWidth = fs->Width();
02276 fTabSize[fPos].fOver = fs->Over();
02277 fTabSize[fPos].fUnder = fs->Under();
02278 fPos++;
02279 if (fPos>=fTabMax) {
02280
02281 FormSize_t *temp = new FormSize_t[fTabMax+100];
02282
02283 memcpy(temp,fTabSize,fTabMax*sizeof(FormSize_t));
02284 fTabMax += 100;
02285
02286 delete [] fTabSize;
02287
02288 fTabSize = temp;
02289 }
02290 }
02291
02292
02293
02294 void TLatex::SavePrimitive(ostream &out, Option_t * )
02295 {
02296
02297
02298 char quote = '"';
02299 if (gROOT->ClassSaved(TLatex::Class())) {
02300 out<<" ";
02301 } else {
02302 out<<" TLatex *";
02303 }
02304 TString s = GetTitle();
02305 s.ReplaceAll("\"","\\\"");
02306 out<<" tex = new TLatex("<<fX<<","<<fY<<","<<quote<<s.Data()<<quote<<");"<<endl;
02307 if (TestBit(kTextNDC)) out<<"tex->SetNDC();"<<endl;
02308
02309 SaveTextAttributes(out,"tex",11,0,1,62,0.05);
02310 SaveLineAttributes(out,"tex",1,1,1);
02311
02312 out<<" tex->Draw();"<<endl;
02313 }
02314
02315
02316
02317 void TLatex::SetIndiceSize(Double_t factorSize)
02318 {
02319
02320
02321 fFactorSize = factorSize;
02322 }
02323
02324
02325
02326 void TLatex::SetLimitIndiceSize(Int_t limitFactorSize)
02327 {
02328
02329
02330 fLimitFactorSize = limitFactorSize;
02331 }