String.cpp

00001 
00002 //
00003 // SFML - Simple and Fast Multimedia Library
00004 // Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
00005 //
00006 // This software is provided 'as-is', without any express or implied warranty.
00007 // In no event will the authors be held liable for any damages arising from the use of this software.
00008 //
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it freely,
00011 // subject to the following restrictions:
00012 //
00013 // 1. The origin of this software must not be misrepresented;
00014 //    you must not claim that you wrote the original software.
00015 //    If you use this software in a product, an acknowledgment
00016 //    in the product documentation would be appreciated but is not required.
00017 //
00018 // 2. Altered source versions must be plainly marked as such,
00019 //    and must not be misrepresented as being the original software.
00020 //
00021 // 3. This notice may not be removed or altered from any source distribution.
00022 //
00024 
00026 // Headers
00028 #include <SFML/Graphics/String.hpp>
00029 #include <SFML/Graphics/FontManager.hpp>
00030 #include <SFML/Graphics/Image.hpp>
00031 #include <SFML/Graphics/OpenGL.hpp>
00032 
00033 
00037 sfString::sfString(const std::string& Text, const std::string& Font, float Size) :
00038 myText(Text),
00039 myFont(Font),
00040 mySize(Size)
00041 {
00042 
00043 }
00044 
00045 
00049 void sfString::PreloadFont(const std::string& Font, float Char)
00050 {
00051     // Requesting the font will make the font manager create it
00052     sf_private::sfFontManager::GetInstance().GetBitmapFont(Font, static_cast<unsigned int>(Char));
00053 }
00054 
00055 
00059 void sfString::SetText(const std::string& Text)
00060 {
00061     myText = Text;
00062 }
00063 
00064 
00068 void sfString::SetFont(const std::string& Font)
00069 {
00070     myFont = Font;
00071 }
00072 
00073 
00077 void sfString::SetSize(float Size)
00078 {
00079     mySize = Size;
00080 }
00081 
00082 
00086 const std::string& sfString::GetText() const
00087 {
00088     return myText;
00089 }
00090 
00091 
00095 const std::string& sfString::GetFont() const
00096 {
00097     return myFont;
00098 }
00099 
00100 
00104 float sfString::GetSize() const
00105 {
00106     return mySize;
00107 }
00108 
00109 
00113 sfFloatRect sfString::GetRect() const
00114 {
00115     // Get the bitmap font from the font manager
00116     const sf_private::sfFontManager::Font& BitmapFont = sf_private::sfFontManager::GetInstance().GetBitmapFont(myFont, static_cast<unsigned int>(mySize));
00117 
00118     // Initial values
00119     float CurWidth = 0;
00120     float Width    = 0;
00121     float Height   = mySize;
00122 
00123     // Go through each character
00124     for (std::size_t i = 0; i < myText.size(); ++i)
00125     {
00126         // Get the current character
00127         unsigned char c = static_cast<unsigned char>(myText[i]);
00128 
00129         // Get the dimensions of the current character from the font description
00130         const float Advance = BitmapFont.Advance[c] * mySize / BitmapFont.CharSize;
00131 
00132         // Handle special characters...
00133         switch (c)
00134         {
00135             case ' ' :  CurWidth += Advance;    continue;
00136             case '\t' : CurWidth += mySize * 4; continue;
00137             case '\v' : Height   += mySize * 4; continue;
00138 
00139             case '\n' :
00140                 Height += mySize;
00141                 if (CurWidth > Width) Width = CurWidth;
00142                 CurWidth = 0;
00143                 continue;
00144         }
00145 
00146         // Advance to the next character
00147         CurWidth += Advance;
00148     }
00149 
00150     // In case there was no '\n' in the string
00151     if (Width < 1)
00152         Width = CurWidth;
00153 
00154     return sfFloatRect(GetLeft(), GetTop(), GetLeft() + Width, GetTop() + Height);
00155 }
00156 
00157 
00161 void sfString::Render(sfRenderWindow&)
00162 {
00163     // No text, no rendering :)
00164     if (myText.empty())
00165         return;
00166 
00167     // Get the bitmap font from the font manager
00168     const sf_private::sfFontManager::Font& BitmapFont = sf_private::sfFontManager::GetInstance().GetBitmapFont(myFont, static_cast<unsigned int>(mySize));
00169 
00170     // Set the scaling factor to get the actual size
00171     float Factor = GetScale() * mySize / BitmapFont.CharSize;
00172     sfGLCheck(glScalef(Factor, Factor, 1.f));
00173 
00174     // Bind the font texture
00175     BitmapFont.Image.Bind();
00176 
00177     float X = 0;
00178     float Y = 0;
00179 
00180     // Draw the sprite
00181     glBegin(GL_QUADS);
00182     for (std::size_t i = 0; i < myText.size(); ++i)
00183     {
00184         // Get the current character
00185         unsigned char c = static_cast<unsigned char>(myText[i]);
00186 
00187         // Get the dimensions of the current character from font description
00188         const sfIntRect&   Rect     = BitmapFont.Rect[c];
00189         const sfFloatRect& Coord    = BitmapFont.Coord[c];
00190         const unsigned int AdvanceX = BitmapFont.Advance[c];
00191         const unsigned int AdvanceY = BitmapFont.CharSize;
00192 
00193         // Handle special characters
00194         switch (c)
00195         {
00196             case ' ' :  X += AdvanceX;        continue;
00197             case '\n' : Y += AdvanceY; X = 0; continue;
00198             case '\t' : X += AdvanceX * 4;    continue;
00199             case '\v' : Y += AdvanceY * 4;    continue;
00200         }
00201 
00202         // Draw a textured quad for the current character
00203         glTexCoord2f(Coord.Left,  Coord.Top);    glVertex2f(X + Rect.Left,  Y + Rect.Top    + AdvanceY);
00204         glTexCoord2f(Coord.Left,  Coord.Bottom); glVertex2f(X + Rect.Left,  Y + Rect.Bottom + AdvanceY);
00205         glTexCoord2f(Coord.Right, Coord.Bottom); glVertex2f(X + Rect.Right, Y + Rect.Bottom + AdvanceY);
00206         glTexCoord2f(Coord.Right, Coord.Top);    glVertex2f(X + Rect.Right, Y + Rect.Top    + AdvanceY);
00207 
00208         // Advance to the next character
00209         X += AdvanceX;
00210     }
00211     glEnd();
00212 }