グリフを変形して合成
前回作ったアンチックフォントでは、ひらがな・カタカナが、縦書き時に少し大きく感じるので、ひらがな・カタカナのグリフを少し縮小したいと思います。
使うのは、AFDKO の rotatefont コマンドです。
rotatefont は、フォントのグリフを変形して、別のフォントに出力することができます。
フォントの変換を行う tx コマンドをベースにして作られているので、tx が対応しているフォントの読み込み・出力ができます。
なお、前回作ったアンチックフォントを元にして、任意のグリフを変形した後、そのグリフのみを再合成するやり方もありますが、今回は、源ノ角ゴシックと源ノ明朝を使って最初から合成します。
使うのは、AFDKO の rotatefont コマンドです。
rotatefont は、フォントのグリフを変形して、別のフォントに出力することができます。
フォントの変換を行う tx コマンドをベースにして作られているので、tx が対応しているフォントの読み込み・出力ができます。
なお、前回作ったアンチックフォントを元にして、任意のグリフを変形した後、そのグリフのみを再合成するやり方もありますが、今回は、源ノ角ゴシックと源ノ明朝を使って最初から合成します。
ひらがな・カタカナのグリフを変形して出力
まずは、源ノ明朝のひらがな・カタカナのグリフを変形して、そのグリフのみを含んだフォントを出力します。
各説明は後で行うので、とりあえず、hirakana.txt を用意した後、以下のコマンドを実行してください。
>> char2name.py (前回使ったものと同じ)
[hirakana.txt]
各説明は後で行うので、とりあえず、hirakana.txt を用意した後、以下のコマンドを実行してください。
>> char2name.py (前回使ったものと同じ)
[hirakana.txt]
u:3041-3096,30a1-30fa,31f0-31ff,1b150-1b152,1b164-1b167
## rotatefont 用のグリフ指定ファイルを出力 $ python3 char2name.py hirakana.txt serif-ginfo.txt -g vert -r 30 30 > rotate.txt ## 指定グリフを変形して出力 $ rotatefont -cff -row -matrix 0.94 0 0 0.94 0 0 -rtf rotate.txt SourceHanSerifJP-Bold.otf hirakana.cff
変形について
rotatefont では、回転角度とオフセット位置、または、変換行列を指定して、グリフの座標を変換できます。
今回はグリフの縮小を行うので、変換行列を使います。
今回の場合、グリフの幅は全角幅のままにして、グリフの形だけ縮小したいので、本来であれば、「変形前に、原点を左下からグリフの中央に移動して、その状態で縮小を行い、最後に原点を元に戻す」、というやり方が正しいのですが、rotatefont では、変形時の原点位置を変更することができないので、「原点は左下のままで縮小を行い、縮小によって減った幅分を余白として移動する」というやり方で行います。
位置を移動しないと、縮小した分、グリフが左下に寄ります。
今回はグリフの縮小を行うので、変換行列を使います。
今回の場合、グリフの幅は全角幅のままにして、グリフの形だけ縮小したいので、本来であれば、「変形前に、原点を左下からグリフの中央に移動して、その状態で縮小を行い、最後に原点を元に戻す」、というやり方が正しいのですが、rotatefont では、変形時の原点位置を変更することができないので、「原点は左下のままで縮小を行い、縮小によって減った幅分を余白として移動する」というやり方で行います。
位置を移動しないと、縮小した分、グリフが左下に寄ります。
縮小後の移動数
グリフの座標値は、1 em の単位を元に、数値がセットされています。
OpenType (CFF/CID) における 1 em は基本的に 1000 なので、1000 が全角幅となります。
今回は、グリフを 0.94 倍に縮小するので、縮小後のグリフ幅は、1000 * 0.94 = 940 となります。
グリフの送り幅(原点から次のグリフへの幅)は、日本語グリフであれば、ほとんどが全角幅の 1000 となるので、縮小によって減った幅は、1000 - 940 = 60 となります。
その減った幅を 1/2 にして、余白として移動するので、60 / 2 = 30 を、オフセット移動します。
OpenType (CFF/CID) における 1 em は基本的に 1000 なので、1000 が全角幅となります。
今回は、グリフを 0.94 倍に縮小するので、縮小後のグリフ幅は、1000 * 0.94 = 940 となります。
グリフの送り幅(原点から次のグリフへの幅)は、日本語グリフであれば、ほとんどが全角幅の 1000 となるので、縮小によって減った幅は、1000 - 940 = 60 となります。
その減った幅を 1/2 にして、余白として移動するので、60 / 2 = 30 を、オフセット移動します。
rotatefont 用のグリフ指定ファイル
rotatefont では、対象とするグリフを、-g LIST または -rtf FILE で指定できます。
グリフが多数の場合は、コマンドラインで指定するのは不便なので、今回はファイルで指定します。
1行で1つのグリフの情報を指定し、各行は空白で区切って、
「<入力グリフ名> <出力グリフ名> <変更する送り幅> <X offset> <Y offset>」の5つの値を指定します。
グリフ名は、CID の場合は 10 進数の値です。
送り幅は、元のグリフのままにしたい場合は、None を指定することができます。
X,Y の offset は、座標の相対移動幅です。
※フォントファイルには、常に .notdef のグリフが必要となるので、CID 0 も含める必要があります。
グリフが多数の場合は、コマンドラインで指定するのは不便なので、今回はファイルで指定します。
1行で1つのグリフの情報を指定し、各行は空白で区切って、
「<入力グリフ名> <出力グリフ名> <変更する送り幅> <X offset> <Y offset>」の5つの値を指定します。
グリフ名は、CID の場合は 10 進数の値です。
送り幅は、元のグリフのままにしたい場合は、None を指定することができます。
X,Y の offset は、座標の相対移動幅です。
※フォントファイルには、常に .notdef のグリフが必要となるので、CID 0 も含める必要があります。
char2name.py で出力
char2name.py で -r <xoffset> <yoffset> オプションを指定すると、rotatefont 用のグリフ指定ファイルを出力します。
xoffset と yoffset は、各グリフのオフセット移動幅です。
-g vert で、ひらかなの縦書き用のグリフも対象に加えています。
出力結果は、以下のようになります。
送り幅はすべて None (変更なし) とします。
また、グリフ名は変更しないので、同じ値をセットします。
1行目は .notdef (CID = 0) のグリフです。
.notdef は常に含める必要があるので、.notdef も同時に変形されてしまいますが、合成時に対象外とすればよいので、問題ありません。
'#' の行はコメントとなり、下のグリフの Unicode と文字、GSUB 置換の feature が記述されています。
各グリフを編集したい場合は、参考にしてください。
xoffset と yoffset は、各グリフのオフセット移動幅です。
-g vert で、ひらかなの縦書き用のグリフも対象に加えています。
出力結果は、以下のようになります。
送り幅はすべて None (変更なし) とします。
また、グリフ名は変更しないので、同じ値をセットします。
0 0 None 0 0 # U+3041 (ぁ) 1460 1460 None 30 30 # U+3042 (あ) 1461 1461 None 30 30 ... # U+31FF (ㇿ) <vert> 64621 64621 None 30 30
1行目は .notdef (CID = 0) のグリフです。
.notdef は常に含める必要があるので、.notdef も同時に変形されてしまいますが、合成時に対象外とすればよいので、問題ありません。
'#' の行はコメントとなり、下のグリフの Unicode と文字、GSUB 置換の feature が記述されています。
各グリフを編集したい場合は、参考にしてください。
rotatefont
rotatefont コマンドで、源ノ明朝の指定グリフを 0.94 倍に縮小し、CFF 形式で、hirakana.cff ファイルに出力します。
出力形式やファイル指定のオプションは tx コマンドと同じなので、tx -u でオプションを表示してください。
ファイルを2つ指定した場合、入力ファイルと出力ファイル名になります。
変形行列は、拡大縮小の場合は、a = X の倍率、d = Y の倍率となります。他はすべて 0 にします。
$ rotatefont -cff -row -matrix 0.94 0 0 0.94 0 0 -rtf rotate.txt SourceHanSerifJP-Bold.otf hirakana.cff
-cff | CFF 形式で出力します。 |
---|---|
-row | 送り幅を元のグリフのままにします。 ※ -matrix の前に指定してください。 |
-matrix a b c d e f | 変形行列のパラメータを6個の数値で指定します。 小数点以下有効です。 ※ -rtf の前に指定してください。 グリフの座標を (x,y) とすると、変形後の座標 (x', y') は、以下の式で計算されます。 x' = a * x + c * y + e y' = b * x + d * y + f |
-rtf FILE | 対象グリフをファイルで指定します。 |
出力形式やファイル指定のオプションは tx コマンドと同じなので、tx -u でオプションを表示してください。
ファイルを2つ指定した場合、入力ファイルと出力ファイル名になります。
変形行列は、拡大縮小の場合は、a = X の倍率、d = Y の倍率となります。他はすべて 0 にします。
psautohint
rotatefont でグリフを変形した場合、90 度単位の回転や移動などの単純な変形の場合は、変形後の形に合わせて、グリフのヒント情報が自動で再セットされます。
しかし、複雑な変形を行った場合は、グリフの現在のアウトライン座標を元に、ヒントを再計算する必要があります。
ヒントというのは、ヒンティングで使われる情報です。
フォントを小さいサイズで描画する時などは、アウトラインが潰れたりする場合がありますが、そうならないように、見栄え重視でアウトラインを調整するための情報となります。
AFDKO の psautohint コマンドを使うと、フォントの各グリフのヒント情報を、アウトラインから自動で判断して、セットできます。
コマンドにフォントファイルだけを指定すると、すべてのグリフが対象となり、ヒント情報をセットした後、フォントが上書きされます。
別のファイルに書き込みたい場合は、-o FILE オプションを付けます。
ヒントをセットするグリフを指定したい場合は、-g LIST, --glyphs-file FILE などで指定します。
今回の場合は、ひらかなのグリフを変形したので、rotatefont で出力したファイルのヒント情報を再計算して、上書きします。
しかし、複雑な変形を行った場合は、グリフの現在のアウトライン座標を元に、ヒントを再計算する必要があります。
ヒントというのは、ヒンティングで使われる情報です。
フォントを小さいサイズで描画する時などは、アウトラインが潰れたりする場合がありますが、そうならないように、見栄え重視でアウトラインを調整するための情報となります。
AFDKO の psautohint コマンドを使うと、フォントの各グリフのヒント情報を、アウトラインから自動で判断して、セットできます。
$ psautohint hirakana.cff
コマンドにフォントファイルだけを指定すると、すべてのグリフが対象となり、ヒント情報をセットした後、フォントが上書きされます。
別のファイルに書き込みたい場合は、-o FILE オプションを付けます。
ヒントをセットするグリフを指定したい場合は、-g LIST, --glyphs-file FILE などで指定します。
今回の場合は、ひらかなのグリフを変形したので、rotatefont で出力したファイルのヒント情報を再計算して、上書きします。
グリフの確認
一度グリフを確認したい場合は、fontplot コマンドなどで PDF を出力できます。
なお、グリフのヒント情報を確認したい場合は、hintplot コマンドを使います (使い方は fontplot などと同じ)。
なお、グリフのヒント情報を確認したい場合は、hintplot コマンドを使います (使い方は fontplot などと同じ)。
$ fontplot2 -o out.pdf -gpp 50 hirakana.cff
合成とフォント作成
次に、mergefonts でグリフを合成します。
「変形したひらかなグリフ」「変形しない明朝のグリフ」「ゴシック体」の3つに分けて合成することになります。
[others.txt] (UTF-8)
cidfontinfo は、前回使ったファイルと同じです。
まず最初に、"merge-hirakana.txt hirakana.cff" で、変形したひらかなのグリフをセットします。
次に、"merge-others.txt SourceHanSerifJP-Bold.otf" で、変形しない明朝の他のグリフをセットします。
最後に、残りのグリフを "SourceHanSansJP-Medium.otf" で埋めます。
「変形したひらかなグリフ」「変形しない明朝のグリフ」「ゴシック体」の3つに分けて合成することになります。
[others.txt] (UTF-8)
c:!?#$&"'()~ c: ゙ ゚゛゜ゝゞ・ーヽヾ c:–—―‘’“”‥…′″※‼⁇⁈⁉、。〃〜〝〟〱〲〳〴〵〻〽 c:!"#&'()*,.:;?@{}~
cidfontinfo は、前回使ったファイルと同じです。
## ひらかなのグリフのマッピングファイルを出力 $ python3 char2name.py hirakana.txt serif-ginfo.txt -g vert -m sans-ginfo.txt > merge-hirakana.txt ## 変形しない明朝のグリフのマッピングファイルを出力 $ python3 char2name.py others.txt serif-ginfo.txt -g vert,hwid -m sans-ginfo.txt > merge-others.txt ## (merge-*.txt の1行目にフォント辞書名を記述) ## 合成 $ mergefonts -cid cidfontinfo merge.cff merge-hirakana.txt hirakana.cff merge-others.txt SourceHanSerifJP-Bold.otf SourceHanSansJP-Medium.otf
まず最初に、"merge-hirakana.txt hirakana.cff" で、変形したひらかなのグリフをセットします。
次に、"merge-others.txt SourceHanSerifJP-Bold.otf" で、変形しない明朝の他のグリフをセットします。
最後に、残りのグリフを "SourceHanSansJP-Medium.otf" で埋めます。
makeotf で OpenType を作成
後は、前回と同じように、makeotf で OpenType フォントを作成します。
$ makeotf -f merge.cff -ff features.JP -ch UniSourceHanSansJP-UTF32-H -ci SourceHanSans_JP_sequences.txt -omitMacNames