Merging Font with FontForge

前些时在cauchy同学的帮助下,解决了长期以来困扰我的字体合并问题。这次把相关的东西记录下来备忘。

问题:将一种字体A(一般是一种英文字体)嵌入到另外一种字体B中(一般是一种中文字体),替换掉B字体中对应的字型。为什么要干这种事情呢?很简单,因为大部分中文字体内置的ASCII字型都太难看或者乏味,而英文字体种类远远多与中文字体,你经常可以看到非常漂亮的英文字体,会希望它可以和你喜欢的宋体、或者圆体、或者黑体显示在一起。TeX提供复杂的功能来实现不同语种文字的字体对应,但是最简单最通用的办法还是自己合成一个字体,同时包含你需要的英文字体A和中文字体B。
p.s. 我合成的字体主要用在WoW以及TeX排版中。

要求:除了保持字体不失真、不丢失字符等基本要求之外,还要做到:
1. 操作方法应该是可以方便的跨平台的,因为我大部分时候用Mac,有时用Windows和Linux;
2. 产生的字体应该具备最大限度的跨平台兼容性,支持Mac、Linux、Windows操作系统,可用于一般应用程序和TeX排版引擎。

这个问题并不容易解决,真是不试不知道,昂贵的工具如FontLab Studio居然有5千字符的限制(唉。。。大概只为拉丁语系服务吧),便宜一点的FontCreator只能手工选择字符复制和粘贴,麻烦不说,而且它生成的TrueType字体缺少某些描述符,不能在Mac下被Font Book正常显示。所以才有了下面这个解决方案,let’s go!

解决方案FontForge
这个开放、强大的工具真是无所不能啊,但是要当心,不要被它那个丑陋、缓慢的GUI前端迷惑了,要想做到合并字体这类的事情,还是它的命令行+Python脚本好用——是的,FontForge支持Python脚本,并且提供了数十个函数来帮助你在脚本中使用它的字体处理功能。
然后按照下面的操作步骤进行:

  1. 安装好FontForge,这个根据你的OS可能需要特定的处理,这里就不细说了:
    $ fontforge -version
    Copyright (c) 2000-2008 by George Williams.
     Executable based on sources from 16:34 GMT 30-Mar-2008.
     Library based on sources from 15:57 GMT 30-Mar-2008.
    fontforge 20080330
    libfontforge 20080330
    
  2. 准备一个临时目录,把你要合并的英文字体A、中文字体B放到目录下;
  3. 准备好下面这个脚本,将其命名为font-merge.pe,保存在上述临时目录下:
    # Pre-operation for some non-standard Chinese font file
    Open("font_b.ttf")
    SelectAll()
    ScaleToEm(1024)
    Generate("temp.ttf", "", 0x14)
    Close()
    
    # Open English font and merge to the Chinese font
    Open("font_a.ttf")
    SelectAll()
    ScaleToEm(1024)
    
    MergeFonts("temp.ttf")
    SetFontNames("FontName", "Font Family", "Full Name", "Style", "")
    Generate("font_merged.ttf", "", 0x14)
    Close()
    

    这里注意几点:

    • 第2行:这里括号里指定中文字体的文件名,和你放到临时目录中的保持一致;
    • 第9行:这里括号里指定英文字体的文件名,和你放到临时目录中的保持一致;
    • 第14行:这里设置输出字体的属性,第一个参数是字体的PostScript名,必须英文,不可以有空格,这也是跨平台唯一的标识;第二个参数是字体的family名,第三个是字体的full名,这两个都可以带空格;第四个参数是样式描述,可以是”Regular”、”Bold”、”Italic”等;
    • 第15行:这里括号里指定输出字体的文件名,和临时目录中已有文件不要重名。

    具体内容参考FontForge的脚本函数说明都很容易理解。

  4. 在上述临时目录下运行下面的命令:
    $ fontforge -script font-merge.pe
  5. 等待命令运行完成,就可以去临时目录取合成好的字体了。这里有时会有一些warning,但是不要紧;某些中文字体会导致出错,比如著名的微软雅黑,由于这个字体内部做了很多hacking所以很多标准工具都处理不了,这类问题暂时没有办法,反正好用的中文字体还有几种,它不行就换别的好了。另外,这里举例用的都是TrueType字体,事实上OpenType也是支持的,其他比较少见的类型,只要FontForge支持就可以用在这里。

