加入收藏 | 设为首页 | 会员中心 | 我要投稿 | RSSRSS-巴斯仪表网
您当前的位置:首页 > 电子发烧 > 单片机学习

在VxWorks系统中使用TrueType字库

时间:2013-09-08  来源:123485.com  作者:9stone

摘要:为了得到高质量而且灵活(包括对字形的各种变形操作)的字符显示,同时又能实现所见即所得(WYSIWYG)的打印,传统的使用点阵字库的方法已经不能满足要求,有一个很好的方法——使用TrueType字库,可以同时解决以上两个问题.介绍了TrueType技术的基本原理及在Vxworks系统中如何通过FreeType应用TrueType字库,在实际应用中,该技术很好地解决了上述问题,但这种技术也可以很容易地移植到很多其他系统中,如Linux。
关键词:VxWorks;TrueType;UGL字体驱动;打印

    与传统的使用点阵字库相比,TrueType字库至少会带来这样的好处:可以高质量地实现字符的无级放大或缩小,高质量地实现字符的旋转、倾斜等操作(如图1),方便地实现“所见即所得”.
 
图1应用效果图
   由于有以上优点,在很多对字形有特殊操作要求的地方最好使用TrueType字库.Windows中现在使用的就是TrueType字库。

l、TrueType字库的基础
1.1 TrueType简介
    TrueType字库是一种轮廓字库,在True—Type字库中,字形的信息是通过使用一系列的点来描述的.这些点之间或通过直线段,或通过二次贝塞尔曲线来连接,从而形成字形轮廓.图2是汉字“乾”的字形示例。
 
图2字形轮廓线示例
    图2左边图形是直接连接字库中描述“乾”的点形成的,其中的圈表示描述字形的点:小圈表示直线段或贝塞尔曲线的端点,大圈表示贝塞尔曲线的控制点.
    形成字形轮廓时对点的处理是这样的:假设有了起点P0(x0,y0)(它肯定是端点,即小圈),再找下一个点P1(x1,y1).如果P1也是端点,则用直线段连接P0,P1,再将P1作为新的起点继续连接剩下的点;否则P是贝塞尔曲线控制点,再找下一个点P2(x2,y2).如果P2是端点,则将P0,P1,P2用贝塞尔曲线连接,P2作为新的起点继续连接剩下的点;否则再找下一个点P3(x3,y3),计算P2与P3的中点Px,将P0,P1,Px用贝塞尔曲线连接,Px作为新的起点继续连接剩下的点.图2右边的图形是加入了二次贝塞尔曲线形成的实际见到的字形轮廓.
    得到字型轮廓后,再对它进行填充就得到了需要的字符位图.剩下的工作就很简单了,通过打点或贴图都可以画出字符来.

1.2 FreeType的介绍
    使用TrueType字库也有一定的困难:主要就是需要对TrueType字库的格式要有所了解。这样才能正确地提取出字形信息,而这对大多数用户来说很困难,也是很麻烦的.但是现在有了FreeType这个开放源码的共享软件(可以从网上下载),就不必亲自做这些工作了.FreeType可以在很多平台下编译并使用(如Windows、Linux、VxWorks等).利用FreeType提供的API,得到字形信息,形成位图等工作都可以很方便地完成.

1.3 FreeType使用
FreeType提供了丰富的API,具体用法可以参见其文档,这里仅作简要介绍.
用FreeType的API画出一个字符的流程大致如下(仅列出函数名):
……
/*初始化 FreeType库 */
FT_Init_FreeType;
/*建立字体,如宋体 、楷体等 */
FT_New_Face:
/*指定查找字符字形的编码,如 Unicode、 GB2312等 *|
FT_Select Charmap
……
/*根据字符编码得到字符字形在字库中的位置 */ 
FT_Get_Char_Index:
/*根据字符字形在字库中的位置得到其字形描述,即字形轮廓*/
FT_Load_Glyph:
/*将轮廓填充成位图*/
FT_Render_Glyph:
/*用户自定义函数画出位图*/
Drawimage;
……
/*撤消字体*/
FT_Done_Face:
/*撤消FreeType库*/
FT_Done_FreeType;
……

当然实际系统中的应用不会这么简单,但是其基本过程是这样的。

2、UGL字体驱动

    UGL是Zinc的基础,首先在Vxworks的UGL字体驱动中加入TrueType字库支持:
1)根据VxWorks的UGL字体驱动的接口标准写出驱动代码.
2)用行命令方式编译UGL.在UGL文档中介绍了行命令方式编译UGL,以及为加入新字库支持而修改相关文件(如uglnit.h等)的方法.
   现有UGL字体驱动只提供了用于水平方向字符显示的接口,为了能够更加灵活地显示字符,可以在驱动接口中增加函数指针UGL-STATUS(*textDrawFree);为了支持打印,可以加入函数指针UGL-STATUS(*textPrint).当然如果用户要调用这2个函数,就得在ugl.h中加入相应的函数声明,并在uglfont1.c中加入相应的函数定义.

