From 8e197828a8f81b2cf2324c473896941d0a421eee Mon Sep 17 00:00:00 2001 From: spartanj Date: Sun, 11 Jul 2010 19:17:01 -0300 Subject: [PATCH] Removed SDL_ttf dependency, replaced by HaikuTTF ( own implementation of a ttf handler library ). Still a work in progress, but working 100 %. Removed compiler warnings from zip_utils. Fixed cTexture and cShape memory leaks ( now using std::vector by default to allocate textures on memory, removed manual dynamic loading because it's not working fine ). Fixed cShaderProgram unloading. Fixed a bug on cInifile. Updated the Makefile. --- Makefile | 18 +- EE.kdevelop => ee.kdevelop | 4 +- ee.linux.cbp | 12 +- src/graphics/base.hpp | 3 +- src/graphics/cshaderprogram.cpp | 16 +- src/graphics/cshaderprogrammanager.cpp | 8 +- src/graphics/cshape.cpp | 109 +- src/graphics/cshape.hpp | 39 +- src/graphics/ctexture.cpp | 79 +- src/graphics/ctexture.hpp | 7 +- src/graphics/ctexturefactory.cpp | 7 +- src/graphics/cttffont.cpp | 414 +++-- src/graphics/cttffont.hpp | 11 +- src/helper/SDL_ttf/SDL_ttf.c | 2052 ------------------------ src/helper/SDL_ttf/SDL_ttf.h | 249 --- src/helper/SOIL/stb_image.c | 4 +- src/helper/haikuttf/haikuttf.hpp | 9 + src/helper/haikuttf/hkbase.hpp | 63 + src/helper/haikuttf/hkfont.cpp | 501 ++++++ src/helper/haikuttf/hkfont.hpp | 77 + src/helper/haikuttf/hkfontmanager.cpp | 155 ++ src/helper/haikuttf/hkfontmanager.hpp | 55 + src/helper/haikuttf/hkglyph.cpp | 33 + src/helper/haikuttf/hkglyph.hpp | 64 + src/helper/haikuttf/stdint.h | 247 +++ src/helper/zip_utils/unzip.cpp | 496 +++--- src/helper/zip_utils/unzip.h | 13 +- src/helper/zip_utils/zip.cpp | 56 +- src/helper/zip_utils/zip.h | 10 +- src/math/math.hpp | 4 +- src/system/cinifile.cpp | 2 +- src/test/ee.cpp | 1 - 32 files changed, 1920 insertions(+), 2898 deletions(-) rename EE.kdevelop => ee.kdevelop (98%) delete mode 100644 src/helper/SDL_ttf/SDL_ttf.c delete mode 100644 src/helper/SDL_ttf/SDL_ttf.h create mode 100644 src/helper/haikuttf/haikuttf.hpp create mode 100644 src/helper/haikuttf/hkbase.hpp create mode 100644 src/helper/haikuttf/hkfont.cpp create mode 100644 src/helper/haikuttf/hkfont.hpp create mode 100644 src/helper/haikuttf/hkfontmanager.cpp create mode 100644 src/helper/haikuttf/hkfontmanager.hpp create mode 100644 src/helper/haikuttf/hkglyph.cpp create mode 100644 src/helper/haikuttf/hkglyph.hpp create mode 100644 src/helper/haikuttf/stdint.h diff --git a/Makefile b/Makefile index 999d1a479..bc03b7391 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +export DEBUGBUILD=yes + ifeq ($(DEBUGBUILD), yes) DEBUGFLAGS = -g -DDEBUG -DEE_DEBUG else @@ -14,6 +16,12 @@ endif export CC = gcc export CPP = g++ + +ifeq ($(LLVM_BUILD), yes) +export CC = llvm-gcc +export CPP = llvm-g++ +endif + export CFLAGS = -Wall $(DEBUGFLAGS) $(BUILDFLAGS) export CFLAGSEXT = $(DEBUGFLAGS) $(BUILDFLAGS) export LDFLAGS = $(LINKFLAGS) @@ -32,10 +40,10 @@ EXE = eetest EXEIV = eeiv SRCGLEW = $(wildcard ./src/helper/glew/*.c) -SRCSDLTTF = $(wildcard ./src/helper/SDL_ttf/*.c) SRCSOIL = $(wildcard ./src/helper/SOIL/*.c) SRCFE = $(wildcard ./src/helper/fastevents/*.c) SRCSTBVORBIS = $(wildcard ./src/helper/stb_vorbis/*.c) +SRCHAIKUTTF = $(wildcard ./src/helper/haikuttf/*.cpp) SRCZIPUTILS = $(wildcard ./src/helper/zip_utils/*.cpp) SRCAUDIO = $(wildcard ./src/audio/*.cpp) @@ -52,7 +60,7 @@ SRCEEIV = $(wildcard ./src/eeiv/*.cpp) OBJGLEW = $(SRCGLEW:.c=.o) OBJFE = $(SRCFE:.c=.o) -OBJSDLTTF = $(SRCSDLTTF:.c=.o) +OBJHAIKUTTF = $(SRCHAIKUTTF:.cpp=.o) OBJSOIL = $(SRCSOIL:.c=.o) OBJSTBVORBIS = $(SRCSTBVORBIS:.c=.o) OBJZIPUTILS = $(SRCZIPUTILS:.cpp=.o) @@ -66,7 +74,7 @@ OBJUI = $(SRCUI:.cpp=.o) OBJUTILS = $(SRCUTILS:.cpp=.o) OBJWINDOW = $(SRCWINDOW:.cpp=.o) -OBJHELPERS = $(OBJGLEW) $(OBJFE) $(OBJSDLTTF) $(OBJSOIL) $(OBJSTBVORBIS) $(OBJZIPUTILS) +OBJHELPERS = $(OBJGLEW) $(OBJFE) $(OBJHAIKUTTF) $(OBJSOIL) $(OBJSTBVORBIS) $(OBJZIPUTILS) OBJMODULES = $(OBJUTILS) $(OBJMATH) $(OBJSYSTEM) $(OBJAUDIO) $(OBJWINDOW) $(OBJGRAPHICS) $(OBJGAMING) $(OBJUI) OBJTEST = $(SRCTEST:.cpp=.o) @@ -90,10 +98,10 @@ libeepp-s.a: $(OBJHELPERS) $(OBJMODULES) libeepp.so: $(OBJHELPERS) $(OBJMODULES) $(CPP) $(LDFLAGS) -Wl,-soname,$(LIB).$(VERSION) -o $(LIBNAME) $(OBJHELPERS) $(OBJMODULES) -lfreetype -lSDL -lsndfile -lopenal -lGL -lGLU -$(OBJMODULES) $(OBJZIPUTILS): %.o: %.cpp +$(OBJMODULES) $(OBJZIPUTILS) $(OBJHAIKUTTF): %.o: %.cpp $(CPP) -o $@ -c $< $(CFLAGS) -I/usr/include/freetype2 -$(OBJGLEW) $(OBJFE) $(OBJSDLTTF) $(OBJSOIL) $(OBJSTBVORBIS): %.o: %.c +$(OBJGLEW) $(OBJFE) $(OBJSOIL) $(OBJSTBVORBIS): %.o: %.c $(CC) -o $@ -c $< $(CFLAGSEXT) -DSTBI_FAILURE_USERMSG -I/usr/include/freetype2 test: $(EXE) diff --git a/EE.kdevelop b/ee.kdevelop similarity index 98% rename from EE.kdevelop rename to ee.kdevelop index 0c4a10a00..3d6f968e0 100644 --- a/EE.kdevelop +++ b/ee.kdevelop @@ -7,7 +7,7 @@ KDevCustomProject C++ - EE + ee . false @@ -17,7 +17,7 @@ executable - ./eetest + eeiv ./ diff --git a/ee.linux.cbp b/ee.linux.cbp index 3b9656363..8d7e10349 100644 --- a/ee.linux.cbp +++ b/ee.linux.cbp @@ -114,10 +114,6 @@ - - - @@ -146,6 +142,14 @@ + + + + + + + + diff --git a/src/graphics/base.hpp b/src/graphics/base.hpp index f467c1ac6..9d90a421f 100644 --- a/src/graphics/base.hpp +++ b/src/graphics/base.hpp @@ -6,7 +6,6 @@ #include #include "../helper/SOIL/SOIL.h" -#include "../helper/SDL_ttf/SDL_ttf.h" #include "../utils/colors.hpp" #include "../utils/rect.hpp" @@ -28,4 +27,6 @@ using namespace EE::System; #include "renders.hpp" +#define ALLOC_VECTORS + #endif diff --git a/src/graphics/cshaderprogram.cpp b/src/graphics/cshaderprogram.cpp index 81930edfc..92239c009 100644 --- a/src/graphics/cshaderprogram.cpp +++ b/src/graphics/cshaderprogram.cpp @@ -30,14 +30,17 @@ cShaderProgram::cShaderProgram( const std::string& VertexShaderFile, const std:: AddToManager( name ); Init(); - cVertexShader vs( VertexShaderFile ); - cFragmentShader fs( FragmentShaderFile ); + cVertexShader * vs = new cVertexShader( VertexShaderFile ); + cFragmentShader * fs = new cFragmentShader( FragmentShaderFile ); - if ( !vs.IsValid() || !fs.IsValid() ) + if ( !vs->IsValid() || !fs->IsValid() ) { + delete vs; + delete fs; return; + } - AddShader( &vs ); - AddShader( &fs ); + AddShader( vs ); + AddShader( fs ); Link(); } @@ -48,6 +51,9 @@ cShaderProgram::~cShaderProgram() { mUniformLocations.clear(); mAttributeLocations.clear(); + + for ( eeUint i = 0; i < mShaders.size(); i++ ) + delete mShaders[i]; } void cShaderProgram::AddToManager( const std::string& name ) { diff --git a/src/graphics/cshaderprogrammanager.cpp b/src/graphics/cshaderprogrammanager.cpp index c03e08920..4959b72a7 100644 --- a/src/graphics/cshaderprogrammanager.cpp +++ b/src/graphics/cshaderprogrammanager.cpp @@ -8,10 +8,10 @@ cShaderProgramManager::cShaderProgramManager() cShaderProgramManager::~cShaderProgramManager() { - std::map::iterator it; - - for ( it = mShaders.begin(); it != mShaders.end(); it++ ) - Remove( it->second ); + std::map::iterator it; + + for ( it = mShaders.begin() ; it != mShaders.end(); it++ ) + delete it->second; } void cShaderProgramManager::Add( cShaderProgram * ShaderProgram ) { diff --git a/src/graphics/cshape.cpp b/src/graphics/cshape.cpp index 6366230bc..55589b8de 100644 --- a/src/graphics/cshape.cpp +++ b/src/graphics/cshape.cpp @@ -12,10 +12,12 @@ cShape::cShape() : mDestWidth(0), mDestHeight(0), mOffSetX(0), - mOffSetY(0), - mPixels(NULL), - mAlpha(NULL) + mOffSetY(0) { + #ifndef ALLOC_VECTORS + mPixels = NULL; + mAlpha = NULL; + #endif CreateUnnamed(); } @@ -28,10 +30,12 @@ cShape::cShape( const Uint32& TexId, const std::string& Name ) : mDestWidth( (eeFloat)mTexture->Width() ), mDestHeight( (eeFloat)mTexture->Height() ), mOffSetX(0), - mOffSetY(0), - mPixels(NULL), - mAlpha(NULL) + mOffSetY(0) { + #ifndef ALLOC_VECTORS + mPixels = NULL; + mAlpha = NULL; + #endif } cShape::cShape( const Uint32& TexId, const eeRecti& SrcRect, const std::string& Name ) : @@ -43,10 +47,12 @@ cShape::cShape( const Uint32& TexId, const eeRecti& SrcRect, const std::string& mDestWidth( (eeFloat)( mSrcRect.Right - mSrcRect.Left ) ), mDestHeight( (eeFloat)( mSrcRect.Bottom - mSrcRect.Top ) ), mOffSetX(0), - mOffSetY(0), - mPixels(NULL), - mAlpha(NULL) + mOffSetY(0) { + #ifndef ALLOC_VECTORS + mPixels = NULL; + mAlpha = NULL; + #endif } cShape::cShape( const Uint32& TexId, const eeRecti& SrcRect, const eeFloat& DestWidth, const eeFloat& DestHeight, const std::string& Name ) : @@ -58,10 +64,12 @@ cShape::cShape( const Uint32& TexId, const eeRecti& SrcRect, const eeFloat& Dest mDestWidth(DestWidth), mDestHeight(DestHeight), mOffSetX(0), - mOffSetY(0), - mPixels(NULL), - mAlpha(NULL) + mOffSetY(0) { + #ifndef ALLOC_VECTORS + mPixels = NULL; + mAlpha = NULL; + #endif } cShape::cShape( const Uint32& TexId, const eeRecti& SrcRect, const eeFloat& DestWidth, const eeFloat& DestHeight, const eeFloat& OffsetX, const eeFloat& OffsetY, const std::string& Name ) : @@ -73,10 +81,12 @@ cShape::cShape( const Uint32& TexId, const eeRecti& SrcRect, const eeFloat& Dest mDestWidth(DestWidth), mDestHeight(DestHeight), mOffSetX(OffsetX), - mOffSetY(OffsetY), - mPixels(NULL), - mAlpha(NULL) + mOffSetY(OffsetY) { + #ifndef ALLOC_VECTORS + mPixels = NULL; + mAlpha = NULL; + #endif } cShape::~cShape() { @@ -116,10 +126,18 @@ eeRecti cShape::SrcRect() const { void cShape::SrcRect( const eeRecti& Rect ) { mSrcRect = Rect; + #ifndef ALLOC_VECTORS if ( NULL != mPixels ) + #else + if ( mPixels.size() ) + #endif CacheColors(); + #ifndef ALLOC_VECTORS if ( NULL != mAlpha ) + #else + if ( mAlpha.size() ) + #endif CacheAlphaMask(); } @@ -191,9 +209,15 @@ void cShape::CreateMaskFromColor(eeColor ColorKey, Uint8 Alpha) { } void cShape::CacheAlphaMask() { - eeSAFE_DELETE_ARRAY( mAlpha ); + Uint32 size = ( mSrcRect.Right - mSrcRect.Left ) * ( mSrcRect.Bottom - mSrcRect.Top ); - mAlpha = new Uint8[ ( mSrcRect.Right - mSrcRect.Left ) * ( mSrcRect.Bottom - mSrcRect.Top ) ]; + #ifndef ALLOC_VECTORS + eeSAFE_DELETE_ARRAY( mAlpha ); + mAlpha = new Uint8[ size ]; + #else + mAlpha.clear(); + mAlpha.resize( size ); + #endif mTexture->Lock(); @@ -215,9 +239,15 @@ void cShape::CacheAlphaMask() { } void cShape::CacheColors() { - eeSAFE_DELETE_ARRAY( mPixels ); + Uint32 size = ( mSrcRect.Right - mSrcRect.Left ) * ( mSrcRect.Bottom - mSrcRect.Top ) ; - mPixels = new eeColorA[ ( mSrcRect.Right - mSrcRect.Left ) * ( mSrcRect.Bottom - mSrcRect.Top ) ]; + #ifndef ALLOC_VECTORS + eeSAFE_DELETE_ARRAY( mPixels ); + mPixels = new eeColorA[ size ]; + #else + mPixels.clear(); + mPixels.resize( size ); + #endif mTexture->Lock(); @@ -242,13 +272,22 @@ Uint8 cShape::GetAlphaAt( const Int32& X, const Int32& Y ) { if ( mTexture->LocalCopy() ) return mTexture->GetPixel( mSrcRect.Left + X, mSrcRect.Right + Y ).A(); + #ifndef ALLOC_VECTORS if ( NULL != mAlpha ) + #else + if ( mAlpha.size() ) + #endif return mAlpha[ X + Y * ( mSrcRect.Right - mSrcRect.Left ) ]; + #ifndef ALLOC_VECTORS if ( NULL != mPixels ) + #else + if ( mPixels.size() ) + #endif return mPixels[ X + Y * ( mSrcRect.Right - mSrcRect.Left ) ].A(); CacheAlphaMask(); + return GetAlphaAt( X, Y ); } @@ -256,15 +295,24 @@ eeColorA cShape::GetColorAt( const Int32& X, const Int32& Y ) { if ( mTexture->LocalCopy() ) return mTexture->GetPixel( mSrcRect.Left + X, mSrcRect.Right + Y ); + #ifndef ALLOC_VECTORS if ( NULL != mPixels ) + #else + if ( mPixels.size() ) + #endif return mPixels[ X + Y * ( mSrcRect.Right - mSrcRect.Left ) ]; CacheColors(); + return GetColorAt( X, Y ); } void cShape::SetColorAt( const Int32& X, const Int32& Y, const eeColorA& Color ) { + #ifndef ALLOC_VECTORS if ( NULL != mPixels ) + #else + if ( mPixels.size() ) + #endif mPixels[ X + Y * ( mSrcRect.Right - mSrcRect.Left ) ] = Color; else { CacheColors(); @@ -273,17 +321,27 @@ void cShape::SetColorAt( const Int32& X, const Int32& Y, const eeColorA& Color ) } void cShape::ClearCache() { + #ifndef ALLOC_VECTORS eeSAFE_DELETE_ARRAY( mPixels ); eeSAFE_DELETE_ARRAY( mAlpha ); + #else + mPixels.clear(); + mAlpha.clear(); + #endif } eeColorA * cShape::Lock() { CacheColors(); + return &mPixels[0]; } bool cShape::Unlock( const bool& KeepData, const bool& Modified ) { + #ifndef ALLOC_VECTORS if ( NULL != mPixels ) { + #else + if ( mPixels.size() ) { + #endif if ( Modified ) { GLint PreviousTexture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &PreviousTexture); @@ -291,14 +349,19 @@ bool cShape::Unlock( const bool& KeepData, const bool& Modified ) { if ( PreviousTexture != (Int32)mTexture->Texture() ) glBindTexture(GL_TEXTURE_2D, mTexture->Texture() ); - glTexSubImage2D( GL_TEXTURE_2D, 0, mSrcRect.Left, mSrcRect.Top, mSrcRect.Size().Width(), mSrcRect.Size().Height(), GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast ( mPixels ) ); + glTexSubImage2D( GL_TEXTURE_2D, 0, mSrcRect.Left, mSrcRect.Top, mSrcRect.Size().Width(), mSrcRect.Size().Height(), GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast ( &mPixels[0] ) ); if ( PreviousTexture != (Int32)mTexture->Texture() ) glBindTexture(GL_TEXTURE_2D, PreviousTexture); } - if ( !KeepData ) + if ( !KeepData ) { + #ifndef ALLOC_VECTORS eeSAFE_DELETE_ARRAY( mPixels ); + #else + mPixels.clear(); + #endif + } return true; } @@ -315,7 +378,11 @@ eeSize cShape::Size() { } const Uint8* cShape::GetPixelsPtr() { + #ifndef ALLOC_VECTORS if ( mPixels == NULL ) { + #else + if ( !mPixels.size() ) { + #endif Lock(); Unlock(true); } diff --git a/src/graphics/cshape.hpp b/src/graphics/cshape.hpp index 53bf90836..2928db081 100644 --- a/src/graphics/cshape.hpp +++ b/src/graphics/cshape.hpp @@ -10,17 +10,17 @@ namespace EE { namespace Graphics { class EE_API cShape { public: cShape(); - + cShape( const Uint32& TexId, const std::string& Name = "" ); - + cShape( const Uint32& TexId, const eeRecti& SrcRect, const std::string& Name = "" ); cShape( const Uint32& TexId, const eeRecti& SrcRect, const eeFloat& DestWidth, const eeFloat& DestHeight, const std::string& Name = "" ); cShape( const Uint32& TexId, const eeRecti& SrcRect, const eeFloat& DestWidth, const eeFloat& DestHeight, const eeFloat& OffsetX, const eeFloat& OffsetY, const std::string& Name = "" ); - + ~cShape(); - + const Uint32& Id() const; const std::string Name() const; @@ -28,31 +28,31 @@ class EE_API cShape { void Name( const std::string& name ); const Uint32 Texture(); - + void Texture( const Uint32& TexId ); - + eeRecti SrcRect() const; - + void SrcRect( const eeRecti& Rect ); - + const eeFloat DestWidth() const; - + void DestWidth( const eeFloat& width ); - + const eeFloat DestHeight() const; - + void DestHeight( const eeFloat& height ); - + const eeFloat OffsetX() const; - + void OffsetX( const eeFloat& offsetx ); - + const eeFloat OffsetY() const; - + void OffsetY( const eeFloat& offsety ); - + void Draw( const eeFloat& X, const eeFloat& Y, const eeRGBA& Color = eeRGBA(), const eeFloat& Angle = 0.f, const eeFloat& Scale = 1.f, const EE_RENDERALPHAS& Blend = ALPHA_NORMAL, const EE_RENDERTYPE& Effect = RN_NORMAL, const bool& ScaleRendered = true ); - + void Draw( const eeFloat& X, const eeFloat& Y, const eeFloat& Angle = 0.f, const eeFloat& Scale = 1.f, const eeRGBA& Color0 = eeRGBA(), const eeRGBA& Color1 = eeRGBA(), const eeRGBA& Color2 = eeRGBA(), const eeRGBA& Color3 = eeRGBA(), const EE_RENDERALPHAS& Blend = ALPHA_NORMAL, const EE_RENDERTYPE& Effect = RN_NORMAL, const bool& ScaleRendered = true ); cTexture * GetTexture(); @@ -97,8 +97,13 @@ class EE_API cShape { eeFloat mOffSetX; eeFloat mOffSetY; + #ifndef ALLOC_VECTORS eeColorA * mPixels; Uint8 * mAlpha; + #else + std::vector mPixels; + std::vector mAlpha; + #endif void CreateUnnamed(); }; diff --git a/src/graphics/ctexture.cpp b/src/graphics/ctexture.cpp index 0b03d86c7..7c32efcb1 100755 --- a/src/graphics/ctexture.cpp +++ b/src/graphics/ctexture.cpp @@ -19,9 +19,11 @@ cTexture::cTexture() : mFilter( TEX_LINEAR ), mCompressedTexture(false), mLocked(false), - mGrabed(false), - mPixels(NULL) + mGrabed(false) { + #ifndef ALLOC_VECTORS + mPixels = NULL; + #endif } cTexture::cTexture( const cTexture& Copy ) : @@ -42,7 +44,7 @@ cTexture::cTexture( const cTexture& Copy ) : mLocked( Copy.mLocked ), mGrabed ( Copy.mGrabed ) { - Pixels( reinterpret_cast( Copy.mPixels ) ); + Pixels( reinterpret_cast( &Copy.mPixels[0] ) ); } cTexture::~cTexture() { @@ -68,7 +70,7 @@ cTexture& cTexture::operator =(const cTexture& Other) { std::swap(mCompressedTexture, Temp.mCompressedTexture); std::swap(mGrabed, Temp.mGrabed); std::swap(mChannels, Temp.mChannels); - Pixels( reinterpret_cast( Temp.mPixels ) ); + Pixels( reinterpret_cast( &Temp.mPixels[0] ) ); return *this; } @@ -83,7 +85,7 @@ void cTexture::DeleteTexture() { mLocked = false; mGrabed = false; - eeSAFE_DELETE_ARRAY( mPixels ); + ClearCache(); } } @@ -117,12 +119,11 @@ void cTexture::Create( const Uint32& texture, const eeInt& width, const eeInt& h void cTexture::Pixels( const Uint8* data ) { if ( data != NULL ) { - eeSAFE_DELETE_ARRAY( mPixels ); - eeUint size = (eeUint)mWidth * (eeUint)mHeight; - mPixels = new eeColorA[ size ]; - memcpy( reinterpret_cast( mPixels ), reinterpret_cast ( data ), size ); + Allocate( size ); + + memcpy( reinterpret_cast( &mPixels[0] ), reinterpret_cast ( data ), size ); } } @@ -140,11 +141,14 @@ eeColorA* cTexture::Lock() { mWidth = (eeInt)width; mHeight = (eeInt)height; + eeUint size = (eeUint)mWidth * (eeUint)mHeight; - if ( !( eeARRAY_SIZE( mPixels ) >= (eeUint)width * (eeUint)height ) ) { - eeSAFE_DELETE_ARRAY( mPixels ); - eeUint size = (eeUint)mWidth * (eeUint)mHeight; - mPixels = new eeColorA[ size ]; + #ifndef ALLOC_VECTORS + if ( eeARRAY_SIZE( mPixels ) != size ) { + #else + if ( mPixels.size() != size ) { + #endif + Allocate( size ); } glGetTexImage( GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast (&mPixels[0]) ); @@ -154,6 +158,7 @@ eeColorA* cTexture::Lock() { mLocked = true; } + return &mPixels[0]; } @@ -186,8 +191,9 @@ bool cTexture::Unlock(const bool& KeepData, const bool& Modified) { mModified = false; } - if (!KeepData) - eeSAFE_DELETE_ARRAY( mPixels ); + if (!KeepData) { + ClearCache(); + } mLocked = false; @@ -198,7 +204,7 @@ bool cTexture::Unlock(const bool& KeepData, const bool& Modified) { } const Uint8* cTexture::GetPixelsPtr() { - if ( mPixels == NULL ) { + if ( !LocalCopy() ) { Lock(); Unlock(true); } @@ -207,21 +213,30 @@ const Uint8* cTexture::GetPixelsPtr() { } const eeColorA& cTexture::GetPixel(const eeUint& x, const eeUint& y) { - #ifdef EE_DEBUG - if ( mPixels == NULL || (eeInt)x > mWidth || (eeInt)y > mHeight ) - return eeColorA::Black; + #ifndef ALLOC_VECTORS + if ( mPixels == NULL || (eeInt)x > mWidth || (eeInt)y > mHeight ) { + #else + if ( !mPixels.size() || (eeInt)x > mWidth || (eeInt)y > mHeight ) { #endif + return eeColorA::Black; + } + return mPixels[ x + y * (Uint32)mWidth ]; } void cTexture::SetPixel(const eeUint& x, const eeUint& y, const eeColorA& Color) { - #ifdef EE_DEBUG - if ( mPixels == NULL || (eeInt)x > mWidth || (eeInt)y > mHeight ) - return; + #ifndef ALLOC_VECTORS + if ( mPixels == NULL || (eeInt)x > mWidth || (eeInt)y > mHeight ) { + #else + if ( !mPixels.size() || (eeInt)x > mWidth || (eeInt)y > mHeight ) { #endif + return; + } - mPixels[ x + y * (eeUint)mWidth ] = Color; + eeUint Pos = x + y * (eeUint)mWidth; + + mPixels[ Pos ] = Color; mModified = true; } @@ -282,7 +297,11 @@ void cTexture::CreateMaskFromColor(eeColor ColorKey, Uint8 Alpha) { } bool cTexture::LocalCopy() { + #ifndef ALLOC_VECTORS return ( mPixels != NULL ); + #else + return mPixels.size() != 0; + #endif } void cTexture::ClampMode( const EE_CLAMP_MODE& clampmode ) { @@ -315,7 +334,11 @@ void cTexture::ApplyClampMode() { } void cTexture::ClearCache() { + #ifndef ALLOC_VECTORS eeSAFE_DELETE_ARRAY( mPixels ); + #else + mPixels.clear(); + #endif } void cTexture::Draw( const eeFloat &x, const eeFloat &y, const eeFloat &Angle, const eeFloat &Scale, const eeColorA& Color, const EE_RENDERALPHAS &blend, const EE_RENDERTYPE &Effect, const bool &ScaleCentered, const eeRecti& texSector) { @@ -531,4 +554,14 @@ const Uint32& cTexture::TexId() const { return mTexId; } +void cTexture::Allocate( const Uint32& size ) { + ClearCache(); + + #ifndef ALLOC_VECTORS + mPixels = new eeColorA[ size ]; + #else + mPixels.resize( size ); + #endif +} + }} diff --git a/src/graphics/ctexture.hpp b/src/graphics/ctexture.hpp index af3214e89..6f655a209 100755 --- a/src/graphics/ctexture.hpp +++ b/src/graphics/ctexture.hpp @@ -240,9 +240,14 @@ class EE_API cTexture { bool mLocked; bool mGrabed; - eeColorA* mPixels; + #ifndef ALLOC_VECTORS + eeColorA * mPixels; + #else + std::vector mPixels; + #endif void ApplyClampMode(); + void Allocate( const Uint32& size ); }; }} diff --git a/src/graphics/ctexturefactory.cpp b/src/graphics/ctexturefactory.cpp index 3fba09966..ab653d4a3 100755 --- a/src/graphics/ctexturefactory.cpp +++ b/src/graphics/ctexturefactory.cpp @@ -35,12 +35,7 @@ void cTextureFactory::BindPrev( const GLint& PreviousTexture ) { Uint32 cTextureFactory::CreateEmptyTexture( const eeUint& Width, const eeUint& Height, const eeColorA& DefaultColor, const bool& mipmap, const EE_CLAMP_MODE& ClampMode, const bool& CompressTexture, const bool& KeepLocalCopy ) { std::vector tmpTex( Width * Height, DefaultColor ); - - Uint32 TexId = LoadFromPixels( reinterpret_cast ( &tmpTex[0] ), Width, Height, 4, mipmap, eeRGB(true), ClampMode, CompressTexture, KeepLocalCopy ); - - tmpTex.clear(); - - return TexId; + return LoadFromPixels( reinterpret_cast ( &tmpTex[0] ), Width, Height, 4, mipmap, eeRGB(true), ClampMode, CompressTexture, KeepLocalCopy ); } Uint32 cTextureFactory::LoadFromPixels( const unsigned char* Surface, const eeUint& Width, const eeUint& Height, const eeUint& Channels, const bool& mipmap, const eeRGB& ColorKey, const EE_CLAMP_MODE& ClampMode, const bool& CompressTexture, const bool& KeepLocalCopy, const std::string& FileName ) { diff --git a/src/graphics/cttffont.cpp b/src/graphics/cttffont.cpp index 1abf6ecc1..2281a1b73 100755 --- a/src/graphics/cttffont.cpp +++ b/src/graphics/cttffont.cpp @@ -5,14 +5,14 @@ namespace EE { namespace Graphics { cTTFFont::cTTFFont() : cFont(), mFont(0) { TF = cTextureFactory::instance(); - if ( TTF_Init() == -1 ) + if ( hkFontManager::instance()->Init() ) mTTFInit = false; else mTTFInit = true; } cTTFFont::~cTTFFont() { - TTF_Quit(); + hkFontManager::instance()->Destroy(); } bool cTTFFont::LoadFromPack( cPack* Pack, const std::string& FilePackPath, const eeUint& Size, EE_TTF_FONTSTYLE Style, const bool& VerticalDraw, const Uint16& NumCharsToGen, const eeColor& FontColor, const Uint8& OutlineSize, const eeColor& OutlineColor ) { @@ -30,8 +30,7 @@ bool cTTFFont::LoadFromMemory( Uint8* TTFData, const eeUint& TTFDataSize, const mFilepath = "from memory"; mLoadedFromMemory = true; - SDL_RWops *rw = SDL_RWFromMem( reinterpret_cast(&TTFData[0]), TTFDataSize ); - mFont = TTF_OpenFontIndexRW( rw, 1, Size, 0 ); + mFont = hkFontManager::instance()->OpenFromMemory( reinterpret_cast(&TTFData[0]), TTFDataSize, Size, 0, NumCharsToGen ); return iLoad( Size, Style, VerticalDraw, NumCharsToGen, FontColor, OutlineSize, OutlineColor ); } @@ -40,222 +39,207 @@ bool cTTFFont::Load(const std::string& Filepath, const eeUint& Size, EE_TTF_FONT mFilepath = Filepath; mLoadedFromMemory = false; - mFont = TTF_OpenFont(mFilepath.c_str(), Size); + mFont = hkFontManager::instance()->OpenFromFile( Filepath.c_str(), Size, 0, NumCharsToGen ); 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}; - SDL_Color GlyphColor = {255, 255, 255, 255}; - SDL_Surface *TempGlyphSurface; - eeFloat Top, Bottom; - Uint8 OutlineTotal = OutlineSize * 2; - - if (!mTTFInit) - return false; - - try { - if (mFont == NULL) - return false; - - TTF_SetFontStyle(mFont, 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 = TTF_FontHeight( mFont ) + OutlineTotal; - - Uint32 rmask, gmask, bmask, amask; - #if SDL_BYTEORDER == SDL_BIG_ENDIAN - rmask = 0xff000000; - gmask = 0x00ff0000; - bmask = 0x0000ff00; - amask = 0x000000ff; - #else - rmask = 0x000000ff; - gmask = 0x0000ff00; - bmask = 0x00ff0000; - amask = 0xff000000; - #endif - SDL_Surface* TempGlyphSheet = SDL_CreateRGBSurface(SDL_SWSURFACE, (eeInt)mTexWidth, (eeInt)mTexHeight, 32, bmask, gmask, rmask, amask); - - CurrentPos.x = OutlineSize; - CurrentPos.y = OutlineSize; - - //Loop through all chars - for ( eeUint i = 0; i < mNumChars; i++) { - //Clear the surface - TempGlyphSurface = NULL; - - //Render the glyph onto the SDL surface, in white - TempGlyphSurface = TTF_RenderGlyph_Blended(mFont, i, GlyphColor); - - //New temp glyph - eeGlyph TempGlyph; - - //Get the glyph attributes - TTF_GlyphMetrics(mFont, i, &TempGlyph.MinX, &TempGlyph.MaxX, &TempGlyph.MinY, &TempGlyph.MaxY, &TempGlyph.Advance); - - //Set size of glyph rect - GlyphRect.w = TempGlyphSurface->w; - GlyphRect.h = TempGlyphSurface->h; - - //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; +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 ) ); + } } - - //Blit the glyph onto the glyph sheet - SDL_BlitSurface(TempGlyphSurface, &GlyphRect, TempGlyphSheet, &CurrentPos); - - // 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 - SDL_FreeSurface(TempGlyphSurface); - } - - if ( !mTexId ) { - - // Recover the Alpha channel - SDL_LockSurface(TempGlyphSheet); - - eeUint ssize = TempGlyphSheet->w * TempGlyphSheet->h * 4; - - for (eeUint i=0; i(TempGlyphSheet->pixels))[i+3] = (static_cast(TempGlyphSheet->pixels))[i+2]; - (static_cast(TempGlyphSheet->pixels))[i+2] = FontColor.B(); - (static_cast(TempGlyphSheet->pixels))[i+1] = FontColor.G(); - (static_cast(TempGlyphSheet->pixels))[i+0] = FontColor.R(); - } - - SDL_UnlockSurface(TempGlyphSheet); - - const unsigned char* Ptr = reinterpret_cast(TempGlyphSheet->pixels); - - //Convert the SDL glyph sheet to an OpenGL texture - mTexId = TF->LoadFromPixels( Ptr, TempGlyphSheet->w, TempGlyphSheet->h, 4 ); - - // Check if need to create the outline - cTexture* Tex = TF->GetTexture( mTexId ); - - 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 ); - - Tex->Lock(); - - // 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 ); - } - - } - - SDL_FreeSurface(TempGlyphSheet); - - //Close the font - TTF_CloseFont(mFont); - - RebuildFromGlyphs(); - - cLog::instance()->Write( "TTF Font " + mFilepath + " loaded." ); - return true; - } catch (...) { - cLog::instance()->Write( "Failed to load TTF Font " + mFilepath + "." ); - return false; - } + + // 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; + } } void cTTFFont::RebuildFromGlyphs() { diff --git a/src/graphics/cttffont.hpp b/src/graphics/cttffont.hpp index 9e877f2b4..e863fc043 100755 --- a/src/graphics/cttffont.hpp +++ b/src/graphics/cttffont.hpp @@ -5,6 +5,9 @@ #include "ctexturefactory.hpp" #include "cfont.hpp" +#include "../helper/haikuttf/haikuttf.hpp" +using namespace HaikuTTF; + namespace EE { namespace Graphics { /** @brief This class loads True Type Font and then draw strings to the screen. */ @@ -25,10 +28,10 @@ class EE_API cTTFFont : public cFont { * @return If success */ bool Load( const std::string& Filepath, const eeUint& Size, EE_TTF_FONTSTYLE Style = EE_TTF_STYLE_NORMAL, const bool& VerticalDraw = false, const Uint16& NumCharsToGen = 512, const eeColor& FontColor = eeColor(), const Uint8& OutlineSize = 0, const eeColor& OutlineColor = eeColor(0,0,0) ); - + /** Load Font from pack * @param Pack Pointer to the pack instance - * @param FilePackPath The path of the file inside the pack + * @param FilePackPath The path of the file inside the pack * @param Size The Size of the Font * @param Style The Font Style * @param VerticalDraw If draw in vertical instead of horizontal @@ -39,7 +42,7 @@ class EE_API cTTFFont : public cFont { * @return If success */ bool LoadFromPack( cPack* Pack, const std::string& FilePackPath, const eeUint& Size, EE_TTF_FONTSTYLE Style = EE_TTF_STYLE_NORMAL, const bool& VerticalDraw = false, const Uint16& NumCharsToGen = 512, const eeColor& FontColor = eeColor(), const Uint8& OutlineSize = 0, const eeColor& OutlineColor = eeColor(0,0,0) ); - + /** Load a True Type Font from memory * @param TTFData The pointer to the data * @param TTFDataSize The size of the data @@ -64,7 +67,7 @@ class EE_API cTTFFont : public cFont { bool Save( const std::string& TexturePath, const std::string& CoordinatesDatPath, const EE_SAVETYPE& Format = EE_SAVE_TYPE_TGA ); private: cTextureFactory* TF; - TTF_Font* mFont; + hkFont * mFont; std::string mFilepath; Uint32 mBase; diff --git a/src/helper/SDL_ttf/SDL_ttf.c b/src/helper/SDL_ttf/SDL_ttf.c deleted file mode 100644 index e134458f6..000000000 --- a/src/helper/SDL_ttf/SDL_ttf.c +++ /dev/null @@ -1,2052 +0,0 @@ -/* - SDL_ttf: A companion library to SDL for working with TrueType (tm) fonts - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ - -/* $Id: SDL_ttf.c 5141 2009-10-18 20:47:04Z slouken $ */ - -#include -#include -#include -#include - -#ifdef HAVE_ALLOCA_H -#include -#endif - -#ifdef HAVE_ALLOCA -#define ALLOCA(n) ((void*)alloca(n)) -#define FREEA(p) -#else -#define ALLOCA(n) malloc(n) -#define FREEA(p) free(p) -#endif - -#include -#include FT_FREETYPE_H -#include FT_OUTLINE_H -#include FT_STROKER_H -#include FT_GLYPH_H -#include FT_TRUETYPE_IDS_H - -#include -#include -#include "SDL_ttf.h" - -/* FIXME: Right now we assume the gray-scale renderer Freetype is using - supports 256 shades of gray, but we should instead key off of num_grays - in the result FT_Bitmap after the FT_Render_Glyph() call. */ -#define NUM_GRAYS 256 - -/* Handy routines for converting from fixed point */ -#define FT_FLOOR(X) ((X & -64) / 64) -#define FT_CEIL(X) (((X + 63) & -64) / 64) - -#define CACHED_METRICS 0x10 -#define CACHED_BITMAP 0x01 -#define CACHED_PIXMAP 0x02 - -/* Cached glyph information */ -typedef struct cached_glyph { - int stored; - FT_UInt index; - FT_Bitmap bitmap; - FT_Bitmap pixmap; - int minx; - int maxx; - int miny; - int maxy; - int yoffset; - int advance; - Uint16 cached; -} c_glyph; - -/* The structure used to hold internal font information */ -struct _TTF_Font { - /* Freetype2 maintains all sorts of useful info itself */ - FT_Face face; - - /* We'll cache these ourselves */ - int height; - int ascent; - int descent; - int lineskip; - - /* The font style */ - int face_style; - int style; - int outline; - - /* Whether kerning is desired */ - int kerning; - - /* Extra width in glyph bounds for text styles */ - int glyph_overhang; - float glyph_italics; - - /* Information in the font for underlining */ - int underline_offset; - int underline_height; - - /* Cache for style-transformed glyphs */ - c_glyph *current; - c_glyph cache[256]; - c_glyph scratch; - - /* We are responsible for closing the font stream */ - SDL_RWops *src; - int freesrc; - FT_Open_Args args; - - /* For non-scalable formats, we must remember which font index size */ - int font_size_family; - - /* really just flags passed into FT_Load_Glyph */ - int hinting; -}; - -/* Handle a style only if the font does not already handle it */ -#define TTF_HANDLE_STYLE_BOLD(font) (((font)->style & TTF_STYLE_BOLD) && \ - !((font)->face_style & TTF_STYLE_BOLD)) -#define TTF_HANDLE_STYLE_ITALIC(font) (((font)->style & TTF_STYLE_ITALIC) && \ - !((font)->face_style & TTF_STYLE_ITALIC)) -#define TTF_HANDLE_STYLE_UNDERLINE(font) ((font)->style & TTF_STYLE_UNDERLINE) -#define TTF_HANDLE_STYLE_STRIKETHROUGH(font) ((font)->style & TTF_STYLE_STRIKETHROUGH) - -/* Font styles that does not impact glyph drawing */ -#define TTF_STYLE_NO_GLYPH_CHANGE (TTF_STYLE_UNDERLINE | TTF_STYLE_STRIKETHROUGH) - -/* The FreeType font engine/library */ -static FT_Library library; -static int TTF_initialized = 0; -static int TTF_byteswapped = 0; - -/* UNICODE string utilities */ -static __inline__ int UNICODE_strlen(const Uint16 *text) -{ - int size = 0; - while ( *text++ ) { - ++size; - } - return size; -} -static __inline__ void UNICODE_strcpy(Uint16 *dst, const Uint16 *src, int swap) -{ - if ( swap ) { - while ( *src ) { - *dst = SDL_Swap16(*src); - ++src; - ++dst; - } - *dst = '\0'; - } else { - while ( *src ) { - *dst = *src; - ++src; - ++dst; - } - *dst = '\0'; - } -} - -/* Gets the top row of the underline. The outline - is taken into account. -*/ -static __inline__ int TTF_underline_top_row(TTF_Font *font) -{ - /* With outline, the underline_offset is underline_offset+outline. */ - /* So, we don't have to remove the top part of the outline height. */ - return font->ascent - font->underline_offset - 1; -} - -/* Gets the bottom row of the underline. The outline - is taken into account. -*/ -static __inline__ int TTF_underline_bottom_row(TTF_Font *font) -{ - int row = TTF_underline_top_row(font) + font->underline_height; - if( font->outline > 0 ) { - /* Add underline_offset outline offset and */ - /* the bottom part of the outline. */ - row += font->outline * 2; - } - return row; -} - -/* Gets the top row of the strikethrough. The outline - is taken into account. -*/ -static __inline__ int TTF_strikethrough_top_row(TTF_Font *font) -{ - /* With outline, the first text row is 'outline'. */ - /* So, we don't have to remove the top part of the outline height. */ - return font->height / 2; -} - -/* Gets the bottom row of the strikethrough. The outline - is taken into account. -*/ -static __inline__ int TTF_strikethrough_bottom_row(TTF_Font *font) -{ - int row = TTF_strikethrough_top_row(font) + font->underline_height; - if( font->outline > 0 ) { - /* Add first text row outline offset and */ - /* the bottom part of the outline. */ - row += font->outline * 2; - } - return row; -} - -static void TTF_initLineMectrics(const TTF_Font *font, const SDL_Surface *textbuf, const int row, Uint8 **pdst, int *pheight) -{ - Uint8 *dst; - int height; - - dst = (Uint8 *)textbuf->pixels; - if( row > 0 ) { - dst += row * textbuf->pitch; - } - - height = font->underline_height; - /* Take outline into account */ - if( font->outline > 0 ) { - height += font->outline * 2; - } - *pdst = dst; - *pheight = height; -} - -/* Draw a solid line of underline_height (+ optional outline) - at the given row. The row value must take the - outline into account. -*/ -static void TTF_drawLine_Solid(const TTF_Font *font, const SDL_Surface *textbuf, const int row) -{ - int line; - Uint8 *dst_check = (Uint8*)textbuf->pixels + textbuf->pitch * textbuf->h; - Uint8 *dst; - int height; - - TTF_initLineMectrics(font, textbuf, row, &dst, &height); - - /* Draw line */ - for ( line=height; line>0 && dst < dst_check; --line ) { - /* 1 because 0 is the bg color */ - memset( dst, 1, textbuf->w ); - dst += textbuf->pitch; - } -} - -/* Draw a shaded line of underline_height (+ optional outline) - at the given row. The row value must take the - outline into account. -*/ -static void TTF_drawLine_Shaded(const TTF_Font *font, const SDL_Surface *textbuf, const int row) -{ - int line; - Uint8 *dst_check = (Uint8*)textbuf->pixels + textbuf->pitch * textbuf->h; - Uint8 *dst; - int height; - - TTF_initLineMectrics(font, textbuf, row, &dst, &height); - - /* Draw line */ - for ( line=height; line>0 && dst < dst_check; --line ) { - memset( dst, NUM_GRAYS - 1, textbuf->w ); - dst += textbuf->pitch; - } -} - -/* Draw a blended line of underline_height (+ optional outline) - at the given row. The row value must take the - outline into account. -*/ -static void TTF_drawLine_Blended(const TTF_Font *font, const SDL_Surface *textbuf, const int row, const Uint32 color) -{ - int line; - Uint32 *dst_check = (Uint32*)textbuf->pixels + textbuf->pitch/4 * textbuf->h; - Uint8 *dst8; /* destination, byte version */ - Uint32 *dst; - int height; - int col; - Uint32 pixel = color | 0xFF000000; /* Amask */ - - TTF_initLineMectrics(font, textbuf, row, &dst8, &height); - dst = (Uint32 *) dst8; - - /* Draw line */ - for ( line=height; line>0 && dst < dst_check; --line ) { - for ( col=0; col < textbuf->w; ++col ) { - dst[col] = pixel; - } - dst += textbuf->pitch/4; - } -} - -/* rcg06192001 get linked library's version. */ -const SDL_version *TTF_Linked_Version(void) -{ - static SDL_version linked_version; - SDL_TTF_VERSION(&linked_version); - return(&linked_version); -} - -/* This function tells the library whether UNICODE text is generally - byteswapped. A UNICODE BOM character at the beginning of a string - will override this setting for that string. - */ -void TTF_ByteSwappedUNICODE(int swapped) -{ - TTF_byteswapped = swapped; -} - -static void TTF_SetFTError(const char *msg, FT_Error error) -{ -#ifdef USE_FREETYPE_ERRORS -#undef FTERRORS_H -#define FT_ERRORDEF( e, v, s ) { e, s }, - static const struct - { - int err_code; - const char* err_msg; - } ft_errors[] = { -#include - }; - int i; - const char *err_msg; - char buffer[1024]; - - err_msg = NULL; - for ( i=0; i<((sizeof ft_errors)/(sizeof ft_errors[0])); ++i ) { - if ( error == ft_errors[i].err_code ) { - err_msg = ft_errors[i].err_msg; - break; - } - } - if ( ! err_msg ) { - err_msg = "unknown FreeType error"; - } - sprintf(buffer, "%s: %s", msg, err_msg); - TTF_SetError(buffer); -#else - TTF_SetError(msg); -#endif /* USE_FREETYPE_ERRORS */ -} - -int TTF_Init( void ) -{ - int status = 0; - - if ( ! TTF_initialized ) { - FT_Error error = FT_Init_FreeType( &library ); - if ( error ) { - TTF_SetFTError("Couldn't init FreeType engine", error); - status = -1; - } - } - if ( status == 0 ) { - ++TTF_initialized; - } - return status; -} - -static unsigned long RWread( - FT_Stream stream, - unsigned long offset, - unsigned char* buffer, - unsigned long count -) -{ - SDL_RWops *src; - - src = (SDL_RWops *)stream->descriptor.pointer; - SDL_RWseek( src, (int)offset, SEEK_SET ); - if ( count == 0 ) { - return 0; - } - return SDL_RWread( src, buffer, 1, (int)count ); -} - -TTF_Font* TTF_OpenFontIndexRW( SDL_RWops *src, int freesrc, int ptsize, long index ) -{ - TTF_Font* font; - FT_Error error; - FT_Face face; - FT_Fixed scale; - FT_Stream stream; - int position; - - if ( ! TTF_initialized ) { - TTF_SetError( "Library not initialized" ); - return NULL; - } - - /* Check to make sure we can seek in this stream */ - position = SDL_RWtell(src); - if ( position < 0 ) { - TTF_SetError( "Can't seek in stream" ); - return NULL; - } - - font = (TTF_Font*) malloc(sizeof *font); - if ( font == NULL ) { - TTF_SetError( "Out of memory" ); - return NULL; - } - memset(font, 0, sizeof(*font)); - - font->src = src; - font->freesrc = freesrc; - - stream = (FT_Stream)malloc(sizeof(*stream)); - if ( stream == NULL ) { - TTF_SetError( "Out of memory" ); - TTF_CloseFont( font ); - return NULL; - } - memset(stream, 0, sizeof(*stream)); - - stream->read = RWread; - stream->descriptor.pointer = src; - stream->pos = (unsigned long)position; - SDL_RWseek(src, 0, SEEK_END); - stream->size = (unsigned long)(SDL_RWtell(src) - position); - SDL_RWseek(src, position, SEEK_SET); - - font->args.flags = FT_OPEN_STREAM; - font->args.stream = stream; - - error = FT_Open_Face( library, &font->args, index, &font->face ); - if( error ) { - TTF_SetFTError( "Couldn't load font file", error ); - TTF_CloseFont( font ); - return NULL; - } - face = font->face; - - /* Make sure that our font face is scalable (global metrics) */ - if ( FT_IS_SCALABLE(face) ) { - - /* Set the character size and use default DPI (72) */ - error = FT_Set_Char_Size( font->face, 0, ptsize * 64, 0, 0 ); - if( error ) { - TTF_SetFTError( "Couldn't set font size", error ); - TTF_CloseFont( font ); - return NULL; - } - - /* Get the scalable font metrics for this font */ - scale = face->size->metrics.y_scale; - font->ascent = FT_CEIL(FT_MulFix(face->ascender, scale)); - font->descent = FT_CEIL(FT_MulFix(face->descender, scale)); - font->height = font->ascent - font->descent + /* baseline */ 1; - font->lineskip = FT_CEIL(FT_MulFix(face->height, scale)); - font->underline_offset = FT_FLOOR(FT_MulFix(face->underline_position, scale)); - font->underline_height = FT_FLOOR(FT_MulFix(face->underline_thickness, scale)); - - } else { - /* Non-scalable font case. ptsize determines which family - * or series of fonts to grab from the non-scalable format. - * It is not the point size of the font. - * */ - if ( ptsize >= font->face->num_fixed_sizes ) - ptsize = font->face->num_fixed_sizes - 1; - font->font_size_family = ptsize; - error = FT_Set_Pixel_Sizes( face, - face->available_sizes[ptsize].height, - face->available_sizes[ptsize].width ); - /* With non-scalale fonts, Freetype2 likes to fill many of the - * font metrics with the value of 0. The size of the - * non-scalable fonts must be determined differently - * or sometimes cannot be determined. - * */ - font->ascent = face->available_sizes[ptsize].height; - font->descent = 0; - font->height = face->available_sizes[ptsize].height; - font->lineskip = FT_CEIL(font->ascent); - font->underline_offset = FT_FLOOR(face->underline_position); - font->underline_height = FT_FLOOR(face->underline_thickness); - } - - if ( font->underline_height < 1 ) { - font->underline_height = 1; - } - -#ifdef DEBUG_FONTS - printf("Font metrics:\n"); - printf("\tascent = %d, descent = %d\n", - font->ascent, font->descent); - printf("\theight = %d, lineskip = %d\n", - font->height, font->lineskip); - printf("\tunderline_offset = %d, underline_height = %d\n", - font->underline_offset, font->underline_height); - printf("\tunderline_top_row = %d, strikethrough_top_row = %d\n", - TTF_underline_top_row(font), TTF_strikethrough_top_row(font)); -#endif - - /* Initialize the font face style */ - font->face_style = TTF_STYLE_NORMAL; - if ( font->face->style_flags & FT_STYLE_FLAG_BOLD ) { - font->face_style |= TTF_STYLE_BOLD; - } - if ( font->face->style_flags & FT_STYLE_FLAG_ITALIC ) { - font->face_style |= TTF_STYLE_ITALIC; - } - /* Set the default font style */ - font->style = font->face_style; - font->outline = 0; - font->kerning = 1; - font->glyph_overhang = face->size->metrics.y_ppem / 10; - /* x offset = cos(((90.0-12)/360)*2*M_PI), or 12 degree angle */ - font->glyph_italics = 0.207f; - font->glyph_italics *= font->height; - - return font; -} - -TTF_Font* TTF_OpenFontRW( SDL_RWops *src, int freesrc, int ptsize ) -{ - return TTF_OpenFontIndexRW(src, freesrc, ptsize, 0); -} - -TTF_Font* TTF_OpenFontIndex( const char *file, int ptsize, long index ) -{ - SDL_RWops *rw = SDL_RWFromFile(file, "rb"); - if ( rw == NULL ) { - TTF_SetError(SDL_GetError()); - return NULL; - } - return TTF_OpenFontIndexRW(rw, 1, ptsize, index); -} - -TTF_Font* TTF_OpenFont( const char *file, int ptsize ) -{ - return TTF_OpenFontIndex(file, ptsize, 0); -} - -static void Flush_Glyph( c_glyph* glyph ) -{ - glyph->stored = 0; - glyph->index = 0; - if( glyph->bitmap.buffer ) { - free( glyph->bitmap.buffer ); - glyph->bitmap.buffer = 0; - } - if( glyph->pixmap.buffer ) { - free( glyph->pixmap.buffer ); - glyph->pixmap.buffer = 0; - } - glyph->cached = 0; -} - -static void Flush_Cache( TTF_Font* font ) -{ - int i; - int size = sizeof( font->cache ) / sizeof( font->cache[0] ); - - for( i = 0; i < size; ++i ) { - if( font->cache[i].cached ) { - Flush_Glyph( &font->cache[i] ); - } - - } - if( font->scratch.cached ) { - Flush_Glyph( &font->scratch ); - } - -} - -static FT_Error Load_Glyph( TTF_Font* font, Uint16 ch, c_glyph* cached, int want ) -{ - FT_Face face; - FT_Error error; - FT_GlyphSlot glyph; - FT_Glyph_Metrics* metrics; - FT_Outline* outline; - - if ( !font || !font->face ) { - return FT_Err_Invalid_Handle; - } - - face = font->face; - - /* Load the glyph */ - if ( ! cached->index ) { - cached->index = FT_Get_Char_Index( face, ch ); - } - error = FT_Load_Glyph( face, cached->index, FT_LOAD_DEFAULT | font->hinting); - if( error ) { - return error; - } - - /* Get our glyph shortcuts */ - glyph = face->glyph; - metrics = &glyph->metrics; - outline = &glyph->outline; - - /* Get the glyph metrics if desired */ - if ( (want & CACHED_METRICS) && !(cached->stored & CACHED_METRICS) ) { - if ( FT_IS_SCALABLE( face ) ) { - /* Get the bounding box */ - cached->minx = FT_FLOOR(metrics->horiBearingX); - cached->maxx = cached->minx + FT_CEIL(metrics->width); - cached->maxy = FT_FLOOR(metrics->horiBearingY); - cached->miny = cached->maxy - FT_CEIL(metrics->height); - cached->yoffset = font->ascent - cached->maxy; - cached->advance = FT_CEIL(metrics->horiAdvance); - } else { - /* Get the bounding box for non-scalable format. - * Again, freetype2 fills in many of the font metrics - * with the value of 0, so some of the values we - * need must be calculated differently with certain - * assumptions about non-scalable formats. - * */ - cached->minx = FT_FLOOR(metrics->horiBearingX); - cached->maxx = cached->minx + FT_CEIL(metrics->horiAdvance); - cached->maxy = FT_FLOOR(metrics->horiBearingY); - cached->miny = cached->maxy - FT_CEIL(face->available_sizes[font->font_size_family].height); - cached->yoffset = 0; - cached->advance = FT_CEIL(metrics->horiAdvance); - } - - /* Adjust for bold and italic text */ - if( TTF_HANDLE_STYLE_BOLD(font) ) { - cached->maxx += font->glyph_overhang; - } - if( TTF_HANDLE_STYLE_ITALIC(font) ) { - cached->maxx += (int)ceil(font->glyph_italics); - } - cached->stored |= CACHED_METRICS; - } - - if ( ((want & CACHED_BITMAP) && !(cached->stored & CACHED_BITMAP)) || - ((want & CACHED_PIXMAP) && !(cached->stored & CACHED_PIXMAP)) ) { - int mono = (want & CACHED_BITMAP); - int i; - FT_Bitmap* src; - FT_Bitmap* dst; - FT_Glyph bitmap_glyph = NULL; - - /* Handle the italic style */ - if( TTF_HANDLE_STYLE_ITALIC(font) ) { - FT_Matrix shear; - - shear.xx = 1 << 16; - shear.xy = (int) ( font->glyph_italics * ( 1 << 16 ) ) / font->height; - shear.yx = 0; - shear.yy = 1 << 16; - - FT_Outline_Transform( outline, &shear ); - } - - /* Render as outline */ - if( (font->outline > 0) && glyph->format != FT_GLYPH_FORMAT_BITMAP ) { - FT_Stroker stroker; - FT_Get_Glyph( glyph, &bitmap_glyph ); - error = FT_Stroker_New( library, &stroker ); - if( error ) { - return error; - } - FT_Stroker_Set( stroker, font->outline * 64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0 ); - FT_Glyph_Stroke( &bitmap_glyph, stroker, 1 /* delete the original glyph */ ); - FT_Stroker_Done( stroker ); - /* Render the glyph */ - error = FT_Glyph_To_Bitmap( &bitmap_glyph, mono ? ft_render_mode_mono : ft_render_mode_normal, 0, 1 ); - if( error ) { - FT_Done_Glyph( bitmap_glyph ); - return error; - } - src = &((FT_BitmapGlyph)bitmap_glyph)->bitmap; - } else { - /* Render the glyph */ - error = FT_Render_Glyph( glyph, mono ? ft_render_mode_mono : ft_render_mode_normal ); - if( error ) { - return error; - } - src = &glyph->bitmap; - } - /* Copy over information to cache */ - if ( mono ) { - dst = &cached->bitmap; - } else { - dst = &cached->pixmap; - } - memcpy( dst, src, sizeof( *dst ) ); - - /* FT_Render_Glyph() and .fon fonts always generate a - * two-color (black and white) glyphslot surface, even - * when rendered in ft_render_mode_normal. */ - /* FT_IS_SCALABLE() means that the font is in outline format, - * but does not imply that outline is rendered as 8-bit - * grayscale, because embedded bitmap/graymap is preferred - * (see FT_LOAD_DEFAULT section of FreeType2 API Reference). - * FT_Render_Glyph() canreturn two-color bitmap or 4/16/256- - * color graymap according to the format of embedded bitmap/ - * graymap. */ - if ( src->pixel_mode == FT_PIXEL_MODE_MONO ) { - dst->pitch *= 8; - } else if ( src->pixel_mode == FT_PIXEL_MODE_GRAY2 ) { - dst->pitch *= 4; - } else if ( src->pixel_mode == FT_PIXEL_MODE_GRAY4 ) { - dst->pitch *= 2; - } - - /* Adjust for bold and italic text */ - if( TTF_HANDLE_STYLE_BOLD(font) ) { - int bump = font->glyph_overhang; - dst->pitch += bump; - dst->width += bump; - } - if( TTF_HANDLE_STYLE_ITALIC(font) ) { - int bump = (int)ceil(font->glyph_italics); - dst->pitch += bump; - dst->width += bump; - } - - if (dst->rows != 0) { - dst->buffer = (unsigned char *)malloc( dst->pitch * dst->rows ); - if( !dst->buffer ) { - return FT_Err_Out_Of_Memory; - } - memset( dst->buffer, 0, dst->pitch * dst->rows ); - - for( i = 0; i < src->rows; i++ ) { - int soffset = i * src->pitch; - int doffset = i * dst->pitch; - if ( mono ) { - unsigned char *srcp = src->buffer + soffset; - unsigned char *dstp = dst->buffer + doffset; - int j; - if ( src->pixel_mode == FT_PIXEL_MODE_MONO ) { - for ( j = 0; j < src->width; j += 8 ) { - unsigned char ch = *srcp++; - *dstp++ = (ch&0x80) >> 7; - ch <<= 1; - *dstp++ = (ch&0x80) >> 7; - ch <<= 1; - *dstp++ = (ch&0x80) >> 7; - ch <<= 1; - *dstp++ = (ch&0x80) >> 7; - ch <<= 1; - *dstp++ = (ch&0x80) >> 7; - ch <<= 1; - *dstp++ = (ch&0x80) >> 7; - ch <<= 1; - *dstp++ = (ch&0x80) >> 7; - ch <<= 1; - *dstp++ = (ch&0x80) >> 7; - } - } else if ( src->pixel_mode == FT_PIXEL_MODE_GRAY2 ) { - for ( j = 0; j < src->width; j += 4 ) { - unsigned char ch = *srcp++; - *dstp++ = (((ch&0xA0) >> 6) >= 0x2) ? 1 : 0; - ch <<= 2; - *dstp++ = (((ch&0xA0) >> 6) >= 0x2) ? 1 : 0; - ch <<= 2; - *dstp++ = (((ch&0xA0) >> 6) >= 0x2) ? 1 : 0; - ch <<= 2; - *dstp++ = (((ch&0xA0) >> 6) >= 0x2) ? 1 : 0; - } - } else if ( src->pixel_mode == FT_PIXEL_MODE_GRAY4 ) { - for ( j = 0; j < src->width; j += 2 ) { - unsigned char ch = *srcp++; - *dstp++ = (((ch&0xF0) >> 4) >= 0x8) ? 1 : 0; - ch <<= 4; - *dstp++ = (((ch&0xF0) >> 4) >= 0x8) ? 1 : 0; - } - } else { - for ( j = 0; j < src->width; j++ ) { - unsigned char ch = *srcp++; - *dstp++ = (ch >= 0x80) ? 1 : 0; - } - } - } else if ( src->pixel_mode == FT_PIXEL_MODE_MONO ) { - /* This special case wouldn't - * be here if the FT_Render_Glyph() - * function wasn't buggy when it tried - * to render a .fon font with 256 - * shades of gray. Instead, it - * returns a black and white surface - * and we have to translate it back - * to a 256 gray shaded surface. - * */ - unsigned char *srcp = src->buffer + soffset; - unsigned char *dstp = dst->buffer + doffset; - unsigned char ch; - int j, k; - for ( j = 0; j < src->width; j += 8) { - ch = *srcp++; - for (k = 0; k < 8; ++k) { - if ((ch&0x80) >> 7) { - *dstp++ = NUM_GRAYS - 1; - } else { - *dstp++ = 0x00; - } - ch <<= 1; - } - } - } else if ( src->pixel_mode == FT_PIXEL_MODE_GRAY2 ) { - unsigned char *srcp = src->buffer + soffset; - unsigned char *dstp = dst->buffer + doffset; - unsigned char ch; - int j, k; - for ( j = 0; j < src->width; j += 4 ) { - ch = *srcp++; - for ( k = 0; k < 4; ++k ) { - if ((ch&0xA0) >> 6) { - *dstp++ = NUM_GRAYS * ((ch&0xA0) >> 6) / 3 - 1; - } else { - *dstp++ = 0x00; - } - ch <<= 2; - } - } - } else if ( src->pixel_mode == FT_PIXEL_MODE_GRAY4 ) { - unsigned char *srcp = src->buffer + soffset; - unsigned char *dstp = dst->buffer + doffset; - unsigned char ch; - int j, k; - for ( j = 0; j < src->width; j += 2 ) { - ch = *srcp++; - for ( k = 0; k < 2; ++k ) { - if ((ch&0xF0) >> 4) { - *dstp++ = NUM_GRAYS * ((ch&0xF0) >> 4) / 15 - 1; - } else { - *dstp++ = 0x00; - } - ch <<= 4; - } - } - } else { - memcpy(dst->buffer+doffset, - src->buffer+soffset, src->pitch); - } - } - } - - /* Handle the bold style */ - if ( TTF_HANDLE_STYLE_BOLD(font) ) { - int row; - int col; - int offset; - int pixel; - Uint8* pixmap; - - /* The pixmap is a little hard, we have to add and clamp */ - for( row = dst->rows - 1; row >= 0; --row ) { - pixmap = (Uint8*) dst->buffer + row * dst->pitch; - for( offset=1; offset <= font->glyph_overhang; ++offset ) { - for( col = dst->width - 1; col > 0; --col ) { - if( mono ) { - pixmap[col] |= pixmap[col-1]; - } else { - pixel = (pixmap[col] + pixmap[col-1]); - if( pixel > NUM_GRAYS - 1 ) { - pixel = NUM_GRAYS - 1; - } - pixmap[col] = (Uint8) pixel; - } - } - } - } - } - - /* Mark that we rendered this format */ - if ( mono ) { - cached->stored |= CACHED_BITMAP; - } else { - cached->stored |= CACHED_PIXMAP; - } - - /* Free outlined glyph */ - if( bitmap_glyph ) { - FT_Done_Glyph( bitmap_glyph ); - } - } - - /* We're done, mark this glyph cached */ - cached->cached = ch; - - return 0; -} - -static FT_Error Find_Glyph( TTF_Font* font, Uint16 ch, int want ) -{ - int retval = 0; - - if( ch < 256 ) { - font->current = &font->cache[ch]; - } else { - if ( font->scratch.cached != ch ) { - Flush_Glyph( &font->scratch ); - } - font->current = &font->scratch; - } - if ( (font->current->stored & want) != want ) { - retval = Load_Glyph( font, ch, font->current, want ); - } - return retval; -} - -void TTF_CloseFont( TTF_Font* font ) -{ - if ( font ) { - Flush_Cache( font ); - if ( font->face ) { - FT_Done_Face( font->face ); - } - if ( font->args.stream ) { - free( font->args.stream ); - } - if ( font->freesrc ) { - SDL_RWclose( font->src ); - } - free( font ); - } -} - -static Uint16 *LATIN1_to_UNICODE(Uint16 *unicode, const char *text, int len) -{ - int i; - - for ( i=0; i < len; ++i ) { - unicode[i] = ((const unsigned char *)text)[i]; - } - unicode[i] = 0; - - return unicode; -} - -static Uint16 *UTF8_to_UNICODE(Uint16 *unicode, const char *utf8, int len) -{ - int i, j; - Uint16 ch; - - for ( i=0, j=0; i < len; ++i, ++j ) { - ch = ((const unsigned char *)utf8)[i]; - if ( ch >= 0xF0 ) { - ch = (Uint16)(utf8[i]&0x07) << 18; - ch |= (Uint16)(utf8[++i]&0x3F) << 12; - ch |= (Uint16)(utf8[++i]&0x3F) << 6; - ch |= (Uint16)(utf8[++i]&0x3F); - } else - if ( ch >= 0xE0 ) { - ch = (Uint16)(utf8[i]&0x0F) << 12; - ch |= (Uint16)(utf8[++i]&0x3F) << 6; - ch |= (Uint16)(utf8[++i]&0x3F); - } else - if ( ch >= 0xC0 ) { - ch = (Uint16)(utf8[i]&0x1F) << 6; - ch |= (Uint16)(utf8[++i]&0x3F); - } - unicode[j] = ch; - } - unicode[j] = 0; - - return unicode; -} - -int TTF_FontHeight(const TTF_Font *font) -{ - return(font->height); -} - -int TTF_FontAscent(const TTF_Font *font) -{ - return(font->ascent); -} - -int TTF_FontDescent(const TTF_Font *font) -{ - return(font->descent); -} - -int TTF_FontLineSkip(const TTF_Font *font) -{ - return(font->lineskip); -} - -int TTF_GetFontKerning(const TTF_Font *font) -{ - return(font->kerning); -} - -void TTF_SetFontKerning(TTF_Font *font, int allowed) -{ - font->kerning = allowed; -} - -long TTF_FontFaces(const TTF_Font *font) -{ - return(font->face->num_faces); -} - -int TTF_FontFaceIsFixedWidth(const TTF_Font *font) -{ - return(FT_IS_FIXED_WIDTH(font->face)); -} - -char *TTF_FontFaceFamilyName(const TTF_Font *font) -{ - return(font->face->family_name); -} - -char *TTF_FontFaceStyleName(const TTF_Font *font) -{ - return(font->face->style_name); -} - -int TTF_GlyphIsProvided(const TTF_Font *font, Uint16 ch) -{ - return(FT_Get_Char_Index(font->face, ch)); -} - -int TTF_GlyphMetrics(TTF_Font *font, Uint16 ch, - int* minx, int* maxx, int* miny, int* maxy, int* advance) -{ - FT_Error error; - - error = Find_Glyph(font, ch, CACHED_METRICS); - if ( error ) { - TTF_SetFTError("Couldn't find glyph", error); - return -1; - } - - if ( minx ) { - *minx = font->current->minx; - } - if ( maxx ) { - *maxx = font->current->maxx; - if( TTF_HANDLE_STYLE_BOLD(font) ) { - *maxx += font->glyph_overhang; - } - } - if ( miny ) { - *miny = font->current->miny; - } - if ( maxy ) { - *maxy = font->current->maxy; - } - if ( advance ) { - *advance = font->current->advance; - if( TTF_HANDLE_STYLE_BOLD(font) ) { - *advance += font->glyph_overhang; - } - } - return 0; -} - -int TTF_SizeText(TTF_Font *font, const char *text, int *w, int *h) -{ - Uint16 *unicode_text; - int unicode_len; - int status; - - /* Copy the Latin-1 text to a UNICODE text buffer */ - unicode_len = strlen(text); - unicode_text = (Uint16 *)ALLOCA((1+unicode_len+1)*(sizeof *unicode_text)); - if ( unicode_text == NULL ) { - TTF_SetError("Out of memory"); - return -1; - } - *unicode_text = UNICODE_BOM_NATIVE; - LATIN1_to_UNICODE(unicode_text+1, text, unicode_len); - - /* Render the new text */ - status = TTF_SizeUNICODE(font, unicode_text, w, h); - - /* Free the text buffer and return */ - FREEA(unicode_text); - return status; -} - -int TTF_SizeUTF8(TTF_Font *font, const char *text, int *w, int *h) -{ - Uint16 *unicode_text; - int unicode_len; - int status; - - /* Copy the UTF-8 text to a UNICODE text buffer */ - unicode_len = strlen(text); - unicode_text = (Uint16 *)ALLOCA((1+unicode_len+1)*(sizeof *unicode_text)); - if ( unicode_text == NULL ) { - TTF_SetError("Out of memory"); - return -1; - } - *unicode_text = UNICODE_BOM_NATIVE; - UTF8_to_UNICODE(unicode_text+1, text, unicode_len); - - /* Render the new text */ - status = TTF_SizeUNICODE(font, unicode_text, w, h); - - /* Free the text buffer and return */ - FREEA(unicode_text); - return status; -} - -int TTF_SizeUNICODE(TTF_Font *font, const Uint16 *text, int *w, int *h) -{ - int status; - const Uint16 *ch; - int swapped; - int x, z; - int minx, maxx; - int miny, maxy; - c_glyph *glyph; - FT_Error error; - FT_Long use_kerning; - FT_UInt prev_index = 0; - int outline_delta = 0; - - /* Initialize everything to 0 */ - if ( ! TTF_initialized ) { - TTF_SetError( "Library not initialized" ); - return -1; - } - status = 0; - minx = maxx = 0; - miny = maxy = 0; - swapped = TTF_byteswapped; - - /* check kerning */ - use_kerning = FT_HAS_KERNING( font->face ) && font->kerning; - - /* Init outline handling */ - if ( font->outline > 0 ) { - outline_delta = font->outline * 2; - } - - /* Load each character and sum it's bounding box */ - x= 0; - for ( ch=text; *ch; ++ch ) { - Uint16 c = *ch; - if ( c == UNICODE_BOM_NATIVE ) { - swapped = 0; - if ( text == ch ) { - ++text; - } - continue; - } - if ( c == UNICODE_BOM_SWAPPED ) { - swapped = 1; - if ( text == ch ) { - ++text; - } - continue; - } - if ( swapped ) { - c = SDL_Swap16(c); - } - - error = Find_Glyph(font, c, CACHED_METRICS); - if ( error ) { - return -1; - } - glyph = font->current; - - /* handle kerning */ - if ( use_kerning && prev_index && glyph->index ) { - FT_Vector delta; - FT_Get_Kerning( font->face, prev_index, glyph->index, ft_kerning_default, &delta ); - x += delta.x >> 6; - } - -#if 0 - if ( (ch == text) && (glyph->minx < 0) ) { - /* Fixes the texture wrapping bug when the first letter - * has a negative minx value or horibearing value. The entire - * bounding box must be adjusted to be bigger so the entire - * letter can fit without any texture corruption or wrapping. - * - * Effects: First enlarges bounding box. - * Second, xstart has to start ahead of its normal spot in the - * negative direction of the negative minx value. - * (pushes everything to the right). - * - * This will make the memory copy of the glyph bitmap data - * work out correctly. - * */ - z -= glyph->minx; - - } -#endif - - z = x + glyph->minx; - if ( minx > z ) { - minx = z; - } - if ( TTF_HANDLE_STYLE_BOLD(font) ) { - x += font->glyph_overhang; - } - if ( glyph->advance > glyph->maxx ) { - z = x + glyph->advance; - } else { - z = x + glyph->maxx; - } - if ( maxx < z ) { - maxx = z; - } - x += glyph->advance; - - if ( glyph->miny < miny ) { - miny = glyph->miny; - } - if ( glyph->maxy > maxy ) { - maxy = glyph->maxy; - } - prev_index = glyph->index; - } - - /* Fill the bounds rectangle */ - if ( w ) { - /* Add outline extra width */ - *w = (maxx - minx) + outline_delta; - } - if ( h ) { - /* Some fonts descend below font height (FletcherGothicFLF) */ - /* Add outline extra height */ - *h = (font->ascent - miny) + outline_delta; - if ( *h < font->height ) { - *h = font->height; - } - /* Update height according to the needs of the underline style */ - if( TTF_HANDLE_STYLE_UNDERLINE(font) ) { - int bottom_row = TTF_underline_bottom_row(font); - if ( *h < bottom_row ) { - *h = bottom_row; - } - } - } - return status; -} - -/* Convert the Latin-1 text to UNICODE and render it -*/ -SDL_Surface *TTF_RenderText_Solid(TTF_Font *font, - const char *text, SDL_Color fg) -{ - SDL_Surface *textbuf; - Uint16 *unicode_text; - int unicode_len; - - /* Copy the Latin-1 text to a UNICODE text buffer */ - unicode_len = strlen(text); - unicode_text = (Uint16 *)ALLOCA((1+unicode_len+1)*(sizeof *unicode_text)); - if ( unicode_text == NULL ) { - TTF_SetError("Out of memory"); - return(NULL); - } - *unicode_text = UNICODE_BOM_NATIVE; - LATIN1_to_UNICODE(unicode_text+1, text, unicode_len); - - /* Render the new text */ - textbuf = TTF_RenderUNICODE_Solid(font, unicode_text, fg); - - /* Free the text buffer and return */ - FREEA(unicode_text); - return(textbuf); -} - -/* Convert the UTF-8 text to UNICODE and render it -*/ -SDL_Surface *TTF_RenderUTF8_Solid(TTF_Font *font, - const char *text, SDL_Color fg) -{ - SDL_Surface *textbuf; - Uint16 *unicode_text; - int unicode_len; - - /* Copy the UTF-8 text to a UNICODE text buffer */ - unicode_len = strlen(text); - unicode_text = (Uint16 *)ALLOCA((1+unicode_len+1)*(sizeof *unicode_text)); - if ( unicode_text == NULL ) { - TTF_SetError("Out of memory"); - return(NULL); - } - *unicode_text = UNICODE_BOM_NATIVE; - UTF8_to_UNICODE(unicode_text, text, unicode_len); - - /* Render the new text */ - textbuf = TTF_RenderUNICODE_Solid(font, unicode_text, fg); - - /* Free the text buffer and return */ - FREEA(unicode_text); - return(textbuf); -} - -SDL_Surface *TTF_RenderUNICODE_Solid(TTF_Font *font, - const Uint16 *text, SDL_Color fg) -{ - int xstart; - int width; - int height; - SDL_Surface* textbuf; - SDL_Palette* palette; - const Uint16* ch; - Uint8* src; - Uint8* dst; - Uint8 *dst_check; - int swapped; - int row, col; - c_glyph *glyph; - - FT_Bitmap *current; - FT_Error error; - FT_Long use_kerning; - FT_UInt prev_index = 0; - - /* Get the dimensions of the text surface */ - if( ( TTF_SizeUNICODE(font, text, &width, &height) < 0 ) || !width ) { - TTF_SetError( "Text has zero width" ); - return NULL; - } - - /* Create the target surface */ - textbuf = SDL_AllocSurface(SDL_SWSURFACE, width, height, 8, 0, 0, 0, 0); - if( textbuf == NULL ) { - return NULL; - } - - /* Adding bound checking to avoid all kinds of memory corruption errors - that may occur. */ - dst_check = (Uint8*)textbuf->pixels + textbuf->pitch * textbuf->h; - - /* Fill the palette with the foreground color */ - palette = textbuf->format->palette; - palette->colors[0].r = 255 - fg.r; - palette->colors[0].g = 255 - fg.g; - palette->colors[0].b = 255 - fg.b; - palette->colors[1].r = fg.r; - palette->colors[1].g = fg.g; - palette->colors[1].b = fg.b; - SDL_SetColorKey( textbuf, SDL_SRCCOLORKEY, 0 ); - - /* check kerning */ - use_kerning = FT_HAS_KERNING( font->face ) && font->kerning; - - /* Load and render each character */ - xstart = 0; - swapped = TTF_byteswapped; - for( ch=text; *ch; ++ch ) { - Uint16 c = *ch; - if ( c == UNICODE_BOM_NATIVE ) { - swapped = 0; - if ( text == ch ) { - ++text; - } - continue; - } - if ( c == UNICODE_BOM_SWAPPED ) { - swapped = 1; - if ( text == ch ) { - ++text; - } - continue; - } - if ( swapped ) { - c = SDL_Swap16(c); - } - - error = Find_Glyph(font, c, CACHED_METRICS|CACHED_BITMAP); - if( error ) { - SDL_FreeSurface( textbuf ); - return NULL; - } - glyph = font->current; - current = &glyph->bitmap; - /* Ensure the width of the pixmap is correct. On some cases, - * freetype may report a larger pixmap than possible.*/ - width = current->width; - if (font->outline <= 0 && width > glyph->maxx - glyph->minx) { - width = glyph->maxx - glyph->minx; - } - /* do kerning, if possible AC-Patch */ - if ( use_kerning && prev_index && glyph->index ) { - FT_Vector delta; - FT_Get_Kerning( font->face, prev_index, glyph->index, ft_kerning_default, &delta ); - xstart += delta.x >> 6; - } - /* Compensate for wrap around bug with negative minx's */ - if ( (ch == text) && (glyph->minx < 0) ) { - xstart -= glyph->minx; - } - - for( row = 0; row < current->rows; ++row ) { - /* Make sure we don't go either over, or under the - * limit */ - if ( row+glyph->yoffset < 0 ) { - continue; - } - if ( row+glyph->yoffset >= textbuf->h ) { - continue; - } - dst = (Uint8*) textbuf->pixels + - (row+glyph->yoffset) * textbuf->pitch + - xstart + glyph->minx; - src = current->buffer + row * current->pitch; - - for ( col=width; col>0 && dst < dst_check; --col ) { - *dst++ |= *src++; - } - } - - xstart += glyph->advance; - if ( TTF_HANDLE_STYLE_BOLD(font) ) { - xstart += font->glyph_overhang; - } - prev_index = glyph->index; - } - - /* Handle the underline style */ - if( TTF_HANDLE_STYLE_UNDERLINE(font) ) { - row = TTF_underline_top_row(font); - TTF_drawLine_Solid(font, textbuf, row); - } - - /* Handle the strikethrough style */ - if( TTF_HANDLE_STYLE_STRIKETHROUGH(font) ) { - row = TTF_strikethrough_top_row(font); - TTF_drawLine_Solid(font, textbuf, row); - } - return textbuf; -} - -SDL_Surface *TTF_RenderGlyph_Solid(TTF_Font *font, Uint16 ch, SDL_Color fg) -{ - SDL_Surface *textbuf; - SDL_Palette *palette; - Uint8 *src, *dst; - int row; - FT_Error error; - c_glyph *glyph; - - /* Get the glyph itself */ - error = Find_Glyph(font, ch, CACHED_METRICS|CACHED_BITMAP); - if ( error ) { - return(NULL); - } - glyph = font->current; - - /* Create the target surface */ - textbuf = SDL_CreateRGBSurface( SDL_SWSURFACE, - glyph->bitmap.pitch, - glyph->bitmap.rows, - 8, 0, 0, 0, 0 ); - if ( ! textbuf ) { - return(NULL); - } - - /* Fill the palette with the foreground color */ - palette = textbuf->format->palette; - palette->colors[0].r = 255-fg.r; - palette->colors[0].g = 255-fg.g; - palette->colors[0].b = 255-fg.b; - palette->colors[1].r = fg.r; - palette->colors[1].g = fg.g; - palette->colors[1].b = fg.b; - SDL_SetColorKey(textbuf, SDL_SRCCOLORKEY, 0); - - /* Copy the character from the pixmap */ - src = glyph->bitmap.buffer; - dst = (Uint8*) textbuf->pixels; - for ( row = 0; row < textbuf->h; ++row ) { - memcpy( dst, src, glyph->bitmap.pitch ); - src += glyph->bitmap.pitch; - dst += textbuf->pitch; - } - - /* Handle the underline style */ - if( TTF_HANDLE_STYLE_UNDERLINE(font) ) { - row = TTF_underline_top_row(font); - TTF_drawLine_Solid(font, textbuf, row); - } - - /* Handle the strikethrough style */ - if( TTF_HANDLE_STYLE_STRIKETHROUGH(font) ) { - row = TTF_strikethrough_top_row(font); - TTF_drawLine_Solid(font, textbuf, row); - } - return(textbuf); -} - - -/* Convert the Latin-1 text to UNICODE and render it -*/ -SDL_Surface *TTF_RenderText_Shaded(TTF_Font *font, - const char *text, SDL_Color fg, SDL_Color bg) -{ - SDL_Surface *textbuf; - Uint16 *unicode_text; - int unicode_len; - - /* Copy the Latin-1 text to a UNICODE text buffer */ - unicode_len = strlen(text); - unicode_text = (Uint16 *)ALLOCA((1+unicode_len+1)*(sizeof *unicode_text)); - if ( unicode_text == NULL ) { - TTF_SetError("Out of memory"); - return(NULL); - } - *unicode_text = UNICODE_BOM_NATIVE; - LATIN1_to_UNICODE(unicode_text+1, text, unicode_len); - - /* Render the new text */ - textbuf = TTF_RenderUNICODE_Shaded(font, unicode_text, fg, bg); - - /* Free the text buffer and return */ - FREEA(unicode_text); - return(textbuf); -} - -/* Convert the UTF-8 text to UNICODE and render it -*/ -SDL_Surface *TTF_RenderUTF8_Shaded(TTF_Font *font, - const char *text, SDL_Color fg, SDL_Color bg) -{ - SDL_Surface *textbuf; - Uint16 *unicode_text; - int unicode_len; - - /* Copy the UTF-8 text to a UNICODE text buffer */ - unicode_len = strlen(text); - unicode_text = (Uint16 *)ALLOCA((1+unicode_len+1)*(sizeof *unicode_text)); - if ( unicode_text == NULL ) { - TTF_SetError("Out of memory"); - return(NULL); - } - *unicode_text = UNICODE_BOM_NATIVE; - UTF8_to_UNICODE(unicode_text+1, text, unicode_len); - - /* Render the new text */ - textbuf = TTF_RenderUNICODE_Shaded(font, unicode_text, fg, bg); - - /* Free the text buffer and return */ - FREEA(unicode_text); - return(textbuf); -} - -SDL_Surface* TTF_RenderUNICODE_Shaded( TTF_Font* font, - const Uint16* text, - SDL_Color fg, - SDL_Color bg ) -{ - int xstart; - int width; - int height; - SDL_Surface* textbuf; - SDL_Palette* palette; - int index; - int rdiff; - int gdiff; - int bdiff; - const Uint16* ch; - Uint8* src; - Uint8* dst; - Uint8* dst_check; - int swapped; - int row, col; - FT_Bitmap* current; - c_glyph *glyph; - FT_Error error; - FT_Long use_kerning; - FT_UInt prev_index = 0; - - /* Get the dimensions of the text surface */ - if( ( TTF_SizeUNICODE(font, text, &width, &height) < 0 ) || !width ) { - TTF_SetError("Text has zero width"); - return NULL; - } - - /* Create the target surface */ - textbuf = SDL_AllocSurface(SDL_SWSURFACE, width, height, 8, 0, 0, 0, 0); - if( textbuf == NULL ) { - return NULL; - } - - /* Adding bound checking to avoid all kinds of memory corruption errors - that may occur. */ - dst_check = (Uint8*)textbuf->pixels + textbuf->pitch * textbuf->h; - - /* Fill the palette with NUM_GRAYS levels of shading from bg to fg */ - palette = textbuf->format->palette; - rdiff = fg.r - bg.r; - gdiff = fg.g - bg.g; - bdiff = fg.b - bg.b; - - for( index = 0; index < NUM_GRAYS; ++index ) { - palette->colors[index].r = bg.r + (index*rdiff) / (NUM_GRAYS-1); - palette->colors[index].g = bg.g + (index*gdiff) / (NUM_GRAYS-1); - palette->colors[index].b = bg.b + (index*bdiff) / (NUM_GRAYS-1); - } - - /* check kerning */ - use_kerning = FT_HAS_KERNING( font->face ) && font->kerning; - - /* Load and render each character */ - xstart = 0; - swapped = TTF_byteswapped; - for( ch = text; *ch; ++ch ) { - Uint16 c = *ch; - if ( c == UNICODE_BOM_NATIVE ) { - swapped = 0; - if ( text == ch ) { - ++text; - } - continue; - } - if ( c == UNICODE_BOM_SWAPPED ) { - swapped = 1; - if ( text == ch ) { - ++text; - } - continue; - } - if ( swapped ) { - c = SDL_Swap16(c); - } - - error = Find_Glyph(font, c, CACHED_METRICS|CACHED_PIXMAP); - if( error ) { - SDL_FreeSurface( textbuf ); - return NULL; - } - glyph = font->current; - /* Ensure the width of the pixmap is correct. On some cases, - * freetype may report a larger pixmap than possible.*/ - width = glyph->pixmap.width; - if (font->outline <= 0 && width > glyph->maxx - glyph->minx) { - width = glyph->maxx - glyph->minx; - } - /* do kerning, if possible AC-Patch */ - if ( use_kerning && prev_index && glyph->index ) { - FT_Vector delta; - FT_Get_Kerning( font->face, prev_index, glyph->index, ft_kerning_default, &delta ); - xstart += delta.x >> 6; - } - /* Compensate for the wrap around with negative minx's */ - if ( (ch == text) && (glyph->minx < 0) ) { - xstart -= glyph->minx; - } - - current = &glyph->pixmap; - for( row = 0; row < current->rows; ++row ) { - /* Make sure we don't go either over, or under the - * limit */ - if ( row+glyph->yoffset < 0 ) { - continue; - } - if ( row+glyph->yoffset >= textbuf->h ) { - continue; - } - dst = (Uint8*) textbuf->pixels + - (row+glyph->yoffset) * textbuf->pitch + - xstart + glyph->minx; - src = current->buffer + row * current->pitch; - for ( col=width; col>0 && dst < dst_check; --col ) { - *dst++ |= *src++; - } - } - - xstart += glyph->advance; - if( TTF_HANDLE_STYLE_BOLD(font) ) { - xstart += font->glyph_overhang; - } - prev_index = glyph->index; - } - - /* Handle the underline style */ - if( TTF_HANDLE_STYLE_UNDERLINE(font) ) { - row = TTF_underline_top_row(font); - TTF_drawLine_Shaded(font, textbuf, row); - } - - /* Handle the strikethrough style */ - if( TTF_HANDLE_STYLE_STRIKETHROUGH(font) ) { - row = TTF_strikethrough_top_row(font); - TTF_drawLine_Shaded(font, textbuf, row); - } - return textbuf; -} - -SDL_Surface* TTF_RenderGlyph_Shaded( TTF_Font* font, - Uint16 ch, - SDL_Color fg, - SDL_Color bg ) -{ - SDL_Surface* textbuf; - SDL_Palette* palette; - int index; - int rdiff; - int gdiff; - int bdiff; - Uint8* src; - Uint8* dst; - int row; - FT_Error error; - c_glyph* glyph; - - /* Get the glyph itself */ - error = Find_Glyph(font, ch, CACHED_METRICS|CACHED_PIXMAP); - if( error ) { - return NULL; - } - glyph = font->current; - - /* Create the target surface */ - textbuf = SDL_CreateRGBSurface( SDL_SWSURFACE, - glyph->pixmap.width, - glyph->pixmap.rows, - 8, 0, 0, 0, 0 ); - if( !textbuf ) { - return NULL; - } - - /* Fill the palette with NUM_GRAYS levels of shading from bg to fg */ - palette = textbuf->format->palette; - rdiff = fg.r - bg.r; - gdiff = fg.g - bg.g; - bdiff = fg.b - bg.b; - for( index = 0; index < NUM_GRAYS; ++index ) { - palette->colors[index].r = bg.r + (index*rdiff) / (NUM_GRAYS-1); - palette->colors[index].g = bg.g + (index*gdiff) / (NUM_GRAYS-1); - palette->colors[index].b = bg.b + (index*bdiff) / (NUM_GRAYS-1); - } - - /* Copy the character from the pixmap */ - src = glyph->pixmap.buffer; - dst = (Uint8*) textbuf->pixels; - for ( row = 0; row < textbuf->h; ++row ) { - memcpy( dst, src, glyph->pixmap.pitch ); - src += glyph->pixmap.pitch; - dst += textbuf->pitch; - } - - /* Handle the underline style */ - if( TTF_HANDLE_STYLE_UNDERLINE(font) ) { - row = TTF_underline_top_row(font); - TTF_drawLine_Shaded(font, textbuf, row); - } - - /* Handle the strikethrough style */ - if( TTF_HANDLE_STYLE_STRIKETHROUGH(font) ) { - row = TTF_strikethrough_top_row(font); - TTF_drawLine_Shaded(font, textbuf, row); - } - return textbuf; -} - -/* Convert the Latin-1 text to UNICODE and render it -*/ -SDL_Surface *TTF_RenderText_Blended(TTF_Font *font, - const char *text, SDL_Color fg) -{ - SDL_Surface *textbuf; - Uint16 *unicode_text; - int unicode_len; - - /* Copy the Latin-1 text to a UNICODE text buffer */ - unicode_len = strlen(text); - unicode_text = (Uint16 *)ALLOCA((1+unicode_len+1)*(sizeof *unicode_text)); - if ( unicode_text == NULL ) { - TTF_SetError("Out of memory"); - return(NULL); - } - *unicode_text = UNICODE_BOM_NATIVE; - LATIN1_to_UNICODE(unicode_text+1, text, unicode_len); - - /* Render the new text */ - textbuf = TTF_RenderUNICODE_Blended(font, unicode_text, fg); - - /* Free the text buffer and return */ - FREEA(unicode_text); - return(textbuf); -} - -/* Convert the UTF-8 text to UNICODE and render it -*/ -SDL_Surface *TTF_RenderUTF8_Blended(TTF_Font *font, - const char *text, SDL_Color fg) -{ - SDL_Surface *textbuf; - Uint16 *unicode_text; - int unicode_len; - - /* Copy the UTF-8 text to a UNICODE text buffer */ - unicode_len = strlen(text); - unicode_text = (Uint16 *)ALLOCA((1+unicode_len+1)*(sizeof *unicode_text)); - if ( unicode_text == NULL ) { - TTF_SetError("Out of memory"); - return(NULL); - } - *unicode_text = UNICODE_BOM_NATIVE; - UTF8_to_UNICODE(unicode_text+1, text, unicode_len); - - /* Render the new text */ - textbuf = TTF_RenderUNICODE_Blended(font, unicode_text, fg); - - /* Free the text buffer and return */ - FREEA(unicode_text); - return(textbuf); -} - -SDL_Surface *TTF_RenderUNICODE_Blended(TTF_Font *font, - const Uint16 *text, SDL_Color fg) -{ - int xstart; - int width, height; - SDL_Surface *textbuf; - Uint32 alpha; - Uint32 pixel; - const Uint16 *ch; - Uint8 *src; - Uint32 *dst; - Uint32 *dst_check; - int swapped; - int row, col; - c_glyph *glyph; - FT_Error error; - FT_Long use_kerning; - FT_UInt prev_index = 0; - - /* Get the dimensions of the text surface */ - if ( (TTF_SizeUNICODE(font, text, &width, &height) < 0) || !width ) { - TTF_SetError("Text has zero width"); - return(NULL); - } - - /* Create the target surface */ - textbuf = SDL_AllocSurface(SDL_SWSURFACE, width, height, 32, - 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); - if ( textbuf == NULL ) { - return(NULL); - } - - /* Adding bound checking to avoid all kinds of memory corruption errors - that may occur. */ - dst_check = (Uint32*)textbuf->pixels + textbuf->pitch/4 * textbuf->h; - - /* check kerning */ - use_kerning = FT_HAS_KERNING( font->face ) && font->kerning; - - /* Load and render each character */ - xstart = 0; - swapped = TTF_byteswapped; - pixel = (fg.r<<16)|(fg.g<<8)|fg.b; - SDL_FillRect(textbuf, NULL, pixel); /* Initialize with fg and 0 alpha */ - - for ( ch=text; *ch; ++ch ) { - Uint16 c = *ch; - if ( c == UNICODE_BOM_NATIVE ) { - swapped = 0; - if ( text == ch ) { - ++text; - } - continue; - } - if ( c == UNICODE_BOM_SWAPPED ) { - swapped = 1; - if ( text == ch ) { - ++text; - } - continue; - } - if ( swapped ) { - c = SDL_Swap16(c); - } - error = Find_Glyph(font, c, CACHED_METRICS|CACHED_PIXMAP); - if( error ) { - SDL_FreeSurface( textbuf ); - return NULL; - } - glyph = font->current; - /* Ensure the width of the pixmap is correct. On some cases, - * freetype may report a larger pixmap than possible.*/ - width = glyph->pixmap.width; - if (font->outline <= 0 && width > glyph->maxx - glyph->minx) { - width = glyph->maxx - glyph->minx; - } - /* do kerning, if possible AC-Patch */ - if ( use_kerning && prev_index && glyph->index ) { - FT_Vector delta; - FT_Get_Kerning( font->face, prev_index, glyph->index, ft_kerning_default, &delta ); - xstart += delta.x >> 6; - } - - /* Compensate for the wrap around bug with negative minx's */ - if ( (ch == text) && (glyph->minx < 0) ) { - xstart -= glyph->minx; - } - - for ( row = 0; row < glyph->pixmap.rows; ++row ) { - /* Make sure we don't go either over, or under the - * limit */ - if ( row+glyph->yoffset < 0 ) { - continue; - } - if ( row+glyph->yoffset >= textbuf->h ) { - continue; - } - dst = (Uint32*) textbuf->pixels + - (row+glyph->yoffset) * textbuf->pitch/4 + - xstart + glyph->minx; - - /* Added code to adjust src pointer for pixmaps to - * account for pitch. - * */ - src = (Uint8*) (glyph->pixmap.buffer + glyph->pixmap.pitch * row); - for ( col = width; col>0 && dst < dst_check; --col) { - alpha = *src++; - *dst++ |= pixel | (alpha << 24); - } - } - - xstart += glyph->advance; - if ( TTF_HANDLE_STYLE_BOLD(font) ) { - xstart += font->glyph_overhang; - } - prev_index = glyph->index; - } - - /* Handle the underline style */ - if( TTF_HANDLE_STYLE_UNDERLINE(font) ) { - row = TTF_underline_top_row(font); - TTF_drawLine_Blended(font, textbuf, row, pixel); - } - - /* Handle the strikethrough style */ - if( TTF_HANDLE_STYLE_STRIKETHROUGH(font) ) { - row = TTF_strikethrough_top_row(font); - TTF_drawLine_Blended(font, textbuf, row, pixel); - } - return(textbuf); -} - -SDL_Surface *TTF_RenderGlyph_Blended(TTF_Font *font, Uint16 ch, SDL_Color fg) -{ - SDL_Surface *textbuf; - Uint32 alpha; - Uint32 pixel; - Uint8 *src; - Uint32 *dst; - int row, col; - FT_Error error; - c_glyph *glyph; - - /* Get the glyph itself */ - error = Find_Glyph(font, ch, CACHED_METRICS|CACHED_PIXMAP); - if ( error ) { - return(NULL); - } - glyph = font->current; - - textbuf = SDL_CreateRGBSurface(SDL_SWSURFACE, - glyph->pixmap.width, glyph->pixmap.rows, 32, - 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); - if ( ! textbuf ) { - return(NULL); - } - - /* Copy the character from the pixmap */ - pixel = (fg.r<<16)|(fg.g<<8)|fg.b; - SDL_FillRect(textbuf, NULL, pixel); /* Initialize with fg and 0 alpha */ - - for ( row=0; rowh; ++row ) { - /* Changed src to take pitch into account, not just width */ - src = glyph->pixmap.buffer + row * glyph->pixmap.pitch; - dst = (Uint32 *)textbuf->pixels + row * textbuf->pitch/4; - for ( col=0; colpixmap.width; ++col ) { - alpha = *src++; - *dst++ = pixel | (alpha << 24); - } - } - - /* Handle the underline style */ - if( TTF_HANDLE_STYLE_UNDERLINE(font) ) { - row = TTF_underline_top_row(font); - TTF_drawLine_Blended(font, textbuf, row, pixel); - } - - /* Handle the strikethrough style */ - if( TTF_HANDLE_STYLE_STRIKETHROUGH(font) ) { - row = TTF_strikethrough_top_row(font); - TTF_drawLine_Blended(font, textbuf, row, pixel); - } - return(textbuf); -} - -void TTF_SetFontStyle( TTF_Font* font, int style ) -{ - int prev_style = font->style; - font->style = style | font->face_style; - - /* Flush the cache if the style has changed. - * Ignore UNDERLINE which does not impact glyph drawning. - * */ - if ( (font->style | TTF_STYLE_NO_GLYPH_CHANGE ) != ( prev_style | TTF_STYLE_NO_GLYPH_CHANGE )) { - Flush_Cache( font ); - } -} - -int TTF_GetFontStyle( const TTF_Font* font ) -{ - return font->style; -} - -void TTF_SetFontOutline( TTF_Font* font, int outline ) -{ - font->outline = outline; - Flush_Cache( font ); -} - -int TTF_GetFontOutline( const TTF_Font* font ) -{ - return font->outline; -} - -void TTF_SetFontHinting( TTF_Font* font, int hinting ) -{ - if (hinting == TTF_HINTING_LIGHT) - font->hinting = FT_LOAD_TARGET_LIGHT; - else if (hinting == TTF_HINTING_MONO) - font->hinting = FT_LOAD_TARGET_MONO; - else if (hinting == TTF_HINTING_NONE) - font->hinting = FT_LOAD_NO_HINTING; - else - font->hinting = 0; - Flush_Cache( font ); -} - -int TTF_GetFontHinting( const TTF_Font* font ) -{ - return font->hinting; -} - -void TTF_Quit( void ) -{ - if ( TTF_initialized ) { - if ( --TTF_initialized == 0 ) { - FT_Done_FreeType( library ); - } - } -} - -int TTF_WasInit( void ) -{ - return TTF_initialized; -} diff --git a/src/helper/SDL_ttf/SDL_ttf.h b/src/helper/SDL_ttf/SDL_ttf.h deleted file mode 100644 index 79c1445d7..000000000 --- a/src/helper/SDL_ttf/SDL_ttf.h +++ /dev/null @@ -1,249 +0,0 @@ -/* - SDL_ttf: A companion library to SDL for working with TrueType (tm) fonts - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ - -/* $Id: SDL_ttf.h 5122 2009-10-17 18:16:33Z slouken $ */ - -/* This library is a wrapper around the excellent FreeType 2.0 library, - available at: - http://www.freetype.org/ -*/ - -#ifndef _SDL_TTF_H -#define _SDL_TTF_H - -#include -#include - -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL -*/ -#define SDL_TTF_MAJOR_VERSION 2 -#define SDL_TTF_MINOR_VERSION 0 -#define SDL_TTF_PATCHLEVEL 10 - -/* This macro can be used to fill a version structure with the compile-time - * version of the SDL_ttf library. - */ -#define SDL_TTF_VERSION(X) \ -{ \ - (X)->major = SDL_TTF_MAJOR_VERSION; \ - (X)->minor = SDL_TTF_MINOR_VERSION; \ - (X)->patch = SDL_TTF_PATCHLEVEL; \ -} - -/* Backwards compatibility */ -#define TTF_MAJOR_VERSION SDL_TTF_MAJOR_VERSION -#define TTF_MINOR_VERSION SDL_TTF_MINOR_VERSION -#define TTF_PATCHLEVEL SDL_TTF_PATCHLEVEL -#define TTF_VERSION(X) SDL_TTF_VERSION(X) - -/* This function gets the version of the dynamically linked SDL_ttf library. - it should NOT be used to fill a version structure, instead you should - use the SDL_TTF_VERSION() macro. - */ -extern DECLSPEC const SDL_version * SDLCALL TTF_Linked_Version(void); - -/* ZERO WIDTH NO-BREAKSPACE (Unicode byte order mark) */ -#define UNICODE_BOM_NATIVE 0xFEFF -#define UNICODE_BOM_SWAPPED 0xFFFE - -/* This function tells the library whether UNICODE text is generally - byteswapped. A UNICODE BOM character in a string will override - this setting for the remainder of that string. -*/ -extern DECLSPEC void SDLCALL TTF_ByteSwappedUNICODE(int swapped); - -/* The internal structure containing font information */ -typedef struct _TTF_Font TTF_Font; - -/* Initialize the TTF engine - returns 0 if successful, -1 on error */ -extern DECLSPEC int SDLCALL TTF_Init(void); - -/* Open a font file and create a font of the specified point size. - * Some .fon fonts will have several sizes embedded in the file, so the - * point size becomes the index of choosing which size. If the value - * is too high, the last indexed size will be the default. */ -extern DECLSPEC TTF_Font * SDLCALL TTF_OpenFont(const char *file, int ptsize); -extern DECLSPEC TTF_Font * SDLCALL TTF_OpenFontIndex(const char *file, int ptsize, long index); -extern DECLSPEC TTF_Font * SDLCALL TTF_OpenFontRW(SDL_RWops *src, int freesrc, int ptsize); -extern DECLSPEC TTF_Font * SDLCALL TTF_OpenFontIndexRW(SDL_RWops *src, int freesrc, int ptsize, long index); - -/* Set and retrieve the font style */ -#define TTF_STYLE_NORMAL 0x00 -#define TTF_STYLE_BOLD 0x01 -#define TTF_STYLE_ITALIC 0x02 -#define TTF_STYLE_UNDERLINE 0x04 -#define TTF_STYLE_STRIKETHROUGH 0x08 -extern DECLSPEC int SDLCALL TTF_GetFontStyle(const TTF_Font *font); -extern DECLSPEC void SDLCALL TTF_SetFontStyle(TTF_Font *font, int style); -extern DECLSPEC int SDLCALL TTF_GetFontOutline(const TTF_Font *font); -extern DECLSPEC void SDLCALL TTF_SetFontOutline(TTF_Font *font, int outline); - -/* Set and retrieve FreeType hinter settings */ -#define TTF_HINTING_NORMAL 0 -#define TTF_HINTING_LIGHT 1 -#define TTF_HINTING_MONO 2 -#define TTF_HINTING_NONE 3 -extern DECLSPEC int SDLCALL TTF_GetFontHinting(const TTF_Font *font); -extern DECLSPEC void SDLCALL TTF_SetFontHinting(TTF_Font *font, int hinting); - -/* Get the total height of the font - usually equal to point size */ -extern DECLSPEC int SDLCALL TTF_FontHeight(const TTF_Font *font); - -/* Get the offset from the baseline to the top of the font - This is a positive value, relative to the baseline. - */ -extern DECLSPEC int SDLCALL TTF_FontAscent(const TTF_Font *font); - -/* Get the offset from the baseline to the bottom of the font - This is a negative value, relative to the baseline. - */ -extern DECLSPEC int SDLCALL TTF_FontDescent(const TTF_Font *font); - -/* Get the recommended spacing between lines of text for this font */ -extern DECLSPEC int SDLCALL TTF_FontLineSkip(const TTF_Font *font); - -/* Get/Set whether or not kerning is allowed for this font */ -extern DECLSPEC int SDLCALL TTF_GetFontKerning(const TTF_Font *font); -extern DECLSPEC void SDLCALL TTF_SetFontKerning(TTF_Font *font, int allowed); - -/* Get the number of faces of the font */ -extern DECLSPEC long SDLCALL TTF_FontFaces(const TTF_Font *font); - -/* Get the font face attributes, if any */ -extern DECLSPEC int SDLCALL TTF_FontFaceIsFixedWidth(const TTF_Font *font); -extern DECLSPEC char * SDLCALL TTF_FontFaceFamilyName(const TTF_Font *font); -extern DECLSPEC char * SDLCALL TTF_FontFaceStyleName(const TTF_Font *font); - -/* Check wether a glyph is provided by the font or not */ -extern DECLSPEC int SDLCALL TTF_GlyphIsProvided(const TTF_Font *font, Uint16 ch); - -/* Get the metrics (dimensions) of a glyph - To understand what these metrics mean, here is a useful link: - http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html - */ -extern DECLSPEC int SDLCALL TTF_GlyphMetrics(TTF_Font *font, Uint16 ch, - int *minx, int *maxx, - int *miny, int *maxy, int *advance); - -/* Get the dimensions of a rendered string of text */ -extern DECLSPEC int SDLCALL TTF_SizeText(TTF_Font *font, const char *text, int *w, int *h); -extern DECLSPEC int SDLCALL TTF_SizeUTF8(TTF_Font *font, const char *text, int *w, int *h); -extern DECLSPEC int SDLCALL TTF_SizeUNICODE(TTF_Font *font, const Uint16 *text, int *w, int *h); - -/* Create an 8-bit palettized surface and render the given text at - fast quality with the given font and color. The 0 pixel is the - colorkey, giving a transparent background, and the 1 pixel is set - to the text color. - This function returns the new surface, or NULL if there was an error. -*/ -extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Solid(TTF_Font *font, - const char *text, SDL_Color fg); -extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUTF8_Solid(TTF_Font *font, - const char *text, SDL_Color fg); -extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUNICODE_Solid(TTF_Font *font, - const Uint16 *text, SDL_Color fg); - -/* Create an 8-bit palettized surface and render the given glyph at - fast quality with the given font and color. The 0 pixel is the - colorkey, giving a transparent background, and the 1 pixel is set - to the text color. The glyph is rendered without any padding or - centering in the X direction, and aligned normally in the Y direction. - This function returns the new surface, or NULL if there was an error. -*/ -extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Solid(TTF_Font *font, - Uint16 ch, SDL_Color fg); - -/* Create an 8-bit palettized surface and render the given text at - high quality with the given font and colors. The 0 pixel is background, - while other pixels have varying degrees of the foreground color. - This function returns the new surface, or NULL if there was an error. -*/ -extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Shaded(TTF_Font *font, - const char *text, SDL_Color fg, SDL_Color bg); -extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUTF8_Shaded(TTF_Font *font, - const char *text, SDL_Color fg, SDL_Color bg); -extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUNICODE_Shaded(TTF_Font *font, - const Uint16 *text, SDL_Color fg, SDL_Color bg); - -/* Create an 8-bit palettized surface and render the given glyph at - high quality with the given font and colors. The 0 pixel is background, - while other pixels have varying degrees of the foreground color. - The glyph is rendered without any padding or centering in the X - direction, and aligned normally in the Y direction. - This function returns the new surface, or NULL if there was an error. -*/ -extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Shaded(TTF_Font *font, - Uint16 ch, SDL_Color fg, SDL_Color bg); - -/* Create a 32-bit ARGB surface and render the given text at high quality, - using alpha blending to dither the font with the given color. - This function returns the new surface, or NULL if there was an error. -*/ -extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Blended(TTF_Font *font, - const char *text, SDL_Color fg); -extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUTF8_Blended(TTF_Font *font, - const char *text, SDL_Color fg); -extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUNICODE_Blended(TTF_Font *font, - const Uint16 *text, SDL_Color fg); - -/* Create a 32-bit ARGB surface and render the given glyph at high quality, - using alpha blending to dither the font with the given color. - The glyph is rendered without any padding or centering in the X - direction, and aligned normally in the Y direction. - This function returns the new surface, or NULL if there was an error. -*/ -extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Blended(TTF_Font *font, - Uint16 ch, SDL_Color fg); - -/* For compatibility with previous versions, here are the old functions */ -#define TTF_RenderText(font, text, fg, bg) \ - TTF_RenderText_Shaded(font, text, fg, bg) -#define TTF_RenderUTF8(font, text, fg, bg) \ - TTF_RenderUTF8_Shaded(font, text, fg, bg) -#define TTF_RenderUNICODE(font, text, fg, bg) \ - TTF_RenderUNICODE_Shaded(font, text, fg, bg) - -/* Close an opened font file */ -extern DECLSPEC void SDLCALL TTF_CloseFont(TTF_Font *font); - -/* De-initialize the TTF engine */ -extern DECLSPEC void SDLCALL TTF_Quit(void); - -/* Check if the TTF engine is initialized */ -extern DECLSPEC int SDLCALL TTF_WasInit(void); - -/* We'll use SDL for reporting errors */ -#define TTF_SetError SDL_SetError -#define TTF_GetError SDL_GetError - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif -#include - -#endif /* _SDL_TTF_H */ diff --git a/src/helper/SOIL/stb_image.c b/src/helper/SOIL/stb_image.c index 1655d0ae3..6d6e14f66 100644 --- a/src/helper/SOIL/stb_image.c +++ b/src/helper/SOIL/stb_image.c @@ -2901,8 +2901,8 @@ static stbi_uc *tga_load(stbi *s, int *x, int *y, int *comp, int req_comp) unsigned char *tga_data; unsigned char *tga_palette = NULL; int i, j; - unsigned char raw_data[4]; - unsigned char trans_data[4]; + unsigned char raw_data[4] = { 0, 0, 0, 0 }; + unsigned char trans_data[4] = { 0, 0, 0, 0 }; int RLE_count = 0; int RLE_repeating = 0; int read_next_pixel = 1; diff --git a/src/helper/haikuttf/haikuttf.hpp b/src/helper/haikuttf/haikuttf.hpp new file mode 100644 index 000000000..e14a49912 --- /dev/null +++ b/src/helper/haikuttf/haikuttf.hpp @@ -0,0 +1,9 @@ +#ifndef HAIKUTTF_HPP +#define HAIKUTTF_HPP + +#include "hkbase.hpp" +#include "hkglyph.hpp" +#include "hkfont.hpp" +#include "hkfontmanager.hpp" + +#endif diff --git a/src/helper/haikuttf/hkbase.hpp b/src/helper/haikuttf/hkbase.hpp new file mode 100644 index 000000000..8132b6b12 --- /dev/null +++ b/src/helper/haikuttf/hkbase.hpp @@ -0,0 +1,63 @@ +#ifndef HAIKUTTF_HKBASE_HPP +#define HAIKUTTF_HKBASE_HPP + +#include +#include + +#ifdef _MSC_VER +#include "stdint.h" +#else +#include +#endif + +#include +#include FT_FREETYPE_H +#include FT_OUTLINE_H +#include FT_STROKER_H +#include FT_GLYPH_H +#include FT_TRUETYPE_IDS_H + +#define NUM_GRAYS 256 + +#define FT_FLOOR(X) ( ( X & -64 ) / 64 ) +#define FT_CEIL(X) ( ( ( X + 63) & -64 ) / 64 ) + +#define CACHED_METRICS 0x10 +#define CACHED_BITMAP 0x01 +#define CACHED_PIXMAP 0x02 + +namespace HaikuTTF { + using namespace std; +} + +/* Handle a style only if the font does not already handle it */ +#define TTF_HANDLE_STYLE_BOLD(font) ( ( (font)->Style() & TTF_STYLE_BOLD ) && !( (font)->FaceStyle() & TTF_STYLE_BOLD ) ) +#define TTF_HANDLE_STYLE_ITALIC(font) ( ( (font)->Style() & TTF_STYLE_ITALIC ) && !( (font)->FaceStyle() & TTF_STYLE_ITALIC ) ) +#define TTF_HANDLE_STYLE_UNDERLINE(font) ( (font)->Style() & TTF_STYLE_UNDERLINE ) +#define TTF_HANDLE_STYLE_STRIKETHROUGH(font) ( (font)->Style() & TTF_STYLE_STRIKETHROUGH ) + +/* Font styles that does not impact glyph drawing */ +#define TTF_STYLE_NO_GLYPH_CHANGE (TTF_STYLE_UNDERLINE | TTF_STYLE_STRIKETHROUGH) + +#define hkARRAY_SIZE(__array) ( sizeof(__array) / sizeof(__array[0]) ) +#define hkSAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } +#define hkSAFE_DELETE_ARRAY(p) { if(p) { delete[](p); (p)=NULL; } } + +#define HK_GETSET( __TYPE, __NAME ) \ + protected: \ + __TYPE m##__NAME; \ + public: \ + inline __TYPE __NAME() const { return m##__NAME; } \ + inline void __NAME( __TYPE value ) { m##__NAME = value; } + +#define TTF_STYLE_NORMAL 0x00 +#define TTF_STYLE_BOLD 0x01 +#define TTF_STYLE_ITALIC 0x02 +#define TTF_STYLE_UNDERLINE 0x04 +#define TTF_STYLE_STRIKETHROUGH 0x08 + +#define TTF_HINTING_NORMAL 0 +#define TTF_HINTING_LIGHT 1 +#define TTF_HINTING_MONO 2 +#define TTF_HINTING_NONE 3 +#endif diff --git a/src/helper/haikuttf/hkfont.cpp b/src/helper/haikuttf/hkfont.cpp new file mode 100644 index 000000000..770087c5f --- /dev/null +++ b/src/helper/haikuttf/hkfont.cpp @@ -0,0 +1,501 @@ +#include "hkfont.hpp" +#include "hkfontmanager.hpp" + +namespace HaikuTTF { + +hkFont::hkFont( hkFontManager * FontManager, unsigned int CacheSize ) : + mFace(NULL), + mHeight(0), + mAscent(0), + mDescent(0), + mLineSkip(0), + mFaceStyle(0), + mKerning(0), + mGlyphOverhang(0), + mGlyphItalics(0), + mUnderlineOffset(0), + mUnderlineHeight(0), + mCurrent(NULL), + mFontSizeFamily(0), + mFm(NULL), + mCache(NULL), + mStyle(0), + mOutline(0), + mHinting(0) +{ + mFm = FontManager; + + mCacheSize = CacheSize; + mCache.resize( mCacheSize ); +} + +hkFont::~hkFont() { + mCache.clear(); +} + +void hkFont::Outline( int outline ) { + mOutline = outline; + CacheFlush(); +} + +void hkFont::Hinting( int hinting ) { + if (hinting == TTF_HINTING_LIGHT) + mHinting = FT_LOAD_TARGET_LIGHT; + else if (hinting == TTF_HINTING_MONO) + mHinting= FT_LOAD_TARGET_MONO; + else if (hinting == TTF_HINTING_NONE) + mHinting = FT_LOAD_NO_HINTING; + else + mHinting = 0; + + CacheFlush(); +} + +void hkFont::Style( int style ) { + int prev_style = mFaceStyle; + mStyle = style | mFaceStyle; + + if ( ( mStyle | TTF_STYLE_NO_GLYPH_CHANGE ) != ( prev_style | TTF_STYLE_NO_GLYPH_CHANGE ) ) + CacheFlush(); +} + +int hkFont::UnderlineTopRow() { + return mAscent - mUnderlineOffset - 1; +} + +int hkFont::StrikeThroughTopRow() { + return mHeight / 2; +} + +void hkFont::CacheFlush() { + for( int i = 0; i < (int)mCacheSize; ++i ) { + if( mCache[i].Cached() ) + mCache[i].Flush(); + } + + if( mScratch.Cached() ) + mScratch.Flush(); +} + +FT_Error hkFont::GlyphFind( uint16_t ch, int want ) { + int retval = 0; + + if( ch < mCacheSize ) { + mCurrent = &mCache[ch]; + } else { + if ( mScratch.Cached() != ch ) + mScratch.Flush(); + + mCurrent = &mScratch; + } + + if ( ( mCurrent->Stored() & want) != want ) + retval = GlyphLoad( ch, mCurrent, want ); + + return retval; +} + +FT_Error hkFont::GlyphLoad( uint16_t ch, hkGlyph * cached, int want ) { + FT_Face face; + FT_Error error; + FT_GlyphSlot glyph; + FT_Glyph_Metrics* metrics; + FT_Outline* outline; + + if ( NULL == mFace ) + return FT_Err_Invalid_Handle; + + face = mFace; + + if ( !cached->Index() ) + cached->Index( FT_Get_Char_Index( face, ch ) ); + + error = FT_Load_Glyph( face, cached->Index(), FT_LOAD_DEFAULT | mHinting ); + + if( error ) + return error; + + glyph = face->glyph; + metrics = &glyph->metrics; + outline = &glyph->outline; + + if ( ( want & CACHED_METRICS ) && !( cached->Stored() & CACHED_METRICS ) ) { + if ( FT_IS_SCALABLE( face ) ) { + cached->MinX( FT_FLOOR( metrics->horiBearingX ) ); + cached->MaxX( cached->MinX() + FT_CEIL( metrics->width ) ); + cached->MaxY( FT_FLOOR( metrics->horiBearingY ) ); + cached->MinY( cached->MaxY() - FT_CEIL( metrics->height ) ); + cached->OffsetY( mAscent - cached->MaxY() ); + cached->Advance( FT_CEIL( metrics->horiAdvance ) ); + } else { + cached->MinX( FT_FLOOR( metrics->horiBearingX ) ); + cached->MaxX( cached->MinX() + FT_CEIL( metrics->horiAdvance ) ); + cached->MaxY( FT_FLOOR( metrics->horiBearingY ) ); + cached->MinY( cached->MaxY() - FT_CEIL( face->available_sizes[ mFontSizeFamily ].height ) ); + cached->OffsetY( 0 ); + cached->Advance( FT_CEIL( metrics->horiAdvance ) ); + } + + if( TTF_HANDLE_STYLE_BOLD(this) ) + cached->MaxX( cached->MaxX() + mGlyphOverhang ); + + if( TTF_HANDLE_STYLE_ITALIC(this) ) + cached->MaxX( cached->MaxX() + (int)ceil( mGlyphItalics ) ); + + cached->Stored( cached->Stored() | CACHED_METRICS ); + } + + if ( ( ( want & CACHED_BITMAP ) && !( cached->Stored() & CACHED_BITMAP ) ) || ( ( want & CACHED_PIXMAP ) && !( cached->Stored() & CACHED_PIXMAP) ) ) { + int mono = ( want & CACHED_BITMAP ); + int i; + FT_Bitmap* src; + FT_Bitmap* dst; + FT_Glyph bitmap_glyph = NULL; + + if( TTF_HANDLE_STYLE_ITALIC(this) ) { + FT_Matrix shear; + + shear.xx = 1 << 16; + shear.xy = (int) ( mGlyphItalics * ( 1 << 16 ) ) / mHeight; + shear.yx = 0; + shear.yy = 1 << 16; + + FT_Outline_Transform( outline, &shear ); + } + + if( ( mOutline > 0 ) && glyph->format != FT_GLYPH_FORMAT_BITMAP ) { + FT_Stroker stroker; + FT_Get_Glyph( glyph, &bitmap_glyph ); + + error = FT_Stroker_New( mFm->Library(), &stroker ); + + if( error ) + return error; + + FT_Stroker_Set( stroker, mOutline * 64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0 ); + FT_Glyph_Stroke( &bitmap_glyph, stroker, 1 ); + FT_Stroker_Done( stroker ); + + error = FT_Glyph_To_Bitmap( &bitmap_glyph, mono ? ft_render_mode_mono : ft_render_mode_normal, 0, 1 ); + + if( error ) { + FT_Done_Glyph( bitmap_glyph ); + return error; + } + + src = &((FT_BitmapGlyph)bitmap_glyph)->bitmap; + } else { + error = FT_Render_Glyph( glyph, mono ? ft_render_mode_mono : ft_render_mode_normal ); + + if( error ) + return error; + + src = &glyph->bitmap; + } + + if ( mono ) { + dst = cached->Bitmap(); + } else { + dst = cached->Pixmap(); + } + + memcpy( dst, src, sizeof( *dst ) ); + + if ( src->pixel_mode == FT_PIXEL_MODE_MONO ) { + dst->pitch *= 8; + } else if ( src->pixel_mode == FT_PIXEL_MODE_GRAY2 ) { + dst->pitch *= 4; + } else if ( src->pixel_mode == FT_PIXEL_MODE_GRAY4 ) { + dst->pitch *= 2; + } + + if( TTF_HANDLE_STYLE_BOLD(this) ) { + int bump = mGlyphOverhang; + dst->pitch += bump; + dst->width += bump; + } + + if( TTF_HANDLE_STYLE_ITALIC(this) ) { + int bump = (int)ceil( mGlyphItalics ); + dst->pitch += bump; + dst->width += bump; + } + + if (dst->rows != 0) { + dst->buffer = (unsigned char *)malloc( dst->pitch * dst->rows ); + + if( !dst->buffer ) { + return FT_Err_Out_Of_Memory; + } + memset( dst->buffer, 0, dst->pitch * dst->rows ); + + for( i = 0; i < src->rows; i++ ) { + int soffset = i * src->pitch; + int doffset = i * dst->pitch; + + if ( mono ) { + unsigned char *srcp = src->buffer + soffset; + unsigned char *dstp = dst->buffer + doffset; + int j; + if ( src->pixel_mode == FT_PIXEL_MODE_MONO ) { + for ( j = 0; j < src->width; j += 8 ) { + unsigned char ch = *srcp++; + *dstp++ = (ch&0x80) >> 7; + ch <<= 1; + *dstp++ = (ch&0x80) >> 7; + ch <<= 1; + *dstp++ = (ch&0x80) >> 7; + ch <<= 1; + *dstp++ = (ch&0x80) >> 7; + ch <<= 1; + *dstp++ = (ch&0x80) >> 7; + ch <<= 1; + *dstp++ = (ch&0x80) >> 7; + ch <<= 1; + *dstp++ = (ch&0x80) >> 7; + ch <<= 1; + *dstp++ = (ch&0x80) >> 7; + } + } else if ( src->pixel_mode == FT_PIXEL_MODE_GRAY2 ) { + for ( j = 0; j < src->width; j += 4 ) { + unsigned char ch = *srcp++; + *dstp++ = (((ch&0xA0) >> 6) >= 0x2) ? 1 : 0; + ch <<= 2; + *dstp++ = (((ch&0xA0) >> 6) >= 0x2) ? 1 : 0; + ch <<= 2; + *dstp++ = (((ch&0xA0) >> 6) >= 0x2) ? 1 : 0; + ch <<= 2; + *dstp++ = (((ch&0xA0) >> 6) >= 0x2) ? 1 : 0; + } + } else if ( src->pixel_mode == FT_PIXEL_MODE_GRAY4 ) { + for ( j = 0; j < src->width; j += 2 ) { + unsigned char ch = *srcp++; + *dstp++ = (((ch&0xF0) >> 4) >= 0x8) ? 1 : 0; + ch <<= 4; + *dstp++ = (((ch&0xF0) >> 4) >= 0x8) ? 1 : 0; + } + } else { + for ( j = 0; j < src->width; j++ ) { + unsigned char ch = *srcp++; + *dstp++ = (ch >= 0x80) ? 1 : 0; + } + } + } else if ( src->pixel_mode == FT_PIXEL_MODE_MONO ) { + unsigned char *srcp = src->buffer + soffset; + unsigned char *dstp = dst->buffer + doffset; + unsigned char ch; + int j, k; + for ( j = 0; j < src->width; j += 8) { + ch = *srcp++; + for (k = 0; k < 8; ++k) { + if ((ch&0x80) >> 7) { + *dstp++ = NUM_GRAYS - 1; + } else { + *dstp++ = 0x00; + } + ch <<= 1; + } + } + } else if ( src->pixel_mode == FT_PIXEL_MODE_GRAY2 ) { + unsigned char *srcp = src->buffer + soffset; + unsigned char *dstp = dst->buffer + doffset; + unsigned char ch; + int j, k; + for ( j = 0; j < src->width; j += 4 ) { + ch = *srcp++; + for ( k = 0; k < 4; ++k ) { + if ((ch&0xA0) >> 6) { + *dstp++ = NUM_GRAYS * ((ch&0xA0) >> 6) / 3 - 1; + } else { + *dstp++ = 0x00; + } + ch <<= 2; + } + } + } else if ( src->pixel_mode == FT_PIXEL_MODE_GRAY4 ) { + unsigned char *srcp = src->buffer + soffset; + unsigned char *dstp = dst->buffer + doffset; + unsigned char ch; + int j, k; + for ( j = 0; j < src->width; j += 2 ) { + ch = *srcp++; + for ( k = 0; k < 2; ++k ) { + if ((ch&0xF0) >> 4) { + *dstp++ = NUM_GRAYS * ((ch&0xF0) >> 4) / 15 - 1; + } else { + *dstp++ = 0x00; + } + ch <<= 4; + } + } + } else { + memcpy(dst->buffer+doffset, + src->buffer+soffset, src->pitch); + } + } + } + + if ( TTF_HANDLE_STYLE_BOLD(this) ) { + int row; + int col; + int offset; + int pixel; + uint8_t* pixmap; + + for( row = dst->rows - 1; row >= 0; --row ) { + pixmap = (uint8_t*) dst->buffer + row * dst->pitch; + for( offset=1; offset <= mGlyphOverhang; ++offset ) { + for( col = dst->width - 1; col > 0; --col ) { + if( mono ) { + pixmap[col] |= pixmap[col-1]; + } else { + pixel = (pixmap[col] + pixmap[col-1]); + if( pixel > NUM_GRAYS - 1 ) { + pixel = NUM_GRAYS - 1; + } + pixmap[col] = (uint8_t) pixel; + } + } + } + } + } + + if ( mono ) { + cached->Stored( cached->Stored() | CACHED_BITMAP ); + } else { + cached->Stored( cached->Stored() | CACHED_PIXMAP ); + } + + if( bitmap_glyph ) { + FT_Done_Glyph( bitmap_glyph ); + } + } + + cached->Cached( ch ); + + return 0; +} + +unsigned char * hkFont::GlyphRender( uint16_t ch, uint32_t fg ) { + unsigned char * textbuf = NULL; + int row; + FT_Error error; + hkGlyph *glyph; + FT_Bitmap * bitmap; + + error = GlyphFind( ch, CACHED_METRICS | CACHED_PIXMAP ); + + if ( error ) + return(NULL); + + glyph = mCurrent; + bitmap = glyph->Pixmap(); + + textbuf = new unsigned char[ bitmap->width * bitmap->rows * 4 ]; + + if ( NULL == textbuf ) + return NULL; + + uint32_t * buffu32 = reinterpret_cast ( &textbuf[0] ); + + memset( buffu32, fg, bitmap->width * bitmap->rows ); + + const uint8_t* pixels = bitmap->buffer; + + for ( int y = 0; y < bitmap->rows; y++ ) { + for ( int x = 0; x < bitmap->width; x++ ) { + uint32_t index = (x + y * bitmap->width) * 4 + 3; + + textbuf[ index ] = pixels[ x ]; + } + + pixels += bitmap->pitch; + } + + if( TTF_HANDLE_STYLE_UNDERLINE(this) ) { + row = UnderlineTopRow(); + DrawLine( textbuf, row, fg, bitmap ); + } + + if( TTF_HANDLE_STYLE_STRIKETHROUGH(this) ) { + row = StrikeThroughTopRow(); + DrawLine( textbuf, row, fg, bitmap ); + } + + return textbuf; +} + +int hkFont::GlyphMetrics( uint16_t ch, int* minx, int* maxx, int* miny, int* maxy, int* advance ) { + FT_Error error; + + error = GlyphFind( ch, CACHED_METRICS ); + + if ( error ) + return -1; + + if ( NULL != minx ) + *minx = mCurrent->MinX(); + + if ( NULL !=maxx ) { + *maxx = mCurrent->MaxX(); + + if( TTF_HANDLE_STYLE_BOLD(this) ) + *maxx += mGlyphOverhang; + } + + if ( NULL !=miny ) + *miny = mCurrent->MinY(); + + if ( NULL !=maxy ) + *maxy = mCurrent->MaxY(); + + if ( advance ) { + *advance = mCurrent->Advance(); + + if( TTF_HANDLE_STYLE_BOLD(this) ) + *advance += mGlyphOverhang; + } + + return 0; +} + +void hkFont::InitLineMectrics( const unsigned char * textbuf, const int row, uint8_t **pdst, int *pheight, FT_Bitmap * bitmap ) { + uint8_t *dst; + int height; + + dst = (uint8_t *)textbuf; + + if( row > 0 ) + dst += row * bitmap->pitch; + + height = mUnderlineHeight; + + if( mOutline > 0 ) + height += mOutline * 2; + + *pdst = dst; + *pheight = height; +} + +void hkFont::DrawLine( const unsigned char * textbuf, const int row, const uint32_t color, FT_Bitmap * bitmap ) { + int line; + uint32_t * dst_check = (uint32_t*)textbuf + bitmap->pitch / 4 * bitmap->rows; + uint8_t * dst8; /* destination, byte version */ + uint32_t * dst; + int height; + int col; + + uint32_t pixel = color | 0xFF000000; + + InitLineMectrics( textbuf, row, &dst8, &height, bitmap ); + dst = (uint32_t *) dst8; + + for ( line = height; line > 0 && dst < dst_check; --line ) { + for ( col = 0; col < bitmap->width; ++col ) + dst[col] = pixel; + + dst += bitmap->pitch / 4; + } +} + +} diff --git a/src/helper/haikuttf/hkfont.hpp b/src/helper/haikuttf/hkfont.hpp new file mode 100644 index 000000000..4187a136c --- /dev/null +++ b/src/helper/haikuttf/hkfont.hpp @@ -0,0 +1,77 @@ +#ifndef HAIKUTTF_HKFONT_HPP +#define HAIKUTTF_HKFONT_HPP + +#include "hkbase.hpp" +#include "hkglyph.hpp" + +namespace HaikuTTF { + +class hkFontManager; + +class hkFont { + public: + hkFont( hkFontManager * FontManager, unsigned int CacheSize = 256 ); + + ~hkFont(); + + void CacheFlush(); + + HK_GETSET( FT_Face, Face ); + + HK_GETSET( int, Height ); + HK_GETSET( int, Ascent ); + HK_GETSET( int, Descent ); + HK_GETSET( int, LineSkip ); + HK_GETSET( int, FaceStyle ); + + HK_GETSET( int, Kerning ); + + HK_GETSET( int, GlyphOverhang ); + HK_GETSET( float, GlyphItalics ); + + HK_GETSET( int, UnderlineOffset ); + HK_GETSET( int, UnderlineHeight ); + + HK_GETSET( hkGlyph*, Current ); + + HK_GETSET( hkGlyph, Scratch ); + + HK_GETSET( int, FontSizeFamily ); + + void Outline( int outline ); + int Outline() const { return mOutline; } + + void Hinting( int hinting ); + int Hinting() const { return mHinting; } + + void Style( int style ); + int Style() {return mStyle; } + + hkFontManager * Manager() const { return mFm; } + + FT_Error GlyphFind( uint16_t ch, int want ); + + FT_Error GlyphLoad( uint16_t ch, hkGlyph * cached, int want ); + + unsigned char * GlyphRender( uint16_t ch, uint32_t fg ); + + int GlyphMetrics( uint16_t ch, int* minx, int* maxx, int* miny, int* maxy, int* advance ); + protected: + hkFontManager * mFm; + + std::vector mCache; + unsigned int mCacheSize; + + int mStyle; + int mOutline; + int mHinting; + + int UnderlineTopRow(); + int StrikeThroughTopRow(); + void DrawLine( const unsigned char * textbuf, const int row, const uint32_t color, FT_Bitmap * bitmap ); + void InitLineMectrics( const unsigned char * textbuf, const int row, uint8_t **pdst, int *pheight, FT_Bitmap * bitmap ); +}; + +} + +#endif diff --git a/src/helper/haikuttf/hkfontmanager.cpp b/src/helper/haikuttf/hkfontmanager.cpp new file mode 100644 index 000000000..0a5a1e125 --- /dev/null +++ b/src/helper/haikuttf/hkfontmanager.cpp @@ -0,0 +1,155 @@ +#include "hkfontmanager.hpp" + +namespace HaikuTTF { + +hkFontManager * hkFontManager::mSingleton = 0; + +hkFontManager::hkFontManager() : + mLibrary(NULL), + mInitialized(0) +{ + Init(); +} + +hkFontManager::~hkFontManager() { + Destroy(); +} + +int hkFontManager::Init() { + int status = 0; + + if ( !mInitialized ) { + FT_Error error = FT_Init_FreeType( &mLibrary ); + + if ( error ) + status = -1; + } + + if ( status == 0 ) + ++mInitialized; + + return status; +} + +void hkFontManager::Destroy() { + if ( mInitialized ) { + if ( --mInitialized == 0 ) + FT_Done_FreeType( mLibrary ); + } +} + +int hkFontManager::WasInit() { + return mInitialized; +} + +void hkFontManager::CloseFont( hkFont * Font ) { + if ( NULL != Font ) { + Font->CacheFlush(); + + /*if ( Font->Face() ) { + FT_Done_Face( Font->Face() ); + Font->Face( NULL ); + }*/ + + hkSAFE_DELETE( Font ); + } +} + +hkFont * hkFontManager::OpenFromMemory( const uint8_t* data, unsigned long size, int ptsize, long index, unsigned int glyphCacheSize ) { + if ( Init() != 0) + return NULL; + + FT_Face face = NULL; + + if ( FT_New_Memory_Face( mLibrary, reinterpret_cast(data), static_cast(size), index, &face ) != 0 ) + return NULL; + + if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) != 0 ) + return NULL; + + hkFont * Font = new hkFont( this, glyphCacheSize ); + + Font->Face( face ); + + return FontPrepare( Font, ptsize ); +} + +hkFont * hkFontManager::OpenFromFile( const char* filename, int ptsize, long index, unsigned int glyphCacheSize ) { + if ( Init() != 0) + return NULL; + + FT_Face face; + + if ( FT_New_Face( mLibrary, filename, index, &face ) != 0 ) + return NULL; + + + if ( FT_Select_Charmap(face, FT_ENCODING_UNICODE) != 0 ) + return NULL; + + hkFont * Font = new hkFont( this, glyphCacheSize ); + + Font->Face( face ); + + return FontPrepare( Font, ptsize ); +} + +hkFont * hkFontManager::FontPrepare( hkFont * font, int ptsize ) { + FT_Error error; + FT_Face face; + FT_Fixed scale; + + face = font->Face(); + + if ( FT_IS_SCALABLE( face ) ) { + error = FT_Set_Char_Size( font->Face(), 0, ptsize * 64, 0, 0 ); + + if( error ) { + CloseFont( font ); + return NULL; + } + + scale = face->size->metrics.y_scale; + font->Ascent( FT_CEIL( FT_MulFix( face->ascender, scale) ) ); + font->Descent( FT_CEIL( FT_MulFix( face->descender, scale ) ) ); + font->Height( font->Ascent() - font->Descent() + 1 ); + font->LineSkip( FT_CEIL( FT_MulFix( face->height, scale ) ) ); + font->UnderlineOffset( FT_FLOOR( FT_MulFix( face->underline_position, scale ) ) ); + font->UnderlineHeight( FT_FLOOR( FT_MulFix( face->underline_thickness, scale ) ) ); + } else { + if ( ptsize >= face->num_fixed_sizes ) + ptsize = face->num_fixed_sizes - 1; + + font->FontSizeFamily( ptsize ); + error = FT_Set_Pixel_Sizes( face, face->available_sizes[ptsize].height, face->available_sizes[ptsize].width ); + + font->Ascent( face->available_sizes[ptsize].height ); + font->Descent( 0 ); + font->Height( face->available_sizes[ptsize].height ); + font->LineSkip( FT_CEIL( font->Ascent() ) ); + font->UnderlineOffset( FT_FLOOR( face->underline_position ) ); + font->UnderlineHeight( FT_FLOOR( face->underline_thickness ) ); + } + + if ( font->UnderlineHeight() < 1 ) + font->UnderlineHeight( 1 ); + + font->FaceStyle( TTF_STYLE_NORMAL ); + + if ( face->style_flags & FT_STYLE_FLAG_BOLD ) + font->FaceStyle( font->FaceStyle() | TTF_STYLE_BOLD ); + + if ( face->style_flags & FT_STYLE_FLAG_ITALIC ) + font->FaceStyle( font->FaceStyle() | TTF_STYLE_ITALIC ); + + font->Style( font->FaceStyle() ); + font->Outline( 0 ); + font->Kerning( 1 ); + font->GlyphOverhang( face->size->metrics.y_ppem / 10 ); + font->GlyphItalics( 0.207f ); + font->GlyphItalics( font->GlyphItalics() * font->Height() ); + + return font; +} + +} diff --git a/src/helper/haikuttf/hkfontmanager.hpp b/src/helper/haikuttf/hkfontmanager.hpp new file mode 100644 index 000000000..51f89b6f6 --- /dev/null +++ b/src/helper/haikuttf/hkfontmanager.hpp @@ -0,0 +1,55 @@ +#ifndef HAIKUTTF_HKFONTMANAGER_HPP +#define HAIKUTTF_HKFONTMANAGER_HPP + +#include "hkbase.hpp" +#include "hkglyph.hpp" +#include "hkfont.hpp" + +namespace HaikuTTF { + +class hkFontManager { + static hkFontManager * mSingleton; + public: + static hkFontManager * instance() { + if (mSingleton == 0) + mSingleton = new hkFontManager(); + + return mSingleton; + } + + static void DestroySingleton() { + if( mSingleton != 0 ) { + delete mSingleton; + mSingleton = 0; + } + } + + hkFontManager(); + + ~hkFontManager(); + + int Init(); + + void Destroy(); + + int WasInit(); + + void CloseFont( hkFont * Font ); + + hkFont * OpenFromMemory( const uint8_t* data, unsigned long size, int ptsize, long index = 0, unsigned int glyphCacheSize = 256 ); + + hkFont * OpenFromFile( const char* filename, int ptsize, long index = 0, unsigned int glyphCacheSize = 256 ); + + const FT_Library Library() const { return mLibrary; } + protected: + FT_Library mLibrary; + int mInitialized; + + hkFont * FontPrepare( hkFont * font, int ptsize ); + private: + +}; + +} + +#endif diff --git a/src/helper/haikuttf/hkglyph.cpp b/src/helper/haikuttf/hkglyph.cpp new file mode 100644 index 000000000..84cc61936 --- /dev/null +++ b/src/helper/haikuttf/hkglyph.cpp @@ -0,0 +1,33 @@ +#include "hkglyph.hpp" + +namespace HaikuTTF { + +hkGlyph::hkGlyph() : + mStored(0), + mIndex(0), + mMinX(0), + mMaxX(0), + mMinY(0), + mMaxY(0), + mOffsetY(0), + mAdvance(0), + mCached(0) +{ + memset( &mBitmap, 0, sizeof(mBitmap) ); + memset( &mPixmap, 0, sizeof(mPixmap) ); +} + +hkGlyph::~hkGlyph() { +} + +void hkGlyph::Flush() { + mStored = 0; + mIndex = 0; + + hkSAFE_DELETE_ARRAY( mBitmap.buffer ); + //hkSAFE_DELETE_ARRAY( mPixmap.buffer ); + + mCached = 0; +} + +} diff --git a/src/helper/haikuttf/hkglyph.hpp b/src/helper/haikuttf/hkglyph.hpp new file mode 100644 index 000000000..c8af35c9f --- /dev/null +++ b/src/helper/haikuttf/hkglyph.hpp @@ -0,0 +1,64 @@ +#ifndef HAIKUTTF_HKGLYPH_HPP +#define HAIKUTTF_HKGLYPH_HPP + +#include "hkbase.hpp" + +namespace HaikuTTF { + +class hkGlyph { + public: + hkGlyph(); + + ~hkGlyph(); + + inline int Stored() const { return mStored; } + inline void Stored( int stored ) { mStored = stored; } + + inline FT_UInt Index() const { return mIndex; } + inline void Index( FT_UInt index ) { mIndex = index; } + + inline FT_Bitmap * Bitmap() { return &mBitmap; } + inline void Bitmap( const FT_Bitmap& bitmap ) { mBitmap = bitmap; } + + inline FT_Bitmap * Pixmap() { return &mPixmap; } + inline void Pixmap( const FT_Bitmap& pixmap ) { mPixmap = pixmap; } + + inline int MinX() const { return mMinX; } + inline void MinX( int minx ) { mMinX = minx; } + + inline int MinY() const { return mMinY; } + inline void MinY( int miny ) { mMinY = miny; } + + inline int MaxX() const { return mMaxX; } + inline void MaxX( int maxx ) { mMaxX = maxx; } + + inline int MaxY() const { return mMaxY; } + inline void MaxY( int maxy ) { mMaxY = maxy; } + + inline int OffsetY() const { return mOffsetY; } + inline void OffsetY( int offsety ) { mOffsetY = offsety; } + + inline int Advance() const { return mAdvance; } + inline void Advance( int advance ) { mAdvance = advance; } + + inline uint16_t Cached() const { return mCached; } + inline void Cached( uint16_t cached ) { mCached = cached; } + + void Flush(); + protected: + int mStored; + FT_UInt mIndex; + FT_Bitmap mBitmap; + FT_Bitmap mPixmap; + int mMinX; + int mMaxX; + int mMinY; + int mMaxY; + int mOffsetY; + int mAdvance; + uint16_t mCached; +}; + +} + +#endif diff --git a/src/helper/haikuttf/stdint.h b/src/helper/haikuttf/stdint.h new file mode 100644 index 000000000..d02608a59 --- /dev/null +++ b/src/helper/haikuttf/stdint.h @@ -0,0 +1,247 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2008 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + + +#endif // _MSC_STDINT_H_ ] diff --git a/src/helper/zip_utils/unzip.cpp b/src/helper/zip_utils/unzip.cpp index f564a215e..5cca23a46 100644 --- a/src/helper/zip_utils/unzip.cpp +++ b/src/helper/zip_utils/unzip.cpp @@ -170,7 +170,7 @@ typedef struct tm_unz_s // ---------------------------------------------------------------------- // some windows<->linux portability things #ifdef ZIP_STD -DWORD GetFilePosU(HANDLE hfout) +DWORD GetFilePosU(ZIPHANDLE hfout) { struct stat st; fstat(fileno(hfout),&st); if ((st.st_mode&S_IFREG)==0) return 0xFFFFFFFF; return ftell(hfout); @@ -182,11 +182,11 @@ bool FileExists(const TCHAR *fn) return (res==0); } -FILETIME dosdatetime2filetime(WORD dosdate,WORD dostime) +ZIPFILETIME dosdatetime2filetime(WORD dosdate,WORD dostime) { struct tm t; t.tm_year = (WORD)(((dosdate>>9)&0x7f) + 1980 - 1900); t.tm_isdst = -1; - t.tm_mon = (WORD)((dosdate>>5)&0xf - 1); + t.tm_mon = (WORD)( ((dosdate>>5)&0xf)- 1); t.tm_mday = (WORD)(dosdate&0x1f); t.tm_hour = (WORD)((dostime>>11)&0x1f); t.tm_min = (WORD)((dostime>>5)&0x3f); @@ -195,29 +195,29 @@ FILETIME dosdatetime2filetime(WORD dosdate,WORD dostime) return t2; } -void LocalFileTimeToFileTime(FILETIME *lft, FILETIME *ft) +void LocalFileTimeToFileTime(ZIPFILETIME *lft, ZIPFILETIME *ft) { *ft = *lft; } -FILETIME timet2filetime(const lutime_t t) +ZIPFILETIME timet2filetime(const lutime_t t) { return t; } #else // ---------------------------------------------------------------------- -DWORD GetFilePosU(HANDLE hfout) +DWORD GetFilePosU(ZIPHANDLE hfout) { return SetFilePointer(hfout,0,0,FILE_CURRENT); } -FILETIME timet2filetime(const lutime_t t) +ZIPFILETIME timet2filetime(const lutime_t t) { LONGLONG i = Int32x32To64(t,10000000) + 116444736000000000LL; - FILETIME ft; + ZIPFILETIME ft; ft.dwLowDateTime = (DWORD) i; ft.dwHighDateTime = (DWORD)(i >>32); return ft; } -FILETIME dosdatetime2filetime(WORD dosdate,WORD dostime) +ZIPFILETIME dosdatetime2filetime(WORD dosdate,WORD dostime) { // date: bits 0-4 are day of month 1-31. Bits 5-8 are month 1..12. Bits 9-15 are year-1980 // time: bits 0-4 are seconds/2, bits 5-10 are minute 0..59. Bits 11-15 are hour 0..23 SYSTEMTIME st; @@ -228,7 +228,7 @@ FILETIME dosdatetime2filetime(WORD dosdate,WORD dostime) st.wMinute = (WORD)((dostime>>5)&0x3f); st.wSecond = (WORD)((dostime&0x1f)*2); st.wMilliseconds = 0; - FILETIME ft; SystemTimeToFileTime(&st,&ft); + ZIPFILETIME ft; SystemTimeToFileTime(&st,&ft); return ft; } @@ -496,7 +496,7 @@ int inflateEnd (z_streamp strm); // was inconsistent. In the error case, msg may be set but then points to a // static string (which must not be deallocated). - // Advanced functions + // Advanced functions // The following functions are needed only in some special applications. @@ -513,7 +513,7 @@ int inflateSetDictionary (z_streamp strm, // if this call returned Z_NEED_DICT. The dictionary chosen by the compressor // can be determined from the Adler32 value returned by this call of // inflate. The compressor and decompressor must use exactly the same -// dictionary. +// dictionary. // // inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a // parameter is invalid (such as NULL dictionary) or the stream state is @@ -524,7 +524,7 @@ int inflateSetDictionary (z_streamp strm, int inflateSync (z_streamp strm); -// +// // Skips invalid compressed data until a full flush point can be found, or until all // available input is skipped. No output is provided. // @@ -615,7 +615,7 @@ const char * const z_errmsg[10] = { // indexed by 2-zlib_error #define ERR_RETURN(strm,err) \ return (strm->msg = (char*)ERR_MSG(err), (err)) -// To be used only when the state is known to be valid +// To be used only when the state is known to be valid // common constants @@ -623,21 +623,21 @@ const char * const z_errmsg[10] = { // indexed by 2-zlib_error #define STORED_BLOCK 0 #define STATIC_TREES 1 #define DYN_TREES 2 -// The three kinds of block type +// The three kinds of block type #define MIN_MATCH 3 #define MAX_MATCH 258 -// The minimum and maximum match lengths +// The minimum and maximum match lengths -#define PRESET_DICT 0x20 // preset dictionary flag in zlib header +#define PRESET_DICT 0x20 // preset dictionary flag in zlib header - // target dependencies + // target dependencies #define OS_CODE 0x0b // Window 95 & Windows NT - // functions + // functions #define zmemzero(dest, len) memset(dest, 0, len) @@ -782,71 +782,71 @@ typedef enum { IBM_DTREE, // get length, distance trees for a dynamic block IBM_CODES, // processing fixed or dynamic block IBM_DRY, // output remaining window bytes - IBM_DONE, // finished last block, done - IBM_BAD} // got a data error--stuck here + IBM_DONE, // finished last block, done + IBM_BAD} // got a data error--stuck here inflate_block_mode; -// inflate blocks semi-private state +// inflate blocks semi-private state struct inflate_blocks_state { - // mode - inflate_block_mode mode; // current inflate_block mode + // mode + inflate_block_mode mode; // current inflate_block mode - // mode dependent information + // mode dependent information union { - uInt left; // if STORED, bytes left to copy + uInt left; // if STORED, bytes left to copy struct { - uInt table; // table lengths (14 bits) + uInt table; // table lengths (14 bits) uInt index; // index into blens (or border) uInt *blens; // bit lengths of codes - uInt bb; // bit length tree depth - inflate_huft *tb; // bit length decoding tree - } trees; // if DTREE, decoding info for trees + uInt bb; // bit length tree depth + inflate_huft *tb; // bit length decoding tree + } trees; // if DTREE, decoding info for trees struct { - inflate_codes_statef + inflate_codes_statef *codes; - } decode; // if CODES, current state + } decode; // if CODES, current state } sub; // submode - uInt last; // true if this block is the last block + uInt last; // true if this block is the last block - // mode independent information - uInt bitk; // bits in bit buffer - uLong bitb; // bit buffer - inflate_huft *hufts; // single malloc for tree space - Byte *window; // sliding window - Byte *end; // one byte after sliding window - Byte *read; // window read pointer - Byte *write; // window write pointer - check_func checkfn; // check function - uLong check; // check on output + // mode independent information + uInt bitk; // bits in bit buffer + uLong bitb; // bit buffer + inflate_huft *hufts; // single malloc for tree space + Byte *window; // sliding window + Byte *end; // one byte after sliding window + Byte *read; // window read pointer + Byte *write; // window write pointer + check_func checkfn; // check function + uLong check; // check on output }; // defines for inflate input/output -// update pointers and return +// update pointers and return #define UPDBITS {s->bitb=b;s->bitk=k;} #define UPDIN {z->avail_in=n;z->total_in+=(uLong)(p-z->next_in);z->next_in=p;} #define UPDOUT {s->write=q;} #define UPDATE {UPDBITS UPDIN UPDOUT} #define LEAVE {UPDATE return inflate_flush(s,z,r);} -// get bytes and bits +// get bytes and bits #define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} #define NEEDBYTE {if(n)r=Z_OK;else LEAVE} #define NEXTBYTE (n--,*p++) #define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} -// output bytes +// output bytes #define WAVAIL (uInt)(qread?s->read-q-1:s->end-q) -#define LOADOUT {q=s->write;m=(uInt)WAVAIL;m;} +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} #define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} #define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} #define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} #define OUTBYTE(a) {*q++=(Byte)(a);m--;} -// load local pointers +// load local pointers #define LOAD {LOADIN LOADOUT} -// masks for lower bits (size given to avoid silly warnings with Visual C++) +// masks for lower bits (size given to avoid silly warnings with Visual C++) // And'ing with mask[n] masks the lower n bits const uInt inflate_mask[17] = { 0x0000, @@ -1017,11 +1017,11 @@ int inflate_flush(inflate_blocks_statef *s,z_streamp z,int r) Byte *p; Byte *q; - // local copies of source and destination pointers + // local copies of source and destination pointers p = z->next_out; q = s->read; - // compute number of bytes to copy as far as end of window + // compute number of bytes to copy as far as end of window n = (uInt)((q <= s->write ? s->write : s->end) - q); if (n > z->avail_out) n = z->avail_out; if (n && r == Z_BUF_ERROR) r = Z_OK; @@ -1030,11 +1030,11 @@ int inflate_flush(inflate_blocks_statef *s,z_streamp z,int r) z->avail_out -= n; z->total_out += n; - // update check information + // update check information if (s->checkfn != Z_NULL) z->adler = s->check = (*s->checkfn)(s->check, q, n); - // copy as far as end of window + // copy as far as end of window if (n!=0) // check for n!=0 to avoid waking up CodeGuard { memcpy(p, q, n); p += n; @@ -1044,21 +1044,21 @@ int inflate_flush(inflate_blocks_statef *s,z_streamp z,int r) // see if more to copy at beginning of window if (q == s->end) { - // wrap pointers + // wrap pointers q = s->window; if (s->write == s->end) s->write = s->window; - // compute bytes to copy + // compute bytes to copy n = (uInt)(s->write - q); if (n > z->avail_out) n = z->avail_out; if (n && r == Z_BUF_ERROR) r = Z_OK; - // update counters + // update counters z->avail_out -= n; z->total_out += n; - // update check information + // update check information if (s->checkfn != Z_NULL) z->adler = s->check = (*s->checkfn)(s->check, q, n); @@ -1083,42 +1083,42 @@ int inflate_flush(inflate_blocks_statef *s,z_streamp z,int r) #define exop word.what.Exop #define bits word.what.Bits -typedef enum { // waiting for "i:"=input, "o:"=output, "x:"=nothing - START, // x: set up for LEN - LEN, // i: get length/literal/eob next - LENEXT, // i: getting length extra (have base) - DIST, // i: get distance next - DISTEXT, // i: getting distance extra +typedef enum { // waiting for "i:"=input, "o:"=output, "x:"=nothing + START, // x: set up for LEN + LEN, // i: get length/literal/eob next + LENEXT, // i: getting length extra (have base) + DIST, // i: get distance next + DISTEXT, // i: getting distance extra COPY, // o: copying bytes in window, waiting for space - LIT, // o: got literal, waiting for output space - WASH, // o: got eob, possibly still output waiting - END, // x: got eob and all data flushed - BADCODE} // x: got error + LIT, // o: got literal, waiting for output space + WASH, // o: got eob, possibly still output waiting + END, // x: got eob and all data flushed + BADCODE} // x: got error inflate_codes_mode; // inflate codes private state struct inflate_codes_state { - // mode - inflate_codes_mode mode; // current inflate_codes mode + // mode + inflate_codes_mode mode; // current inflate_codes mode - // mode dependent information + // mode dependent information uInt len; union { struct { - const inflate_huft *tree; // pointer into tree - uInt need; // bits needed - } code; // if LEN or DIST, where in tree - uInt lit; // if LIT, literal + const inflate_huft *tree; // pointer into tree + uInt need; // bits needed + } code; // if LEN or DIST, where in tree + uInt lit; // if LIT, literal struct { - uInt get; // bits to get for extra - uInt dist; // distance back to copy from - } copy; // if EXT or COPY, where and how much + uInt get; // bits to get for extra + uInt dist; // distance back to copy from + } copy; // if EXT or COPY, where and how much } sub; // submode - // mode independent information - Byte lbits; // ltree bits decoded per branch - Byte dbits; // dtree bits decoder per branch + // mode independent information + Byte lbits; // ltree bits decoded per branch + Byte dbits; // dtree bits decoder per branch const inflate_huft *ltree; // literal/length/eob tree const inflate_huft *dtree; // distance tree @@ -1190,7 +1190,7 @@ int inflate_codes(inflate_blocks_statef *s, z_streamp z, int r) t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); DUMPBITS(t->bits) e = (uInt)(t->exop); - if (e == 0) // literal + if (e == 0) // literal { c->sub.lit = t->base; LuTracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? @@ -1199,30 +1199,30 @@ int inflate_codes(inflate_blocks_statef *s, z_streamp z, int r) c->mode = LIT; break; } - if (e & 16) // length + if (e & 16) // length { c->sub.copy.get = e & 15; c->len = t->base; c->mode = LENEXT; break; } - if ((e & 64) == 0) // next table + if ((e & 64) == 0) // next table { c->sub.code.need = e; c->sub.code.tree = t + t->base; break; } - if (e & 32) // end of block + if (e & 32) // end of block { LuTracevv((stderr, "inflate: end of block\n")); c->mode = WASH; break; } - c->mode = BADCODE; // invalid code + c->mode = BADCODE; // invalid code z->msg = (char*)"invalid literal/length code"; r = Z_DATA_ERROR; LEAVE - case LENEXT: // i: getting length extra (have base) + case LENEXT: // i: getting length extra (have base) j = c->sub.copy.get; NEEDBITS(j) c->len += (uInt)b & inflate_mask[j]; @@ -1231,40 +1231,40 @@ int inflate_codes(inflate_blocks_statef *s, z_streamp z, int r) c->sub.code.tree = c->dtree; LuTracevv((stderr, "inflate: length %u\n", c->len)); c->mode = DIST; - case DIST: // i: get distance next + case DIST: // i: get distance next j = c->sub.code.need; NEEDBITS(j) t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); DUMPBITS(t->bits) e = (uInt)(t->exop); - if (e & 16) // distance + if (e & 16) // distance { c->sub.copy.get = e & 15; c->sub.copy.dist = t->base; c->mode = DISTEXT; break; } - if ((e & 64) == 0) // next table + if ((e & 64) == 0) // next table { c->sub.code.need = e; c->sub.code.tree = t + t->base; break; } - c->mode = BADCODE; // invalid code + c->mode = BADCODE; // invalid code z->msg = (char*)"invalid distance code"; r = Z_DATA_ERROR; LEAVE - case DISTEXT: // i: getting distance extra + case DISTEXT: // i: getting distance extra j = c->sub.copy.get; NEEDBITS(j) c->sub.copy.dist += (uInt)b & inflate_mask[j]; DUMPBITS(j) LuTracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); c->mode = COPY; - case COPY: // o: copying bytes in window, waiting for space + case COPY: // o: copying bytes in window, waiting for space f = q - c->sub.copy.dist; while (f < s->window) // modulo window size-"while" instead - f += s->end - s->window; // of "if" handles invalid distances + f += s->end - s->window; // of "if" handles invalid distances while (c->len) { NEEDOUT @@ -1275,18 +1275,18 @@ int inflate_codes(inflate_blocks_statef *s, z_streamp z, int r) } c->mode = START; break; - case LIT: // o: got literal, waiting for output space + case LIT: // o: got literal, waiting for output space NEEDOUT OUTBYTE(c->sub.lit) c->mode = START; break; - case WASH: // o: got eob, possibly more output - if (k > 7) // return unused byte, if any + case WASH: // o: got eob, possibly more output + if (k > 7) // return unused byte, if any { //Assert(k < 16, "inflate_codes grabbed too many bytes") k -= 8; n++; - p--; // can always return one + p--; // can always return one } FLUSH if (s->read != s->write) @@ -1316,7 +1316,7 @@ void inflate_codes_free(inflate_codes_statef *c,z_streamp z) // Copyright (C) 1995-1998 Mark Adler // For conditions of distribution and use, see copyright notice in zlib.h -//struct inflate_codes_state {int dummy;}; // for buggy compilers +//struct inflate_codes_state {int dummy;}; // for buggy compilers @@ -1422,12 +1422,12 @@ int inflate_blocks(inflate_blocks_statef *s, z_streamp z, int r) Byte *p; // input data pointer uInt n; // bytes available there Byte *q; // output window write pointer - uInt m; // bytes to end of window or read pointer + uInt m; // bytes to end of window or read pointer - // copy input/output information to locals (UPDATE macro restores) + // copy input/output information to locals (UPDATE macro restores) LOAD - // process input based on current state + // process input based on current state for(;;) switch (s->mode) { case IBM_TYPE: @@ -1436,15 +1436,15 @@ int inflate_blocks(inflate_blocks_statef *s, z_streamp z, int r) s->last = t & 1; switch (t >> 1) { - case 0: // stored + case 0: // stored LuTracev((stderr, "inflate: stored block%s\n", s->last ? " (last)" : "")); DUMPBITS(3) - t = k & 7; // go to byte boundary + t = k & 7; // go to byte boundary DUMPBITS(t) s->mode = IBM_LENS; // get length of stored block break; - case 1: // fixed + case 1: // fixed LuTracev((stderr, "inflate: fixed codes block%s\n", s->last ? " (last)" : "")); { @@ -1462,7 +1462,7 @@ int inflate_blocks(inflate_blocks_statef *s, z_streamp z, int r) DUMPBITS(3) s->mode = IBM_CODES; break; - case 2: // dynamic + case 2: // dynamic LuTracev((stderr, "inflate: dynamic codes block%s\n", s->last ? " (last)" : "")); DUMPBITS(3) @@ -1486,7 +1486,7 @@ int inflate_blocks(inflate_blocks_statef *s, z_streamp z, int r) LEAVE } s->sub.left = (uInt)b & 0xffff; - b = k = 0; // dump bits + b = k = 0; // dump bits LuTracev((stderr, "inflate: stored length %u\n", s->sub.left)); s->mode = s->sub.left ? IBM_STORED : (s->last ? IBM_DRY : IBM_TYPE); break; @@ -1571,7 +1571,7 @@ int inflate_blocks(inflate_blocks_statef *s, z_streamp z, int r) DUMPBITS(t) s->sub.trees.blens[s->sub.trees.index++] = c; } - else // c == 16..18 + else // c == 16..18 { i = c == 18 ? 7 : c - 14; j = c == 18 ? 11 : 3; @@ -1603,7 +1603,7 @@ int inflate_blocks(inflate_blocks_statef *s, z_streamp z, int r) inflate_huft *tl, *td; inflate_codes_statef *c; - bl = 9; // must be <= 9 for lookahead assumptions + bl = 9; // must be <= 9 for lookahead assumptions bd = 6; // must be <= 9 for lookahead assumptions t = s->sub.trees.table; t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), @@ -1698,12 +1698,12 @@ int huft_build ( const uInt *, // list of base values for non-simple codes const uInt *, // list of extra bits for non-simple codes inflate_huft **,// result: starting table - uInt *, // maximum lookup bits (returns actual) - inflate_huft *, // space for trees - uInt *, // hufts used in space - uInt * ); // space for values + uInt *, // maximum lookup bits (returns actual) + inflate_huft *, // space for trees + uInt *, // hufts used in space + uInt * ); // space for values -// Tables for deflate from PKZIP's appnote.txt. +// Tables for deflate from PKZIP's appnote.txt. const uInt cplens[31] = { // Copy lengths for literal codes 257..285 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; @@ -1715,7 +1715,7 @@ const uInt cpdist[30] = { // Copy offsets for distance codes 0..29 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; -const uInt cpdext[30] = { // Extra bits for distance codes +const uInt cpdext[30] = { // Extra bits for distance codes 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; @@ -1753,7 +1753,7 @@ const uInt cpdext[30] = { // Extra bits for distance codes // -// If BMAX needs to be larger than 16, then h and x[] should be uLong. +// If BMAX needs to be larger than 16, then h and x[] should be uLong. #define BMAX 15 // maximum bit length of any code int huft_build( @@ -1775,36 +1775,36 @@ uInt *v) // working area: values in order of bit length uInt a; // counter for codes of length k uInt c[BMAX+1]; // bit length count table - uInt f; // i repeats in table every f entries - int g; // maximum code length - int h; // table level - register uInt i; // counter, current code + uInt f; // i repeats in table every f entries + int g; // maximum code length + int h; // table level + register uInt i; // counter, current code register uInt j; // counter - register int k; // number of bits in current code - int l; // bits per table (returned in m) - uInt mask; // (1 << w) - 1, to avoid cc -O bug on HP + register int k; // number of bits in current code + int l; // bits per table (returned in m) + uInt mask; // (1 << w) - 1, to avoid cc -O bug on HP register uInt *p; // pointer into c[], b[], or v[] - inflate_huft *q; // points to current table - struct inflate_huft_s r; // table entry for structure assignment - inflate_huft *u[BMAX]; // table stack - register int w; // bits before this table == (l * h) - uInt x[BMAX+1]; // bit offsets, then code stack - uInt *xp; // pointer into x - int y; // number of dummy codes added - uInt z; // number of entries in current table + inflate_huft *q; // points to current table + struct inflate_huft_s r = { { { 0 } }, 0 }; // table entry for structure assignment + inflate_huft *u[BMAX]; // table stack + register int w; // bits before this table == (l * h) + uInt x[BMAX+1]; // bit offsets, then code stack + uInt *xp; // pointer into x + int y; // number of dummy codes added + uInt z; // number of entries in current table - // Generate counts for each bit length + // Generate counts for each bit length p = c; #define C0 *p++ = 0; #define C2 C0 C0 C0 C0 #define C4 C2 C2 C2 C2 - C4; p; // clear c[]--assume BMAX+1 is 16 + C4; // clear c[]--assume BMAX+1 is 16 p = b; i = n; do { - c[*p++]++; // assume all entries <= BMAX + c[*p++]++; // assume all entries <= BMAX } while (--i); - if (c[0] == n) // null input--all zero length codes + if (c[0] == n) // null input--all zero length codes { *t = (inflate_huft *)Z_NULL; *m = 0; @@ -1812,24 +1812,24 @@ uInt *v) // working area: values in order of bit length } - // Find minimum and maximum length, bound *m by those + // Find minimum and maximum length, bound *m by those l = *m; for (j = 1; j <= BMAX; j++) if (c[j]) break; - k = j; // minimum code length + k = j; // minimum code length if ((uInt)l < j) l = j; for (i = BMAX; i; i--) if (c[i]) break; - g = i; // maximum code length + g = i; // maximum code length if ((uInt)l > i) l = i; *m = l; - // Adjust last length count to fill out codes, if needed + // Adjust last length count to fill out codes, if needed for (y = 1 << j; j < i; j++, y <<= 1) if ((y -= c[j]) < 0) return Z_DATA_ERROR; @@ -1838,94 +1838,94 @@ uInt *v) // working area: values in order of bit length c[i] += y; - // Generate starting offsets into the value table for each length + // Generate starting offsets into the value table for each length x[1] = j = 0; p = c + 1; xp = x + 2; - while (--i) { // note that i == g from above + while (--i) { // note that i == g from above *xp++ = (j += *p++); } - // Make a table of values in order of bit lengths + // Make a table of values in order of bit lengths p = b; i = 0; do { if ((j = *p++) != 0) v[x[j]++] = i; } while (++i < n); - n = x[g]; // set n to length of v + n = x[g]; // set n to length of v - // Generate the Huffman codes and for each, make the table entries - x[0] = i = 0; // first Huffman code is zero - p = v; // grab values in bit order - h = -1; // no tables yet--level -1 - w = -l; // bits decoded == (l * h) - u[0] = (inflate_huft *)Z_NULL; // just to keep compilers happy - q = (inflate_huft *)Z_NULL; // ditto - z = 0; // ditto + // Generate the Huffman codes and for each, make the table entries + x[0] = i = 0; // first Huffman code is zero + p = v; // grab values in bit order + h = -1; // no tables yet--level -1 + w = -l; // bits decoded == (l * h) + u[0] = (inflate_huft *)Z_NULL; // just to keep compilers happy + q = (inflate_huft *)Z_NULL; // ditto + z = 0; // ditto - // go through the bit lengths (k already is bits in shortest code) + // go through the bit lengths (k already is bits in shortest code) for (; k <= g; k++) { a = c[k]; while (a--) { - // here i is the Huffman code of length k bits for value *p - // make tables up to required level + // here i is the Huffman code of length k bits for value *p + // make tables up to required level while (k > w + l) { h++; - w += l; // previous table always l bits + w += l; // previous table always l bits // compute minimum size table less than or equal to l bits z = g - w; - z = z > (uInt)l ? l : z; // table size upper limit - if ((f = 1 << (j = k - w)) > a + 1) // try a k-w bit table - { // too few codes for k-w bit table - f -= a + 1; // deduct codes from patterns left + z = z > (uInt)l ? l : z; // table size upper limit + if ((f = 1 << (j = k - w)) > a + 1) // try a k-w bit table + { // too few codes for k-w bit table + f -= a + 1; // deduct codes from patterns left xp = c + k; if (j < z) - while (++j < z) // try smaller tables up to z bits + while (++j < z) // try smaller tables up to z bits { if ((f <<= 1) <= *++xp) - break; // enough codes to use up j bits + break; // enough codes to use up j bits f -= *xp; // else deduct codes from patterns } } - z = 1 << j; // table entries for j-bit table + z = 1 << j; // table entries for j-bit table - // allocate new table - if (*hn + z > MANY) // (note: doesn't matter for fixed) - return Z_DATA_ERROR; // overflow of MANY + // allocate new table + if (*hn + z > MANY) // (note: doesn't matter for fixed) + return Z_DATA_ERROR; // overflow of MANY u[h] = q = hp + *hn; *hn += z; - // connect to last table, if there is one + // connect to last table, if there is one if (h) { x[h] = i; // save pattern for backing up - r.bits = (Byte)l; // bits to dump before this table - r.exop = (Byte)j; // bits in this table + r.bits = (Byte)l; // bits to dump before this table + r.exop = (Byte)j; // bits in this table j = i >> (w - l); - r.base = (uInt)(q - u[h-1] - j); // offset to this table - u[h-1][j] = r; // connect to last table + r.base = (uInt)(q - u[h-1] - j); // offset to this table + u[h-1][j] = r; // connect to last table } else - *t = q; // first table is returned result + *t = q; // first table is returned result } - // set up table entry in r + // set up table entry in r r.bits = (Byte)(k - w); if (p >= v + n) - r.exop = 128 + 64; // out of values--invalid code + r.exop = 128 + 64; // out of values--invalid code else if (*p < s) { - r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); // 256 is end-of-block - r.base = *p++; // simple code is just the value + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); // 256 is end-of-block + r.base = *p++; // simple code is just the value } else { - r.exop = (Byte)(e[*p - s] + 16 + 64);// non-simple--look up in lists + r.exop = (Byte)(e[*p - s] + 16 + 64);// non-simple--look up in lists r.base = d[*p++ - s]; } @@ -1934,13 +1934,13 @@ uInt *v) // working area: values in order of bit length for (j = i >> w; j < z; j += f) q[j] = r; - // backwards increment the k-bit code i + // backwards increment the k-bit code i for (j = 1 << (k - 1); i & j; j >>= 1) i ^= j; i ^= j; - // backup over finished tables - mask = (1 << w) - 1; // needed on HP, cc -O bug + // backup over finished tables + mask = (1 << w) - 1; // needed on HP, cc -O bug while ((i & mask) != x[h]) { h--; // don't need to update q @@ -1951,7 +1951,7 @@ uInt *v) // working area: values in order of bit length } - // Return Z_BUF_ERROR if we were given an incomplete table + // Return Z_BUF_ERROR if we were given an incomplete table return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; } @@ -1964,8 +1964,8 @@ inflate_huft *hp, // space for trees z_streamp z) // for messages { int r; - uInt hn = 0; // hufts used in space - uInt *v; // work area for huft_build + uInt hn = 0; // hufts used in space + uInt *v; // work area for huft_build if ((v = (uInt*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL) return Z_MEM_ERROR; @@ -1995,14 +1995,14 @@ inflate_huft *hp, // space for trees z_streamp z) // for messages { int r; - uInt hn = 0; // hufts used in space - uInt *v; // work area for huft_build + uInt hn = 0; // hufts used in space + uInt *v; // work area for huft_build - // allocate work area + // allocate work area if ((v = (uInt*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) return Z_MEM_ERROR; - // build literal/length tree + // build literal/length tree r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); if (r != Z_OK || *bl == 0) { @@ -2017,7 +2017,7 @@ z_streamp z) // for messages return r; } - // build distance tree + // build distance tree r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); if (r != Z_OK || (*bd == 0 && nl > 257)) { @@ -2036,7 +2036,7 @@ z_streamp z) // for messages return r; } - // done + // done ZFREE(z, v); return Z_OK; } @@ -2066,17 +2066,17 @@ z_streamp ) // for memory allocation // -//struct inflate_codes_state {int dummy;}; // for buggy compilers +//struct inflate_codes_state {int dummy;}; // for buggy compilers -// macros for bit input with no checking and for returning unused bytes +// macros for bit input with no checking and for returning unused bytes #define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3;} // Called with number of bytes left to write in window at least 258 // (the maximum string length) and number of input bytes available // at least ten. The ten bytes are six bytes for the longest length/ -// distance pair plus four bytes for overloading the bit buffer. +// distance pair plus four bytes for overloading the bit buffer. int inflate_fast( uInt bl, uInt bd, @@ -2085,31 +2085,31 @@ const inflate_huft *td, // need separate declaration for Borland C++ inflate_blocks_statef *s, z_streamp z) { - const inflate_huft *t; // temporary pointer - uInt e; // extra bits or operation - uLong b; // bit buffer - uInt k; // bits in bit buffer - Byte *p; // input data pointer - uInt n; // bytes available there - Byte *q; // output window write pointer - uInt m; // bytes to end of window or read pointer + const inflate_huft *t; // temporary pointer + uInt e; // extra bits or operation + uLong b; // bit buffer + uInt k; // bits in bit buffer + Byte *p; // input data pointer + uInt n; // bytes available there + Byte *q; // output window write pointer + uInt m; // bytes to end of window or read pointer uInt ml; // mask for literal/length tree - uInt md; // mask for distance tree - uInt c; // bytes to copy - uInt d; // distance back to copy from - Byte *r; // copy source pointer + uInt md; // mask for distance tree + uInt c; // bytes to copy + uInt d; // distance back to copy from + Byte *r; // copy source pointer - // load input, output, bit values + // load input, output, bit values LOAD - // initialize masks + // initialize masks ml = inflate_mask[bl]; md = inflate_mask[bd]; - // do until not enough input or output space for fast loop - do { // assume called with m >= 258 && n >= 10 - // get literal/length code - GRABBITS(20) // max bits for literal/length code + // do until not enough input or output space for fast loop + do { // assume called with m >= 258 && n >= 10 + // get literal/length code + GRABBITS(20) // max bits for literal/length code if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) { DUMPBITS(t->bits) @@ -2124,22 +2124,22 @@ z_streamp z) DUMPBITS(t->bits) if (e & 16) { - // get extra bits for length + // get extra bits for length e &= 15; c = t->base + ((uInt)b & inflate_mask[e]); DUMPBITS(e) LuTracevv((stderr, "inflate: * length %u\n", c)); - // decode distance base of block to copy - GRABBITS(15); // max bits for distance code + // decode distance base of block to copy + GRABBITS(15); // max bits for distance code e = (t = td + ((uInt)b & md))->exop; for (;;) { DUMPBITS(t->bits) if (e & 16) { - // get extra bits to add to distance base + // get extra bits to add to distance base e &= 15; - GRABBITS(e) // get extra bits (up to 13) + GRABBITS(e) // get extra bits (up to 13) d = t->base + ((uInt)b & inflate_mask[e]); DUMPBITS(e) LuTracevv((stderr, "inflate: * distance %u\n", d)); @@ -2561,7 +2561,7 @@ int inflateInit2(z_streamp z) } LuTracev((stderr, "inflate: allocated\n")); - // reset state + // reset state inflateReset(z); return Z_OK; } @@ -2606,7 +2606,7 @@ int inflate(z_streamp z, int f) { z->state->mode = IM_BAD; z->msg = (char*)"incorrect header check"; - z->state->sub.marker = 5; // can't try inflateSync + z->state->sub.marker = 5; // can't try inflateSync break; } LuTracev((stderr, "inflate: zlib header ok\n")); @@ -2629,7 +2629,7 @@ int inflate(z_streamp z, int f) z->state->sub.check.need += (uLong)IM_NEXTBYTE << 8; z->state->mode = IM_DICT1; case IM_DICT1: - IM_NEEDBYTE; r; + IM_NEEDBYTE; z->state->sub.check.need += (uLong)IM_NEXTBYTE; z->adler = z->state->sub.check.need; z->state->mode = IM_DICT0; @@ -2637,14 +2637,14 @@ int inflate(z_streamp z, int f) case IM_DICT0: z->state->mode = IM_BAD; z->msg = (char*)"need dictionary"; - z->state->sub.marker = 0; // can try inflateSync + z->state->sub.marker = 0; // can try inflateSync return Z_STREAM_ERROR; case IM_BLOCKS: r = inflate_blocks(z->state->blocks, z, r); if (r == Z_DATA_ERROR) { z->state->mode = IM_BAD; - z->state->sub.marker = 0; // can try inflateSync + z->state->sub.marker = 0; // can try inflateSync break; } if (r == Z_OK) @@ -2679,7 +2679,7 @@ int inflate(z_streamp z, int f) { z->state->mode = IM_BAD; z->msg = (char*)"incorrect data check"; - z->state->sub.marker = 5; // can't try inflateSync + z->state->sub.marker = 5; // can't try inflateSync break; } LuTracev((stderr, "inflate: zlib check ok\n")); @@ -2725,7 +2725,7 @@ typedef struct { bool is_handle; // either a handle or memory bool canseek; // for handles: - HANDLE h; bool herr; unsigned long initial_offset; bool mustclosehandle; + ZIPHANDLE h; bool herr; unsigned long initial_offset; bool mustclosehandle; // for memory: void *buf; unsigned int len,pos; // if it's a memory block } LUFILE; @@ -2734,11 +2734,11 @@ typedef struct LUFILE *lufopen(void *z,unsigned int len,DWORD flags,ZRESULT *err) { if (flags!=ZIP_HANDLE && flags!=ZIP_FILENAME && flags!=ZIP_MEMORY) {*err=ZR_ARGS; return NULL;} // - HANDLE h=0; bool canseek=false; *err=ZR_OK; + ZIPHANDLE h=0; bool canseek=false; *err=ZR_OK; bool mustclosehandle=false; if (flags==ZIP_HANDLE||flags==ZIP_FILENAME) { if (flags==ZIP_HANDLE) - { HANDLE hf = (HANDLE)z; + { ZIPHANDLE hf = (ZIPHANDLE)z; h=hf; mustclosehandle=false; #ifdef DuplicateHandle BOOL res = DuplicateHandle(GetCurrentProcess(),hf,GetCurrentProcess(),&h,0,FALSE,DUPLICATE_SAME_ACCESS); @@ -2803,7 +2803,7 @@ long int luftell(LUFILE *stream) int lufseek(LUFILE *stream, long offset, int whence) { if (stream->is_handle && stream->canseek) - { + { #ifdef ZIP_STD return fseek(stream->h,stream->initial_offset+offset,whence); #else @@ -2827,7 +2827,7 @@ int lufseek(LUFILE *stream, long offset, int whence) size_t lufread(void *ptr,size_t size,size_t n,LUFILE *stream) { unsigned int toread = (unsigned int)(size*n); if (stream->is_handle) - { + { #ifdef ZIP_STD return fread(ptr,size,n,stream->h); #else @@ -2965,7 +2965,7 @@ int unzlocal_getLong (LUFILE *fin,uLong *pX) err = unzlocal_getByte(fin,&i); x = (uLong)i; - + if (err==UNZ_OK) err = unzlocal_getByte(fin,&i); x += ((uLong)i)<<8; @@ -2977,7 +2977,7 @@ int unzlocal_getLong (LUFILE *fin,uLong *pX) if (err==UNZ_OK) err = unzlocal_getByte(fin,&i); x += ((uLong)i)<<24; - + if (err==UNZ_OK) *pX = x; else @@ -2986,7 +2986,7 @@ int unzlocal_getLong (LUFILE *fin,uLong *pX) } -// My own strcmpi / strcasecmp +// My own strcmpi / strcasecmp int strcmpcasenosensitive_internal (const char* fileName1,const char *fileName2) { for (;;) @@ -3019,7 +3019,7 @@ int strcmpcasenosensitive_internal (const char* fileName1,const char *fileName2) int unzStringFileNameCompare (const char*fileName1,const char*fileName2,int iCaseSensitivity) { if (iCaseSensitivity==1) return strcmp(fileName1,fileName2); else return strcmpcasenosensitive_internal(fileName1,fileName2); -} +} #define BUFREADCOMMENT (0x400) @@ -3135,7 +3135,7 @@ int unzClose (unzFile file) // Write info about the ZipFile in the *pglobal_info structure. // No preparation of the structure is needed -// return UNZ_OK if there is no problem. +// return UNZ_OK if there is no problem. int unzGetGlobalInfo (unzFile file,unz_global_info *pglobal_info) { unz_s* s; @@ -3193,11 +3193,12 @@ int unzlocal_GetCurrentFileInfoInternal (unzFile file, unz_file_info *pfile_info // we check the magic - if (err==UNZ_OK) + if (err==UNZ_OK) { if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) err=UNZ_ERRNO; else if (uMagic!=0x02014b50) err=UNZ_BADZIPFILE; + } if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK) err=UNZ_ERRNO; @@ -3273,11 +3274,13 @@ int unzlocal_GetCurrentFileInfoInternal (unzFile file, unz_file_info *pfile_info else uSizeRead = extraFieldBufferSize; - if (lSeek!=0) + if (lSeek!=0) { if (lufseek(s->file,lSeek,SEEK_CUR)==0) lSeek=0; else - err=UNZ_ERRNO; + err=UNZ_ERRNO; + } + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) if (lufread(extraField,(uInt)uSizeRead,1,s->file)!=1) err=UNZ_ERRNO; @@ -3298,11 +3301,13 @@ int unzlocal_GetCurrentFileInfoInternal (unzFile file, unz_file_info *pfile_info else uSizeRead = commentBufferSize; - if (lSeek!=0) + if (lSeek!=0) { if (lufseek(s->file,lSeek,SEEK_CUR)==0) {} // unused lSeek=0; else - err=UNZ_ERRNO; + err=UNZ_ERRNO; + } + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) if (lufread(szComment,(uInt)uSizeRead,1,s->file)!=1) err=UNZ_ERRNO; @@ -3445,11 +3450,12 @@ int unzlocal_CheckCurrentFileCoherencyHeader (unz_s *s,uInt *piSizeVar, return UNZ_ERRNO; - if (err==UNZ_OK) + if (err==UNZ_OK) { if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) err=UNZ_ERRNO; else if (uMagic!=0x04034b50) err=UNZ_BADZIPFILE; + } if (unzlocal_getShort(s->file,&uData) != UNZ_OK) err=UNZ_ERRNO; @@ -3868,7 +3874,7 @@ int unzCloseCurrentFile (unzFile file); class TUnzip { public: - TUnzip(const char *pwd) : uf(0), unzbuf(0), currentfile(-1), czei(-1), password(0) {if (pwd!=0) {password=new char[strlen(pwd)+1]; strcpy(password,pwd);}} + TUnzip(const char *pwd) : uf(0), currentfile(-1), czei(-1), password(0), unzbuf(0) {if (pwd!=0) {password=new char[strlen(pwd)+1]; strcpy(password,pwd);}} ~TUnzip() {if (password!=0) delete[] password; password=0; if (unzbuf!=0) delete[] unzbuf; unzbuf=0;} unzFile uf; int currentfile; ZIPENTRY cze; int czei; @@ -3902,7 +3908,7 @@ ZRESULT TUnzip::Open(void *z,unsigned int len,DWORD flags) // if (flags==ZIP_HANDLE) { // test if we can seek on it. We can't use GetFileType(h)==FILE_TYPE_DISK since it's not on CE. - DWORD res = GetFilePosU((HANDLE)z); + DWORD res = GetFilePosU((ZIPHANDLE)z); bool canseek = (res!=0xFFFFFFFF); if (!canseek) return ZR_SEEK; } @@ -4000,7 +4006,7 @@ ZRESULT TUnzip::Get(int index,ZIPENTRY *ze) isdir= (a&0x00000010)!=0; archive= (a&0x00000020)!=0; } - readonly; hidden; system; isdir; archive; + ze->attr=0; #ifdef ZIP_STD ze->attr = (a&0xFFFF0000)>>16; @@ -4018,8 +4024,8 @@ ZRESULT TUnzip::Get(int index,ZIPENTRY *ze) // WORD dostime = (WORD)(ufi.dosDate&0xFFFF); WORD dosdate = (WORD)((ufi.dosDate>>16)&0xFFFF); - FILETIME ftd = dosdatetime2filetime(dosdate,dostime); - FILETIME ft; LocalFileTimeToFileTime(&ftd,&ft); + ZIPFILETIME ftd = dosdatetime2filetime(dosdate,dostime); + ZIPFILETIME ft; LocalFileTimeToFileTime(&ftd,&ft); ze->atime=ft; ze->ctime=ft; ze->mtime=ft; // the zip will always have at least that dostime. But if it also has // an extra header, then we'll instead get the info from that. @@ -4151,8 +4157,8 @@ ZRESULT TUnzip::Unzip(int index,void *dst,unsigned int len,DWORD flags) return ZR_OK; } // otherwise, we write the zipentry to a file/handle - HANDLE h; TCHAR fn[MAX_PATH]; fn[0]=0; - if (flags==ZIP_HANDLE) h=(HANDLE)dst; + ZIPHANDLE h; TCHAR fn[MAX_PATH]; fn[0]=0; + if (flags==ZIP_HANDLE) h=(ZIPHANDLE)dst; else { const TCHAR *ufn = (const TCHAR*)dst; // We'll qualify all relative names to our root dir, and leave absolute names as they are @@ -4177,7 +4183,7 @@ ZRESULT TUnzip::Unzip(int index,void *dst,unsigned int len,DWORD flags) if (h==INVALID_HANDLE_VALUE) return ZR_NOFILE; unzOpenCurrentFile(uf,password); if (unzbuf==0) unzbuf=new char[16384]; DWORD haderr=0; - // + // for (; haderr==0;) { bool reached_eof; @@ -4263,7 +4269,7 @@ HZIP OpenZipInternal(void *z,unsigned int len,DWORD flags, const char *password) TUnzipHandleData *han = new TUnzipHandleData; han->flag=1; han->unz=unz; return (HZIP)han; } -HZIP OpenZipHandle(HANDLE h, const char *password) {return OpenZipInternal((void*)h,0,ZIP_HANDLE,password);} +HZIP OpenZipHandle(ZIPHANDLE h, const char *password) {return OpenZipInternal((void*)h,0,ZIP_HANDLE,password);} HZIP OpenZip(const TCHAR *fn, const char *password) {return OpenZipInternal((void*)fn,0,ZIP_FILENAME,password);} HZIP OpenZip(void *z,unsigned int len, const char *password) {return OpenZipInternal(z,len,ZIP_MEMORY,password);} @@ -4295,7 +4301,7 @@ ZRESULT UnzipItemInternal(HZIP hz, int index, void *dst, unsigned int len, DWORD lasterrorU = unz->Unzip(index,dst,len,flags); return lasterrorU; } -ZRESULT UnzipItemHandle(HZIP hz, int index, HANDLE h) {return UnzipItemInternal(hz,index,(void*)h,0,ZIP_HANDLE);} +ZRESULT UnzipItemHandle(HZIP hz, int index, ZIPHANDLE h) {return UnzipItemInternal(hz,index,(void*)h,0,ZIP_HANDLE);} ZRESULT UnzipItem(HZIP hz, int index, const TCHAR *fn) {return UnzipItemInternal(hz,index,(void*)fn,0,ZIP_FILENAME);} ZRESULT UnzipItem(HZIP hz, int index, void *z,unsigned int len) {return UnzipItemInternal(hz,index,z,len,ZIP_MEMORY);} diff --git a/src/helper/zip_utils/unzip.h b/src/helper/zip_utils/unzip.h index e11e8282e..6f61c2c96 100644 --- a/src/helper/zip_utils/unzip.h +++ b/src/helper/zip_utils/unzip.h @@ -10,8 +10,11 @@ #endif typedef unsigned long DWORD; typedef char TCHAR; -typedef FILE* HANDLE; -typedef time_t FILETIME; +typedef FILE* ZIPHANDLE; +typedef time_t ZIPFILETIME; +#else +typedef HANDLE ZIPHANDLE; +typedef FILETIME ZIPFILETIME; #endif // UNZIPPING functions -- for unzipping. @@ -34,7 +37,7 @@ typedef struct { int index; // index of this file within the zip TCHAR name[MAX_PATH]; // filename within the zip DWORD attr; // attributes, as in GetFileAttributes. - FILETIME atime,ctime,mtime;// access, create, modify filetimes + ZIPFILETIME atime,ctime,mtime;// access, create, modify filetimes long comp_size; // sizes of item, compressed and uncompressed. These long unc_size; // may be -1 if not yet known (e.g. being streamed in) } ZIPENTRY; @@ -42,7 +45,7 @@ typedef struct HZIP OpenZip(const TCHAR *fn, const char *password); HZIP OpenZip(void *z,unsigned int len, const char *password); -HZIP OpenZipHandle(HANDLE h, const char *password); +HZIP OpenZipHandle(ZIPHANDLE h, const char *password); // OpenZip - opens a zip file and returns a handle with which you can // subsequently examine its contents. You can open a zip file from: // from a pipe: OpenZipHandle(hpipe_read,0); @@ -82,7 +85,7 @@ ZRESULT FindZipItem(HZIP hz, const TCHAR *name, bool ic, int *index, ZIPENTRY *z ZRESULT UnzipItem(HZIP hz, int index, const TCHAR *fn); ZRESULT UnzipItem(HZIP hz, int index, void *z,unsigned int len); -ZRESULT UnzipItemHandle(HZIP hz, int index, HANDLE h); +ZRESULT UnzipItemHandle(HZIP hz, int index, ZIPHANDLE h); // UnzipItem - given an index to an item, unzips it. You can unzip to: // to a pipe: UnzipItemHandle(hz,i, hpipe_write); // to a file (by handle): UnzipItemHandle(hz,i, hfile); diff --git a/src/helper/zip_utils/zip.cpp b/src/helper/zip_utils/zip.cpp index fd3cb4bf2..809a12ddd 100644 --- a/src/helper/zip_utils/zip.cpp +++ b/src/helper/zip_utils/zip.cpp @@ -633,7 +633,7 @@ struct TState // ---------------------------------------------------------------------- // some windows<->linux portability things #ifdef ZIP_STD -void filetime2dosdatetime(const FILETIME ft, WORD *dosdate, WORD *dostime) +void filetime2dosdatetime(const ZIPFILETIME ft, WORD *dosdate, WORD *dostime) { struct tm *st=gmtime(&ft); *dosdate = (ush)(((st->tm_year+1900 -1980)&0x7f) << 9); *dosdate |= (ush)((st->tm_mon&0xf) << 5); @@ -649,8 +649,8 @@ void GetNow(lutime_t *ft, WORD *dosdate, WORD *dostime) *ft = (lutime_t)tm; } -DWORD GetFilePosZ(HANDLE hfout) -{ struct stat st; fstat(fileno(hfout),&st); +DWORD GetFilePosZ(ZIPHANDLE hfout) +{ struct stat st; fstat(fileno(hfout),&st); if ((st.st_mode&S_IFREG)==0) return 0xFFFFFFFF; return ftell(hfout); } @@ -686,7 +686,7 @@ ZRESULT GetFileInfo(FILE *hf, ulg *attr, long *size, iztimes *times, ulg *timest // ---------------------------------------------------------------------- #else -void filetime2dosdatetime(const FILETIME ft, WORD *dosdate,WORD *dostime) +void filetime2dosdatetime(const ZIPFILETIME ft, WORD *dosdate,WORD *dostime) { // date: bits 0-4 are day of month 1-31. Bits 5-8 are month 1..12. Bits 9-15 are year-1980 // time: bits 0-4 are seconds/2, bits 5-10 are minute 0..59. Bits 11-15 are hour 0..23 SYSTEMTIME st; FileTimeToSystemTime(&ft,&st); @@ -698,24 +698,24 @@ void filetime2dosdatetime(const FILETIME ft, WORD *dosdate,WORD *dostime) *dostime |= (WORD)((st.wSecond*2)&0x1f); } -lutime_t filetime2timet(const FILETIME ft) -{ LONGLONG i = *(LONGLONG*)&ft; +lutime_t filetime2timet(const ZIPFILETIME ft) +{ LONGLONG i = *(LONGLONG*)&ft; return (lutime_t)((i-116444736000000000LL)/10000000LL); } void GetNow(lutime_t *pft, WORD *dosdate, WORD *dostime) { SYSTEMTIME st; GetLocalTime(&st); - FILETIME ft; SystemTimeToFileTime(&st,&ft); + ZIPFILETIME ft; SystemTimeToFileTime(&st,&ft); filetime2dosdatetime(ft,dosdate,dostime); *pft = filetime2timet(ft); } -DWORD GetFilePosZ(HANDLE hfout) +DWORD GetFilePosZ(ZIPHANDLE hfout) { return SetFilePointer(hfout,0,0,FILE_CURRENT); } -ZRESULT GetFileInfo(HANDLE hf, ulg *attr, long *size, iztimes *times, ulg *timestamp) +ZRESULT GetFileInfo(ZIPHANDLE hf, ulg *attr, long *size, iztimes *times, ulg *timestamp) { // The handle must be a handle to a file // The date and time is returned in a long with the date most significant to allow // unsigned integer comparison of absolute times. The attributes have two @@ -776,8 +776,8 @@ void Assert(TState &state,bool cond, const char *msg) { if (cond) return; state.err=msg; } -void Trace(const char *x, ...) {va_list paramList; va_start(paramList, x); paramList; va_end(paramList);} -void Tracec(bool ,const char *x, ...) {va_list paramList; va_start(paramList, x); paramList; va_end(paramList);} +void Trace(const char *x, ...) {va_list paramList; va_start(paramList, x); va_end(paramList);} +void Tracec(bool ,const char *x, ...) {va_list paramList; va_start(paramList, x); va_end(paramList);} @@ -1314,7 +1314,7 @@ void send_all_trees(TState &state,int lcodes, int dcodes, int blcodes) for (rank = 0; rank < blcodes; rank++) { Trace("\nbl code %2d ", bl_order[rank]); send_bits(state,state.ts.bl_tree[bl_order[rank]].dl.len, 3); - } + } Trace("\nbl tree: sent %ld", state.bs.bits_sent); send_tree(state,(ct_data *)state.ts.dyn_ltree, lcodes-1); /* send the literal tree */ @@ -1811,7 +1811,7 @@ int longest_match(TState &state,IPos cur_match) scan < strend); Assert(state,scan <= state.ds.window+(unsigned)(state.ds.window_size-1), "wild scan"); - + len = MAX_MATCH - (int)(strend - scan); scan = strend - MAX_MATCH; @@ -2340,15 +2340,15 @@ bool HasZipSuffix(const TCHAR *fn) class TZip { public: - TZip(const char *pwd) : hfout(0),mustclosehfout(false),hmapout(0),zfis(0),obuf(0),hfin(0),writ(0),oerr(false),hasputcen(false),ooffset(0),encwriting(false),encbuf(0),password(0), state(0) {if (pwd!=0 && *pwd!=0) {password=new char[strlen(pwd)+1]; strcpy(password,pwd);}} + TZip(const char *pwd) : password(0),hfout(0),mustclosehfout(false),hmapout(0),ooffset(0),oerr(false),writ(0),obuf(0),hasputcen(false),encwriting(false),encbuf(0),zfis(0),state(0),hfin(0) {if (pwd!=0 && *pwd!=0) {password=new char[strlen(pwd)+1]; strcpy(password,pwd);}} ~TZip() {if (state!=0) delete state; state=0; if (encbuf!=0) delete[] encbuf; encbuf=0; if (password!=0) delete[] password; password=0;} // These variables say about the file we're writing into // We can write to pipe, file-by-handle, file-by-name, memory-to-memmapfile char *password; // keep a copy of the password - HANDLE hfout; // if valid, we'll write here (for files or pipes) + ZIPHANDLE hfout; // if valid, we'll write here (for files or pipes) bool mustclosehfout; // if true, we are responsible for closing hfout - HANDLE hmapout; // otherwise, we'll write here (for memmap) + ZIPHANDLE hmapout; // otherwise, we'll write here (for memmap) unsigned ooffset; // for hfout, this is where the pointer was initially ZRESULT oerr; // did a write operation give rise to an error? unsigned writ; // how far have we written. This is maintained by Add, not write(), to avoid confusion over seeks @@ -2379,7 +2379,7 @@ class TZip ulg attr; iztimes times; ulg timestamp; // all open_* methods set these bool iseekable; long isize,ired; // size is not set until close() on pips ulg crc; // crc is not set until close(). iwrit is cumulative - HANDLE hfin; bool selfclosehf; // for input files and pipes + ZIPHANDLE hfin; bool selfclosehf; // for input files and pipes const char *bufin; unsigned int lenin,posin; // for memory // and a variable for what we've done with the input: (i.e. compressed it!) ulg csize; // compressed size, set by the compression routines @@ -2388,7 +2388,7 @@ class TZip ZRESULT open_file(const TCHAR *fn); - ZRESULT open_handle(HANDLE hf,unsigned int len); + ZRESULT open_handle(ZIPHANDLE hf,unsigned int len); ZRESULT open_mem(void *src,unsigned int len); ZRESULT open_dir(); static unsigned sread(TState &s,char *buf,unsigned size); @@ -2409,7 +2409,7 @@ ZRESULT TZip::Create(void *z,unsigned int len,DWORD flags) { if (hfout!=0 || hmapout!=0 || obuf!=0 || writ!=0 || oerr!=ZR_OK || hasputcen) return ZR_NOTINITED; // if (flags==ZIP_HANDLE) - { HANDLE hf = (HANDLE)z; + { ZIPHANDLE hf = (ZIPHANDLE)z; hfout=hf; mustclosehfout=false; #ifdef DuplicateHandle BOOL res = DuplicateHandle(GetCurrentProcess(),hf,GetCurrentProcess(),&hfout,0,FALSE,DUPLICATE_SAME_ACCESS); @@ -2506,7 +2506,7 @@ bool TZip::oseek(unsigned int pos) return true; } else if (hfout!=0) - { + { #ifdef ZIP_STD fseek(hfout,pos+ooffset,SEEK_SET); #else @@ -2549,12 +2549,12 @@ ZRESULT TZip::open_file(const TCHAR *fn) { hfin=0; bufin=0; selfclosehf=false; crc=CRCVAL_INITIAL; isize=0; csize=0; ired=0; if (fn==0) return ZR_ARGS; #ifdef ZIP_STD - HANDLE hf = fopen(fn,"rb"); + ZIPHANDLE hf = fopen(fn,"rb"); if (hf==0) return ZR_NOFILE; ZRESULT res = open_handle(hf,0); if (res!=ZR_OK) {fclose(hf); return res;} #else - HANDLE hf = CreateFile(fn,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL); + ZIPHANDLE hf = CreateFile(fn,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL); if (hf==INVALID_HANDLE_VALUE) return ZR_NOFILE; ZRESULT res = open_handle(hf,0); if (res!=ZR_OK) {CloseHandle(hf); return res;} @@ -2562,7 +2562,7 @@ ZRESULT TZip::open_file(const TCHAR *fn) selfclosehf=true; return ZR_OK; } -ZRESULT TZip::open_handle(HANDLE hf,unsigned int len) +ZRESULT TZip::open_handle(ZIPHANDLE hf,unsigned int len) { hfin=0; bufin=0; selfclosehf=false; crc=CRCVAL_INITIAL; isize=0; csize=0; ired=0; if (hf==0 || hf==INVALID_HANDLE_VALUE) return ZR_ARGS; bool canseek; @@ -2655,7 +2655,7 @@ unsigned TZip::read(char *buf, unsigned size) } ZRESULT TZip::iclose() -{ +{ #ifdef ZIP_STD if (selfclosehf && hfin!=0) fclose(hfin); hfin=0; #else @@ -2725,7 +2725,7 @@ ZRESULT TZip::Add(const TCHAR *odstzn, void *src,unsigned int len, DWORD flags) // now open whatever was our input source: ZRESULT openres; if (flags==ZIP_FILENAME) openres=open_file((const TCHAR*)src); - else if (flags==ZIP_HANDLE) openres=open_handle((HANDLE)src,len); + else if (flags==ZIP_HANDLE) openres=open_handle((ZIPHANDLE)src,len); else if (flags==ZIP_MEMORY) openres=open_mem(src,len); else if (flags==ZIP_FOLDER) openres=open_dir(); else return ZR_ARGS; @@ -2942,7 +2942,7 @@ HZIP CreateZipInternal(void *z,unsigned int len,DWORD flags, const char *passwor TZipHandleData *han = new TZipHandleData; han->flag=2; han->zip=zip; return (HZIP)han; } -HZIP CreateZipHandle(HANDLE h, const char *password) {return CreateZipInternal(h,0,ZIP_HANDLE,password);} +HZIP CreateZipHandle(ZIPHANDLE h, const char *password) {return CreateZipInternal(h,0,ZIP_HANDLE,password);} HZIP CreateZip(const TCHAR *fn, const char *password) {return CreateZipInternal((void*)fn,0,ZIP_FILENAME,password);} HZIP CreateZip(void *z,unsigned int len, const char *password) {return CreateZipInternal(z,len,ZIP_MEMORY,password);} @@ -2957,8 +2957,8 @@ ZRESULT ZipAddInternal(HZIP hz,const TCHAR *dstzn, void *src,unsigned int len, D } ZRESULT ZipAdd(HZIP hz,const TCHAR *dstzn, const TCHAR *fn) {return ZipAddInternal(hz,dstzn,(void*)fn,0,ZIP_FILENAME);} ZRESULT ZipAdd(HZIP hz,const TCHAR *dstzn, void *src,unsigned int len) {return ZipAddInternal(hz,dstzn,src,len,ZIP_MEMORY);} -ZRESULT ZipAddHandle(HZIP hz,const TCHAR *dstzn, HANDLE h) {return ZipAddInternal(hz,dstzn,h,0,ZIP_HANDLE);} -ZRESULT ZipAddHandle(HZIP hz,const TCHAR *dstzn, HANDLE h, unsigned int len) {return ZipAddInternal(hz,dstzn,h,len,ZIP_HANDLE);} +ZRESULT ZipAddHandle(HZIP hz,const TCHAR *dstzn, ZIPHANDLE h) {return ZipAddInternal(hz,dstzn,h,0,ZIP_HANDLE);} +ZRESULT ZipAddHandle(HZIP hz,const TCHAR *dstzn, ZIPHANDLE h, unsigned int len) {return ZipAddInternal(hz,dstzn,h,len,ZIP_HANDLE);} ZRESULT ZipAddFolder(HZIP hz,const TCHAR *dstzn) {return ZipAddInternal(hz,dstzn,0,0,ZIP_FOLDER);} diff --git a/src/helper/zip_utils/zip.h b/src/helper/zip_utils/zip.h index b98613a36..b453105fb 100644 --- a/src/helper/zip_utils/zip.h +++ b/src/helper/zip_utils/zip.h @@ -10,8 +10,8 @@ #endif typedef unsigned long DWORD; typedef char TCHAR; -typedef FILE* HANDLE; -typedef time_t FILETIME; +typedef FILE* ZIPHANDLE; +typedef time_t ZIPFILETIME; #endif // ZIP functions -- for creating zip files @@ -33,7 +33,7 @@ typedef DWORD ZRESULT; HZIP CreateZip(const TCHAR *fn, const char *password); HZIP CreateZip(void *buf,unsigned int len, const char *password); -HZIP CreateZipHandle(HANDLE h, const char *password); +HZIP CreateZipHandle(ZIPHANDLE h, const char *password); // CreateZip - call this to start the creation of a zip file. // As the zip is being created, it will be stored somewhere: // to a pipe: CreateZipHandle(hpipe_write); @@ -67,8 +67,8 @@ HZIP CreateZipHandle(HANDLE h, const char *password); ZRESULT ZipAdd(HZIP hz,const TCHAR *dstzn, const TCHAR *fn); ZRESULT ZipAdd(HZIP hz,const TCHAR *dstzn, void *src,unsigned int len); -ZRESULT ZipAddHandle(HZIP hz,const TCHAR *dstzn, HANDLE h); -ZRESULT ZipAddHandle(HZIP hz,const TCHAR *dstzn, HANDLE h, unsigned int len); +ZRESULT ZipAddHandle(HZIP hz,const TCHAR *dstzn, ZIPHANDLE h); +ZRESULT ZipAddHandle(HZIP hz,const TCHAR *dstzn, ZIPHANDLE h, unsigned int len); ZRESULT ZipAddFolder(HZIP hz,const TCHAR *dstzn); // ZipAdd - call this for each file to be added to the zip. // dstzn is the name that the file will be stored as in the zip file. diff --git a/src/math/math.hpp b/src/math/math.hpp index d2ccb6613..c6ce72273 100755 --- a/src/math/math.hpp +++ b/src/math/math.hpp @@ -47,7 +47,7 @@ T NextPowOfTwo( T Size ) { template T LineAngle( const T& X1, const T& Y1, const T& X2, const T& Y2 ) { - return atan2(Y2 - Y1, X2 - X1) * d180PI; + return atan2( (eeFloat)(Y2 - Y1), (eeFloat)(X2 - X1) ) * d180PI; } eeFloat EE_API LineAngle( const eeVector2f& p1, const eeVector2f& p2 ); @@ -75,7 +75,7 @@ void EE_API RotateVectorCentered( eeVector2f* p, const eeFloat& Angle, const eeV template T Distance( T x1, T y1, T x2, T y2 ) { - return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); + return sqrt( (eeFloat)( (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) ) ); } eeFloat EE_API Distance( const eeVector2f& p1, const eeVector2f& p2); diff --git a/src/system/cinifile.cpp b/src/system/cinifile.cpp index 1eed83124..4f2b09d8e 100755 --- a/src/system/cinifile.cpp +++ b/src/system/cinifile.cpp @@ -66,7 +66,7 @@ bool cIniFile::ReadFile() { // Note that the '\r' will be written to INI files from // Unix so that the created INI file can be read under Win32 // without change. - if ( line[line.length() - 1] == '\r' ) + if ( line.length() && line[line.length() - 1] == '\r' ) line = line.substr ( 0, line.length() - 1 ); if ( line.length() ) { diff --git a/src/test/ee.cpp b/src/test/ee.cpp index fd58e446c..fa1825920 100644 --- a/src/test/ee.cpp +++ b/src/test/ee.cpp @@ -1,7 +1,6 @@ #include "../ee.h" /** -@TODO Remove SDL_ttf dependency, use Free Type directly ( the license is restrictive ). @TODO Create a asynchronous resource loader ( at least for textures ). @TODO Create a basic UI system ( add basic controls, add skinning support ). @TODO Add support for Joysticks.