Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/textEngine: moved the fonts into a new File textEngine, and also implemented a TextEngine-Singleton-class

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