APP下载

基于Freetype的终端设备字体绘制方案的研究

2024-06-20葸鑫胡彪任继翔

中国新通信 2024年6期
关键词:字符串指针字符

葸鑫 胡彪 任继翔

摘要:Freetype引擎是一个十分重要的字体绘制工具,被广泛运用于众多有文字绘制需求的应用场景中。在当前的大量字体绘制解决方案中,首先将Freetype中的字体轮廓数据转换为位图,然后再进行绘制。但这样的方式使得在放大显示等场景下字体存在边缘模糊或出现锯齿等问题。基于此,本文提出了一种将VG技术与Freetype引擎相结合的字体渲染方案,以实现绘制的字体在放大、旋转等操作时不失真且具有良好的矢量特性,从而达到更好的字体绘制效果。

关键字:Freetype; VG图形;字体绘制;数据解析

一、引言

在技术飞速发展的今天,各类显示设备已经深深融入了人们生活的方方面面,如电子手表、智能手环、洗衣机、冰箱、平板电脑触摸屏和电子广告牌等。它们在各自的应用场景下为人们的日常生活提供了极大的便利,可视化的交互方式方便人们操作这些设备。这些设备上显示的内容主要有图形和文字两类,显示屏上的文字指导人们日常操作,

终端设备上显示的字体主要涉及两项关键技术。其一是获取待显示字符的轮廓数据,其二是将轮廓数据渲染并绘制到显示屏上。其中,字符轮廓数据的获取可由Freetype字体渲染引擎完成;而轮廓数据的绘制和显示可由OpenGL、OpenCV或OpenVG等开源图形库完成。

二、Freetype字体渲染引擎和VG技术

Freetype是一种开源的字体渲染引擎,最早于1996年由David Turner开发[1],并以开源的形式面向全球。在计算机图形学中,字体的渲染和绘制是一个非常重要但也十分复杂的领域。在实际社会生活中,需要准确、高效地显示字体的需求非常多,Freetype的出现为解决这个技术难题提供了强大而简便的方法。它具有强大的字体解析能力和出色的字体渲染功能,在移动设备、应用程序、各种操作系统和图形项目中被广泛和频繁地使用[2]。Freetype的一个显著优势是在主流操作系统(如Linux、Windows和Mac OS)中提供支持,并具有先进的算法和技术。通过实现子像素和抗锯齿等技术,字体图像可以在不同的图像尺寸和分辨率下保持清晰和平滑。Freetype的核心功能包括解析字体文件、绘制渲染字体轮廓等,并且支持多种字体,包括TrueType和OpenType。它可以解析和绘制不同的字体,并获得相同的渲染效果,为应用程序的开发和兼容性提供了极大的便利。

VG矢量图是一种基于矢量描述的精确曲线和形状的图像表示方法,它使用数学公式来定义和绘制图像[3]。由于VG图形保存的是图形的几何形状和曲线的信息,因此可以对图像进行旋转和缩放等操作,并具有文件大小、尺寸独立等优点。VG技术被广泛应用于数据可视化、计算机辅助设计和地理信息系统等领域。

三、基于VG技术的字体绘制方案

在现有的字体绘制方案中,通常使用Freetype将矢量的字体图形转换为位图,再将位图渲染至实现设备上。然而,位图由像素阵列组成,每个像素点都带有颜色信息来表示图像。高分辨率的位图能够很好地展示图像的细节,但它存在分辨率固定的缺点,同时图像放大会引起边缘失真和锯齿效应。

从技术角度而言,将矢量字体图形转换为位图的过程会丢失其矢量特性。如果在屏幕上放大字体,图像的清晰度就会降低。虽然在大多数应用场景中,以较小的图像大小来显示字体时这种损失并不明显。但实际上,Freetype获得的字形轮廓数据本身就是矢量数据,这与VG技术擅长处理的数据类型非常匹配。通过VG技术,可以以矢量图形的形式将字体数据绘制到屏幕上,有效地保留了矢量图形的伸缩性,从而在显示设备上呈现更好的字体显示效果。因此,将VG技术和Freetype字体渲染引擎结合起来,以完成对字体的绘制和渲染,是一个理想的解决方案。

