アンチックフォントを作る: グリフの合成

はじめに
ここからは、AFDKO を使って、アンチックフォントを作成してみたいと思います。

アンチックフォントは、漫画のセリフで使われるフォントです。
漢字がゴシック体で、ひらがなやカタカナなどが明朝体となっています。

今回は、ゴシック体のフォントをベースにして、ひらがな・カタカナなどを明朝体のグリフで置き換えます。
使うのは、mergefonts, makeotf のコマンドです。

今回の例では、源ノ角ゴシック Medium と源ノ明朝 Bold を使います。
SourceHanSansJP-Medium.otfSourceHanSerifJP-Bold.otf を用意しておいてください。

なお、合成するフォントが TrueType の場合は、フォントの変換が必要になるので、少し複雑になります。
TrueType のフォントを合成したい場合は、FontForge などで OpenType に変換してから、合成したほうが良いでしょう。
TrueType の場合、em の単位が 1024 や 2048 などになっているので、1000 に変更した上で、すべてのグリフの座標を、それに合わせて縮小する必要があります。

まずは、グリフの変形などを行わず、そのままのグリフで合成する場合の方法を説明します。
グリフ名の取得
AFDKO のコマンドで任意のグリフを指定する場合、そのフォント内における、グリフ名や CID/GID で指定する必要があります。

spot コマンドでフォントの各情報を出力すると、Unicode からグリフ名を取得できますが、手動でやるのは大変なので、Python スクリプトを作りました。

>> make-ginfo.py
>> char2name.py

make-ginfo.py は、spot コマンドで出力した情報から、各グリフの情報をまとめたテキストを出力します。

char2name.py は、make-ginfo.py で出力したテキストを元に、指定文字のグリフ名をリスト化したり、各コマンド用のファイルを出力します。
フォント情報から、グリフの情報を出力
まずは、spot コマンドで出力したファイルの内容をまとめて、一つグリフ情報ファイルを作成します。
FONTFILE の部分は、合成するフォントのファイル名に置き換えてください。

## GID とグリフ名のマッピング情報

$ spot -nc FONTFILE > gid.txt

## Unicode とグリフ名のマッピング情報

$ spot -t cmap=7 FONTFILE > cmap.txt

## GSUB のグリフ置き換え情報

$ spot -t GSUB=7 FONTFILE > gsub.txt

## グリフ情報をまとめる

$ python3 make-ginfo.py gid.txt cmap.txt gsub.txt > ginfo.txt

グリフ情報は、合成する両方のフォントで必要となるので、SourceHanSansJP-Medium.otf と SourceHanSerifJP-Bold.otf でそれぞれ行ってください。

また、その際、出力ファイル名は、sans-ginfo.txt, serif-ginfo.txt などとしてください。

出力結果は以下のような形式で、各項目はタブで区切られています。

0    0    0    
1    1    20/A0    fwid:1396/hwid:63164
2    2    21    fwid:59047/hwid:63165

<グリフ名(CID/GID)> <GID> <割り当てられている Unicode> <GSUB 置換先のリスト> となっています。
char2name.py
char2name.py は、実行時にいくつかオプションを指定できるので、詳しくはファイルの中身を見てください。

char2name.py [options] <文字指定のテキストファイル名> <グリフ情報のテキストファイル>

最初の引数で、グリフ名を取得したい文字を記述した、テキストファイルを指定します。
グリフ情報のテキストファイルは、make-ginfo.py で出力したファイルです。

  • 文字指定のテキストは、UTF-8 のコードで作成してください。
  • "c:" で始まる行は、":" 以降に、文字そのものを連続して記述します。
    ただし、半角空白はスキップされます。
  • "u:" で始まる行では、Unicode の数値で文字を指定します。
    16進数の数値で指定してください。
    複数ある場合は、',' で区切ります。
    数値の間に '-' が含まれる場合、範囲の値を指定します。
  • それ以外の行は、スキップされます。

[例]
c:あいうえお ABCD 1234
u:3041-309f,30a0,31F0-31Ff
合成する文字の記述
では、実際に、今回合成対象とする文字(明朝体で置き換えたい文字)のリストを、テキストで記述します。
今回の場合は、ひらがな・カタカナと、一部の記号を対象とするので、以下のようにします。

