Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/textEngine/src/lib/graphics/font/glfont.cc @ 3700

Last change on this file since 3700 was 3700, checked in by bensch, 19 years ago

orxonox/branches/textEngine: coloring issue, now the color is set right, and a little plastic surgery on the texCoord (struct instead of float*)

File size: 12.6 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
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, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14
15   ***
16   * This file is extended to the needs of the orxonox-project.         *
17   * the Copyright of the original file is below this copyright         *
18   *                                                                  ***
19
20   for some fonts and licenses visit: =http://www.dafont.com/en/font.php=
21*/
22
23/*
24    glfont:  An example of using the SDL_ttf library with OpenGL.
25    Copyright (C) 1997-2004 Sam Lantinga
26
27    This library is free software; you can redistribute it and/or
28    modify it under the terms of the GNU Library General Public
29    License as published by the Free Software Foundation; either
30    version 2 of the License, or (at your option) any later version.
31
32    This library is distributed in the hope that it will be useful,
33    but WITHOUT ANY WARRANTY; without even the implied warranty of
34    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
35    Library General Public License for more details.
36
37    You should have received a copy of the GNU Library General Public
38    License along with this library; if not, write to the Free
39    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
40
41    The SDL_GL_* functions in this file are available in the public domain.
42
43    Sam Lantinga
44    slouken@libsdl.org
45*/
46
47#include "glfont.h"
48
49#include <stdlib.h>
50#include <stdio.h>
51#include <string.h>
52
53#include "debug.h"
54
55/**
56   \brief constructs a Font
57   \param fontFile the File to load the font from
58*/
59GLFont::GLFont(const char* fontFile)
60{
61  this->init(fontFile);
62}
63
64/**
65   \brief destructs a font
66*/
67GLFont::~GLFont(void)
68{
69  if (this->font)
70    TTF_CloseFont(this->font);
71}
72
73/**
74   \brief function to enable TTF_Fonts
75*/
76void GLFont::enableFonts(void)
77{
78  if (!GLFont::ttfInitialized)
79    {
80      if(TTF_Init()==-1) {
81        PRINTF(1)("TTF_Init: %s\n", TTF_GetError());
82        exit(2);
83      }
84      GLFont::checkVersion();
85      GLFont::ttfInitialized = true;
86    }
87  else
88    PRINTF(4)("Fonts already initialized\n");
89     
90}
91
92/**
93   \brief function to disable TTF_fonts
94*/
95void GLFont::disableFonts(void)
96{
97  if (GLFont::ttfInitialized)
98    {
99      TTF_Quit();
100      GLFont::ttfInitialized = false;
101    }
102  else
103    PRINTF(4)("Fonts were not initialized.\n");
104}
105
106//! A simple variable for checking if ttf was initialized
107bool GLFont::ttfInitialized = false;
108
109/**
110   \brief initializes a new Font
111   \param fontFile The file to load a Font from
112   \param fontSize the Size in pixels of the Font
113*/
114bool GLFont::init(const char* fontFile, unsigned int fontSize)
115{
116  if (!GLFont::ttfInitialized)
117    GLFont::enableFonts();
118
119  // setting default values.
120  this->font = NULL;
121  this->fontFile = NULL;
122  this->text = NULL;
123  this->texture = 0;
124 
125  this->setSize(fontSize);
126 
127  this->renderStyle = TTF_STYLE_NORMAL;
128
129  this->setFont(fontFile);
130
131  this->setColor(0, 255, 0);
132
133  this->setText(FONT_DEFAULT_TEXT);
134
135  this->createTexture();
136}
137
138/**
139   \brief sets The Font.
140   \param fontFile The file containing the font.
141   \returns true if loaded, false if something went wrong, or if a font was loaded before.
142*/
143bool GLFont::setFont(const char* fontFile)
144{
145  if (!this->fontFile)
146    {
147      this->fontFile = new char[strlen(fontFile)+1];
148      strcpy(this->fontFile, fontFile);
149     
150      this->font = TTF_OpenFont(this->fontFile, this->fontSize);
151      if(!this->font) 
152        {
153          PRINTF(1)("TTF_OpenFont: %s\n", TTF_GetError());
154          return false;
155      }
156      return true;
157    }
158  else
159    {
160      PRINTF(2)("Font already initialized, unable to change it now.\n");
161      return false;
162    }
163}
164
165/**
166   \brief Sets a new Text to the font
167   \param text the new text to set
168*/
169void GLFont::setText(const char* text)
170{
171  if (this->text)
172    delete []this->text;
173  this->text = new char[strlen(text)+1];
174  strcpy(this->text, text);
175}
176
177/**
178   \brief sets a specific renderStyle
179   \param renderStyle the Style to render: a char-array containing:
180   i: italic, b: bold, u, underline
181*/
182void GLFont::setStyle(char* renderStyle)
183{
184  this->renderStyle = TTF_STYLE_NORMAL;
185 
186  for (int i = 0; i < strlen(renderStyle); i++)
187    if (strncmp(renderStyle+i, "b", 1) == 0) 
188      this->renderStyle |= TTF_STYLE_BOLD;
189    else if (strncmp(renderStyle+i, "i", 1) == 0)
190      this->renderStyle |= TTF_STYLE_ITALIC;
191    else if (strncmp(renderStyle+i, "u", 1) == 0) 
192      this->renderStyle |= TTF_STYLE_UNDERLINE;
193
194  if (this->font)
195    TTF_SetFontStyle(this->font, this->renderStyle);
196  else
197    PRINTF(2)("Font was not initialized, please do so before setting the Font-Style.\n");
198}
199
200/**
201   \brief Sets a new Size to the font
202   \param fontSize The new Size in pixels.
203*/
204void GLFont::setSize(unsigned int fontSize)
205{
206  this->fontSize = fontSize;
207}
208
209/**
210   \brief sets a new color to the font
211   \param r Red
212   \param g Green
213   \param b Blue
214*/
215void GLFont::setColor(Uint8 r, Uint8 g, Uint8 b)
216{
217  this->color.r = r;
218  this->color.g = g;
219  this->color.b = b;
220}
221
222/**
223   \brief sets a Position.
224   \param x the x-position in pixels from the left border
225   \param y the y-position in pixels from the top border
226*/
227void GLFont::setPosition(int x, int y)
228{
229  this->textPosSize.x = x;
230  this->textPosSize.y = y;
231}
232
233/**
234   \brief draws the Font
235   \todo FIX this is to slow/static
236*/
237void GLFont::draw(void)
238{
239  this->enter2DMode();
240  glBindTexture(GL_TEXTURE_2D, texture);
241  glEnable(GL_TEXTURE_2D);
242  glBegin(GL_QUADS);
243  glTexCoord2f(this->texCoord.minU, this->texCoord.minV); glVertex2i(20,   20  );
244  glTexCoord2f(this->texCoord.maxU, this->texCoord.minV); glVertex2i(20+this->textPosSize.w, 20  );
245  glTexCoord2f(this->texCoord.maxU, this->texCoord.maxV); glVertex2i(20+this->textPosSize.w, 20+this->textPosSize.h);
246  glTexCoord2f(this->texCoord.minU, this->texCoord.maxV); glVertex2i(20, 20+this->textPosSize.h);
247  glEnd();
248  this->leave2DMode();
249
250}
251
252
253/**
254   \brief creates a texture out of the given parameters
255*/
256void GLFont::createTexture(void)
257{
258  SDL_Surface* tmpSurf;
259  if (this->texture)
260    glDeleteTextures(1, &this->texture);
261  tmpSurf = TTF_RenderText_Blended(this->font, this->text, this->color);
262  if (tmpSurf)
263    this->texture = loadTexture(tmpSurf, &texCoord);
264
265  this->textPosSize.w = tmpSurf->w;
266  this->textPosSize.h = tmpSurf->h;
267  SDL_FreeSurface(tmpSurf);
268}
269
270
271/**
272   \returns the maximum height of the Font, if the font was initialized, 0 otherwise
273*/
274int GLFont::getMaxHeight(void)
275{
276  if (this->font)
277    return TTF_FontHeight(this->font);
278  else
279    return 0;
280}
281
282/**
283   \returns the maximum ascent of the Font, if the font was initialized, 0 otherwise
284
285   the ascent is the pixels of the font above the baseline
286*/
287int GLFont::getMaxAscent(void)
288{
289  if (this->font)
290    return TTF_FontAscent(this->font);
291  else
292    return 0;
293}
294
295/**
296   \returns the maximum descent of the Font, if the font was initialized, 0 otherwise
297
298   the descent is the pixels of the font below the baseline
299*/
300int GLFont::getMaxDescent(void)
301{
302  if (this->font)
303    return TTF_FontDescent(this->font);
304  else
305    return 0;
306}
307
308/**
309   \param character The character to get info about.
310   \returns a Glyph struct of a character.
311
312   This only works for horizontal fonts. see
313   http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html
314   for more info about vertical Fonts
315*/
316Glyph GLFont::getGlyphMetrics(Uint16 character)
317{
318  Glyph rg;
319  rg.character = character;
320  TTF_GlyphMetrics(this->font, rg.character,
321                   &rg.minX, &rg.maxX,
322                   &rg.minY, &rg.maxY,
323                   &rg.advance);
324  rg.height = rg.maxY - rg.minY;
325  rg.width = rg.maxX - rg.minX;
326  rg.bearingX = (rg.advance - rg.width) / 2;
327  rg.bearingY = rg.maxY;
328  return rg;
329}
330
331/**
332   \brief entering 2D Mode
333   
334   this is a GL-Projection-mode, that is orthogonal, for placing the font in fron of everything else
335*/
336void GLFont::enter2DMode(void)
337{
338  SDL_Surface *screen = SDL_GetVideoSurface();
339 
340  /* Note, there may be other things you need to change,
341     depending on how you have your OpenGL state set up.
342  */
343  glPushAttrib(GL_ENABLE_BIT);
344  glDisable(GL_DEPTH_TEST);
345  glDisable(GL_CULL_FACE);
346  glDisable(GL_LIGHTING);  // will be set back when leaving 2D-mode
347  glEnable(GL_TEXTURE_2D);
348
349  /* This allows alpha blending of 2D textures with the scene */
350  glEnable(GL_BLEND);
351  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
352 
353  glViewport(0, 0, screen->w, screen->h);
354 
355  glMatrixMode(GL_PROJECTION);
356  glPushMatrix();
357  glLoadIdentity();
358 
359  glOrtho(0.0, (GLdouble)screen->w, (GLdouble)screen->h, 0.0, 0.0, 1.0);
360 
361  glMatrixMode(GL_MODELVIEW);
362  glPushMatrix();
363  glLoadIdentity();
364 
365  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
366}
367
368/**
369   \brief leaves the 2DMode again also \see GLFont::enter2DMode(void)
370*/
371void GLFont::leave2DMode(void)
372{
373        glMatrixMode(GL_MODELVIEW);
374        glPopMatrix();
375
376        glMatrixMode(GL_PROJECTION);
377        glPopMatrix();
378
379        glPopAttrib();
380}
381
382/**
383   \brief Loads a Font from an SDL_surface into a texture.
384   \param surface The surface to make the texture of
385   \param texCoord The texture coordinates of the 4 corners of the texture
386   \returns the ID of the texture
387*/
388GLuint GLFont::loadTexture(SDL_Surface *surface, TexCoord* texCoord)
389{
390  GLuint texture;
391  int w, h;
392  SDL_Surface *image;
393  SDL_Rect area;
394  Uint32 saved_flags;
395  Uint8  saved_alpha;
396 
397  /* Use the surface width and height expanded to powers of 2 */
398  w = powerOfTwo(surface->w);
399  h = powerOfTwo(surface->h);
400  texCoord->minU = 0.0f;
401  texCoord->minV = 0.0f;
402  texCoord->maxU = (GLfloat)surface->w / w;
403  texCoord->maxV = (GLfloat)surface->h / h;
404 
405  image = SDL_CreateRGBSurface(
406                               SDL_SWSURFACE,
407                               w, h,
408                               32,
409#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
410                               0x000000FF, 
411                               0x0000FF00, 
412                               0x00FF0000, 
413                               0xFF000000
414#else
415                               0xFF000000,
416                               0x00FF0000, 
417                               0x0000FF00, 
418                               0x000000FF
419#endif
420                               );
421  if ( image == NULL ) {
422    return 0;
423  }
424 
425  /* Save the alpha blending attributes */
426  saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
427  saved_alpha = surface->format->alpha;
428  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
429    SDL_SetAlpha(surface, 0, 0);
430  }
431 
432  /* Copy the surface into the GL texture image */
433  area.x = 0;
434  area.y = 0;
435  area.w = surface->w;
436  area.h = surface->h;
437  SDL_BlitSurface(surface, &area, image, &area);
438 
439  /* Restore the alpha blending attributes */
440  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
441    SDL_SetAlpha(surface, saved_flags, saved_alpha);
442  }
443 
444  /* Create an OpenGL texture for the image */
445  glGenTextures(1, &texture);
446  glBindTexture(GL_TEXTURE_2D, texture);
447  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
448  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
449  glTexImage2D(GL_TEXTURE_2D,
450               0,
451               GL_RGBA,
452               w, h,
453               0,
454               GL_RGBA,
455               GL_UNSIGNED_BYTE,
456               image->pixels);
457  SDL_FreeSurface(image); /* No longer needed */
458 
459  return texture;
460}
461
462/**
463   \brief Quick utility function for texture creation
464   \param input an integer
465   \returns the next bigger 2^n-integer than input
466*/
467int GLFont::powerOfTwo(int input)
468{
469  int value = 1;
470 
471  while ( value < input ) {
472    value <<= 1;
473  }
474  return value;
475}
476
477
478/**
479   \brief checks if the compiled version and the local version of SDL_ttf match.
480   \returns true if match, false otherwise
481*/
482bool GLFont::checkVersion(void)
483{
484  SDL_version compile_version;
485  SDL_version link_version;
486  TTF_VERSION(&compile_version);
487  link_version = *TTF_Linked_Version();
488
489  if (compile_version.major == link_version.major &&
490      compile_version.minor == link_version.minor &&
491      compile_version.patch == link_version.patch)
492    {
493      return true;
494    }
495  else
496    {
497      PRINTF(2)("compiled with SDL_ttf version: %d.%d.%d\n", 
498                compile_version.major,
499                compile_version.minor,
500                compile_version.patch);
501     
502      PRINTF(2)("running with SDL_ttf version: %d.%d.%d\n", 
503                link_version.major,
504                link_version.minor,
505                link_version.patch);
506      return false;
507    }
508}
509
510
511
512/**
513   \brief a simple function to get some interesting information about this class
514*/
515void GLFont::debug(void)
516{
517
518  // print the loaded font's style
519  int style;
520  style=TTF_GetFontStyle(this->font);
521  PRINTF(0)("The font style is:");
522  if(style==TTF_STYLE_NORMAL)
523    PRINTF(0)(" normal");
524  else {
525    if(style&TTF_STYLE_BOLD)
526      PRINTF(0)(" bold");
527    if(style&TTF_STYLE_ITALIC)
528      PRINTF(0)(" italic");
529    if(style&TTF_STYLE_UNDERLINE)
530      PRINTF(0)(" underline");
531  }
532  PRINTF(0)("\n");
533
534
535}
Note: See TracBrowser for help on using the repository browser.