Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/textEngine: minor change and doxy-tags

File size: 12.4 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->setText(FONT_DEFAULT_TEXT);
132
133  this->createTexture();
134}
135
136/**
137   \brief sets The Font.
138   \param fontFile The file containing the font.
139   \returns true if loaded, false if something went wrong, or if a font was loaded before.
140*/
141bool GLFont::setFont(const char* fontFile)
142{
143  if (!this->fontFile)
144    {
145      this->fontFile = new char[strlen(fontFile)+1];
146      strcpy(this->fontFile, fontFile);
147     
148      this->font = TTF_OpenFont(this->fontFile, this->fontSize);
149      if(!this->font) 
150        {
151          PRINTF(1)("TTF_OpenFont: %s\n", TTF_GetError());
152          return false;
153      }
154      return true;
155    }
156  else
157    {
158      PRINTF(2)("Font already initialized, unable to change it now.\n");
159      return false;
160    }
161}
162
163/**
164   \brief Sets a new Text to the font
165   \param text the new text to set
166*/
167void GLFont::setText(const char* text)
168{
169  if (this->text)
170    delete []this->text;
171  this->text = new char[strlen(text)+1];
172  strcpy(this->text, text);
173}
174
175/**
176   \brief sets a specific renderStyle
177   \param renderStyle the Style to render: a char-array containing:
178   i: italic, b: bold, u, underline
179*/
180void GLFont::setStyle(char* renderStyle)
181{
182  this->renderStyle = TTF_STYLE_NORMAL;
183 
184  for (int i = 0; i < strlen(renderStyle); i++)
185    if (strncmp(renderStyle+i, "b", 1) == 0) 
186      this->renderStyle |= TTF_STYLE_BOLD;
187    else if (strncmp(renderStyle+i, "i", 1) == 0)
188      this->renderStyle |= TTF_STYLE_ITALIC;
189    else if (strncmp(renderStyle+i, "u", 1) == 0) 
190      this->renderStyle |= TTF_STYLE_UNDERLINE;
191
192  if (this->font)
193    TTF_SetFontStyle(this->font, this->renderStyle);
194  else
195    PRINTF(2)("Font was not initialized, please do so before setting the Font-Style.\n");
196}
197
198/**
199   \brief Sets a new Size to the font
200   \param fontSize The new Size in pixels.
201*/
202void GLFont::setSize(unsigned int fontSize)
203{
204  this->fontSize = fontSize;
205}
206
207/**
208   \brief sets a new color to the font
209   \param r Red
210   \param g Green
211   \param b Blue
212*/
213void GLFont::setColor(Uint8 r, Uint8 g, Uint8 b)
214{
215  this->color.r = r;
216  this->color.g = g;
217  this->color.b = b;
218}
219
220/**
221   \brief sets a Position.
222   \param x the x-position in pixels from the left border
223   \param y the y-position in pixels from the top border
224*/
225void GLFont::setPosition(int x, int y)
226{
227  this->textPosSize.x = x;
228  this->textPosSize.y = y;
229}
230
231/**
232   \brief draws the Font
233   \todo FIX this is to slow/static
234*/
235void GLFont::draw(void)
236{
237  this->enter2DMode();
238  glBindTexture(GL_TEXTURE_2D, texture);
239  glEnable(GL_TEXTURE_2D);
240  glBegin(GL_QUADS);
241  glTexCoord2f(0, 0); glVertex2i(20,   20  );
242  glTexCoord2f(1, 0); glVertex2i(20+this->textPosSize.w, 20  );
243  glTexCoord2f(1, 1); glVertex2i(20+this->textPosSize.w, 20+this->textPosSize.h);
244  glTexCoord2f(0, 1); glVertex2i(20, 20+this->textPosSize.h);
245  glEnd();
246  this->leave2DMode();
247
248}
249
250
251/**
252   \brief creates a texture out of the given parameters
253*/
254void GLFont::createTexture(void)
255{
256  GLfloat texcoord[4];
257  SDL_Surface* tmpSurf;
258  if (this->texture)
259    glDeleteTextures(1, &this->texture);
260  tmpSurf = TTF_RenderText_Blended(this->font, this->text, this->color);
261  if (tmpSurf)
262    this->texture = loadTexture(tmpSurf, texcoord);
263
264  this->textPosSize.w = tmpSurf->w;
265  this->textPosSize.h = tmpSurf->h;
266  SDL_FreeSurface(tmpSurf);
267}
268
269
270/**
271   \returns the maximum height of the Font, if the font was initialized, 0 otherwise
272*/
273int GLFont::getMaxHeight(void)
274{
275  if (this->font)
276    return TTF_FontHeight(this->font);
277  else
278    return 0;
279}
280
281/**
282   \returns the maximum ascent of the Font, if the font was initialized, 0 otherwise
283
284   the ascent is the pixels of the font above the baseline
285*/
286int GLFont::getMaxAscent(void)
287{
288  if (this->font)
289    return TTF_FontAscent(this->font);
290  else
291    return 0;
292}
293
294/**
295   \returns the maximum descent of the Font, if the font was initialized, 0 otherwise
296
297   the descent is the pixels of the font below the baseline
298*/
299int GLFont::getMaxDescent(void)
300{
301  if (this->font)
302    return TTF_FontDescent(this->font);
303  else
304    return 0;
305}
306
307/**
308   \param character The character to get info about.
309   \returns a Glyph struct of a character.
310
311   This only works for horizontal fonts. see
312   http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html
313   for more info about vertical Fonts
314*/
315Glyph GLFont::getGlyphMetrics(Uint16 character)
316{
317  Glyph rg;
318  rg.character = character;
319  TTF_GlyphMetrics(this->font, rg.character,
320                   &rg.minX, &rg.maxX,
321                   &rg.minY, &rg.maxY,
322                   &rg.advance);
323  rg.height = rg.maxY - rg.minY;
324  rg.width = rg.maxX - rg.minX;
325  rg.bearingX = (rg.advance - rg.width) / 2;
326  rg.bearingY = rg.maxY;
327  return rg;
328}
329
330/**
331   \brief entering 2D Mode
332   
333   this is a GL-Projection-mode, that is orthogonal, for placing the font in fron of everything else
334*/
335void GLFont::enter2DMode(void)
336{
337  SDL_Surface *screen = SDL_GetVideoSurface();
338 
339  /* Note, there may be other things you need to change,
340     depending on how you have your OpenGL state set up.
341  */
342  glPushAttrib(GL_ENABLE_BIT);
343  glDisable(GL_DEPTH_TEST);
344  glDisable(GL_CULL_FACE);
345  glEnable(GL_TEXTURE_2D);
346 
347  /* This allows alpha blending of 2D textures with the scene */
348  glEnable(GL_BLEND);
349  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
350 
351  glViewport(0, 0, screen->w, screen->h);
352 
353  glMatrixMode(GL_PROJECTION);
354  glPushMatrix();
355  glLoadIdentity();
356 
357  glOrtho(0.0, (GLdouble)screen->w, (GLdouble)screen->h, 0.0, 0.0, 1.0);
358 
359  glMatrixMode(GL_MODELVIEW);
360  glPushMatrix();
361  glLoadIdentity();
362 
363  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
364}
365
366/**
367   \brief leaves the 2DMode again also \see GLFont::enter2DMode(void)
368*/
369void GLFont::leave2DMode(void)
370{
371        glMatrixMode(GL_MODELVIEW);
372        glPopMatrix();
373
374        glMatrixMode(GL_PROJECTION);
375        glPopMatrix();
376
377        glPopAttrib();
378}
379
380/**
381   \brief Loads a Font from an SDL_surface into a texture.
382   \param surface The surface to make the texture of
383   \param texcoord The texture coordinates of the 4 corners of the texture
384   \returns the ID of the texture
385*/
386GLuint GLFont::loadTexture(SDL_Surface *surface, GLfloat *texcoord)
387{
388  GLuint texture;
389  int w, h;
390  SDL_Surface *image;
391  SDL_Rect area;
392  Uint32 saved_flags;
393  Uint8  saved_alpha;
394 
395  /* Use the surface width and height expanded to powers of 2 */
396  w = powerOfTwo(surface->w);
397  h = powerOfTwo(surface->h);
398  texcoord[0] = 0.0f;                   /* Min X */
399  texcoord[1] = 0.0f;                   /* Min Y */
400  texcoord[2] = (GLfloat)surface->w / w;        /* Max X */
401  texcoord[3] = (GLfloat)surface->h / h;        /* Max Y */
402 
403  image = SDL_CreateRGBSurface(
404                               SDL_SWSURFACE,
405                               w, h,
406                               32,
407#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
408                               0x000000FF, 
409                               0x0000FF00, 
410                               0x00FF0000, 
411                               0xFF000000
412#else
413                               0xFF000000,
414                               0x00FF0000, 
415                               0x0000FF00, 
416                               0x000000FF
417#endif
418                               );
419  if ( image == NULL ) {
420    return 0;
421  }
422 
423  /* Save the alpha blending attributes */
424  saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
425  saved_alpha = surface->format->alpha;
426  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
427    SDL_SetAlpha(surface, 0, 0);
428  }
429 
430  /* Copy the surface into the GL texture image */
431  area.x = 0;
432  area.y = 0;
433  area.w = surface->w;
434  area.h = surface->h;
435  SDL_BlitSurface(surface, &area, image, &area);
436 
437  /* Restore the alpha blending attributes */
438  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
439    SDL_SetAlpha(surface, saved_flags, saved_alpha);
440  }
441 
442  /* Create an OpenGL texture for the image */
443  glGenTextures(1, &texture);
444  glBindTexture(GL_TEXTURE_2D, texture);
445  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
446  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
447  glTexImage2D(GL_TEXTURE_2D,
448               0,
449               GL_RGBA,
450               w, h,
451               0,
452               GL_RGBA,
453               GL_UNSIGNED_BYTE,
454               image->pixels);
455  SDL_FreeSurface(image); /* No longer needed */
456 
457  return texture;
458}
459
460/**
461   \brief Quick utility function for texture creation
462   \param input an integer
463   \returns the next bigger 2^n-integer than input
464*/
465int GLFont::powerOfTwo(int input)
466{
467  int value = 1;
468 
469  while ( value < input ) {
470    value <<= 1;
471  }
472  return value;
473}
474
475
476/**
477   \brief checks if the compiled version and the local version of SDL_ttf match.
478   \returns true if match, false otherwise
479*/
480bool GLFont::checkVersion(void)
481{
482  SDL_version compile_version;
483  SDL_version link_version;
484  TTF_VERSION(&compile_version);
485  link_version = *TTF_Linked_Version();
486
487  if (compile_version.major == link_version.major &&
488      compile_version.minor == link_version.minor &&
489      compile_version.patch == link_version.patch)
490    {
491      return true;
492    }
493  else
494    {
495      PRINTF(2)("compiled with SDL_ttf version: %d.%d.%d\n", 
496                compile_version.major,
497                compile_version.minor,
498                compile_version.patch);
499     
500      PRINTF(2)("running with SDL_ttf version: %d.%d.%d\n", 
501                link_version.major,
502                link_version.minor,
503                link_version.patch);
504      return false;
505    }
506}
507
508
509
510/**
511   \brief a simple function to get some interesting information about this class
512*/
513void GLFont::debug(void)
514{
515
516  // print the loaded font's style
517  int style;
518  style=TTF_GetFontStyle(this->font);
519  PRINTF(0)("The font style is:");
520  if(style==TTF_STYLE_NORMAL)
521    PRINTF(0)(" normal");
522  else {
523    if(style&TTF_STYLE_BOLD)
524      PRINTF(0)(" bold");
525    if(style&TTF_STYLE_ITALIC)
526      PRINTF(0)(" italic");
527    if(style&TTF_STYLE_UNDERLINE)
528      PRINTF(0)(" underline");
529  }
530  PRINTF(0)("\n");
531
532
533}
Note: See TracBrowser for help on using the repository browser.