使用Tslib在触摸屏上显示汉字效果

中文、英文字库在触摸屏显示效果

迟思堂主人:李迟

个人主页:http://www.latelee.org

个人电子邮件:$ echo "bGF0ZWxlZUAxNjMuY29tCg==" | base64 -d

区区才疏学浅,孤陋寡闻,能力有限,诸君如遇问题,万望自行解决,切切,切切!

本次测试是在Tslib原来基础上添加汉字显示的代码,显示代码添加在fbutils.c和fbutils.h中,测试代码在ts_test.c中添加。编译Tslib命令如下:

$ git clone https://github.com/kergoth/tslib                    # 下载
$ cd tslib                                                      # 进入tslib目录
$ ./autogen.sh                                                  # 产生autotool必要文件
$ ./configure --host=arm-linux --prefix=/home/latelee/lib/tslib # 配置及指定安装目录

$ make                                                          # 编译
$ make install                                                  # 安装到指定目录
实际测试过程中,Tslib已经安装到开发板上,因此,只需要重新编译(即直接运行make命令)即可,无须重新配置及安装。当执行make后,在./tests目录下.libs中生成测试文件ts_test

本页面只显示测试效果,无实际代码及其讲解。本次研究最终版本代码示例附于文后,本文作者对代码保留一些权利,使用代码者风险自担(如代码中的bug),作者对代码的进一步修改无须通知他人。 由于代码、效果图均已公布,恕本人无义务提供技术支持。

效果图均由fb2png程序截图获取,使用命令如下:

./fb2png /dev/fb0 test_s_new.png 1 240 320 16
命令解释:
/dev/fb0       :帧缓冲(frame buffer)设备名称
test_s_new.png :图片文件名称
1              :延时
240 320        :水平、垂直大小(即长、宽)
16             :颜色值(经测试,不能为24)
16*16点阵字体截图:
原始英文(8*8)          16*16点阵宋体          16*16点阵宋体          16*16点阵宋体(测与试之间是镕字)

24*24点阵宋体:
24*24点阵宋体        24*24点阵仿宋        24*24点阵宋体(添加其它中文字符)
         24*24点阵楷体        24*24点阵宋体

另外两张:
24*24点阵楷体        24*24点阵宋体

由于24点阵汉字库中没有中文字符(如“◆ □ ■ △ ▲”等等,因此显示失败。),同样,由于所用的汉字字库为GB2312,不在此字符集中的汉字显示失败。
解决方法:
1、使用其它能兼容更多汉字的字库;
2、在代码中跳过这些不能正常显示的中文字符。

fbutils.h文件添加的内容:
/* new add by Late Lee */
/* ascii code */
void put_string_ascii(int x, int y, char *s, unsigned colidx);
void put_string_center_ascii(int x, int y, char *s, unsigned colidx);
/* cineses character */
void put_string_hz(FILE *fp, int x, int y, unsigned char *s, unsigned colidx);
void put_string_center_hz(FILE *fp, int x, int y, unsigned char *s, unsigned colidx);
/* chineses character & ascii */
void put_font(FILE *fp, int x, int y, unsigned char *s, unsigned colidx);
void put_font_center(FILE *fp, int x, int y, unsigned char *s, unsigned colidx);
/* end of new add */
fbutils.c文件添加的内容:
/* new add by Late Lee 2011-05-30*/
//#define HZK24
#ifdef HZK24 /* 24 */
#include "ascii24.h"
#define ASCII_CODE ascii24
#define FONT_SIZE  24			/* size: 24 */
#else	/* 16 */
#include "ascii16.h"
#define ASCII_CODE ascii16
#define FONT_SIZE  16			/* size: 16 */
#endif


#define BYTES (FONT_SIZE/8)			/* for HZ: 3 bytes  2 bytes*/
#define BUF_SIZE (BYTES * FONT_SIZE)		/* HZ buff 3*24 = 72 bytes 2*16 = 32 bytes */

#define ASCII_BYTES (BYTES-1)		/* 2 1*/
#define ASCII_SIZE (FONT_SIZE * ASCII_BYTES)	/* ASCII buffer: 24*2 = 48 bytes 16 * 1 = 16 bytes */
#define ASCII_WIDTH (FONT_SIZE/2)		/* ASCII: 16*8 24*12 */

/* end here Late Lee*/


/*****************************************************************************
*           new add by Late Lee 2011-05-30
*****************************************************************************/

/**
 * __display_ascii - Display an ASCII code on touch screen
 * @x: Column
 * @y: Row
 * @ascii: Which ASCII code to display 
 * @colidx: Color index(?)
 * This routine display an ASCII code that stored in an array(eg, ASCII_CODE).
 * 16x8 ASCII code takes 1 byte, 24*12 ASCII code takes 2 bytes, so we need 
 * -ASCII_BYTES-.
 */
static void __display_ascii(int x, int y, char *ascii, unsigned colidx)
{
	int i, j, k;
	unsigned char *p_ascii;
	int offset;	
	
	offset = (*ascii - 0x20 ) * ASCII_SIZE; /* find the code in the array */
	p_ascii = ASCII_CODE + offset;

	for(i=0;i<FONT_SIZE;i++)
		for(j=0;j<ASCII_BYTES;j++)
			for(k=0;k<8;k++)
				if( p_ascii[i*ASCII_BYTES+j] & (0x80>>k) )
				//if(*( p_ascii + i*ASCII_BYTES+j) & (0x80>>k))
					pixel (x + j*8 + k, y + i, colidx);
}

