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