#include "FTFace.h" #include "FTFont.h" #include "FTGlyphContainer.h" #include "FTBBox.h" FTFont::FTFont( const char* fontname) : face( fontname), glyphList(0) { err = face.Error(); if( err == 0) { glyphList = new FTGlyphContainer( &face); } } FTFont::FTFont( const unsigned char *pBufferBytes, size_t bufferSizeInBytes) : face( pBufferBytes, bufferSizeInBytes), glyphList(0) { err = face.Error(); if( err == 0) { glyphList = new FTGlyphContainer( &face); } } FTFont::~FTFont() { delete glyphList; } bool FTFont::Attach( const char* filename) { if( face.Attach( filename)) { err = 0; return true; } else { err = face.Error(); return false; } } bool FTFont::Attach( const unsigned char *pBufferBytes, size_t bufferSizeInBytes) { if( face.Attach( pBufferBytes, bufferSizeInBytes)) { err = 0; return true; } else { err = face.Error(); return false; } } bool FTFont::FaceSize( const unsigned int size, const unsigned int res ) { charSize = face.Size( size, res); if( face.Error()) { return false; } if( glyphList != NULL) { delete glyphList; } glyphList = new FTGlyphContainer( &face); return true; } unsigned int FTFont::FaceSize() const { return charSize.CharSize(); } bool FTFont::CharMap( FT_Encoding encoding) { bool result = glyphList->CharMap( encoding); err = glyphList->Error(); return result; } unsigned int FTFont::CharMapCount() { return face.CharMapCount(); } FT_Encoding* FTFont::CharMapList() { return face.CharMapList(); } float FTFont::Ascender() const { return charSize.Ascender(); } float FTFont::Descender() const { return charSize.Descender(); } void FTFont::BBox( const char* string, float& llx, float& lly, float& llz, float& urx, float& ury, float& urz) { FTBBox totalBBox; if((NULL != string) && ('\0' != *string)) { const unsigned char* c = (unsigned char*)string; CheckGlyph( *c); totalBBox = glyphList->BBox( *c); float advance = glyphList->Advance( *c, *(c + 1)); ++c; while( *c) { CheckGlyph( *c); FTBBox tempBBox = glyphList->BBox( *c); tempBBox.Move( FTPoint( advance, 0.0f, 0.0f)); totalBBox += tempBBox; advance += glyphList->Advance( *c, *(c + 1)); ++c; } } llx = totalBBox.lowerX; lly = totalBBox.lowerY; llz = totalBBox.lowerZ; urx = totalBBox.upperX; ury = totalBBox.upperY; urz = totalBBox.upperZ; } void FTFont::BBox( const wchar_t* string, float& llx, float& lly, float& llz, float& urx, float& ury, float& urz) { FTBBox totalBBox; if((NULL != string) && ('\0' != *string)) { const wchar_t* c = string; CheckGlyph( *c); totalBBox = glyphList->BBox( *c); float advance = glyphList->Advance( *c, *(c + 1)); ++c; while( *c) { CheckGlyph( *c); FTBBox tempBBox = glyphList->BBox( *c); tempBBox.Move( FTPoint( advance, 0.0f, 0.0f)); totalBBox += tempBBox; advance += glyphList->Advance( *c, *(c + 1)); ++c; } } llx = totalBBox.lowerX; lly = totalBBox.lowerY; llz = totalBBox.lowerZ; urx = totalBBox.upperX; ury = totalBBox.upperY; urz = totalBBox.upperZ; } float FTFont::Advance( const wchar_t* string) { const wchar_t* c = string; float width = 0.0f; while( *c) { CheckGlyph( *c); width += glyphList->Advance( *c, *(c + 1)); ++c; } return width; } float FTFont::Advance( const char* string) { const unsigned char* c = (unsigned char*)string; float width = 0.0f; while( *c) { CheckGlyph( *c); width += glyphList->Advance( *c, *(c + 1)); ++c; } return width; } void FTFont::Render( const char* string ) { const unsigned char* c = (unsigned char*)string; pen.x = 0; pen.y = 0; while( *c) { DoRender( *c, *(c + 1)); ++c; } } void FTFont::Render( const wchar_t* string ) { const wchar_t* c = string; pen.x = 0; pen.y = 0; while( *c) { DoRender( *c, *(c + 1)); ++c; } } void FTFont::DoRender( const unsigned int chr, const unsigned int nextChr) { CheckGlyph( chr); FTPoint kernAdvance = glyphList->Render( chr, nextChr, pen); pen.x += kernAdvance.x; pen.y += kernAdvance.y; } void FTFont::CheckGlyph( const unsigned int characterCode) { if( NULL == glyphList->Glyph( characterCode)) { unsigned int glyphIndex = glyphList->FontIndex( characterCode); glyphList->Add( MakeGlyph( glyphIndex), characterCode); } }