1. 初始化FT lib
FT_Library library; /* handle to library */
FT_Face face; /* handle to face object */
// 1. Init the library
if ( FT_Init_FreeType( &library ) )
{
MessageBox(_T("Init freetype library failed."), _T("Error"), MB_OK | MB_ICONERROR);
FT_Done_FreeType(library);
return;
}
int nface = 0;
//nface = 1;
//pathstring是TTF文件的路径
FT_Error error = FT_New_Face(
library,
pathstring,
nface,
&face );
if ( error == FT_Err_Unknown_File_Format )
{
MessageBox(_T("Font format not supported."), _T("Error"), MB_OK | MB_ICONERROR);
FT_Done_FreeType(library);
return;
}
else if ( error )
{
MessageBox(_T("Font face open failed."), _T("Error"), MB_OK | MB_ICONERROR);
FT_Done_FreeType(library);
return;
}
2. 获取font face信息
AddMessage(_T("Face information:"));
//glyph数量
sMessage.Format(_T(" Totally %d glyphs."), face->num_glyphs);
AddMessage(sMessage);
//每EM unit数量
sMessage.Format(_T(" %d uints per EM."), face->units_per_EM);
AddMessage(sMessage);
//char map数量
sMessage.Format(_T(" %d char maps."), face->num_charmaps);
AddMessage(sMessage);
//fix size
//这个对于汉字很重要,fix size对于小字体显示很有帮助
sMessage.Format(_T(" %d fixed sizes:"), face->num_fixed_sizes);
if(face->available_sizes)
{
for(int ii = 0 ; ii < face->num_fixed_sizes ; ii++)
{
sTemp.Format(_T(" %d"), face->available_sizes[ii].size / 64);
sMessage += sTemp;
}
}
AddMessage(sMessage);
int iUnderlinePos = 0;
//下划线位置
if( FT_IS_SCALABLE(face) )
{
iUnderlinePos = FT_MulFix( face->underline_position , face->size->metrics.y_scale);
iUnderlinePos >>= 6;
sMessage.Format(_T(" underline position:%d"), iUnderlinePos);
AddMessage(sMessage);
}
3. 设置参数,为获取glyph image做准备
//按pixel大小设置字体尺寸
FT_Set_Pixel_Sizes(face, m_iFontHeight, m_iFontHeight);
//检查是否SCALABLE
if( !FT_IS_SCALABLE(face) )
{
//Not a scalable font (Truetype or Type1)
ASSERT(0);
}
//当需要竖排文字时检查是否支持
if( !m_bHorizontal && !FT_HAS_VERTICAL(face))
{
MessageBox(_T("This font doesn't support vertical layout!"), _T("Error"), MB_OK | MB_ICONERROR);
// Do the clean up
FT_Done_Face( face );
FT_Done_FreeType(library);
return;
}
//下面这个matrix用于设置斜体字
FT_Matrix matrix; /* transformation matrix */
matrix.xx = 1 << 16;
matrix.xy = 0x5800;
matrix.yx = 0;
matrix.yy = 1 << 16;
4. 获取glyph,并设置格式
//curchar是该字符的unicode编码
FT_Load_Char(face, curchar, FT_LOAD_DEFAULT);
if(m_bBold)
{//加粗
int strength = 1 << 6;
FT_Outline_Embolden(&face->glyph->outline, strength);
}
if(m_bItalic)
{//斜体
/* set transformation */
//FT_Set_Transform( face, &matrix, 0 );
FT_Outline_Transform(&face->glyph->outline, &matrix);
}
5. Render glyph,准备拷贝glyph image
ftResult = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
if (ftResult)
{
continue;//因为这是在一个循环中
}
// 获取该文字整个宽度,包含跨距
FT_Int advance = (face->glyph->advance.x >> 6 );// + pixelwordspacing;
// 得到渲染后bitmap buffer指针
unsigned char* buffer = face->glyph->bitmap.buffer;
if (!buffer)
{
continue;
}
6. 拷贝glyph image
switch (face->glyph->bitmap.pixel_mode)
{
case FT_PIXEL_MODE_GRAY:
{
for(int k = 0; k < face->glyph->bitmap.width; k++ )
{
pixelclr = buffer[j * face->glyph->bitmap.pitch + k];
// 可以使用pixelclr作为alpha值
// pDest是显示用的image内存指针
*pDest++= pixelclr;
}
break;
case FT_PIXEL_MODE_MONO:
//很多人不知道这个对应的就是fix size时的图片格式,每个bit对应一个点,非黑即白
for(int k = 0; k < face->glyph->bitmap.width; k++ )
{
pixelclr = (src [k / 8] & (0x80 >> (k & 7))) ? 0xFFFFFFFF : 0x00000000;
// pDest是显示用的image内存指针
*pDest++= pixelclr;
}
break;
default:
//throw InvalidRequestException("Error - unsupported pixel mode");
break;
}
7. 关于竖排文字
//
ftResult = FT_Load_Char( face, curchar, FT_LOAD_DEFAULT | FT_LOAD_VERTICAL_LAYOUT);