Main Page | File List | File Members

FTVectoriser.cpp

Go to the documentation of this file.
00001 #include    "FTVectoriser.h"
00002 #include    "FTGL.h"
00003 
00004 #ifndef CALLBACK
00005 #define CALLBACK
00006 #endif
00007 
00008 #ifdef __APPLE_CC__    
00009     typedef GLvoid (*GLUTesselatorFunction)(...);
00010 #elif defined( __mips ) || defined( __linux__ ) || defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __sun )
00011     typedef GLvoid (*GLUTesselatorFunction)();
00012 #elif defined ( WIN32)
00013     typedef GLvoid (CALLBACK *GLUTesselatorFunction)( );
00014 #else
00015     #error "Error - need to define type GLUTesselatorFunction for this platform/compiler"
00016 #endif
00017 
00018 
00019 void CALLBACK ftglError( GLenum errCode, FTMesh* mesh)
00020 {
00021     mesh->Error( errCode);
00022 }
00023 
00024 
00025 void CALLBACK ftglVertex( void* data, FTMesh* mesh)
00026 {
00027     FTGL_DOUBLE* vertex = static_cast<FTGL_DOUBLE*>(data);
00028     mesh->AddPoint( vertex[0], vertex[1], vertex[2]);
00029 }
00030 
00031 
00032 void CALLBACK ftglCombine( FTGL_DOUBLE coords[3], void* vertex_data[4], GLfloat weight[4], void** outData, FTMesh* mesh)
00033 {
00034     FTGL_DOUBLE* vertex = static_cast<FTGL_DOUBLE*>(coords);
00035     *outData = mesh->Combine( vertex[0], vertex[1], vertex[2]);
00036 }
00037         
00038 
00039 void CALLBACK ftglBegin( GLenum type, FTMesh* mesh)
00040 {
00041     mesh->Begin( type);
00042 }
00043 
00044 
00045 void CALLBACK ftglEnd( FTMesh* mesh)
00046 {
00047     mesh->End();
00048 }
00049 
00050 
00051 FTMesh::FTMesh()
00052 :   currentTesselation(0),
00053     err(0)
00054 {
00055     tesselationList.reserve( 16);
00056 }
00057 
00058 
00059 FTMesh::~FTMesh()
00060 {
00061     for( size_t t = 0; t < tesselationList.size(); ++t)
00062     {
00063         delete tesselationList[t];
00064     }
00065     
00066     tesselationList.clear();
00067 }
00068 
00069 
00070 void FTMesh::AddPoint( const FTGL_DOUBLE x, const FTGL_DOUBLE y, const FTGL_DOUBLE z)
00071 {
00072     currentTesselation->AddPoint( x, y, z);
00073 }
00074 
00075 
00076 FTGL_DOUBLE* FTMesh::Combine( const FTGL_DOUBLE x, const FTGL_DOUBLE y, const FTGL_DOUBLE z)
00077 {
00078     tempPointList.push_back( FTPoint( x, y,z));
00079     return &tempPointList.back().x;
00080 }
00081 
00082 
00083 void FTMesh::Begin( GLenum meshType)
00084 {
00085     currentTesselation = new FTTesselation( meshType);
00086 }
00087 
00088 
00089 void FTMesh::End()
00090 {
00091     tesselationList.push_back( currentTesselation);
00092 }
00093 
00094 
00095 const FTTesselation* const FTMesh::Tesselation( unsigned int index) const
00096 {
00097     return ( index < tesselationList.size()) ? tesselationList[index] : NULL;
00098 }
00099 
00100 
00101 FTVectoriser::FTVectoriser( const FT_Glyph glyph)
00102 :   contourList(0),
00103     mesh(0),
00104     ftContourCount(0),
00105     contourFlag(0)
00106 {
00107     if( glyph)
00108     {
00109         FT_OutlineGlyph outline = (FT_OutlineGlyph)glyph;
00110         ftOutline = outline->outline;
00111         
00112         ftContourCount = ftOutline.n_contours;;
00113         contourList = 0;
00114         contourFlag = ftOutline.flags;
00115         
00116         ProcessContours();
00117     }
00118 }
00119 
00120 
00121 FTVectoriser::~FTVectoriser()
00122 {
00123     for( size_t c = 0; c < ContourCount(); ++c)
00124     {
00125         delete contourList[c];
00126     }
00127 
00128     delete [] contourList;
00129     delete mesh;
00130 }
00131 
00132 
00133 void FTVectoriser::ProcessContours()
00134 {
00135     short contourLength = 0;
00136     short startIndex = 0;
00137     short endIndex = 0;
00138     
00139     contourList = new FTContour*[ftContourCount];
00140     
00141     for( short contourIndex = 0; contourIndex < ftContourCount; ++contourIndex)
00142     {
00143         FT_Vector* pointList = &ftOutline.points[startIndex];
00144         char* tagList = &ftOutline.tags[startIndex];
00145         
00146         endIndex = ftOutline.contours[contourIndex];
00147         contourLength =  ( endIndex - startIndex) + 1;
00148 
00149         FTContour* contour = new FTContour( pointList, tagList, contourLength);
00150         
00151         contourList[contourIndex] = contour;
00152         
00153         startIndex = endIndex + 1;
00154     }
00155 }
00156 
00157 
00158 size_t FTVectoriser::PointCount()
00159 {
00160     size_t s = 0;
00161     for( size_t c = 0; c < ContourCount(); ++c)
00162     {
00163         s += contourList[c]->PointCount();
00164     }
00165     
00166     return s;
00167 }
00168 
00169 
00170 const FTContour* const FTVectoriser::Contour( unsigned int index) const
00171 {
00172     return ( index < ContourCount()) ? contourList[index] : NULL;
00173 }
00174 
00175 
00176 void FTVectoriser::MakeMesh( FTGL_DOUBLE zNormal)
00177 {
00178     if( mesh)
00179     {
00180         delete mesh;
00181     }
00182         
00183     mesh = new FTMesh;
00184     
00185     GLUtesselator* tobj = gluNewTess();
00186 
00187     gluTessCallback( tobj, GLU_TESS_BEGIN_DATA,     (GLUTesselatorFunction)ftglBegin);
00188     gluTessCallback( tobj, GLU_TESS_VERTEX_DATA,    (GLUTesselatorFunction)ftglVertex);
00189     gluTessCallback( tobj, GLU_TESS_COMBINE_DATA,   (GLUTesselatorFunction)ftglCombine);
00190     gluTessCallback( tobj, GLU_TESS_END_DATA,       (GLUTesselatorFunction)ftglEnd);
00191     gluTessCallback( tobj, GLU_TESS_ERROR_DATA,     (GLUTesselatorFunction)ftglError);
00192     
00193     if( contourFlag & ft_outline_even_odd_fill) // ft_outline_reverse_fill
00194     {
00195         gluTessProperty( tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
00196     }
00197     else
00198     {
00199         gluTessProperty( tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
00200     }
00201     
00202     
00203     gluTessProperty( tobj, GLU_TESS_TOLERANCE, 0);
00204     gluTessNormal( tobj, 0.0f, 0.0f, zNormal);
00205     gluTessBeginPolygon( tobj, mesh);
00206     
00207         for( size_t c = 0; c < ContourCount(); ++c)
00208         {
00209             const FTContour* contour = contourList[c];
00210 
00211             gluTessBeginContour( tobj);
00212             
00213                 for( size_t p = 0; p < contour->PointCount(); ++p)
00214                 {
00215                     FTGL_DOUBLE* d = const_cast<FTGL_DOUBLE*>(&contour->Point(p).x);
00216                     gluTessVertex( tobj, d, d);
00217                 }
00218 
00219             gluTessEndContour( tobj);
00220         }
00221         
00222     gluTessEndPolygon( tobj);
00223 
00224     gluDeleteTess( tobj);
00225 }
00226 

Generated on Wed Nov 19 19:35:34 2003 for FTGL by doxygen 1.3.4