PDFlib HOWTO

e-mail: pdflib @ hykw.tv

$Id: index.html,v 1.111 2009-04-09 13:08:20 cz Exp $

目次

PDFlib とは

PDF は世界中の政府機関や企業で使われており、電子文書ファイルの事実上の標準となっています。EC サイトで商品の見積もりや購入を行った際に、見積書や請求書などが PDF として送付(あるいは表示)されることもまったく珍しくありません。

現在のところ競合するフォーマットは存在せず、PDF はますます広く使われていくことが確実ですが、氏名や商品などの項目を動的に設定して PDF を生成したいと思ったことは無いでしょうか? いくつかの会社から PDF 化を行う製品が出ていますが、その中でもこの文書内で言及する PDFlib は、Windows は言うまでもなく、非 Windows 環境(特に Unix や Linux)での PDF生成に最適なライブラリです。

PDFlib は主要な OS, 言語に対応しており、自分の使っているOS, 言語に PDFlib が対応していないということはほとんどありません。VB, VC++, C#, .NET, Java, PHP, Perl, RPG, COBOL, Python, Tcl などに標準で対応しており、また OS は Windows, Linux, MacOS, FreeBSD, OpenBSD, AIX, HP-UX, Solaris などに加え、System i(旧AS/400) や System z(旧S/390) ですら対応しています。特に PHP との相性はバッチリで、非常に使いやすいです。PDF出力と言えばPDFlib と言ってしまっても言い過ぎではないと思います。

なお http://pdflib.com/jp/http://pdflib.jp/ はまったく同じコンテンツが表示されます。

codeなにがし のPDFlib にも、PDFlib に関する各種サンプルプログラムがありますので、参考にしてみてください。

▲目次

PDFlib でできること

普通のファイルを PDF に変換することを除き、PDFlib は PDF に関して行いたいであろうことの、ほとんど全てを行うことができます。

PDF 関連で必要となりそうな一般的な機能は、基本的には下記の3種類に分けられるかと思います。

  1. 既存ファイルの PDF 化(Adobe Acrobat などを利用) → PDFlib では出来ない。
  2. PDF ファイルの動的生成(PDFlib, PDI, PPS で可能)
  3. 既存 PDF ファイルを読み込み、住所や氏名、商品名など、好きな文字を上から付け加えて、PDF ファイルを再生成(PDI, PPS で可能)

「既存ファイルの PDF 化」は PDFlib ではできませんが、それを行いたいのであれば Adobe Acrobat や Office 2007 を利用すればよいだけです。

筆者自身、Linux の PHP で「雛形となる PDF ファイルを元に、氏名や住所などのユーザの入力項目を動的に埋めて PDF を生成する」ことが必要となった際には必ず PDFlib(実際には PDI か PPS)を利用していますが、速度や使い勝手が非常に良く、また機能と比較すると高価でもないため、非常に気に入っています。

フリーの PDF 生成ソフトもいくつかありますが、日本語の扱いが面倒であったり、「①」や「髙」などの機種依存文字や外字がうまく利用できなかったりするので、時間を買う(あるいはトラブルが発生した時のリスクヘッジ)と思えば、非常に安価では無いでしょうか(ハマり方にもよりますが、フォントやら文字コードやらでハマると*ものすごく*大変なので、個人的にはなるべく関わりたくないです(笑))。

ただ学生や個人用途など、時間や手間・苦労よりもコストが安い(かからない)ということが重要な場合には非常に便利ですので、適材適所で使い分けるのがいいかと思います。

なお自分が知る限り、PDFlib+PDI や PPS のように、既存の PDF ファイルを読み込み、文字列や画像を差し込んで PDF を再生成することが可能なフリーソフトは存在しません(知っていたら教えてください :-)。

▲目次

PDFlib 製品群

2007年8月時点では、下記の製品があります。

PLOP/TET/pCOS は単体で動作するアプリケーションのため、ちょっと毛色の違う製品なのですが、PDFlib, PDFlib+PDI, PPS は実際には同一のバイナリーファイルで提供されています。

PDFlib のバイナリーファイルにはすべての機能が含まれており、設定するライセンスキーにより、使用できる機能が決まってくることになります。ライセンスキーを設定しない状態(試用モード)では、PDFlib/PDI/PPS の全機能(全関数)が使用できます。

製品名 使用できる機能
PDFlib PDFlib の機能が使用可能
PDFlib+PDI(もしくはPDI とも言う) PDFlib と PDI の機能が使用可能
PDFlib Personalization Server(もしくは PPS とも言う) PDFlib と PDI と PPS の機能が使用可能

