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