Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 8764 in orxonox.OLD for trunk/src/lib/graphics/text_engine/font.cc


Ignore:
Timestamp:
Jun 24, 2006, 3:12:14 AM (19 years ago)
Author:
bensch
Message:

load-implementation of font in font-data

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/graphics/text_engine/font.cc

    r8763 r8764  
    3131
    3232Font::Font()
    33   : data(Font::defaultFontData)
     33    : data(Font::defaultFontData)
    3434{
    3535  this->init();
     
    4343 */
    4444Font::Font(const std::string& fontFile, unsigned int renderSize)
    45   : data(Font::defaultFontData)
     45    : data(Font::defaultFontData)
    4646{
    4747  this->init();
     
    5757 */
    5858Font::Font(const std::string& imageFile)
    59   : data(Font::defaultFontData)
     59    : data(Font::defaultFontData)
    6060{
    6161  this->init();
     
    8282 */
    8383Font::Font(char** xpmArray)
    84   : data(Font::defaultFontData)
     84    : data(Font::defaultFontData)
    8585{
    8686  this->init();
     
    133133  if (Font::defaultFontData.get() == NULL)
    134134  {
    135      Font::initDefaultFont();
     135    Font::initDefaultFont();
    136136    this->data = Font::defaultFontData;
    137137  }
     
    161161{
    162162  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)
    182165    this->data = Font::defaultFontData;
    183     return false;
    184   }
    185 
     166
     167  this->setTexture(this->data->texData);
     168  return retVal;
    186169}
    187170
     
    192175bool Font::loadFontFromSDL_Surface(SDL_Surface* surface)
    193176{
    194   if(surface == NULL)
    195     return false;
    196 
    197177  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)
    210180    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;
    242184}
    243185
     
    250192void Font::setStyle(const std::string& renderStyle)
    251193{
    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
     198void Font::setTexture(const TextureDataPointer& texDataPointer)
     199{
     200  this->setDiffuseMap(texDataPointer);
     201}
     202
    268203
    269204/**
     
    327262
    328263
    329 /**
    330  * @returns the maximum height of the Font, if the font was initialized, 0 otherwise
    331  */
    332 int Font::getMaxHeight() const
    333 {
    334   if (likely (this->data->fontTTF != NULL))
    335     return TTF_FontHeight(this->data->fontTTF);
    336   else
    337     return 1;
    338 }
    339 
    340 /**
    341  * @returns the maximum ascent of the Font, if the font was initialized, 0 otherwise
    342  *
    343  * the ascent is the pixels of the font above the baseline
    344  */
    345 int Font::getMaxAscent() const
    346 {
    347   if (likely(this->data->fontTTF != NULL))
    348     return TTF_FontAscent(this->data->fontTTF);
    349   else
    350     return 0;
    351 }
    352 
    353 /**
    354  * @returns the maximum descent of the Font, if the font was initialized, 0 otherwise
    355  *
    356  * the descent is the pixels of the font below the baseline
    357  */
    358 int Font::getMaxDescent() const
    359 {
    360   if (likely(this->data->fontTTF != NULL))
    361     return TTF_FontDescent(this->data->fontTTF);
    362   else
    363     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. see
    373  * http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html
    374  * for more info about vertical Fonts
    375  */
    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 Font
    408  */
    409 bool Font::createFastTexture()
    410 {
    411   /* interesting GLYPHS:
    412   *  32: space
    413   *  33-47: Special Characters.
    414   *  48-57: 0-9
    415   *  58-63: some more special chars (minor)
    416   *  65-90: A-Z
    417   *  97-122: a-z
    418   */
    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 Space
    423 
    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                           0xFF000000
    438 #else
    439                           0xFF000000,
    440                           0x00FF0000,
    441                           0x0000FF00,
    442                           0x000000FF
    443 #endif
    444                                               );
    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 Glyphs
    450   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 Glyph
    471       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-table
    494 //       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 NULL
    526   *  only if the Glyph-array has not been initialized
    527   */
    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     else
    544     {
    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 size
    554  *
    555  * @todo: this algorithm can be a lot faster, althought it does
    556  * not really matter within the init-context, and 128 glyphs.
    557  *
    558  * This function searches for a 2^n sizes texture-size, this is for
    559  * 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 counters
    568   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     else
    599       size *= 2;
    600   }
    601   return size;
    602 }
    603264
    604265
Note: See TracChangeset for help on using the changeset viewer.