▲目次

PDFlib

線や絵の添付、文字の出力、フォントの指定など、PDF(というか書類?)を作成する上で必要となりそうな機能は全部あります。

ただ PDFlib だけだと、空の状態の PDF に白紙のページを追加していき、その上に線や文字などを一から指定して書いてあげる必要があるため、請求書などの自動生成という用途には使い辛いと思います。線や文字等の座標をプログラムで指定するのは、非常に面倒です。例えば 公文書公開請求書 のような PDF を、いちいち座標を指定して全ての線や文字を指定することを想像してみてください。綺麗な PDF を作ろうとすればするほど大変です。

当然ですが、PDFlib では PDFlib+PDI や PPS の機能(関数)を使うことはできません。

▲目次

PDI(PDFlib+PDI)

PDI は既存の PDF ファイルを読み込み、文字や画像などを追加して PDF ファイルを再生成することができます。そのため、あらかじめ雛形となる PDF を Adobe Acrobat のような製品で作成しておき、その PDF のページに氏名や住所などの項目を指定、というような使い方が非常に簡単に実現できます。

ただし、まだこれでも追加する文字列や画像は、座標を指定して出力する必要があります。そのため雛形の PDF ファイルのデザインをちょっと変えたときには、プログラムの座標を指定している部分もいじってあげなきゃならないため、ちょっと面倒です。

PDI には PDFlib の機能が含まれます。

▲目次

PPS

PPS では雛形となる PDF を作成する際に、「ブロック」というテキストボックスみたいなものを PDF のページ内に指定しておき、プログラムでそのブロックに文字などを埋めることができます。

例えば氏名や住所といった項目にブロック(下記の NAME や ADDRESS など)を指定し、プログラムからそのブロックに表示したい値を設定して PDF を再生成することが可能になります。文字の表示位置やフォント、サイズ、色などは、ブロックのプロパティで指定することができます。

  氏名: |NAME             |
  住所: |ADDRESS                        |
  電話: |  TEL1| - |TEL2| - |TEL3|

雛形の PDF を作る人はプログラムで埋めてもらいたい項目にブロックを設定しておくだけで、ブロックの位置やフォントなどは PDF を編集する人がいつでも自由に変更することができます。

Web 系のプログラムでは HTML とプログラムの分離を行うことが増えてきていますが、PPS のブロック機能を利用することで、「PDF をデザインする人」と「PDF を生成するプログラムを作る人」とで、デザインとプログラミングの分離を行うことが可能となります。

分離することのメリットが見えないですか? 雛形 PDF のデザインもプログラミングも一人でやってしまっていると、そのメリットが見えにくいかもしれませんね。ただ、例えば氏名と住所の順番を入れ替えたり、位置をちょっと変更したとしたらどうでしょうか。PDF をちょっといじる度にプログラムもいちいち変更することが苦になりませんか? PDF を編集する人とプログラミングを行う人が別だった場合、なおさらですね。

PPS には PDFlib および PDFlib+PDI の機能が含まれます(つまり全機能/全関数を利用することができます)。

▲目次

PLOP

PLOP は PDF ファイルにアクセス制限(印刷不可、編集不可など)をかけたり暗号化することができます。他の製品とはちょっと方向性が違い、コマンドラインからバッチ的に実行できるようになっています(もちろんライブラリも付いています)。複数の PDF ファイルに一度でまとめてアクセス制限をかける時に便利です。価格も PDFlib 単品よりもさらに安価です。

新製品の PLOP DS では従来の PLOP の機能に加え、ついに待望の電子署名機能が付きました。既存の PDF ファイルに Adobe Acrobat や Adobe Reader の標準の機能で検証可能な電子署名をすることができます。

▲目次

TET

TET は PDF ファイルから文字列などを抜き出し、テキストファイルや XML として出力することができるツールです。英数字に対応したツールはいくつかありますが、TET は日本語や Unicode に完全対応しているため、日本人が使うにはとても便利です。PDF の全文検索や、PDI と組み合わせて既存 PDF ファイルに透明テキストを自動追加する処理などに使うと便利ではないでしょうか。

TET に関しては別途ページを用意しました。PDFlib TET について をご参照ください。

▲目次

PDFlib7 について

