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 }