~ubuntu-branches/debian/stretch/connectome-workbench/stretch

« back to all changes in this revision

Viewing changes to .pc/deb_system_ftgl/src/Brain/FtglFontTextRenderer.cxx

  • Committer: Package Import Robot
  • Author(s): Yaroslav Halchenko
  • Date: 2014-10-21 10:04:22 UTC
  • Revision ID: package-import@ubuntu.com-20141021100422-mh7mwoe3hemux3gh
Tags: 1.0-2
* debian/copyright
  - additional/adjusted entries. Thanks Thorsten
    Alteholz for the review
* Re-upload to Debian proper (Closes: #744130)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*LICENSE_START*/
 
3
/*
 
4
 *  Copyright (C) 2014  Washington University School of Medicine
 
5
 *
 
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.
 
10
 *
 
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.
 
15
 *
 
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.
 
19
 */
 
20
/*LICENSE_END*/
 
21
/****************************************************************************
 
22
 **
 
23
 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
 
24
 ** Contact: http://www.qt-project.org/legal
 
25
 **
 
26
 ** This file is part of the QtOpenGL module of the Qt Toolkit.
 
27
 **
 
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.
 
36
 **
 
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.
 
44
 **
 
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.
 
48
 **
 
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.
 
56
 **
 
57
 **
 
58
 ** $QT_END_LICENSE$
 
59
 **
 
60
 ****************************************************************************/
 
61
 
 
62
#define __FTGL_FONT_TEXT_RENDERER_DECLARE__
 
63
#include "FtglFontTextRenderer.h"
 
64
#undef __FTGL_FONT_TEXT_RENDERER_DECLARE__
 
65
 
 
66
#include <QFile>
 
67
 
 
68
#include "CaretAssert.h"
 
69
#include "CaretLogger.h"
 
70
#include "CaretOpenGLInclude.h"
 
71
 
 
72
#ifdef HAVE_FREETYPE
 
73
#include <FtglConfig.h>
 
74
#include <FTGL/ftgl.h>
 
75
using namespace FTGL;
 
76
#endif // HAVE_FREETYPE
 
77
 
 
78
using namespace caret;
 
79
 
 
80
 
 
81
    
 
82
/**
 
83
 * \class caret::FtglFontTextRenderer 
 
84
 * \brief Text rendering using QGLWidget.
 
85
 *
 
86
 * Draws text using methods in QGLWidget.
 
87
 * 
 
88
 * @param glWidget
 
89
 *   QGLWidget that does the text rendering.
 
90
 */
 
91
/**
 
92
 * Constructor.
 
93
 */
 
94
FtglFontTextRenderer::FtglFontTextRenderer()
 
95
: BrainOpenGLTextRenderInterface()
 
96
{
 
97
#ifdef HAVE_FREETYPE
 
98
    m_boldFont.initialize(":/FtglFonts/VeraBd.ttf");
 
99
    m_normalFont.initialize(":/FtglFonts/VeraSe.ttf");
 
100
#endif // HAVE_FREETYPE
 
101
}
 
102
 
 
103
/**
 
104
 * Destructor.
 
105
 */
 
106
FtglFontTextRenderer::~FtglFontTextRenderer()
 
107
{
 
108
#ifdef HAVE_FREETYPE
 
109
#endif // HAVE_FREETYPE
 
110
}
 
111
 
 
112
/**
 
113
 * @return The font system is valid.
 
114
 */
 
115
bool
 
116
FtglFontTextRenderer::isValid() const
 
117
{
 
118
    return m_normalFont.m_valid;
 
119
}
 
120
 
 
121
/*
 
122
 * Get the font with the given style and height.
 
123
 * Returned font not guaranteed to be desired size.
 
124
 *
 
125
 * @param textStyle
 
126
 *    Style of the text.
 
127
 * @param fontHeight
 
128
 *    Height of the font.
 
129
 * @return
 
130
 *    The font.  May be NULL due to 
 
131
 */
 
132
FTPixmapFont*
 
133
FtglFontTextRenderer::getFont(const TextStyle textStyle,
 
134
                              const int fontHeight)
 
135
{
 
136
#ifdef HAVE_FREETYPE
 
137
    FTPixmapFont* pixmapFont = NULL;
 
138
    switch (textStyle) {
 
139
        case BrainOpenGLTextRenderInterface::BOLD:
 
140
            if (m_boldFont.m_valid) {
 
141
                pixmapFont = m_boldFont.m_pixmapFont;
 
142
            }
 
143
            break;
 
144
        case BrainOpenGLTextRenderInterface::NORMAL:
 
145
            if (m_normalFont.m_valid) {
 
146
                pixmapFont = m_normalFont.m_pixmapFont;
 
147
            }
 
148
            break;
 
149
    }
 
150
    
 
151
    if (pixmapFont != NULL) {
 
152
        if ( ! pixmapFont->FaceSize(fontHeight)) {
 
153
            QString msg("Failed to set requested font height="
 
154
                        + AString::number(fontHeight)
 
155
                        + ".");
 
156
            if (pixmapFont->FaceSize(14)) {
 
157
                msg += "  Defaulting to font height=14";
 
158
            }
 
159
            else {
 
160
                msg += "  Defaulting to font height=14 also failed.";
 
161
            }
 
162
            CaretLogWarning(msg);
 
163
        }
 
164
        
 
165
        return pixmapFont;
 
166
    }
 
167
 
 
168
    CaretLogSevere("Trying to use FTGL Font rendering but font is not valid.");
 
169
    return NULL;
 
170
#else  // HAVE_FREETYPE
 
171
    return NULL;
 
172
#endif // HAVE_FREETYPE
 
173
}
 
174
 
 
175
/**
 
176
 * Draw text at the given window coordinates.
 
177
 *
 
178
 * @param viewport
 
179
 *   The current viewport.
 
180
 * @param windowX
 
181
 *   X-coordinate in the window of first text character
 
182
 *   using the 'alignment'
 
183
 * @param windowY
 
184
 *   Y-coordinate in the window at which bottom of text is placed.
 
185
 * @param text
 
186
 *   Text that is to be drawn.
 
187
 * @param alignment
 
188
 *   Alignment of text
 
189
 * @param textStyle
 
190
 *   Style of the text.
 
191
 * @param fontHeight
 
192
 *   Height of the text.
 
193
 */
 
194
void 
 
195
FtglFontTextRenderer::drawTextAtWindowCoords(const int viewport[4],
 
196
                                                      const int windowX,
 
197
                                                      const int windowY,
 
198
                                                      const QString& text,
 
199
                                                      const TextAlignmentX alignmentX,
 
200
                                                      const TextAlignmentY alignmentY,
 
201
                                                      const TextStyle textStyle,
 
202
                                                      const int fontHeight)
 
203
{
 
204
    if (text.isEmpty()) {
 
205
        return;
 
206
    }
 
207
    
 
208
#ifdef HAVE_FREETYPE
 
209
    FTPixmapFont* pixmapFont = getFont(textStyle, fontHeight);
 
210
    if (! pixmapFont) {
 
211
        return;
 
212
    }
 
213
    
 
214
    saveStateOfOpenGL();
 
215
 
 
216
    /*
 
217
     * Disable depth testing so text not occluded
 
218
     */
 
219
    glDisable(GL_DEPTH_TEST);
 
220
    
 
221
    
 
222
    
 
223
    /*
 
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.
 
230
     */
 
231
    glMatrixMode(GL_PROJECTION);
 
232
    glLoadIdentity();
 
233
    glOrtho(0,
 
234
            (viewport[2]),
 
235
            0,
 
236
            (viewport[3]),
 
237
            -1,
 
238
            1);
 
239
    
 
240
    /*
 
241
     * Viewing projection is just the identity matrix since
 
242
     * we are drawing in window coordinates.
 
243
     */
 
244
    glMatrixMode(GL_MODELVIEW);
 
245
    glLoadIdentity();
 
246
    
 
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);
 
252
        glLineWidth(1.0);
 
253
        glPushMatrix();
 
254
        glTranslatef(windowX, windowY, 0.0);
 
255
        glBegin(GL_LINES);
 
256
        glVertex2i(-20, 0);
 
257
        glVertex2i( 20, 0);
 
258
        glVertex2i(0, -20);
 
259
        glVertex2i(0,  20);
 
260
        glEnd();
 
261
        glPopMatrix();
 
262
        glColor3f(savedRGBA[0], savedRGBA[1], savedRGBA[2]);
 
263
    }
 
