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