2006年10月6日に、PDFlib の新バージョンである PDFlib 7 がリリースされました。新機能の紹介や使い方などについては、今後ここに追記していく予定です。なお、PHP4.3.0未満のバイナリーファイルはリリースされていないので、注意する必要があります(4.3.0 未満で使う場合、よっぽど古いバージョンの PHP でなければ、DSO 版 PDFlib の自前ビルド の手順で、簡単に生成することが可能です)。

主な機能追加としては、テーブルを作成する新機能、PDF ファイルの長期間の保存に適した PDF/A 形式での出力、AESでの暗号化、pCOS ツールの統合、読み込んだ PDF ファイルの修復および最適化等です。このうち、テーブルの自動作成機能は個人的に注目しています。サンプルのコードや PDF は PDFlib Cookbook にありますが、テーブルの動的作成やセルの自動拡張は、とても便利そうです。

ちなみにPDFlib 7 各製品のライセンス形態は、従来の PDFlib で採用されていた物理 CPU 数ベースのものから、機器の台数ベースに変更となりました。機器の CPU が SMP でもマルチコアでも、一台のマシンで必要なライセンスキーは一つだけですむようになっています。このため PDFlib 7 を使用している 1CPU の機器を SMP やマルチコアの機器にリプレースする場合でも、ライセンスキーを買い足す必要は無くなりました!

▲目次

PDFlib6 と PDFlib7 の互換性

PDFlib7 のソースコードは基本的には PDFlib6 の上位互換ですが、PDFlib 6 で廃止予定だった関数や、一部関数の機能に少しだけ変更点があります。API 変更点の詳細に関しては日本総代理店の 各種ファイルの日本語訳についてPDFlib 6 から PDFlib 7 の変更点 を参照してください。

PDFlib 7 で日本語等、CJK(日中韓)の文字列を出力する場合、PDFlib は CMap ファイルを読み込む必要がありますので注意してください。CMap を指定しない場合、日本語の文字列出力時にエラーもしくは文字が空白となります。

この HOWTO の全てのサンプルプログラムは、プログラム中に PDFlib 7 に関する言及が無い場合には CMap を指定する必要があることを除き、PDFlib 7 でそのまま動作します(随時、PDFlib 7 対応にしていきます)。

▲目次

PDFlib のアップグレードとアップデート

PDFlib 製品のユーザは、上位製品(PDIやPPS)にアップグレードしたり、新バージョンにアップデートする場合には、ディスカウント価格が適用されます。アップデートとアップグレードという用語はどっちがどっちなのか日本人にはちょっとややこしいので、個人的には何とかして欲しいと思っています。

なお、アップデート時に同時にアップグレードすることも可能です(例えば PDFlib 6 から PPS 7 に変更)。アップグレード/アップデート価格は、PDFlib7 価格表 にあります。アップグレード/アップデートの見積もりは、代理店のメールアドレス に対象のライセンスキーと共にメールしてください。

▲目次

PDFlib5 と PDFlib6 の互換性

もはや不要かと思いますが、削除する必要も無いかと思うので、一応 PDFlib 5 と 6 の互換性に関する記述も残しておきます。

PDFlib6 は基本的には PDFlib5 の上位互換ですが、Java 等の型のある言語においては、全ての float 型が double 型に変更となっているため、変数の型を変更する必要があります。PHP 等では特に問題なくそのまま動作するはずです。

一部、PDFlib6 で deprecated(使用は非推奨)と指定された関数があります。例えばサンプルでも使用していた PDF_open_file()や PDF_begin_page()は、オプションを指定できるようになり別名の関数が用意されたため、deprecated に指定されました。2004/12/29: PDFlib6 で deprecated となった関数を、下記のように PDFlib6 で推奨される方を使用するように全サンプルプログラムを更新しました。また、PDF_open_pdi()実行時に(エラー等があった場合)警告を表示するようにしました

PDF_open_file() → PDF_begin_document()
PDF_begin_page() → PDF_begin_page_ext()
PDF_end_page() → PDF_end_page_ext()
PDF_close() → PDF_end_document()

PDF_open_pdi() → 第三引数で "pdiwarning=true" を指定するようにした

▲目次

PDFlib の試用

PDFlib 製品で色々できる(かもしれない)ということはわかったけど、実際試用してみないと信用できないし、自分の環境で動くかどうか不安

という人も多いと思います(もちろん筆者もそうです :-)。PDFlib PLOP, PDFlib TET を含め、全ての製品は ダウンロードページ からダウンロードできます。生成した PDF ファイルに「www.pdflib.com」というロゴが大きく表示されることを除いて、試用版でも製品版の全機能を使用できます。試用版、PDFlib, PDI, PPSの各製品は実際にはまったく同一のファイルで、製品のライセンスキーにより、下記のどの機能が使えるかが決まります。

