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

Last change on this file since 4164 was 4164, checked in by ldelgass, 7 years ago

Fix coloring of fonts in grid labels

  • Property svn:eol-style set to native
File size: 7.4 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    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
85
86    glMatrixMode(GL_PROJECTION);
87    glPushMatrix();
88    glLoadIdentity();
89
90    gluOrtho2D(0.0f, _screenWidth, _screenHeight, 0.0f);
91
92    glMatrixMode(GL_MODELVIEW);
93    glPushMatrix();
94    glLoadIdentity();
95
96#if 0
97    glDisable(GL_BLEND);
98    glEnable(GL_DEPTH_TEST);
99#else
100    glEnable(GL_BLEND);
101    glDisable(GL_DEPTH_TEST);
102#endif
103}
104
105void
106Fonts::end()
107{
108    glBindTexture(GL_TEXTURE_2D, 0);
109
110    glMatrixMode(GL_PROJECTION);
111    glPopMatrix();
112
113    glMatrixMode(GL_MODELVIEW);
114    glPopMatrix();
115
116    glPopAttrib();
117}
118
119void
120Fonts::initializeFont(FontAttributes& attr)
121{
122    attr._displayLists = glGenLists(256);
123
124    int index;
125    for (index = 0; index < 256; ++index) {
126        FontAttributes::CharInfo& charInfo = attr._chars[index];
127        glNewList(attr._displayLists + index, GL_COMPILE);
128        if (charInfo._valid) {
129            glBegin(GL_TRIANGLE_STRIP);
130           
131            glTexCoord2f(charInfo._left, charInfo._top);
132            glVertex2i(0, 0);
133           
134            glTexCoord2f(charInfo._left, charInfo._bottom);
135            glVertex2i(0, (GLint)attr._fontHeight);
136           
137            glTexCoord2f(charInfo._right, charInfo._top);
138            glVertex2i((GLint)charInfo._width, 0);
139           
140            glTexCoord2f(charInfo._right,  charInfo._bottom);
141            glVertex2i((GLint)charInfo._width, (GLint)attr._fontHeight);
142           
143            glEnd();
144            glTranslatef(charInfo._width, 0.0f, 0.0f);
145        }
146        glEndList();
147    }
148}
149
150bool
151Fonts::loadFont(const char *fontName, const char *fontFileName,
152                FontAttributes& sFont)
153{
154    bool bSuccess = false;
155
156    std::string path = FilePath::getInstance()->getPath(fontFileName);
157    if (path.empty()) {
158        return false;
159    }
160    std::ifstream fsInput(path.c_str(), std::ios::binary);
161    if (fsInput) {
162        sFont._fontName = fontName;
163
164        // make sure this file is the correct type by checking the header
165        unsigned int uiFileId = 0;
166        fsInput.read(reinterpret_cast<char*>(&uiFileId), sizeof(unsigned int));
167        if (uiFileId == (unsigned int)c_nFileMagicHeader) {
168            // read general font/texture dimensions
169            fsInput.read(reinterpret_cast<char*>(&sFont._textureWidth),
170                         sizeof(unsigned int));
171            fsInput.read(reinterpret_cast<char*>(&sFont._textureHeight),
172                         sizeof(unsigned int));
173            fsInput.read(reinterpret_cast<char*>(&sFont._fontHeight),
174                         sizeof(unsigned int));
175
176            // read dimensions for each character in 256-char ASCII chart
177            for (int i = 0; i < 256; ++i) {
178                unsigned int uiSize = 0;
179
180                // top
181                fsInput.read(reinterpret_cast<char*>(&uiSize),
182                             sizeof(unsigned int));
183                sFont._chars[i]._top = static_cast<float>(uiSize) / sFont._textureHeight;
184                // left
185                fsInput.read(reinterpret_cast<char*>(&uiSize), sizeof(unsigned int));
186                sFont._chars[i]._left = static_cast<float>(uiSize) / sFont._textureWidth;
187                // bottom
188                fsInput.read(reinterpret_cast<char*>(&uiSize), sizeof(unsigned int));
189                sFont._chars[i]._bottom = static_cast<float>(uiSize) / sFont._textureHeight;
190                // right
191                fsInput.read(reinterpret_cast<char*>(&uiSize), sizeof(unsigned int));
192                sFont._chars[i]._right = static_cast<float>(uiSize) / sFont._textureWidth;
193                // enabled
194                fsInput.read(reinterpret_cast<char*>(&uiSize), sizeof(unsigned int));
195                sFont._chars[i]._valid = (uiSize != 0);
196                // width factor
197                float fWidthFactor = 1.0f;
198                fsInput.read(reinterpret_cast<char*>(&fWidthFactor), sizeof(float));
199                sFont._chars[i]._width = fWidthFactor * sFont._fontHeight;
200            }
201        }
202
203        // allocate and read the texture map
204        if (!fsInput.eof() && !fsInput.fail()) {
205            unsigned int uiArea = sFont._textureWidth * sFont._textureHeight;
206            unsigned char *pRawMap = new unsigned char[uiArea];
207            fsInput.read(reinterpret_cast<char *>(pRawMap), uiArea);
208
209            // we've only read the luminance values, but we need a luminance +
210            // alpha buffer, so we make a new buffer and duplicate the
211            // luminance values
212            unsigned char *pTexMap = new unsigned char[2 * uiArea];
213            unsigned char *pMap = pTexMap;
214            for (unsigned int i = 0; i < uiArea; ++i) {
215                *pMap++ = pRawMap[i];
216                *pMap++ = pRawMap[i];
217            }
218            delete[] pRawMap;
219            pRawMap = NULL;
220
221            // make texture map out of new buffer
222            glGenTextures(1, &sFont._fontTextureID);
223            glBindTexture(GL_TEXTURE_2D, sFont._fontTextureID);
224            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
225            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
226            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
227            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
228            glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA,
229                         sFont._textureWidth, sFont._textureHeight, 0,
230                         GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, pTexMap);
231            glBindTexture(GL_TEXTURE_2D, 0);
232
233            delete[] pTexMap;
234            pTexMap = NULL;
235
236            bSuccess = true;
237        }
238
239        fsInput.close();
240    }
241    return bSuccess;
242}
243
244void
245Fonts::resize(int width, int height)
246{
247    _screenWidth = width;
248    _screenHeight = height;
249}
250
Note: See TracBrowser for help on using the repository browser.