韦东山视频心得体会之矢量字体

时间:2021-09-24 18:53:05
之前在LCD显示汉字的实验中,我通过使用HZK16文件来实现汉字取模和使用内核中自带的font8x16.c文件来实现ASCII码取模这两种取模的方式。但是缺点就是得到的是固定的显示字符,只能显示8x16和16x16这样大小的字体。如果以后在实际应用中想要放大或者缩小或者旋转字体达到其他的效果,那么岂不是得重新找其他的字库了吗?所幸,我在视频的第三期找到了解决这个问题的答案。
这个方法就是使用矢量字体。矢量字体(Vector font)中每一个字形是通过数学曲线来描述的,它包含了字形边界上的关键点,连线的导数信息等,字体的渲染引擎通过读取这些数学矢量,然后进行一定的数学运算来进行渲染。这类字体的优点是字体实际尺寸可以任意缩放而不变形、变色。矢量字体主要包括 Type1 、 TrueType、OpenType等几类。又叫Outline font,通常使用贝塞尔曲线,绘图指令和数学公式进行绘制。这样可以在对字体进行任意缩放的时候保持字体边缘依然光滑,字体色素不会丢失。
正如韦东山老师所说的,不必被贝塞尔曲线所吓到。虽然在C语言中并没有像C#那样,有相关的贝塞尔曲线绘制函数来帮助我们做出一个贝塞尔曲线,但是呢,总会有别人会做的,我们做的只需要调用即可,这里要引用视频中推荐的freetype库。除此之外,还需要一个字库文件,这里取simsun.ttc文件。
先大致介绍一下字库文件。在这个文件的开头是一些字符映射表,以适应不同的编码格式。不同的编码通过自己的字符映射表找到当前这个文字对应的点阵数据,称为glyph。
在写代码之前先整理一下思路。
1.给定一个文字,如'A'(0x41),'中'(有GBK码和Unicode码等多种可能的编码值)
2.根据编码值从字体文件中找到'glyph'
3.设置字体大小
4.用某些函数把glyph里的关键字缩放为字体大小
5.转换为位图
6.在LCD上显示出来


下面对每一步所要调用的freetype库中的函数进行分析。
一、初始化freetype库。
用到的函数是FT_Init_Freetype()函数。在调用这个函数之前要先定义FT_Library library这个变量,然后调用上面这个函数,参数就是这个library的地址。初始化完后我们就用这个表示库的变量来进行后续操作。代码如下:
FT_Library library;
error = FT_Init_FreeType( &library );
if ( error ) { ... }


二、加载字体Face
要用到的函数是FT_New_Face函数。在调用这个函数之前要先定义FT_Face face这个变量,然后调用这个new_face文件,参数有字库文件名、一个face变量还有其他的参数。主要是要添加一个字库文件名,而且是绝对路径名,我们这里用的是同一目录下的simsun.ttc。还有一个是face变量,其中保存了从字库中提取出来的所要的汉字信息。代码如下:
FT_Face face;
error = FT_New_Face( library,
"/usr/share/fonts/truetype/arial.ttf",
0,
&face );
if ( error)
{
...
}


三、设置字体大小
要调用的函数是FT_Set_Char_Size函数。这个函数可以设置face这个变量中的字体信息,如重新设置字体的大小。第一个参数是要传入的face变量,第二个参数和第三个参数分别是字符的宽和高,如果其中一个为0表示和另外一个值相同。这里要注意单位是1/64个点,而一个点等于1/72英寸。要注意单位的转换。最后两个参数是屏幕的分辨率。具体代码如下:
error = FT_Set_Char_Size(
face, /* handle to face object */
0, /* char_width in 1/64th of points */
16*64, /* char_height in 1/64th of points */
300, /* horizontal device resolution */
300 ); /* vertical device resolution */




四、加载glyph
要调用的函数是FT_Load_char函数。第一个参数时face变量,第二参数时之前得到的编码值,第三个变量是标识符,指定那个转换要求,如要最终转换为位图,则设为FT_LOAD_RENDER、具体代码如下:
error = FT_Load_Glyph(
face, /* handle to face object */
glyph_index, /* glyph index */
load_flags ); /* load flags, see below */


五、显示
经过上面四步之后就得到了字体的位图信息,保存在face->glyph->bitmap中,要显示的时候只需从中提取即可。显示的函数可以用之前汉字库显示的程序中的显示点函数即可,只需传入要显示的坐标就可以了。这样矢量字体就可以在显示屏上显示了。