来源:百问网
作者:韦东山
本笔墨数:2208,阅读时长:4分钟
(图片来自网络侵删)利用 GIT 下载所有源码后,本节源码位于如下目录:
01_all_series_quickstart\
04_嵌入式 Linux 运用开拓根本知识\source\10_freetype\
04_show_line\show_line.c
本节的目的:在 LCD 上指定一个左上角坐标(x, y),把一行笔墨显示出来。下图中,笔墨的外框用虚线表示,外框的左上角坐标便是(x, y)。
图1
1、笛卡尔坐标系在 LCD 的坐标系中,原点在屏幕的左上角。对付笛卡尔坐标系,原点在左下角。freetype 利用笛卡尔坐标系,在显示时须要转换为 LCD 坐标系。从下图可知,X 方向坐标值是一样的。在 Y 方向坐标值须要换算,假设 LCD 的高度是 V。在 LCD 坐标系中坐标是(x, y),那么它在笛卡尔坐标系中的坐标值为(x, V-y)。反过来也是一样的,在笛卡尔坐标系中坐标是(x, y),那么它在 LCD 坐标系中坐标值为(x, V-y)。图2
2、每个字符的大小可能不同在利用 FT_Set_Pixel_Sizes 函数设置字体大小时,这只是“期望值”。比如“百问网 www.100ask.net”,如果把“.”显示得跟其他汉字一样大,不好看。
以是在显示一行笔墨时,后面笔墨的位置会受到前面笔墨的影响。
幸好,freetype 帮我们考虑到了这些影响。
对付 freetype 字体的尺寸(freetype Metrics),须要参考下图这个文档:
图3
上述文档中列出了一个图,摘录如下:
图4
在显示一行笔墨时,这些笔墨会基于同一个基线来绘制位图:baseline。在 baseline 上,每一个字符都有它的原点(origin),比如上图中 baseline 左边的玄色圆点便是字母“g”的原点。当前 origin 加上 advance 就可以得到下一个字符的 origin,比如上图中 baseline 右边的玄色圆点。在显示一行中多个文件字时,后一个笔墨的原点依赖于前一个笔墨的原点及 advance。字符的位图是有可能超越 baseline 的,比如上图中字母“g”在 baseline 下方还有图像。上图中赤色方框内便是字母“g”所点据的位图,它的四个角落不一定与原点重合。上图中那些 xMin、xMax、yMin、yMax 如何得到?可以利用 FT_Glyph_Get_CBox 函数得到一个字体的这些参数,将会保存在一个 FT_BBox 构造体中,往后想打算一行笔墨的外框时要用到这些信息:图5
3、怎么在指定位置显示一行笔墨要显示一行笔墨时,每一个字符都有自己外框:xMin、xMax、yMin、yMax。把这些字符的 xMin、yMin中的最小值取出来,把这些字符的 xMax、yMax 中的最大值取出来,就可以确定这行笔墨的外框了。要想在指定位置(x, y)显示一行笔墨,步骤如下图所示:图6
① 先指定第 1 个字符的原点 pen 坐标为(0, 0),打算出它的外框
② 再打算右边字符的原点,也打算出它的外框
把所有字符都处理完后就可以得到一行笔墨的整体外框:假设外框左上角坐标为(x', y')。
③ 想在(x, y)处显示这行笔墨,调度一下 pen 坐标即可
怎么调度?
pen 为(0, 0)时对应左上角(x', y');
那么左上角为(x, y)时就可以算出 pen 为(x-x', y-y')。
4、freetype 的几个主要数据构造
要想形象地理解程序,须要先先容一下 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、位图,如下图:
图7
一个 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 的外框:
图8
可以利用以下代码从 glyph 中得到这些信息:
FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &bbox );
针对上述流程,示例代码如下:
图9
「新品首发」STM32MP157开拓板火爆预售!
首批仅300套点击“理解更多”阅读更多干系章节