HZK16应用实例

2019-12-01 13:24栏目:竞技宝app
TAG:

要求:竞技宝app,原操作系统代码里只是永葆了克罗地亚语呈现,必要做的是兑现对那一个系统的方块字全角扶持。

FrameBuffer的原理     FrameBuffer 是出新在 2.2.xx 根本当中的黄金时代种驱动程序接口。

在C51中,HZK16汉字库的施用(mydows's Blog转发卡塔尔(قطر‎

hzk16的介绍以致轻巧的接纳办法

    Linux是办事在爱抚情势下,所以顾客态进度是无可奈何象DOS那样选用显卡BIOS里提供的间歇调用来落到实处直接写屏,Linux抽象出 FrameBuffer那几个装置来供顾客态进度完毕直接写屏。Framebuffer机制模仿显卡的效应,将显卡硬件构造抽象掉,能够通过 Framebuffer的读写直接对显存实行操作。客商能够将Framebuffer看成是突显内存的三个影象,将其映射到进程地址空间之后,就足以一直开展读写操作,而写操作可以即时反应在显示屏上。这种操作是空虚的,统大器晚成的。顾客不用关怀物理显存的岗位、换页机制等等具体细节。这几个都以由 Framebuffer设备驱动来成功的。

概念如下:
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

HZK16字库是顺应GB2312规范的16×16点阵字库,HZK16的GB2312-80帮衬的汉字有67陆17个,符号681个。个中一级汉字有3752个,按声序排列,二级汉字有3008个,按偏旁部首排列。我们在某些施用处合根本用不到如此多汉字字模,所以在接收时就足以只领到部分字体作为己用。

    但Framebuffer本身不抱有任何运算数据的力量,就只可以比是三个一时寄存水的水池.CPU将运算后的结果放到那个水池,水池再将结果流到显示器. 中间不会对数据做管理. 应用程序也能够直接读写这些水池的内容.在这里种机制下,就算Framebuffer需求真正的显卡驱动的支撑,但具备突显任务都有CPU达成,由此CPU 担当相当重

         HZK16字库是相符GB2312标准的16×16点阵字库,HZK16的GB2312-80帮衬的方块字有67六16个,符号6捌11个。当中顶尖汉字有3753个,按声序排列,二级汉字有3008个,按偏旁部首排列。大家在局地使用处合根本用不到如此多汉字字模,所以在选取时就足以只领到部分字体作为己用。

HZK16字Curry的16×16中国字黄金时代共须求2五拾六个点来展现,也正是说须求叁十三个字节本领达到规定的规范彰显多个何奇之有汉字的目标。

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

HZK16字Curry的16×16中夏族民共和国字风度翩翩共供给2五十多少个点来展现,也正是说要求三14个字节手艺实现展现贰个家常汉字的目标。

大家精通三个GB2312汉字是由八个字节编码的,范围为A1A1~FEFE。A1-A9为符号区,B0到F7为汉字区。每八个区有九十几个字符(注意:那只是编码的特许范围,不肯定都有字型对应,比如符号区就有不菲编码空白区域)。上面以汉字“小编”为例,介绍怎么着在HZK16文件中找到它对应的三15个字节的字样数据。

可以用命令: #dd if=/dev/zero of=/dev/fb 清空显示器. 要是展现形式是 1024x768-8 位色,

咱俩领略三个GB2312汉字是由三个字节编码的,范围为A1A1~FEFE。A1-A9为符号区,B0到F7为汉字区。每三个区有九十四个字符(注意:那只是编码的特许约束,不料定皆有字型对应,例如符号区就有许多编码空白区域)。上边以汉字“笔者”为例,介绍怎么着在HZK16文本中找到它对应的34个字节的字样数据。

眼下谈起三个中夏族民共和国字占多个字节,那四个中前一个字节为该汉字的区号,后四个字节为该字的位号。在那之中,每一种区记录95个汉字,位号为该字在该区中的地点。所以要找到“作者”在hzk16库中之处就必需得到它的区码和位码。(为了不相同使用了区码和区号,其实是叁个事物,别被本人误导了)

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

前方提及贰个中华夏族民共和国字占七个字节,这两个中前一个字节为该汉字的区号,后三个字节为该字的位号。在那之中,每一个区记录93个汉字,位号为该字在该区中的地点。所以要找到“小编”在hzk16库中的地方就必须要得到它的区码和位码。(为了差距使用了区码和区号,其实是二个事物,别被自个儿错误的指导了)

区码:区号(汉字的率先个字节)-0xa0 (因为汉字编码是从0xa0区初始的,所以文件最前方正是从0xa0区开首,要算出相对区码卡塔尔(英语:State of Qatar)

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

区码:区号(汉字的第一个字节)-0xa0    (因为汉字编码是从0xa0区初叶的,所以文件最前面正是从0xa0区开首,要算出相对区码卡塔尔(英语:State of Qatar)

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

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

位码:位号(汉字的第叁个字节)-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 将显示屏清空(这里假使显示方式是 1024x768-8 位色方式,线性内部存款和储蓄器情势):

            2、(94*(区号-1卡塔尔国+位号-1卡塔尔(قطر‎是多少个中国字字模占用的字节数

3、最后乘以32是因为汉字库文应从该职位起的32字节新闻记录该字的字样新闻(前边提到二个中黄炎子孙民共和国字要有31个字节展现)

int fb;

           3、最终乘以32是因为汉字库文应从该职位起的32字节信息记录该字的字样消息(前边提到三个汉字要有三19个字节彰显)

 有了摇头地址就可以从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. 注意:阿尔巴尼亚语的编码是分为左半局地和右半部分,而大家运用的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);

竞技宝app 1

字符点阵突显

                               图形LCD模块ACM19284ASB的汉字展现

参谋资料:

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()函数来总结HZK16文件消息

再由区位码能够拿走它在汉字库中字模第4个字节的职位:

 

(区码×94+位码卡塔尔国×32 于是,能够向后总是读出由三11个字节组成的该字的点阵数据。

    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.2汉字展现

版权声明:本文由龙竞技官网发布于竞技宝app,转载请注明出处:HZK16应用实例