フォントファイルから使いたい文字を抜き出してコマンドラインでWebフォント化するfontminが便利だった


Webページで日本語のWebフォントを使いたいんだけどフォントファイルのサイズが大きくて諦めたなんて経験ないですか?

例えばIPAゴシックだと6.2MBほどのファイルサイズがあるので、さすがにそのままWebフォントとして使うのには抵抗がありますよね。

じゃあ使いたい文字だけ引っこ抜いてフォントファイルを再構築すればいいじゃね?という考え方を元にした手法としてフォントのサブセット化というものがあります。

fontmin

fontminはWebフォントフレンドリーなフォントのサブセット化をサポートするツールです。
nodeモジュールであり、CLIもサポートしているのでビルドプロセスに組込みやすいという点ではフロントエンダーには嬉しいところではないでしょうか。

出来ること

具体的に出来ることは下記になります。

  • フォントファイルを指定した文字でサブセット化したフォントファイルに変換
    • 出力できる形式はwoffttf、、eotsvg。Webフォントフレンドリー。
  • レガシーブラウザも考慮したベストプラクティスっぽいcssの@font-faceを吐いてくれる
  • ソースはTrueTypeFont(ttf)のみっぽい
    • OpenTypeFont(otf)を使いたい場合は一旦TrueTypeFontに変換しなければならない。

使い方

インストール


# グローバルで使う場合
$ npm install -g fontmin

# ヘルプを見る
$ fontmin --help

コマンドラインで使う

サンプルとしてIPAゴシックを使ってみる。
ファイルサイズは6,235,344バイトある。

フォントにフォント?という文字だけに対応したIPAゴシックのサブセットを作る。


# フォント(ipga.ttf)をoptimizeディレクトリに出力
# -tオプションでサブセット化する文字列を指定
fontmin -t フォントにフォント? ipag.ttf ./optimized

optimizedディレクトリには以下のファイルが出力される。

  • ipag.css ( 416バイト)
  • ipag.eot (2,904バイト)
  • ipag.svg (2,480バイト)
  • ipag.ttf (2,732バイト)
  • ipag.woff (2,804バイト)

めちゃくちゃサイズが減りましたね!!

ipag.cssの中身はこんな感じです。


@font-face {
     font-family: "ipag";
     src: url("ipag.eot"); /* IE9 */
     src: url("ipag.eot?#iefix") format("embedded-opentype"), /* IE6-IE8 */
     url("ipag.woff") format("woff"), /* chrome、firefox */
     url("ipag.ttf") format("truetype"), /* chrome、firefox、opera、Safari, Android, iOS 4.2+ */
     url("ipag.svg#ipag") format("svg"); /* iOS 4.1- */
     font-style: normal;
     font-weight: normal;
}

eotはレガシーIEをターゲットにしていないのなら消してもいいですね。

実際の表示を確認してみます。

まずWebフォントを使わずfont-familyにヒラギノ明朝を指定。

次にサブセット化してないオリジナルIPAゴシックを指定。
当然ながらすべての文字がIPAゴシックで表示されてます。

最後にサブセット化したIPAゴシックを指定。
「フォントにフォント?」だけIPAゴシックで表示されています。
それ以外の文字はサブセット化したフォントに無いのでヒラギノ明朝で表示されています。
ちゃんと指定した文字でサブセット化されていますね。

ビルドプロセスで使う

ビルドプロセスに組み込む場合はCLIがあるのでGulpやGruntからコマンドを直接叩けばいいかなと思います。

一応Gulpのプラグインもあります。

gulp-fontmin

フォントのライセンスに注意

フォントのサブセット化はプログラムの改変にもなるので利用するフォントがサブセット化して配布しても良いのか確認しましょう。

Tips

Webページからサブセット化したい文字を抜き出す

本家のREADMEに紹介されていましたがhtml-to-textというnode製のコマンドラインツールで、HTMLの中のテキストを引っこ抜く方法が紹介されていました。


$ npm install -g html-to-text
$ text=`curl www.baidu.com | html-to-text` && fontmin -t $text font.ttf

AngularJSなどで作ったSPA(Single Page Application)だとcurlの替わりにphantom-fetch-cliというnode製のコマンドラインツールを使うと良いとのこと。

但し、試してみたところ拾ってくる文字によってフォントファイルとの兼ね合いでなのかエラーで落ちる場合がありました。
ここらへんは突っ込んで調べてない。。

OpenTypeFontをTrueTypeFontに変換する

fontminの入力ソースはTrueTypeFontのみのようなのでOpenTypeFontで配布されているものはTrueTypeFontに変換する必要があります。
fontminでは出来ないので、fontforgeなどのツールを使って変換すると良いでしょう。

まずfontforgeをインストール


$ brew install fontforge

fontforgeでTrueTypeFontに変換するためのスクリプトファイルを作成します。

ファイル名はotf2ttf.peとします。


#!/usr/local/bin/fontforge
Open($1)
Generate($1:r + ".ttf")

fontforgeでスクリプトを実行します。


fontforge otf2ttf.pe hogehoge.otf

hogehoge.ttfファイルが出来ました!

FontForge Scripting Tutorialを参考にしました。

ちなみに、fontminのpluginでotf2ttfというのがあるんですが、まだ準備中とのことなので将来的にはfontminでttfへのコンバート処理が組み込まれるんじゃないかと思っています。

感想

ちょっと触っただけですがビルドプロセスに組み込みやすいfontminを使って日本語Webフォントを積極的に使ってみたくなりました。

これからも生暖かく見守りたいと思います。