[replace.txt] (UTF-8)
u:3041-309f,30a0-30ff,31f0-31ff,1b150-1b152,1b164-1b167
c:!?#$&"'()~
c:–—―‘’“”‥…′″※‼⁇⁈⁉、。〃〜〝〟〱〲〳〴〵〻〽
c:!"#&'()*,.:;?@{}~

増やしたり除外する文字がある場合は、編集してください。

なお、「〜」の文字が2つ存在しますが、この文字は、U+301C と U+FF5E で Unicode が異なります。
日本語 Windows (Shift-JIS) では U+FF5E、Linux では U+301C が使われます。
(OS の文字コードから Unicode の変換により、このような違いが生じます)
両方で同じグリフが割り当てられていることが多いですが、別のグリフになっている場合もあります。
char2name.py の実行例
まずは、char2name.py の実行例を紹介しておきます。

$ python3 char2name.py replace.txt serif-ginfo.txt
2-5,7-10,32,95,714-715,718-719,...

結果は、標準出力に出力されます。

オプションを指定しなかった場合は、AFDKO の各コマンドでグリフを指定するための、カンマで区切った1行のリストが出力されます。

-gid オプションを指定すると、CID の代わりに、GID を出力できます。
-cid オプションを指定すると、数字の前に '/' を付けて、CID 番号の指定とします (一部のコマンドでは、CID は "/12" というように指定する必要があります)。

なお、フォント内に、指定した Unicode 文字に割り当てられているグリフがない場合、そのグリフ名は出力されません。

OpenType/CID なら、CID の値。
TrueType なら、GID の値。
OpenType/CFF など、グリフ名で識別されるフォントの場合は、グリフ名の文字列となります。
mergefonts 用のマッピングファイルを作成
今回の場合は、mergefonts を使って、ゴシック体と明朝体のグリフを合成するので、mergefonts のマッピングファイルの形式で、グリフの変換先と変換元を指定する必要があります。
(mergefonts については以前に説明したので、詳細は省きます)

今回は、ゴシック体をベースフォントとして、一部のグリフのデータだけを明朝体に置き換えたいので、変換先はゴシック体フォントのグリフ名をそのまま指定し、変換元グリフは、明朝体フォントでのグリフ名を指定します。

char2name.py で -m オプションを付けると、mergefonts 用のマッピングファイルを出力できます。

$ python3 char2name.py replace.txt serif-ginfo.txt -g vert,hwid -m sans-ginfo.txt > merge-map.txt

mergefonts 用のマッピングファイルは、merge-map.txt に出力されます。
GSUB
-g <feature,...> オプションがある場合、ソース側(明朝体)の GSUB 情報を元に、指定 feature において、指定文字から置き換えられるグリフがある場合は、そのグリフもリストの対象に加えます。

feature は、"vert,vrt2" などです。
複数指定する場合は、',' で区切ってください。

たとえば、「ー」の場合、縦書き時はグリフのアウトラインが異なるため、GSUB の vert で別のグリフに置き換えられます。
mergefonts で横書きの「ー」グリフのみを合成した場合、縦書き用のグリフは元のフォントのままとなるため、横書きと縦書きでグリフが一致しなくなります。

そのため、特定の文字を合成で置き換えるのであれば、GSUB で置き換えられるグリフも、一緒に置き換えなければなりません。

今回の場合は、縦書き用のグリフを vert から、半角幅のグリフを hwid のデータから取得します。
-m
-m <dst-ginfo> で、変換元のグリフを、変換先の同じグリフに置き換えるための、mergefonts のマッピングファイルを出力します。
変換先のグリフ情報のファイルを指定してください。

今回の場合、変換先はゴシック体のフォントなので、make-ginfo.py で出力した sans-ginfo.txt を指定します。

なお、-g オプションがある場合、GSUB の置換グリフも対象となります。
CID のフォント辞書名
合成のベースとなるフォントが CID フォントの場合は、出力した mergefonts のマッピングファイルの1行目で、フォント辞書名を指定してください。

mergefonts Antique-Medium-Serif
...

とりあえず、名前は適当でも問題ありませんが、一般的には、"<PostScript名>-<文字種>" などとします。

源ノ角ゴシックであれば、各グリフのフォント辞書名は、文字種に応じて、"SourceHanSansJP-Medium-Kana" などとなっているので、本来であれば、それぞれのグリフを、元のフォント辞書に割り当てたいところですが、マッピングファイルを複数にしなければならなかったりと面倒なので、合成するグリフは、まとめて一つのフォント辞書にします。

