Linux电子书项目之字符编码与字符的点阵显示(1)

一、字符编码

为更好的存储和展示,于是出现了字符编码。下面来看一下字符编码的发展过程。分为三个阶段:

阶段1:ASCII码

欧美人发明,用一个字节来标志。也就是常说的ASCII码,由于英语中只有26个英文字母,以及常用符号,可以很简单的编码出来。Ox41:A;0x61:a。

阶段2:国家编码GB2312(GBK)

我们国家有上千的汉子,所以编码要比较多一些,用两个字节来表示一个汉字。对于内地采用GB2312编码(GBK);big5(繁体字)等等。

D6DO:中。

阶段3:世界统一unicode码

世界需要一个统一的标准,于是出现了unicode,常见的utf-8;utf-16等

问题:

源文件用不同的编码方式编写,会导致执行结果不一样。

怎么解决?编译程序时,要指定字符集

man gcc , /charset

-finput-charset=charset  表示源文件的编码方式, 默认以UTF-8来解析

-fexec-charset=charset   表示可执行程序里的字时候以什么编码方式来表示,默认是UTF-8

gcc -o a a.c  

gcc -finput-charset=GBK-fexec-charset=UTF-8 -o utf-8_2 ansi.c

二、点阵显示

(1)打开lcd设备:

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

(2)得到lcd信息

  1.  if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))  
  2.     {  
  3.         printf("can't get var\n");  
  4.         return -1;  
  5.     }  
  6.   
  7.     if (ioctl(fd_fb, FBIOGET_FSCREENINFO, &fix))  
  8.     {  
  9.         printf("can't get fix\n");  
  10.         return -1;  
  11.     }  

(3)显存占据多少字节

  1.  line_width  = var.xres * var.bits_per_pixel / 8;  
  2.     pixel_width = var.bits_per_pixel / 8;  
  3.     screen_size = var.xres * var.yres * var.bits_per_pixel / 8;  

(4)LCD提供mmap

显存fb内存映射:

fbmem= (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED,fd_fb, 0);

screen_size:大小

PROT_READ | PROT_WRITE, MAP_SHARED:可读可写

(5)显示A+中

       unsignedchar str[] = "中";

       lcd_put_ascii(var.xres/2, var.yres/2, 'A');

       printf("chinesecode: %02x %02x\n", str[0], str[1]);

       lcd_put_chinese(var.xres/2 + 8,  var.yres/2, str);

       return0;  

三、代码

应用程序代码

