アウトライン (目次)

アウトライン
PDF は、オプションとして、画面にアウトライン (目次) を表示することができます。

アウトラインの項目を選択すると、指定されているページへ移動することができます。

アウトラインはツリー構造となっており、子がある場合、各項目は開いたり閉じたりすることができます。

カタログ辞書の Outlines エントリで、アウトラインのルートとなる「アウトライン辞書」を指定します。
(エントリの指定はオプションです。辞書は常に間接参照で指定します)
アウトライン辞書
カタログ辞書の Outlines エントリで指定する辞書です。
アウトラインのルート情報を設定します。

Typename(オプション) オブジェクトのタイプ。/Outlines
Firstdictionary(間接参照) アウトラインのルートの先頭のアイテム
Lastdictionary(間接参照) アウトラインのルートの最後のアイテム
Countintegerこのアウトライン上で開かれているすべてのアイテムの総数。
すべてのアイテムが閉じている場合は、エントリを省略します。
アウトラインアイテム辞書
アウトラインの各アイテムの辞書です。

Titletext string(必須) 画面上に表示されるテキスト
Parentdictionary(必須。間接参照) このアイテムの親。
トップレベルのアイテムの場合は、アウトライン辞書を指定します。
Prevdictionary(間接参照) この階層における一つ前のアイテム
Nextdictionary(間接参照) この階層における一つ次のアイテム
Firstdictionary(間接参照) このアイテムの最初の子アイテム
Lastdictionary(間接参照) このアイテムの最後の子アイテム
Countinteger(子がある場合は必須)
このアイテムが開いている場合は、このアイテムのすべての下位レベルで開かれているアイテムの総数。
このアイテムが閉じている場合は、アイテムを再度開いた時に表示される子孫の数を、負の値で指定します。
Destname or byte string or arrayこのアイテムが選択された時に表示されるページの宛先。
A エントリがある場合は許可されない。
Adictionary(PDF 1.1) このアイテムが選択された時に実行されるアクション。
Dest エントリがある場合は許可されない。
SEdictionary(PDF 1.3。間接参照) アイテムが参照する構造要素
Carray(PDF 1.4) アウトラインのテキストに使用される色 (DeviceRGB 色空間)。
0.0〜1.0 の範囲の、3つの数値の配列。
default = [0.0 0.0 0.0]
Finteger(PDF 1.4) アウトラインのテキストのスタイル属性のフラグ値。
default = 0。

bit 0: 斜体
bit 1: 太字
宛先
アウトラインアイテム辞書の Dest エントリでは、移動するページの情報を指定します。
ページの移動先を「宛先」と呼びます。

宛先の指定方法はいくつかあり、[ 配列・名前・byte string ] のいずれかで指定します。
(配列) 宛先を明示的に指定する
配列で指定する場合は、移動先のページなどの情報を明示的に指定します。

以下は、宛先の記述方法の一覧です。

page は、ページオブジェクトの辞書への間接参照です。
left, right, top, bottom は、ページの座標 (ユーザー空間単位) です。

[page /XYZ left top zoom]ページの (left, top) の位置がウィンドウの左上に来るように配置し、指定倍率でズームする。
left, top, zoom の値が null の場合、現在の値を維持します。
zoom は 1.0 で 100%。zoom = 0 は null と同じ。
[page /Fit]ページがウィンドウ全体に収まるように拡大して表示
[page /FitH top]垂直方向は top の位置から表示。
水平方向はページ幅がウィンドウ幅に収まるように拡大される。
[page /FitV left]水平方向は left の位置から表示。
垂直方向はページ高さがウィンドウ高さに収まるように拡大される。
[page /FitR left bottom right top]ページの指定矩形内がウィンドウに収まるように拡大する
[page /FitB](PDF 1.1) ページの境界ボックスがウィンドウ内に収まるように拡大する
[page /FitBH top](PDF 1.1) ページの境界ボックスに合わせる以外は /FitH と同じ
[page /FitBV left](PDF 1.1) ページの境界ボックスに合わせる以外は /FitV と同じ

通常は、[page /Fit] を使います。
(名前) あらかじめ定義した名前の宛先へ [PDF 1.1]
名前オブジェクトで指定する場合、あらかじめ定義した名前の宛先へ移動することができます。

名前と宛先の定義は、カタログ辞書の Dests エントリで、辞書を使って指定します。

この辞書の各キーは「任意の宛先の名前」で、
値は、「上記の明示的な指定方法による配列」または「D エントリで宛先の配列を指定した辞書」です。

値を辞書で指定する場合は、辞書の他のエントリで、追加の属性を関連付けることができます。
(byte string) 文字列を名前として使う宛先 [PDF 1.2]
byte string で指定する場合、あらかじめ定義した文字列 (バイナリデータを含む) の宛先へ移動することができます。
主に、数値などを名前として使いたい場合に使用します。

文字列と宛先の定義は、カタログ辞書の Names エントリで指定する名前辞書の中に、Dests エントリを含めて、その値として名前ツリーを指定します。

