PCtoLCD2002 生成字模转换为字库 .h文件

打开字体取模软件PCtoLCD2002.exe,选项进行如下设置:
PCtoLCD2002 生成字模转换为字库 .h文件_第1张图片
然后在下方打入需要取的汉字,点击生成字模,生成字模,存储字模的txt文件。
PCtoLCD2002 生成字模转换为字库 .h文件_第2张图片

使用如下python代码, 将生成字模转换为字库的.h文件
txt与python文件放在同一目录下

# 说明:
# 每次生成字库的字数限制: 100及以内
# 取模字高/宽限制: 3-256
# 取模字高宽比任意
import codecs
import os
import chardet


# 获取文件编码类型
def get_encoding(file):
    # 二进制方式读取,获取字节数据,检测类型
    with open(file, 'rb') as f:
        return chardet.detect(f.read())['encoding']


# 删除列表多余元素
def remove_list_items(list_name):
    while ' ' in list_name:
        list_name.remove(' ')
    while '\n' in list_name:
        list_name.remove('\n')
    while '(' in list_name:
        list_name.remove('(')
    while ')' in list_name:
        list_name.remove(')')


# 获取每个汉字所用的行数
def recognize_line_nums(file_list_name):
    lines_num_of_index = file_list_name.index('\n')
    for a in range(lines_num_of_index, len(file_list_name)):
        if list(file_list_name[a + 1])[-2] == '/':
            return a - lines_num_of_index + 1
            break


# 获取需转换的文件
def get_file_path():
    dir_list = os.listdir('./')
    txt_list = []
    for a in dir_list:
        if a[-4:] == '.txt':
            txt_list.append(a)
    for b in txt_list:
        print(txt_list.index(b) + 1, '\t', b)
    choice = int(input('Choose file to generate.'))
    path = f'./{txt_list[choice - 1]}'
    return path


file_path = get_file_path()
font_height = int(input('Font Height:'))
font_width = int(input('Font Width:'))
# ANSI文件转UTF-8
if not get_encoding(file_path) == 'utf-8':
    f = codecs.open(file_path, 'r', 'ansi').read()
    os.remove(file_path)  # 删除文件
    new_file = codecs.open(file_path, 'w', 'utf-8')
    new_file.write(f)

with open(file_path, 'r', encoding='utf-8') as f1:
    f1_list = list(f1)
    lines_num_of_index = f1_list.index('\n')
    character_num = 0
    index_list = []

    for line in range(lines_num_of_index):
        index_list += list(f1_list[line])  # 索引拼接成一个列表

    remove_list_items(index_list)  # 删除多余元素,方便计算

with open('./Font.h', 'w', encoding='utf-8') as f2:
    f2.write('#include \n\n')
    lines_of_each_character = recognize_line_nums(f1_list)
    if not lines_of_each_character == 1:
        for i in range(lines_num_of_index + 1, len(f1_list) - 2, lines_of_each_character):
            if character_num < 10:
                f2.write(f'const unsigned char hz_{character_num} PROGMEM[] = \n')
                character_num += 1

                line_first_list = list(f1_list[i])
                line_first_list[-2] = ','
                line_first_str = ''.join(line_first_list)
                f2.write(line_first_str)
                i += 1

                if lines_of_each_character > 2:
                    for each_line in range(lines_of_each_character - 2):
                        line_list = list(f1_list[i])
                        line_list[0] = ''
                        line_list[-2] = ','
                        line_str = ''.join(line_list)
                        f2.write(line_str)
                        i += 1

                line2_list = list(f1_list[i])
                line2_list[0] = ''
                line2_list[-11] = '};'
                line2_str = ''.join(line2_list)
                f2.write(line2_str)
                f2.write('\n')
            elif 10 <= character_num < 100:
                f2.write(f'const unsigned char hz_{character_num} PROGMEM[] = \n')
                character_num += 1

                line_first_list = list(f1_list[i])
                line_first_list[-2] = ','
                line_first_str = ''.join(line_first_list)
                f2.write(line_first_str)
                i += 1

                if lines_of_each_character > 2:
                    for each_line in range(lines_of_each_character - 2):
                        line_list = list(f1_list[i])
                        line_list[0] = ''
                        line_list[-2] = ','
                        line_str = ''.join(line_list)
                        f2.write(line_str)
                        i += 1

                line2_list = list(f1_list[i])
                line2_list[0] = ''
                line2_list[-12] = '};'
                line2_str = ''.join(line2_list)
                f2.write(line2_str)
                f2.write('\n')

    if lines_of_each_character == 1:
        for i in range(lines_num_of_index + 1, len(f1_list) - 1, lines_of_each_character):
            if character_num < 10:
                f2.write(f'const unsigned char hz_{character_num} PROGMEM[] = \n')
                character_num += 1

                line_list = list(f1_list[i])
                line_list[-11] = '};'
                line_str = ''.join(line_list)
                f2.write(line_str)
                f2.write('\n')

            elif 10 <= character_num < 100:
                f2.write(f'const unsigned char hz_{character_num} PROGMEM[] = \n')
                character_num += 1

                line_list = list(f1_list[i])
                line_list[-12] = '};'
                line_str = ''.join(line_list)
                f2.write(line_str)
                f2.write('\n')

    f2.write('\n\n')
    f2.write('struct FNT_HZ // 汉字字模数据结构\n{\n')
    f2.write('\tchar  Index[4];              ')
    f2.write('// 汉字内码索引,存放内码,如"中",在UTF-8编码下,每个汉字占3个字节,第四个是结束符0\n')
    f2.write('\tconst unsigned char* hz_Id;  // 点阵码数据      存放内码后对应的 点阵序列  每个字需要32个字节的点阵序列\n')
    f2.write('\tunsigned char hz_heitht;\n')
    f2.write('\tunsigned char hz_width;\n};')

    f2.write('\n\n\n')
    f2.write('PROGMEM const FNT_HZ hanzi[] =\n{\n')
    if len(index_list) <= 20:
        for j in range(int(len(index_list) / 2)):
            # print(index_list[j * 2], index_list[j * 2 + 1])
            f2.write('\t{')
            f2.write(f'"{index_list[j * 2]}", hz_{index_list[j * 2 + 1]}, {font_height}, {font_width}')
            f2.write('},\n')
    if 20 < len(index_list) <= 290:
        for j in range(10):
            # print(index_list[j * 2], index_list[j * 2 + 1])
            f2.write('\t{')
            f2.write(f'"{index_list[j * 2]}", hz_{index_list[j * 2 + 1]}, {font_height}, {font_width}')
            f2.write('},\n')
        for j in range(10, int((len(index_list) - 20) / 3) + 10):
            # print(index_list[(j - 10) * 3 + 20], index_list[(j - 10) * 3 + 21] + index_list[(j - 10) * 3 + 22])
            f2.write('\t{')
            f2.write(f'"{index_list[(j - 10) * 3 + 20]}", ')
            f2.write(f'hz_{index_list[(j - 10) * 3 + 21] + index_list[(j - 10) * 3 + 22]}, {font_height}, {font_width}')
            f2.write('},\n')
    f2.write('};')

