点阵字体BDF的生成

做点阵字体的原因,是我觉得Windows下的16点阵的宋体不如原来DOS下的好看。在分析点阵字体的时候,就萌生了要把Windows下的TTF字体转成点阵字体的想法。

在网上查了一些资料,TTF转点阵字体,绕不开的就是描边矢量化。这个倒是有工具Potrace可以做。但是转成的点阵字,是按比例缩放的,在特定的字体大小下,可能会显得模糊,那么就需要针对这个大小的字体,制作BDF格式的字体。比如我们编辑一个带有点阵字体的TTF文件,会发现它有一个或多个BMP字体。

如下图:

于是,我就开始研究BDF文件格式。在网上搜索资料,得到以下的内容:

复制代码
//一个BDF字体文件,首先需要确定分辨率DPI,一般我们设置为96,符合大部分显示器的分辨率
STARTFONT 2.1                                    //BDF版本号
COMMENT 该字体来自于宋体                        //注释
FONT Song                                        //字体名
SIZE 12 96 96                                    //字体大小,格式SIZE <磅数> <X分辨率> <Y分辨率>
                                                //磅数=像素*72/DPI,16像素点阵,磅数就是12
FONTBOUNDINGBOX 16 16 0 0                        //字体外围大小,<宽度> <高度> <X偏移量> <Y偏移量>
STARTPROPERTIES 12                                //这里开始属性定义,数字代表有多少条属性
COPYRIGHT 版权所有 (c) 2025 www.51xiazai.com    //版权定义
FOUNDRY "www.51xiazai.com"                        //发行商,还是版权定义
FAMILY_NAME Song                                //字体家族,在Windows中,同家族的字体会合并管理
SEWINDTH_NAME "Normal"                            //字体的水平宽度,也就是字符的相对间距
                                                //例如 "Normal"(正常)、"Condensed"(紧缩)、"Expanded"(扩展)等。
                                                //这个属性对于等宽字体(Monospace)和可变宽度字体(Proportional)的分类很有用
AVERAGE_WIDTH 16                                //字体的平均宽度
PIXEL_SIZE 16                                    //字体的平均高度
RESOLUTION_X 96                                    //X分辨率
RESOLUTION_Y 96                                    //Y分辨率
CHARSET_REGISTRY "gb2312"                        //字符集 CHARSET_REGISTRY 通常会和 CHARSET_ENCODING 一起出现
CHARSET_ENCODING "O"                            //CHARSET_ENCODING 指定了注册机构下的具体编码版本
FONT_ASCENT 12                                    //上升线:基线到最高点的距离
FONT_DESCENT 4                                    //下降线:基线到最低点的距离
ENDPROPERTIES                                    //属性定义结束
CHARS 21126                                        //本BDF文件一共描述的字符数量
//每一个字符的具体描述
STARTCHAR U+554A                                //定义要描述的字符UNICODE
ENCODING 21834                                    //字符的编码
SWIDTH 16000 0                                    //字符的可伸缩宽度,这个值通常为DWIDTH值的1000倍
DWIDTH 16 0                                        //字符宽度
BBX 16 16 0 0                                    //单个字符的边界框 BBX <宽度> <高度> <X偏移量> <Y偏移量>
//字符的点阵描述
BITMAP
0000
0EFC
EA08
AA08
AAE8
AAA8
ACA8
AAA8
AAA8
AAA8
EAE8
AAA8
0C08
0808
0828
0810
ENDCHAR

上面的点阵字符,描述的是汉字"啊",它的点阵用二进制表示就是如下的样子:

看明白了吗?所以BDF的字体格式很简单。

上面的字体大小是16*16,正好是8的倍数,那么,如果字体的大小不是8的倍数怎么办呢?

看下面的例子:

横向扩展成8的倍数,末位补0即可。