freetype的移植笔记
经过一段时间的移植freetype,在网上找了许多的资料,看完之后还有有点云里雾里的感觉,大部分的文档也是官方网上的文档翻译过来的,就比如sfnt,网上是说这是字体的标识,具体的就不知道是干嘛的了,所以还是就纠结。但发现
FT_USE_MODULE( FT_Module_Class, sfnt_module_class )这个模块必须有,下面就主要说下移植的步骤和代码。用的是freetype-2.5.4,移植到arm9上虽然运行了下的操作系统,访问题的字库在内存中,所以没有文件访问的调用。
1.ftmodule.h文件
只保留了下面几个模块
FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class )
FT_USE_MODULE( FT_Module_Class, sfnt_module_class )
//FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class ) //8位图采用
FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class )//支持1位图
FT_USE_MODULE( FT_Module_Class, sfnt_module_class )
//FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class ) //8位图采用
FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class )//支持1位图
8位图和1位图就不介绍了,我用的是位图的,因为只需要得到一个字体的内存块,如果用8位图的话,还得拼装成一块完整的内存块。sfnt_module_class 模块我也没明白,但不可缺少,看来就是字体标识的东东吧。
2.ftoption.h
这个文件我就保留了几个宏,问题中多是一些宏开关,其他的都注释了。
#define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT //因为字库是放在内存中的,所以没有数据流这个概念。如果是要访问文件的话,比如带Linux操作系统。
#define FT_RENDER_POOL_SIZE 16384L
#define FT_MAX_MODULES 32
#define TT_CONFIG_CMAP_FORMAT_4 //可能和字库有关,我的只需要这个。
3.src目录下的工程文件
(1)base目录
(2)src下的替他目录
4.ftbase.c
#include <ft2build.h>
#define FT_MAKE_OPTION_SINGLE_OBJECT
//#include "ftpic.c"
//#include "basepic.c"
//#include "ftadvanc.c"
#include "ftcalc.c"
//#include "ftdbgmem.c"
#include "ftgloadr.c"
#include "ftobjs.c"
#include "ftoutln.c"
#include "ftrfork.c"
//#include "ftsnames.c"
#include "ftstream.c"
#include "fttrigon.c"
#include "ftutil.c"
#ifdef FT_MACINTOSH
//#include "ftmac.c"
#endif
#define FT_MAKE_OPTION_SINGLE_OBJECT
//#include "ftpic.c"
//#include "basepic.c"
//#include "ftadvanc.c"
#include "ftcalc.c"
//#include "ftdbgmem.c"
#include "ftgloadr.c"
#include "ftobjs.c"
#include "ftoutln.c"
#include "ftrfork.c"
//#include "ftsnames.c"
#include "ftstream.c"
#include "fttrigon.c"
#include "ftutil.c"
#ifdef FT_MACINTOSH
//#include "ftmac.c"
#endif
5.最后就是字库编程的主要流程了,主要流程几乎很许多资料一样,代码如下:
unsigned char glyph_buff[256 * 32]; // 字体最大位图为 256 x 256,存放最后输出的字形图
int font_size = 0;
int ShowString(int ucode[],int lengh,char *LibFont)
{
FT_Library pFTLib = NULL;
FT_Face pFTFace = NULL;
FT_Error error = 0 ;
int n;
int num_chars;
num_chars=lengh;
FT_Long file_size = 15323232;//font size 14.6M
unsigned char *mem_addr = LibFont;
error = FT_Init_FreeType( & pFTLib);
//PRINTF("FT_Init_FreeType error = %d",error);
error = FT_New_Memory_Face( pFTLib,mem_addr,file_size,0,& pFTFace);
//PRINTF(" FT_New_Memory_Face error = %d",error);
if ( ! error)
{
FT_Glyph glyph;
FT_UInt glyph_index;
FT_GlyphSlot slot;
slot = pFTFace->glyph;
int font_size = 0;
int ShowString(int ucode[],int lengh,char *LibFont)
{
FT_Library pFTLib = NULL;
FT_Face pFTFace = NULL;
FT_Error error = 0 ;
int n;
int num_chars;
num_chars=lengh;
FT_Long file_size = 15323232;//font size 14.6M
unsigned char *mem_addr = LibFont;
error = FT_Init_FreeType( & pFTLib);
//PRINTF("FT_Init_FreeType error = %d",error);
error = FT_New_Memory_Face( pFTLib,mem_addr,file_size,0,& pFTFace);
//PRINTF(" FT_New_Memory_Face error = %d",error);
if ( ! error)
{
FT_Glyph glyph;
FT_UInt glyph_index;
FT_GlyphSlot slot;
slot = pFTFace->glyph;
error = FT_Set_Pixel_Sizes(pFTFace,0,font_size);//设置字体的大小,你也可以调用另外接口。
sys_trace(" FT_Set_Pixel_Sizeserror = %d",error);
for ( n = 0; n < num_chars; n++ )
{
glyph_index = FT_Get_Char_Index( pFTFace, ucode[n] );//获得字索引
error = FT_Load_Glyph( pFTFace, glyph_index, FT_LOAD_DEFAULT);// FT_LOAD_RENDER
error = FT_Get_Glyph(pFTFace -> glyph, & glyph);
error = FT_Render_Glyph(pFTFace->glyph, FT_RENDER_MODE_MONO); // 1位图
int fill = font_size - pFTFace->glyph->bitmap.rows;// 填充的部分
int fill = font_size - pFTFace->glyph->bitmap.rows;
for (j = 0; j < fill; j++)
{
memset(glyph_buff + pFTFace->glyph->bitmap.pitch*j,0,pFTFace->glyph->bitmap.pitch);
for (i = 0; i < font_size; i++)
{
PutChar('0');
}
sys_trace("\r");
}
int k = 0,temp,counter,l = 0;
for (; j < font_size;j++,l++)
{
memcpy(glyph_buff + pFTFace->glyph->bitmap.pitch*j,pFTFace->glyph->bitmap.buffer + l * pFTFace->glyph->bitmap.pitch ,pFTFace->glyph->bitmap.pitch);
for (i = 0; i < pFTFace->glyph->bitmap_left; i++)
{
PutChar(' ');
}
for (k = 0; k < pFTFace->glyph->bitmap.pitch; k++)
{
temp = pFTFace->glyph->bitmap.buffer[pFTFace->glyph->bitmap.pitch*(j - fill) + k];
for (counter = 0; counter < 8; counter++)
{
if (temp & 0x80){
PutChar('*');
} else{
PutChar(' ');
}
temp <<= 1;
i++;
if (i > font_size)
{
break;
}
}
}
for (; i < font_size; i++)
{
PutChar(' ');
}
sys_trace("\r");
}
for (j = 0; j < fill; j++)
{
memset(glyph_buff + pFTFace->glyph->bitmap.pitch*j,0,pFTFace->glyph->bitmap.pitch);
for (i = 0; i < font_size; i++)
{
PutChar('0');
}
sys_trace("\r");
}
int k = 0,temp,counter,l = 0;
for (; j < font_size;j++,l++)
{
memcpy(glyph_buff + pFTFace->glyph->bitmap.pitch*j,pFTFace->glyph->bitmap.buffer + l * pFTFace->glyph->bitmap.pitch ,pFTFace->glyph->bitmap.pitch);
for (i = 0; i < pFTFace->glyph->bitmap_left; i++)
{
PutChar(' ');
}
for (k = 0; k < pFTFace->glyph->bitmap.pitch; k++)
{
temp = pFTFace->glyph->bitmap.buffer[pFTFace->glyph->bitmap.pitch*(j - fill) + k];
for (counter = 0; counter < 8; counter++)
{
if (temp & 0x80){
PutChar('*');
} else{
PutChar(' ');
}
temp <<= 1;
i++;
if (i > font_size)
{
break;
}
}
}
for (; i < font_size; i++)
{
PutChar(' ');
}
sys_trace("\r");
}
//填充内存块
//memset(glyph_buff, 0, pFTFace->glyph->bitmap.pitch * fill);
//memcpy(glyph_buff+ pFTFace->glyph->bitmap.pitch * fill, pFTFace->glyph->bitmap.buffer, pFTFace->glyph->bitmap.pitch * pFTFace->glyph->bitmap.rows);
}
FT_Done_Face(pFTFace);
pFTFace = NULL;
}
FT_Done_FreeType(pFTLib);
pFTLib = NULL;
return 0;
}
int main()
{
int len = 1;
int text[4];
font_size = 64;
text[0]=39551; //驿
ShowString(text,len,LibFont);
}
//memcpy(glyph_buff+ pFTFace->glyph->bitmap.pitch * fill, pFTFace->glyph->bitmap.buffer, pFTFace->glyph->bitmap.pitch * pFTFace->glyph->bitmap.rows);
}
FT_Done_Face(pFTFace);
pFTFace = NULL;
}
FT_Done_FreeType(pFTLib);
pFTLib = NULL;
return 0;
}
int main()
{
int len = 1;
int text[4];
font_size = 64;
text[0]=39551; //驿
ShowString(text,len,LibFont);
}
6.串口输出的结果:
7.可以通过调用FT_Set_Transform()将字体旋转。
具体的API中。
http://www.freetype.org