免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1849 | 回复: 0
打印 上一主题 下一主题

[学习分享] 关于电子书阅读器的代码问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-01-10 13:26 |只看该作者 |倒序浏览
10可用积分
这个代码怎么弄成可以翻上一页或者可以显示中文
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <fcntl.h>
  6. #include <sys/stat.h>
  7. #include <sys/mman.h>
  8. #include <sys/time.h>
  9. #include <sys/wait.h>
  10. #include <sys/ipc.h>
  11. #include <linux/fb.h>
  12. #include <sys/types.h>
  13. #include <stdlib.h>
  14. #include "font_8x16.h"
  15.                
  16. //画好显示区域,x方向左右空一个字,y方向上下空一个字节
  17. #define Start_x 16
  18. #define Start_y 8
  19. #define End_x        (320 - 16)
  20. #define End_y        (240 - 8)

  21. struct fb_var_screeninfo vinfo;
  22. struct fb_fix_screeninfo finfo;
  23. char *fbp = 0;
  24. long screensize = 0;
  25. long location = 0;
  26. int r = 0;       
  27. unsigned int number;
  28. int fk;
  29. char buttom_status[6];
  30. int next_page = 0;
  31. unsigned int page[1000];
  32. unsigned int  count = 0;
  33. int page_n;


  34. //清屏
  35. void Clean_screen()
  36. {
  37.         memset(fbp, 0xf8, screensize);
  38. }

  39. void Draw_text16X16(long location_t,unsigned short color, const unsigned char ch[])
  40. {
  41.         int i, j;
  42.         unsigned char mask, buffer;
  43.         for (i = 0; i < 16; i++)
  44.         {
  45.                 mask = 0x80;
  46.                 buffer = ch[i * 2];
  47.                 location_t +=  finfo.line_length;
  48.                 for (j = 0; j < 8; j++) {
  49.                         if ((buffer & mask))
  50.                                 {        
  51.                                         *(fbp +location_t + j * vinfo.bits_per_pixel / 8) = color;
  52.                                         *(fbp +location_t + j * vinfo.bits_per_pixel / 8 + 1) = color>>8;
  53.                                   }
  54.                          mask = mask >> 1;
  55.                  }

  56.                 mask = 0x80;
  57.                 buffer = ch[i * 2 + 1];
  58.                 for (j = 0; j < 8; j++)
  59.                 {
  60.                         if ((buffer & mask))
  61.                                 {
  62.                                         *(fbp +location_t + (8 + j) * vinfo.bits_per_pixel / 8) = color;
  63.                                         *(fbp +location_t + (8 + j) * vinfo.bits_per_pixel / 8 + 1) = color>>8;
  64.                                 }
  65.                         mask = mask >> 1;
  66.                 }
  67.         }               
  68. }

  69. void Draw_text16X8(long location_t,unsigned short color, const unsigned char ch[])
  70. {
  71.         int i, j;
  72.         unsigned char mask, buffer;

  73.         for (i = 0; i < 16; i++)
  74.         {
  75.                 mask = 0x80;
  76.                 buffer = ch[i];
  77.                 location_t +=  finfo.line_length;
  78.                 for (j = 0; j < 8; j++)
  79.                 {
  80.                         if ((buffer & mask))
  81.                                 {
  82.                                         *(fbp +location_t + j * vinfo.bits_per_pixel / 8) = color;
  83.                                         *(fbp +location_t + j * vinfo.bits_per_pixel / 8 + 1) = color>>8;
  84.                                 }
  85.                         mask = mask >> 1;
  86.                 }
  87.         }
  88. }

  89. void Next_screen(long location_t, unsigned short color, unsigned char ch[], int Flag)
  90. {
  91.         int ret;
  92.         while (1)
  93.         {       
  94.                 ret = read(fk, buttom_status, 6);
  95.                 if (ret < 0)
  96.                 {
  97.                         printf("read buttom status err\n");
  98.                 }
  99.        
  100.                 if (buttom_status[0] == '1')
  101.                 {
  102.                         next_page = 1;
  103.                 }
  104.                 if (next_page == 1)
  105.                 {
  106.                         next_page = 0;       
  107.                         //清屏
  108.                         Clean_screen();
  109.                         //重新定一屏的起始位置
  110.                         location = location_t;
  111.                         r = 0;
  112.                         page[page_n] = count;
  113.                         page_n += 1;
  114.                         count = 0;
  115.                         //打印汉字
  116.                         if (Flag == 1)
  117.                                 Draw_text16X16(location, color, ch);
  118.                         else if (Flag == 0)
  119.                                    Draw_text16X8(location, color, ch);
  120.                         break;
  121.                 }else
  122.                 {
  123.                         continue;
  124.                 }
  125.         }
  126. }
  127.        
  128. void Next_line(long location_t,int r_t)
  129. {
  130.         location = location_t +  16 * r_t * finfo.line_length;
  131. }

  132. void Put_lcd_Hz(long location_t, unsigned short color, unsigned char ch[])
  133. {
  134.         int Flag_Hz = 0;  //汉字标志位,默认为字符非汉字
  135.         //计算字最右边的点有没有越界,判断位置需不需要换行
  136.         location += 16 * (vinfo.bits_per_pixel / 8);
  137.         //这个针对320x240的屏,最后一个字的点去除刚好整除为0,可以考虑用下面的方法——通用一些
  138.         //if ((location % (vinfo.xres * vinfo.bits_per_pixel / 8)) < (16 * vinfo.bits_per_pixel /8))
  139.         if((location - (Start_y + 16 * r) * finfo.line_length)  > End_x * (vinfo.bits_per_pixel / 8))
  140.         {
  141.                 //计算字最下边的点有没有越界,判断需不需要换屏
  142.                 if ((location + 16 * finfo.line_length) > (End_x * (vinfo.bits_per_pixel / 8) + End_y * finfo.line_length))
  143.                 {
  144.                         Flag_Hz = 1;
  145.                         Next_screen(location_t, color, ch, Flag_Hz);
  146.                 }else
  147.                 {
  148.                         r = r + 1;
  149.                         Next_line(location_t,r);
  150.                 }
  151.         }
  152.         //字最右边的点没有越界,位置要记得复位
  153.         else
  154.                 location -= 16 * (vinfo.bits_per_pixel / 8);
  155.         //打印16X16字
  156.            Draw_text16X16(location, color, ch);
  157.         //指向下一个字或字符的起始位置
  158.         location += 16 * (vinfo.bits_per_pixel / 8);
  159. }

  160. void Put_lcd_CH(long location_t, unsigned short color, unsigned char ch[])
  161. {
  162.         int Flag_Hz = 0;  //汉字标志位,默认为字符非汉字
  163.         //计算字最右边的点有没有越界,判断位置需不需要换行
  164.         location += 8 * (vinfo.bits_per_pixel / 8);
  165.         //判断位置需不需要换行
  166.         if ((location - (Start_y + 16 * r) * finfo.line_length) > End_x * (vinfo.bits_per_pixel / 8))               
  167.         {
  168.                 //计算字最下边的点有没有越界,判断需不需要换屏
  169.                 if ((location + 16 * finfo.line_length) > (End_x * (vinfo.bits_per_pixel / 8) + End_y * finfo.line_length))
  170.                 {
  171.                         Next_screen(location_t, color, ch, Flag_Hz);
  172.                 }else
  173.                 {
  174.                         r = r + 1;
  175.                         Next_line(location_t,r);
  176.                 }
  177.         }
  178.         else
  179.                 location -= 8 * (vinfo.bits_per_pixel / 8);
  180.        
  181.         //打印16X8字
  182.            Draw_text16X8(location, color, ch);
  183.         location += 8 * (vinfo.bits_per_pixel / 8);
  184. }

  185. //换行符处理函数
  186. void do_line_break(long location_t)
  187. {
  188.         //换行有可能是刚刚好也是换屏的时候
  189.         if ((location + 16 * finfo.line_length) > (End_x * (vinfo.bits_per_pixel / 8) + (End_y - 1) * finfo.line_length))
  190.         {
  191.                 Next_screen(location_t, 0, "next_screen", 2);
  192.         }else
  193.         {
  194.                 r = r + 1;
  195.                 Next_line(location_t, r);
  196.         }
  197. }       
  198.        
  199. int main(void)
  200. {
  201.         int fd, fp;                                                                                        //fp----LCD   fd------.txt  
  202.         FILE *Hz_fp;                                                                                //Hz_fp-----HZK16
  203.         struct stat txt_stat;                                                                //文件状态,可获得文件的字节数
  204.         off_t file_size;                                                                        //文件字节数
  205.         unsigned int hz_index, assic_index;                                        //汉字在汉字库中的偏移量
  206.         unsigned char *buffer;                                                                //存放文本文件内容的缓存
  207.         unsigned char hz_buf[32], assic_buf[16];                        //存放字模的数组
  208.         long location_t;                                                                        //保存一屏的起始位置       

  209.         //打开LCD设备
  210.         fp = open("/dev/fb0", O_RDWR);
  211.         if(fp < 0)
  212.         {
  213.                 printf("Error : Can not open framebuffer device\n");
  214.                 exit(1);
  215.         }
  216.         puts("hello world.\n");
  217.         printf("open framebuffer device\n");
  218.        
  219.        
  220.         //初始化lcd       
  221.         if (ioctl(fp, FBIOGET_FSCREENINFO, &finfo))
  222.         {
  223.                 printf("Error reading fixed information\n");
  224.                 exit(2);
  225.         }
  226.         if (ioctl(fp, FBIOGET_VSCREENINFO, &vinfo))
  227.         {
  228.                 printf("Error reading fixed information\n");
  229.                 exit(3);

  230.         }
  231.         screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
  232.        
  233.         fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fp, 0);
  234.         if ((int)fbp == -1)       
  235.         {
  236.                 printf("Error: failed to map framebuffer device to memory.\n");
  237.                 exit(4);
  238.         }
  239.         //清屏       
  240.         Clean_screen();
  241.         //一屏的起始位置location_t
  242.         location_t = Start_x * (vinfo.bits_per_pixel / 8) + Start_y * finfo.line_length;
  243.         //location做一个全局变量,用于确定每个汉字或字符的输出位置
  244.         location = location_t;

  245.         fk = open("/dev/buttons", O_RDWR);
  246.         if (fk < 0)
  247.         {
  248.                 printf("can't open /dev/buttons\n");
  249.                 return -1;
  250.         }

  251.         //打开16x16的汉字库
  252.         Hz_fp = fopen("HZK16", "rb");
  253.         if (Hz_fp == NULL)
  254.         {
  255.                 printf("HZK16 can't open!\n");
  256.                 return (-1);
  257.         }
  258.         //打开txt文本
  259.         fd = open("/home/1.txt", O_RDONLY);
  260.         if (fd < 0)       
  261.         {
  262.                 printf("txt can't open!\n");
  263.                 return -1;
  264.         }
  265.         //通过struct stat结构体求得文本的字节数
  266.         fstat(fd, &txt_stat);
  267.         file_size = txt_stat.st_size;
  268.         //开辟与文本字节数一样大小的缓存
  269.         buffer = (unsigned char *)malloc(file_size);
  270.         //将申请到的缓存清零
  271.         memset(buffer, 0, file_size);
  272.         //一次性将文本的内容读到缓存中
  273.         read(fd,buffer, file_size);

  274.         while(*buffer != '\0')
  275.         {
  276.                 //文本换行符
  277.                 if (*buffer == '\r' || *buffer == '\n')  
  278.                 {
  279.                         do_line_break(location_t); //换行符处理函数
  280.                         buffer += 1;
  281.                         continue;
  282.                 }
  283.                 //一个tab用四个字节代替
  284.                 if (*buffer == '\t')               
  285.                 {
  286.                         location += 32 * (vinfo.bits_per_pixel / 8);
  287.                         *buffer++;
  288.                         count += 1;
  289.                         continue;
  290.                 }
  291.                
  292.                 if (*buffer == ' ' || *buffer == 0xa1)
  293.                 {
  294.                         location += 8 * (vinfo.bits_per_pixel / 8);
  295.                         *buffer++;
  296.                         count += 1;
  297.                         continue;
  298.                 }

  299.                 //判断汉字还是英文
  300.                 if (*buffer > 0xa1)       
  301.                 {
  302.                         hz_index = ((*buffer - 0xa1) * 94 + (*(buffer + 1) - 0xa1)) * 32;
  303.                         fseek(Hz_fp, hz_index, SEEK_SET);
  304.                         fread(hz_buf, 32, 1, Hz_fp);
  305.                     Put_lcd_Hz(location_t, 0xf800, hz_buf);
  306.                         //sleep(1);
  307.                         buffer += 2;
  308.                         count += 2;
  309.                 }
  310.                 else
  311.                 {
  312.                         assic_index = *buffer * 16;
  313.                         memcpy(assic_buf, &Assic[assic_index], 16);
  314.                     Put_lcd_CH(location_t, 0x07e0, assic_buf);
  315.                         count++;
  316.                         buffer++;
  317.                 }
  318.         }
  319.        
  320.         munmap(fbp, screensize);
  321.         close(fp);
  322.         fclose(Hz_fp);
  323.         close(fk);       
  324.         close(fd);
  325.         return 0;
  326. }
复制代码

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP