1. 交叉编译 freetype
#include
#include
#include
#include
#include
#include
int main()
{
FT_Error error;
FT_Library library;
FT_Face face;
int glyph_index;
FT_GlyphSlot slot;
FT_Glyph glyph;
error = FT_Init_FreeType ( &library );
if ( error )
{
printf("init a freetype library error!\n");
return -1;
}
error = FT_New_Face( library, "./arial.ttf", 0, &face );
//error = FT_New_Face( library, "/usr/share/fonts/zh_CN/TrueType/zysong.ttf", 0, &face );
//error = FT_New_Face( library, "/usr/share/fonts/KhmerOS.ttf", 0, &face );
if ( error == FT_Err_Unknown_File_Format )
{
printf("open font file failed! -1 \n");
return -1;
/*可以打开和读这个文件,但不支持它的字体格式*/
}
else if ( error )
{
printf("open font file failed! -2\n");
return -2;
/*... 其它的错误码意味着这个字体文件不能打开和读,或者简单的说它损坏了... */
}
error = FT_Set_Char_Size(
face, /* face对象的句柄 */
16*64, /* 以1/64点为单位的字符宽度 */
16*64, /* 以1/64点为单位的字符高度 */
300, /* 设备水平分辨率 */
300 ); /* 设备垂直分辨率 */
/*
一个face对象包含一个或多个字符表(charmap),
字符表是用来转换字符码到字形索引的。
例如,很多TrueType字体包含两个字符表,一个用来转换Unicode字符码到字形索引,
另一个用来转换Apple Roman编码到字形索引。
这样的字体既可以用在Windows(使用Unicode)和Macintosh(使用Apple Roman)。
同时要注意,一个特定的字符表可能没有覆盖完字体里面的全部字形。
当新建一个face对象时,它默认选择Unicode字符表。
如果字体没包含Unicode字符表,
FreeType会尝试在字形名的基础上模拟一个。注意,
如果字形名是不标准的那么模拟的字符表有可能遗漏某些字形。
对于某些字体,包括符号字体和旧的亚洲手写字体,Unicode模拟是不可能的。
*/
glyph_index = FT_Get_Char_Index( face, 29233 ); /* 爱的unicode编码为29233*/
printf("get the glyph_index = %d\n",glyph_index);
error = FT_Load_Glyph(
face, /* face对象的句柄 */
glyph_index, /* 字形索引 */
0); /* 装载标志load_flags的值是位标志集合,
是用来指示某些特殊操作的。
其默认值是FT_LOAD_DEFAULT即0。 */
if(error)
{
printf("Ft_Load_Glyph return error!\n");
return -1;
}
#if 1
error = FT_Get_Glyph(face->glyph, &glyph);
printf("bitmap top = %d ,left=%d\n",face->glyph->bitmap_top ,face->glyph->bitmap_left);
if ( !error)
{
// convert glyph to bitmap with 256 gray
FT_Bitmap *Pbitmap;
int i,j;
FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0 , 1 );
FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;
Pbitmap = &(bitmap_glyph->bitmap);
printf("get bitmap.rows =%d , bitmap.witdth=%d\n",Pbitmap->rows,Pbitmap->width);
printf("num_grays =%d\n",Pbitmap->num_grays);
printf("pitch = %d\n",Pbitmap->pitch);
printf("pixel_mode=%d\n",Pbitmap->pixel_mode);
for (i = 0 ; i < Pbitmap->rows; ++ i)
{
for ( j= 0 ; j < Pbitmap->width; ++ j)
{
// if it has gray>0 we set show it as 1, o otherwise
//printf( " %d " , Pbitmap->buffer[i * Pbitmap->width + j] );
printf( "%c" , Pbitmap->buffer[i * Pbitmap->width + j] ? 'O' : '_' );
}
printf( "\n" );
}
// free glyph
FT_Done_Glyph(glyph);
glyph = NULL;
}
#endif
FT_Done_Face(face);
face = NULL;
return 0;
}
其实,上面的例子仅仅是把一个字符给解析出来后用printf打印出来。真正用的时候,肯定得将解析出来的灰阶值转换成RGB值,并把相应的点显示出来。 在现实多个字符的时候,还要考虑前一个字符的长、宽 、高、左间距。(参考 Pbitmap->rows,Pbitmap->width,face->glyph->bitmap_top ,face->glyph->bitmap_left). 另外矢量字库有很多种,在嵌入式系统里受容量的限制我们可以选择小一点的字库大概只有200KB左右。