音响论坛 门户 查看内容

矢量字体在机顶盒上的实现与应用

1970-1-1 08:00| 发布者: | 查看: 1458| 评论: 0

作者:万明磊,刘卫忠
1前言
随着数字电视广播的发展,各大中城市陆续开播了数字电视节目。作为模拟电视到数字电视的过渡产品,STB(Set Top Box,机顶盒)正逐步走进千家万户。机顶盒作为直接面向用户的新兴家电产品,其人机交互界面(GUI)要美观大方。文字作为GUI界面的主要组成元素与信息承载点,其重要性不言而喻。
文字显示一般采用矢量或点阵两种字体,矢量字体可进行字体的无级放大、快速变形以及制作动画,放大后的字体平滑圆润,没有锯齿,做成的动画速度很快,感觉不到字型变换带来的滞留感。利用矢量字库进行字型变换,如平移、缩放、旋转、倾斜等,算法简单,速度快,失真小,效果好,可产生高质量的汉字输出。而点阵字体大小固定单一,不仅在放大缩小时很困难,效果也不好,速度慢,字体单调,很难达到美观的要求。使用矢量字体来提高机顶盒界面质量是有效的方法。
2机顶盒实现矢量字体的特殊要求
为节约成本,机顶盒的硬件资源往往很有限,CPU主频,ROM,RAM分别在100 MHz,2 MB,8 MB左右,所以,实用的机顶盒矢量字体应达到以下指标:
①字库大小在2 MB以下;
②动态内存占用在10 kB以下;
③24×24字体呈现速度达到每秒250汉字以上。
2.1矢量字库的选择
广义的矢量字库包括矢量字库和曲线字库,其中又分为单线体、笔画轮廓体、纯轮廓体、多线体。为适应无级放大时的填充,建议选用笔画轮廓体或纯轮廓体。

曲线字库使用曲线函数描述字型,因此字库很小,一种字体的字库大多在700 kB以下,但每条曲线的拟合计算对机顶盒有限的硬件资源是一个沉重的负担,呈现速度很慢,约每秒20汉字。
矢量字库中直接描述了字体的坐标信息。UCDOS中就提供了多种笔画轮廓体和纯轮廓体矢量字库,大多在1.3~1.7 MB左右,呈现速度约每秒300汉字,是很好的选择。
2.2程序优化
在编制程序时要进一步优化程序的运行速度和内存使用。首先优化核心循环、核心算法,如解码、填充,必要时使用嵌入汇编;其次去除冗余代码,多用移位代替乘除,在许可范围内以空间换时间。
矢量字体的性能主要由字库决定,生成或选择一个好的字库是实现机顶盒矢量字体的关键,程序算法在一定程度上能提高性能,弥补不足。

3矢量字体的呈现
矢量字库一般包括字库信息、索引区、空白区和数据区几个部分,其中最重要的是索引区和数据区。根据字库结构,矢量字体的呈现步骤如图1所示。


图1矢量字体的呈现步骤

3.1计算索引值
矢量字库的索引值一般与字符的区位码相关,得到区位码后,就可以通过其计算得到索引值存放的相对首地址,计算公式应由生成矢量字库者提供。用此相对首地址加上字库在机顶盒存储区中存放的首地址,即可取得索引信息的绝对地址。
在程序中,汉字是以机内码的形式存储的,每个汉字占用两个字节:第一个字节为区码,为了与ASCII码(小于80H)区别,范围从A1H开始,对应区位码中区码的第一区;第二个字节为位码,范围也是从A1H开始,对应某区中的第一个位码。这样就有汉字的索引信息首地址:
indexAdd=((x1-0xA0)×94+y1-0xA0)×L+head
其中,x1为汉字内码高位;y1为汉字内码低位;L为索引项长度;head为字库在机顶盒存储区中存放的首地址。
取得索引信息首地址后,就可以提取长度为L的索引信息。
3.2提取字型数据
索引信息中包含了字型数据在库中的偏移地址和字型数据的长度信息。数据长度可由后一索引的偏移地址减去当前索引的偏移地址得到,为了减少字库大小,也有字库在索引信息中去掉数据长度,只保留了数据地址信息。
在矢量字库中每个字符或汉字的索引信息是定长的,一般为4字节或6字节(含2字节数据长度信息)。由4字节的偏移地址得到字型数据首地址dataAdd:
dataAdd=indexAdd[3]×(256^3)+indexAdd[2]×(256^2)+indexAdd[1]×256+indexAdd[0]+head
由数据首地址和长度信息可取得字型数据信息。
3.3解码取得字型矢量信息
为了压缩字库数据,节省存储空间,在字库中存放的字型数据一般并不是真正在呈现时用到的数据,而是以一定算法编码甚至压缩过的。在呈现前需要对其进行解压或解码,还原出可用的字体轮廓信息。解压、解码算法应由生成矢量字库者提供。
最终取得的字体轮廓信息,即以绝对或相对坐标系描述的字体边缘轮廓点集合,以及进一步由多个轮廓点形成闭合多边形,从而得到的轮廓多边形集合。
3.4绘出字体
得到轮廓多边形后,即可进行字体呈现,具体步骤为:
(1)在轮廓多边形每两点间连线,描绘轮廓;
(2)填充轮廓多边形。
填充多边形的算法很普遍,在此不冗述。根据需要,或为了提高显示速度,也可以只描绘轮廓,或不绘轮廓只进行填充。
填充笔画轮廓体时,注意两个笔画交叉处由于4条轮廓线相交产生的“井”字问题;填充纯轮廓体时,注意内部空心笔画的填充。
4字体变换及特殊效果
4.1字体变换
字体轮廓完全描述了字体外观,因此改变字体轮廓点的坐标就可以改变字体,实现字体变换,如常用的平移、缩放、旋转、倾斜等。
字体变换必须在得到绝对坐标轮廓点后进行,处于图1的第(3)步与第(4)步之间。以下设点(x,y)为原字体轮廓上的绝对坐标点,点(x′,y′)为变换后字体轮廓的点,常用的基本变换算法如下:
(1)平移
设将字体向右平移dx,向下平移dy(dx为负则向左,dy为负则向上)
x′=x+dx
y′=y+dy
(2)缩放
设字体原始大小为width(宽)×height(高)(一般为96×96或128×128),变换为dw×dh:
x′=x×dw/width
y′=y×dh/height
若想精确字型,减少失真,建议进行四舍五入:
x′=(x×dw+width/2)/width
y′=(y×dh+height/2)/height
(3)旋抓
设字体绕原点逆时针旋兹角:
x′=x×cosθ-y×sinθ
y′=x×sinθ-y×cosθ
(4)倾斜
设字体下端不变,上端向右倾斜θ角(θ为负则向左倾斜),height为字体高度:
x′=x+(height-y)×tgθ
y=y
组合以上的基本变换,可实现组合变换。
例如要实现绕固定点(ox,oy)逆时针旋兹角,按照以下步骤即可实现。
(1)平移(-ox,-oy);
(2)旋兹角;
(3)平移(ox,oy)。
4.2字体特殊效果
光靠改变字体轮廓无法实现一些特殊文字效果,此时需进行特殊处理。下面介绍几种常用特殊效果的处理方法:
(1)加粗
加粗分为横向加粗和纵向加粗,实现常见的加粗效果只需横向加粗即可。
横向加粗的基本思想:沿Y轴自上而下以水平线扫描字体,对每一条水平线求出其与字体轮廓线的一组交点;对这一组交点按点的x坐标大小由小至大排序,排序完成后,奇数点处于字体的左边缘轮廓线上,偶数点处于字体的右边缘轮廓线上。将奇数点向左扩展,偶数点向右扩展,即实现字体横向加粗。
纵向加粗:与横向加粗的通理相同。
(2)阴影
最简单的办法是用阴影色与原坐标错开一点距离绘字,再用字体色在原坐标位置呈现字体覆盖即可。错开距离较小时,阴影字可只绘轮廓以提高速度。
亦可遵循加粗中的思想,找出字体的右边缘点和下边缘点,以阴影色加粗字体。
(3)阳文与阴文
实现此效果必须采用纯轮廓体矢量字,笔画轮廓体可以转换成纯轮廓体来实现。
首先遵循加粗中的思想,按横向找出字体的左边缘和右边缘,按纵向找出字体的上边缘和下边缘:
阳文:绘制右边缘和下边缘,不填充,最好以阴影色,绘制右下边缘阴影。
阴文:绘制左边缘和上边缘,不填充,最好以阴影色,绘制左上边缘阴影。
4总结
本文所论述的矢量字体技术在基于PSOS嵌入式系统的机顶盒上,使用ANSI-C标准语言开发实现。
矢量字体可以无级缩放,快速变换,美观大方,拥有点阵字体无法比拟的优点。作为新一代的智能家电,在机顶盒上使用矢量字体是大势所趋。随着机顶盒技术的发展,矢量字体必将得到更加广泛的使用。

微信扫码关注公众号