VG技术与Freetype相结合的终端设备字体绘制方案主要包含以下步骤:首先,在系统上安装OpenVG和Freetype以获取功能支持。由于这两个工具都是开源技术,所以它们的下载和安装非常简单。在Windows系统下,只需下载相应的库文件和头文件;而在Linux系统平台上,需要下载源文件,并通过交叉编译的方式编译出适用于特定平台的库文件。

对于OpenVG工程,首先需要进行初始化,然后创建OpenVG上下文(context),用于存储VG的当前状态信息和图像的绘制信息等。接下来,设置OpenVG相关的状态参数,例如当前画布大小和颜色格式等初始化信息。然后在OpenVG工程中初始化Freetype引擎,这包括链接库文件以及在代码中引入Freetype的头文件和库文件:

#include

#include FT_FREETYPE_H

使得能够在OpenVG工程中调用Freetype的接口函数。二是调用FreeType接口函数FT_Init_FreeType()对Freetype引擎进行初始化,并将字体文件的文件名和路径作为输入参数,使用FT_New_Face()函数接口加载所需要使用的字体文件,并可使用FT_Set_Char_Size()函数接口设置字体的大小。不同的字体文件都能够提供不同的字体字形,Freetype涵盖了大多数常用的字体格式,根据需要提前准备好字体文件,其中最为常见的字体是TrueType文件(文件以.ttf为后缀),最初由微软和苹果公司共同开发,用于高质量地渲染和显示的文字,并能够确保跨平台应用的一致性。由于其具有可缩放性、良好的嵌入性和高效的性能,被广泛地应用于操作系统、桌面出版、网页设计等领域[4],并且有越来越多的开发者开发出了TrueType格式的精美字体,进一步丰富和完善了TrueType库。

最后是字体的绘制。使用OpenVG的接口函数创建图像画布,用于存储待绘制字体的相关信息。针对每个待绘制的字体数据,使用接口函数FT_Load_Char()从字体文件中加载对应字形的数据,并在Freetype引擎中转化为字体的轮廓数据后传出。然后使用OpenVG的绘图函数将图像绘制于初始化后的图像画布上,最后使用显示函数将图像画布上的字体图形渲染至待显示设备的待显示区域中,从而完成了字体的整个流程。

OpenVG和Freetype都提供了十分丰富的绘图函数,可根据实际的字体绘制需求进行特异性的优化和配置,充分合理地使用OpenVG的函数接口可实现复杂、精美的字体渲染效果,如艺术字体,倾斜字体,字体镜像反射效果等。将Freetype和VG技术相结合来绘制字体的方案的一大优势在于,该方案拥有良好的可扩展性,例如,在复杂的绘制场景下,如果需要额外使用其他的图形库来辅助字体的绘制和渲染,可将OpenGL ES引入系统用于创建和管理OpenVG的上下文信息,以便于字体图形的绘制和管理;如有 对图像显示有更高帧率的要求,可在方案中引入额外的显示模块,用于加速字体图形到绘制屏幕的数据传输。

四、矢量图绘制的关键技术

Freetype提供了字体的轮廓数据。在当前的常规字体绘制解决方案中,通常使用Freetype引擎中的FT_Render_Glyph()接口函数,将字体的轮廓转换为位图的形式后再进行绘制渲染。这会使得在字体进行放大操作后再绘制的场景下产生轮廓边缘失真、清晰度降低等问题。在Freetype引擎中提供的原始轮廓数据是字形的若干个轮廓关键点,以及相邻关键点间的连接方式等信息,这高度契合了VG技术输入数据的形式。而VG技术能够使得字形以矢量图的形式进行渲染和绘制,具有旋转、缩放不变性,意味着图像无论在屏幕多大的显示场景中绘制,均能够任意缩放和旋转而不损失细节信息或产生锯齿状的边缘,这在社会生产生活中有极其重要的价值。但在Freetype引擎中由接口函数FT_Load_Char()获取到的字形轮廓数据并不能作为VG技术的输入数据直接传输,其原因在于OpenVG中存在一种专有的被称为路径(Path)的矢量格式。但Freetype输出的轮廓数据是以字符串的形式给出,因而需要将Freetype的输出数据进行转换。

