1月 03

GhostScriptでPDFをPNGに透過で書き出す際のおかしな挙動

名刺[55x91mm]に塗り足し3mmとトンボ9mmを追加したデータ[79x115mm]をTCPDFで作製し、それを画像化していたのですが、一定の解像度(400dpi)を超えると透過に失敗することが判明しました。
350と600で書き出したかったのですが、設計し直しですかね…

となみにスクリプトはPHPで、こんな感じ。

$command = sprintf("%s -q -dSAFER -dNOPAUSE -dBATCH -sDEVICE=pngalpha -dEPSCrop -r%d -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sOutputFile=%s %s",
(isset($_SERVER['WINDIR']) ? 'gswin32c' : 'gs'),
$dpi,
$to,
$from
);

11月 22

TCPDFで縦書きテキストをフォント埋め込みに対応させる

TCPDFで縦書きを実現するには、フォント設定ファイルの書き換えで実現するのが一般的です。
※ IPA明朝の場合

$type = 'cidfont0';
$dw = 1000;
$enc = 'UniJIS-UFT16-V';
$diff='';
//$file='ipam.z';
//$ctg='ipam.ctg.z';
$cidinfo=array('Registry'=>'Adobe', 'Ordering'=>'Japan1','Supplement'=>5);
include(dirname(__FILE__).'/uni2cid_aj16.php');

この方法ではAdobe ReaderまたはAdobe Acrobatでは、PostScriptで印刷ができません。
「文章を印刷できません。」
「印刷するページが選択されていません。」
と表示されて出力できません。
画像として印刷することはできますが、今一つな感じです。
Illustratorに読み込ませればアウトライン化されるので印刷に使用できるようになりますが、
ページが複数ある場合は現実的ではありません。

ちなみに、「Foxit」ではPostScriptのままで出力できるので、こちらを使用するのも手です。

要は、TCPDFで縦書きテキストを生成する際に指定するCIDフォントは非埋め込みであり、
これがPostScriptで印刷する場合に問題となるというわけです。
では、埋め込んで縦書きを実現してみる方法を探してみましょう。

