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_GlyphSlot glyph) 00102 : contourList(0), 00103 mesh(0), 00104 ftContourCount(0), 00105 contourFlag(0) 00106 { 00107 if( glyph) 00108 { 00109 outline = glyph->outline; 00110 00111 ftContourCount = outline.n_contours;; 00112 contourList = 0; 00113 contourFlag = outline.flags; 00114 00115 ProcessContours(); 00116 } 00117 } 00118 00119 00120 FTVectoriser::~FTVectoriser() 00121 { 00122 for( size_t c = 0; c < ContourCount(); ++c) 00123 { 00124 delete contourList[c]; 00125 } 00126 00127 delete [] contourList; 00128 delete mesh; 00129 } 00130 00131 00132 void FTVectoriser::ProcessContours() 00133 { 00134 short contourLength = 0; 00135 short startIndex = 0; 00136 short endIndex = 0; 00137 00138 contourList = new FTContour*[ftContourCount]; 00139 00140 for( short contourIndex = 0; contourIndex < ftContourCount; ++contourIndex) 00141 { 00142 FT_Vector* pointList = &outline.points[startIndex]; 00143 char* tagList = &outline.tags[startIndex]; 00144 00145 endIndex = outline.contours[contourIndex]; 00146 contourLength = ( endIndex - startIndex) + 1; 00147 00148 FTContour* contour = new FTContour( pointList, tagList, contourLength); 00149 00150 contourList[contourIndex] = contour; 00151 00152 startIndex = endIndex + 1; 00153 } 00154 } 00155 00156 00157 size_t FTVectoriser::PointCount() 00158 { 00159 size_t s = 0; 00160 for( size_t c = 0; c < ContourCount(); ++c) 00161 { 00162 s += contourList[c]->PointCount(); 00163 } 00164 00165 return s; 00166 } 00167 00168 00169 const FTContour* const FTVectoriser::Contour( unsigned int index) const 00170 { 00171 return ( index < ContourCount()) ? contourList[index] : NULL; 00172 } 00173 00174 00175 void FTVectoriser::MakeMesh( FTGL_DOUBLE zNormal) 00176 { 00177 if( mesh) 00178 { 00179 delete mesh; 00180 } 00181 00182 mesh = new FTMesh; 00183 00184 GLUtesselator* tobj = gluNewTess(); 00185 00186 gluTessCallback( tobj, GLU_TESS_BEGIN_DATA, (GLUTesselatorFunction)ftglBegin); 00187 gluTessCallback( tobj, GLU_TESS_VERTEX_DATA, (GLUTesselatorFunction)ftglVertex); 00188 gluTessCallback( tobj, GLU_TESS_COMBINE_DATA, (GLUTesselatorFunction)ftglCombine); 00189 gluTessCallback( tobj, GLU_TESS_END_DATA, (GLUTesselatorFunction)ftglEnd); 00190 gluTessCallback( tobj, GLU_TESS_ERROR_DATA, (GLUTesselatorFunction)ftglError); 00191 00192 if( contourFlag & ft_outline_even_odd_fill) // ft_outline_reverse_fill 00193 { 00194 gluTessProperty( tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); 00195 } 00196 else 00197 { 00198 gluTessProperty( tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO); 00199 } 00200 00201 00202 gluTessProperty( tobj, GLU_TESS_TOLERANCE, 0); 00203 gluTessNormal( tobj, 0.0f, 0.0f, zNormal); 00204 gluTessBeginPolygon( tobj, mesh); 00205 00206 for( size_t c = 0; c < ContourCount(); ++c) 00207 { 00208 const FTContour* contour = contourList[c]; 00209 00210 gluTessBeginContour( tobj); 00211 00212 for( size_t p = 0; p < contour->PointCount(); ++p) 00213 { 00214 FTGL_DOUBLE* d = const_cast<FTGL_DOUBLE*>(&contour->Point(p).x); 00215 gluTessVertex( tobj, d, d); 00216 } 00217 00218 gluTessEndContour( tobj); 00219 } 00220 00221 gluTessEndPolygon( tobj); 00222 00223 gluDeleteTess( tobj); 00224 } 00225

Generated on Wed Aug 18 19:46:15 2004 for FTGL by doxygen 1.3.7