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.
|
2014-01-20 00:52:40 +00:00
|
|
|
// txf_load_fonts and txf_render_string,
|
|
|
|
// with extra options on the latter for rotating etc
|
2010-12-08 23:06:07 +00:00
|
|
|
|
2012-08-02 06:53:11 +00:00
|
|
|
// originally adapted by Carl Christensen
|
2010-12-08 23:06:07 +00:00
|
|
|
|
2020-06-04 08:24:49 +00:00
|
|
|
#ifdef _WIN32
|
2012-08-03 02:02:05 +00:00
|
|
|
#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
|
2014-01-20 00:52:40 +00:00
|
|
|
//
|
2023-05-05 18:05:20 +00:00
|
|
|
namespace TTFont {
|
2010-12-08 23:06:07 +00:00
|
|
|
|
2023-05-05 18:05:20 +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
|
2012-08-02 06:53:11 +00:00
|
|
|
// download the license and fonts from
|
|
|
|
// https://fedorahosted.org/liberation-fonts
|
|
|
|
//
|
2023-05-05 18:05:20 +00:00
|
|
|
// Another source of free fonts is the GNU FreeFont project
|
2012-08-02 06:53:11 +00:00
|
|
|
// at http://www.gnu.org/software/freefont
|
2010-12-08 23:06:07 +00:00
|
|
|
|
2023-05-05 18:05:20 +00:00
|
|
|
// you'll want to define a 2-d array of char as appropriate for your
|
2010-12-08 23:06:07 +00:00
|
|
|
// truetype font filenames (path is set in the call to ttf_load_fonts)
|
2014-01-20 00:52:40 +00:00
|
|
|
//
|
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
|
|
|
|
};
|
2023-05-05 18:05:20 +00:00
|
|
|
|
2012-08-02 06:53:11 +00:00
|
|
|
// 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
|
|
|
|
2014-01-20 00:52:40 +00:00
|
|
|
// Load fonts. call once.
|
|
|
|
// Pass in the font directory (normally the project directory:
|
|
|
|
// APP_INIT_DATA::project_dir for BOINC apps),
|
|
|
|
// 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)
|
|
|
|
//
|
|
|
|
void ttf_load_fonts(
|
|
|
|
const char* dir, const char* strScaleFont, const int& iScaleFont
|
|
|
|
) {
|
|
|
|
static bool bInit = false;
|
|
|
|
// flag so we don't call again, otherwise we'll have memory leaks
|
|
|
|
// each subsequent call to new FTTextureFont etc
|
2012-08-02 06:53:11 +00:00
|
|
|
if (bInit) return; // we've already been here
|
|
|
|
bInit = true; // we're in now!
|
|
|
|
ttf_cleanup();
|
2014-01-20 00:52:40 +00:00
|
|
|
memset(g_font, 0x00, sizeof(FTFont*) * NUM_FONT);
|
|
|
|
// initialize to null's for error checking later
|
2012-08-02 06:53:11 +00:00
|
|
|
char vpath[MAXPATHLEN];
|
|
|
|
g_iFont = -1;
|
|
|
|
for (unsigned int i=0 ; i < NUM_FONT; i++){
|
2022-08-03 09:21:59 +00:00
|
|
|
snprintf(vpath, sizeof(vpath), "%s/%s", dir, g_cstrFont[i]);
|
2012-08-02 06:53:11 +00:00
|
|
|
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;
|
2014-01-20 00:52:40 +00:00
|
|
|
if(!g_font[i]->FaceSize(iScale)) {
|
2012-08-02 06:53:11 +00:00
|
|
|
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
|
2014-01-20 00:52:40 +00:00
|
|
|
else {
|
2012-08-02 06:53:11 +00:00
|
|
|
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
|
|
|
}
|
2023-05-05 18:05:20 +00:00
|
|
|
}
|
2010-12-08 23:06:07 +00:00
|
|
|
}
|
|
|
|
|
2014-01-20 00:52:40 +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
|
2014-01-20 00:52:40 +00:00
|
|
|
) {
|
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
|
|
|
|
|
|
|
|
|