/**
 * put_string_ascii - Display an ASCII string on touch screen
 * @x: Column
 * @y: Row
 * @s: Which string to display
 * @colidx: Color index
 */
void put_string_ascii(int x, int y, char *s, unsigned colidx)
{
	while (*s != 0) {
		__display_ascii(x, y, s, colidx);
		x += ASCII_WIDTH;
		s++;
	}
}

/* not test */
void put_string_center_ascii(int x, int y, char *s, unsigned colidx)
{
	size_t sl = strlen (s);
        put_string_ascii (x - (sl / 2) * ASCII_WIDTH,
                    y - FONT_SIZE / 2, s, colidx);
}

/**
 * __display_font_16 - Display a 16x16 (chinese) character on touch screen
 * @fp: File pointer points to HZK(ie, HZK16)
 * @x: Column
 * @y: Row
 * @font: Which (chinese) character to display
 * @colidx: Color index
 * This routine ONLY display 16*16 character.
 * Every character takes two bytes, we show the first 8 bits, then the second 8 bits,
 * then the whole world will be shown before us.
 */
static void __display_font_16 (FILE *fp, int x, int y, unsigned char *font, unsigned colidx)
{
	int i, j, k;
	unsigned char mat[BUF_SIZE]={0};
	int qh,wh;
	unsigned long offset;
	qh = *font   - 0xa0;
	wh = *(font+1) - 0xa0;
	offset = ( 94*(qh-1) + (wh-1) ) * BUF_SIZE; /* offset of the character in HZK */

	/* read it */
	fseek(fp,offset,SEEK_SET);
	fread(mat,BUF_SIZE,1,fp);

	/* show it */
	for(i=0;i<FONT_SIZE;i++)
		for(j=0;j<BYTES;j++)
			for(k=0;k<8;k++)
				if(mat [i*BYTES+j] & (0x80>>k))
					pixel (x + j*8 + k, y + i, colidx);
}

/**
 * __display_font_24 - Display a 24x24 (chinese) character on touch screen
 * @fp: File pointer points to HZK(ie, HZK24)
 * @x: Column
 * @y: Row
 * @font: Which (chinese) character to display
 * @colidx: Color index
 */
static void __display_font_24 (FILE *fp, int x, int y, unsigned char *font, unsigned colidx)
{
	unsigned int i, j;
	unsigned char mat[FONT_SIZE][BYTES]=0;
	int qh,wh;
	unsigned long offset;
	qh = *font   - 0xaf;
	wh = *(font+1) - 0xa0;
	offset = ( 94*(qh-1) + (wh-1) ) * BUF_SIZE;

	fseek(fp,offset,SEEK_SET);
	fread(mat,BUF_SIZE,1,fp);

	for(i=0;i<FONT_SIZE;i++)
		for(j=0;j<FONT_SIZE;j++)
			if( mat[j][i>>3] & (0x80>>(i&7)) )
			// if ( mat[j][i/8] & (0x80>>i%8) ) /* org */
				pixel (x + j, y + i, colidx);
}

/**
 * put_string_hz - Display a (chinese) character string on touch screen
 * @fp: File pointer points to HZK(ie, HZK24 or HZK16)
 * @x: Column
 * @y: Row
 * @s: Which string to display(must be 'unsigned char*')
 * @colidx: Color index
 */
void put_string_hz (FILE *fp, int x, int y, unsigned char *s, unsigned colidx)
{	
	while (*s != 0) {
		#ifdef HZK24
		__display_font_24 (fp, x, y, s, colidx); /* for HZK24 */
		#else
		__display_font_16 (fp, x, y, s, colidx);
		#endif
		x += FONT_SIZE;
		s += 2;	/* 2 bytes */
	}
}

/* not test */
void put_string_center_hz (FILE *fp, int x, int y, unsigned char *s, unsigned colidx)
{
	size_t sl = strlen ((char *)s);
        put_string_hz (fp, x - (sl/2) * FONT_SIZE, y - FONT_SIZE/2, s, colidx);
}

/**
 * put_font - Display an ASCII or/and (chinese) character string on touch screen
 * @fp: File pointer points to HZK(ie, HZK24 or HZK16)
 * @x: Column
 * @y: Row
 * @s: Which string to display
 * @colidx: Color index
 */
void put_font(FILE *fp, int x, int y, unsigned char *s, unsigned colidx)
{
	while (*s != 0) {
		if ( (*s>0xa0) && (*(s+1)>0xa0) ) {
			#ifdef HZK24
			__display_font_24 (fp, x, y, s, colidx); 	/* for HZK24 */
			#else
			__display_font_16 (fp, x, y, s, colidx);	/* for HZK16 */
			#endif
			x += FONT_SIZE;
			s += 2;	/* 2 bytes */
		} else {
			__display_ascii (x, y, (char *)s, colidx);
			x += ASCII_WIDTH;
			s++;	/* 1 byte */
		}
	}
}
/* not test */
void put_font_center(FILE *fp, int x, int y, unsigned char *s, unsigned colidx)
{
	size_t sl = strlen ((char *)s);
        put_font (fp, x - (sl/2) * 16, y - 16/2, s, colidx);
}