まず、TCPDFの標準エンコードは「Identity-H」です。
この形式でないとフォントを埋め込めないというか、フォント埋め込み用の独自エンコードかもしれません。
PostScriptを弄っている人なら、末尾の「-H」が気になりますね。
これを変更するには、本体の「tcpdf.php」ファイルを書き換える必要があります。
メソッド「AddFont」に

} elseif ($type == 'TrueTypeUnicode') {
$enc = 'Identity-H';

というコードがあるので、「’Identity-V’」に書き換えてみましょう。
すると、なんということでしょう。
テキストが縦書きになりました。
もちろん、フォント設定ファイルは何も弄りません。
ただし、フォントは埋め込みの状態にしておきます。
非埋め込みでは化けます。

しかしよく見ると括弧やハイフンなどが横書き用のままです。
CIDフォントでは「uni2cid_aj16.php」をincludeすることでマッピングを変更しているのですが、
Identityでマッピングをしているところがまだよくわかりません。
おそらく、これを調整でいれば完全な縦書きを実現できるはずです。

もし参考頂き、対応方法を見つけられましたらご一報いただければ幸いです。
また、余裕があれば調査します。

4月 08

ゆうちょ銀行払い込み用紙印刷ライブラリ

お仕事の都合でゆうちょ銀行の払い込み用紙に印刷するライブラリを作ることになりました。
ベースになるのはTCPDFです。
とりあえずクラス化して、適当に放り込んでoutすれば印刷できちゃうものを作ろうと思います。
ちなみに振込ではなく、払込(払い込み)と呼ぶのが正しいようです。

1月 23

TCPDFでOTFフォントを使用する

PHPでPDFを扱うためのライブラリにTCPDFがあります。
TCPDFでOTFフォントを使用すると、AcrobatReaderでは正常に読めても、Illustratorで正常に読めず、テキストがラスタライズされて少々気持ちの悪い事態に遭遇することとなります。
Illutratorで開くことを想定しているなら、TCPDFで扱うフォントには少々の工夫が必要なので、ここに残しておきます。

まず、TCPDFで扱うフォントはTTFフォントで統一します。フォント名が同じであればTTFで作成したPDFでも、OTFフォントがインストールされた環境のIllustratorでも問題なく読むことが出来ます。

OTFフォントをTTFフォントに変換するにはFontForgeを使用します。
インストール方法を検索すると、Windowsのcygwin環境下でのインストール方法が沢山ヒットしますが、個人的にはうまくいかなかったので、LinuxのCentOS5を使用しました。アプリケーションはGUIでx11環境が必要なので、デスクトップ版を用意しましょう。
パッケージはhttp://sourceforge.net/projects/fontforge/files/fontforge-executables/から「fontforge-20090923-1.i386.rpm」をダウンロードします。少々古いものですが、特に問題ありません。ダウンロードが終わると、ファイルをダブルクリックするだけでインストールが始まり、あっさりと完了します。

アプリケーションはGUIなのですが、メニューには登録されませんのでファイルを直接起動するか、ターミナルから起動する必要があります。ターミナルで「fontforge」と入力して起動すると、読み込むファイルを要求されるのでTTFフォントに変換したいOTFフォントを選択します。

選択したOTFファイルの内容によってはCIDマップファイルが必要と言われるかもしれません。CIDマップファイルはhttp://fontforge.sourceforge.net/cidmaps.tgzにありますので、ダウンロードして展開したファイルを「/usr/share/fontforge/」にコピーします。

しばらくして読み込みが完了すると文字コード表が表示されるので、メニューより「CID>単一化」を選択してファイルを統合します。
そしてメニューより「ファイル>フォントを保存」を選択して、保存形式を「TrueType」に設定し、保存ファイル名を入力して保存すれば完了です。
これで変換作業は完了です。作成されたTTFファイルを開いて正常に読み込むことができれば成功です。

フォントファイルをTCPDFで扱える状態にする方法は、ライブラリ内のtcpdf/fonts/utils/README.TXTにある通りで問題ありません。むしろ他に方法がありません。
「$ ttf2ufm -a -F myfont.ttf」
「$ php -q makefont.php myfont.ttf myfont.ufm」
これで作成されたファイルをfontsディレクトリにコピーし、TCPDFよりPDFを作成すればAcrobatReaderでもIllustratorでも問題なく開くことが出来るPDFファイルの完成です。

いまいち文章が推敲されていないのでまとめます。

TCPDFはPDF作成ライブラリですごい
TCPDFのPDFはOTFフォントを使うとIllustratorでは読めない(ラスタライズされる)ことがある
TCPDFのPDFをIllustratorで読む可能性があるならOTFフォントをTTFフォントに変換しておく
OTFフォントをTTFフォントに変換するにはFontForgeを利用する
CIDマップがないとOTFファイルを展開できない(ことがあるかもしれない)

9月 29

TCPDF5.8.034のフォント指定の不具合

PHPでPDFを扱うにはまずTCPDF一択なわけですが、バージョンをよく見ると4.6.026という3年ぐらい前のソースなので新しくしようと思い立ちました。
動いていたので特に問題はないのですが、これだけ古いとどうかなという感覚的なものです。
最新版の5.8.034を入れて、動作を確認したところ、特に問題なし。
次のステップとして自前で用意したIPAフォントを指定したところ、処理が戻ってこないままタイムアウトになりました。
古い4.6に戻すと正常に出力されます。
新しい5.8にするとタイムアウトします。
だめだこりゃ。
別のバージョンで試すしかない。
どのミラーも最新版に更新されていて、最新版しか置いてない。
あちこち探し回った結果、発見したのが
http://ftp.heanet.ie/disk1/sourceforge/t/project/tc/tcpdf/OldFiles/
これで1つづつ遡りながら、動くバージョンを選ぶ作業に移ります。

時間をかけてマイナーバージョンごとに動作を確認して言ったのですが、どうも5.2から実装されたらしいサブセット埋め込みで不具合が発生している模様。
解説サイトでは5.4で解消されたと書いてあるけれど、検証していないみたいで実際に走らせるとタイムアウトになってしまう。
時間を大きくとれば言いなんて書いてあるけど、レスポンスが分単位なんて実際問題ありえないし、これは実装の不具合としか言いようがない。
結局、5.2の前のバージョン、5.1.002を導入してシステムを構築することにしました。