EM9280(嵌入式Linux版)矢量字库应用简介

 2013-6-5          [nemail]    
[lablebox]

1、简述

        使用矢量字库的好处是可灵活选择显示的字体以及字体大小,便于客户进行用户界面的设计。一般来说一个矢量字库文件包含一组字形,每个字形可以存成位图、向量表示或其他结构(可缩放的格式使用一种数学表示和控制数据/程序的结合方式),字体文件包含一个或多个表,叫做字符图,可用来为某种字符编码将字符码转换成字形索引,例如ASCII、Unicode、Big5等等。因此如何从字体文件中获取到字符码所对应的位图数据才是关键。

 

        FreeType 是一个开源的获取字模数据的软件包,其函数库可实现让客户应用程序方便的访问字体文件,并方便地提取某个字符的字形数据(bitmap),从而使得应用程序可按照bitmap格式将字形显示出来。所以要在EM9280上实现矢量字库的应用,必须首先移植FreeType。

 

2、FreeType移植

        FreeType的移植过程:

        1、下载源码:git clone git://git.sv.nongnu.org/freetype/freetype2.git

        2、转入工作目录:cd freetype2

        3、生成configure:./autogen.sh

        4、配置,生成Makefile

              ./configure --host=arm-none-linux-gnueabi(平台) --prefix=/(安装目录)

        5、编译 make

        6、安装 make install

 

        编译成功后将生成的libfreetype.so.2.6.10等库文件,这些文件放入到EM9280根文件系统/lib目录下。为了方便客户使用,同时我们还放置了两个字体文件:

        simsun_2_50.ttc (宋体)

        arial_1_08.ttf (Arial)

 

        到此EM9280的环境下FreeType的移植就完成了。下面将介绍应用程序如何利用FreeType函数进行字符显示。

 

