http://blog.csdn.net/subfate/article/details/6444578

起因:

早在阅读tslib源代码时就注意到里面有font_8x8.c和font_8x16.c两个文件(后来才得知,它们来自Linux内核,具体目录是./drivers/video/console),它们包含了在屏幕上显示所需的所有字符(当然,是可打印字符),由此也看了一下tslib显示字符的代码。对将来在触摸屏上显示汉字有所帮助,——这是后话,暂且按下不提。

上面所说的字符当然是ASCII码了,这种编码学过计算机的人可能会很熟悉,就不多讲了。本文所述者,就是通过ASCII码字库文件(网上有下载)和上面提到的其中之一的文件在终端上显示ASCII字符。这也为研究汉字显示打下基础(此为假话,写文章及做作所需也,实际上本文作者是先研究汉字显示再研究ASCII码显示的,勿模仿,切切)。

本文中使用的字库是8x16,每个字符占用内存空间为16字节(后面不再提及),文中显示字符所做工作有下面几步(显示汉字也差不多,当然,这又是后话 ):

1、打开字库文件(似乎是废话);

2、计算出要打印的字符在字库文件中的偏移量(亦即网上所说的“寻址”);

3、将这个偏移地址的数据(16字节)读取缓冲区中;

4、显示这个缓冲区,为1者打印,为0者留空。(由于是在终端上显示,因此,可以使用如“#”、“*”等字符代替。)

先说说如何找到某个字符在字库文件中的偏移量。字库里的字符排序是符合ASCII码顺序的,而每个字符占16字节,因此,将要打印的字符与16相乘,便得到这个字符在字库中的位置了,这个位置之后的16个字节的数据,就是这个字符了。比如大写字母“A”,十六进制是0x41(“A”还是十进制的65、八进制的101,其实都是一回事),它与0x10(十进制的16)相乘,得到0x410(计算机中使用十六进制十分方便,对于某些试题要求计算出某地址的十进制,我表示不理解,既不直观,又不方便,还容易出错)。使用十六进制编辑器(用UE相信会更方便些)查看这个偏移量,会发现有如下数据:

$ hexdump -C ../HZK/ASC16 | grep 410

00000410  00 00 10 38 6c c6 c6 fe  c6 c6 c6 c6 00 00 00 00  |...8l...........|

所谓的字库,里面就是一些二进制数据。我们看看上面得到“A”的16个字节数据显示效果是怎样的。将上面的十六进制数据按二进制输出,一个字节一行,共占16行,如下:

00000000

00000000

00010000

00111000

01101100

11000110

11000110

11111110

11000110

11000110

11000110

11000110

00000000

00000000

00000000

00000000

不直观,将出现0的地方留空,则变成如下形状(受网页影响,为美观起见进行调整,虽非实际中二进制所示,但形状是一致的):

                

                

      1        

    111      

  11  11    

11      11  

11      11  

1111111  

11      11  

11      11  

11      11  

11      11  

                

                

                

                

上面的便是传说中的“A”了。

下面就用代码读取字库信息,并显示出来。完整代码如下:

/***************************************************

 源代码文件编码:ANSI

 测试环境编码:zh_CN.UTF-8、zh_CN.gd2312

 * ************************************************/



#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>



#ifdef DEBUG

#define debug(fmt, ...) printf(fmt, #__VA_ARGS__)

#else

#define debug(fmt, ...)

#endif





void display_font_ascii(char *asc)

{

        int i, j;

        debug("=================/n");

        ;i<;i++)

        {

                ;j<;j++)

                {

                        /* 逐位相与,为1者打印“*”,否则打印空格 */

                        if(asc[i] & (0x80>>j))

                                printf("*");

                        else

                                printf(" ");

                }

                printf("/n");

        }

        debug("=================/n");

}



int main()

{

        int i;

        unsigned char *p;

        unsigned char asciicode[] = "Ab";

        unsigned long offset;

        FILE *asc;

        ];



        if((asc=fopen("ASC16","rb"))==NULL)

        {

                perror("Can't Open ASC16");

                exit();

        }



         /* ASCII字库文件 */

        ; i < ; i++)

        {

                debug("%c %x/n", asciicode[i], asciicode[i]); /* 打印数值 */

                offset = asciicode[i]*;

                debug("offset: %x/n", offset); /* 打印偏移量 */

                fseek(asc,offset,SEEK_SET);

                fread(ascii,,,asc);              /* 读取16字节 */

                display_font_ascii(ascii);        /* 显示 */

        }

        fclose(asc);



        ;

}

由于是示意性代码,不必纠结于代码优化、代码风格等等问题。效果(同样进行了调整)如下:

$ ./a.out             

                

                

      *        

    ***      

  **  **    

**      **  

**      **  

*******  

**      **  

**      **  

**      **  

**      **  

                

                

                

                

                

                

***          

  **          

  **          

  ****      

  **  **    

  **    **  

  **    **  

  **    **  

  **    **  

  *****    

                

                

                

                


还有另一种方法,不读取字库,而是将所有的字符存放于某个数组中,比如像font_8x16.c文件中的fontdata_8x16数组。这里假设数组为ascii_code,那么,上面的代码只需修改一小部分,如下:

 for (i = 0; i < sizeof(asciicode)-1; i++)

 {

  debug("%c %x/n", asciicode[i], asciicode[i]);

  offset = asciicode[i]* 16; // 寻址

  p = ascii_code+offset;    // 查找字符在ascii_code数组中的偏移量

  debug("offset: %x/n", offset);

  display_font_ascii(p);

 }

