Linux应用开发基础知识——LCD上的矢量字体Freetype(六)

简介: Linux应用开发基础知识——LCD上的矢量字体Freetype(六)

一、程序运行的一些基础知识

1.编译程序时去哪找头文件?

系统目录:就是交叉编译工具链里的某个 include 目录;也可以自己指定:编译时用 “ -I dir ”选项指定。

2.链接时去哪找库文件?

系统目录:就是交叉编译工具链里的某个 lib 目录;也可以自己指定:链接 时用 “ -L dir ”选项指定。

3.运行时去哪找库文件?

系统目录:就是板子上的/lib、/usr/lib 目录;也可以自己指定:运行程序用环境变量 LD_LIBRARY_PATH 指定。 运行时不需要头文件,所以头文件不用放到板子上。

二、常见错误的解决方法

1.头文件问题

编译时找不到头文件。在程序中这样包含头文件:#include

对于尖括号里的头文件,去哪里找它?

系统目录:就是交叉编译工具链里的某个 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 上看到一行文字“嵌入式的那些事~”


目录
相关文章
|
1月前
|
Linux 应用服务中间件 Apache
Linux Apache服务详解——Apache服务基础知识
Linux Apache服务详解——Apache服务基础知识
35 2
|
1月前
|
域名解析 缓存 网络协议
Linux DNS服务详解——DNS基础知识
Linux DNS服务详解——DNS基础知识
79 1
|
1月前
|
缓存 Linux Windows
Linux下安装宋体以及微软雅黑字体-转PDF后不显示中文,以及中文乱码
Linux下安装宋体以及微软雅黑字体-转PDF后不显示中文,以及中文乱码
53 0
|
1月前
|
算法 Linux 编译器
【Linux 第三方库】 linux 交叉编译fontconfig,freetype,libxml2,uuid
【Linux 第三方库】 linux 交叉编译fontconfig,freetype,libxml2,uuid
45 0
|
1月前
|
运维 网络协议 安全
Linux vsFTPd服务详解——vsFTPd基础知识
Linux vsFTPd服务详解——vsFTPd基础知识
28 4
|
1月前
|
Linux C语言 芯片
嵌入式linux系统中设备树基础知识
嵌入式linux系统中设备树基础知识
49 0
|
2月前
|
Linux 芯片 开发者
Linux 驱动开发基础知识——内核对设备树的处理与使用(十)
Linux 驱动开发基础知识——内核对设备树的处理与使用(十)
167 0
Linux 驱动开发基础知识——内核对设备树的处理与使用(十)
|
2月前
|
Ubuntu Linux 芯片
Linux 驱动开发基础知识——设备树的语法驱动开发基础知识(九)
Linux 驱动开发基础知识——设备树的语法驱动开发基础知识(九)
74 1
Linux 驱动开发基础知识——设备树的语法驱动开发基础知识(九)
|
2月前
|
Linux
Linux 驱动开发基础知识——总线设备驱动模型(八)
Linux 驱动开发基础知识——总线设备驱动模型(八)
40 0
Linux 驱动开发基础知识——总线设备驱动模型(八)
|
2月前
|
Linux
Linux 驱动开发基础知识——总线设备驱动模型(七)
Linux 驱动开发基础知识——总线设备驱动模型(七)
50 0
Linux 驱动开发基础知识——总线设备驱动模型(七)