Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/textEngine: SDL include fix in configure and texture

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