ag旗舰厅官网_ag旗舰厅下载客户端

热门关键词: ag旗舰厅官网,ag旗舰厅下载客户端

操作系统

当前位置:ag旗舰厅官网 > 操作系统 > 添加中文字库,文件浏览器及数码相框

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

来源:http://www.pedaLyourcycLe.com 作者:ag旗舰厅官网 时间:2019-11-01 22:51

要求:原操作系统代码里只是支撑了保加利亚共和国(Народна република България)语展现,供给做的是贯彻对那几个系统的方块字全角扶植。

FrameBuffer的原理     FrameBuffer 是出新在 2.2.xx 基石个中的意气风发种驱动程序接口。

hzk16的牵线甚至简单的接收办法

    Linux是职业在爱慕格局下,所以客户态进度是无能为力象DOS那样选拔显卡BIOS里提供的脚刹踏板调用来落到实处直接写屏,Linux抽象出 FrameBuffer这些装置来供客户态进度完结直接写屏。Framebuffer机制模仿显卡的职能,将显卡硬件结构抽象掉,能够经过 Framebuffer的读写直接对显存进行操作。顾客能够将Framebuffer看成是呈现内部存款和储蓄器的一个影象,将其映射到进度地址空间之后,就能够直接进行读写操作,而写操作可甚至时反馈在显示器上。这种操作是架空的,统后生可畏的。顾客不用关切物理显存的职分、换页机制等等具体细节。这个都以由 Framebuffer设备驱动来落成的。

HZK16字库是切合GB2312标准的16×16点阵字库,HZK16的GB2312-80支撑的汉字有67陆10个,符号6捌十个。个中一流汉字有3751个,按声序排列,二级汉字有3008个,按偏旁部首排列。我们在部分使用场馆根本用不到这么多汉字字模,所以在利用时就能够只领到部分字体作为己用。

    但Framebuffer本人不享有别的运算数据的才能,就只好比是贰个权且贮存水的水池.CPU将运算后的结果放到那么些水池,水池再将结果流到显示屏. 中间不会对数据做管理. 应用程序也足以直接读写那么些水池的内容.在此种机制下,固然Framebuffer必要真正的显卡驱动的帮衬,但全数呈现任务都有CPU完结,由此CPU 肩负超重

HZK16字库里的16×16汉字大器晚成共供给2伍十几个点来体现,也正是说须求三十二个字节技巧实现展现一个弃之可惜汉字的目标。

framebuffer的器具文件日常是 /dev/fb0、/dev/fb1 等等。

我们清楚贰个GB2312汉字是由七个字节编码的,范围为A1A1~FEFE。A1-A9为符号区,B0到F7为汉字区。每三个区有九十一个字符(注意:那只是编码的批准范围,不确定都有字型对应,举个例子符号区就有好多编码空白区域)。上边以汉字“作者”为例,介绍如何在HZK16文本中找到它对应的34个字节的字样数据。

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

前方说起四个中黄炎子孙民共和国字占四个字节,那三个中前八个字节为该汉字的区号,后八个字节为该字的位号。个中,每一个区记录九十五个汉字,位号为该字在该区中的地点。所以要找到“笔者”在hzk16库中之处就必需获得它的区码和位码。(为了分裂使用了区码和区号,其实是一个东西,别被小编误导了)

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

区码:区号(汉字的首先个字节)-0xa0 (因为汉字编码是从0xa0区启幕的,所以文件最前面正是从0xa0区早先,要算出相对区码)

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

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

可以重复写回屏幕: #dd if=fbfile of=/dev/fb;

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

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

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

 

批注:1、区码减1是因为数组是以0为先河而区号位号是以1为最初的

    在应用程序中,平时经过将 FrameBuffer 设备映射到过程地址空间的不二等秘书籍采取,举例下边包车型地铁程序就张开 /dev/fb0 设备,

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

并透过 mmap 系统调用进行地址映射,随后用 memset 将显示器清空(这里假如呈现形式是 1024x768-8 位色情势,线性内部存款和储蓄器方式):

3、最终乘以32是因为汉字库文应从该岗位起的32字节音信记录该字的字样新闻(前边提到贰当中华夏族民共和国字要有33个字节显示)

int fb;

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

unsigned char* fb_mem;

落成思路:

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

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

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

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

第6步,要专心,HZK16是内外两部分,不相同于阿拉伯语的左右两部分的构造。

 

代码如下:

宪章写一个

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

 

 

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中出席一些汉字。

 

图片 1

字符点阵展现

参照他事他说加以调查资料:

8*16像素的字符点阵

1. 30天操作系统扶植中文。

一个字节8位来表示风流罗曼蒂克行的8个像素是还是不是被选中式点心亮

每一种字符由14个字节表示

仅要求用asii码值乘以16就能够一定到近期字符的点阵地点

 

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

 

刷写8*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     

 

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

 使用#include <sys/stat.h>中的fstat()函数来总括HZK16文件消息

 

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

 

 

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

 

HZK16字Curry的16×16汉字风流罗曼蒂克共要求2五十多个点来彰显,也正是说需求叁十四个字节技能达成显示三个兴致索然汉字的目标。

我们精通三个GB2312汉字是由多个字节编码的,范围为A1A1~FEFE。A1-A9为符号区,B0到F7为汉字区。每一个区有九十多个字符(注意:那只是编码的特许约束,不自然都有字型对应,举例符号区就有无数编码空白区域)。上边以汉字“笔者”为例,介绍如何在HZK16文书中找到它对应的叁10个字节的字样数据。

 

前边提及三个中夏族民共和国字占八个字节,这两个中前多个字节为该汉字的区号,后八个字节为该字的 位号。个中,每种区记录玖拾伍个汉字,位号为该字在该区中的地点。所以要找到“笔者”在hzk16库中之处就必需获得它的区码和位码。(为了不相同使用了区码 和区号,其实是叁个东西,别被小编误导了)

 

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

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

像这种类型我们就足以获得汉字在HZK16中的绝对偏移地方:

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

 

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

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

   3、最终乘以32是因为汉字库文应从该地方起的32字节消息记录该字的字样音讯(后边提到两在那之中夏族民共和国字要有33个字节展现)

 

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

 

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

 

显示屏输出‘a’,“中”

 

本文由ag旗舰厅官网发布于操作系统,转载请注明出处:添加中文字库,文件浏览器及数码相框

关键词:

上一篇:Windows下的Nessus安装与启动,漏洞评估

下一篇:没有了