fbpx

PDFってこうなってる? 実践でPDFの内部構造を学ぼう Part4:白紙のPDFページを自作する

準備はいいですか? もう間もなく、あなたは自分自身で制作した輝く真新しい完全な白紙のPDFドキュメントの所有者となることができます。その前に、Part 3ではPDFのボディ部分について詳しく説明します。これらの知識を使って、テキストエディタとバイナリエディタでシンプルな白紙のPDFを実際に作ってみましょう。完成したPDFファイルは、あなたにとって特別な一品になることでしょう。
Part4:白紙のPDFページを自作する

以前にも触れましたが、ボディ部分にはPDFビューアーで目にする文書の内容を形作る全オブジェクトが含まれています。これらをPDFリーダーが正確に解釈できるよう、いくつかの重要なディクショナリーオブジェクトが必要不可欠です。

PDFファイルのボディセクションにあるオブジェクトは、すべて「カタログ」と呼ばれるディクショナリーオブジェクトを根本に持つ木構造で配置されています。これはトレーラーセクションのディクショナリーが指していたルートオブジェクトです。カタログディクショナリーには最低限、/Type /Catalog(これがカタログであることをPDFリーダーに伝えるため)と、ページツリーのルートを表す別のディクショナリーオブジェクトへの参照、つまり/Pages 2 0 Rが必要です。

				
					1 0 obj
<</Type /Catalog /Pages 2 0 R>>
endobj
				
			

ページツリーには2種類のノードがあり、どちらもディクショナリーオブジェクトです。カタログが知っている必要があるページツリーノードと、ドキュメント内の単一ページを表すページノードです。ページツリーノードは、ページノードへの参照と他のページツリーノードへの参照を含みます。ページツリーノードが章などの実際の論理構造を指すわけではなく、多くのページを持つ大きなドキュメントが迅速にアクセスできるように木構造のページをバランスよく配置するためのものです。

私たちのページツリーノード(2 0 obj)にはいくつかの要素を追加する必要があります。通常通り、それが何であるかを示すエントリー/Type /Pagesが必要です。そして、接続されているページツリーの他の部分への参照を含む配列/Kidsも必要です。今回は大胆にもドキュメントに1ページだけ含めます:
/Kids 3 0 R
このページノードが接続するすべてのページノードの数をカウントする必要があります。ルートにある100ページのドキュメントであればカウントは100ですが、同じドキュメント内で1ページだけを持つ別のページツリーノードの場合はカウントは1です。

ここでの目標は、ルートページツリーノードに以下の内容を持たせることです:

				
					2 0 obj
<</Type /Pages /Kids [3 0 R] /Count 1>>
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
<</Type /Page /Parent 2 0 R /Resources<</MediaBox [0 0 500 800]>>
endobj
				
			

これで白紙ページが完成します。Part 3で作成したものから調整を加えると、以下のようになります:

				
					%PDF-2.0
1 0 obj
<</Type /Catalog /Pages 2 0 R>>
endobj
2 0 obj
<</Type /Pages /Kids [3 0 R] /Count 1>>
endobj
3 0 obj
<</Type /Page /Parent 2 0 R /MediaBox [0 0 500 800]>>
endobj
xref
0 4
0000000000 65535 fq
0000000010 00000 n
0000000060 00000 n
0000000115 00000 n
trailer
<</Size 4 /Root 1 0 R>>
startxref
180
%%EOF
				
			

PDFファイルの構造を調整する際、クロスリファレンス(xref)テーブルとトレーラーセクションの微調整が必要となります。具体的には、xrefセクション直後に表されるテーブルのエントリ数を4に更新し、トレーラーディクショナリーにはファイル内の新しいオブジェクトの正確な位置を指し示す新たな情報を加えます。

さらに、ファイル内のxrefテーブルへの参照となるstartxrefアドレスも、テーブルの新しい位置に合わせて調整することが求められます。これらの変更を行う際には、数字を正確に編集するためにバイナリエディタの使用が不可欠です。このプロセスを通じて、PDFファイルの構造が正しく更新され、内容の整合性が保たれるようにします。

具体的には、xrefという文字列が始まる直前の空白を含む全てのバイトが、startxrefに記載すべき正確な位置となります。この位置をバイト単位で正確に計算し、startxrefの値として指定することが重要です。これにより、PDFリーダーはクロスリファレンステーブルを正しく見つけることができ、ファイル内のオブジェクトへのアクセスが正確に行われます。

xrefの位置を特定する
図をクリックして拡大する

PDFアプリ開発ツール(SDK)をお探しのみなさま、効率のよい開発作業のためにJPedal、BuildVu、JDeliがきっとお役に立つことと思います。
これら3製品は無料で試用していただけますので、まずはお試しのうえ、ぜひ導入をご検討ください。
JPedal、BuildVu、JDeliのシステム開発やプログラミング、無料トライアルの情報は下記の各製品のトライアルページをご覧ください。技術的なことから費用面まで、ご質問・ご相談も各製品ページの問合せボタンからお寄せください。

    Facebook
    Twitter
    Email
    公式ブログロゴ

    製品に関する記事や開発者のブログ

    PDFファイルを扱うシステム開発・ウェブ開発に役立つ

    開発者向けPDF入門ガイド

    開発者向けPDF入門ガイド

    PDFの基礎から応用まで開発者のための入門ガイド2024年版

    PDF の仕様や活用方法など、開発者に必要な情報がコンパクトにまとめました。初めてPDFを扱う開発者にも分かりやすく、基礎から応用までカバーしているため、PDF のポテンシャルを最大限に引き出し、アプリケーション開発やドキュメント管理の効率化を図るための手引きとなるでしょう。技術的な側面に興味がある開発者だけでなく、ビジネスでPDFを有効活用したい方にもおすすめの一冊です。

    MENU
    PAGE TOP
    ロボット
    PDFソフトウェアの開発に役立つ情報をメールでお届けします