Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/textEngine/src/lib/graphics/font/text_engine.cc @ 3771

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

orxonox/branches/textEngine: no more compile-warnings :)

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