以前にも触れましたが、ボディ部分にはPDFビューアーで目にする文書の内容を形作る全オブジェクトが含まれています。これらをPDFリーダーが正確に解釈できるよう、いくつかの重要なディクショナリーオブジェクトが必要不可欠です。
PDFファイルのボディセクションにあるオブジェクトは、すべて「カタログ」と呼ばれるディクショナリーオブジェクトを根本に持つ木構造で配置されています。これはトレーラーセクションのディクショナリーが指していたルートオブジェクトです。カタログディクショナリーには最低限、/Type /Catalog(これがカタログであることをPDFリーダーに伝えるため)と、ページツリーのルートを表す別のディクショナリーオブジェクトへの参照、つまり/Pages 2 0 R
が必要です。
1 0 obj
<>
endobj
ページツリーには2種類のノードがあり、どちらもディクショナリーオブジェクトです。カタログが知っている必要があるページツリーノードと、ドキュメント内の単一ページを表すページノードです。ページツリーノードは、ページノードへの参照と他のページツリーノードへの参照を含みます。ページツリーノードが章などの実際の論理構造を指すわけではなく、多くのページを持つ大きなドキュメントが迅速にアクセスできるように木構造のページをバランスよく配置するためのものです。
私たちのページツリーノード(2 0 obj)にはいくつかの要素を追加する必要があります。通常通り、それが何であるかを示すエントリー/Type /Pagesが必要です。そして、接続されているページツリーの他の部分への参照を含む配列/Kidsも必要です。今回は大胆にもドキュメントに1ページだけ含めます:/Kids 3 0 R
このページノードが接続するすべてのページノードの数をカウントする必要があります。ルートにある100ページのドキュメントであればカウントは100ですが、同じドキュメント内で1ページだけを持つ別のページツリーノードの場合はカウントは1です。
ここでの目標は、ルートページツリーノードに以下の内容を持たせることです:
2 0 obj
<>
endobj
このオブジェクトは3 0 objを参照しますが、これがページノードになります。これには/Type /Pageが必要で、その親ノードへの参照 /Parent 2 0 R
が必要です。
ページとしてのオブジェクトには、ページについての多くの情報を記述するリソース要素が必要です。/Resourcesキーは、ページが使用するフォントや、グラフィック、シェーディング、面白い名前の要素を含むディクショナリーにマッピングされます。しかし、当面はこれらの面白い要素を避け、リソースを次のパートで詳しく扱うため、ここではそれを無視します。これを省略することで白紙のページが得られます。/Resources<<>>
や /Resources null
と記述すれば、PDFリーダーには白紙のページとして認識されます。
ページオブジェクトがPDFビューアに受け入れられるために必要な最後の要素は、/MediaBoxエントリーです。MediaBoxは、ページの全体サイズを記述する配列を参照します。ですが、このMediaBox配列の内容を説明する前に、オブジェクト内で使用されるさまざまなデータ型について説明するのが良い時です。例えば、メディアボックスのエントリーは次のようになります:
/MediaBox [0 0 500 800]
これは名前オブジェクト( /MediaBox
)と配列オブジェクト [0 0 500 800]
で、配列内のデータは長方形の二つの角の座標を表します(左下の角が0 0で、右上の角が500 800)。これら4つの数字は配列オブジェクト内で必要な「長方形」型のデータを表します。これらは、PDF内で特定の場所に物を配置するために非常に便利です。さて、ここが私たちのページオブジェクトです:
3 0 obj
<>
endobj
これで白紙ページが完成します。Part 3で作成したものから調整を加えると、以下のようになります:
%PDF-2.0
1 0 obj
<>
endobj
2 0 obj
<>
endobj
3 0 obj
<>
endobj
xref
0 4
0000000000 65535 fq
0000000010 00000 n
0000000060 00000 n
0000000115 00000 n
trailer
<>
startxref
180
%%EOF
PDFファイルの構造を調整する際、クロスリファレンス(xref)テーブルとトレーラーセクションの微調整が必要となります。具体的には、xrefセクション直後に表されるテーブルのエントリ数を4に更新し、トレーラーディクショナリーにはファイル内の新しいオブジェクトの正確な位置を指し示す新たな情報を加えます。
さらに、ファイル内のxrefテーブルへの参照となるstartxrefアドレスも、テーブルの新しい位置に合わせて調整することが求められます。これらの変更を行う際には、数字を正確に編集するためにバイナリエディタの使用が不可欠です。このプロセスを通じて、PDFファイルの構造が正しく更新され、内容の整合性が保たれるようにします。
具体的には、xref
という文字列が始まる直前の空白を含む全てのバイトが、startxref
に記載すべき正確な位置となります。この位置をバイト単位で正確に計算し、startxref
の値として指定することが重要です。これにより、PDFリーダーはクロスリファレンステーブルを正しく見つけることができ、ファイル内のオブジェクトへのアクセスが正確に行われます。
PDFアプリ開発ツール(SDK)をお探しのみなさま、効率のよい開発作業のためにJPedal、BuildVu、JDeliがきっとお役に立つことと思います。
これら3製品は無料で試用していただけますので、まずはお試しのうえ、ぜひ導入をご検討ください。
JPedal、BuildVu、JDeliのシステム開発やプログラミング、無料トライアルの情報は下記の各製品のトライアルページをご覧ください。技術的なことから費用面まで、ご質問・ご相談も各製品ページの問合せボタンからお寄せください。