Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/graphics/text_engine.cc @ 5070

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

orxonox/trunk: taken out the extremely useless debug-information

File size: 23.2 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   for some fonts and licenses visit: =http://www.dafont.com/en/font.php=
16
17   !! IMPORTANT !! When using ttf fonts clear the license issues prior to
18   adding them to orxonox. This is really important, because we do not
19   want to offend anyone.
20*/
21
22#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_FONT
23
24#include "text_engine.h"
25
26using namespace std;
27
28#include <stdlib.h>
29#include <stdio.h>
30#include <string.h>
31
32#include "graphics_engine.h"
33#include "resource_manager.h"
34
35#include "p_node.h"
36#include "vector.h"
37#include "debug.h"
38#include "list.h"
39
40////////////
41/// TEXT ///
42////////////
43/**
44 *  creates a new Text Element
45 * @param font the Font to render this text in
46 * @param type The renderType to display this font in
47
48   this constructor is private, because the user should initialize
49   a text with the TextEngine.
50*/
51Text::Text(Font* font, int type)
52{
53  this->setClassID(CL_TEXT, "Text");
54
55  // initialize this Text
56  this->bindNode = NULL;
57  this->font = font;
58  this->text = NULL;
59  this->alignment = TEXT_DEFAULT_ALIGNMENT;
60  this->texture = 0;
61  this->blending = 1.0f;
62  this->setType(type);
63
64  this->setText(FONT_DEFAULT_TEXT);
65}
66
67/**
68 *  deletes a Text out of memory
69
70   This also ereases the text from the textList of the TextEngine
71*/
72Text::~Text()
73{
74  TextEngine::getInstance()->deleteText(this);
75}
76
77/**
78 *  sets the Type of this Text
79 * @param type the type to set.
80*/
81void Text::setType(int type)
82{
83  if (this->font->font)
84    this->type = type;
85  else
86    this->type = TEXT_DYNAMIC;
87}
88
89/**
90 *  Sets a new Text to the font
91 * @param text the new text to set
92*/
93void Text::setText(const char* text)
94{
95  if (this->text)
96    delete []this->text;
97  this->text = new char[strlen(text)+1];
98  strcpy(this->text, text);
99
100
101  // setting up the Text-Width if DYNAMIC
102  if (this->type == TEXT_DYNAMIC)
103    {
104      Glyph** glyphArray = this->font->getGlyphArray();
105
106      int width = 0;
107      char* tmpText = this->text;
108      while (*tmpText != '\0')
109        {
110          if(glyphArray[*tmpText])
111            {
112              width += glyphArray[*tmpText]->width;
113            }
114          tmpText++;
115        }
116      this->posSize.w = width;
117    }
118}
119
120/**
121 *  sets a new color to the font
122 * @param r Red
123 * @param g Green
124 * @param b Blue
125*/
126void Text::setColor(Uint8 r, Uint8 g, Uint8 b)
127{
128  this->color.r = r;
129  this->color.g = g;
130  this->color.b = b;
131}
132
133/**
134 *  creates a texture out of the given parameters
135
136   this has to be called every time by the user, to if changes were made.
137   this is only for TEXT_STATIC-mode
138*/
139void Text::createTexture()
140{
141  SDL_Surface* tmpSurf;
142  if (this->texture)
143    glDeleteTextures(1, &this->texture);
144  if (likely(this->font != NULL))
145    tmpSurf = TTF_RenderText_Blended(this->font->font,
146                                     this->text,
147                                     this->color);
148  if (tmpSurf)
149    this->texture = loadTexture(tmpSurf, &this->texCoord);
150
151  this->posSize.w = tmpSurf->w;
152  this->posSize.h = tmpSurf->h;
153  SDL_FreeSurface(tmpSurf);
154}
155
156/**
157 *  draws the Text
158*/
159void Text::draw() const
160{
161  glPushMatrix();
162  // transform for alignment.
163  if (this->alignment == TEXT_ALIGN_RIGHT)
164    glTranslatef(-this->posSize.w, 0, 0);
165  else if (this->alignment == TEXT_ALIGN_CENTER || this->alignment == TEXT_ALIGN_SCREEN_CENTER)
166    glTranslatef(-this->posSize.w/2, 0, 0);
167
168  // drawing this Text.
169  // setting the Blending effects
170  glColor4f(1.0f,1.0f,1.0f, this->blending);
171  glEnable(GL_BLEND);
172  glEnable(GL_TEXTURE_2D);
173  glBlendFunc(GL_SRC_ALPHA, GL_ONE);
174
175  if(type == TEXT_STATIC)
176    {
177      glBindTexture(GL_TEXTURE_2D, this->texture);
178      glBegin(GL_QUADS);
179
180      glTexCoord2f(this->texCoord.minU, this->texCoord.minV);
181      glVertex2f(this->absPos2D.x,   this->absPos2D.);
182
183      glTexCoord2f(this->texCoord.maxU, this->texCoord.minV);
184      glVertex2f(this->absPos2D.x + this->posSize.w, this->absPos2D.);
185
186      glTexCoord2f(this->texCoord.maxU, this->texCoord.maxV);
187      glVertex2f(this->absPos2D.x + this->posSize.w, absPos2D.y + this->posSize.h);
188
189      glTexCoord2f(this->texCoord.minU, this->texCoord.maxV);
190      glVertex2f(absPos2D.x, absPos2D.y + this->posSize.h);
191
192      glEnd();
193    }
194  else //(if type == TEXT_DYNAMIC)
195    {
196      Glyph** glyphArray = this->font->getGlyphArray();
197      glBindTexture(GL_TEXTURE_2D, this->font->getFastTextureID());
198      //      glEnable(GL_TEXTURE_2D);
199      glTranslatef(absPos2D.x, absPos2D.y, 0);
200
201      const char* tmpText = this->text;
202      while (*tmpText != '\0')
203        {
204          if(glyphArray[*tmpText])
205            {
206              glCallList(glyphArray[*tmpText]->displayList);
207              glTranslatef(glyphArray[*tmpText]->width, 0, 0);
208            }
209          tmpText++;
210        }
211    }
212  glPopMatrix();
213}
214
215/**
216 *  prints out some nice debug information about this text
217*/
218void Text::debug() const
219{
220  PRINT(0)("=== TEXT: %s ===\n", this->text);
221  if (this->bindNode)
222    PRINT(0)("is bind to %s; ref=%p\n", this->bindNode->getName(), this->bindNode);
223  PRINT(0)("Relative Position: (%d::%d)\n", this->posSize.x, this->posSize.y);
224  PRINT(0)("Color: %d %d %d\n", this->color.r, this->color.g, this->color.b);
225}
226
227
228////////////
229/// UTIL ///
230////////////
231/**
232 *  Loads a Font from an SDL_surface into a texture.
233 * @param surface The surface to make the texture of
234 * @param texCoord The texture coordinates of the 4 corners of the texture
235 * @returns the ID of the texture
236*/
237GLuint Text::loadTexture(SDL_Surface *surface, TexCoord* texCoord)
238{
239  GLuint texture;
240  int w, h;
241  SDL_Surface *image;
242  SDL_Rect area;
243  Uint32 saved_flags;
244  Uint8  saved_alpha;
245
246  /* Use the surface width and height expanded to powers of 2 */
247  w = powerOfTwo(surface->w);
248  h = powerOfTwo(surface->h);
249  if (texCoord)
250    {
251      texCoord->minU = 0.0f;
252      texCoord->minV = 0.0f;
253      texCoord->maxU = (GLfloat)surface->w / w;
254      texCoord->maxV = (GLfloat)surface->h / h;
255    }
256  image = SDL_CreateRGBSurface(SDL_SWSURFACE,
257                               w, h,
258                               32,
259#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
260                               0x000000FF,
261                               0x0000FF00,
262                               0x00FF0000,
263                               0xFF000000
264#else
265                               0xFF000000,
266                               0x00FF0000,
267                               0x0000FF00,
268                               0x000000FF
269#endif
270                               );
271  if ( image == NULL ) {
272    return 0;
273  }
274
275  /* Save the alpha blending attributes */
276  saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
277  saved_alpha = surface->format->alpha;
278  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
279    SDL_SetAlpha(surface, 0, 0);
280  }
281
282  /* Copy the surface into the GL texture image */
283  area.x = 0;
284  area.y = 0;
285  area.w = surface->w;
286  area.h = surface->h;
287  SDL_BlitSurface(surface, &area, image, &area);
288
289  /* Restore the alpha blending attributes */
290  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
291    SDL_SetAlpha(surface, saved_flags, saved_alpha);
292  }
293
294  /* Create an OpenGL texture for the image */
295  glGenTextures(1, &texture);
296  glBindTexture(GL_TEXTURE_2D, texture);
297  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
298  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
299  glTexImage2D(GL_TEXTURE_2D,
300               0,
301               GL_RGBA,
302               w, h,
303               0,
304               GL_RGBA,
305               GL_UNSIGNED_BYTE,
306               image->pixels);
307  SDL_FreeSurface(image); /* No longer needed */
308
309  return texture;
310}
311
312/**
313 *  Quick utility function for texture creation
314 * @param input an integer
315 * @returns the next bigger 2^n-integer than input
316*/
317int Text::powerOfTwo(int input)
318{
319  int value = 1;
320
321  while ( value < input ) {
322    value <<= 1;
323  }
324  return value;
325}
326
327
328////////////
329/// FONT ///
330////////////
331/**
332 *  constructs a Font
333 * @param fontFile the File to load the font from
334 * @param fontSize the Size of the Font in Pixels
335 * @param r Red value of the Font.
336 * @param g Green value of the Font.
337 * @param b Blue value of the Font.
338*/
339Font::Font(const char* fontFile, unsigned int fontSize, Uint8 r, Uint8 g, Uint8 b)
340{
341  this->setClassID(CL_FONT, "Font");
342  // setting default values.
343  this->font = NULL;
344  this->fontFile = NULL;
345  this->glyphArray = NULL;
346  this->fastTextureID = 0;
347
348  this->setSize(fontSize);
349
350  this->setFont(fontFile);
351
352  this->setStyle("c");//TTF_STYLE_NORMAL);
353
354  this->setFastColor(r, g, b);
355
356  this->fastTextureID = this->createFastTexture();
357}
358
359/**
360 *  destructs a font
361*/
362Font::~Font()
363{
364  // deleting the List of all Texts
365
366  // deleting all Glyphs
367  if (this->glyphArray)
368    {
369      for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)
370        delete this->glyphArray[i];
371      delete []this->glyphArray;
372    }
373
374  // erease this font out of the memory.
375  if (likely(this->font != NULL))
376    TTF_CloseFont(this->font);
377}
378
379/**
380 *  sets The Font.
381 * @param fontFile The file containing the font.
382 * @returns true if loaded, false if something went wrong, or if a font was loaded before.
383*/
384bool Font::setFont(const char* fontFile)
385{
386  if (!this->fontFile)
387    {
388      this->setName(fontFile);
389      this->fontFile = new char[strlen(fontFile)+1];
390      strcpy(this->fontFile, fontFile);
391
392      this->font = TTF_OpenFont(this->fontFile, this->fontSize);
393      if(!this->font)
394        {
395          PRINTF(1)("TTF_OpenFont: %s\n", TTF_GetError());
396          return false;
397        }
398      else
399          return true;
400    }
401  else
402    {
403      PRINTF(2)("Font already initialized, unable to change it now.\n");
404      return false;
405    }
406}
407
408/**
409 *  sets a specific renderStyle
410 * @param renderStyle the Style to render: a char-array containing:
411   i: italic, b: bold, u, underline
412*/
413void Font::setStyle(const char* renderStyle)
414{
415  this->renderStyle = TTF_STYLE_NORMAL;
416
417  for (int i = 0; i < strlen(renderStyle); i++)
418    if (strncmp(renderStyle+i, "b", 1) == 0)
419      this->renderStyle |= TTF_STYLE_BOLD;
420    else if (strncmp(renderStyle+i, "i", 1) == 0)
421      this->renderStyle |= TTF_STYLE_ITALIC;
422    else if (strncmp(renderStyle+i, "u", 1) == 0)
423      this->renderStyle |= TTF_STYLE_UNDERLINE;
424
425  if (likely(this->font != NULL))
426    TTF_SetFontStyle(this->font, this->renderStyle);
427  else
428    PRINTF(2)("Font was not initialized, please do so before setting the Font-Style.\n");
429}
430
431/**
432 *  Sets a new Size to the font
433 * @param fontSize The new Size in pixels.
434*/
435void Font::setSize(unsigned int fontSize)
436{
437  this->fontSize = fontSize;
438}
439
440/**
441 *  sets a new color to the font
442 * @param r Red
443 * @param g Green
444 * @param b Blue
445*/
446void Font::setFastColor(Uint8 r, Uint8 g, Uint8 b)
447{
448  this->fastColor.r = r;
449  this->fastColor.g = g;
450  this->fastColor.b = b;
451}
452
453/**
454 * @returns the maximum height of the Font, if the font was initialized, 0 otherwise
455*/
456int Font::getMaxHeight()
457{
458  if (likely (this->font != NULL))
459    return TTF_FontHeight(this->font);
460  else
461    return 0;
462}
463
464/**
465 * @returns the maximum ascent of the Font, if the font was initialized, 0 otherwise
466
467   the ascent is the pixels of the font above the baseline
468*/
469int Font::getMaxAscent()
470{
471  if (likely(this->font != NULL))
472    return TTF_FontAscent(this->font);
473  else
474    return 0;
475}
476
477/**
478 * @returns the maximum descent of the Font, if the font was initialized, 0 otherwise
479
480   the descent is the pixels of the font below the baseline
481*/
482int Font::getMaxDescent()
483{
484  if (likely(this->font != NULL))
485    return TTF_FontDescent(this->font);
486  else
487    return 0;
488}
489
490/**
491 * @param character The character to get info about.
492 * @returns a Glyph struct of a character. This Glyph is a pointer,
493   and MUST be deleted by the user..
494
495   This only works for horizontal fonts. see
496   http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html
497   for more info about vertical Fonts
498*/
499Glyph* Font::getGlyphMetrics(Uint16 character)
500{
501  Glyph* rg = new Glyph;
502  rg->character = character;
503  if (likely (this->font!= NULL))
504    TTF_GlyphMetrics(this->font, rg->character,
505                     &rg->minX, &rg->maxX,
506                     &rg->minY, &rg->maxY,
507                     &rg->advance);
508  rg->height = rg->maxY - rg->minY;
509  rg->width = rg->maxX - rg->minX;
510  rg->bearingX = (rg->advance - rg->width) / 2;
511  rg->bearingY = rg->maxY;
512  return rg;
513}
514
515GLuint Font::createFastTexture()
516{
517  /* interesting GLYPHS:
518   *  32: space
519   *  33-47: Special Characters.
520   *  48-57: 0-9
521   *  58-63: some more special chars (minor)
522   *  65-90: A-Z
523   *  97-122: a-z
524   */
525  int numberOfGlyphs = 91;
526
527  this->initGlyphs(32, numberOfGlyphs);
528  this->glyphArray[32]->width = fontSize/3; //!< @todo find out the real size of a Space
529
530  int rectSize = this->findOptimalFastTextureSize();
531
532  // setting default values. (maybe not needed afterwards)
533  SDL_Color tmpColor;  tmpColor.r = tmpColor.g = tmpColor.b = 0;
534  // Surface definition.
535  SDL_Rect tmpRect; // this represents a Rectangle for blitting.
536  SDL_Surface* tmpSurf =  SDL_CreateRGBSurface(SDL_SWSURFACE,
537                                               rectSize, rectSize,
538                                               32,
539#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
540                                               0x000000FF,
541                                               0x0000FF00,
542                                               0x00FF0000,
543                                               0xFF000000
544#else
545                                               0xFF000000,
546                                               0x00FF0000,
547                                               0x0000FF00,
548                                               0x000000FF
549#endif
550                                               );
551  tmpRect.x = 0; tmpRect.y = 0; tmpRect.w = tmpSurf->w; tmpRect.h = tmpSurf->h;
552  SDL_SetClipRect(tmpSurf, &tmpRect);
553  int maxLineHeight = 0;
554
555  // all the interessting Glyphs
556  for (int i = 0; i <= 127; i++)
557    {
558      SDL_Surface* glyphSurf = NULL;
559      Glyph* tmpGlyph;
560
561      if (tmpGlyph = this->glyphArray[i])
562        {
563          if (tmpGlyph->height > maxLineHeight)
564            maxLineHeight = tmpGlyph->height;
565
566          if (tmpRect.x+tmpGlyph->width > tmpSurf->w)
567            {
568              tmpRect.x = 0;
569              tmpRect.y = tmpRect.y + maxLineHeight + 1;
570              maxLineHeight = 0;
571            }
572          if (tmpRect.y + maxLineHeight > tmpSurf->h)
573            {
574              PRINTF(1)("Protection, so font cannot write over the boundraries error (this should not heappen\n");
575              break;
576            }
577          // reading in the new Glyph
578          if (likely(this->font != NULL))
579            glyphSurf = TTF_RenderGlyph_Blended(this->font, i, this->fastColor);
580          if( glyphSurf != NULL )
581            {
582
583              SDL_SetAlpha(glyphSurf, 0, 0);
584
585              SDL_BlitSurface(glyphSurf, NULL, tmpSurf, &tmpRect);
586              TexCoord tmpTexCoord;
587              tmpTexCoord.minU = (float)tmpRect.x/(float)tmpSurf->w;
588              tmpTexCoord.maxU = (float)(tmpRect.x +1 +tmpGlyph->width)/(float)tmpSurf->w;
589              tmpTexCoord.minV = (float)tmpRect.y/(float)tmpSurf->w;
590              tmpTexCoord.maxV = (float)(tmpRect.y+tmpGlyph->height)/(float)tmpSurf->w;
591              tmpGlyph->displayList = glGenLists(1);
592
593              glNewList(tmpGlyph->displayList, GL_COMPILE);
594              glBegin(GL_QUADS);
595              glTexCoord2f(tmpTexCoord.minU, tmpTexCoord.minV);
596              glVertex2d(0, 0);
597              glTexCoord2f(tmpTexCoord.minU, tmpTexCoord.maxV);
598              glVertex2d(0, tmpGlyph->height);
599              glTexCoord2f(tmpTexCoord.maxU, tmpTexCoord.maxV);
600              glVertex2d(tmpGlyph->width, tmpGlyph->height);
601              glTexCoord2f(tmpTexCoord.maxU, tmpTexCoord.minV);
602              glVertex2d(tmpGlyph->width, 0);
603              glEnd();
604              glEndList();
605              SDL_FreeSurface(glyphSurf);
606
607              tmpRect.x += tmpGlyph->width + 2;
608
609              // Outputting Glyphs to BMP-files.
610              /*
611                char outname[64];
612                if (i < 10)
613                sprintf( outname, "glyph-00%d.bmp", i );
614                else if (i <100)
615                sprintf( outname, "glyph-0%d.bmp", i );
616                else
617                sprintf( outname, "glyph-%d.bmp", i );
618                SDL_SaveBMP(tmpSurf, outname);
619              */
620            }
621        }
622    }
623
624  GLuint texture;
625  glGenTextures(1, &texture);
626  glBindTexture(GL_TEXTURE_2D, texture);
627  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
628  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
629  glTexImage2D(GL_TEXTURE_2D,
630               0,
631               GL_RGBA,
632               tmpSurf->w, tmpSurf->h,
633               0,
634               GL_RGBA,
635               GL_UNSIGNED_BYTE,
636               tmpSurf->pixels);
637  SDL_FreeSurface(tmpSurf);
638  return texture;
639}
640
641/**
642 *  stores Glyph Metrics in an Array.
643 * @param from The Glyph to start from.
644 * @param count The number of Glyphs to start From.
645*/
646void Font::initGlyphs(Uint16 from, Uint16 count)
647{
648  /* initialize the Array, and set all its entries to NULL
649   *  only if the Glyph-array has not been initialized
650   */
651  if (!this->glyphArray)
652    {
653      this->glyphArray = new Glyph*[FONT_HIGHEST_KNOWN_CHAR];
654      for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)
655        this->glyphArray[i] = NULL;
656    }
657
658  Uint16 lastGlyph = from + count;
659
660  for (int i = from; i <= lastGlyph; i++)
661    {
662      // setting up all the Glyphs we like.
663      glyphArray[i] = getGlyphMetrics(i);
664    }
665  return;
666}
667
668/**
669 * @returns the optimal size to use as the texture size
670
671   @todo: this algorithm can be a lot more faster, althought it does
672   not really matter within the init-context, and 128 glyphs.
673
674   This function searches for a 2^n sizes texture-size, this is for
675   openGL-version < 1.2 compatibility ( and because it is realy easy like this :))
676*/
677int Font::findOptimalFastTextureSize()
678{
679  int i;
680  int x,y; // the counters
681  int maxLineHeight;
682  int size = 32;      // starting Value, we have to start somewhere 32 seems reasonable.
683  bool sizeOK = false;
684  Glyph* tmpGlyph;
685
686  while (!sizeOK)
687    {
688      x = 0; y = 0;
689      maxLineHeight = 0;
690      for (i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)
691        {
692          if(tmpGlyph = this->glyphArray[i])
693            {
694              // getting the height of the highest Glyph in the Line.
695              if (tmpGlyph->height > maxLineHeight)
696                maxLineHeight = tmpGlyph->height;
697
698              if (x + tmpGlyph->width > size)
699                {
700                  x = 0;
701                  y = y + maxLineHeight;
702                  maxLineHeight = 0;
703                }
704              if (y + maxLineHeight + 1 > size)
705                break;
706              x += tmpGlyph->width + 1;
707
708            }
709        }
710      if (i == FONT_HIGHEST_KNOWN_CHAR)
711        sizeOK = true;
712      else
713        size *= 2;
714    }
715  return size;
716}
717
718
719/**
720 *  a simple function to get some interesting information about this class
721*/
722void Font::debug()
723{
724  // print the loaded font's style
725  int style;
726  if (likely(this->font != NULL))
727    style = TTF_GetFontStyle(this->font);
728  PRINTF(0)("The font style is:");
729  if(style==TTF_STYLE_NORMAL)
730    PRINTF(0)(" normal");
731  else {
732    if(style&TTF_STYLE_BOLD)
733      PRINTF(0)(" bold");
734    if(style&TTF_STYLE_ITALIC)
735      PRINTF(0)(" italic");
736    if(style&TTF_STYLE_UNDERLINE)
737      PRINTF(0)(" underline");
738  }
739  PRINTF(0)("\n");
740}
741
742
743///////////////////
744/// TEXT-ENGINE ///
745///////////////////
746/**
747 *  standard constructor
748*/
749TextEngine::TextEngine ()
750{
751   this->setClassID(CL_TEXT_ENGINE, "TextEngine");
752   this->setName("TextEngine");
753   this->enableFonts();
754
755   this->textList = new tList<Text>;
756}
757
758/**
759 *  the singleton reference to this class
760*/
761TextEngine* TextEngine::singletonRef = NULL;
762
763/**
764 *  standard deconstructor
765
766*/
767TextEngine::~TextEngine ()
768{
769  this->disableFonts();
770
771  delete this->textList;
772
773  TextEngine::singletonRef = NULL;
774}
775
776/**
777 *  function to enable TTF_Fonts
778*/
779void TextEngine::enableFonts()
780{
781  if (!TTF_WasInit())
782    {
783      if(TTF_Init()==-1)
784        PRINTF(1)("TTF_Init: %s\n", TTF_GetError());
785
786      TextEngine::checkVersion();
787    }
788  else
789    PRINTF(4)("Fonts already initialized\n");
790}
791
792/**
793 *  function to disable TTF_fonts
794*/
795void TextEngine::disableFonts()
796{
797  if (TTF_WasInit())
798    {
799      TTF_Quit();
800    }
801  else
802    PRINTF(4)("Fonts were not initialized.\n");
803}
804
805/**
806 *  creates a new Text with a certain font.
807   \see Font::Font
808   \see Text::Text
809*/
810Text* TextEngine::createText(const char* fontFile, unsigned int fontSize, int textType, Uint8 r, Uint8 g, Uint8 b)
811{
812  Font* tmpFont;
813  Text* newText;
814  Vector tmpVec;
815
816  tmpVec = Vector(r, g, b);
817  tmpFont = (Font*)ResourceManager::getInstance()->load(fontFile, TTF, RP_GAME, &fontSize, &tmpVec);
818  if (!tmpFont)
819    {
820      PRINTF(2)("Font %s could not be loaded, probably file not found\n", fontFile);
821      return NULL;
822    }
823
824  newText = new Text(tmpFont, TEXT_DYNAMIC);
825  textList->add(newText);
826
827  return newText;
828}
829
830/**
831 *  removes a Text from the List
832 * @param text: the text to delete
833
834   this only ereases allocated memory, and removes the text
835   The normal way to call it, is through "delete text;"
836   So you do not have to concetn yourselves with this.
837*/
838void TextEngine::deleteText(Text* text)
839{
840  ResourceManager::getInstance()->unload(text->font);
841  textList->remove(text);
842}
843
844/**
845 *  deletes all the Text, and tries to delete all allocated fonts
846*/
847void TextEngine::flush()
848{
849  tIterator<Text>* textIterator = textList->getIterator();
850  Text* text = textIterator->nextElement();
851  while( text != NULL)
852    {
853      delete text;
854      text = textIterator->nextElement();
855    }
856  delete textIterator;
857}
858
859/**
860 *  outputs some nice Debug information
861
862   @todo there should also be something outputted about Font
863*/
864void TextEngine::debug() const
865{
866  PRINT(0)("+-------------------------------+\n");
867  PRINT(0)("+ TEXT ENGINE DEBUG INFORMATION +\n");
868  PRINT(0)("+-------------------------------+\n");
869  PRINT(0)("Reference: %p; Text Counts: %d\n", this, this->textList->getSize());
870
871  tIterator<Text>* textIterator = textList->getIterator();
872  Text* text = textIterator->nextElement();
873  while( text != NULL)
874    {
875      text->debug();
876      text = textIterator->nextElement();
877    }
878  delete textIterator;
879  PRINT(0)("+---------------------------TE--+\n");
880}
881
882
883/**
884 *  checks if the compiled version and the local version of SDL_ttf match.
885 * @returns true if match, false otherwise
886*/
887bool TextEngine::checkVersion()
888{
889  SDL_version compile_version;
890  SDL_version link_version;
891  TTF_VERSION(&compile_version);
892  link_version = *TTF_Linked_Version();
893
894  if (compile_version.major == link_version.major &&
895      compile_version.minor == link_version.minor &&
896      compile_version.patch == link_version.patch)
897    {
898      return true;
899    }
900  else
901    {
902      PRINTF(2)("compiled with SDL_ttf version: %d.%d.%d\n",
903                compile_version.major,
904                compile_version.minor,
905                compile_version.patch);
906
907      PRINTF(2)("running with SDL_ttf version: %d.%d.%d\n",
908                link_version.major,
909                link_version.minor,
910                link_version.patch);
911      return false;
912    }
913}
Note: See TracBrowser for help on using the repository browser.