本文提出了一种数据转换方法。在OpenVG中,路径(Path)数据是用于定义和描述矢量图形的形状,包括一系列命令和坐标参数。OpenVG中常用的路径数据格式有:

MoveTo:用于将当前的绘制坐标点移动至参数指向的特定坐标点,如命令“M10 10”表示将当前绘图坐标点移动到(10,10)处。

LineTo:用于将绘制一条直线连接当前位置和目标位置,如命令“L10 10”表示从当前点绘制一条直线至(10,10)处。

CurveTo:用于绘制出一条贝塞尔曲线连接当前点和目标点,如命令“C10 10”表示从当前点绘制一条贝塞尔曲线至(10,10)处。

QuadTo:用于绘制一条二次贝塞尔曲线连接当前点和目标点,如命令“Q10 10”表示从当前点绘制一条二次贝塞尔曲线至(10,10)处。

在VG程序中,需要将绘图指令和具体的坐标点数据分别传输到Path结构体中。然而,从Freetype引擎中获取得到的字形轮廓为一段连续的字符串,例如字符“A”的轮廓数据为:“M 18 -45 L 27 -3 Q 27 1 31 1 L 31 3 L 19 1 Q 22 1 22 -1 Q 22 -2 22 -3 L 19 -15 L 7 -2 L 7 -1 Q 7 1 10 1 L 10 3 L 1 3 L 1 1 Q 4 1 5 -2 L 15 -44 L 18 -45 M10 -17 L 19 -17 L 15 -37 L 10 17”。因此,需要将这段字符串分别解析为控制指令和坐标数据。以下阐述一种解析算法,在获取字符轮廓数据的字符串后开始对字符串进行解析,定义指针n指向字符的某一位置,定义指针p从字符串的首地址开始遍历,并遵循以下遍历规则:

(1)如果指针p当前所指向的内容为空,则指针p后移一位;

(2)如果指针p当前所指向的内容为“M”“C”“L”或“Q”等绘制指令,则记录当前指令,且指针p后移一位;

(3)如果指针p当前所指向的内容为字符“0”至字符“9”,便将指针n移动至当前位置,指针p后移至所指向的内容为空处,则指针p与指针n中间所指向的内容即为一个坐标数据。紧接着将字符串类型的坐标数据转化为整数类型后进行保存。

(4)指针p遍历至轮廓数据字符串的末尾,算法结束。

其中字符串数据类型的坐标数据转换为整数类型的坐标数据的具体方法是将该数据保存为一个新的字符串,定义指针s从该字符串起始地址开始遍历;将指针s所指向的第一个字符类型的数字与字符“0”做差,即将当前字符的ASCII值与字符“0”的ASCII值的差,其结果为当前字符所对应的整数类型的数字;然后将指针s后移1位,按上述方法解析得到当前位的整数类型的数字,并将上一个解析得到的数字乘10后加上当前位数字,得到的结果记为A1;如果指针s指向的下一位置仍存在字符s1,则将A1乘10后加上s1所对应的整数数字,得到的结果记为A2;按照上述方法继续计算,直至指针s将字符串完全遍历,最后得到结果An。由此便能够将字符串类型的数字转为对其对应的十进制的整数类型的数。

以字符“A”的轮廓数据解析为例,详细阐述算法流程,将“A”的轮廓数据记为ch,指针n初始指向ch的首地址,指针p从ch的首地址开始遍历。指针p指向的第一个字符为“M”,由于“M”是路径Path的控制指令之一,则将其进行存储;紧接着指针p后移一位,所指向的内容为空,则继续后移一位;然后指针p所对应的内容为字符“1”,则开始坐标点的解析,将指针n移动至当前位置,指针p继续后移至第一次所指向的内容为空后停止,此时由指针p和指针n的地址做差可获得第一个解析的数据为字符“18”;然后用字符“1”和字符“0”做差得到整数类型的数字1,用字符“8”和字符“0”做差得到整数类型的8,将数字1乘10后加上数字8便得到了整数类型的18,由此将字符“18”转换为了整数18,并将其保存为第一个坐标点的数据。指针s继续遍历获得字符“-45”,按上述方法转化为整数45并取负值后进行数据存储,由此便完成了第一段指令“M 18 -45”的指令解析。依此规则,让指针p遍历完字符串后便能够解析得到所有字符“A”的轮廓数据和绘制指令,有了矢量形式的轮廓数据便能够用VG技术绘制出矢量字形。

