PDF 内部構造 構造の概念 簡単な説明 新しいページはコチラ

提供: yonewiki
移動: 案内, 検索
(関連記事)
 
1行: 1行:
[[PDF 内部構造]]に戻る。
+
[[PDF 内部構造#説明|PDF 内部構造]]に戻る。
 
== '''概要''' ==
 
== '''概要''' ==
 
 ファイルの構造の大まかな分類があるので、その分類をここで説明します。PDF内部構造の用語にもなれていかないといけません。この記事では最初の一歩に必要な内容を記述したいと思います。
 
 ファイルの構造の大まかな分類があるので、その分類をここで説明します。PDF内部構造の用語にもなれていかないといけません。この記事では最初の一歩に必要な内容を記述したいと思います。
6行: 6行:
 
PDFファイルのテキストが一つあるだけのシンプルな構造のファイルイメージは以下のようになります。
 
PDFファイルのテキストが一つあるだけのシンプルな構造のファイルイメージは以下のようになります。
 
<syntaxhighlight2 lang="text" line=1>
 
<syntaxhighlight2 lang="text" line=1>
%PDF-1.7
+
%PDF-1.7
 
%★(適当な129~255までの値を何バイトか)
 
%★(適当な129~255までの値を何バイトか)
 
1 0 obj  
 
1 0 obj  
16行: 16行:
 
2 0 obj  
 
2 0 obj  
 
<< /Type /Page
 
<< /Type /Page
   /MediaBox [0 0 ★(xx xx)]
+
   /MediaBox [0 0 ★(xx xx 横 縦 用紙サイズpixel)]
 
   /Resources 3 0 R
 
   /Resources 3 0 R
 
   /Parent 1 0 R
 
   /Parent 1 0 R
24行: 24行:
 
3 0 obj  
 
3 0 obj  
 
<< /Font  
 
<< /Font  
     << /F0
+
     << /FBase
 
           << /Type /Font
 
           << /Type /Font
 
             /BaseFont /Helvetica-Bold
 
             /BaseFont /Helvetica-Bold
33行: 33行:
 
4 0 obj  
 
4 0 obj  
 
<<
 
<<
/length ★(xx)
+
/length ★(xx stream部(30行目~36行目終わり)のバイト長)
 
>>
 
>>
 
stream
 
stream
1. 0. 0. 1. ★(xx. xx). cm
+
1. 0. 0. 1. ★(xx. xx 描画座標位置 左下原点で上と右方向に増えていくpixel座標値). cm
 
BT
 
BT
   /F0 12. Tf
+
   /FBase 12. Tf
 
   (PDF Strings! Parts) Tj
 
   (PDF Strings! Parts) Tj
 
ET  
 
ET  
50行: 50行:
 
0 6
 
0 6
 
0000000000 65535 f  
 
0000000000 65535 f  
0000000★(xxx) 00000 n  
+
0000000★(xxx 1 0 objの始まるバイト長) 00000 n  
0000000★(xxx) 00000 n  
+
0000000★(xxx 2 0 objの始まるバイト長) 00000 n  
0000000★(xxx) 00000 n  
+
0000000★(xxx 3 0 objの始まるバイト長) 00000 n  
0000000★(xxx) 00000 n  
+
0000000★(xxx 4 0 objの始まるバイト長) 00000 n  
0000000★(xxx) 00000 n  
+
0000000★(xxx 5 0 objの始まるバイト長) 00000 n  
 
trailer
 
trailer
 
<< /Size 6
 
<< /Size 6
60行: 60行:
 
>>
 
>>
 
startxref
 
startxref
★(xx)
+
★(xx ファイルサイズ バイト長)
 
%%EOF
 
%%EOF
  
 
</syntaxhighlight2>
 
</syntaxhighlight2>
  
 はじめて見たときは、なんじゃコレ。って感じでした。皆さんの中にも初めての人がいたら同じような気持ちだったはずです。冷静にみてみると見えてくるものがあります。最初の2行あたりは、すべての拡張子のファイルにもあるファイルヘッダ部です。なんらかのファイル操作をしたことがある人なら知っているかもしれません。★マークがあるところは、任意の数値を指定したり、PDFtkに自動で算出してもらう数値だったりが入る箇所です。このファイルは実際はバイナリファイルですが、テキストで閲覧しても上記のように表示されるくらいテキストに近いものです。そして出回っているPDF生成ツールを使うとたいていは圧縮されて、なにがなんだかわからないファイルになっているのですが、上記のようにテキストでも理解できる非圧縮の見通しのいいPDFファイルも存在しています。ファイルを理解したい人にとってはこれでいいのですが、世の中そうもいかないらしい。いまファイルを理解しようとしている我々も含めて、単純に便利に使いたい人の方が多い。では上から見てます。
+
 サンプルソース:[[メディア:PDF_String_Sample-text.pdf|PDF_String_Sample-text.pdf‎]]<br />
 +
 サンプルPDF :[[メディア:PDF_String_Sample.pdf|PDF_String_Sample.pdf‎]]
 +
 
 +
 
 +
 サンプルソースを載せましたが、これもpdfとして開けば、Acrobat Readerが気を利かせて、PDF文書として表示されますが、2つのファイルリンクを右クリックしてリンクをファイルとして保存のようにしてダウンロードしたものをテキストエディタで開くと、肝心なところが自動補完されたっぽいことがわかります。PDF_String_Sample.pdf‎には★マークの部分の数値がすべて埋まっています。
 +
 
 +
 
 +
 ちなみにPDFtkのコマンドは以下の通りになります。
 +
 
 +
PDFtk PDF_String_Sample-text.pdf output PDF_String_Sample.pdf
 +
 
 +
 
 +
 ファイルの中身について、はじめて見たときは、なんじゃコレ。って感じでした。皆さんの中にも初めての人がいたら同じような気持ちだったはずです。冷静にみてみると見えてくるものがあります。最初の2行あたりは、すべての拡張子のファイルにもあるファイルヘッダ部です。なんらかのファイル操作をしたことがある人なら知っているかもしれません。★マークがあるところは、任意の数値を指定したり、PDFtkに自動で算出してもらう数値だったりが入る箇所です。このファイルは実際はバイナリファイルですが、テキストで閲覧しても上記のように表示されるくらいテキストに近いものです。そして出回っているPDF生成ツールを使うとたいていは圧縮されて、なにがなんだかわからないファイルになっているのですが、上記のようにテキストでも理解できる非圧縮の見通しのいいPDFファイルも存在しています。ファイルを理解したい人にとってはこれでいいのですが、世の中そうもいかないらしい。いまファイルを理解しようとしている我々も含めて、単純に便利に使いたい人の方が多い。では上から見てみます。
  
  
88行: 100行:
  
  
 これがオブジェクトという単位です。まだオブジェクトの中身はわからなくていいです。まずは全体を見渡しましょう。数字は先頭からオブジェクト番号、世代番号と呼ばれています。オブジェクト番号はファイル内で唯一の番号(ユニークな番号)になっている必要があります。連番である必要がありそうです。最後のendobjのある42行目からはx x obj ~ endobjという対がおわり
+
 これが<span style = "background:linear-gradient(transparent 75%, #ff7f7f 75%); font-weight:bold; ">オブジェクト</span>という単位です。まだオブジェクトの中身はわからなくていいです。まずは全体を見渡しましょう。数字は先頭から<span style = "background:linear-gradient(transparent 75%, #ff7f7f 75%); font-weight:bold; ">オブジェクト番号</span>、<span style = "background:linear-gradient(transparent 75%, #ff7f7f 75%); font-weight:bold; ">世代番号</span>と呼ばれています。オブジェクト番号はファイル内で唯一の番号(ユニークな番号)になっている必要があります。連番である必要がありそうです。最後のendobjのある42行目からはx x obj ~ endobjという対がおわり
  
  
97行: 109行:
  
  
 のような構造があります。この部分は相互参照テーブルと呼ばれています。オブジェクトは文書の中身を記述して構成していく要素ですが、相互参照テーブルは、そのオブジェクトがどこにあるかを記述したりします。実はファイルを開いたときは、たいていの閲覧ソフトは、この部分を探します。いまから見たいページがどこにあるかが記録されているからです。オブジェクトはフォルダのようなツリー構造になっていて、それぞれのオブジェクト内で、何がぶら下がっているか、どこにぶら下がっているかという情報をもっています。相互参照テーブルはその頂点であるルートのオブジェクトがどれかを保持したり、オブジェクトがいくつあるかという情報も保持しています。
+
 のような構造があります。この部分は<span style = "background:linear-gradient(transparent 75%, #ff7f7f 75%); font-weight:bold; ">相互参照テーブル</span>と呼ばれています。オブジェクトは文書の中身を記述して構成していく要素ですが、相互参照テーブルは、そのオブジェクトがどこにあるかを記述したりします。実はファイルを開いたときは、たいていの閲覧ソフトは、この部分を探します。いまから見たいページがどこにあるかが記録されているからです。オブジェクトはフォルダのようなツリー構造になっていて、それぞれのオブジェクト内で、何がぶら下がっているか、どこにぶら下がっているかという情報をもっています。相互参照テーブルはその頂点であるルートのオブジェクトがどれかを保持したり、オブジェクトがいくつあるかという情報も保持しています。
 +
 
 +
 
 +
 そして、最後に55行目で相互参照テーブルの開始位置をバイト単位で指定した数値部分があって、ここでは、0 を指定しています。0と記述しておけば、PDFtkが相互参照テーブルの開始位置のバイト値を補完してくれます。最終行は%%EOFというファイル終端記号で終わっています。
 +
 
 +
 
 +
 PDFファイルとは、こういう構造になっています。ここまでの説明では、まだ理解しきれるものではありませんが、シンプルな表現のみの文書の全貌はみえてきたと思います。
 +
 
 +
 
 +
 5つの obj がどのような役割なのかを確認します。ちなみに<< … >>のような二重の小なり、大なり記号は、<span style = "background:linear-gradient(transparent 75%, #ff7f7f 75%); font-weight:bold; ">辞書</span>という意味があり、いくつかの情報をまとめて、無意味順序として記述するという意味があります。単なる塊とも取れます。でも塊の中に指定されているものを、そのオブジェクトや名前が差している内容とみなすので、辞書の指定はよく使います。
 +
 
 +
 
 +
 ■5 0 obj
 +
:: ルートオブジェクト(<span style = "background:linear-gradient(transparent 75%, #ff7f7f 75%); font-weight:bold; ">カタログ</span>:目録 全体の目次といってもよいかも)です。相互参照テーブルのトレーラ部で/Root 5 0 R のように指定されています。5 0 R は/Rootという名前のモノは5 0 objを参照(Referrence)しますという意味の 5 0 Rです。x x R という形式はよく登場します。/Root という表記もよく登場します。 / のあとに文字列が記述されたようなパターンを<span style = "background:linear-gradient(transparent 75%, #ff7f7f 75%); font-weight:bold; ">名前</span>といい。名前には固有の役割があるものは<span style = "background:linear-gradient(transparent 75%, #ff7f7f 75%); font-weight:bold; ">キー</span>と呼んでいて、ユーザが自由につけるものは名前と呼んでいます。プログラムで言うところの変数みたいなものです。
 +
 
 +
 
 +
:: 5 0 obj には/Type は /Catalogだと指定しています。カタログには参照するページとして/Page 0 1 R がありますと指定もしています。0 1 obj は カタログのページ構成要素なんですね。
 +
 
 +
 
 +
 ■1 0 obj
 +
:: <span style = "background:linear-gradient(transparent 75%, #ff7f7f 75%); font-weight:bold; ">ページ</span>です。5 0 obj のカタログにぶら下がっているページ要素という意味です。
 +
 
 +
 
 +
:: 5 0 obj には/Type は /Pageだと指定しています。/Count は 1 と指定してあるので、このページは1つのページのオブジェクトであるということになります。このページの詳細情報をこの1 0 objには書かずそのページ要素の詳細は/Kidsという名前の参照先に書くことにしていて、/Kids [2 0 R] なので、2 0 R を参照しています。通常はフォントの設定や用紙の設定を個別にオブジェクトとして記述するので、このように、1つのページの情報はページの親的なオブジェクトから、参照して、また参照してというツリー構造になります。
 +
 
 +
 ■2 0 obj
 +
:: このオブジェクトもページです。1 0 obj のページにぶら下がっているページの要素です。
 +
 
 +
 
 +
:: 5 0 obj にも/Type は /Pageだと指定しています。但し、要素には1 0 obj には記述しなかったような名前について定義されています。/MediaBox は 用紙サイズをピクセル単位で指定します。A4用紙サイズの縦なら[0 0 1033 1462]というように指定します。[ ] 角カッコ(ブラケット)は配列の中身を空白区切りで記述するような仕組みになっています。このような記述方法を配列と呼んでいます。プログラムの配列は角カッコを使って要素数を指定しますが、そのような要素数の指定をするといったことの意味はありません。プログラムでいうと { } 波カッコ(ブレース)のような配列初期化指定に似ているかもしれません。
 +
 
 +
:: ページ要素の親は 1 0 obj という意味で/Parent 1 0 R が指定されています。
 +
 
 +
 
 +
:: このページの資源(Resourceの直訳は資源とはいうものの、日本語としては、ページの書式ですね。英語ではこういったものもResourcesと言うのでしょう。)は3 0 obj を参照するようにという意味で/Resources 3 0 Rが指定されています。
 +
 
 +
 
 +
:: ページの内容(コンテンツ)は /Contents [4 0 R]という具合に配列で 4 0 R にあると指定しています。このように参照値を入れる場合の配列は参照値を示すための空白(4 0 R)と配列の区分けの空白が混ざりますが、PDFの書式としてはなんら問題にならないようです。
 +
 
 +
 
 +
  ■3 0 obj
 +
:: このオブジェクトには書式を指定する辞書が指定されています。この辞書の中で/Fontという名前の値を指定することで、書体を指定しています。/Font には一つの辞書が結び付けられています。その辞書は /FBase というユーザ指定の名前をもっていて、/FBase にはまた辞書の値が指定されています。そこに、/Type は /Font 、/BaseFont は /Helevetica-Bold、/Subtype は /Type1 であると指定しています。
 +
 
 +
 
 +
:: ややこしい感じで設定されていますが、/FBaseというユーザ定義のフォント書式が定義されている上でフォントの設定を実際に3つ指定しているという形式です。/BaseFontで実際にフォント名をしていして、使うフォントを定義しています。英字フォントはフォント名にハイフン「-」で連結させるようにしてBold(太字)やItalic(斜体)を使うという指定ができるものが多いです。フォント名には英字フォント名というのがあるので、その値を設定します。/Subtypeもややこしいですが、フォントにはいくつかの形式があります。標準Type1(ASN Developer ProgramサイトからもダウンロードできるAdobeFontMetricsFileFormatファイル)は以下のとおりらしいです。Obliqueは斜体です。Italicと同様の意味です。
 +
 
 +
   Courier, Courier-Bold, Courier-Oblique, Courier-BoldOblique<br />
 +
   Helvetica, Helvetica-Bold, Helvetica-Oblique, Helvetica-BoldOblique<br />
 +
   Times-Roman, Times-Bold, Times-Italic, Times-BoldOblique<br />
 +
   Symbol, ZapfDingbats
 +
 
 +
 
 +
:: 他にも/SubTypeには、Type0, MMType1, Type3, TrueType, CIDFontType0, CIDFontType2というのがあります。そのあたりはまた別途です。日本語フォントなんかを使う我々はもう少し、深く勉強しないと、PDF文書を扱えるレベルには到達できないようになっています。
 +
 
 +
 
 +
  ■4 0 obj
 +
:: ここに<span style = "background:linear-gradient(transparent 75%, #ff7f7f 75%); font-weight:bold; ">コンテンツ</span>を置きます。stream部をもうけるので、名前/Lengthの値にstreamのバイト長をちゃんと数えて埋める必要がありますが、PDFtkによって自動で算出するので、変換前のテキストPDFには << >> のように記述して、辞書がここにはいるよ。よろしく。という感じだけ書いておけば良いです。
 +
 
 +
 
 +
:: streamからendstreamの間でテキストを描くペンを移動させるため 1. 0. 0. 1. 50. 50. cm のようにします。この表記はもっと意味深いのですが、1(X方向の倍率), 0, 0, 1(Y方向の倍率), 50(X方向移動), 50(Y方向の移動)を意味しています。このときの cm を<span style = "background:linear-gradient(transparent 75%, #ff7f7f 75%); font-weight:bold; ">オペレータ</span>、1, 0, 0, 1, 50 , 50 は<span style = "background:linear-gradient(transparent 75%, #ff7f7f 75%); font-weight:bold; ">オペランド</span>といいます。これについても、のちほど触れたいと思いますが、cm オペレーターは単純に移動をするためのものではなく、空間座標変換というような簡単にはわかりにくい機能をもっています。ここでは、cm オペレータはそういう機能があるんだなっていうことを把握しておいてもらえればいいと思います。
  
  
 そして、最後に55行目でファイルのサイズをバイト単位で指定した数値部分があって、%%EOFというファイル終端記号で終わっています。
+
:: BT~ETがテキストの始まりと終わりを示すオペレータです。Tf はテキストサイズを設定するオペレータです。第二オペランドにポイント(72分の1インチが1ポイント)という単位のテキストサイズの大きさ値を設定します。第一オペランドにはテキストフォント書式を設定したテキスト名前(こういうのをフォントリソースの名前と呼びます)を設定します。ユーザが好きな名前を付けていいものに、ある一定の役割があるものを関連付けてある必要があるというパターンはよくあります。Tj は第一オペランドで設定した文字列を出力するということです。
  
 +
 
  
 PDFファイルとは、こういう構造になっています。ここまでの、説明ではまだ理解しきれるものではありませんが、シンプルな表現のみの文書の全貌はみえてきたと思います。
+
== '''関連記事''' ==
 +
[[フォント TrueType 構造解析]]
  
 +
 
  
[[PDF 内部構造]]に戻る。
+
[[PDF 内部構造#説明|PDF 内部構造]]に戻る。

2022年9月13日 (火) 00:00時点における最新版



個人用ツール
名前空間

変種
操作
案内
ツールボックス