2010-12-08 23:07:07 +00:00
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2010 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// BOINC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
2010-12-08 23:06:07 +00:00
// utility functions for TrueType font OpenGL graphics
// FTGL OpenGL TrueType/FreeType font rendering
// you will need to build & link against freetype2 and ftgl
2012-08-02 06:53:11 +00:00
// tested using ftgl version 2.1.3 rc5 and freetype version 2.4.10
2010-12-08 23:06:07 +00:00
// ftgl library: http://sourceforge.net/projects/ftgl/files/FTGL%20Source/
// freetype2 library: http://www.freetype.org/
// this should basically be a drop-in for the old boinc txf_* functions i.e.
// txf_load_fonts and txf_render_string, with extra options on the latter for rotating etc
2012-08-02 06:53:11 +00:00
// originally adapted by Carl Christensen
2010-12-08 23:06:07 +00:00
2012-08-03 02:02:05 +00:00
# if defined(_WIN32) && !defined(__STDWX_H__) && !defined(_BOINC_WIN_) && !defined(_AFX_STDAFX_H_)
# include "boinc_win.h"
# endif
2012-08-03 01:18:20 +00:00
# include "boinc_gl.h"
# include <FTGL/ftgl.h>
2010-12-08 23:06:07 +00:00
# include "ttfont.h"
# include "filesys.h" // from boinc for file_exists
// I put in it's own namespace so call TTFont::ttf_load_fonts() etc
namespace TTFont {
2012-08-02 06:53:11 +00:00
// The Liberation version 2.00.0 fonts referenced below are free
// fonts under the SIL Open Font License version 1.1. You can
// download the license and fonts from
// https://fedorahosted.org/liberation-fonts
//
// Another source of free fonts is the GNU FreeFont project
// at http://www.gnu.org/software/freefont
2010-12-08 23:06:07 +00:00
// you'll want to define a 2-d array of char as appropriate for your
// truetype font filenames (path is set in the call to ttf_load_fonts)
2012-08-02 06:53:11 +00:00
static const char * g_cstrFont [ ] = {
" LiberationSans-Regular.ttf " , // 0, this is the default
" LiberationSans-Bold.ttf " , // 1
" LiberationSans-Italic.ttf " , // 2
" LiberationSans-BoldItalic.ttf " , // 3
" LiberationSerif-Regular.ttf " , // 4
" LiberationSerif-Bold.ttf " , // 5
" LiberationSerif-Italic.ttf " , // 6
" LiberationSerif-BoldItalic.ttf " , // 7
" LiberationMono-Regular.ttf " , // 8
" LiberationMono-Bold.ttf " , // 9
" LiberationMono-Italic.ttf " , // 10
" LiberationMono-BoldItalic.ttf " // 11
} ;
// define the number of fonts supported
# define NUM_FONT (sizeof(g_cstrFont) / sizeof(char*))
FTFont * g_font [ NUM_FONT ] ;
int g_iFont = - 1 ;
2010-12-08 23:06:07 +00:00
// load fonts. call once.
2012-08-02 06:53:11 +00:00
// pass in the font directory, and any special-scaling font name & size (e.g. if I want a huge typeface for Sans-Serif Regular then I pass in "LiberationSans-Regular.ttf", 3000)
2010-12-08 23:06:07 +00:00
void ttf_load_fonts ( const char * dir , const char * strScaleFont , const int & iScaleFont ) {
2012-08-02 06:53:11 +00:00
static bool bInit = false ; // flag so we don't call again, otherwise we'll have memory leaks each subsequent call to new FTTextureFont etc
if ( bInit ) return ; // we've already been here
bInit = true ; // we're in now!
ttf_cleanup ( ) ;
memset ( g_font , 0x00 , sizeof ( FTFont * ) * NUM_FONT ) ; // initialize to null's for error checking later
char vpath [ MAXPATHLEN ] ;
g_iFont = - 1 ;
for ( unsigned int i = 0 ; i < NUM_FONT ; i + + ) {
sprintf ( vpath , " %s/%s " , dir , g_cstrFont [ i ] ) ;
if ( boinc_file_exists ( vpath ) ) {
//g_font[i] = new FTBitmapFont(vpath);
//g_font[i] = new FTPixmapFont(vpath);
//g_font[i] = new FTPolygonFont(vpath);
g_font [ i ] = new FTTextureFont ( vpath ) ;
if ( ! g_font [ i ] - > Error ( ) ) {
2010-12-08 23:06:07 +00:00
# ifdef _DEBUG
fprintf ( stderr , " Successfully loaded '%s'... \n " , vpath ) ;
# endif
2012-08-02 06:53:11 +00:00
int iScale = 30 ;
if ( strScaleFont & & ! strcmp ( strScaleFont , g_cstrFont [ i ] ) ) iScale = iScaleFont ;
if ( ! g_font [ i ] - > FaceSize ( iScale ) )
{
fprintf ( stderr , " Failed to set size " ) ;
}
2010-12-08 23:06:07 +00:00
2012-08-02 06:53:11 +00:00
g_font [ i ] - > Depth ( 3. ) ;
g_font [ i ] - > Outset ( - .5f , 1.5f ) ;
2010-12-08 23:06:07 +00:00
2012-08-02 06:53:11 +00:00
g_font [ i ] - > CharMap ( ft_encoding_unicode ) ;
g_iFont = i ;
2010-12-08 23:06:07 +00:00
2012-08-02 06:53:11 +00:00
}
2010-12-08 23:06:07 +00:00
# ifdef _DEBUG
2012-08-02 06:53:11 +00:00
else {
fprintf ( stderr , " Failed to load '%s'... \n " , vpath ) ;
}
2010-12-08 23:06:07 +00:00
# endif
2012-08-02 06:53:11 +00:00
}
2010-12-08 23:06:07 +00:00
}
}
// remove our objects?
void ttf_cleanup ( )
{
2012-08-02 06:53:11 +00:00
for ( unsigned int i = 0 ; i < NUM_FONT ; i + + ) {
if ( g_font [ i ] ) {
delete g_font [ i ] ;
g_font [ i ] = NULL ;
}
}
2010-12-08 23:06:07 +00:00
}
void ttf_render_string (
2012-08-02 06:53:11 +00:00
const double & x ,
const double & y ,
const double & z , // text position
const float & fscale , // scale factor
const GLfloat * col , // colour 4vf
const char * s , // string ptr
const int & iFont , // font index
const float & fRotAngle , // optional rotation angle
const float & fRotX , // optional rotation vector for X
const float & fRotY , // optional rotation vector for Y
const float & fRotZ , // optional rotation vector for Z
const float & fRadius // circular radius to draw along
2010-12-08 23:06:07 +00:00
)
{
// http://ftgl.sourceforge.net/docs/html/
2012-08-02 06:53:11 +00:00
// if requested font isn't available, find first one that is
//
unsigned int theFont = iFont ;
while ( ( theFont < NUM_FONT ) & & ! g_font [ theFont ] ) theFont + + ;
if ( ( theFont > = NUM_FONT ) | | ! g_font [ theFont ] ) {
// bad font index
return ;
}
int renderMode = FTGL : : RENDER_FRONT ; //ALL; //FRONT | FTGL::FTGL_RENDER_BACK;
glColor4fv ( col ) ;
glPushMatrix ( ) ;
glTranslated ( x , y , z ) ;
glScaled ( 1.0f / fscale , 1.0f / fscale , 1.0f / fscale ) ;
glEnable ( GL_TEXTURE_2D ) ;
if ( fRotAngle ! = 0.0f ) {
glRotatef ( fRotAngle , fRotX , fRotY , fRotZ ) ;
}
if ( fRadius = = 0.0f ) {
g_font [ theFont ] - > Render ( s , - 1 , FTPoint ( ) , FTPoint ( ) , renderMode ) ;
}
else {
int i = 0 ;
float fAdvance = 1.0f ;
while ( * ( s + i ) ) {
fAdvance = g_font [ theFont ] - > Advance ( ( s + i ) , 1 , FTPoint ( ) ) ;
g_font [ theFont ] - > Render ( ( s + i ) , 1 , FTPoint ( ) , FTPoint ( ) , renderMode ) ;
glTranslated ( fAdvance , 0.0f , 0.0f ) ;
glRotatef ( fRadius * fAdvance / ( float ) 20.0f , 0.0f , 0.0f , 1.0f ) ;
i + + ;
2010-12-08 23:06:07 +00:00
}
2012-08-02 06:53:11 +00:00
}
2010-12-08 23:06:07 +00:00
2012-08-02 06:53:11 +00:00
glDisable ( GL_TEXTURE_2D ) ;
2010-12-08 23:06:07 +00:00
2012-08-02 06:53:11 +00:00
glPopMatrix ( ) ;
2010-12-08 23:06:07 +00:00
}
} // namespace