Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/textEngine: some more simple movement around classes

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