Changeset 5343 in orxonox.OLD for trunk/src/lib/graphics/text_engine
- Timestamp:
- Oct 10, 2005, 12:16:19 AM (19 years ago)
- Location:
- trunk/src/lib/graphics/text_engine
- Files:
-
- 2 edited
- 4 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/graphics/text_engine/font.cc
r5330 r5343 10 10 11 11 ### File Specific: 12 main-programmer: ...12 main-programmer: Benjamin Grauer 13 13 co-programmer: ... 14 14 */ 15 15 16 //#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ 17 18 #include "proto_class.h" 16 #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_FONT 17 18 #include "font.h" 19 #include "text.h" 20 21 #ifdef HAVE_SDL_IMAGE_H 22 #include <SDL_image.h> 23 #else 24 #include <SDL/SDL_image.h> 25 #endif 26 #include "font.xpm" 27 28 #include "debug.h" 29 #include "compiler.h" 19 30 20 31 using namespace std; 21 32 22 23 /** 24 * standard constructor 25 * @todo this constructor is not jet implemented - do it 26 */ 27 ProtoClass::ProtoClass () 28 { 29 this->setClassID(CL_PROTO_ID, "ProtoClass"); 30 31 /* If you make a new class, what is most probably the case when you write this file 32 don't forget to: 33 1. Add the new file new_class.cc to the ./src/Makefile.am 34 2. Add the class identifier to ./src/class_id.h eg. CL_NEW_CLASS 35 36 Advanced Topics: 37 - if you want to let your object be managed via the ObjectManager make sure to read 38 the object_manager.h header comments. You will use this most certanly only if you 39 make many objects of your class, like a weapon bullet. 40 */ 41 } 42 43 44 /** 45 * standard deconstructor 46 */ 47 ProtoClass::~ProtoClass () 48 { 49 // delete what has to be deleted here 50 } 33 /** 34 * constructs a Font 35 * @param fontFile the File to load the font from 36 * @param fontSize the Size of the Font in Pixels 37 */ 38 Font::Font(const char* fontFile, unsigned int fontSize) 39 { 40 this->init(); 41 42 this->setSize(fontSize); 43 44 if (fontFile != NULL) 45 this->loadFont(fontFile); 46 47 this->setStyle("c");//TTF_STYLE_NORMAL); 48 49 this->fastTextureID = this->createFastTexture(); 50 51 52 // this->createAsciiImage("test.bmp"); 53 } 54 55 /** 56 * constructs a Font 57 * @param fontFile the File to load the font from 58 * @param fontSize the Size of the Font in Pixels 59 */ 60 Font::Font(char** xpmArray) 61 { 62 this->init(); 63 64 // this->setSize(fontSize); 65 SDL_Surface* image = NULL; 66 if (xpmArray != NULL) 67 image = IMG_ReadXPMFromArray(xpmArray); 68 if (image != NULL) 69 { 70 this->loadFontFromSDL_Surface(image); 71 SDL_FreeSurface(image); 72 } 73 else 74 PRINTF(1)("loading from surface failed: %s\n", IMG_GetError()); 75 76 } 77 78 79 /** 80 * destructs a font 81 * this releases the memory a font uses to be opened. 82 * deletes the glLists, and the TTF-handler, if present. 83 */ 84 Font::~Font() 85 { 86 // deleting all Glyphs 87 if (this->glyphArray != NULL) 88 { 89 for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++) 90 { 91 if (this->glyphArray[i] != NULL) 92 { 93 glDeleteLists(this->glyphArray[i]->displayList, 1); 94 delete this->glyphArray[i]; 95 } 96 } 97 delete[] this->glyphArray; 98 } 99 100 // erease this font out of the memory. 101 if (likely(this->font != NULL)) 102 TTF_CloseFont(this->font); 103 } 104 105 /** 106 * initializes a Font (with default values) 107 */ 108 void Font::init() 109 { 110 this->setClassID(CL_FONT, "Font"); 111 // setting default values. 112 this->font = NULL; 113 this->glyphArray = NULL; 114 this->fastTextureID = 0; 115 } 116 117 118 /** 119 * sets The Font. 120 * @param fontFile The file containing the font. 121 * @returns true if loaded, false if something went wrong, or if a font was loaded before. 122 */ 123 bool Font::loadFont(const char* fontFile) 124 { 125 if (!this->getName()) 126 { 127 this->setName(fontFile); 128 129 this->font = TTF_OpenFont(this->getName(), this->fontSize); 130 if(!this->font) 131 { 132 PRINTF(1)("TTF_OpenFont: %s\n", TTF_GetError()); 133 return false; 134 } 135 else 136 return true; 137 } 138 else 139 { 140 PRINTF(2)("Font already initialized, unable to change it now.\n"); 141 return false; 142 } 143 } 144 145 /** 146 * loads a font From an XPM-array. 147 * @param xpmArray the array of the XPM to load the font from. 148 */ 149 bool Font::loadFontFromSDL_Surface(SDL_Surface* surface) 150 { 151 // loading to a texture. 152 if(surface == NULL) 153 return false; 154 this->fastTextureID = Text::loadTexture(surface, NULL); 155 156 // initializing the Glyphs. 157 if (this->glyphArray == NULL) 158 { 159 float cx,cy; 160 Glyph* glyph; 161 this->glyphArray = new Glyph*[FONT_HIGHEST_KNOWN_CHAR]; 162 for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++) 163 { 164 glyph = this->glyphArray[i] = new Glyph; 165 glyph->displayList = glGenLists(1); 166 if (!glIsList(glyph->displayList)) 167 { 168 PRINTF(2)("Error creating glList for Font character %c\n", i); 169 this->glyphArray[i] = NULL; 170 delete glyph; 171 continue; 172 } 173 cx=(float)(i%16)/16.0f; // X Position Of Current Character 174 cy=(float)(i/16)/16.0f; // Y Position Of Current Character 175 glNewList(glyph->displayList, GL_COMPILE); // Start Building A List 176 glBegin(GL_QUADS); // Use A Quad For Each Character 177 glTexCoord2f(cx, cy+0.001f); // Texture Coord (Bottom Left) 178 glVertex2d(0,-16); // Vertex Coord (Bottom Left) 179 glTexCoord2f(cx+0.0625f, cy+0.001f); // Texture Coord (Bottom Right) 180 glVertex2i(16,-16); // Vertex Coord (Bottom Right) 181 glTexCoord2f(cx+0.0625f, cy+0.0625f); // Texture Coord (Top Right) 182 glVertex2i(16,0); // Vertex Coord (Top Right) 183 glTexCoord2f(cx, cy+0.0625f); // Texture Coord (Top Left) 184 glVertex2i(0,0); // Vertex Coord (Top Left) 185 glEnd(); // Done Building Our Quad (Character) 186 // glTranslated(12,0,0); // Move To The Right Of The Character 187 glEndList(); // Done Building The Display List 188 this->glyphArray[i]->width = 12; 189 } 190 } 191 return true; 192 } 193 194 195 /** 196 * sets a specific renderStyle 197 * @param renderStyle the Style to render: a char-array containing: 198 i: italic, b: bold, u, underline 199 */ 200 void Font::setStyle(const char* renderStyle) 201 { 202 this->renderStyle = TTF_STYLE_NORMAL; 203 204 for (int i = 0; i < strlen(renderStyle); i++) 205 if (strncmp(renderStyle+i, "b", 1) == 0) 206 this->renderStyle |= TTF_STYLE_BOLD; 207 else if (strncmp(renderStyle+i, "i", 1) == 0) 208 this->renderStyle |= TTF_STYLE_ITALIC; 209 else if (strncmp(renderStyle+i, "u", 1) == 0) 210 this->renderStyle |= TTF_STYLE_UNDERLINE; 211 212 if (likely(this->font != NULL)) 213 TTF_SetFontStyle(this->font, this->renderStyle); 214 else 215 PRINTF(2)("Font was not initialized, please do so before setting the Font-Style.\n"); 216 } 217 218 /** 219 * Sets a new Size to the font 220 * @param fontSize The new Size in pixels. 221 */ 222 void Font::setSize(unsigned int fontSize) 223 { 224 this->fontSize = fontSize; 225 } 226 227 Font* Font::defaultFont = NULL; 228 229 void Font::createAsciiImage(const char* fileName) 230 { 231 if (this->font == NULL) 232 return; 233 int height = this->getMaxHeight(); 234 235 // 236 SDL_Color tmpColor = {0, 0, 0}; 237 // Surface definition. 238 SDL_Rect tmpRect; // this represents a Rectangle for blitting. 239 SDL_Surface* tmpSurf = SDL_CreateRGBSurface(SDL_SWSURFACE, 240 height*16, height*16, 241 32, 242 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */ 243 0x000000FF, 244 0x0000FF00, 245 0x00FF0000, 246 0xFF000000 247 #else 248 0xFF000000, 249 0x00FF0000, 250 0x0000FF00, 251 0x000000FF 252 #endif 253 ); 254 tmpRect.x = 0; tmpRect.y = 0; tmpRect.w = tmpSurf->w; tmpRect.h = tmpSurf->h; 255 SDL_SetClipRect(tmpSurf, &tmpRect); 256 int maxLineHeight = 0; 257 258 int posX, posY; 259 // all the interessting Glyphs 260 for (posY = 0; posY < 16; posY++) 261 { 262 for (posX = 0; posX < 16; posX++) 263 { 264 SDL_Surface* glyphSurf = NULL; 265 if (likely(this->font != NULL)) 266 { 267 SDL_Color white = {255, 255, 255}; 268 glyphSurf = TTF_RenderGlyph_Blended(this->font, posX+16*posY, white); 269 } 270 if( glyphSurf != NULL ) 271 { 272 tmpRect.x = height*posX; 273 tmpRect.y = height*posY; 274 SDL_SetAlpha(glyphSurf, 0, 0); 275 276 SDL_BlitSurface(glyphSurf, NULL, tmpSurf, &tmpRect); 277 SDL_FreeSurface(glyphSurf); 278 // Outputting Glyphs to BMP-files. 279 /* 280 char outname[512]; 281 if (i < 10) 282 sprintf( outname, "%s-glyph-00%d.bmp", this->getName(), i ); 283 else if (i <100) 284 sprintf( outname, "%s-glyph-0%d.bmp", this->getName(), i ); 285 else 286 sprintf( outname, "%s-glyph-%d.bmp", this->getName(), i ); 287 SDL_SaveBMP(tmpSurf, outname);*/ 288 289 } 290 } 291 } 292 SDL_SaveBMP(tmpSurf, fileName); 293 SDL_FreeSurface(tmpSurf); 294 } 295 296 /** 297 * initializes the default font 298 */ 299 void Font::initDefaultFont() 300 { 301 if (Font::defaultFont == NULL) 302 Font::defaultFont = new Font(font_xpm); 303 } 304 305 /** 306 * deletes the default font 307 */ 308 void Font::removeDefaultFont() 309 { 310 if (Font::defaultFont != NULL) 311 delete Font::defaultFont; 312 Font::defaultFont = NULL; 313 } 314 315 316 /** 317 * @returns the maximum height of the Font, if the font was initialized, 0 otherwise 318 */ 319 int Font::getMaxHeight() 320 { 321 if (likely (this->font != NULL)) 322 return TTF_FontHeight(this->font); 323 else 324 return 0; 325 } 326 327 /** 328 * @returns the maximum ascent of the Font, if the font was initialized, 0 otherwise 329 330 the ascent is the pixels of the font above the baseline 331 */ 332 int Font::getMaxAscent() 333 { 334 if (likely(this->font != NULL)) 335 return TTF_FontAscent(this->font); 336 else 337 return 0; 338 } 339 340 /** 341 * @returns the maximum descent of the Font, if the font was initialized, 0 otherwise 342 343 the descent is the pixels of the font below the baseline 344 */ 345 int Font::getMaxDescent() 346 { 347 if (likely(this->font != NULL)) 348 return TTF_FontDescent(this->font); 349 else 350 return 0; 351 } 352 353 /** 354 * @param character The character to get info about. 355 * @returns a Glyph struct of a character. This Glyph is a pointer, 356 and MUST be deleted by the user.. 357 358 This only works for horizontal fonts. see 359 http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html 360 for more info about vertical Fonts 361 */ 362 Glyph* Font::getGlyphMetrics(Uint16 character) 363 { 364 Glyph* rg = new Glyph; 365 rg->character = character; 366 if (likely (this->font!= NULL)) 367 TTF_GlyphMetrics(this->font, rg->character, 368 &rg->minX, &rg->maxX, 369 &rg->minY, &rg->maxY, 370 &rg->advance); 371 rg->height = rg->maxY - rg->minY; 372 rg->width = rg->maxX - rg->minX; 373 rg->bearingX = (rg->advance - rg->width) / 2; 374 rg->bearingY = rg->maxY; 375 return rg; 376 } 377 378 /** 379 * creates a Fast-Texture of this Font 380 */ 381 GLuint Font::createFastTexture() 382 { 383 /* interesting GLYPHS: 384 * 32: space 385 * 33-47: Special Characters. 386 * 48-57: 0-9 387 * 58-63: some more special chars (minor) 388 * 65-90: A-Z 389 * 97-122: a-z 390 */ 391 int numberOfGlyphs = 91; 392 393 this->initGlyphs(32, numberOfGlyphs); 394 this->glyphArray[32]->width = fontSize/2; //!< @todo find out the real size of a Space 395 396 int rectSize = this->findOptimalFastTextureSize(); 397 398 // setting default values. (maybe not needed afterwards) 399 SDL_Color tmpColor; tmpColor.r = tmpColor.g = tmpColor.b = 0; 400 // Surface definition. 401 SDL_Rect tmpRect; // this represents a Rectangle for blitting. 402 SDL_Surface* tmpSurf = SDL_CreateRGBSurface(SDL_SWSURFACE, 403 rectSize, rectSize, 404 32, 405 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */ 406 0x000000FF, 407 0x0000FF00, 408 0x00FF0000, 409 0xFF000000 410 #else 411 0xFF000000, 412 0x00FF0000, 413 0x0000FF00, 414 0x000000FF 415 #endif 416 ); 417 tmpRect.x = 0; tmpRect.y = 0; tmpRect.w = tmpSurf->w; tmpRect.h = tmpSurf->h; 418 SDL_SetClipRect(tmpSurf, &tmpRect); 419 int maxLineHeight = 0; 420 421 // all the interessting Glyphs 422 for (int i = 0; i < 128; i++) 423 { 424 SDL_Surface* glyphSurf = NULL; 425 Glyph* tmpGlyph; 426 427 if (tmpGlyph = this->glyphArray[i]) 428 { 429 if (tmpGlyph->height > maxLineHeight) 430 maxLineHeight = tmpGlyph->height; 431 432 if (tmpRect.x+tmpGlyph->advance > tmpSurf->w) 433 { 434 tmpRect.x = 0; 435 tmpRect.y = tmpRect.y + maxLineHeight + 1; 436 maxLineHeight = 0; 437 } 438 if (tmpRect.y + maxLineHeight > tmpSurf->h) 439 { 440 PRINTF(1)("Protection, so font cannot write over the boundraries error (this should not heappen\n"); 441 break; 442 } 443 // reading in the new Glyph 444 if (likely(this->font != NULL)) 445 { 446 SDL_Color white = {255, 255, 255}; 447 glyphSurf = TTF_RenderGlyph_Blended(this->font, i, white); 448 } 449 if( glyphSurf != NULL ) 450 { 451 SDL_SetAlpha(glyphSurf, 0, 0); 452 453 SDL_BlitSurface(glyphSurf, NULL, tmpSurf, &tmpRect); 454 TexCoord tmpTexCoord; 455 tmpTexCoord.minU = (float)tmpRect.x/(float)tmpSurf->w; 456 tmpTexCoord.maxU = (float)(tmpRect.x + tmpGlyph->advance)/(float)tmpSurf->w; 457 tmpTexCoord.minV = (float)(tmpRect.y)/(float)tmpSurf->w; 458 tmpTexCoord.maxV = (float)(tmpRect.y+tmpGlyph->height)/(float)tmpSurf->w; 459 tmpGlyph->displayList = glGenLists(1); 460 461 glNewList(tmpGlyph->displayList, GL_COMPILE); 462 glBegin(GL_QUADS); 463 glTexCoord2f(tmpTexCoord.minU, tmpTexCoord.minV); 464 glVertex2d(0, - tmpGlyph->bearingY); 465 glTexCoord2f(tmpTexCoord.minU, tmpTexCoord.maxV); 466 glVertex2d(0, tmpGlyph->height - tmpGlyph->bearingY); 467 glTexCoord2f(tmpTexCoord.maxU, tmpTexCoord.maxV); 468 glVertex2d(tmpGlyph->width, tmpGlyph->height - tmpGlyph->bearingY); 469 glTexCoord2f(tmpTexCoord.maxU, tmpTexCoord.minV); 470 glVertex2d(tmpGlyph->width, - tmpGlyph->bearingY); 471 glEnd(); 472 glEndList(); 473 SDL_FreeSurface(glyphSurf); 474 475 tmpRect.x += tmpGlyph->advance; 476 477 // Outputting Glyphs to BMP-files. 478 /* 479 char outname[512]; 480 if (i < 10) 481 sprintf( outname, "%s-glyph-00%d.bmp", this->getName(), i ); 482 else if (i <100) 483 sprintf( outname, "%s-glyph-0%d.bmp", this->getName(), i ); 484 else 485 sprintf( outname, "%s-glyph-%d.bmp", this->getName(), i ); 486 SDL_SaveBMP(tmpSurf, outname);*/ 487 488 } 489 } 490 } 491 492 GLuint texture; 493 glGenTextures(1, &texture); 494 glBindTexture(GL_TEXTURE_2D, texture); 495 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 496 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 497 glTexImage2D(GL_TEXTURE_2D, 498 0, 499 GL_RGBA, 500 tmpSurf->w, tmpSurf->h, 501 0, 502 GL_RGBA, 503 GL_UNSIGNED_BYTE, 504 tmpSurf->pixels); 505 SDL_FreeSurface(tmpSurf); 506 return texture; 507 } 508 509 /** 510 * stores Glyph Metrics in an Array. 511 * @param from The Glyph to start from. 512 * @param count The number of Glyphs to start From. 513 */ 514 void Font::initGlyphs(Uint16 from, Uint16 count) 515 { 516 /* initialize the Array, and set all its entries to NULL 517 * only if the Glyph-array has not been initialized 518 */ 519 if (!this->glyphArray) 520 { 521 this->glyphArray = new Glyph*[FONT_HIGHEST_KNOWN_CHAR]; 522 for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++) 523 this->glyphArray[i] = NULL; 524 } 525 526 Uint16 lastGlyph = from + count; 527 528 for (int i = from; i <= lastGlyph; i++) 529 { 530 // setting up all the Glyphs we like. 531 glyphArray[i] = getGlyphMetrics(i); 532 } 533 return; 534 } 535 536 /** 537 * @returns the optimal size to use as the texture size 538 539 @todo: this algorithm can be a lot more faster, althought it does 540 not really matter within the init-context, and 128 glyphs. 541 542 This function searches for a 2^n sizes texture-size, this is for 543 openGL-version < 1.2 compatibility ( and because it is realy easy like this :)) 544 */ 545 int Font::findOptimalFastTextureSize() 546 { 547 int i; 548 int x,y; // the counters 549 int maxLineHeight = this->getMaxHeight(); 550 unsigned int size = 32; // starting Value, we have to start somewhere 32 seems reasonable. (take any small enough 2^i number) 551 bool sizeOK = false; 552 Glyph* tmpGlyph; 553 554 while (!sizeOK) 555 { 556 x = 0; y = 0; 557 for (i = 0; i <= FONT_HIGHEST_KNOWN_CHAR; i++) 558 { 559 if((tmpGlyph = this->glyphArray[i]) != NULL) 560 { 561 // getting the height of the highest Glyph in the Line. 562 if (tmpGlyph->height > maxLineHeight) 563 maxLineHeight = tmpGlyph->height; 564 565 if (x + tmpGlyph->advance > size) 566 { 567 x = 0; 568 y = y + maxLineHeight; 569 //maxLineHeight = 0; 570 } 571 if (y + maxLineHeight + 1 > size) 572 break; 573 x += tmpGlyph->advance; 574 575 } 576 } 577 if (i >= FONT_HIGHEST_KNOWN_CHAR-1 || size > 8192) 578 sizeOK = true; 579 else 580 size *= 2; 581 } 582 return size; 583 } 584 585 586 /** 587 * a simple function to get some interesting information about this class 588 */ 589 void Font::debug() 590 { 591 // print the loaded font's style 592 int style; 593 if (likely(this->font != NULL)) 594 style = TTF_GetFontStyle(this->font); 595 PRINTF(0)("The font style is:"); 596 if(style==TTF_STYLE_NORMAL) 597 PRINTF(0)(" normal"); 598 else { 599 if(style&TTF_STYLE_BOLD) 600 PRINTF(0)(" bold"); 601 if(style&TTF_STYLE_ITALIC) 602 PRINTF(0)(" italic"); 603 if(style&TTF_STYLE_UNDERLINE) 604 PRINTF(0)(" underline"); 605 } 606 PRINTF(0)("\n"); 607 } -
trunk/src/lib/graphics/text_engine/font.h
r5330 r5343 1 1 /*! 2 * @file proto_class.h3 * @brief Definition of ...4 */2 * @file font.h 3 * brief Definition of the FONT-loading class 4 */ 5 5 6 #ifndef _ PROTO_CLASS_H7 #define _ PROTO_CLASS_H6 #ifndef _FONT_H 7 #define _FONT_H 8 8 9 9 #include "base_object.h" 10 10 11 #include "glincl.h" 12 13 14 #ifdef HAVE_SDL_TTF_H 15 #include <SDL_ttf.h> 16 #else 17 #include <SDL/SDL_ttf.h> 18 #endif 19 20 /* some default values */ 21 #define FONT_NUM_COLORS 256 //!< number of colors. 22 23 #define FONT_HIGHEST_KNOWN_CHAR 128 //!< The highest character known to the textEngine. 24 11 25 // FORWARD DECLARATION 12 26 27 //! A struct for handling glyphs 28 /** 29 a Glyph is one letter of a certain font 30 */ 31 struct Glyph 32 { 33 // Glyph-specific (size and so on) 34 Uint16 character; //!< The character 35 int minX; //!< The minimum distance from the origin in X 36 int maxX; //!< The maximum distance from the origin in X 37 int minY; //!< The minimum distance from the origin in Y 38 int maxY; //!< The maximum distance from the origin in Y 39 int width; //!< The width of the Glyph 40 int height; //!< The height of the Glyph 41 int bearingX; //!< How much is right of the Origin 42 int bearingY; //!< How much is above the Origin 43 int advance; //!< How big a Glyph would be in monospace-mode 44 45 // OpenGL-specific 46 // TexCoord texCoord; //!< A Texture Coordinate for this glyph. 47 GLuint displayList; //!< DiplayList to render this Glyph. 48 }; 13 49 14 50 15 //! A class for ... 16 class ProtoClass : public BaseObject { 51 //////////// 52 /// FONT /// 53 //////////// 54 //! A class to handle a Font of a certain ttf-File, Size and Color. 55 class Font : public BaseObject 56 { 57 friend class Text; 17 58 18 public: 19 ProtoClass(); 20 virtual ~ProtoClass(); 59 public: 60 Font(const char* fontFile, 61 unsigned int fontSize); 62 Font(char** xpmArray); 63 virtual ~Font(); 21 64 65 void init(); 22 66 23 private: 67 // font 68 bool loadFont(const char* fontFile); 69 bool loadFontFromSDL_Surface(SDL_Surface* surface); 24 70 71 void setSize(unsigned int fontSize); 72 void setStyle(const char* renderStyle); 73 74 /** @returns a Pointer to the Array of Glyphs */ 75 inline Glyph** getGlyphArray() const { return this->glyphArray; }; 76 /** @returns the texture to the fast-texture */ 77 inline GLuint getFastTextureID() const { return this->fastTextureID; }; 78 /** @returns the default Font */ 79 inline static Font* getDefaultFont() { return Font::defaultFont; }; 80 81 void createAsciiImage(const char* fileName); 82 static void initDefaultFont(); 83 static void removeDefaultFont(); 84 85 private: 86 int getMaxHeight(); 87 int getMaxAscent(); 88 int getMaxDescent(); 89 Glyph* getGlyphMetrics(Uint16 character); 90 91 GLuint createFastTexture(); 92 93 void initGlyphs(Uint16 from, Uint16 count); 94 int findOptimalFastTextureSize(); 95 96 void debug(); 97 98 private: 99 static Font* defaultFont; //!< a default font, that is used, if other fonts were unable to be loaded. 100 // information about the Font 101 TTF_Font* font; //!< The font we use for this. 102 unsigned int fontSize; //!< The size of the font in pixels. each Font has one size. 103 int renderStyle; //!< The Renderstyle 104 105 Glyph** glyphArray; //!< An Array of all the Glyphs stored in the Array of Glyphs. 106 GLuint fastTextureID; //!< The fast textureID. 25 107 }; 26 108 27 #endif /* _ PROTO_CLASS_H */109 #endif /* _FONT_H */ -
trunk/src/lib/graphics/text_engine/text.cc
r5330 r5343 10 10 11 11 ### File Specific: 12 main-programmer: ...12 main-programmer: Benjamin Grauer 13 13 co-programmer: ... 14 14 */ 15 15 16 //#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ 17 18 #include "proto_class.h" 16 #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_FONT 17 18 #include "text.h" 19 #include "font.h" 20 21 #include "graphics_engine.h" 22 #include "resource_manager.h" 23 #include "class_list.h" 24 #include "debug.h" 25 #include "p_node.h" 19 26 20 27 using namespace std; 21 28 22 23 /** 24 * standard constructor 25 * @todo this constructor is not jet implemented - do it 26 */ 27 ProtoClass::ProtoClass () 28 { 29 this->setClassID(CL_PROTO_ID, "ProtoClass"); 30 31 /* If you make a new class, what is most probably the case when you write this file 32 don't forget to: 33 1. Add the new file new_class.cc to the ./src/Makefile.am 34 2. Add the class identifier to ./src/class_id.h eg. CL_NEW_CLASS 35 36 Advanced Topics: 37 - if you want to let your object be managed via the ObjectManager make sure to read 38 the object_manager.h header comments. You will use this most certanly only if you 39 make many objects of your class, like a weapon bullet. 40 */ 41 } 42 43 44 /** 45 * standard deconstructor 46 */ 47 ProtoClass::~ProtoClass () 48 { 49 // delete what has to be deleted here 50 } 29 /** 30 * creates a new Text Element 31 * @param fontFile the Font to render this text in 32 * @param type The renderType to display this font in 33 */ 34 Text::Text(const char* fontFile, unsigned int fontSize, TEXT_RENDER_TYPE type) 35 { 36 this->init(); 37 38 if (fontFile != NULL) 39 this->setFont(fontFile, fontSize); 40 this->setType(type); 41 } 42 43 /** 44 * creates a new Text Element 45 * @param font the Font to render this text in 46 * @param type The renderType to display this font in 47 * 48 * this constructor is private, because the user should initialize 49 * a text with the TextEngine. 50 */ 51 Text::Text(Font* font, TEXT_RENDER_TYPE type) 52 { 53 this->init(); 54 55 this->font = font; 56 this->setType(type); 57 } 58 59 /** 60 * deletes a Text out of memory 61 * 62 * This also ereases the text from the textList of the TextEngine 63 */ 64 Text::~Text() 65 { 66 if (this->font != NULL) 67 ResourceManager::getInstance()->unload(this->font); 68 69 if (this->text) 70 delete[] this->text; 71 } 72 73 void Text::init() 74 { 75 this->setClassID(CL_TEXT, "Text"); 76 77 // initialize this Text 78 this->font = NULL; 79 this->text = NULL; 80 this->externText = NULL; 81 this->setAlignment(TEXT_DEFAULT_ALIGNMENT); 82 this->texture = 0; 83 this->blending = TEXT_DEFAULT_BLENDING; 84 this->color = TEXT_DEFAULT_COLOR; 85 this->setType(TEXT_RENDER_DYNAMIC); 86 87 this->setText(NULL); 88 } 89 90 /** 91 * sets the Font of this Text to font 92 * @param font the Font (normaly from the ResourceManager) to allocate to this Text 93 */ 94 void Text::setFont(Font* font) 95 { 96 if (this->font != NULL) 97 ResourceManager::getInstance()->unload(this->font); 98 this->font = font; 99 } 100 101 /** 102 * sets the Font of this Text to font from fontFile 103 * @param fontFile the File to load the Font from. 104 * @param fontSize the Size of the Font 105 */ 106 void Text::setFont(const char* fontFile, unsigned int fontSize) 107 { 108 Font* tmpFont; 109 Text* newText; 110 Vector tmpVec; 111 112 tmpFont = (Font*)ResourceManager::getInstance()->load(fontFile, TTF, RP_GAME, &fontSize); 113 if (tmpFont == NULL) 114 { 115 PRINTF(2)("Font %s could not be loaded, probably file not found\n", fontFile); 116 this->setFont(NULL); 117 } 118 else 119 this->setFont(tmpFont); 120 } 121 122 /** 123 * sets the Type of this Text 124 * @param type the type to set. 125 */ 126 void Text::setType(TEXT_RENDER_TYPE type) 127 { 128 if (this->font != NULL && this->font->font) 129 this->type = type; 130 else 131 this->type = TEXT_RENDER_DYNAMIC; 132 } 133 134 /** 135 * Sets a new Text to the font 136 * @param text the new text to set 137 */ 138 void Text::setText(const char* text, bool isExtern) 139 { 140 if (isExtern) 141 { 142 this->externText = text; 143 144 if (unlikely(this->text != NULL)) 145 { 146 delete[] this->text; 147 this->text = NULL; 148 } 149 } 150 else 151 { 152 this->externText = NULL; 153 if (this->text) 154 delete[] this->text; 155 if (text != NULL) 156 { 157 this->text = new char[strlen(text)+1]; 158 strcpy(this->text, text); 159 } 160 else 161 this->text = NULL; 162 } 163 164 // setting up the Text-Width if DYNAMIC 165 if (this->type & TEXT_RENDER_DYNAMIC && this->getAlignment() != TEXT_ALIGN_LEFT && this->font != NULL) 166 { 167 Glyph** glyphArray = this->font->getGlyphArray(); 168 169 int width = 0; 170 const char* tmpText = this->externText; 171 if (this->externText == NULL) 172 tmpText = this->text; 173 if (tmpText != NULL) 174 { 175 while (*tmpText != '\0') 176 { 177 if(glyphArray[*tmpText]) 178 { 179 width += glyphArray[*tmpText]->width; 180 } 181 tmpText++; 182 } 183 this->width = width; 184 } 185 } 186 } 187 188 /** 189 * creates a texture out of the given parameters 190 191 this has to be called every time by the user, to if changes were made. 192 this is only for TEXT_STATIC-mode 193 */ 194 void Text::createTexture() 195 { 196 SDL_Surface* tmpSurf; 197 if (this->texture) 198 glDeleteTextures(1, &this->texture); 199 if (likely(this->font != NULL)) 200 { 201 SDL_Color theColor = { (int)(this->color.x*255), (int)(this->color.y*255), (int)(this->color.z*255) }; 202 tmpSurf = TTF_RenderText_Blended(this->font->font, 203 this->text, 204 theColor); 205 } 206 if (tmpSurf) 207 this->texture = loadTexture(tmpSurf, &this->texCoord); 208 209 this->width = tmpSurf->w; 210 this->height = tmpSurf->h; 211 SDL_FreeSurface(tmpSurf); 212 } 213 214 /** 215 * draws the Text 216 */ 217 void Text::draw() const 218 { 219 glPushMatrix(); 220 // transform for alignment. 221 if (this->getAlignment() == TEXT_ALIGN_RIGHT) 222 glTranslatef(-this->width, 0, 0); 223 else if (this->getAlignment() == TEXT_ALIGN_CENTER || this->getAlignment() == TEXT_ALIGN_SCREEN_CENTER) 224 glTranslatef(-this->width/2, 0, 0); 225 226 // drawing this Text. 227 // setting the Blending effects 228 glColor4f(this->color.x, this->color.y, this->color.z, this->blending); 229 glEnable(GL_BLEND); 230 glEnable(GL_TEXTURE_2D); 231 glBlendFunc(GL_SRC_ALPHA, GL_ONE); 232 233 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, GL_MODULATE ); 234 235 if(likely(type & TEXT_RENDER_DYNAMIC )) 236 { 237 Glyph** glyphArray; 238 if (likely (this->font != NULL)) 239 { 240 glyphArray = this->font->getGlyphArray(); 241 glBindTexture(GL_TEXTURE_2D, font->getFastTextureID()); 242 } 243 else 244 { 245 if (unlikely(Font::getDefaultFont() == NULL)) 246 Font::initDefaultFont(); 247 glyphArray = Font::getDefaultFont()->getGlyphArray(); 248 glBindTexture(GL_TEXTURE_2D, Font::getDefaultFont()->getFastTextureID()); 249 } 250 glTranslatef(getAbsCoor2D().x, getAbsCoor2D().y, 0); 251 // glRotatef(this->getAbsDir2D(), 0,0,1); 252 const char* tmpText = this->externText; 253 if (this->externText == NULL) 254 tmpText = this->text; 255 if (likely(tmpText != NULL)) 256 { 257 while (likely(*tmpText != '\0')) 258 { 259 if(likely(glyphArray[*tmpText] != NULL)) 260 { 261 glCallList(glyphArray[*tmpText]->displayList); 262 glTranslatef(glyphArray[*tmpText]->width, 0, 0); 263 } 264 tmpText++; 265 } 266 } 267 } 268 else //(if type & TEXT_RENDER_STATIC) 269 { 270 glBindTexture(GL_TEXTURE_2D, this->texture); 271 glBegin(GL_QUADS); 272 273 glTexCoord2f(this->texCoord.minU, this->texCoord.minV); 274 glVertex2f(this->getAbsCoor2D().x, this->getAbsCoor2D().y ); 275 276 glTexCoord2f(this->texCoord.maxU, this->texCoord.minV); 277 glVertex2f(this->getAbsCoor2D().x + this->width, this->getAbsCoor2D().y ); 278 279 glTexCoord2f(this->texCoord.maxU, this->texCoord.maxV); 280 glVertex2f(this->getAbsCoor2D().x + this->width, getAbsCoor2D().y + this->height); 281 282 glTexCoord2f(this->texCoord.minU, this->texCoord.maxV); 283 glVertex2f(getAbsCoor2D().x, getAbsCoor2D().y + this->height); 284 285 glEnd(); 286 287 } 288 glPopMatrix(); 289 } 290 291 /** 292 * prints out some nice debug information about this text 293 */ 294 void Text::debug() const 295 { 296 if (this->externText == NULL) 297 PRINT(0)("=== TEXT: %s ===\n", this->text); 298 else 299 PRINT(0)("=== TEXT: %s ===\n", this->externText); 300 301 if (this->getBindNode()) 302 PRINT(0)("is bind to %s; ref=%p\n", this->getBindNode()->getName(), this->getBindNode()); 303 PRINT(0)("Color: %0.2f %0.2f %0.2f\n", this->color.x, this->color.y, this->color.z); 304 } 305 306 307 //////////// 308 /// UTIL /// 309 //////////// 310 /** 311 * Loads a Font from an SDL_surface into a texture. 312 * @param surface The surface to make the texture of 313 * @param texCoord The texture coordinates of the 4 corners of the texture 314 * @returns the ID of the texture 315 */ 316 GLuint Text::loadTexture(SDL_Surface *surface, TexCoord* texCoord) 317 { 318 GLuint texture; 319 int w, h; 320 SDL_Surface *image; 321 SDL_Rect area; 322 Uint32 saved_flags; 323 Uint8 saved_alpha; 324 325 /* Use the surface width and height expanded to powers of 2 */ 326 w = powerOfTwo(surface->w); 327 h = powerOfTwo(surface->h); 328 if (texCoord != NULL) 329 { 330 texCoord->minU = 0.0f; 331 texCoord->minV = 0.0f; 332 texCoord->maxU = (GLfloat)surface->w / w; 333 texCoord->maxV = (GLfloat)surface->h / h; 334 } 335 image = SDL_CreateRGBSurface(SDL_SWSURFACE, 336 w, h, 337 32, 338 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */ 339 0x000000FF, 340 0x0000FF00, 341 0x00FF0000, 342 0xFF000000 343 #else 344 0xFF000000, 345 0x00FF0000, 346 0x0000FF00, 347 0x000000FF 348 #endif 349 ); 350 if ( image == NULL ) { 351 return 0; 352 } 353 354 /* Save the alpha blending attributes */ 355 saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK); 356 saved_alpha = surface->format->alpha; 357 if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { 358 SDL_SetAlpha(surface, 0, 0); 359 } 360 361 /* Copy the surface into the GL texture image */ 362 area.x = 0; 363 area.y = 0; 364 area.w = surface->w; 365 area.h = surface->h; 366 SDL_BlitSurface(surface, &area, image, &area); 367 368 /* Restore the alpha blending attributes */ 369 if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { 370 SDL_SetAlpha(surface, saved_flags, saved_alpha); 371 } 372 373 /* Create an OpenGL texture for the image */ 374 glGenTextures(1, &texture); 375 glBindTexture(GL_TEXTURE_2D, texture); 376 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 377 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 378 glTexImage2D(GL_TEXTURE_2D, 379 0, 380 GL_RGBA, 381 w, h, 382 0, 383 GL_RGBA, 384 GL_UNSIGNED_BYTE, 385 image->pixels); 386 SDL_FreeSurface(image); /* No longer needed the data */ 387 388 return texture; 389 } 390 391 /** 392 * Quick utility function for texture creation 393 * @param input an integer 394 * @returns the next bigger 2^n-integer than input 395 */ 396 int Text::powerOfTwo(int input) 397 { 398 int value = 1; 399 400 while ( value < input ) 401 value <<= 1; 402 return value; 403 } -
trunk/src/lib/graphics/text_engine/text.h
r5330 r5343 1 1 /*! 2 * @file proto_class.h3 * @brief Definition of ...2 * @file text.h 3 * @brief Definition of a text Class, that is able to render text. 4 4 */ 5 5 6 #ifndef _ PROTO_CLASS_H7 #define _ PROTO_CLASS_H6 #ifndef _TEXT_H 7 #define _TEXT_H 8 8 9 #include "base_object.h" 9 #include "element_2d.h" 10 11 #include "glincl.h" 12 13 #define TEXT_ALIGN_LEFT E2D_ALIGN_LEFT 14 #define TEXT_ALIGN_RIGHT E2D_ALIGN_RIGHT 15 #define TEXT_ALIGN_CENTER E2D_ALIGN_CENTER 16 #define TEXT_ALIGN_SCREEN_CENTER E2D_ALIGN_SCREEN_CENTER 17 #define TEXT_DEFAULT_COLOR Vector(1.0, 1.0, 1.0) //!< the default Color (white) 18 #define TEXT_DEFAULT_BLENDING 1.0f //!< the default blending of the text, (no blending at all) 19 20 #define TEXT_DEFAULT_ALIGNMENT TEXT_ALIGN_CENTER //!< default alignment 21 #define TEXT_DEFAULT_SIZE 20 //!< default size of the Text 22 10 23 11 24 // FORWARD DECLARATION 25 class Font; 12 26 13 27 28 /** 29 * STATIC means: a font, that is only one GL-face. 30 ** it is very fast, and can be used for all text 31 ** that does not have to be changed anymore, or if 32 ** the the text should look very nice 33 * DYNAMIC means: a very fast font, that will is build 34 ** from multiple quads. 35 ** Use this type, if you want to create fast changing 36 ** text like a counter. 37 */typedef enum TEXT_RENDER_TYPE 38 { 39 TEXT_RENDER_STATIC = 1, 40 TEXT_RENDER_DYNAMIC = 2 41 }; 14 42 15 //! A class for ... 16 class ProtoClass : public BaseObject { 17 18 public: 19 ProtoClass(); 20 virtual ~ProtoClass(); 43 //! A Struct to handel Texture Coordinates for quads 44 struct TexCoord 45 { 46 float minU; //!< The minimum U-Coordinate 47 float maxU; //!< The maximum U-Coordinate 48 float minV; //!< The minimum V-Coordinate 49 float maxV; //!< The maximum V-Coordinate 50 }; 21 51 22 52 23 private: 53 //////////// 54 /// TEXT /// 55 //////////// 56 //! Represents one textElement. 57 class Text : public Element2D 58 { 59 friend class TextEngine; 60 public: 61 Text(const char* fontFile, unsigned int fontSize = TEXT_DEFAULT_SIZE, TEXT_RENDER_TYPE type = TEXT_RENDER_DYNAMIC); 62 ~Text(); 24 63 64 void init(); 65 66 void setFont(const char* fontFile, unsigned int fontSize); 67 void setType(TEXT_RENDER_TYPE type); 68 void setText(const char* text, bool isExtern = false); 69 /** @returns the String this Text displays */ 70 inline const char* getText() const { return (externText == NULL)?this->text:this->externText; }; 71 /** @param blending the blending intensity to set (between 0.0 and 1.0) */ 72 inline void setBlending(float blending) { this->blending = blending; }; 73 74 /** sets the Color of the Text to render (values in [0-1]) @param r red @param g green @param b blue */ 75 void setColor(float r, float g, float b) { this->color = Vector(r,g,b); }; 76 77 void createTexture(); 78 79 virtual void draw() const; 80 81 void debug() const; 82 83 // helpers. 84 static GLuint loadTexture(SDL_Surface* surface, TexCoord* texCoord); 85 static int powerOfTwo(int input); 86 87 private: 88 Text(Font* font = NULL, TEXT_RENDER_TYPE type = TEXT_RENDER_DYNAMIC); 89 void setFont(Font* font); 90 91 92 private: 93 Font* font; //!< Font of this text 94 95 TEXT_RENDER_TYPE type; //!< The type of this Font. 96 char* text; //!< The text to display 97 const char* externText; //!< the text to Display from an external Source. 98 Vector color; //!< The color of the font. 99 float blending; //!< The blending intensity. 100 101 // placement in openGL 102 GLuint texture; //!< A GL-texture to hold the text 103 TexCoord texCoord; //!< Texture-coordinates @todo fix this to have a struct 104 float height; 105 float width; 25 106 }; 26 107 27 #endif /* _ PROTO_CLASS_H */108 #endif /* _TEXT_H */ -
trunk/src/lib/graphics/text_engine/text_engine.cc
r5342 r5343 30 30 #include <string.h> 31 31 32 #ifdef HAVE_SDL_IMAGE_H33 #include <SDL_image.h>34 #else35 #include <SDL/SDL_image.h>36 #endif37 #include "font.xpm"38 39 40 32 #include "graphics_engine.h" 41 33 #include "resource_manager.h" … … 46 38 #include "debug.h" 47 39 #include "list.h" 48 49 ////////////50 /// TEXT ///51 ////////////52 53 /**54 * creates a new Text Element55 * @param fontFile the Font to render this text in56 * @param type The renderType to display this font in57 */58 Text::Text(const char* fontFile, unsigned int fontSize, TEXT_RENDER_TYPE type)59 {60 this->init();61 62 if (fontFile != NULL)63 this->setFont(fontFile, fontSize);64 this->setType(type);65 }66 67 /**68 * creates a new Text Element69 * @param font the Font to render this text in70 * @param type The renderType to display this font in71 *72 * this constructor is private, because the user should initialize73 * a text with the TextEngine.74 */75 Text::Text(Font* font, TEXT_RENDER_TYPE type)76 {77 this->init();78 79 this->font = font;80 this->setType(type);81 }82 83 /**84 * deletes a Text out of memory85 *86 * This also ereases the text from the textList of the TextEngine87 */88 Text::~Text()89 {90 if (this->font != NULL)91 ResourceManager::getInstance()->unload(this->font);92 93 if (this->text)94 delete[] this->text;95 }96 97 void Text::init()98 {99 this->setClassID(CL_TEXT, "Text");100 101 // initialize this Text102 this->font = NULL;103 this->text = NULL;104 this->externText = NULL;105 this->setAlignment(TEXT_DEFAULT_ALIGNMENT);106 this->texture = 0;107 this->blending = TEXT_DEFAULT_BLENDING;108 this->color = TEXT_DEFAULT_COLOR;109 this->setType(TEXT_RENDER_DYNAMIC);110 111 this->setText(NULL);112 }113 114 /**115 * sets the Font of this Text to font116 * @param font the Font (normaly from the ResourceManager) to allocate to this Text117 */118 void Text::setFont(Font* font)119 {120 if (this->font != NULL)121 ResourceManager::getInstance()->unload(this->font);122 this->font = font;123 }124 125 /**126 * sets the Font of this Text to font from fontFile127 * @param fontFile the File to load the Font from.128 * @param fontSize the Size of the Font129 */130 void Text::setFont(const char* fontFile, unsigned int fontSize)131 {132 Font* tmpFont;133 Text* newText;134 Vector tmpVec;135 136 tmpFont = (Font*)ResourceManager::getInstance()->load(fontFile, TTF, RP_GAME, &fontSize);137 if (tmpFont == NULL)138 {139 PRINTF(2)("Font %s could not be loaded, probably file not found\n", fontFile);140 this->setFont(NULL);141 }142 else143 this->setFont(tmpFont);144 }145 146 /**147 * sets the Type of this Text148 * @param type the type to set.149 */150 void Text::setType(TEXT_RENDER_TYPE type)151 {152 if (this->font != NULL && this->font->font)153 this->type = type;154 else155 this->type = TEXT_RENDER_DYNAMIC;156 }157 158 /**159 * Sets a new Text to the font160 * @param text the new text to set161 */162 void Text::setText(const char* text, bool isExtern)163 {164 if (isExtern)165 {166 this->externText = text;167 168 if (unlikely(this->text != NULL))169 {170 delete[] this->text;171 this->text = NULL;172 }173 }174 else175 {176 this->externText = NULL;177 if (this->text)178 delete[] this->text;179 if (text != NULL)180 {181 this->text = new char[strlen(text)+1];182 strcpy(this->text, text);183 }184 else185 this->text = NULL;186 }187 188 // setting up the Text-Width if DYNAMIC189 if (this->type & TEXT_RENDER_DYNAMIC && this->getAlignment() != TEXT_ALIGN_LEFT && this->font != NULL)190 {191 Glyph** glyphArray = this->font->getGlyphArray();192 193 int width = 0;194 const char* tmpText = this->externText;195 if (this->externText == NULL)196 tmpText = this->text;197 if (tmpText != NULL)198 {199 while (*tmpText != '\0')200 {201 if(glyphArray[*tmpText])202 {203 width += glyphArray[*tmpText]->width;204 }205 tmpText++;206 }207 this->width = width;208 }209 }210 }211 212 /**213 * creates a texture out of the given parameters214 215 this has to be called every time by the user, to if changes were made.216 this is only for TEXT_STATIC-mode217 */218 void Text::createTexture()219 {220 SDL_Surface* tmpSurf;221 if (this->texture)222 glDeleteTextures(1, &this->texture);223 if (likely(this->font != NULL))224 {225 SDL_Color theColor = { (int)(this->color.x*255), (int)(this->color.y*255), (int)(this->color.z*255) };226 tmpSurf = TTF_RenderText_Blended(this->font->font,227 this->text,228 theColor);229 }230 if (tmpSurf)231 this->texture = loadTexture(tmpSurf, &this->texCoord);232 233 this->width = tmpSurf->w;234 this->height = tmpSurf->h;235 SDL_FreeSurface(tmpSurf);236 }237 238 /**239 * draws the Text240 */241 void Text::draw() const242 {243 glPushMatrix();244 // transform for alignment.245 if (this->getAlignment() == TEXT_ALIGN_RIGHT)246 glTranslatef(-this->width, 0, 0);247 else if (this->getAlignment() == TEXT_ALIGN_CENTER || this->getAlignment() == TEXT_ALIGN_SCREEN_CENTER)248 glTranslatef(-this->width/2, 0, 0);249 250 // drawing this Text.251 // setting the Blending effects252 glColor4f(this->color.x, this->color.y, this->color.z, this->blending);253 glEnable(GL_BLEND);254 glEnable(GL_TEXTURE_2D);255 glBlendFunc(GL_SRC_ALPHA, GL_ONE);256 257 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, GL_MODULATE );258 259 if(likely(type & TEXT_RENDER_DYNAMIC ))260 {261 Glyph** glyphArray;262 if (likely (this->font != NULL))263 {264 glyphArray = this->font->getGlyphArray();265 glBindTexture(GL_TEXTURE_2D, font->getFastTextureID());266 }267 else268 {269 if (unlikely(Font::getDefaultFont() == NULL))270 Font::initDefaultFont();271 glyphArray = Font::getDefaultFont()->getGlyphArray();272 glBindTexture(GL_TEXTURE_2D, Font::getDefaultFont()->getFastTextureID());273 }274 glTranslatef(getAbsCoor2D().x, getAbsCoor2D().y, 0);275 // glRotatef(this->getAbsDir2D(), 0,0,1);276 const char* tmpText = this->externText;277 if (this->externText == NULL)278 tmpText = this->text;279 if (likely(tmpText != NULL))280 {281 while (likely(*tmpText != '\0'))282 {283 if(likely(glyphArray[*tmpText] != NULL))284 {285 glCallList(glyphArray[*tmpText]->displayList);286 glTranslatef(glyphArray[*tmpText]->width, 0, 0);287 }288 tmpText++;289 }290 }291 }292 else //(if type & TEXT_RENDER_STATIC)293 {294 glBindTexture(GL_TEXTURE_2D, this->texture);295 glBegin(GL_QUADS);296 297 glTexCoord2f(this->texCoord.minU, this->texCoord.minV);298 glVertex2f(this->getAbsCoor2D().x, this->getAbsCoor2D().y );299 300 glTexCoord2f(this->texCoord.maxU, this->texCoord.minV);301 glVertex2f(this->getAbsCoor2D().x + this->width, this->getAbsCoor2D().y );302 303 glTexCoord2f(this->texCoord.maxU, this->texCoord.maxV);304 glVertex2f(this->getAbsCoor2D().x + this->width, getAbsCoor2D().y + this->height);305 306 glTexCoord2f(this->texCoord.minU, this->texCoord.maxV);307 glVertex2f(getAbsCoor2D().x, getAbsCoor2D().y + this->height);308 309 glEnd();310 311 }312 glPopMatrix();313 }314 315 /**316 * prints out some nice debug information about this text317 */318 void Text::debug() const319 {320 if (this->externText == NULL)321 PRINT(0)("=== TEXT: %s ===\n", this->text);322 else323 PRINT(0)("=== TEXT: %s ===\n", this->externText);324 325 if (this->getBindNode())326 PRINT(0)("is bind to %s; ref=%p\n", this->getBindNode()->getName(), this->getBindNode());327 PRINT(0)("Color: %0.2f %0.2f %0.2f\n", this->color.x, this->color.y, this->color.z);328 }329 330 331 ////////////332 /// UTIL ///333 ////////////334 /**335 * Loads a Font from an SDL_surface into a texture.336 * @param surface The surface to make the texture of337 * @param texCoord The texture coordinates of the 4 corners of the texture338 * @returns the ID of the texture339 */340 GLuint Text::loadTexture(SDL_Surface *surface, TexCoord* texCoord)341 {342 GLuint texture;343 int w, h;344 SDL_Surface *image;345 SDL_Rect area;346 Uint32 saved_flags;347 Uint8 saved_alpha;348 349 /* Use the surface width and height expanded to powers of 2 */350 w = powerOfTwo(surface->w);351 h = powerOfTwo(surface->h);352 if (texCoord != NULL)353 {354 texCoord->minU = 0.0f;355 texCoord->minV = 0.0f;356 texCoord->maxU = (GLfloat)surface->w / w;357 texCoord->maxV = (GLfloat)surface->h / h;358 }359 image = SDL_CreateRGBSurface(SDL_SWSURFACE,360 w, h,361 32,362 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */363 0x000000FF,364 0x0000FF00,365 0x00FF0000,366 0xFF000000367 #else368 0xFF000000,369 0x00FF0000,370 0x0000FF00,371 0x000000FF372 #endif373 );374 if ( image == NULL ) {375 return 0;376 }377 378 /* Save the alpha blending attributes */379 saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);380 saved_alpha = surface->format->alpha;381 if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {382 SDL_SetAlpha(surface, 0, 0);383 }384 385 /* Copy the surface into the GL texture image */386 area.x = 0;387 area.y = 0;388 area.w = surface->w;389 area.h = surface->h;390 SDL_BlitSurface(surface, &area, image, &area);391 392 /* Restore the alpha blending attributes */393 if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {394 SDL_SetAlpha(surface, saved_flags, saved_alpha);395 }396 397 /* Create an OpenGL texture for the image */398 glGenTextures(1, &texture);399 glBindTexture(GL_TEXTURE_2D, texture);400 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);401 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);402 glTexImage2D(GL_TEXTURE_2D,403 0,404 GL_RGBA,405 w, h,406 0,407 GL_RGBA,408 GL_UNSIGNED_BYTE,409 image->pixels);410 SDL_FreeSurface(image); /* No longer needed the data */411 412 return texture;413 }414 415 /**416 * Quick utility function for texture creation417 * @param input an integer418 * @returns the next bigger 2^n-integer than input419 */420 int Text::powerOfTwo(int input)421 {422 int value = 1;423 424 while ( value < input )425 value <<= 1;426 return value;427 }428 429 430 ////////////431 /// FONT ///432 ////////////433 /**434 * constructs a Font435 * @param fontFile the File to load the font from436 * @param fontSize the Size of the Font in Pixels437 */438 Font::Font(const char* fontFile, unsigned int fontSize)439 {440 this->init();441 442 this->setSize(fontSize);443 444 if (fontFile != NULL)445 this->loadFont(fontFile);446 447 this->setStyle("c");//TTF_STYLE_NORMAL);448 449 this->fastTextureID = this->createFastTexture();450 451 452 // this->createAsciiImage("test.bmp");453 }454 455 /**456 * constructs a Font457 * @param fontFile the File to load the font from458 * @param fontSize the Size of the Font in Pixels459 */460 Font::Font(char** xpmArray)461 {462 this->init();463 464 // this->setSize(fontSize);465 SDL_Surface* image = NULL;466 if (xpmArray != NULL)467 image = IMG_ReadXPMFromArray(xpmArray);468 if (image != NULL)469 {470 this->loadFontFromSDL_Surface(image);471 SDL_FreeSurface(image);472 }473 else474 PRINTF(1)("loading from surface failed: %s\n", IMG_GetError());475 476 }477 478 479 /**480 * destructs a font481 * this releases the memory a font uses to be opened.482 * deletes the glLists, and the TTF-handler, if present.483 */484 Font::~Font()485 {486 // deleting all Glyphs487 if (this->glyphArray != NULL)488 {489 for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)490 {491 if (this->glyphArray[i] != NULL)492 {493 glDeleteLists(this->glyphArray[i]->displayList, 1);494 delete this->glyphArray[i];495 }496 }497 delete[] this->glyphArray;498 }499 500 // erease this font out of the memory.501 if (likely(this->font != NULL))502 TTF_CloseFont(this->font);503 }504 505 /**506 * initializes a Font (with default values)507 */508 void Font::init()509 {510 this->setClassID(CL_FONT, "Font");511 // setting default values.512 this->font = NULL;513 this->glyphArray = NULL;514 this->fastTextureID = 0;515 }516 517 518 /**519 * sets The Font.520 * @param fontFile The file containing the font.521 * @returns true if loaded, false if something went wrong, or if a font was loaded before.522 */523 bool Font::loadFont(const char* fontFile)524 {525 if (!this->getName())526 {527 this->setName(fontFile);528 529 this->font = TTF_OpenFont(this->getName(), this->fontSize);530 if(!this->font)531 {532 PRINTF(1)("TTF_OpenFont: %s\n", TTF_GetError());533 return false;534 }535 else536 return true;537 }538 else539 {540 PRINTF(2)("Font already initialized, unable to change it now.\n");541 return false;542 }543 }544 545 /**546 * loads a font From an XPM-array.547 * @param xpmArray the array of the XPM to load the font from.548 */549 bool Font::loadFontFromSDL_Surface(SDL_Surface* surface)550 {551 // loading to a texture.552 if(surface == NULL)553 return false;554 TexCoord texCoord;555 this->fastTextureID = Text::loadTexture(surface, &texCoord);556 557 // initializing the Glyphs.558 if (this->glyphArray == NULL)559 {560 float cx,cy;561 Glyph* glyph;562 this->glyphArray = new Glyph*[FONT_HIGHEST_KNOWN_CHAR];563 for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)564 {565 glyph = this->glyphArray[i] = new Glyph;566 glyph->displayList = glGenLists(1);567 if (!glIsList(glyph->displayList))568 {569 PRINTF(2)("Error creating glList for Font character %c\n", i);570 this->glyphArray[i] = NULL;571 delete glyph;572 continue;573 }574 cx=(float)(i%16)/16.0f; // X Position Of Current Character575 cy=(float)(i/16)/16.0f; // Y Position Of Current Character576 glNewList(glyph->displayList, GL_COMPILE); // Start Building A List577 glBegin(GL_QUADS); // Use A Quad For Each Character578 glTexCoord2f(cx, cy+0.001f); // Texture Coord (Bottom Left)579 glVertex2d(0,-16); // Vertex Coord (Bottom Left)580 glTexCoord2f(cx+0.0625f, cy+0.001f); // Texture Coord (Bottom Right)581 glVertex2i(16,-16); // Vertex Coord (Bottom Right)582 glTexCoord2f(cx+0.0625f, cy+0.0625f); // Texture Coord (Top Right)583 glVertex2i(16,0); // Vertex Coord (Top Right)584 glTexCoord2f(cx, cy+0.0625f); // Texture Coord (Top Left)585 glVertex2i(0,0); // Vertex Coord (Top Left)586 glEnd(); // Done Building Our Quad (Character)587 // glTranslated(12,0,0); // Move To The Right Of The Character588 glEndList(); // Done Building The Display List589 this->glyphArray[i]->width = 12;590 }591 }592 return true;593 }594 595 596 /**597 * sets a specific renderStyle598 * @param renderStyle the Style to render: a char-array containing:599 i: italic, b: bold, u, underline600 */601 void Font::setStyle(const char* renderStyle)602 {603 this->renderStyle = TTF_STYLE_NORMAL;604 605 for (int i = 0; i < strlen(renderStyle); i++)606 if (strncmp(renderStyle+i, "b", 1) == 0)607 this->renderStyle |= TTF_STYLE_BOLD;608 else if (strncmp(renderStyle+i, "i", 1) == 0)609 this->renderStyle |= TTF_STYLE_ITALIC;610 else if (strncmp(renderStyle+i, "u", 1) == 0)611 this->renderStyle |= TTF_STYLE_UNDERLINE;612 613 if (likely(this->font != NULL))614 TTF_SetFontStyle(this->font, this->renderStyle);615 else616 PRINTF(2)("Font was not initialized, please do so before setting the Font-Style.\n");617 }618 619 /**620 * Sets a new Size to the font621 * @param fontSize The new Size in pixels.622 */623 void Font::setSize(unsigned int fontSize)624 {625 this->fontSize = fontSize;626 }627 628 Font* Font::defaultFont = NULL;629 630 void Font::createAsciiImage(const char* fileName)631 {632 if (this->font == NULL)633 return;634 int height = this->getMaxHeight();635 636 //637 SDL_Color tmpColor = {0, 0, 0};638 // Surface definition.639 SDL_Rect tmpRect; // this represents a Rectangle for blitting.640 SDL_Surface* tmpSurf = SDL_CreateRGBSurface(SDL_SWSURFACE,641 height*16, height*16,642 32,643 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */644 0x000000FF,645 0x0000FF00,646 0x00FF0000,647 0xFF000000648 #else649 0xFF000000,650 0x00FF0000,651 0x0000FF00,652 0x000000FF653 #endif654 );655 tmpRect.x = 0; tmpRect.y = 0; tmpRect.w = tmpSurf->w; tmpRect.h = tmpSurf->h;656 SDL_SetClipRect(tmpSurf, &tmpRect);657 int maxLineHeight = 0;658 659 int posX, posY;660 // all the interessting Glyphs661 for (posY = 0; posY < 16; posY++)662 {663 for (posX = 0; posX < 16; posX++)664 {665 SDL_Surface* glyphSurf = NULL;666 if (likely(this->font != NULL))667 {668 SDL_Color white = {255, 255, 255};669 glyphSurf = TTF_RenderGlyph_Blended(this->font, posX+16*posY, white);670 }671 if( glyphSurf != NULL )672 {673 tmpRect.x = height*posX;674 tmpRect.y = height*posY;675 SDL_SetAlpha(glyphSurf, 0, 0);676 677 SDL_BlitSurface(glyphSurf, NULL, tmpSurf, &tmpRect);678 SDL_FreeSurface(glyphSurf);679 // Outputting Glyphs to BMP-files.680 /*681 char outname[512];682 if (i < 10)683 sprintf( outname, "%s-glyph-00%d.bmp", this->getName(), i );684 else if (i <100)685 sprintf( outname, "%s-glyph-0%d.bmp", this->getName(), i );686 else687 sprintf( outname, "%s-glyph-%d.bmp", this->getName(), i );688 SDL_SaveBMP(tmpSurf, outname);*/689 690 }691 }692 }693 SDL_SaveBMP(tmpSurf, fileName);694 SDL_FreeSurface(tmpSurf);695 }696 697 /**698 * initializes the default font699 */700 void Font::initDefaultFont()701 {702 if (Font::defaultFont == NULL)703 Font::defaultFont = new Font(font_xpm);704 }705 706 /**707 * deletes the default font708 */709 void Font::removeDefaultFont()710 {711 if (Font::defaultFont != NULL)712 delete Font::defaultFont;713 Font::defaultFont = NULL;714 }715 716 717 /**718 * @returns the maximum height of the Font, if the font was initialized, 0 otherwise719 */720 int Font::getMaxHeight()721 {722 if (likely (this->font != NULL))723 return TTF_FontHeight(this->font);724 else725 return 0;726 }727 728 /**729 * @returns the maximum ascent of the Font, if the font was initialized, 0 otherwise730 731 the ascent is the pixels of the font above the baseline732 */733 int Font::getMaxAscent()734 {735 if (likely(this->font != NULL))736 return TTF_FontAscent(this->font);737 else738 return 0;739 }740 741 /**742 * @returns the maximum descent of the Font, if the font was initialized, 0 otherwise743 744 the descent is the pixels of the font below the baseline745 */746 int Font::getMaxDescent()747 {748 if (likely(this->font != NULL))749 return TTF_FontDescent(this->font);750 else751 return 0;752 }753 754 /**755 * @param character The character to get info about.756 * @returns a Glyph struct of a character. This Glyph is a pointer,757 and MUST be deleted by the user..758 759 This only works for horizontal fonts. see760 http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html761 for more info about vertical Fonts762 */763 Glyph* Font::getGlyphMetrics(Uint16 character)764 {765 Glyph* rg = new Glyph;766 rg->character = character;767 if (likely (this->font!= NULL))768 TTF_GlyphMetrics(this->font, rg->character,769 &rg->minX, &rg->maxX,770 &rg->minY, &rg->maxY,771 &rg->advance);772 rg->height = rg->maxY - rg->minY;773 rg->width = rg->maxX - rg->minX;774 rg->bearingX = (rg->advance - rg->width) / 2;775 rg->bearingY = rg->maxY;776 return rg;777 }778 779 /**780 * creates a Fast-Texture of this Font781 */782 GLuint Font::createFastTexture()783 {784 /* interesting GLYPHS:785 * 32: space786 * 33-47: Special Characters.787 * 48-57: 0-9788 * 58-63: some more special chars (minor)789 * 65-90: A-Z790 * 97-122: a-z791 */792 int numberOfGlyphs = 91;793 794 this->initGlyphs(32, numberOfGlyphs);795 this->glyphArray[32]->width = fontSize/2; //!< @todo find out the real size of a Space796 797 int rectSize = this->findOptimalFastTextureSize();798 799 // setting default values. (maybe not needed afterwards)800 SDL_Color tmpColor; tmpColor.r = tmpColor.g = tmpColor.b = 0;801 // Surface definition.802 SDL_Rect tmpRect; // this represents a Rectangle for blitting.803 SDL_Surface* tmpSurf = SDL_CreateRGBSurface(SDL_SWSURFACE,804 rectSize, rectSize,805 32,806 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */807 0x000000FF,808 0x0000FF00,809 0x00FF0000,810 0xFF000000811 #else812 0xFF000000,813 0x00FF0000,814 0x0000FF00,815 0x000000FF816 #endif817 );818 tmpRect.x = 0; tmpRect.y = 0; tmpRect.w = tmpSurf->w; tmpRect.h = tmpSurf->h;819 SDL_SetClipRect(tmpSurf, &tmpRect);820 int maxLineHeight = 0;821 822 // all the interessting Glyphs823 for (int i = 0; i < 128; i++)824 {825 SDL_Surface* glyphSurf = NULL;826 Glyph* tmpGlyph;827 828 if (tmpGlyph = this->glyphArray[i])829 {830 if (tmpGlyph->height > maxLineHeight)831 maxLineHeight = tmpGlyph->height;832 833 if (tmpRect.x+tmpGlyph->advance > tmpSurf->w)834 {835 tmpRect.x = 0;836 tmpRect.y = tmpRect.y + maxLineHeight + 1;837 maxLineHeight = 0;838 }839 if (tmpRect.y + maxLineHeight > tmpSurf->h)840 {841 PRINTF(1)("Protection, so font cannot write over the boundraries error (this should not heappen\n");842 break;843 }844 // reading in the new Glyph845 if (likely(this->font != NULL))846 {847 SDL_Color white = {255, 255, 255};848 glyphSurf = TTF_RenderGlyph_Blended(this->font, i, white);849 }850 if( glyphSurf != NULL )851 {852 SDL_SetAlpha(glyphSurf, 0, 0);853 854 SDL_BlitSurface(glyphSurf, NULL, tmpSurf, &tmpRect);855 TexCoord tmpTexCoord;856 tmpTexCoord.minU = (float)tmpRect.x/(float)tmpSurf->w;857 tmpTexCoord.maxU = (float)(tmpRect.x + tmpGlyph->advance)/(float)tmpSurf->w;858 tmpTexCoord.minV = (float)(tmpRect.y)/(float)tmpSurf->w;859 tmpTexCoord.maxV = (float)(tmpRect.y+tmpGlyph->height)/(float)tmpSurf->w;860 tmpGlyph->displayList = glGenLists(1);861 862 glNewList(tmpGlyph->displayList, GL_COMPILE);863 glBegin(GL_QUADS);864 glTexCoord2f(tmpTexCoord.minU, tmpTexCoord.minV);865 glVertex2d(0, - tmpGlyph->bearingY);866 glTexCoord2f(tmpTexCoord.minU, tmpTexCoord.maxV);867 glVertex2d(0, tmpGlyph->height - tmpGlyph->bearingY);868 glTexCoord2f(tmpTexCoord.maxU, tmpTexCoord.maxV);869 glVertex2d(tmpGlyph->width, tmpGlyph->height - tmpGlyph->bearingY);870 glTexCoord2f(tmpTexCoord.maxU, tmpTexCoord.minV);871 glVertex2d(tmpGlyph->width, - tmpGlyph->bearingY);872 glEnd();873 glEndList();874 SDL_FreeSurface(glyphSurf);875 876 tmpRect.x += tmpGlyph->advance;877 878 // Outputting Glyphs to BMP-files.879 /*880 char outname[512];881 if (i < 10)882 sprintf( outname, "%s-glyph-00%d.bmp", this->getName(), i );883 else if (i <100)884 sprintf( outname, "%s-glyph-0%d.bmp", this->getName(), i );885 else886 sprintf( outname, "%s-glyph-%d.bmp", this->getName(), i );887 SDL_SaveBMP(tmpSurf, outname);*/888 889 }890 }891 }892 893 GLuint texture;894 glGenTextures(1, &texture);895 glBindTexture(GL_TEXTURE_2D, texture);896 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);897 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);898 glTexImage2D(GL_TEXTURE_2D,899 0,900 GL_RGBA,901 tmpSurf->w, tmpSurf->h,902 0,903 GL_RGBA,904 GL_UNSIGNED_BYTE,905 tmpSurf->pixels);906 SDL_FreeSurface(tmpSurf);907 return texture;908 }909 910 /**911 * stores Glyph Metrics in an Array.912 * @param from The Glyph to start from.913 * @param count The number of Glyphs to start From.914 */915 void Font::initGlyphs(Uint16 from, Uint16 count)916 {917 /* initialize the Array, and set all its entries to NULL918 * only if the Glyph-array has not been initialized919 */920 if (!this->glyphArray)921 {922 this->glyphArray = new Glyph*[FONT_HIGHEST_KNOWN_CHAR];923 for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)924 this->glyphArray[i] = NULL;925 }926 927 Uint16 lastGlyph = from + count;928 929 for (int i = from; i <= lastGlyph; i++)930 {931 // setting up all the Glyphs we like.932 glyphArray[i] = getGlyphMetrics(i);933 }934 return;935 }936 937 /**938 * @returns the optimal size to use as the texture size939 940 @todo: this algorithm can be a lot more faster, althought it does941 not really matter within the init-context, and 128 glyphs.942 943 This function searches for a 2^n sizes texture-size, this is for944 openGL-version < 1.2 compatibility ( and because it is realy easy like this :))945 */946 int Font::findOptimalFastTextureSize()947 {948 int i;949 int x,y; // the counters950 int maxLineHeight = this->getMaxHeight();951 unsigned int size = 32; // starting Value, we have to start somewhere 32 seems reasonable. (take any small enough 2^i number)952 bool sizeOK = false;953 Glyph* tmpGlyph;954 955 while (!sizeOK)956 {957 x = 0; y = 0;958 for (i = 0; i <= FONT_HIGHEST_KNOWN_CHAR; i++)959 {960 if((tmpGlyph = this->glyphArray[i]) != NULL)961 {962 // getting the height of the highest Glyph in the Line.963 if (tmpGlyph->height > maxLineHeight)964 maxLineHeight = tmpGlyph->height;965 966 if (x + tmpGlyph->advance > size)967 {968 x = 0;969 y = y + maxLineHeight;970 //maxLineHeight = 0;971 }972 if (y + maxLineHeight + 1 > size)973 break;974 x += tmpGlyph->advance;975 976 }977 }978 if (i >= FONT_HIGHEST_KNOWN_CHAR-1 || size > 8192)979 sizeOK = true;980 else981 size *= 2;982 }983 return size;984 }985 986 987 /**988 * a simple function to get some interesting information about this class989 */990 void Font::debug()991 {992 // print the loaded font's style993 int style;994 if (likely(this->font != NULL))995 style = TTF_GetFontStyle(this->font);996 PRINTF(0)("The font style is:");997 if(style==TTF_STYLE_NORMAL)998 PRINTF(0)(" normal");999 else {1000 if(style&TTF_STYLE_BOLD)1001 PRINTF(0)(" bold");1002 if(style&TTF_STYLE_ITALIC)1003 PRINTF(0)(" italic");1004 if(style&TTF_STYLE_UNDERLINE)1005 PRINTF(0)(" underline");1006 }1007 PRINTF(0)("\n");1008 }1009 1010 40 1011 41 /////////////////// -
trunk/src/lib/graphics/text_engine/text_engine.h
r5342 r5343 17 17 #define _TEXT_ENGINE_H 18 18 19 20 #include "glincl.h"21 22 #ifdef HAVE_SDL_TTF_H23 #include <SDL_ttf.h>24 #else25 #include <SDL/SDL_ttf.h>26 #endif27 28 19 #include "base_object.h" 29 #include "element_2d.h" 20 #include "font.h" 21 #include "text.h" 30 22 31 23 #include "vector.h" … … 34 26 class PNode; 35 27 class Font; 36 37 #define TEXT_ALIGN_LEFT E2D_ALIGN_LEFT38 #define TEXT_ALIGN_RIGHT E2D_ALIGN_RIGHT39 #define TEXT_ALIGN_CENTER E2D_ALIGN_CENTER40 #define TEXT_ALIGN_SCREEN_CENTER E2D_ALIGN_SCREEN_CENTER41 #define TEXT_DEFAULT_COLOR Vector(1.0, 1.0, 1.0) //!< the default Color (white)42 #define TEXT_DEFAULT_BLENDING 1.0f //!< the default blending of the text, (no blending at all)43 44 /* some default values */45 #define FONT_DEFAULT_SIZE 50 //!< default size of the Text46 #define FONT_NUM_COLORS 256 //!< number of colors.47 48 #define FONT_HIGHEST_KNOWN_CHAR 128 //!< The highest character known to the textEngine.49 50 #define TEXT_DEFAULT_ALIGNMENT TEXT_ALIGN_CENTER //!< default alignment51 52 typedef enum TEXT_RENDER_TYPE53 {54 TEXT_RENDER_STATIC = 1,55 TEXT_RENDER_DYNAMIC = 256 };57 /**58 * STATIC means: a font, that is only one GL-face.59 ** it is very fast, and can be used for all text60 ** that does not have to be changed anymore, or if61 ** the the text should look very nice62 * DYNAMIC means: a very fast font, that will is build63 ** from multiple quads.64 ** Use this type, if you want to create fast changing65 ** text like a counter.66 */67 68 69 //! A Struct to handel Texture Coordinates for quads70 struct TexCoord71 {72 float minU; //!< The minimum U-Coordinate73 float maxU; //!< The maximum U-Coordinate74 float minV; //!< The minimum V-Coordinate75 float maxV; //!< The maximum V-Coordinate76 };77 78 //! A struct for handling glyphs79 /**80 a Glyph is one letter of a certain font81 */82 struct Glyph83 {84 // Glyph-specific (size and so on)85 Uint16 character; //!< The character86 int minX; //!< The minimum distance from the origin in X87 int maxX; //!< The maximum distance from the origin in X88 int minY; //!< The minimum distance from the origin in Y89 int maxY; //!< The maximum distance from the origin in Y90 int width; //!< The width of the Glyph91 int height; //!< The height of the Glyph92 int bearingX; //!< How much is right of the Origin93 int bearingY; //!< How much is above the Origin94 int advance; //!< How big a Glyph would be in monospace-mode95 96 // OpenGL-specific97 // TexCoord texCoord; //!< A Texture Coordinate for this glyph.98 GLuint displayList; //!< DiplayList to render this Glyph.99 };100 101 ////////////102 /// TEXT ///103 ////////////104 //! Represents one textElement.105 class Text : public Element2D106 {107 friend class TextEngine;108 public:109 Text(const char* fontFile, unsigned int fontSize = FONT_DEFAULT_SIZE, TEXT_RENDER_TYPE type = TEXT_RENDER_DYNAMIC);110 ~Text();111 112 void init();113 114 void setFont(const char* fontFile, unsigned int fontSize);115 void setType(TEXT_RENDER_TYPE type);116 void setText(const char* text, bool isExtern = false);117 /** @returns the String this Text displays */118 inline const char* getText() const { return (externText == NULL)?this->text:this->externText; };119 /** @param blending the blending intensity to set (between 0.0 and 1.0) */120 inline void setBlending(float blending) { this->blending = blending; };121 122 /** sets the Color of the Text to render (values in [0-1]) @param r red @param g green @param b blue */123 void setColor(float r, float g, float b) { this->color = Vector(r,g,b); };124 125 void createTexture();126 127 virtual void draw() const;128 129 void debug() const;130 131 // helpers.132 static GLuint loadTexture(SDL_Surface* surface, TexCoord* texCoord);133 static int powerOfTwo(int input);134 135 private:136 Text(Font* font = NULL, TEXT_RENDER_TYPE type = TEXT_RENDER_DYNAMIC);137 void setFont(Font* font);138 139 140 private:141 Font* font; //!< Font of this text142 143 TEXT_RENDER_TYPE type; //!< The type of this Font.144 char* text; //!< The text to display145 const char* externText; //!< the text to Display from an external Source.146 Vector color; //!< The color of the font.147 float blending; //!< The blending intensity.148 149 // placement in openGL150 GLuint texture; //!< A GL-texture to hold the text151 TexCoord texCoord; //!< Texture-coordinates @todo fix this to have a struct152 float height;153 float width;154 };155 156 ////////////157 /// FONT ///158 ////////////159 //! A class to handle a Font of a certain ttf-File, Size and Color.160 class Font : public BaseObject161 {162 friend class Text;163 164 public:165 Font(const char* fontFile,166 unsigned int fontSize = FONT_DEFAULT_SIZE);167 Font(char** xpmArray);168 virtual ~Font();169 170 void init();171 172 // font173 bool loadFont(const char* fontFile);174 bool loadFontFromSDL_Surface(SDL_Surface* surface);175 176 void setSize(unsigned int fontSize);177 void setStyle(const char* renderStyle);178 179 /** @returns a Pointer to the Array of Glyphs */180 inline Glyph** getGlyphArray() const { return this->glyphArray; };181 /** @returns the texture to the fast-texture */182 inline GLuint getFastTextureID() const { return this->fastTextureID; };183 /** @returns the default Font */184 inline static Font* getDefaultFont() { return Font::defaultFont; };185 186 void createAsciiImage(const char* fileName);187 static void initDefaultFont();188 static void removeDefaultFont();189 190 private:191 int getMaxHeight();192 int getMaxAscent();193 int getMaxDescent();194 Glyph* getGlyphMetrics(Uint16 character);195 196 GLuint createFastTexture();197 198 void initGlyphs(Uint16 from, Uint16 count);199 int findOptimalFastTextureSize();200 201 void debug();202 203 private:204 static Font* defaultFont; //!< a default font, that is used, if other fonts were unable to be loaded.205 // information about the Font206 TTF_Font* font; //!< The font we use for this.207 unsigned int fontSize; //!< The size of the font in pixels. each Font has one size.208 int renderStyle; //!< The Renderstyle209 210 Glyph** glyphArray; //!< An Array of all the Glyphs stored in the Array of Glyphs.211 GLuint fastTextureID; //!< The fast textureID.212 213 tList<Text>* textList; //!< A list of texts this Font is mapped to.214 };215 28 216 29 /////////////////// … … 226 39 227 40 Text* createText(const char* fontFile, 228 unsigned int fontSize = FONT_DEFAULT_SIZE,41 unsigned int fontSize = TEXT_DEFAULT_SIZE, 229 42 int textType = TEXT_RENDER_DYNAMIC); 230 43
Note: See TracChangeset
for help on using the changeset viewer.