『Making Software』は Dan Hollick が執筆中の、ソフトウェアの底層原理を図解する本です。その一章 How to make a font. は、約六千語でデジタルフォントの作り方をベクターアウトラインから hinting まで一気に解説します。表面的には、フォントは各文字のベクターの集まりにすぎず、フォント作りはそのベクターを一筆ずつ描く作業に見えます。しかし字形を描くこと自体はむしろ簡単な部分で、難しいのは何百もの字形をあらゆるサイズ・大文字小文字・ウェイトで互いに調和させることです。
この章の内容は自然に三つの層に分かれます。機械がフォントをどう保存しレンダリングするか、デザイナーがどんな言葉で文字を語るか、そして本当の手間はどこにかかっているか。本メモもこの三層に沿って進めます。
機械の側:フォントファイルはデータベース
まず用語の整理から。typeface(書体ファミリー)はファミリー全体を指します——Garamond とそのすべてのウェイトとスタイル。font(フォント)はその具体的な一つのインスタンスで、たとえば 12pt の Garamond Roman です。日常では混用されますが、type デザイナーはこの区別を大切にします。
技術的にもっと直感に反するのは、フォントファイルの本質が複数のテーブル(table)で構成された構造化データベースだという点です。私たちが「フォント」だと思っているもの——glyph(字形)のアウトライン——はその中の一つのテーブルにすぎません。残りのテーブルには、文字を正しくレンダリングするためのすべてが入っています。各文字が占めるスペースを定めるメトリクス、特定の文字ペアの間隔を微調整する kerning(カーニング)テーブル、小さいサイズで鮮明さを保つ hinting(ヒンティング)命令、そして名前・ライセンス・対応言語などのメタデータです。
四十年のフォーマット変遷
- PostScript Type 1(Adobe、1984):三次(cubic)Bézier 曲線でアウトラインを記述し、プロ印刷の標準になりました。ただし 1 ファイルに 256 glyph までという制限があり、多くの言語にはまったく足りず、しかも 2 つのファイルを組み合わせて使う必要がありました。
- TrueType(Apple、1980 年代末):二次(quadratic)Bézier に切り替えました——制御点が 1 つ少なく(4 つではなく 3 つ)シンプルですが、同じ形を作るにはより多くの点が要ります。最大の売りは内蔵の hinting で、小さいサイズで glyph をピクセルグリッドにどう合わせるかをデザイナーが精密に制御できました。Microsoft が Windows に採用し、一気に普及します。
- OpenType(Microsoft + Adobe、1990 年代末):統一コンテナで、TrueType 系と PostScript 系どちらのアウトラインも格納できます。1 ファイル最大 65,536 glyph で数十言語分の完全な Unicode をカバーでき、さらに layout テーブルを導入して、ligature(合字)、small caps(スモールキャップ)、スタイル代替字形、文脈依存の置換といった組版機能をフォントファイル自体に組み込みました。
- Variable fonts(可変フォント):最新の一歩で、デザインスペース全体を 1 ファイルに圧縮します。Light・Regular・Bold を別ファイルで配る代わりに、いくつかの axis(軸)——weight、width、slant、optical size——を定義し、実行時に master(マスター)間で interpolation(補間)して、軸上の任意の一点を取り出せます。web には特にありがたい話で、5 ウェイトはかつて 5 回のネットワークリクエストを意味していました。
OpenType ファイルの中身を開く
アウトラインテーブルの形式は、フォントの「フレーバー」(flavor)で決まります。TrueType フレーバー(.ttf)は glyf と loca の 2 テーブルを使います。glyf は点の列で、二次 Bézier によって字形を記述します。各点は x,y 座標と、曲線上の点(on-curve)か制御点(off-curve)かを示すフラグを持ちます。この仕組みはなかなか巧妙で——連続する 2 つの on-curve 点の間は直線、on-curve → off-curve → on-curve は一つの二次 Bézier セグメント、そして off-curve 点が 2 つ連続すると、rasterizer(ラスタライザ)がその中点に仮想の on-curve 点を自動挿入するため、すべてのアンカー点を明示的に保存する必要がありません。loca は各 glyph のバイトオフセットだけを持ち、字形データの始まりと終わりを示します。
OpenType フレーバー(.otf)は CFF または CFF2 テーブルを使います。点を保存する代わりに、描画オペレーターの列(rmoveto、rlineto、rrcurveto)を保存し、スタックから数値を取り出してペンを動かします。SVG の path データによく似た形式で、数値が相対値なのでサイズが小さく、圧縮も効きます。CFF2 は variable fonts のために設計された現代版で、基準の字形が weight・width・optical size に応じてどうずれるかのオフセットを追加で保存し、レンダリング時にまず基準点を処理してから、現在の設定に応じてオフセットを重ねます。
そのほかの重要なテーブルです:
cmap:Unicode コードポイントから字形への対応表。A を打つとコンピュータはU+0041と認識し、このテーブルで対応する glyph を引きます。head:ファイルヘッダ。バージョン、全体のバウンディングボックス、そして UPM(Units Per em)で表されるグリッドの尺度を持ちます。UPM は 1 つの em square が何フォント単位に当たるかを定め、CFF 系は通常 1000、TrueType 系は通常 1024 です。hhea:横書きテキストのグローバルメトリクス——最大の ascender/descender、推奨の leading(行送り)、ファイル中で最も幅の広い字形の Max Advance Width。縦書き用にはオプションのvheaがあります。hmtx(縦書きはvmtx):glyph ごとのスペーシングデータで、各 glyph に Advance Width(送り幅)、LSB(左サイドベアリング)、RSB(右サイドベアリング)を定義します。Advance Width は文字の占有ボックスに相当し、行を組むときのスペース配分に使われます。RSB は通常、幅と LSB から計算されます。- ほかに、メモリ要件を持つ
maxp、名前などのテキスト情報を持つname、そしてOS/2テーブル——名前は 1980 年代末の同名 OS に由来しますが、いまはウェイトと幅のレンジ、ファミリースタイル(Serif、Sans-Serif、Script、Monospace)、x-height、cap height、それに Windows・macOS・web のレンダリング差を吸収するクロスプラットフォームメトリクス一式を格納しています。
Text shaping:文字列から配置済みの字形へ
コンピュータがテキストを組むときは、text shaping(テキストシェーピング)と総称される一連のステップを通ります。glyph を描く前に、テキストはまず run に切り分けられます。run はフォント・サイズ・色・言語がすべて同じ断片で、どれか一つでも変わると(文中の斜体の単語など)現在の run が終わり、新しい run が始まります。文字には strong と weak の二種類があります。strong な文字は特定のアルファベットに強く属し(ラテンの「A」、ギリシャの「Δ」)、レンダラーに言語の帰属を伝えます。weak な文字はスペース・数字・記号で、どの言語にも属さず、run を中断しません。run 同士は完全に隔離され、kerning は run の境界を越えません——ギリシャ文字とラテン文字が別々の run に入れば、互いの間隔は調整されないのです。
切り分けが終わると、各 run は次の四つのステップを通ります:
- 参照:文字の Unicode 値(A は
U+0041)をcmapで Glyph ID に変換します。 - 置換(
GSUB):文脈に応じて字形を置き換えます。たとえば隣り合った「f」と「i」を、結合した「fi」の ligature に差し替えます。 - 配置(
GPOS):文字ペアに間隔調整を適用します。たとえば「o」を左へ寄せて、大文字 T の横棒の下に潜り込ませる——文脈を考慮した kerning です。 - レンダリング:ここまでの三つのステップで動かしてきたのは、見えない空のボックスだけでした。この最後のステップで初めて Glyph ID からアウトラインデータを取り出し、スケールに合わせて描画します。各 glyph は自分の sidebearing に従ってボックス内に収まります。
variable font を使う場合も、run に切り分ける前にウェイトを確定させるだけで、あとは同じです。この流れはブラウザが HTML/CSS をレイアウトする過程とよく似ています。Unicode テキストがコンテンツ、フォントと色が CSS、四つのステップがレイアウトボックスを組み立てて画面に描画する処理に当たります。
Hinting:ピクセルグリッドへの妥協
字形は約 1000 単位のグリッド上に描かれますが、小さいサイズでレンダリングすると、この座標系全体がほんの数ピクセルに押し込まれます。11px では、100 単位幅のステム(縦画)が 1 ピクセル強にしかならず、ピクセルグリッドにきれいに乗ることはほぼありません。H の一方のステムはくっきりした 1 列のピクセルにラスタライズされるのに、もう一方は 2 列のグレーに滲み、文字全体がぼやけて歪んで見えます。
hinting はフォントに格納された命令で、特定のサイズでアウトラインを歪ませ、ラスタライズの前にピクセルグリッドへ整列させます。目的は文字の本当の形を守ることではなく、鮮明さと引き換えに形を少しだけ裏切ること——ステムを整数ピクセル幅に丸め、H の 2 本のステムを強制的に揃え、行内の x-height を一定に保ちます。
二つのフレーバーの扱い方はまったく異なります。TrueType の hint は本質的に小さなプログラムです。fpgm、prep、glyf テーブルにバイトコードとして格納され、rasterizer 内蔵の小さな仮想マシンが実行します。デザイナーはピクセル単位・サイズ単位の制御を手にできました。低解像度 CRT の時代にはこの制御が決定的で——Verdana や Georgia は 1 ピクセルずつ手作業で hint されており、当時の画面であれほど読みやすかった大きな理由です。CFF は宣言的な路線です。具体的な結果を振り付けるのではなく、ステムの位置と幅、それに blue zone と呼ばれる水平方向の整列帯(baseline、x-height、cap height に対応)だけを記し、グリッドへの合わせ込みは rasterizer に任せます。いまでは hinting の重要性は大きく下がりました。高解像度の画面ではステムが最初から数ピクセルの幅を持ち、anti-aliasing(アンチエイリアス)が残りを均し、macOS に至ってはほとんどの hinting を無視して忠実なアウトラインをそのまま描画します。現在の多くのフォントはフォントエディタや ttfautohint による自動 hint で、手作業の hinting はほぼ失われた技術になりつつあります。
デザインの側:文字をめぐる言葉
機械の話はここまでです。type デザインはとても古い手仕事で、独自の語彙体系を持っています。その大半は活版時代の物理的な組版に由来します。font はフランス語の *fondre*(鋳造する)から来ており、もともとは特定サイズの活字一式の鋳造を指しました。文字の一つひとつは sort と呼ばれ、ケース(case)に収められていました——大文字は上の段(upper case)、より頻繁に使うその他の文字は下の段(lower case)。これが uppercase/lowercase という呼び名の由来です。植字工は薄い鉛の板で行間を空けたので、行送りは leading(lead=鉛から)と呼ばれます。活字の胴からはみ出して間隔を補った部分は kern と呼ばれ、文字間調整が kerning と呼ばれるのはそのためです。
サイズとプロポーション
各字形は em と呼ばれる枠の中に描かれ、その単位尺度が先ほどの UPM(通常 1000)です。以降のあらゆる寸法はこの座標系を基準にします。フォントサイズを 14px にすると、この em の枠がその 14 ピクセルの高さを占めます。サイズを上げても枠が拡大されるだけで、座標そのものは相対値なので変わりません。原点も隅にはなく、baseline(ベースライン)によって決まります。baseline は書体全体の整列を支える基準線で、欧文ではふつう em グリッドの上から約 4 分の 3 の位置に置かれます。
baseline の上に、書体は順にいくつかの高さの線を定めていきます:
- cap height(大文字の高さ):上辺が平らな H で決めます(E や I でも可)。これは絶対の上限ではありません——丸い文字(O、C、G、Q、S)や尖った文字(A、V)は cap height と baseline をわずかに越えるのが普通で、これを overshoot(オーバーシュート)と呼びます。数学的な整列ではなく、視覚的な整列のためです。
- x-height(小文字の高さ):x(ときに o や n)で決めます。おそらく書体作りで最も影響の大きい決定で——書体の「見かけの大きさ」を決め、通常は cap height の 60–75% に取ります。x-height が高いほど読みやすく、同じサイズでも大きく見えます。Zuzana Licko が Emigre のためにデザインした Mrs. Eaves はわずか 57% で、のちの Mrs. Eaves XL は 72% まで引き上げられました。同じサイズで並べると差は驚くほどです。ただし効果には限界があり——高すぎると ascender と descender の区別がつきにくくなります。ある研究は最適値を視角およそ 0.3°(視角はサイズと距離の両方で決まり、実験では 40cm)とし、この範囲を超えると読む速さが落ち始めると報告しています。
- ascender/descender(アセンダー/ディセンダー):小文字が x-height の上、baseline の下へ伸びる部分に対応する整列線です。ascender はまっすぐなステムを持つ h、d、b、l で、descender は p、q で決めます。f や g のような曲線を持つ文字は、例によって overshoot します。
- そのほかに figure height(数字の高さ、通常は cap height と同じ)、small cap height(cap height と x-height の中間)、アクセント記号の高さ、上付き・下付き文字のベースラインシフトとスケールがあります。
幅について。proportional(プロポーショナル)フォントでは文字ごとに幅が異なり、monospaced(等幅)フォントではすべて同じです。1 文字が占める全幅は advance width = LSB + 字形の幅 + RSB。sidebearing(サイドベアリング)は各文字に組み込まれた余白のようなもので、隣の文字との距離を保ちます——kerning と混同しないでください。x-height が小さいほど、小文字は判読性を保つために大きめの sidebearing を必要とする傾向があります。condensed(コンデンス)系のフォントは逆に、全体を狭めます。
ウェイト、コントラスト、stress
weight(ウェイト)は直感的には線の太さですが、regular・semi-bold・bold が実際どれくらい太いべきか、そもそもこの名前でいいのかに標準はありません。標準に最も近いのは web で、CSS が regular を 400、bold を 700 と定めています。それ以外は各社バラバラです。
それでもウェイトは数値化できます。タイプデザイナーの Charles Bigelow は、x-height と縦ステムの太さの比で測ります。典型的な regular は 1:5–1:6 あたりです。em グリッドで考えると、x-height を 500 単位(0.5em)とすれば regular のステムは約 100 単位。隣り合うウェイトは線の太さが 1.3–1.5 倍違わないと見分けがつきません——一段上は約 130 単位、一段下は約 70 単位です。これは線形の目盛りですが、同じくデザイナーの Luc(as) de Groot はイージングカーブのような非線形の進行を提唱しています(原文は Inter のウェイト列を例に図示しています)。もちろん、どれも絶対の規則ではありません。
縦のステムと横のステムはふつう太さが違い、その差を contrast(コントラスト) と呼びます。差が大きければハイコントラスト、小さければローコントラスト、すべて同じ太さなら monolinear(モノリニア)です。ただし monolinear な書体でも、線は方向と曲率でわずかに太さを変えます。原因は thickness illusion(太さの錯視)——水平な線は同じ太さの垂直・斜めの線より太く見えるため、横のステムは少し削って釣り合わせるのが普通です。同じ補正は bowl(ボウル、閉じた曲線のストローク) にも適用されます。曲線の最も太い部分は縦ステムより太く、最も細い部分は横ステムより細くしないと、一貫して見えません。contrast が「どれだけ違うか」だとすれば、stress(ストレス) は「その違いがどの方向に現れるか」です。カリグラフィーでペン先が筆圧と速度によって線の太さを変えることに由来し、一つの書体の中では stress の軸を一貫させ、すべての文字が同じペンで書かれたように見せます。
視覚的な補正はいたるところにあります。double-story(二層構造)の文字(E、B、S)は、横棒を数学的な中央に置くと低く見えるため、少し上へずらします。ただ E や B ではそのずれが目立つので、今度は下の層を少し広げてバランスを取り戻します。
一文字の解剖学
文字のあらゆる部位に名前がついています。serif(セリフ) はストローク末端の小さな足です。横の部分を内側に反らせて錯視を打ち消したものは cupped serif と呼ばれます(EB Garamond がそうです)。形によってさらに、bracketed(曲線の支えでステムとつながる)、wedged(先細り)、slab(均一な太さ)、hairline(均一で極細)などに分かれます。セリフで終わらないストロークの末端は総称して terminal(ターミナル) で、teardrop(雫)、ball(球)、flare(フレア)などの装飾が付くことがあります。文字の上部だけに付く縦のセリフは beak、ステムの片側だけの横のセリフ(数字の 1 のような)は flag、baseline より下へ伸びるストロークは tail、装飾的な飾り筆は swash です。
文字の内側の閉じた・半ば閉じた空間は counter(カウンター) です——小文字 e のそれは特に eye、二層構造の g の下の輪は loop と呼ばれます。ほかにも長いリストがあります。i や j の点は tittle、f の曲がった頭は hook、n や m の曲線の接合部は shoulder、k や R の斜めの画は leg、E の横画は arm、s や 8 の中心の曲線は spine。ステム同士をつなぐ横画は crossbar、斜めの画が下で交わる点は vertex、上で交わる点は apex です。原文にはさらに長い用語集があります——ここでは最もよく使うものだけを残しました。
工芸の側:ネガティブスペースと最初の一画
スペーシング:主役はネガティブスペース
書体作りの労力のかなりの部分は、字形を描くことではなく、字形の間のネガティブスペースを磨くことに費やされます。スペーシングが可読性に与える影響は想像以上です。緩すぎると単語の中に「余白の川」が生まれて形をなさず、詰めすぎると文字同士が溶け合ってしまいます。理想は、どの文字ペアの間も視覚的な余白が等しいことです。一行のテキストが、腕を伸ばした距離では均一なグレーに、近くでは予測可能な縞のリズムに見える状態です。ネガティブスペースの多い文字(多くは counter の大きさに関係します)は、その分だけ間隔を詰める必要があります。業界の言い回しでは「spacing matches counters」(スペーシングはカウンターに合わせる)です。
道具は二つだけです。sidebearing と kerning。前者は各文字に組み込まれ、後者は特定の文字ペア(AV など)への追加補正で、理想的には sidebearing で対処しきれないときにだけ使います。文字ごとに sidebearing を決めるのは骨が折れるので、Walter Tracy が方法を残しています。形で分類して、値を共有するのです。まず H と O から始めます——一方は極端に直線的、他方は極端に丸い——「HHHOOHHH」「OOOHHOOO」のような組み合わせを試しながら、ステムのリズムが均一に見えるまで調整します。次に小文字の o と n で同じことをします。残りの文字は、最も形の近いものから値を借ります。B の左の sidebearing は H から(平らな辺)、右は O から(丸い辺)。A や w のような斜めの文字では公式が破綻するので、手作業で調整するしかありません。
検証方法は、すべての文字を他のすべての文字の間に置いてみて、視覚的リズムが乱れる箇所を探すことです。sidebearing だけでは解決できないペアが必ず残ります。たとえば Ti——i は T の張り出しの下に潜り込む必要があります。ここで kerning の出番です。特定の文字ペア用の間隔オフセットとして GPOS テーブルに保存され、run を組むときに参照されます。頻出ペアをすべて手作業で kern するのは膨大な作業ですが、OpenType は class-based kerning(クラスベースのカーニング)に対応しています。形の似た文字を「辺」でグループ化するのです——D、E、F は左辺がどれも直線なので、前に来る文字に対して同じ kerning 規則を共有できます。
一そろいの文字を、どこから描き始めるか
いよいよ字形を描く段になると、原文は「フクロウの残りを描け」の段階に入ったと自嘲しつつ、駆け足で進みます。デザイナーは A から Z へ順に描いたりはしません。まず数個の control letter(コントロールレター)を作り、stress・contrast・プロポーション・性格といった、他のすべての文字へ波及する決定を先に固めます。大文字では通常 O と H/E です。
O はとりわけ重要です。stress(斜めか垂直か)、contrast(太細の比率)、プロポーション(広い円か細い楕円か)を確立し、他のすべての丸い文字はそれに従います——C はおおよそ O の一部を切り取ったもの、G は横棒を足し、Q は尾を足し、D は右側をステムで閉じたものです。O を間違えれば、書体全体が崩れます。四角い基準に H を使う人もいますが、E のほうが便利です。terminal を備え、O や H より幅が狭いため、プロポーションの体系を立ち上げられます。E の三本の横画は、しばしば意図的に長さを変えます——下が最長、上が中間、真ん中が最短で、真ん中の画はわずかに中央より上へ。大文字は構造のグループごとに進めます。丸型(O、Q、C、G、S)、四角型(E、F、H、I、L、T)、斜め型(V、A、W、X)、それに丸と四角の複合(D、B、P、R)、斜めと四角の複合(M、N、K、Z、Y)です。
小文字はふつう a、e、g、n、o から始めます。理由は O と E の場合と同じです。定番のテスト単語「hamburgefontsiv」は高頻度の小文字をほぼ網羅し、形同士の相互作用をあぶり出します。o はボウルを持つすべての文字(a、c、e、p、d、b、q、g)の基礎で、contrast・stress・ボウルの比率を一貫させます。o のボウルが最も広く、c と e は開いていてネガティブスペースが多いぶん、狭めに作ります。ボウルとステムの接合部にはふつう小さな切り欠きを残し、これを relief と呼びます。n は m、h、u の基礎で、o よりわずかに狭く、r は n に似ていますが切り欠きをさらに低くします。最も分類しにくいのは、二層構造の小文字 a です。アーチは n の shoulder から借りられますが、終筆の処理が違い、下層のボウルの高さはふつう x-height の 55–65% に取ります。
覚えておきたいポイント
- フォントファイルはデータベースであって、図形の山ではない。アウトラインは一つのテーブルにすぎず、
cmap、hmtx、GSUB/GPOS、OS/2といったテーブルがあってはじめて、文字は検索され、組まれ、プラットフォームをまたいで一貫して描画されます。 - 二つの曲線、二つの技術系譜。TrueType は二次 Bézier(
glyf/loca)、OpenType/CFF は三次 Bézier と SVG 風の描画命令。variable fonts は master 間の補間で、デザインスペース全体を 1 ファイルに収めます。 - 組版はパイプライン。text shaping はまず run を切り、
cmap参照 →GSUB置換 →GPOS配置 → レンダリングの四段を通ります。ブラウザの HTML/CSS レイアウトと驚くほど同型です。 - type デザインは視覚的なごまかしの芸術。overshoot、thickness illusion の補正、上へずらした横棒——数学的な整列は、ほぼあらゆる場面で視覚的な整列に道を譲ります。
- スペーシングは字形より手間がかかる。可読性を決めるのはネガティブスペースです。まず sidebearing を形のグループで決めて基調を作り、kerning で例外を片付ける。hinting はかつて小サイズの鮮明さの生命線でしたが、高解像度画面とアンチエイリアスの前で、ほぼ役目を終えました。