Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/textEngine/src/lib/graphics/font/glfont.cc @ 3713

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

orxonox/branches/textEngine: deleted obsolete sfont.c

File size: 12.8 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14
15   ***
16   * This file is extended to the needs of the orxonox-project.         *
17   * the Copyright of the original file is below this copyright         *
18   *                                                                  ***
19
20   for some fonts and licenses visit: =http://www.dafont.com/en/font.php=
21
22   !! IMPORTANT !! When using ttf fonts clear the license issues prior to
23   adding them to orxonox. This is really important, because we do not
24   want to defend anyone.
25*/
26
27/*
28  glfont:  An example of using the SDL_ttf library with OpenGL.
29  Copyright (C) 1997-2004 Sam Lantinga
30 
31  This library is free software; you can redistribute it and/or
32  modify it under the terms of the GNU Library General Public
33  License as published by the Free Software Foundation; either
34  version 2 of the License, or (at your option) any later version.
35 
36  This library is distributed in the hope that it will be useful,
37  but WITHOUT ANY WARRANTY; without even the implied warranty of
38  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
39  Library General Public License for more details.
40 
41  You should have received a copy of the GNU Library General Public
42  License along with this library; if not, write to the Free
43  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
44 
45  The SDL_GL_* functions in this file are available in the public domain.
46 
47  Sam Lantinga
48  slouken@libsdl.org
49*/
50
51#include "glfont.h"
52
53#include <stdlib.h>
54#include <stdio.h>
55#include <string.h>
56
57#include "debug.h"
58
59/**
60   \brief constructs a Font
61   \param fontFile the File to load the font from
62*/
63GLFont::GLFont(const char* fontFile)
64{
65  this->init(fontFile);
66}
67
68/**
69   \brief destructs a font
70*/
71GLFont::~GLFont(void)
72{
73  if (this->font)
74    TTF_CloseFont(this->font);
75}
76
77/**
78   \brief function to enable TTF_Fonts
79*/
80void GLFont::enableFonts(void)
81{
82  if (!GLFont::ttfInitialized)
83    {
84      if(TTF_Init()==-1) {
85        PRINTF(1)("TTF_Init: %s\n", TTF_GetError());
86        exit(2);
87      }
88      GLFont::checkVersion();
89      GLFont::ttfInitialized = true;
90    }
91  else
92    PRINTF(4)("Fonts already initialized\n");
93     
94}
95
96/**
97   \brief function to disable TTF_fonts
98*/
99void GLFont::disableFonts(void)
100{
101  if (GLFont::ttfInitialized)
102    {
103      TTF_Quit();
104      GLFont::ttfInitialized = false;
105    }
106  else
107    PRINTF(4)("Fonts were not initialized.\n");
108}
109
110//! A simple variable for checking if ttf was initialized
111bool GLFont::ttfInitialized = false;
112
113/**
114   \brief initializes a new Font
115   \param fontFile The file to load a Font from
116   \param fontSize the Size in pixels of the Font
117*/
118bool GLFont::init(const char* fontFile, unsigned int fontSize)
119{
120  if (!GLFont::ttfInitialized)
121    GLFont::enableFonts();
122
123  // setting default values.
124  this->font = NULL;
125  this->fontFile = NULL;
126  this->text = NULL;
127  this->texture = 0;
128 
129  this->setSize(fontSize);
130 
131  this->renderStyle = TTF_STYLE_NORMAL;
132
133  this->setFont(fontFile);
134
135  this->setColor(0, 255, 0);
136
137  this->setText(FONT_DEFAULT_TEXT);
138
139  this->createTexture();
140}
141
142/**
143   \brief sets The Font.
144   \param fontFile The file containing the font.
145   \returns true if loaded, false if something went wrong, or if a font was loaded before.
146*/
147bool GLFont::setFont(const char* fontFile)
148{
149  if (!this->fontFile)
150    {
151      this->fontFile = new char[strlen(fontFile)+1];
152      strcpy(this->fontFile, fontFile);
153     
154      this->font = TTF_OpenFont(this->fontFile, this->fontSize);
155      if(!this->font) 
156        {
157          PRINTF(1)("TTF_OpenFont: %s\n", TTF_GetError());
158          return false;
159      }
160      return true;
161    }
162  else
163    {
164      PRINTF(2)("Font already initialized, unable to change it now.\n");
165      return false;
166    }
167}
168
169/**
170   \brief Sets a new Text to the font
171   \param text the new text to set
172*/
173void GLFont::setText(const char* text)
174{
175  if (this->text)
176    delete []this->text;
177  this->text = new char[strlen(text)+1];
178  strcpy(this->text, text);
179}
180
181/**
182   \brief sets a specific renderStyle
183   \param renderStyle the Style to render: a char-array containing:
184   i: italic, b: bold, u, underline
185*/
186void GLFont::setStyle(char* renderStyle)
187{
188  this->renderStyle = TTF_STYLE_NORMAL;
189 
190  for (int i = 0; i < strlen(renderStyle); i++)
191    if (strncmp(renderStyle+i, "b", 1) == 0) 
192      this->renderStyle |= TTF_STYLE_BOLD;
193    else if (strncmp(renderStyle+i, "i", 1) == 0)
194      this->renderStyle |= TTF_STYLE_ITALIC;
195    else if (strncmp(renderStyle+i, "u", 1) == 0) 
196      this->renderStyle |= TTF_STYLE_UNDERLINE;
197
198  if (this->font)
199    TTF_SetFontStyle(this->font, this->renderStyle);
200  else
201    PRINTF(2)("Font was not initialized, please do so before setting the Font-Style.\n");
202}
203
204/**
205   \brief Sets a new Size to the font
206   \param fontSize The new Size in pixels.
207*/
208void GLFont::setSize(unsigned int fontSize)
209{
210  this->fontSize = fontSize;
211}
212
213/**
214   \brief sets a new color to the font
215   \param r Red
216   \param g Green
217   \param b Blue
218*/
219void GLFont::setColor(Uint8 r, Uint8 g, Uint8 b)
220{
221  this->color.r = r;
222  this->color.g = g;
223  this->color.b = b;
224}
225
226/**
227   \brief sets a Position.
228   \param x the x-position in pixels from the left border
229   \param y the y-position in pixels from the top border
230*/
231void GLFont::setPosition(int x, int y)
232{
233  this->textPosSize.x = x;
234  this->textPosSize.y = y;
235}
236
237/**
238   \brief draws the Font
239   \todo FIX this is to slow/static
240*/
241void GLFont::draw(void)
242{
243  this->enter2DMode();
244  glBindTexture(GL_TEXTURE_2D, texture);
245  glEnable(GL_TEXTURE_2D);
246  glBegin(GL_QUADS);
247  glTexCoord2f(this->texCoord.minU, this->texCoord.minV); glVertex2i(20,   20  );
248  glTexCoord2f(this->texCoord.maxU, this->texCoord.minV); glVertex2i(20+this->textPosSize.w, 20  );
249  glTexCoord2f(this->texCoord.maxU, this->texCoord.maxV); glVertex2i(20+this->textPosSize.w, 20+this->textPosSize.h);
250  glTexCoord2f(this->texCoord.minU, this->texCoord.maxV); glVertex2i(20, 20+this->textPosSize.h);
251  glEnd();
252  this->leave2DMode();
253
254}
255
256
257/**
258   \brief creates a texture out of the given parameters
259
260   this has to be called every time by the user, to if changes were made.
261*/
262void GLFont::createTexture(void)
263{
264  SDL_Surface* tmpSurf;
265  if (this->texture)
266    glDeleteTextures(1, &this->texture);
267  tmpSurf = TTF_RenderText_Blended(this->font, this->text, this->color);
268  if (tmpSurf)
269    this->texture = loadTexture(tmpSurf, &texCoord);
270
271  this->textPosSize.w = tmpSurf->w;
272  this->textPosSize.h = tmpSurf->h;
273  SDL_FreeSurface(tmpSurf);
274}
275
276
277/**
278   \returns the maximum height of the Font, if the font was initialized, 0 otherwise
279*/
280int GLFont::getMaxHeight(void)
281{
282  if (this->font)
283    return TTF_FontHeight(this->font);
284  else
285    return 0;
286}
287
288/**
289   \returns the maximum ascent of the Font, if the font was initialized, 0 otherwise
290
291   the ascent is the pixels of the font above the baseline
292*/
293int GLFont::getMaxAscent(void)
294{
295  if (this->font)
296    return TTF_FontAscent(this->font);
297  else
298    return 0;
299}
300
301/**
302   \returns the maximum descent of the Font, if the font was initialized, 0 otherwise
303
304   the descent is the pixels of the font below the baseline
305*/
306int GLFont::getMaxDescent(void)
307{
308  if (this->font)
309    return TTF_FontDescent(this->font);
310  else
311    return 0;
312}
313
314/**
315   \param character The character to get info about.
316   \returns a Glyph struct of a character.
317
318   This only works for horizontal fonts. see
319   http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html
320   for more info about vertical Fonts
321*/
322Glyph GLFont::getGlyphMetrics(Uint16 character)
323{
324  Glyph rg;
325  rg.character = character;
326  TTF_GlyphMetrics(this->font, rg.character,
327                   &rg.minX, &rg.maxX,
328                   &rg.minY, &rg.maxY,
329                   &rg.advance);
330  rg.height = rg.maxY - rg.minY;
331  rg.width = rg.maxX - rg.minX;
332  rg.bearingX = (rg.advance - rg.width) / 2;
333  rg.bearingY = rg.maxY;
334  return rg;
335}
336
337/**
338   \brief entering 2D Mode
339   
340   this is a GL-Projection-mode, that is orthogonal, for placing the font in fron of everything else
341*/
342void GLFont::enter2DMode(void)
343{
344  SDL_Surface *screen = SDL_GetVideoSurface();
345 
346  /* Note, there may be other things you need to change,
347     depending on how you have your OpenGL state set up.
348  */
349  glPushAttrib(GL_ENABLE_BIT);
350  glDisable(GL_DEPTH_TEST);
351  glDisable(GL_CULL_FACE);
352  glDisable(GL_LIGHTING);  // will be set back when leaving 2D-mode
353  glEnable(GL_TEXTURE_2D);
354
355  /* This allows alpha blending of 2D textures with the scene */
356  glEnable(GL_BLEND);
357  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
358 
359  glViewport(0, 0, screen->w, screen->h);
360 
361  glMatrixMode(GL_PROJECTION);
362  glPushMatrix();
363  glLoadIdentity();
364 
365  glOrtho(0.0, (GLdouble)screen->w, (GLdouble)screen->h, 0.0, 0.0, 1.0);
366 
367  glMatrixMode(GL_MODELVIEW);
368  glPushMatrix();
369  glLoadIdentity();
370 
371  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
372}
373
374/**
375   \brief leaves the 2DMode again also \see GLFont::enter2DMode(void)
376*/
377void GLFont::leave2DMode(void)
378{
379        glMatrixMode(GL_MODELVIEW);
380        glPopMatrix();
381
382        glMatrixMode(GL_PROJECTION);
383        glPopMatrix();
384
385        glPopAttrib();
386}
387
388/**
389   \brief Loads a Font from an SDL_surface into a texture.
390   \param surface The surface to make the texture of
391   \param texCoord The texture coordinates of the 4 corners of the texture
392   \returns the ID of the texture
393*/
394GLuint GLFont::loadTexture(SDL_Surface *surface, TexCoord* texCoord)
395{
396  GLuint texture;
397  int w, h;
398  SDL_Surface *image;
399  SDL_Rect area;
400  Uint32 saved_flags;
401  Uint8  saved_alpha;
402 
403  /* Use the surface width and height expanded to powers of 2 */
404  w = powerOfTwo(surface->w);
405  h = powerOfTwo(surface->h);
406  texCoord->minU = 0.0f;
407  texCoord->minV = 0.0f;
408  texCoord->maxU = (GLfloat)surface->w / w;
409  texCoord->maxV = (GLfloat)surface->h / h;
410 
411  image = SDL_CreateRGBSurface(
412                               SDL_SWSURFACE,
413                               w, h,
414                               32,
415#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
416                               0x000000FF, 
417                               0x0000FF00, 
418                               0x00FF0000, 
419                               0xFF000000
420#else
421                               0xFF000000,
422                               0x00FF0000, 
423                               0x0000FF00, 
424                               0x000000FF
425#endif
426                               );
427  if ( image == NULL ) {
428    return 0;
429  }
430 
431  /* Save the alpha blending attributes */
432  saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
433  saved_alpha = surface->format->alpha;
434  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
435    SDL_SetAlpha(surface, 0, 0);
436  }
437 
438  /* Copy the surface into the GL texture image */
439  area.x = 0;
440  area.y = 0;
441  area.w = surface->w;
442  area.h = surface->h;
443  SDL_BlitSurface(surface, &area, image, &area);
444 
445  /* Restore the alpha blending attributes */
446  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
447    SDL_SetAlpha(surface, saved_flags, saved_alpha);
448  }
449 
450  /* Create an OpenGL texture for the image */
451  glGenTextures(1, &texture);
452  glBindTexture(GL_TEXTURE_2D, texture);
453  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
454  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
455  glTexImage2D(GL_TEXTURE_2D,
456               0,
457               GL_RGBA,
458               w, h,
459               0,
460               GL_RGBA,
461               GL_UNSIGNED_BYTE,
462               image->pixels);
463  SDL_FreeSurface(image); /* No longer needed */
464 
465  return texture;
466}
467
468/**
469   \brief Quick utility function for texture creation
470   \param input an integer
471   \returns the next bigger 2^n-integer than input
472*/
473int GLFont::powerOfTwo(int input)
474{
475  int value = 1;
476 
477  while ( value < input ) {
478    value <<= 1;
479  }
480  return value;
481}
482
483
484/**
485   \brief checks if the compiled version and the local version of SDL_ttf match.
486   \returns true if match, false otherwise
487*/
488bool GLFont::checkVersion(void)
489{
490  SDL_version compile_version;
491  SDL_version link_version;
492  TTF_VERSION(&compile_version);
493  link_version = *TTF_Linked_Version();
494
495  if (compile_version.major == link_version.major &&
496      compile_version.minor == link_version.minor &&
497      compile_version.patch == link_version.patch)
498    {
499      return true;
500    }
501  else
502    {
503      PRINTF(2)("compiled with SDL_ttf version: %d.%d.%d\n", 
504                compile_version.major,
505                compile_version.minor,
506                compile_version.patch);
507     
508      PRINTF(2)("running with SDL_ttf version: %d.%d.%d\n", 
509                link_version.major,
510                link_version.minor,
511                link_version.patch);
512      return false;
513    }
514}
515
516
517
518/**
519   \brief a simple function to get some interesting information about this class
520*/
521void GLFont::debug(void)
522{
523
524  // print the loaded font's style
525  int style;
526  style=TTF_GetFontStyle(this->font);
527  PRINTF(0)("The font style is:");
528  if(style==TTF_STYLE_NORMAL)
529    PRINTF(0)(" normal");
530  else {
531    if(style&TTF_STYLE_BOLD)
532      PRINTF(0)(" bold");
533    if(style&TTF_STYLE_ITALIC)
534      PRINTF(0)(" italic");
535    if(style&TTF_STYLE_UNDERLINE)
536      PRINTF(0)(" underline");
537  }
538  PRINTF(0)("\n");
539
540
541}
Note: See TracBrowser for help on using the repository browser.