diff options
author | Kent Mein <mein@cs.umn.edu> | 2005-01-21 08:15:33 +0300 |
---|---|---|
committer | Kent Mein <mein@cs.umn.edu> | 2005-01-21 08:15:33 +0300 |
commit | 26f63bfa197e82a6d3a3f298c603f1878891b8f8 (patch) | |
tree | 370880862bd533224e42e7b374f39a43279e79f8 /extern/bFTGL/src | |
parent | b561ca88cfc2445b82c3dc59bdbb8d9e46ee7e31 (diff) |
Added bFTGL to extern and updated the Makefiles. I'm guessing there will
need to be tweaks but it seems to work on my linux box. I haven't
touched any of the other build systems so those will need to be done.
We probably don't need all of this stuff but I figured better to add a little
too much then to little.
Kent
Diffstat (limited to 'extern/bFTGL/src')
25 files changed, 2291 insertions, 0 deletions
diff --git a/extern/bFTGL/src/FTBitmapGlyph.cpp b/extern/bFTGL/src/FTBitmapGlyph.cpp new file mode 100755 index 00000000000..5db33f10c79 --- /dev/null +++ b/extern/bFTGL/src/FTBitmapGlyph.cpp @@ -0,0 +1,66 @@ +#include <string> + +#include "FTBitmapGlyph.h" + +FTBitmapGlyph::FTBitmapGlyph( FT_GlyphSlot glyph) +: FTGlyph( glyph), + destWidth(0), + destHeight(0), + data(0) +{ + err = FT_Render_Glyph( glyph, FT_RENDER_MODE_MONO); + if( err || ft_glyph_format_bitmap != glyph->format) + { + return; + } + + FT_Bitmap bitmap = glyph->bitmap; + + unsigned int srcWidth = bitmap.width; + unsigned int srcHeight = bitmap.rows; + unsigned int srcPitch = bitmap.pitch; + + destWidth = srcWidth; + destHeight = srcHeight; + destPitch = srcPitch; + + if( destWidth && destHeight) + { + data = new unsigned char[destPitch * destHeight]; + unsigned char* dest = data + (( destHeight - 1) * destPitch); + + unsigned char* src = bitmap.buffer; + + for( unsigned int y = 0; y < srcHeight; ++y) + { + memcpy( dest, src, srcPitch); + dest -= destPitch; + src += srcPitch; + } + } + + pos.x = glyph->bitmap_left; + pos.y = static_cast<int>(srcHeight) - glyph->bitmap_top; +} + + +FTBitmapGlyph::~FTBitmapGlyph() +{ + delete [] data; +} + + +float FTBitmapGlyph::Render( const FTPoint& pen) +{ + if( data) + { + glBitmap( 0, 0, 0.0, 0.0, pen.x + pos.x, pen.y - pos.y, (const GLubyte*)0 ); + + glPixelStorei( GL_UNPACK_ROW_LENGTH, destPitch * 8); + glBitmap( destWidth, destHeight, 0.0f, 0.0, 0.0, 0.0, (const GLubyte*)data); + + glBitmap( 0, 0, 0.0, 0.0, -pen.x - pos.x, -pen.y + pos.y, (const GLubyte*)0 ); + } + + return advance; +} diff --git a/extern/bFTGL/src/FTBufferGlyph.cpp b/extern/bFTGL/src/FTBufferGlyph.cpp new file mode 100755 index 00000000000..27310103152 --- /dev/null +++ b/extern/bFTGL/src/FTBufferGlyph.cpp @@ -0,0 +1,59 @@ +#include "FTBufferGlyph.h" + +FTBufferGlyph::FTBufferGlyph( FT_GlyphSlot glyph, unsigned char* b) +: FTGlyph( glyph), + destWidth(0), + destHeight(0), + data(0), + buffer(b) +{ + err = FT_Render_Glyph( glyph, FT_RENDER_MODE_NORMAL); + if( err || ft_glyph_format_bitmap != glyph->format) + { + return; + } + + FT_Bitmap bitmap = glyph->bitmap; + + unsigned int srcWidth = bitmap.width; + unsigned int srcHeight = bitmap.rows; + unsigned int srcPitch = bitmap.pitch; + + destWidth = srcWidth; + destHeight = srcHeight; + destPitch = srcPitch; + + if( destWidth && destHeight) + { + data = new unsigned char[destPitch * destHeight]; + unsigned char* dest = data + (( destHeight - 1) * destPitch); + + unsigned char* src = bitmap.buffer; + + for( unsigned int y = 0; y < srcHeight; ++y) + { + memcpy( dest, src, srcPitch); + dest -= destPitch; + src += srcPitch; + } + } + + pos.x = glyph->bitmap_left; + pos.y = srcHeight - glyph->bitmap_top; +} + + +FTBufferGlyph::~FTBufferGlyph() +{ + delete [] data; +} + + +float FTBufferGlyph::Render( const FTPoint& pen) +{ + if( data && buffer) + { + } + + return advance; +} diff --git a/extern/bFTGL/src/FTCharmap.cpp b/extern/bFTGL/src/FTCharmap.cpp new file mode 100644 index 00000000000..f2400eea0f6 --- /dev/null +++ b/extern/bFTGL/src/FTCharmap.cpp @@ -0,0 +1,62 @@ +#include "FTFace.h" +#include "FTCharmap.h" + + +FTCharmap::FTCharmap( FTFace* face) +: ftFace( *(face->Face())), + err(0) +{ + if( !ftFace->charmap) + { + err = FT_Set_Charmap( ftFace, ftFace->charmaps[0]); + } + + ftEncoding = ftFace->charmap->encoding; +} + + +FTCharmap::~FTCharmap() +{ + charMap.clear(); +} + + +bool FTCharmap::CharMap( FT_Encoding encoding) +{ + if( ftEncoding == encoding) + { + return true; + } + + err = FT_Select_Charmap( ftFace, encoding ); + + if( !err) + { + ftEncoding = encoding; + } + else + { + ftEncoding = ft_encoding_none; + } + + charMap.clear(); + return !err; +} + + +unsigned int FTCharmap::GlyphListIndex( unsigned int characterCode ) +{ + return charMap.find( characterCode); +} + + +unsigned int FTCharmap::FontIndex( unsigned int characterCode ) +{ + return FT_Get_Char_Index( ftFace, characterCode); +} + + +void FTCharmap::InsertIndex( const unsigned int characterCode, const unsigned int containerIndex) +{ + charMap.insert( characterCode, containerIndex); +} diff --git a/extern/bFTGL/src/FTContour.cpp b/extern/bFTGL/src/FTContour.cpp new file mode 100644 index 00000000000..6b0cf8a23e1 --- /dev/null +++ b/extern/bFTGL/src/FTContour.cpp @@ -0,0 +1,149 @@ +#include "FTContour.h" + +static const float BEZIER_STEP_SIZE = 0.2f; + + +void FTContour::AddPoint( FTPoint point) +{ + if( pointList.empty() || point != pointList[pointList.size() - 1]) + { + pointList.push_back( point); + } +} + + +void FTContour::AddPoint( float x, float y) +{ + AddPoint( FTPoint( x, y, 0.0f)); +} + + +void FTContour::evaluateQuadraticCurve() +{ + for( unsigned int i = 0; i <= ( 1.0f / BEZIER_STEP_SIZE); i++) + { + float bezierValues[2][2]; + + float t = static_cast<float>(i) * BEZIER_STEP_SIZE; + + bezierValues[0][0] = (1.0f - t) * controlPoints[0][0] + t * controlPoints[1][0]; + bezierValues[0][1] = (1.0f - t) * controlPoints[0][1] + t * controlPoints[1][1]; + + bezierValues[1][0] = (1.0f - t) * controlPoints[1][0] + t * controlPoints[2][0]; + bezierValues[1][1] = (1.0f - t) * controlPoints[1][1] + t * controlPoints[2][1]; + + bezierValues[0][0] = (1.0f - t) * bezierValues[0][0] + t * bezierValues[1][0]; + bezierValues[0][1] = (1.0f - t) * bezierValues[0][1] + t * bezierValues[1][1]; + + AddPoint( bezierValues[0][0], bezierValues[0][1]); + } +} + +void FTContour::evaluateCubicCurve() +{ + for( unsigned int i = 0; i <= ( 1.0f / BEZIER_STEP_SIZE); i++) + { + float bezierValues[3][2]; + + float t = static_cast<float>(i) * BEZIER_STEP_SIZE; + + bezierValues[0][0] = (1.0f - t) * controlPoints[0][0] + t * controlPoints[1][0]; + bezierValues[0][1] = (1.0f - t) * controlPoints[0][1] + t * controlPoints[1][1]; + + bezierValues[1][0] = (1.0f - t) * controlPoints[1][0] + t * controlPoints[2][0]; + bezierValues[1][1] = (1.0f - t) * controlPoints[1][1] + t * controlPoints[2][1]; + + bezierValues[2][0] = (1.0f - t) * controlPoints[2][0] + t * controlPoints[3][0]; + bezierValues[2][1] = (1.0f - t) * controlPoints[2][1] + t * controlPoints[3][1]; + + bezierValues[0][0] = (1.0f - t) * bezierValues[0][0] + t * bezierValues[1][0]; + bezierValues[0][1] = (1.0f - t) * bezierValues[0][1] + t * bezierValues[1][1]; + + bezierValues[1][0] = (1.0f - t) * bezierValues[1][0] + t * bezierValues[2][0]; + bezierValues[1][1] = (1.0f - t) * bezierValues[1][1] + t * bezierValues[2][1]; + + bezierValues[0][0] = (1.0f - t) * bezierValues[0][0] + t * bezierValues[1][0]; + bezierValues[0][1] = (1.0f - t) * bezierValues[0][1] + t * bezierValues[1][1]; + + AddPoint( bezierValues[0][0], bezierValues[0][1]); + } +} + + +FTContour::FTContour( FT_Vector* contour, char* pointTags, unsigned int numberOfPoints) +{ + for( unsigned int pointIndex = 0; pointIndex < numberOfPoints; ++ pointIndex) + { + char pointTag = pointTags[pointIndex]; + + if( pointTag == FT_Curve_Tag_On || numberOfPoints < 2) + { + AddPoint( contour[pointIndex].x, contour[pointIndex].y); + continue; + } + + FTPoint controlPoint( contour[pointIndex]); + FTPoint previousPoint = ( 0 == pointIndex) + ? FTPoint( contour[numberOfPoints - 1]) + : pointList[pointList.size() - 1]; + + FTPoint nextPoint = ( pointIndex == numberOfPoints - 1) + ? pointList[0] + : FTPoint( contour[pointIndex + 1]); + + if( pointTag == FT_Curve_Tag_Conic) + { + char nextPointTag = ( pointIndex == numberOfPoints - 1) + ? pointTags[0] + : pointTags[pointIndex + 1]; + + while( nextPointTag == FT_Curve_Tag_Conic) + { + nextPoint = FTPoint( static_cast<float>( controlPoint.x + nextPoint.x) * 0.5f, + static_cast<float>( controlPoint.y + nextPoint.y) * 0.5f, + 0); + + controlPoints[0][0] = previousPoint.x; controlPoints[0][1] = previousPoint.y; + controlPoints[1][0] = controlPoint.x; controlPoints[1][1] = controlPoint.y; + controlPoints[2][0] = nextPoint.x; controlPoints[2][1] = nextPoint.y; + + evaluateQuadraticCurve(); + ++pointIndex; + + previousPoint = nextPoint; + controlPoint = FTPoint( contour[pointIndex]); + nextPoint = ( pointIndex == numberOfPoints - 1) + ? pointList[0] + : FTPoint( contour[pointIndex + 1]); + nextPointTag = ( pointIndex == numberOfPoints - 1) + ? pointTags[0] + : pointTags[pointIndex + 1]; + } + + controlPoints[0][0] = previousPoint.x; controlPoints[0][1] = previousPoint.y; + controlPoints[1][0] = controlPoint.x; controlPoints[1][1] = controlPoint.y; + controlPoints[2][0] = nextPoint.x; controlPoints[2][1] = nextPoint.y; + + evaluateQuadraticCurve(); + continue; + } + + if( pointTag == FT_Curve_Tag_Cubic) + { + FTPoint controlPoint2 = nextPoint; + + FTPoint nextPoint = ( pointIndex == numberOfPoints - 2) + ? pointList[0] + : FTPoint( contour[pointIndex + 2]); + + controlPoints[0][0] = previousPoint.x; controlPoints[0][1] = previousPoint.y; + controlPoints[1][0] = controlPoint.x; controlPoints[1][1] = controlPoint.y; + controlPoints[2][0] = controlPoint2.x; controlPoints[2][1] = controlPoint2.y; + controlPoints[3][0] = nextPoint.x; controlPoints[3][1] = nextPoint.y; + + evaluateCubicCurve(); + ++pointIndex; + continue; + } + } +} diff --git a/extern/bFTGL/src/FTExtrdGlyph.cpp b/extern/bFTGL/src/FTExtrdGlyph.cpp new file mode 100644 index 00000000000..0b120e68709 --- /dev/null +++ b/extern/bFTGL/src/FTExtrdGlyph.cpp @@ -0,0 +1,141 @@ +#include <math.h> + +#include "FTExtrdGlyph.h" +#include "FTVectoriser.h" + + +FTExtrdGlyph::FTExtrdGlyph( FT_GlyphSlot glyph, float d) +: FTGlyph( glyph), + glList(0), + depth(d) +{ + bBox.SetDepth( -depth); + + if( ft_glyph_format_outline != glyph->format) + { + err = 0x14; // Invalid_Outline + return; + } + + FTVectoriser vectoriser( glyph); + if ( ( vectoriser.ContourCount() < 1) || ( vectoriser.PointCount() < 3)) + { + return; + } + + unsigned int tesselationIndex; + glList = glGenLists(1); + glNewList( glList, GL_COMPILE); + + vectoriser.MakeMesh( 1.0); + glNormal3d(0.0, 0.0, 1.0); + + const FTMesh* mesh = vectoriser.GetMesh(); + for( tesselationIndex = 0; tesselationIndex < mesh->TesselationCount(); ++tesselationIndex) + { + const FTTesselation* subMesh = mesh->Tesselation( tesselationIndex); + unsigned int polyonType = subMesh->PolygonType(); + + glBegin( polyonType); + for( unsigned int pointIndex = 0; pointIndex < subMesh->PointCount(); ++pointIndex) + { + glVertex3f( subMesh->Point( pointIndex).x / 64.0f, + subMesh->Point( pointIndex).y / 64.0f, + 0.0f); + } + glEnd(); + } + + vectoriser.MakeMesh( -1.0); + glNormal3d(0.0, 0.0, -1.0); + + mesh = vectoriser.GetMesh(); + for( tesselationIndex = 0; tesselationIndex < mesh->TesselationCount(); ++tesselationIndex) + { + const FTTesselation* subMesh = mesh->Tesselation( tesselationIndex); + unsigned int polyonType = subMesh->PolygonType(); + + glBegin( polyonType); + for( unsigned int pointIndex = 0; pointIndex < subMesh->PointCount(); ++pointIndex) + { + glVertex3f( subMesh->Point( pointIndex).x / 64.0f, + subMesh->Point( pointIndex).y / 64.0f, + -depth); + } + glEnd(); + } + + int contourFlag = vectoriser.ContourFlag(); + + for( size_t c = 0; c < vectoriser.ContourCount(); ++c) + { + const FTContour* contour = vectoriser.Contour(c); + unsigned int numberOfPoints = contour->PointCount(); + + glBegin( GL_QUAD_STRIP); + for( unsigned int j = 0; j <= numberOfPoints; ++j) + { + unsigned int index = ( j == numberOfPoints) ? 0 : j; + unsigned int nextIndex = ( index == numberOfPoints - 1) ? 0 : index + 1; + + FTPoint normal = GetNormal( contour->Point(index), contour->Point(nextIndex)); + glNormal3f( normal.x, normal.y, 0.0f); + + if( contourFlag & ft_outline_reverse_fill) + { + glVertex3f( contour->Point(index).x / 64.0f, contour->Point(index).y / 64.0f, 0.0f); + glVertex3f( contour->Point(index).x / 64.0f, contour->Point(index).y / 64.0f, -depth); + } + else + { + glVertex3f( contour->Point(index).x / 64.0f, contour->Point(index).y / 64.0f, -depth); + glVertex3f( contour->Point(index).x / 64.0f, contour->Point(index).y / 64.0f, 0.0f); + } + } + glEnd(); + } + + glEndList(); +} + + +FTExtrdGlyph::~FTExtrdGlyph() +{ + glDeleteLists( glList, 1); +} + + +float FTExtrdGlyph::Render( const FTPoint& pen) +{ + if( glList) + { + glTranslatef( pen.x, pen.y, 0); + glCallList( glList); + glTranslatef( -pen.x, -pen.y, 0); + } + + return advance; +} + + +FTPoint FTExtrdGlyph::GetNormal( const FTPoint &a, const FTPoint &b) +{ + float vectorX = a.x - b.x; + float vectorY = a.y - b.y; + + float length = sqrt( vectorX * vectorX + vectorY * vectorY ); + + if( length > 0.0f) + { + length = 1 / length; + } + else + { + length = 0.0f; + } + + return FTPoint( -vectorY * length, + vectorX * length, + 0.0f); +} + diff --git a/extern/bFTGL/src/FTFace.cpp b/extern/bFTGL/src/FTFace.cpp new file mode 100755 index 00000000000..0385e234d6c --- /dev/null +++ b/extern/bFTGL/src/FTFace.cpp @@ -0,0 +1,154 @@ +#include "FTFace.h" +#include "FTLibrary.h" + +#include FT_TRUETYPE_TABLES_H + +FTFace::FTFace( const char* filename) +: numGlyphs(0), + fontEncodingList(0), + err(0) +{ + const FT_Long DEFAULT_FACE_INDEX = 0; + ftFace = new FT_Face; + + err = FT_New_Face( *FTLibrary::Instance().GetLibrary(), filename, DEFAULT_FACE_INDEX, ftFace); + + if( err) + { + delete ftFace; + ftFace = 0; + } + else + { + numGlyphs = (*ftFace)->num_glyphs; + } +} + + +FTFace::FTFace( const unsigned char *pBufferBytes, size_t bufferSizeInBytes) +: numGlyphs(0), + err(0) +{ + const FT_Long DEFAULT_FACE_INDEX = 0; + ftFace = new FT_Face; + + err = FT_New_Memory_Face( *FTLibrary::Instance().GetLibrary(), (FT_Byte *)pBufferBytes, bufferSizeInBytes, DEFAULT_FACE_INDEX, ftFace); + + if( err) + { + delete ftFace; + ftFace = 0; + } + else + { + numGlyphs = (*ftFace)->num_glyphs; + } +} + + +FTFace::~FTFace() +{ + Close(); +} + + +bool FTFace::Attach( const char* filename) +{ + err = FT_Attach_File( *ftFace, filename); + return !err; +} + + +bool FTFace::Attach( const unsigned char *pBufferBytes, size_t bufferSizeInBytes) +{ + FT_Open_Args open; + + open.flags = FT_OPEN_MEMORY; + open.memory_base = (FT_Byte *)pBufferBytes; + open.memory_size = bufferSizeInBytes; + + err = FT_Attach_Stream( *ftFace, &open); + return !err; +} + + +void FTFace::Close() +{ + if( ftFace) + { + FT_Done_Face( *ftFace); + delete ftFace; + ftFace = 0; + } +} + + +const FTSize& FTFace::Size( const unsigned int size, const unsigned int res) +{ + charSize.CharSize( ftFace, size, res, res); + err = charSize.Error(); + + return charSize; +} + + +unsigned int FTFace::CharMapCount() +{ + return (*ftFace)->num_charmaps; +} + + +FT_Encoding* FTFace::CharMapList() +{ + if( 0 == fontEncodingList) + { + fontEncodingList = new FT_Encoding[CharMapCount()]; + for( size_t encodingIndex = 0; encodingIndex < CharMapCount(); ++encodingIndex) + { + fontEncodingList[encodingIndex] = (*ftFace)->charmaps[encodingIndex]->encoding; + } + } + + return fontEncodingList; +} + + +unsigned int FTFace::UnitsPerEM() const +{ + return (*ftFace)->units_per_EM; +} + + +FTPoint FTFace::KernAdvance( unsigned int index1, unsigned int index2) +{ + float x, y; + x = y = 0.0f; + + if( FT_HAS_KERNING((*ftFace)) && index1 && index2) + { + FT_Vector kernAdvance; + kernAdvance.x = kernAdvance.y = 0; + + err = FT_Get_Kerning( *ftFace, index1, index2, ft_kerning_unfitted, &kernAdvance); + if( !err) + { + x = static_cast<float>( kernAdvance.x) / 64.0f; + y = static_cast<float>( kernAdvance.y) / 64.0f; + } + } + + return FTPoint( x, y, 0.0); +} + + +FT_GlyphSlot FTFace::Glyph( unsigned int index, FT_Int load_flags) +{ + err = FT_Load_Glyph( *ftFace, index, load_flags); + if( err) + { + return NULL; + } + + return (*ftFace)->glyph; +} + diff --git a/extern/bFTGL/src/FTFont.cpp b/extern/bFTGL/src/FTFont.cpp new file mode 100755 index 00000000000..c06d883104b --- /dev/null +++ b/extern/bFTGL/src/FTFont.cpp @@ -0,0 +1,271 @@ +#include "FTFace.h" +#include "FTFont.h" +#include "FTGlyphContainer.h" +#include "FTBBox.h" + + +FTFont::FTFont( const char* fontname) +: face( fontname), + glyphList(0) +{ + err = face.Error(); + if( err == 0) + { + glyphList = new FTGlyphContainer( &face); + } +} + + +FTFont::FTFont( const unsigned char *pBufferBytes, size_t bufferSizeInBytes) +: face( pBufferBytes, bufferSizeInBytes), + glyphList(0) +{ + err = face.Error(); + if( err == 0) + { + glyphList = new FTGlyphContainer( &face); + } +} + + +FTFont::~FTFont() +{ + delete glyphList; +} + + +bool FTFont::Attach( const char* filename) +{ + if( face.Attach( filename)) + { + err = 0; + return true; + } + else + { + err = face.Error(); + return false; + } +} + + +bool FTFont::Attach( const unsigned char *pBufferBytes, size_t bufferSizeInBytes) +{ + if( face.Attach( pBufferBytes, bufferSizeInBytes)) + { + err = 0; + return true; + } + else + { + err = face.Error(); + return false; + } +} + + +bool FTFont::FaceSize( const unsigned int size, const unsigned int res ) +{ + charSize = face.Size( size, res); + + if( face.Error()) + { + return false; + } + + if( glyphList != NULL) + { + delete glyphList; + } + + glyphList = new FTGlyphContainer( &face); + return true; +} + + +unsigned int FTFont::FaceSize() const +{ + return charSize.CharSize(); +} + + +bool FTFont::CharMap( FT_Encoding encoding) +{ + bool result = glyphList->CharMap( encoding); + err = glyphList->Error(); + return result; +} + + +unsigned int FTFont::CharMapCount() +{ + return face.CharMapCount(); +} + + +FT_Encoding* FTFont::CharMapList() +{ + return face.CharMapList(); +} + + +float FTFont::Ascender() const +{ + return charSize.Ascender(); +} + + +float FTFont::Descender() const +{ + return charSize.Descender(); +} + + +void FTFont::BBox( const char* string, + float& llx, float& lly, float& llz, float& urx, float& ury, float& urz) +{ + FTBBox totalBBox; + + if((NULL != string) && ('\0' != *string)) + { + const unsigned char* c = (unsigned char*)string; + + CheckGlyph( *c); + + totalBBox = glyphList->BBox( *c); + float advance = glyphList->Advance( *c, *(c + 1)); + ++c; + + while( *c) + { + CheckGlyph( *c); + FTBBox tempBBox = glyphList->BBox( *c); + tempBBox.Move( FTPoint( advance, 0.0f, 0.0f)); + totalBBox += tempBBox; + advance += glyphList->Advance( *c, *(c + 1)); + ++c; + } + } + + llx = totalBBox.lowerX; + lly = totalBBox.lowerY; + llz = totalBBox.lowerZ; + urx = totalBBox.upperX; + ury = totalBBox.upperY; + urz = totalBBox.upperZ; +} + + +void FTFont::BBox( const wchar_t* string, + float& llx, float& lly, float& llz, float& urx, float& ury, float& urz) +{ + FTBBox totalBBox; + + if((NULL != string) && ('\0' != *string)) + { + const wchar_t* c = string; + + CheckGlyph( *c); + + totalBBox = glyphList->BBox( *c); + float advance = glyphList->Advance( *c, *(c + 1)); + ++c; + + while( *c) + { + CheckGlyph( *c); + FTBBox tempBBox = glyphList->BBox( *c); + tempBBox.Move( FTPoint( advance, 0.0f, 0.0f)); + totalBBox += tempBBox; + advance += glyphList->Advance( *c, *(c + 1)); + ++c; + } + } + + llx = totalBBox.lowerX; + lly = totalBBox.lowerY; + llz = totalBBox.lowerZ; + urx = totalBBox.upperX; + ury = totalBBox.upperY; + urz = totalBBox.upperZ; +} + + +float FTFont::Advance( const wchar_t* string) +{ + const wchar_t* c = string; + float width = 0.0f; + + while( *c) + { + CheckGlyph( *c); + width += glyphList->Advance( *c, *(c + 1)); + ++c; + } + + return width; +} + + +float FTFont::Advance( const char* string) +{ + const unsigned char* c = (unsigned char*)string; + float width = 0.0f; + + while( *c) + { + CheckGlyph( *c); + width += glyphList->Advance( *c, *(c + 1)); + ++c; + } + + return width; +} + + +void FTFont::Render( const char* string ) +{ + const unsigned char* c = (unsigned char*)string; + pen.x = 0; pen.y = 0; + + while( *c) + { + DoRender( *c, *(c + 1)); + ++c; + } +} + + +void FTFont::Render( const wchar_t* string ) +{ + const wchar_t* c = string; + pen.x = 0; pen.y = 0; + + while( *c) + { + DoRender( *c, *(c + 1)); + ++c; + } +} + + +void FTFont::DoRender( const unsigned int chr, const unsigned int nextChr) +{ + CheckGlyph( chr); + + FTPoint kernAdvance = glyphList->Render( chr, nextChr, pen); + + pen.x += kernAdvance.x; + pen.y += kernAdvance.y; +} + + +void FTFont::CheckGlyph( const unsigned int characterCode) +{ + if( NULL == glyphList->Glyph( characterCode)) + { + unsigned int glyphIndex = glyphList->FontIndex( characterCode); + glyphList->Add( MakeGlyph( glyphIndex), characterCode); + } +} + diff --git a/extern/bFTGL/src/FTGLBitmapFont.cpp b/extern/bFTGL/src/FTGLBitmapFont.cpp new file mode 100755 index 00000000000..7e982a608da --- /dev/null +++ b/extern/bFTGL/src/FTGLBitmapFont.cpp @@ -0,0 +1,66 @@ +#include "FTGLBitmapFont.h" +#include "FTBitmapGlyph.h" + + +FTGLBitmapFont::FTGLBitmapFont( const char* fontname) +: FTFont( fontname) +{} + + +FTGLBitmapFont::FTGLBitmapFont( const unsigned char *pBufferBytes, size_t bufferSizeInBytes) +: FTFont( pBufferBytes, bufferSizeInBytes) +{} + + +FTGLBitmapFont::~FTGLBitmapFont() +{} + + +FTGlyph* FTGLBitmapFont::MakeGlyph( unsigned int g) +{ + FT_GlyphSlot ftGlyph = face.Glyph( g, FT_LOAD_DEFAULT); + + if( ftGlyph) + { + FTBitmapGlyph* tempGlyph = new FTBitmapGlyph( ftGlyph); + return tempGlyph; + } + + err = face.Error(); + return NULL; +} + + +void FTGLBitmapFont::Render( const char* string) +{ + glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT); + glPushAttrib( GL_ENABLE_BIT); + + glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE); + glPixelStorei( GL_UNPACK_ALIGNMENT, 1); + + glDisable( GL_BLEND); + + FTFont::Render( string); + + glPopAttrib(); + glPopClientAttrib(); +} + + +void FTGLBitmapFont::Render( const wchar_t* string) +{ + glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT); + glPushAttrib( GL_ENABLE_BIT); + + glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE); + glPixelStorei( GL_UNPACK_ALIGNMENT, 1); + + glDisable( GL_BLEND); + + FTFont::Render( string); + + glPopAttrib(); + glPopClientAttrib(); +} + diff --git a/extern/bFTGL/src/FTGLBufferFont.cpp b/extern/bFTGL/src/FTGLBufferFont.cpp new file mode 100755 index 00000000000..b8af0fcb05f --- /dev/null +++ b/extern/bFTGL/src/FTGLBufferFont.cpp @@ -0,0 +1,53 @@ +#include "FTGLBufferFont.h" +#include "FTBufferGlyph.h" + + +FTGLBufferFont::FTGLBufferFont( const char* fontname) +: FTFont( fontname), + buffer(0) +{} + + +FTGLBufferFont::FTGLBufferFont( const unsigned char *pBufferBytes, size_t bufferSizeInBytes) +: FTFont( pBufferBytes, bufferSizeInBytes), + buffer(0) +{} + + +FTGLBufferFont::~FTGLBufferFont() +{} + + +FTGlyph* FTGLBufferFont::MakeGlyph( unsigned int g) +{ + FT_GlyphSlot ftGlyph = face.Glyph( g, FT_LOAD_NO_HINTING); + + if( ftGlyph) + { + FTBufferGlyph* tempGlyph = new FTBufferGlyph( ftGlyph, buffer); + return tempGlyph; + } + + err = face.Error(); + return NULL; +} + + +void FTGLBufferFont::Render( const char* string) +{ + if( NULL != buffer) + { + FTFont::Render( string); + } +} + + +void FTGLBufferFont::Render( const wchar_t* string) +{ + if( NULL != buffer) + { + FTFont::Render( string); + } +} + + diff --git a/extern/bFTGL/src/FTGLExtrdFont.cpp b/extern/bFTGL/src/FTGLExtrdFont.cpp new file mode 100644 index 00000000000..37d89333a60 --- /dev/null +++ b/extern/bFTGL/src/FTGLExtrdFont.cpp @@ -0,0 +1,35 @@ +#include "FTGLExtrdFont.h" +#include "FTExtrdGlyph.h" + + +FTGLExtrdFont::FTGLExtrdFont( const char* fontname) +: FTFont( fontname), + depth( 0.0f) +{} + + +FTGLExtrdFont::FTGLExtrdFont( const unsigned char *pBufferBytes, size_t bufferSizeInBytes) +: FTFont( pBufferBytes, bufferSizeInBytes), + depth( 0.0f) +{} + + +FTGLExtrdFont::~FTGLExtrdFont() +{} + + +FTGlyph* FTGLExtrdFont::MakeGlyph( unsigned int glyphIndex) +{ + FT_GlyphSlot ftGlyph = face.Glyph( glyphIndex, FT_LOAD_NO_HINTING); + + if( ftGlyph) + { + FTExtrdGlyph* tempGlyph = new FTExtrdGlyph( ftGlyph, depth); + return tempGlyph; + } + + err = face.Error(); + return NULL; +} + + diff --git a/extern/bFTGL/src/FTGLOutlineFont.cpp b/extern/bFTGL/src/FTGLOutlineFont.cpp new file mode 100755 index 00000000000..b9fd187e862 --- /dev/null +++ b/extern/bFTGL/src/FTGLOutlineFont.cpp @@ -0,0 +1,66 @@ +#include "FTGLOutlineFont.h" +#include "FTOutlineGlyph.h" + + +FTGLOutlineFont::FTGLOutlineFont( const char* fontname) +: FTFont( fontname) +{} + + +FTGLOutlineFont::FTGLOutlineFont( const unsigned char *pBufferBytes, size_t bufferSizeInBytes) +: FTFont( pBufferBytes, bufferSizeInBytes) +{} + + +FTGLOutlineFont::~FTGLOutlineFont() +{} + + +FTGlyph* FTGLOutlineFont::MakeGlyph( unsigned int g) +{ + FT_GlyphSlot ftGlyph = face.Glyph( g, FT_LOAD_NO_HINTING); + + if( ftGlyph) + { + FTOutlineGlyph* tempGlyph = new FTOutlineGlyph( ftGlyph); + return tempGlyph; + } + + err = face.Error(); + return NULL; +} + + +void FTGLOutlineFont::Render( const char* string) +{ + glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_COLOR_BUFFER_BIT); + + glDisable( GL_TEXTURE_2D); + + glEnable( GL_LINE_SMOOTH); + glHint( GL_LINE_SMOOTH_HINT, GL_DONT_CARE); + glEnable(GL_BLEND); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE + + FTFont::Render( string); + + glPopAttrib(); +} + + +void FTGLOutlineFont::Render( const wchar_t* string) +{ + glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_COLOR_BUFFER_BIT); + + glDisable( GL_TEXTURE_2D); + + glEnable( GL_LINE_SMOOTH); + glHint( GL_LINE_SMOOTH_HINT, GL_DONT_CARE); + glEnable(GL_BLEND); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE + + FTFont::Render( string); + + glPopAttrib(); +} + diff --git a/extern/bFTGL/src/FTGLPixmapFont.cpp b/extern/bFTGL/src/FTGLPixmapFont.cpp new file mode 100755 index 00000000000..1b35e2ab11d --- /dev/null +++ b/extern/bFTGL/src/FTGLPixmapFont.cpp @@ -0,0 +1,68 @@ +#include "FTGLPixmapFont.h" +#include "FTPixmapGlyph.h" + + +FTGLPixmapFont::FTGLPixmapFont( const char* fontname) +: FTFont( fontname) +{} + + +FTGLPixmapFont::FTGLPixmapFont( const unsigned char *pBufferBytes, size_t bufferSizeInBytes) +: FTFont( pBufferBytes, bufferSizeInBytes) +{} + + +FTGLPixmapFont::~FTGLPixmapFont() +{} + + +FTGlyph* FTGLPixmapFont::MakeGlyph( unsigned int g) +{ + FT_GlyphSlot ftGlyph = face.Glyph( g, FT_LOAD_NO_HINTING); + + if( ftGlyph) + { + FTPixmapGlyph* tempGlyph = new FTPixmapGlyph( ftGlyph); + return tempGlyph; + } + + err = face.Error(); + return NULL; +} + + +void FTGLPixmapFont::Render( const char* string) +{ + glPushAttrib( GL_ENABLE_BIT | GL_PIXEL_MODE_BIT | GL_COLOR_BUFFER_BIT); + glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT); + + glEnable(GL_BLEND); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable( GL_TEXTURE_2D); + + FTFont::Render( string); + + glPopClientAttrib(); + glPopAttrib(); +} + + +void FTGLPixmapFont::Render( const wchar_t* string) +{ + //glPushAttrib( GL_ENABLE_BIT | GL_PIXEL_MODE_BIT | GL_COLOR_BUFFER_BIT); + // glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT); + + glEnable(GL_BLEND); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable( GL_TEXTURE_2D); + + FTFont::Render( string); + + glDisable(GL_BLEND); + // glPopClientAttrib(); + // glPopAttrib(); +} + + diff --git a/extern/bFTGL/src/FTGLPolygonFont.cpp b/extern/bFTGL/src/FTGLPolygonFont.cpp new file mode 100755 index 00000000000..2d4dfa1f26a --- /dev/null +++ b/extern/bFTGL/src/FTGLPolygonFont.cpp @@ -0,0 +1,33 @@ +#include "FTGLPolygonFont.h" +#include "FTPolyGlyph.h" + + +FTGLPolygonFont::FTGLPolygonFont( const char* fontname) +: FTFont( fontname) +{} + + +FTGLPolygonFont::FTGLPolygonFont( const unsigned char *pBufferBytes, size_t bufferSizeInBytes) +: FTFont( pBufferBytes, bufferSizeInBytes) +{} + + +FTGLPolygonFont::~FTGLPolygonFont() +{} + + +FTGlyph* FTGLPolygonFont::MakeGlyph( unsigned int g) +{ + FT_GlyphSlot ftGlyph = face.Glyph( g, FT_LOAD_NO_HINTING); + + if( ftGlyph) + { + FTPolyGlyph* tempGlyph = new FTPolyGlyph( ftGlyph); + return tempGlyph; + } + + err = face.Error(); + return NULL; +} + + diff --git a/extern/bFTGL/src/FTGLTextureFont.cpp b/extern/bFTGL/src/FTGLTextureFont.cpp new file mode 100755 index 00000000000..aa6b645d3ab --- /dev/null +++ b/extern/bFTGL/src/FTGLTextureFont.cpp @@ -0,0 +1,178 @@ +#include <string> // For memset + +#include "FTGLTextureFont.h" +#include "FTTextureGlyph.h" + + +inline GLuint NextPowerOf2( GLuint in) +{ + in -= 1; + + in |= in >> 16; + in |= in >> 8; + in |= in >> 4; + in |= in >> 2; + in |= in >> 1; + + return in + 1; +} + + +FTGLTextureFont::FTGLTextureFont( const char* fontname) +: FTFont( fontname), + maxTextSize(0), + textureWidth(0), + textureHeight(0), + glyphHeight(0), + glyphWidth(0), + padding(3), + xOffset(0), + yOffset(0) +{ + remGlyphs = numGlyphs = face.GlyphCount(); +} + + +FTGLTextureFont::FTGLTextureFont( const unsigned char *pBufferBytes, size_t bufferSizeInBytes) +: FTFont( pBufferBytes, bufferSizeInBytes), + maxTextSize(0), + textureWidth(0), + textureHeight(0), + glyphHeight(0), + glyphWidth(0), + padding(3), + xOffset(0), + yOffset(0) +{ + remGlyphs = numGlyphs = face.GlyphCount(); +} + + +FTGLTextureFont::~FTGLTextureFont() +{ + glDeleteTextures( textureIDList.size(), (const GLuint*)&textureIDList[0]); +} + + +FTGlyph* FTGLTextureFont::MakeGlyph( unsigned int glyphIndex) +{ + FT_GlyphSlot ftGlyph = face.Glyph( glyphIndex, FT_LOAD_NO_HINTING); + + if( ftGlyph) + { + glyphHeight = static_cast<int>( charSize.Height()); + glyphWidth = static_cast<int>( charSize.Width()); + + if( textureIDList.empty()) + { + textureIDList.push_back( CreateTexture()); + xOffset = yOffset = padding; + } + + if( xOffset > ( textureWidth - glyphWidth)) + { + xOffset = padding; + yOffset += glyphHeight; + + if( yOffset > ( textureHeight - glyphHeight)) + { + textureIDList.push_back( CreateTexture()); + yOffset = padding; + } + } + + FTTextureGlyph* tempGlyph = new FTTextureGlyph( ftGlyph, textureIDList[textureIDList.size() - 1], + xOffset, yOffset, textureWidth, textureHeight); + xOffset += static_cast<int>( tempGlyph->BBox().upperX - tempGlyph->BBox().lowerX + padding); + + --remGlyphs; + return tempGlyph; + } + + err = face.Error(); + return NULL; +} + + +void FTGLTextureFont::CalculateTextureSize() +{ + if( !maxTextSize) + { + glGetIntegerv( GL_MAX_TEXTURE_SIZE, (GLint*)&maxTextSize); + } + + textureWidth = NextPowerOf2( (remGlyphs * glyphWidth) + ( padding * 2)); + if( textureWidth > maxTextSize) + { + textureWidth = maxTextSize; + } + + int h = static_cast<int>( (textureWidth - ( padding * 2)) / glyphWidth); + + textureHeight = NextPowerOf2( (( numGlyphs / h) + 1) * glyphHeight); + textureHeight = textureHeight > maxTextSize ? maxTextSize : textureHeight; +} + + +GLuint FTGLTextureFont::CreateTexture() +{ + CalculateTextureSize(); + + int totalMemory = textureWidth * textureHeight; + unsigned char* textureMemory = new unsigned char[totalMemory]; + memset( textureMemory, 0, totalMemory); + + GLuint textID; + glGenTextures( 1, (GLuint*)&textID); + + glBindTexture( GL_TEXTURE_2D, textID); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, textureWidth, textureHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, textureMemory); + + delete [] textureMemory; + + return textID; +} + + +bool FTGLTextureFont::FaceSize( const unsigned int size, const unsigned int res) +{ + if( !textureIDList.empty()) + { + glDeleteTextures( textureIDList.size(), (const GLuint*)&textureIDList[0]); + remGlyphs = numGlyphs = face.GlyphCount(); + } + + return FTFont::FaceSize( size, res); +} + + +void FTGLTextureFont::Render( const char* string) +{ + glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT); + + glEnable(GL_BLEND); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE + + FTFont::Render( string); + + glPopAttrib(); +} + + +void FTGLTextureFont::Render( const wchar_t* string) +{ + glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT); + + glEnable(GL_BLEND); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE + + FTFont::Render( string); + + glPopAttrib(); +} + diff --git a/extern/bFTGL/src/FTGlyph.cpp b/extern/bFTGL/src/FTGlyph.cpp new file mode 100755 index 00000000000..c68632949c2 --- /dev/null +++ b/extern/bFTGL/src/FTGlyph.cpp @@ -0,0 +1,17 @@ +#include "FTGlyph.h" + + +FTGlyph::FTGlyph( FT_GlyphSlot glyph) +: advance(0.0f), + err(0) +{ + if( glyph) + { + bBox = FTBBox( glyph); + advance = static_cast<float>( glyph->advance.x) / 64.0f; + } +} + + +FTGlyph::~FTGlyph() +{} diff --git a/extern/bFTGL/src/FTGlyphContainer.cpp b/extern/bFTGL/src/FTGlyphContainer.cpp new file mode 100755 index 00000000000..2c1881bbfff --- /dev/null +++ b/extern/bFTGL/src/FTGlyphContainer.cpp @@ -0,0 +1,93 @@ +#include "FTGlyphContainer.h" +#include "FTGlyph.h" +#include "FTFace.h" +#include "FTCharmap.h" + + +FTGlyphContainer::FTGlyphContainer( FTFace* f) +: face(f), + err(0) +{ + glyphs.push_back( NULL); + charMap = new FTCharmap( face); +} + + +FTGlyphContainer::~FTGlyphContainer() +{ + GlyphVector::iterator glyphIterator; + for( glyphIterator = glyphs.begin(); glyphIterator != glyphs.end(); ++glyphIterator) + { + delete *glyphIterator; + } + + glyphs.clear(); + delete charMap; +} + + +bool FTGlyphContainer::CharMap( FT_Encoding encoding) +{ + bool result = charMap->CharMap( encoding); + err = charMap->Error(); + return result; +} + + +unsigned int FTGlyphContainer::FontIndex( const unsigned int characterCode) const +{ + return charMap->FontIndex( characterCode); +} + + +void FTGlyphContainer::Add( FTGlyph* tempGlyph, const unsigned int characterCode) +{ + charMap->InsertIndex( characterCode, glyphs.size()); + glyphs.push_back( tempGlyph); +} + + +const FTGlyph* const FTGlyphContainer::Glyph( const unsigned int characterCode) const +{ + signed int index = charMap->GlyphListIndex( characterCode); + return glyphs[index]; +} + + +FTBBox FTGlyphContainer::BBox( const unsigned int characterCode) const +{ + return glyphs[charMap->GlyphListIndex( characterCode)]->BBox(); +} + + +float FTGlyphContainer::Advance( const unsigned int characterCode, const unsigned int nextCharacterCode) +{ + unsigned int left = charMap->FontIndex( characterCode); + unsigned int right = charMap->FontIndex( nextCharacterCode); + + float width = face->KernAdvance( left, right).x; + width += glyphs[charMap->GlyphListIndex( characterCode)]->Advance(); + + return width; +} + + +FTPoint FTGlyphContainer::Render( const unsigned int characterCode, const unsigned int nextCharacterCode, FTPoint penPosition) +{ + FTPoint kernAdvance; + float advance = 0; + + unsigned int left = charMap->FontIndex( characterCode); + unsigned int right = charMap->FontIndex( nextCharacterCode); + + kernAdvance = face->KernAdvance( left, right); + + if( !face->Error()) + { + advance = glyphs[charMap->GlyphListIndex( characterCode)]->Render( penPosition); + } + + kernAdvance.x = advance + kernAdvance.x; +// kernAdvance.y = advance.y + kernAdvance.y; + return kernAdvance; +} diff --git a/extern/bFTGL/src/FTLibrary.cpp b/extern/bFTGL/src/FTLibrary.cpp new file mode 100755 index 00000000000..29ab5ae2693 --- /dev/null +++ b/extern/bFTGL/src/FTLibrary.cpp @@ -0,0 +1,64 @@ +#include "FTLibrary.h" + + +FTLibrary& FTLibrary::Instance() +{ + static FTLibrary ftlib; + return ftlib; +} + + +FTLibrary::~FTLibrary() +{ + if( library != 0) + { + FT_Done_FreeType( *library); + + delete library; + library= 0; + } + +// if( manager != 0) +// { +// FTC_Manager_Done( manager ); +// +// delete manager; +// manager= 0; +// } +} + + +FTLibrary::FTLibrary() +: library(0), + err(0) +{ + Initialise(); +} + + +bool FTLibrary::Initialise() +{ + if( library != 0) + return true; + + library = new FT_Library; + + err = FT_Init_FreeType( library); + if( err) + { + delete library; + library = 0; + return false; + } + +// FTC_Manager* manager; +// +// if( FTC_Manager_New( lib, 0, 0, 0, my_face_requester, 0, manager ) +// { +// delete manager; +// manager= 0; +// return false; +// } + + return true; +} diff --git a/extern/bFTGL/src/FTOutlineGlyph.cpp b/extern/bFTGL/src/FTOutlineGlyph.cpp new file mode 100644 index 00000000000..340c7804140 --- /dev/null +++ b/extern/bFTGL/src/FTOutlineGlyph.cpp @@ -0,0 +1,57 @@ +#include "FTOutlineGlyph.h" +#include "FTVectoriser.h" + + +FTOutlineGlyph::FTOutlineGlyph( FT_GlyphSlot glyph) +: FTGlyph( glyph), + glList(0) +{ + if( ft_glyph_format_outline != glyph->format) + { + err = 0x14; // Invalid_Outline + return; + } + + FTVectoriser vectoriser( glyph); + + size_t numContours = vectoriser.ContourCount(); + if ( ( numContours < 1) || ( vectoriser.PointCount() < 3)) + { + return; + } + + glList = glGenLists(1); + glNewList( glList, GL_COMPILE); + for( unsigned int c = 0; c < numContours; ++c) + { + const FTContour* contour = vectoriser.Contour(c); + + glBegin( GL_LINE_LOOP); + for( unsigned int p = 0; p < contour->PointCount(); ++p) + { + glVertex2f( contour->Point(p).x / 64.0f, contour->Point(p).y / 64.0f); + } + glEnd(); + } + glEndList(); +} + + +FTOutlineGlyph::~FTOutlineGlyph() +{ + glDeleteLists( glList, 1); +} + + +float FTOutlineGlyph::Render( const FTPoint& pen) +{ + if( glList) + { + glTranslatef( pen.x, pen.y, 0); + glCallList( glList); + glTranslatef( -pen.x, -pen.y, 0); + } + + return advance; +} + diff --git a/extern/bFTGL/src/FTPixmapGlyph.cpp b/extern/bFTGL/src/FTPixmapGlyph.cpp new file mode 100755 index 00000000000..b051a06b6e3 --- /dev/null +++ b/extern/bFTGL/src/FTPixmapGlyph.cpp @@ -0,0 +1,109 @@ +#include "FTPixmapGlyph.h" + +FTPixmapGlyph::FTPixmapGlyph( FT_GlyphSlot glyph) +: FTGlyph( glyph), + destWidth(0), + destHeight(0), + data(0) +{ + err = FT_Render_Glyph( glyph, FT_RENDER_MODE_NORMAL); + if( err || ft_glyph_format_bitmap != glyph->format) + { + return; + } + + FT_Bitmap bitmap = glyph->bitmap; + + //check the pixel mode + //ft_pixel_mode_grays + + int srcWidth = bitmap.width; + int srcHeight = bitmap.rows; + + // FIXME What about dest alignment? + destWidth = srcWidth; + destHeight = srcHeight; + + if( destWidth && destHeight) + { + data = new unsigned char[destWidth * destHeight * 4]; + + // Get the current glColor. + float ftglColour[4]; +// glGetFloatv( GL_CURRENT_COLOR, ftglColour); + ftglColour[0] = ftglColour[1] = ftglColour[2] = ftglColour[3] = 1.0; + + unsigned char redComponent = static_cast<unsigned char>( ftglColour[0] * 255.0f); + unsigned char greenComponent = static_cast<unsigned char>( ftglColour[1] * 255.0f); + unsigned char blueComponent = static_cast<unsigned char>( ftglColour[2] * 255.0f); + + unsigned char* src = bitmap.buffer; + + unsigned char* dest = data + ((destHeight - 1) * destWidth) * 4; + size_t destStep = destWidth * 4 * 2; + + if( ftglColour[3] == 1.0f) + { + for( int y = 0; y < srcHeight; ++y) + { + for( int x = 0; x < srcWidth; ++x) + { + *dest++ = redComponent; + *dest++ = greenComponent; + *dest++ = blueComponent; + *dest++ = *src++; + } + dest -= destStep; + } + } + else + { + for( int y = 0; y < srcHeight; ++y) + { + for( int x = 0; x < srcWidth; ++x) + { + *dest++ = redComponent; + *dest++ = greenComponent; + *dest++ = blueComponent; + *dest++ = static_cast<unsigned char>(ftglColour[3] * *src++); + } + dest -= destStep; + } + } + + destHeight = srcHeight; + } + + pos.x = glyph->bitmap_left; + pos.y = srcHeight - glyph->bitmap_top; +} + + +FTPixmapGlyph::~FTPixmapGlyph() +{ + delete [] data; +} + +#include <math.h> +float FTPixmapGlyph::Render( const FTPoint& pen) +{ + if( data) + { + float dx, dy; + + dx= floor( (pen.x + pos.x ) ); + dy= ( (pen.y - pos.y ) ); + + // Move the glyph origin + glBitmap( 0, 0, 0.0f, 0.0f, dx, dy, (const GLubyte*)0); + + glPixelStorei( GL_UNPACK_ROW_LENGTH, 0); + + glDrawPixels( destWidth, destHeight, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid*)data); + + // Restore the glyph origin + glBitmap( 0, 0, 0.0f, 0.0f, -dx, -dy, (const GLubyte*)0); + } + + return advance; +} diff --git a/extern/bFTGL/src/FTPoint.cpp b/extern/bFTGL/src/FTPoint.cpp new file mode 100755 index 00000000000..e4678bc9564 --- /dev/null +++ b/extern/bFTGL/src/FTPoint.cpp @@ -0,0 +1,14 @@ +#include "FTPoint.h" + + +bool operator == ( const FTPoint &a, const FTPoint &b) +{ + return((a.x == b.x) && (a.y == b.y) && (a.z == b.z)); +} + +bool operator != ( const FTPoint &a, const FTPoint &b) +{ + return((a.x != b.x) || (a.y != b.y) || (a.z != b.z)); +} + + diff --git a/extern/bFTGL/src/FTPolyGlyph.cpp b/extern/bFTGL/src/FTPolyGlyph.cpp new file mode 100644 index 00000000000..7e0d695493c --- /dev/null +++ b/extern/bFTGL/src/FTPolyGlyph.cpp @@ -0,0 +1,62 @@ +#include "FTPolyGlyph.h" +#include "FTVectoriser.h" + + +FTPolyGlyph::FTPolyGlyph( FT_GlyphSlot glyph) +: FTGlyph( glyph), + glList(0) +{ + if( ft_glyph_format_outline != glyph->format) + { + err = 0x14; // Invalid_Outline + return; + } + + FTVectoriser vectoriser( glyph); + + if(( vectoriser.ContourCount() < 1) || ( vectoriser.PointCount() < 3)) + { + return; + } + + vectoriser.MakeMesh( 1.0); + + glList = glGenLists( 1); + glNewList( glList, GL_COMPILE); + + const FTMesh* mesh = vectoriser.GetMesh(); + for( unsigned int index = 0; index < mesh->TesselationCount(); ++index) + { + const FTTesselation* subMesh = mesh->Tesselation( index); + unsigned int polyonType = subMesh->PolygonType(); + + glBegin( polyonType); + for( unsigned int x = 0; x < subMesh->PointCount(); ++x) + { + glVertex3f( subMesh->Point(x).x / 64.0f, + subMesh->Point(x).y / 64.0f, + 0.0f); + } + glEnd(); + } + glEndList(); +} + + +FTPolyGlyph::~FTPolyGlyph() +{ + glDeleteLists( glList, 1); +} + + +float FTPolyGlyph::Render( const FTPoint& pen) +{ + if( glList) + { + glTranslatef( pen.x, pen.y, 0); + glCallList( glList); + glTranslatef( -pen.x, -pen.y, 0); + } + + return advance; +} diff --git a/extern/bFTGL/src/FTSize.cpp b/extern/bFTGL/src/FTSize.cpp new file mode 100755 index 00000000000..5fb8ffba157 --- /dev/null +++ b/extern/bFTGL/src/FTSize.cpp @@ -0,0 +1,105 @@ +#include "FTSize.h" + + +FTSize::FTSize() +: ftFace(0), + ftSize(0), + size(0), + err(0) +{} + + +FTSize::~FTSize() +{} + + +bool FTSize::CharSize( FT_Face* face, unsigned int point_size, unsigned int x_resolution, unsigned int y_resolution ) +{ + err = FT_Set_Char_Size( *face, 0L, point_size * 64, x_resolution, y_resolution); + + if( !err) + { + ftFace = face; + size = point_size; + ftSize = (*ftFace)->size; + } + else + { + ftFace = 0; + size = 0; + ftSize = 0; + } + + return !err; +} + + +unsigned int FTSize::CharSize() const +{ + return size; +} + + +float FTSize::Ascender() const +{ + return ftSize == 0 ? 0.0f : static_cast<float>( ftSize->metrics.ascender) / 64.0f; +} + + +float FTSize::Descender() const +{ + return ftSize == 0 ? 0.0f : static_cast<float>( ftSize->metrics.descender) / 64.0f; +} + + +float FTSize::Height() const +{ + if( 0 == ftSize) + { + return 0.0f; + } + + if( FT_IS_SCALABLE((*ftFace))) + { + return ( (*ftFace)->bbox.yMax - (*ftFace)->bbox.yMin) * ( (float)ftSize->metrics.y_ppem / (float)(*ftFace)->units_per_EM); + } + else + { + return static_cast<float>( ftSize->metrics.height) / 64.0f; + } +} + + +float FTSize::Width() const +{ + if( 0 == ftSize) + { + return 0.0f; + } + + if( FT_IS_SCALABLE((*ftFace))) + { + return ( (*ftFace)->bbox.xMax - (*ftFace)->bbox.xMin) * ( static_cast<float>(ftSize->metrics.x_ppem) / static_cast<float>((*ftFace)->units_per_EM)); + } + else + { + return static_cast<float>( ftSize->metrics.max_advance) / 64.0f; + } +} + + +float FTSize::Underline() const +{ + return 0.0f; +} + +unsigned int FTSize::XPixelsPerEm() const +{ + return ftSize == 0 ? 0 : ftSize->metrics.x_ppem; +} + +unsigned int FTSize::YPixelsPerEm() const +{ + return ftSize == 0 ? 0 : ftSize->metrics.y_ppem; +} + diff --git a/extern/bFTGL/src/FTTextureGlyph.cpp b/extern/bFTGL/src/FTTextureGlyph.cpp new file mode 100755 index 00000000000..4b29268f1ce --- /dev/null +++ b/extern/bFTGL/src/FTTextureGlyph.cpp @@ -0,0 +1,82 @@ +#include "FTTextureGlyph.h" + + +FTTextureGlyph::FTTextureGlyph( FT_GlyphSlot glyph, int id, int xOffset, int yOffset, GLsizei width, GLsizei height) +: FTGlyph( glyph), + destWidth(0), + destHeight(0), + glTextureID(id), + activeTextureID(0) +{ + err = FT_Render_Glyph( glyph, FT_RENDER_MODE_NORMAL); + if( err || glyph->format != ft_glyph_format_bitmap) + { + return; + } + + FT_Bitmap bitmap = glyph->bitmap; + + destWidth = bitmap.width; + destHeight = bitmap.rows; + + if( destWidth && destHeight) + { + glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT); + glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE); + glPixelStorei( GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei( GL_UNPACK_ALIGNMENT, 1); + + glBindTexture( GL_TEXTURE_2D, glTextureID); + glTexSubImage2D( GL_TEXTURE_2D, 0, xOffset, yOffset, destWidth, destHeight, GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.buffer); + + glPopClientAttrib(); + } + + +// 0 +// +----+ +// | | +// | | +// | | +// +----+ +// 1 + + uv[0].x = static_cast<float>(xOffset) / static_cast<float>(width); + uv[0].y = static_cast<float>(yOffset) / static_cast<float>(height); + uv[1].x = static_cast<float>( xOffset + destWidth) / static_cast<float>(width); + uv[1].y = static_cast<float>( yOffset + destHeight) / static_cast<float>(height); + + pos.x = glyph->bitmap_left; + pos.y = glyph->bitmap_top; +} + + +FTTextureGlyph::~FTTextureGlyph() +{} + + +float FTTextureGlyph::Render( const FTPoint& pen) +{ + glGetIntegerv( GL_TEXTURE_2D_BINDING_EXT, &activeTextureID); + if( activeTextureID != glTextureID) + { + glBindTexture( GL_TEXTURE_2D, (GLuint)glTextureID); + } + + glBegin( GL_QUADS); + glTexCoord2f( uv[0].x, uv[0].y); + glVertex2f( pen.x + pos.x, pen.y + pos.y); + + glTexCoord2f( uv[0].x, uv[1].y); + glVertex2f( pen.x + pos.x, pen.y + pos.y - destHeight); + + glTexCoord2f( uv[1].x, uv[1].y); + glVertex2f( pen.x + destWidth + pos.x, pen.y + pos.y - destHeight); + + glTexCoord2f( uv[1].x, uv[0].y); + glVertex2f( pen.x + destWidth + pos.x, pen.y + pos.y); + glEnd(); + + return advance; +} + diff --git a/extern/bFTGL/src/FTVectoriser.cpp b/extern/bFTGL/src/FTVectoriser.cpp new file mode 100644 index 00000000000..bb133d025b4 --- /dev/null +++ b/extern/bFTGL/src/FTVectoriser.cpp @@ -0,0 +1,225 @@ +#include "FTVectoriser.h" +#include "FTGL.h" + +#ifndef CALLBACK +#define CALLBACK +#endif + +#ifdef __APPLE_CC__ + typedef GLvoid (*GLUTesselatorFunction)(...); +#elif defined( __mips ) || defined( __linux__ ) || defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __sun ) || defined (__CYGWIN__) + typedef GLvoid (*GLUTesselatorFunction)(); +#elif defined ( WIN32) + typedef GLvoid (CALLBACK *GLUTesselatorFunction)( ); +#else + #error "Error - need to define type GLUTesselatorFunction for this platform/compiler" +#endif + + +void CALLBACK ftglError( GLenum errCode, FTMesh* mesh) +{ + mesh->Error( errCode); +} + + +void CALLBACK ftglVertex( void* data, FTMesh* mesh) +{ + FTGL_DOUBLE* vertex = static_cast<FTGL_DOUBLE*>(data); + mesh->AddPoint( vertex[0], vertex[1], vertex[2]); +} + + +void CALLBACK ftglCombine( FTGL_DOUBLE coords[3], void* vertex_data[4], GLfloat weight[4], void** outData, FTMesh* mesh) +{ + FTGL_DOUBLE* vertex = static_cast<FTGL_DOUBLE*>(coords); + *outData = mesh->Combine( vertex[0], vertex[1], vertex[2]); +} + + +void CALLBACK ftglBegin( GLenum type, FTMesh* mesh) +{ + mesh->Begin( type); +} + + +void CALLBACK ftglEnd( FTMesh* mesh) +{ + mesh->End(); +} + + +FTMesh::FTMesh() +: currentTesselation(0), + err(0) +{ + tesselationList.reserve( 16); +} + + +FTMesh::~FTMesh() +{ + for( size_t t = 0; t < tesselationList.size(); ++t) + { + delete tesselationList[t]; + } + + tesselationList.clear(); +} + + +void FTMesh::AddPoint( const FTGL_DOUBLE x, const FTGL_DOUBLE y, const FTGL_DOUBLE z) +{ + currentTesselation->AddPoint( x, y, z); +} + + +FTGL_DOUBLE* FTMesh::Combine( const FTGL_DOUBLE x, const FTGL_DOUBLE y, const FTGL_DOUBLE z) +{ + tempPointList.push_back( FTPoint( x, y,z)); + return &tempPointList.back().x; +} + + +void FTMesh::Begin( GLenum meshType) +{ + currentTesselation = new FTTesselation( meshType); +} + + +void FTMesh::End() +{ + tesselationList.push_back( currentTesselation); +} + + +const FTTesselation* const FTMesh::Tesselation( unsigned int index) const +{ + return ( index < tesselationList.size()) ? tesselationList[index] : NULL; +} + + +FTVectoriser::FTVectoriser( const FT_GlyphSlot glyph) +: contourList(0), + mesh(0), + ftContourCount(0), + contourFlag(0) +{ + if( glyph) + { + outline = glyph->outline; + + ftContourCount = outline.n_contours;; + contourList = 0; + contourFlag = outline.flags; + + ProcessContours(); + } +} + + +FTVectoriser::~FTVectoriser() +{ + for( size_t c = 0; c < ContourCount(); ++c) + { + delete contourList[c]; + } + + delete [] contourList; + delete mesh; +} + + +void FTVectoriser::ProcessContours() +{ + short contourLength = 0; + short startIndex = 0; + short endIndex = 0; + + contourList = new FTContour*[ftContourCount]; + + for( short contourIndex = 0; contourIndex < ftContourCount; ++contourIndex) + { + FT_Vector* pointList = &outline.points[startIndex]; + char* tagList = &outline.tags[startIndex]; + + endIndex = outline.contours[contourIndex]; + contourLength = ( endIndex - startIndex) + 1; + + FTContour* contour = new FTContour( pointList, tagList, contourLength); + + contourList[contourIndex] = contour; + + startIndex = endIndex + 1; + } +} + + +size_t FTVectoriser::PointCount() +{ + size_t s = 0; + for( size_t c = 0; c < ContourCount(); ++c) + { + s += contourList[c]->PointCount(); + } + + return s; +} + + +const FTContour* const FTVectoriser::Contour( unsigned int index) const +{ + return ( index < ContourCount()) ? contourList[index] : NULL; +} + + +void FTVectoriser::MakeMesh( FTGL_DOUBLE zNormal) +{ + if( mesh) + { + delete mesh; + } + + mesh = new FTMesh; + + GLUtesselator* tobj = gluNewTess(); + + gluTessCallback( tobj, GLU_TESS_BEGIN_DATA, (GLUTesselatorFunction)ftglBegin); + gluTessCallback( tobj, GLU_TESS_VERTEX_DATA, (GLUTesselatorFunction)ftglVertex); + gluTessCallback( tobj, GLU_TESS_COMBINE_DATA, (GLUTesselatorFunction)ftglCombine); + gluTessCallback( tobj, GLU_TESS_END_DATA, (GLUTesselatorFunction)ftglEnd); + gluTessCallback( tobj, GLU_TESS_ERROR_DATA, (GLUTesselatorFunction)ftglError); + + if( contourFlag & ft_outline_even_odd_fill) // ft_outline_reverse_fill + { + gluTessProperty( tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); + } + else + { + gluTessProperty( tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO); + } + + + gluTessProperty( tobj, GLU_TESS_TOLERANCE, 0); + gluTessNormal( tobj, 0.0f, 0.0f, zNormal); + gluTessBeginPolygon( tobj, mesh); + + for( size_t c = 0; c < ContourCount(); ++c) + { + const FTContour* contour = contourList[c]; + + gluTessBeginContour( tobj); + + for( size_t p = 0; p < contour->PointCount(); ++p) + { + FTGL_DOUBLE* d = const_cast<FTGL_DOUBLE*>(&contour->Point(p).x); + gluTessVertex( tobj, d, d); + } + + gluTessEndContour( tobj); + } + + gluTessEndPolygon( tobj); + + gluDeleteTess( tobj); +} + diff --git a/extern/bFTGL/src/Makefile b/extern/bFTGL/src/Makefile new file mode 100644 index 00000000000..064480fbd16 --- /dev/null +++ b/extern/bFTGL/src/Makefile @@ -0,0 +1,62 @@ +# +# $Id$ +# +# ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. The Blender +# Foundation also sells licenses for use in proprietary software under +# the Blender License. See http://www.blender.org/BL/ for information +# about this. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): none yet. +# +# ***** END GPL/BL DUAL LICENSE BLOCK ***** +# +# + +LIBNAME = ftgl +DIR = $(OCGDIR)/extern/$(LIBNAME) + +CCFLAGS += $(LEVEL_1_CPP_WARNINGS) + +CSRCS = +CCSRCS = FTBitmapGlyph.cpp FTCharmap.cpp FTContour.cpp FTExtrdGlyph.cpp \ + FTFace.cpp FTFont.cpp FTGLBitmapFont.cpp FTGLExtrdFont.cpp \ + FTGLOutlineFont.cpp FTGLPixmapFont.cpp FTGLPolygonFont.cpp \ + FTGLTextureFont.cpp FTGlyph.cpp FTGlyphContainer.cpp FTLibrary.cpp \ + FTOutlineGlyph.cpp FTPixmapGlyph.cpp FTPoint.cpp FTPolyGlyph.cpp \ + FTSize.cpp FTTextureGlyph.cpp FTVectoriser.cpp + +include nan_compile.mk +CPPFLAGS += -I../include +CPPFLAGS += -I$(NAN_FREETYPE)/include -I$(NAN_FREETYPE)/include/freetype2 + +install: all debug + @[ -d $(NAN_FTGL) ] || mkdir -p $(NAN_FTGL) + @[ -d $(NAN_FTGL)/include ] || mkdir -p $(NAN_FTGL)/include + @[ -d $(NAN_FTGL)/lib ] || mkdir -p $(NAN_FTGL)/lib + @[ -d $(NAN_FTGL)/lib/debug ] || mkdir -p $(NAN_FTGL)/lib/debug + @$(NANBLENDERHOME)/intern/tools/cpifdiff.sh $(DIR)/lib$(LIBNAME).a $(NAN_FTGL)/lib/ +# @$(NANBLENDERHOME)/intern/tools/cpifdiff.sh $(DIR)/debug/lib$(LIBNAME).a $(NAN_FTGL)/lib/debug/ +ifeq ($(OS),darwin) + ranlib $(NAN_FTGL)/lib/lib$(LIBNAME).a +endif + @$(NANBLENDERHOME)/intern/tools/cpifdiff.sh ../include/*.h $(NAN_FTGL)/include/ + |