なお、フォント辞書を指定しなかった場合は、変換元フォントでのフォント辞書名が使われます。
源ノ明朝であれば、グリフごとに、"SourceHanSerifJP-Bold-Kana" などのフォント辞書が追加されるような形となります。
(フォントを使う上では、そのような状態でも問題はありません)
mergefonts で合成
マッピングファイルが用意できたら、mergefonts コマンドを使って、ゴシック体のフォントに、明朝体の指定グリフを合成します。
※合成できるのはグリフのアウトラインのみで、OpenType フォントはまだ作成できません。

源ノ角ゴシックと源ノ明朝を合成する場合は、以下のコマンドを実行します。

$ mergefonts -cid cidfontinfo merge.cff merge-map.txt SourceHanSerifJP-Bold.otf SourceHanSansJP-Medium.otf 

CID フォントを作成するので、cidfontinfo ファイルが必要になります。
とりあえず、フォント名を "Antique"、スタイル名を "Medium" とした場合、以下のようになります。

[cidfontinfo]
FontName       (Antique-Medium)
FullName       (Antique Medium)
FamilyName     (Antique)
Weight         (Medium)
AdobeCopyright (Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'.)
Trademark      (Source is a trademark of Adobe in the United States and/or other countries.)
FSType         0
isFixedPitch   false
version        1.0
Registry       (Adobe)
Ordering       (Identity)
Supplement     0

次は出力ファイル名。その次が、明朝体のマッピングファイルと、フォント名です。
最後に、ゴシック体のフォントを指定します。

マッピングファイルと入力フォント名は、2つを対で指定します。
一つ前でマッピングファイルの指定がない場合は、すべてのグリフがそのままコピーされます。

mergefonts で複数の入力フォントを指定した場合は、先頭から順に処理されます。
いくつかの入力フォントで、変換先のグリフ名が重複した場合は、最初に処理したグリフが優先されます。
そのため、置き換えたいグリフを先にセットしておけば、それ以外のグリフは、後のフォントで埋められるような形となります。

今回の場合は、明朝体の指定グリフを先にセットしているので、残りのグリフはすべて、ゴシック体のフォントからコピーされます。

結果として、合成されたフォントは、Adobe-Identity-0 の CID フォントとして、merge.cff ファイルに出力されます。
ただし、このファイルには、基本的にアウトラインデータしか含まれていないので、この後、makeotf コマンドで、OpenType フォントを作成する必要があります。
makeotf で OpenType フォントを作成
最後に、OpenType フォントを作成するのに必要なファイルを用意して、makeotf コマンドでフォントを作成します。

同じディレクトリ内に、以下のファイルを配置してください。

- merge.cff (mergefonts で出力したファイル)
- FontMenuNameDB
- UniSourceHanSansJP-UTF32-H
- SourceHanSans_JP_sequences.txt
- features.JP

https://github.com/adobe-fonts/source-han-sans

源ノ角ゴシックのソースファイルから、以下のファイルをダウンロードしてください。

- UniSourceHanSansJP-UTF32-H
- SourceHanSans_JP_sequences.txt
- Medium/features.JP

CMap (Unicode と CID のマッピング)・異体字のマッピング・features ファイルは、源ノ角ゴシックの情報をそのまま使います。

FontMenuNameDB は、以下のような形で、フォント名を指定してください。

[Antique-Medium]
f=Antique
s=Medium
l=Antique Medium
makeotf コマンド
以下のコマンドを実行すると、Antique-Medium.otf ファイルが作成されます。

$ makeotf -f merge.cff -ff features.JP -ch UniSourceHanSansJP-UTF32-H -ci SourceHanSans_JP_sequences.txt -omitMacNames

カレントディレクトリに FontMenuNameDB ファイルが存在する場合、-mf FILE で FontMenuNameDB ファイルを指定する必要はありません。

なお、Adobe-Identity-0 の CID フォントを作成する場合、Mac 関連の警告が出ます。
源ノ角ゴシックの COMMANDS.txt で指定されているように、オプションを追加しておきます。

-omitMacNames で、name テーブルに、Mac 用の文字列を書き込みません。

Mac 用の CMap については、とりあえず必要ないので、無視しても構いません。

後は、実際にフォントを使ってみてください。