ftvectoriser.cpp

来自「ftgl-2.1.2 夸平台的opengl显示字体」· C++ 代码 · 共 226 行

CPP
226
字号
#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"#endifvoid 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){    const FTGL_DOUBLE* vertex = static_cast<const FTGL_DOUBLE*>(coords);    *outData = const_cast<FTGL_DOUBLE*>(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);}const FTGL_DOUBLE* FTMesh::Combine( const FTGL_DOUBLE x, const FTGL_DOUBLE y, const FTGL_DOUBLE z){    tempPointList.push_back( FTPoint( x, y,z));    return static_cast<const FTGL_DOUBLE*>(tempPointList.back());}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)                {                    const FTGL_DOUBLE* d = contour->Point(p);                    gluTessVertex( tobj, (GLdouble*)d, (GLdouble*)d);                }            gluTessEndContour( tobj);        }            gluTessEndPolygon( tobj);    gluDeleteTess( tobj);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?