▲目次

PDFlib のインストール

PDFlib - インストール方法 に移動しました。

▲目次

PDF を生成してみる

PDFlib のアーカイブを展開すると bind/各言語/ 以下に、PDFlib の簡単なサンプルがいくつか入っています。まず始めに bind/php/hello.php(あるいは他の言語用の hello のソース)を参照すると、PDFlib でのプログラミングの世界に入って行きやすいかと思います。

hello1.pdf は、bind/php/hello.php を製品版ライセンス無しの状態で実行して生成された PDF ファイルです。ライセンスキーを設定していないために、「www.pdflib.com」というロゴが表示されています。ライセンスキーを設定して bind/php/hello.php を実行した場合の PDF ファイルは hello2.pdf です。製品版と試用版の違いはロゴが表示されるかどうかだけで、使用できる機能に差異はありません(試用版は PDFlib ~ PPS までの全機能が使用できますが、製品版は当たり前ですが購入した製品の機能までしか使用できません。例えば PDI を買った場合は PPS の機能は使用できません)。

hello.php(PDFlib 7 用) (PDFlib 6 用) は、日本語を表示するように PDFlib 同梱の hello.php を変更したものです。PDFlib 6 用は、PDFlib 7 用のものから errorpolicy オプションおよび CMap の指定をコメントアウトし、表示するフォントを PDFlib 7 以降で使用可能な KozMinProVI-Regular から KozGoPro-Medium-Acro に変更してあるだけです(KozGoPro-Medium と KozMinProVI-Regular は Acrobat 7 と 8 の標準CJKフォントで、PDFlib 6 の発売時点では Acrobat 6 までしかリリースされていなかったため、PDFlib 6 で指定するとエラーになります)。

▲目次

PHP による PDFlib プログラミング例

ここで、PDI および PPS による PDF 再生成の例を PHP で作成してみたいと思います。雛形となる PDF ファイルは作成する手間を省くため、HOWTO 執筆時に Google で「届 申請書様式 ダウンロード」で検索して見つかった北見市の 公文書公開請求書の PDF を使います。

▲目次

PDI による PDFlib プログラミング例

実際に動作するサンプルソース sample_pdi.php(PDFlib 7 用) (PDFlib 6 用) と、プログラム中で読み込んでいる 雛型 PDF です。プログラム実行後に生成された PDF ファイルは sample_pdi.pdf です。

文字や数字の出力のために、PDF_show_xy()関数に直接座標を指定していることがわかると思います。この例ではたった4種類の文字でしたが、下記を何度も何度も繰り返し実行して、正しい座標に文字を移動していく作業はちょっと面倒です。

対象となる PDF ファイルが多い場合や、一度座標を決めてから各項目の位置を微調整する場合などには、また同じ作業を繰り返す必要があります。そのため単純作業ではありますが、結構面倒な作業となります。

▲目次

PPS による PDFlib プログラミング例

PDI で文字等の出力時に座標を指定するのが非常に面倒ということは PDFlib 社でも考えていたらしく、PDFlib+PDI の上位製品として PDFlib Personalization Server(通称 PPS) という製品が用意されました。早速 PDFlib+PDI の例が PPS だと、どれぐらい楽になるかを見てみましょう。

雛形 PDF の各項目にブロックを指定したファイルは 560-0201_blocked.pdf です。ここではわざと、日付のブロックの位置はガタガタにしてあります。なおブロックの[テキスト]タブの fontname のデフォルト値は Helvetica になっています。 そのため日本語を表示するには、ブロックの fontname の値か、もしくはプログラム中でブロックに値を設定する際に日本語フォントを設定するのを忘れないように注意してください。

動作サンプルのソースは sample_pps.php(PDFlib 7 用) (PDFlib 6 用) で、生成された PDF ファイルは sample_pps.pdf です。文字等を設定する部分は、PDI のサンプルに比べ非常に簡単になっているのがわかるかと思います。

次に、日付の表示位置を修正してみます。日付のブロックの位置を修正した雛形 PDF ファイルは 560-0201_blocked2.pdf です。この雛形 PDF を利用するサンプルソースは sample_pps2.php(PDFlib 7 用) (PDFlib 6 用) で、生成された PDF ファイルは sample_pps2.pdf です。

