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