Romantic Irony

好きなこと・気になったことについて書いていきます!

Ghostscript(PostScript)でフォントデザイン

イントロ

今回は呉高専エンジニア勉強会 Advent Calendar 2017の4日目の記事です。呉高専OBで信州大学B3のNonKuRuです。というわけでアドベントカレンダーに参加することになったので、急遽何か良い題材はないかなと考えたところ思いつかなかったのでGhostscript(PostScript)という言語でフォントデザインをしてみることにした。

Ghostscript(PostScript)とは

そもそもPostScriptに馴染みのない人や初めて聞いたという人も多いと思うので、少し説明する。PostScriptは、画像編集ソフトのPhotoshopIllustrator、動画編集ソフトのPremiere ProやAfter Effectなどで有名なAdobe社によって開発されたページ記述言語のひとつである。

印刷するページ内の文字や画像のようなデータの位置、サイズ、色などをプログラム言語として記述できる。この記述されたスクリプトファイルとPostScriptに対応するソフトウェアとプリンタを使用すれば同じ印刷結果を得ることができる。そのためドキュメントが正確にプリントされることにシビアであるDTPの分野ではグローバルスタンダードとなっている。

コンピュータ黎明期はPostScriptで記述した図形をプリンタで実際に紙に印刷して確認していたが、それをモニタ上でも確認したいということでPostScriptのコードをグラフィックとして表示してくれるIllustratorが開発された。同様にAdobe社が開発したPDF(Portable Document Format)は、PostScriptをベースにして透明やレイヤといった概念も加えた新しいドキュメントフォーマットである。

そしてそのPostScriptをフリーソフトウェアとしたものがGhostscriptである。このGhostscriptは科学研究分野で論文記述のための組版システムとしてよく使用されているTEX(テフ)でもPDFへの変換ソフトとして使用されている。そのためTEXもしくはLATEXがインストールされた環境ではGhostscriptが使える状態になっていると思われる。

簡単な例

実際にどのように記述していくか見ていこうと思う。

・簡単な計算(1)
1 + 3 =これをGS(Ghostscript)で計算するには1 3 add ==と記述する。

・簡単な計算(2)
1 + 3 - 2 =これをGSでは1 3 add 2 sub ==と記述する。

この2つの例からわかるように、GSはスタック指向型の言語である。つまり「add」や「sub」や「==」のようなオペレータが記述されるまで数値は順にスタックにプッシュされ、オペレータが記述された時点までの値と命令の内容によって計算し、その解をこれまた一旦保持し最終的に「==」で計算結果が出力される。ただしオペレータの前に3つ以上数値がプッシュされた状態では最後にプッシュされた2つまでしか計算されずそれ以前にプッシュされた数値はスタックに保持されたままになる。

つまり、1 2 3 add ==の出力結果は 「5」になる。全て加算したい場合は1 2 add 3 add ==もしくは1 2 3 add add ==となる。

以上のことがわかった上で、実際に図形を描画していく。

・直線の描画(相対位置の指定:rmoveto, rlineto)
f:id:n0x2ca:20171203013603p:plain

newpath  
100 200 moveto  
100 100 rmoveto //カレントポイント(描画開始位置を移動)  
200 300 lineto  
250 400 rlineto   //直線描画  
stroke  
showpage  

・直線の描画(幅と色の指定:setlinewidth, setrgbcolor)
f:id:n0x2ca:20171203012604p:plain

newpath  
100 100 moveto  
70 setlinewidth                        //線幅の指定  
100 100 rlineto  
1 0.5 0.3 setrgbcolor stroke   //RGB色の指定  
stroke  
showpage  

・円弧の描画(中心を指定する方法:arc, arcn)
cx cy radius ang_begin ang_end arc //中心 半径 開始角度 終了角度

・円弧の描画(接線を指定する方法:arcto)
px1 py1 px2 py2 radius arcto //2つの接戦を表すための3点と半径を指定

ベジェ曲線の描画(4点の制御点による曲線の描画:curveto)
px1 py1 px2 py2 px3 py3 curveto

・パスを塗りつぶす(fill)
f:id:n0x2ca:20171203014755p:plain

newpath  
140 300 moveto  
100 400 350 400 250 300 curveto  
20 setlinewidth  
0.6 1 0.6 setrgbcolor  
fill  
showpage  

・参考

算術オペレータ 意味 スタックオペレータ 意味
A B add 加算 clear 削除
A B sub 減算 pop ポップ
A B mul 乗算 exch 1番目と2番目を交換
A B div 除算
A B idiv
A B mod 剰余
A B neg 符号反転

オリジナルフォント

今回は「1018」をオリジナルフォントで表現してみた。このフォントのコンセプトは「実用性は完全無視で認知できる最小限の筆の軌跡」である。以下にそれぞれのソースコードも載せておく。
f:id:n0x2ca:20171203021740p:plain

「1」のソースコード

newpath
250 100 moveto
10 setlinewidth
350 100 lineto
300 400 moveto
300 500 lineto
250 450 lineto
0 0 0 setrgbcolor
stroke
showpage

「0」のソースコード

newpath
300 100 moveto
10 setlinewidth
400 100 450 150 450 300 curveto
300 600 moveto
200 600 150 550 150 400 curveto
0 0 0 setrgbcolor
stroke
showpage

「8」のソースコード

newpath
10 setlinewidth
300 200 150 130 320 arc
stroke
newpath
300 500 150 300 150 arc
0 0 0 setrgbcolor
stroke
newpath
250 420 moveto
350 250 lineto
stroke
showpage

アウトロ

今回はプログラミングでフォントデザインをしてみたが、これは実用的かと問われるとその道を極めたい人以外はあまりないと思うので、テクニカルな遊びとして楽しんでもらえると良いのではないかと思う。