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 }