自从写完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 %x/n", *p, *(p+
1));
offset = (
94*(qh-
1) + (wh-
1) ) *
72;
//offset = 0;
debug(
"qh: %x wh: %x offset: %x/n", 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 %x/n", *p, *(p+
1));
offset = (
94*(qh-
1) + (wh-
1) ) * buf_size;
debug(
"qh: %x wh: %x offset: %x/n", 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 %x/n", *p, *(p+
1));
offset = (
94*(qh-
1) + (wh-
1) ) *
72;
debug(
"qh: %x wh: %x offset: %x/n", 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