Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TLatex.cxx
Go to the documentation of this file.
1// @(#)root/graf:$Id$
2// Author: Nicolas Brun, Olivier Couet, Oleksandr Grebenyuk
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <iostream>
13#include "TROOT.h"
14#include "TLatex.h"
15#include "TMathText.h"
16#include "TMath.h"
17#include "TVirtualPad.h"
18#include "TVirtualPS.h"
19#include "TVirtualX.h"
20#include "snprintf.h"
21
23
24
25/** \class TLatex
26\ingroup BasicGraphics
27
28To draw Mathematical Formula.
29
30TLatex's purpose is to write mathematical equations. The syntax is very similar
31to the Latex's one. It provides several functionalities:
32
33- [Subscripts and Superscripts](\ref L1)
34- [Fractions](\ref L2)
35- [Splitting Lines](\ref L3)
36- [Roots](\ref L4)
37- [Mathematical Symbols](\ref L5)
38- [Delimiters](\ref L6)
39- [Greek Letters](\ref L7)
40- [Accents](\ref L8)
41- [Changing Style](\ref L9)
42- [Alignment Rules](\ref L10)
43- [Character Adjustment](\ref L11)
44- [Italic and Boldface](\ref L12)
45- [Examples](\ref L13)
46- [Interface to TMathText](\ref L14)
47
48When the font precision (see `TAttText`) is low (0 or 1), TLatex is
49painted as a normal TText, the control characters are not interpreted.
50
51\anchor L1
52## Subscripts and Superscripts
53Subscripts and superscripts are made with the `_` and `^`
54commands. These commands can be combined to make complicated subscript and
55superscript expressions. You may adjust the display of subscripts and
56superscripts by using the two functions `SetIndiceSize(Double_t)`,
57which set relative size of subscripts and superscripts, and
58`SetLimitIndiceSize(Int_t)`, which set limits for text resizing of
59subscripts and superscripts.
60
61Examples:
62
63Begin_Macro
64{
65 TCanvas *cl = new TCanvas("cl","cl",10,10,700,500);
66 TLatex Tl; Tl.SetTextFont(43); Tl.SetTextSize(20);
67 Double_t dy = 1./7.;
68 Tl.DrawText(.1, dy, "x^{2y} :"); Tl.DrawLatex(.5, dy, "x^{2y}");
69 Tl.DrawText(.1, 2*dy, "x_{2y} :"); Tl.DrawLatex(.5, 2*dy, "x_{2y}");
70 Tl.DrawText(.1, 3*dy, "x^{y^{2}} :"); Tl.DrawLatex(.5, 3*dy, "x^{y^{2}}");
71 Tl.DrawText(.1, 4*dy, "x^{y_{1}} :"); Tl.DrawLatex(.5, 4*dy, "x^{y_{1}}");
72 Tl.DrawText(.1, 5*dy, "x^{y}_{1} :"); Tl.DrawLatex(.5, 5*dy, "x^{y}_{1}");
73 Tl.DrawText(.1, 6*dy, "x_{1}^{y} :"); Tl.DrawLatex(.5, 6*dy, "x_{1}^{y}");
74}
75End_Macro
76
77The best way to put the subscripts and superscripts before the character and not
78after, is to use an empty character:
79
80Begin_Macro
81{
82 TCanvas *cl = new TCanvas("cl","cl",10,10,700,100);
83 TLatex Tl; Tl.SetTextFont(43); Tl.SetTextSize(20);
84 Tl.DrawText(.1, .5, "{}^{40}_{20}Ca :"); Tl.DrawLatex(.5, .5, "{}^{40}_{20}Ca");
85}
86End_Macro
87
88The subscripts and superscripts operators apply not only on one character but
89on all the "normal text" preceding them. In the following example the second
90`E` is lower than the first one because the operator `_` is
91applied on `/f` which has a descending part, and not only on `f`
92which as no descending part.
93
94Begin_Macro
95{
96 TCanvas *cl = new TCanvas("cl","cl",10,10,700,100);
97 TLatex Tl; Tl.SetTextFont(43); Tl.SetTextSize(20);
98 Tl.DrawText(.1, .5, "f_{E}/f_{E} :"); Tl.DrawLatex(.5, .5, "f_{E}/f_{E}");
99}
100End_Macro
101
102To make sure the second operator `_` applies only on `f` a dummy operator `^{}`
103should be introduced to separate the `f` from the `/`.
104
105Begin_Macro
106{
107 TCanvas *cl = new TCanvas("cl","cl",10,10,700,100);
108 TLatex Tl; Tl.SetTextFont(43); Tl.SetTextSize(20);
109 Tl.DrawText(.1, .5, "f_{E}/^{}f_{E} :"); Tl.DrawLatex(.5, .5, "f_{E}/^{}f_{E}");
110}
111End_Macro
112
113\anchor L2
114## Fractions
115Fractions denoted by the `/` symbol are made in the obvious way.
116The `#frac` command is used for large fractions in displayed formula;
117it has two arguments: the numerator and the denominator.
118
119Examples:
120
121Begin_Macro
122{
123 TCanvas *cl = new TCanvas("cl","cl",10,10,700,100);
124 TLatex Tl; Tl.SetTextFont(43); Tl.SetTextSize(20);
125 Tl.DrawText(.1, .5, "x = #frac{y+z/2}{y^{2}+1} :"); Tl.DrawLatex(.5, .5, "x = #frac{y+z/2}{y^{2}+1}");
126}
127End_Macro
128
129\anchor L3
130## Splitting Lines
131Text can be split in two lines via the command `#splitline`.
132
133Examples:
134
135Begin_Macro
136{
137 TCanvas *cl = new TCanvas("cl","cl",10,10,700,100);
138 TLatex Tl; Tl.SetTextFont(43); Tl.SetTextSize(20);
139 Tl.DrawText(.1, .5, "#splitline{21 April 2003}{14:02:30} :"); Tl.DrawLatex(.6, .5, "#splitline{21 April 2003}{14:02:30}");
140}
141End_Macro
142
143\anchor L4
144## Roots
145The `#sqrt` command produces the square root of its argument; it has
146an optional first argument for other roots.
147
148Examples:
149
150Begin_Macro
151{
152 TCanvas *cl = new TCanvas("cl","cl",10,10,700,100);
153 TLatex Tl; Tl.SetTextFont(43); Tl.SetTextSize(20);
154 Tl.DrawText(.1, .5, "#sqrt{10} #sqrt[3]{10} :"); Tl.DrawLatex(.5, .5, "#sqrt{10} #sqrt[3]{10}");
155}
156End_Macro
157
158\anchor L5
159## Mathematical Symbols
160TLatex can display dozens of special mathematical symbols. A few of them, such
161as `+` and `>` , are produced by typing the corresponding
162keyboard character. Others are obtained with the commands in the following
163table:
164
165Begin_Macro
166mathsymbols.C
167End_Macro
168
169
170\anchor L6
171## Delimiters
172TLatex provides 4 kinds of proportional delimiters:
173
174 #[]{....} or "a la" Latex #left[.....#right] : big square brackets
175 #{}{....} or #left{.....#right} : big curly brackets
176 #||{....} or #left|.....#right| : big absolute value symbols
177 #(){....} or #left(.....#right) : big parentheses
178
179\anchor L7
180## Greek Letters
181The command to produce a lowercase Greek letter is obtained by adding a
182`#` to the name of the letter. For an uppercase Greek letter, just
183capitalize the first letter of the command name. Some letters have two
184representations. The name of the second one (the "variation") starts with "var".
185The following table gives the complete list:
186
187Begin_Macro
188greekletters.C
189End_Macro
190
191
192\anchor L8
193## Accents
194Several kind of accents are available:
195
196Begin_Macro
197{
198 TCanvas *cl = new TCanvas("cl","cl",10,10,700,300);
199 TLatex Tl; Tl.SetTextFont(43); Tl.SetTextSize(20);
200 Tl.DrawText(.1, .10, "#hat : "); Tl.DrawLatex(.3, .10, " #hat{a} ");
201 Tl.DrawText(.1, .23, "#check : "); Tl.DrawLatex(.3, .23, " #check{a} ");
202 Tl.DrawText(.1, .36, "#acute : "); Tl.DrawLatex(.3, .36, " #acute{a} ");
203 Tl.DrawText(.1, .50, "#grave : "); Tl.DrawLatex(.3, .50, " #grave{a} ");
204 Tl.DrawText(.1, .63, "#dot : "); Tl.DrawLatex(.3, .63, " #dot{a} ");
205 Tl.DrawText(.1, .76, "#ddot : "); Tl.DrawLatex(.3, .76, " #ddot{a} ");
206 Tl.DrawText(.1, .90, "#tilde : "); Tl.DrawLatex(.3, .90, " #tilde{a} ");
207}
208End_Macro
209
210
211The special sign: `#slash` draws a slash on top of the text between brackets:
212
213Begin_Macro
214{
215 TCanvas *cl = new TCanvas("cl","cl",10,10,700,100);
216 TLatex Tl; Tl.SetTextFont(43); Tl.SetTextSize(20);
217 Tl.DrawText(.1, .5, "#slash{E}_{T} :"); Tl.DrawLatex(.5, .5, "#slash{E}_{T}");
218}
219End_Macro
220
221Bar and vectors sign are done the following way:
222
223Begin_Macro
224{
225 TCanvas *cl = new TCanvas("cl","cl",10,10,700,100);
226 TLatex Tl; Tl.SetTextFont(43); Tl.SetTextSize(20);
227 Tl.DrawText(.1, .5, "#bar{a} and #vec{a} :"); Tl.DrawLatex(.5, .5, "#bar{a} and #vec{a}");
228}
229End_Macro
230
231\anchor L9
232## Changing Style
233One can change the font, the text color, or the text size at any time using :
234`#font[font-number]{...}`, `#color[color-number]{...}`
235and `#scale[scale-factor]{...}`
236
237Examples:
238
239Begin_Macro
240{
241 TCanvas *cl = new TCanvas("cl","cl",10,10,900,300);
242 TLatex Tl; Tl.SetTextFont(43); Tl.SetTextSize(20);
243 Double_t dy = 1./4.;
244 Tl.DrawText(.01, dy, "#font[12]{Times Italic} and #font[22]{Times bold} :"); Tl.DrawLatex(.7, dy, "#font[12]{Times Italic} and #font[22]{Times bold}");
245 Tl.DrawText(.01, 2*dy, "#color[2]{Red} and #color[4]{Blue} :"); Tl.DrawLatex(.7, 2*dy, "#color[2]{Red} and #color[4]{Blue}");
246 Tl.DrawText(.01, 3*dy, "#scale[1.2]{Bigger} and #scale[0.8]{Smaller} :"); Tl.DrawLatex(.7, 3*dy, "#scale[1.2]{Bigger} and #scale[0.8]{Smaller}");
247}
248End_Macro
249
250\anchor L10
251## Alignment Rules
252The `TText` alignment rules apply to the `TLatex` objects with one exception
253concerning the vertical alignment:
254
255- if the vertical alignment = 1 , subscripts are not taken into account
256- if the vertical alignment = 0 , the text is aligned to the box surrounding
257 the full text with sub and superscripts
258
259This is illustrated by the following example:
260
261Begin_Macro(source)
262{
263 TCanvas Tlva("Tlva","Tlva",500,500);
264 Tlva.SetGrid();
265 Tlva.DrawFrame(0,0,1,1);
266 const char *longstring = "K_{S}... K^{*0}... #frac{2s}{#pi#alpha^{2}} #frac{d#sigma}{dcos#theta} (e^{+}e^{-} #rightarrow f#bar{f} ) = #left| #frac{1}{1 - #Delta#alpha} #right|^{2} (1+cos^{2}#theta)";
267
268 TLatex latex;
269 latex.SetTextSize(0.025);
270 latex.SetTextAlign(13); //align at top
271 latex.DrawLatex(.2,.9,"K_{S}");
272 latex.DrawLatex(.3,.9,"K^{*0}");
273 latex.DrawLatex(.2,.8,longstring);
274
275 latex.SetTextAlign(12); //centered
276 latex.DrawLatex(.2,.6,"K_{S}");
277 latex.DrawLatex(.3,.6,"K^{*0}");
278 latex.DrawLatex(.2,.5,longstring);
279
280 latex.SetTextAlign(11); //default bottom alignment
281 latex.DrawLatex(.2,.4,"K_{S}");
282 latex.DrawLatex(.3,.4,"K^{*0}");
283 latex.DrawLatex(.2,.3,longstring);
284
285 latex.SetTextAlign(10); //special bottom alignment
286 latex.DrawLatex(.2,.2,"K_{S}");
287 latex.DrawLatex(.3,.2,"K^{*0}");
288 latex.DrawLatex(.2,.1,longstring);
289
290 latex.SetTextAlign(12);
291 latex.SetTextFont(72);
292 latex.DrawLatex(.1,.80,"13");
293 latex.DrawLatex(.1,.55,"12");
294 latex.DrawLatex(.1,.35,"11");
295 latex.DrawLatex(.1,.18,"10");
296 return Tlva;
297}
298End_Macro
299
300
301\anchor L11
302## Character Adjustment
303
304The two commands `#kern` and `#lower` enable a better control
305over character placement. The command `#kern[(Float_t)dx]{text}` moves
306the output string horizontally by the fraction `dx` of its length.
307Similarly, `#lower[(Float_t)dy]{text}` shifts the text up or down by
308the fraction `dy` of its height.
309
310Examples:
311
312Begin_Macro
313{
314 TCanvas *cl = new TCanvas("cl","cl",10,10,900,300);
315 TLatex Tl; Tl.SetTextFont(43); Tl.SetTextSize(20);
316 TLatex Tt; Tt.SetTextFont(43); Tt.SetTextSize(16);
317 Double_t dy = 1./7.;
318 Tl.DrawLatex(.5, dy, "Positive k#kern[0.3]{e}#kern[0.3]{r}#kern[0.3]{n}#kern[0.3]{i}#kern[0.3]{n}#kern[0.3]{g}");
319 Tt.DrawText(.01, 2*dy, "Positive k#kern[0.3]{e}#kern[0.3]{r}#kern[0.3]{n}#kern[0.3]{i}#kern[0.3]{n}#kern[0.3]{g} :");
320 Tl.DrawLatex(.5, 3*dy, "Negative k#kern[-0.3]{e}#kern[-0.3]{r}#kern[-0.3]{n}#kern[-0.3]{i}#kern[-0.3]{n}#kern[-0.3]{g}");
321 Tt.DrawText(.01, 4*dy, "Negative k#kern[-0.3]{e}#kern[-0.3]{r}#kern[-0.3]{n}#kern[-0.3]{i}#kern[-0.3]{n}#kern[-0.3]{g} :");
322 Tl.DrawLatex(.5, 5*dy, "Vertical a#lower[0.2]{d}#lower[0.4]{j}#lower[0.1]{u}#lower[-0.1]{s}#lower[-0.3]{t}#lower[-0.4]{m}#lower[-0.2]{e}#lower[0.1]{n}t");
323 Tt.DrawText(.01, 6*dy, "Vertical a#lower[0.2]{d}#lower[0.4]{j}#lower[0.1]{u}#lower[-0.1]{s}#lower[-0.3]{t}#lower[-0.4]{m}#lower[-0.2]{e}#lower[0.1]{n}t :");
324
325}
326End_Macro
327
328\anchor L12
329## Italic and Boldface
330Text can be turned italic or boldface using the commands
331`#it` and `#bf`.
332
333Examples:
334
335Begin_Macro
336{
337 TCanvas *cl = new TCanvas("cl","cl",10,10,900,300);
338 TLatex Tl; Tl.SetTextFont(43); Tl.SetTextSize(20);
339 Double_t dy = 1./3.;
340 Tl.DrawText(.01, dy, "abc#alpha#beta#gamma, #it{abc#alpha#beta#gamma} :"); Tl.DrawLatex(.7, dy, "abc#alpha#beta#gamma, #it{abc#alpha#beta#gamma}");
341 Tl.DrawText(.01, 2*dy, "#bf{bold}, #it{italic}, #bf{#it{bold italic}}, #bf{#bf{unbold}} :"); Tl.DrawLatex(.7, 2*dy, "#bf{bold}, #it{italic}, #bf{#it{bold italic}}, #bf{#bf{unbold}}");
342}
343End_Macro
344
345\anchor L13
346## Examples
347
348Begin_Macro(source)
349{
350 TCanvas ex1("ex1","Latex",500,600);
351 TLatex Tl;
352 Tl.SetTextAlign(12);
353 Tl.SetTextSize(0.04);
354 Tl.DrawLatex(0.1,0.8,"1) C(x) = d #sqrt{#frac{2}{#lambdaD}} #int^{x}_{0}cos(#frac{#pi}{2}t^{2})dt");
355 Tl.DrawLatex(0.1,0.6,"2) C(x) = d #sqrt{#frac{2}{#lambdaD}} #int^{x}cos(#frac{#pi}{2}t^{2})dt");
356 Tl.DrawLatex(0.1,0.4,"3) R = |A|^{2} = #frac{1}{2}(#[]{#frac{1}{2}+C(V)}^{2}+#[]{#frac{1}{2}+S(V)}^{2})");
357 Tl.DrawLatex(0.1,0.2,"4) F(t) = #sum_{i=-#infty}^{#infty}A(i)cos#[]{#frac{i}{t+i}}");
358 return ex1;
359}
360End_Macro
361Begin_Macro(source)
362{
363 TCanvas ex2("ex2","Latex",500,300);
364 TLatex Tl;
365 Tl.SetTextAlign(23);
366 Tl.SetTextSize(0.08);
367 Tl.DrawLatex(0.5,0.95,"e^{+}e^{-}#rightarrowZ^{0}#rightarrowI#bar{I}, q#bar{q}");
368 Tl.DrawLatex(0.5,0.75,"|#vec{a}#bullet#vec{b}|=#Sigmaa^{i}_{jk}+b^{bj}_{i}");
369 Tl.DrawLatex(0.5,0.5,"i(#partial_{#mu}#bar{#psi}#gamma^{#mu}+m#bar{#psi}=0#Leftrightarrow(#Box+m^{2})#psi=0");
370 Tl.DrawLatex(0.5,0.3,"L_{em}=eJ^{#mu}_{em}A_{#mu} , J^{#mu}_{em}=#bar{I}#gamma_{#mu}I , M^{j}_{i}=#SigmaA_{#alpha}#tau^{#alphaj}_{i}");
371 return ex2;
372}
373End_Macro
374Begin_Macro(source)
375{
376 TCanvas ex3("ex3","Latex",500,300);
377 TPaveText pt(.1,.1,.9,.9);
378 pt.AddText("#frac{2s}{#pi#alpha^{2}} #frac{d#sigma}{dcos#theta} (e^{+}e^{-} #rightarrow f#bar{f} ) = ");
379 pt.AddText("#left| #frac{1}{1 - #Delta#alpha} #right|^{2} (1+cos^{2}#theta");
380 pt.AddText("+ 4 Re #left{ #frac{2}{1 - #Delta#alpha} #chi(s) #[]{#hat{g}_{#nu}^{e}#hat{g}_{#nu}^{f} (1 + cos^{2}#theta) + 2 #hat{g}_{a}^{e}#hat{g}_{a}^{f} cos#theta) } #right}");
381 pt.SetLabel("Born equation");
382 pt.Draw();
383 return ex3;
384}
385End_Macro
386
387
388\anchor L14
389## Interface to TMathText
390
391The class `TMathText` is a TeX math formulae interpreter. It uses plain
392TeX syntax and uses "\\" as control instead of "#". If a piece of text containing
393"\\" is given to `TLatex` then `TMathText` is automatically invoked.
394Therefore, as histograms' titles, axis titles, labels etc ... are drawn using
395`TLatex`, the `TMathText` syntax can be used for them also.
396*/
397
398////////////////////////////////////////////////////////////////////////////////
399/// Default constructor.
400
402{
403 fFactorSize = 1.5;
404 fFactorPos = 0.6;
405 fError = nullptr;
406 fShow = kFALSE;
407 fOriginSize = 0.04;
408 fItalic = kFALSE;
410 SetLineWidth(2);
411}
412
413////////////////////////////////////////////////////////////////////////////////
414/// Normal constructor.
415
416TLatex::TLatex(Double_t x, Double_t y, const char *text)
417 :TText(x,y,text)
418{
419 fFactorSize = 1.5;
420 fFactorPos = 0.6;
421 fError = nullptr;
422 fShow = kFALSE;
423 fOriginSize = 0.04;
424 fItalic = kFALSE;
426 SetLineWidth(2);
427}
428
429////////////////////////////////////////////////////////////////////////////////
430/// Destructor.
431
433{
434}
435
436////////////////////////////////////////////////////////////////////////////////
437/// Copy constructor.
438
440{
441 fFactorSize = 1.5;
442 fFactorPos = 0.6;
443 fError = nullptr;
444 fShow = kFALSE;
445 fOriginSize = 0.04;
446 fItalic = kFALSE;
448 latex.TLatex::Copy(*this);
449}
450
451////////////////////////////////////////////////////////////////////////////////
452///assignment operator
453
455{
456 if (this != &lt) {
458 TAttLine::operator=(lt);
459 fFactorSize = lt.fFactorSize;
460 fFactorPos = lt.fFactorPos;
461 fLimitFactorSize = lt.fLimitFactorSize;
462 fError = lt.fError;
463 fShow = lt.fShow;
464 fTabSize = lt.fTabSize;
465 fOriginSize = lt.fOriginSize;
466 fItalic = lt.fItalic;
467 }
468 return *this;
469}
470
471////////////////////////////////////////////////////////////////////////////////
472/// Copy this TLatex object to another TLatex.
473
474void TLatex::Copy(TObject &obj) const
475{
476 TText::Copy(obj);
477 TAttLine::Copy((TLatex &)obj);
478 ((TLatex&)obj).fFactorSize = fFactorSize;
479 ((TLatex&)obj).fFactorPos = fFactorPos;
480 ((TLatex&)obj).fLimitFactorSize = fLimitFactorSize;
481 ((TLatex&)obj).fError = fError;
482 ((TLatex&)obj).fShow = fShow;
483 ((TLatex&)obj).fTabSize = fTabSize;
484 ((TLatex&)obj).fOriginSize = fOriginSize;
485 ((TLatex&)obj).fItalic = fItalic;
486}
487
488////////////////////////////////////////////////////////////////////////////////
489/// Analyse function.
490
492{
493 return Analyse(0, 0, spec, t, length);
494}
495
496////////////////////////////////////////////////////////////////////////////////
497/// Analyse and paint the TLatex formula
498///
499/// It is called twice : first for calculating the size of
500/// each portion of the formula, then to paint the formula.
501/// When analyse finds an operator or separator, it calls
502/// itself recursively to analyse the arguments of the operator.
503/// when the argument is an atom (normal text), it calculates
504/// the size of it and return it as the result.
505/// for example : if the operator #%frac{arg1}{arg2} is found :
506/// Analyse(arg1) return the size of arg1 (width, up, down)
507/// Analyse(arg2) return the size of arg2
508/// now, we know the size of #%frac{arg1}{arg2}:
509///
510/// ~~~ {.cpp}
511/// width = max(width_arg1, width_arg2)
512/// up = up_arg1 + down_arg1
513/// down = up_arg2 + down_arg2
514/// ~~~
515///
516/// so, when the user wants to paint a fraction at position (x,y),
517/// the rect used for the formula is : (x,y-up,x+width,y+down)
518///
519/// return size of zone occupied by the text/formula
520/// - `t` : chain to be analyzed
521/// - `length` : number of chars in t.
522
524{
525 const char *tab[] = { "alpha","beta","chi","delta","varepsilon","phi","gamma","eta","iota","varphi","kappa","lambda",
526 "mu","nu","omicron","pi","theta","rho","sigma","tau","upsilon","varomega","omega","xi","psi","zeta",
527 "Alpha","Beta","Chi","Delta","Epsilon","Phi","Gamma","Eta","Iota","vartheta",
528 "Kappa","Lambda","Mu","Nu","Omicron","Pi","Theta","Rho","Sigma","Tau",
529 "Upsilon","varsigma","Omega","Xi","Psi","Zeta","varUpsilon","epsilon"};
530
531 const char *tab2[] = { "leq","/","infty","voidb","club","diamond","heart",
532 "spade","leftrightarrow","leftarrow","uparrow","rightarrow",
533 "downarrow","circ","pm","doublequote","geq","times","propto",
534 "partial","bullet","divide","neq","equiv","approx","3dots",
535 "cbar","topbar","downleftarrow","aleph","Jgothic","Rgothic","voidn",
536 "otimes","oplus","oslash","cap","cup","supset","supseteq",
537 "notsubset","subset","subseteq","in","notin","angle","nabla",
538 "oright","ocopyright","trademark","prod","surd","upoint","corner","wedge",
539 "vee","Leftrightarrow","Leftarrow","Uparrow","Rightarrow",
540 "Downarrow","diamond","LT","void1","copyright","void3","sum",
541 "arctop","lbar","arcbottom","topbar","void8", "bottombar","arcbar",
542 "ltbar","AA","aa","void06","GT","int","forall","exists" };
543
544 const char *tab3[] = { "bar","vec","dot","hat","ddot","acute","grave","check","tilde","slash"};
545
546 if (fError) return TLatexFormSize(0,0,0);
547
549 Int_t i, k;
550 Int_t min = 0, max = 0;
551 Bool_t cont = kTRUE;
552 while(cont) {
553 // count leading blanks
554 //while(nBlancDeb+nBlancFin<length && t[nBlancDeb]==' ') nBlancDeb++;
555
556 if (nBlancDeb==length) return TLatexFormSize(0,0,0); // empty string
557
558 // count trailing blanks
559 //while(nBlancDeb+nBlancFin<length && t[length-nBlancFin-1]==' ') nBlancFin++;
560
562
563 // remove characters { }
564 if (t[nBlancDeb]=='{' && t[length-nBlancFin-1]=='}') {
565 Int_t nBrackets = 0;
567 for(i=nBlancDeb;i<length-nBlancFin;i++) {
568 if (t[i] == '{' && !(i>0 && t[i-1] == '@')) nBrackets++;
569 if (t[i] == '}' && t[i-1]!= '@') nBrackets--;
570 if (nBrackets==0 && i<length-nBlancFin-2) {
572 break;
573 }
574 }
575
576 if (sameBrackets) {
577 // begin and end brackets match
578 nBlancDeb++;
579 nBlancFin++;
580 if (nBlancDeb+nBlancFin==length) return TLatexFormSize(0,0,0); // empty string
581 cont = kTRUE;
582 }
583
584 }
585
588 }
589
590 // make a copy of the current processed chain of characters
591 // removing leading and trailing blanks
592 length -= nBlancFin+nBlancDeb; // length of string without blanks
593 if (length <=0) {
594 Error("Analyse", "It seems there is a syntax error in the TLatex string");
595 return TLatexFormSize(0,0,0);
596 }
597 Char_t* text = new Char_t[length+1];
599 text[length] = 0;
600
601 // compute size of subscripts and superscripts
604 indiceSize = spec.fSize;
605 // subtract 0.001 because of rounding errors
607 specNewSize.fSize = indiceSize;
608
609 // recherche des operateurs
610 Int_t opPower = -1; // Position of first ^ (power)
611 Int_t opUnder = -1; // Position of first _ (indice)
612 Int_t opFrac = -1; // Position of first \frac
613 Int_t opSqrt = -1; // Position of first \sqrt
614 Int_t nBrackets = 0; // Nesting level in { }
615 Int_t nCroch = 0; // Nesting level in [ ]
616 Int_t opCurlyCurly = -1; // Position of first }{
617 Int_t opSquareCurly = -1; // Position of first ]{
618 Int_t opCloseCurly = -2; // Position of first }
619 Int_t opColor = -1; // Position of first #color
620 Int_t opFont = -1; // Position of first #font
621 Int_t opScale = -1; // Position of first #scale
622 Int_t opGreek = -1; // Position of a Greek letter
623 Int_t opSpec = -1; // position of a special character
624 Int_t opAbove = -1; // position of a vector/overline
625 Int_t opSquareBracket = 0 ; // position of a "[]{" operator (#[]{arg})
626 Int_t opBigCurly = 0 ; // position of a "{}{" operator (big curly bracket #{}{arg})
627 Int_t opAbs = 0 ; // position of a "||{" operator (absolute value) (#||{arg})
628 Int_t opParen = 0 ; // position of a "(){" operator (big parenthesis #(){arg})
629 Int_t abovePlace = 0 ; // true if subscripts must be written above and not after
630 Int_t opBox = 0 ; // position of #Box
631 Int_t opPerp = 0; // position of #perp
632 Int_t opOdot = 0; // position of #odot
633 Int_t opHbar = 0; // position of #hbar
634 Int_t opMinus = 0; // position of #minus
635 Int_t opPlus = 0; // position of #plus
636 Int_t opMp = 0; // position of #mp
637 Int_t opBackslash = 0; // position of #backslash
638 Int_t opParallel = 0; // position of #parallel
639 Int_t opSplitLine = -1; // Position of first #splitline
640 Int_t opKern = -1; // Position of first #kern
641 Int_t opLower = -1; // Position of first #lower
642 Int_t opBf = -1; // Position of first #bf
643 Int_t opIt = -1; // Position of first #it
644 Int_t opMbox = -1; // Position of first #mbox
645
648
649 for(i=0;i<length;i++) {
650 switch (text[i]) {
651 case '\'' : quote1 = !quote1 ; break ;
652 case '"' : quote2 = !quote2 ; break ;
653 }
654 //if (quote1 || quote2) continue ;
655 switch (text[i]) {
656 case '{':
657 if (nCroch==0) {
658 if (!(i>0 && text[i-1] == '@')) nBrackets++;
659 }
660 break;
661 case '}':
662 if (nCroch==0) {
663 if (!(i>0 && text[i-1] == '@')) nBrackets--;
664 if (nBrackets==0) {
665 if (i<length-1) if (text[i+1]=='{' && opCurlyCurly==-1) opCurlyCurly=i;
666 if (i<length-2) {
667 if (text[i+1]!='{' && !(text[i+2]=='{' && (text[i+1]=='^' || text[i+1]=='_'))
668 && opCloseCurly==-2) opCloseCurly=i;
669 }
670 else if (i<length-1) {
671 if (text[i+1]!='{' && opCloseCurly==-2) opCloseCurly=i;
672 }
673 else if (opCloseCurly==-2) opCloseCurly=i;
674 }
675 }
676 break;
677 case '[':
678 if (nBrackets==0) {
679 if (!(i>0 && text[i-1] == '@')) nCroch++;
680 }
681 break;
682 case ']':
683 if (nBrackets==0) {
684 if (!(i>0 && text[i-1] == '@')) nCroch--;
685 if (nCroch<0) {
686 // more "]" than "["
687 fError = "Missing \"[\"";
688 delete [] text;
689 return TLatexFormSize(0,0,0);
690 }
691 }
692 break;
693 }
694 if (length>i+1) {
695 Char_t buf[3];
696 strncpy(buf,&text[i],2);
697 if (strncmp(buf,"^{",2)==0) {
698 if (opPower==-1 && nBrackets==0 && nCroch==0) opPower=i;
699 if (i>3) {
700 Char_t buf1[5];
701 strncpy(buf1,&text[i-4],4);
702 if (strncmp(buf1,"#int",4)==0) {
703 abovePlace = 1;
704 if (i>4 && opCloseCurly==-2) opCloseCurly=i-5;
705 }
706 if (strncmp(buf1,"#sum",4)==0) {
707 abovePlace = 2;
708 if (i>4 && opCloseCurly==-2) opCloseCurly=i-5;
709 }
710 }
711 }
712 if (strncmp(buf,"_{",2)==0) {
713 if (opUnder==-1 && nBrackets==0 && nCroch==0) opUnder=i;
714 if (i>3) {
715 Char_t buf2[5];
716 strncpy(buf2,&text[i-4],4);
717 if (strncmp(buf2,"#int",4)==0) {
718 abovePlace = 1;
719 if (i>4 && opCloseCurly==-2) opCloseCurly=i-5;
720 }
721 if (strncmp(buf2,"#sum",4)==0) {
722 abovePlace = 2;
723 if (i>4 && opCloseCurly==-2) opCloseCurly=i-5;
724 }
725 }
726 }
727 if (strncmp(buf,"]{",2)==0)
728 if (opSquareCurly==-1 && nBrackets==0 && nCroch==0) opSquareCurly=i;
729 }
730 // detect other operators
731 if (text[i]=='\\' || (text[i]=='#' && !opFound && nBrackets==0 && nCroch==0)) {
732
733 if (length>i+10) {
734 Char_t buf[11];
735 strncpy(buf,&text[i+1],10);
736 if (strncmp(buf,"splitline{",10)==0) {
738 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
739 continue;
740 }
741 }
742 if (length>i+9) {
743 Char_t buf[10];
744 strncpy(buf,&text[i+1],9);
745 if (!opBackslash && strncmp(buf,"backslash",9)==0) {
747 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
748 continue;
749 }
750 }
751 if (length>i+8) {
752 Char_t buf[9];
753 strncpy(buf,&text[i+1],8);
754 if (!opParallel && strncmp(buf,"parallel",8)==0) {
756 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
757 continue;
758 }
759 }
760 if (length>i+6) {
761 Char_t buf[7];
762 strncpy(buf,&text[i+1],6);
763 if (strncmp(buf,"lower[",6)==0 || strncmp(buf,"lower{",6)==0) {
764 opLower=i; opFound = kTRUE;
765 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
766 continue ;
767 }
768 if (strncmp(buf,"scale[",6)==0 || strncmp(buf,"scale{",6)==0) {
769 opScale=i; opFound = kTRUE;
770 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
771 continue ;
772 }
773 if (strncmp(buf,"color[",6)==0 || strncmp(buf,"color{",6)==0) {
774 opColor=i; opFound = kTRUE;
775 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
776 continue ;
777 }
778 }
779 if (length>i+5) {
780 Char_t buf[6];
781 strncpy(buf,&text[i+1],5);
782 if (strncmp(buf,"frac{",5)==0) {
783 opFrac=i; opFound = kTRUE;
784 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
785 continue;
786 }
787 if (strncmp(buf,"sqrt{",5)==0 || strncmp(buf,"sqrt[",5)==0) {
788 opSqrt=i; opFound = kTRUE;
789 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
790 continue;
791 }
792 if (strncmp(buf,"font{",5)==0 || strncmp(buf,"font[",5)==0) {
793 opFont=i; opFound = kTRUE;
794 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
795 continue;
796 }
797 if (strncmp(buf,"kern[",5)==0 || strncmp(buf,"kern{",5)==0) {
798 opKern=i; opFound = kTRUE;
799 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
800 continue ;
801 }
802 if (!opMinus && strncmp(buf,"minus",5)==0) {
803 opMinus=1; opFound = kTRUE;
804 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
805 continue;
806 }
807 if (strncmp(buf,"mbox[",5)==0 || strncmp(buf,"mbox{",5)==0) {
808 opMbox=i; opFound = kTRUE;
809 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
810 continue ;
811 }
812 }
813 if (length>i+4) {
814 Char_t buf[5];
815 strncpy(buf,&text[i+1],4);
816 if (!opOdot && strncmp(buf,"odot",4)==0) {
817 opOdot=1; opFound = kTRUE;
818 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
819 continue;
820 }
821 if (!opHbar && strncmp(buf,"hbar",4)==0) {
822 opHbar=1; opFound = kTRUE;
823 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
824 continue;
825 }
826 if (!opPerp && strncmp(buf,"perp",4)==0) {
827 opPerp=1; opFound = kTRUE;
828 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
829 continue;
830 }
831 if (!opPlus && strncmp(buf,"plus",4)==0) {
832 opPlus=1; opFound = kTRUE;
833 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
834 continue;
835 }
836 }
837 if (length>i+3) {
838 Char_t buf[4];
839 strncpy(buf,&text[i+1],3);
840 buf[3] = 0;
841 if (strncmp(buf,"[]{",3)==0) {
843 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
844 continue;
845 }
846 if (strncmp(buf,"{}{",3)==0 ) {
848 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
849 continue;
850 }
851 if (strncmp(buf,"||{",3)==0) {
852 opAbs=1; opFound = kTRUE;
853 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
854 continue;
855 }
856 if (strncmp(buf,"(){",3)==0) {
857 opParen=1; opFound = kTRUE;
858 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
859 continue;
860 }
861 if (!opBox && strncmp(buf,"Box",3)==0) {
862 opBox=1; opFound = kTRUE;
863 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
864 continue;
865 }
866 if (strncmp(buf,"bf[",3)==0 || strncmp(buf,"bf{",3)==0) {
867 opBf=i; opFound = kTRUE;
868 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
869 continue ;
870 }
871 if (strncmp(buf,"it[",3)==0 || strncmp(buf,"it{",3)==0) {
872 opIt=i; opFound = kTRUE;
873 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
874 continue ;
875 }
876 }
877 if (length>i+2) {
878 Char_t buf[3];
879 strncpy(buf,&text[i+1],2);
880 if (!opMp && strncmp(buf,"mp",2)==0) {
881 opMp=1; opFound = kTRUE;
882 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
883 continue;
884 }
885 }
886 for(k=0;k<54;k++) {
887 if (!opFound && UInt_t(length)>i+strlen(tab[k])) {
888 if (strncmp(&text[i+1],tab[k],strlen(tab[k]))==0) {
889 opGreek=k;
890 opFound = kTRUE;
891 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
892 }
893 }
894 }
895 for(k=0;k<10;k++) {
896 if (!opFound && UInt_t(length)>i+strlen(tab3[k])) {
897 if (strncmp(&text[i+1],tab3[k],strlen(tab3[k]))==0) {
898 opAbove=k;
899 opFound = kTRUE;
900 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
901 }
902 }
903 }
904 UInt_t lastsize = 0;
905 if (!opFound)
906 for(k=0;k<82;k++) {
907 if ((opSpec==-1 || strlen(tab2[k])>lastsize) && UInt_t(length)>i+strlen(tab2[k])) {
908 if (strncmp(&text[i+1],tab2[k],strlen(tab2[k]))==0) {
909 lastsize = strlen(tab2[k]);
910 opSpec=k;
911 opFound = kTRUE;
912 if (i>0 && opCloseCurly==-2) opCloseCurly=i-1;
913 }
914 }
915 }
916 }
917 }
918
923
924 // analysis of operators found
925 if (opCloseCurly>-1 && opCloseCurly<length-1) { // separator } found
926 if(!fShow) {
929 Savefs(&fs1);
930 } else {
931 fs1 = Readfs();
934 }
935 result = fs1+fs2;
936 }
937
938 else if (opPower>-1 && opUnder>-1) { // ^ and _ found
940 max = std::max(opPower,opUnder);
941 Double_t xfpos = 0. ; //GetHeight()*spec.fSize/5.;
942 Double_t prop=1, propU=1; // scale factor for #sum & #int
943 switch (abovePlace) {
944 case 1 :
945 prop = .8 ; propU = 1.75 ; // Int
946 break;
947 case 2:
948 prop = .9 ; propU = 1.75 ; // Sum
949 break;
950 }
951 // propU acts on upper number
952 // when increasing propU value, the upper indice position is higher
953 // when increasing prop values, the lower indice position is lower
954
955 if (!fShow) {
956 Int_t ltext = min ;
957 if (min >= 2 && strncmp(&text[min-2],"{}",2)==0) {
958 // upper and lower indice before the character
959 // like with chemical element
960 snprintf(&text[ltext-2],length-(ltext-2),"I ") ;
961 ltext-- ;
962 }
964 fs2 = Anal1(specNewSize,text+min+1,max-min-1);
965 fs3 = Anal1(specNewSize,text+max+1,length-max-1);
966 Savefs(&fs1);
967 Savefs(&fs2);
968 Savefs(&fs3);
969 } else {
970 fs3 = Readfs();
971 fs2 = Readfs();
972 fs1 = Readfs();
973 Double_t pos = 0;
974 if (!abovePlace) {
975 Double_t addW = fs1.Width()+xfpos, addH1, addH2;
976 if (opPower<opUnder) {
977 addH1 = -fs1.Over()*(fFactorPos)-fs2.Under();
978 addH2 = fs1.Under()+fs3.Over()*(fFactorPos);
979 } else {
980 addH1 = fs1.Under()+fs2.Over()*(fFactorPos);
981 addH2 = -fs1.Over()*(fFactorPos)-fs3.Under();
982 }
983 Analyse(x+addW,y+addH2,specNewSize,text+max+1,length-max-1);
984 Analyse(x+addW,y+addH1,specNewSize,text+min+1,max-min-1);
985 } else {
987 Double_t m = std::max(fs1.Width(),std::max(fs2.Width(),fs3.Width()));
988 pos = (m-fs1.Width())/2;
989 if (opPower<opUnder) {
990 addH1 = -fs1.Over()*propU-fs2.Under();
991 addW1 = (m-fs2.Width())/2;
992 addH2 = fs1.Under()*prop+fs3.Over();
993 addW2 = (m-fs3.Width())/2;
994 } else {
995 addH1 = fs1.Under()*prop+fs2.Over();
996 addW1 = (m-fs2.Width())/2;
997 addH2 = -fs1.Over()*propU-fs3.Under();
998 addW2 = (m-fs3.Width())/2;
999 }
1000
1001 Analyse(x+addW2,y+addH2,specNewSize,text+max+1,length-max-1);
1002 Analyse(x+addW1,y+addH1,specNewSize,text+min+1,max-min-1);
1003 }
1004
1005 if (min >= 2 && strncmp(&text[min-2],"{}",2)==0) {
1006 snprintf(&text[min-2],length-(min-2)," ") ;
1007 Analyse(x+pos,y,spec,text,min-1);
1008 } else {
1009 Analyse(x+pos,y,spec,text,min);
1010 }
1011 }
1012
1013 if (!abovePlace) {
1014 if (opPower<opUnder) {
1015 result.Set(fs1.Width()+xfpos+std::max(fs2.Width(),fs3.Width()),
1016 fs1.Over()*fFactorPos+fs2.Height(),
1017 fs1.Under()+fs3.Height()-fs3.Over()*(1-fFactorPos));
1018 } else {
1019 result.Set(fs1.Width()+xfpos+std::max(fs2.Width(),fs3.Width()),
1020 fs1.Over()*fFactorPos+fs3.Height(),
1021 fs1.Under()+fs2.Height()-fs2.Over()*(1-fFactorPos));
1022 }
1023 } else {
1024 if (opPower<opUnder) {
1025 result.Set(std::max(fs1.Width(),std::max(fs2.Width(),fs3.Width())),
1026 fs1.Over()*propU+fs2.Height(),fs1.Under()*prop+fs3.Height());
1027 } else {
1028 result.Set(std::max(fs1.Width(),std::max(fs2.Width(),fs3.Width())),
1029 fs1.Over()*propU+fs3.Height(),fs1.Under()*prop+fs2.Height());
1030 }
1031 }
1032 }
1033 else if (opPower>-1) { // ^ found
1034 Double_t prop=1;
1035 Double_t xfpos = 0. ; //GetHeight()*spec.fSize/5. ;
1036 switch (abovePlace) {
1037 case 1 : //int
1038 prop = 1.75 ; break ;
1039 case 2 : // sum
1040 prop = 1.75; break ;
1041 }
1042 // When increasing prop, the upper indice position is higher
1043 if (!fShow) {
1044 Int_t ltext = opPower ;
1045 if (ltext >= 2 && strncmp(&text[ltext-2],"{}",2)==0) {
1046 // upper and lower indice before the character
1047 // like with chemical element
1048 snprintf(&text[ltext-2],length-(ltext-2),"I ") ;
1049 ltext-- ;
1050 }
1051 fs1 = Anal1(spec,text,ltext);
1053 Savefs(&fs1);
1054 Savefs(&fs2);
1055 } else {
1056 fs2 = Readfs();
1057 fs1 = Readfs();
1058 Int_t pos = 0;
1059 if (!abovePlace){
1060 Double_t over = fs1.Over();
1061 if (over <= 0) over = 1.5*fs2.Over();
1063 } else {
1064 Int_t pos2=0;
1065 if (fs2.Width()>fs1.Width())
1066 pos=Int_t((fs2.Width()-fs1.Width())/2);
1067 else
1068 pos2=Int_t((fs1.Width()-fs2.Width())/2);
1069
1071 }
1072 if (opPower >= 2 && strncmp(&text[opPower-2],"{}",2)==0) {
1073 snprintf(&text[opPower-2],length-(opPower-2)," ") ;
1074 Analyse(x+pos,y,spec,text,opPower-1);
1075 } else {
1076 Analyse(x+pos,y,spec,text,opPower);
1077 }
1078 }
1079
1080 if (!abovePlace)
1081 result.Set(fs1.Width()+xfpos+fs2.Width(),
1082 fs1.Over()*fFactorPos+fs2.Over(),fs1.Under());
1083 else
1084 result.Set(std::max(fs1.Width(),fs2.Width()),fs1.Over()*prop+fs2.Height(),fs1.Under());
1085
1086 }
1087 else if (opUnder>-1) { // _ found
1088 Double_t prop = .9; // scale factor for #sum & #frac
1089 Double_t xfpos = 0.;//GetHeight()*spec.fSize/5. ;
1091 // When increasing prop, the lower indice position is lower
1092 if(!fShow) {
1093 Int_t ltext = opUnder ;
1094 if (ltext >= 2 && strncmp(&text[ltext-2],"{}",2)==0) {
1095 // upper and lower indice before the character
1096 // like with chemical element
1097 snprintf(&text[ltext-2],length-(ltext-2),"I ") ;
1098 ltext-- ;
1099 }
1100 fs1 = Anal1(spec,text,ltext);
1102 Savefs(&fs1);
1103 Savefs(&fs2);
1104 } else {
1105 fs2 = Readfs();
1106 fs1 = Readfs();
1107 Int_t pos = 0;
1108 if (!abovePlace)
1109 Analyse(x+fs1.Width()+xfpos,y+fs1.Under()+fs2.Over()*fpos,specNewSize,text+opUnder+1,length-opUnder-1);
1110 else {
1111 Int_t pos2=0;
1112 if (fs2.Width()>fs1.Width())
1113 pos=Int_t((fs2.Width()-fs1.Width())/2);
1114 else
1115 pos2=Int_t((fs1.Width()-fs2.Width())/2);
1116
1118 }
1119 if (opUnder >= 2 && strncmp(&text[opUnder-2],"{}",2)==0) {
1120 snprintf(&text[opUnder-2],length-(opUnder-2)," ") ;
1121 Analyse(x+pos,y,spec,text,opUnder-1);
1122 } else {
1123 Analyse(x+pos,y,spec,text,opUnder);
1124 }
1125 }
1126 if (!abovePlace)
1127 result.Set(fs1.Width()+xfpos+fs2.Width(),fs1.Over(),
1128 fs1.Under()+fs2.Under()+fs2.Over()*fpos);
1129 else
1130 result.Set(std::max(fs1.Width(),fs2.Width()),fs1.Over(),fs1.Under()*prop+fs2.Height());
1131 }
1132 else if (opBox) {
1133 Double_t square = GetHeight()*spec.fSize/2;
1134 if (!fShow) {
1135 fs1 = Anal1(spec,text+4,length-4);
1136 } else {
1138 Double_t adjust = GetHeight()*spec.fSize/20;
1139 Double_t x1 = x+adjust ;
1141 Double_t y1 = y;
1147 }
1149 }
1150 else if (opOdot) {
1151 Double_t square = GetHeight()*spec.fSize/2;
1152 if (!fShow) {
1153 fs1 = Anal1(spec,text+5,length-5);
1154 } else {
1155 fs1 = Analyse(x+1.3*square,y,spec,text+5,length-5);
1156 Double_t adjust = GetHeight()*spec.fSize/20;
1157 Double_t r1 = 0.62*square;
1158 Double_t y1 = y-0.3*square-adjust;
1159 DrawCircle(x+0.6*square,y1,r1,spec) ;
1160 DrawCircle(x+0.6*square,y1,r1/100,spec) ;
1161 }
1163 }
1164 else if (opHbar) {
1165 Double_t square = GetHeight()*spec.fSize/2;
1166 if (!fShow) {
1167 fs1 = Anal1(spec,text+5,length-5);
1168 } else {
1170 TText hbar;
1171 hbar.SetTextFont(12);
1172 hbar.SetTextColor(spec.fColor);
1173 hbar.SetTextSize(spec.fSize);
1174 hbar.SetTextAngle(fTextAngle);
1175 hbar.SetTextAlign(11);
1176 Double_t xOrigin = (Double_t)gPad->XtoAbsPixel(fX);
1177 Double_t yOrigin = (Double_t)gPad->YtoAbsPixel(fY);
1178 Double_t angle = kPI*spec.fAngle/180.;
1181 hbar.PaintText(xx,yy,"h");
1182 DrawLine(x,y-0.8*square,x+0.75*square,y-square,spec);
1183 }
1185 }
1186 else if (opMinus) {
1187 Double_t square = GetHeight()*spec.fSize/2;
1188 if (!fShow) {
1189 fs1 = Anal1(spec,text+6,length-6);
1190 } else {
1192 TText minus;
1193 minus.SetTextFont(122);
1194 minus.SetTextColor(spec.fColor);
1195 minus.SetTextSize(spec.fSize);
1196 minus.SetTextAngle(fTextAngle);
1197 minus.SetTextAlign(11);
1198 Double_t xOrigin = (Double_t)gPad->XtoAbsPixel(fX);
1199 Double_t yOrigin = (Double_t)gPad->YtoAbsPixel(fY);
1200 Double_t angle = kPI*spec.fAngle/180.;
1203 minus.PaintText(xx,yy,"-");
1204 }
1206 }
1207 else if (opPlus) {
1208 Double_t square = GetHeight()*spec.fSize/2;
1209 if (!fShow) {
1210 fs1 = Anal1(spec,text+5,length-5);
1211 } else {
1213 TText plus;
1214 plus.SetTextFont(122);
1215 plus.SetTextColor(spec.fColor);
1216 plus.SetTextSize(spec.fSize);
1217 plus.SetTextAngle(fTextAngle);
1218 plus.SetTextAlign(11);
1219 Double_t xOrigin = (Double_t)gPad->XtoAbsPixel(fX);
1220 Double_t yOrigin = (Double_t)gPad->YtoAbsPixel(fY);
1221 Double_t angle = kPI*spec.fAngle/180.;
1224 plus.PaintText(xx,yy,"+");
1225 }
1227 }
1228 else if (opMp) {
1229 Double_t square = GetHeight()*spec.fSize/2;
1230 if (!fShow) {
1231 fs1 = Anal1(spec,text+3,length-3);
1232 } else {
1234 TText mp;
1235 mp.SetTextFont(122);
1236 mp.SetTextColor(spec.fColor);
1237 mp.SetTextSize(spec.fSize);
1238 mp.SetTextAngle(fTextAngle+180);
1239 mp.SetTextAlign(11);
1240 Double_t xOrigin = (Double_t)gPad->XtoAbsPixel(fX);
1241 Double_t yOrigin = (Double_t)gPad->YtoAbsPixel(fY);
1242 Double_t angle = kPI*spec.fAngle/180.;
1245 mp.PaintText(xx,yy,"\261");
1246 }
1248 }
1249 else if (opPerp) {
1250 Double_t square = GetHeight()*spec.fSize/1.4;
1251 if (!fShow) {
1252 fs1 = Anal1(spec,text+5,length-5);
1253 } else {
1254 fs1 = Analyse(x+0.5*square,y,spec,text+5,length-5);
1255 Double_t x0 = x + 0.50*square;
1256 Double_t x1 = x0 - 0.48*square;
1257 Double_t x2 = x0 + 0.48*square;
1258 Double_t y1 = y + 0.6*square;
1259 Double_t y2 = y1 - 1.3*square;
1261 DrawLine(x0,y1,x0,y2,spec);
1262 }
1263 result = fs1;
1264 }
1265 else if (opBackslash) {
1266 Double_t square = GetHeight()*spec.fSize/2;
1267 if (!fShow) {
1268 fs1 = Anal1(spec,text+10,length-10);
1269 } else {
1270 fs1 = Analyse(x+square,y,spec,text+10,length-10);
1271 TText bs;
1272 bs.SetTextFont(GetTextFont());
1273 bs.SetTextColor(spec.fColor);
1274 bs.SetTextSize(spec.fSize);
1275 bs.SetTextAngle(fTextAngle);
1276 bs.SetTextAlign(11);
1277 Double_t xOrigin = (Double_t)gPad->XtoAbsPixel(fX);
1278 Double_t yOrigin = (Double_t)gPad->YtoAbsPixel(fY);
1279 Double_t angle = kPI*spec.fAngle/180.;
1282 bs.PaintText(xx,yy,"\\");
1283 }
1285 }
1286 else if (opParallel) {
1287 Double_t square = GetHeight()*spec.fSize/1.4;
1288 if (!fShow) {
1289 fs1 = Anal1(spec,text+9,length-9);
1290 } else {
1291 fs1 = Analyse(x+0.5*square,y,spec,text+9,length-9);
1292 Double_t x1 = x + 0.15*square;
1293 Double_t x2 = x + 0.45*square;
1294 Double_t y1 = y + 0.3*square;
1295 Double_t y2 = y1- 1.3*square;
1298 }
1300 }
1301 else if (opGreek>-1) {
1303 newSpec.fFont = fItalic ? 152 : 122;
1304 char letter = 97 + opGreek;
1305 Double_t yoffset = 0.; // Greek letter too low
1306 if (opGreek>25) letter -= 58;
1307 if (opGreek == 52) letter = '\241'; //varUpsilon
1308 if (opGreek == 53) letter = '\316'; //epsilon
1309 if (!fShow) {
1310 fs1 = Anal1(newSpec,&letter,1);
1312 Savefs(&fs1);
1313 } else {
1314 fs1 = Readfs();
1317 }
1318 fs1.AddOver(TLatexFormSize(0,yoffset,0)) ;
1319 result = fs1+fs2;
1320 }
1321
1322 else if (opSpec>-1) {
1324 newSpec.fFont = fItalic ? 152 : 122;
1325 char letter = '\243' + opSpec;
1326 if(opSpec == 75 || opSpec == 76) {
1327 newSpec.fFont = GetTextFont();
1328 if (gVirtualX->InheritsFrom("TGCocoa")) {
1329 if (opSpec == 75) letter = '\201'; // AA Angstroem
1330 if (opSpec == 76) letter = '\214'; // aa Angstroem
1331 } else {
1332 if (opSpec == 75) letter = '\305'; // AA Angstroem
1333 if (opSpec == 76) letter = '\345'; // aa Angstroem
1334 }
1335 }
1336 if(opSpec == 80 || opSpec == 81) {
1337 if (opSpec == 80) letter = '\042'; // #forall
1338 if (opSpec == 81) letter = '\044'; // #exists
1339 }
1341 props = 1.8 ; // scale factor for #sum(66)
1342 propi = 2.3 ; // scale factor for #int(79)
1343
1344 if (opSpec==66 ) {
1345 newSpec.fSize = spec.fSize*props;
1346 } else if (opSpec==79) {
1347 newSpec.fSize = spec.fSize*propi;
1348 }
1349 if (!fShow) {
1350 fs1 = Anal1(newSpec,&letter,1);
1351 if (opSpec == 79 || opSpec == 66)
1352 fs1.Set(fs1.Width(),fs1.Over()*0.45,fs1.Over()*0.45);
1353
1355 Savefs(&fs1);
1356 } else {
1357 fs1 = Readfs();
1359 if (opSpec!=66 && opSpec!=79)
1360 Analyse(x,y,newSpec,&letter,1);
1361 else {
1362 Analyse(x,y+fs1.Under()/2.,newSpec,&letter,1);
1363 }
1364 }
1365 result = fs1+fs2;
1366 }
1367 else if (opAbove>-1) {
1368 if (!fShow) {
1370 Savefs(&fs1);
1371 } else {
1372 fs1 = Readfs();
1374 Double_t sub = GetHeight()*spec.fSize/14;
1375 switch(opAbove) {
1376 case 0: { // bar
1377 Double_t xx[2], yy[2];
1378 xx[0] = x; xx[1] = x + fs1.Width();
1379 yy[0] = yy[1] = y - sub - fs1.Over();
1380 DrawPolyLine(2, xx, yy, spec, 0.03);
1381 break;
1382 }
1383 case 1: { // vec
1384 Double_t xx[3], yy[3],
1385 dd = GetHeight()*spec.fSize/8, // arrow size
1386 midy = y - sub - fs1.Over() - dd; // middle arrow line
1387 xx[0] = x; xx[1] = x + fs1.Width();
1388 yy[0] = yy[1] = midy;
1389 DrawPolyLine(2, xx, yy, spec, 0.03);
1390 xx[1] = x + fs1.Width(); xx[0] = xx[2] = xx[1] - 2*dd;
1391 yy[0] = midy - dd; yy[1] = midy; yy[2] = midy + dd;
1392 DrawPolyLine(3, xx, yy, spec, 0.03);
1393 break;
1394 }
1395 case 2: { // dot
1396 Double_t dd = std::max(0.5*GetLineWidth(), 0.5*sub), // dot size
1397 midx = x + fs1.Width()/2,
1398 midy = y - sub - fs1.Over() - dd;
1399 Double_t xx[5] = { midx - dd, midx - dd, midx + dd, midx + dd, midx - dd },
1400 yy[5] = { midy + dd, midy - dd, midy - dd, midy + dd, midy + dd };
1401 DrawPolyLine(5, xx, yy, spec, 10.);
1402 break;
1403 }
1404 case 3: { // hat
1405 Double_t xx[3], yy[3];
1406 xx[1] = x + fs1.Width()/2;
1407 xx[0] = xx[1] - fs1.Width()/3;
1408 xx[2] = xx[1] + fs1.Width()/3;
1409 yy[0] = y - sub - fs1.Over();
1410 yy[1] = yy[0] - 2*sub;
1411 yy[2] = yy[0];
1412 DrawPolyLine(3, xx, yy, spec, 0.03);
1413 break;
1414 }
1415 case 4: { // ddot
1416 Double_t dd = std::max(0.5*GetLineWidth(), 0.5*sub), // dot size
1417 midx = x + fs1.Width()/2 - 1.5*sub,
1418 midy = y - sub - fs1.Over() - dd;
1419 Double_t xx1[5] = { midx - dd, midx - dd, midx + dd, midx + dd, midx - dd },
1420 yy1[5] = { midy + dd, midy - dd, midy - dd, midy + dd, midy + dd };
1421 DrawPolyLine(5, xx1, yy1, spec, 10.);
1422 midx = x + fs1.Width()/2 + 1.5*sub;
1423 Double_t xx2[5] = { midx - dd, midx - dd, midx + dd, midx + dd, midx - dd },
1424 yy2[5] = { midy + dd, midy - dd, midy - dd, midy + dd, midy + dd };
1425 DrawPolyLine(5, xx2, yy2, spec, 10.);
1426 break;
1427 }
1428 case 5: { // acute
1429 Double_t xx[2], yy[2];
1430 xx[0] = x + fs1.Width()/2; xx[1] = xx[0] + 3*sub;
1431 yy[0] = y - sub - fs1.Over();
1432 yy[1] = yy[0] - 2.5*sub;
1433 DrawPolyLine(2, xx, yy, spec, 0.03);
1434 break;
1435 }
1436 case 6: { // grave
1437 Double_t xx[2], yy[2];
1438 xx[0] = x + fs1.Width()/2 + sub; xx[1] = xx[0] - 2*sub;
1439 yy[0] = y - sub - fs1.Over();
1440 yy[1] = yy[0] - 2*sub;
1441 DrawPolyLine(2, xx, yy, spec, 0.03);
1442 break;
1443 }
1444 case 7: { // check
1445 Double_t xx[3], yy[3];
1446 xx[1] = x+fs1.Width()/2; xx[0] = xx[1] - 2*sub; xx[2] = xx[1] + 2*sub;
1447 yy[1] = y - sub - fs1.Over();
1448 yy[0] = yy[2] = yy[1] - 2*sub;
1449 DrawPolyLine(3, xx, yy, spec, 0.03);
1450 break;
1451 }
1452 case 8: { // tilde
1453 Double_t x2 = x+fs1.Width()/2, y2 = y -fs1.Over();
1454 // tilde must be drawn separately on screen and on PostScript
1455 // because an adjustment is required along Y for PostScript.
1457 if (gVirtualPS) gVirtualPS = nullptr;
1458 Double_t y22 = y2;
1459 if (gVirtualX->InheritsFrom("TGCocoa")) y2 -= 4.7*sub;
1460 Double_t sinang = TMath::Sin(spec.fAngle/180*kPI);
1461 Double_t cosang = TMath::Cos(spec.fAngle/180*kPI);
1462 Double_t xOrigin = (Double_t)gPad->XtoAbsPixel(fX);
1463 Double_t yOrigin = (Double_t)gPad->YtoAbsPixel(fY);
1464 Double_t xx = gPad->AbsPixeltoX(Int_t((x2-xOrigin)*cosang+(y2-yOrigin)*sinang+xOrigin));
1465 Double_t yy = gPad->AbsPixeltoY(Int_t((x2-xOrigin)*-sinang+(y2-yOrigin)*cosang+yOrigin));
1466 TText tilde;
1467 tilde.SetTextFont(fTextFont);
1468 tilde.SetTextColor(spec.fColor);
1469 tilde.SetTextSize(0.9*spec.fSize);
1470 tilde.SetTextAlign(22);
1471 tilde.SetTextAngle(fTextAngle);
1472 tilde.PaintText(xx,yy,"~");
1473 if (saveps) {
1475 if (!strstr(gVirtualPS->GetTitle(),"IMG")) y22 -= 4*sub;
1476 xx = gPad->AbsPixeltoX(Int_t((x2-xOrigin)*cosang+(y22-yOrigin)*sinang+xOrigin));
1477 yy = gPad->AbsPixeltoY(Int_t((x2-xOrigin)*-sinang+(y22-yOrigin)*cosang+yOrigin));
1479 gVirtualPS->Text(xx, yy, "~");
1480 }
1481 break;
1482 }
1483 case 9: { // slash
1484 Double_t xx[2], yy[2];
1485 xx[0] = x + 0.8*fs1.Width();
1486 yy[0] = y - fs1.Over() - sub;
1487 xx[1] = x + 0.3*fs1.Width();
1488 yy[1] = yy[0] + fs1.Height() + 2*sub;
1489 DrawPolyLine(2, xx, yy, spec, 0.03);
1490 break;
1491 }
1492 }
1493 }
1494 Double_t div = 3;
1495 if (opAbove==1) div=4;
1496 result.Set(fs1.Width(),fs1.Over()+GetHeight()*spec.fSize/div,fs1.Under());
1497 }
1498 else if (opSquareBracket) { // operator #[]{arg}
1499 Double_t l = GetHeight()*spec.fSize/4;
1500 Double_t l2 = l/2 ;
1501 if (!fShow) {
1502 fs1 = Anal1(spec,text+3,length-3);
1503 Savefs(&fs1);
1504 } else {
1505 fs1 = Readfs();
1506 Analyse(x+l2+l,y,spec,text+3,length-3);
1507 DrawLine(x+l2,y-fs1.Over(),x+l2,y+fs1.Under(),spec);
1508 DrawLine(x+l2,y-fs1.Over(),x+l2+l,y-fs1.Over(),spec);
1509 DrawLine(x+l2,y+fs1.Under(),x+l2+l,y+fs1.Under(),spec);
1510 DrawLine(x+l2+fs1.Width()+2*l,y-fs1.Over(),x+l2+fs1.Width()+2*l,y+fs1.Under(),spec);
1511 DrawLine(x+l2+fs1.Width()+2*l,y-fs1.Over(),x+l2+fs1.Width()+l,y-fs1.Over(),spec);
1512 DrawLine(x+l2+fs1.Width()+2*l,y+fs1.Under(),x+l2+fs1.Width()+l,y+fs1.Under(),spec);
1513 }
1514 result.Set(fs1.Width()+3*l,fs1.Over(),fs1.Under());
1515 }
1516 else if (opParen) { // operator #(){arg}
1517 Double_t l = GetHeight()*spec.fSize/4;
1518 Double_t radius2,radius1 , dw, l2 = l/2 ;
1519 Double_t angle = 35 ;
1520 if (!fShow) {
1521 fs1 = Anal1(spec,text+3,length-3);
1522 Savefs(&fs1);
1523 radius2 = fs1.Height() ;
1524 radius1 = radius2 * 2 / 3;
1525 dw = radius1*(1 - TMath::Cos(kPI*angle/180)) ;
1526 } else {
1527 fs1 = Readfs();
1528 radius2 = fs1.Height();
1529 radius1 = radius2 * 2 / 3;
1530 dw = radius1*(1 - TMath::Cos(kPI*angle/180)) ;
1531 Double_t x1 = x+l2+radius1 ;
1532 Double_t x2 = x+5*l2+2*dw+fs1.Width()-radius1 ;
1533 Double_t y1 = y - (fs1.Over() - fs1.Under())/2. ;
1536 Analyse(x+3*l2+dw,y,spec,text+3,length-3);
1537 }
1538 // result = TLatexFormSize(fs1.Width()+3*l,fs1.Over(),fs1.Under());
1539 result.Set(fs1.Width()+3*l+2*dw,fs1.Over(),fs1.Under());
1540 }
1541 else if (opAbs) { // operator #||{arg}
1542 Double_t l = GetHeight()*spec.fSize/4;
1543 Double_t l2 = l/2 ;
1544 if (!fShow) {
1545 fs1 = Anal1(spec,text+3,length-3);
1546 Savefs(&fs1);
1547 } else {
1548 fs1 = Readfs();
1549 Analyse(x+l2+l,y,spec,text+3,length-3);
1550 DrawLine(x+l2,y-fs1.Over(),x+l2,y+fs1.Under(),spec);
1551 DrawLine(x+l2+fs1.Width()+2*l,y-fs1.Over(),x+l2+fs1.Width()+2*l,y+fs1.Under(),spec);
1552 }
1553 result.Set(fs1.Width()+3*l,fs1.Over(),fs1.Under());
1554 }
1555 else if (opBigCurly) { // big curly bracket #{}{arg}
1556 Double_t l = GetHeight()*spec.fSize/4;
1557 Double_t l2 = l/2 ;
1558 Double_t l8 , ltip;
1559
1560 if (!fShow) {
1561 fs1 = Anal1(spec,text+3,length-3);
1562 l8 = fs1.Height()/8 ;
1563 ltip = TMath::Min(l8,l) ;
1564 l = ltip ;
1565 Savefs(&fs1);
1566 } else {
1567 fs1 = Readfs();
1568 Double_t y2 = y + (fs1.Under()-fs1.Over())/2 ;
1569 l8 = fs1.Height()/8 ;
1570 ltip = TMath::Min(l8,l) ;
1571 l = ltip ;
1572 Analyse(x+l+ltip+l2,y,spec,text+3,length-3);
1573 // Draw open curly bracket
1574 // Vertical lines
1575 DrawLine(x+l2+ltip,y-fs1.Over(),x+l2+ltip,y2-ltip,spec);
1576 DrawLine(x+l2+ltip,y2+ltip,x+l2+ltip,y+fs1.Under(),spec);
1577 // top and bottom lines
1578 DrawLine(x+l2+ltip,y-fs1.Over(),x+l2+ltip+l,y-fs1.Over(),spec);
1579 DrawLine(x+l2+ltip,y+fs1.Under(),x+l2+ltip+l,y+fs1.Under(),spec);
1580 // < sign
1583
1584 // Draw close curly bracket
1585 // vertical lines
1586 DrawLine(x+l2+ltip+fs1.Width()+2*l,y-fs1.Over(),x+l2+ltip+fs1.Width()+2*l,y2-ltip,spec);
1587 DrawLine(x+l2+ltip+fs1.Width()+2*l,y2+ltip,x+l2+ltip+fs1.Width()+2*l,y+fs1.Under(),spec);
1588 // Top and bottom lines
1589 DrawLine(x+l2+fs1.Width()+l+ltip,y-fs1.Over(),x+l2+ltip+fs1.Width()+2*l,y-fs1.Over(),spec);
1590 DrawLine(x+l2+fs1.Width()+l+ltip,y+fs1.Under(),x+l2+ltip+fs1.Width()+2*l,y+fs1.Under(),spec);
1591 // > sign
1592 DrawLine(x+l2+ltip+2*l+fs1.Width(),y2-ltip,x+l2+2*l+2*ltip+fs1.Width(),y2,spec);
1593 DrawLine(x+l2+ltip+2*l+fs1.Width(),y2+ltip,x+l2+2*l+2*ltip+fs1.Width(),y2,spec);
1594 }
1595 result.Set(fs1.Width()+3*l+2*ltip,fs1.Over(),fs1.Under());
1596 }
1597 else if (opFrac>-1) { // \frac found
1598 if (opCurlyCurly==-1) { // }{ not found
1599 // arguments missing for \frac
1600 fError = "Missing denominator for #frac";
1601 delete[] text;
1602 return TLatexFormSize(0,0,0);
1603 }
1604 Double_t height = GetHeight()*spec.fSize/8;
1605 if (!fShow) {
1608 Savefs(&fs1);
1609 Savefs(&fs2);
1610 } else {
1611 fs2 = Readfs();
1612 fs1 = Readfs();
1614 if (fs1.Width()<fs2.Width()) {
1615 addW1 = (fs2.Width()-fs1.Width())/2;
1616 addW2 = 0;
1617 } else {
1618 addW1 = 0;
1619 addW2 = (fs1.Width()-fs2.Width())/2;
1620 }
1621 Analyse(x+addW2,y+fs2.Over()-height,spec,text+opCurlyCurly+2,length-opCurlyCurly-3); // denominator
1622 Analyse(x+addW1,y-fs1.Under()-3*height,spec,text+opFrac+6,opCurlyCurly-opFrac-6); //numerator
1623
1624 DrawLine(x,y-2*height,x+std::max(fs1.Width(),fs2.Width()),y-2*height,spec);
1625 }
1626
1627 result.Set(std::max(fs1.Width(),fs2.Width()),fs1.Height()+3*height,fs2.Height()-height);
1628
1629 }
1630 else if (opSplitLine>-1) { // \splitline found
1631 if (opCurlyCurly==-1) { // }{ not found
1632 // arguments missing for \splitline
1633 fError = "Missing second line for #splitline";
1634 delete[] text;
1635 return TLatexFormSize(0,0,0);
1636 }
1637 Double_t height = GetHeight()*spec.fSize/8;
1638 if (!fShow) {
1641 Savefs(&fs1);
1642 Savefs(&fs2);
1643 } else {
1644 fs2 = Readfs();
1645 fs1 = Readfs();
1646 Analyse(x,y+fs2.Over()-height,spec,text+opCurlyCurly+2,length-opCurlyCurly-3); // second line
1647 Analyse(x,y-fs1.Under()-3*height,spec,text+opSplitLine+11,opCurlyCurly-opSplitLine-11); //first line
1648 }
1649
1650 result.Set(std::max(fs1.Width(),fs2.Width()),fs1.Height()+3*height,fs2.Height()-height);
1651
1652 }
1653 else if (opSqrt>-1) { // \sqrt found
1654 if (!fShow) {
1655 if (opSquareCurly>-1) {
1656 // power nth #sqrt[n]{arg}
1659 Savefs(&fs1);
1660 Savefs(&fs2);
1661 result.Set(fs2.Width()+ GetHeight()*spec.fSize/10+std::max(GetHeight()*spec.fSize/2,(Double_t)fs1.Width()),
1662 fs2.Over()+fs1.Height()+GetHeight()*spec.fSize/4,fs2.Under());
1663 } else {
1665 Savefs(&fs1);
1666 result.Set(fs1.Width()+GetHeight()*spec.fSize/2,fs1.Over()+GetHeight()*spec.fSize/4,fs1.Under());
1667 }
1668 } else {
1669 if (opSquareCurly>-1) { // ]{
1670 fs2 = Readfs();
1671 fs1 = Readfs();
1672 Double_t pas = std::max(GetHeight()*spec.fSize/2,(Double_t)fs1.Width());
1673 Double_t pas2 = pas + GetHeight()*spec.fSize/10;
1674 Double_t y1 = y-fs2.Over() ;
1675 Double_t y2 = y+fs2.Under() ;
1676 Double_t y3 = y1-GetHeight()*spec.fSize/4;
1678 Analyse(x,y-fs2.Over()-fs1.Under(),specNewSize,text+opSqrt+6,opSquareCurly-opSqrt-6); // indice
1679 DrawLine(x,y1,x+pas,y2,spec);
1681 DrawLine(x+pas,y3,x+pas2+fs2.Width(),y3,spec);
1682 } else {
1683 fs1 = Readfs();
1684 Double_t x1 = x+GetHeight()*spec.fSize*2/5 ;
1685 Double_t x2 = x+GetHeight()*spec.fSize/2+fs1.Width() ;
1686 Double_t y1 = y-fs1.Over() ;
1687 Double_t y2 = y+fs1.Under() ;
1688 Double_t y3 = y1-GetHeight()*spec.fSize/4;
1689
1691
1693 SetLineWidth(1);
1694 Double_t dx = (y2-y3)/8;
1695 UInt_t a,d;
1697 if (a>12) SetLineWidth(std::max(2,(Int_t)(dx/2)));
1698 DrawLine(x1-2*dx,y1,x1-dx,y2,spec);
1699 if (a>12) SetLineWidth(std::max(1,(Int_t)(dx/4)));
1703 }
1704 }
1705 }
1706 else if (opColor>-1) { // \color found
1707 if (opSquareCurly==-1) {
1708 // color number is not specified
1709 fError = "Missing color number. Syntax is #color[(Int_t)nb]{ ... }";
1710 delete[] text;
1711 return TLatexFormSize(0,0,0);
1712 }
1716 nb[opSquareCurly-opColor-7] = 0;
1717 if (sscanf(nb,"%d",&newSpec.fColor) < 1) {
1718 delete[] nb;
1719 // color number is invalid
1720 fError = "Invalid color number. Syntax is #color[(Int_t)nb]{ ... }";
1721 delete[] text;
1722 return TLatexFormSize(0,0,0);
1723 }
1724 delete[] nb;
1725 if (!fShow) {
1727 } else {
1729 }
1730 }
1731 else if (opFont>-1) { // \font found
1732 if (opSquareCurly==-1) {
1733 // font number is not specified
1734 fError = "Missing font number. Syntax is #font[nb]{ ... }";
1735 delete[] text;
1736 return TLatexFormSize(0,0,0);
1737 }
1741 nb[opSquareCurly-opFont-6] = 0;
1742 if (sscanf(nb,"%d",&newSpec.fFont) < 1) {
1743 delete[] nb;
1744 // font number is invalid
1745 fError = "Invalid font number. Syntax is #font[(Int_t)nb]{ ... }";
1746 delete[] text;
1747 return TLatexFormSize(0,0,0);
1748 }
1749 delete[] nb;
1750 if (!fShow) {
1752 } else {
1754 }
1755 }
1756 else if (opKern>-1) { // #kern found
1757 if (opSquareCurly==-1) {
1758 // horizontal shift is not specified
1759 fError = "Missing horizontal shift number. Syntax is #kern[dx]{ ... }";
1760 delete[] text;
1761 return TLatexFormSize(0,0,0);
1762 }
1765 dxc[opSquareCurly-opKern-6] = 0;
1766 Float_t dx = 0;
1767 if (sscanf(dxc,"%f",&dx) < 1) {
1768 delete[] dxc;
1769 // horizontal shift number is invalid
1770 fError = "Invalid horizontal shift number. Syntax is #kern[(Float_t)dx]{ ... }";
1771 delete[] text;
1772 return TLatexFormSize(0,0,0);
1773 }
1774 delete[] dxc;
1775 if (!fShow) {
1777 Savefs(&fs1);
1778 Double_t ddx = dx * fs1.Width();
1779 result = TLatexFormSize(fs1.Width() + ddx, fs1.Over(), fs1.Under());
1780 } else {
1781 fs1 = Readfs();
1782 Double_t ddx = dx * fs1.Width();
1784 }
1785 }
1786 else if (opLower>-1) { // #lower found
1787 if (opSquareCurly==-1) {
1788 // vertical shift is not specified
1789 fError = "Missing vertical shift number. Syntax is #lower[dy]{ ... }";
1790 delete[] text;
1791 return TLatexFormSize(0,0,0);
1792 }
1795 dyc[opSquareCurly-opLower-7] = 0;
1796 Float_t dy = 0;
1797 if (sscanf(dyc,"%f",&dy) < 1) {
1798 delete[] dyc;
1799 // vertical shift number is invalid
1800 fError = "Invalid vertical shift number. Syntax is #lower[(Float_t)dy]{ ... }";
1801 delete[] text;
1802 return TLatexFormSize(0,0,0);
1803 }
1804 delete[] dyc;
1805 if (!fShow) {
1807 Savefs(&fs1);
1808 Double_t ddy = dy * (fs1.Over() + fs1.Under());
1809 result = TLatexFormSize(fs1.Width(), fs1.Over() + ddy, fs1.Under() + ddy);
1810 } else {
1811 fs1 = Readfs();
1812 Double_t ddy = dy * (fs1.Over() + fs1.Under());
1814 }
1815 }
1816 else if (opScale>-1) { // \scale found
1817 if (opSquareCurly==-1) {
1818 // scale factor is not specified
1819 fError = "Missing scale factor. Syntax is #scale[(Double_t)nb]{ ... }";
1820 delete[] text;
1821 return TLatexFormSize(0,0,0);
1822 }
1826 nb[opSquareCurly-opScale-7] = 0;
1827 if (sscanf(nb,"%lf",&newSpec.fSize) < 1) {
1828 delete[] nb;
1829 // scale factor is invalid
1830 fError = "Invalid scale factor. Syntax is #factor[(Double_t)nb]{ ... }";
1831 delete[] text;
1832 return TLatexFormSize(0,0,0);
1833 }
1834 newSpec.fSize *= spec.fSize;
1835 delete[] nb;
1836 if (!fShow) {
1838 } else {
1840 }
1841 }
1842 else if (opBf>-1) { // operator #bf{arg}
1844 Int_t lut[] = {3, 13, 1, 6, 7, 4, 5, 10, 11, 8, 9, 12, 2, 14, 15};
1845 Int_t fontId = (newSpec.fFont/10);
1846 if ((fontId >= 1) && (fontId <= (Int_t)(sizeof(lut)/sizeof(lut[0])))) fontId = lut[fontId-1];
1847 newSpec.fFont = fontId*10 + newSpec.fFont%10;
1848 if (!fShow) {
1849 fs1 = Anal1(newSpec,text+3,length-3);
1850 Savefs(&fs1);
1851 } else {
1852 fs1 = Readfs();
1854 }
1855 result = fs1;
1856 }
1857 else if (opMbox>-1) { // dummy operator #mbox{arg}
1859 if (!fShow) {
1860 fs1 = Anal1(newSpec,text+5,length-5);
1861 Savefs(&fs1);
1862 } else {
1863 fs1 = Readfs();
1865 }
1866 result = fs1;
1867 }
1868 else if (opIt>-1) { // operator #it{arg}
1870 Int_t lut[] = {13, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 15, 1, 14, 12};
1871 Int_t fontId = (newSpec.fFont/10);
1872 if ((fontId >= 1) && (fontId <= (Int_t)(sizeof(lut)/sizeof(lut[0])))) fontId = lut[fontId-1];
1873 newSpec.fFont = fontId*10 + newSpec.fFont%10;
1874 fItalic = !fItalic;
1875 if (!fShow) {
1876 fs1 = Anal1(newSpec,text+3,length-3);
1877 Savefs(&fs1);
1878 } else {
1879 fs1 = Readfs();
1881 }
1882 fItalic = !fItalic;
1883 result = fs1;
1884 }
1885 else { // no operators found, it is a character string
1886 SetTextSize(spec.fSize);
1887 SetTextAngle(spec.fAngle);
1888 SetTextColor(spec.fColor);
1889 SetTextFont(spec.fFont);
1890 SetTextAlign(11);
1892 UInt_t w=0,h=0;
1893
1894 Int_t leng = strlen(text) ;
1895
1896 quote1 = quote2 = kFALSE ;
1897 Char_t *p ;
1898 for (i=0 ; i<leng ; i++) {
1899 switch (text[i]) {
1900 case '\'' : quote1 = !quote1 ; break ; // single quote symbol not correctly interpreted when PostScript
1901 case '"' : quote2 = !quote2 ; break ;
1902 }
1903 //if (quote1 || quote2) continue ;
1904 if (text[i] == '@') { // @ symbol not correctly interpreted when PostScript
1905 p = &text[i] ;
1906 if ( *(p+1) == '{' || *(p+1) == '}' || *(p+1) == '[' || *(p+1) == ']') {
1907 while (*p != 0) {
1908 *p = *(p+1) ; p++ ;
1909 }
1910 leng-- ;
1911 }
1912 }
1913 }
1914 text[leng] = 0 ;
1915
1916 if (fShow) {
1917 // paint the Latex sub-expression per sub-expression
1918 Double_t xOrigin = (Double_t)gPad->XtoAbsPixel(fX);
1919 Double_t yOrigin = (Double_t)gPad->YtoAbsPixel(fY);
1920 Double_t angle = kPI*spec.fAngle/180.;
1923 gPad->PaintText(xx,yy,text);
1924 } else {
1926 Double_t width = w;
1927 UInt_t a,d;
1929 fs1.Set(width,a,d);
1930 }
1931
1932 result = fs1;
1933 }
1934
1935 delete[] text;
1936
1937 return result;
1938}
1939
1940////////////////////////////////////////////////////////////////////////////////
1941/// Make a copy of this object with the new parameters
1942/// And copy object attributes
1943
1945{
1946 TLatex *newtext = new TLatex(x, y, text);
1949 newtext->SetBit(kCanDelete);
1950 if (TestBit(kTextNDC)) newtext->SetNDC();
1951 newtext->AppendPad();
1952 return newtext;
1953}
1954
1955////////////////////////////////////////////////////////////////////////////////
1956/// Draw this TLatex with new coordinates in NDC.
1957
1959{
1961 newtext->SetNDC();
1962 return newtext;
1963}
1964
1965
1966////////////////////////////////////////////////////////////////////////////////
1967/// Draw a poly line in a Latex formula
1968/// Is scale_width parameter >=1, fill area will be drawn
1969/// Otherwise line width will be scaled proportional to current font size
1970/// If not specified - default line width will be used
1972{
1973 if (!gPad) return ;
1974 Double_t sinang = TMath::Sin(spec.fAngle/180*kPI);
1975 Double_t cosang = TMath::Cos(spec.fAngle/180*kPI);
1976 Double_t xOrigin = (Double_t)gPad->XtoAbsPixel(fX);
1977 Double_t yOrigin = (Double_t)gPad->YtoAbsPixel(fY);
1978 for (Int_t n = 0; n < npoints; ++n) {
1979 Double_t mx = gPad->AbsPixeltoX(Int_t((xx[n]-xOrigin)*cosang+(yy[n]-yOrigin)*sinang+xOrigin));
1980 Double_t my = gPad->AbsPixeltoY(Int_t((xx[n]-xOrigin)*-sinang+(yy[n]-yOrigin)*cosang+yOrigin));
1981 xx[n] = mx;
1982 yy[n] = my;
1983 }
1984
1985 if (scale_width >= 1.) {
1986 TAttFill fill(spec.fColor, 1001);
1987 fill.Modify();
1988 gPad->PaintFillArea(npoints, xx, yy, "f");
1989 return;
1990 }
1991
1992 auto prevWidth = GetLineWidth();
1993 if (scale_width) {
1996 }
1997
1998 SetLineColor(spec.fColor);
2000
2001 gPad->PaintPolyLine(npoints, xx, yy);
2002 if (scale_width)
2004}
2005
2006
2007////////////////////////////////////////////////////////////////////////////////
2008/// Draw a line in a Latex formula
2009
2011{
2012 if (!gPad) return ;
2013 Double_t sinang = TMath::Sin(spec.fAngle/180*kPI);
2014 Double_t cosang = TMath::Cos(spec.fAngle/180*kPI);
2015 Double_t xOrigin = (Double_t)gPad->XtoAbsPixel(fX);
2016 Double_t yOrigin = (Double_t)gPad->YtoAbsPixel(fY);
2017 Double_t xx = gPad->AbsPixeltoX(Int_t((x1-xOrigin)*cosang+(y1-yOrigin)*sinang+xOrigin));
2018 Double_t yy = gPad->AbsPixeltoY(Int_t((x1-xOrigin)*-sinang+(y1-yOrigin)*cosang+yOrigin));
2019
2020 Double_t xx2 = gPad->AbsPixeltoX(Int_t((x2-xOrigin)*cosang+(y2-yOrigin)*sinang+xOrigin));
2021 Double_t yy2 = gPad->AbsPixeltoY(Int_t((x2-xOrigin)*-sinang+(y2-yOrigin)*cosang+yOrigin));
2022
2023 SetLineColor(spec.fColor);
2025 gPad->PaintLine(xx,yy,xx2,yy2);
2026}
2027
2028////////////////////////////////////////////////////////////////////////////////
2029/// Draw an arc of ellipse in a Latex formula (right or left parenthesis)
2030
2032{
2033 if (!gPad) return ;
2034 if (r < 1) r = 1;
2035 Double_t sinang = TMath::Sin(spec.fAngle/180*kPI);
2036 Double_t cosang = TMath::Cos(spec.fAngle/180*kPI);
2037 Double_t xOrigin = (Double_t)gPad->XtoAbsPixel(fX);
2038 Double_t yOrigin = (Double_t)gPad->YtoAbsPixel(fY);
2039
2040 const Int_t np = 40;
2041 Double_t dphi = 2*kPI/np;
2042 Double_t x[np+3], y[np+3];
2044
2045 SetLineColor(spec.fColor);
2046 TAttLine::Modify(); //Change line attributes only if necessary
2047
2048 for (Int_t i=0;i<=np;i++) {
2049 angle = Double_t(i)*dphi;
2052 x[i] = gPad->AbsPixeltoX(TMath::Nint( dx*cosang+ dy*sinang +xOrigin));
2053 y[i] = gPad->AbsPixeltoY(TMath::Nint(-dx*sinang+ dy*cosang +yOrigin));
2054 }
2055 gPad->PaintPolyLine(np+1,x,y);
2056}
2057
2058////////////////////////////////////////////////////////////////////////////////
2059/// Draw an arc of ellipse in a Latex formula (right or left parenthesis)
2060
2063{
2064 if (!gPad) return ;
2065 if (r1 < 1) r1 = 1;
2066 if (r2 < 1) r2 = 1;
2067 Double_t sinang = TMath::Sin(spec.fAngle/180*kPI);
2068 Double_t cosang = TMath::Cos(spec.fAngle/180*kPI);
2069 Double_t xOrigin = (Double_t)gPad->XtoAbsPixel(fX);
2070 Double_t yOrigin = (Double_t)gPad->YtoAbsPixel(fY);
2071
2072 const Int_t np = 40;
2073 Double_t dphi = (phimax-phimin)*kPI/(180*np);
2074 Double_t x[np+3], y[np+3];
2076
2077 SetLineColor(spec.fColor);
2078 TAttLine::Modify(); //Change line attributes only if necessary
2079
2080 for (Int_t i=0;i<=np;i++) {
2081 angle = phimin*kPI/180 + Double_t(i)*dphi;
2084 x[i] = gPad->AbsPixeltoX(Int_t( dx*cosang+dy*sinang +xOrigin));
2085 y[i] = gPad->AbsPixeltoY(Int_t(-dx*sinang+dy*cosang +yOrigin));
2086 }
2087 gPad->PaintPolyLine(np+1,x,y);
2088}
2089
2090////////////////////////////////////////////////////////////////////////////////
2091/// Paint.
2092
2093void TLatex::Paint(Option_t *)
2094{
2095 if (!gPad) return ;
2096 Double_t xsave = fX;
2097 Double_t ysave = fY;
2098 if (TestBit(kTextNDC)) {
2099 fX = gPad->GetX1() + xsave*(gPad->GetX2() - gPad->GetX1());
2100 fY = gPad->GetY1() + ysave*(gPad->GetY2() - gPad->GetY1());
2102 } else {
2103 PaintLatex(gPad->XtoPad(fX),gPad->YtoPad(fY),GetTextAngle(),GetTextSize(),GetTitle());
2104 }
2105 fX = xsave;
2106 fY = ysave;
2107}
2108
2109////////////////////////////////////////////////////////////////////////////////
2110/// Main drawing function
2111///
2112/// Warning: Unlike most others "XYZ::PaintXYZ" methods, PaintLatex modifies
2113/// the TLatex data members.
2114
2116{
2117 if (size<=0 || strlen(text1) <= 0) return; // do not paint empty text or text with size <= 0
2118
2119 TAttText::Modify(); // Change text attributes only if necessary.
2120
2122
2123 if (gVirtualPS) {
2124 if (gVirtualPS->InheritsFrom("TTeXDump")) {
2126 TString t(text1);
2127 if (t.Index("#")>=0 || t.Index("^")>=0 || t.Index("\\")>=0) {
2128 t.ReplaceAll("#LT","\\langle");
2129 t.ReplaceAll("#GT","\\rangle");
2130 t.ReplaceAll("#club","\\clubsuit");
2131 t.ReplaceAll("#spade","\\spadesuit");
2132 t.ReplaceAll("#heart","\\heartsuit");
2133 t.ReplaceAll("#diamond","\\diamondsuit");
2134 t.ReplaceAll("#voidn","\\wp");
2135 t.ReplaceAll("#voidb","f");
2136 t.ReplaceAll("#ocopyright","\\copyright");
2137 t.ReplaceAll("#trademark","TM");
2138 t.ReplaceAll("#void3","TM");
2139 t.ReplaceAll("#oright","R");
2140 t.ReplaceAll("#void1","R");
2141 t.ReplaceAll("#3dots","\\ldots");
2142 t.ReplaceAll("#lbar","\\mid");
2143 t.ReplaceAll("#bar","\\wwbar");
2144 t.ReplaceAll("#void8","\\mid");
2145 t.ReplaceAll("#divide","\\div");
2146 t.ReplaceAll("#Jgothic","\\Im");
2147 t.ReplaceAll("#Rgothic","\\Re");
2148 t.ReplaceAll("#doublequote","\"");
2149 t.ReplaceAll("#plus","+");
2150 t.ReplaceAll("#minus","-");
2151 t.ReplaceAll("#/","/");
2152 t.ReplaceAll("#upoint",".");
2153 t.ReplaceAll("#aa","\\mbox{\\aa}");
2154 t.ReplaceAll("#AA","\\mbox{\\AA}");
2155
2156 t.ReplaceAll("#omicron","o");
2157 t.ReplaceAll("#Alpha","A");
2158 t.ReplaceAll("#Beta","B");
2159 t.ReplaceAll("#Epsilon","E");
2160 t.ReplaceAll("#Zeta","Z");
2161 t.ReplaceAll("#Eta","H");
2162 t.ReplaceAll("#Iota","I");
2163 t.ReplaceAll("#Kappa","K");
2164 t.ReplaceAll("#Mu","M");
2165 t.ReplaceAll("#Nu","N");
2166 t.ReplaceAll("#Omicron","O");
2167 t.ReplaceAll("#Rho","P");
2168 t.ReplaceAll("#Tau","T");
2169 t.ReplaceAll("#Chi","X");
2170 t.ReplaceAll("#varomega","\\varpi");
2171
2172 t.ReplaceAll("#varUpsilon","?");
2173 t.ReplaceAll("#corner","?");
2174 t.ReplaceAll("#ltbar","?");
2175 t.ReplaceAll("#bottombar","?");
2176 t.ReplaceAll("#notsubset","?");
2177 t.ReplaceAll("#arcbottom","?");
2178 t.ReplaceAll("#cbar","?");
2179 t.ReplaceAll("#arctop","?");
2180 t.ReplaceAll("#topbar","?");
2181 t.ReplaceAll("#arcbar","?");
2182 t.ReplaceAll("#downleftarrow","?");
2183 t.ReplaceAll("#splitline","\\genfrac{}{}{0pt}{}");
2184
2185 t.ReplaceAll("#","\\");
2186 t.ReplaceAll("%","\\%");
2187 }
2188 gVirtualPS->Text(x,y,t.Data());
2189 } else {
2190 Bool_t saveb = gPad->IsBatch();
2191 gPad->SetBatch(kTRUE);
2192 if (!PaintLatex1( x, y, angle, size, text1)) {
2193 if (saveps) gVirtualPS = saveps;
2194 return;
2195 }
2196 gPad->SetBatch(saveb);
2197 }
2198 gVirtualPS = nullptr;
2199 }
2200
2201 if (!gPad->IsBatch()) PaintLatex1( x, y, angle, size, text1);
2202 if (saveps) gVirtualPS = saveps;
2203}
2204
2205////////////////////////////////////////////////////////////////////////////////
2206/// Drawing function
2207
2209{
2210 if (!gPad) return 0;
2212 if( newText.Length() == 0) return 0;
2213 newText.ReplaceAll("#hbox","#mbox");
2214
2215 fError = nullptr;
2217 std::cout<<"\n*ERROR<TLatex>: "<<fError<<std::endl;
2218 std::cout<<"==> "<<text1<<std::endl;
2219 return 0;
2220 }
2221 fError = nullptr;
2222
2223 // Do not use Latex if font is low precision.
2224 if (fTextFont%10 < 2) {
2225 if (gVirtualX) gVirtualX->SetTextAngle(angle);
2227 gPad->PaintText(x,y,text1);
2228 return 1;
2229 }
2230
2231 Bool_t saveb = gPad->IsBatch();
2232 // Paint the text using TMathText if contains a "\"
2233 if (strstr(text1,"\\")) {
2234 TMathText tm;
2235 tm.SetTextAlign(GetTextAlign());
2236 tm.SetTextFont(GetTextFont());
2237 tm.SetTextColor(GetTextColor());
2238 tm.PaintMathText(x, y, angle, size, text1);
2239 // If PDF, paint using TLatex
2240 if (gVirtualPS) {
2241 if (gVirtualPS->InheritsFrom("TPDF") ||
2242 gVirtualPS->InheritsFrom("TSVG")) {
2243 newText.ReplaceAll("\\","#");
2244 gPad->SetBatch(kTRUE);
2245 } else {
2246 return 1;
2247 }
2248 } else {
2249 return 1;
2250 };
2251 }
2252
2255 if (fTextFont%10 > 2) {
2257 SetTextFont(10*(saveFont/10) + 2);
2258 }
2259
2260 Int_t length = newText.Length() ;
2261 const Char_t *text = newText.Data() ;
2262
2263 Double_t xsave = fX;
2264 Double_t ysave = fY;
2265 fX = x;
2266 fY = y;
2267 x = gPad->XtoAbsPixel(x);
2268 y = gPad->YtoAbsPixel(y);
2269 fShow = kFALSE ;
2271
2272 fOriginSize = size;
2273
2274 // Get current line attributes.
2277
2279 spec.fAngle = angle;
2280 spec.fSize = size;
2281 spec.fColor = GetTextColor();
2282 spec.fFont = GetTextFont();
2286 if (fError) {
2287 std::cout<<"*ERROR<TLatex>: "<<fError<<std::endl;
2288 std::cout<<"==> "<<text<<std::endl;
2289 } else {
2290 fShow = kTRUE;
2291 newSpec.fSize = size;
2292
2293 switch (valign) {
2294 case 0: y -= fs.Under() ; break;
2295 case 1: break;
2296 case 2: y += fs.Height()*0.5-fs.Under(); y++; break;
2297 case 3: y += fs.Over() ; break;
2298 }
2299 switch (halign) {
2300 case 2: x -= fs.Width()/2 ; break;
2301 case 3: x -= fs.Width() ; break;
2302 }
2304 }
2305
2306 gPad->SetBatch(saveb);
2310 SetTextColor(spec.fColor);
2314 fTabSize.clear();
2315 fX = xsave;
2316 fY = ysave;
2317 if (fError) return 0;
2318 return 1;
2319}
2320
2321////////////////////////////////////////////////////////////////////////////////
2322/// Check if the Latex syntax is correct
2323
2325{
2326 const Char_t *kWord1[] = {"{}^{","{}_{","^{","_{","#scale{","#color{","#font{","#sqrt{","#[]{","#{}{","#||{",
2327 "#bar{","#vec{","#dot{","#hat{","#ddot{","#acute{","#grave{","#check{","#tilde{","#slash{","#bf{","#it{","#mbox{",
2328 "\\scale{","\\color{","\\font{","\\sqrt{","\\[]{","\\{}{","\\||{","#(){","\\(){",
2329 "\\bar{","\\vec{","\\dot{","\\hat{","\\ddot{","\\acute{","\\grave{","\\check{","\\bf{","\\it{","\\mbox{"}; // check for }
2330 const Char_t *kWord2[] = {"#scale[","#color[","#font[","#sqrt[","#kern[","#lower[","\\scale[","\\color[","\\font[","\\sqrt[","\\kern[","\\lower["}; // check for ]{ + }
2331 const Char_t *kWord3[] = {"#frac{","\\frac{","#splitline{","\\splitline{"}; // check for }{ then }
2332 const Char_t *kLeft1[] = {"#left[","\\left[","#left{","\\left{","#left|","\\left|","#left(","\\left("};
2333 const Char_t *kLeft2[] = {"#[]{","#[]{","#{}{","#{}{","#||{","#||{","#(){","#(){"};
2334 const Char_t *kRight[] = {"#right]","\\right]","#right}","\\right}","#right|","\\right|","#right)","\\right)"};
2335 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,6,7,7,6,6,4,4,4,4,4,5,5,5,5,6,7,7,7,4,4,6};
2336 const Int_t lkWord2[] = {7,7,6,6,6,7,7,7,6,6,6,7} ;
2337 const Int_t lkWord3[] = {6,6,11,11} ;
2338 Int_t nkWord1 = 44, nkWord2 = 12, nkWord3 = 4;
2339 Int_t i,k ;
2341 Int_t lLeft1 = 6 ;
2342 Int_t lLeft2 = 4 ;
2343 Int_t lRight = 7 ;
2344 nLeft1 = nRight = 8 ;
2345 nOfLeft = nOfRight = 0 ;
2346
2347 Char_t buf[11] ; for (i=0;i<11;i++) buf[i]=0;
2348 Bool_t opFound ;
2349 Int_t opFrac = 0;
2350 Int_t length = text.Length() ;
2351
2354 Int_t error = 0 ;
2356
2357 // first find and replace all occurrences of "kLeft1" keyword by "kLeft2" keyword,
2358 // and all occurrences of "kRight" keyword by "}".
2359 i = 0 ;
2360 while (i < length) {
2361 // The string in 'buf' does not need to be null terminated,
2362 // we will only check with strncmp.
2363 strncpy(buf,&text[i],TMath::Min(7,length-i));
2364 opFound = kFALSE ;
2365 for (k = 0 ; k < nLeft1 ; k++) {
2366 if (strncmp(buf,kLeft1[k],lLeft1)==0) {
2367 nOfLeft++ ;
2368 i+=lLeft1 ;
2369 opFound = kTRUE ;
2370 break ;
2371 }
2372 }
2373 if (opFound) continue ;
2374
2375 for(k=0;k<nRight;k++) {
2376 if (strncmp(buf,kRight[k],lRight)==0) {
2377 nOfRight++ ;
2378 i+=lRight ;
2379 opFound = kTRUE ;
2380 break ;
2381 }
2382 }
2383 if (!opFound) i++ ;
2384 }
2385 if (nOfLeft != nOfRight) {
2386 printf(" nOfLeft = %d, nOfRight = %d\n",nOfLeft,nOfRight) ;
2387 error = 1 ;
2388 fError = "Operators \"#left\" and \"#right\" don't match !" ;
2389 goto ERROR_END ;
2390 }
2391
2392 for (k = 0 ; k < nLeft1 ; k++) {
2393 text.ReplaceAll(kLeft1[k],lLeft1,kLeft2[k],lLeft2) ;
2394 }
2395 for (k = 0 ; k < nRight ; k++) {
2396 text.ReplaceAll(kRight[k],lRight,"}",1) ;
2397 }
2398 length = text.Length() ;
2399
2401 while (i< length){
2402 switch (text[i]) {
2403 case '"' : quote1 = !quote1 ; break ;
2404 case '\'': quote2 = !quote2 ; break ;
2405 }
2406 // The string in 'buf' does not need to be null terminated,
2407 // we will only check with strncmp
2408 strncpy(buf,&text[i],TMath::Min(11,length-i));
2409 opFound = kFALSE ;
2410
2411 for(k=0;k<nkWord1;k++) {
2412 if (strncmp(buf,kWord1[k],lkWord1[k])==0) {
2413 nOfKW1++ ;
2414 i+=lkWord1[k] ;
2415 opFound = kTRUE ;
2416 nOfCurlyBracket++ ;
2417 break ;
2418 }
2419 }
2420 if (opFound) continue ;
2421
2422 for(k=0;k<nkWord2;k++) {
2423 if (strncmp(buf,kWord2[k],lkWord2[k])==0) {
2424 nOfKW2++ ;
2425 i+=lkWord2[k] ;
2426 opFound = kTRUE ;
2428 break ;
2429 }
2430 }
2431 if (opFound) continue ;
2432
2433 for(k=0;k<nkWord3;k++) {
2434 if (strncmp(buf,kWord3[k],lkWord3[k])==0) {
2435 nOfKW3++ ;
2436 i+=lkWord3[k] ;
2437 opFound = kTRUE ;
2438 opFrac++ ;
2439 nOfCurlyBracket++ ;
2440 break ;
2441 }
2442 }
2443 if (opFound) continue ;
2444 if (strncmp(buf,"}{",2) == 0 && opFrac) {
2445 opFrac-- ;
2446 nOfCurlyCurly++ ;
2447 i+= 2;
2448 }
2449 else if (strncmp(buf,"]{",2) == 0 && nOfSquareBracket) {
2450 nOfSquareCurly++ ;
2451 i+= 2 ;
2452 nOfCurlyBracket++ ;
2454 }
2455 else if (strncmp(buf,"@{",2) == 0 || strncmp(buf,"@}",2) == 0) {
2456 i+= 2 ;
2457 }
2458 else if (strncmp(buf,"@[",2) == 0 || strncmp(buf,"@]",2) == 0) {
2459 i+= 2 ;
2460 }
2461 else if (text[i] == ']' ) { // not belonging to a key word, add @ in front
2462 text.Insert(i,"@") ;
2463 length++ ;
2464 i+=2 ;
2465 }
2466 else if (text[i] == '[' ) { // not belonging to a key word, add @ in front
2467 text.Insert(i,"@") ;
2468 length++ ;
2469 i+=2 ;
2470 }
2471 else if (text[i] == '{' ) { // not belonging to a key word, add @ in front
2472 text.Insert(i,"@") ;
2473 length++ ;
2474 i+=2 ;
2475 }
2476 else if (text[i] == '}' ) {
2477 if ( nOfCurlyBracket) {
2478 nOfCurlyBracket-- ;
2479 i++ ;
2480 } else { // extra }, add @ in front
2481 text.Insert(i,"@") ;
2482 length++ ;
2483 i+=2 ;
2484 }
2485 } else {
2486 i++ ;
2487 buf[1] = 0 ;
2488 }
2489 }
2490
2491 if (nOfKW2 != nOfSquareCurly) {
2492 error = 1 ;
2493 fError = "Invalid number of \"]{\"" ;
2494 }
2495 else if (nOfKW3 != nOfCurlyCurly) {
2496 error = 1 ;
2497 fError = "Error in syntax of \"#frac\"" ;
2498 }
2499 else if (nOfCurlyBracket < 0) {
2500 error = 1 ;
2501 fError = "Missing \"{\"" ;
2502 }
2503 else if (nOfCurlyBracket > 0) {
2504 error = 1 ;
2505 fError = "Missing \"}\"" ;
2506 }
2507 else if (nOfSquareBracket < 0) {
2508 error = 1 ;
2509 fError = "Missing \"[\"" ;
2510 }
2511 else if (nOfSquareBracket > 0) {
2512 error = 1 ;
2513 fError = "Missing \"]\"" ;
2514 }
2515
2516 ERROR_END:
2517 return error ;
2518}
2519
2520////////////////////////////////////////////////////////////////////////////////
2521/// First parsing of the analyse sequence
2522
2524{
2525 fTabSize.reserve(100); // ensure 100 entries before memory reallocation required
2526 fShow = kFALSE;
2527 fOriginSize = size;
2528
2529 //get current line attributes
2532
2534 spec.fAngle = angle;
2535 spec.fSize = GetTextSizePercent(size);
2536 spec.fColor = GetTextColor();
2537 spec.fFont = GetTextFont();
2540
2542
2545 SetTextFont(spec.fFont);
2546 SetTextColor(spec.fColor);
2550 return fs;
2551}
2552
2553////////////////////////////////////////////////////////////////////////////////
2554/// Return height of current pad in pixels
2555
2557{
2558 if (!gPad) return 0.;
2559 Double_t w = gPad->GetAbsWNDC()*Double_t(gPad->GetWw());
2560 Double_t h = gPad->GetAbsHNDC()*Double_t(gPad->GetWh());
2561 if (w < h)
2562 return w;
2563 else
2564 return h;
2565}
2566
2567////////////////////////////////////////////////////////////////////////////////
2568/// Return size of the formula along X in pad coordinates when the text precision
2569/// is smaller than 3.
2570
2572{
2573 if (!gPad) return 0.;
2575 if( newText.Length() == 0) return 0;
2576
2577 // The text is a TMathText.
2578 if ( newText.Contains("\\") ) {
2579 TMathText tm(0., 0., newText.Data());
2580 return tm.GetXsize();
2581 }
2582
2583 fError = nullptr;
2585 std::cout<<"\n*ERROR<TLatex>: "<<fError<<std::endl;
2586 std::cout<<"==> "<<GetTitle()<<std::endl;
2587 return 0;
2588 }
2589 fError = nullptr;
2590
2591 const Char_t *text = newText.Data() ;
2595 fTabSize.clear();
2596 return std::abs(gPad->AbsPixeltoX(Int_t(fs.Width())) - gPad->AbsPixeltoX(0));
2597}
2598
2599////////////////////////////////////////////////////////////////////////////////
2600/// Return text size in pixels
2601
2603{
2604 if (!gPad) return;
2606 if( newText.Length() == 0) return;
2607
2608 // The text is a TMathText.
2609 if ( newText.Contains("\\") ) {
2610 TMathText tm(0., 0., newText.Data());
2611 tm.GetBoundingBox(w, h);
2612 return;
2613 }
2614
2615 fError = nullptr;
2617 std::cout<<"\n*ERROR<TLatex>: "<<fError<<std::endl;
2618 std::cout<<"==> "<<GetTitle()<<std::endl;
2619 return;
2620 }
2621 fError = nullptr;
2622
2623 if (angle) {
2624 Int_t cBoxX[4], cBoxY[4];
2625 Int_t ptx, pty;
2626 if (TestBit(kTextNDC)) {
2627 ptx = gPad->UtoPixel(fX);
2628 pty = gPad->VtoPixel(fY);
2629 } else {
2630 ptx = gPad->XtoAbsPixel(gPad->XtoPad(fX));
2631 pty = gPad->YtoAbsPixel(gPad->YtoPad(fY));
2632 }
2634 Int_t x1 = cBoxX[0];
2635 Int_t x2 = cBoxX[0];
2636 Int_t y1 = cBoxY[0];
2637 Int_t y2 = cBoxY[0];
2638 for (Int_t i=1; i<4; i++) {
2639 if (cBoxX[i] < x1) x1 = cBoxX[i];
2640 if (cBoxX[i] > x2) x2 = cBoxX[i];
2641 if (cBoxY[i] < y1) y1 = cBoxY[i];
2642 if (cBoxY[i] > y2) y2 = cBoxY[i];
2643 }
2644 w = x2-x1;
2645 h = y2-y1;
2646 } else {
2647 const Char_t *text = newText.Data() ;
2649 fTabSize.clear();
2650 w = (UInt_t)fs.Width();
2651 h = (UInt_t)fs.Height();
2652 }
2653}
2654
2655////////////////////////////////////////////////////////////////////////////////
2656/// Return size of the formula along Y in pad coordinates when the text precision
2657/// is smaller than 3.
2658
2660{
2661 if (!gPad) return 0.;
2663 if( newText.Length() == 0) return 0;
2664
2665 // The text is a TMathText.
2666 if ( newText.Contains("\\") ) {
2667 TMathText tm(0., 0., newText.Data());
2668 return tm.GetYsize();
2669 }
2670
2671 fError = nullptr;
2673 std::cout<<"\n*ERROR<TLatex>: "<<fError<<std::endl;
2674 std::cout<<"==> "<<GetTitle()<<std::endl;
2675 return 0;
2676 }
2677 fError = nullptr;
2678
2679 const Char_t *text = newText.Data();
2683 fTabSize.clear();
2684 return std::abs(gPad->AbsPixeltoY(Int_t(fs.Height())) - gPad->AbsPixeltoY(0));
2685}
2686
2687////////////////////////////////////////////////////////////////////////////////
2688/// Read fs in fTabSize
2689
2691{
2692 if (fTabSize.empty()) {
2693 Error("Readfs", "No data in fTabSize stack");
2694 return TLatexFormSize(0,0,0);
2695 }
2696
2698 fTabSize.pop_back();
2699 return result;
2700}
2701
2702////////////////////////////////////////////////////////////////////////////////
2703/// Save fs values in array fTabSize
2704
2706{
2707 fTabSize.emplace_back(*fs);
2708}
2709
2710////////////////////////////////////////////////////////////////////////////////
2711/// Save primitive as a C++ statement(s) on output stream out
2712
2713void TLatex::SavePrimitive(std::ostream &out, Option_t *option)
2714{
2716 out, Class(), "tex",
2717 TString::Format("%g, %g, \"%s\"", fX, fY, TString(GetTitle()).ReplaceSpecialCppChars().Data()), kFALSE);
2718
2719 SaveTextAttributes(out, "tex", 11, 0, 1, 62, 0.05);
2720 SaveLineAttributes(out, "tex", 1, 1, 1);
2721
2722 if (TestBit(kTextNDC))
2723 out << " tex->SetNDC();\n";
2724
2725 SavePrimitiveDraw(out, "tex", option);
2726}
2727
2728////////////////////////////////////////////////////////////////////////////////
2729/// Set relative size of subscripts and superscripts
2730
2732{
2734}
2735
2736////////////////////////////////////////////////////////////////////////////////
2737/// Set limit for text resizing of subscripts and superscripts
2738
2740{
2742}
#define d(i)
Definition RSha256.hxx:102
#define a(i)
Definition RSha256.hxx:99
#define h(i)
Definition RSha256.hxx:106
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
char Char_t
Character 1 byte (char)
Definition RtypesCore.h:51
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:60
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
short Short_t
Signed Short integer 2 bytes (short)
Definition RtypesCore.h:53
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
constexpr Double_t kPI
Definition TEllipse.cxx:24
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t SetLineWidth
Option_t Option_t SetTextSize
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h prop
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t SetLineColor
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t SetTextFont
Option_t Option_t TPoint TPoint angle
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t TPoint TPoint const char DrawLine
Option_t Option_t width
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize fs
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t height
Option_t Option_t TPoint TPoint const char text
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char mx
Option_t Option_t TPoint TPoint const char y1
const Double_t kPI
Definition TLatex.cxx:22
R__EXTERN TVirtualPS * gVirtualPS
Definition TVirtualPS.h:81
#define gPad
#define gVirtualX
Definition TVirtualX.h:337
const char * tab3
const char * tab2
#define snprintf
Definition civetweb.c:1579
Fill Area Attributes class.
Definition TAttFill.h:20
Line Attributes class.
Definition TAttLine.h:20
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:35
virtual Width_t GetLineWidth() const
Return the line width.
Definition TAttLine.h:37
virtual void Modify()
Change current line attributes if necessary.
Definition TAttLine.cxx:246
void Copy(TAttLine &attline) const
Copy this line attributes to a new TAttLine.
Definition TAttLine.cxx:176
virtual void SaveLineAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t widdef=1)
Save line attributes as C++ statement(s) on output stream out.
Definition TAttLine.cxx:274
virtual Float_t GetTextSize() const
Return the text size.
Definition TAttText.h:38
virtual void Modify()
Change current text attributes if necessary.
Definition TAttText.cxx:328
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
Definition TAttText.h:44
virtual Short_t GetTextAlign() const
Return the text alignment.
Definition TAttText.h:34
virtual Font_t GetTextFont() const
Return the text font.
Definition TAttText.h:37
Float_t fTextAngle
Text angle.
Definition TAttText.h:23
virtual Color_t GetTextColor() const
Return the text color.
Definition TAttText.h:36
virtual void SetTextAngle(Float_t tangle=0)
Set the text angle.
Definition TAttText.h:45
virtual Float_t GetTextAngle() const
Return the text angle.
Definition TAttText.h:35
virtual void SetTextColor(Color_t tcolor=1)
Set the text color.
Definition TAttText.h:46
Font_t fTextFont
Text font.
Definition TAttText.h:27
virtual void SaveTextAttributes(std::ostream &out, const char *name, Int_t alidef=12, Float_t angdef=0, Int_t coldef=1, Int_t fondef=61, Float_t sizdef=1)
Save text attributes as C++ statement(s) on output stream out.
Definition TAttText.cxx:372
virtual Float_t GetTextSizePercent(Float_t size)
Return the text in percent of the pad size.
Definition TAttText.cxx:309
Short_t fTextAlign
Text alignment.
Definition TAttText.h:25
void Copy(TAttText &atttext) const
Copy this text attributes to a new TAttText.
Definition TAttText.cxx:293
TLatex helper class used to compute the size of a portion of a formula.
Definition TLatex.h:33
To draw Mathematical Formula.
Definition TLatex.h:18
virtual void SetLimitIndiceSize(Int_t limitFactorSize)
Set limit for text resizing of subscripts and superscripts.
Definition TLatex.cxx:2737
Double_t GetXsize()
Return size of the formula along X in pad coordinates when the text precision is smaller than 3.
Definition TLatex.cxx:2569
Double_t GetHeight() const
Return height of current pad in pixels.
Definition TLatex.cxx:2554
void Copy(TObject &text) const override
Copy this TLatex object to another TLatex.
Definition TLatex.cxx:472
Double_t fFactorPos
! Relative position of subscripts and superscripts
Definition TLatex.h:63
Int_t fLimitFactorSize
lower bound for subscripts/superscripts size
Definition TLatex.h:64
void DrawLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2, const TextSpec_t &spec)
Draw a line in a Latex formula.
Definition TLatex.cxx:2008
TLatexFormSize Anal1(const TextSpec_t &spec, const Char_t *t, Int_t length)
Analyse function.
Definition TLatex.cxx:489
void DrawParenthesis(Double_t x1, Double_t y1, Double_t r1, Double_t r2, Double_t phimin, Double_t phimax, const TextSpec_t &spec)
Draw an arc of ellipse in a Latex formula (right or left parenthesis)
Definition TLatex.cxx:2059
static TClass * Class()
virtual void SetIndiceSize(Double_t factorSize)
Set relative size of subscripts and superscripts.
Definition TLatex.cxx:2729
std::vector< TLatexFormSize > fTabSize
! array of values for the different zones
Definition TLatex.h:67
Int_t PaintLatex1(Double_t x, Double_t y, Double_t angle, Double_t size, const char *text)
Drawing function.
Definition TLatex.cxx:2206
Double_t fOriginSize
Font size of the starting font.
Definition TLatex.h:68
Double_t GetYsize()
Return size of the formula along Y in pad coordinates when the text precision is smaller than 3.
Definition TLatex.cxx:2657
TLatexFormSize FirstParse(Double_t angle, Double_t size, const Char_t *text)
First parsing of the analyse sequence.
Definition TLatex.cxx:2521
TLatexFormSize Readfs()
Read fs in fTabSize.
Definition TLatex.cxx:2688
void GetBoundingBox(UInt_t &w, UInt_t &h, Bool_t angle=kFALSE) override
Return text size in pixels.
Definition TLatex.cxx:2600
@ kTextNDC
The text position is in NDC coordinates.
Definition TLatex.h:94
TLatex * DrawLatexNDC(Double_t x, Double_t y, const char *text)
Draw this TLatex with new coordinates in NDC.
Definition TLatex.cxx:1956
void DrawCircle(Double_t x1, Double_t y1, Double_t r, const TextSpec_t &spec)
Draw an arc of ellipse in a Latex formula (right or left parenthesis)
Definition TLatex.cxx:2029
virtual void PaintLatex(Double_t x, Double_t y, Double_t angle, Double_t size, const char *text)
Main drawing function.
Definition TLatex.cxx:2113
TLatex()
Default constructor.
Definition TLatex.cxx:399
Bool_t fShow
! is true during the second pass (Painting)
Definition TLatex.h:66
~TLatex() override
Destructor.
Definition TLatex.cxx:430
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
Definition TLatex.cxx:2711
TLatex & operator=(const TLatex &)
assignment operator
Definition TLatex.cxx:452
void DrawPolyLine(Int_t npoints, Double_t *xx, Double_t *yy, const TextSpec_t &spec, Double_t scale_width=0.)
Draw a poly line in a Latex formula Is scale_width parameter >=1, fill area will be drawn Otherwise l...
Definition TLatex.cxx:1969
TLatex * DrawLatex(Double_t x, Double_t y, const char *text)
Make a copy of this object with the new parameters And copy object attributes.
Definition TLatex.cxx:1942
Double_t fFactorSize
! Relative size of subscripts and superscripts
Definition TLatex.h:62
const Char_t * fError
! error code
Definition TLatex.h:65
Bool_t fItalic
! Currently inside italic operator
Definition TLatex.h:69
void Paint(Option_t *option="") override
Paint.
Definition TLatex.cxx:2091
TLatexFormSize Analyse(Double_t x, Double_t y, const TextSpec_t &spec, const Char_t *t, Int_t length)
Analyse and paint the TLatex formula.
Definition TLatex.cxx:521
Int_t CheckLatexSyntax(TString &text)
Check if the Latex syntax is correct.
Definition TLatex.cxx:2322
void Savefs(TLatexFormSize *fs)
Save fs values in array fTabSize.
Definition TLatex.cxx:2703
To draw TeX Mathematical Formula.
Definition TMathText.h:19
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
Mother of all ROOT objects.
Definition TObject.h:41
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:202
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:543
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
static void SavePrimitiveDraw(std::ostream &out, const char *variable_name, Option_t *option=nullptr)
Save invocation of primitive Draw() method Skipped if option contains "nodraw" string.
Definition TObject.cxx:822
static void SavePrimitiveConstructor(std::ostream &out, TClass *cl, const char *variable_name, const char *constructor_agrs="", Bool_t empty_line=kTRUE)
Save object constructor in the output stream "out".
Definition TObject.cxx:771
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:68
Basic string class.
Definition TString.h:138
const char * Data() const
Definition TString.h:384
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:712
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2384
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:659
Base class for several text objects.
Definition TText.h:22
Double_t fY
Y position of text (left,center,etc..)
Definition TText.h:26
void Copy(TObject &text) const override
Copy this text to text.
Definition TText.cxx:106
TText & operator=(const TText &src)
Assignment operator.
Definition TText.cxx:97
Double_t fX
X position of text (left,center,etc..)
Definition TText.h:25
virtual void GetTextExtent(UInt_t &w, UInt_t &h, const char *text) const
Return text extent for string text.
Definition TText.cxx:590
virtual void GetTextAscentDescent(UInt_t &a, UInt_t &d, const char *text) const
Return text ascent and descent for string text.
Definition TText.cxx:524
virtual void GetControlBox(Int_t x, Int_t y, Double_t theta, Int_t cBoxX[4], Int_t cBoxY[4])
Return the text control box.
Definition TText.cxx:423
TVirtualPS is an abstract interface to Postscript, PDF, SVG.
Definition TVirtualPS.h:30
virtual void Text(Double_t x, Double_t y, const char *string)=0
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition TMath.h:704
Double_t Exp(Double_t x)
Returns the base-e exponential function of x, which is e raised to the power x.
Definition TMath.h:720
Double_t Log(Double_t x)
Returns the natural logarithm of x.
Definition TMath.h:767
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:199
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Definition TMath.h:605
constexpr Double_t Pi()
Definition TMath.h:40
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Definition TMath.h:599
TLatex helper struct holding the attributes of a piece of text.
Definition TLatex.h:24
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4