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