source: trunk/packages/vizservers/nanovis/R2/src/R2Fonts.cpp @ 2972

Last change on this file since 2972 was 2972, checked in by ldelgass, 12 years ago

Remove vrutil library. Was only used for FilePath? that already exists in
R2 library (may need some fixing for windows portability though). Make
R2FilePath::getPath return a std::string so users can allocate a std::string
on the stack and not worry about deleting the string buffer returned. Also,
use std::string in R2Fonts to avoid leaking font names. Remove R2string as
it is now replaced by std::strings.

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