source: trunk/packages/vizservers/nanovis/util/Fonts.cpp @ 3559

Last change on this file since 3559 was 3559, checked in by gah, 7 years ago
  • Clean up unused variable warnings.
  • Remove use of ffmpeg libraries from nanovis. This should make it easier to maintain (don't have to keep up with all the backward incompatible changes to the ffmpeg library).
  • Property svn:eol-style set to native
File size: 7.3 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 *  Copyright (c) 2004-2013  HUBzero Foundation, LLC
4 */
5
6#include <stdarg.h>
7#include <string.h>
8
9#include <fstream>
10
11#include <GL/glew.h>
12
13#include "Fonts.h"
14#include "FilePath.h"
15
16using namespace nv::util;
17
18// constants
19const int c_nFileMagicHeader = 6666;
20
21Fonts::Fonts() : 
22    _fontIndex(-1), 
23    _screenWidth(512), 
24    _screenHeight(512)
25{
26}
27
28Fonts::~Fonts()
29{
30    for (unsigned index = 0; index < _fonts.size(); ++index) {
31        glDeleteLists(_fonts[index]._displayLists, 256);
32        glDeleteTextures(1, &(_fonts[_fontIndex]. _fontTextureID));
33    }
34}
35
36void 
37Fonts::setFont(const char *fontName)
38{
39    if (fontName != NULL) {
40        unsigned int i;
41        for (i = 0; i < _fonts.size(); ++i) {
42            if (strcmp(_fonts[i]._fontName.c_str(), fontName) == 0) {
43                _fontIndex = i;
44                break;
45            }
46        }
47    }
48}
49
50void 
51Fonts::addFont(const char *fontName, const char *fontFileName)
52{
53    FontAttributes sFont;
54   
55    loadFont(fontName, fontFileName, sFont);
56    initializeFont(sFont);
57    _fonts.push_back(sFont);
58}
59
60void 
61Fonts::draw(const char *pString, ...) const
62{
63    va_list vlArgs;
64    char szVargsBuffer[1024];
65
66    va_start(vlArgs, pString);
67    vsprintf(szVargsBuffer, pString, vlArgs);
68
69    if (_fontIndex != -1) {
70        int length = strlen(szVargsBuffer);
71
72        glListBase(_fonts[_fontIndex]._displayLists);
73        glCallLists(length, GL_UNSIGNED_BYTE, 
74                    reinterpret_cast<const GLvoid*>(szVargsBuffer));
75    }
76}
77
78void 
79Fonts::begin()
80{
81    glPushAttrib(GL_TRANSFORM_BIT | GL_ENABLE_BIT);
82    glEnable(GL_TEXTURE_2D);
83    glBindTexture(GL_TEXTURE_2D, _fonts[_fontIndex]._fontTextureID);
84
85    glMatrixMode(GL_PROJECTION);
86    glPushMatrix();
87    glLoadIdentity();
88
89    gluOrtho2D(0.0f, _screenWidth, _screenHeight, 0.0f);
90
91    glMatrixMode(GL_MODELVIEW);
92    glPushMatrix();
93    glLoadIdentity();
94
95    glEnable(GL_BLEND);
96    glDisable(GL_DEPTH_TEST);
97}
98
99void 
100Fonts::end()
101{
102    glBindTexture(GL_TEXTURE_2D, 0);
103
104    glMatrixMode(GL_PROJECTION);
105    glPopMatrix();
106
107    glMatrixMode(GL_MODELVIEW);
108    glPopMatrix();
109
110    glPopAttrib();
111}
112
113void 
114Fonts::initializeFont(FontAttributes& attr)
115{
116    attr._displayLists = glGenLists(256);
117
118    int index;
119    for (index = 0; index < 256; ++index) {
120        FontAttributes::CharInfo& charInfo = attr._chars[index];
121        glNewList(attr._displayLists + index, GL_COMPILE);
122        if (charInfo._valid) {
123            glBegin(GL_TRIANGLE_STRIP);
124           
125            glTexCoord2f(charInfo._left, charInfo._top); 
126            glVertex2i(0, 0);
127           
128            glTexCoord2f(charInfo._left, charInfo._bottom);
129            glVertex2i(0, (GLint)attr._fontHeight);
130           
131            glTexCoord2f(charInfo._right, charInfo._top);
132            glVertex2i((GLint)charInfo._width, 0);
133           
134            glTexCoord2f(charInfo._right,  charInfo._bottom);
135            glVertex2i((GLint)charInfo._width, (GLint)attr._fontHeight);
136           
137            glEnd();
138            glTranslatef(charInfo._width, 0.0f, 0.0f);
139        }
140        glEndList();
141    }
142}
143
144bool 
145Fonts::loadFont(const char *fontName, const char *fontFileName, 
146                FontAttributes& sFont)
147{
148    bool bSuccess = false;
149
150    std::string path = FilePath::getInstance()->getPath(fontFileName);
151    if (path.empty()) {
152        return false;
153    }
154    std::ifstream fsInput(path.c_str(), std::ios::binary);
155    if (fsInput) {
156        sFont._fontName = fontName;
157
158        // make sure this file is the correct type by checking the header
159        unsigned int uiFileId = 0;
160        fsInput.read(reinterpret_cast<char*>(&uiFileId), sizeof(unsigned int));
161        if (uiFileId == (unsigned int)c_nFileMagicHeader) {
162            // read general font/texture dimensions
163            fsInput.read(reinterpret_cast<char*>(&sFont._textureWidth), 
164                         sizeof(unsigned int));
165            fsInput.read(reinterpret_cast<char*>(&sFont._textureHeight), 
166                         sizeof(unsigned int));
167            fsInput.read(reinterpret_cast<char*>(&sFont._fontHeight), 
168                         sizeof(unsigned int));
169
170            // read dimensions for each character in 256-char ASCII chart
171            for (int i = 0; i < 256; ++i) {
172                unsigned int uiSize = 0;
173
174                // top
175                fsInput.read(reinterpret_cast<char*>(&uiSize), 
176                             sizeof(unsigned int));
177                sFont._chars[i]._top = static_cast<float>(uiSize) / sFont._textureHeight;
178                // left
179                fsInput.read(reinterpret_cast<char*>(&uiSize), sizeof(unsigned int));
180                sFont._chars[i]._left = static_cast<float>(uiSize) / sFont._textureWidth;
181                // bottom
182                fsInput.read(reinterpret_cast<char*>(&uiSize), sizeof(unsigned int));
183                sFont._chars[i]._bottom = static_cast<float>(uiSize) / sFont._textureHeight;
184                // right
185                fsInput.read(reinterpret_cast<char*>(&uiSize), sizeof(unsigned int));
186                sFont._chars[i]._right = static_cast<float>(uiSize) / sFont._textureWidth;
187                // enabled
188                fsInput.read(reinterpret_cast<char*>(&uiSize), sizeof(unsigned int));
189                sFont._chars[i]._valid = (uiSize != 0);
190                // width factor
191                float fWidthFactor = 1.0f;
192                fsInput.read(reinterpret_cast<char*>(&fWidthFactor), sizeof(float));
193                sFont._chars[i]._width = fWidthFactor * sFont._fontHeight;
194            }
195        }
196
197        // allocate and read the texture map
198        if (!fsInput.eof() && !fsInput.fail()) {
199            unsigned int uiArea = sFont._textureWidth * sFont._textureHeight;
200            unsigned char *pRawMap = new unsigned char[uiArea];
201            fsInput.read(reinterpret_cast<char *>(pRawMap), uiArea);
202
203            // we've only read the luminance values, but we need a luminance +
204            // alpha buffer, so we make a new buffer and duplicate the
205            // luminance values
206            unsigned char *pTexMap = new unsigned char[2 * uiArea];
207            unsigned char *pMap = pTexMap;
208            for (unsigned int i = 0; i < uiArea; ++i) {
209                *pMap++ = pRawMap[i];
210                *pMap++ = pRawMap[i];
211            }
212            delete[] pRawMap;
213            pRawMap = NULL;
214
215            // make texture map out of new buffer
216            glGenTextures(1, &sFont._fontTextureID);
217            glBindTexture(GL_TEXTURE_2D, sFont._fontTextureID);
218            glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 
219                         sFont._textureWidth, sFont._textureHeight, 0, 
220                         GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, pTexMap);
221            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
222            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
223            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
224            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
225            glBindTexture(GL_TEXTURE_2D, 0);
226
227            delete[] pTexMap;
228            pTexMap = NULL;
229
230            bSuccess = true;
231        }
232
233        fsInput.close();
234    }
235    return bSuccess;
236}
237
238void 
239Fonts::resize(int width, int height)
240{
241    _screenWidth = width;
242    _screenHeight = height;
243}
244
Note: See TracBrowser for help on using the repository browser.