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 = ( controlPoint + nextPoint) * 0.5f;
00103
00104 controlPoints[0][0] = previousPoint.X(); controlPoints[0][1] = previousPoint.Y();
00105 controlPoints[1][0] = controlPoint.X(); controlPoints[1][1] = controlPoint.Y();
00106 controlPoints[2][0] = nextPoint.X(); controlPoints[2][1] = nextPoint.Y();
00107
00108 evaluateQuadraticCurve();
00109 ++pointIndex;
00110
00111 previousPoint = nextPoint;
00112 controlPoint = FTPoint( contour[pointIndex]);
00113 nextPoint = ( pointIndex == numberOfPoints - 1)
00114 ? pointList[0]
00115 : FTPoint( contour[pointIndex + 1]);
00116 nextPointTag = ( pointIndex == numberOfPoints - 1)
00117 ? pointTags[0]
00118 : pointTags[pointIndex + 1];
00119 }
00120
00121 controlPoints[0][0] = previousPoint.X(); controlPoints[0][1] = previousPoint.Y();
00122 controlPoints[1][0] = controlPoint.X(); controlPoints[1][1] = controlPoint.Y();
00123 controlPoints[2][0] = nextPoint.X(); controlPoints[2][1] = nextPoint.Y();
00124
00125 evaluateQuadraticCurve();
00126 continue;
00127 }
00128
00129 if( pointTag == FT_Curve_Tag_Cubic)
00130 {
00131 FTPoint controlPoint2 = nextPoint;
00132
00133 FTPoint nextPoint = ( pointIndex == numberOfPoints - 2)
00134 ? pointList[0]
00135 : FTPoint( contour[pointIndex + 2]);
00136
00137 controlPoints[0][0] = previousPoint.X(); controlPoints[0][1] = previousPoint.Y();
00138 controlPoints[1][0] = controlPoint.X(); controlPoints[1][1] = controlPoint.Y();
00139 controlPoints[2][0] = controlPoint2.X(); controlPoints[2][1] = controlPoint2.Y();
00140 controlPoints[3][0] = nextPoint.X(); controlPoints[3][1] = nextPoint.Y();
00141
00142 evaluateCubicCurve();
00143 ++pointIndex;
00144 continue;
00145 }
00146 }
00147 }