3、矢量字库的应用程序开发

        调用FreeType函数库进行字符显示一般是以下几个步骤:
        1、初始化库 FT_Init_FreeType( )
        2、通过创建一个新的 face 对象来打开一个字体文件 FT_New_Face( )
        3、以点或者象素的形式选择一个字符大小 FT_Set_Char_Size( )
        4、装载一个字形(glyph)图像,并把它转换为位图 FT_Render_Glyph( )
        5、显示一个简单的字符 draw_bitmap( )

 

        在进行应用程序开发时,首先需要将FreeType相关的头文件添加到编译工具的相关include目录下,对应英创公司提供eclipse编译环境,即如下图所示,需要将 FreeType2 include目录下的ft2build.h 和freetype复制到 PC机的c:\Sourcery G++ Lite \ arm-none-linux-gnueabi\libc\usr\include\目录下。

 

 

        FreeType的应用需要用到专用的动态库libfreetype.so、libz.so两个文件,所以需要将这两个文件复制到应用程序工程文件project目录下,同时在eclipse环境对此程序编译时,需要设置相应的编译属性。在Project Explorer视窗下,选择需要设置的工程文件,然后点击鼠标右键,选择 Properties项,在窗口中选择C/C++ Build -> Settings -> Tool Settings -> Sourcery G++ C++ Linker -> Libraries,如下图所示。其中的一个窗口用于指定库文件的名称,一个用于指定库文件的路径。

 

 

        在英创公司提供的光盘示例程序step1_lcdtest中, 其中lcd_graph.h文件图形操作的API函数,在此基础之上,我们增加了显示文本的几个函数:

 

        功能描述: 初始化FreeType库,并创建face打开simsun_2_50.ttc字体文件。
        返回值: 0 成功     <0 失败
        int loadttf( )

 

        功能描述: 设置字体大小。
        输入参数: size 字体大小标号,对应关系:10 -- 五号   14 -- 四号   16 -- 三号   22 -- 二号   26 -- 一号   42 -- 初号

        返回值: 当前字体大小值。
        int setfntsize( int size )

 

        功能描述: 获取字体大小。
        返回值: 当前字体大小值。
        int getfntsize( )

 

        功能描述: 设置前景色。
        输入参数: color 32位rgb值
        void setcolor( unsigned int color )

 

        功能描述: 设置背景色。
        输入参数: color 32位rgb值
        void setbkcolor( unsigned int color )

 

        功能描述: 显示字符串到屏幕相应位置。
        输入参数: rect 用于定义字符串显示位置框:left top right bottom。    textstring 字符串内容,由汉字内码和ASCII码组成 
        返回值: 当前字体大小值。 
        void drawtext( RECT rect, char* textstring )

 

        在调用drawtext()函数之前,客户可调用setcolor( ) 、setbkcolor( )分别设置字体的颜色以及背景颜色。对于字体显示来说,目前我们提供的范例程序仅支持单一背景颜色。

 

        以下为FreeType应用实现的部分代码:

 

        int loadttf( )
        {
                int error;

                error = FT_Init_FreeType( &library );
                if( error )
                { 
                        printf( 'FT_Init_FreeType error:%d\n ', error );
                        return -1;
                }

                error = FT_New_Face( library,'/usr/simsun_2_50.ttc',0,&face_simsun );
                if( error )
                {
                        printf( 'FT_New_Face error:%d\n ', error );
                        return -1; 
                }

                error = FT_Select_Charmap( face_simsun, FT_ENCODING_UNICODE );
                if( error )
                {
                        printf( 'FT_Select_Charmap error:%d\n ', error );
                        return -1;
                }

                return 0; 
        }

 

        void drawtext( RECT rect, char* textstring )
        {
                int i1, len;
                char* u_text; 
                int pen_x, pen_y;
                int error;
                FT_UInt glyph_index;
                FT_ULong ul_char; 
                FT_Bool use_kerning;
                FT_UInt previous;

                pen_x = rect.left;
                pen_y = rect.bottom;

                if( textstring==NULL ) return; 
                i1 = strlen(textstring);

                u_text = new char[2*i1]; 
                /*字符串进行unicode的转换*/
                len = UCS2.GetUniCode( textstring, u_text, 2*i1 );

                use_kerning = FT_HAS_KERNING( face_simsun );
                previous = 0;

                for( i1=0; i1<LEN; )
                {
                        ul_char = (u_text[i1+1]<<8) | u_text[i1];
                        glyph_index = FT_Get_Char_Index( face_simsun, ul_char );
                        if( use_kerning && previous && glyph_index )
                        {
                                FT_Vector delta;
                                FT_Get_Kerning( face_simsun, previous, glyph_index, FT_KERNING_DEFAULT, &delta );
                                pen_x += delta.x >> 6; 
                        }  
                        error = FT_Load_Glyph( face_simsun, /* handle to face object */
                                glyph_index, /* glyph index */
                                FT_LOAD_DEFAULT); /* load flags, see below */
                        if( error )
                                printf( 'FT_Load_Glyph():%d\n ', error );
                        error = FT_Render_Glyph( face_simsun->glyph, /* glyph slot */
                                FT_RENDER_MODE_LCD);

                        if( error )
                                printf( 'FT_Render_Glyph():%d\n ', error );

                        FT_GlyphSlot slot = face_simsun->glyph; 
                        /*显示字符的bitmap*/
                        draw_bitmap( &slot->bitmap, pen_x + slot->bitmap_left, pen_y-slot->bitmap_top );
                        pen_x += slot->advance.x >> 6; 
                }

                delete u_text; 
        }

        void setfntsize( int size )
        {
                int error;

                error = FT_Set_Char_Size(
                        face_simsun, /* handle to face object */
                        0, /* char_width in 1/64th of points */
                        size*64, /* char_height in 1/64th of points */
                        129, /* horizontal device resolution */
                        135 ); /* vertical device resolution */ 
                if( error )
                {
                        printf( 'FT_Set_Char_Size error:%d\n ', error );
                        return;
                }
                FontSize = (unsigned int)size;
        }

 

        这里需要解释下设置字符大小参数中垂直分辨率以及水平分辨率的定义,这两个参数均是指显示设备的分辨率,单位每英寸(inch)的点数(dpi),所以对于不同尺寸的LCD屏,其参数值是不同的。以下为EM9280常接的几种LCD屏dpi值。

 


名称型号分辨率dpi分辨率
4.3' TFT彩色LCDLR430480×272128×128
5.6' TFT彩色LCDAT056TN52640×480144×144
7.0' TFT彩色LCDAT070TN83640×480135×129
8.4' TFT彩色LCDG084SN03800×600119×119
10.4' TFT彩色LCDG104SN03800×600119×119


 

        后续我们提供的光盘资料会更新step1_lcdtest相关代码,感兴趣的客户可以我们联系索取相应的代码。

        技术支持电话:028-85329360

        技术支持邮箱:support@emtronix.com 或 support@emlinix.com

[lablebox]