00001 #include "FTContour.h"
00002
00003 static const float BEZIER_STEP_SIZE = 0.2f;
00004
00005
00006 void FTContour::AddPoint( FTPoint point)
00007 {
00008 if( pointList.empty() || point != pointList[pointList.size() - 1])
00009 {
00010 pointList.push_back( point);
00011 }
00012 }
00013
00014
00015 void FTContour::AddPoint( float x, float y)
00016 {
00017 AddPoint( FTPoint( x, y, 0.0f));
00018 }
00019
00020
00021 void FTContour::evaluateQuadraticCurve()
00022 {
00023 for( unsigned int i = 0; i <= ( 1.0f / BEZIER_STEP_SIZE); i++)
00024 {
00025 float bezierValues[2][2];
00026
00027 float t = static_cast<float>(i) * BEZIER_STEP_SIZE;
00028
00029 bezierValues[0][0] = (1.0f - t) * controlPoints[0][0] + t * controlPoints[1][0];
00030 bezierValues[0][1] = (1.0f - t) * controlPoints[0][1] + t * controlPoints[1][1];
00031
00032 bezierValues[1][0] = (1.0f - t) * controlPoints[1][0] + t * controlPoints[2][0];
00033 bezierValues[1][1] = (1.0f - t) * controlPoints[1][1] + t * controlPoints[2][1];
00034
00035 bezierValues[0][0] = (1.0f - t) * bezierValues[0][0] + t * bezierValues[1][0];
00036 bezierValues[0][1] = (1.0f - t) * bezierValues[0][1] + t * bezierValues[1][1];
00037
00038 AddPoint( bezierValues[0][0], bezierValues[0][1]);
00039 }
00040 }
00041
00042 void FTContour::evaluateCubicCurve()
00043 {
00044 for( unsigned int i = 0; i <= ( 1.0f / BEZIER_STEP_SIZE); i++)
00045 {
00046 float bezierValues[3][2];
00047
00048 float t = static_cast<float>(i) * BEZIER_STEP_SIZE;
00049
00050 bezierValues[0][0] = (1.0f - t) * controlPoints[0][0] + t * controlPoints[1][0];
00051 bezierValues[0][1] = (1.0f - t) * controlPoints[0][1] + t * controlPoints[1][1];
00052
00053 bezierValues[1][0] = (1.0f - t) * controlPoints[1][0] + t * controlPoints[2][0];
00054 bezierValues[1][1] = (1.0f - t) * controlPoints[1][1] + t * controlPoints[2][1];
00055
00056 bezierValues[2][0] = (1.0f - t) * controlPoints[2][0] + t * controlPoints[3][0];
00057 bezierValues[2][1] = (1.0f - t) * controlPoints[2][1] + t * controlPoints[3][1];
00058
00059 bezierValues[0][0] = (1.0f - t) * bezierValues[0][0] + t * bezierValues[1][0];
00060 bezierValues[0][1] = (1.0f - t) * bezierValues[0][1] + t * bezierValues[1][1];
00061
00062 bezierValues[1][0] = (1.0f - t) * bezierValues[1][0] + t * bezierValues[2][0];
00063 bezierValues[1][1] = (1.0f - t) * bezierValues[1][1] + t * bezierValues[2][1];
00064
00065 bezierValues[0][0] = (1.0f - t) * bezierValues[0][0] + t * bezierValues[1][0];
00066 bezierValues[0][1] = (1.0f - t) * bezierValues[0][1] + t * bezierValues[1][1];
00067
00068 AddPoint( bezierValues[0][0], bezierValues[0][1]);
00069 }
00070 }
00071
00072
00073 FTContour::FTContour( FT_Vector* contour, char* pointTags, unsigned int numberOfPoints)
00074 {
00075 for( unsigned int pointIndex = 0; pointIndex < numberOfPoints; ++ pointIndex)
00076 {
00077 char pointTag = pointTags[pointIndex];
00078
00079 if( pointTag == FT_Curve_Tag_On || numberOfPoints < 2)
00080 {
00081 AddPoint( contour[pointIndex].x, contour[pointIndex].y);
00082 continue;
00083 }
00084
00085 FTPoint controlPoint( contour[pointIndex]);
00086 FTPoint previousPoint = ( 0 == pointIndex)
00087 ? FTPoint( contour[numberOfPoints - 1])
00088 : pointList[pointList.size() - 1];
00089
00090 FTPoint nextPoint = ( pointIndex == numberOfPoints - 1)
00091 ? pointList[0]
00092 : FTPoint( contour[pointIndex + 1]);
00093
00094 if( pointTag == FT_Curve_Tag_Conic)
00095 {
00096 char nextPointTag = ( pointIndex == numberOfPoints - 1)
00097 ? pointTags[0]
00098 : pointTags[pointIndex + 1];
00099
00100 while( nextPointTag == FT_Curve_Tag_Conic)
00101 {
00102 nextPoint = FTPoint( static_cast<float>( controlPoint.x + nextPoint.x) * 0.5f,
00103 static_cast<float>( controlPoint.y + nextPoint.y) * 0.5f,
00104 0);
00105
00106 controlPoints[0][0] = previousPoint.x; controlPoints[0][1] = previousPoint.y;
00107 controlPoints[1][0] = controlPoint.x; controlPoints[1][1] = controlPoint.y;
00108 controlPoints[2][0] = nextPoint.x; controlPoints[2][1] = nextPoint.y;
00109
00110 evaluateQuadraticCurve();
00111 ++pointIndex;
00112
00113 previousPoint = nextPoint;
00114 controlPoint = FTPoint( contour[pointIndex]);
00115 nextPoint = ( pointIndex == numberOfPoints - 1)
00116 ? pointList[0]
00117 : FTPoint( contour[pointIndex + 1]);
00118 nextPointTag = ( pointIndex == numberOfPoints - 1)
00119 ? pointTags[0]
00120 : pointTags[pointIndex + 1];
00121 }
00122
00123 controlPoints[0][0] = previousPoint.x; controlPoints[0][1] = previousPoint.y;
00124 controlPoints[1][0] = controlPoint.x; controlPoints[1][1] = controlPoint.y;
00125 controlPoints[2][0] = nextPoint.x; controlPoints[2][1] = nextPoint.y;
00126
00127 evaluateQuadraticCurve();
00128 continue;
00129 }
00130
00131 if( pointTag == FT_Curve_Tag_Cubic)
00132 {
00133 FTPoint controlPoint2 = nextPoint;
00134
00135 FTPoint nextPoint = ( pointIndex == numberOfPoints - 2)
00136 ? pointList[0]
00137 : FTPoint( contour[pointIndex + 2]);
00138
00139 controlPoints[0][0] = previousPoint.x; controlPoints[0][1] = previousPoint.y;
00140 controlPoints[1][0] = controlPoint.x; controlPoints[1][1] = controlPoint.y;
00141 controlPoints[2][0] = controlPoint2.x; controlPoints[2][1] = controlPoint2.y;
00142 controlPoints[3][0] = nextPoint.x; controlPoints[3][1] = nextPoint.y;
00143
00144 evaluateCubicCurve();
00145 ++pointIndex;
00146 continue;
00147 }
00148 }
00149 }