HZK16施用实例

那边别的的地方相比较弄,第5步将大小修改一下,作者的是nihongo = (unsigned char *) memman_alloc_4k(memman, 55*94*32);

能够重新写回显示屏: #dd if=fbfile of=/dev/fb;

1.3、汉字调换码
  汉字交流码是一种用于汉字音信管理系统里面,只怕与广播发表系统之间实行音信调换的汉字代码。汉字沟通码位于一台机械的言语和另一台机械(包蕴输出设备与记录设备)的入口之间。为了要完毕系统设备之间或记录介质之间新闻置换的指标,汉字交流码必得使用统一的样式。近些日子境内Computer连串所选拔的规范消息管理调换码,是依据国家规范制订的,即GB一九八八— 《新闻管理交流使用的四个人编码字符集》;还制定了对应的代码增加规范,即GB2311 — 《新闻处理沟通使用的五人编码字符集的扩张方法》。因为汉字交流码应与GB一九八八包容,并基于GB2311所鲜明的主意举行编辑。由于汉字数量远远出乎陆人编码所能表示的四千多个常用汉字制定了交流码的国标,即GB2312 — 《音讯调换用汉字编码字符基本集》,当中每种汉字用对应于GB一九八六的四个七人码来代表。

代码如下:

 

//显示

参照他事他说加以考察资料:

    Linux是专门的学业在爱慕方式下,所以客户态进度是不能够象DOS那样采取显卡BIOS里提供的中止调用来贯彻直接写屏,Linux抽象出 FrameBuffer那个设备来供顾客态进程实现直接写屏。Framebuffer机制模仿显卡的功效,将显卡硬件结构抽象掉,能够透过 Framebuffer的读写直接对显存实行操作。客商能够将Framebuffer看成是显得内部存款和储蓄器的三个影象,将其映射到进度地址空间之后,就足以一贯开展读写操作,而写操作可以及时反应在显示器上。这种操作是空虚的,统一的。客商不用关切物理显存的职位、换页机制等等具体细节。那一个都以由 Framebuffer设备驱动来成功的。

汉字占用能源太多(如16点阵,每种汉字就需32字节),由此常常把汉字库放在EEPROM里,需求展现某些汉字时,先算出它的区位码,再求出点阵初始地点,从EEPROM中各样调出该字的点阵数据,存在缓冲区里,最终依次送往LCD展现,描出该字。须求表明的是汉字存款和储蓄形式与LCD呈现格局有一定不一样。

那般我们就能够获得汉字在HZK16中的绝对偏移地方:

1 lcd_put_ascii(int x, int y, unsigned char c )
 2 {
 3     unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16];
 4     int i, b;
 5     unsigned char byte;
 6     
 7     for(i = 0; i < 16; i++)
 8     {
 9         byte = dots[i];
10         
11         for(b = 7; b >= 0; b --)
12         {
13             if(byte & (1<<b))
14             {
15                 /* 显示 */
16                 lcd_put_pixel(x + 7 - b, y + i, 0xffffff);//白
17             }
18             else
19             {
20                         /* 不显示 */
21                 lcd_put_pixel(x + 7 - b, y + i, 0);//黑
22             
23             }
24         }
25     }
26     

}

位码:位号(汉字的第三个字节)-0xa0

framebuffer的设施文件日常是 /dev/fb0、/dev/fb1 等等。

       chip=2;

  1. 叩问HZK编码,明白一下适合GB2312标准的汉语点阵字库文件HZK16;
  2. 下载汉语GB2312的二进制点阵文件;
  3. 将HZK16.fnt文书归入nihongo文件夹中;
  4. 修改主makefile文件和app_make.txt文件,将本来装载nihongo.fnt的言辞替换到装载HZK16.fnt就可以;
  5. 修改bootpack.c文件,将事先分配的装载俄文字体的内部存款和储蓄器扩张,载入字库的文本名;
  6. 在haribote/graphic.c中丰硕支持汉字的代码,增加多少个函数用于展示汉字;
  7. 修改putfonts8_asc函数里if (task->langmode == 3)语句块;
  8. 测量检验程序。
  9. 小心:斯洛伐克语的编码是分为左半有的和右半部分,而小编辈选用的HZK16是分为上半部分和下半部分的。

 

