分类: LINUX
2011-09-15 17:41:03
嵌入式GUI系统是嵌入式系统中实现友好人机界面的关键技术,应用于嵌入式的GUI系统必须具备体积小、反应快、高可靠性、可移植性好以及可裁减等特点,对于实时系统还需要有时实方面的要求。目前,流行的嵌入式GUI系统有Microwindows、MiniGUI、Qt/Embedded等。基中Microwindows以其开放的源代码、可以裁减到100k的内核、与W in32兼容的API以及高度的可移植性在嵌入式系统中得到了广泛的应用。
Microwindows是一个开放源码的嵌入式GU项目,目的在于把现代图形视窗环境的特性引入到小型设备上。MicroW indows起源于NanoGUI项目目前的发布包括Mircrowindows和Nano-X两部分代码。Microwindows系统采用分层的设计方案以满足不同的实现需要。总体分为三层:最下面的设备驱动层、中间的图形引擎层、面向应用程序的API接口层。设备驱动部分提供了屏幕、鼠标/触摸屏、键盘以及其它I/O设备的实际操作,并向上提供统一接口以实现设备无关图形引擎。中间层实现了画点、画线、多边形、剪切区以及颜色模式设置等功能。Microwindows提供了ECMAAPIW和Nano-XAPIs两套不同标准的API,分别兼容W in32和XW indow,其它系统上编写的应用程序可以很容易移到Microwindows上运行。
Microwindows的中文化
1、中文编码与Unicode编码
中文不同于ASCII字符,一个中文需要2个字节来编码,通用的中文编码标准有GB2312、GBK、GB18030、BIG5(繁体),在嵌入式系统中我们采用GB2312标准,也是国家标准。为了区别中文与基本的ASCII字符,汉字的编码的每个字节是高位均为1,而0-127之间的编码用于基本的ASCII字符,因此我们可以同时显示中文与英文,而不会出现问题。而不同的多字节编码之间是不容易区分的,比如中文与日文,还有拉丁文,因此一些系统在进行处理的时候,会把不同的编码转成为通用的Unicode编码,Unicode编码规则是每个字符采用2字节或4字节进行编码,基本包括了世界上所有字符的编码。
2、直接加载中文字体
Microwindows内建了对中文的支持,通过下载中文字库包,修改config文件,可以让Microwindow支持简单的中文输出,这是一种最简单的方法,在这里不作具体介绍。
3、添加Truetype字体驱动模块Freetype2
Microwindows增加了对Freetype2的支持FreeType2是TTF矢量字体的图形引擎库,通过引入Freetype2,使得Microwindows可以支持任何在W indows下使用的TTF、TTC字体库。具体实现如下:
(1)下载Freetype2的源代码,解压编译后,生成libfreetype. a库文件,拷贝到uClinx的/usr/lib库
目录下。
(2)从W indows字库拷贝所需字库文件到uClinux的/fonts/truetype目录下,如simhe.i ttf(简
体黑体)、simson. fft(简体宋体)。
(3)修改config文件如下:
HAVE_FREETYPE_2_SUPPORT = Y
HZK_FONT_DIR = /usr/include
LIBFT2LIB = /usr/lib/libfreetype. A
(4)修改应用程序的CreateFont函数如下:
newfont = CreateFont(12, //可以设置为任意值0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,FF_DONTCARE|DEFAULT_PITCH,“simson. ttf”//设置为字库文件名); //创建汉字字体
(5)修正Freetype2的编码问题
通过输出中文进行验证,出来的并不是预期的结果,而字符的输出是正确的。这是因为Freetype字库引擎对文本的输入是按Unicode编码处理的(这与4. 2节中加载中文字库是不同的,前者是按ASCII处理的)。
在文件src/engine/font_freetype2. c的freetype_drawtext(... )函数中有明确的说明如下:
static void freetype2 _ drawtext(PMWFONT pfont, PSDpsd, MWCOORD ax,MWCOORD ay, const void * text, int cc, MWTEXT-FLAGS flags);
//text: 16位Unicode编码字符串
//cc:字符串字符个数
再看一下文本输出API函数: DrawText、DrawTextA、DrawTexWt与freetype2_drawtext的关系,其中DrawText被定义为宏#define DrawTextDrawTextA, DrawTextA与DrawTexWt实现基本相同,其中DrawTextA接受ASCII字符, DrawTexWt接受宽字符。DrawText的内部实现如下(-->表示调用->表示指针):
a) DrawText -->MwDrawText -->MwExtTextOu
--> GdText
b) GdText调用gr_pfont->fontprocs->DrawText
c)其中gr_pfont->fontproc->DrawText为系统当前字体的处理例程,当使用Freetype2字库驱动库时,DrawTex即为freetype2_drawtext。
当用DrawText输出中文时,在GdText函数内有一个从ASCII到Unicode的转换,可是这个转换并没有解决问题,这一点可以从src/engine/dev-fon.t c的GdConvertEncoding函数中得到验证,此函数只是简单在每一个ASCII编码前加上一个0字节转为双字节,根本不符合GB2312到Unicode的转换规则,从而导致了freetype2_drawtext的输出错误。
那么,是否可以像W in32那样直接如下调用
DrawTexWt ()实现呢?
DrawTexWt (…TEXT(“要输出的文本”)…);
确实在Microwindows下也定义了如下的字符串转换的宏,可惜没有实现。
#define __TEXT(quote) quote
#defineTEXT(quote) __TEXT(quote)
由以上分析可得,Freetype2的中文化还需要进行编码转换,下面给出了两种解决从GB2312到
Unicode的方法:
方法一:使用iconv编码转换库
Libiconv. a提供三个转换接口函数iconv-open、icon、iconv_close来实现编码转换,要包含头
文件iconv. h。
方法二:使用setlocale进行转换
setlocale是与系统locale设置相关的函数,即系统本地化设置,介绍如下:
string setlocale(string category, string locale);
//设置本地化属性,主要是字符集和语言相及关信息
size_tmbstowcs(wchar_t*wcstr, const char*mbstr, size_t count);
//将多字节字字符串转换为Unicode字符串
size_twcstombs(char*mbstr, constwchar_t*wcstr, size_t count);
//将Unicode字符串转换为多字节字字符串当设置如下时,可以实现GB2312到Unicod的转换:
Setlocale(LT_CTYPE,“zh_CN.GB2312”);
以上两种方法均可实现GB2312字符集到Unicode编码的相互转换问题,不仅适用于中文,也适用于其它DBCS字符集的情况。
4、修改图形引擎实现本地化和中文化
软件中引入国际化与本地化是实现软件通用化的基本方法。在21世纪信息化高度发达的时
代,软件国际化与本地化越来越受到人们的高度重视,尽管Microwindows支持多种语言文字,但要实现灵活的多国语言支持,还需要进一步地改进与完善。下面是通过修改图形引擎,结合Linux的Lo-cale设置实现的软件运行时多种语言任意切换的功能。实现如下:
(1)Microwindows的字体设置
Microwindows的字体设置并不是在窗口创建时进行初始化的,而是在窗体第一次绘制时调用GetDC获取设备上下文时设置的,这是创建窗口的一种优化技术,如下所示:
调用关系如下: GetDC( ) --> GetDCEx( ) ( srcmwin/wingd.i c)
DC WINAPI GetDCEx(HWND hwnd, HRGN hrgnClip,
DWORD flags)
{
...
//设置窗口设备句柄的字体
hdc->font= (MWFONTOBJ* )GetStockObject(SYS-TEM_FONT);
...
hwnd->owndc = hdc; //保存设备句柄到窗口,下次调用时使用
}
由于GetDCEx()是所有窗口显示必须调用的函数,因此通过修改hdc->font的值,我们可以改变所有窗口的默认字库,从而更换了系统的字体。
(2)加入FreeType2内建字体支持,支持本地化为了加入我们需要的默认字体,可以创建基于
Unicode编码的Freetype2内建字体,在src/mwinwingd.i c中加入以下代码:
#define FONTNAME“simson”
staticMWFONTOBJOBJ_FREETYPE_FONT = {
{OBJ_FONT, TRUE},
NULL,
FONTNAME; //字体名
};
//创建FreeType作为内建字体
MWFONTOBJ* GetFreeTypeFontOBJ()
{
Static PMWFONT pfont = NULL;
MWFONTOBJ* pFont =&OBJ_FREETYPE_FONT;
If(! pfont)
{
pFont- > pfont = GdCreateFont(&srcdev,“”, 16,NULL);
pFont->font = pfont;
}
return pFont;
}
(3)使用setlocale进行编码转换,将前面的Setlocale(LT_CTYPE,“zh_CN. GB2312”)修改为Setlocale(LT_CTYPE, CHARSETNAME)。最后,通过将字体名FONTNAME与字符集名CHARSETNAME与作为环境变量进行传入,一个支持多字体多语言切换的Microwindows就实现了。
5、中文化方法小结与比较
(1)直接加载中文字库是Microwindows自带的最容易实现的一种中文化方法。其优点是实现简单,容易操作;缺点是只支持固定的12和16两种高度的点阵字体,而且必须在应用程序中指定所用字体。
(2)通过引入Truetype字体驱动模块实现中文化是比较理想的方案, FreeType2不仅对TrueTyp
字库提供了良好的支持,而且完全兼容微软的TT字库。其优点是字形美观、字体大小可以任意变化;可选用的字体库多;兼容其它编码的字体库,为支持多国语言提供了条件。缺点是实现比较复杂,不仅需要下载Freetype2的库,还要修正其中的编码问题;另外对嵌入式的系统而言,额外的存空间开销也是不利的因素。
(3)修改图形引擎实现本地化和中文化是软件国际化的一部分。通过引入Freetype2、修改窗口句柄的字体加载机制,将Microwindows图形系统与Linux系统中的Locale连接起来,使Microwindow具备了支持软件本地化的能力。该方法是对M-crowindows的进一步改进与功能增强,是Microwin-dows中文化的高级方法。其优点是不仅解决了中文化问题,同时具有良好的适应性和更大的灵活性。其缺点是实现复杂,需要更多的系统支持和开销。综上所述,我们可以用不同的方法来实现M-crowindows的中文化,但各种方法的实现难度和代价不尽相同,用户可以根据实际需求进行选择。