diff --git a/src/graphics/cshape.cpp b/src/graphics/cshape.cpp index b78f47ae7..b244d5689 100644 --- a/src/graphics/cshape.cpp +++ b/src/graphics/cshape.cpp @@ -94,7 +94,7 @@ cShape::~cShape() { } void cShape::CreateUnnamed() { - Name( StrFormated( "unnamed%d", cShapeManager::instance()->Count() - 1 ) ); + Name( std::string( "unnamed" ) + toStr( cShapeManager::instance()->Count() ) ); } const Uint32& cShape::Id() const { diff --git a/src/graphics/cshapemanager.cpp b/src/graphics/cshapemanager.cpp index dda5e78c4..37b49d335 100644 --- a/src/graphics/cshapemanager.cpp +++ b/src/graphics/cshapemanager.cpp @@ -115,7 +115,7 @@ void cShapeManager::Clear() { } Uint32 cShapeManager::Count() { - return mShapes.size(); + return mCount; } }} diff --git a/src/graphics/cttffont.cpp b/src/graphics/cttffont.cpp index 2281a1b73..afafd75ab 100755 --- a/src/graphics/cttffont.cpp +++ b/src/graphics/cttffont.cpp @@ -2,7 +2,7 @@ namespace EE { namespace Graphics { -cTTFFont::cTTFFont() : cFont(), mFont(0) { +cTTFFont::cTTFFont() : cFont(), mFont(0), mPixels(NULL) { TF = cTextureFactory::instance(); if ( hkFontManager::instance()->Init() ) @@ -44,202 +44,198 @@ bool cTTFFont::Load(const std::string& Filepath, const eeUint& Size, EE_TTF_FONT return iLoad( Size, Style, VerticalDraw, NumCharsToGen, FontColor, OutlineSize, OutlineColor ); } -bool cTTFFont::iLoad(const eeUint& Size, EE_TTF_FONTSTYLE Style, const bool& VerticalDraw, const Uint16& NumCharsToGen, const eeColor& FontColor, const Uint8& OutlineSize, const eeColor& OutlineColor ) { - SDL_Rect CurrentPos = {0, 0, 0, 0}; - SDL_Rect GlyphRect = {0, 0, 0, 0}; - - unsigned char * TempGlyphSurface; - - eeFloat Top, Bottom; - Uint8 OutlineTotal = OutlineSize * 2; - - if ( !mTTFInit ) - return false; - - try { - if ( mFont == NULL ) - return false; - - mFont->Style( Style ); - - mVerticalDraw = VerticalDraw; - mSize = Size; - mNumChars = NumCharsToGen; - - mFontColor = FontColor; - mOutlineColor = OutlineColor; - - mStyle = Style; - - mGlyphs.clear(); - mGlyphs.resize( mNumChars ); - - mTexWidth = (eeFloat)NextPowOfTwo( mSize * 16 ); - mTexHeight = mTexWidth; - - if ( ( mSize >= 60 && mNumChars > 256 ) || ( OutlineSize > 2 && mNumChars >= 512 && mSize >= 24 ) ) - mTexHeight *= 2; - - mHeight = mFont->Height() + OutlineTotal; - - Uint32 TexId = TF->CreateEmptyTexture( mTexWidth, mTexHeight, eeColorA(0x00000000) ); - - cTexture * Tex = TF->GetTexture( TexId ); - - Tex->Lock(); - - CurrentPos.x = OutlineSize; - CurrentPos.y = OutlineSize; - - //Loop through all chars - for ( eeUint i = 0; i < mNumChars; i++) { - TempGlyphSurface = mFont->GlyphRender( i, 0x00000000 ); - - //New temp glyph - eeGlyph TempGlyph; - - //Get the glyph attributes - mFont->GlyphMetrics( i, &TempGlyph.MinX, &TempGlyph.MaxX, &TempGlyph.MinY, &TempGlyph.MaxY, &TempGlyph.Advance ); - - //Set size of glyph rect - GlyphRect.w = mFont->Current()->Pixmap()->width; - GlyphRect.h = mFont->Current()->Pixmap()->rows; - - //Set size of current position rect - CurrentPos.w = CurrentPos.x + TempGlyph.MaxX; - CurrentPos.h = CurrentPos.y + TempGlyph.MaxY; - - if (CurrentPos.w >= mTexWidth) { - CurrentPos.x = 0 + OutlineSize; - CurrentPos.y += mHeight; - } - - //Blit the glyph onto the glyph sheet - Uint32 * TexGlyph = reinterpret_cast ( TempGlyphSurface ); - Uint32 Alpha; - Uint32 w = Tex->Width(); - Uint32 h = Tex->Height(); - Uint32 px, py; - - for (int y = 0; y < GlyphRect.h; ++y ) { - for (int x = 0; x < GlyphRect.w; ++x ) { - Alpha = ( TexGlyph[ x + y * GlyphRect.w ] >> 24 ) & 0xFF; - - px = CurrentPos.x + x; - py = CurrentPos.y + y; - - if ( px < w && py < h ) - Tex->SetPixel( px, py, eeColorA( FontColor.R(), FontColor.G(), FontColor.B(), Alpha ) ); - } +bool cTTFFont::iLoad(const eeUint& Size, EE_TTF_FONTSTYLE Style, const bool& VerticalDraw, const Uint16& NumCharsToGen, const eeColor& FontColor, const Uint8& OutlineSize, const eeColor& OutlineColor ) { + eeRect CurrentPos; + eeSize GlyphRect; + + unsigned char * TempGlyphSurface; + + eeFloat Top, Bottom; + Uint8 OutlineTotal = OutlineSize * 2; + Uint32 TexSize; + + if ( !mTTFInit ) + return false; + + try { + if ( mFont == NULL ) + return false; + + mFont->Style( Style ); + + mVerticalDraw = VerticalDraw; + mSize = Size; + mNumChars = NumCharsToGen; + + mFontColor = FontColor; + mOutlineColor = OutlineColor; + + mStyle = Style; + + mGlyphs.clear(); + mGlyphs.resize( mNumChars ); + + mTexWidth = (eeFloat)NextPowOfTwo( mSize * 16 ); + mTexHeight = mTexWidth; + + TexSize = mTexWidth * mTexHeight; + + if ( ( mSize >= 60 && mNumChars > 256 ) || ( OutlineSize > 2 && mNumChars >= 512 && mSize >= 24 ) ) + mTexHeight *= 2; + + mHeight = mFont->Height() + OutlineTotal; + + mPixels = new eeColorA[ TexSize ]; + memset( mPixels, 0x00000000, TexSize * 4 ); + + CurrentPos.Left = OutlineSize; + CurrentPos.Top = OutlineSize; + + //Loop through all chars + for ( eeUint i = 0; i < mNumChars; i++) { + TempGlyphSurface = mFont->GlyphRender( i, 0x00000000 ); + + //New temp glyph + eeGlyph TempGlyph; + + //Get the glyph attributes + mFont->GlyphMetrics( i, &TempGlyph.MinX, &TempGlyph.MaxX, &TempGlyph.MinY, &TempGlyph.MaxY, &TempGlyph.Advance ); + + //Set size of glyph rect + GlyphRect.x = mFont->Current()->Pixmap()->width; + GlyphRect.y = mFont->Current()->Pixmap()->rows; + + //Set size of current position rect + CurrentPos.Right = CurrentPos.Left + TempGlyph.MaxX; + CurrentPos.Bottom = CurrentPos.Top + TempGlyph.MaxY; + + if (CurrentPos.Right >= mTexWidth) { + CurrentPos.Left = 0 + OutlineSize; + CurrentPos.Top += mHeight; } - - // Fixes the width and height of the current pos - CurrentPos.w = GlyphRect.w; - CurrentPos.h = GlyphRect.h; - - // Set texture coordinates to te list - eeRectf tR; - tR.Left = (eeFloat)( CurrentPos.x - OutlineSize ) / mTexWidth; - tR.Top = (eeFloat)( CurrentPos.y - OutlineSize ) / mTexHeight; - - tR.Right = (eeFloat)(CurrentPos.x + CurrentPos.w + OutlineSize ) / mTexWidth; - tR.Bottom = (eeFloat)(CurrentPos.y + CurrentPos.h + OutlineSize ) / mTexHeight; - - GlyphRect.h += OutlineSize; - TempGlyph.Advance += OutlineSize; - - Top = static_cast ( mSize - GlyphRect.h - TempGlyph.MinY ); - Bottom = static_cast ( mSize + GlyphRect.h - TempGlyph.MaxY ); - - // Translate the Glyph coordinates to the new texture coordinates - TempGlyph.MinX -= OutlineSize; - TempGlyph.MinY -= OutlineSize; - TempGlyph.MaxX += OutlineSize; - TempGlyph.MaxY += OutlineSize; - TempGlyph.CurX = CurrentPos.x - OutlineSize; - TempGlyph.CurW = CurrentPos.w + OutlineTotal; - TempGlyph.CurY = CurrentPos.y - OutlineSize; - TempGlyph.CurH = CurrentPos.h + OutlineTotal; - TempGlyph.GlyphH = GlyphRect.h + OutlineSize; - - //Position xpos ready for next glyph - CurrentPos.x += GlyphRect.w + OutlineTotal; - - //If the next character will run off the edge of the glyph sheet, advance to next row - if (CurrentPos.x + CurrentPos.w > mTexWidth) { - CurrentPos.x = 0 + OutlineSize; - CurrentPos.y += mHeight; - } - - //Push back to glyphs vector - mGlyphs[i] = TempGlyph; - - //Free surface - eeSAFE_DELETE_ARRAY( TempGlyphSurface ); - } - - if ( !mTexId ) { - - // Recover the Alpha channel - mTexId = TexId; - - if ( OutlineSize && Tex ) { - eeColorA P, R; - Uint32 Pos = 0; - - std::vector TexO( (Uint32)Tex->Width() * (Uint32)Tex->Height(), 0 ); - std::vector TexN( (Uint32)Tex->Width() * (Uint32)Tex->Height(), 0 ); - std::vector TexI( (Uint32)Tex->Width() * (Uint32)Tex->Height(), 0 ); - - // Fill the TexO ( the default font alpha channels ) and the TexN ( the new outline ) - for ( Int32 y = 0; y < Tex->Height(); y++ ) { - for( Int32 x = 0; x < Tex->Width(); x++) { - Pos = x + y * (Uint32)Tex->Width(); - TexO[ Pos ] = Tex->GetPixel( x, y ).A(); - TexN[ Pos ] = TexO[ Pos ]; - } - } - - Uint8* alpha = reinterpret_cast( &TexN[0] ); - Uint8* alpha2 = reinterpret_cast( &TexI[0] ); - - // Create the outline - for ( Uint8 passes = 0; passes < OutlineSize; passes++ ) { - MakeOutline( alpha, alpha2, static_cast( Tex->Width() ), static_cast( Tex->Height() ) ); - - Uint8* temp = alpha; - alpha = alpha2; - alpha2 = temp; - } - - for ( Int32 y = 0; y < Tex->Height(); y++ ) { - for( Int32 x = 0; x < Tex->Width(); x++) { - Pos = x + y * (Uint32)Tex->Width(); - - // Fill the outline color - Tex->SetPixel( x, y, eeColorA( OutlineColor.R(), OutlineColor.G(), OutlineColor.B(), alpha[ Pos ] ) ); - - // Fill the font color - if ( TexO[ Pos ] > 50 ) - Tex->SetPixel( x, y, eeColorA( FontColor.R(), FontColor.G(), FontColor.B(), TexO[ Pos ] ) ); - } - } - } - - Tex->Unlock( false, true ); - - } - - hkFontManager::instance()->CloseFont( mFont ); - - RebuildFromGlyphs(); - - cLog::instance()->Write( "TTF Font " + mFilepath + " loaded." ); - return true; - } catch (...) { - cLog::instance()->Write( "Failed to load TTF Font " + mFilepath + "." ); - return false; - } + + //Blit the glyph onto the glyph sheet + Uint32 * TexGlyph = reinterpret_cast ( TempGlyphSurface ); + Uint32 Alpha; + Uint32 w = mTexWidth; + Uint32 h = mTexHeight; + Uint32 px, py; + + for (int y = 0; y < GlyphRect.y; ++y ) { + for (int x = 0; x < GlyphRect.x; ++x ) { + Alpha = ( TexGlyph[ x + y * GlyphRect.x ] >> 24 ) & 0xFF; + + px = CurrentPos.Left + x; + py = CurrentPos.Top + y; + + if ( px < w && py < h ) { + mPixels[ px + py * w ] = eeColorA( FontColor.R(), FontColor.G(), FontColor.B(), Alpha ); + } + } + } + + // Fixes the width and height of the current pos + CurrentPos.Right = GlyphRect.x; + CurrentPos.Bottom = GlyphRect.y; + + // Set texture coordinates to te list + eeRectf tR; + tR.Left = (eeFloat)( CurrentPos.Left - OutlineSize ) / mTexWidth; + tR.Top = (eeFloat)( CurrentPos.Top - OutlineSize ) / mTexHeight; + + tR.Right = (eeFloat)(CurrentPos.Left + CurrentPos.Right + OutlineSize ) / mTexWidth; + tR.Bottom = (eeFloat)(CurrentPos.Top + CurrentPos.Bottom + OutlineSize ) / mTexHeight; + + GlyphRect.y += OutlineSize; + TempGlyph.Advance += OutlineSize; + + Top = static_cast ( mSize - GlyphRect.y - TempGlyph.MinY ); + Bottom = static_cast ( mSize + GlyphRect.y - TempGlyph.MaxY ); + + // Translate the Glyph coordinates to the new texture coordinates + TempGlyph.MinX -= OutlineSize; + TempGlyph.MinY -= OutlineSize; + TempGlyph.MaxX += OutlineSize; + TempGlyph.MaxY += OutlineSize; + TempGlyph.CurX = CurrentPos.Left - OutlineSize; + TempGlyph.CurW = CurrentPos.Right + OutlineTotal; + TempGlyph.CurY = CurrentPos.Top - OutlineSize; + TempGlyph.CurH = CurrentPos.Bottom + OutlineTotal; + TempGlyph.GlyphH = GlyphRect.y + OutlineSize; + + //Position xpos ready for next glyph + CurrentPos.Left += GlyphRect.x + OutlineTotal; + + //If the next character will run off the edge of the glyph sheet, advance to next row + if (CurrentPos.Left + CurrentPos.Right > mTexWidth) { + CurrentPos.Left = 0 + OutlineSize; + CurrentPos.Top += mHeight; + } + + //Push back to glyphs vector + mGlyphs[i] = TempGlyph; + + //Free surface + eeSAFE_DELETE_ARRAY( TempGlyphSurface ); + } + + if ( OutlineSize ) { + eeColorA P, R; + Uint32 Pos = 0; + + std::vector TexO( TexSize, 0 ); + std::vector TexN( TexSize, 0 ); + std::vector TexI( TexSize, 0 ); + + // Fill the TexO ( the default font alpha channels ) and the TexN ( the new outline ) + for ( Int32 y = 0; y < mTexHeight; y++ ) { + for( Int32 x = 0; x < mTexWidth; x++) { + Pos = x + y * mTexWidth; + TexO[ Pos ] = mPixels[ Pos ].A(); + TexN[ Pos ] = TexO[ Pos ]; + } + } + + Uint8* alpha = reinterpret_cast( &TexN[0] ); + Uint8* alpha2 = reinterpret_cast( &TexI[0] ); + + // Create the outline + for ( Uint8 passes = 0; passes < OutlineSize; passes++ ) { + MakeOutline( alpha, alpha2, static_cast( mTexWidth ), static_cast( mTexHeight ) ); + + Uint8* temp = alpha; + alpha = alpha2; + alpha2 = temp; + } + + for ( Int32 y = 0; y < mTexHeight; y++ ) { + for( Int32 x = 0; x < mTexWidth; x++) { + Pos = x + y * mTexWidth; + + // Fill the outline color + mPixels[ Pos ] = eeColorA( OutlineColor.R(), OutlineColor.G(), OutlineColor.B(), alpha[ Pos ] ); + + // Fill the font color + if ( TexO[ Pos ] > 50 ) + mPixels[ Pos ] = eeColorA( FontColor.R(), FontColor.G(), FontColor.B(), TexO[ Pos ] ); + } + } + } + + hkFontManager::instance()->CloseFont( mFont ); + + mTexId = TF->LoadFromPixels( reinterpret_cast ( &mPixels[0] ), mTexWidth, mTexHeight, 4 ); + + eeSAFE_DELETE_ARRAY( mPixels ); + + RebuildFromGlyphs(); + + cLog::instance()->Write( "TTF Font " + mFilepath + " loaded." ); + return true; + } catch (...) { + cLog::instance()->Write( "Failed to load TTF Font " + mFilepath + "." ); + return false; + } } void cTTFFont::RebuildFromGlyphs() { diff --git a/src/graphics/cttffont.hpp b/src/graphics/cttffont.hpp index e863fc043..bad6a740a 100755 --- a/src/graphics/cttffont.hpp +++ b/src/graphics/cttffont.hpp @@ -68,6 +68,7 @@ class EE_API cTTFFont : public cFont { private: cTextureFactory* TF; hkFont * mFont; + eeColorA * mPixels; std::string mFilepath; Uint32 mBase; diff --git a/src/helper/haikuttf/hkfont.cpp b/src/helper/haikuttf/hkfont.cpp index 770087c5f..da593e91f 100644 --- a/src/helper/haikuttf/hkfont.cpp +++ b/src/helper/haikuttf/hkfont.cpp @@ -26,11 +26,11 @@ hkFont::hkFont( hkFontManager * FontManager, unsigned int CacheSize ) : mFm = FontManager; mCacheSize = CacheSize; - mCache.resize( mCacheSize ); + mCache = new hkGlyph[ mCacheSize ]; } hkFont::~hkFont() { - mCache.clear(); + hkSAFE_DELETE_ARRAY( mCache ); } void hkFont::Outline( int outline ) { diff --git a/src/helper/haikuttf/hkfont.hpp b/src/helper/haikuttf/hkfont.hpp index 4187a136c..35dbcee04 100644 --- a/src/helper/haikuttf/hkfont.hpp +++ b/src/helper/haikuttf/hkfont.hpp @@ -59,7 +59,8 @@ class hkFont { protected: hkFontManager * mFm; - std::vector mCache; + hkGlyph * mCache; + unsigned int mCacheSize; int mStyle; diff --git a/src/helper/haikuttf/hkfontmanager.cpp b/src/helper/haikuttf/hkfontmanager.cpp index 0a5a1e125..5f75f3115 100644 --- a/src/helper/haikuttf/hkfontmanager.cpp +++ b/src/helper/haikuttf/hkfontmanager.cpp @@ -46,10 +46,10 @@ void hkFontManager::CloseFont( hkFont * Font ) { if ( NULL != Font ) { Font->CacheFlush(); - /*if ( Font->Face() ) { + if ( NULL != Font->Face() ) { FT_Done_Face( Font->Face() ); Font->Face( NULL ); - }*/ + } hkSAFE_DELETE( Font ); } diff --git a/src/utils/rect.hpp b/src/utils/rect.hpp index 3dd7d4cfc..83b7d9540 100755 --- a/src/utils/rect.hpp +++ b/src/utils/rect.hpp @@ -68,6 +68,7 @@ typedef tRECT eeRectu; typedef tRECT eeRectf; typedef tRECT eeAABB; // Axis-Aligned Bounding Box typedef tRECT eeRecti; +typedef tRECT eeRect; }} diff --git a/src/utils/string.cpp b/src/utils/string.cpp index 929c988eb..4a022dab5 100644 --- a/src/utils/string.cpp +++ b/src/utils/string.cpp @@ -110,44 +110,33 @@ void StrFormat( char * Buffer, int BufferSize, const char * format, ... ) { va_end( args ); } -std::string StrFormated( const char* format, ... ) { - char buf[256]; - - va_list( args ); - - va_start( args, format ); - - #ifdef EE_COMPILER_MSVC - int nb = _vsnprintf_s( buf, 256, 256, format, args ); - #else - int nb = vsnprintf( buf, 256, format, args ); - #endif - - va_end( args ); - - if ( nb < 256 ) - return buf; - - // The static size was not big enough, try again with a dynamic allocation. - ++nb; - - char * buf2 = new char[nb]; - - va_start( args, format ); - - #ifdef EE_COMPILER_MSVC - _vsnprintf_s( buf2, nb, nb, format, args ); - #else - vsnprintf( buf2, nb, format, args ); - #endif - - va_end( args ); - - std::string res( buf2 ); - - delete [] buf2; - - return res; +std::string StrFormated( const char * format, ... ) { + int n, size = 256; + std::string tstr( size, '\0' ); + + va_list args; + + while (1) { + va_start( args, format ); + + #ifdef EE_COMPILER_MSVC + n = _vsnprintf_s( &tstr[0], size, size, format, args ); + #else + n = vsnprintf( &tstr[0], size, format, args ); + #endif + + va_end( args ); + + if ( n > -1 && n < size ) + return tstr; + + if ( n > -1 ) // glibc 2.1 + size = n+1; // precisely what is needed + else // glibc 2.0 + size *= 2; // twice the old size + + tstr.resize( size, '\0' ); + } } std::string LTrim( const std::string & str ) {