00001 #include <math.h>
00002
00003 #include "FTExtrdGlyph.h"
00004 #include "FTVectoriser.h"
00005
00006
00007 FTExtrdGlyph::FTExtrdGlyph( FT_Glyph glyph, float d)
00008 : FTGlyph( glyph),
00009 glList(0),
00010 depth(d)
00011 {
00012 bBox.upperZ = -depth;
00013
00014 if( ft_glyph_format_outline != glyph->format)
00015 {
00016 return;
00017 }
00018
00019 FTVectoriser vectoriser( glyph);
00020 if ( ( vectoriser.ContourCount() < 1) || ( vectoriser.PointCount() < 3))
00021 {
00022 return;
00023 }
00024
00025 unsigned int tesselationIndex;
00026 glList = glGenLists(1);
00027 glNewList( glList, GL_COMPILE);
00028
00029 vectoriser.MakeMesh( 1.0);
00030 glNormal3d(0.0, 0.0, 1.0);
00031
00032 const FTMesh* mesh = vectoriser.GetMesh();
00033 for( tesselationIndex = 0; tesselationIndex < mesh->TesselationCount(); ++tesselationIndex)
00034 {
00035 const FTTesselation* subMesh = mesh->Tesselation( tesselationIndex);
00036 unsigned int polyonType = subMesh->PolygonType();
00037
00038 glBegin( polyonType);
00039 for( unsigned int pointIndex = 0; pointIndex < subMesh->PointCount(); ++pointIndex)
00040 {
00041 glVertex3f( subMesh->Point( pointIndex).x / 64.0f,
00042 subMesh->Point( pointIndex).y / 64.0f,
00043 0.0f);
00044 }
00045 glEnd();
00046 }
00047
00048 vectoriser.MakeMesh( -1.0);
00049 glNormal3d(0.0, 0.0, -1.0);
00050
00051 mesh = vectoriser.GetMesh();
00052 for( tesselationIndex = 0; tesselationIndex < mesh->TesselationCount(); ++tesselationIndex)
00053 {
00054 const FTTesselation* subMesh = mesh->Tesselation( tesselationIndex);
00055 unsigned int polyonType = subMesh->PolygonType();
00056
00057 glBegin( polyonType);
00058 for( unsigned int pointIndex = 0; pointIndex < subMesh->PointCount(); ++pointIndex)
00059 {
00060 glVertex3f( subMesh->Point( pointIndex).x / 64.0f,
00061 subMesh->Point( pointIndex).y / 64.0f,
00062 -depth);
00063 }
00064 glEnd();
00065 }
00066
00067 int contourFlag = vectoriser.ContourFlag();
00068
00069 for( size_t c = 0; c < vectoriser.ContourCount(); ++c)
00070 {
00071 const FTContour* contour = vectoriser.Contour(c);
00072 unsigned int numberOfPoints = contour->PointCount();
00073
00074 glBegin( GL_QUAD_STRIP);
00075 for( unsigned int j = 0; j <= numberOfPoints; ++j)
00076 {
00077 unsigned int index = ( j == numberOfPoints) ? 0 : j;
00078 unsigned int nextIndex = ( index == numberOfPoints - 1) ? 0 : index + 1;
00079
00080 FTPoint normal = GetNormal( contour->Point(index), contour->Point(nextIndex));
00081 glNormal3f( normal.x, normal.y, 0.0f);
00082
00083 if( contourFlag & ft_outline_reverse_fill)
00084 {
00085 glVertex3f( contour->Point(index).x / 64.0f, contour->Point(index).y / 64.0f, 0.0f);
00086 glVertex3f( contour->Point(index).x / 64.0f, contour->Point(index).y / 64.0f, -depth);
00087 }
00088 else
00089 {
00090 glVertex3f( contour->Point(index).x / 64.0f, contour->Point(index).y / 64.0f, -depth);
00091 glVertex3f( contour->Point(index).x / 64.0f, contour->Point(index).y / 64.0f, 0.0f);
00092 }
00093 }
00094 glEnd();
00095 }
00096
00097 glEndList();
00098
00099
00100 FT_Done_Glyph( glyph);
00101 }
00102
00103
00104 FTExtrdGlyph::~FTExtrdGlyph()
00105 {
00106 glDeleteLists( glList, 1);
00107 }
00108
00109
00110 float FTExtrdGlyph::Render( const FTPoint& pen)
00111 {
00112 if( glList)
00113 {
00114 glTranslatef( pen.x, pen.y, 0);
00115 glCallList( glList);
00116 glTranslatef( -pen.x, -pen.y, 0);
00117 }
00118
00119 return advance;
00120 }
00121
00122
00123 FTPoint FTExtrdGlyph::GetNormal( const FTPoint &a, const FTPoint &b)
00124 {
00125 float vectorX = a.x - b.x;
00126 float vectorY = a.y - b.y;
00127
00128 float length = sqrt( vectorX * vectorX + vectorY * vectorY );
00129
00130 if( length > 0.0f)
00131 {
00132 length = 1 / length;
00133 }
00134 else
00135 {
00136 length = 0.0f;
00137 }
00138
00139 return FTPoint( -vectorY * length,
00140 vectorX * length,
00141 0.0f);
00142 }
00143