// @(#)root/base:$Name: $:$Id: TAttText.cxx,v 1.19 2006/07/03 16:10:43 brun Exp $ // Author: Rene Brun 12/12/94 /************************************************************************* * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ #include "Riostream.h" #include "Strlen.h" #include "TROOT.h" #include "TAttText.h" #include "TVirtualPad.h" #include "TStyle.h" #include "TVirtualX.h" #include "TError.h" #include "TVirtualPadEditor.h" #include "TColor.h" ClassImp(TAttText) //______________________________________________________________________________ //*-*-*-*-*-*-*-*-*-*-*-*-*Text Attributes class*-*-*-*-*-*-*-*-*-*-*-*-*-*-* //*-* ===================== //*-* Text attributes are: //*-* Text Alignment //*-* Text Color //*-* Text Font //*-* Text Size //*-* Text Angle //*-* //*-* This class is used (in general by secondary inheritance) //*-* //*-* by many other classes (graphics, histograms). //*-* align : Text alignment = 10*HorizontalAlign + VerticalAlign //*-* For Horizontal alignment the following convention applies: //*-* 1=left adjusted, 2=centered, 3=rigth adjusted //*-* For Vertical alignment the following convention applies: //*-* 1=bottom adjusted, 2=centered, 3=top adjusted //*-* For example align = 11 = left adjusted and bottom adjusted //*-* align = 32 = right adjusted and vertically centered //*-* angle : Text angle in degrees //*-* color : Text Color Index //*-* font : Text font code = 10*fontnumber + precision //*-* Font numbers must be between 1 and 14 //*-* precision = 0 fast hardware fonts (steps in the size) //*-* precision = 1 scalable and rotatable hardware fonts (see below) //*-* precision = 2 scalable and rotatable hardware fonts //*-* precision = 3 scalable and rotatable hardware fonts. Text size //*-* is given in pixels. //*-* size : Character size expressed in percentage of the current pad height //*-* The textsize in pixels (say charheight) will be: //*-* charheight = textsize*canvas_height if current pad is horizontal. //*-* charheight = textsize*canvas_width if current pad is vertical. //*-* charheight = number of pixels if font precision is greater than 2 //*-* //*-* Font quality and speed //*-* ====================== //*-* When precision 0 is used, only the original non-scaled system fonts //*-* are used. The fonts have a minimum (4) and maximum (37) size in pixels. //*-* These fonts are fast and are of good quality. Their size varies with //*-* large steps and they cannot be rotated. //*-* Precision 1 and 2 fonts have a different behaviour depending if the //*-* True Type Fonts are used or not. If TTF are used, you always get //*-* very good quality scalable and rotatable fonts. However TTF are slow. //*-* Precision 1 and 2 fonts have a different behaviour for Postscript //*-* in case of TLatex objects. With precision 1, the Postscript text uses //*-* the old convention (see TPostScript) for some special characters //*-* to draw sub and superscripts or greek text. //*-* With precision 2 the "PostScript" special characters are drawn as such. //*-* To draw sub and superscripts it is highly recommended to use TLatex //*-* objects instead. //*-* //*-* How to use True Type Fonts //*-* ========================== //*-* You can activate the TTF by adding (or activating) the following line //*-* in your .rootrc file. //*-* Unix.*.Root.UseTTFonts: true //*-* WinNT for NT //*-* You can check that you indeed use the TTF in your Root session. //*-* When the TTF is active, you get the following message at the start //*-* of a session: //*-* "FreeType Engine v1.x used to render TrueType fonts." //*-* You can also check with the command gEnv->Print(). //*-* //*-* List of the currently supported fonts (screen and PostScript) //*-* ============================================================= //*-* Font ID X11 Win32 TTF lfItalic lfWeight x 10 //*-* 1 : times-medium-i-normal "Times New Roman" 1 4 //*-* 2 : times-bold-r-normal "Times New Roman" 0 7 //*-* 3 : times-bold-i-normal "Times New Roman" 1 7 //*-* 4 : helvetica-medium-r-normal "Arial" 0 4 //*-* 5 : helvetica-medium-o-normal "Arial" 1 4 //*-* 6 : helvetica-bold-r-normal "Arial" 0 7 //*-* 7 : helvetica-bold-o-normal "Arial" 1 7 //*-* 8 : courier-medium-r-normal "Courier New" 0 4 //*-* 9 : courier-medium-o-normal "Courier New" 1 4 //*-* 10 : courier-bold-r-normal "Courier New" 0 7 //*-* 11 : courier-bold-o-normal "Courier New" 1 7 //*-* 12 : symbol-medium-r-normal "Symbol" 0 6 //*-* 13 : times-medium-r-normal "Times New Roman" 0 4 //*-* 14 : "Wingdings" 0 4 //*-* //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* //______________________________________________________________________________ TAttText::TAttText() { //*-*-*-*-*-*-*-*-*-*-*-*-*AttText default constructor*-*-*-*-*-*-*-*-*-*-*-* //*-* =========================== //*-* Default text attributes are taking from the current style //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* if (!gStyle) { ResetAttText(); return; } fTextAlign = gStyle->GetTextAlign(); fTextAngle = gStyle->GetTextAngle(); fTextColor = gStyle->GetTextColor(); fTextFont = gStyle->GetTextFont(); fTextSize = gStyle->GetTextSize(); } //______________________________________________________________________________ TAttText::TAttText(Int_t align, Float_t angle, Color_t color, Style_t font, Float_t tsize) { //*-*-*-*-*-*-*-*-*-*-*-*-*AttText normal constructor*-*-*-*-*-*-*-*-*-*-*-* //*-* =========================== //*-* Text attributes are taking from the argument list //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* fTextAlign = align; fTextAngle = angle; fTextColor = color; fTextFont = font; fTextSize = tsize; } //______________________________________________________________________________ TAttText::~TAttText() { //*-*-*-*-*-*-*-*-*-*-*-*-*AttText destructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* //*-* ================= } //______________________________________________________________________________ void TAttText::Copy(TAttText &atttext) const { //*-*-*-*-*-*-*-*-*Copy this text attributes to a new atttext*-*-*-*-*-*-*-*-* //*-* ========================================== atttext.fTextAlign = fTextAlign; atttext.fTextAngle = fTextAngle; atttext.fTextColor = fTextColor; atttext.fTextFont = fTextFont; atttext.fTextSize = fTextSize; } //______________________________________________________________________________ void TAttText::Modify() { //*-*-*-*-*-*-*-*-*-*Change current text attributes if necessary*-*-*-*-*-*-* //*-* =========================================== if (!gPad) return; //*-*- Do we need to change font? if (!gPad->IsBatch()) { gVirtualX->SetTextAngle(fTextAngle); Float_t wh = (Float_t)gPad->XtoPixel(gPad->GetX2()); Float_t hh = (Float_t)gPad->YtoPixel(gPad->GetY1()); Float_t tsize; if (wh < hh) tsize = fTextSize*wh; else tsize = fTextSize*hh; if (fTextFont%10 > 2) tsize = fTextSize; again: if (gVirtualX->HasTTFonts()) { if (gVirtualX->GetTextFont() != fTextFont) { gVirtualX->SetTextFont(fTextFont); if (!gVirtualX->HasTTFonts()) goto again; gVirtualX->SetTextSize(tsize); } if (gVirtualX->GetTextSize() != tsize) gVirtualX->SetTextSize(tsize); } else if (gVirtualX->GetTextFont() != fTextFont || gVirtualX->GetTextSize() != tsize) { char fx11[64]; Int_t fpx11 = fTextFont; if (fpx11 < 0) fpx11 = -fpx11; Int_t ifpx11 = fpx11/10; Int_t ih = Int_t(tsize); // to be set to IH = INT(WKSC(IWKNB)*YRATIO*RCHH*1.5) Float_t rsize = Float_t(ih); if (ih > 37) ih = 37; if (ih <= 0) ih = 1; if (ifpx11 <= 0 || ifpx11 > 13) ifpx11 = 6; //*-*- Set Font name switch (ifpx11) { case 1 : strcpy(fx11, "-*-times-medium-i-normal--"); break; case 2 : strcpy(fx11, "-*-times-bold-r-normal--"); break; case 3 : strcpy(fx11, "-*-times-bold-i-normal--"); break; case 4 : strcpy(fx11, "-*-helvetica-medium-r-normal--"); break; case 5 : strcpy(fx11, "-*-helvetica-medium-o-normal--"); break; case 6 : strcpy(fx11, "-*-helvetica-bold-r-normal--"); break; case 7 : strcpy(fx11, "-*-helvetica-bold-o-normal--"); break; case 8 : strcpy(fx11, "-*-courier-medium-r-normal--"); break; case 9 : strcpy(fx11, "-*-courier-medium-o-normal--"); break; case 10 : strcpy(fx11, "-*-courier-bold-r-normal--"); break; case 11 : strcpy(fx11, "-*-courier-bold-o-normal--"); break; case 12 : strcpy(fx11, "-*-symbol-medium-r-normal--"); break; case 13 : strcpy(fx11, "-*-times-medium-r-normal--"); break; }; char *buffer; Int_t il = strlen(fx11); //*-* Check if closest font has already been computed static Int_t first = 1; static Int_t fontchecked[13][40]; if (first) { for (int ifont=0;ifont<13;ifont++) { for (int isize=0;isize<40;isize++) fontchecked[ifont][isize] = 0; } first = 0; } Int_t ihh = fontchecked[ifpx11-1][ih-1]; if (ihh) { buffer = fx11 + il; sprintf(buffer,"%d-*",ihh); gVirtualX->SetTextFont(fx11, TVirtualX::kLoad); } else { //*-*- Find smallest size available Int_t isxfnt; for (isxfnt=8; isxfnt<17; isxfnt++) { buffer = fx11 + il; sprintf(buffer,"%d-*",isxfnt); if (!gVirtualX->SetTextFont(fx11, TVirtualX::kCheck) ) break; if (isxfnt == 16) Warning("TAttText::Modify", "cannot find the right size font"); } //*-*- Find the closest size available ihh = ih; while (1) { if (ihh < isxfnt) ihh = isxfnt; buffer = fx11 + il; sprintf(buffer,"%d-*",ihh); if (!gVirtualX->SetTextFont(fx11, TVirtualX::kLoad) ) { fontchecked[ifpx11-1][ih-1] = ihh; break; } if (ihh == isxfnt) { Warning("TAttText::Modify", "cannot find the right size font"); return; } ihh--; } } //*-*- ready to draw text Float_t mgn = rsize/Float_t(ihh); if (mgn > 100) mgn = 100; if (mgn <0) mgn = 1; if (fTextFont%10 == 0 || fTextFont%10 > 2) mgn = 1; gVirtualX->SetTextMagnitude(mgn); gVirtualX->DrawText(0,0,0,-1.,0,TVirtualX::kClear); gVirtualX->SetTextFont(fTextFont); gVirtualX->SetTextSize(tsize); } gVirtualX->SetTextAlign(fTextAlign); gVirtualX->SetTextColor(fTextColor); } gPad->SetAttTextPS(fTextAlign,fTextAngle,fTextColor,fTextFont,fTextSize); } //______________________________________________________________________________ void TAttText::ResetAttText(Option_t *) { //*-*-*-*-*-*-*-*-*Reset this text attributes to default values*-*-*-*-*-*-* //*-* ============================================ fTextAlign = 11; fTextAngle = 0; fTextColor = 1; fTextFont = 62; fTextSize = 0.05; } //______________________________________________________________________________ void TAttText::SaveTextAttributes(ostream &out, const char *name, Int_t alidef, Float_t angdef, Int_t coldef, Int_t fondef, Float_t sizdef) { // Save text attributes as C++ statement(s) on output stream out if (fTextAlign != alidef) { out<<" "<<name<<"->SetTextAlign("<<fTextAlign<<");"<<endl; } if (fTextColor != coldef) { if (fTextColor > 228) { TColor::SaveColor(out, fTextColor); out<<" "<<name<<"->SetTextColor(ci);" << endl; } else out<<" "<<name<<"->SetTextColor("<<fTextColor<<");"<<endl; } if (fTextFont != fondef) { out<<" "<<name<<"->SetTextFont("<<fTextFont<<");"<<endl; } if (fTextSize != sizdef) { out<<" "<<name<<"->SetTextSize("<<fTextSize<<");"<<endl; } if (fTextAngle != angdef) { out<<" "<<name<<"->SetTextAngle("<<fTextAngle<<");"<<endl; } } //______________________________________________________________________________ void TAttText::SetTextAttributes() { //*-*-*-*-*-*-*-*-*Invoke the DialogCanvas Text attributes*-*-*-*-*-*-* //*-* ======================================= //if (gPad) gPad->UpdateTextAttributes(fTextAlign,fTextAngle,fTextColor,fTextFont,fTextSize); TVirtualPadEditor::UpdateTextAttributes(fTextAlign,fTextAngle,fTextColor, fTextFont,fTextSize); } //______________________________________________________________________________ void TAttText::SetTextSizePixels(Int_t npixels) { // Set the text size in pixels. // If the font precision is greater than 2, the text size is set to npixels, // otherwise the text size is computed as a per cent of the pad size. if (fTextFont%10 > 2) { fTextSize = Float_t(npixels); } else { TVirtualPad *pad = gROOT->GetSelectedPad(); if (!pad) return; Float_t dy = pad->AbsPixeltoY(0) - pad->AbsPixeltoY(npixels); fTextSize = dy/(pad->GetY2() - pad->GetY1()); } }