文本浏览器及数码相框 -2.2-字符点阵及汉字库

要求:原操作系统代码里只是支撑了荷兰语显示,须要做的是贯彻对那么些系统的汉字全角扶助。

 

return 0;

正文使用另一种突显格局,即事先将次第用到的方块字、符号和数码(为了省去突显空间,可以将数据压成8×16点阵),编成3个文书文件,用一段小程序做出相应小的汉字库,那一个小字库的方块字点阵数据取自于一般汉字库。再经过转换和调整,得到新的汉字库,末了把新字库固化在EEPROM中。单片机只需按序号读出点阵字节,送往LCD即可突显所需汉字。减轻了单片机的承受,去除了繁琐的搜索内码、求初阶地点、转换、调整等工作,升高了系统可相信性。

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

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

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

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

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

framebuffer的配备文件一般是
/dev/fb0、/dev/fb1 等等。

printf(“\n”);

1.④ 、汉字字型码
  由于近年来汉字新闻处理系统中发出汉字字形的情势大多是数字式的,即以点阵的方法形成汉字,过汉字字形码是指显然三个汉字字形码也就差距。

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

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

if(fphzk == NULL){

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

参考资料:

 

以下是作者本人写的演示程序, 可以协调修改成其余的数码格式.(很不难,
所以没写注释)。

在C51中,HZK16汉字库的施用(mydows’s Blog转发)

代码如下:

   
但Framebuffer本身不负有其余运算数据的能力,就只能比是2个权且存放水的水池.CPU将运算后的结果放到那几个水池,水池再将结果流到屏幕.
中间不会对数据做处理.
应用程序也得以一直读写那么些水池的内容.在那种体制下,固然Framebuffer须要真正的显卡驱动的协理,但拥有彰显任务都有CPU完成,因而CPU
负担很重

if(*word == ‘\n’)

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

hzk16的牵线以及不难的施用方法

 

for(;;){

譬如说汉字“房”的机内码为十六进制的“B7BF”,其中“B7”表示区码,“BF”表示位码。所以“房”的区位码为0B7BFH-0A0A0H=171FH。将区码和位码分别转换为十进制得汉字“房”的区位码为“2331”,即“房”的点阵位于第②3区的第壹十二个字的职位,相当于在文书HZK16中的地方为第12×[(23-1)
×94+(31-1)]=67136B未来的三十二个字节为“房”的来得点阵。

如此大家就足以得到汉字在HZK16中的相对偏移地方:

FrameBuffer的规律     FrameBuffer
是出新在 2.2.xx 基本当中的一种驱动程序接口。

0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01

    }   

三 、最后乘以32是因为汉字库文应从该义务起的32字节音讯记录该字的字样音讯(前边提到多个中国字要有三十多个字节呈现)

 

示例源代码

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

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

 

for(j=0; j<2; j++){

1.③ 、汉字沟通码
  汉字互换码是一种用于汉字信息处理系统里面,恐怕与报导系统之间开展新闻交换的方块字代码。汉字交流码位于一台机械的讲话和另一台机器(包罗输出设备与记录设备)的入口之间。为了要达标系统设备之间或记录介质之间新闻沟通的目标,汉字交流码必须利用联合的方式。如今国内总结机系列所运用的正规化新闻处理沟通码,是基于国家标准制定的,即GB一九八九—
《音信处理沟通使用的八人编码字符集》;还制定了对应的代码扩张标准,即GB2311

《音讯处理交流使用的7个人编码字符集的伸张方法》。因为汉字互换码应与GB一九八七包容,并基于GB2311所显然的章程开展编制。由于汉字数量远远出乎7人编码所能表示的六千三个常用汉字制定了交流码的国家标准,即GB2312

《音讯置换用汉字编码字符基本集》,其中每种汉字用对应于GB壹玖捌玖的两个7个人码来代表。

小编们了解2个GB2312汉字是由八个字节编码的,范围为A1A1~FEFE。A1-A9为符号区,B0到F7为汉字区。每一种区有9陆个字符(注意:那只是编码的准许限制,不必然都有字型对应,比如符号区就有不少编码空白区域)。下边以汉字“作者”为例,介绍如何在HZK16文件中找到它对应的三十二个字节的字样数据。

刷写8*16字符点阵

};

    {

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

 

for(k=0; k<16; k++){

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

HZK16字Curry的16×16汉字一共必要25九个点来体现,约等于说需求三十几个字节才能达到突显3个常备汉字的目的。

可以再度写回显示器: #dd if=fbfile
of=/dev/fb;

}

int8   chip;  //字模所在的芯片,可用74HC138等等的芯片译码。

此间其余的地方相比弄,第⑥步将大小修改一下,作者的是nihongo = (unsigned
char *) memman_alloc_4k(memman, 55*94*32);

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

fseek(fphzk, offset, SEEK_SET);

#define int32 unsigned long

HZK16字库是相符GB2312标准的16×16点阵字库,HZK16的GB2312-80帮助的汉字有676三个,符号68一个。其中超级汉字有37五拾肆个,按声序排列,二级汉字有3008个,按偏旁部首排列。大家在局地施用场所根本用不到那样多汉字字模,所以在行使时就可以只领到部分字体作为己用。

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依据单片机的方块字展现原理

前边说到2个中国字占几个字节,这多个中前3个字节为该汉字的区号,后1个字节为该字的位号。其中,各种区记录9五个汉字,位号为该字在该区中的地方。所以要找到“作者”在hzk16库中的地方就必须得到它的区码和位码。(为了不同使用了区码和区号,其实是二个事物,别被小编误导了)

int fb;

int flag;

前面说到1个汉字占三个字节,那八个中前3个字节为该汉字的区号,后1个字节为该字的位号。其中,每种区记录9四个汉字,位号为该字在该区中的地方。所以要找到“作者”在hzk16库中的地方就必须得到它的区码和位码。(为了不相同使用了区码和区号,其实是壹个东西,别被自个儿误导了)

第陆步,要小心,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);

}

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

