00001 #include "FTFace.h"
00002 #include "FTFont.h"
00003 #include "FTGlyphContainer.h"
00004 #include "FTBBox.h"
00005
00006
00007 FTFont::FTFont( const char* fontFilePath)
00008 : face( fontFilePath),
00009 useDisplayLists(true),
00010 preRenderCalled(false),
00011 glyphList(0)
00012 {
00013 err = face.Error();
00014 if( err == 0)
00015 {
00016 glyphList = new FTGlyphContainer( &face);
00017 }
00018 }
00019
00020
00021 FTFont::FTFont( const unsigned char *pBufferBytes, size_t bufferSizeInBytes)
00022 : face( pBufferBytes, bufferSizeInBytes),
00023 glyphList(0)
00024 {
00025 err = face.Error();
00026 if( err == 0)
00027 {
00028 glyphList = new FTGlyphContainer( &face);
00029 }
00030 }
00031
00032
00033 FTFont::~FTFont()
00034 {
00035 delete glyphList;
00036 }
00037
00038
00039 bool FTFont::Attach( const char* fontFilePath)
00040 {
00041 if( face.Attach( fontFilePath))
00042 {
00043 err = 0;
00044 return true;
00045 }
00046 else
00047 {
00048 err = face.Error();
00049 return false;
00050 }
00051 }
00052
00053
00054 bool FTFont::Attach( const unsigned char *pBufferBytes, size_t bufferSizeInBytes)
00055 {
00056 if( face.Attach( pBufferBytes, bufferSizeInBytes))
00057 {
00058 err = 0;
00059 return true;
00060 }
00061 else
00062 {
00063 err = face.Error();
00064 return false;
00065 }
00066 }
00067
00068
00069 bool FTFont::FaceSize( const unsigned int size, const unsigned int res )
00070 {
00071 charSize = face.Size( size, res);
00072 err = face.Error();
00073
00074 if( err != 0)
00075 {
00076 return false;
00077 }
00078
00079 if( glyphList != NULL)
00080 {
00081 delete glyphList;
00082 }
00083
00084 glyphList = new FTGlyphContainer( &face);
00085 return true;
00086 }
00087
00088
00089 unsigned int FTFont::FaceSize() const
00090 {
00091 return charSize.CharSize();
00092 }
00093
00094
00095 bool FTFont::CharMap( FT_Encoding encoding)
00096 {
00097 bool result = glyphList->CharMap( encoding);
00098 err = glyphList->Error();
00099 return result;
00100 }
00101
00102
00103 unsigned int FTFont::CharMapCount()
00104 {
00105 return face.CharMapCount();
00106 }
00107
00108
00109 FT_Encoding* FTFont::CharMapList()
00110 {
00111 return face.CharMapList();
00112 }
00113
00114
00115 void FTFont::UseDisplayList( bool useList)
00116 {
00117 useDisplayLists = useList;
00118 }
00119
00120 float FTFont::Ascender() const
00121 {
00122 return charSize.Ascender();
00123 }
00124
00125
00126 float FTFont::Descender() const
00127 {
00128 return charSize.Descender();
00129 }
00130
00131 float FTFont::LineHeight() const
00132 {
00133 return charSize.Height();
00134 }
00135
00136 void FTFont::BBox( const char* string,
00137 float& llx, float& lly, float& llz, float& urx, float& ury, float& urz)
00138 {
00139 FTBBox totalBBox;
00140
00141 if((NULL != string) && ('\0' != *string))
00142 {
00143 const unsigned char* c = (unsigned char*)string;
00144 float advance = 0;
00145
00146 if(CheckGlyph( *c))
00147 {
00148 totalBBox = glyphList->BBox( *c);
00149 advance = glyphList->Advance( *c, *(c + 1));
00150 }
00151
00152 while( *++c)
00153 {
00154 if(CheckGlyph( *c))
00155 {
00156 FTBBox tempBBox = glyphList->BBox( *c);
00157 tempBBox.Move( FTPoint( advance, 0.0f, 0.0f));
00158 totalBBox += tempBBox;
00159 advance += glyphList->Advance( *c, *(c + 1));
00160 }
00161 }
00162 }
00163
00164 llx = totalBBox.lowerX;
00165 lly = totalBBox.lowerY;
00166 llz = totalBBox.lowerZ;
00167 urx = totalBBox.upperX;
00168 ury = totalBBox.upperY;
00169 urz = totalBBox.upperZ;
00170 }
00171
00172
00173 void FTFont::BBox( const wchar_t* string,
00174 float& llx, float& lly, float& llz, float& urx, float& ury, float& urz)
00175 {
00176 FTBBox totalBBox;
00177
00178 if((NULL != string) && ('\0' != *string))
00179 {
00180 const wchar_t* c = string;
00181 float advance = 0;
00182
00183 if(CheckGlyph( *c))
00184 {
00185 totalBBox = glyphList->BBox( *c);
00186 advance = glyphList->Advance( *c, *(c + 1));
00187 }
00188
00189 while( *++c)
00190 {
00191 if(CheckGlyph( *c))
00192 {
00193 FTBBox tempBBox = glyphList->BBox( *c);
00194 tempBBox.Move( FTPoint( advance, 0.0f, 0.0f));
00195 totalBBox += tempBBox;
00196 advance += glyphList->Advance( *c, *(c + 1));
00197 }
00198 }
00199 }
00200
00201 llx = totalBBox.lowerX;
00202 lly = totalBBox.lowerY;
00203 llz = totalBBox.lowerZ;
00204 urx = totalBBox.upperX;
00205 ury = totalBBox.upperY;
00206 urz = totalBBox.upperZ;
00207 }
00208
00209
00210 float FTFont::Advance( const wchar_t* string)
00211 {
00212 const wchar_t* c = string;
00213 float width = 0.0f;
00214
00215 while( *c)
00216 {
00217 if(CheckGlyph( *c))
00218 {
00219 width += glyphList->Advance( *c, *(c + 1));
00220 }
00221 ++c;
00222 }
00223
00224 return width;
00225 }
00226
00227
00228 float FTFont::Advance( const char* string)
00229 {
00230 const unsigned char* c = (unsigned char*)string;
00231 float width = 0.0f;
00232
00233 while( *c)
00234 {
00235 if(CheckGlyph( *c))
00236 {
00237 width += glyphList->Advance( *c, *(c + 1));
00238 }
00239 ++c;
00240 }
00241
00242 return width;
00243 }
00244
00245
00246 void FTFont::Render( const char* string )
00247 {
00248 bool pre_post = ! preRenderCalled;
00249 if (pre_post) PreRender();
00250
00251 const unsigned char* c = (unsigned char*)string;
00252 pen.X(0); pen.Y(0);
00253
00254 while( *c)
00255 {
00256 if(CheckGlyph( *c))
00257 {
00258 pen = glyphList->Render( *c, *(c + 1), pen);
00259 }
00260 ++c;
00261 }
00262
00263 if (pre_post) PostRender();
00264 }
00265
00266
00267 void FTFont::Render( const char* string, float w_max, float w_fade )
00268 {
00269 bool pre_post = ! preRenderCalled;
00270 if (pre_post) PreRender();
00271
00272 float col[4];
00273 glGetFloatv(GL_CURRENT_COLOR, col);
00274 float alpha_fac = col[3] / (w_max - w_fade);
00275 float w = 0;
00276
00277 const unsigned char* c = (unsigned char*)string;
00278 pen.X(0); pen.Y(0);
00279
00280 while( *c)
00281 {
00282 if(CheckGlyph( *c))
00283 {
00284 pen = glyphList->Render( *c, *(c + 1), pen);
00285 w += pen.X();
00286 if(w > w_max)
00287 break;
00288 if(w > w_fade)
00289 {
00290 col[3] = alpha_fac * (w_max - w);
00291 glColor4fv(col);
00292 }
00293 }
00294 ++c;
00295 }
00296
00297 if (pre_post) PostRender();
00298 }
00299
00300
00301 void FTFont::Render( const wchar_t* string )
00302 {
00303 bool pre_post = ! preRenderCalled;
00304 if (pre_post) PreRender();
00305
00306 const wchar_t* c = string;
00307 pen.X(0); pen.Y(0);
00308
00309 while( *c)
00310 {
00311 if(CheckGlyph( *c))
00312 {
00313 pen = glyphList->Render( *c, *(c + 1), pen);
00314 }
00315 ++c;
00316 }
00317
00318 if (pre_post) PostRender();
00319 }
00320
00321
00322 bool FTFont::CheckGlyph( const unsigned int characterCode)
00323 {
00324 if( NULL == glyphList->Glyph( characterCode))
00325 {
00326 unsigned int glyphIndex = glyphList->FontIndex( characterCode);
00327 FTGlyph* tempGlyph = MakeGlyph( glyphIndex);
00328 if( NULL == tempGlyph)
00329 {
00330 if( 0 == err)
00331 {
00332 err = 0x13;
00333 }
00334
00335 return false;
00336 }
00337 glyphList->Add( tempGlyph, characterCode);
00338 }
00339
00340 return true;
00341 }
00342