ROOT logo
// @(#)root/gl:$Id$
// Author:  Olivier Couet  12/04/2007

/*************************************************************************
 * Copyright (C) 1995-2006, 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 "TROOT.h"
#include "TError.h"

#include "TGLText.h"
#include "TGLUtil.h"
#include "TColor.h"
#include "TSystem.h"
#include "TEnv.h"
#include "TGLIncludes.h"

// Direct inclussion of FTGL headers is deprecated in ftgl-2.1.3 while
// ftgl-2.1.2 shipped with ROOT requires manual inclusion.
#ifndef BUILTIN_FTGL
# include <FTGL/FTFont.h>
# include <FTGL/FTGLExtrdFont.h>
# include <FTGL/FTGLOutlineFont.h>
# include <FTGL/FTGLPolygonFont.h>
# include <FTGL/FTGLTextureFont.h>
# include <FTGL/FTGLPixmapFont.h>
# include <FTGL/FTGLBitmapFont.h>
#else
# include "FTFont.h"
# include "FTGLExtrdFont.h"
# include "FTGLOutlineFont.h"
# include "FTGLPolygonFont.h"
# include "FTGLTextureFont.h"
# include "FTGLPixmapFont.h"
# include "FTGLBitmapFont.h"
#endif

#include <fontconfig/fontconfig.h>

#define FTGL_BITMAP  0
#define FTGL_PIXMAP  1
#define FTGL_OUTLINE 2
#define FTGL_POLYGON 3
#define FTGL_EXTRUDE 4
#define FTGL_TEXTURE 5

//______________________________________________________________________________
/* Begin_Html
<center><h2>GL Text</h2></center>
To draw a 3D text in a GL window. This class uses uses FTGL to render text.
FTGL is a package making the interface between the Free Type fonts and GL.
End_Html */

ClassImp(TGLText)

//______________________________________________________________________________
TGLText::TGLText()
{
   fX      = 0;
   fY      = 0;
   fZ      = 0;
   fAngle1 = 90;
   fAngle2 = 0;
   fAngle3 = 0;
   fGLTextFont = 0;
   SetGLTextFont(13); // Default font.
}


//______________________________________________________________________________
TGLText::TGLText(Double_t x, Double_t y, Double_t z, const char * /*text*/)
{
   // TGLext normal constructor.

   fX      = x;
   fY      = y;
   fZ      = z;
   fAngle1 = 90;
   fAngle2 = 0;
   fAngle3 = 0;
   fGLTextFont = 0;
   SetGLTextFont(13); // Default font.
}


//______________________________________________________________________________
TGLText::~TGLText()
{
   if (fGLTextFont) delete fGLTextFont;
}


//______________________________________________________________________________
void TGLText::PaintGLText(Double_t x, Double_t y, Double_t z, const char *text)
{
   // Draw text

   if (!fGLTextFont) return;

   glPushMatrix();
   glTranslatef(x, y, z);

   TGLUtil::Color(GetTextColor());
   Double_t s = GetTextSize();
   glScalef(s,s,s);

   // Text alignment
   Float_t llx, lly, llz, urx, ury, urz;
   fGLTextFont->BBox(text, llx, lly, llz, urx, ury, urz);
   Short_t halign = fTextAlign/10;
   Short_t valign = fTextAlign - 10*halign;
   Float_t dx = 0, dy = 0;
   switch (halign) {
      case 1 : dx =  0    ; break;
      case 2 : dx = -urx/2; break;
      case 3 : dx = -urx  ; break;
   }
   switch (valign) {
      case 1 : dy =  0    ; break;
      case 2 : dy = -ury/2; break;
      case 3 : dy = -ury  ; break;
   }
   glTranslatef(dx, dy, 0);

   //In XY plane
   glRotatef(fAngle1,1.,0.,0.);

   //In XZ plane
   glRotatef(fAngle2,0.,1.,0.);

   //In YZ plane
   glRotatef(fAngle3,0.,0.,1.);

   // Render text
   fGLTextFont->Render(text);

   glPopMatrix();
}


