void Read_Config(const char* fn,int* n) { /* 读取分页及书签配置 参数说明: fn: 当前打开文件的文件名 n: 接受已缓存页数的缓冲区 */ char tmp[64]; FONTCHARACTER fname[64]; int handle,_n=*n; memset(tmp,0,sizeof(tmp)); strncpy(tmp,fn,strlen(fn)-strlen(strrchr(fn,'.'))); // 取文件名部分 strcat(tmp,".cfg"); char_to_font(tmp,fname); handle=Bfile_OpenFile_OS(fname,0); *n=_n; if (handle<=0) return; Bfile_ReadFile_OS(handle,&_n,4,0);*n=_n-1; // 读入已缓存页数 Bfile_ReadFile_OS(handle,bookmark,16,4); // 读入书签页码 Bfile_ReadFile_OS(handle,bytes,_n*4,20); //读入页面缓存 Bfile_CloseFile_OS(handle); }
void Save_Config(const char* fn,int n) { /* 存储分页及书签配置 参数说明: fn: 当前打开文件的文件名 n: 已缓存页数 */ char tmp[64]; FONTCHARACTER fname[64]; int handle,size=0; memset(tmp,0,sizeof(tmp)); strncpy(tmp,fn,strlen(fn)-strlen(strrchr(fn,'.'))); // 取文件名部分 strcat(tmp,".cfg"); char_to_font(tmp,fname); Bfile_CreateEntry_OS(fname,1,&size); // 创建 .cfg 文件 handle=Bfile_OpenFile_OS(fname,2); if (handle<=0) return; Bfile_WriteFile_OS(handle,&n,4); // 前 4 字节,写入已缓存页数 Bfile_SeekFile_OS(handle,4); Bfile_WriteFile_OS(handle,bookmark,16); // 4*4 字节,写入书签指向的页数 Bfile_SeekFile_OS(handle,20); Bfile_WriteFile_OS(handle,bytes,n*4); // 4*n 字节,写入页面缓存 Bfile_CloseFile_OS(handle); }
FONTFILE * open_font(const char * cfname) { int fh,r; FONTFILE *ff; fontc ffname[32]; char_to_font(cfname,ffname); fh = Bfile_OpenFile_OS(ffname,0); if (fh<=0) return NULL; ff = (FONTFILE*)malloc(sizeof(FONTFILE)); Bfile_ReadFile_OS (fh,ff,sizeof(FONTFILE)-2*sizeof(int),0); ff->file_handle = fh; ff->width = x86_dword_to_sh(ff->width); ff->height = x86_dword_to_sh(ff->height); ff->asc_offset = x86_dword_to_sh(ff->asc_offset); ff->chs_offset = x86_dword_to_sh(ff->chs_offset); r =ff->width/8 + (ff->width % 8 ? 1 : 0); ff->font_size = r*ff->height; return ff; }
int open_file (const char * cfname,int mode) { fontc ffname[32]; char_to_font(cfname,ffname); return Bfile_OpenFile(ffname,mode); }
void nx_display_string(const char *str) { while (*str != '\0') { if (*str == '\n') update_cursor(TRUE); else { int x_offset = display.cursor.x * NX__CELL_WIDTH; memcpy(&display.buffer[display.cursor.y][x_offset], char_to_font(*str), NX__FONT_WIDTH); update_cursor(FALSE); } str++; } dirty_display(); }
int check_consistency() { /* 检查文件一致性,若文件有缺失则显示错误信息 */ FONTCHARACTER fname[64]; int handle,i; char_to_font("\\\\fls0\\24PX.hzk",fname); handle=Bfile_OpenFile_OS(fname,0); if (handle<0) return 0; Bfile_CloseFile_OS(handle); return 1; }
void browse_main() { /* 文件浏览器主函数 */ char ncat[64], workdir[64] = "\\\\fls0"; // 当前目录 f_name *a=get_file_list("\\\\fls0\\*.*"); // 存储文件列表的二维数组 int pos=0,firstn=0; // 列表光标位置、列表下移的行数 unsigned int key; char subdir_fn[32]; // 供接收子目录文件名输入的缓冲区 FONTCHARACTER fname[64]; int handle = 0; DefineStatusAreaFlags(3, 0x01 | 0x02 | 0x100, 0, 0); beg: if (a) qsort(a, getn(a), sizeof(char *), cmp); font16 = open_font("\\\\fls0\\24PX.hzk"); select_font(font16); draw_browser(workdir,firstn,pos,a); // 绘制浏览器界面 close_font(font16); // 显示当前工作目录于状态栏 if (strcmp(workdir, "\\\\fls0") == 0) DefineStatusMessage("", 0, 0, 0); else { memset(ncat, 0, sizeof(ncat)); GetDisplayDirName(workdir, ncat); DefineStatusMessage(ncat, 0, 0, 0); } while (1) { GetKey(&key); switch (key) { case KEY_CTRL_UP: // 光标上移 if (a) { aa(&pos,&firstn,getn(a)); goto beg; } break; case KEY_CTRL_DOWN: // 光标下移 if (a) { bb(&pos,&firstn,getn(a)); goto beg; } break; case KEY_CTRL_F6: // 显示关于信息 Disp_About(); goto beg; break; case KEY_CTRL_F1: // 打开光标位置的文件 case KEY_CTRL_EXE: if (a) // 如果文件列表不为空 { if (strchr(a[pos+firstn].name,'[')) // 如果打开的是文件夹 { memset(ncat,0,sizeof(ncat)); //strcat(ncat,"\\\\fls0\\"); strcat(ncat, workdir); strcat(ncat, "\\"); strcat(ncat, ++a[pos+firstn].name); memset(workdir, 0, sizeof(workdir)); strcpy(workdir, ncat); strcat(ncat, "\\*.*"); // 解析出文件夹名称 a=get_file_list(ncat); // 浏览该文件夹 pos=0; firstn=0; // 列表初始化 goto beg; } else // 如果打开的是文本文件 { memset(ncat,0,sizeof(ncat)); strcpy(ncat,workdir); strcat(ncat,"\\"); strcat(ncat,a[pos+firstn].name); // 解析出文件名称 iRead_main(ncat); // 启动阅读器 goto beg; } } break; case KEY_CTRL_F2: // 根据输入的文件名打开文件 memset(subdir_fn, 0, sizeof(subdir_fn)); if (Subdir_Open(subdir_fn)) { memset(ncat, 0, sizeof(ncat)); strcpy(ncat, workdir); strcat(ncat, "\\"); strcat(ncat, subdir_fn); // 连接上输入的文件名字 strcat(ncat, ".txt"); char_to_font(ncat, fname); handle = Bfile_OpenFile_OS(fname,0); if (handle <= 0) // 如果文件未找到 { Disp_FileNotFound(); MsgBoxPop(); goto beg; break; } MsgBoxPop(); Bfile_CloseFile_OS(handle); // 重新绘制浏览器界面 font16 = open_font("\\\\fls0\\24PX.hzk"); select_font(font16); draw_browser(workdir, firstn, pos, a); close_font(font16); // 启动阅读器 iRead_main(ncat); } goto beg; break; case KEY_CTRL_EXIT: // 从文件夹返回根目录 if (strcmp(workdir,"\\\\fls0")!=0) // 如果当前在文件夹内 { memset(ncat,0,sizeof(ncat)); strncpy(ncat,workdir,strlen(workdir)-strlen(strrchr(workdir,'\\'))); memset(workdir,0,sizeof(workdir)); strcpy(workdir,ncat); strcat(ncat,"\\*.*"); // 解析出上一级目录的名称 a=get_file_list(ncat); // 浏览该文件夹 pos=0;firstn=0; // 初始化列表 goto beg; } break; } } }
void iRead_main(const char* filename) { /* 阅读界面主函数 参数说明: filename: 打开的文件名 (从文件浏览器得到) */ int key,handle; char* buf=(char*)malloc(461); FONTCHARACTER fname[64]; char tip[64], tmp[64]; page=0;cached=0; memset(bytes,0,sizeof(bytes)); memset(bookmark,0,sizeof(bookmark));bookmark[3]=0; Read_Config(filename,&cached); // 读取书签及分页配置 // 如果分的页数不满 500 的整数倍,补分页满 if (cached==0) divide_page(filename,500-cached,1); else if (cached%500!=0) divide_page(filename,500-cached%500,1); // 补至 500 的整数倍 totbytes=0; /* 设置状态栏显示文字 0x0001:显示电量 0x0100:显示文字 */ DefineStatusAreaFlags(3, 0x01 | 0x02 | 0x100, 0, 0); beg: font16=open_font("\\\\fls0\\24PX.hzk"); select_font(font16); Bdisp_AllClr_VRAM(); draw_pic(0,192,124,22,0,Menu_Read); draw_pic(126,192,61,22,0,Menu_Sub_Jump); // 若翻下一页时超出已缓存页面范围 if (cached<=page) { // 如果分的页数不满 500 的整数倍,补分页满 if (!divide_page(filename,1,0)) page=cached-1; else if (cached%500!=0) divide_page(filename,500-cached%500,0); close_font(font16); goto beg; } totbytes=bytes[page]; // 修正读取字节指针位置 char_to_font(filename,fname); handle=Bfile_OpenFile_OS(fname,0); // 打开文件 Bfile_ReadFile_OS(handle,buf,400,totbytes); Bfile_CloseFile_OS(handle); print_chs_page(0,24,totbytes,(unsigned char*)buf); // 绘制一页 close_font(font16); // 准备显示浏览进度 char fn_ptr[64]; memset(fn_ptr, 0, sizeof(fn_ptr)); GetDisplayFileName(filename, fn_ptr); memset(tip, 0, sizeof(tip)); memset(tmp, 0, sizeof(tmp)); strcat(tip, fn_ptr); strcat(tip, " "); itoa(page + 1, tmp, 10); strcat(tip, tmp); strcat(tip, "/"); memset(tmp, 0, sizeof(tmp)); itoa(cached, tmp, 10);strcat(tip, tmp); // 状态栏显示文件名及进度 DefineStatusMessage(tip, 0, 0, 0); while (1) { GetKey(&key); switch (key) { case KEY_CTRL_UP: // 跳到上一页 if (page>0) { --page; goto beg; } break; case KEY_CTRL_DOWN: // 跳到下一页 ++page; goto beg; break; case KEY_CTRL_EXIT: // 离开,返回文件浏览器 Save_Config(filename,cached+1); DefineStatusAreaFlags(3, 0x01 | 0x02 | 0x100, 0, 0); return;break; case KEY_CTRL_F2: // 打开存储书签对话框 Save_Bookmark(filename,page,cached+1); goto beg;break; case KEY_CTRL_F1: // 打开读取书签对话框 Read_Bookmark(filename,&page,&cached); goto beg;break; case KEY_CTRL_F3: // 打开跳页对话框 Page_Jump(filename); goto beg;break; } } }
int divide_page(const char* filename,const int pages,int save) { /* 分页函数 参数说明: filename: 当前打开文件的文件名 pages: 需要分的页数 save: 是否需要跳回第一页 (初始化时使用) 返回值: 0: 已读到文件末尾 1: 未读到文件末尾 */ int cx,cy; int i=0,j; const int pp=16; int is_chs=0; // 中文字符标识 int tmp=cached,total=0; int decades_passed = 1; int handle; char* buf=(char*)malloc(460); FONTCHARACTER fname[64]; char_to_font(filename,fname); handle=Bfile_OpenFile_OS(fname,0); tmp=cached; totbytes=bytes[cached]; // 保险修正 // 如果请求的页数超过 9999 页,修正为 9999 页 if ((total=tmp+pages)>9999) total=9999; // 在 9999 页时尝试往后翻一页,跳出 if (cached+1>9999) {Bfile_CloseFile_OS(handle);return 0;}; // 在屏幕上显示分页的进度 ProgressBar(0, total - tmp); for (j=tmp;j<total;++j) // 从当前已缓存页面分到请求的页面,使用模拟填充显示区域方法 { // 尝试读取一段文字以备分页 memset(buf,0,461); Bfile_ReadFile_OS(handle,buf,400,totbytes); // 如果读到文件末尾则跳出 if (!buf[0]) { ProgressBar(total - tmp, total - tmp); Bfile_CloseFile_OS(handle); MsgBoxPop(); return 0; } // 填充位置设置为初始状态 cx=0; cy=24; for (i=0;;) { is_chs=buf[i] & 0x80; // 判断高位字节,确定是否为中文 if ((cx+pp)>368) // 填充超过屏幕右边缘 goto cn; if (is_chs) i+=2; // 中文,跳2字节 else { if (buf[i] == '\r' || buf[i] == '\n') // 若读到回车符直接进入下一行 { i++; if (buf[i] == '\r' || buf[i] == '\n') // 若读到回车符直接进入下一行 i++; goto cn; } i++; } // 将字符填充入当前行,增加字符偏移 if (is_chs) cx+=25; else cx+=18; // 填充超过屏幕右边缘 if (cx>368) { cn: cx=0; cy+=24; // 增加纵向字符偏移,进入下一行 if (cy>190) // 填充超过屏幕下边缘,跳出 break; } } bytes[j+1]=i+totbytes; // 将最后一个字符在文件中的位置存入下一页的缓存,以备读取 totbytes+=i; // 读取字节指针增加 ++cached; // 已缓存页面增加,表示分页成功 // 每分完1/10的总体,增加进度显示 if (j - tmp == (total - tmp) / 10 * decades_passed) { ProgressBar(j - tmp, total - tmp); decades_passed++; } } if (save) page=0; // 跳回第一页 ProgressBar(total - tmp, total - tmp); Bfile_CloseFile_OS(handle); MsgBoxPop(); return 1; }