typedef struct ugl-font-driver
{
/*原来的驱动接口*/
……
/*新加入的驱动接口*/
UGL_STATUS(*textDrawFree)
(structu ug_lgc * pGc,
const char * text,
unsigned long length,
const UGL_TT_PARAM * param);
UGL_STATUS(*textPrint)(struct ugl_font_driver  * pFontDriver,
const char * pFaceName。
FILE * outfile,
const char* text,
int length,
const UGL_TT_PARAM * param);
}UGL-FONT-DRIVER;
textDrawFree中的结构UGLrr_PARAM中,定义了一些要用到的参数,如大小、前景及背景颜色、旋转角度、倾斜程度等.
    另外,为了提高字符显示速度,可以用下面的方法:
1)将TrueType字库调人内存.即用FT_New_Memory_Face代替FT_New_Face;
2)利用FreeType提供的缓存功能.具体用法可以参见FreeType提供的文档.
3)对固定尺寸的字体(一般用于界面,这种情况下对速度有较高的要求)专门建立一个Cache.现举例说明如下:

假设Cache的结构如下:

struct tt_cache_
{
/*code_aray存储字符编码*/
unsigned long code_aray[TT_CACHE_NUM];
/*cache_glyph存储相应的位图*/
struct tt_glyph_cache_glyph[TT_CACHE_NUM];
};
    TT_CACHE_NUM是需要建立Cache的字符数量.一般来说,Cache中应包括ASCII可显示字符、汉字中的一级字及一些常用符号.
1)假设tt_cache一>code_aray中已经存储了需要建立Cache的字符编码,首先对它排序(用C语言的qsort即可):
qsort(tt_cache—>code_array,TT_CACHE_NUM,sizeof(unsignedlong),compare);
2)为所有字符生成相应的位图.
3)系统运行过程中需要查找字符的字形时,执行以下步骤:
①用bsearch在tt_cache一>code_aray中查找字符编码.
②若查找到,则相应的位图也找到了.
③若没查找到,则到字库中去找.
4)销毁字体时要同时销毁Cache.
应该注意的是上面的步骤1)、2)是在系统启动时做的,如果第2)步时间太长的话,可以不执行步骤2),只需改变步骤3):
①用bsearch在tt_cache一>code_aray中查找字符编码.
②若查找到,再看相应的位图是不是存在.如果已经存在,则相应的位图也找到了.如果还没有,则根据字库生成位图,并添加到Cache中.
③若没查找到,则到字库中去找.
实践证明,这种方法稍好一点.

3、打印

    下面介绍在窗口系统Zinc中利用UGL字体驱动如何实现打印中的“所见即所得”.
    Zinc中的打印流程是:先生成PS(PostScript)文件,再把PS文件发到打印机端口进行打印,所以下面只讨论如何生成PS文件.
    由于现有系统Zinc不支持汉字的打印,所以必须回到UGL中用打点的方式画出汉字.这就是为什么实现UGL字体驱动时要加人函数指针UGL_STATUS(*textPrint)的原因.
textPrint中的参数意义为:
pFaceName字体名,如宋体、黑体等;
outfile指向打印的输出目标:PS文件.
    修改Zinc中的ZafPrinter,当要打印字符时就调用UGL中的打印函数,UGL中实现打印的部分基本与屏幕显示相同,不同的只是把向屏幕(或内存位图)打点(或贴图)换成了向PS文件写人打点(或贴图)命令.
    由于打印和屏幕显示两者只是输出目标的不同:前者是显示器(如果是内存位图也一样);后者是PS文件.这样就很容易实现WYSISYG——只要将坐标单位设置为英寸(或英寸的千分之一)就行了.这里介绍一个技巧,由于汉字的打印是通过打点实现的,所以这样会使得PS文件比较大.要减小PS文件,可以将连续的打点用画线来代替.由于打印机的分辨率很高,这样做的效果会很明显:一般可以将PS文件减小到原来的1/5,这将大大减少写打印机端口的时间.

4、结束语

   在VxWorks中使用TrueType字库的方法已成功地应用于Vxworks嵌人式地理信息系统中,并可以很容易地移植到很多其他的系统中.


分享到:
来顶一下
返回首页
返回首页
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
栏目导航->单片机学习
  • 电子应用基础
  • 电源技术
  • 无线传输技术
  • 信号处理
  • PCB设计
  • EDA技术
  • 单片机学习
  • 电子工具设备
  • 技术文章
  • 精彩拆解欣赏
  • 推荐资讯
    使用普通运放的仪表放大器
    使用普通运放的仪表放
    3V与5V混合系统中逻辑器接口问题
    3V与5V混合系统中逻辑
    数字PID控制及其改进算法的应用
    数字PID控制及其改进
    恶劣环境下的高性价比AD信号处理数据采集系统
    恶劣环境下的高性价比
    栏目更新
    栏目热门