Apache FOPで日本語システムフォントを使う
長らくApache FOPでOpenTypeフォントが使えないかと実験していたのですが、やっとその方法を発見しました。
Apache FOPというのはXSL-FOの処理系で、XML文章を整形してPDFを書き出すことができます。ポイントは、
- サーバーサイドで動く
- XSLTを使って「文章本体」と「スタイル」を分離できる
- 1度作ったスタイルは他の文章にも使い回せる
- WikiFormeを使えばXMLはWiki記法で書けるよー
- XSLTを直接書くのはやってられないけど、WikiFormeでXSLT記法を作れば解決!
などなど、なかなか夢広がります。
例に漏れずフォント方面が鬼門で、現状ではType1フォントかTrueTypeフォントしか使えません(TrueTypeでも使えるようにするまでに結構難儀します)。しかし、ぜひともOpenTypeフォントが使いたい。Mac OS Xに標準搭載されているヒラギノ、Adobe Creative Suiteに入っている小塚、りょうフォントファミリーは、どれもOpenType(中身がPostScriptのタイプ)になっています。
Apache FOPはJavaで書かれているのですが、AWTを使ってディスプレイに出力するオプションがあります。このときはJavaの機能を使ってフォントをレンダリングしているらしく、OSにインストールされているフォントがそのまま使えます。さらに、これをそのままプリントする機能も実装されています。そこで、プリンターにPDFプリンタを使えば、PDFが出力されます。
具体的なコマンドラインは↓こんな感じです。(苦労した割には、意外と簡単にできたんだなぁ…)
$ fop xsl-fo-file.xml -print
これでデフォルトのプリンタから印刷されます。デフォルトプリンタはあらかじめPDFプリンタにセットしておけば、(Mac OS X + Acrobat Distillerなら)デスクトップにPDFファイルが出力されます。プリントダイアログは表示されないようになっていて、各種オプションや、出力先のディレクトリやファイル名は変更できません。
さて、本題はここからで、このままではいろいろと問題があります。
まずAcrobat Disitllerですが、おそらくはGhostScriptも使えると思います。要するにJREがプリンタと認識できる何かであればOKなハズ。となれば、Linux + Apachoe FOP + JRE + CUPS + GhostSciprt(cups-pdf)でPDFが作成できるはず。
出力先ファイル名は "FOP Document" に固定されています。Mac OS XのAcrobat Disitillerのデフォルトの出力先ディレクトリはデスクトップになっているので、~/Desktop/FOP\ Document.pdfに出力されます。この"Fop Document"は、java.org.apache.fop.render.print.PrinterRender.javaの中で設定されているので、ここを書き換える or 外部から設定可能にすれば解決しそうです。
描画にAWTを使っているので、おそらくX11は必須になると思います。そこはXvfbでごまかせば何とかなるはず。
※追記:X11は無くても大丈夫でした。
あとは、X.orgとJREは既にOpenTypeフォントに対応している…と思う(最悪対応していなくてもメトリクスだけ分かればうまくいく気がする。FontForgeでTrueTypeに変換しても大丈夫かな)。GhostScriptはOpenType対応済み。
というわけで、
- Apache FOP + cups-pdfでPDFを作成する手法を確立する
- XSL-FOを勉強して手中に収める
- WikiFormeのarticle.4me記法バンドルにメソッドを追加して、スタイル付けしやすいXMLを出力できるようにする
- 出力されたXMLにXSL-FOスタイルを適用するXSLTを、CSS風の分かりやすい記法で書けるようにするためのWikiForme記法バンドルを作る
と言う流れで、Wiki記法→PDF変換が実現できそうです。WikiForme→SmartDoc→TeXで作成した、なんとも「TeX風」なPDFではなく、キレイに整形したPDFが出力できるはず!
サーバーサイドで自然言語からPDFを自動組版する需要があるのかどうかはサッパリ不明。WYSIWYGよりマークアップ言語の方が使いやすいと思う派閥のためのドキュメント作成ツール? 高品質なデザイナー's XSLスタイルファイルのようなものが作成できれば、誰でも高品質な組版ができてハッピーかも。(日本語特有に処理は苦しい?)
しかし先は長そうだー
※追記 :
わざわざ印刷しなくても、Javaから直接PostScriptに変換できるのではなかろうか。そこからGhostScriptでPDFへ。できそうな気がする。iTextを使えば直にPDFも生成できる?
逆にApache FOPがわざわざフォント周り等々を自前で実装しているのが気になるところ。実はAWTに任せるとラスタライズされてしまうとか?うーむ、ありそう。要調査。