以下以移植到SPCE3200为例
从http://www.freetype.org/下载代码。
可以下载总计三份资料:
ft241.zip freetype源码
ftdmo241.zip freetype demo源码
ftdoc241.zip freetype文档
把freetype源码解压,可以看到其中有src、include和builds几个目录(当然还有其他的,暂时不用关心)
用S+core IDE新建一个library工程,并将src和include复制到工程下
接下来,需要将src和include中的文件添加到工程。
不过,不能将所有文件全部添加,因为其中某些.c已经将其他的.c include进来了。
具体该添加哪些文件,需要参考在builds\win32\visualc\目录下的vc的工程。
打开这个vc的工程,参照Source Files 中的文件列表,将这些文件添加到S+core project里。

然后,在S+core IDE内设置Additional Directories,将include目录添加进来。

然后编译即可。
我编译的时候,出现找不到#include后面的宏的情况,可能是因为编译器在处理预编译指令的时候顺序问题造成的。
修改include\freetype\config\ftheader.h头文件,在里面包含:
#include <freetype\internal\internal.h>
再编译,没有发现其他问题。
编译之后可以得到freetype的library。
freetype因为在内部并没有涉及到任何有关OS的特性的操作,所以在Non-OS平台下可以非常方便的使用。
另外,freetype原生支持memory font和filesystem font两种形态的TrueType字库文件,并且可以允许用户自行编写I/O function对任意形式的字库文件进行存取。
memory font使用起来比较方便,只需要把字库文件一并链接到程序中,就可以访问,不需要增加额外的软件包进来。
这一点,也可以保证不管是在哪个平台下,只要ram或者rom够大,就可以先来尝试freetype的魅力了。
如果在SPCE3200平台下使用freetype去装载sd card上的ttf文件,需要有ufat的支持,并且,freetype使用的是流式的文件操作函数(fopen、fread、fwrite之类的),而ufat默认没有提供流式的文件操作函数,所以必须将ufat更新到ufatv1.2的版本,才可以正常使用!
对freetype的使用,有相关doc可以参考。这里贴一段小范例程序,供参考
#include <ft2build.h>
#include FT_FREETYPE_H
#include "Resource.h"
#include "TFT\TFT_API.h"
#include "UFAT\UFAT.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
typedef UINT16 UNI_CHAR;
//下面两个函数是SPCE3200平台下的文件系统中提供的unicode和GB2312转换的API
//因为在TrueType font中,是以Unicode为直接支持的编码的。
int uni2char(UNI_CHAR uni, unsigned char *out);
int char2uni(const char **rawstring, UNI_CHAR * uni);
//下面的函数可以将获取到的某个字符的bitmap画到LCD上
void draw_bitmap(WIN_HANDLE win, FT_Face face, FT_Int x, FT_Int y)
{
COLOR bkColor = TFT_GetColor(win);
FT_Int xoff = face->glyph->bitmap_left;
FT_Int yoff = face->glyph->metrics.vertAdvance / 64 - face->glyph->bitmap_top;
// FT_Int yoff = face->glyph->bitmap_top - face->glyph->metrics.horiBearingY / 64;
FT_Int i, j, p, q;
FT_Int x_max = x + face->glyph->bitmap.width;
FT_Int y_max = y + face->glyph->bitmap.rows;
for(j = y, q = 0; j < y_max; j++, q++)
{
unsigned char *pData = face->glyph->bitmap.buffer + q * face->glyph->bitmap.width;
for(i = x, p = 0; i < x_max; i++, p++)
{
if(*pData > 0x7F)
TFT_PutPixel(win, i + xoff, j + yoff);
pData++;
}
}
#if 0
for ( i = x, p = 0; i < x_max; i++, p++ )
{
for ( j = y, q = 0; j < y_max; j++, q++ )
{
COLOR drawColor = COLOR_BLACK;
int nIndex = q * face->glyph->bitmap.width + p;
unsigned char nData = face->glyph->bitmap.buffer[nIndex];
drawColor = nData;// | 0xFF00;
TFT_SetColor(win, drawColor);
TFT_PutPixel(win, i + xoff, j + yoff);
}
}
#endif
TFT_SetColor(win, bkColor);
}
//下面这个函数可以显示一个字符串,其中使用到了FT_Load_Char,该函数用于获取到某个字符的bitmap
void putString(WIN_HANDLE win, FT_Face face, int x, int y, const char *string)
{
int cx = x;
while(*string)
{
UNI_CHAR ch;
char2uni(&string, &ch);
FT_Load_Char(face, ch, FT_LOAD_RENDER);
int w = face->glyph->metrics.horiAdvance / 64;
if((cx + w) >= TFT_WIDTH)
{
cx = 0;
y += face->glyph->metrics.vertAdvance / 64;
}
draw_bitmap(win, face, cx, y);
cx += w;
if(y >= TFT_HEIGHT)
break;
}
}
//====================================================
// 语法格式:int main(void)
// 功能描述: 主函数
// 入口参数: 无
// 出口参数: 无
//====================================================
int main(void)
{
int FONT_SIZE = 32;
/************************************************/
/* Attach ISRs. See User_IRQ.c for details */
/************************************************/
AP_Init_SysIRQs();
/************************************************/
/* TODO: add your code here */
/************************************************/
fs_init();
while(fs_mount(0));
chdir("A:\\");
FT_Library library; /* handle to library */
FT_Error error;
FT_Face face; /* handle to face object */
// 首先初始化FreeType library
error = FT_Init_FreeType(&library); /* initialize library */
// 然后从sd card 装载一个TrueType字体
error = FT_New_Face(library,
"A:\\Stxihei.ttf",
0, &face);
// 设置字体大小
error = FT_Set_Char_Size(face, FONT_SIZE * 64, 0,
64, 64 ); /* set character size */
// 下面这段代码可以用于对字体进行变形
FT_Matrix matrix; /* transformation matrix */
FT_Vector pen; /* untransformed origin */
pen.x = 0;//30 * 64;
pen.y = 0;//( target_height - 30 ) * 64;
double angle = ( -0.0 / 360 ) * 3.14159 * 2;
matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );
// FT_Set_Transform( face, &matrix, &pen );
// 初始化LCD并显示字符
TFT_Init();
WIN_HANDLE win = TFT_CreateWindowEx(0, 0, TFT_WIDTH, TFT_HEIGHT, COLOR_BLACK);
putString(win, face, 0, 0, “测试一下哈test1234567890”);
return 0;
}