Edit

kc3-lang/ftgl/src/FTExtrdGlyph.cpp

Branch :

  • Show log

    Commit

  • Author : henry
    Date : 2002-12-08 06:57:27
    Hash : 6b4e1f14
    Message : Made vectoriser a local variable

  • src/FTExtrdGlyph.cpp
  • #include    <math.h>
    
    #include    "FTExtrdGlyph.h"
    #include    "FTVectoriser.h"
    
    
    FTExtrdGlyph::FTExtrdGlyph( FT_Glyph glyph, float d)
    :   FTGlyph(),
        glList(0),
        depth(d)
    {
        if( ft_glyph_format_outline != glyph->format)
        {
            return;
        }
    
        FTVectoriser* vectoriser = new FTVectoriser( glyph);
        
        vectoriser->ProcessContours();
    
        // Make the front polygons
        vectoriser->MakeMesh( 1.0);
        
        bBox = FTBBox( glyph);
        bBox.upperZ = -depth;
        advance = glyph->advance.x >> 16;
        
        int numPoints = vectoriser->MeshPoints();
        if ( numPoints < 3)
        {
            delete vectoriser;
            return;
        }
        
        FTGL_DOUBLE* frontMesh = new FTGL_DOUBLE[ numPoints * 3];
        vectoriser->GetMesh( frontMesh);
        
        // Make the back polygons
        vectoriser->MakeMesh( -1.0);
        
        numPoints = vectoriser->MeshPoints();
        if ( numPoints < 3)
        {
            delete vectoriser;
            delete [] frontMesh;
            return;
        }
        
        FTGL_DOUBLE* backMesh =  new FTGL_DOUBLE[ numPoints * 3];
        vectoriser->GetMesh( backMesh);
        
        numPoints = vectoriser->points();
        int numContours = vectoriser->contours(); // FIXME
        
        if ( ( numContours < 1) || ( numPoints < 3))
        {
            delete vectoriser;
            delete [] frontMesh;
            delete [] backMesh;
            return;
        }
        
        // Build the edge polygons
        int* contourLength = new int[ numContours];
        for( int cn = 0; cn < numContours; ++cn)
        {
            contourLength[cn] = vectoriser->contourSize( cn);
        }
        
        FTGL_DOUBLE* sidemesh = new FTGL_DOUBLE[ numPoints * 3];
        vectoriser->GetOutline( sidemesh);
        
        delete vectoriser;
        
        // Draw the glyph
        int offset = 0;
        glList = glGenLists(1);
        glNewList( glList, GL_COMPILE);
        // Render Front Mesh
            int i;
            int BEPairs = static_cast<int>(frontMesh[0]);
            for( i = 0; i < BEPairs; ++i)
            {
                int polyType = (int)frontMesh[offset + 1];
                glBegin( polyType);
                    glNormal3d(0.0, 0.0, 1.0);
            
                    int verts = (int)frontMesh[offset+2];
                    offset += 3;
                    for( int x = 0; x < verts; ++x)
                    {
                        glVertex3dv( frontMesh + offset);
                        offset += 3;
                    }
                glEnd();
            }
            
        // Render Back Mesh
            offset = 0;
            BEPairs = static_cast<int>(backMesh[0]);
            for( i = 0; i < BEPairs; ++i)
            {
                int polyType = (int)backMesh[offset + 1];
                glBegin( polyType);
    
                    glNormal3d(0.0, 0.0, -1.0);
                    int verts = (int)backMesh[offset+2];
                    offset += 3;
                    for( int x = 0; x < verts; ++x)
                    {
                        glVertex3d( backMesh[offset], backMesh[offset + 1], -depth); // FIXME
                        offset += 3;
                    }
                glEnd();
            }
            
            FT_OutlineGlyph outline = (FT_OutlineGlyph)glyph;
            FT_Outline ftOutline = outline->outline;
            int contourFlag = ftOutline.flags; // this is broken for winding direction in freetype...           
            // BUT THIS DOESN'T WORK EITHER!!!!!
    //      bool winding = Winding( contourLength[0], sidemesh);
                            
        // Join them together.
            // Extrude each contour to make the sides.
            FTGL_DOUBLE* contour = sidemesh;
            for (int c=0; c<numContours; ++c)
            {
                // Make a quad strip using each successive
                // pair of points in this contour.
                numPoints = contourLength[c];
                
                glBegin( GL_QUAD_STRIP);
    
                    for( int j= 0; j <= numPoints; ++j)
                    {
                        int j1 = (j < numPoints) ? j : 0;
                        int j0 = (j1 == 0) ? (numPoints-1) : (j1-1);
    
                        FTGL_DOUBLE* p0 = contour + j0*3;
                        FTGL_DOUBLE* p1 = contour + j1*3;
    
                        // Compute normal for this quad.
                        FTGL_DOUBLE vx = p1[0] - p0[0];
                        FTGL_DOUBLE vy = p1[1] - p0[1];
                        // Normalise
                        FTGL_DOUBLE length = sqrt( ( ( vx * vx) + ( vy * vy)));
                        vx /= length; vy /= length;
                        glNormal3d(-vy, vx, 0.0);
                        
                        // Add vertices to the quad strip.
                        // Winding order
                        if( contourFlag & ft_outline_reverse_fill)
    //                  if( winding)
                        {
                            glVertex3d(p0[0], p0[1], 0);
                            glVertex3d(p0[0], p0[1], -depth);
                        }
                        else
                        {
                            glVertex3d(p0[0], p0[1], -depth);
                            glVertex3d(p0[0], p0[1], 0);
                        }
                    } // for
                glEnd();
                contour += numPoints*3;
            } // for 
            
            
        glEndList();
    
        delete [] sidemesh; // FIXME
        delete [] frontMesh;
        delete [] backMesh;
        delete [] contourLength;
    
        // discard glyph image (bitmap or not)
        FT_Done_Glyph( glyph); // Why does this have to be HERE
    }
    
    
    FTExtrdGlyph::~FTExtrdGlyph()
    {
    }
    
    
    bool FTExtrdGlyph::Winding( int numPoints, FTGL_DOUBLE *points)
    {
        // Calculate the winding direction. use formula from redbook.
        FTGL_DOUBLE area = 0;
        
        for( int count = 0; count <= numPoints; ++count)
        {
            int j1 = (count < numPoints) ? count : 0;
            int j0 = (j1 == 0) ? ( numPoints - 1) : ( j1 - 1);
    
            FTGL_DOUBLE* p0 = points + j0 * 3;
            FTGL_DOUBLE* p1 = points + j1 * 3;
    
            area += ( p0[0] * p1[1]) - ( p1[0] * p0[1]);    
        }
        
        return( area >= 0 );
    }
    
    
    float FTExtrdGlyph::Render( const FTPoint& pen)
    {
        if( glList)
        {
            glTranslatef( pen.x, pen.y, 0);
                glCallList( glList);    
            glTranslatef( -pen.x, -pen.y, 0);
        }
        
        return advance;
    }