拉长国语字库

要求:原操作系统代码里只是补助了丹麦语显示,须要做的是完毕对这么些系统的汉字全角扶助。

FrameBuffer的原理     FrameBuffer
是出以往 2.2.xx 根本个中的朝气蓬勃种驱动程序接口。

在C51中,HZK16汉字库的施用(mydows’s Blog转发卡塔尔国

2017/07/02
更新,以前随手复制的旁人的,只筹算本身存档,所以格式没怎么管,然而看看500+阅读量感觉挺对不起在此之前点开的仇人的,何况终于思忖好好经营那些号了,所以能够收拾了弹指间。

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六18个,符号6八十几个。个中一流汉字有37五拾伍个,按声序排列,二级汉字有3008个,按偏旁部首排列。大家在局地选择场馆根本用不到那样多汉字字模,所以在行使时就足以只领到部分字体作为己用。

   
但Framebuffer本人不持有任何运算数据的力量,就不能不比是一个有的时候寄放水的水池.CPU将运算后的结果放到这几个水池,水池再将结果流到显示屏.
中间不会对数据做管理.
应用程序也足以平素读写这些水池的内容.在这里种体制下,即使Framebuffer须要真正的显卡驱动的支撑,但装有突显职责都有CPU实现,由此CPU
负责非常重

        
HZK16字库是切合GB2312规范的16×16点阵字库,HZK16的GB2312-80支撑的汉字有67陆十五个,符号681个。当中拔尖汉字有3753个,按声序排列,二级汉字有3008个,按偏旁部首排列。大家在有的行使场面根本用不到这么多汉字字模,所以在利用时就能够只领到部分字体作为己用。

HZK16字库是切合GB2312标准的16×16点阵字库,HZK16的GB2312-80支撑的汉字有6765个,符号6八十几个。个中一级汉字有
3754个,按声序排列,二级汉字有3008个,按偏旁部首排列。

HZK16字Curry的16×16中国字豆蔻梢头共须要2六十三个点来体现,也等于说供给叁十六个字节才干落得突显三个日常性汉字的目标。

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

HZK16字Curry的16×16中国字豆蔻梢头共要求2陆拾一个点来呈现,也便是说必要28个字节技巧完成彰显贰个惯常汉字的指标。

我们在一些利用项合根本用不到如此多汉字字模,所以在采纳时就足以只领到部分字体作为己用。

咱俩知晓多个GB2312汉字是由七个字节编码的,范围为A1A1~FEFE。A1-A9为符号区,B0到F7为汉字区。每二个区有九十一个字符(注意:那只是编码的许可约束,不明确都有字型对应,举个例子符号区就有为数不菲编码空白区域)。上面以汉字“小编”为例,介绍怎样在HZK16文本中找到它对应的33个字节的字样数据。

能够用命令: #dd if=/dev/zero of=/dev/fb
清空荧屏. 假诺呈现形式是 1024×768-8 位色,

小编们驾驭叁个GB2312汉字是由五个字节编码的,范围为A1A1~FEFE。A1-A9为符号区,B0到F7为汉字区。每叁个区有九十多个字符(注意:那只是编码的特许限定,不自然都有字型对应,比如符号区就有繁多编码空白区域)。下边以汉字“作者”为例,介绍如何在HZK16文书中找到它对应的三十一个字节的字样数据。

HZK16字库里的16×16中中原人民共和国字生机勃勃共必要258个点来显示,约等于说须要三贰拾伍个字节工夫完结展现三个常备汉字的目标。

前面聊起三个汉字占四个字节,这两当中前叁个字节为该汉字的区号,后七个字节为该字的位号。此中,种种区记录玖拾肆个汉字,位号为该字在该区中的地点。所以要找到“小编”在hzk16库中的地方就非得得到它的区码和位码。(为了差距使用了区码和区号,其实是一个东西,别被自身错误的指导了)

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

这段时间说起一个汉字占四个字节,那七个中前一个字节为该汉字的区号,后一个字节为该字的位号。当中,各种区记录93个汉字,位号为该字在该区中的地点。所以要找到“作者”在hzk16库中的地点就必需得到它的区码和位码。(为了差距使用了区码和区号,其实是一个东西,别被本人误导了)

我们清楚三个GB2312汉字是由三个字节编码的,范围为0xA1A1~0xFEFE。A1-A9为符号区,B0-F7为汉字区。每三个区有九十三个字符(注意:那只是编码的特许范围,不明确都有字型对应,譬喻符号区就有为数不菲编码空白区域卡塔尔(英语:State of Qatar)。

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

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

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

下边以汉字”小编”为例,介绍怎么着在HZK16文书中找到它对应的31个字节的字样数据。前边提起二个汉字占四个字节,这两在那之中前一个字节为该汉字的区号,后一个字节为该字的位号。此中,各个区记录玖拾贰个汉字,位号为该字在该区中的地点。所以要找到”作者”在hzk16库中之处就必须要得到它的区码和位码。

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

能够另行写回显示器: #dd if=fbfile
of=/dev/fb;

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

区码:汉字的第一个字节-0xA0(因为汉字编码是从0xA0区发轫的,
所以文件最前头正是从0xA0区开端, 要算出绝对区码卡塔尔(英语:State of Qatar)

与上述同类大家就能够收获汉字在HZK16中的相对偏移地点:

在利用Framebuffer时,Linux是将显卡置于图形格局下的.

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

位码:汉字的其次个字节-0xA0

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

 

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

那般我们就足以博得汉字在HZK16中的相对偏移地点:

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

    在应用程序中,日常通过将 FrameBuffer
设备映射到进度地址空间的艺术利用,比如上面包车型大巴前后相继就开拓 /dev/fb0
设备,

讲授:1、区码减1是因为数组是以0为开首而区号位号是以1为早先的

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

2、(94*(区号-1卡塔尔(英语:State of Qatar)+位号-1卡塔尔(قطر‎是三个汉字字模占用的字节数

并透过 mmap 系统调用举办地址映射,随后用
memset 将荧屏清空(这里假如展现形式是 1024×768-8
位色形式,线性内部存款和储蓄器情势):

            2、(94*(区号-1卡塔尔(英语:State of Qatar)+位号-1卡塔尔是一个汉字字模占用的字节数

注解:

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

int fb;

           3、最后乘以32是因为汉字库文应从该职位起的32字节新闻记录该字的字样新闻(前面提到三个汉字要有三13个字节彰显)

区码减1是因为数组是以0为发端而区号位号是以1为发端的

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

unsigned char* fb_mem;

有了摇头地址就可以从HZK16中读取汉字编码了,剩下的正是文本操作了,就背着了,要看代码(汉字)便是底下的:“hzk16汉字库的精简读写程序 ”,是三个最简便易行的c语言程序。

(94*(区号-1卡塔尔(英语:State of Qatar)+位号-1卡塔尔(英语:State of Qatar)是多个中华夏儿女民共和国字字模占用的字节数

落到实处思路:

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

                                                 hzk16汉字库的简短读写程序

最终乘以32是因为汉字库文应从该职位起的32字节音信记录该字的字样音讯(前边提到六在那之中华夏儿女民共和国字要有34个字节显示卡塔尔国

  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能够进行

//显示

所以,’我’在HZK16 16*16点阵字库的寄放的行列为:

第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的位则体现*/
                    {

(风度翩翩行豆蔻梢头行地保存,共16行,每行2个字节, 共35个字节卡塔尔国

代码如下:

宪章写三个

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

04 80 0E A0 78 90 08 90 08 84 FF FE 08 80 08 90

0A 90 0C 60 18 40 68 A0 09 20 0A 14 28 14 10 0C

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

版本1

参谋资料:

8*16像素的字符点阵

1引言

int main(void)

1. 30天操作系统接济汉语。

一个字节8位来代表一行的8个像素是不是被入选点亮

在依据单片机的智能系列中,汉字显示模块是很关键的三个组成都部队分,它使用遍布、操作轻巧、调节和测量试验简便。

{

各种字符由拾多少个字节表示

只是,在单片机上呈现汉字也存在多少个难题。首先,单片机能源有限,大家无法为了显得汉字占用太多的财富;其次,汉字存款和储蓄读取比较麻烦,使用不便民;第三,汉字是由此点阵展现出来的,往往与LCD写入措施不等同,那就得进行更改和调度。

FILE* fphzk = NULL;

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

值得注意的是,基于单片机的方块字显示不能够在字符LCD上贯彻。使用图形LCD有相当多亮点,不仅能展现汉字,并且能够兑现汉字动态移动和左右滚屏,完结汉字与图片的搅拌展现,同期功耗低。

int i, j, k, offset;

 

2依据单片机的方块字显示原理

int flag;

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中夏族民共和国字字模

unsigned char buffer[32];

发表评论

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