sample_pps2.php と sample_pps.php との差異は、読み書きする PDF ファイルの名前が異なるだけで、あとは変更ありません。今回は PDF ファイルの名前を変更するためにプログラムに手を入れましたが、通常の利用時には雛形となる PDF ファイルを編集しても、(雛型 PDF ファイルのパスや名前が変わらない限り)プログラムを変更する必要は一切ありません。そのため、プログラムの開発と雛形 PDF のデザインを平行して進めることができます。

※PDFlib ブロックでテキストフローを利用し、かつエンコーディングとして UTF-16/UTF-16BE/UTF-16LE を指定した場合には、PDF_fill_textblock()で textlen オプションに文字列の長さを指定する必要があります(例: textlen=123)。指定しなかった場合には PDF_fill_textblock()関数がエラーとなり、指定した文字列は設定されませんので注意してください。

▲目次

おまけ

5ポイントごとにグリッド線を引いた PDF ファイルを作りました。PHP でのソースは grid.php です。プログラムにコピーしてグリッド線を表示すると、座標の位置調整などに便利じゃないかと思います。

▲目次

CMap やフォントについて

色々ややこしい点があるのでここで説明しておきます。まだ書きかけのため、随時手を入れていく予定です。 なお、小形克宏の「文字の海、ビットの舟」――文字コードが私たちに問いかけるもの や、安岡 孝一氏の Adobe-Japan1-6とUnicode─異体字処理と文字コードの現実 (PDF)には一度は目を通しておくと良いかと思います。ちなみに Adobe-Japan1-6 は Adobe 社が日本語フォントのために制定した文字セット(文字集合とも言います)のことです。

CMap とは

CMap とは簡単に言うとフォントと文字コードの対応表のようなものです。文字コードごとに別々のフォントのファイルを作成するのは無意味ですし非常に無駄が多いため、PDF では文字に対してフォントの種類やエンコーディング(CMap)の情報が設定されています(PDF 限定の概念ではありません。また厳密に言うと1文字ごとにいちいち設定されているわけではありません。実際に PDF ファイルの中を参照し、/Encoding という文字を探してみると面白いかもしれません)。

例えば「あいうえお」という文字に対し「90msp-RKSJ-H」という CMap が設定されていた場合、「あいうえお」という各文字の文字コードを「90msp-RKSJ-H」というCMap を参照して CID という ID に変換し、フォントの該当 CID の文字を表示します。

「あいうえお」の文字コード → <CMap「90msp-RKSJ-H」を参照> → 対応するCIDに変換

このような動作をしていることから、設定する文字列と CMap が異なっていた場合には、最終的に表示される文字がいわゆる文字化けのような出力となってしまいます。

例えば「あ」という文字の文字コードが 82A0 だとします。また CMap「90msp-RKSJ-H」では 82A0 は CID 847 に変換するように定義されていたとします(数値は適当です)。CMap として「90msp-RKSJ-H」を設定しているにもかかわらず、別の文字コードで「あ」を指定してしまうと(文字コード A4A2 とします)、A4A2 は全く別の CID に変換されてしまうことになるため、表示される文字列がまったく違う文字(いわゆる文字化け)となってしまいます。

文字コード EUCの「あ」 → ShiftJIS 用の CMap → なんか変な文字の CID

文字化けの際は、指定した文字列の文字コードと CMap が正しいかを確認しましょう。

各CMapの対応する文字セット

      代表的な CMap が対応している文字セットを説明します。-H は横書き、-V は縦書きに対応しています。詳細に関してはマニュアルを参照してください。

90ms-RKSJ-H
Windows(Windows Vista) で一般的に使用されている文字セットで、○に1「①」という文字や、はしごたか「髙」、ローマ数字のII「Ⅱ」といった、いわゆる機種依存文字と呼ばれる文字も使用できます。

正確には、「90ms-RKSJ-H」 ≒ 文字セット「JIS X 0208:1997」 + 「NEC・IBM拡張文字(いわゆる機種依存文字)」です。

PDFlib の文字出力関連の関数に渡す文字列の文字コードは Shift-JIS で指定します。厳密に言うと Shift-JIS ではなく文字コード 90ms-RKSJ-H ですが、Windows 環境の場合は両者はほぼ同義と考えて良いのではないでしょうか。またこのため、例えば PHP で文字コードを指定あるいは文字コード変換する場合には、SJIS ではなく SJIS-win で指定/変換します。
指定例(Linux で 90ms-RKSJ-H を指定する場合)

