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