CharacterMatrix 生成带索引的字体库文件解析
按照官方的说明是:字库格式为 C+O+D,C和O两个域为可选域。其中C为32 Bits[4 Bytes]的数据,表示该字库文件中包含的字模总数;O占用的字节数为C*10,即每个字符各占80 Bits,前16 Bits[2 Bytes]为该字模的编码值[MBCS或UNICODE码值,可设置],第二个16 Bits[2 Bytes]为该字模的宽度,第三个16 Bits[2 Bytes]为字模的高度,最后32 Bits[4 Bytes]表示该字模的点阵数据在字库文件中的偏移量[偏移量从D起始处开始计算,即第一个字模的偏移量值为0];D用来描述字库中各字模的点阵数据,占用的字节数与字模大小及生成字库时使用的设置相关;C和O两个域的字节顺序为BigEndian,即高字节在前;
对于图形字模以及使用MBCS编码时添加的UNICODE专有字符,将使用0x0A00~0x0E7F区间作为字模的编码值使用 [覆盖UNICODE编码的果鲁穆奇语、古吉拉特语、奥里雅语、泰米尔语、泰卢固语、卡纳达语、马拉雅拉姆语区间];
下面开始用python进行解析:
def parse_font_library(file_path):
with open(file_path, 'rb') as f:
# 读取 C 域,获取字模总数
font_count = int.from_bytes(f.read(4), byteorder='big')
print(f"字库中包含的字模总数: {font_count}")
font_info = {}
# 读取 O 域,获取每个字模的信息
for _ in range(font_count):
# 读取编码值,占 2 字节
code = int.from_bytes(f.read(2), byteorder='big')
# 读取宽度,占 2 字节
width = int.from_bytes(f.read(2), byteorder='big')
# 读取高度,占 2 字节
height = int.from_bytes(f.read(2), byteorder='big')
# 读取偏移量,占 4 字节
offset = int.from_bytes(f.read(4), byteorder='big')
font_info[code] = {
'width': width,
'height': height,
'offset': offset
}
# 记录 D 域起始位置
d_start = f.tell()
# 读取 D 域,即字模点阵数据
font_data = f.read()
return font_info, font_data, d_start
def get_font_matrix(font_info, font_data, d_start, ascii_code):
if ascii_code not in font_info:
print(f"未找到编码为 {ascii_code} 对应的字模。")
return None
info = font_info[ascii_code]
width = info['width']
height = info['height']
offset = info['offset'] + d_start
# 计算字模数据长度
data_length = (width * height + 7) // 8
# 提取对应字模数据
matrix_data = font_data[offset - d_start:offset - d_start + data_length]
matrix = []
for byte in matrix_data:
binary_str = bin(byte)[2:].zfill(8)
matrix.extend([int(bit) for bit in binary_str])
result_matrix = [matrix[i * width:(i + 1) * width] for i in range(height)]
return result_matrix
def print_font_matrix(matrix):
if matrix is None:
return
for row in matrix:
for bit in row:
if bit == 1:
print('*', end=' ')
else:
print(' ', end=' ')
print()
if __name__ == "__main__":
file_path = "your_font_file.bin"
font_info, font_data, d_start = parse_font_library(file_path)
while True:
try:
ascii_input = input("请输入字符的编码(十六进制,如 0x41;输入 'q' 退出):")
if ascii_input.lower() == 'q':
break
if ascii_input.startswith('0x'):
ascii_code = int(ascii_input, 16)
else:
print("输入格式有误,请输入十六进制编码,如 0x41。")
continue
matrix = get_font_matrix(font_info, font_data, d_start, ascii_code)
print_font_matrix(matrix)
except ValueError:
print("输入无效,请输入有效的十六进制编码。")代码解释
parse_font_library 函数
读取 C 域:从文件开头读取 4 个字节,以大端字节序转换为整数,得到字库中包含的字模总数,并打印该信息。
读取 O 域:循环 font_count 次,每次读取 10 个字节,分别获取字模的编码值、宽度、高度和偏移量,并将这些信息存储在 font_info 字典中。
记录 D 域起始位置:使用 f.tell() 记录 D 域的起始位置,方便后续计算偏移量。
读取 D 域:读取文件剩余部分,即字模的点阵数据。
get_font_matrix 函数
检查编码是否存在:检查输入的编码是否在 font_info 字典中,如果不存在则提示未找到对应字模。
计算偏移量:将存储的偏移量加上 D 域的起始位置,得到字模点阵数据在文件中的实际偏移量。
提取字模数据:根据宽度和高度计算字模数据的长度,并从 font_data 中提取对应的数据。
转换为矩阵:将提取的字节数据转换为二进制矩阵。
print_font_matrix 函数
遍历矩阵,将值为 1 的位置打印为 *,值为 0 的位置打印为空格。
主程序
加载字库:调用 parse_font_library 函数加载字库文件,并获取字模信息、点阵数据和 D 域起始位置。
循环输入:提示用户输入字符的十六进制编码,输入 q 退出。
获取并打印字模矩阵:根据用户输入的编码调用 get_font_matrix 函数获取字模矩阵,并调用 print_font_matrix 函数打印矩阵。
使用说明
将 "your_font_file.bin" 替换为实际的字库文件路径。
运行代码后,程序会显示字库中包含的字模总数。
按照提示输入字符的十六进制编码(如 0x41),程序会打印对应的字模矩阵。输入 q 可退出程序。




支付宝打赏
微信打赏 
