[位运算简单原理] 用点阵显示汉字

参考:HZK16汉字16*16点阵字库的使用及示例程序
今天课上老师让我们写一个用16*16的点阵字库显示汉字的程序,给了一个HZK16字库。但是奈何本人太过愚钝,上课时候没怎么听懂,只能在网上借鉴了大神的博客。

我们想要显示一个汉字的16×16的样子,就需要先明白这个原理。
在HZK16字库中,用二进制的形式存储了很多汉字的形状。一个汉字使用32个字节储存。其中0代表空白(白色方块),1代表有笔画/墨水的黑色方块。
啊字

比如这个“啊”字。
一字节(byte)对应着8位(bit),8位中的每一位都代表着一个0或者1,这就是计算机最底层的存储。
也就是说,一个字节能够保存的数字,换算成16进制也就是0x00-0xFF。
上面说了,每一个0或者1都分别代表着空白或者有笔画,所以,我们用一个字节(byte)可以存储8个方块。
16×16就可以被分割为16×2×8,也就是32个字节。
比如第一行,我们把白色方块变成0,黑色方块变成1,8个为一组分开,将会是这样:
0b00000000=0x00;0b00000100=0x04
第二行,就是这样:
0b00101111=0x2F;0b01111110=0x7E
所以存储这个“啊”字的32个字节分别是:00 04 2F 7E ……

我们想要打印这个汉字,只要找到这32个字节,然后分别将每一个位置上的0或者1用别的形式打印出来。
那么怎么将一个二进制数字的每一位都取出来呢?这就需要运用位运算。

1
flag = buffer[k*2+j]&key[i];

也就是这一行。
比如0x2F
二进制形式是0b00101111,想要取出他每一位上的数字,分别和0b10000000(也就是十进制的128,十六进制的0x80)、0x40,0x20…进行&运算,就可以得到结果。

1
2
3
unsigned char key[8] = {
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01
};

这也是最开始定义key数组的原因。

那么怎么在字库中找到这个汉字的位置呢?

老师的PPT中给了一个字形码计算的公式:word[1]-0xA1+94×(word[0]-0xb0)+15×94
这个公式其实等价于:(94×(区码-1)+(位码-1))
如果有对区码和位码的概念不清楚的同学可以参考上面的博客。

但是这个公式并不能用来找到一个汉字在字库中的位置,需要乘以32,可能是因为一个汉字用32个字节显示。

1
2
unsigned int offset = (94*(unsigned int)(word[0]-0xa1)+(word[1]-0xa1))*32;
unsigned int offset2 = (word[1]-0xA1+94*(word[0]-0xb0)+15*94)*32;

这两种都是正确的。

最后,注意字库文件应该用二进制形式打开。

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2020-2024 Rye
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信