图片 1

 

for(k=0; k<16; k++){

       chip=2;

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

     2、(94*(区号-1)+位号-1)是贰个中国字字模占用的字节数

}

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

落到实处思路:

 

for(k=0; k<32; k++){

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

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

 

printf(“0x%02X};\n”, buffer[31]);

汉字相似是以点阵式存储的,如16×16,24×24点阵(即汉字的字样),每一种汉字由32字节(16点阵)或72字节(24点阵)描述。根据汉字的两样字体,也可分为草书字模、宋体字模、草书字模等等。

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

 

printf(“%s”, flag?”●”:”○”);

(区码×94+位码)×32
于是,能够向后总是读出由3多少个字节组成的该字的点阵数据。

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

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);                   //清屏,黑色

}

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    hzk16\n”);   
   exit(0);   
   }   
   fseek(HZK,    offset,    SEEK_SET);   
   fread(mat,    32,    1,    HZK);

 

   叁 、最终乘以32是因为汉字库文应从该职位起的32字节音讯记录该字的字样音讯(后面提到1个中国字要有叁拾两个字节突显)

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

                                                      汉字库的利用 

  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是分为上半部分和下半部分的。

各类字符由拾伍个字节表示

int i, j, k, offset;

   
 在骨子里中,由于现很少使用EPROM芯片,可以用并口、SPI,I2C接口的大容积Flash、EEPROM芯片。但I2C接口速度较慢,展现汉字的进程将会很慢,可以在局地比较少字场馆使用;而SPI接口的存储芯片速度较快,接口不难,对于一般的施用场面还能满意的;对于大气施用的场所,可以动用并行接口,它具储存空间大,读取速度快的表征,如采纳AT29各个的Flash存储器,单片容积可以高达256K上述,就不需求分开储存,但其需求较多的IO口,接口复杂。所以应按照实际来摘取存储器。

 

fphzk = NULL;

       chip=0;addr=(int16)pos;

仅必要用asii码值乘以16就足以一定到日前字符的点阵地方

return 1;

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

 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 }

fphzk = NULL;

2.2中国字突显

 

{

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

发表评论

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