00001 #include <iostream>
00002
00003 #include <math.h>
00004
00005 #include "FTExtrdGlyph.h"
00006 #include "FTVectoriser.h"
00007
00008
00009 FTExtrdGlyph::FTExtrdGlyph( FT_GlyphSlot glyph, float depth, bool useDisplayList)
00010 : FTGlyph( glyph),
00011 glList(0)
00012 {
00013 bBox.SetDepth( -depth);
00014
00015 if( ft_glyph_format_outline != glyph->format)
00016 {
00017 err = 0x14;
00018 return;
00019 }
00020
00021 FTVectoriser vectoriser( glyph);
00022 if( ( vectoriser.ContourCount() < 1) || ( vectoriser.PointCount() < 3))
00023 {
00024 return;
00025 }
00026
00027 unsigned int tesselationIndex;
00028
00029 if(useDisplayList)
00030 {
00031 glList = glGenLists(1);
00032 glNewList( glList, GL_COMPILE);
00033 }
00034
00035 vectoriser.MakeMesh( 1.0);
00036 glNormal3d(0.0, 0.0, 1.0);
00037
00038 unsigned int horizontalTextureScale = glyph->face->size->metrics.x_ppem * 64;
00039 unsigned int verticalTextureScale = glyph->face->size->metrics.y_ppem * 64;
00040
00041 const FTMesh* mesh = vectoriser.GetMesh();
00042 for( tesselationIndex = 0; tesselationIndex < mesh->TesselationCount(); ++tesselationIndex)
00043 {
00044 const FTTesselation* subMesh = mesh->Tesselation( tesselationIndex);
00045 unsigned int polyonType = subMesh->PolygonType();
00046
00047 glBegin( polyonType);
00048 for( unsigned int pointIndex = 0; pointIndex < subMesh->PointCount(); ++pointIndex)
00049 {
00050 FTPoint point = subMesh->Point(pointIndex);
00051
00052 glTexCoord2f( point.X() / horizontalTextureScale,
00053 point.Y() / verticalTextureScale);
00054
00055 glVertex3f( point.X() / 64.0f,
00056 point.Y() / 64.0f,
00057 0.0f);
00058 }
00059 glEnd();
00060 }
00061
00062 vectoriser.MakeMesh( -1.0);
00063 glNormal3d(0.0, 0.0, -1.0);
00064
00065 mesh = vectoriser.GetMesh();
00066 for( tesselationIndex = 0; tesselationIndex < mesh->TesselationCount(); ++tesselationIndex)
00067 {
00068 const FTTesselation* subMesh = mesh->Tesselation( tesselationIndex);
00069 unsigned int polyonType = subMesh->PolygonType();
00070
00071 glBegin( polyonType);
00072 for( unsigned int pointIndex = 0; pointIndex < subMesh->PointCount(); ++pointIndex)
00073 {
00074 FTPoint point = subMesh->Point(pointIndex);
00075
00076 glTexCoord2f( subMesh->Point(pointIndex).X() / horizontalTextureScale,
00077 subMesh->Point(pointIndex).Y() / verticalTextureScale);
00078
00079 glVertex3f( subMesh->Point( pointIndex).X() / 64.0f,
00080 subMesh->Point( pointIndex).Y() / 64.0f,
00081 -depth);
00082 }
00083 glEnd();
00084 }
00085
00086 int contourFlag = vectoriser.ContourFlag();
00087
00088 for( size_t c = 0; c < vectoriser.ContourCount(); ++c)
00089 {
00090 const FTContour* contour = vectoriser.Contour(c);
00091 unsigned int numberOfPoints = contour->PointCount();
00092
00093 glBegin( GL_QUAD_STRIP);
00094 for( unsigned int j = 0; j <= numberOfPoints; ++j)
00095 {
00096 unsigned int pointIndex = ( j == numberOfPoints) ? 0 : j;
00097 unsigned int nextPointIndex = ( pointIndex == numberOfPoints - 1) ? 0 : pointIndex + 1;
00098
00099 FTPoint point = contour->Point(pointIndex);
00100
00101 FTPoint normal = GetNormal( point, contour->Point(nextPointIndex));
00102 if(normal != FTPoint( 0.0f, 0.0f, 0.0f))
00103 {
00104 glNormal3dv((FTGL_DOUBLE*)normal);
00105 }
00106
00107 if( contourFlag & ft_outline_reverse_fill)
00108 {
00109 glTexCoord2f( point.X() / horizontalTextureScale,
00110 point.X() / verticalTextureScale);
00111
00112 glVertex3f( point.X() / 64.0f, point.Y() / 64.0f, 0.0f);
00113 glVertex3f( point.X() / 64.0f, point.Y() / 64.0f, -depth);
00114 }
00115 else
00116 {
00117 glTexCoord2f( point.X() / horizontalTextureScale,
00118 point.Y() / verticalTextureScale);
00119
00120 glVertex3f( point.X() / 64.0f, point.Y() / 64.0f, -depth);
00121 glVertex3f( point.X() / 64.0f, point.Y() / 64.0f, 0.0f);
00122 }
00123 }
00124 glEnd();
00125 }
00126
00127 if(useDisplayList)
00128 {
00129 glEndList();
00130 }
00131 }
00132
00133
00134 FTExtrdGlyph::~FTExtrdGlyph()
00135 {
00136 glDeleteLists( glList, 1);
00137 }
00138
00139
00140 const FTPoint& FTExtrdGlyph::Render( const FTPoint& pen)
00141 {
00142 glTranslatef( pen.X(), pen.Y(), 0);
00143
00144 if( glList)
00145 {
00146 glCallList( glList);
00147 }
00148
00149 return advance;
00150 }
00151
00152
00153 FTPoint FTExtrdGlyph::GetNormal( const FTPoint &a, const FTPoint &b)
00154 {
00155 float vectorX = a.X() - b.X();
00156 float vectorY = a.Y() - b.Y();
00157
00158 float length = sqrt( vectorX * vectorX + vectorY * vectorY );
00159
00160 if( length > 0.01f)
00161 {
00162 length = 1 / length;
00163 }
00164 else
00165 {
00166 length = 0.0f;
00167 }
00168
00169 return FTPoint( -vectorY * length,
00170 vectorX * length,
00171 0.0f);
00172 }
00173