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