Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Apr 29, 2006, 9:38:44 PM (18 years ago)
Author:
bensch
Message:

orxonox/trunk: added MultiLineText a Text for multiple line-input, that should automatically shilft position

File:
1 copied

Legend:

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

    r7449 r7450  
    1616#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
    1717
    18 #include "text.h"
     18#include "multi_line_text.h"
    1919#include "font.h"
    20 
    21 #include "util/loading/resource_manager.h"
    22 #include "debug.h"
    2320
    2421using namespace std;
     
    2926 * @param type The renderType to display this font in
    3027 */
    31 Text::Text(const std::string& fontFile, unsigned int textSize)
     28MultiLineText::MultiLineText(const std::string& fontFile, unsigned int textSize)
     29  : Text(fontFile, textSize)
    3230{
    33   this->setClassID(CL_TEXT, "Text");
     31  this->setClassID(CL_MULTI_LINE_TEXT, "MultiLineText");
    3432
    35   // initialize this Text
    36   this->font = NULL;
    37   this->text = "";
    38   this->setAlignment(TEXT_DEFAULT_ALIGNMENT);
    39   this->blending = TEXT_DEFAULT_BLENDING;
    40   this->color = TEXT_DEFAULT_COLOR;
    41   this->setSize(TEXT_DEFAULT_SIZE);
    42   this->setText("");
    43 
    44 
    45   if (!fontFile.empty())
    46     this->setFont(fontFile, FONT_DEFAULT_RENDER_SIZE);
    47   this->setSizeY2D(textSize);
     33  this->lineSpacing = 1.0f;
     34  this->lineWidth = 100.0f;
     35  this->setupTextWidth();
    4836}
    4937
    5038/**
    51  * @brief deletes a Text out of memory
     39 * @brief sets the maximum Line width
     40 * @param lineWidth the maximum lineWidth.
    5241 */
    53 Text::~Text()
     42void MultiLineText::setLineWidth(float lineWidth)
    5443{
    55   if (this->font != NULL && this->font != Font::getDefaultFont())
    56     ResourceManager::getInstance()->unload(this->font);
     44  this->lineWidth = lineWidth;
     45  this->setupTextWidth();
    5746}
    5847
    5948
    6049/**
    61  * @brief sets the Font of this Text to font from fontFile
    62  * @param fontFile the File to load the Font from.
    63  * @param fontSize the Size of the Font
    64  */
    65 void Text::setFont(const std::string& fontFile, unsigned int fontSize)
    66 {
    67   Font* newFont;
    68   Font* oldFont = this->font;
    69 
    70   // load a new Font
    71   if (!fontFile.empty())
    72   {
    73     newFont = (Font*)ResourceManager::getInstance()->load(fontFile, TTF, RP_GAME, (int)fontSize);
    74     if (newFont == NULL)
    75     {
    76       newFont = Font::getDefaultFont();
    77       PRINTF(2)("Font %s could not be loaded, probably file not found\n", fontFile.c_str());
    78     }
    79   }
    80   else
    81     newFont = Font::getDefaultFont();
    82 
    83   // unloading the Font if we alrady have one loaded.
    84   this->font = newFont;
    85   if (oldFont != NULL && oldFont != Font::getDefaultFont())
    86     ResourceManager::getInstance()->unload(oldFont);
    87 }
    88 
    89 /**
    90  * @brief Sets a new Text to the font
    91  * @param text the new text to set
    92  */
    93 void Text::setText(const std::string& text)
    94 {
    95   this->text = text;
    96 
    97   // setting up the Text-Width if DYNAMIC
    98   //  if (this->type & TEXT_RENDER_DYNAMIC && this->getAlignment() != TEXT_ALIGN_LEFT && this->font != NULL)
    99   const Font* calcSizeFont = this->font;
    100   if (calcSizeFont != NULL || (calcSizeFont = Font::getDefaultFont()) != NULL)
    101   {
    102     Glyph** glyphArray = calcSizeFont->getGlyphArray();
    103 
    104     float width = 0;
    105     if (!this->text.empty())
    106     {
    107       for (unsigned int i = 0; i < this->text.size(); i++)
    108       {
    109         if(glyphArray[this->text[i]] != NULL)
    110         {
    111           width += glyphArray[this->text[i]]->advance;
    112         }
    113       }
    114       this->setSizeX2D(width *this->getSizeY2D());
    115     }
    116   }
    117 }
    118 
    119 /**
    12050 * @brief draws the Text
    12151 */
    122 void Text::draw() const
     52void MultiLineText::draw() const
    12353{
    124   if (unlikely(this->text.empty()))
     54  if (unlikely(this->getText().empty()))
    12555    return;
    12656  glPushMatrix();
    12757  // transform for alignment.
     58  // TODO make the Stuff with the alignment
    12859  if (this->getAlignment() == TEXT_ALIGN_RIGHT)
    12960    glTranslatef(-this->getSizeX2D(), 0, 0);
     
    13364  // drawing this Text.
    13465  // setting the Blending effects
    135   glColor4f(this->color.x, this->color.y, this->color.z, this->blending);
     66  glColor4f(this->getColor().x, this->getColor().y, this->getColor().z, this->getBlending());
    13667  glEnable(GL_BLEND);
    13768  glEnable(GL_TEXTURE_2D);
     
    13970  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, GL_MODULATE );
    14071
    141   Glyph** glyphArray = this->font->getGlyphArray();
    142   glBindTexture(GL_TEXTURE_2D, font->getTexture());
    143   glTranslatef(getAbsCoor2D().x, getAbsCoor2D().y, 0);
     72  glBindTexture(GL_TEXTURE_2D, this->getFont()->getTexture());
     73  glTranslatef(this->getAbsCoor2D().x, this->getAbsCoor2D().y, 0);
    14474  glRotatef(this->getAbsDir2D(), 0, 0, 1);
    14575
    14676  Glyph* tmpGlyph;
    14777  float posX = 0.0f;
     78  float posY = 0.0f;
     79  unsigned int lineNumber = 0;
     80
    14881  glBegin(GL_QUADS);
    149   for (unsigned int i = 0; i < this->text.size(); i++)
     82  for (unsigned int i = 0; i < this->getText().size(); i++)
    15083  {
    151     if(likely((tmpGlyph = glyphArray[this->text[i]]) != NULL))
     84    if (unlikely(tmpGlyph->character == '\n' || i == this->lineEnds[lineNumber]))
     85    {
     86    // go to the next Line.
     87      lineNumber++;
     88      posX = 0.0f;
     89      posY += this->lineSpacing + this->getFont()->getMaxHeight();
     90    }
     91
     92    if(likely((tmpGlyph = this->getFont()->getGlyphArray()[this->getText()[i]]) != NULL))
    15293    {
    15394      glTexCoord2f(tmpGlyph->texCoord[1], tmpGlyph->texCoord[2]);
    154       glVertex2d(posX+tmpGlyph->maxX*this->getSizeY2D(), 0);
     95      glVertex2d(posX+tmpGlyph->maxX*this->getSize(), posY);
    15596
    15697      glTexCoord2f(tmpGlyph->texCoord[1], tmpGlyph->texCoord[3]);
    157       glVertex2d(posX+tmpGlyph->maxX*this->getSizeY2D(), this->getSizeY2D());
     98      glVertex2d(posX+tmpGlyph->maxX*this->getSize(), posY + this->getSize());
    15899
    159100      glTexCoord2f(tmpGlyph->texCoord[0], tmpGlyph->texCoord[3]);
    160       glVertex2d(posX+tmpGlyph->minX*this->getSizeY2D(), this->getSizeY2D());
     101      glVertex2d(posX+tmpGlyph->minX*this->getSize(), posY+ this->getSize());
    161102
    162103      glTexCoord2f(tmpGlyph->texCoord[0], tmpGlyph->texCoord[2]);
    163       glVertex2d(posX+tmpGlyph->minX*this->getSizeY2D(), 0);
     104      glVertex2d(posX+tmpGlyph->minX*this->getSize(), posY);
    164105
    165       posX += tmpGlyph->advance * this->getSizeY2D();
     106      posX += tmpGlyph->advance * this->getSize();
    166107    }
    167108  }
     
    171112
    172113/**
    173  * @brief prints out some nice debug information about this text
     114 * @brief setting up the Text-Width if DYNAMIC
    174115 */
    175 void Text::debug() const
     116void MultiLineText::setupTextWidth()
    176117{
    177   PRINT(0)("=== TEXT: %s ===\n", this->text.c_str());
    178   PRINT(0)("Color: %0.2f %0.2f %0.2f\n", this->color.x, this->color.y, this->color.z);
     118  this->lineEnds.clear();
     119  float width = 0.0f;
     120  // TODO make size local to this (not using the one from Element2D.
     121  float maxWidth = this->lineWidth / this->getSize();
     122
     123  for (unsigned int i = 0; i < this->getText().size(); i++)
     124  {
     125    if (width > maxWidth || this->getText()[i] == '\n')
     126    {
     127      this->lineEnds.push_back(i);
     128      width = 0.0f;
     129    }
     130    // Advance the Text.
     131    if(this->getFont()->getGlyphArray()[this->getText()[i]] != NULL)
     132      width += this->getFont()->getGlyphArray()[this->getText()[i]]->advance;
     133  }
    179134}
    180 
    181 
    182 ////////////
    183 /// UTIL ///
    184 ////////////
    185 /**
    186  * @brief Loads a Font from an SDL_surface into a texture.
    187  * @param surface The surface to make the texture of
    188  * @param texCoord The texture coordinates of the 4 corners of the texture
    189  * @returns the ID of the texture
    190  */
    191 GLuint Text::loadTexture(SDL_Surface *surface, TexCoord* texCoord)
    192 {
    193   GLuint texture;
    194   int w, h;
    195   SDL_Surface *image;
    196   SDL_Rect area;
    197   Uint32 saved_flags;
    198   Uint8  saved_alpha;
    199 
    200   /* Use the surface width and height expanded to powers of 2 */
    201   w = powerOfTwo(surface->w);
    202   h = powerOfTwo(surface->h);
    203   if (texCoord != NULL)
    204   {
    205     texCoord->minU = 0.0f;
    206     texCoord->minV = 0.0f;
    207     texCoord->maxU = (GLfloat)surface->w / w;
    208     texCoord->maxV = (GLfloat)surface->h / h;
    209   }
    210   image = SDL_CreateRGBSurface(SDL_SWSURFACE,
    211                                w, h,
    212                                32,
    213 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
    214                                0x000000FF,
    215                                0x0000FF00,
    216                                0x00FF0000,
    217                                0xFF000000
    218 #else
    219                                0xFF000000,
    220                                0x00FF0000,
    221                                0x0000FF00,
    222                                0x000000FF
    223 #endif
    224                               );
    225   if ( image == NULL )
    226   {
    227     return 0;
    228   }
    229 
    230   /* Save the alpha blending attributes */
    231   saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
    232   saved_alpha = surface->format->alpha;
    233   if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA )
    234   {
    235     SDL_SetAlpha(surface, 0, 0);
    236   }
    237 
    238   /* Copy the surface into the GL texture image */
    239   area.x = 0;
    240   area.y = 0;
    241   area.w = surface->w;
    242   area.h = surface->h;
    243   SDL_BlitSurface(surface, &area, image, &area);
    244 
    245   /* Restore the alpha blending attributes */
    246   if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA )
    247   {
    248     SDL_SetAlpha(surface, saved_flags, saved_alpha);
    249   }
    250 
    251   /* Create an OpenGL texture for the image */
    252   glGenTextures(1, &texture);
    253   glBindTexture(GL_TEXTURE_2D, texture);
    254   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    255   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    256   glTexImage2D(GL_TEXTURE_2D,
    257                0,
    258                GL_RGBA,
    259                w, h,
    260                0,
    261                GL_RGBA,
    262                GL_UNSIGNED_BYTE,
    263                image->pixels);
    264   SDL_FreeSurface(image); /* No longer needed the data */
    265 
    266   return texture;
    267 }
    268 
    269 /**
    270  * @brief Quick utility function for texture creation
    271  * @param input an integer
    272  * @returns the next bigger 2^n-integer than input
    273  */
    274 int Text::powerOfTwo(int input)
    275 {
    276   int value = 1;
    277 
    278   while ( value < input )
    279     value <<= 1;
    280   return value;
    281 }
Note: See TracChangeset for help on using the changeset viewer.