264
    
 
265
    const FTBBox bbox = pixmapFont->BBox(text.toAscii().constData());
 
266
    const FTPoint lower = bbox.Lower();
 
267
    const FTPoint upper = bbox.Upper();
 
268
    
 
269
    float textOffsetX = 0;
 
270
    switch (alignmentX) {
 
271
        case BrainOpenGLTextRenderInterface::X_CENTER:
 
272
            textOffsetX = -((upper.X() - lower.X()) / 2.0);
 
273
            break;
 
274
        case BrainOpenGLTextRenderInterface::X_LEFT:
 
275
            textOffsetX = -lower.X();
 
276
            break;
 
277
        case BrainOpenGLTextRenderInterface::X_RIGHT:
 
278
            textOffsetX = -upper.X();
 
279
            break;
 
280
    }
 
281
    
 
282
    float textOffsetY = 0;
 
283
    switch (alignmentY) {
 
284
        case BrainOpenGLTextRenderInterface::Y_BOTTOM:
 
285
            textOffsetY = -lower.Y();
 
286
            break;
 
287
        case BrainOpenGLTextRenderInterface::Y_CENTER:
 
288
            textOffsetY = -((upper.Y() - lower.Y()) / 2.0);
 
289
            break;
 
290
        case BrainOpenGLTextRenderInterface::Y_TOP:
 
291
            textOffsetY = -upper.Y();
 
292
            break;
 
293
    }
 
