1.安装交叉编译器freetype库
#安装部分
tar xjf freetype-2.4.10.tar.bz2
cd freetype-2.4.10/
#docs/INSTALL.CROSS 是对交叉编译的一个说明文档
#--host=arm-linux 交叉编译器时使用
#--buid=i386-unknown-freebsd 这个是在pc使用时使用
#--prefix=<prefix> 编译后生成的文件的目录,默认在usr/local(pc用)下,而这个给开发板用的,就得放到交叉工具链下
./config --host=arm-linux #选这个的时候,应该就默认用arm-linux-gcc来编译了
make DESTDIR=$PWD/tmp install
#把tmp/usr/local/lib/* 复制到 /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib
cd tmp/usr/local/lib/
sudo cp * /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib -d -rfd
#把tmp/usr/local/include/* 复制到 /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include
cd tmp/usr/local/include/
cp * /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include -rfd # d的意思是把 链接 也考过去
mv freetype2/freetype . #下面会讲为什么会有这个
#编译部分
arm-linux-gcc -o example1 example1.c -lfreetype -lm
sudo cp example1 simsun.ttc /work/nfs_root/
#开发板上运行
./example1 simsun.ttc abcd
注意事项:
1.编译出来的头文件放在 /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include
2.编译出来的库文件放在 /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib
3.正常来说,头文件目录和库文件目录应该是一样的,即以下这两个目录应该是一样的,不一样的话我们就把头文件和库文件编译到一个指定目录,然后再拷贝到相应的目录里去
/usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib
/usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include
在编译时就先指定到一个目录,然后编译好了再CP
4. mv freetype2/freetype
在我们拷贝了头文件和动态库到相应的位置后,我们编译会出错,错误信息如下
提示找不到 ftheader.h,我们去刚刚的头文件目录下搜索这个文件 /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include
发现路径多了一个freetype2,所以拷贝出来即可
5.编译时:arm-linux-gcc -o example1 example1.c -lfreetype -lm
-
我编译时没有加 ”-finput-charset=GBK“,是因为我用的是nodepad++写的程序,nodepad默认编码就是UTF-8,而韦东山用的是source insight,SI默认编码是GB2312,所以我不用加 -finput-charset=GBK,而韦东山需要加。
-
另外, -lfreetype -lm是添加动态链接库,不添加会出现一些函数找不到,如下图
6.运行时的问题(很重要!!)
韦东山在运行的时候多了条命令,拷贝动态链接库的命令
cp *so* /work/nfs_root/fs_mini_mdev_new/lib -d
这个是因为根文件系统不同,我直接用他给的根文件系统,里面有freetype的动态链接库
而他的是从服务器上挂载原始的根文件系统,所以没有动态库,需要拷贝一下。
为什么不拷贝头文件? 因为编译好了freetype程序后,头文件会被gcc展开存到可执行文件里,所以运行时,只会用到库文件.
2.LCD上显示汉字
1.添加头文件
#include <stdio.h>
#include <string.h>
#include <math.h>
#include<wchar.h>
#include <ft2build.h>
#include FT_FREETYPE_H
2.主函数中的内容
//初始化句柄,初始化库
error = FT_Init_FreeType( &library );
//加载face对象,也就是打开字库文件
error = FT_New_Face(library , "simsun.ttc" ,0 ,&face);
//设置字体大小
FT_Set_Pixel_Sizes(face,24,24);
slot = face->glyph;
/*不旋转,所以这里就不加那几个矩阵的初始化了*/
//设置从哪里开始显示,上面两行是像素字,都是高16的
//所以这里设置成从(0,32)开始显示 转换为笛卡尔坐标洗
target_height = var.yres; //获取屏幕的高度
pen.x = 0 * 64;
pen.y = (target_height - (32+24)) *64 ; // !!!注意这里,我们想让从(0,32)开始显示,一定要再多减去一个字符的高度,
//因为它是从左下角往上走的,而不是从左上角往下走的
//这个一会儿在下面详解
for ( n = 0; n < wcslen(wst) ; n++ ) //一个符号循环一次
{
//设置字用不用旋转和开始显示的位置
FT_Set_Transform( face, 0, &pen );
//转换为点阵
error = FT_Load_Char( face, wst[n] , FT_LOAD_RENDER );
if ( error )
continue;
//开始画点
draw_bitmap( &slot->bitmap,
slot->bitmap_left,
target_height - slot->bitmap_top );
/* increment pen position */
pen.x += slot->advance.x; //位置自加,算出下一个字符的位置
pen.y += slot->advance.y;
}
3.draw_bitmap()函数
void draw_bitmap( FT_Bitmap* bitmap,FT_Int x,FT_Int y)
{
FT_Int i, j, p, q; //i j表示的是物理坐标
FT_Int x_max = x + bitmap->width; //bitmap->width表示的是这个字的宽度
FT_Int y_max = y + bitmap->rows; //同理bitmap->row 这个字的高度
for ( i = x, p = 0; i < x_max; i++, p++ )
{
for ( j = y, q = 0; j < y_max; j++, q++ )
{
if ( i < 0 || j < 0 || i >= var.xres || j >= var.yres ) //这里判断目前的点在不在物理分辨率中,如果不在的话就不往显存写数据
continue;
//image[j][i] |= bitmap->buffer[q * bitmap->width + p];
lcd_put_pixel(i , j, bitmap->buffer[q * bitmap->width + p] );
}
}
}
4.如果要加倾斜
改动这两个地方
!!!!需要注意的是,一个C语言问题,就是计算angle的时候,倾斜角度(20.0),一定要是一个浮点型,如果是整形的话括号里算出就是0,最后angle算出也是0,相当于不倾斜
#ifdef QINGXIE //要不要倾斜一个角度
double angle=( 20.0 / 360 ) * 3.14159 * 2; //设置一个倾斜角度 20度
FT_Matrix matrix;
matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L ); //若设置了字体旋转,就需要这几行,固定的,只用把前面的angle按照那样算一下就行
matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );
/**************end矢量字用到的变量end**************/
#endif
/**************************************************************************/
#ifdef QINGXIE //要不要倾斜一个角度
FT_Set_Transform( face, &matrix, &pen );
#else
FT_Set_Transform( face, 0, &pen );
#endif
5.注意的地方
以上就是为什么在设置矢量坐标的时候,按照正常的坐标(左上角为原点),我们想让它开始于(0,32),而实际我们定位的时候多减去24 的原因。