内码 ch1 ch2
   不 不
1字节 1字节

实现思路:

刷写8*16字符点阵

概念如下:
unsigned char str[]="我"
在运作时str被初阶化为2个字节长度,内容为“作者”的GBK码,为:0xCE(区码),0xD2(位码)。
采纳如下换算公式获得“我”在HZK16文本中的地址,从该地方上马的一一32字节为“小编”的字样。
    ADD=【(区码-0xa1)×0x5e + (位码-0xa1)】×0x20
鲁人持竿上面的计量格局,“笔者”的字样地址:0x216E0 。他的C语言字模为:0x04,0x80,0x0E,0xA0,0x78,0x90,0x08,
0x90,0x08,0x84,0xFF,0xFE,0x08,0x80,
0x08,0x90,0x0A,0x90,0x0C,0x60,0x18,
0x40,0x68,0xA0,0x09,0x20,0x0A,0x14,
0x28,0x14,0x10,0x0C

第6步,要注意,HZK16是内外两有个别,不一致于英文的左右两有个别的构造。

     2、(94*(区号-1)+位号-1)是叁其中夏族民共和国字字模占用的字节数

位码=内码第二字节-160

图片 1

仅供给用asii码值乘以16就能够固定到当前字符的点阵地点

    {

运营结果,大家在euc.txt中步向一些汉字。

区码:区号(汉字的第一个字节)-0xa0    (因为汉字编码是从0xa0区始发的,所以文件最前方正是从0xa0区伊始,要算出相对区码)

    {

2、(94*(区号-1)+位号-1)是两在那之中中原人民共和国字字模占用的字节数

选拔HZK16 字库,将它拷贝到内部存款和储蓄器中,使用时直接用数组指向某些汉字所在地方

       chip=0;addr=(int16)pos;

hzk16的牵线以及不难的使用办法

上行下效写一个

pos=32*((int32)((area_h-1)*94)+area_l-1); //总结在多个整机的字库中的地点(256K)

3、最终乘以32是因为汉字库文应从该位置起的32字节音信记录该字的字样音讯(前边提到贰个汉字要有34个字节展现)

    在应用程序中,日常经过将 FrameBuffer 设备映射到进度地址空间的主意使用,举例上边包车型地铁顺序就张开 /dev/fb0 设备,

1引言

要求:原操作系统代码里只是支撑了英文展现,须要做的是促成对这几个系统的汉字全角接济。

 使用#include <sys/stat.h>中的fstat()函数来总计HZK16文件新闻

                              }

offset=(94*(区码-1)+(位码-1))*32

8*16像素的字符点阵

for(i=0;i<32;i++)

近来聊到贰其中中原人民共和国字占四个字节,这两个中前四个字节为该汉字的区号,后五个字节为该字的位号。个中,每一个区记录93个汉字,位号为该字在该区中的地方。所以要找到“我”在hzk16库中的地方就务须获得它的区码和位码。(为了差异使用了区码和区号,其实是多少个东西,别被我误导了)

fb = open ("/dev/fb0", O_RDWR);

                                  汉字的字样与呈现--汉字的代码种类
目 录
  1.1 汉字机内码
  1.2 汉字地址码
  1.3 汉字交换码
  1.4 汉字字型码

区码:区号(汉字的率先个字节)-0xa0 (因为汉字编码是从0xa0区始发的,所以文件最前头正是从0xa0区初阶,要算出相对区码)

笔者们知道一个GB2312汉字是由五个字节编码的,范围为A1A1~FEFE。A1-A9为符号区,B0到F7为汉字区。每三个区有玖拾肆个字符(注意:那只是编码的承认范围,不必然都有字型对应,举个例子符号区就有好些个编码空白区域)。上边以汉字“作者”为例,介绍如何在HZK16文书中找到它对应的三十二个字节的字样数据。

select_chip(chip);   //选择第chip片27512芯片

 有了摇头地址就足以从HZK16中读取汉字编码了

 

         HZK16字库是相符GB2312规范的16×16点阵字库,HZK16的GB2312-80支撑的方块字有67六二十个,符号6八十五个。当中超级汉字有3753个,按声序排列,二级汉字有3008个,按偏旁部首排列。大家在部分行使场面根本用不到那样多汉字字模,所以在行使时就足以只领到部分字体作为己用。

HZK16字库里的16×16中夏族民共和国字一共需求2六18个点来显示,也正是说必要叁十一个字节技能完毕展现二个经常汉字的目标。

 

#define int8 unsigned char

评释:1、区码减1是因为数组是以0为开端而区号位号是以1为始发的

各个字符由十两个字节表示

在依照单片机的智能类别中,汉字展现模块是很要紧的一个组成都部队分,它应用分布、操作轻便、调节和测量试验简便。

 

fb_mem = mmap (NULL, 1024*768, PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);

    {

void putfont32(char *vram, int xsize, int x, int y, char c, char *font1, char *font2)
{
    int i,k,j,f;
    char *p, d ;
    j=0;
    p=vram+(y+j)*xsize+x;
    j++;
    //上半部分
    for(i=0;i<16;i++)
    {
        for(k=0;k<8;k++)
        {
            if(font1[i]&(0x80>>k))
            {
                p[k+(i%2)*8]=c;
            }
        }
        if(i%2==0){
            for(k=0;k<4;k++){
                f=p[k];
                p[k]=p[7-k];
                p[7-k]=f;
            }
        }else{
            for(k=0;k<4;k++){
                f=p[k+8];
                p[k+8]=p[15-k];
                p[15-k]=f;
            }
        }
       /* for(k=0;k<8/2;k++)
        {
            f=p[k+(i%2)*8];
            p[k+(i%2)*8]=p[8-1-k+(i%2)*8];
            p[8-1-k+(i%2)*8]=f;
        }*/
        if(i%2)
        {
            p=vram+(y+j)*xsize+x;
            j++;
        }
    }
    //下半部分
    for(i=0;i<16;i++)
    {
        for(k=0;k<8;k++)
        {
            if(font2[i]&(0x80>>k))
            {
                p[k+(i%2)*8]=c;
            }
        }
        if(i%2==0){
            for(k=0;k<4;k++){
                f=p[k];
                p[k]=p[7-k];
                p[7-k]=f;
            }
        }else{
            for(k=0;k<4;k++){
                f=p[k+8];
                p[k+8]=p[15-k];
                p[15-k]=f;
            }
        }
        /*for(k=0;k<8/2;k++)
        {
            f=p[k+(i%2)*8];
            p[k+(i%2)*8]=p[8-1-k+(i%2)*8];
            p[8-1-k+(i%2)*8]=f;
        }*/
        if(i%2)
        {
            p=vram+(y+j)*xsize+x;
            j++;
        }
    }
    return;
}

FrameBuffer的原理     FrameBuffer 是出新在 2.2.xx 基石其中的一种驱动程序接口。

else if((pos>=64*1024)&&(pos<128*1024)) //在其次片27512微芯片

1. 30天操作系统扶助汉语。

int fb;

HZK16字库是适合GB2312标准的16×16点阵字库,HZK16的GB2312-80帮忙的方块字有67六16个,符号684个。在那之中一级汉字有37五11个,按声序排列,二级汉字有3008个,按偏旁部首排列。大家在部分应用地方根本用不到如此多汉字字模,所以在选用时就足以只领到部分字体作为己用。

 

       chip=1;

咱俩理解多少个GB2312汉字是由四个字节编码的,范围为A1A1~FEFE。A1-A9为符号区,B0到F7为汉字区。每二个区有九十三个字符(注意:那只是编码的准予限制,不自然都有字型对应,比方符号区就有广大编码空白区域)。上边以汉字“小编”为例,介绍怎么样在HZK16文本中找到它对应的叁拾贰个字节的字样数据。

 

这么我们就足以获得汉字在HZK16中的相对偏移地方:

 

int8   *int8_p;//定义多少个unsigned char 指针

日前谈起二个中华夏族民共和国字占三个字节,这两个中前二个字节为该汉字的区号,后多少个字节为该字的 位号。当中,每种区记录九十五个汉字,位号为该字在该区中的地点。所以要找到“小编”在hzk16库中的位置就亟须猎取它的区码和位码。(为了区别使用了区码 和区号,其实是三个事物,别被本身误导了)

  依照CGB2312-80中的汉字、图形符号,根据其岗位分为九十四个“区”,各个区包涵玖拾二个汉字,每种汉字字符又称作“位”。个中“区”的序号,由01到94,“位”的序号,也是从01到94。若以横向表示“位”号,纵向表示“区”号,则“区”和“位”构成三个二维坐标。给定三个“区”值和“位”值就可以规定贰个独一的方块字或图形符号。所以4位数字就能够独一明确几当中中原人民共和国字或标识,下边给出汉字的区内和内码对应关系表。

    fd_hzk16 =  open("HZK16",O_RDWR);
    if(fd_hzk16 < 0)
    {
        printf("can't open HZK16 \n");
        return -1;
    }

    if(fstat(fd_hzk16, &hzk_stat))    //得到文件统计信息
    {
        printf("can't get fstat\n");
        return -1;

    }
    hzk_mem = (unsigned char *)mmap(NULL, hzk_stat.st_size, \
        PROT_READ, MAP_SHARED, fd_hzk16, 0);
    if(hzk_mem == (unsigned char *) -1)
    {
        printf("can't mmap hzk_mem\n");
        return -1;
    }

int16 addr;  //在某一晶片64K字节空间内的地点

memset (fb_mem, 0, 1024*768); //那些命令应该唯有在root能够实施

汉字的字样其实是汉字字形的图形化。对于16点阵字模,正是把汉字写在二个16×16的网格内,汉字的笔画能过某网格时该网格就对应1,不然该网格对应0,这样每一网格均对应1或0,把对应1的网格连起来看,正是这几个汉字。汉字就是那样经过字节表示点阵存储在字库中的。

 1 void lcd_put_chinese(int x, int y, unsigned char *str)
 2 {
 3     unsigned int area = str[0] - 0xa1;
 4     unsigned int where = str[1] - 0xa1;
 5     unsigned char *dots = hzk_mem + (area * 94 + where) * 32;
 6     unsigned char byte;
 7     int i,j,b;
 8 
 9     for(i=0; i < 16; i++)
10         for(j=0; j < 2; j++)
11         {
12             byte = dots[i*2 + j];
13             for(b=7; b >=0; b--)
14             {
15                 if(byte & (1<<b))
16                 {
17                     /* 显示 */
18                     lcd_put_pixel(x + j * 8 + 7 - b, y + i, 0xffffff);//白
19                 }
20                 else
21                 {
22                             /* 不显示 */
23                     lcd_put_pixel(x + j * 8 + 7 - b, y + i, 0);//黑
24                 
25                 }
26             }
27         }
28 
29 }

在PC机的文件文件中,汉字是以机内码的款型积累的,各种汉字占用多个字节:首个字节为区码,为了与ASCII码分歧,范围从十六进制的0A1H起始(小于80H的为ASCII码字符),对应区位码中区码的第一区;第二个字节为位码,范围也是从0A1H开头,对应某区中的第一个位码。那样,将汉字机内码减去0A0AH就得该汉字的区位码。

 

                                                 hzk16汉字库的简练读写程序

    lcd_put_ascii(var.xres / 2, var.yres / 2, 'a');
    printf("中: chinese code: %02x %02x\n", str[0], str[1]);
    lcd_put_chinese(var.xres / 2 + 32, var.yres / 2, str);

                         }else{   printf("%s",'-');

 

1.1、汉字机内码
  汉字机内码(亦称汉字内码)是系统内处和积存汉字而采纳的代码。门到户说,西方文字字符的机内码多使用一个字节来代表的ASCII码,有的系统则动用EBCDIC码。通常只使用7位来代表1贰二十一个字符,而把高位用作奇偶校验(只怕不用)。国内的国家标准GB2312-80分明,贰当中华夏族民共和国字用八个字节表示,近年来规定每一个字节也只用七人,其高位未作定义。
  为了保险系统的中西方文字包容,意味着系统的机内码中必需保险ASCII(IBM-PC接纳该码作为西方文字字符的机内码)的施用,同期又要允许汉字机内码的运用,而且使两个之间未有争辩。如若用GB2312-80中的国家规范码作为机内码,则在系统中同不经常间设有ASCII码和国标码时,将会生出二义性。比如,机内有四个字节的开始和结果分别为30H和21H,它们既可以够表示汉字“啊”的国家标准码,又足以象征字符“0”和“!”的ASCII码。所以,原原本本地使用国家典型码作为汉字机内码是非常的,必须求加以合适的转变。
  经常景观下是将国家标准码的种种字节的高级任务位成1,作为汉字机内码,这种编码称作为变形国家标准码。那样作既缓慢解决了西方文字机内码与汉字机内码的二义性,又确定保证汉字机内码与国家规范码之间有极轻松的应和关系。其团队如下:

 

1.4、汉字字型码
  由于当下汉字音信管理系统中发生汉字字形的艺术大多是数字式的,即以点阵的不二秘技产生汉字,过汉字字形码是指明确三个汉字字形码也就不一样。

像这种类型大家就足以拿走汉字在HZK16中的相对偏移位置:

鉴于E2PROM中存款和储蓄了全副汉字库,只须在硬件上设定存放汉字库的存款和储蓄器片选地址,直接将汉字作为字符数组付给汉字展现函数,通过机内码计算出区号和位号,就能够方便地对汉字字模实行调用了。与前三种方式相比较,无须事先提取字模和设定其地点用于程序调用,由此在张开程序晋级,涉及到汉字突显时,不用更动汉字字模数据。

1 static const unsigned char fontdata_8x16[FONTDATAMAX] = {
 2 
 3     /* 0 0x00 '^@' */
 4     0x00, /* 00000000 */
 5     0x00, /* 00000000 */
 6     0x00, /* 00000000 */
 7     0x00, /* 00000000 */
 8     0x00, /* 00000000 */
 9     0x00, /* 00000000 */
10     0x00, /* 00000000 */
11     0x00, /* 00000000 */
12     0x00, /* 00000000 */
13     0x00, /* 00000000 */
14     0x00, /* 00000000 */
15     0x00, /* 00000000 */
16     0x00, /* 00000000 */
17     0x00, /* 00000000 */
18     0x00, /* 00000000 */
19     0x00, /* 00000000 */
20 
21     /* 1 0x01 '^A' */
22     0x00, /* 00000000 */
23     0x00, /* 00000000 */
24     0x7e, /* 01111110 */
25     0x81, /* 10000001 */
26     0xa5, /* 10100101 */
27     0x81, /* 10000001 */
28     0x81, /* 10000001 */
29     0xbd, /* 10111101 */
30     0x99, /* 10011001 */
31     0x81, /* 10000001 */
32     0x81, /* 10000001 */
33     0x7e, /* 01111110 */
34     0x00, /* 00000000 */
35     0x00, /* 00000000 */
36     0x00, /* 00000000 */
37     0x00, /* 00000000 */
38 
39         /*****
40     ****
41     ****
42     ****
43     ****
44     ****
45     ****
46     ****
47     *****/
48 
49     /* 255 0xff '' */
50     0x00, /* 00000000 */
51     0x00, /* 00000000 */
52     0x00, /* 00000000 */
53     0x00, /* 00000000 */
54     0x00, /* 00000000 */
55     0x00, /* 00000000 */
56     0x00, /* 00000000 */
57     0x00, /* 00000000 */
58     0x00, /* 00000000 */
59     0x00, /* 00000000 */
60     0x00, /* 00000000 */
61     0x00, /* 00000000 */
62     0x00, /* 00000000 */
63     0x00, /* 00000000 */
64     0x00, /* 00000000 */
65     0x00, /* 00000000 */
66 
67 };

area_h=*(int8_p+1)-0xa0; //机内码高字节能减少排放去0xa0得到位码

在动用Framebuffer时,Linux是将显卡置于图形情势下的.

函数void read_hz(int16 hz)的参数hz为两字节的机内码,调用方法:read_hz(‘汉’);

    但Framebuffer自身不具备别的运算数据的力量,就只能比是二个权且寄放水的水池.CPU将运算后的结果放到那么些水池,水池再将结果流到显示屏. 中间不会对数码做管理. 应用程序也得以一贯读写那些水池的内容.在这种体制下,就算Framebuffer须求真正的显卡驱动的支撑,但具备显示职责都有CPU完成,由此CPU 担任非常重

else if((pos>=128*1024)&&(pos<192*1024)) //在第三片27512微电路