• DJYGUI系列文章四:GK文本显示


    目录

    1 GK文本显示概述

    1.1 ansi系

    1.2 unicode系

    1.3 DJYGUI文本显示

    2 字符集说明

    3 字符集API说明

    3.1 ModuleInstall_Charset:字符编码模块初始化

    ​​​​​​​3.2Charset_NlsInstallCharset:安装字符编码

    ​​​​​​​3.3 Charset_NlsGetCurCharset:获取当前字符编码

    ​​​​​​​3.4 Charset_NlsSetCurCharset:设定当前字符编码

    ​​​​​​​3.5 Charset_NlsSearchCharset:搜索字符编码资源

    ​​​​​​​3.6 ModuleInstall_CharsetNls:初始化Nls模块

    ​​​​​​​3.7 Charset_NlsGetLocCharset:获取区域字符编码

    ​​​​​​​3.8 ModuleInstall_CharsetAscii:安装ASCII字符集

    ​​​​​​​3.9 ModuleInstall_CharsetGb2312:安装Gb2312字符集

    ​​​​​​​3.10 ModuleInstall_CharsetUtf8:安装utf8字符集

    ​​​​​​​4 字体说明

    5 字体API说明

    5.1ModuleInstall_Font:字体模块初始化

    ​​​​​​​5.2 Font_InstallFont:安装字体

    ​​​​​​​5.3 Font_GetCurFont:获取当前字符编码

    ​​​​​​​5.4Font_SetCurFont :设定当前字体

    ​​​​​​​5.5Font_SearchFont:搜索字体资源

    ​​​​​​​5.6 Font_GetFontLineHeight:取字体点阵行高

    ​​​​​​​5.7 Font_GetFontLineWidth:取字体点阵竖行宽

    ​​​​​​​5.8 Font_GetFontAttr:取字体属性字

    ​​​​​​​5.9 ModuleInstall_FontAscii6x12Font:安装ascii6x12字体

    ​​​​​​​5.10 ModuleInstall_FontAscii8x12Font:安装ascii8x16字体

    ​​​​​​​5.11 ModuleInstall_FontAscii8x8Font:安装ascii8x8字体

    ​​​​​​​5.12 ModuleInstall_FontGb2312_816_1616_Array:安装ascii8x8字体


    1 GK文本显示概述

            计算机使用二进制语言,而使用计算机的人则用各自的自然语言,这些自然语言的文字,需要编码才能在计算机中标识。为了让计算机“理解”人类的语言,人们设计了许多字符集和字符编码方式,主要分以下两大类。

    1.1 ansi系

            ansi系是一种兼容ascii编码的多字节字符集,其显著特点是:兼容编码值为0x00~0x7f的单字节ascii编码,任何ascii编码的文本,都是合法的字符串。正常字符流中不会出现值为0x00的字节,这点很重要,因为c语言把0x00看成字符串结束符。字符是变长的,一个字符可能是1字节、2字节、3字节甚至4字节,多字节字符的首字节最高位必为0。一个字符集只能表示一种语言,不同的ansi系的字符集,可能有冲突,即不同语言的不同字符,编码可能相同。

    1.2 unicode系

            unicode是一种收录了以及打算收录世界上所有字符的单一编码字符集,因此,它跟ansi系不一样,unicode只有一种字符集。unicode把字符分为17个页面,每个页面65536个编码,页面0也叫BMP页面,我们常用的绝大多数字符都在BMP页面上。unicode的字符集和字符编码是分开的,主要字符编码有:

            1)ucs-2:只能实现unicode的一个子集的编码,只能表示BMP页面上的字符,所有字符都编码成2字节,在正常字符流中有0x00这个字符,需特别注意。

            2)ucs-4:能实现所有unicode字符,所有字符都编码成2字节,同样在正常字符流中有0x00这个字符,需特别注意。

            3)utf-8:能实现所有unicode字符,是一种变长字符编码,最长者可达6字节,但按照目前unicode的实际标准,表示unicode定义的所有17个页面的字符,只需要4个字节,5、6字节编码其实要等猴年马月才能用上。utf-8的好处是,正常字符流中间不会出现0x00

            4)utf-16:同样是一种变长编码,用2字节或4字节来表示一个字符,绝大多数BMP页面上的字符可以用2字节编码来表示,超出2字节的部分用4字节来表示。同样,其正常字符流中有0x00这个字符,需特别注意。

    1.3 DJYGUI文本显示

            DJYGUI的语言支持是多方面的,这里只描述与图形界面输出相关的部分。DJYGUI提供多语言支持,允许用户设计多语言支持界面。DJYGUI中,字符集和字体都作为一种资源存在,应用程序通过选择相应的资源来支持多国语言。应用程序也可以创建资源来实现自己的“小语言”,例如,某应用程序只需要使用100个汉字,且存储空间紧张,就可以创建一个小语言,该语言只包含100个汉字。语言属性由字符集和字体资源组成,字符集资源决定本字符集能表示多少种字符和字符如何编码;字体资源决定本字体有多少种字符和每个字符的字形。目前DJYGUI提供了ascii6x12字体、ascii8x16字体、ascii8x8字体、gb2312 16点阵字体等字体可供选择使用。同时DJYGUI支持ASCII、Unicode、GB2312等字符编码。

    ​​​​​​​2 字符集说明

            字符集资源是用来映射一个字符集合中的字符与二进制代码之间的转换关系的,一个字符集可以表示一种语言、多种语言,或者是一种语言的一个子集,甚至是所有unicode字符,视字符集的定义而定。在DJYOS中,字符集资源并非只为gui服务,这里只介绍跟gui有关的部分。

            正如上文提及DJYOS支持ASCII、utf8、GB2312等字符编码,但是DJYOS将ucs4作为桥梁,ASCII、utf8、GB2312等字符编码首先转换成ucs4,进而进行编码显示。要想将一个字符编码转换成ucs4,需要完成以下工作:

            1)字符解析函数,把给定的字符转化成ucs-4编码;

            2)字符串解析函数,从一个字符串中取出一个字符并转化为ucs-4编码,并给出这个字符的长度(字节数);

            3)逆字符解析函数,把一个ucs-4编码的字符转换成本字符集的字符,并给出这个字符的长度(字节数)。

    字符编码结构体tagCharEncodingRsc用于表征某个字符编码,其定义如下:

    struct tagCharEncodingRsc

    {

        struct tagRscNode node;

        /* 单个字符的最大字节数 */

        u32 max_len;

    //----多字节字符转为ucs4字符

    //功能: 把一个多字节字符转换为ucs4字符。

    //参数: pwc,保存转换结果的指针,调用方确保不为NULL,不判断,gui将确保本函数不会被其他模//块调用

    //      mbs, 指向待转换的多字节字符字节序列的指针(由调用函数判断s的合法性)

    //      n,最大检测长度

    //返回: 0: pwc,mbs是NULL指针或者mbs指向空串。

    //      -1:mbs指向的不是合法多字节字符,或者长度n内未能检测到完整多字节字符

    //      其他:mbs缓冲区内第一个完整多字节字符的长度。

    //说明:

    //      此函数是C Run-time库的mblenmbtowc服务函数。

    //      传入的s指针必须非NULL

        s32 (*mb_to_ucs4)(u32* pwc, const char* mbs, s32 n);

    //----ucs4字符转为多字节字符

    //功能: 把一个ucs4字符转换为多字节字符。

    //参数: mb,保存转换结果的指针(由调用函数判断s的合法性)

    //      wc,待转换的字符

    //返回:-1,如果wc不能对应一个有效的多字节字符,

    //      字节数,返回对应的多字节字符的字节数。

    //说明:

    //      此函数是C Run-time库的wctomb服务函数。

        s32 (*ucs4_to_mb)(char* mb, s32 wc);

    //----多字节字符串转为ucs4串

    //功能: 把一个多字节字符串转换为ucs4字符串

    //参数: pwcs,保存转换结果的指针,缓冲区由调用方提供,若空,则本函数转变为只计算

    //          保存转换结果所需的字节数

    //      mbs,保存多字节字符的缓冲区指针

    //      n,最大检测长度,

    //返回: 0: mbs是NULL指针

    //      -1:结束条件到达前,有不能转换的字符

    //      其他:得到的字符数,=n表示源串是不包含串结束符'\0'。

        s32 (*mbs_to_ucs4s)(u32* pwcs, const char* mbs, s32 n);

    //----ucs4字符串转为多字节字符串-----------------------------------------------

    //功能: 把一个ucs4字符串转换为多字节字符串。

    //参数: mbs,保存转换结果的指针,缓冲区由调用方提供,若空,则本函数转变为只计算保存转换结//果所需的字节数

    //      pwcs,待转换的字符

    //      n,最大检测长度,遇串结束符或长度达到n结束转换,注意ucs4的结束符是连续4个0x00.

    //返回: 0: pwcs是NULL指针

    //      -1:结束条件到达前,有不能转换的字符

    //      其他:写入mbs缓冲区的字节数,含串结束符'\0'

    //-------------------------------------------------------------------------

        s32 (*ucs4s_to_mbs)(char* mbs, const u32* pwcs, s32 n);

    };

            要想在DJYOS上使用某个特定字符编码,其实就是实现该字符编码结构体中4个钩子函数,使其能与ucs4进行转换。如果实现了相应的转换函数,将其挂接到其字符编码结构体中,然后将其安装到系统字符编码资源树下,即可实现支持该字符编码。例如DJYOS支持gb2312,需要首先调用系统函数Charset_CharEncodingModuleInit创建字符编码树资源节点(如果已创建则不必调用),然后调用系统函数Charset_Gb2312EncodeModuleInit将该字符编码安装到字符编码树节点下即可。Charset_Gb2312EncodeModuleInit函数源代码如下:

    ptu32_t Charset_Gb2312EncodeModuleInit(ptu32_t para)

    {

        static struct tagCharEncodingRsc encoding;

        encoding.max_len = 2;

        encoding.mb_to_ucs4 = __Gk_Gb2312MbToUcs4;  //多字节字符转为ucs4字符

        encoding.ucs4_to_mb = __Gk_Gb2312Ucs4ToMb;  // ucs4字符转为多字节字符

        encoding.mbs_to_ucs4s = __Gk_Gb2312MbsToUcs4s;// 多字节字符串转为ucs4串

        encoding.ucs4s_to_mbs = __Gk_Gb2312Ucs4sToMbs;// ucs4字符串转为多字节字符串

        if(Charset_NlsInstallCharEncoding(&encoding, CN_NLS_CHARSET_GB2312))

        {

            printf("gb2312 encoding install sucess\n\r");

            return 1;

        }else

        {

            Djy_SaveLastError(EN_GK_CHARSET_INSTALL_ERROR);

            printf("gb2312 encoding install fail\n\r");

            return 0;

        }

    }

            除了标准字符集外,应用程序也可以方便地安装自己定义的字符集,例如某项目只用到100个汉字和50个日文字符,如果要节省存储空间,完全可以自己创建一个名字为cnjp的字符集,包含100个汉字和50个日文字符。只需将该字符编码安装到DJYOS字符编码根资源树下即可,安装过程同上述Gb23123,在此不赘述。

    3 字符集API说明

    3.1 ModuleInstall_Charset:字符编码模块初始化

    ptu32_t ModuleInstall_Charset(ptu32_t para)

    头文件:

    charset.h

    参数:

    无。

    返回值:

    成功初始化则返回1;失败则返回0。

    说明:

    字符编码模块初始化,其实就是在资源链中添加字符编码资源根节点。

    ​​​​​​​3.2Charset_NlsInstallCharset:安装字符编码

    bool_t Charset_NlsInstallCharset(struct tagCharset *encoding, char* name)

    头文件:

    charset.h

    参数:

    encoding,新增的字符编码指针;

    name,新增字符编码名。

    返回值:

    成功安装字符编码则返回true;失败则返回false。

    说明:

    将新字符编码安装到系统字符编码资源根节点下。

    ​​​​​​​3.3 Charset_NlsGetCurCharset:获取当前字符编码

    struct tagCharset* Charset_NlsGetCurCharset (void)

    头文件:

    charset.h

    参数:

    空。

    返回值:

    当前使用的字符编码结构体指针。

    说明:

    获取当前使用的字符编码。

    ​​​​​​​3.4 Charset_NlsSetCurCharset:设定当前字符编码

    struct tagCharset* Charset_NlsSetCurCharset(struct tagCharset* encoding)

    头文件:

    charset.h

    参数:

    encoding,设定的字符编码结构体指针。

    返回值:

    设定后当前字符编码结构体指针。

    说明:

    把新字符编码设为当前使用的字符编码,新字符编码必须事先安装到系统中。

    ​​​​​​​3.5 Charset_NlsSearchCharset:搜索字符编码资源

    struct tagCharset* Charset_NlsSearchCharset(const char* name)

    头文件:

    charset.h

    参数:

    name,指定的字符编码。

    返回值:

    如果成功搜到指定字符编码则返回该字符编码结构体指针;否则返回NULL。

    说明:

    从字体资源根节点下搜索指定名称的字符编码资源。

    ​​​​​​​3.6 ModuleInstall_CharsetNls:初始化Nls模块

    ptu32_t ModuleInstall_CharsetNls(const char * para)

    头文件:

    nls.h

    参数:

    无。

    返回值:

    成功初始化则返回1;失败则返回0。

    说明:

    Nls模块初始化,其实就是找到本地字符编码资源并将其设定为当前字符编码。

    ​​​​​​​3.7 Charset_NlsGetLocCharset:获取区域字符编码

    struct tagCharset* Charset_NlsGetLocCharset(const char* loc)

    头文件:

    nls.h

    参数:

    loc,区域名称编码。

    返回值:

    返回匹配的字符编码结构体指针,若未有匹配编码,使用默认的ASCII编码。

    说明:

    根据区域名称获取字符编码,"C"是默认编码的代号。

    ​​​​​​​3.8 ModuleInstall_CharsetAscii:安装ASCII字符集

    ptu32_t ModuleInstall_CharsetAscii(ptu32_t para)

    头文件:

    ascii.h

    参数:

    para,无实际意义。

    返回值:

    1=成功,0=失败。

    说明:

    安装ascii字符集,当系统使用西方字符界面时,使用这个字符集。特别注意,gb2312已经包含了英文字符集,使用中文或中英文混合界面的,不需要安装ascii字符集。但是,由于GB2312的字库只包含了全角的英文字符,故还需要安装ascii 的字体资源,尺寸(8*8、8*16)可选。

    ​​​​​​​3.9 ModuleInstall_CharsetGb2312:安装Gb2312字符集

    ptu32_t ModuleInstall_CharsetGb2312(ptu32_t para)

    头文件:

    gb2312.h

    参数:

    para,无实际意义。

    返回值:

    1=成功,0=失败。

    说明:

    安装gb2312字符集,当系统使用西方字符界面时,使用这个字符集。特别注意,gb2312已经包含了英文字符集,使用中文或中英文混合界面的,不需要安装ascii字符集。

    ​​​​​​​3.10 ModuleInstall_CharsetUtf8:安装utf8字符集

    ptu32_t ModuleInstall_CharsetUtf8(ptu32_t para)

    头文件:

    utf8.h

    参数:

    para,无实际意义。

    返回值:

    1=成功,0=失败。

    说明:

    安装utf8字符编码解析器,执行ucs4和编码和utf8编码之间转换。

    ​​​​​​​4 字体说明

            字体资源其实叫字形资源更加贴切,该资源描述了一个集合的字符的图形表示,与字符集一样,字体资源可以包含一种语言、多种语言,或者是一种语言的一个子集,甚至是所有unicode字符。一般来说,一个系统使用的字体资源与字符集资源保持一致即可。在djyos中,字体资源并非只为gui服务,这里只介绍跟gui有关的部分。

            字体结构体tagFontRsc定义如下:

    struct tagFontRsc

    {

        struct  tagRscNode node;

        s32 MaxWidth;       //最宽字符的宽度,纵向显示时可用作为竖行宽

        s32 MaxHeight;      //最高字符的高度

        u32 Attr;

        bool_t (*LoadFont)(void *zk_addr);      //加载字体

        void (*UnloadFont)(void);      //卸载字体

    // 获取ucs4编码为charcode字符的显示点阵,把点阵填充到font_bitmap中,调用者应该提

    // 供font_bitmap所需内存。

    // 如果font_bitmap参数中的bm_bits参数为NULL,则本函数退化为查询函数。在

    // font_bitmap参数中返回图像参数,利用它可以计算bm_bits所需内存尺寸,这在一个文

    // 档中使用多种尺寸的文字时,特别有用。

    // resv,保留参数。

    // 返回: true = 成功执行,false=不支持字符

        bool_t (*GetBitmap)(u32 charcode, u32 size, u32 resv,

                            struct tagRectBitmap *font_bitmap);

        s32 (*GetCharWidth)(u32 Charcode);      //获取某字符宽度

        s32 (*GetCharHeight)(u32 CharCode);     //获取某字符高度

    };

            DJYOS目前支持提供了ascii6x12、ascii8x16、ascii8x8、gb2312 16点阵等字体可供选择使用,要想使用某个具体字体只需调用改字体的初始化函如(如ModuleInstall_FontAscii8x12Font),该初始化函数将该字体安装到系统字体资源树节点下。 

    1. 如果想使用自己创建的字体,那么过程同创建自己的字符编码过程类似,首先要实现字体数据结构中load_font、unload_font、get_char_bitmap、GetCharWidth、GetCharHeight5个钩子函数,其中load_font、unload_font两个函数可以置空。然后将该字体安装到系统字体资源树节点下即可

    5 字体API说明

    5.1ModuleInstall_Font:字体模块初始化

    ptu32_t  ModuleInstall_Font(ptu32_t para)

    头文件:

    font.h

    参数:

    无。

    返回值:

    成功初始化则返回true;失败则返回false。

    说明:

    字体模块初始化,其实就是在资源链中添加字体资源根节点。

    ​​​​​​​5.2 Font_InstallFont:安装字体

    bool_t  Font_InstallFont(struct tagFontRsc *font, char* name)

    头文件:

    font.h

    参数:

    font,新增的字体资源指针;

    name,新增字体名。

    返回值:

    成功安装字体则返回true;失败则返回false。

    说明:

    将新字体安装到系统字体资源根节点下。

    ​​​​​​​5.3 Font_GetCurFont:获取当前字符编码

    struct tagFontRsc*  Font_GetCurFont(void)

    头文件:

    font.h

    参数:

    空。

    返回值:

    当前字体结构体指针。

    说明:

    获取当前使用的字体。

    ​​​​​​​5.4Font_SetCurFont :设定当前字体

    struct tagFontRsc*  Font_SetCurFont(struct tagFontRsc* font)

    头文件:

    font.h

    参数:

    font,设定的字体结构体指针。

    返回值:

    设定后当前字体结构体指针。

    说明:

    把新字体设为当前使用的字体,新字体必须事先安装到系统中。

    ​​​​​​​5.5Font_SearchFont:搜索字体资源

    struct tagFontRsc* Font_SearchFont(const char* name)

    头文件:

    font.h

    参数:

    name,指定的字体名称。

    返回值:

    如果成功搜到指定字体则返回该字体结构体指针;否则返回NULL。

    说明:

    从字体资源根节点下搜索指定名称的字体资源。

    ​​​​​​​5.6 Font_GetFontLineHeight:取字体点阵行高

    s32 Font_GetFontLineHeight(struct tagFontRsc* font)

    头文件:

    font.h

    参数:

    font,被查询的字体。

    返回值:

    该字库竖式排版时的行宽(像素值)。

    说明:

    获取字体中竖行排版行宽,一般是该字体中最宽的那个字符的允许宽度。

     

    ​​​​​​​5.7 Font_GetFontLineWidth:取字体点阵竖行宽

    s32 Font_GetFontLineWidth(struct tagFontRsc* font)

    头文件:

    font.h

    参数:

    font,被查询的字体。

    返回值:

    该字库最高的那个字符的宽度(像素值)。

    说明:

    获取字体中字符的点阵竖行宽度,即该字体中最宽的那个字符的宽度。

    ​​​​​​​5.8 Font_GetFontAttr:取字体属性字

    s32 Font_GetFontAttr(struct tagFontRsc* font)

    头文件:

    font.h

    参数:

    font,被查询的字体。

    返回值:

    字体属性字,font.c模块并不解析该属性字。

    说明:

    获取字体的属性字。

    ​​​​​​​5.9 ModuleInstall_FontAscii6x12Font:安装ascii6x12字体

    ptu32_t  ModuleInstall_FontAscii6x12Font(ptu32_t para)

    头文件:

    ascii6x12.h

    参数:

    空。

    返回值:

    1=成功,0=失败。

    说明:

    安装ascii字体,当系统使用西方字符界面时,使用这个字符集。特别注意,gb2312已经包含了英文字体,在使用中文的界面中可以不安装ascii字体。

    ​​​​​​​5.10 ModuleInstall_FontAscii8x12Font:安装ascii8x16字体

    ptu32_t  ModuleInstall_FontAscii8x12Font(ptu32_t para)

    头文件:

    ascii8x16.h

    参数:

    空。

    返回值:

    1=成功,0=失败。

    说明:

    安装ascii字体,当系统使用西方字符界面时,使用这个字符集。特别注意,gb2312已经包含了英文字体,在使用中文的界面中可以不安装ascii字体。

    ​​​​​​​5.11 ModuleInstall_FontAscii8x8Font:安装ascii8x8字体

    ptu32_t  ModuleInstall_FontAscii8x8Font(ptu32_t para)

    头文件:

    ascii8x8.h

    参数:

    空。

    返回值:

    1=成功,0=失败。

    说明:

    安装ascii字体,当系统使用西方字符界面时,使用这个字符集。特别注意,gb2312已经包含了英文字体,在使用中文的界面中可以不安装ascii字体。

    ​​​​​​​5.12 ModuleInstall_FontGb2312_816_1616_Array:安装ascii8x8字体

    ptu32_t  ModuleInstall_FontGb2312_816_1616_Array(ptu32_t para)

    头文件:

    gb2312_16.h

    参数:

    文件名。

    返回值:

    1=成功,0=失败。

    说明:

    安装gb2312 16点阵,字模保存在文件中,文件名由参数传入。

  • 相关阅读:
    Bilibili直播录制工具B站录播姬
    安卓毕业设计选题基于Uniapp+SSM实现的智能课堂管理APP在线学习网
    图像识别技术在农业领域的应用与挑战
    linux操作系统虚拟机的环境配置
    【基础篇】三、SpringBoot基础配置
    【唐山海德教育】职称有哪些?
    阿里云的域名和ip绑定
    广州华资应届生Java面试2022-4-20
    小白能理解的奈奎斯特采样及延伸出的理论
    提升装备制造企业竞争力:2023年CRM选型与应用完全解读
  • 原文地址:https://blog.csdn.net/wangjianzhongfj/article/details/72840380