使用Tslib在触摸屏上显示汉字【转】
转自:http://www.latelee.org/embedded-linux/use-tslib-to-display-chinese-character.html
终于到了在触摸屏上显示汉字了,真正写代码、测试的时间是1天,在此之前的一切准备、学习花费约2周到3周时间。而为了获取触摸屏上显示的图像,花费约2天。由于网络驱动已经接近于放弃状态,NFS用不了,只好用U盘来回复制(即使没有耐心也必须有耐心了)。明明在内核中选择了支持NTFS格式的读写,但却不能将开发板上的文件复制到U盘,而用另一个FAT32格式的另一牌子的U盘,开发板死活认不出来,网上的资料说要修改代码,我又懒得去改。无奈之下,只好格式化那个NTFS的U盘,结果,这篇文章拖到现在才发表。
郑重说明:
本文作者在本文及前面的文章中没有提及作者的工作内容、工作时间、业余时间及业余生活,因为在这些文章中涉及那些工作、生活内容是不明智的。这些文章并没有任何迹象表明作者没有工作、没有业余生活,也并没有表明作者只生活在写代码中。
免责声明:
本文是作者在研究过程中的一篇文章,本着互联网共享、自由(free,应该不是“免费”)之精神发布于此。本文使用的是Tslib中的代码,并在此基础上添加自己的代码,关于Tslib,作者已经写过很多篇相关的文章了,这里公布的仅仅是自己添加的代码。作者对文中代码没有任何义务,仅因为Tslib使用GPL协议,本文作者必须使用这个协议。作者才疏学浅,孤陋寡闻,能力有限,文中错误的地方,欢迎在文后留言,趁作者还有激情研究之时,大家一直探讨,共同学习,天天向上。
再声明一点,本文作者在S3C2440芯片的开发板上,使用最新下载的tslib,使用汉字字库HZK16、HZK24*,通过自己写的代码,在开发板自带的触摸屏上显示汉字。但是,并没有在其它的测试环境、平台下进行测试。
关于汉字显示的算法(其实没啥算法)、步骤已经在前面的文章说了很多了,此处不再提及。
由于还没有对autotool进行研究,而Tslib又使用这个工具管理代码,因此不懂如何添加新文件,如果让新文件也能编译。只好在原来的原来的文件中添加代码了。添加的代码的函数声明在fbutils.h中,函数定义在fbutils.c文件中,测试代码在ts_test.c中。
代码修改了约三次,基本上都是一些结构上的调整,就不说那些体面的话了。至于真正改动之处,只在最底层的显示字符的代码修改了几个地方,就是将原来的乘法改为移位,而对其它一些地方的乘法及移位测试时,发现没什么区别,因此保留乘法。举一例,如
offset = (*ascii – 0x20 ) * 16;
就没有改为
offset = (*ascii – 0x20 ) << 4;
前者更能让人明白这里的ASCII字符在字库数组中占用16字节,而左移4位,的确让人不知道有什么含义。
已知bug:
1、不在GB2312范围之内的汉字不能正常显示——这是废话,正如在en_US字符集下显示中文一样。
2、UCDOS的HZK24*系列字库文件没有中文字符,像“◆ □ ■ △ ▲”等在16点阵下显示正常,而在24点阵中显示失败(乱码或其它汉字),网上找不到包括完整的中文字符的字库,另外,不知道使用UCDOS的字库算不算侵权(这些东西都可以在网络下载)。
函数声明:
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 */
测试代码(ts_test.c):
{
……
/* just a test */
unsigned char incode[] = “▲!ADC■测镕试◎示例”; // 注:“镕”字不在GB2312范围之内,不能正常显示。
int y = yres/4+50;
put_string_ascii(0, y, “Powered by Late Lee”, 9);
put_string_hz(fp, 0, y+30, “波神留我看斜阳听取蛙声一片”, 2);
put_font(fp, 0, y+56, incode, 5);
/* end of the test */
……
}
关键的代码(fbutils.c):
#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).
* 16×8 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 16×16 (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 24×24 (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);
}
关于截图:
使用fb2png(可通过google搜索“fb2png”,我是很辛苦才找到的),交叉编译,在开发板上执行如下命令:
实际中使用的命令为:
效果图如下(由于图片已经有了本人的大名,故不打水印了):


效果图亦可以参见:
http://www.latelee.org/yetanothertest/display-hz-on-touch-screen.html
临时整理的工程目录压缩包:
下一计划是ADC和TS驱动。
本文固定链接: http://www.latelee.org/embedded-linux/use-tslib-to-display-chinese-character.html
使用Tslib在触摸屏上显示汉字【转】的更多相关文章
- PCB上 如何显示 汉字
原理图上有汉字,那如何在PCB上显示汉子呢 ? 而不至于显示乱码 按如下操作 ,双击乱码 ,进入设置模式 设置好后,显示的字体样式.
- 【Qt开发】【ARM-Linux开发】 QT在ARM上显示字体的问题
在PC机上利用QT开发的应用程序在设置字体时,在PC上运行,可根据自己的设置,字体随之变大或变小.而移植到ARM上运行时发现,显示字体与所设置的字体不用,字体普遍偏小.经过上网搜索发现,是环境变量字库 ...
- 逆向project第004篇:令计算器程序显示汉字(下)
一.前言 钩子技术是一项很有有用价值的技术.在Windows下HOOK技术的方法比較多,使用比較灵活,常见的应用层的HOOK方法有Inline HOOK(详见<反病毒攻防研究第012篇:利用In ...
- 2.数码相框-编码(ASCII/GB2312/Unicode)介绍,并使LCD显示汉字字符(2)
在上章-学习了数码相框的框架分析(1)了 本章主要内容如下: 1)熟悉ASCII/GB2312/Unicode编码 2)写应用程序,使LCD显示汉字和字符 大家都知道,数据传输的是二进制,而字符和汉字 ...
- Android上显示生僻字的方法
安卓5.0+是可以显示所有(8万多个)Unicode汉字的,本文介绍显示生僻汉字的方法,这个方法也适用于其它特殊字符. Unicode值在0xFFFF以下的(2万多个简体.繁体)汉字早已被广泛支持,所 ...
- easyui页面上显示和PL/SQL编码问题
在页面上,只需要显示人们看的懂的文字就行,但是在数据库里面就不一定了,一般情况下,在数据库里面存字母,数字等除了汉字以外的字符,存汉字有个问题,就是有时候不同oracle数据库的客户端会出现乱码问题: ...
- activiti部署到linux后流程图不显示汉字的问题
linux和windows的字体文件一般是不一样的,默认情况下,linux的java7中一般不支持中文,activiti的动态流程图中的汉字需要java调用汉字的字库,这里需要配置一下java的汉字字 ...
- JS文件中的中文在网页上显示为乱码解决方法
转自:http://www.pc6.com/infoview/Article_63835.html 如果JS文件中的中文在网页上显示为乱码,不妨采用本文章中的方法来试一试,或许能解决使你很头疼的问题. ...
- emwin显示汉字使用vs studio仿真和使用keil编写烧录的不同
我用emwin是在新唐的开发板上练习的,所有我就去官网下了开发板的资料,别的开发板应该也有对应的资料,这些软件网上应该很容易搜得到 然后用GUIBuilder构建一个界面,再用FontArchitec ...
随机推荐
- python 自动化-"Elements not visible"
一,今天试着跑一个多乘客下单的python脚本, 总是遇到 Elements not visible 或者 not clickable的错误 解决方法: 1. 首先观察脚本运行时, 报错的那个元素 ...
- python基础训练营02
任务二 时长:2天 1. 列表 a. 标志 b. 基本操作(创建,append( ),pop( ) ,del( ), 拷贝) c. 列表相关方法 2. 元组 a. 标志 b. 基本操作(创建及不可变性 ...
- linux备忘录-例行性工作排程 (crontab)
例行性工作排程 例行性工作排程分为两类 at at是只执行一次就结束的指令安排.要想使用at,必须要有atd服务的支持. crontab crontab是每隔一段时间自动执行的指令安排.crontab ...
- c# 复选下拉框
引用dll: http://pan.baidu.com/s/1qXa97UO 自定义类: namespace TMI_S { /// <summary> /// 功能描述:自定义多选下拉框 ...
- Spring MVC温故而知新 – 参数绑定、转发与重定向、异常处理、拦截器
请求参数绑定 当用户发送请求时,根据Spring MVC的请求处理流程,前端控制器会请求处理器映射器返回一个处理器,然后请求处理器适配器之心相应的处理器,此时处理器映射器会调用Spring Mvc 提 ...
- delphi如何模块内部获得自身路径ExtractFilePath和paramstr(0)
如何模块内部获得自身路径?Exe程序:DLL程序: ExtractFilePath(Application.ExeName) GetCurrentDir TIniFile.Create(GetCurr ...
- oracle分区技术提高查询效率
概述: 当表中的数据量不断增大,查询数据的速度就会变慢,应用程序的性能就会下降,这时就应该考虑对表进行分区.表进行分区后,逻辑上表仍然是一张完整的表,只是将表中的数据在物理上存放到多个表空间(物理文件 ...
- Netscaler重置密码的方法
Netscaler重置密码的方法 http://blog.51cto.com/caojin/1898401 有时候我们会碰到忘记Netscaler的密码,或接手别人的设备而不知道密码的情况.在这种情况 ...
- (补漏)Springboot2.0 集成shiro权限管理
原文Springboot2.0 集成shiro权限管理 一.关于停止使用外键. 原本集成shiro建立用户.角色.权限表的时候使用了外键,系统自动创建其中两个关联表,用@JoinTable.看起来省事 ...
- [洛谷P3254]圆桌问题
题目大意:有$m$个单位,每个单位有$r_i$个代表,有$n$张餐桌,每张餐桌可容纳$c_i$个代表.要求同一个单位的代表不在同一个餐桌就餐.若可以,输出$1$以及其中一种方案,否则输出$0$ 题解: ...