自从写完16点阵后,由于没啥事做,就继续看看24点阵是如何显示的。这种规格的点阵是使用UCDOS(虽然下载了,但用不了)中的汉字字库。又千辛万苦找到ASCII码的24点阵,再修改前面的程序,生成24点阵ASCII码的数组。测试完后,用一天时间,在触摸屏搞出了汉字显示,不过对比了Tslib库的代码,发觉自己写的简直是一塌糊涂,于是继续修改代码。不过,由于不知道如何优化代码及组织代码结构,修改后的成果仅仅是生成的可执行文件大小比原来的版本少240个字节(使用size命令查看得到的结果)。这也算是一个进步吧,网络上关于专门针对某种平台、某种情景的代码优化资料比较少,靠以前和平时一点一点积累,实属不易。 在这里贴上两个版本的源代码,估计没啥人研究这玩意,因此程序不作解释。在不影响代码功能及坚持本人代码风格前提下,尽量减少不必要的行数,对代码中的笔误及其它不影响功能的小毛病,恕不再作修改。 原来的版本: #include <stdio.h>
#include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <ncurses.h> /* ncurses库头文件 */#include “ascii24.h” #define ascii_code ascii24 /* for debug */ //#define DEBUG #ifdef DEBUG #define debug(fmt, …) printw(fmt, ##__VA_ARGS__) #else #define debug(fmt, …) #endif #define size 24 /* 点阵规格:24点阵 */ #define bytes (size/8) /* 汉字占用字节:3字节,即分3次取数据 */ #define buf_size (bytes * size) /* 汉字缓冲区大小:3*24 = 72字节 */ #define ascii_bytes (bytes-1) /* 24点阵ASCII码占用字节:2字节,即分2次取数据,与16点阵汉字一样*/ #define ascii_size (size * ascii_bytes) /* ASCII缓冲区大小:24*2 = 48字节 */ /* 使用UCDOS汉字库显示汉字,需转置 y:行 x:列 mat:二维数组 code:显示的字符(如”*”等) */ static void __display_font(int y, int x, unsigned char mat[][3], char *code) { int i, j; for(i=0;i<size;i++) for(j=0;j<size;j++) if(mat[j][i/8] & (0x80>>i%8)) mvprintw(y+i, x+j, code); else mvprintw(y+i, x+j, ” “); refresh(); } static void __display_ascii(int y, int x, unsigned char *mat, char *code) { int i, j, k; for(i=0;i<size;i++) for(j=0;j<ascii_bytes;j++) for(k=0;k<8;k++) /* 从高位开始,逐位相与,为1者,输出“*” */ if(mat[i*ascii_bytes+j] & (0x80>>k)) mvprintw(y+i, x+j*8+k, code); else mvprintw(y+i, x+j*8+k, ” “); refresh(); } /* * 打印ASCII,使用96个可打印字符版本的ASCII码数组 * y:屏幕行 * x:屏幕列 * font:ASCII字符串 * note:注意函数中的unsigned char*类型 */ void display_ascii(int y, int x, unsigned char *font) { unsigned char *p_ascii; int offset; unsigned char *p = font; while (*p != 0) { offset = (*p – 0x20) * ascii_size; p_ascii = ascii_code + offset; __display_ascii(y, x, p_ascii, “*”); x += 13; /* 12或以上 */ p++; } } /* * 打印汉字,使用HZK24文件 * fp:汉字库文件指针 * y:屏幕行 * x:屏幕列 * font:汉字字符串 * note:注意函数中的unsigned char*类型 */ void display_hz(FILE *fp, int y, int x, unsigned char *font) { unsigned char mat[24][3]={{0}}; int qh,wh; unsigned long offset; unsigned char *p = font; while (*p != 0) { qh = *p – 0xaf; wh = *(p+1) – 0xa0; debug(“code : %x %xn”, *p, *(p+1)); offset = ( 94*(qh-1) + (wh-1) ) * 72; //offset = 0; debug(“qh: %x wh: %x offset: %xn”, qh, wh, offset); fseek(fp,offset,SEEK_SET); fread(mat,72,1,fp); __display_font(y, x, mat, “*”); x += 24; p+=2; /* 中文字符,移动2个字节 */ } } /* * 打印字符,中英文混合版本 * fp:汉字库文件指针 * y:屏幕行 * x:屏幕列 * font:字符串 * note: * 注意函数中的unsigned char*类型 */ void display_font(FILE *fp, int y, int x, unsigned char *font) { unsigned char mat[size][bytes]={{0}}; int qh,wh; unsigned long offset; unsigned char *p = font; unsigned char *p_ascii; while (*p != 0) { qh = *p – 0xaf; wh = *(p+1) – 0xa0; if (qh > 0 && wh > 0){ debug(“code : %x %xn”, *p, *(p+1)); offset = ( 94*(qh-1) + (wh-1) ) * buf_size; debug(“qh: %x wh: %x offset: %xn”, qh, wh, offset); fseek(fp,offset,SEEK_SET); fread(mat,buf_size,1,fp); __display_font(y, x, mat, “*”); x += 25; /* 24或以上 */ p+=2; /* 中文字符,移动2个字节 */ } else { offset = (*p – 0x20) * ascii_size; p_ascii = ascii_code + offset; __display_ascii(y, x, p_ascii, “*”); x += 13; /* 12或以上 */ p+=1; /* 英文字符,移动1个字节 */ } } } int main() { unsigned char incode[] = “我顶ABC”; FILE *HZK; initscr(); /* init screen */ if((HZK=fopen(“HZK24S”,“rb”))==NULL) { perror(“Can’t Open hzk24″); exit(0); } display_font(HZK, 1, 0, incode); fclose(HZK); //getch(); /*暂停*/ endwin(); /* close it */ return 0; } size命令结果: $ size a.out
text data bss dec hex filename 3042 4892 12 7946 1f0a a.out
修改后的版本: #include <stdio.h>
#include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <ncurses.h> /* ncurses库头文件 */#include “ascii24.h” #define ascii_code ascii24 /* for debug */ //#define DEBUG #ifdef DEBUG #define debug(fmt, …) printw(fmt, ##__VA_ARGS__) #else #define debug(fmt, …) #endif #define size 24 /* 点阵规格:24点阵 */ #define bytes (size/8) /* 汉字占用字节:3字节,即分3次取数据 */ #define buf_size (bytes * size) /* 汉字缓冲区大小:3*24 = 72字节 */ #define ascii_bytes (bytes-1) /* 24点阵ASCII码占用字节:2字节,即分2次取数据,与16点阵汉字一样*/ #define ascii_size (size * ascii_bytes) /* ASCII缓冲区大小:24*2 = 48字节 */ /* 使用UCDOS汉字库显示汉字,需转置 y:行 x:列 mat:二维数组 code:显示的字符(如”*”等) */ static void __display_font(FILE *fp, int y, int x, unsigned char *s, char *code) { unsigned int i, j; unsigned char mat[24][3]={{0}}; int qh,wh; unsigned long offset; qh = *s – 0xaf; wh = *(s+1) – 0xa0; debug(“code : %x %xn”, *p, *(p+1)); offset = ( 94*(qh-1) + (wh-1) ) * 72; debug(“qh: %x wh: %x offset: %xn”, qh, wh, offset); fseek(fp,offset,SEEK_SET); fread(mat,72,1,fp); for(i=0;i<size;i++) for(j=0;j<size;j++) if(mat[j][i>>3] & (0x80>>(i&7))) mvprintw(y+i, x+j, code); else mvprintw(y+i, x+j, ” “); refresh(); } static void __display_ascii(int y, int x, unsigned char *ascii, char *code) { int i, j, k; unsigned char *p_ascii; int offset; offset = (*ascii – 0x20) * ascii_size; p_ascii = ascii_code + offset; for(i=0;i<size;i++) for(j=0;j<ascii_bytes;j++) for(k=0;k<8;k++) /* 从高位开始,逐位相与,为1者,输出“*” */ //if(*( p_ascii + i*ascii_bytes+j) & (0x80>>k)) if(p_ascii[i*ascii_bytes+j] & (0x80>>k)) mvprintw(y+i, x+j*8+k, code); else mvprintw(y+i, x+j*8+k, ” “); refresh(); } /* * 打印ASCII,使用96个可打印字符版本的ASCII码数组 * y:屏幕行 * x:屏幕列 * font:ASCII字符串 * note:注意函数中的unsigned char*类型 */ void display_ascii(int y, int x, unsigned char *font) { //unsigned char *p = font; while (*font != 0) { __display_ascii(y, x, font, “*”); x += 12; /* 12或以上 */ font++; } } /* * 打印汉字,使用HZK24文件 * fp:汉字库文件指针 * y:屏幕行 * x:屏幕列 * font:汉字字符串 * note:注意函数中的unsigned char*类型 */ void display_hz(FILE *fp, int y, int x, unsigned char *font) { #if 01 while (*font != 0) { __display_font(fp, y, x, font, “*”); x += 24; font+=2; /* 中文字符,移动2个字节 */ } #endif #if 0 /* 比前一种方法多一条指令:i++ */ int i; for (i = 0; *font; i++, x += 24, font += 2) __display_font(fp, y, x, font, “*”); #endif } /* * 打印字符,中英文混合版本 * fp:汉字库文件指针 * y:屏幕行 * x:屏幕列 * font:字符串 * note: * 注意函数中的unsigned char*类型 */ void display_font(FILE *fp, int y, int x, unsigned char *font) { while (*font != 0) { if ( (*font – 0xaf) > 0 && (*(font) – 0xa0) > 0) { __display_font(fp, y, x, font, “*”); x += 24; font+=2; /* 中文字符,移动2个字节 */ } else { __display_ascii(y, x, font, “*”); x += 12; /* 12或以上 */ font++; } } } int main() { unsigned char incode[] = “我顶ABC”; FILE *HZK; initscr(); /* init screen */ if((HZK=fopen(“HZK24S”,“rb”))==NULL) { perror(“Can’t Open hzk24″); exit(0); } display_font(HZK, 1, 0, incode); fclose(HZK); endwin(); /* close it */ return 0; } size命令结果: $ size a.out text data bss dec hex filename 2802 4892 12 7706 1e1a a.out 本文固定链接: http://www./programming-under-linux/dot-font-24.html |
|