Index: orxonox/branches/textEngine/src/lib/graphics/font/text_engine.cc
===================================================================
--- orxonox/branches/textEngine/src/proto/proto_singleton.cc	(revision 3681)
+++ orxonox/branches/textEngine/src/lib/graphics/font/text_engine.cc	(revision 3766)
@@ -10,21 +10,809 @@
 
    ### File Specific:
-   main-programmer: ...
+   main-programmer: Benjamin Grauer
    co-programmer: ...
-*/
-
-//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
-
-#include "proto_singleton.h"
+
+   for some fonts and licenses visit: =http://www.dafont.com/en/font.php=
+
+   !! IMPORTANT !! When using ttf fonts clear the license issues prior to
+   adding them to orxonox. This is really important, because we do not 
+   want to defend anyone.
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_FONT
+
+#include "text_engine.h"
 
 using namespace std;
 
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "graphics_engine.h"
+#include "p_node.h"
+#include "vector.h"
+#include "debug.h"
+
+
+////////////
+/// FONT ///
+////////////
+
+/**
+   \brief constructs a Font
+   \param fontFile the File to load the font from
+*/
+Font::Font(const char* fontFile)
+{
+  this->init(fontFile);
+}
+
+/**
+   \brief destructs a font
+*/
+Font::~Font(void)
+{
+  delete this->currentText;
+
+  if (this->glyphArray)
+    {
+      for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)
+	delete this->glyphArray[i];
+      delete []this->glyphArray;
+    }
+
+  if (this->font)
+    TTF_CloseFont(this->font);
+}
+
+/**
+   \brief initializes a new Font
+   \param fontFile The file to load a Font from
+   \param fontSize the Size in pixels of the Font
+*/
+bool Font::init(const char* fontFile, unsigned int fontSize)
+{
+  if (!TTF_WasInit())
+    TextEngine::enableFonts();
+
+  // setting default values.
+  this->font = NULL;
+  this->fontFile = NULL;
+  this->glyphArray = NULL;
+  this->fastTextureID = 0;
+
+  this->currentText = new Text;
+
+  this->currentText->bindNode = NULL;
+  this->currentText->text = NULL;
+  this->currentText->texture = 0;
+  
+  this->setSize(fontSize);
+  this->setType(TEXT_DYNAMIC);
+  
+  this->currentText->renderStyle = TTF_STYLE_NORMAL;
+
+  this->setFont(fontFile);
+
+  this->setColor(0, 255, 0);
+  this->setPosition(0, 0);
+
+  this->setText(FONT_DEFAULT_TEXT);
+  
+  this->setColor(0,255,0);
+
+  this->createTexture();
+
+  this->fastTextureID = this->createFastTexture();
+}
+
+/**
+   \brief sets The Font.
+   \param fontFile The file containing the font.
+   \returns true if loaded, false if something went wrong, or if a font was loaded before.
+*/
+bool Font::setFont(const char* fontFile)
+{
+  if (!this->fontFile)
+    {
+      this->fontFile = new char[strlen(fontFile)+1];
+      strcpy(this->fontFile, fontFile);
+      
+      this->font = TTF_OpenFont(this->fontFile, this->fontSize);
+      if(!this->font) 
+	{
+	  PRINTF(1)("TTF_OpenFont: %s\n", TTF_GetError());
+	  return false;
+      }
+      return true;
+    }
+  else
+    {
+      PRINTF(2)("Font already initialized, unable to change it now.\n");
+      return false;
+    }
+}
+
+void Font::setBindNode(PNode* bindNode)
+{
+  this->currentText->bindNode = bindNode;
+}
+
+/**
+   \brief sets the Type of this Text
+   \param type the type to set.
+*/
+void Font::setType(int type)
+{
+  this->currentText->type = type;
+}
+
+
+/**
+   \brief Sets a new Text to the font
+   \param text the new text to set
+*/
+void Font::setText(const char* text)
+{
+  if (this->currentText->text)
+    delete []this->currentText->text;
+  this->currentText->text = new char[strlen(text)+1];
+  strcpy(this->currentText->text, text);
+}
+
+/**
+   \brief sets a specific renderStyle
+   \param renderStyle the Style to render: a char-array containing:
+   i: italic, b: bold, u, underline
+*/
+void Font::setStyle(char* renderStyle)
+{
+  this->currentText->renderStyle = TTF_STYLE_NORMAL;
+  
+  for (int i = 0; i < strlen(renderStyle); i++)
+    if (strncmp(renderStyle+i, "b", 1) == 0) 
+      this->currentText->renderStyle |= TTF_STYLE_BOLD;
+    else if (strncmp(renderStyle+i, "i", 1) == 0)
+      this->currentText->renderStyle |= TTF_STYLE_ITALIC;
+    else if (strncmp(renderStyle+i, "u", 1) == 0) 
+      this->currentText->renderStyle |= TTF_STYLE_UNDERLINE;
+
+  if (this->font)
+    TTF_SetFontStyle(this->font, this->currentText->renderStyle);
+  else
+    PRINTF(2)("Font was not initialized, please do so before setting the Font-Style.\n");
+}
+
+/**
+   \brief Sets a new Size to the font
+   \param fontSize The new Size in pixels.
+*/
+void Font::setSize(unsigned int fontSize)
+{
+  this->fontSize = fontSize;
+}
+
+/**
+   \brief sets a new color to the font
+   \param r Red
+   \param g Green
+   \param b Blue
+*/
+void Font::setColor(Uint8 r, Uint8 g, Uint8 b)
+{
+  this->currentText->color.r = r;
+  this->currentText->color.g = g;
+  this->currentText->color.b = b;
+}
+
+/**
+   \brief sets a Position.
+   \param x the x-position in pixels from the left border
+   \param y the y-position in pixels from the top border
+*/
+void Font::setPosition(int x, int y)
+{
+  this->currentText->textPosSize.x = x;
+  this->currentText->textPosSize.y = y;
+}
+
+/**
+   \brief draws the Font
+   \todo FIX this is to slow/static
+*/
+void Font::draw(void)
+{
+  // storing all the Transformation Matrices.
+  GLdouble modMat[16];
+  GLint viewPort[4];
+  glGetDoublev(GL_PROJECTION_MATRIX, this->projMat);
+  glGetDoublev(GL_MODELVIEW_MATRIX, modMat);
+  glGetIntegerv(GL_VIEWPORT, viewPort);
+  this->enter2DMode();
+
+  // setting the Position of this Text.
+  Vector pos;
+  if (this->currentText->bindNode)
+    {
+      GLdouble x = this->currentText->bindNode->getAbsCoor().x;
+      GLdouble y = this->currentText->bindNode->getAbsCoor().y;
+      GLdouble z = this->currentText->bindNode->getAbsCoor().z;
+      GLdouble tmp[3];
+      gluProject(x, y, z, modMat, projMat, viewPort, tmp, tmp+1, tmp+2);
+      printf("test %f %f %f,\n", tmp[0], tmp[1], tmp[2]);
+      pos.x = tmp[0] + this->currentText->textPosSize.x;
+      pos.y = GraphicsEngine::getInstance()->getResolutionY() - tmp[1] + this->currentText->textPosSize.y;
+      pos.z = tmp[2];
+    }
+  else 
+    {
+      pos.x = this->currentText->textPosSize.x;
+      pos.y = this->currentText->textPosSize.y;
+      pos.z = 0;
+    }
+
+  // drawing this Text.
+  if(currentText->type == TEXT_STATIC)
+    {
+      glBindTexture(GL_TEXTURE_2D, this->currentText->texture);
+      glEnable(GL_TEXTURE_2D);
+      glBegin(GL_QUADS);
+      
+      glTexCoord2f(this->currentText->texCoord.minU, this->currentText->texCoord.minV);
+      glVertex2i(pos.x,   pos.y  );
+      
+      glTexCoord2f(this->currentText->texCoord.maxU, this->currentText->texCoord.minV);
+      glVertex2i(pos.x + this->currentText->textPosSize.w, pos.y  );
+      
+      glTexCoord2f(this->currentText->texCoord.maxU, this->currentText->texCoord.maxV);
+      glVertex2i(pos.x + this->currentText->textPosSize.w, pos.y + this->currentText->textPosSize.h);
+      
+      glTexCoord2f(this->currentText->texCoord.minU, this->currentText->texCoord.maxV);
+      glVertex2i(pos.x, pos.y + this->currentText->textPosSize.h);
+      
+      glEnd();
+    }
+  else //(if currentText->type & TEXT_DYNAMIC)
+    {
+      glBindTexture(GL_TEXTURE_2D, this->fastTextureID);
+      //      glEnable(GL_TEXTURE_2D);
+      glTranslatef(pos.x, pos.y, 0);
+
+      printf("%d, %d\n", this->fastTextureID, glyphArray[65]->displayList);
+      char* tmpText = this->currentText->text;
+      while (*tmpText != '\0')
+	{
+	  if(glyphArray[*tmpText])
+	    {
+	      glCallList(this->glyphArray[*tmpText]->displayList);
+	      glTranslatef(this->glyphArray[*tmpText]->width, 0, 0);
+	    }
+	  tmpText++;
+	}
+    }
+  this->leave2DMode();
+}
+
+/**
+   \brief creates a texture out of the given parameters
+
+   this has to be called every time by the user, to if changes were made.
+*/
+void Font::createTexture(void)
+{
+  SDL_Surface* tmpSurf;
+  if (this->currentText->texture)
+    glDeleteTextures(1, &this->currentText->texture);
+  tmpSurf = TTF_RenderText_Blended(this->font,
+				   this->currentText->text,
+				   this->currentText->color);
+  if (tmpSurf)
+    this->currentText->texture = loadTexture(tmpSurf, &this->currentText->texCoord);
+
+  this->currentText->textPosSize.w = tmpSurf->w;
+  this->currentText->textPosSize.h = tmpSurf->h;
+  SDL_FreeSurface(tmpSurf);
+}
+
+
+/**
+   \returns the maximum height of the Font, if the font was initialized, 0 otherwise
+*/
+int Font::getMaxHeight(void)
+{
+  if (this->font)
+    return TTF_FontHeight(this->font);
+  else
+    return 0;
+}
+
+/**
+   \returns the maximum ascent of the Font, if the font was initialized, 0 otherwise
+
+   the ascent is the pixels of the font above the baseline
+*/
+int Font::getMaxAscent(void)
+{
+  if (this->font)
+    return TTF_FontAscent(this->font);
+  else
+    return 0;
+}
+
+/**
+   \returns the maximum descent of the Font, if the font was initialized, 0 otherwise
+
+   the descent is the pixels of the font below the baseline
+*/
+int Font::getMaxDescent(void)
+{
+  if (this->font)
+    return TTF_FontDescent(this->font);
+  else
+    return 0;
+}
+
+/**
+   \param character The character to get info about.
+   \returns a Glyph struct of a character. This Glyph is a pointer,
+   and MUST be deleted by the user..
+
+   This only works for horizontal fonts. see 
+   http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html
+   for more info about vertical Fonts
+*/
+Glyph* Font::getGlyphMetrics(Uint16 character)
+{
+  Glyph* rg = new Glyph;
+  rg->character = character;
+  TTF_GlyphMetrics(this->font, rg->character,
+		   &rg->minX, &rg->maxX,
+		   &rg->minY, &rg->maxY,
+		   &rg->advance);
+  rg->height = rg->maxY - rg->minY;
+  rg->width = rg->maxX - rg->minX;
+  rg->bearingX = (rg->advance - rg->width) / 2;
+  rg->bearingY = rg->maxY;
+  return rg;
+}
+
+/**
+   \brief entering 2D Mode
+   
+   this is a GL-Projection-mode, that is orthogonal, for placing the font in fron of everything else
+*/
+void Font::enter2DMode(void)
+{
+  SDL_Surface *screen = SDL_GetVideoSurface();
+  
+  /* Note, there may be other things you need to change,
+     depending on how you have your OpenGL state set up.
+  */
+  glPushAttrib(GL_ENABLE_BIT);
+  glDisable(GL_DEPTH_TEST);
+  glDisable(GL_CULL_FACE);
+  glDisable(GL_LIGHTING);  // will be set back when leaving 2D-mode
+  glEnable(GL_TEXTURE_2D);
+
+  /* This allows alpha blending of 2D textures with the scene */
+  glEnable(GL_BLEND);
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+  
+  glViewport(0, 0, screen->w, screen->h);
+  
+  glMatrixMode(GL_PROJECTION);
+  glPushMatrix();
+  glLoadIdentity();
+  
+  glOrtho(0.0, (GLdouble)screen->w, (GLdouble)screen->h, 0.0, 0.0, 1.0);
+  
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glLoadIdentity();
+  
+  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+}
+
+/**
+   \brief leaves the 2DMode again also \see Font::enter2DMode(void)
+*/
+void Font::leave2DMode(void)
+{
+	glMatrixMode(GL_MODELVIEW);
+	glPopMatrix();
+
+	glMatrixMode(GL_PROJECTION);
+	glPopMatrix();
+
+	glPopAttrib();
+}
+
+
+GLuint Font::createFastTexture(void)
+{
+  /* interesting GLYPHS: 
+   *  33-47: Special Characters.
+   *  48-57: 0-9
+   *  58-63: some more special chars (minor)
+   *  65-90: A-Z
+   *  97-122: a-z
+   */
+  int numberOfGlyphs = 90;
+
+  this->initGlyphs(33, numberOfGlyphs);
+
+  int rectSize = this->findOptimalFastTextureSize();
+
+  // setting default values. (maybe not needed afterwards)
+  SDL_Color tmpColor;  tmpColor.r = tmpColor.g = tmpColor.b = 0;
+  // Surface definition.
+  SDL_Rect tmpRect; // this represents a Rectangle for blitting.
+  SDL_Surface* tmpSurf =  SDL_CreateRGBSurface(SDL_SWSURFACE,
+					       rectSize, rectSize,
+					       32,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
+					       0x000000FF, 
+					       0x0000FF00, 
+					       0x00FF0000, 
+					       0xFF000000
+#else
+					       0xFF000000,
+					       0x00FF0000, 
+					       0x0000FF00, 
+					       0x000000FF
+#endif
+					       );
+  tmpRect.x = 0; tmpRect.y = 0; tmpRect.w = tmpSurf->w; tmpRect.h = tmpSurf->h;
+  SDL_SetClipRect(tmpSurf, &tmpRect);
+  int maxLineHeight = 0;
+
+  // all the interessting Glyphs
+  for (int i = 33; i <= 122; i++)
+    {
+      SDL_Surface* glyphSurf = NULL;
+      Glyph* tmpGlyph;
+
+      if (tmpGlyph = this->glyphArray[i])
+	{
+	  if (tmpGlyph->height > maxLineHeight)
+	    maxLineHeight = tmpGlyph->height;
+	  
+	  if (tmpRect.x+tmpGlyph->width > tmpSurf->w)
+	    {
+	      tmpRect.x = 0;
+	      tmpRect.y = tmpRect.y + maxLineHeight + 1;
+	      maxLineHeight = 0;
+	    }
+	  if (tmpRect.y + maxLineHeight > tmpSurf->h)
+	    {
+	      PRINTF(1)("Protection, so font cannot write over the boundraries error (this should not heappen\n");
+	      break;
+	    }
+	  // reading in the new Glyph
+	  //glyphSurf = TTF_RenderGlyph_Shaded(this->font, i, this->currentText->color, tmpColor);
+	  glyphSurf = TTF_RenderGlyph_Blended(this->font, i, this->currentText->color);
+	  if( glyphSurf ) 
+	    {
+
+	      SDL_SetAlpha(glyphSurf, 0, 0);
+
+	      SDL_BlitSurface(glyphSurf, NULL, tmpSurf, &tmpRect);
+	      TexCoord tmpTexCoord;
+	      tmpTexCoord.minU = (float)tmpRect.x/(float)tmpSurf->w;
+	      tmpTexCoord.maxU = (float)(tmpRect.x+tmpGlyph->width)/(float)tmpSurf->w;
+	      tmpTexCoord.minV = (float)tmpRect.y/(float)tmpSurf->w;
+	      tmpTexCoord.maxV = (float)(tmpRect.y+tmpGlyph->height)/(float)tmpSurf->w;
+	      tmpGlyph->displayList = glGenLists(1);
+
+	      glNewList(tmpGlyph->displayList, GL_COMPILE);
+	      glBegin(GL_QUADS);
+	      glTexCoord2f(tmpTexCoord.minU, tmpTexCoord.minV);
+	      glVertex2d(0, 0);
+	      glTexCoord2f(tmpTexCoord.minU, tmpTexCoord.maxV);
+	      glVertex2d(0, tmpGlyph->height);
+	      glTexCoord2f(tmpTexCoord.maxU, tmpTexCoord.maxV);
+	      glVertex2d(tmpGlyph->width, tmpGlyph->height);
+	      glTexCoord2f(tmpTexCoord.maxU, tmpTexCoord.minV);
+	      glVertex2d(tmpGlyph->width, 0);
+	      glEnd();
+	      glEndList();
+	      SDL_FreeSurface(glyphSurf);
+
+	      tmpRect.x += tmpGlyph->width + 1;
+
+	      // Outputting Glyphs to BMP-files.
+	      /*
+		char outname[64];
+		if (i < 10)
+		sprintf( outname, "glyph-00%d.bmp", i );
+		else if (i <100)
+		sprintf( outname, "glyph-0%d.bmp", i );
+		else
+		sprintf( outname, "glyph-%d.bmp", i );
+		SDL_SaveBMP(tmpSurf, outname);
+	      */
+	    }
+	}
+    }
+  GLuint texture;
+  glGenTextures(1, &texture);
+  glBindTexture(GL_TEXTURE_2D, texture);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+  glTexImage2D(GL_TEXTURE_2D,
+	       0,
+	       GL_RGBA,
+	       tmpSurf->w, tmpSurf->h,
+	       0,
+	       GL_RGBA,
+	       GL_UNSIGNED_BYTE,
+	       tmpSurf->pixels);
+  SDL_FreeSurface(tmpSurf);
+  return texture;
+}
+
+/**
+   \brief Loads a Font from an SDL_surface into a texture.
+   \param surface The surface to make the texture of
+   \param texCoord The texture coordinates of the 4 corners of the texture
+   \returns the ID of the texture
+*/
+GLuint Font::loadTexture(SDL_Surface *surface, TexCoord* texCoord)
+{
+  GLuint texture;
+  int w, h;
+  SDL_Surface *image;
+  SDL_Rect area;
+  Uint32 saved_flags;
+  Uint8  saved_alpha;
+  
+  /* Use the surface width and height expanded to powers of 2 */
+  w = powerOfTwo(surface->w);
+  h = powerOfTwo(surface->h);
+  if (texCoord)
+    {
+      texCoord->minU = 0.0f;
+      texCoord->minV = 0.0f;
+      texCoord->maxU = (GLfloat)surface->w / w;
+      texCoord->maxV = (GLfloat)surface->h / h;
+    }
+  image = SDL_CreateRGBSurface(SDL_SWSURFACE,
+			       w, h,
+			       32,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
+			       0x000000FF, 
+			       0x0000FF00, 
+			       0x00FF0000, 
+			       0xFF000000
+#else
+			       0xFF000000,
+			       0x00FF0000, 
+			       0x0000FF00, 
+			       0x000000FF
+#endif
+			       );
+  if ( image == NULL ) {
+    return 0;
+  }
+  
+  /* Save the alpha blending attributes */
+  saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
+  saved_alpha = surface->format->alpha;
+  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
+    SDL_SetAlpha(surface, 0, 0);
+  }
+  
+  /* Copy the surface into the GL texture image */
+  area.x = 0;
+  area.y = 0;
+  area.w = surface->w;
+  area.h = surface->h;
+  SDL_BlitSurface(surface, &area, image, &area);
+  
+  /* Restore the alpha blending attributes */
+  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
+    SDL_SetAlpha(surface, saved_flags, saved_alpha);
+  }
+  
+  /* Create an OpenGL texture for the image */
+  glGenTextures(1, &texture);
+  glBindTexture(GL_TEXTURE_2D, texture);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+  glTexImage2D(GL_TEXTURE_2D,
+	       0,
+	       GL_RGBA,
+	       w, h,
+	       0,
+	       GL_RGBA,
+	       GL_UNSIGNED_BYTE,
+	       image->pixels);
+  SDL_FreeSurface(image); /* No longer needed */
+  
+  return texture;
+}
+
+/**
+   \brief stores Glyph Metrics in an Array.
+   \param from The Glyph to start from.
+   \param count The number of Glyphs to start From.
+*/
+void Font::initGlyphs(Uint16 from, Uint16 count)
+{
+  /* initialize the Array, and set all its entries to NULL
+   *  only if the Glyph-array has not been initialized
+   */
+  if (!this->glyphArray)
+    {
+      this->glyphArray = new Glyph*[FONT_HIGHEST_KNOWN_CHAR];
+      for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)
+	this->glyphArray[i] = NULL;
+    }
+  
+  Uint16 lastGlyph = from + count;
+  
+  for (int i = from; i <= lastGlyph; i++)
+    {
+      // setting up all the Glyphs we like.
+      glyphArray[i] = getGlyphMetrics(i);
+    }
+  return;
+}
+
+/**
+   \returns the optimal size to use as the texture size
+
+   \todo: this algorithm can be a lot more faster, althought it does 
+   not really matter within the init-context, and 128 glyphs.
+
+   This function searches for a 2^n sizes texture-size, this is for 
+   openGL-version < 1.2 compatibility. and because it is realy easy like this.
+*/
+int Font::findOptimalFastTextureSize(void)
+{
+  int i;
+  int x,y; // the counters
+  int maxLineHeight;
+  int size = 32;      // starting Value, we have to start somewhere 32 seems reasonable.
+  bool sizeOK = false;
+  Glyph* tmpGlyph;
+
+  while (!sizeOK)
+    {
+      x = 0; y = 0;
+      maxLineHeight = 0;
+      for (i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)
+	{
+	  if(tmpGlyph = this->glyphArray[i])
+	    {
+	      // getting the height of the highest Glyph in the Line.
+	      if (tmpGlyph->height > maxLineHeight)
+		maxLineHeight = tmpGlyph->height;
+
+	      if (x + tmpGlyph->width > size)
+		{
+		  x = 0;
+		  y = y + maxLineHeight;
+		  maxLineHeight = 0;
+		}
+	      if (y + maxLineHeight + 1 > size)
+		break;
+	      x += tmpGlyph->width + 1;
+
+	    }
+	}
+      if (i == FONT_HIGHEST_KNOWN_CHAR)
+	sizeOK = true;
+      else
+	size *= 2;
+    }
+  return size;
+  
+}
+
+/**
+   \brief Quick utility function for texture creation 
+   \param input an integer
+   \returns the next bigger 2^n-integer than input
+*/
+int Font::powerOfTwo(int input)
+{
+  int value = 1;
+  
+  while ( value < input ) {
+    value <<= 1;
+  }
+  return value;
+}
+
+
+
+/**
+   \brief a simple function to get some interesting information about this class
+*/
+void Font::debug(void)
+{
+
+  // print the loaded font's style
+  int style;
+  style=TTF_GetFontStyle(this->font);
+  PRINTF(0)("The font style is:");
+  if(style==TTF_STYLE_NORMAL)
+    PRINTF(0)(" normal");
+  else {
+    if(style&TTF_STYLE_BOLD)
+      PRINTF(0)(" bold");
+    if(style&TTF_STYLE_ITALIC)
+      PRINTF(0)(" italic");
+    if(style&TTF_STYLE_UNDERLINE)
+      PRINTF(0)(" underline");
+  }
+  PRINTF(0)("\n");
+
+
+}
+
+
+void m_inverse(const float *m, float *out)
+{
+    float det;
+    det=  m[0]*m[5]*m[10];
+    det+= m[4]*m[9]*m[2];
+    det+= m[8]*m[1]*m[6];
+    det-= m[8]*m[5]*m[2];
+    det-= m[4]*m[1]*m[10];
+    det-= m[0]*m[9]*m[6];
+    
+    if(det!= 0.0)
+	det=1.0/det;
+    out[0]=  (m[5]*m[10]-m[9]*m[6])*det;
+    out[1]= -(m[1]*m[10]-m[9]*m[2])*det;
+    out[2]=  (m[1]*m[6]-m[5]*m[2])*det;
+    out[3]= 0.0;
+    out[4]= -(m[4]*m[10]-m[8]*m[6])*det;
+    out[5]=  (m[0]*m[10]-m[8]*m[2])*det;
+    out[6]= -(m[0]*m[6]-m[4]*m[2])*det;
+    out[7]= 0.0;
+    out[8]=  (m[4]*m[9]-m[8]*m[5])*det;
+    out[9]= -(m[0]*m[9]-m[8]*m[1])*det;
+    out[10]= (m[0]*m[5]-m[4]*m[1])*det;
+    out[11]= 0.0;
+    out[12]=- (m[12]*out[0]+m[13]*out[4]+m[14]*out[8]);
+    out[13]=- (m[12]*out[1]+m[13]*out[5]+m[14]*out[9]);
+    out[14]=- (m[12]*out[2]+m[13]*out[6]+m[14]*out[10]);
+    out[15]= 1.0;
+}
+
+
+Vector mvMult(const float *mat, const Vector* vec)
+{
+  Vector tmp;
+  tmp.x = mat[0]*vec->x+mat[1]*vec->y+mat[2]*vec->z;
+  tmp.y = mat[4]*vec->x+mat[5]*vec->y+mat[6]*vec->z;
+  tmp.z = mat[8]*vec->x+mat[9]*vec->y+mat[10]*vec->z;
+  return tmp;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 /**
    \brief standard constructor
 */
-ProtoSingleton::ProtoSingleton () 
-{
-   this->setClassName ("ProtoSingleton");
+TextEngine::TextEngine () 
+{
+   this->setClassName ("TextEngine");
 
 }
@@ -33,14 +821,14 @@
    \brief the singleton reference to this class
 */
-ProtoSingleton* ProtoSingleton::singletonRef = NULL;
+TextEngine* TextEngine::singletonRef = NULL;
 
 /**
    \returns a Pointer to this Class
 */
-ProtoSingleton* ProtoSingleton::getInstance(void)
-{
-  if (!ProtoSingleton::singletonRef)
-    ProtoSingleton::singletonRef = new ProtoSingleton();
-  return ProtoSingleton::singletonRef;
+TextEngine* TextEngine::getInstance(void)
+{
+  if (!TextEngine::singletonRef)
+    TextEngine::singletonRef = new TextEngine();
+  return TextEngine::singletonRef;
 }
 
@@ -49,7 +837,69 @@
 
 */
-ProtoSingleton::~ProtoSingleton () 
-{
-  ProtoSingleton::singletonRef = NULL;
-
-}
+TextEngine::~TextEngine () 
+{
+  TextEngine::singletonRef = NULL;
+
+}
+
+/**
+   \brief function to enable TTF_Fonts
+*/
+void TextEngine::enableFonts(void)
+{
+  if (!TTF_WasInit())
+    {
+      if(TTF_Init()==-1)
+	PRINTF(1)("TTF_Init: %s\n", TTF_GetError());
+
+      TextEngine::checkVersion();
+    }
+  else
+    PRINTF(4)("Fonts already initialized\n");
+      
+}
+
+/**
+   \brief function to disable TTF_fonts
+*/
+void TextEngine::disableFonts(void)
+{
+  if (TTF_WasInit())
+    {
+      TTF_Quit();
+    }
+  else
+    PRINTF(4)("Fonts were not initialized.\n");
+}
+
+/**
+   \brief checks if the compiled version and the local version of SDL_ttf match.
+   \returns true if match, false otherwise
+*/
+bool TextEngine::checkVersion(void)
+{
+  SDL_version compile_version;
+  SDL_version link_version;
+  TTF_VERSION(&compile_version);
+  link_version = *TTF_Linked_Version();
+
+  if (compile_version.major == link_version.major &&
+      compile_version.minor == link_version.minor &&
+      compile_version.patch == link_version.patch)
+    {
+      return true;
+    }
+  else
+    {
+      PRINTF(2)("compiled with SDL_ttf version: %d.%d.%d\n", 
+		compile_version.major,
+		compile_version.minor,
+		compile_version.patch);
+      
+      PRINTF(2)("running with SDL_ttf version: %d.%d.%d\n", 
+		link_version.major,
+		link_version.minor,
+		link_version.patch);
+      return false;
+    }
+}
