Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: reimplemented the list functions, as i did before in revision 5110.
This time, i looked out for the bugs, and i think i found one

@patrick: i know, that you do not want to code at the moment… :/ → see mail

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