That’s it. 希望对于有类似需要的朋友有帮助。

16 Comments

  1. Neo

    To Mic:

    FontForge Windows版本我没有用过,而且我上面写的办法是针对命令行的,一般来说应该和OS无关。

  2. Haijiang

    寻寻觅觅,终于找到了。

    一点补充:如果报告无法打开字体,在第2,9,13
    行加上 flag “1″

    2: Open(“font_b.ttf”, 1)
    9: Open(“font_a.ttf”, 1)
    13: MergeFonts(“temp.ttf”, 1)

  3. Nas

    您好,我最近也在試著合併字體(也是用OS X),之前找到您這篇文章,就去下載了這個軟體,可惜我完全外行,所以想請教您個問題:

    請問那個存成pe 副檔名的檔案是用什麼軟體編輯呢?是FontForge 還是一般文字編輯軟體呢?因為我試著用FontForge 開這樣一個檔案,卻找不到方法,使用文字編輯軟體存成pe 後又毫無反應(老實說我連腳本是什麼都不知道…),但我還是想學著自己做字體啊~有些英文藝術字體中文配上正黑體怎麼看怎麼怪啊…

    先在這裡謝謝您了!

  4. Neo

    To Nas:

    pe这个文件就是一个文本文件,你可以用任何文本编辑器去编辑,里面不要出现中文什么的特殊字符就基本不会有太大问题。运行这个文本文件的命令和注意事项上面都有说。说实话,fontforge这个工具并不是为普通用户开发的,所以对于一般人来说不太好用。。。

  5. Nas

    謝謝您的回答!我發現我的問題在於不知道該怎麼命令它運行…

    我將兩個字體和pe 放在同一資料夾之後,開啓fontforge, 隨便挑一個字體打開,然後file->execute script->輸入$ fontforge -script font-merge.pe, 點選OK

    我這樣是動作有錯誤嗎?因為完全沒有任何反應也沒有看到新字體…

    抱歉,我的問題好像很蠢的樣子…

  6. Neo

    To Nas:

    简单的办法是把字体和脚本放在同一个目录,打开命令行界面(cmd.exe),进入这个目录,运行:

    [你的fontforge所在的目录]\fontforge -script font-merge.pe

    直接运行fontforge的图形界面的话,我没试过,不过你可以试试选File->Execute Script,在打开的对话框里点“Call…”这个按钮,选择你编辑好的那个pe文件。

  7. Vick

    你好,我现在也有一个类似合并的需求,不过是在同一个ttf上操作;这个ttf只有简体,没有繁体,我需要把简体的Glyph取到后更改mapping,变成繁体的然后拷贝进去,等于繁体和简体显示的都是同一个字体。用fontforge操作,如何找到对应Glyph并改变他的mapping呢?
    一直没找打其他的解决方法,来这问问,麻烦了,谢谢。

  8. Neo

    @Vick 抱歉最近很忙没看到你的 comment。你的需求据我所致是没有办法简单的实现的,必须用字体编辑软件打开字体然后逐个或者逐片 glygh 的处理。FontForge 的 GUI 版本倒是也可以做这事儿,不过总的来说是个体力活儿……

  9. www

    感谢您的分享,我合并时遇到了一个小问题:中文的引号本来应该占一个中文的宽度,但是合并后变得很窄很小,按理来说英文字体里没有中文引号不存在替换的问题,不知道您有没有解决方案。

Leave a Reply