Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Mein <mein@cs.umn.edu>2005-01-21 08:15:33 +0300
committerKent Mein <mein@cs.umn.edu>2005-01-21 08:15:33 +0300
commit26f63bfa197e82a6d3a3f298c603f1878891b8f8 (patch)
tree370880862bd533224e42e7b374f39a43279e79f8 /extern/bFTGL/src
parentb561ca88cfc2445b82c3dc59bdbb8d9e46ee7e31 (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')
-rwxr-xr-xextern/bFTGL/src/FTBitmapGlyph.cpp66
-rwxr-xr-xextern/bFTGL/src/FTBufferGlyph.cpp59
-rw-r--r--extern/bFTGL/src/FTCharmap.cpp62
-rw-r--r--extern/bFTGL/src/FTContour.cpp149
-rw-r--r--extern/bFTGL/src/FTExtrdGlyph.cpp141
-rwxr-xr-xextern/bFTGL/src/FTFace.cpp154
-rwxr-xr-xextern/bFTGL/src/FTFont.cpp271
-rwxr-xr-xextern/bFTGL/src/FTGLBitmapFont.cpp66
-rwxr-xr-xextern/bFTGL/src/FTGLBufferFont.cpp53
-rw-r--r--extern/bFTGL/src/FTGLExtrdFont.cpp35
-rwxr-xr-xextern/bFTGL/src/FTGLOutlineFont.cpp66
-rwxr-xr-xextern/bFTGL/src/FTGLPixmapFont.cpp68
-rwxr-xr-xextern/bFTGL/src/FTGLPolygonFont.cpp33
-rwxr-xr-xextern/bFTGL/src/FTGLTextureFont.cpp178
-rwxr-xr-xextern/bFTGL/src/FTGlyph.cpp17
-rwxr-xr-xextern/bFTGL/src/FTGlyphContainer.cpp93
-rwxr-xr-xextern/bFTGL/src/FTLibrary.cpp64
-rw-r--r--extern/bFTGL/src/FTOutlineGlyph.cpp57
-rwxr-xr-xextern/bFTGL/src/FTPixmapGlyph.cpp109
-rwxr-xr-xextern/bFTGL/src/FTPoint.cpp14
-rw-r--r--extern/bFTGL/src/FTPolyGlyph.cpp62
-rwxr-xr-xextern/bFTGL/src/FTSize.cpp105
-rwxr-xr-xextern/bFTGL/src/FTTextureGlyph.cpp82
-rw-r--r--extern/bFTGL/src/FTVectoriser.cpp225
-rw-r--r--extern/bFTGL/src/Makefile62
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/
+