Edit

kc3-lang/ftgl/src/FTContour.cpp

Branch :

  • Show log

    Commit

  • Author : henry
    Date : 2002-12-08 04:37:28
    Hash : 739dac83
    Message : Moved from FTVectoriser to own file

  • src/FTContour.cpp
  • #include "FTContour.h"
    
    static const unsigned int SECOND_ORDER_CURVE = 2;
    static const unsigned int THIRD_ORDER_CURVE = 3;
    
    
    FTContour::FTContour( FT_Vector* contour, char* pointTags, unsigned int numberOfPoints)
    :   kBSTEPSIZE( 0.2f)
    {   
        FTVector<ContourPoint> tempPointList;
        
        for( unsigned int pointIndex = 0; pointIndex < numberOfPoints; ++ pointIndex)
        {
            if( pointIndex == numberOfPoints - 1)
            {
                if( pointTags[pointIndex] == FT_Curve_Tag_Conic && pointTags[0] == FT_Curve_Tag_Conic)
                {
                    tempPointList.push_back( ContourPoint( FTPoint( contour[pointIndex]), pointTags[pointIndex]));
        
                    FTPoint implicitPoint( static_cast<float>( contour[pointIndex].x + contour[0].x) * 0.5f,
                                           static_cast<float>( contour[pointIndex].y + contour[0].y) * 0.5f,
                                           0);
                    tempPointList.push_back( ContourPoint( implicitPoint, FT_Curve_Tag_On));
                }
                else
                {
                    tempPointList.push_back( ContourPoint( FTPoint( contour[pointIndex]), pointTags[pointIndex]));
                }
            }
            else if( pointTags[pointIndex] == FT_Curve_Tag_Conic && pointTags[pointIndex + 1] == FT_Curve_Tag_Conic)
            {
                tempPointList.push_back( ContourPoint( FTPoint( contour[pointIndex]), pointTags[pointIndex]));
    
                FTPoint implicitPoint( static_cast<float>( contour[pointIndex].x + contour[pointIndex + 1].x) * 0.5f,
                                       static_cast<float>( contour[pointIndex].y + contour[pointIndex + 1].y) * 0.5f,
                                       0);
                tempPointList.push_back( ContourPoint( implicitPoint, FT_Curve_Tag_On));
            }
            else
            {
                tempPointList.push_back( ContourPoint( FTPoint( contour[pointIndex]), pointTags[pointIndex]));
            }
        }
    
        for( unsigned int pointIndex = 0; pointIndex < tempPointList.size();)
        {
            switch( tempPointList[pointIndex].tag)
            {
                case FT_Curve_Tag_Conic:
                    EvaluateConicCurve( pointIndex, tempPointList);
                    ++pointIndex;
                    break;
                case FT_Curve_Tag_Cubic:
                    EvaluateCubicCurve( pointIndex, tempPointList);
                    pointIndex += 2;
                    break;
                case FT_Curve_Tag_On:
                default:
                    AddPoint( tempPointList[pointIndex].point);
                    ++pointIndex;
                    break;
            }
        }
        
    }
    
    
    void FTContour::AddPoint( FTPoint point)
    {
        if( pointList.empty() || point != pointList[pointList.size() - 1])
        {
            pointList.push_back( point);
        }
    }
    
    
    void FTContour::EvaluateConicCurve( const int index, const FTVector<ContourPoint>& pointList)
    {
        unsigned int controlPoint = index;
        unsigned int startPoint = index -1;
        unsigned int endPoint = index + 1;
        
        if( 0 == controlPoint)
        {
            startPoint = pointList.size() - 1;
        }
        else if( pointList.size() - 1 == controlPoint)
        {
            endPoint = 0;
        }
        
        ctrlPtArray[0][0] = pointList[startPoint].point.x;   ctrlPtArray[0][1] = pointList[startPoint].point.y;
        ctrlPtArray[1][0] = pointList[controlPoint].point.x; ctrlPtArray[1][1] = pointList[controlPoint].point.y;
        ctrlPtArray[2][0] = pointList[endPoint].point.x;     ctrlPtArray[2][1] = pointList[endPoint].point.y;
        
        evaluateCurve( SECOND_ORDER_CURVE);
    }
    
    
    void FTContour::EvaluateCubicCurve( const int index, const FTVector<ContourPoint>& pointList)
    {
        unsigned int controlPointOne = index;
        unsigned int controlPointTwo = index + 1;
        unsigned int startPoint = index -1;
        
        if( controlPointOne == pointList.size() - 1)
        {
            controlPointTwo = 0; 
        }
        
        unsigned int endPoint = controlPointTwo + 1;
        
        if( controlPointTwo == pointList.size() - 1)
        {
            endPoint = 0;
        }
        
        if( 0 == controlPointOne)
        {
            startPoint = pointList.size() - 1; 
        }
    
        ctrlPtArray[0][0] = pointList[startPoint].point.x;      ctrlPtArray[0][1] = pointList[startPoint].point.y;
        ctrlPtArray[1][0] = pointList[controlPointOne].point.x; ctrlPtArray[1][1] = pointList[controlPointOne].point.y;
        ctrlPtArray[2][0] = pointList[controlPointTwo].point.x; ctrlPtArray[2][1] = pointList[controlPointTwo].point.y;
        ctrlPtArray[3][0] = pointList[endPoint].point.x;        ctrlPtArray[3][1] = pointList[endPoint].point.y;
    
        evaluateCurve( THIRD_ORDER_CURVE);
    }
    
    
    void FTContour::deCasteljau( const float t, const int n)
    {
        //Calculating successive b(i)'s using de Casteljau algorithm.
        for( int i = 1; i <= n; i++)
        {
            for( int k = 0; k <= (n - i); k++)
            {
                bValues[i][k][0] = (1 - t) * bValues[i - 1][k][0] + t * bValues[i - 1][k + 1][0];
                bValues[i][k][1] = (1 - t) * bValues[i - 1][k][1] + t * bValues[i - 1][k + 1][1];
            }
        }
           
        //Specify next vertex to be included on curve
        AddPoint( FTPoint( bValues[n][0][0], bValues[n][0][1], 0));
    }
    
    
    void FTContour::evaluateCurve( const int n)
    {
        // setting the b(0) equal to the control points
        for( int i = 0; i <= n; i++)
        {
            bValues[0][i][0] = ctrlPtArray[i][0];
            bValues[0][i][1] = ctrlPtArray[i][1];
        }
    
        float t; //parameter for curve point calc. [0.0, 1.0]
    
        for( int m = 0; m <= ( 1 / kBSTEPSIZE); m++)
        {
            t = m * kBSTEPSIZE;
            deCasteljau( t, n);  //calls to evaluate point on curve at t.
        }
    }