汉字的绘制方法。对于待绘制字符的轮廓数据,可以用Freetype中的FT_Get_Char_Index()获取当前字符的索引,再利用该索引通过函数接口FT_Load_Glyph()获取轮廓数据。对于常用的字符,如26个英文字符的大小写、加号、减号等,它们的ASCII值和Unicode编码是一致的,因此直接将这些字符作为传入参数传入接口函数FT_Get_Char_Index()中就能获取到它们索引值,进而得到轮廓数据。但接口函数FT_Get_Char_Index()的字形编码输入参数类型是Unicode编码,而中文字符并不能直接获取到其对应的Unicode编码,需要进行一定的转换。以下阐述一种汉字的Unicode编码转换方法:

(1)定义指针p指向汉字字符串的首地址,依次遍历汉字字符串中的每个字符,直到遇到字符串的结束符。

(2)从第一个字符开始遍历,首先获取其字符编码,并使用无符号字符ch表示。

(3)利用位运算的方法确定当前字符的Unicode编码的类型,具体为根据其编码的高四位确定其所占的字节数:若高四位中的最高位为1,则该字符为单字节字符;若高四位中的高两位均为1,则该字符为双字节字符;若高四位中的高三位均为1,则该字符为三字节字符。

(4)若当前字符为单字节字符,则其编码范围在ASCII字符范围内,其ASCII值即为Unicode值;若该字符为双字节字符,则需要将当前字符的后五位先左移六位后,将结果以位运算的方式与下一个字符进行计算便能够得到其Unicode值;若该字符为三字节字符,则需要将当前字符编码的后四位左移12位,并将下一字符的后六位左移六位,最后再与正序第二个字符的后六位的方式计算得到其Unicode值。

计算得到汉字字符的Unicode编码后,传入FT_Get_Char_Index()接口函数中获取到汉字的轮廓索引,再利用该索引通过函数FT_Load_Glyph()便能够得到其轮廓数据。

五、结束语

针对日益增长的移动端设备的字体绘制需求,本文提出了一种将VG技术和Freetype引擎相结合的字体绘制方案。该方案旨在更加高效、高质量地绘制字体图像。同时,本文介绍了一种将Freetype引擎中输入的字符串类型的字体轮廓数据转换成VG技术所需的控制指令和坐标点形式的轮廓数据的解析方法,以及一种汉字Unicode编码的转换方法。基于这些技术,实现了字体的矢量绘制和渲染。

作者单位:葸鑫 胡彪 任继翔 成都大公博创信息技术有限公司

参考文献

[1] 霍长和.基于FreeType的ttf字体算法研究与应用[D].长春工业大学, 2017.

[2] 黄秀珍,何加铭,邰晓英.基于FreeType嵌入式矢量字体引擎的研究[J].宁波大学学报(理工版), 2010, 23(04): 56-61.

[3] 唐善成,鲁彪,张雪等.面向汉字矢量图形特征的字向量表征方法[J].科学技术与工程, 2023, 23(16): 6967- 6973.

[4] 廖平,杨德友,刘仁喜.一种激光打标中TrueType字体轮廓直线逼近优化算法[J].激光技术, 2016, 40(04): 483- 486.

猜你喜欢

字符串指针字符
寻找更强的字符映射管理器
字符代表几
一种USB接口字符液晶控制器设计
消失的殖民村庄和神秘字符
为什么表的指针都按照顺时针方向转动
基于改进Hough变换和BP网络的指针仪表识别
ARM Cortex—MO/MO+单片机的指针变量替换方法
一种新的基于对称性的字符串相似性处理算法
依据字符串匹配的中文分词模型研究
一种针对Java中字符串的内存管理方案