FontForge スクリプトのチュートリアル

説明をとても解りやすくするつもりではありますが、ここでプログラムを教えるつもりはありません

簡単な例

(PFB と AFM が対になった) Type1 形式の PostScript フォントがあって、それを TrueTypeフォントを変換したいものとしましょう。これを行うのにはどのようなスクリプトを書けばいいのでしょう?

これを UI 上で行う場合には、フォントを ファイル((F)→開く(O) で開き、続いて ファイル((F)→フォントを出力(G)... で TrueType フォントを書き出します。スクリプトを書く時には、これと本質的に同じ事を行うことになります。

とりあえずの解決法

Open($1)
Generate($1:r + ".ttf")

大体において、メニューコマンドと同じ名前のスクリプト関数が存在します (まあ、英語メニューのコマンド名と同じ物だけですが)。

'$1' はおまじないです。これはスクリプトに渡す最初の引数の意味です。

'$1:r + ".ttf" ' はずっと複雑なおまじないです。その意味は、「最初の引数 ($1) を取り、拡張子 (おそらく ".pfb" ) を削除し、文字列 ".ttf" をファイル名に付け加える」というものです。

スクリプトコマンド Generate は、どのタイプのフォントを出力するかを与えられた拡張子によって決定します。この例では“ttf”なので TrueType を指定しています。

AFM ファイルを読み込むように指定していないことに注意して下さい。これは、Open コマンドが PFB と同じディレクトリにあるかどうかを自動的にチェックしているからです。

実世界で考慮すべき事柄

スクリプトがどのようなものかについて説明しました。これを実用的な物にするには、このデータを格納する専用のファイルがおそらく必要でしょう。“convert.pe”という名前のファイルを作成し、上記のスクリプトをそれに格納します。

しかし、それを遥かに有用な物にするために、スクリプトの先頭に 1 行のコメント行を追加するべきです (コメント行とは文字‘#’で始まる行のことです)。

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

このように記述したならば以下のようにタイプします:

$ chmod +x convert.pe

このコメントは FontForge にとって重要ではありませんが、Unix シェルでは意味があります。これについては次のセクションで説明します。

スクリプトの起動法と引数の指定方法

OK, これで基本的なスクリプトができました。使うにはどうするのでしょうか?

まあ、以下のようにタイプして FontForge に直接渡すこともできますが、

$ fontforge -script convert.pe foo.pfb

前述のコメントを追加しているならば、以下のようにタイプすれば十分です:

$ convert.pe foo.pfb

この場合シェルは、スクリプトを処理するために FontForge を呼び出すことを知っています。

ループの使い方

これでどこにも問題は無いのですが、多数のフォントを変換したいとなった時には、それは面倒な作業となるでしょう。そういうわけで、多数のファイル名をとるように変更し、一度にそれらを処理できるようにしましょう。

#!/usr/local/bin/fontforge
i=1
while ( i<$argc )
  Open($argv[i])
  Generate($argv[i]:r + ".ttf")
  i = i+1
endloop

ここで我々は $argc$argv という変数を導入しました。前者はこのスクリプトに対して指定した個数を単に表し、後者はそれらの引数をすべて含む配列ですから、$argv[i] は i 番目に指定した引数ということになります。

次に、以下の記述が現れます:

i=1

これは、“i”というローカル変数を用いることを宣言し、それに値 1 を代入しています。

while ループは“"while”キーワードと“endloop”キーワードの間にあるすべての文を、条件 (i<$argv ) が真である限り実行します。言い替えれば、まだ変換を行うべき引数が存在する限り、このループは実行され続けます。

これにより、我々はこのスクリプトを

$ convert.pe *.pfb

または何らかの同様のコマンドにより実行することができます。

より複雑な例

ここで、Type1 フォントから TrueType への変換に加え、TrueType フォントを OpenType フォントに変換することができるスクリプトが必要になったとしましょう。ではこのスクリプトをもっと複雑にしてみましょう:

#!/usr/local/bin/fontforge
i=1
format=".ttf"
while ( i<$argc )
  if ( $argv[i]=="-format" || $argv[i]=="--format" )
    i=i+1
    format = $argv[i]
  else
    Open($argv[i])
    Generate($argv[i]:r + format)
  endif
  i = i+1
endloop

そして、このスクリプトの起動法は以下のようになります:

$ convert.pe --format ".ttf" *.pfb --format ".otf" *.ttf

ここでは、format という新しい変数を導入しています。これは、そこから先で使用する出力形式を表します。この値はまず TrueType の“.ttf”で初期化されますが、ユーザが“--format”(または“-format”) という引数を指定したならば、どんな出力形式にでも、ユーザが指定して切り替えることができます。

ここで新しく“if”を付け加えています。この文は、条件 ( $argv[i]=="-format" || $argv[i]=="--format" ) が真である場合に“if”と“else”の間の各文を実行し、偽の場合には“else”と“endif”の間の各文を実行します。 || 演算子は“または”を意味しますので、この条件文は $argv[i] が“-format”または“--format”のどちらかである時に真になります。

実際には、以下の事を確認するために、いくつかのエラーチェックを行う必要があります:

#!/usr/local/bin/fontforge
i=1
format=".ttf"
while ( i<$argc )
  if ( $argv[i]=="-format" || $argv[i]=="--format" )
    i=i+1
    if ( i<$argc )
      format = $argv[i]
      if ( format!=".ttf" && format!=".otf" && \
	  format!=".pfb" && format!=".svg" )
	Error( "Expected one of '.ttf', '.otf', '.pfb' or '.svg' for format" )
      endif
    endif
  else
    Open($argv[i])
    Generate($argv[i]:r + format)
  endif
  i = i+1
endloop

長い行が含まれているため、バックスラッシュを用いて 2 行に分割していることに注意してください。通常行末は文の終わりを表しますので、バックスラッシュを用いて次の行まで文が続いていることを示す必要があるのです。

これで、TrueType から PostScript フォントを変換したい場合にも、正しく出力ができるようになりました。しかし、この変換をより改善することができます:

#!/usr/local/bin/fontforge
i=1
format=".ttf"
while ( i<$argc )
  if ( $argv[i]=="-format" || $argv[i]=="--format" )
    i=i+1
    if ( i<$argc )
      format = $argv[i]
      if ( format!=".ttf" && format!=".otf" && \
	  format!=".pfb" && format!=".svg" )
	Error( "Expected one of '.ttf', '.otf', '.pfb' or '.svg' for format" )
      endif
    endif
  else
    Open($argv[i])
    if ( $order==2 && (format==".otf" || format==".pfb" ))
      SetFontOrder(3)
      SelectAll()
      Simplify(128+32+8,1.5)
      ScaleToEm(1000)
    elseif ( $order==3 && format==".ttf" )
      ScaleToEm(2048)
      RoundToInt()
    endif
    Generate($argv[i]:r + format)
  endif
  i = i+1
endloop

TrueType はその性質上、PostScript よりも多くの点を含む傾向があります。しかし、Simplify コマンドを用いれば、あるフォーマットから別のフォーマットへの変換を行う際に、点の個数を減らすことができます。また、TrueType フォントが em あたりユニット数が 2 の冪であるべきなのに対し、PostScript フォントは em あたり 1000 ユニットであるべきです。最後に、TrueType フォントは点の座標に整数値 (また、ある場合には半整数値) しか使用することができません。

その他の実例

Type1 フォントにアクセントつき文字を追加する

Unicode で定義されたアクセントつき文字の全範囲を含んだ Type1 フォントはほとんどありません。FontForge を使えば、Type1 フォントを読み込み、フォントが許す限り (フォントにオゴネクが含まれていなければ、FF はオゴネクつき A を作成することはできません) できるだけ多くのアクセントつき文字を追加することは簡単です。

#!/usr/local/bin/fontforge
Open($1)
Reencode("unicode")
SelectWorthOutputting()
SelectInvert()
BuildAccented()
Generate($1:r + ".otf")

Type1 フォントと Type1 エキスパートフォントを併合し、適切な GSUB テーブルを作成する

かつて Adobe は通常フォントを含むフォントパックと、小型大文字・ノンライニング数字などを含む“エキスパート”フォントを含むフォントパックを出荷していました。現在では、それらはすべて、適切な GSUB 項目によってグリフ同士にリンクが張られた 1 個の OTF フォントに詰め込まれています。

#!/usr/local/bin/fontforge
Open($1)
MergeFonts($2)
RenameGlyphs("AGL with PUA")
SelectAll()
DefaultATT("*")

より多くの例

スクリプト処理に関するページを参照してください。