s3c2440 上txt 小说阅读器
文件结构
Makefile:
- CROSSCOMPILE := arm-linux-
- CFLAGS := -Wall -O2 -c
- LDFLAGS := -lm -lfreetype
- CC := $(CROSSCOMPILE)gcc
- LD := $(CROSSCOMPILE)ld
- OBJS := main.o \
- font/font_manager.o \
- font/font_gbk.o \
- font/font_asc.o \
- display/display_manager.o \
- display/lcd_fb.o \
- draw/draw.o
- all: $(OBJS)
- $(CC) $(LDFLAGS) -o txt $^
- clean:
- rm -f txt
- rm -f $(OBJS)
- %.o:%.c
- $(CC) $(CFLAGS) -o $@ $<
main.c
- #include <stdio.h>
- #include "font/font_manager.h"
- #include "display/display_manager.h"
- #include "draw/draw.h"
- int main(int argc,char **argv)
- {
- //命令操作
- char cmd;
- //第一个参数 要显示的TXT 文件
- char *file = argv[];
- if(- == font_init())
- {
- printf("font manager init error \r\n");
- return -;
- }
- printf("font init ok \r\n");
- if(- == display_init())
- {
- printf("display manager init error \r\n");
- return -;
- }
- printf("display init ok \r\n");
- if(- == open_txt(file))
- {
- printf("cat't open %s txt \r\n", file);
- return -;
- }
- printf("read file : %s ok \r\n", file);
- show_page();
- while()
- {
- cmd = getchar();
- if('n' == cmd)
- {
- show_page_next();
- }
- if('p' == cmd)
- {
- show_page_pre();
- }
- if('q' == cmd)
- {
- return ;
- }
- }
- return ;
- }
HZK16 这个就不发了,网上自己找吧。
display/display_manager.h
- #ifndef __DISPLAY_MANAGER__
- #define __DISPLAY_MANAGER__
- #include <stdio.h>
- #include <string.h>
- typedef struct display{
- char *name;
- int width;
- int height;
- int (*display_init)(void);
- int (*display_px)(int color, int x, int y);
- struct display *next;
- } T_display, *PT_display;
- int display_init(void);
- int display_register(PT_display new_display);
- PT_display display_select(char *name);
- int init_lcd_fb();
- #endif
display/display_manager.c
- #include "display_manager.h"
- static PT_display head_pt_display;
- PT_display display_select(char *name)
- {
- PT_display temp_pt_display = head_pt_display;
- while(temp_pt_display)
- {
- if( == strcmp(name, temp_pt_display->name))
- {
- temp_pt_display->display_init();
- return temp_pt_display;
- }
- else
- {
- temp_pt_display = temp_pt_display->next;
- }
- }
- return NULL;
- }
- int display_init(void)
- {
- if(- == init_lcd_fb())
- {
- printf("lcd fb init error \n");
- return -;
- }
- return ;
- }
- int display_register(PT_display new_display)
- {
- PT_display temp_pt_display = head_pt_display;
- new_display->next = NULL;
- if(! head_pt_display)
- {
- head_pt_display = new_display;
- }
- else
- {
- while(temp_pt_display->next)
- {
- temp_pt_display = temp_pt_display->next;
- }
- temp_pt_display = new_display;
- }
- return ;
- }
display/lcd_fb.c
- #include "display_manager.h"
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <linux/fb.h>
- #include <sys/ioctl.h>
- #include <unistd.h>
- #include <string.h>
- #include <sys/mman.h>
- static int lcd_fb_display_init(void);
- static int lcd_fb_display_px(int color, int x, int y);
- static int fb_fd;
- static unsigned char *fb_mem;
- static int px_width;
- static int line_width;
- static int screen_width;
- static struct fb_var_screeninfo var;
- static T_display lcd_disp = {
- .name = "lcd_fb",
- .display_init = lcd_fb_display_init,
- .display_px = lcd_fb_display_px,
- };
- int init_lcd_fb()
- {
- return display_register(&lcd_disp);
- }
- static int lcd_fb_display_init(void)
- {
- //如果使用 mmap 打开方式 必须是 读定方式
- fb_fd = open("/dev/fb0", O_RDWR);
- if(- == fb_fd)
- {
- printf("cat't open /dev/fb0 \n");
- return -;
- }
- //获取屏幕参数
- if(- == ioctl(fb_fd, FBIOGET_VSCREENINFO, &var))
- {
- close(fb_fd);
- printf("cat't ioctl /dev/fb0 \n");
- return -;
- }
- //计算参数
- px_width = var.bits_per_pixel / ;
- line_width = var.xres * px_width;
- screen_width = var.yres * line_width;
- fb_mem = (unsigned char *)mmap(NULL, screen_width, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, );
- if(fb_mem == (void *)-)
- {
- close(fb_fd);
- printf("cat't mmap /dev/fb0 \n");
- return -;
- }
- //清屏
- memset(fb_mem, , screen_width);
- //设置参数
- lcd_disp.width = var.xres;
- lcd_disp.height = var.yres;
- return ;
- }
- static int lcd_fb_display_px(int color, int x, int y)
- {
- unsigned char *pen8;
- unsigned short *pen16;
- unsigned char r,g,b;
- pen8 = (unsigned char *)(fb_mem + y*line_width + x*px_width);
- pen16 = (unsigned short *)pen8;
- //合并为 565 格式 16bbp
- r = (color>>) & 0xff;
- g = (color>>) & 0xff;
- b = (color>>) & 0xff;
- *pen16 = (r>>)<< | (g>>)<< | (b>>);
- return ;
- }
draw/draw.h
- #include <stdio.h>
- #include <sys/mman.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include "../display/display_manager.h"
- #include "../font/font_manager.h"
- //定义一个用来实现 上下 翻页的链表
- typedef struct t_draw_page{
- int p;
- int pos; //相对于 基地址的 位置
- struct t_draw_page *pre;
- struct t_draw_page *next;
- } T_draw_page, *PT_draw_page;
- int open_txt(char *file);
- int show_page_pre();
- int show_page_next();
- int show_page();
- int draw_page(unsigned char **pos);
- int draw_font(int color, PT_fontMap pt_font);
- void draw_screen(int color);
draw/draw.c
- #include "draw.h"
- int txt_fd;
- struct stat txt_stat;
- unsigned char *txt_mem;
- #define TXT_COLOR 0xff0000
- #define BACKGROUND_COLOR 0xE7DBB5
- PT_display disp;
- PT_font gbk_font;
- PT_font asc_font;
- unsigned char *pos; //当前文件指针位置
- PT_draw_page pt_head_draw_page;
- //读取文件后使用 内存映射 缺点是大文件时死机,实际上也没有几百M 的文件
- int open_txt(char *file)
- {
- txt_fd = open(file, O_RDONLY);
- if(- == txt_fd)
- {
- printf("cat't get txt stat \n");
- return -;
- }
- if(- == fstat(txt_fd, &txt_stat))
- {
- close(txt_fd);
- printf("cat't get txt stat \n");
- return -;
- }
- txt_mem = (unsigned char *)mmap(NULL, txt_stat.st_size, PROT_READ, MAP_SHARED, txt_fd, );
- if(txt_mem == (void *)-)
- {
- close(txt_fd);
- printf("cat't mmap txt \n");
- return -;
- }
- //打开文件成功后 初始化 lcd
- disp = display_select("lcd_fb");
- //初始化字库
- asc_font = font_select("asc");
- gbk_font = font_select("gbk");
- //当前文件指针位置
- pos = txt_mem;
- printf("lcd width : %d height : %d \r\n", disp->width, disp->height);
- return ;
- }
- void draw_screen(int color)
- {
- int x,y;
- for(x=; x< disp->width; x++)
- {
- for(y=; y< disp->height; y++)
- {
- disp->display_px(color, x, y);
- }
- }
- }
- //渲染一个字模
- int draw_font(int color, PT_fontMap pt_font)
- {
- int i,j,k,x,y;
- unsigned char *buffer = pt_font->buffer;
- x = pt_font->x;
- y = pt_font->y;
- //循环字模 y
- for(i=; i<pt_font->height; i++)
- {
- //循环字模 x
- for(j=; j<pt_font->width/;j++)
- {
- //循环字模 1 字节的数据
- for(k=; k>=; k--)
- {
- if(*buffer & (<<k))
- {
- disp->display_px(color, x+-k + j*, y+i);
- }
- else
- {
- disp->display_px(BACKGROUND_COLOR, x+-k + j*, y+i);
- }
- }
- //移动下 1 字节数据
- buffer++;
- }
- }
- //移动下一个字符显示位置 这里会比较 x y 当显示满屏幕时 退出 返回 -1
- pt_font->x += pt_font->width;
- if(pt_font->x >= disp->width)
- {
- pt_font->x = ;
- pt_font->y += pt_font->height;
- }
- //width 已满 height 已满
- if(pt_font->y >= disp->height)
- {
- return -;
- }
- return ;
- }
- //渲染一页
- int draw_page(unsigned char **pos)
- {
- T_fontMap font = {
- .x = , /* 字要显示的位置x */
- .y = , /* 字要显示的位置y */
- .width = , /* 字高度 */
- .height = , /* 字大小 */
- };
- //绘一个背景颜色
- //draw_screen(0xE7DBB5);
- draw_screen(BACKGROUND_COLOR);
- //如何实别是 asc 码 还是 gbk 码
- //asc 小于 128
- //gbk 要减去 0xa1
- //递归读取文字绘制在屏幕上,当屏幕满时退出
- while()
- {
- //显示到文本最后了
- if((*pos - txt_stat.st_size) >= txt_mem )
- {
- return -;
- }
- //处理 \r\n 换行
- if('\r' == **pos)
- {
- (*pos)++;
- continue;
- }
- if('\n' == **pos)
- {
- //换行 y + 上一个字符的高度 这里有一点问题,如果 上一行 和下一行
- //显示的文字高度不同? 不过这不是HTML TXT 每行都一样
- (*pos)++;
- font.x = ;
- font.y += font.height;
- //换行时还要检查屏幕是否满
- if(font.y >= disp->height)
- {
- return -;
- }
- continue;
- }
- if('\t' == **pos)
- {
- //换行 y + 上一个字符的高度 这里有一点问题,如果 上一行 和下一行
- //显示的文字高度不同? 不过这不是HTML TXT 每行都一样
- (*pos)++;
- font.x += font.width;
- continue;
- }
- if(0x80 > **pos)
- {
- asc_font->font_getMap(*pos, &font);
- //asc 码每次移动1个
- (*pos)++;
- }
- else if((0xa0 < **pos) && (0xa0 < *(*pos+)))
- {
- gbk_font->font_getMap(*pos, &font);
- //gbk 码每次移动2个
- (*pos) += ;
- }
- //1 屏幕显示完毕
- if(- == draw_font(TXT_COLOR, &font))
- {
- return -;
- }
- }
- return ;
- }
- //显示一页
- int show_page()
- {
- //首次初始化头链表
- pt_head_draw_page = malloc(sizeof(T_draw_page));
- //默认时等于 文件开头
- draw_page(&pos);
- pt_head_draw_page->pos = ;
- pt_head_draw_page->pre = NULL;
- pt_head_draw_page->next = NULL;
- return ;
- }
- int show_page_pre()
- {
- PT_draw_page now_draw_page = pt_head_draw_page->pre;
- if(NULL == now_draw_page)
- {
- printf("no pre page \r\n");
- return -;
- }
- //重新定义指针
- pos = txt_mem + now_draw_page->pos;
- draw_page(&pos);
- pt_head_draw_page = now_draw_page;
- return ;
- }
- int show_page_next()
- {
- //首次初始化头链表
- PT_draw_page now_draw_page = pt_head_draw_page;
- if(! now_draw_page->next)
- {
- now_draw_page = malloc(sizeof(T_draw_page));
- //先记录下来当前位置在渲染
- now_draw_page->pos = pos - txt_mem;
- //默认时等于 文件开头
- draw_page(&pos);
- now_draw_page->pre = pt_head_draw_page;
- now_draw_page->next = NULL;
- //当前链表位置 等于 新生成的
- pt_head_draw_page = now_draw_page;
- }
- else
- {
- //如果当前节点有下节点 直接赋值
- pt_head_draw_page = pt_head_draw_page->next;
- pos = txt_mem + now_draw_page->pos;
- draw_page(&pos);
- }
- return ;
- }
font/font_manager.h
- #ifndef __FONT_MANAGER__
- #define __FONT_MANAGER__
- #include <stdio.h>
- #include <string.h>
- /* 定义一个存放 字模数据,字模显示位置等信息的struct */
- typedef struct{
- int x; /* 字要显示的位置x */
- int y; /* 字要显示的位置y */
- int width; /* 字高度 */
- int height; /* 字大小 */
- unsigned char *buffer; /* 字模的数据 */
- } T_fontMap, *PT_fontMap;
- /* 定义一个用来管理字体的 struct */
- typedef struct Font{
- char *name;
- int (*font_init)(void);
- int (*font_getMap)(unsigned char *str, PT_fontMap pfontMap);
- struct Font *next;
- } T_font, *PT_font;
- /* 所有字体初始化 */
- int font_init();
- /* 字体注册 */
- int font_register(PT_font);
- /* 获取一个字体 */
- PT_font font_select(char *name);
- /* gbk 字体初始化 */
- int gbk_init();
- /* asc 字体初始化 */
- int asc_init();
- #endif
font/font_manager.c
- #include "font_manager.h"
- /* 静态变量 全局变量 未初始化时内容为 0 局部变量未初始化时内容为垃圾值 */
- static PT_font tfont_head;
- /* 工作流程:font_init() 中调用 gbk asc 的初始化方法, gbk_init 中调用
- * font_register 注册到链表中 在对每个进行 init 操作
- */
- /* 所有字体初始化 */
- int font_init()
- {
- if(- == gbk_init())
- {
- printf("gbk font init error \n");
- return -;
- }
- if(- == asc_init())
- {
- printf("asc font init error \n");
- return -;
- }
- return ;
- }
- /* 字体注册 */
- int font_register(PT_font new_font)
- {
- PT_font temp_font = tfont_head;
- //设置链表下一个为 NULL
- new_font->next = NULL;
- //注册时初始化字体
- if(- == new_font->font_init())
- {
- return -;
- }
- //没有时添加第一个
- if(! tfont_head)
- {
- tfont_head = new_font;
- }
- else
- {
- //判断是否有 下个节点
- while(temp_font->next)
- {
- temp_font = temp_font->next;
- }
- temp_font->next = new_font;
- }
- return ;
- }
- PT_font font_select(char *name)
- {
- PT_font temp_pt_font = tfont_head;
- while(temp_pt_font)
- {
- if( == strcmp(name, temp_pt_font->name))
- {
- return temp_pt_font;
- }
- else
- {
- temp_pt_font = temp_pt_font->next;
- }
- }
- return NULL;
- }
font/font_gbk.c
- #include "font_manager.h"
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <sys/mman.h>
- #include <unistd.h>
- #include <stdio.h>
- static int hzk_fd;
- static struct stat hzk_stat;
- static unsigned char *hzk_mem;
- static int gbk_font_init(void);
- static int gbk_font_getMap(unsigned char *str,PT_fontMap pfontMap);
- //语法只适用于 初始化时,不适用在 函数内部。
- static T_font tfont_gbk = {
- .name = "gbk",
- .font_init = gbk_font_init,
- .font_getMap = gbk_font_getMap,
- };
- int gbk_init()
- {
- return font_register(&tfont_gbk);
- }
- /**
- * 打开字库
- * 内存映射
- */
- static int gbk_font_init(void)
- {
- hzk_fd = open("HZK16", O_RDONLY);
- if(- == hzk_fd)
- {
- printf("cat't open HZK16 \n");
- return -;
- }
- if(- == fstat(hzk_fd, &hzk_stat))
- {
- printf("cat't get HZK16 size\n");
- return -;
- }
- hzk_mem = (unsigned char *)mmap(NULL, hzk_stat.st_size, PROT_READ, MAP_SHARED, hzk_fd, );
- if(hzk_mem == (void *)-)
- {
- printf("cat't mmap HZK16\n");
- return -;
- }
- return ;
- }
- static int gbk_font_getMap(unsigned char *str, PT_fontMap pfontMap)
- {
- //编码规则
- //GBK 字库 区码 -0xA0 位码 -0xA0 , 每个区中有 94个字符
- //每个汉字使用16bit * 16bit 表示
- //高位在左侧显示
- //16bit 16行
- pfontMap->buffer = hzk_mem +((*str - 0xa1)* + (*(str+) - 0xa1))*;
- pfontMap->width = ;
- pfontMap->height = ;
- return ;
- }
font_asc.c
- #include "font_manager.h"
- static int asc_font_init(void);
- static int asc_font_getMap(unsigned char *str, PT_fontMap pfontMap);
- static T_font tfont_asc = {
- .name = "asc",
- .font_init = asc_font_init,
- .font_getMap = asc_font_getMap,
- };
- #define FONTDATAMAX 4096
- static const unsigned char fontdata_8x16[FONTDATAMAX] = {
- //..... 内容太多 .... 去 linux 内核里面找吧
- };
- int asc_init()
- {
- return font_register(&tfont_asc);
- }
- static int asc_font_init(void)
- {
- return ;
- }
- static int asc_font_getMap(unsigned char *str, PT_fontMap pfontMap)
- {
- unsigned char *asc_base = (unsigned char *)fontdata_8x16;
- //编码规则
- //8bit 16行
- pfontMap->buffer = asc_base + *str * ;
- pfontMap->width = ;
- pfontMap->height = ;
- return ;
- }
s3c2440 上txt 小说阅读器的更多相关文章
- PC免费的小说阅读器,可提取章节
最近自己做了个小说阅读器,就是下面这个东西啦,目前仅支持Window系统: 个人喜欢在电脑.平板上等大屏幕设备上阅读小说或电子书籍.原因其一是屏幕足够大,可以选择更舒服的字体大小:其二是觉得小屏幕看字 ...
- 开发微信小程序——古龙小说阅读器
概述 由于面试的关系接触了一下微信小程序,花了2晚上开发了一个带书签功能的古龙小说阅读器,并且已经提交审核等待发布.这篇博文记录了我的开发过程和对微信小程序的看法,供以后开发时参考,相信对其他人也有用 ...
- 从零开发一款txt小说下载器
在日常开发中,列表是一个非常常用的一个东西,可以用listview和recyclerview实现.当然,由于recyclerview更为实用且强大,它也是更好的方案. 而我以前为了方便,习惯直接拿网上 ...
- android优化中国风应用、完整NBA客户端、动态积分效果、文件传输、小说阅读器等源码
Android精选源码 android拖拽下拉关闭效果源码 一款优雅的中国风Android App源码 EasySignSeekBar一个漂亮而强大的自定义view15 android仿蘑菇街,蜜芽宝 ...
- Android 上的代码阅读器 CoderBrowserHD 修改支持 go 语言代码
我在Android上的代码阅读器用的是 https://github.com/zerob13/CoderBrowserHD 改造的版本,改造后的版本我放在 https://github.com/ghj ...
- 读取本地HTML的小说阅读器应用源码项目
该源码是一个不错的读取本地HTML的小说阅读器,读取本地HTML的小说阅读器,并且源码也比较简单的,非常适合我们的新手朋友拿来学习,有兴趣的朋友研究下. 源码下载: http://code.662p. ...
- 基于Core Text实现的TXT电子书阅读器
本篇文章的项目地址基于Core Text实现的TXT电子书阅读器. 最近花了一点时间学习了iOS的底层文字处理的框架Core Text.在网上也参考很多资料,具体的资料在文章最后列了出来,有兴趣的可参 ...
- 如何在使用摩托罗拉上的RSS阅读器应用进行一次订阅
订阅一个CSDN的RSS为例. 1.打开RSS阅读器. 2.设置->新增订阅->手动新增 订阅URL:输入http://articles.csdn.net/api/rss.php?tid= ...
- Vue小说阅读器(仿追书神器)
一个vue阅读器项目,目前已升级到2.0,阅读器支持横向分页并滑动翻页(没有动画,需要动画的可以自己设置,增加transitionDuration即可) 技术栈 vue全家桶+mint-ui gith ...
随机推荐
- 文本编辑器VIM/VI
vim/vi 功能强大全屏文本编辑器.主要是建立,编辑,显示文本. www.vim.org 构建shell脚本 :set number 使文件出现行号 a 光标后附件文件 i在光标前插入文 ...
- Jackson
Jackson可以轻松的将Java对象转换成json对象和xml文档,同样也可以将json.xml转换成Java对象. 1. 下载依赖库jar包 Jackson的jar all下载地址:http:// ...
- java常用集合框架底层实现简介与注意点
Collection: ArrayList:1:底层实现是数组,默认长度是10.2:add(),判断是否数组越界,是数组扩容为原来的两倍.3:remove(),copy数组,size-1,释放空虚的空 ...
- Codeigniter 3.0 相关文档 part two
分页 首先,配置 $this->load->library('pagination'); $config = array(); // $this->config->load(' ...
- protected $appends in Laravel
protected $appends = ['icon']; public function getIconAttribute(){ return Gravatar::src($this->em ...
- [转]Linux学习笔记——例说makefile 头文件查找路径
0.前言 从学习C语言开始就慢慢开始接触makefile,查阅了很多的makefile的资料但总感觉没有真正掌握makefile,如果自己动手写一个makefile总觉得非常吃力.所以特意借助 ...
- js正则匹配的一个日常应用
应用实例 1 /** 将段落中的 \n 转换为 <p></p>, 规范存储 */ 2 function formatParagraphForStore(val) { 3 var ...
- 关于IOS音频的开发积累
1.设置类别,表示该应用同时支持播放和录音 OSStatus error; UInt32 sessionCategory = kAudioSessionCategory_PlayAndRecord; ...
- OpenStack学习参考
预备知识 Python 调试手段.日志:pdb 开源框架 Django 面向对象:类.继承.多态 编码规范 搭建环境 安装docker,下载openstack镜像,关于docker参考 使用fuel来 ...
- java测试框架整理
Test: Junit4+Hamcrest 不多说了,就靠着两个 import static org.hamcrest.Matchers.equalTo; import static org.juni ...