//______________________________________________________________________________
void TGLText::PaintBBox(const char *text)
{
   Float_t llx, lly, llz, urx, ury, urz;
   fGLTextFont->BBox(text, llx, lly, llz, urx, ury, urz);
   glBegin(GL_LINES);
   glVertex3f(   0,   0, 0); glVertex3f( urx,   0, 0);
   glVertex3f(   0,   0, 0); glVertex3f(   0, ury, 0);
   glVertex3f(   0, ury, 0); glVertex3f( urx, ury, 0);
   glVertex3f( urx, ury, 0); glVertex3f( urx,   0, 0);
   glEnd();
}

//______________________________________________________________________________
void TGLText::BBox(const char* string, float& llx, float& lly, float& llz,
                                       float& urx, float& ury, float& urz)
{
   // Calculate bounding-box for given string.

   fGLTextFont->BBox(string, llx, lly, llz, urx, ury, urz);
}

//______________________________________________________________________________
void TGLText::SetGLTextAngles(Double_t a1, Double_t a2, Double_t a3)
{
   // Set the text rotation angles.

   fAngle1 = a1;
   fAngle2 = a2;
   fAngle3 = a3;
}


//______________________________________________________________________________
void TGLText::SetGLTextFont(Font_t fontnumber)
{
   int fontid = fontnumber / 10;

   FcPattern *pat, *match;
   FcResult result;
   char *ttfont;
   int ttindex;

   pat = FcPatternCreate ();

   switch (fontid) {
   case 1:
      FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freeserif");
      FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
      FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ITALIC);
      break;
   case 2:
      FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freeserif");
      FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
      FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
      break;
   case 3:
      FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freeserif");
      FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
      FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ITALIC);
      break;
   case 4:
      FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freesans");
      FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
      FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
      break;
   case 5:
      FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freesans");
      FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
      FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ITALIC);
      break;
   case 0:
   case 6:
      FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freesans");
      FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
      FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
      break;
   case 7:
      FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freesans");
      FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
      FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ITALIC);
      break;
   case 8:
      FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freemono");
      FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
      FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
      break;
   case 9:
      FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freemono");
      FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
      FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ITALIC);
      break;
   case 10:
      FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freemono");
      FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
      FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
      break;
   case 11:
      FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freemono");
      FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
      FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ITALIC);
      break;
   case 12:
      FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"symbol");
      FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
      FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
      break;
   case 13:
      FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"freeserif");
      FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
      FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
      break;
   case 14:
      FcPatternAddString (pat, FC_FAMILY, (const FcChar8*)"dingbats");
      FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
      FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ROMAN);
      break;
   }

   FcConfigSubstitute (NULL, pat, FcMatchPattern);
   FcDefaultSubstitute (pat);
   match = FcFontMatch (NULL, pat, &result);
   FcPatternGetString (match, FC_FILE, 0, (FcChar8**)&ttfont);
   FcPatternGetInteger (match, FC_INDEX, 0, &ttindex);

   if (fGLTextFont) delete fGLTextFont;

// fGLTextFont = new FTGLOutlineFont(ttfont);

   fGLTextFont = new FTGLPolygonFont(ttfont);

   FcPatternDestroy (match);
   FcPatternDestroy (pat);

   if (!fGLTextFont->FaceSize(1))
      Error("SetGLTextFont","Cannot set FTGL::FaceSize");
}
 TGLText.cxx:1
 TGLText.cxx:2
 TGLText.cxx:3
 TGLText.cxx:4
 TGLText.cxx:5
 TGLText.cxx:6
 TGLText.cxx:7
 TGLText.cxx:8
 TGLText.cxx:9
 TGLText.cxx:10
 TGLText.cxx:11
 TGLText.cxx:12
 TGLText.cxx:13
 TGLText.cxx:14
 TGLText.cxx:15
 TGLText.cxx:16
 TGLText.cxx:17
 TGLText.cxx:18
 TGLText.cxx:19
 TGLText.cxx:20
 TGLText.cxx:21
 TGLText.cxx:22
 TGLText.cxx:23
 TGLText.cxx:24
 TGLText.cxx:25
 TGLText.cxx:26
 TGLText.cxx:27
 TGLText.cxx:28
 TGLText.cxx:29
 TGLText.cxx:30
 TGLText.cxx:31
 TGLText.cxx:32
 TGLText.cxx:33
 TGLText.cxx:34
 TGLText.cxx:35
 TGLText.cxx:36
 TGLText.cxx:37
 TGLText.cxx:38
 TGLText.cxx:39
 TGLText.cxx:40
 TGLText.cxx:41
 TGLText.cxx:42
 TGLText.cxx:43
 TGLText.cxx:44
 TGLText.cxx:45
 TGLText.cxx:46
 TGLText.cxx:47
 TGLText.cxx:48
 TGLText.cxx:49
 TGLText.cxx:50
 TGLText.cxx:51
 TGLText.cxx:52
 TGLText.cxx:53
 TGLText.cxx:54
 TGLText.cxx:55
 TGLText.cxx:56
 TGLText.cxx:57
 TGLText.cxx:58
 TGLText.cxx:59
 TGLText.cxx:60
 TGLText.cxx:61
 TGLText.cxx:62
 TGLText.cxx:63
 TGLText.cxx:64
 TGLText.cxx:65
 TGLText.cxx:66
 TGLText.cxx:67
 TGLText.cxx:68
 TGLText.cxx:69
 TGLText.cxx:70
 TGLText.cxx:71
 TGLText.cxx:72
 TGLText.cxx:73
 TGLText.cxx:74
 TGLText.cxx:75
 TGLText.cxx:76
 TGLText.cxx:77
 TGLText.cxx:78
 TGLText.cxx:79
 TGLText.cxx:80
 TGLText.cxx:81
 TGLText.cxx:82
 TGLText.cxx:83
 TGLText.cxx:84
 TGLText.cxx:85
 TGLText.cxx:86
 TGLText.cxx:87
 TGLText.cxx:88
 TGLText.cxx:89
 TGLText.cxx:90
 TGLText.cxx:91
 TGLText.cxx:92
 TGLText.cxx:93
 TGLText.cxx:94
 TGLText.cxx:95
 TGLText.cxx:96
 TGLText.cxx:97
 TGLText.cxx:98
 TGLText.cxx:99
 TGLText.cxx:100
 TGLText.cxx:101
 TGLText.cxx:102
 TGLText.cxx:103
 TGLText.cxx:104
 TGLText.cxx:105
 TGLText.cxx:106
 TGLText.cxx:107
 TGLText.cxx:108
 TGLText.cxx:109
 TGLText.cxx:110
 TGLText.cxx:111
 TGLText.cxx:112
 TGLText.cxx:113
 TGLText.cxx:114
 TGLText.cxx:115
 TGLText.cxx:116
 TGLText.cxx:117
 TGLText.cxx:118
 TGLText.cxx:119
 TGLText.cxx:120
 TGLText.cxx:121
 TGLText.cxx:122
 TGLText.cxx:123
 TGLText.cxx:124
 TGLText.cxx:125
 TGLText.cxx:126
 TGLText.cxx:127
 TGLText.cxx:128
 TGLText.cxx:129
 TGLText.cxx:130
 TGLText.cxx:131
 TGLText.cxx:132
 TGLText.cxx:133
 TGLText.cxx:134
 TGLText.cxx:135
 TGLText.cxx:136
 TGLText.cxx:137
 TGLText.cxx:138
 TGLText.cxx:139
 TGLText.cxx:140
 TGLText.cxx:141
 TGLText.cxx:142
 TGLText.cxx:143
 TGLText.cxx:144
 TGLText.cxx:145
 TGLText.cxx:146
 TGLText.cxx:147
 TGLText.cxx:148
 TGLText.cxx:149
 TGLText.cxx:150
 TGLText.cxx:151
 TGLText.cxx:152
 TGLText.cxx:153
 TGLText.cxx:154
 TGLText.cxx:155
 TGLText.cxx:156
 TGLText.cxx:157
 TGLText.cxx:158
 TGLText.cxx:159
 TGLText.cxx:160
 TGLText.cxx:161
 TGLText.cxx:162
 TGLText.cxx:163
 TGLText.cxx:164
 TGLText.cxx:165
 TGLText.cxx:166
 TGLText.cxx:167
 TGLText.cxx:168
 TGLText.cxx:169
 TGLText.cxx:170
 TGLText.cxx:171
 TGLText.cxx:172
 TGLText.cxx:173
 TGLText.cxx:174
 TGLText.cxx:175
 TGLText.cxx:176
 TGLText.cxx:177
 TGLText.cxx:178
 TGLText.cxx:179
 TGLText.cxx:180
 TGLText.cxx:181
 TGLText.cxx:182
 TGLText.cxx:183
 TGLText.cxx:184
 TGLText.cxx:185
 TGLText.cxx:186
 TGLText.cxx:187
 TGLText.cxx:188
 TGLText.cxx:189
 TGLText.cxx:190
 TGLText.cxx:191
 TGLText.cxx:192
 TGLText.cxx:193
 TGLText.cxx:194
 TGLText.cxx:195
 TGLText.cxx:196
 TGLText.cxx:197
 TGLText.cxx:198
 TGLText.cxx:199
 TGLText.cxx:200
 TGLText.cxx:201
 TGLText.cxx:202
 TGLText.cxx:203
 TGLText.cxx:204
 TGLText.cxx:205
 TGLText.cxx:206
 TGLText.cxx:207
 TGLText.cxx:208
 TGLText.cxx:209
 TGLText.cxx:210
 TGLText.cxx:211
 TGLText.cxx:212
 TGLText.cxx:213
 TGLText.cxx:214
 TGLText.cxx:215
 TGLText.cxx:216
 TGLText.cxx:217
 TGLText.cxx:218
 TGLText.cxx:219
 TGLText.cxx:220
 TGLText.cxx:221
 TGLText.cxx:222
 TGLText.cxx:223
 TGLText.cxx:224
 TGLText.cxx:225
 TGLText.cxx:226
 TGLText.cxx:227
 TGLText.cxx:228
 TGLText.cxx:229
 TGLText.cxx:230
 TGLText.cxx:231
 TGLText.cxx:232
 TGLText.cxx:233
 TGLText.cxx:234
 TGLText.cxx:235
 TGLText.cxx:236
 TGLText.cxx:237
 TGLText.cxx:238
 TGLText.cxx:239
 TGLText.cxx:240
 TGLText.cxx:241
 TGLText.cxx:242
 TGLText.cxx:243
 TGLText.cxx:244
 TGLText.cxx:245
 TGLText.cxx:246
 TGLText.cxx:247
 TGLText.cxx:248
 TGLText.cxx:249
 TGLText.cxx:250
 TGLText.cxx:251
 TGLText.cxx:252
 TGLText.cxx:253
 TGLText.cxx:254
 TGLText.cxx:255
 TGLText.cxx:256
 TGLText.cxx:257
 TGLText.cxx:258
 TGLText.cxx:259
 TGLText.cxx:260
 TGLText.cxx:261
 TGLText.cxx:262
 TGLText.cxx:263
 TGLText.cxx:264
 TGLText.cxx:265
 TGLText.cxx:266
 TGLText.cxx:267
 TGLText.cxx:268
 TGLText.cxx:269
 TGLText.cxx:270
 TGLText.cxx:271
 TGLText.cxx:272
 TGLText.cxx:273
 TGLText.cxx:274
 TGLText.cxx:275
 TGLText.cxx:276
 TGLText.cxx:277
 TGLText.cxx:278
 TGLText.cxx:279
 TGLText.cxx:280
 TGLText.cxx:281
 TGLText.cxx:282