效果是一样的,所不同的是,前一种方法需要读取字库文件,后一种方法直接在内存中读取,完整的ASCII码占用空间为4KB。不过,ASCII中可打印的字符共96个(经过认真数那些可打印的字符,发现实际上是95个(即32号到126号),这里将127号算上了,具体的请搜索一下ASCII),占用空间为96*16,即1536字节。由于前面0x20(即32)个字符在显示中没有用到,因此是可以去掉的,这样一来,寻址方式又稍有不同,如下:

 for (i = 0; i < sizeof(asciicode)-1; i++)

 {

  debug("%c %x/n", asciicode[i], asciicode[i]);

  offset = (asciicode[i] - 0x20 )* 16; // 寻址

  p = ascii_code+offset;    // 查找字符在ascii_code数组中的偏移量

  debug("offset: %x/n", offset);

  display_font_ascii(p);

 }

由于文中涉及知识、代码、字库文件都可以在网络上找到,因此文中就不提供下载了。

资料:

1、ASCII码字库,有多种形式,如8*16、8*12,名称为ASC12、ASC16,搜索一下就能找到。

2、“字库数组”,可以在Linux内核源代码的./drivers/video/console目录下找到很多相关代码文件,如font_8x8.c、font_8x16.c、font_sun8x16.c等等。像font_8x16.c文件,代码中说是由cpi2fnt这个东西产生的,但搜索一下,没什么介绍,英文的又不想去看,对这个东西也就不了解了。

3、可以搜索一下字库生成工具,用这些工具可以生成需要的字库。

点阵字体显示系列之一:ASCII码字库的显示的更多相关文章

  1. LCD显示——点阵字体

    Bitmap font 点阵字体是把每一个字符都分成16×16或24×24个点,然后用每个点的虚实来表示字符的轮廓. 点阵字体优点是显示速度快,不像矢量字体需要计算:其最大的缺点是不能放大,一旦放大后 ...

  2. 【STM32H7教程】第52章 STM32H7的LTDC应用之点阵字体和字符编码(重要)

    完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第52章       STM32H7的LTDC应用之点阵字体和 ...

  3. Windows7 系统 CMD命令行,点阵字体不能改变大小以及中文乱码的问题

    之前装了oracle 11g后,发现开机速度竟然奇葩的达到了3分钟.经过旁边大神指点,说是因为oracle某个(具体不清楚)服务,在断网的时候会不断的ping网络,导致速度变慢.然后就关服务呗,然后一 ...

  4. 【MM系列】SAP SAP库龄报表逻辑理解

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP SAP库龄报表逻辑理解   ...

  5. 一点理解之 CmBacktrace: ARM Cortex-M 系列 MCU 错误追踪库

    @2019-02-14 [小记] CmBacktrace: ARM Cortex-M 系列 MCU 错误追踪库,用来将单片机故障状态寄存器值翻译出来输出至终端上以便排错 CmBacktrace: AR ...

  6. 【C++自我精讲】基础系列五 隐式转换和显示转换

    [C++自我精讲]基础系列五 隐式转换和显示转换 0 前言 1)C++的类型转换分为两种,一种为隐式转换,另一种为显式转换. 2)C++中应该尽量不要使用转换,尽量使用显式转换来代替隐式转换. 1 隐 ...

  7. 不显示Zetero导出的文献库中的部分内容

    不显示Zetero导出的文献库中的部分内容 Zetero作为文献管理软件,收集到的参考文献的相关信息(域fields)比较齐全.文章或书籍的引用中仅仅只用到了其中的一部分,如作者.发表年.题名.期刊( ...

  8. 【ABAP系列】SAP 业务界面同时显示KEY和文本

      公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP 业务界面同时显示KEY和 ...

  9. 【ABAP系列】SAP ABAP实现LOG显示的方法

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP实现LOG显示的 ...

随机推荐

  1. 最简单的PHP开发环境搭建

    近期发现一个非常easy的,适合刚開始学习的人的PHP开发环境,整个环境仅仅有三样东东,PHP ,APACHE , MYSQL可是对于初学PHP的人来说,己经足够了. 假设有兴趣的话能够直接去百度PN ...

  2. JS实现图片无缝滚动特效;附addEventListener()方法、offsetLeft和offsetWidth属性。

    一:html部分 <body> <input id="btn1" type="button" value="向左"> ...

  3. 九度OJ 1023:EXCEL排序 (排序)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:14605 解决:3307 题目描述:     Excel可以对一组纪录按任意指定列排序.现请你编写程序实现类似功能.     对每个测试用例 ...

  4. sap crm 常用表

    [转自 http://blog.csdn.net/zhongguomao/article/details/6714616] SAP CRM 参数文件集目标组常用表: CRMD_MKTTG_TG_T C ...

  5. Java for LeetCode 111 Minimum Depth of Binary Tree

    Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the shor ...

  6. Could not find JSON in http://updates.jenkins-ci.org/update-center.json?id=default&version=2.7.4

    14-Sep-2016 21:43:58.241 INFO [Download metadata thread] hudson.model.AsyncPeriodicWork$1.run Finish ...

  7. matlab之text()函数

    text()函数用来给图加上说明性文字. 格式:text(x,y,'txt') 或者:text(x,y,'txt','color','k') x,y是位置 txt是说明文字,如果说明性文字是数字,则这 ...

  8. 我所理解的RESTful Web API [设计篇]【转】

    原文:http://www.cnblogs.com/artech/p/restful-web-api-02.html <我所理解的RESTful Web API [Web标准篇]>Web服 ...

  9. babel-runtime 和 babel-polyfill

    Babel 默认只转换新的 JavaScript 语法 https://excaliburhan.com/post/babel-preset-and-plugins.html babel-plugin ...

  10. tomcat 6.0 安装及配置

    前提:安装并配置好jdk 1.免安装版存放目录:D:\01Install\tomcat