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