[cpp]  view plain  copy
  1. #include <sys/mman.h>  
  2. #include <sys/types.h>  
  3. #include <sys/stat.h>  
  4. #include <unistd.h>  
  5. #include <linux/fb.h>  
  6. #include <fcntl.h>  
  7. #include <stdio.h>  
  8. #include <string.h>  
  9.   
  10. #define FONTDATAMAX 4096  
  11.   
  12. static const unsigned char fontdata_8x16[FONTDATAMAX] = {  
  13.     ...  
  14. }  
  15.       
  16.   
  17. int fd_fb;  
  18. struct fb_var_screeninfo var;   /* Current var */  
  19. struct fb_fix_screeninfo fix;   /* Current fix */  
  20. int screen_size;  
  21. unsigned char *fbmem;  
  22. unsigned int line_width;  
  23. unsigned int pixel_width;  
  24.   
  25. int fd_hzk16;  
  26. struct stat hzk_stat;  
  27. unsigned char *hzkmem;  
  28.   
  29.   
  30.   
  31. /* color : 0x00RRGGBB */  
  32. void lcd_put_pixel(int x, int y, unsigned int color)  
  33. {  
  34.     unsigned char *pen_8 = fbmem+y*line_width+x*pixel_width;  
  35.     unsigned short *pen_16;   
  36.     unsigned int *pen_32;     
  37.   
  38.     unsigned int red, green, blue;    
  39.   
  40.     pen_16 = (unsigned short *)pen_8;  
  41.     pen_32 = (unsigned int *)pen_8;  
  42.   
  43.     switch (var.bits_per_pixel)  
  44.     {  
  45.         case 8:  
  46.         {  
  47.             *pen_8 = color;  
  48.             break;  
  49.         }  
  50.         case 16:  
  51.         {  
  52.             /* 565 */  
  53.             red   = (color >> 16) & 0xff;  
  54.             green = (color >> 8) & 0xff;  
  55.             blue  = (color >> 0) & 0xff;  
  56.             color = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);  
  57.             *pen_16 = color;  
  58.             break;  
  59.         }  
  60.         case 32:  
  61.         {  
  62.             *pen_32 = color;  
  63.             break;  
  64.         }  
  65.         default:  
  66.         {  
  67.             printf("can't surport %dbpp\n", var.bits_per_pixel);  
  68.             break;  
  69.         }  
  70.     }  
  71. }  
  72.   
  73. void lcd_put_ascii(int x, int y, unsigned char c)  
  74. {  
  75.     unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16];  
  76.     int i, b;  
  77.     unsigned char byte;  
  78.   
  79.     for (i = 0; i < 16; i++)  
  80.     {  
  81.         byte = dots[i];  
  82.         for (b = 7; b >= 0; b--)  
  83.         {  
  84.             if (byte & (1<<b))  
  85.             {  
  86.                 /* show */  
  87.                 lcd_put_pixel(x+7-b, y+i, 0xffffff); /* 白 */  
  88.             }  
  89.             else  
  90.             {  
  91.                 /* hide */  
  92.                 lcd_put_pixel(x+7-b, y+i, 0); /* 黑 */  
  93.             }  
  94.         }  
  95.     }  
  96. }  
  97.   
  98. void lcd_put_chinese(int x, int y, unsigned char *str)  
  99. {  
  100.     unsigned int area  = str[0] - 0xA1;  
  101.     unsigned int where = str[1] - 0xA1;  
  102.     unsigned char *dots = hzkmem + (area * 94 + where)*32;  
  103.     unsigned char byte;  
  104.   
  105.     int i, j, b;  
  106.     for (i = 0; i < 16; i++)  
  107.         for (j = 0; j < 2; j++)  
  108.         {  
  109.             byte = dots[i*2 + j];  
  110.             for (b = 7; b >=0; b--)  
  111.             {  
  112.                 if (byte & (1<<b))  
  113.                 {  
  114.                     /* show */  
  115.                     lcd_put_pixel(x+j*8+7-b, y+i, 0xffffff); /* 白 */  
  116.                 }  
  117.                 else  
  118.                 {  
  119.                     /* hide */  
  120.                     lcd_put_pixel(x+j*8+7-b, y+i, 0); /* 黑 */  
  121.                 }  
  122.                   
  123.             }  
  124.         }  
  125.       
  126. }  
  127.   
  128. int main(int argc, char **argv)  
  129. {  
  130.     unsigned char str[] = "中";  
  131.       
  132.   
  133.     fd_fb = open("/dev/fb0", O_RDWR);  
  134.     if (fd_fb < 0)  
  135.     {  
  136.         printf("can't open /dev/fb0\n");  
  137.         return -1;  
  138.     }  
  139.   
  140.     if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))  
  141.     {  
  142.         printf("can't get var\n");  
  143.         return -1;  
  144.     }  
  145.   
  146.     if (ioctl(fd_fb, FBIOGET_FSCREENINFO, &fix))  
  147.     {  
  148.         printf("can't get fix\n");  
  149.         return -1;  
  150.     }  
  151.   
  152.     line_width  = var.xres * var.bits_per_pixel / 8;  
  153.     pixel_width = var.bits_per_pixel / 8;  
  154.     screen_size = var.xres * var.yres * var.bits_per_pixel / 8;  
  155.     fbmem = (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);  
  156.     if (fbmem == (unsigned char *)-1)  
  157.     {  
  158.         printf("can't mmap\n");  
  159.         return -1;  
  160.     }  
  161.   
  162.     fd_hzk16 = open("HZK16", O_RDONLY);  
  163.     if (fd_hzk16 < 0)  
  164.     {  
  165.         printf("can't open HZK16\n");  
  166.         return -1;  
  167.     }  
  168.     if(fstat(fd_hzk16, &hzk_stat))  
  169.     {  
  170.         printf("can't get fstat\n");  
  171.         return -1;  
  172.     }  
  173.     hzkmem = (unsigned char *)mmap(NULL , hzk_stat.st_size, PROT_READ, MAP_SHARED, fd_hzk16, 0);  
  174.     if (hzkmem == (unsigned char *)-1)  
  175.     {  
  176.         printf("can't mmap for hzk16\n");  
  177.         return -1;  
  178.     }  
  179.   
  180.     /* 清屏: 全部设为黑色 */  
  181.     memset(fbmem, 0, screen_size);  
  182.   
  183.     lcd_put_ascii(var.xres/2, var.yres/2, 'A');  
  184.   
  185.     printf("chinese code: %02x %02x\n", str[0], str[1]);  
  186.     lcd_put_chinese(var.xres/2 + 8,  var.yres/2, str);  
  187.   
  188.     return 0;     
  189. }  


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值