Logo ROOT   6.12/07
Reference Guide
TText.cxx
Go to the documentation of this file.
1 // @(#)root/graf:$Id$
2 // Author: Nicolas Brun 12/12/94
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 "TText.h"
13 
14 #include "Riostream.h"
15 #include "TROOT.h"
16 #include "TVirtualPad.h"
17 # include <ft2build.h>
18 # include FT_FREETYPE_H
19 # include FT_GLYPH_H
20 #include "TTF.h"
21 #include "TVirtualX.h"
22 #include "TMath.h"
23 #include "TPoint.h"
24 #include "TClass.h"
25 #include <wchar.h>
26 #include <cstdlib>
27 
29 
30 
31 /** \class TText
32 \ingroup BasicGraphics
33 
34 Base class for several text objects.
35 
36 See TAttText for a list of text attributes or fonts,
37 and also for a discussion on text speed and font quality.
38 
39 By default, the text is drawn in the pad coordinates system.
40 One can draw in NDC coordinates [0,1] if the function SetNDC
41 is called for a TText object.
42 
43 Example:
44 Begin_Macro(source)
45 {
46  TText *t = new TText(.5,.5,"Hello World !");
47  t->SetTextAlign(22);
48  t->SetTextColor(kRed+2);
49  t->SetTextFont(43);
50  t->SetTextSize(40);
51  t->SetTextAngle(45);
52  t->Draw();
53 }
54 End_Macro
55 */
56 
57 ////////////////////////////////////////////////////////////////////////////////
58 /// Text default constructor.
59 
60 TText::TText(): TNamed(), TAttText(), fWcsTitle(NULL)
61 {
62  fX = 0.;
63  fY = 0.;
64 }
65 
66 ////////////////////////////////////////////////////////////////////////////////
67 /// Text normal constructor.
68 
69 TText::TText(Double_t x, Double_t y, const char *text) : TNamed("",text), TAttText(), fWcsTitle(NULL)
70 {
71  fX = x;
72  fY = y;
73 }
74 
75 ////////////////////////////////////////////////////////////////////////////////
76 /// Text normal constructor.
77 
78 TText::TText(Double_t x, Double_t y, const wchar_t *text) : TAttText()
79 {
80  fX = x;
81  fY = y;
82  fWcsTitle = new std::wstring(text);
83  SetName("");
84  SetMbTitle(text);
85 }
86 
87 ////////////////////////////////////////////////////////////////////////////////
88 /// Text default destructor.
89 
91 {
92  if (fWcsTitle != NULL) delete reinterpret_cast<std::wstring *>(fWcsTitle);
93 }
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 /// Copy constructor.
97 
98 TText::TText(const TText &text) : TNamed(text), TAttText(text), TAttBBox2D(text), fWcsTitle(NULL)
99 {
100  fX = 0.;
101  fY = 0.;
102  ((TText&)text).Copy(*this);
103 }
104 
105 ////////////////////////////////////////////////////////////////////////////////
106 /// Copy this text to text.
107 
108 void TText::Copy(TObject &obj) const
109 {
110  ((TText&)obj).fX = fX;
111  ((TText&)obj).fY = fY;
112  TNamed::Copy(obj);
113  TAttText::Copy(((TText&)obj));
114  if (((TText&)obj).fWcsTitle != NULL) {
115  if (fWcsTitle != NULL) {
116  *reinterpret_cast<std::wstring*>(&((TText&)obj).fWcsTitle) = *reinterpret_cast<const std::wstring*>(&fWcsTitle);
117  } else {
118  delete reinterpret_cast<std::wstring*>(&((TText&)obj).fWcsTitle);
119  ((TText&)obj).fWcsTitle = NULL;
120  }
121  } else {
122  if (fWcsTitle != NULL) {
123  ((TText&)(obj)).fWcsTitle = new std::wstring(*reinterpret_cast<const std::wstring*>(fWcsTitle));
124  }
125  }
126 }
127 
128 ////////////////////////////////////////////////////////////////////////////////
129 /// Returns the text as UNICODE.
130 
131 const void *TText::GetWcsTitle(void) const
132 {
133  if (fWcsTitle != NULL) {
134  return reinterpret_cast<std::wstring *>(fWcsTitle)->c_str();
135  } else {
136  return NULL;
137  }
138 }
139 
140 ////////////////////////////////////////////////////////////////////////////////
141 /// Compute distance from point px,py to a string.
142 /// The rectangle surrounding this string is evaluated.
143 /// If the point (px,py) is in the rectangle, the distance is set to zero.
144 
146 {
147  Int_t ptx, pty;
148 
149  TAttText::Modify(); // change text attributes only if necessary
150 
151  if (TestBit(kTextNDC)) {
152  ptx = gPad->UtoPixel(fX);
153  pty = gPad->VtoPixel(fY);
154  } else {
155  ptx = gPad->XtoAbsPixel(gPad->XtoPad(fX));
156  pty = gPad->YtoAbsPixel(gPad->YtoPad(fY));
157  }
158 
159  // Get the text control box
160  Int_t cBoxX[5], cBoxY[5];
161  GetControlBox(ptx, pty, -fTextAngle, cBoxX, cBoxY);
162  cBoxY[4] = cBoxY[0];
163  cBoxX[4] = cBoxX[0];
164 
165  // Check if the point (px,py) is inside the text control box
166  if (TMath::IsInside(px, py, 5, cBoxX, cBoxY)){
167  return 0;
168  } else {
169  return 9999;
170  }
171 }
172 
173 ////////////////////////////////////////////////////////////////////////////////
174 /// Draw this text with new coordinates.
175 
177 {
178  TText *newtext = new TText(x, y, text);
179  TAttText::Copy(*newtext);
180  newtext->SetBit(kCanDelete);
181  if (TestBit(kTextNDC)) newtext->SetNDC();
182  newtext->AppendPad();
183  return newtext;
184 }
185 
186 ////////////////////////////////////////////////////////////////////////////////
187 /// Draw this text with new coordinates.
188 
190 {
191  TText *newtext = new TText(x, y, text);
192  TAttText::Copy(*newtext);
193  newtext->SetBit(kCanDelete);
194  if (TestBit(kTextNDC)) newtext->SetNDC();
195  newtext->AppendPad();
196  return newtext;
197 }
198 
199 ////////////////////////////////////////////////////////////////////////////////
200 /// Draw this text with new coordinates in NDC.
201 
203 {
204  TText *newtext = DrawText(x, y, text);
205  newtext->SetNDC();
206  return newtext;
207 }
208 
209 ////////////////////////////////////////////////////////////////////////////////
210 /// Draw this text with new coordinates in NDC.
211 
213 {
214  TText *newtext = DrawText(x, y, text);
215  newtext->SetNDC();
216  return newtext;
217 }
218 
219 ////////////////////////////////////////////////////////////////////////////////
220 /// Execute action corresponding to one event.
221 ///
222 /// This member function must be implemented to realize the action
223 /// corresponding to the mouse click on the object in the window
224 
226 {
227  if (!gPad) return;
228 
229  static Int_t px1, py1, pxold, pyold, Size, height, width;
230  static Bool_t resize,turn;
231  Int_t dx, dy;
232  const char *text = GetTitle();
233  Int_t len = strlen(text);
234  Double_t sizetowin = gPad->GetAbsHNDC()*Double_t(gPad->GetWh());
235  Double_t fh = (fTextSize*sizetowin);
236  Int_t h = Int_t(fh/2);
237  Int_t w = h*len;
238  Short_t halign = fTextAlign/10;
239  Short_t valign = fTextAlign - 10*halign;
240  Double_t co, si, dtheta, norm;
241  static Bool_t right, ndcsav;
242  static Double_t theta;
243  Int_t ax, ay, bx, by, cx, cy;
244  ax = ay = 0;
245  Double_t lambda, x2,y2;
246  Double_t dpx,dpy,xp1,yp1;
247  Int_t cBoxX[4], cBoxY[4], part;
248  Double_t div = 0;
249  Bool_t opaque = gPad->OpaqueMoving();
250 
251  if (!gPad->IsEditable()) return;
252  switch (event) {
253 
254  case kArrowKeyPress:
255  case kButton1Down:
256  ndcsav = TestBit(kTextNDC);
257  // No break !!!
258 
259  case kMouseMotion:
260  if (TestBit(kTextNDC)) {
261  px1 = gPad->UtoPixel(fX);
262  py1 = gPad->VtoPixel(fY);
263  } else {
264  px1 = gPad->XtoAbsPixel(gPad->XtoPad(fX));
265  py1 = gPad->YtoAbsPixel(gPad->YtoPad(fY));
266  }
267  theta = fTextAngle;
268  Size = 0;
269  pxold = px;
270  pyold = py;
271  co = TMath::Cos(fTextAngle*0.017453293);
272  si = TMath::Sin(fTextAngle*0.017453293);
273  resize = kFALSE;
274  turn = kFALSE;
275  GetControlBox(px1, py1, -theta, cBoxX, cBoxY);
276  div = ((cBoxX[3]-cBoxX[0])*co-(cBoxY[3]-cBoxY[0])*si);
277  if (TMath::Abs(div) > 1e-8) part = (Int_t)(3*((px-cBoxX[0])*co-(py-cBoxY[0])*si)/ div);
278  else part = 0;
279  switch (part) {
280  case 0:
281  if (halign == 3) {
282  turn = kTRUE;
283  right = kTRUE;
284  gPad->SetCursor(kRotate);
285  } else {
286  resize = kTRUE;
287  height = valign;
288  width = halign;
289  gPad->SetCursor(kArrowVer);
290  }
291  break;
292  case 1:
293  gPad->SetCursor(kMove);
294  break;
295  case 2:
296  if (halign == 3) {
297  resize = kTRUE;
298  height = valign;
299  width = halign;
300  gPad->SetCursor(kArrowVer);
301  } else {
302  turn = kTRUE;
303  right = kFALSE;
304  gPad->SetCursor(kRotate);
305  }
306  }
307  break;
308 
309  case kArrowKeyRelease:
310  case kButton1Motion:
311  if (!opaque) PaintControlBox(px1, py1, -theta);
312  if (turn) {
313  norm = TMath::Sqrt(Double_t((py-py1)*(py-py1)+(px-px1)*(px-px1)));
314  if (norm>0) {
315  theta = TMath::ACos((px-px1)/norm);
316  dtheta= TMath::ASin((py1-py)/norm);
317  if (dtheta<0) theta = -theta;
318  theta = theta/TMath::ACos(-1)*180;
319  if (theta<0) theta += 360;
320  if (right) {theta = theta+180; if (theta>=360) theta -= 360;}
321  }
322  } else if (resize) {
323 
324  co = TMath::Cos(fTextAngle*0.017453293);
325  si = TMath::Sin(fTextAngle*0.017453293);
326  if (width == 1) {
327  switch (valign) {
328  case 1 : ax = px1; ay = py1; break;
329  case 2 : ax = px1+Int_t(si*h/2); ay = py1+Int_t(co*h/2); break;
330  case 3 : ax = px1+Int_t(si*h*3/2); ay = py1+Int_t(co*h*3/2); break;
331  }
332  }
333  if (width == 2) {
334  switch (valign) {
335  case 1 : ax = px1-Int_t(co*w/2); ay = py1+Int_t(si*w/2); break;
336  case 2 : ax = px1-Int_t(co*w/2+si*h/2); ay = py1+Int_t(si*w/2+co*h/2); break;
337  case 3 : ax = px1-Int_t(co*w/2+si*h*3/2); ay = py1+Int_t(si*w/2+co*h*3/2); break;
338  }
339  }
340  if (width == 3) {
341  switch (valign) {
342  case 1 : ax = px1-Int_t(co*w); ay = py1+Int_t(si*w); break;
343  case 2 : ax = px1-Int_t(co*w+si*h/2); ay = py1+Int_t(si*w+co*h/2); break;
344  case 3 : ax = px1-Int_t(co*w+si*h*3/2); ay = py1+Int_t(si*w+co*h*3/2); break;
345  }
346  }
347  if (height == 3) {bx = ax-Int_t(si*h); by = ay-Int_t(co*h);}
348  else {bx = ax; by = ay;}
349  cx = bx+Int_t(co*w); cy = by-Int_t(si*w);
350  lambda = Double_t(((px-bx)*(cx-bx)+(py-by)*(cy-by)))/Double_t(((cx-bx)*(cx-bx)+(cy-by)*(cy-by)));
351  x2 = Double_t(px) - lambda*Double_t(cx-bx)-Double_t(bx);
352  y2 = Double_t(py) - lambda*Double_t(cy-by)-Double_t(by);
353  Size = Int_t(TMath::Sqrt(x2*x2+y2*y2)*2);
354  if (Size<4) Size = 4;
355 
356  SetTextSize(Size/sizetowin);
358  } else {
359  dx = px - pxold; px1 += dx;
360  dy = py - pyold; py1 += dy;
361  }
362  if (opaque) {
363  if (ndcsav) this->SetNDC(kFALSE);
364  this->SetX(gPad->PadtoX(gPad->AbsPixeltoX(px1)));
365  this->SetY(gPad->PadtoY(gPad->AbsPixeltoY(py1)));
366  if (resize) gPad->ShowGuidelines(this, event, 't', false);
367  if ((!resize)&&(!turn)) gPad->ShowGuidelines(this, event, 'i', true);
368  gPad->ShowGuidelines(this, event, !resize&!turn);
369  this->SetTextAngle(theta);
370  gPad->Modified(kTRUE);
371  gPad->Update();
372  }
373  if (!opaque) PaintControlBox(px1, py1, -theta);
374  pxold = px; pyold = py;
375  break;
376 
377  case kButton1Up:
378  if (opaque) {
379  if (ndcsav && !this->TestBit(kTextNDC)) {
380  this->SetX((fX - gPad->GetX1())/(gPad->GetX2()-gPad->GetX1()));
381  this->SetY((fY - gPad->GetY1())/(gPad->GetY2()-gPad->GetY1()));
382  this->SetNDC();
383  }
384  gPad->ShowGuidelines(this, event, !resize&!turn);
385  } else {
386  if (TestBit(kTextNDC)) {
387  dpx = gPad->GetX2() - gPad->GetX1();
388  dpy = gPad->GetY2() - gPad->GetY1();
389  xp1 = gPad->GetX1();
390  yp1 = gPad->GetY1();
391  fX = (gPad->AbsPixeltoX(px1)-xp1)/dpx;
392  fY = (gPad->AbsPixeltoY(py1)-yp1)/dpy;
393  } else {
394  fX = gPad->PadtoX(gPad->AbsPixeltoX(px1));
395  fY = gPad->PadtoY(gPad->AbsPixeltoY(py1));
396  }
397  fTextAngle = theta;
398  }
399  gPad->Modified(kTRUE);
400  break;
401 
402  case kButton1Locate:
403  ExecuteEvent(kButton1Down, px, py);
404 
405  while (1) {
406  px = py = 0;
407  event = gVirtualX->RequestLocator(1, 1, px, py);
408 
409  ExecuteEvent(kButton1Motion, px, py);
410 
411  if (event != -1) { // button is released
412  ExecuteEvent(kButton1Up, px, py);
413  return;
414  }
415  }
416  }
417 }
418 
419 ////////////////////////////////////////////////////////////////////////////////
420 /// Return the text control box. The text position coordinates is (x,y) and
421 /// the text angle is theta. The control box coordinates are returned in cBoxX
422 /// and cBoxY.
423 
425  Int_t cBoxX[4], Int_t cBoxY[4])
426 {
427  Short_t halign = fTextAlign/10; // horizontal alignment
428  Short_t valign = fTextAlign - 10*halign; // vertical alignment
429  UInt_t cBoxW, cBoxH; // control box width and heigh
430  UInt_t Dx = 0, Dy = 0; // delta along x and y to align the box
431 
432  GetBoundingBox(cBoxW, cBoxH);
433 
434  // compute the translations (Dx, Dy) required by the alignments
435  switch (halign) {
436  case 1 : Dx = 0 ; break;
437  case 2 : Dx = cBoxW/2; break;
438  case 3 : Dx = cBoxW ; break;
439  }
440  switch (valign) {
441  case 1 : Dy = 0 ; break;
442  case 2 : Dy = cBoxH/2; break;
443  case 3 : Dy = cBoxH ; break;
444  }
445 
446  // compute the control box coordinates before rotation
447  cBoxX[0] = x-Dx;
448  cBoxY[0] = y+Dy;
449  cBoxX[1] = x-Dx;
450  cBoxY[1] = y-cBoxH+Dy;
451  cBoxX[2] = x+cBoxW-Dx;
452  cBoxY[2] = y-cBoxH+Dy;
453  cBoxX[3] = x+cBoxW-Dx;
454  cBoxY[3] = y+Dy;
455 
456  // rotate the control box if needed
457  if (theta) {
458  Double_t cosTheta = TMath::Cos(theta*0.017453293);
459  Double_t sinTheta = TMath::Sin(theta*0.017453293);
460  for (int i=0; i<4 ; i++) {
461  Int_t hcBoxX = cBoxX[i];
462  Int_t hcBoxY = cBoxY[i];
463  cBoxX[i] = (Int_t)((hcBoxX-x)*cosTheta-(hcBoxY-y)*sinTheta+x);
464  cBoxY[i] = (Int_t)((hcBoxX-x)*sinTheta+(hcBoxY-y)*cosTheta+y);
465  }
466  }
467 }
468 
469 ////////////////////////////////////////////////////////////////////////////////
470 /// Return text size in pixels. By default the size returned does not take
471 /// into account the text angle (angle = kFALSE). If angle is set to kTRUE
472 /// w and h take the angle into account.
473 
475 {
476  const char *text = GetTitle();
477  if (!text[0]) {
478  w = h = 0;
479  return;
480  }
481 
482  if (angle) {
483  Int_t cBoxX[4], cBoxY[4];
484  Int_t ptx, pty;
485  if (TestBit(kTextNDC)) {
486  ptx = gPad->UtoPixel(fX);
487  pty = gPad->VtoPixel(fY);
488  } else {
489  ptx = gPad->XtoAbsPixel(gPad->XtoPad(fX));
490  pty = gPad->YtoAbsPixel(gPad->YtoPad(fY));
491  }
492  GetControlBox(ptx, pty, fTextAngle, cBoxX, cBoxY);
493  Int_t x1 = cBoxX[0];
494  Int_t x2 = cBoxX[0];
495  Int_t y1 = cBoxY[0];
496  Int_t y2 = cBoxY[0];
497  for (Int_t i=1; i<4; i++) {
498  if (cBoxX[i] < x1) x1 = cBoxX[i];
499  if (cBoxX[i] > x2) x2 = cBoxX[i];
500  if (cBoxY[i] < y1) y1 = cBoxY[i];
501  if (cBoxY[i] > y2) y2 = cBoxY[i];
502  }
503  w = x2-x1;
504  h = y2-y1;
505  } else {
506  if ((gVirtualX->HasTTFonts() && TTF::IsInitialized()) || gPad->IsBatch()) {
507  TTF::GetTextExtent(w, h, (char*)GetTitle());
508  } else {
509  const Font_t oldFont = gVirtualX->GetTextFont();
510  if (gVirtualX->InheritsFrom("TGCocoa"))
511  gVirtualX->SetTextFont(fTextFont);
512  gVirtualX->GetTextExtent(w, h, (char*)GetTitle());
513  if (gVirtualX->InheritsFrom("TGCocoa"))
514  gVirtualX->SetTextFont(oldFont);
515  }
516  }
517 }
518 
519 ////////////////////////////////////////////////////////////////////////////////
520 /// Return text ascent and descent for string text
521 /// - in a return total text ascent
522 /// - in d return text descent
523 
524 void TText::GetTextAscentDescent(UInt_t &a, UInt_t &d, const char *text) const
525 {
526  Double_t wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
527  Double_t hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
528  Double_t tsize;
529  if (wh < hh) tsize = fTextSize*wh;
530  else tsize = fTextSize*hh;
531 
532  if (gVirtualX->HasTTFonts() || gPad->IsBatch()) {
534  TTF::SetTextSize(tsize);
535  a = TTF::GetBox().yMax;
536  d = TMath::Abs(TTF::GetBox().yMin);
537  } else {
538  const Font_t oldFont = gVirtualX->GetTextFont();
539  if (gVirtualX->InheritsFrom("TGCocoa"))
540  gVirtualX->SetTextFont(fTextFont);
541  gVirtualX->SetTextSize(tsize);
542  a = gVirtualX->GetFontAscent(text);
543  if (!a) {
544  UInt_t w;
545  gVirtualX->GetTextExtent(w, a, (char*)text);
546  }
547  d = gVirtualX->GetFontDescent(text);
548  if (gVirtualX->InheritsFrom("TGCocoa"))
549  gVirtualX->SetTextFont(oldFont);
550  }
551 }
552 
553 
554 ////////////////////////////////////////////////////////////////////////////////
555 /// Return text ascent and descent for string text
556 /// - in a return total text ascent
557 /// - in d return text descent
558 
559 void TText::GetTextAscentDescent(UInt_t &a, UInt_t &d, const wchar_t *text) const
560 {
561  Double_t wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
562  Double_t hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
563  Double_t tsize;
564  if (wh < hh) tsize = fTextSize*wh;
565  else tsize = fTextSize*hh;
566 
567  if (gVirtualX->HasTTFonts() || gPad->IsBatch() || gVirtualX->InheritsFrom("TGCocoa")) {
569  TTF::SetTextSize(tsize);
570  a = TTF::GetBox().yMax;
571  d = TMath::Abs(TTF::GetBox().yMin);
572  } else {
573  gVirtualX->SetTextSize(tsize);
574  a = gVirtualX->GetFontAscent();
575  if (!a) {
576  UInt_t w;
577  gVirtualX->GetTextExtent(w, a, (wchar_t*)text);
578  }
579  d = gVirtualX->GetFontDescent();
580  }
581 }
582 
583 ////////////////////////////////////////////////////////////////////////////////
584 /// Return text extent for string text
585 /// - in w return total text width
586 /// - in h return text height
587 
588 void TText::GetTextExtent(UInt_t &w, UInt_t &h, const char *text) const
589 {
590  Double_t wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
591  Double_t hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
592  Double_t tsize;
593  if (wh < hh) tsize = fTextSize*wh;
594  else tsize = fTextSize*hh;
595 
596  if (gVirtualX->HasTTFonts() || gPad->IsBatch()) {
598  TTF::SetTextSize(tsize);
599  TTF::GetTextExtent(w, h, (char*)text);
600  } else {
601  const Font_t oldFont = gVirtualX->GetTextFont();
602  if (gVirtualX->InheritsFrom("TGCocoa"))
603  gVirtualX->SetTextFont(fTextFont);
604  gVirtualX->SetTextSize(tsize);
605  gVirtualX->GetTextExtent(w, h, (char*)text);
606  if (gVirtualX->InheritsFrom("TGCocoa"))
607  gVirtualX->SetTextFont(oldFont);
608  }
609 }
610 
611 ////////////////////////////////////////////////////////////////////////////////
612 /// Return text advance for string text
613 /// if kern is true (default) kerning is taken into account. If it is false
614 /// the kerning is not taken into account.
615 
616 void TText::GetTextAdvance(UInt_t &a, const char *text, const Bool_t kern) const
617 {
618  Double_t wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
619  Double_t hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
620  Double_t tsize;
621  if (wh < hh) tsize = fTextSize*wh;
622  else tsize = fTextSize*hh;
623 
624  if (gVirtualX->HasTTFonts() || gPad->IsBatch()) {
625  Bool_t kernsave = TTF::GetKerning();
626  TTF::SetKerning(kern);
628  TTF::SetTextSize(tsize);
629  TTF::GetTextAdvance(a, (char*)text);
630  TTF::SetKerning(kernsave);
631  } else {
632  UInt_t h;
633  const Font_t oldFont = gVirtualX->GetTextFont();
634  //how do I know what to calculate without a font???
635  if (gVirtualX->InheritsFrom("TGCocoa"))
636  gVirtualX->SetTextFont(fTextFont);
637 
638  gVirtualX->SetTextSize(tsize);
639  gVirtualX->GetTextExtent(a, h, (char*)text);
640 
641  if (gVirtualX->InheritsFrom("TGCocoa"))
642  gVirtualX->SetTextFont(oldFont);
643  }
644 }
645 
646 ////////////////////////////////////////////////////////////////////////////////
647 /// Return text extent for string text
648 /// - in w return total text width
649 /// - in h return text height
650 
651 void TText::GetTextExtent(UInt_t &w, UInt_t &h, const wchar_t *text) const
652 {
653  Double_t wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
654  Double_t hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
655  Double_t tsize;
656  if (wh < hh) tsize = fTextSize*wh;
657  else tsize = fTextSize*hh;
658 
659  if (gVirtualX->HasTTFonts() || gPad->IsBatch() || gVirtualX->InheritsFrom("TGCocoa")) {
661  TTF::SetTextSize(tsize);
662  TTF::GetTextExtent(w, h, (wchar_t*)text);
663  } else {
664  gVirtualX->SetTextSize(tsize);
665  gVirtualX->GetTextExtent(w, h, (wchar_t*)text);
666  }
667 }
668 
669 ////////////////////////////////////////////////////////////////////////////////
670 /// List this text with its attributes.
671 
672 void TText::ls(Option_t *) const
673 {
675  printf("Text X=%f Y=%f Text=%s\n",fX,fY,GetTitle());
676 }
677 
678 ////////////////////////////////////////////////////////////////////////////////
679 /// Paint this text with its current attributes.
680 
682 {
683  TAttText::Modify(); //Change text attributes only if necessary
684  if (TestBit(kTextNDC)) gPad->PaintTextNDC(fX,fY,GetTitle());
685  else gPad->PaintText(gPad->XtoPad(fX),gPad->YtoPad(fY),GetTitle());
686 }
687 
688 ////////////////////////////////////////////////////////////////////////////////
689 /// Paint the text control box. (x,y) are the coordinates where the control
690 /// box should be painted and theta is the angle of the box.
691 
693 {
694  Int_t cBoxX[4], cBoxY[4];
695  Short_t halign = fTextAlign/10; // horizontal alignment
696  Short_t valign = fTextAlign - 10*halign; // vertical alignment
697 
698  GetControlBox(x, y, theta, cBoxX, cBoxY);
699  // Draw the text control box outline
700  gVirtualX->SetLineStyle((Style_t)1);
701  gVirtualX->SetLineWidth(1);
702  gVirtualX->SetLineColor(1);
703  gVirtualX->DrawLine(cBoxX[0], cBoxY[0], cBoxX[1], cBoxY[1]);
704  gVirtualX->DrawLine(cBoxX[1], cBoxY[1], cBoxX[2], cBoxY[2]);
705  gVirtualX->DrawLine(cBoxX[2], cBoxY[2], cBoxX[3], cBoxY[3]);
706  gVirtualX->DrawLine(cBoxX[3], cBoxY[3], cBoxX[0], cBoxY[0]);
707 
708  // Draw a symbol at the text starting point
709  TPoint p;
710  Int_t ix = 0, iy = 0;
711  switch (halign) {
712  case 1 :
713  switch (valign) {
714  case 1 : ix = 0 ; iy = 0 ; break;
715  case 2 : ix = 0 ; iy = 1 ; break;
716  case 3 : ix = 1 ; iy = 1 ; break;
717  }
718  break;
719  case 2 :
720  switch (valign) {
721  case 1 : ix = 0 ; iy = 3 ; break;
722  case 2 : ix = 0 ; iy = 2 ; break;
723  case 3 : ix = 1 ; iy = 2 ; break;
724  }
725  break;
726  case 3 :
727  switch (valign) {
728  case 1 : ix = 3 ; iy = 3 ; break;
729  case 2 : ix = 2 ; iy = 3 ; break;
730  case 3 : ix = 2 ; iy = 2 ; break;
731  }
732  break;
733  }
734  p.fX = (cBoxX[ix]+cBoxX[iy])/2;
735  p.fY = (cBoxY[ix]+cBoxY[iy])/2;
736  gVirtualX->SetMarkerColor(1);
737  gVirtualX->SetMarkerStyle(24);
738  gVirtualX->SetMarkerSize(0.7);
739  gVirtualX->DrawPolyMarker(1, &p);
740 }
741 
742 ////////////////////////////////////////////////////////////////////////////////
743 /// Draw this text with new coordinates.
744 
746 {
747  TAttText::Modify(); //Change text attributes only if necessary
748  gPad->PaintText(x,y,text);
749 }
750 
751 ////////////////////////////////////////////////////////////////////////////////
752 /// Draw this text with new coordinates.
753 
754 void TText::PaintText(Double_t x, Double_t y, const wchar_t *text)
755 {
756  TAttText::Modify(); //Change text attributes only if necessary
757  gPad->PaintText(x,y,text);
758 }
759 
760 ////////////////////////////////////////////////////////////////////////////////
761 /// Draw this text with new coordinates in NDC.
762 
764 {
765  TAttText::Modify(); //Change text attributes only if necessary
766  gPad->PaintTextNDC(u,v,text);
767 }
768 
769 ////////////////////////////////////////////////////////////////////////////////
770 /// Draw this text with new coordinates in NDC.
771 
772 void TText::PaintTextNDC(Double_t u, Double_t v, const wchar_t *text)
773 {
774  TAttText::Modify(); //Change text attributes only if necessary
775  gPad->PaintTextNDC(u,v,text);
776 }
777 
778 ////////////////////////////////////////////////////////////////////////////////
779 /// Dump this text with its attributes.
780 
781 void TText::Print(Option_t *) const
782 {
783  printf("Text X=%f Y=%f Text=%s Font=%d Size=%f",fX,fY,GetTitle(),GetTextFont(),GetTextSize());
784  if (GetTextColor() != 1 ) printf(" Color=%d",GetTextColor());
785  if (GetTextAlign() != 10) printf(" Align=%d",GetTextAlign());
786  if (GetTextAngle() != 0 ) printf(" Angle=%f",GetTextAngle());
787  printf("\n");
788 }
789 
790 ////////////////////////////////////////////////////////////////////////////////
791 /// Save primitive as a C++ statement(s) on output stream out
792 
793 void TText::SavePrimitive(std::ostream &out, Option_t * /*= ""*/)
794 {
795  char quote = '"';
796  if (gROOT->ClassSaved(TText::Class())) {
797  out<<" ";
798  } else {
799  out<<" TText *";
800  }
801  TString s = GetTitle();
802  s.ReplaceAll("\"","\\\"");
803  out<<"text = new TText("<<fX<<","<<fY<<","<<quote<<s.Data()<<quote<<");"<<std::endl;
804  if (TestBit(kTextNDC)) out<<" text->SetNDC();"<<std::endl;
805 
806  SaveTextAttributes(out,"text",11,0,1,62,0.05);
807 
808  out<<" text->Draw();"<<std::endl;
809 }
810 
811 ////////////////////////////////////////////////////////////////////////////////
812 /// Set NDC mode on if isNDC = kTRUE, off otherwise
813 
815 {
817  if (isNDC) SetBit(kTextNDC);
818 }
819 
820 ////////////////////////////////////////////////////////////////////////////////
821 /// Change (i.e. set) the title of the TNamed.
822 
823 void TText::SetMbTitle(const wchar_t *title)
824 {
825  char *mb_title = new char[MB_CUR_MAX * wcslen(title) + 1]();
826  char *p = mb_title;
827  size_t length = wcslen(title);
828  for (size_t i = 0; i < length; i++) {
829  const int n = wctomb(p, title[i]);
830  if (n >= 0) p += n;
831  }
832  fTitle = mb_title;
833  delete [] mb_title;
834  if (gPad && TestBit(kMustCleanup)) gPad->Modified();
835 }
836 
837 ////////////////////////////////////////////////////////////////////////////////
838 /// Stream an object of class TText.
839 
840 void TText::Streamer(TBuffer &R__b)
841 {
842  if (R__b.IsReading()) {
843  UInt_t R__s, R__c;
844  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
845  if (R__v > 1) {
846  R__b.ReadClassBuffer(TText::Class(), this, R__v, R__s, R__c);
847  return;
848  }
849  //====process old versions before automatic schema evolution
850  TNamed::Streamer(R__b);
851  TAttText::Streamer(R__b);
852  Float_t x,y;
853  R__b >> x; fX = x;
854  R__b >> y; fY = y;
855  //====end of old versions
856 
857  } else {
858  R__b.WriteClassBuffer(TText::Class(),this);
859  }
860 }
861 ////////////////////////////////////////////////////////////////////////////////
862 /// Return the "bounding Box" of the Box
863 
865 {
866  UInt_t w, h;
867  Int_t Dx, Dy;
868  Dx = Dy = 0;
869  GetBoundingBox(w, h, false);
870 
871  Short_t halign = fTextAlign/10;
872  Short_t valign = fTextAlign - 10*halign;
873 
874  switch (halign) {
875  case 1 : Dx = 0 ; break;
876  case 2 : Dx = w/2 ; break;
877  case 3 : Dx = w ; break;
878  }
879  switch (valign) {
880  case 1 : Dy = h ; break;
881  case 2 : Dy = h/2 ; break;
882  case 3 : Dy = 0 ; break;
883  }
884 
885  Rectangle_t BBox;
886  BBox.fX = gPad->XtoPixel(fX)-Dx;
887  BBox.fY = gPad->YtoPixel(fY)-Dy;
888  BBox.fWidth = w;
889  BBox.fHeight = h;
890  return (BBox);
891 }
892 
893 ////////////////////////////////////////////////////////////////////////////////
894 /// Return the point given by Alignment as 'center'
895 
897 {
898  TPoint p;
899  p.SetX(gPad->XtoPixel(fX));
900  p.SetY(gPad->YtoPixel(fY));
901  return(p);
902 }
903 
904 ////////////////////////////////////////////////////////////////////////////////
905 /// Set the point given by Alignment as 'center'
906 
908 {
909  this->SetX(gPad->PixeltoX(p.GetX()));
910  this->SetY(gPad->PixeltoY(p.GetY()-gPad->VtoPixel(0)));
911 }
912 
913 ////////////////////////////////////////////////////////////////////////////////
914 /// Set X coordinate of the point given by Alignment as 'center'
915 
917 {
918  this->SetX(gPad->PixeltoX(x));
919 }
920 
921 ////////////////////////////////////////////////////////////////////////////////
922 /// Set Y coordinate of the point given by Alignment as 'center'
923 
925 {
926  this->SetY(gPad->PixeltoY(y - gPad->VtoPixel(0)));
927 }
928 
929 ////////////////////////////////////////////////////////////////////////////////
930 /// Set left hand side of BoundingBox to a value
931 /// (resize in x direction on left)
932 
933 void TText::SetBBoxX1(const Int_t /*x*/)
934 {
935  //NOT IMPLEMENTED
936 }
937 
938 ////////////////////////////////////////////////////////////////////////////////
939 /// Set right hand side of BoundingBox to a value
940 /// (resize in x direction on right)
941 
942 void TText::SetBBoxX2(const Int_t /*x*/)
943 {
944  //NOT IMPLEMENTED
945 }
946 
947 ////////////////////////////////////////////////////////////////////////////////
948 /// Set top of BoundingBox to a value (resize in y direction on top)
949 
950 void TText::SetBBoxY1(const Int_t /*y*/)
951 {
952  //NOT IMPLEMENTED
953 }
954 
955 ////////////////////////////////////////////////////////////////////////////////
956 /// Set bottom of BoundingBox to a value
957 /// (resize in y direction on bottom)
958 
959 void TText::SetBBoxY2(const Int_t /*y*/)
960 {
961  //NOT IMPLEMENTED
962 }
TString fTitle
Definition: TNamed.h:33
UShort_t fWidth
Definition: GuiTypes.h:362
Bool_t IsReading() const
Definition: TBuffer.h:83
virtual void Print(Option_t *option="") const
Dump this text with its attributes.
Definition: TText.cxx:781
void SetX(SCoord_t x)
Definition: TPoint.h:49
Short_t fY
Definition: GuiTypes.h:361
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 Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
UShort_t fHeight
Definition: GuiTypes.h:362
virtual void SetBBoxCenterY(const Int_t y)
Set Y coordinate of the point given by Alignment as &#39;center&#39;.
Definition: TText.cxx:924
short Style_t
Definition: RtypesCore.h:76
short Version_t
Definition: RtypesCore.h:61
virtual Color_t GetTextColor() const
Return the text color.
Definition: TAttText.h:34
float Float_t
Definition: RtypesCore.h:53
virtual Short_t GetTextAlign() const
Return the text alignment.
Definition: TAttText.h:32
const char Option_t
Definition: RtypesCore.h:62
virtual void SetMbTitle(const wchar_t *title=L"")
Change (i.e. set) the title of the TNamed.
Definition: TText.cxx:823
const char * Size
Definition: TXMLSetup.cxx:55
virtual void SetX(Double_t x)
Definition: TText.h:74
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:638
virtual void ls(Option_t *option="") const
List this text with its attributes.
Definition: TText.cxx:672
static Bool_t IsInitialized()
Definition: TTF.cxx:605
void Copy(TObject &text) const
Copy this text to text.
Definition: TText.cxx:108
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
TH1 * h
Definition: legend2.C:5
virtual Float_t GetTextAngle() const
Return the text angle.
Definition: TAttText.h:33
SCoord_t fX
Definition: TPoint.h:35
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
The text position is in the NDC space.
Definition: TText.h:33
#define gROOT
Definition: TROOT.h:402
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
SCoord_t fY
Definition: TPoint.h:36
Basic string class.
Definition: TString.h:125
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:424
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
SCoord_t GetY() const
Definition: TPoint.h:48
virtual void Paint(Option_t *option="")
Paint this text with its current attributes.
Definition: TText.cxx:681
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
Definition: TText.cxx:793
virtual void PaintTextNDC(Double_t u, Double_t v, const char *text)
Draw this text with new coordinates in NDC.
Definition: TText.cxx:763
SCoord_t GetX() const
Definition: TPoint.h:47
virtual ~TText()
Text default destructor.
Definition: TText.cxx:90
short Font_t
Definition: RtypesCore.h:75
void SetY(SCoord_t y)
Definition: TPoint.h:50
Short_t Abs(Short_t d)
Definition: TMathBase.h:108
virtual void SetBBoxY1(const Int_t y)
Set top of BoundingBox to a value (resize in y direction on top)
Definition: TText.cxx:950
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
if object in a list can be deleted
Definition: TObject.h:58
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition: TObject.cxx:105
virtual void Modify()
Change current text attributes if necessary.
Definition: TAttText.cxx:306
virtual void GetTextAdvance(UInt_t &a, const char *text, const Bool_t kern=kTRUE) const
Return text advance for string text if kern is true (default) kerning is taken into account...
Definition: TText.cxx:616
virtual void SetBBoxX2(const Int_t x)
Set right hand side of BoundingBox to a value (resize in x direction on right)
Definition: TText.cxx:942
static const double x2[5]
virtual TPoint GetBBoxCenter()
Return the point given by Alignment as &#39;center&#39;.
Definition: TText.cxx:896
Double_t x[n]
Definition: legend1.C:17
void Class()
Definition: Class.C:29
static void SetTextFont(Font_t fontnumber)
Set specified font.
Definition: TTF.cxx:488
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual Float_t GetTextSize() const
Return the text size.
Definition: TAttText.h:36
static void GetTextExtent(UInt_t &w, UInt_t &h, char *text)
Get width (w) and height (h) when text is horizontal.
Definition: TTF.cxx:132
virtual TText * DrawTextNDC(Double_t x, Double_t y, const char *text)
Draw this text with new coordinates in NDC.
Definition: TText.cxx:202
virtual void SetBBoxX1(const Int_t x)
Set left hand side of BoundingBox to a value (resize in x direction on left)
Definition: TText.cxx:933
virtual void PaintControlBox(Int_t x, Int_t y, Double_t theta)
Paint the text control box.
Definition: TText.cxx:692
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a string.
Definition: TText.cxx:145
Base class for several text objects.
Definition: TText.h:23
static void GetTextAdvance(UInt_t &a, char *text)
Get advance (a) when text is horizontal.
Definition: TTF.cxx:148
virtual void SetNDC(Bool_t isNDC=kTRUE)
Set NDC mode on if isNDC = kTRUE, off otherwise.
Definition: TText.cxx:814
Bool_t IsInside(T xp, T yp, Int_t np, T *x, T *y)
Definition: TMath.h:1204
Short_t fX
Definition: GuiTypes.h:361
Definition: TPoint.h:31
virtual void SetBBoxY2(const Int_t y)
Set bottom of BoundingBox to a value (resize in y direction on bottom)
Definition: TText.cxx:959
void Copy(TAttText &atttext) const
Copy this text attributes to a new TAttText.
Definition: TAttText.cxx:294
Float_t fTextAngle
Text angle.
Definition: TAttText.h:21
virtual Rectangle_t GetBBox()
Return the "bounding Box" of the Box.
Definition: TText.cxx:864
SVector< double, 2 > v
Definition: Dict.h:5
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:347
auto * a
Definition: textangle.C:12
virtual Font_t GetTextFont() const
Return the text font.
Definition: TAttText.h:35
static Bool_t GetKerning()
Definition: TTF.cxx:591
virtual void SetTextAngle(Float_t tangle=0)
Set the text angle.
Definition: TAttText.h:42
Text Attributes class.
Definition: TAttText.h:18
Double_t fY
Y position of text (left,center,etc..)
Definition: TText.h:27
unsigned int UInt_t
Definition: RtypesCore.h:42
TText()
Text default constructor.
Definition: TText.cxx:60
short Short_t
Definition: RtypesCore.h:35
static void IndentLevel()
Functions used by ls() to indent an object hierarchy.
Definition: TROOT.cxx:2746
Double_t ACos(Double_t)
Definition: TMath.h:571
Font_t fTextFont
Text font.
Definition: TAttText.h:25
static void SetKerning(Bool_t state)
Set kerning flag.
Definition: TTF.cxx:331
if object destructor must call RecursiveRemove()
Definition: TObject.h:60
#define gVirtualX
Definition: TVirtualX.h:350
Double_t Cos(Double_t)
Definition: TMath.h:550
const Bool_t kFALSE
Definition: RtypesCore.h:88
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
static const double x1[5]
#define ClassImp(name)
Definition: Rtypes.h:359
double Double_t
Definition: RtypesCore.h:55
TText * text
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute action corresponding to one event.
Definition: TText.cxx:225
Double_t y[n]
Definition: legend1.C:17
static constexpr double s
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
Float_t fTextSize
Text size.
Definition: TAttText.h:22
virtual void GetTextExtent(UInt_t &w, UInt_t &h, const char *text) const
Return text extent for string text.
Definition: TText.cxx:588
Mother of all ROOT objects.
Definition: TObject.h:37
void * fWcsTitle
!Used by TMathText
Definition: TText.h:28
virtual void SetBBoxCenter(const TPoint &p)
Set the point given by Alignment as &#39;center&#39;.
Definition: TText.cxx:907
virtual void Copy(TObject &named) const
Copy this to obj.
Definition: TNamed.cxx:94
Abstract base class for elements drawn in the editor.
Definition: TAttBBox2D.h:19
virtual void SetBBoxCenterX(const Int_t x)
Set X coordinate of the point given by Alignment as &#39;center&#39;.
Definition: TText.cxx:916
Double_t Sin(Double_t)
Definition: TMath.h:547
Double_t ASin(Double_t)
Definition: TMath.h:565
const void * GetWcsTitle(void) const
Returns the text as UNICODE.
Definition: TText.cxx:131
virtual TText * DrawText(Double_t x, Double_t y, const char *text)
Draw this text with new coordinates.
Definition: TText.cxx:176
#define gPad
Definition: TVirtualPad.h:285
static void SetTextSize(Float_t textsize)
Set current text size.
Definition: TTF.cxx:559
virtual void SetY(Double_t y)
Definition: TText.h:75
void ResetBit(UInt_t f)
Definition: TObject.h:171
Double_t Sqrt(Double_t x)
Definition: TMath.h:590
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Definition: TAttText.h:46
const Bool_t kTRUE
Definition: RtypesCore.h:87
virtual void PaintText(Double_t x, Double_t y, const char *text)
Draw this text with new coordinates.
Definition: TText.cxx:745
const Int_t n
Definition: legend1.C:16
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
Double_t fX
X position of text (left,center,etc..)
Definition: TText.h:26
static const FT_BBox & GetBox()
Definition: TTF.cxx:640
Short_t fTextAlign
Text alignment.
Definition: TAttText.h:23
virtual void GetBoundingBox(UInt_t &w, UInt_t &h, Bool_t angle=kFALSE)
Return text size in pixels.
Definition: TText.cxx:474
const char * Data() const
Definition: TString.h:345