Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/textEngine: unloading works

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