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