Ubuntu Weekly Recipe

第332回Webフォントをつくろう

Webフォントは、サーバー上にあるフォントファイルをWebブラウザーがダウンロードして表示するCSS3の@font-faceルールで使われるフォントです。今回は、Ubuntu上でこのWebフォントのうち、W3C勧告になっているWeb Open Font Format(WOFF)をUbuntu上で作成する方法を紹介します。

Webフォントとは

最近、250文字の絵文字が追加されたUnicode 7.0がアナウンスされました。対応しているフォントが手元にあれば、ドクロマークやサングラスといった使い道が難しい絵文字も、文字として表示できるようになります。

この「対応しているフォント」というのが曲者です。コンピューターにおけるフォントファイルは、特定の書体に従って作成されたグリフデータとその他のメタデータの集合体です。あるフォントファイルが特定の文字を表示するためには、フォントファイルの中にその文字のグリフデータを持っている必要があります[1]⁠。言い換えると、グリフデータがない状態では、その文字は表示できず、たとえば「豆腐化」のように文字化けしてしまうのです。

図1 グリフが存在しないために豆腐が表示されてしまった例
図1 グリフが存在しないために豆腐が表示されてしまった例

ローカルのソフトウェアであれば、そのソフトウェアをインストールするときに必要になるフォントデータもセットでインストールすることで対応できます。しかしWebページで表示するフォントは、アクセスするユーザーの環境にどんなフォントがインストールされているのかわかりませんし、アクセスする度にフォントをシステムにインストールすることもできません。

そこで、⁠@font-face」というルールがCSS3で用意されました[2]⁠。@font-faceに書体名とフォントファイルのURLを指定することで、Webブラウザーはページへのアクセス時にフォントファイル(Webフォント)をダウンロードし、システムにインストールされていないフォントであってもfont-familyに指定できるようにするものです。

@font-face {
    font-family: "My font"
    src: url("http://example.com/fonts/myfont.woff");
}

h1 {
    font-family: "My Font", serif;
}

これにより、Webページの作成者は、閲覧者の環境にどんなフォントがインストールされているか気にすることなく、デザインを考えられるようになったのです。

モダンなWebブラウザーが一通り@font-faceルールに対応したのに合わせて、Google FontsTypeSquareと言ったWebフォントを無償・有償で提供するサービスも始まっています。

Web Open Font Format(WOFF)

Webフォントはフォントファイルをダウンロードします。しかしながら従来のフォントファイルのサイズは大きく、グリフの少ない英語フォントでも数十Kバイト、日本語フォントだと数Mバイトものサイズになってしまいます。これをアクセスのたびにダウンロードするのは非効率ですし、ページの描画にも時間がかかってしまいます。そこで通常のフォントを圧縮して利用できるフォントファイルフォーマットがいくつか作成されました。

そんなフォーマットの1つが、W3C勧告になったWeb Open Font FormatWOFFです。WOFFは、OpenType/TrueTypeをベースに圧縮されたファイルで、XMLのメタデータを追加することも可能です。仕様が公開されているため、モダンなWebブラウザーなら一通り対応していますし、Ubuntuでも比較的簡単にWOFFファイルを作成できます。

既存のフォントをWOFFに変換する

実は@font-faceルールは、Webブラウザーにも依存するものの、OpenTypeやTrueTypeと言った既存のフォントファイルに対しても使用できます。ただし前述のとおりファイルサイズが大きく、ロード時間が長くなってしまいます。さらにWebページで使用するグリフはそこまで多くはありません。メニューにのみ特殊な書体を使いたいのであれば、多くてもせいぜい数十文字でしょう。

そうすると既存のフォントから必要なグリフのみを抽出したファイルを用意して、それをWOFFに変換すれば、ページのロード時間がより短くなります。ここでは、Ubuntuで必要なグリフのみを揃えたWOFFを作る方法を紹介します。

なお、同じことを他のフォントにも行う場合は、フォントのライセンスに注意してください。とくに「フリーフォント」と呼ばれるものの中には再配布自体は許可していても、グリフの抽出や別フォーマットへの変換といった「改変」になりうる行為は許可していない場合も多いようです。

Ubuntuのリポジトリには「fonts-foo」「ttf-foo」といった名前のフォントパッケージが多数存在します。そのほとんどはDebian Fonts Task Forceによってメンテナンスされているフォントで、比較的自由に使用可能です。ただしフォントは一般的なFLOSSと異なり、独自ライセンスであることも多く、一筋縄ではいかないことも事実です。パッケージからインストールできるフォントの詳しいライセンス情報は、⁠/usr/share/doc/パッケージ名/copyright」を参照してください。