名前ツリーのキーは byte string で、値は、名前オブジェクトで指定する場合と同じです。
名前ツリー (name tree)
名前ツリーは、辞書と同じように、キーと値をペアにして記述しますが、以下の点で辞書とは異なります。

  • キーは名前オブジェクトではなく、文字列。
  • 値は、どのタイプのオブジェクトでも良い。
  • 値がストリームオブジェクトの場合は、間接参照によって指定する。
  • 辞書に関する実装上の制限 (要素の最大数) は適用されない。

名前ツリーはツリー構造にすることができます。
先頭がルートノードで、間に中間ノードがあり、末端がリーフノードとなります。

ルートノードのみとする場合は、Names エントリのみを含めます。
名前ツリーのノード辞書
Kidsarrayこのノードの直接の子への間接参照の配列。
子は、中間ノードまたはリーフノードです。
Namesarray(ルートおよびリーフノードのみ。リーフノードでは必須)
配列で、キーと値を連続で指定します。

[key1 value1 key2 value2 ... keyN valueN]

key は文字列で、value はキーに関連付けられるオブジェクト。
キーは文字列の昇順でソートされ、同じ文字列は含まれません。
Limitsarray(ルート以外で必須)
配列で、2つの文字列を指定します。

ツリー上において、このノードのすべての子を対象として、Names エントリの配列内のすべてのキー文字列を比較した時に、一番最小となる文字列と、一番最大となる文字列の2つを指定します。

この情報は、ツリーからキーの文字列を検索する際に、どのノードを辿るかの判定として使われます。

検索したい文字列と比較して、1つ目の文字列より小さい、または2つ目の文字列より大きければ、文字列はそのノードには含まれません。

ツリーにルートノードしか存在しない場合は、Names エントリの先頭のキーが最小で、最後のキーが最大であるため、この項目は必要ありません。
% ルートノード
1 0 obj
<< /Kids [ 2 0 R ] >>
endobj

% リーフノード
2 0 obj
<< /Names [ (abc) 10 0 R
            (def) 11 0 R
            (ghi) 12 0 R
          ]
   /Limits [ (abc) (ghi) ]
>>
endobj
アウトラインの例
2つのページに、各方法で宛先を指定してあります。

なお、/PageMode /UseOutlines で、PDF を開いた時に目次を表示させています。
a. 明示的な宛先指定
>> 09a.pdf

% カタログ辞書
1 0 obj
<< /Type /Catalog
   /Pages 2 0 R
   /Outlines 7 0 R % アウトライン辞書
   /PageMode /UseOutlines
>>
endobj
...
% アウトライン辞書 (ルート)
7 0 obj
<< /Type /Outlines
   /First 8 0 R
   /Last 9 0 R
   /Count 2
>>
endobj

% アウトラインアイテム1
8 0 obj
<< /Title (Item1)
   /Parent 7 0 R
   /Next 9 0 R
   /Dest [ 3 0 R /Fit ] % ページ1へ移動
>>
endobj

% アウトラインアイテム2
9 0 obj
<< /Title (Item2)
   /Parent 7 0 R
   /Prev 8 0 R
   /Dest [ 4 0 R /Fit ] % ページ2へ移動
>>
endobj
b. 名前での宛先指定
>> 09b.pdf

% カタログ辞書
1 0 obj
<< /Type /Catalog
   /Pages 2 0 R
   /Outlines 7 0 R
   /Dests 10 0 R
   /PageMode /UseOutlines
>>
endobj
...
% アウトラインアイテム1
8 0 obj
<< /Title (Item1)
   /Parent 7 0 R
   /Next 9 0 R
   /Dest /item1
>>
endobj

% アウトラインアイテム2
9 0 obj
<< /Title (Item2)
   /Parent 7 0 R
   /Prev 8 0 R
   /Dest /item2
>>
endobj

% 宛先辞書
10 0 obj
<< /item1 [ 3 0 R /Fit ] % /item1 = ページ1
   /item2 [ 4 0 R /Fit ] % /item2 = ページ2
>>
endobj
c. byte string で指定
>> 09c.pdf

% カタログ辞書
1 0 obj
<< /Type /Catalog
   /Pages 2 0 R
   /Outlines 7 0 R
   /Names << /Dests 10 0 R >>
   /PageMode /UseOutlines
>>
endobj
...
% アウトラインアイテム1
8 0 obj
<< /Title (Item1)
   /Parent 7 0 R
   /Next 9 0 R
   /Dest (0001)
>>
endobj

% アウトラインアイテム2
9 0 obj
<< /Title (Item2)
   /Parent 7 0 R
   /Prev 8 0 R
   /Dest (0002)
>>
endobj

% 名前ツリー(ルート)
10 0 obj
<< /Names [ (0001) [3 0 R /Fit]
            (0002) [4 0 R /Fit]
          ]
>>
endobj

※宛先の名前をバイナリデータにすると、宛先へ移動できないビューアがあったため、ASCII 文字列にしています。