位图字体的原理及应用

2018-07-16

前言

常用的字体分为两种:矢量字体和位图字体。

网页中大部分用的都是矢量字体,使用矢量图形来渲染字符,便于无损缩放、修改颜色、样式与内容分离。我之前写过几篇矢量字体相关的博客,这里不再展开。

而位图字体则使用图片来渲染字体,字体的颜色、形状、图案,都可以使用图片来绘制,可以实现复杂的字体样式,常用于游戏开发中。本文介绍位图字体的原理和制作方法。


应用

计算机最早的字体称之为点阵字体,用一系列的像素点来渲染一个字符。如今已经很少用到点阵字体了,但位图字体的原理却与它相同。位图字体使用图片来渲染字符,而图片本身就是用像素点来储存的。


主流的游戏引擎使用.fnt方案(如Cocos和LibGdx),这里给出一个简单的Demo,首先保存下面这张图:

位图字体原图

重命名为“num.png”,然后在同个目录下新建一个num.fnt的文件,打开输入以下内容:

info face="Num" size=32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0
  common lineHeight=32 base=26 scaleW=256 scaleH=256 pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0
  page id=0 file="num.png"
  chars count=10
  char id=48   x=0     y=0     width=50    height=81    xoffset=0     yoffset=0     xadvance=50    page=0  chnl=15
  char id=49   x=194   y=82    width=33    height=81    xoffset=0     yoffset=0     xadvance=33    page=0  chnl=15
  char id=50   x=98    y=82    width=47    height=81    xoffset=0     yoffset=0     xadvance=47    page=0  chnl=15
  char id=51   x=146   y=82    width=47    height=81    xoffset=0     yoffset=0     xadvance=47    page=0  chnl=15
  char id=52   x=51    y=0     width=50    height=81    xoffset=0     yoffset=0     xadvance=50    page=0  chnl=15
  char id=53   x=204   y=0     width=48    height=81    xoffset=0     yoffset=0     xadvance=48    page=0  chnl=15
  char id=54   x=102   y=0     width=50    height=81    xoffset=0     yoffset=0     xadvance=50    page=0  chnl=15
  char id=55   x=0     y=82    width=48    height=81    xoffset=0     yoffset=0     xadvance=48    page=0  chnl=15
  char id=56   x=153   y=0     width=50    height=81    xoffset=0     yoffset=0     xadvance=50    page=0  chnl=15
  char id=57   x=49    y=82    width=48    height=81    xoffset=0     yoffset=0     xadvance=48    page=0  chnl=15

保存一下,这两个文件组合起来,就是一个名为“Num”的位图字体了。Cocos的文档中有使用位图字体的介绍,可以根据文档说明,直接把字体文件拖进去看看效果。


原理

看上面的图片和.fnt文件,可见原理类似我们熟悉的CSS sprites,一张图片储存字符的样式,.fnt文件储存一系列的定位信息。下面分析一下.fnt文件的内容。


info face="Num" size=32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0


 这一行定义了字体名(face),大小(size),加粗(bold)、斜体(italic)、编码字符集(charset)、纵向缩放百分比(stretchH)、平滑(smooth)、抗锯齿(aa)、内边距(padding)、外边距(spacing);


common lineHeight=32 base=26 scaleW=256 scaleH=256 pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0


 这一行定义了行高(lineHeight)、基本大小(base)、图片大小(scaleW/scaleH)、用到几张图(pages)、图片是否压缩(packed)、图片的几个通道(alphaChnl/redChnl/greenChnl/blueChnl);


page id=0 file="num.png"

这一行以下就是具体的定位信息了。说明引用哪个图片文件,并给出每个字符对应的图片中的具体定位。


制作

推荐两个软件:HieroBMfont


以BMfont为例子。选择Edit菜单最后一项进行图片资源管理:

选择图片资源


进入Image Manager之后,选择左上角Image -> import image,到如下页面:

制作位图字体

选择该字符的图片文件,然后在Id的输入框中,输入这一字符的Assic编码。比如我们这次选择的是数字0的图片,那么Id就填上0的Assic编码48。


如此依次添加每个字符的图片,最后保存即可导出位图字体资源。



本文未经许可禁止转载,如需转载关注微信公众号【工程师加一】并留言。