$font = PDF_load_font($p, "HeiseiKakuGo-W5", "90ms-RKSJ-H", "");
PDF_setfont($p, $font, 10);
PDF_set_text_pos($p, 50, 500);

// EUC-JP から SJIS-win に文字コードを変換
$str = mb_convert_encoding("あいうえお①Ⅱ", "SJIS-win", "EUC-JP");
PDF_show($p, $str);
90msp-RKSJ-V
90ms-RKSJ-H の縦書き版です。
90msp-RKSJ-H
90ms-RKSJ-H の半角英字がプロポーショナルになっただけのものです。
UniJIS-UCS2-H
Adobe-Japan1 に対応した文字セットで、文字列は Unicode(UCS-2)で指定します。2007年1月時点では Adobe-Japan1-1 ~ Adobe-Japan1-6 まであり、Adobe-Japan1-6 には 90ms-RKSJ-H や Windows Vista が新しく対応する JIS X 0213:2004 まで、通常の使用で必要となるほとんどの文字が含まれています(PDF を表示する Acrobat もしくは Acrobat Reader のバージョンにより、Adobe-Japan1-1 ~ Adobe-Japan1-6 のどの文字セットまで表示できるかが決まります)。
指定例

$org = "あいうえお";
# UTF-8 で指定する場合(BOM = \xEF\xBB\xBF)
$org = "\xEF\xBB\xBF" . mb_convert_encoding($org, "UTF-8", "EUC-JP");
PDF_fill_textblock($p, $page, "org", $org, "encoding UniJIS-UCS2-H textformat auto fontname HeiseiKakuGo-W5");
EUC-H
文字セット JIS X 0208 に対応しており、文字コードはEUC(EUC-JP)となります。(昔のAIXを除き)Unix 系の OS の文字コードは通常は EUC のため、文字コードを変換する必要が無く、お勧めです(Windows の機種依存文字を出力する必要がある場合は、素直に 90ms-RKSJ-H を使い、文字コード変換しましょう)。
指定例

$font = PDF_load_font($p, "HeiseiKakuGo-W5", "EUC-H", "");
PDF_setfont($p, $font, 20);
PDF_show_xy($p, "あいうえお", 100, 500);

フォント

Acrobat の「標準CJKフォント」はバージョンにより異なるため、「標準CJKフォント」を指定した PDF を作成した場合、環境により表示されるフォントが異なってしまうという問題があります(PDFlib ではなく、Acrobat の制限)。

例えばフォントとして HeiseiMin-W3 を指定したとします。このフォントは Acrobat 4(Acrobat Reader 4 には含まれません)にしか付属していないため、Acrobat 4 以外で表示を行うと HeiseiMin-W3 フォントとは異なるフォント(例えばKozMinProVI-Regular)で表示されるため、文字が重なったりずれたりする現象が発生することがあります。

そのため、どのバージョンでも確実に同じように見えるようにしたいのであれば PDF ファイルにフォントを埋め込むしかありません。Acrobat の「標準CJKフォント」は、「そのバージョンの Acrobat に標準で添付されてくるフォント」という意味で捉えた方が、実態を表していると思います。

各 Acrobat に添付のCIDフォントは下記のようになっています。Acrobat Reader にはフォントは付属しないため、「標準CJKフォント」で指定した文字は Acrobat Reader で置換フォントとして定義されている「MSP明朝」や「MSゴシック」等で表示されることになります(Windows 版の場合)。

各 Acrobat 付属のフォントは「C:\Program Files\Adobe\Acrobat バージョン\Resource\CIDFont」にありますが、Acrobat Reader しか無い環境用にフォントを埋め込む場合には、 Adobe Readerのアジア・中央ヨーロッパ言語フォントパック からフォントを入手するのが一番手っ取り早いかと思います。

なお Acrobat 付属のフォントを PDF に埋め込むには、下記「カスタムフォントの取り扱い」の通りに行う必要があります(PDF への埋め込みが許可されているかどうかはフォントのライセンスを確認してください)。

2008/09/03 に公開を開始した『PDFlib 日本語リソースキット』には日本語版Windows XP同梱のものと同一のMSフォントファイル(MSゴシック、MS明朝)が同梱されています。 PDFlib日本総代理店である オープンタイプ株式会社 から PDFlib/PDFlib+PDI/PPSバージョン7以降のライセンスを買った全てのユーザは、『PDFlib 日本語リソースキット』同梱のMSフォントを無償で利用することが可能になりました。

