图片 1

文件浏览器及数码相框,添加中文字库

要求:原操作系统代码里只是帮助了克罗地亚语展现,要求做的是兑现对那一个系统的汉字全角扶持。

FrameBuffer的法规     FrameBuffer
是出以往 2.2.xx 底蕴当中的生龙活虎种驱动程序接口。

在C5第11中学,HZK16汉字库的使用(mydows’s Blog转发)

hzk16的牵线以致轻易的选择方法

   
Linux是干活在珍重方式下,所以客户态进度是爱莫能助象DOS那样接受显卡BIOS里提供的间歇调用来落到实处间接写屏,Linux抽象出
FrameBuffer那个设备来供顾客态进度落成直接写屏。Framebuffer机制模仿显卡的功力,将显卡硬件结构抽象掉,能够通过
Framebuffer的读写直接对显存实行操作。顾客能够将Framebuffer看成是突显内部存储器的多个影象,将其映射到进度地址空间之后,就足以一向开展读写操作,而写操作能够立时反应在荧屏上。这种操作是虚幻的,统意气风发的。客商不用关怀物理显存的岗位、换页机制等等具体细节。那一个都以由
Framebuffer设备驱动来完毕的。

概念如下:
unsigned char str[]=”我”
在运作时str被开始化为2个字节长度,内容为“小编”的GBK码,为:0xCE(区码卡塔尔,0xD2(位码卡塔 尔(英语:State of Qatar)。
动用如下换算公式拿到“作者”在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

HZK16字库是切合GB2312标准的16×16点阵字库,HZK16的GB2312-80援救的方块字有67六二十一个,符号685个。个中顶级汉字有3754个,按声序排列,二级汉字有3008个,按偏旁部首排列。大家在局地选择地方根本用不到如此多汉字字模,所以在采纳时就足以只领到部分字体作为己用。

   
但Framebuffer自己不辜负有别的运算数据的力量,就只能比是叁个一时贮存水的水池.CPU将运算后的结果放到那几个水池,水池再将结果流到荧屏.
中间不会对数码做管理.
应用程序也足以向来读写那几个水池的内容.在这里种体制下,尽管Framebuffer必要真正的显卡驱动的协理,但持有彰显职责都有CPU实现,因而CPU
肩负相当重

        
HZK16字库是切合GB2312规范的16×16点阵字库,HZK16的GB2312-80帮忙的汉字有6765个,符号6捌12个。个中一流汉字有3752个,按声序排列,二级汉字有3008个,按偏旁部首排列。我们在有的使用途合根本用不到那般多汉字字模,所以在运用时就足以只领到部分字体作为己用。

HZK16字库里的16×16中华夏族民共和国字少年老成共供给2伍二十一个点来显示,也正是说要求三十多少个字节才干完毕呈现叁个见怪不怪汉字的目标。

framebuffer的装置文件日常是
/dev/fb0、/dev/fb1 等等。

HZK16字库里的16×16汉字风华正茂共要求2五18个点来彰显,也正是说须求31个字节技术落得呈现一个常见汉字的目标。

我们了然叁个GB2312汉字是由七个字节编码的,范围为A1A1~FEFE。A1-A9为符号区,B0到F7为汉字区。每四个区有九十几个字符(注意:那只是编码的批准范围,不自然都有字型对应,举例符号区就有过多编码空白区域卡塔 尔(英语:State of Qatar)。上边以汉字“小编”为例,介绍怎样在HZK16文本中找到它对应的34个字节的字样数据。

能够用命令: #dd if=/dev/zero of=/dev/fb
清空显示屏. 假如展现方式是 1024×768-8 位色,

大家驾驭多少个GB2312汉字是由四个字节编码的,范围为A1A1~FEFE。A1-A9为符号区,B0到F7为汉字区。每多个区有九十五个字符(注意:那只是编码的批准约束,不必然都有字型对应,例如符号区就有那几个编码空白区域卡塔 尔(英语:State of Qatar)。下边以汉字“作者”为例,介绍怎样在HZK16文书中找到它对应的三11个字节的字样数据。

日前提及叁当中国字占多个字节,这两在那之中前二个字节为该汉字的区号,后二个字节为该字的位号。个中,每一种区记录93个汉字,位号为该字在该区中的地点。所以要找到“笔者”在hzk16库中的地点就必需拿到它的区码和位码。(为了差距使用了区码和区号,其实是一个事物,别被小编误导了卡塔 尔(英语:State of Qatar)

用命令:$ dd if=/dev/zero of=/dev/fb0
bs=1024 count=768 清空显示器;

眼前提起三个中黄炎子孙民共和国字占五个字节,这两当中前多个字节为该汉字的区号,后二个字节为该字的位号。此中,种种区记录九十几个汉字,位号为该字在该区中的地点。所以要找到“我”在hzk16库中的地点就必须要获得它的区码和位码。(为了不同使用了区码和区号,其实是叁个事物,别被小编错误的教导了卡塔 尔(英语:State of Qatar)

区码:区号(汉字的第三个字节卡塔尔国-0xa0
(因为汉字编码是从0xa0区启幕的,所以文件最前面正是从0xa0区开端,要算出相对区码)

用命令: #dd if=/dev/fb of=fbfile 
能够将fb中的内容保留下来;

区码:区号(汉字的第叁个字节卡塔 尔(英语:State of Qatar)-0xa0   
(因为汉字编码是从0xa0区启幕的,所以文件最前面就是从0xa0区起始,要算出相对区码)

位码:位号(汉字的第4个字节卡塔 尔(阿拉伯语:قطر‎-0xa0

能够重复写回荧屏: #dd if=fbfile
of=/dev/fb;

位码:位号(汉字的第叁个字节卡塔 尔(英语:State of Qatar)-0xa0

这般我们就能够得到汉字在HZK16中的相对偏移地方:

在行使Framebuffer时,Linux是将显卡置于图形方式下的.

与此相类似我们就足以博得汉字在HZK16中的相对偏移地方:

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

 

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

证明:1、区码减1是因为数组是以0为发端而区号位号是以1为最初的

    在应用程序中,日常经过将 FrameBuffer
设备映射到进程地址空间的方法接收,比方上边包车型大巴顺序就开采 /dev/fb0
设备,

表明:1、区码减1是因为数组是以0为带头而区号位号是以1为始发的

2、(94*(区号-1)+位号-1)是贰在那之中黄炎子孙民共和国字字模占用的字节数

并由此 mmap 系统调用进行地址映射,随后用
memset 将显示器清空(这里假若突显形式是 1024×768-8
位色情势,线性内部存款和储蓄器方式卡塔尔国:

            2、(94*(区号-1)+位号-1)是多少个汉字字模占用的字节数

3、最后乘以32是因为汉字库文应从该任务起的32字节音信记录该字的字样信息(前边提到叁个汉字要有34个字节展现卡塔尔国

int fb;

           3、最终乘以32是因为汉字库文应从该职责起的32字节音信记录该字的字样新闻(前边提到贰此中中原人民共和国字要有叁10个字节显示卡塔 尔(英语:State of Qatar)

 有了舞狮地址就能够从HZK16中读取汉字编码了

unsigned char* fb_mem;

有了摇头地址就足以从HZK16中读取汉字编码了,剩下的正是文本操作了,就掩瞒了,要看代码(汉字卡塔 尔(阿拉伯语:قطر‎正是底下的:“hzk16汉字库的差非常少读写程序 ”,是三个最简便的c语言程序。

兑现思路:

fb = open (“/dev/fb0”, O_RDWR);

                                                 hzk16汉字库的简易读写程序

  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. 瞩目:立陶宛(Lithuania卡塔 尔(阿拉伯语:قطر‎语的编码是分为左半有个别和右半部分,而笔者辈接受的HZK16是分为上半部分和下半部分的。

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

hzk汉字点阵   
    
   int    i,j,k;   
   unsigned    char    incode[3]=”作者”;    //    要读出的方块字   
   unsigned    char    qh,wh;   
   unsigned    long    offset;   
   //    占六个字节,    取其区位号   
   qh    =    incode[0]    –    0xa0;/ /获得区码            
   wh    =    incode[1]    –    0xa0;   / /获得位码               
   offset    =    (94*(qh-1)+(wh-1))*32;          /   
*收获偏移地方*    /   
      
   FILE    *HZK;   
   char    mat[32];   
   if((HZK=fopen(“hzk16”,    “rb”))    ==    NULL)   
   {   
   printf(“Can’t    Open    hzk16n”);   
   exit(0);   
   }   
   fseek(HZK,    offset,    SEEK_SET);   
   fread(mat,    32,    1,    HZK);

此间其余的地点比较弄,第5步将大小更正一下,作者的是nihongo = (unsigned
char *) memman_alloc_4k(memman, 55*94*32);

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

//显示

第6步,要在乎,HZK16是内外两有的,分歧于拉脱维亚语的左右两局地的构造。

 

for(j=0;j<16;j++)
        for(i=0;i<2;i++)
            for(k=0;k<8;k++)
               
if(mat[j][i]&(0x80>>k)) /*测量检验为1的位则展现*/
                    {

代码如下:

一成不改变写一个

                            printf(“%s”,’#’);

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;
}

 

                         }else{   printf(“%s”,’-‘);

 

1     fd_fb = open("/dev/fb0",O_RDWR);
 2     if(fd_fb < 0)
 3     {
 4         printf("can't open /dev/fb0 n");
 5         return -1;
 6     }
 7     if(ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))            //取出可变信息
 8     {
 9         printf("can't get var n");
10         return -1;    
11     }
12     if(ioctl(fd_fb, FBIOGET_FSCREENINFO, &fix))            //取出固定信息
13     {
14         printf("can't get fix n");
15         return -1;    
16     }
17     screen_size = var.xres * var.yres * var.bits_per_pixel / 8;    //占内存大小 单位字节
18     line_width = var.xres *  var.bits_per_pixel / 8;         //一行像素大小
19     pixel_width =  var.bits_per_pixel / 8;               //一点像素大小
20     
21     fb_mem = (unsigned char *)mmap(NULL, screen_size,        //mmap 系统调用进行地址映射
22         PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
23     if(fb_mem == (unsigned char *) -1)
24     {                                      
25         printf("can't mmap n");
26         return -1;
27     }
28     memset(fb_mem, 0, screen_size);                   //清屏,黑色

                              }

运维结果,我们在euc.txt中参加一些汉字。

 

    fclose(HZK);
     fclose(fp);

图片 1

字符点阵展现

                               图形LCD模块ACM一九二七4ASB的方块字呈现

参谋资料:

8*16像素的字符点阵

1引言

1. 30天操作系统帮忙汉语。

二个字节8位来代表风度翩翩行的8个像素是不是被入选点亮

在依附单片机的智能种类中,汉字彰显模块是比较重大的一个组成都部队分,它利用遍布、操作轻巧、调节和测验简便。

每种字符由十四个字节表示

只是,在单片机上突显汉字也存在多少个难点。首先,单片机资源有限,我们不能够为了显示汉字占用太多的财富;其次,汉字存款和储蓄读取相比较繁杂,使用不低价;第三,汉字是透过点阵彰显出来的,往往与LCD写入措施不相通,那就得进行改造和调动。

仅要求用asii码值乘以16就足以固定到当前字符的点阵地点

值得注意的是,基于单片机的汉字突显无法在字符LCD上落成。使用图形LCD有好些个独特之处,不仅能显得汉字,何况能够兑现汉字动态移动和左右滚屏,达成汉字与图片的老婆当军展现,同不时间耗电低。

 

2依照单片机的方块字展现原理

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 };

2.1汉字字模

 

汉字相仿是以点阵式存款和储蓄的,如16×16,24×24点阵(即汉字的字样卡塔尔国,每一个汉字由32字节(16点阵卡塔 尔(阿拉伯语:قطر‎或72字节(24点阵卡塔尔国描述。依据汉字的两样字体,也可分为燕体字模、陶文字模、行书字模等等。

刷写8*16字符点阵

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

 

为了便利寻觅所需汉字的点阵,每一个汉字都与八个双字节的内码后生可畏风度翩翩对应。通过汉字的内码能够估测计算出它的点阵早先字节。现以16点阵为例表明。

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     

先由内码总计出它在汉字库中的区位码,计算公式为:

 

区码=内码第一字节-160

选用HZK16
字库,将它拷贝到内存中,使用时一向用数组指向某些汉字所在地方

位码=内码第二字节-160

 使用#include <sys/stat.h>中的fstat(卡塔 尔(英语:State of Qatar)函数来总计HZK16文本消息

再由区位码能够赢得它在汉字库中字模第2个字节的地点:

 

(区码×94+位码)×32
于是,能够向后连连读出由叁十五个字节组成的该字的点阵数据。

    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 fstatn");
        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_memn");
        return -1;
    }

2.第22中学黄炎子孙民共和国字展现

 

汉字占用能源太多(如16点阵,各类汉字就需32字节卡塔 尔(英语:State of Qatar),因此常常把汉字库放在EEPROM里,必要出示某些汉字时,先算出它的区位码,再求出点阵起头地方,从EEPROM中逐个调出该字的点阵数据,存在缓冲区里,最终依次送往LCD突显,描出该字。须要验证的是汉字存款和储蓄方式与LCD显示情势有一定差异。

 

本文使用另少年老成种突显方式,即事先将顺序用到的汉字、符号和数量(为了省去呈现空间,能够将数据压成8×16点阵卡塔 尔(阿拉伯语:قطر‎,编成一个文书文件,用意气风发段小程序做出相应小的汉字库,这一个小字库的汉字点阵数据取自于常常汉字库。再经过转变和调动,获得新的汉字库,最终把新字库固化在EEPROM中。单片机只需按序号读出点阵字节,送往LCD就能够显示所需汉字。缓和了单片机的担当,去除了繁琐的检索内码、求伊始位置、调换、调解等工作,进步了系统可信赖性。

HZK16
字库是切合GB2312规范的16×16点阵字库,HZK16的GB2312-80支撑的方块字有67陆十一个,符号685个。在那之中一级汉字有37五13个,按
声序排列,二级汉字有3008个,按偏旁部首排列。大家在局地选取场面根本用不到那样多汉字字模,所以在应用时就可以只领到部分字体作为己用。

表116点阵汉字字库存储方式

 

3自定义小字库的创立

HZK16字Curry的16×16汉字风华正茂共须求2五拾几个点来体现,也正是说须要三10个字节才干落得展现七个普通汉字的目标。

出色的汉字库可选拔UCDOS下的字库,如16点阵字库HZK16。要求256K上空,用了极大的EEPROM,又不便利读取,而实在应用中需求的汉字又超级少,因此我们得以自个儿创设小的汉字库,在这里个小字Curry只含有系统必要的方块字。那样,一方面节省读取时间,另一面大大地节约了能源。

我们驾驭三个GB2312汉字是由五个字节编码的,范围为A1A1~FEFE。A1-A9为符号区,B0到F7为汉字区。每一个区有91个字符(注意:那只是编码的准许节制,不必然皆有字型对应,举个例子符号区就有众多编码空白区域卡塔尔国。上面以汉字“作者”为例,介绍怎样在HZK16文书中找到它对应的35个字节的字样数据。

防止篇幅,这里仅仅给出流程图(假定事先将所需汉字写到了一个文书文件卡塔 尔(阿拉伯语:قطر‎,如图1所示。

 

前方谈到三个中黄炎子孙民共和国字占八个字节,这两当中前叁个字节为该汉字的区号,后三个字节为该字的
位号。此中,每一个区记录九十多个汉字,位号为该字在该区中的地点。所以要找到“作者”在hzk16库中的地点就务须得到它的区码和位码。(为了分裂使用了区码
和区号,其实是二个事物,别被小编错误的指导了卡塔 尔(阿拉伯语:قطر‎

将全体汉字字库寄放在EPROM或E2PROM内,程序依据要出示汉字的机内码来调用汉字字模。

 

一点高档单片机,如中兴的M68300体系叁十四位单片机,寻址范围可达8M,液晶呈现常用的16×16汉字库二进制数据文件为八百多k,将汉字字仓库储存入大体量的E2PROM,通过地点线可寻址到汉字库中的每六此中炎黄子孙民共和国字。

区码:区号(汉字的第七个字节卡塔尔-0xa0   
(因为汉字编码是从0xa0区开始的,所以文件最终边正是从0xa0区开头,要算出相对区码)

在微型机中对汉字的鉴定识别是由此机内码来兑现的,汉字标准机内码为两字节代码。汉字在汉字库中是根据区位来排列的,每后生可畏区中有九十四个汉字,每一个汉字都对应唯风度翩翩的区号和在本区的位号,汉字输入法中就有区位码方法,实际上,汉字机内码和区位码有职业的相应关系,有些汉字在字库中的区号加上0xa0等于其机内码的高字节,位号加上0xa0等于其机内码的低字节,因而比较轻便通过程序总计出要显示的汉字在汉字库中的区位号,即获得了其在汉字库中的偏移地址。

位码:位号(汉字的第一个字节卡塔尔-0xa0

出于E2PROM中存款和储蓄了一切汉字库,只须在硬件上设定寄存汉字库的存款和储蓄器片选地址,直接将汉字作为字符数组付给汉字显示函数,通过机内码总结出区号和位号,就可以方便地对汉字字模实行调用了。与前二种办法比较,无须事先提取字模和设定其地址用于程序调用,由此在进展程序晋级,涉及到汉字呈现时,不用校订汉字字模数据。

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

                                  汉字的字样与显示–汉字的代码种类
目 录
  1.1 汉字机内码
  1.2 汉字地址码
  1.3 汉字调换码
  1.4 汉字字型码

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


 

  在汉字音信管理系统中留存着冒尖汉字编码。经常的话,在系统的不相同地方,可依照其情况给汉字定以相应的编码,因为在汉字消息管理系统中设有着数种汉字编码。那么些编码构成了八个汉字的代码连串。

表明:1、区码减1是因为数组是以0为开头而区号位号是以1为始发的

1.1、汉字机内码
  汉字机内码(亦称汉字内码卡塔 尔(阿拉伯语:قطر‎是系统内处和储存汉字而采纳的代码。威名昭著,西方文字字符的机内码多使用五个字节来表示的ASCII码,有的系统则应用EBCDIC码。平日只利用7位来表示129个字符,而把高位用作奇偶校验(只怕不用卡塔 尔(英语:State of Qatar)。本国的国家标准GB2312-80规定,五在那之中夏族民共和国字用七个字节表示,这段时间规定各类字节也只用六个人,其高位未作定义。
  为了有限支撑系统的中西方文字宽容,意味着系统的机内码中必得保证ASCII(IBM-PC采取该码作为西方文字字符的机内码卡塔尔的运用,同期又要允许汉字机内码的接收,何况使两个之间未有冲突。要是用GB2312-80中的国家标准码作为机内码,则在系统中同一时候存在ASCII码和国家标准码时,将会时有发生二义性。例如,机内有八个字节的剧情分别为30H和21H,它们既可以够代表汉字“啊”的国家规范码,又足以象征字符“0”和“!”的ASCII码。所以,从头到尾地利用国家标准码作为汉字机内码是丰盛的,应当要加以合适的转移。
  平常意况下是将国家标准码的每一种字节的高职责令1,作为汉字机内码,这种编码称作为变形国家规范码。那样作既解决了西方文字机内码与汉字机内码的二义性,又确定保障汉字机内码与国家标准码之间有极轻松的相应关系。其团队如下:

     2、(94*(区号-1)+位号-1)是叁在那之中黄炎子孙民共和国字字模占用的字节数

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

   3、最后乘以32是因为汉字库文应从该职位起的32字节音讯记录该字的字样音信(后边提到一个汉字要有叁拾肆个字节呈现卡塔 尔(英语:State of Qatar)

  依据CGB2312-80中的汉字、图形符号,依照其职责分为玖拾伍个“区”,各种区包含玖拾伍个汉字,种种汉字字符又称之为“位”。此中“区”的序号,由01到94,“位”的序号,也是从01到94。若以横向表示“位”号,纵向表示“区”号,则“区”和“位”构成三个二维坐标。给定四个“区”值和“位”值就足以明确叁个唯风姿洒脱的汉字或图形符号。所以4位数字就足以唯大器晚成明确二个汉字或标识,上面给出汉字的区内和内码对应关系表。

 

区位码(10进制) 内码(16进制)
区号 位号 高字节 低字节
1—9 1—94 A1—A9 A1—FE
10—12 1—94 AA—AC A1—FE
13—15 1—94 AD—AF A1—FE
16—87 1—94 B0—F7 A1—FE

 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 }

1.2、汉字地址码
  汉字地址码是指汉字字模库(这里根本指整字形的点阵字模库卡塔 尔(阿拉伯语:قطر‎中存款和储蓄各汉字字形消息的逻辑地址码。中国语言历史学系统中的汉字字模库有三种,它们分别贮存在RAM(或EPROM卡塔 尔(阿拉伯语:قطر‎春日磁盘上。故中国语言历史学系统中的汉字地址码有二种,风姿洒脱种采用内部存款和储蓄器地址数来表示(对应RAM和EPROM中的字库卡塔 尔(英语:State of Qatar),别的风流倜傥种选取盘地址来表示(对应于磁盘中的字库卡塔 尔(阿拉伯语:قطر‎。由于中国语言历史学系统的汉字字模库中汉字字形音信排列的平整,使得中国语言军事学系统的汉字字模库中的汉字字形新闻排列连串的法规,使得中国语言管理学系统的方块字地址码与汉字机内码之间存在着三个简短的函数关系。

 

1.3、汉字调换码
  汉字沟通码是生机勃勃种用于汉字音信管理系统里头,或然与报纸发表系统里面张开消息沟通的方块字代码。汉字交流码位于生龙活虎台机器的开口和另一台机械(包罗输出设备与记录设备卡塔尔的输入之间。为了要高达系统装置之间或记录介质媒质之间音讯置换的指标,汉字交流码必须使用统风流罗曼蒂克的样式。近期境内Computer连串所采取的科班音信管理交流码,是依赖国标制订的,即GB1990—
《新闻管理沟通使用的五人编码字符集》;还拟订了相应的代码扩大规范,即GB2311

《新闻管理沟通使用的陆位编码字符集的扩展方法》。因为汉字调换码应与GB1990宽容,并基于GB2311所分明的诀窍开展编辑。由于汉字数量远远胜出七人编码所能表示的八千七个常用汉字制订了调换码的国标,即GB2312

《新闻沟通用汉字编码字符基本集》,当中各样汉字用对应于GB一九八八的三个八人码来表示。

 

1.4、汉字字型码
  由于当下汉字消息管理系统中生出汉字字形的形式多数是数字式的,即以点阵的方法产生汉字,过汉字字形码是指明确叁个汉字字形码也就不一致。

对像素进行瞄颜色

                                                      汉字库的施用 

 

UCDOS软件中的文件HZK16为16×16的国家规范汉字点阵文件,以二进制格式存储。在文书HZK16中,按汉字区位码从小到大依次存有国家标准区位码表中的兼具汉字,每一种汉字占用三11个字节,各个区为九十二个汉字。

 1 void lcd_put_pixel(int x, int y, unsigned int color)
 2 {
 3     unsigned char *pen_8 = fb_mem + y * line_width + x * pixel_width;     //当前像素对应内存位置
 4     unsigned short *pen_16;
 5     unsigned int *pen_32;
 6 
 7     unsigned int red, blue, green;
 8     
 9     pen_16 = (unsigned short *)pen_8;
10     pen_32 = (unsigned int *)pen_8;
11     
12     switch(var.bits_per_pixel)
13     {
14         case 8:
15         {
16             *pen_8 = color;            //对应调色板颜色
17             
18             break;
19         }
20         case 16:
21         {
22             /* 5*6*5 */
23             red   = (color >> 16) & 0xff;
24             green = (color >> 8) & 0xff;
25             blue  = (color >> 0) & 0xff;
26 
27             color = ((red >> 3 ) << 11) | ((green >> 2) << 5) | ( blue >> 3);
28             
29             /* 颜色数据为高位 */
30             *pen_16 = color;
31             
32             break;
33         }
34         case 32:
35         {
36             *pen_32 = color;
37             break;
38         }
39         
40     }
41 
42 }

在PC机的文件文件中,汉字是以机内码的样式储存的,每种汉字占用四个字节:第多个字节为区码,为了与ASCII码分歧,范围从十三进制的0A1H从头(小于80H的为ASCII码字符卡塔尔,对应区位码中区码的率先区;第叁个字节为位码,范围也是从0A1H起首,对应某区中的第三个位码。那样,将汉字机内码减去0A0AH就得该汉字的区位码。

 

比方说汉字“房”的机内码为十二进制的“B7BF”,在那之中“B7”表示区码,“BF”表示位码。所以“房”的区位码为0B7BFH-0A0A0H=171FH。将区码和位码分别转变为十进制得汉字“房”的区位码为“2331”,即“房”的点阵位于第23区的第35个字的职分,也就是在文件HZK16中之处为第32×[(23-1)
×94+(31-1)]=67136B以往的31个字节为“房”的显得点阵。

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

上面给出叁个基于汉字机内码(两字节卡塔尔在汉字库中查究汉字的字样的次第。字库文件分成四片段,分别设有四片27512(并行EPROM)中。读出的字样存入hz_buffer[32]数组中。

 

int8
hz_buffer[32];//定义32字节数组,用于存款和储蓄点阵字模,该字模为横排字模。

荧屏输出‘a’,“中”

#define int8 unsigned char

 

#define int16 unsigned int

#define int32 unsigned long

/*

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

对ASCII字符,则read_hz(‘A’+0xa380);读取

*/

void   read_hz(int16 hz){

void   *void_p;//定义三个空类型指针

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

int8    i;   //定义三个循环变量

int16 area_l,area_h;//定义三个整型变量,用于存款和储蓄区码和位码

int32 pos;  //定义一个long型变量,用于存款和储蓄计算机技巧讨论所得字模在字库的职分,

int8   chip;  //字模所在的晶片,可用74HC138之类的微电路译码。

int16 addr;  //在某黄金年代微芯片64K字节空间内的地址

   

void_p=&hz;    //空指针指向机内码的低字节

int8_p=void_p;    //char类型指针指向空指针,即机内码的低字节

area_l=*int8_p-0xa0; //机内码低字节能减排去0xa0得到区码

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

pos=32*((int32)((area_h-1)*94)+area_l-1);
//计算在一个完完全全的字库中的地点(256K)

//pos=116672;        
//那是“请”字在HZK16文件中的地点,单位为字节。用于测验

if(pos<64*1024)   //在首先片27512微电路

    {

       chip=0;addr=(int16)pos;

    }

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

    {

       chip=1;

       addr=(int16)pos;  

    }

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

    {

       chip=2;

       addr=(int16)pos;

    }   

else if((pos>=192*1024)&&(pos<256*1024)) //在第四片27512晶片

    {

       chip=3;

       addr=(int16)pos;         

    }

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

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

    {

      hz_buffer[i]=read_data(addr+i); //读取一字节的数量

    }

}

   
 在事实上中,由于现相当少使用EPROM微芯片,能够用并口、SPI,I2C接口的大容积Flash、EEPROM微电路。但I2C接口速度极慢,呈现汉字的速度将会超慢,能够在生龙活虎部分超少字场地使用;而SPI接口的存款和储蓄集成电路速度超快,接口简单,对于平时的接受地方仍为能够满意的;对于大气选择的场面,能够动用并行接口,它具积攒空间大,读取速度快的风味,如使用AT29多种的Flash存款和储蓄器,单片体量能够达成256K上述,就无需分开积累,但其索要超级多的IO口,接口复杂。所以应基于实际来抉择存款和储蓄器。

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注