Changeset 8764 in orxonox.OLD for trunk/src/lib/graphics/text_engine/font.cc
- Timestamp:
- Jun 24, 2006, 3:12:14 AM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/graphics/text_engine/font.cc
r8763 r8764 31 31 32 32 Font::Font() 33 : data(Font::defaultFontData)33 : data(Font::defaultFontData) 34 34 { 35 35 this->init(); … … 43 43 */ 44 44 Font::Font(const std::string& fontFile, unsigned int renderSize) 45 : data(Font::defaultFontData)45 : data(Font::defaultFontData) 46 46 { 47 47 this->init(); … … 57 57 */ 58 58 Font::Font(const std::string& imageFile) 59 : data(Font::defaultFontData)59 : data(Font::defaultFontData) 60 60 { 61 61 this->init(); … … 82 82 */ 83 83 Font::Font(char** xpmArray) 84 : data(Font::defaultFontData)84 : data(Font::defaultFontData) 85 85 { 86 86 this->init(); … … 133 133 if (Font::defaultFontData.get() == NULL) 134 134 { 135 135 Font::initDefaultFont(); 136 136 this->data = Font::defaultFontData; 137 137 } … … 161 161 { 162 162 this->data = FontDataPointer (new FontData()); 163 164 this->setName(fontFile); 165 this->data->fontTTF = TTF_OpenFont(fontFile.c_str(), renderSize); 166 this->data->renderSize = renderSize; 167 168 if(this->data->fontTTF != NULL) 169 { 170 this->setStyle("c"); 171 if (this->createFastTexture()) 172 return true; 173 else 174 { 175 this->data = Font::defaultFontData; 176 return false; 177 } 178 } 179 else 180 { 181 PRINTF(1)("TTF_OpenFont: %s\n", TTF_GetError()); 163 bool retVal = this->data->loadFontFromTTF(fontFile, renderSize); 164 if (!retVal) 182 165 this->data = Font::defaultFontData; 183 return false; 184 }185 166 167 this->setTexture(this->data->texData); 168 return retVal; 186 169 } 187 170 … … 192 175 bool Font::loadFontFromSDL_Surface(SDL_Surface* surface) 193 176 { 194 if(surface == NULL)195 return false;196 197 177 this->data = FontDataPointer (new FontData()); 198 // loading to a texture. 199 200 bool hasAlpha; 201 SDL_Surface* newSurf = Texture::prepareSurface(surface, hasAlpha); 202 if (newSurf != NULL) 203 { 204 this->data->texData->setSurface(newSurf); 205 this->data->texData->setAlpha(hasAlpha); 206 this->setTexture(Texture::loadTexToGL(newSurf)); 207 } 208 else 209 { 178 bool retVal = this->data->loadFontFromSDL_Surface(surface); 179 if (!retVal) 210 180 this->data = Font::defaultFontData; 211 return false; 212 } 213 214 // initializing the Glyphs. 215 if (this->data->glyphArray == NULL) 216 { 217 float cx,cy; 218 Glyph* tmpGlyph; 219 this->data->glyphArray = new Glyph*[FONT_HIGHEST_KNOWN_CHAR]; 220 for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++) 221 { 222 tmpGlyph = this->data->glyphArray[i] = new Glyph; 223 cx=(float)(i%16)/16.0f; // X Position Of Current Character 224 cy=(float)(i/16)/16.0f; // Y Position Of Current Character 225 226 tmpGlyph->texCoord[0] = cx; 227 tmpGlyph->texCoord[1] = cx+0.0625f; 228 tmpGlyph->texCoord[2] = cy; 229 tmpGlyph->texCoord[3] = cy+0.0625f; 230 tmpGlyph->minX = 0.0f; 231 tmpGlyph->maxX = 1.0f; 232 tmpGlyph->minY = 0.0f; 233 tmpGlyph->maxY = 1.0f; 234 tmpGlyph->width = 1.0f; 235 tmpGlyph->advance = 1.0f; 236 tmpGlyph->bearingX = 0.0f; 237 tmpGlyph->bearingY = 0.0f; 238 tmpGlyph->height = 1.0f; 239 } 240 } 241 return true; 181 182 this->setTexture(this->data->texData); 183 return retVal; 242 184 } 243 185 … … 250 192 void Font::setStyle(const std::string& renderStyle) 251 193 { 252 this->data->renderStyle = TTF_STYLE_NORMAL; 253 254 for (unsigned int i = 0; i < renderStyle.size(); i++) 255 { 256 if (renderStyle[i] == 'b') 257 this->data->renderStyle |= TTF_STYLE_BOLD; 258 else if (renderStyle[i] == 'i') 259 this->data->renderStyle |= TTF_STYLE_ITALIC; 260 else if (renderStyle[i] == 'u') 261 this->data->renderStyle |= TTF_STYLE_UNDERLINE; 262 } 263 if (likely(this->data->fontTTF != NULL)) 264 TTF_SetFontStyle(this->data->fontTTF, this->data->renderStyle); 265 // else 266 // PRINTF(2)("Font was not initialized, please do so before setting the Font-Style.\n"); 267 } 194 this->data->setStyle(renderStyle); 195 } 196 197 198 void Font::setTexture(const TextureDataPointer& texDataPointer) 199 { 200 this->setDiffuseMap(texDataPointer); 201 } 202 268 203 269 204 /** … … 327 262 328 263 329 /**330 * @returns the maximum height of the Font, if the font was initialized, 0 otherwise331 */332 int Font::getMaxHeight() const333 {334 if (likely (this->data->fontTTF != NULL))335 return TTF_FontHeight(this->data->fontTTF);336 else337 return 1;338 }339 340 /**341 * @returns the maximum ascent of the Font, if the font was initialized, 0 otherwise342 *343 * the ascent is the pixels of the font above the baseline344 */345 int Font::getMaxAscent() const346 {347 if (likely(this->data->fontTTF != NULL))348 return TTF_FontAscent(this->data->fontTTF);349 else350 return 0;351 }352 353 /**354 * @returns the maximum descent of the Font, if the font was initialized, 0 otherwise355 *356 * the descent is the pixels of the font below the baseline357 */358 int Font::getMaxDescent() const359 {360 if (likely(this->data->fontTTF != NULL))361 return TTF_FontDescent(this->data->fontTTF);362 else363 return 0;364 }365 366 /**367 * @param glyph: The Glyph to set the Parameters to.368 * @param character: The character to get info about.369 * @returns a Glyph struct of a character. This Glyph is a pointer,370 * and MUST be deleted by the user..371 *372 * This only works for horizontal fonts. see373 * http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html374 * for more info about vertical Fonts375 */376 bool Font::getGlyphMetrics(Glyph* glyph, Uint16 character)377 {378 glyph->character = character;379 if (likely (this->data->fontTTF!= NULL))380 {381 int miX, maX, miY, maY, adv;382 if (TTF_GlyphMetrics(this->data->fontTTF, glyph->character,383 &miX, &maX,384 &miY, &maY,385 &adv) == -1)386 return false;387 glyph->minX = (float)miX / (float)this->data->renderSize;388 glyph->maxX = (float)maX / (float)this->data->renderSize;389 glyph->minY = (float)miY / (float)this->data->renderSize;390 glyph->maxY = (float)maY / (float)this->data->renderSize;391 glyph->advance = (float)adv / (float)this->data->renderSize;392 393 // Calculate the Rest.394 glyph->height = glyph->maxY - glyph->minY;395 glyph->width = glyph->maxX - glyph->minX;396 glyph->bearingX = (glyph->advance - glyph->width) / 2;397 glyph->bearingY = glyph->maxY;398 399 //printf("%c:: %d %d %d %d %d\n", character, miX, maX, miY, maY, adv);400 401 return true;402 }403 return false;404 }405 406 /**407 * @brief creates a Fast-Texture of this Font408 */409 bool Font::createFastTexture()410 {411 /* interesting GLYPHS:412 * 32: space413 * 33-47: Special Characters.414 * 48-57: 0-9415 * 58-63: some more special chars (minor)416 * 65-90: A-Z417 * 97-122: a-z418 */419 int numberOfGlyphs = 91;420 421 this->initGlyphs(32, numberOfGlyphs);422 // this->data->glyphArray[32]->width = .5f; //!< @todo find out the real size of a Space423 424 int rectSize = this->findOptimalFastTextureSize();425 426 // setting default values. (maybe not needed afterwards)427 SDL_Color tmpColor; tmpColor.r = tmpColor.g = tmpColor.b = 0;428 // Surface definition.429 SDL_Rect tmpRect; // this represents a Rectangle for blitting.430 SDL_Surface* tmpSurf = SDL_CreateRGBSurface(SDL_HWSURFACE,431 rectSize, rectSize,432 32,433 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */434 0x000000FF,435 0x0000FF00,436 0x00FF0000,437 0xFF000000438 #else439 0xFF000000,440 0x00FF0000,441 0x0000FF00,442 0x000000FF443 #endif444 );445 tmpRect.x = 0; tmpRect.y = 0; tmpRect.w = tmpSurf->w; tmpRect.h = tmpSurf->h;446 SDL_SetClipRect(tmpSurf, &tmpRect);447 int maxLineHeight = this->getMaxHeight();448 449 // all the interessting Glyphs450 for (int i = 0; i < 128; i++)451 {452 SDL_Surface* glyphSurf = NULL;453 Glyph* tmpGlyph;454 455 if (tmpGlyph = this->data->glyphArray[i])456 {457 if (tmpGlyph->height*this->data->renderSize > maxLineHeight)458 maxLineHeight = (int)(tmpGlyph->height*this->data->renderSize);459 460 if (tmpRect.x+tmpGlyph->advance*this->data->renderSize > tmpSurf->w)461 {462 tmpRect.x = 0;463 tmpRect.y = tmpRect.y + maxLineHeight;464 }465 if (tmpRect.y + maxLineHeight > tmpSurf->h)466 {467 PRINTF(1)("Protection, so font cannot write over the boundraries (!!this should not heappen!!)\n");468 break;469 }470 // reading in the new Glyph471 if (likely(this->data->fontTTF != NULL))472 {473 SDL_Color white = {255, 255, 255};474 glyphSurf = TTF_RenderGlyph_Blended(this->data->fontTTF, i, white);475 }476 if( glyphSurf != NULL )477 {478 SDL_SetAlpha(glyphSurf, 0, 0);479 int tmpY = tmpRect.y;480 tmpRect.y += this->getMaxAscent()-(int)((float)tmpGlyph->bearingY*this->data->renderSize);481 SDL_BlitSurface(glyphSurf, NULL, tmpSurf, &tmpRect);482 tmpRect.y = tmpY;483 484 tmpGlyph->texCoord[0] = (float)((float)tmpRect.x )/(float)tmpSurf->w;485 tmpGlyph->texCoord[1] = (float)((float)tmpRect.x + tmpGlyph->width*(float)this->data->renderSize)/(float)tmpSurf->w;486 tmpGlyph->texCoord[2] = (float)(tmpRect.y)/(float)tmpSurf->w;487 tmpGlyph->texCoord[3] = (float)((float)tmpRect.y+(float)this->getMaxHeight())/(float)tmpSurf->w;488 SDL_FreeSurface(glyphSurf);489 tmpRect.x += (int)(tmpGlyph->width * this->data->renderSize) + 1;490 }491 }492 }493 // outputting the GLYPH-table494 // char outName[1024];495 // sprintf( outName, "%s-glyphs.bmp", this->getName());496 // SDL_SaveBMP(tmpSurf, outName);497 this->data->texData->setAlpha(true);498 if (this->data->texData->setSurface(tmpSurf))499 this->setTexture(Texture::loadTexToGL(tmpSurf));500 return true;501 }502 503 /**504 * @brief the Internal implementation of setting up the Texture.505 * @param texture the Texture to load.506 * @returns true on success, false otherwise.507 */508 bool Font::setTexture(GLuint texture)509 {510 bool retVal = this->data->texData->setTexture(texture);511 this->setDiffuseMap(data->texData, 0);512 printf("this->texture %d\n", texture);513 //printf(this->getT)514 this->debug();515 return retVal;516 };517 518 /**519 * @brief stores Glyph Metrics in an Array.520 * @param from The Glyph to start from.521 * @param count The number of Glyphs to start From.522 */523 void Font::initGlyphs(Uint16 from, Uint16 count)524 {525 /* initialize the Array, and set all its entries to NULL526 * only if the Glyph-array has not been initialized527 */528 if (!this->data->glyphArray)529 {530 this->data->glyphArray = new Glyph*[FONT_HIGHEST_KNOWN_CHAR];531 for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)532 this->data->glyphArray[i] = NULL;533 }534 535 Uint16 lastGlyph = from + count;536 537 for (int i = from; i <= lastGlyph; i++)538 {539 // setting up all the Glyphs we like.540 Glyph* newGlyph = new Glyph;541 if (getGlyphMetrics(newGlyph, i))542 data->glyphArray[i] = newGlyph;543 else544 {545 delete newGlyph;546 data->glyphArray[i] = NULL;547 }548 }549 return;550 }551 552 /**553 * @returns the optimal size to use as the texture size554 *555 * @todo: this algorithm can be a lot faster, althought it does556 * not really matter within the init-context, and 128 glyphs.557 *558 * This function searches for a 2^n sizes texture-size, this is for559 * openGL-version < 1.2 compatibility ( and because it is realy easy like this :))560 */561 int Font::findOptimalFastTextureSize()562 {563 if (this->data->glyphArray == NULL)564 return 0;565 566 unsigned int i;567 unsigned int x,y; // the counters568 int maxLineHeight = this->getMaxHeight();569 unsigned int size = 32; // starting Value, we have to start somewhere 32 seems reasonable. (take any small enough 2^i number)570 bool sizeOK = false;571 Glyph* tmpGlyph;572 573 while (!sizeOK)574 {575 x = 0; y = 0;576 for (i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)577 {578 if((tmpGlyph = this->data->glyphArray[i]) != NULL)579 {580 // getting the height of the highest Glyph in the Line.581 if (tmpGlyph->height*this->data->renderSize > maxLineHeight)582 maxLineHeight = (int)(tmpGlyph->height*this->data->renderSize);583 584 if (x + tmpGlyph->advance*this->data->renderSize > size)585 {586 x = 0;587 y = y + maxLineHeight;588 //maxLineHeight = 0;589 }590 if (y + maxLineHeight + 1 > size)591 break;592 x += (int)(tmpGlyph->advance*this->data->renderSize)+1;593 594 }595 }596 if (i >= FONT_HIGHEST_KNOWN_CHAR-1 || size > 8192)597 sizeOK = true;598 else599 size *= 2;600 }601 return size;602 }603 264 604 265
Note: See TracChangeset
for help on using the changeset viewer.