これによりようやく、Windows以外のOSにおいてもMSフォントを PDF ファイルに合法的に埋め込むことができるようになりました。MS フォントを埋め込む方法については FAQ の「.TTC ファイルのフォントの指定方法」を参照してください。

※フォントファイルのライセンスなど、「PDFlib日本語リソースキット」同梱のファイルの日本語訳は、各種ファイルの日本語訳についてを参照してください。

▲目次

カスタムフォントの取り扱い

これまでは、Acrobat の標準CJKフォントを指定していましたが、カスタムフォントを使用するように変更してみます。

サンプルではフリーで配布されている みかちゃんフォント を使用しますが、TrueType フォント(拡張子 .ttf/.ttc)や OpenType フォント(拡張子 .otf)であれば、フォントのプロパティで埋め込みが禁止されていない限り、技術的にはどのフォントでも埋め込むことが可能です。

なお、Windows 付属の MS フォントや Acrobat 付属のフォントも当然埋め込むことが可能ですが、PDF へのフォントの埋め込みはフォントメーカーにより禁止されていたり別途契約が必要なことも多いため、実際にフォントを埋め込む際にはフォントのライセンスを確認するようにしてください。商用で使用可能な無償のフォントとしては、ライセンスが明確な VLゴシックフォント もお薦めです。

2008/09/03 に公開された PDFlib 日本語リソースキット を利用することにより、Windows以外のOSにおいても PDF生成時にMSフォントを利用することが可能になりました。

前準備

まずはフォントファイルを入手します。みかちゃんフォントのサイト へ行き、ダウンロード から Windows用を選択 します。どのフォントでも構いませんが、ここではプロポーショナル・ボールド(PB)のOpenTypeフォントである、mikachanPB_o.lzh を入手します。

ファイルをダウンロード後ファイルを展開し、フォントファイル(mikafont_pb.otf)を「PDFlib を実行するプロセス(PHP の場合は Apache のプロセス)がアクセスできるファイル名&パーミッション&場所」に置いておきます。ここでは /tmp にしました。

なお Font name aliasing という機能により勝手にフォント名を探してくれるため、FontOutline オプションに設定する FontName は適当な名前でかまいません。カスタムフォントとして MS フォントを指定する方法は FAQ の「.TTC ファイルのフォントの指定方法」を参照してください。

▲目次

PDIでの例

サンプルソースは embed_pdi.php(PDFlib 7 用) (PDFlib 6 用) で、生成された PDF ファイルは embed_pdi.pdf です。フォント非埋め込み版との差はフォント回りの設定だけです。なお PDFlib 6 以前ではカスタム(CJK)フォントの場合のエンコーディングは unicodeである必要がありますが、PDFlib 7 ではそのような制約は無いので、生成された PDF の通り、カスタムフォントで機種依存文字を使うことも可能となっています。

なおカスタムCJKフォントの場合、PDFlib 6 以前では必ずフォントが埋め込まれます。PDFlib 7 でも同様だったのですが、PDFlib 社にリクエストをして keepnative というオプションを作ってもらいました。PDFlib 7.0.1 以降で使えるようになるとのことです。

このオプションを TRUE に設定するとカスタムフォントを使用した場合でもフォントは埋め込まれないため、下記のような記述により「表示はMSPゴシックを使用するけれども、PDF にはフォントは埋め込まない」ことが可能となります。この機能を使用して生成した PDF は embed_pdi_keepnative.pdf です。

PDF_set_parameter($p, "FontOutline", "MS-PGothic=/tmp/msgothic.ttc");
$font = PDF_load_font($p, "MS-PGothic", "90ms-RKSJ-H", "keepnative=true");

ただしこの機能は、雛型となる PDF ファイルで使われているフォントと、カスタムフォントで使用するフォントが同一の場合には embed_pdi_corrupt.pdf のように、表示がおかしくなる可能性があるので、注意する必要があります。既にMSゴシックが使われている(& 埋め込まれていない)雛型PDFを読み込み、keepnative=true を指定してカスタムフォントとしてMSゴシックを使った場合に、このような表示になりました。

また、標準フォントに対して単純に embedding=true を指定してしまうと、下記のようなエラーとなりますので注意してください(※標準フォントを PDF に埋め込む場合、カスタムフォントの設定と同様に標準フォントファイルの場所を FontOutline オプションで指定した上で、embedding=true を指定します)。

PHP Fatal error: pdf_load_font(): [nnnn] PDF_load_font: Font with predefined CMap '指定したCMAP名' cannot be embedded in ファイル名 on line エラー行

