4
* Copyright (C) 2014 Washington University School of Medicine
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License along
17
* with this program; if not, write to the Free Software Foundation, Inc.,
18
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
/****************************************************************************
23
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
24
** Contact: http://www.qt-project.org/legal
26
** This file is part of the QtOpenGL module of the Qt Toolkit.
28
** $QT_BEGIN_LICENSE:LGPL$
29
** Commercial License Usage
30
** Licensees holding valid commercial Qt licenses may use this file in
31
** accordance with the commercial license agreement provided with the
32
** Software or, alternatively, in accordance with the terms contained in
33
** a written agreement between you and Digia. For licensing terms and
34
** conditions see http://qt.digia.com/licensing. For further information
35
** use the contact form at http://qt.digia.com/contact-us.
37
** GNU Lesser General Public License Usage
38
** Alternatively, this file may be used under the terms of the GNU Lesser
39
** General Public License version 2.1 as published by the Free Software
40
** Foundation and appearing in the file LICENSE.LGPL included in the
41
** packaging of this file. Please review the following information to
42
** ensure the GNU Lesser General Public License version 2.1 requirements
43
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
45
** In addition, as a special exception, Digia gives you certain additional
46
** rights. These rights are described in the Digia Qt LGPL Exception
47
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
49
** GNU General Public License Usage
50
** Alternatively, this file may be used under the terms of the GNU
51
** General Public License version 3.0 as published by the Free Software
52
** Foundation and appearing in the file LICENSE.GPL included in the
53
** packaging of this file. Please review the following information to
54
** ensure the GNU General Public License version 3.0 requirements will be
55
** met: http://www.gnu.org/copyleft/gpl.html.
60
****************************************************************************/
62
#define __FTGL_FONT_TEXT_RENDERER_DECLARE__
63
#include "FtglFontTextRenderer.h"
64
#undef __FTGL_FONT_TEXT_RENDERER_DECLARE__
68
#include "CaretAssert.h"
69
#include "CaretLogger.h"
70
#include "CaretOpenGLInclude.h"
73
#include <FtglConfig.h>
74
#include <FTGL/ftgl.h>
76
#endif // HAVE_FREETYPE
78
using namespace caret;
83
* \class caret::FtglFontTextRenderer
84
* \brief Text rendering using QGLWidget.
86
* Draws text using methods in QGLWidget.
89
* QGLWidget that does the text rendering.
94
FtglFontTextRenderer::FtglFontTextRenderer()
95
: BrainOpenGLTextRenderInterface()
98
m_boldFont.initialize(":/FtglFonts/VeraBd.ttf");
99
m_normalFont.initialize(":/FtglFonts/VeraSe.ttf");
100
#endif // HAVE_FREETYPE
106
FtglFontTextRenderer::~FtglFontTextRenderer()
109
#endif // HAVE_FREETYPE
113
* @return The font system is valid.
116
FtglFontTextRenderer::isValid() const
118
return m_normalFont.m_valid;
122
* Get the font with the given style and height.
123
* Returned font not guaranteed to be desired size.
128
* Height of the font.
130
* The font. May be NULL due to
133
FtglFontTextRenderer::getFont(const TextStyle textStyle,
134
const int fontHeight)
137
FTPixmapFont* pixmapFont = NULL;
139
case BrainOpenGLTextRenderInterface::BOLD:
140
if (m_boldFont.m_valid) {
141
pixmapFont = m_boldFont.m_pixmapFont;
144
case BrainOpenGLTextRenderInterface::NORMAL:
145
if (m_normalFont.m_valid) {
146
pixmapFont = m_normalFont.m_pixmapFont;
151
if (pixmapFont != NULL) {
152
if ( ! pixmapFont->FaceSize(fontHeight)) {
153
QString msg("Failed to set requested font height="
154
+ AString::number(fontHeight)
156
if (pixmapFont->FaceSize(14)) {
157
msg += " Defaulting to font height=14";
160
msg += " Defaulting to font height=14 also failed.";
162
CaretLogWarning(msg);
168
CaretLogSevere("Trying to use FTGL Font rendering but font is not valid.");
170
#else // HAVE_FREETYPE
172
#endif // HAVE_FREETYPE
176
* Draw text at the given window coordinates.
179
* The current viewport.
181
* X-coordinate in the window of first text character
182
* using the 'alignment'
184
* Y-coordinate in the window at which bottom of text is placed.
186
* Text that is to be drawn.
192
* Height of the text.
195
FtglFontTextRenderer::drawTextAtWindowCoords(const int viewport[4],
199
const TextAlignmentX alignmentX,
200
const TextAlignmentY alignmentY,
201
const TextStyle textStyle,
202
const int fontHeight)
204
if (text.isEmpty()) {
209
FTPixmapFont* pixmapFont = getFont(textStyle, fontHeight);
217
* Disable depth testing so text not occluded
219
glDisable(GL_DEPTH_TEST);
224
* Set the orthographic projection so that its origin is in the bottom
225
* left corner. It needs to be there since we are drawing in window
226
* coordinates. We do not know the true size of the window but that
227
* is okay since we can set the orthographic view so that the bottom
228
* left corner is the origin and the top right corner is the top
229
* right corner of the user's viewport.
231
glMatrixMode(GL_PROJECTION);
241
* Viewing projection is just the identity matrix since
242
* we are drawing in window coordinates.
244
glMatrixMode(GL_MODELVIEW);
247
const bool drawCrosshairsAtFontStartingCoordinate = false;
248
if (drawCrosshairsAtFontStartingCoordinate) {
249
GLfloat savedRGBA[4];
250
glGetFloatv(GL_CURRENT_COLOR, savedRGBA);
251
glColor3f(0.0, 0.0, 0.0);
254
glTranslatef(windowX, windowY, 0.0);
262
glColor3f(savedRGBA[0], savedRGBA[1], savedRGBA[2]);
265
const FTBBox bbox = pixmapFont->BBox(text.toAscii().constData());
266
const FTPoint lower = bbox.Lower();
267
const FTPoint upper = bbox.Upper();
269
float textOffsetX = 0;
270
switch (alignmentX) {
271
case BrainOpenGLTextRenderInterface::X_CENTER:
272
textOffsetX = -((upper.X() - lower.X()) / 2.0);
274
case BrainOpenGLTextRenderInterface::X_LEFT:
275
textOffsetX = -lower.X();
277
case BrainOpenGLTextRenderInterface::X_RIGHT:
278
textOffsetX = -upper.X();
282
float textOffsetY = 0;
283
switch (alignmentY) {
284
case BrainOpenGLTextRenderInterface::Y_BOTTOM:
285
textOffsetY = -lower.Y();
287
case BrainOpenGLTextRenderInterface::Y_CENTER:
288
textOffsetY = -((upper.Y() - lower.Y()) / 2.0);
290
case BrainOpenGLTextRenderInterface::Y_TOP:
291
textOffsetY = -upper.Y();
295
float textX = windowX + textOffsetX;
296
float textY = windowY + textOffsetY;
300
pixmapFont->Render(text.toAscii().constData());
302
restoreStateOfOpenGL();
303
#else // HAVE_FREETYPE
304
CaretLogSevere("Trying to use FTGL Font rendering but it cannot be used due to FreeType not found.");
305
#endif // HAVE_FREETYPE
309
* Get the bounds of the text (in pixels) using the given text
313
* Output containing width of text characters.
315
* Output containing height of text characters.
317
* Text that is to be drawn.
321
* Height of the text.
324
FtglFontTextRenderer::getTextBoundsInPixels(int32_t& widthOut,
327
const TextStyle textStyle,
328
const int fontHeight)
333
FTPixmapFont* pixmapFont = getFont(textStyle, fontHeight);
338
const FTBBox bbox = pixmapFont->BBox(text.toAscii().constData());
339
const FTPoint lower = bbox.Lower();
340
const FTPoint upper = bbox.Upper();
342
widthOut = upper.X() - lower.X();
343
heightOut = upper.Y() - lower.Y();
344
#endif // HAVE_FREETYPE
349
* Draw text at the given model coordinates.
352
* X-coordinate in model space of first text character
354
* Y-coordinate in model space.
356
* Z-coordinate in model space.
358
* Text that is to be drawn.
362
* Height of the text.
365
FtglFontTextRenderer::drawTextAtModelCoords(const double modelX,
369
const TextStyle textStyle,
370
const int fontHeight)
372
GLdouble modelMatrix[16];
373
GLdouble projectionMatrix[16];
376
glGetDoublev(GL_MODELVIEW_MATRIX,
378
glGetDoublev(GL_PROJECTION_MATRIX,
380
glGetIntegerv(GL_VIEWPORT,
383
GLdouble windowX, windowY, windowZ;
384
if (gluProject(modelX, modelY, modelZ,
385
modelMatrix, projectionMatrix, viewport,
386
&windowX, &windowY, &windowZ) == GL_TRUE) {
388
drawTextAtWindowCoords(viewport,
398
CaretLogSevere("gluProject() failed for drawing text at model coordinates.");
403
* Save the state of OpenGL.
404
* Copied from Qt's qgl.cpp, qt_save_gl_state().
407
FtglFontTextRenderer::saveStateOfOpenGL()
409
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
410
glPushAttrib(GL_ALL_ATTRIB_BITS);
411
glMatrixMode(GL_TEXTURE);
414
glMatrixMode(GL_PROJECTION);
416
glMatrixMode(GL_MODELVIEW);
419
glShadeModel(GL_FLAT);
420
glDisable(GL_CULL_FACE);
421
glDisable(GL_LIGHTING);
422
glDisable(GL_STENCIL_TEST);
423
glDisable(GL_DEPTH_TEST);
425
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
429
* Restore the state of OpenGL.
430
* Copied from Qt's qgl.cpp, qt_restore_gl_state().
433
FtglFontTextRenderer::restoreStateOfOpenGL()
435
glMatrixMode(GL_TEXTURE);
437
glMatrixMode(GL_PROJECTION);
439
glMatrixMode(GL_MODELVIEW);
446
* Constructs invalid font data.
448
FtglFontTextRenderer::FontData::FontData()
455
* Destructs font data.
457
FtglFontTextRenderer::FontData::~FontData()
459
if (m_pixmapFont != NULL) {
466
* Initialize font data.
468
* @param fontFileName
472
FtglFontTextRenderer::FontData::initialize(const AString& fontFileName)
475
QFile file(fontFileName);
476
if (file.open(QFile::ReadOnly)) {
477
m_fontData = file.readAll();
478
const size_t numBytes = m_fontData.size();
480
const unsigned char* data = (const unsigned char*)m_fontData.data();
481
m_pixmapFont = new FTPixmapFont(data,
483
if (m_pixmapFont->Error()) {
486
CaretLogSevere("Unable to load font file " + file.fileName());
491
CaretLogSevere("Error reading data from "
494
+ file.errorString());
499
CaretLogSevere("Unable to open "
502
+ file.errorString());
507
#else // HAVE_FREETYPE
508
CaretLogWarning("Trying to initialize FTGL fonts but program was compiled without FreeType.\n"
509
"Text labels may be missing in graphics windows.");
510
#endif // HAVE_FREETYPE
514
* @return Name of the text renderer.
517
FtglFontTextRenderer::getName() const