汉字自定义点阵语句

在一些特殊情况下,比如少量使用一些生僻字显示姓名,这样如果使用全部GBK汉字库会占用大量的flash内存,况且还有少量生僻字连GBK也不包含;为此我们设置了由串口传入汉字点阵字符串,然后通过语句写入flash字库的方案。

语句介绍详见:fontdot

在使用fontdot语句之前,我们需要了解以下概念:

一、flash是按4K的数据块进行擦除的

需要更改数据库,必然要对存储数据库的flash进行写入操作,而写入则必须先擦除(所谓擦除是指将存储器由0擦除成1,这个擦除是按4K字节的一个数据块整体操作的);而存储器由1写成0则可以按字节进行操作;

因此,在写入第一个汉字点阵时,必须要擦除存储器,而写入第二个汉字在同一存储区时,则不能擦除存储器;

二、需要根据汉字点阵确定4K存储边界

首先,需要了解各点阵汉字的大小以及在汉字库中的位置计算规则:

点阵大小 存储大小(字节) 4K存储字数
16 32 128
24 72 56.89
32 128 32
48 288 14.22
64 512 8

无论是GB2312还是GBK,对于 内码AAA1~AFFE这个区间全部点阵为空,前面已经在这个区域构建图标体系,同样,自定义汉字也可以使用该区域;

具体区域:

区码 汉字内码
AA AAA1~AAFE
AB ABA1~ABFE
AC ACA1~ACFE
AD ADA1~ADFE
AE AEA1~AEFE
AF AFA1~AFFE
//GB2312:
addr=((q-161)*94+(w-161))*size;

//GBK:
addr=((q-129)*191+(w-64))*size;

//其中q为汉字的区码,也就是汉字内码高8位
//其中w为汉字的位码,也就是汉字内码低8位
//size为汉字点阵存储大小,详见上表
计算示例:

使用16点阵GBK2312汉字的AA区域,计算数据块:

addr=((0xaa-161)*94+(0xa1-161))*32
    =27072
//而27072/4096=6.609  
//因此最佳存储位置应该是汉字库的第7个数据块
//起始地址:7*4096=28672;
//结束地址:28672+4095=32767;

//28672对应的汉字内码:
//设 x=q-161;  y=w-161; 
//按汉字内码规则要求 x<94; y<94;
x*94+y=896;  //28672/32=896
//因此:
x=896/94=9.531914894 取整为9
y=896%94=50
则:q=161+9=170=0xAA;
w=161+50=211=0xD3

//同理:32768对应的汉字为:
32768/32=1024
1024/94=10...(余)84
因此:q=161+10=171=0xAB;
w=161+84=245=0xF5

//因此得出结论:第7个数据块对应汉字为:
AAD3 ~ ABF4
//由于AB跨区,因此实际区域:
AAD3~AAFE ABA1~ABF5

//因此,在写AAD3的时候,需要擦除存储区,而后面的不需要

总结:

GB2312字库各点阵使用AAA1 附近数据块对应汉字内码:

点阵 块编号 起始地址 结束地址 内码范围
16 7 28672 32767 AAD3~AAFE ABA1~ABF5
24 15 61440 65535 AAA9~AAE1
32 27 110592 114687 AAB3~AAD3
48 60 245760 249855 AAA9~AAB6
64 106 434176 438271 AAA3~AAAB

汉字点阵算法

汉字点阵,是按行计算的,以上图的32X32点阵汉字为例,一行4个字节,对应点阵关系如下:

1字节[bit7]...[bit0] 2字节[bit7]...[bit0] ......4字节[bit7]...[bit0]

因此,按照上图点阵逐行转换:

第一行和第二行无显示点,都是:

[1]:0x00 0x00 0x00 0x00 
[2]:0x00 0x00 0x00 0x00

第三行有两个点:

[3]:0x08 0x00 0x00 0x20

第四行为:

[4]:0x0F 0xFF 0xFF 0xF8

......

因此最后全部点数据为:

0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x08,0x00,0x00,0x20,
0x0F,0xFF,0xFF,0xF8,
0x0C,0x00,0x00,0x30,
0x0C,0x00,0x00,0x30,
0x0C,0x00,0x03,0x30,
0x0C,0xFF,0xFF,0xB0,
0x0C,0x01,0x80,0x30,
0x0C,0x01,0x80,0x30,
0x0C,0x01,0x80,0x30,
0x0C,0x01,0x80,0x30,
0x0C,0x01,0x80,0x30,
0x0C,0x01,0x84,0x30,
0x0C,0x7F,0xFE,0x30,
0x0C,0x01,0x80,0x30,
0x0C,0x01,0xA0,0x30,
0x0C,0x01,0x98,0x30,
0x0C,0x01,0x8C,0x30,
0x0C,0x01,0x8E,0x30,
0x0C,0x01,0x84,0x30,
0x0C,0x01,0x84,0x30,
0x0C,0x01,0x83,0x30,
0x0D,0xFF,0xFF,0xB0,
0x0C,0x00,0x00,0x30,
0x0C,0x00,0x00,0x30,
0x0C,0x00,0x00,0x30,
0x0F,0xFF,0xFF,0xF0,
0x0C,0x00,0x00,0x30,
0x0C,0x00,0x00,0x30,
0x08,0x00,0x00,0x00,
0x00,0x00,0x00,0x00