▲目次

PPSでの例

サンプルソースは embed_pps.php(PDFlib 7 用) (PDFlib 6 用) で、生成された PDF ファイルは embed_pps.pdf です。フォント非埋め込み版との差はフォント回りの設定だけです。

▲目次

応用編

カスタムフォントの利用の応用編として、バーコードと QR コードを出力してみましょう。

▲目次

バーコードの出力

いまさらバーコードとは何かということを説明する必要はないでしょうが、バーコードの規格など、バーコード自身に関しては バーコード入門/バーコードハンドブック などが参考になるかと思います。

バーコードの出力自体は、通常の文字を出力することと何ら変わりがありません。そもそもバーコードは、スキャナなどの読み取り装置で英数字などを読み込めるように白黒のバーの組み合わせで表現されているだけで、実質的には単なる英数字にすぎないからです(例えば 1 という数字のかわりに || ||| のようなバーを出力しているだけです)。読み込んだ英数字がどのような意味を持つかは、読み込んだ後にその値を解釈するソフトウェア等に依存します。

PDFlib におけるバーコードの出力は、単にバーコードフォント(文字のグリフ(字形)がバーコードになっているフォント)を使用して文字を出力するだけです。つまり必要な作業はバーコードフォントを入手するだけと言っても過言ではありません。バーコードフォントを指定して0という数字を出力すればバーコードの表現での0が、aという英字を出力すればバーコードの表現でのaが出力されることになります。なお当然ながら、チェックサムはアプリケーション側で計算する必要があります。

ここでは バーコード入門/バーコードハンドブック より無償で利用できる CODE39 を利用してバーコードを作成してみます。サンプルソースは barcode.php で、生成された PDF ファイルは barcode.pdf です。ソースコードを見ればすぐ分かると思いますが、単にカスタムフォントとしてバーコードフォントを指定して数字を表示しているだけで、難しい点は何もありません。

ここで使用したフォントのグリフにはバーコードのバーしかなく、英数字のグリフが含まれていないため、人間が読める普通の文字(グリフ)を出力する場合には 商用フォントを使うのが無難かと思われます。有償のバーコードフォントを google で調べてみると、Morovia Font日立IT などがあるようです。

▲目次

QR コードの出力

QR コードは二次元コードの一つで、バーコードが同じ長さの縦棒だけ(つまり横方向にしか情報を持たない)なのに比べ、二次コードは縦方向にも情報をもっているため、似たようなサイズの二次コードではバーコード(一次元バーコード)の、何十倍ものデータを表現することができます。下記は「PDFlib HOWTO」という文字列をエラー訂正レベルMのサイズ3で作成したQRコードです。

最近は宅配便などの荷物のラベルや商品の化粧箱などに印刷されてることも増えてきましたので、ご覧になった方も多いかと思います。登録できる情報量がバーコードと比べて桁違いに多いため、バーコードでは通番ぐらいの情報しか持たせられなかったケースでも、QRコードでは全情報を表わすことが可能となります。例えば見積書や請求書に書類の全内容(製品名から金額、住所や電話番号など)を保持させたQRコードも出力しておき、受け取り側はスキャナで読み込むだけ、ということも可能となります(なお、QRコードは暗号化されているわけではないので、QRコードの改竄に関する考慮は必要です)。

QRコード(および二次コード)に関しては、

などが参考になるでしょう。

QRコードの生成自体は QRコード・バーコード のライブラリが非常に参考になるかと思います。日立IT 二次バーコードフォント を利用するという手もありますが、バーコードのように数字と図形が一対一に対応するわけではないので、自分で図形(QRコード)生成ルーチンを用意してあげる必要があります(日立ITのフォントにはライブラリも付いてきます)。

▲目次

FAQ

別ページ に移動しました。

▲目次

PDFlib の購入方法

日本国内で購入や見積もりを行う場合には PDFlib の国内総代理店PDFlib製品見積りページ からオンラインで行うことが可能です(pOCS を除く)。PDFlib 価格は PDFlib 価格表 を参照ください。

▲目次

ライセンスキーの指定方法

別ページ に移動しました。

▲目次

関連リンク集

▲目次

更新履歴

2008/09/03PDFlib 日本語リソースキット に関する記述を追加
2007/01/23色々更新
2007/01/12CMap やフォントについて を追加
2006/11/30PDFlib7 について を追加
2003/06/09初期リリース

▲目次

$Id: index.html,v 1.111 2009-04-09 13:08:20 cz Exp $