with open('./Function.h', 'w', encoding='utf-8') as f3:
    f3.write('/*******************单个汉字显示****************/\n')
    f3.write('void showMyFont(int32_t x, int32_t y, const char c[3], uint32_t color) {\n')
    f3.write(f'\tfor (int k = 0; k < {character_num}; k++)// 根据字库的字数调节循环的次数\n')
    f3.write('\t\tif (hanzi[k].Index[0] == c[0] && hanzi[k].Index[1] == c[1] && hanzi[k].Index[2] == c[2]) {\n')
    f3.write('\t\t\ttft.drawBitmap(x, y, hanzi[k].hz_Id, hanzi[k].hz_width, hanzi[k].hz_heitht, color);')
    f3.write('\n\t}\n}')

代码将生成Font.h与Function.h两个文件
Function.h中的函数可以在TFT屏幕上显示单个汉字

/*******************单个汉字显示****************/
void showMyFont(int32_t x, int32_t y, const char c[3], uint32_t color) {
	for (int k = 0; k < 8; k++)// 根据字库的字数调节循环的次数
		if (hanzi[k].Index[0] == c[0] && hanzi[k].Index[1] == c[1] && hanzi[k].Index[2] == c[2]) {
			tft.drawBitmap(x, y, hanzi[k].hz_Id, hanzi[k].hz_width, hanzi[k].hz_heitht, color);
	}
}

以下函数显示多个汉字

/*******************整句汉字显示****************/
//显示整句汉字,字库比较简单,上下、左右输出是在函数内实现
//参数说明:
//x,y显示位置  str为输入字符串  mode 0为水平,1为竖直  enable_auto_change_line自动换行
void showMyFonts(int32_t x, int32_t y, const char str[], uint32_t color, char mode, bool enable_auto_change_line) {
    int x0 = x;
    int y0 = y;
    if (mode == 0) {
        for (int i = 0; i < strlen(str); i += 3) {
            if (enable_auto_change_line) {
                if (x0 + hanzi[0].hz_width >= TFT_WIDTH) {
                    x0 = 0;
                    y0 = y0 + hanzi[0].hz_heitht;
                }
            }
            showMyFont(x0, y0, str + i, color);
            x0 += hanzi[0].hz_width;
        }
    }
    if (mode == 1) {
        for (int i = 0; i < strlen(str); i += 3) {
            if (enable_auto_change_line) {
                if (y0 + hanzi[0].hz_heitht >= TFT_HEIGHT) {
                    y0 = 0;
                    x0 = x0 + hanzi[0].hz_width;
                }
            }
            showMyFont(x0, y0, str + i, color);
            y0 += hanzi[0].hz_heitht;
        }
    }
}

你可能感兴趣的:(python,开发语言,嵌入式硬件,单片机)