使用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的字库算不算侵权(这些东西都可以在网络下载)。

函数声明:

/* 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 */

测试代码(ts_test.c):

static FILE *fp;  /* HZK file pointer by Late Lee */#define HZK “HZK/HZK16″ /* HZK16 or HZK24K/HZK24S */static void refresh_screen ()

{

……

/* 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):

/* 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).

* 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”,我是很辛苦才找到的),交叉编译,在开发板上执行如下命令:

fb2png /dev/fb0 filename.png 5 800 600 24

实际中使用的命令为:

fb2png /dev/fb0 filename.png 5 240 320 16

效果图如下(由于图片已经有了本人的大名,故不打水印了):

效果图亦可以参见:

http://www.latelee.org/yetanothertest/display-hz-on-touch-screen.html

临时整理的工程目录压缩包:

能显示汉字的tslib压缩包

下一计划是ADC和TS驱动。

本文固定链接: http://www.latelee.org/embedded-linux/use-tslib-to-display-chinese-character.html

时间: 2024-11-25 15:23:53

使用Tslib在触摸屏上显示汉字【转】的相关文章

逆向工程第003篇:令计算器程序显示汉字(上)

一.前言 计算器(Calc.exe)程序在Windows系统中已经存在了很长的时间,也是我们十分常用的软件.但是一般来说,它所显示的都是阿拉伯数字,而且也没有字符显示的切换.这次我会以两篇文章来进行讨论如何让计算器程序显示汉字的数字.本篇来讨论修改的基本原理,下一篇则来讨论如何编程实现. 二.修改原理剖析 在我以前的很多文章中,始终在强调,Windows编程在很大程度上其实就是各种API函数的堆砌,谁掌握了更多的API函数,那么他往往就能够编写出功能齐全的强大软件.当然,编写出优秀的软件还由其它

用BadgeView在actionbar menu上显示提醒信息

有时候需要在actionbar menu上显示消息个数,所以可以用BadgeView来实现. 实现方法是获取actionbar menuitem的view,然后创建BadgeView.注意,通常只能在Optionsmenu创建完成之后去获取menuitem的view.我们可以在onCreate方法中延时1秒去处理. <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="ht

IOS 自定义UIBUTTON 直接拖个xib 就能在button上显示多行文本 并且添加了点击的效果

拖个button继承一下  几行代码 就搞定 自用效果还行 IOS 自定义UIBUTTON 直接拖个xib 就能在button上显示多行文本 并且添加了点击的效果,布布扣,bubuko.com

Eclipse或MyEclipse没有在java类文件上显示Spring图标的问题

Eclipse或MyEclipse没有在java类文件上显示接口图标的问题解决办法: 前: 后:

OpenCV获取摄像头视频并在MFC的Picture控件上显示

分为两步:OpenCV获取摄像头数据+图像在Picture上显示 第一步:OpenCV获取摄像头数据 参考:http://www.cnblogs.com/epirus/archive/2012/06/04/2535190.html http://blog.sina.com.cn/s/blog_6dbe9bdb0100nii7.html http://blog.csdn.net/augusdi/article/details/8762961 #include "stdafx.h" #in

使用seek()方法,将Hadoop文件系统中的一个文件在标准输出上显示两次

//使用seek()方法,将Hadoop文件系统中的一个文件在标准输出上显示两次 package com; import java.io.IOException; import java.net.URI; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FileSystem; import org.apac

placeholder怎样用IE和谷歌上显示统一内容

placeholder怎样用IE和谷歌上显示统一内容 击"开始"菜单中的"运行"命令,并在其对话框中输入"gpedit.msc"命令,进入"组策略"操作窗口. 在"组策略"左操作窗口中依次选择"用户配置→Windows设置→Internet Explorer维护→浏览器用户界面". 在"组策略"右操作窗口中双击"浏览器工具栏按钮",并在弹出的窗口中

在屏幕上显示日志的Android类库

Galgo是Android日志类库,用于在屏幕上显示应用的日志信息.这对于测试人员和开发人员非常有用,可以根据屏幕上的日志文件了解应用出现BUG时发生的事情. 可以定义屏幕上显示日志的背景颜色.文本颜色.文本大小和日志显示的行数. https://github.com/inaka/galgo public class ExampleActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceS

长姿势 教你在qq空间上显示iPhone6尾巴

下午刚午休完的时候,广州很多童鞋都感受到了震感,半青也感受到了,不仅如此,我还感受到了更大震感,那就是翻一下QQ空间动态,竟然看到有一位好友的尾巴竟然显示为“iPhone6”,顿时觉得该好友逼格太高了.但作为一名苹果资讯编辑,我觉得独乐乐不如众乐乐,下面就教大家如何在QQ空间上显示iPhone6小尾巴. 具体步骤如下: 第一步.打开手机QQ空间,点击[我的空间],然后再点击右上角的[个性化]选项. 第二步.把[我的手机标识]设置为[不显示].如果不记得把这个去掉,你就等着出糗吧.其次,不要被黄钻