woff-toolsを使う

OpenTypeやTrueTypeから一括してWOFFに変換するなら、woff-toolsを使うのが一番簡単です。ためしに改変も含めて自由に利用できる衡山毛筆フォントをWOFFにしてみましょう。衡山毛筆フォントはパッケージ化されているので、リポジトリからインストールできます。

$ sudo apt install fonts-kouzan-mouhitsu
$ dpkg -L fonts-kouzan-mouhitsu
/.
/usr
/usr/share
/usr/share/fonts
/usr/share/fonts/truetype
/usr/share/fonts/truetype/kouzan-mouhitsu
/usr/share/fonts/truetype/kouzan-mouhitsu/kouzan-mouhitsu-gyosho.ttf
/usr/share/fonts/truetype/kouzan-mouhitsu/kouzan-mouhitsu.ttf
/usr/share/fonts/truetype/kouzan-mouhitsu/kouzan-mouhitsu-sosho.ttf
/usr/share/doc
/usr/share/doc/fonts-kouzan-mouhitsu
/usr/share/doc/fonts-kouzan-mouhitsu/changelog.Debian.gz
/usr/share/doc/fonts-kouzan-mouhitsu/copyright

woff-toolsもリポジトリからインストールします。

$ sudo apt install woff-tools

woff-toolsには、sfnt2woffコマンドとwoff2sfntコマンドの2つがあります。sfnt2woffコマンドはOpenType、TrueTypeフォントをWOFFに変換し、woff2sfntコマンドはその逆を行うコマンドです。

$ cp /usr/share/fonts/truetype/kouzan-mouhitsu/kouzan-mouhitsu.ttf .
$ sfnt2woff kouzan-mouhitsu.ttf
$ file kouzan-mouhitsu.woff
kouzan-mouhitsu.woff: Web Open Font Format, flavor 65536, length 5585588, version 0.0

作成したフォントを使うHTMLファイルを作成してみましょう。

<!DOCTYPE html>
<html><head>
<meta charset="utf-8" />
<title>Webフォント</title>
<style>
  @font-face {
    font-family: "衡山毛筆Webフォント";
    src: url("kouzan-mouhitsu.woff");
  }
  p {
    font-size: 200%;
    font-family: "衡山毛筆Webフォント", serif;
  }
</style>
</head>
<body>
<p>衡山毛筆フォントのテスト</p>
</body>
</html>

このHTMLファイルをWebブラウザーに読み込ませれば、フォントが衡山毛筆フォントになっているはずです[3]⁠。

図2 システムにインストールされていない書体名を指定しても、期待通りのフォントで表示されていることがわかる
図2 システムにインストールされていない書体名を指定しても、期待通りのフォントで表示されていることがわかる

メタデータを埋め込む

Webフォントには、Extended Metadata Blockというライセンスや作成者、フォントの説明を埋め込むメタデータ領域が存在します。sfnt2woffで変換する時にXMLファイルを渡しておくと、このメタデータを埋め込むことができます。

<?xml version="1.0" encoding="UTF-8"?>
<metadata version="1.0">
  <uniqueid id="com.example.KouzanMouhitsu"/>
  <vendor name="青柳 衡山 (Kouzan Aoyagi)" url="http://opentype.jp/kouzanmouhitufont.htm"/>
  <credits>
    <credit name="青柳 衡山 (Kouzan Aoyagi)" role="design"/>
  </credits>
  <description>
    <text lang="ja">衡山毛筆フォント for the Web</text>
  </description>
  <license url="http://opentype.jp/kouzanmouhitufont.htm">
    <text lang="ja">
      無料でご利用できます。
      著作権放棄で完全フリーです。
      改編も自由です。
      雑誌・書籍への掲載・CD収録も自由です。
      使用についての制限はありません。
      無保証です。お客様の責任でご利用ください。
    </text>
  </license>
</metadata>

上記のような情報をmetadata.xmlファイルに保存し、次のコマンドでWOFF作成時に埋め込みます。

$ sfnt2woff -m metadata.xml kouzan-mouhitsu.ttf

FontForgeでグリフを抽出する

woff-toolsはフォントファイルをそのままWOFFに変換します。このため、日本語フォントの場合、そこまでサイズは小さくならず、せいぜい半分から2/3になるといったところです。しかしながら日本語フォントファイルに含まれる文字をすべて使うケースは稀です。UIなどあらかじめ使う文字がわかっているのであれば、必要なグリフのみを抽出したフォントファイルを作ったほうがより軽量になるでしょう。

古くから存在するフォントエディタであるFontForgeを使うと、フォントファイルから特定のグリフを抽出したフォントファイルを作成したり、さらにそれをWOFFで出力することが可能です。

$ sudo apt install fontforge

起動するには端末からfontforgeコマンドを実行するか、Unityでfontforgeを検索してください。

図3 起動画面で編集するフォントを選ぶ
図3 起動画面で編集するフォントを選ぶ
図4 UIは若干古いが、フォント編集に必要な機能は一通り揃っている
図4 UIは若干古いが、フォント編集に必要な機能は一通り揃っている

グリフは、Unicode順に並んでいます。グリフの検索は「表示>移動(Ctrl+Shift+>⁠⁠」です。文字を入力することでも検索できますし、⁠U+NNNN」という形でUnicodeの数字を直接指定してジャンプもできます[4]⁠。

グリフを抽出するには、他のグリフを削除して保存します。まず、必要なグリフを1つずつShiftキーを押しながら選択していきます。⁠表示>移動」使う場合は選択状態を維持するために、⁠Merge into selection」にチェックを入れるのを忘れないでください。すべて選んだら、⁠編集>選択>選択範囲を反転」を選んで、対象のグリフ以外のすべてのグリフを選択状態にします。⁠エンコーディング>グリフの切り離し・削除」を選ぶと、選択したグリフが削除されます。最後に「ファイル>フォントを出力」を選び、ファイル名と「Web Open Font」を指定した上で保存してください。

FontForgeもWOFFに変更できる機能があるため、あとは@font-faceに出力したフォントを指定するだけです。たとえば衡山毛筆フォントのうち、⁠衡」「山」の字だけを抽出したWebフォントを作ると、次のように表示されるでしょう。

図5 ⁠衡山」だけ毛筆になり、他は標準のフォントが使われている
図5 「衡山」だけ毛筆になり、他は標準のフォントが使われている

Pythonでグリフを抽出する

FontForgeのUIで、必要な文字を1つずつ選択するのは大変です。文字列を渡したら適切なグリフを選んで新しいファイルに出力するところまでを自動化できたほうが便利でしょう。幸いFontForgeは、Pythonからも操作できるようになっているため、Pythonスクリプトを作成すれば、前述の作業を自動化できます。

$ sudo apt install python-fontforge

さらに次のようなPythonスクリプト(picup.py)を作成してください。

#!/usr/bin/env python2
# -*- coding: utf-8; -*-

import sys
import fontforge

def pickup_glyphs(src, dst, strings):
    glyphs = []
    for c in unicode(strings, 'utf-8'):
        glyphs.append(ord(c))

    font = fontforge.open(src)
    for glyph in glyphs:
        font.selection.select(('more', 'unicode'), glyph)
        try:
            for ref in font[glyph].references:
                font.selection.select(('more'), ref[0])
        except:
            sys.stderr.write("Error: not found for U+{:04x}\n".format(glyph))

    font.selection.invert()
    font.cut()
    font.generate(dst)
    font.close()

if __name__ == '__main__':
    src = sys.argv[1]
    dst = sys.argv[2]
    strings = sys.argv[3]
    pickup_glyphs(src, dst, strings)

第一引数が元データのフォントファイル、第二引数が出力先、第三引数に抽出したい文字列を指定します。

$ python2 kouzan-mouhitsu.ttf kouzan-subset.woff "毛筆"

上記のように実行すると、⁠毛」「筆」のグリフだけ取り込んだWOFFフォントが作成されます。出力先のファイルフォーマットは拡張子で判定しているため、第二引数の最後をwoffからttfに変更すればTrueTypeフォントとしても出力可能です[5]⁠。

Webフォントを活用しよう

Webフォントを使用すればユーザーの環境に依存することなく、Webブラウザー上に任意のグリフを表示できます。

たとえば和田研細丸ゴシックといった絵文字に対応したフォントをWebフォント化すると、絵文字がインストールされていない環境でも絵文字を表示できます。ただし、絵文字に対応したWebフォントはかなり存在していますので、あえて作るまでもないかもしれません。

IPAmj明朝花園フォントなどの広範囲の異体字に対応したフォントから必要なグリフのみを抽出すれば、コンテンツに応じて特定の異体字のみ表示できるサイトを作ることも可能です。最近はUnicodeの私用領域にアイコンを配置したWebフォントを使うことで、文字の装飾と同じ方法でアイコンを装飾してデザインするサイトも増えているそうです[6]⁠。

いわゆるWebアプリもレンダリングしているのはWebブラウザーそのものなので、Webアプリのデザインをカスタマイズする際にもWebフォントを利用できるケースは増えています。今後いろいろな用途が現れてくるであろうWebフォント、一度試してみてはいかがでしょうか。

おすすめ記事

記事・ニュース一覧