294
    
 
295
    float textX = windowX + textOffsetX;
 
296
    float textY = windowY + textOffsetY;
 
297
    glRasterPos2f(textX,
 
298
                  textY);
 
299
 
 
300
    pixmapFont->Render(text.toAscii().constData());
 
301
    
 
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
 
306
}
 
307
 
 
308
/**
 
309
 * Get the bounds of the text (in pixels) using the given text
 
310
 * attributes.
 
311
 *
 
312
 * @param widthOut
 
313
 *   Output containing width of text characters.
 
314
 * @param heightOut
 
315
 *   Output containing height of text characters.
 
316
 * @param text
 
317
 *   Text that is to be drawn.
 
318
 * @param textStyle
 
319
 *   Style of the text.
 
320
 * @param fontHeight
 
321
 *   Height of the text.
 
322
 */
 
323
void
 
324
FtglFontTextRenderer::getTextBoundsInPixels(int32_t& widthOut,
 
325
                                            int32_t& heightOut,
 
326
                                           const QString& text,
 
327
                                           const TextStyle textStyle,
 
328
                                           const int fontHeight)
 
329
{
 
330
    widthOut  = 0;
 
331
    heightOut = 0;
 
332
#ifdef HAVE_FREETYPE
 
333
    FTPixmapFont* pixmapFont = getFont(textStyle, fontHeight);
 
334
    if (! pixmapFont) {
 
335
        return;
 
336
    }
 
337
 
 
338
    const FTBBox bbox = pixmapFont->BBox(text.toAscii().constData());
 
339
    const FTPoint lower = bbox.Lower();
 
340
    const FTPoint upper = bbox.Upper();
 
341
    
 
342
    widthOut = upper.X() - lower.X();
 
343
    heightOut = upper.Y() - lower.Y();
 
344
#endif // HAVE_FREETYPE
 
345
}
 
346
 
 
347
 
 
348
/**
 
349
 * Draw text at the given model coordinates.
 
350
 *
 
351
 * @param modelX
 
352
 *   X-coordinate in model space of first text character
 
353
 * @param modelY
 
354
 *   Y-coordinate in model space.
 
355
 * @param modelZ
 
356
 *   Z-coordinate in model space.
 
357
 * @param text
 
358
 *   Text that is to be drawn.
 
359
 * @param textStyle
 
360
 *   Style of the text.
 
361
 * @param fontHeight
 
362
 *   Height of the text.
 
363
 */
 
364
void 
 
365
FtglFontTextRenderer::drawTextAtModelCoords(const double modelX,
 
366
                                                     const double modelY,
 
367
                                                     const double modelZ,
 
368
                                                     const QString& text,
 
369
                                                     const TextStyle textStyle,
 
370
                                                     const int fontHeight)
 
371
{
 
372
    GLdouble modelMatrix[16];
 
373
    GLdouble projectionMatrix[16];
 
374
    GLint viewport[4];
 
375
    
 
376
    glGetDoublev(GL_MODELVIEW_MATRIX,
 
377
                 modelMatrix);
 
378
    glGetDoublev(GL_PROJECTION_MATRIX,
 
379
                 projectionMatrix);
 
380
    glGetIntegerv(GL_VIEWPORT,
 
381
                  viewport);
 
382
    
 
383
    GLdouble windowX, windowY, windowZ;
 
384
    if (gluProject(modelX, modelY, modelZ,
 
385
                   modelMatrix, projectionMatrix, viewport,
 
386
                   &windowX, &windowY, &windowZ) == GL_TRUE) {
 
387
        
 
388
        drawTextAtWindowCoords(viewport,
 
389
                               windowX,
 
390
                               windowY,
 
391
                               text,
 
392
                               X_CENTER,
 
393
                               Y_CENTER,
 
394
                               textStyle,
 
395
                               fontHeight);
 
396
    }
 
397
    else {
 
398
        CaretLogSevere("gluProject() failed for drawing text at model coordinates.");
 
399
    }
 
400
}
 
