u8glib中文显示
时间:10-02
整理:3721RD
点击:
在麦知项目中,使用u8glib+m2tklib负责在oled1.3上做显示,屏的控制器是sh1106。
根据MakerLab创客实验室的文章,可以显示中文,但是按照他的说法,将末尾的一位删掉,尽管可以持续显示后面的汉字,但实际上字会缺一小部分,而他的完整例子中的字体好像又没问题。
使用bdf2u8g生成一个汉字:
其数据格式,在u8g_font.c中有描述,如下:
这里面说明字体通用描述是17个字节。
对照生成的数据,可以得到每个字节的对应解释。
0 - format 0
13 - 字体外框宽度
13 - 字体外框高度
255 - 字体外框 x偏移 -1
254 - 字体外框 y偏移 254
...
实际上,生成字体数据的第2行,首位置的0是 第17字节数据: 字体x下降;若删掉每行的末尾数字,则 0 变成每个字的末尾像素,显示就为缺角。
第2行数据,0,11,12,24,12,0,255,0,128,68,160,34,192,128,128,87 是对字进行描述。
很好的看到,11是字宽, 12是字高, 24是字数据的尺寸,通过 (11+7)/8×12 ≈24, 后面的数据长度与此相符。因为数是除不尽的,所以末尾224,0xe0是高字节用来表示像素。
这次遇到的问题不算太难,被一行16个数据的表现形式迷惑。当然,主要原因还是对数据组织结构不了解,不知道每行的意义。 了解以后,自然很轻松的找到解决办法。
第32~127的部分,直接用命令生成:
c3.py代码如下,python2.7.10:
生成的文件如下:
在程序中引用:
汉字显示效果,结尾的像素是完整的,而且可以连续显示:
根据MakerLab创客实验室的文章,可以显示中文,但是按照他的说法,将末尾的一位删掉,尽管可以持续显示后面的汉字,但实际上字会缺一小部分,而他的完整例子中的字体好像又没问题。
使用bdf2u8g生成一个汉字:
- const u8g_fntpgm_uint8_t c11[47] U8G_SECTION(".progmem.c11") = {
- 0,13,13,255,254,0,0,0,0,0,136,136,0,11,255,0,
- 0,11,12,24,12,0,255,0,128,68,160,34,192,128,128,87,
- 224,20,32,39,224,36,32,199,224,68,32,68,32,68,224};
其数据格式,在u8g_font.c中有描述,如下:
- /*
- ... instead the fields of the font data structure are accessed directly by offset
- font information
- offset
- 0 font format
- 1 FONTBOUNDINGBOX width unsigned
- 2 FONTBOUNDINGBOX height unsigned
- 3 FONTBOUNDINGBOX x-offset signed
- 4 FONTBOUNDINGBOX y-offset signed
- 5 capital A height unsigned
- 6 start 'A'
- 8 start 'a'
- 10 encoding start
- 11 encoding end
- 12 descent 'g' negative: below baseline
- 13 font max ascent
- 14 font min decent negative: below baseline
- 15 font xascent
- 16 font xdecent negative: below baseline
-
- */
这里面说明字体通用描述是17个字节。
对照生成的数据,可以得到每个字节的对应解释。
0 - format 0
13 - 字体外框宽度
13 - 字体外框高度
255 - 字体外框 x偏移 -1
254 - 字体外框 y偏移 254
...
实际上,生成字体数据的第2行,首位置的0是 第17字节数据: 字体x下降;若删掉每行的末尾数字,则 0 变成每个字的末尾像素,显示就为缺角。
第2行数据,0,11,12,24,12,0,255,0,128,68,160,34,192,128,128,87 是对字进行描述。
- /*
- format 0
- glyph information
- offset
- 0 BBX width unsigned
- 1 BBX height unsigned
- 2 data size unsigned (BBX width + 7)/8 * BBX height
- 3 DWIDTH signed
- 4 BBX xoffset signed
- 5 BBX yoffset signed
- */
很好的看到,11是字宽, 12是字高, 24是字数据的尺寸,通过 (11+7)/8×12 ≈24, 后面的数据长度与此相符。因为数是除不尽的,所以末尾224,0xe0是高字节用来表示像素。
这次遇到的问题不算太难,被一行16个数据的表现形式迷惑。当然,主要原因还是对数据组织结构不了解,不知道每行的意义。 了解以后,自然很轻松的找到解决办法。
第32~127的部分,直接用命令生成:
- bdf2u8g.exe -b 32 -e 127 abc-12.bdf abc-12 abc-12.c
- 确 786E
- 定 5B9A
- 取 53D6
- 消 6D88
- G:\17\u>c3 a.txt
c3.py代码如下,python2.7.10:
- # encoding: utf-8
- import os
- import sys
- import re
- def get_c(list):
- # a 是16进制
- # font = 'unifont'
- #font = 'fireflyR11'
- font = 'abc-12'
- command = "bdf2u8g.exe -b {b} -e {e} {sub} %s.bdf c11 {out}" % font
-
- word, code = list # 得到字,编码
- out_file = 'c11_%s.c' % code # 输出文件名后缀, 前缀默认为c11
-
- code = int(code, 16)
- page = code / 0x80 # 页数
- begin = code & 0x00ff
- end = begin
-
- sub_command = '-%s %s'
-
- if begin > 0x7F: # 使用-l 还是-u
- sub_command = sub_command % ('u', page)
- else:
- sub_command = sub_command % ('l', page)
-
- command = command.format(b=begin, e=end, sub=sub_command, out=out_file)
-
- print(command)
- os.system(command) # 执行命令
-
- # 读取.c文件进行合并
- # 提取{}中内容
- # 正则, \{([^\}]+)\}
- if os.path.exists(out_file):
- lines = open(out_file).read()
- pattern = r'\{([^\}]+)\}'
- m = re.search(pattern, lines)
-
- if m:
- return word, m.groups()[0].strip()
- else:
- return None
- def main():
- if len(sys.argv) != 2:
- print(u'请输入汉字txt')
- return
- # 打开txt
- if not os.path.exists(sys.argv[1]):
- print(u"文件 %s 不存在" % sys.argv[1])
- return
- # 读取行
- head = ''
- # result = {}
-
- lines = open(sys.argv[1]).readlines()
- out_file = os.path.splitext(sys.argv[1])[0]+'_cvt.c'
-
- No = 0x80;
-
- try:
- f = open(out_file, 'w')
- f.write('#include "u8g.h" \nconst u8g_fntpgm_uint8_t c11[55] U8G_SECTION(".progmem.c11") = {\n')
- write_head = True
- first_word = True
- for i, line in enumerate(lines):
- if line:
- line = line.split()
- list = [line[0], line[1]] # ['\xe5\xae\xa2', '5BA2']
- w, c = get_c(list)
- c = c.split()
- del c[0] # 删掉第1行
- pos_first = c[0].index(',')
- c[0] = c[0][pos_first+1:] # 删掉第1个零,字体结构的第17字节
- c[1] = c[1] + ',' # 补充末尾逗号
- # result[w] = c
-
- # 写出到文件
- f.write('// ' + line[0] + '\t' + line[1] + '\t\t' + hex(0x80 + i) + '\n')
- for v in c:
- f.write(v + '\n')
-
- f.write('};')
- print(u'写%s文件成功。' % out_file)
- except IOError:
- print(u'写%s文件失败。' % out_file)
- f.close()
-
-
- if __name__ == '__main__':
- main()
生成的文件如下:
// 确 786E 0x84
- <blockquote>11,11,22,12,0,255,2,0,243,192,36,64,43,224,114,
在程序中引用:
- // 第1行:状态, 档位
- const char *stage = "\x80\x81";
- const char *power_level = "";
- M2_LABELPTR(el_home_stage, "f0", &stage); // 显示工作阶段
汉字显示效果,结尾的像素是完整的,而且可以连续显示: