时间:2024-05-04
王凤
摘 要:快速发展的社会经济与日益发达的科技水平,使得社会中的多个层面开始普遍运用嵌入式系统,且人们也将关注的重点放在了嵌入式系统中的高质量汉字字库上。文章首先对FreeType字体引擎TrueType矢量字体的概念分别进行了阐述;其次,介绍了裁剪与优化的方法,以供参考。
关键词:FreeType;矢量字体;嵌入式
与TrueType矢量字库相比,由于嵌入式系统以阵点为主的字库不能对字体随意进行缩大和缩小,不能满足分辨率较高的屏幕的要求,由于分辨率较高的屏幕显示的数据量较大,所以显示的速度非常慢。但是,如果在嵌入式系统中使用矢量字体就能够将效果很好地呈现出来。在嵌入式系统中,为了达到渲染TrueType矢量字库的目的,通常都会用到FreeType字体引擎,对于FreeType字体引擎只有很少的一部分嵌入式系统能够直接支持,由于受应算能力和储存空间的限制,有很大一部门嵌入式系统都不能直接使用FreeType字体引擎,甚至有些还需要在移植过程中进行剪裁和优化。
1 FreeType字体引擎TrueType矢量字体
1.1 FreeType字体引擎
作为一个字体引擎,FreeType的优势众多,其不仅质量较高,且不收取任何费用,也可进行移植,其能够对包括TrueType、OpenType,WindowsFON/FNT,Type1,CFF,X11PCF和CID等在内的多种字体格式文件进行访问,且用到的接口也是统一的。在单色位图、反走样位图等渲染上FreeType给予了大力支持。作为一个高度模块化的程序库,FreeType库的开发虽然受益于ANSIC,但在思想上却是面向对象的,所以,用户可以对它进行灵活的裁减。
1.2 TrueType矢量字体
作为一种新型的数字化矢量字体格式,TrueType字体格式由两家公司联合提出,即Microsoft公司与美国Apple公司[1]。几何学中的B样条曲线与直线通常用于描述字体的外形轮廓。正切连续性和一阶连续性是二次B样条曲线的特点,而精确表示出抛物线则是二次B样条曲线的优势所在。
大多数情况下,诸如TrueType字体描述信息、各种标记表格和指令集等均可在MAC与PC平台中得到有效应用,而这些都是描述TrueType字体的文件。“Sfnt”资源是这些文件存放于MAC平台的一种主要存放形式,而在Windows平台中,其存放形式便发生了变化,即为TTF形式。一般,高位在前,低位在后的Motorola式数据结构用得最多,而这样做的目的也是为了避免TrueType的跨平台兼容性受到影响。GDI图形设备接口中已经包含了Windows的TrueType解释器,因此TrueType字体输出能在所有的Windows支持的输出设备上使用。
2 裁剪与优化
因为FreeType库中的API均为封装好的组件,所以若要看到其中的具体细节,就必须进入到源码中。利用分析源码,对删减了一些没有用的步骤和定义,对一些算法进行了适当的裁减和改进。
首先,在初始化FreeType库的时候,要将一些复杂的对象删除掉,如FT_Library和FT_Face等,因为FreeType了面对对象的思想编程,里面包含了多个字体驱动的抽象接口,并使用抽象类来对所有的字体驱动初始化过程进行统一。而在这里不需要对字体驱动进行判断,只需要用到格式TrueType矢量字体。
在对TrueType字体进行初始化的过程中,首先要在各个表项中将TrueType字体载入进来,针对Library对象、face对象的创建与初始化以及判断字体平台驱动进行相应的简化,使之以TrueType中各个重要表项载入的形式呈现出来,以同初始化字体的相关参数予以对应。相对简单一点的是字体大小的设置部分,这一部分主要是按照制定的大小,将包括额定的高度、宽度、EM正方形的像素宽度、高度等在内的缩放的规模以及缩放后字体的规格参数确定下来,且这一部分也不会用到其他结构体,如face对象等。
FreeType中涉及的字体与字符轮廓种类较多,这里主要对TrueType字符轮廓的载入方法进行介绍。首先取得字符索引方法是运用了函数FT_Get_Char_Index,二分查找和有线性查找是查找的主要方法。有序数据中使用的是二分法查找字符索引,获取glyf表中的图元信息一般都是利用local表中偏移量和字符索引。在载入图元信息时,图元头应该第一个载入,简单图元排在第二,最后再对图元信息进行处理。如果点阵信息为最后轮换的图元数据,则可将smooth渲染器作用利用起来。这一渲染器优势较多,其既可生成256色位图信息,也可呈现出渐变的字体边缘。在渲染过程中,平移操作应先于其他步骤进行,使之与目标窗口的位置相差无几,之后再对ControlBox的值进行计算,同时分解轮廓,填充光栅化。
2.1 读取字库
针对不相关的字体,将其driver初始化去除掉,改用另一种字体的driver初始化,即TrueType字体[2]。第一,将字库文件打开,对初始化的信息进行读取。在包含支撐字体轮廓的数据上,TrueType矢量字体一般都是采取的多个表的形式,所以字体引擎在字体渲染上,必须要将各个表的信息利用起来,之后再对表目录进行读取。每个表中均包含有一个tableentry结构项,而资源标记、校验和、偏移量以及每个表的大小均被其囊括其中。因为TrueType中的每个表其保存的逻辑信息各不相同,其中就包括字符调整信息、字符到图元的映射以及图元中数据等,所以,一些表是不可或缺的,当然也要做出合理选择,之后再读取如maxp,hhea,head,cmap,hmtx,vhea,loca,vmtx等一系列得常用表信息。
2.2 设置字体大小
该部分主要是为了函数FT_Set_Pixel_Sizes的实现部分进行优化。原函数实现部分主要是在FT_Request_Size的几个函数,通常字体缩放的各个参数均来源于事先设定好的字体高度与宽度,诸如除法函数FT_MulFix、FT_DivFix和取整函数FT_PIX_CEIL等这些数学中的知识用得比较多。
2.3 取得字符轮廓信息
第一步,获得字符的字形索引,二分法查找cmap表中字形索引是函FT_Get_Char_Index()中主要使用的方法,之后再结合偏移查找与字形索引找出字符所对应的图元信息。glyf表在TrueType字体中居于核心位置,其也就是我们所谓的图元数据。若无意外其最大表的地位不会被撼动。位置索引表是单独存在的,并不存在依附情况,但图元的序列却全部在图元数据表中;图云头结构是每个图元的开始,当前图元的轮廓线额数目保存于简单图元中,而一般要通过计算组成该合成图元的所有图元数据,方可将合成图元的总共轮廓数得出来。针对简单图元,其图元描述应在图元头结构之后进行。而要组成图元描述则需要依靠所有轮廓线结束点的索引、图元指令以及一系列的控制。每一个控制点均包括两个坐标的标志,即x坐标与y坐标。控制所用到的信息与GDI函数、PolyDraw函数所要用的信息相比,两者的概念并未有何不同,都代表的是坐标,而前者是一组标志,后者则是一组点。图元中并未对轮廓线做强制要求,可以是一条,也可是多条。以图1的汉字“宋”为例,其轮廓线有3条,而控制点则有多个。而TrueType字体中的图元轮廓定义主要用到的便是二阶Bezier曲线,其具体包括了曲线上的点、曲线外的点以及一个曲线上的点这3个点。对于多个连续的不在曲线上的点,并没有做出不允许的要求。
2.4 轮换图元数据为点阵信息
从字库中对图元信息进行提取是上一小节的主要内容,而本节的主要内容则是描述图元信息的作图与填充。直线与贝塞尔曲线是作图的主要依据,而光栅填充排在第二。在填充字体后,可提取出字模,并按照2048X2048的格式进行缩小保存。FreeType带了两个渲染器,分别为raster和smooth,两者支持的各不相同,前者主要针对向量轮廓到单色位图的转换,而后者则是由相同轮廓到高质量反走样像素图的转换。通过smooth渲染器可直接生成span。若要使反走样的位图质量更高,那么smooth渲染器无疑是首选。首先,应分解轮廓。作为一系列封闭轮廓线的总和,轮廓主要存在于2D平面上,每一轮廓线均由两部分组成,即一系列线段與Bezier弧。在分解轮廓点,使之以线段与弧的形式出现时,需对以下规定引起注意:两个相邻的“on”点代表的是一条线段,而conicBezier弧则由两个on点之间的conicoff点来表示,off是控制点,on是起、止点;两个on点之间的两个相邻cubicoff点代表的是一个cubicBezier弧,其必须由两部分组成,即两个on与两个cubic控制点。最后,创建一个on点,其并非是真实的,且位置在两个相邻的conicoff点的正中间。为了对目标窗口的位置进行调整,就要在渲染成目标位图之前,平移装入或变换过的轮廓。
目前,无论是在日常生活中经常使用到的电子产品中,还是被用于工业自动化和监测的可编辑控制器中,甚至是娱乐设备的游戏机都属于嵌入式系统。嵌入式系统运用越来越广泛。
3 结语
本文对基于FreeType嵌入式矢量字体引擎进行了研究。通过对FreeType作为字体引擎的使用,将移植过程中的剪裁和优化步骤及方法进行了总结,以期在实际运用中取得良好的效果。
我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自各大过期杂志,内容仅供学习参考,不准确地方联系删除处理!