401
 
 
402
/**
 
403
 * Save the state of OpenGL.
 
404
 * Copied from Qt's qgl.cpp, qt_save_gl_state().
 
405
 */
 
406
void
 
407
FtglFontTextRenderer::saveStateOfOpenGL()
 
408
{
 
409
    glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
 
410
    glPushAttrib(GL_ALL_ATTRIB_BITS);
 
411
    glMatrixMode(GL_TEXTURE);
 
412
    glPushMatrix();
 
413
    glLoadIdentity();
 
414
    glMatrixMode(GL_PROJECTION);
 
415
    glPushMatrix();
 
416
    glMatrixMode(GL_MODELVIEW);
 
417
    glPushMatrix();
 
418
    
 
419
    glShadeModel(GL_FLAT);
 
420
    glDisable(GL_CULL_FACE);
 
421
    glDisable(GL_LIGHTING);
 
422
    glDisable(GL_STENCIL_TEST);
 
423
    glDisable(GL_DEPTH_TEST);
 
424
    glEnable(GL_BLEND);
 
425
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
 
426
}
 
427
 
 
428
/**
 
429
 * Restore the state of OpenGL.
 
430
 * Copied from Qt's qgl.cpp, qt_restore_gl_state().
 
431
 */
 
432
void
 
433
FtglFontTextRenderer::restoreStateOfOpenGL()
 
434
{
 
435
    glMatrixMode(GL_TEXTURE);
 
436
    glPopMatrix();
 
437
    glMatrixMode(GL_PROJECTION);
 
438
    glPopMatrix();
 
439
    glMatrixMode(GL_MODELVIEW);
 
440
    glPopMatrix();
 
441
    glPopAttrib();
 
442
    glPopClientAttrib();
 
443
}
 
444
 
 
445
/**
 
446
 * Constructs invalid font data.
 
447
 */
 
448
FtglFontTextRenderer::FontData::FontData()
 
449
{
 
450
    m_valid = false;
 
451
    m_pixmapFont = NULL;
 
452
}
 
453
 
 
454
/**
 
455
 * Destructs font data.
 
456
 */
 
457
FtglFontTextRenderer::FontData::~FontData()
 
458
{
 
459
    if (m_pixmapFont != NULL) {
 
460
        delete m_pixmapFont;
 
461
        m_pixmapFont = NULL;
 
462
    }
 
463
}
 
464
 
 
465
/**
 
466
 * Initialize font data.    
 
467
 *
 
468
 * @param fontFileName
 
469
 *    Name of font file.
 
470
 */
 
471
void
 
472
FtglFontTextRenderer::FontData::initialize(const AString& fontFileName)
 
473
{
 
474
#ifdef HAVE_FREETYPE
 
475
    QFile file(fontFileName);
 
476
    if (file.open(QFile::ReadOnly)) {
 
477
        m_fontData = file.readAll();
 
478
        const size_t numBytes = m_fontData.size();
 
479
        if (numBytes > 0) {
 
480
            const unsigned char* data = (const unsigned char*)m_fontData.data();
 
481
            m_pixmapFont = new FTPixmapFont(data,
 
482
                                                 numBytes);
 
483
            if (m_pixmapFont->Error()) {
 
484
                delete m_pixmapFont;
 
485
                m_pixmapFont = NULL;
 
486
                CaretLogSevere("Unable to load font file " + file.fileName());
 
487
                return;
 
488
            }
 
489
        }
 
490
        else {
 
491
            CaretLogSevere("Error reading data from "
 
492
                           + file.fileName()
 
493
                           + " error: "
 
494
                           + file.errorString());
 
495
            return;
 
496
        }
 
497
    }
 
498
    else {
 
499
        CaretLogSevere("Unable to open "
 
500
                       + file.fileName()
 
501
                       + " error: "
 
502
                       + file.errorString());
 
503
        return;
 
504
    }
 
505
    
 
506
    m_valid = true;
 
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
 
511
}
 
512
 
 
513
/**
 
514
 * @return Name of the text renderer.
 
515
 */
 
516
AString
 
517
FtglFontTextRenderer::getName() const
 
518
{
 
519
    return "FTGL Font";
 
520
}
 
521