Fontforge Python调用glyphPen时Unicode值260触发索引越界报错
问题根因
报错来自三个叠加的问题:
- Fontforge新建字体默认使用
ISO8859-1编码,仅支持0-255范围的字符。连续创建字符时Fontforge会自动切换到支持更大范围的Unicode编码,但如果255之后的字符存在跳空(实际解析CAD字体时,256-259这几个编码没有对应字形、不会被创建),自动编码切换逻辑不会触发,访问260时就会抛出索引越界。 - 调用
createChar()创建字符后,又通过font[uniname]二次索引字形对象的写法是冗余的,在编码未正确设置的场景下会直接触发索引错误。 - 手动移位拼接字节的解析逻辑容易出现位运算、字节序判断错误,可能生成无效Unicode值触发异常。
修复方案
按顺序做以下修改即可解决问题:
- 新建字体对象后第一时间显式设置全范围Unicode编码,不要依赖默认配置:
font = fontforge.font() # 显式指定Unicode全范围编码,覆盖所有合法Unicode码点 font.encoding = "UnicodeFull"
- 直接使用
createChar()返回的字形对象获取画笔,不要二次索引字体对象,同时增加码点合法性校验:
uniname = glyph['glyphname'] # 过滤无效Unicode值,避免解析错误导致崩溃 if 0 <= uniname <= 0x10FFFF: current_glyph = font.createChar(uniname) pen = current_glyph.glyphPen() else: # 跳过当前无效字形的路径数据,保证文件指针位置正确 f.seek(glyph['pathsize'], 1) continue
- 用标准库
struct替换手动字节拼接逻辑,从根源避免字节计算错误:
import struct # 读取4字节字形头 data = f.read(4) # 按小端序解析:前2字节为字形对应Unicode值,后2字节为路径数据长度 glyph['glyphname'], glyph['pathsize'] = struct.unpack("<HH", data) # 记录路径数据的起始偏移,和原有逻辑保持一致 glyph['offset'] = f.tell()
补充说明
遍历测试代码能正常运行的原因是:从253连续创建字符到280时,255之后的码点是连续生成的,Fontforge检测到码点超出ISO8859-1范围后自动升级了编码,因此不会触发报错。而实际解析CAD字体时,256-259通常是空码位、没有对应字形,不会被创建,触发不了自动编码切换,就会在260的位置崩溃。
内容的提问来源于stack exchange,提问作者Dave Coventry
相关产品推荐
相关产品推荐

