前言:
使用 buildroot 来给 ARM 板编译程序、编译库会很简单,以后系统讲解 buildroot 时再使用 buildroot,现在我们还是手工交叉编译 freetype,这种方法在编译、安装一些小程序时很有用。
Freetype 是开源的字体引擎库,它提供统一的接口来访问多种字体格式文件, 从而实现矢量字体显示。我们只需要移植这个字体引擎,调用对应的 API 接口, 提供字体文件,就可以让 freetype 库帮我们取出关键点、实现闭合曲线,填充颜色,达到显示矢量字体的目的。
目录
一、程序运行的一些基础知识
1.编译程序时去哪找头文件?
2.链接时去哪找库文件?
3.运行时去哪找库文件?
二、常见错误的解决方法
1.头文件问题
2.库文件问题
3.运行问题
三、交叉编译程序的万能命令
1.进行万能命令:
2.把头文件、库文件放到工具链目录里
四、使用 freetype 显示单个文字
1.矢量字体引入
2.Freetype 介绍
3.在 LCD 上显示一个矢量字体
(1)使用 wchar_t 获得字符的 UNICODE 值
(2)使用 freetype 得到位图
(3)在屏幕上显示位图
五、在 LCD 上令矢量字体旋转某个角度
关键代码
六、使用 freetype 显示一行文字
1.笛卡尔坐标系
2.每个字符的大小可能不同
3.怎么在指定位置显示一行文字
4.freetype 的几个重要数据结构
(1)FT_Library
(2)FT_Face
(3) FT_GlyphSlot
(4)FT_Glyph
(5)FT_BBox
5.示例代码如下:
6.计算一行文字的外框
7.调整原点并绘制
七、编译与上机测试
1.显示一个字体
(1)编译程序
(2)上机测试:
(3)实验效果:
2.进行字体翻转
(1)编译程序
(2)上机测试
(3)实验效果
3.显示一行文字
(1)编译程序
(2)上机测试
(3)实验效果
一、程序运行的一些基础知识
1.编译程序时去哪找头文件?
系统目录:就是交叉编译工具链里的某个 include 目录;也可以自己指定:编译时用 “ -I dir ”选项指定。
2.链接时去哪找库文件?
系统目录:就是交叉编译工具链里的某个 lib 目录;也可以自己指定:链接 时用 “ -L dir ”选项指定。
3.运行时去哪找库文件?
系统目录:就是板子上的/lib、/usr/lib 目录;也可以自己指定:运行程序用环境变量 LD_LIBRARY_PATH 指定。 运行时不需要头文件,所以头文件不用放到板子上。
二、常见错误的解决方法
1.头文件问题
编译时找不到头文件。在程序中这样包含头文件:#include <xxx.h>
对于尖括号里的头文件,去哪里找它?
系统目录:就是交叉编译工具链里的某个 include 目录;
也可以自己指定:编译时用 “ -I dir ”选项指定。
怎么确定“系统目录”? 执行下面命令确定目录:
echo 'main(){}'| arm-buildroot-linux-gnueabihf-gcc -E -v -
它会列出头文件目录、库目录(LIBRARY_PATH)。 你需要在头文件目录中确定有没有这个文件,或是自己指定头文件目录。
2.库文件问题
链接程序时如果有这样的提示:undefined reference to `xxx',它表示 xxx 函数未定义。
(1)去写出这个函数
(2)或是使用库函数,那需要在链接时指定库
怎么指定库?想链接 libabc.so,那链接时加上:-labc。
库在哪里?
系统目录:就是交叉编译工具链里的某个 lib 目录
也可以自己指定:链接时用 “ -L dir ”选项指定
怎么确定“系统目录”?执行下面命令确定目录:
echo 'main(){}'| arm-buildroot-linux-gnueabihf-gcc -E -v –
它会列出头文件目录、库目录(LIBRARY_PATH)。 你需要在头文件目录中确定有没有这个文件,或是自己指定头文件目录。
查看stdio.h 的头文件的目录
book@100ask:~$ ls /home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/include/stdio.h
查看lib库目录
book@100ask:~$ ls /home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/lib/
3.运行问题
运行程序时找不到库:
error while loading shared libraries: libxxx.so: cannot open shared object file: No such file or directory
找不到库,库在哪?
系统目录:就是板子上的/lib、/usr/lib 目录
也可以自己指定:
运行程序用环境变量 LD_LIBRARY_PATH 指定,执行以下的命令:
export LD_LIBRARY_PATH=/xxx_dir ; ./test
或者
LD_LIBRARY_PATH=/xxx_dir ./test
三、交叉编译程序的万能命令
1.进行万能命令:
如果交叉编辑工具链的前缀是 arm-buildroot-linux-gnueabihf-,比如 arm-buildroot-linux-gnueabihf-gcc,交叉编译开源软件时,如果它里面有configure
万能命令如下:
book@100ask:~/source/10_freetype/freetype-2.10.2$ ./configure --host=arm-buildroot-linux-gnueabihf --prefix=$PWD/tmp
book@100ask:~/source/10_freetype/freetype-2.10.2$ make
book@100ask:~/source/10_freetype/freetype-2.10.2$ make install
就可以在当前目录的 tmp 目录下看见 bin, lib, include 等目录,里面存有可执行程序、库、头文件。
2.把头文件、库文件放到工具链目录里
如果你编译的是一个库,请把得到的头文件、库文件放入工具链的 include、 lib 目录里。别的程序要使用这些头文件、库时,会很方便。
工具链里可能有多个 include、lib 目录,放到哪里去?
按照上面步骤找到你最喜欢的目录进行cp
echo 'main(){}'| arm-buildroot-linux-gnueabihf-gcc -E -v –
它会列出头文件目录、库目录(LIBRARY_PATH)
程序在板子上运行时,需要用到板子上/lib 或/usr/lib 下的库文件;程序运行时不需要头文件。
//把头文件放到工具交叉链中
book@100ask:~/source/10_freetype/freetype-2.10.2/tmp/include$ cp * -rf //home/book/100ask_imx6ull-sdk/ToolChain/a rm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/include
//把库文件放到工具交叉链中
book@100ask:~/source/10_freetype/freetype-2.10.2/tmp/lib$ cp -drf * /home/book/100ask_imx6ull-sdk/ToolChain/arm-b uildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/lib/
四、使用 freetype 显示单个文字
1.矢量字体引入
使用点阵字库显示英文字母、汉字时,大小固定,如果放大缩小则会模糊甚至有锯齿出现,为了解决这个问题,引用矢量字体。
矢量字体形成分三步:
第1步 确定关键点
第2步 使用数学曲线(贝塞尔曲线)连接头键点
第3步 填充闭合区线内部空间。
什么是关键点?以字母“A”为例,它的的关键点如图 中的黄色所示。
再用数学曲线(比如贝塞尔曲线)将关键点都连接起来,得到一系列的封闭的曲线
最后把封闭空间填满颜色,就显示出一个 A 字母
如果需要放大或者缩小字体,关键点的相对位置是不变的,只要数学曲线平 滑,字体就不会变形。
2.Freetype 介绍
关 键 点 (glyph) 存 在 字 体 文 件 中 , Windows 使 用 的 字 体 文 件 在 c:\Windows\Fonts 目录下,扩展名为 TTF 的都是矢量字库,我们的是新宋字体 simsun.ttc。
给定一个字符,怎么在字体文件中找到它的关键点?
首先要确定该字符的编码值:比如 ASCII 码、GB2312 码、UNICODE 码。如果字体文件支持某种编码格式(charset),就可以使用这类编码值去找到该字符的关键点(glyph)。有些字体文件支持多种编码格式(charset),这在文件中被称为 charmaps(注意:这个单词是复数,意味着可能支持多种 charset)。
以 simsun.ttc 为例,该字体文件的格如下:头部含有 charmaps,可以使 用某种编码值去 charmaps 中找到它对应的关键点。下图中的“A、B、中、国、 韦”等只是 glyph 的示意图,表示关键点。
Charmaps 表示字符映射表,字体文件可能支持哪一些编码,GB2312、 UNICODE、BIG5 或其他。如果字体文件支持该编码,使用编码值通过 charmap 就 可以找到对应的 glyph,一般而言都支持 UNICODE 码。 有了以上基础,一个文字的显示过程可以概括如下:
(1)给定一个字符可以确定它的编码值(ASCII、UNICODE、GB2312);
(2)设置字体大小;
(3)根据编码值,从文件头部中通过 charmap 找到对应的关键点(glyph),它会根据字体大小调整关键点;
(4) 把关键点转换为位图点阵;
(5)在 LCD 上显示出来
从http:// https://www.freetype.org/ 可 以 下 载 到 “ freetype-doc-2.10.2.tar.xz”,下图中的文件就是
3.在 LCD 上显示一个矢量字体
(1)使用 wchar_t 获得字符的 UNICODE 值
要显示一个字符,首先要确定它的编码值。常用的是 UNICODE 编码,在程序 里使用这样的语句定义字符串时,str 中保存的要么是 GB2312 编码值,要么是 UTF-8 格式的编码值,即使编译时使用“-fexec-charset=UTF-8”,str 中保存 的也不是直接能使用的 UNICODE 值:
char *str = “中”;
如果想在代码中能直接使用 UNICODE 值,需要使用 wchar_t,宽字符,代码如下:
#include <stdio.h>
#include <string.h>
#include <wchar.h>
int main( int argc, char** argv)
{
wchar_t *chinese_str = L"中gif";
unsigned int *p = (wchar_t *)chinese_str;
int i;
printf("sizeof(wchar_t) = %d, str's Uniocde: \n", (int)sizeof(wchar_t));
for (i = 0; i < wcslen(chinese_str); i++)
{
printf("0x%x ", p[i]);
}
printf("\n");
return 0;
}
进行编译:
出现编译错误
book@100ask:~/source/10_freetype/01_wchar$ gcc -o test_wchar test_wchar.c
book@100ask:~/source/10_freetype/01_wchar$ ./test_wchar
每个 wchar_t 占据 4 字节,可执行程序里 wchar_t 中保存的就是字符的 UNICODE 值。
注意:如果 test_wchar.c 是以 ANSI(GB2312)格式保存,那么需要使用以下命令来编译:
book@100ask:~/source/10_freetype/01_wchar$ gcc -finput-charset=GB2312 -fexec-charset=UTF-8 -o test_wchar test_wchar.c
(2)使用 freetype 得到位图
要使用 freetype 得到一个字符的位图,只需要 4 个步骤,核心代码:
157 /* 显示矢量字体 */
158 error = FT_Init_FreeType( &library ); /* initialize library */
159 /* error handling omitted */
160
161 error = FT_New_Face( library, argv[1], 0, &face ); /* create face object */
162 /* error handling omitted */
163 slot = face->glyph;
164
165 FT_Set_Pixel_Sizes(face, font_size, 0);
166
167 /* 确定座标:
168 */
169 //pen.x = 0;
170 //pen.y = 0;
171
172 /* set transformation */
173 //FT_Set_Transform( face, 0, &pen);
174
175 /* load glyph image into the slot (erase previous one) */
176 error = FT_Load_Char( face, chinese_str[0], FT_LOAD_RENDER );
177 if (error)
178 {
179 printf("FT_Load_Char error\n");
180 return -1;
181 }
初始化 freetype 库
158 error = FT_Init_FreeType( &library ); /* initialize library */
加载字体文件,保存在&face 中:
第 163 行是从 face 中获得 FT_GlyphSlot,后面的代码中文字的位图就是保存 在 FT_GlyphSlot 里。
161 error = FT_New_Face( library, argv[1], 0, &face ); /* create face object */
162 /* error handling omitted */
163 slot = face->glyph;
设置字体大小:
165 FT_Set_Pixel_Sizes(face, font_size, 0);
根据编码值得到位图
使用 FT_Load_Char 函数,就可以实现这 3 个功能:
⚫ 根据编码值获得 glyph_index:FT_Get_Char_Index
⚫ 根据 glyph_idex 取出 glyph:FT_Load_Glyph
⚫ 渲染出位图:FT_Render_Glyph
175 /* load glyph image into the slot (erase previous one) */
176 error = FT_Load_Char( face, chinese_str[0], FT_LOAD_RENDER );
执 行 FT_Load_Char 之后,字符的位图被存在 slot->bitmap 里 , 即 face->glyph->bitmap
(3)在屏幕上显示位图
要在屏幕上显示出这些位图,代码如下:
183 draw_bitmap( &slot->bitmap,
184 var.xres/2,
185 var.yres/2);
draw_bitmap 函数代码如下,由于位图中每一个像素用一个字节来表示,在 0x00RRGGBB 的颜色格式中它只能表示蓝色,所以在 LCD 上显示出来的文字是蓝色的:
85 void
86 draw_bitmap( FT_Bitmap* bitmap,
87 FT_Int x,
88 FT_Int y)
89 {
90 FT_Int i, j, p, q;
91 FT_Int x_max = x + bitmap->width;
92 FT_Int y_max = y + bitmap->rows;
93
94 //printf("x = %d, y = %d\n", x, y);
95
96 for ( j = y, q = 0; j < y_max; j++, q++ )
97 {
98 for ( i = x, p = 0; i < x_max; i++, p++ )
99 {
100 if ( i < 0 || j < 0 ||
101 i >= var.xres || j >= var.yres )
102 continue;
103
104 //image[j][i] |= bitmap->buffer[q * bitmap->width + p];
105 lcd_put_pixel(i, j, bitmap->buffer[q * bitmap->width + p]);
106 }
107 }
108 }
五、在 LCD 上令矢量字体旋转某个角度
在实现显示一个矢量字体后,我们可以添加让该字旋转某个角度的功能,主要代码还是参照 example1.c。
关键代码
(1)定义 2 个变量:角度、矩阵
121 FT_Matrix matrix; /* transformation matrix */
122 double angle;
123
(2)设置角度值:
130 angle = ( 1.0* strtoul(argv[2], NULL, 0) / 360 ) * 3.14159 * 2; /* use 25 degrees */
(3)设置矩阵、变形、加载位图:
176 /* set up matrix */
177 matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
178 matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
179 matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
180 matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );
181
182 /* set transformation */
183 FT_Set_Transform( face, &matrix, &pen);
184
185 /* load glyph image into the slot (erase previous one) */
186 error = FT_Load_Char( face, chinese_str[0], FT_LOAD_RENDER );
187 if (error)
188 {
189 printf("FT_Load_Char error\n");
190 return -1;
191 }
192
六、使用 freetype 显示一行文字
目的:在 LCD 上指定一个左上角坐标(x, y),把一行文字显示出来。
文字的外框用虚线表示,外框的左上角坐标就是(x, y)。
1.笛卡尔坐标系
在 LCD 的坐标系中,原点在屏幕的左上角。对于笛卡尔坐标系,原点在左下角。freetype 使用笛卡尔坐标系,在显示时需要转换为 LCD 坐标系。
X 方向坐标值是一样的,在 Y 方向坐标值需要换算,假设 LCD 的高度是 V。
在 LCD 坐标系中坐标是(x, y),那么它在笛卡尔坐标系中的坐标值为(x, V-y)。 反过来也是一样的,在笛卡尔坐标系中坐标是(x, y),那么它在 LCD 坐标 系中坐标值为(x, V-y)。
2.每个字符的大小可能不同
在使用 FT_Set_Pixel_Sizes 函数设置字体大小时,这只是“期望值”。比 如“百问网 www.100ask.net”,如果把“.”显示得跟其他汉字一样大,不好看。
所以在显示一行文字时,后面文字的位置会受到前面文字的影响。
幸好,freetype 帮我们考虑到了这些影响, 对于 freetype 字体的尺寸(freetype Metrics)需要参考这个 文档:
在显示一行文字时,这些文字会基于同一个基线来绘制位图:baseline。
在 baseline 上,每一个字符都有它的原点(origin),比如上图中 baseline 左边的黑色圆点就是字母“g”的原点。当前 origin 加上 advance 就可以得到 下一个字符的 origin,比如上图中 baseline 右边的黑色圆点。在显示一行中多个文件字时,后一个文字的原点依赖于前一个文字的原点及 advance。
字符的位图是有可能越过 baseline 的,比如上图中字母“g”在 baseline 下方还有图像。
上图中红色方框内就是字母“g”所点据的位图,它的四个角落不一定与原点重合。
那些 xMin 、 xMax 、 yMin 、 yMax 如 何 获 得 ? 可 以 使 用 FT_Glyph_Get_CBox 函数获得一个字体的这些参数,将会保存在一个 FT_BBox 211 / 577 结构体中,以后想计算一行文字的外框时要用到这些信息:
3.怎么在指定位置显示一行文字
要显示一行文字时,每一个字符都有自己外框:xMin、xMax、yMin、yMax。 把这些字符的 xMin、yMin 中的最小值取出来,把这些字符的 xMax、yMax 中的 最大值取出来,就可以确定这行文字的外框了。
(1)先指定第 1 个字符的原点 pen 坐标为(0, 0),计算出它的外框.
(2)再计算右边字符的原点,也计算出它的外框把所有字符都处理完后就可以得到一行文字的整体外框:假设外框左上角坐 标为(x', y')。
(3)想在(x, y)处显示这行文字,调整一下 pen 坐标即可,pen 为(0, 0)时对应左上角(x', y');那么左上角为(x, y)时就可以算出 pen 为(x-x', y-y')。
4.freetype 的几个重要数据结构
(1)FT_Library
对应 freetype 库,使用 freetype 之前要先调用以下代码:
FT_Library library; /* 对应 freetype 库 */
error = FT_Init_FreeType( &library ); /* 初始化 freetype 库 */
(2)FT_Face
它对应一个矢量字体文件,在源码中使用 FT_New_Face 函数打开字体文件 后,就可以得到一个 face,对于face认为它对应一个字体文件就可以。
error = FT_New_Face(library, font_file, 0, &face ); /* 加载字体文件 *
(3) FT_GlyphSlot
用来保存字符的处理结果:比如转换后的 glyph、位图
一个 face 中有很多字符,生成一个字符的点阵位图时,位图保存在哪里? 保存在插槽中:face->glyph。
生成第 1 个字符位图时,它保存在 face->glyph 中;生成第 2 个字符位图 时,也会保存在 face->glyph 中,会覆盖第 1 个字符的位图。
FT_GlyphSlot slot = face->glyph; /* 插槽: 字体的处理结果保存在这里 */
(4)FT_Glyph
字体文件中保存有字符的原始关键点信息,使用 freetype 的函数可以放大、 缩小、旋转,这些新的关键点保存在插槽中(注意:位图也是保存在插槽中)。
新的关键点使用 FT_Glyph 来表示,可以使用这样的代码从 slot 中获得glyph:
error = FT_Get_Glyph(slot , &glyph);
(5)FT_BBox
FT_BBox 结构体定义如下,它表示一个字符的外框,即新 glyph 的外框:
可以使用以下代码从 glyph 中获得这些信息:
FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &bbox );
5.示例代码如下:
int main(int argc, char **argv)
{
FT_Library library; /* 对应freetype库 */
FT_Face face; /* 对应字体文件 */
FT_GlyphSlot slot; /* 对应字符的处理结果: 含glyph和位图 */
FT_Glyph glyph; /* 对应字符经过处理后的glyph即外形、轮廓 */
FT_BBox bbox; /* 字符的外框 */
FT_Vector pen; /* 字符的原点 */
error = FT_Init_FreeType( &library ); /* 初始化freetype库 */
error = FT_New_Face(library, font_file, 0, &face ); /* 加载字体文件 */
slot = face->glyph; /* 插槽: 字体的处理结果保存在这里 */
FT_Set_Pixel_Sizes(face, 24, 0); /* 设置大小 */
/* 确定坐标 */
pen.x = 0; /* 单位: 1/64 像素 */
pen.y = 0; /* 单位: 1/64 像素 */
FT_Set_Transform( face, 0, &pen); /* 变形 */
/* 根据font_code加载字符, 得到新的glyph和位图, 结果保存在slot中 */
error = FT_Load_Char(face, font_code, FT_LOAD_RENDER);
error = FT_Get_Glyph(slot, &glyph); /* 从slot中得到新的glyph */
FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &bbox ); /* 从glyph中得到字符外框 */
draw_bitmap(&slot->bitmap, lcd_x, lcd_y); /* 位图也保存在slot->bitmap中 */
return 0;
}
6.计算一行文字的外框
后一个字符的原点=前一个字符的原点+advance。 所以要计算一行文字的外框,需要按照排列顺序处理其中的每一个字符。
102 int compute_string_bbox(FT_Face face, wchar_t *wstr, FT_BBox *abbox)
103 {
104 int i;
105 int error;
106 FT_BBox bbox;
107 FT_BBox glyph_bbox;
108 FT_Vector pen;
109 FT_Glyph glyph;
110 FT_GlyphSlot slot = face->glyph;
111
112 /* 初始化 */
113 bbox.xMin = bbox.yMin = 32000;
114 bbox.xMax = bbox.yMax = -32000;
115
116 /* 指定原点为(0, 0) */
117 pen.x = 0;
118 pen.y = 0;
119
120 /* 计算每个字符的bounding box */
121 /* 先translate, 再load char, 就可以得到它的外框了 */
122 for (i = 0; i < wcslen(wstr); i++)
123 {
124 /* 转换:transformation */
125 FT_Set_Transform(face, 0, &pen);
126
127 /* 加载位图: load glyph image into the slot (erase previous one) */
128 error = FT_Load_Char(face, wstr[i], FT_LOAD_RENDER);
129 if (error)
130 {
131 printf("FT_Load_Char error\n");
132 return -1;
133 }
134
135 /* 取出glyph */
136 error = FT_Get_Glyph(face->glyph, &glyph);
137 if (error)
138 {
139 printf("FT_Get_Glyph error!\n");
140 return -1;
141 }
142
143 /* 从glyph得到外框: bbox */
144 FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &glyph_bbox);
145
146 /* 更新外框 */
147 if ( glyph_bbox.xMin < bbox.xMin )
148 bbox.xMin = glyph_bbox.xMin;
149
150 if ( glyph_bbox.yMin < bbox.yMin )
151 bbox.yMin = glyph_bbox.yMin;
152
153 if ( glyph_bbox.xMax > bbox.xMax )
154 bbox.xMax = glyph_bbox.xMax;
155
156 if ( glyph_bbox.yMax > bbox.yMax )
157 bbox.yMax = glyph_bbox.yMax;
158
159 /* 计算下一个字符的原点: increment pen position */
160 pen.x += slot->advance.x;
161 pen.y += slot->advance.y;
162 }
163
164 /* return string bbox */
165 *abbox = bbox;
166 }
167
7.调整原点并绘制
169 int display_string(FT_Face face, wchar_t *wstr, int lcd_x, int lcd_y)
170 {
171 int i;
172 int error;
173 FT_BBox bbox;
174 FT_Vector pen;
175 FT_Glyph glyph;
176 FT_GlyphSlot slot = face->glyph;
177
178 /* 把LCD坐标转换为笛卡尔坐标 */
179 int x = lcd_x;
180 int y = var.yres - lcd_y;
181
182 /* 计算外框 */
183 compute_string_bbox(face, wstr, &bbox);
184
185 /* 反推原点 */
186 pen.x = (x - bbox.xMin) * 64; /* 单位: 1/64像素 */
187 pen.y = (y - bbox.yMax) * 64; /* 单位: 1/64像素 */
188
189 /* 处理每个字符 */
190 for (i = 0; i < wcslen(wstr); i++)
191 {
192 /* 转换:transformation */
193 FT_Set_Transform(face, 0, &pen);
194
195 /* 加载位图: load glyph image into the slot (erase previous one) */
196 error = FT_Load_Char(face, wstr[i], FT_LOAD_RENDER);
197 if (error)
198 {
199 printf("FT_Load_Char error\n");
200 return -1;
201 }
202
203 /* 在LCD上绘制: 使用LCD坐标 */
204 draw_bitmap( &slot->bitmap,
205 slot->bitmap_left,
206 var.yres - slot->bitmap_top);
207
208 /* 计算下一个字符的原点: increment pen position */
209 pen.x += slot->advance.x;
210 pen.y += slot->advance.y;
211 }
212
213 return 0;
214 }
七、编译与上机测试
1.显示一个字体
(1)编译程序
arm-buildroot-linux-gnueabihf-gcc -o freetype_show_font freetype_show_font.c -lfreetype
它会出现如下错误:
我们编译出 freetype 后,得到的 ft2build.h 是位于 freetype2 目录里, 我们把整个 freetype2 目录复制进了工具链里。
但是包括头文件时,用的是“#include ”,要么改成:
#include <freetype2/ft2build.h>
要么把工具链里 incldue/freetype2/*.h 复制到上一级目录,我们使用这种方法:跟 freetype 文档保持一致。执行以下命令:
book@100ask:~/source/10_freetype/02_freetype_show_font$ cd /home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/include
book@100ask:~/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/include$
book@100ask:~/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/include$
book@100ask:~/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/include$ mv freetype2/* ./
然后再次执行以下命令进行挂载:
arm-buildroot-linux-gnueabihf-gcc -o freetype_show_font freetype_show_font.c -lfreetype
(2)上机测试:
ubuntu:
book@100ask:~/source/10_freetype/02_freetype_show_font$ cp freetype_show_font ~/nfs_rootfs/
book@100ask:~/source/10_freetype/02_freetype_show_font$
book@100ask:~/source/10_freetype/02_freetype_show_font$ cp simsun.ttc ~/nfs_rootfs/
开发板:
[root@100ask:~]# /mnt/freetype_show_font /mnt/simsun.ttc 300
(3)实验效果:
我们将在屏幕中间看到一个蓝色的“繁”字。
2.进行字体翻转
(1)编译程序
book@100ask:~/source/10_freetype/03_freetype_show_font_angle$ arm-buildroot-linux-gnueabihf-gcc -o freetype_show_font_angle freetype_show_font_angle.c -lfreetype -lm
(2)上机测试
ubuntu:
book@100ask:~/source/10_freetype/03_freetype_show_font_angle$ arm-buildroot-linux-gnueabihf-gcc -o freetype_show_font_angle freetype_show_font_angle.c -lfreetype -lm
book@100ask:~/source/10_freetype/03_freetype_show_font_angle$ cp freetype_show_font_angle ~/nfs_rootfs/
book@100ask:~/source/10_freetype/03_freetype_show_font_angle$
book@100ask:~/source/10_freetype/03_freetype_show_font_angle$ cp simsun.ttc ~/nfs_rootfs/
开发板:
[root@100ask:~]# /mnt/freetype_show_font_angle /mnt/simsun.ttc 90 200
(3)实验效果
我们将在屏幕中间看到一个蓝色的、旋转了 90 度的“繁”字。
3.显示一行文字
(1)编译程序
book@100ask:~/source/10_freetype/03_freetype_show_font_angle$ arm-buildroot-linux-gnueabihf-gcc -o freetype_show_font_angle freetype_show_font_angle.c -lfreetype -lm
(2)上机测试
ubuntu:
book@100ask:~/source/10_freetype/04_show_line$ arm-buildroot-linux-gnueabihf-gcc -o show_line show_line.c -lfreetype
book@100ask:~/source/10_freetype/04_show_line$
book@100ask:~/source/10_freetype/04_show_line$ cp show_line simsun.ttc ~/nfs_rootfs/
book@100ask:~/source/10_freetype/04_show_line$
开发板:
[root@100ask:~]# mount -t nfs -o nolock,vers=3 192.168.5.11:/home/book/nfs_rootfs /mnt
[root@100ask:~]# /mnt/show_line /mnt/simsun.ttc 330 340 100
(3)实验效果
在 LCD 上看到一行文字“嵌入式的那些事~”