13 #include "RConfigure.h"
29 # include <FTGL/ftgl.h>
32 # include "FTGLExtrdFont.h"
33 # include "FTGLOutlineFont.h"
34 # include "FTGLPolygonFont.h"
35 # include "FTGLTextureFont.h"
36 # include "FTGLPixmapFont.h"
37 # include "FTGLBitmapFont.h"
54 fFont(0), fManager(0), fDepth(0),
55 fSize(0), fFile(0), fMode(kUndef),
63 TGLFont::TGLFont(Int_t size, Int_t font, EMode mode, FTFont* f, TGLFontManager* mng):
64 fFont(f), fManager(mng), fDepth(0),
65 fSize(size), fFile(font), fMode(mode),
73 TGLFont::TGLFont(
const TGLFont &o):
74 fFont(0), fManager(0), fDepth(0), fTrashCount(0)
76 fFont = (FTFont*)o.GetFont();
82 fTrashCount = o.fTrashCount;
90 if (fManager) fManager->ReleaseFont(*
this);
96 void TGLFont::CopyAttributes(
const TGLFont &o)
99 SetManager(o.fManager);
107 fTrashCount = o.fTrashCount;
116 Float_t TGLFont::GetAscent()
const
118 return fFont->Ascender();
124 Float_t TGLFont::GetDescent()
const
126 return -fFont->Descender();
132 Float_t TGLFont::GetLineHeight()
const
134 return fFont->LineHeight();
142 void TGLFont::MeasureBaseLineParams(Float_t& ascent, Float_t& descent, Float_t& line_height,
143 const char* txt)
const
145 Float_t dum, lly, ury;
146 const_cast<FTFont*
>(fFont)->BBox(txt, dum, lly, dum, dum, ury, dum);
149 line_height = ury - lly;
155 void TGLFont::BBox(
const char* txt,
156 Float_t& llx, Float_t& lly, Float_t& llz,
157 Float_t& urx, Float_t& ury, Float_t& urz)
const
160 const_cast<FTFont*
>(fFont)->BBox(txt, llx, lly, llz, urx, ury, urz);
166 void TGLFont::BBox(
const wchar_t* txt,
167 Float_t& llx, Float_t& lly, Float_t& llz,
168 Float_t& urx, Float_t& ury, Float_t& urz)
const
171 const_cast<FTFont*
>(fFont)->BBox(txt, llx, lly, llz, urx, ury, urz);
179 void TGLFont::RenderHelper(
const Char *txt, Double_t x, Double_t y, Double_t angle, Double_t )
const
185 Float_t llx = 0.f, lly = 0.f, llz = 0.f, urx = 0.f, ury = 0.f, urz = 0.f;
186 BBox(txt, llx, lly, llz, urx, ury, urz);
197 const Double_t dx = urx - llx, dy = ury - lly;
198 Double_t xc = 0., yc = 0.;
199 const UInt_t align = gVirtualX->GetTextAlign();
205 if (gVirtualX->InheritsFrom(
"TGCocoa")) {
206 const UInt_t hAlign = UInt_t(align / 10);
218 const UInt_t vAlign = UInt_t(align % 10);
264 glTranslated(x, y, 0.);
265 glRotated(angle, 0., 0., 1.);
266 glTranslated(xc, yc, 0.);
267 glTranslated(-0.5 * dx, -0.5 * dy, 0.);
270 const_cast<FTFont*
>(fFont)->Render(txt);
277 void TGLFont::Render(
const wchar_t* txt, Double_t x, Double_t y, Double_t angle, Double_t mgn)
const
279 RenderHelper(txt, x, y, angle, mgn);
284 void TGLFont::Render(
const char* txt, Double_t x, Double_t y, Double_t angle, Double_t mgn)
const
286 RenderHelper(txt, x, y, angle, mgn);
292 void TGLFont::Render(
const TString &txt)
const
294 Bool_t scaleDepth = (fMode == kExtrude && fDepth != 1.0f);
299 glTranslatef(0.0f, 0.0f, 0.5f*fDepth * 0.2f*fSize);
300 glScalef(1.0f, 1.0f, fDepth);
304 const_cast<FTFont*
>(fFont)->Render(txt);
314 void TGLFont:: Render(
const TString &txt, Float_t x, Float_t y, Float_t z,
315 ETextAlignH_e alignH, ETextAlignV_e alignV)
const
319 glTranslatef(x, y, z);
322 Float_t llx, lly, llz, urx, ury, urz;
323 BBox(txt, llx, lly, llz, urx, ury, urz);
327 case TGLFont::kRight:
331 case TGLFont::kCenterH:
340 case TGLFont::kBottom:
343 case TGLFont::kCenterV:
350 if (fMode == TGLFont::kPixmap || fMode == TGLFont::kBitmap)
353 glBitmap(0, 0, 0, 0, x, y, 0);
357 glTranslatef(x, y, 0);
366 void TGLFont::PreRender(Bool_t autoLight, Bool_t lightOn)
const
372 glPushAttrib(GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT);
373 glEnable(GL_ALPHA_TEST);
374 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
375 glAlphaFunc(GL_GEQUAL, 0.0625);
378 glPushAttrib(GL_POLYGON_BIT | GL_ENABLE_BIT);
379 glEnable(GL_TEXTURE_2D);
380 glDisable(GL_CULL_FACE);
381 glEnable(GL_ALPHA_TEST);
382 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
383 glAlphaFunc(GL_GEQUAL, 0.0625);
388 glPushAttrib(GL_POLYGON_BIT | GL_ENABLE_BIT);
389 glEnable(GL_NORMALIZE);
390 glDisable(GL_CULL_FACE);
393 Warning(
"TGLFont::PreRender",
"Font mode undefined.");
394 glPushAttrib(GL_LIGHTING_BIT);
398 if ((autoLight && fMode > TGLFont::kOutline) || (!autoLight && lightOn))
399 glEnable(GL_LIGHTING);
401 glDisable(GL_LIGHTING);
407 void TGLFont::PostRender()
const
420 ClassImp(TGLFontManager);
422 TObjArray TGLFontManager::fgFontFileArray;
423 Int_t TGLFontManager::fgExtendedFontStart;
424 TGLFontManager::FontSizeVec_t TGLFontManager::fgFontSizeArray;
425 Bool_t TGLFontManager::fgStaticInitDone = kFALSE;
430 TGLFontManager::~TGLFontManager()
432 FontMap_i it = fFontMap.begin();
433 while (it != fFontMap.end()) {
434 delete it->first.GetFont();
443 void TGLFontManager::RegisterFont(Int_t sizeIn, Int_t fileID, TGLFont::EMode mode, TGLFont &out)
445 if (fgStaticInitDone == kFALSE) InitStatics();
447 Int_t size = GetFontSize(sizeIn);
448 if (mode == out.GetMode() && fileID == out.GetFile() && size == out.GetSize())
451 FontMap_i it = fFontMap.find(TGLFont(size, fileID, mode));
452 if (it == fFontMap.end())
454 TString ttpath, file;
455 ttpath = gEnv->GetValue(
"Root.TTGLFontPath", TROOT::GetTTFFontDir());
458 char *fp = gSystem->Which(ttpath, fileID < fgExtendedFontStart ?
459 ((TObjString*)fgFontFileArray[fileID])->String() +
".ttf" :
460 ((TObjString*)fgFontFileArray[fileID])->String());
468 case TGLFont::kBitmap:
469 ftfont =
new FTGLBitmapFont(file);
471 case TGLFont::kPixmap:
472 ftfont =
new FTGLPixmapFont(file);
474 case TGLFont::kOutline:
475 ftfont =
new FTGLOutlineFont(file);
477 case TGLFont::kPolygon:
478 ftfont =
new FTGLPolygonFont(file);
480 case TGLFont::kExtrude:
481 ftfont =
new FTGLExtrdFont(file);
482 ftfont->Depth(0.2*size);
484 case TGLFont::kTexture:
485 ftfont =
new FTGLTextureFont(file);
488 Error(
"TGLFontManager::RegisterFont",
"invalid FTGL type");
492 ftfont->FaceSize(size);
493 const TGLFont &mf = fFontMap.insert(std::make_pair(TGLFont(size, fileID, mode, ftfont, 0), 1)).first->first;
494 out.CopyAttributes(mf);
498 if (it->first.GetTrashCount() > 0) {
499 fFontTrash.remove(&(it->first));
500 it->first.SetTrashCount(0);
503 out.CopyAttributes(it->first);
505 out.SetManager(
this);
511 void TGLFontManager::RegisterFont(Int_t size,
const char* name, TGLFont::EMode mode, TGLFont &out)
513 TObjArray* farr = GetFontFileArray();
517 while ((os = (TObjString*) next()) != 0)
519 if (os->String() == name)
524 if (cnt < farr->GetEntries())
525 RegisterFont(size, cnt, mode, out);
527 Error(
"TGLFontManager::RegisterFont",
"unknown font name %s", name);
534 void TGLFontManager::ReleaseFont(TGLFont& font)
536 FontMap_i it = fFontMap.find(font);
538 if (it != fFontMap.end())
543 assert(it->first.GetTrashCount() == 0);
544 it->first.IncTrashCount();
545 fFontTrash.push_back(&it->first);
553 TObjArray* TGLFontManager::GetFontFileArray()
555 if (fgStaticInitDone == kFALSE) InitStatics();
556 return &fgFontFileArray;
562 TGLFontManager::FontSizeVec_t* TGLFontManager::GetFontSizeArray()
564 if (fgStaticInitDone == kFALSE) InitStatics();
565 return &fgFontSizeArray;
570 Int_t TGLFontManager::GetExtendedFontStartIndex()
572 if (fgStaticInitDone == kFALSE) InitStatics();
574 assert(fgExtendedFontStart > 0 &&
"GetExtendedFontStartIndex, invalid index");
576 return fgExtendedFontStart;
582 Int_t TGLFontManager::GetFontSize(Int_t ds)
584 if (fgStaticInitDone == kFALSE) InitStatics();
586 Int_t idx = TMath::BinarySearch(fgFontSizeArray.size(), &fgFontSizeArray[0],
587 TMath::CeilNint(ds));
589 if (idx < 0) idx = 0;
590 return fgFontSizeArray[idx];
596 Int_t TGLFontManager::GetFontSize(Int_t ds, Int_t min, Int_t max)
598 if (ds < min) ds = min;
599 if (ds > max) ds = max;
600 return GetFontSize(ds);
606 const char* TGLFontManager::GetFontNameFromId(Int_t
id)
608 if (fgStaticInitDone == kFALSE) InitStatics();
610 Int_t fontIndex =
id / 10;
612 if (fontIndex > fgFontFileArray.GetEntries() || !fontIndex)
617 TObjString* os = (TObjString*)fgFontFileArray[fontIndex];
618 return os->String().Data();
624 void TGLFontManager::InitStatics()
626 fgFontFileArray.Add(
new TObjString(
"timesi"));
627 fgFontFileArray.Add(
new TObjString(
"timesbd"));
628 fgFontFileArray.Add(
new TObjString(
"timesbi"));
630 fgFontFileArray.Add(
new TObjString(
"arial"));
631 fgFontFileArray.Add(
new TObjString(
"ariali"));
632 fgFontFileArray.Add(
new TObjString(
"arialbd"));
633 fgFontFileArray.Add(
new TObjString(
"arialbi"));
635 fgFontFileArray.Add(
new TObjString(
"cour"));
636 fgFontFileArray.Add(
new TObjString(
"couri"));
637 fgFontFileArray.Add(
new TObjString(
"courbd"));
638 fgFontFileArray.Add(
new TObjString(
"courbi"));
640 fgFontFileArray.Add(
new TObjString(
"symbol"));
641 fgFontFileArray.Add(
new TObjString(
"times"));
642 fgFontFileArray.Add(
new TObjString(
"wingding"));
643 fgFontFileArray.Add(
new TObjString(
"symbol"));
645 fgExtendedFontStart = fgFontFileArray.GetEntries();
648 fgFontFileArray.Add(
new TObjString(
"FreeSerifItalic.otf"));
649 fgFontFileArray.Add(
new TObjString(
"FreeSerifBold.otf"));
650 fgFontFileArray.Add(
new TObjString(
"FreeSerifBoldItalic.otf"));
652 fgFontFileArray.Add(
new TObjString(
"FreeSans.otf"));
653 fgFontFileArray.Add(
new TObjString(
"FreeSansOblique.otf"));
654 fgFontFileArray.Add(
new TObjString(
"FreeSansBold.otf"));
655 fgFontFileArray.Add(
new TObjString(
"FreeSansBoldOblique.otf"));
657 fgFontFileArray.Add(
new TObjString(
"FreeMono.otf"));
658 fgFontFileArray.Add(
new TObjString(
"FreeMonoOblique.otf"));
659 fgFontFileArray.Add(
new TObjString(
"FreeMonoBold.otf"));
660 fgFontFileArray.Add(
new TObjString(
"FreeMonoBoldOblique.otf"));
662 fgFontFileArray.Add(
new TObjString(
"symbol.ttf"));
663 fgFontFileArray.Add(
new TObjString(
"FreeSerif.otf"));
664 fgFontFileArray.Add(
new TObjString(
"wingding.ttf"));
665 fgFontFileArray.Add(
new TObjString(
"symbol.ttf"));
667 fgFontFileArray.Add(
new TObjString(
"STIXGeneral.otf"));
668 fgFontFileArray.Add(
new TObjString(
"STIXGeneralItalic.otf"));
669 fgFontFileArray.Add(
new TObjString(
"STIXGeneralBol.otf"));
670 fgFontFileArray.Add(
new TObjString(
"STIXGeneralBolIta.otf"));
672 fgFontFileArray.Add(
new TObjString(
"STIXSiz1Sym.otf"));
673 fgFontFileArray.Add(
new TObjString(
"STIXSiz1SymBol.otf"));
674 fgFontFileArray.Add(
new TObjString(
"STIXSiz2Sym.otf"));
675 fgFontFileArray.Add(
new TObjString(
"STIXSiz2SymBol.otf"));
677 fgFontFileArray.Add(
new TObjString(
"STIXSiz3Sym.otf"));
678 fgFontFileArray.Add(
new TObjString(
"STIXSiz3SymBol.otf"));
679 fgFontFileArray.Add(
new TObjString(
"STIXSiz4Sym.otf"));
680 fgFontFileArray.Add(
new TObjString(
"STIXSiz4SymBol.otf"));
682 fgFontFileArray.Add(
new TObjString(
"STIXSiz5Sym.otf"));
683 fgFontFileArray.Add(
new TObjString(
"DroidSansFallback.ttf"));
684 fgFontFileArray.Add(
new TObjString(
"DroidSansFallback.ttf"));
685 fgFontFileArray.Add(
new TObjString(
"DroidSansFallback.ttf"));
687 for (Int_t i = 10; i <= 20; i+=2)
688 fgFontSizeArray.push_back(i);
689 for (Int_t i = 24; i <= 64; i+=4)
690 fgFontSizeArray.push_back(i);
691 for (Int_t i = 72; i <= 128; i+=8)
692 fgFontSizeArray.push_back(i);
694 fgStaticInitDone = kTRUE;
700 void TGLFontManager::ClearFontTrash()
702 FontList_i it = fFontTrash.begin();
703 while (it != fFontTrash.end())
705 if ((*it)->IncTrashCount() > 10000)
707 FontMap_i mi = fFontMap.find(**it);
708 assert(mi != fFontMap.end());
710 delete (*it)->GetFont();
712 FontList_i li = it++;
713 fFontTrash.erase(li);