PDFium Delphi Component Docs

トランザクションとして扱うナビゲーション結合

uses に FPdfMerge を追加して TPdfNavigationMergeHelper.MergeFilesWithNavigation を使うか、出力先文書を明示してグローバル関数 MergePdfFilesWithNavigation を呼び出します

ヘルパーはネイティブのページインポートを準備し、階層 outline の再構築、名前付き宛先の結合、ページリンクの再対応付けを行います。結果を別途開いてから呼び出し元の文書を置き換えます

pmnPreserve はソースの階層を維持し、pmnGroupBySource はソースファイル名を見出しとして追加します

タイトル、親子関係、スタイル、色、展開された枝、URI アクション、解決済みの内部ページ宛先を保持します。選択、重複、並べ替えしたページは最初のインポート位置に対応付け、省略したページへの宛先は見出しになります

ページを挿入すると既存の出力先 outline の位置をずらします。ナビゲーションとネイティブページを取得する間、ソースファイルは書き込み共有を拒否して開いたままにします

エラー時に停止する結合だけに対応します。署名済みの出力先、未対応の outline アクション、暗号化の後処理はエラー報告とともに拒否し、失敗やキャンセル時は呼び出し元の文書を保持します

この API は既存のネイティブフォームポリシーを維持します。AcroForm の高度なフィールド衝突処理やリソース処理には FPdfFormMerge を使ってください

名前付き宛先とページリンク

PreserveNamedDestinations と PreservePageLinks はどちらも既定で True です。どちらかを False にすると、追加ナビゲーション処理の該当部分を省略します

名前付き宛先は従来の catalog の /Dests 辞書と /Names/Dests 名前ツリーの両方から読みます。階層ツリー、間接配列、/D を持つ宛先辞書にも対応し、同じキーを両形式が定義した場合は名前ツリーを優先します

結果はバランスの取れた /Names/Dests ツリーを使い、出力先の /EmbeddedFiles など無関係な名前ツリーを保持します。ソースの宛先以外のツリーはインポートしません

キーは UTF-16BE を含む元の PDF 文字列バイトを保持します。/FitH null や /XYZ null 34 null を含め、表示モードとパラメーターを正確に維持します

ポリシー動作
pndReject出力先に既にあるソースキーが見つかると、トランザクション全体を拒否します
pndRename既定のポリシーは衝突しない名前を保持し、衝突する名前に DestinationPrefix を付けます。既定値は Imported_ で、さらに衝突する場合は 2_Imported_Shared など決定的な接頭辞を使います
pndNamespaceすべてのソースキーに DestinationPrefix、1 始まりのソース番号、アンダースコアを付けます。例は Imported_1_Shared です。残る衝突には決定的な数値の接頭辞を付けます

DestinationPrefix は印字可能な ASCII 文字 1 から 256 個で指定します。UTF-16BE のキーには BOM の後ろに接頭辞を挿入します

/Dest または単一の /A /GoTo を使う内部リンク注釈を明示的な宛先に書き換えます。そのため名前衝突で変更された後もリンク先は正しく維持されます

挿入時は既存リンクの所属ページと宛先をずらします。重複インポートしたページには個別のリンク注釈を作り、内部宛先は対象ページの最初の選択位置に対応付けます

省略されたページを指す宛先は名前付き宛先ツリーから削除します。影響するリンクは注釈と他の属性を残し、/Dest または GoTo アクションを削除します

URI リンクは保持します。/Next を使う連鎖リンクアクションは、現在のヘルパーで再対応付けできないため拒否します

不正または循環した宛先ツリー、取得できないオブジェクト参照、名前ツリーのキー重複はトランザクションを拒否します。失敗、キャンセル、上限超過では呼び出し元の文書を変更しません

上限と報告

既定の上限は outline 10,000 項目、深さ 128、タイトル 1,048,576 文字、名前付き宛先 10,000 件、ページリンク 100,000 件、文書 256 MiB です。文書バイト数の上限は MaxInt を超えてはいけません

追加の宛先/リンク処理を有効にした場合、設定できる深さは最大 256、名前付き宛先は最大 65,536、ページリンクは最大 1,000,000 です。ソース取得時の raw キーバイトにも 1 MiB の上限があります

結合する名前付きキーには MaxTitleCharacters と同じ値の独立したバイト上限を使います。各ソースは選択ページで絞り込む前に、指定上限内で取得します

PreservedNamedDestinationCount は最終的な名前付き宛先数、RenamedNamedDestinationCount は選択したポリシーで変更したインポートキー数、RemovedNamedDestinationCount は未解決または省略した宛先数です

RemappedPageLinkCount は既存とインポート両方のリンクにある最終的な内部宛先数、RemovedPageLinkCount は削除した内部宛先数です。/Dest と GoTo の両方があるリンクは、それぞれを 1 件と数えます

公開宣言

type
  TPdfMergeNavigationPolicy= (pmnPreserve, pmnGroupBySource);
  TPdfMergeNamedDestinationPolicy= (pndReject, pndRename, pndNamespace);

  TPdfNavigationMergeOptions= record
    NativeOptions: TPdfBatchMergeOptions;
    NavigationPolicy: TPdfMergeNavigationPolicy;
    MaxOutlineItems: Integer;
    MaxOutlineDepth: Integer;
    MaxTitleCharacters: Integer;
    MaxDocumentBytes: Int64;
    PreserveNamedDestinations, PreservePageLinks: Boolean;
    NamedDestinationPolicy: TPdfMergeNamedDestinationPolicy;
    DestinationPrefix: string;
    MaxNamedDestinations, MaxPageLinks: Integer;
    class function Default: TPdfNavigationMergeOptions; static;
  end;

  TPdfNavigationMergeReport= record
    Succeeded: Boolean;
    Cancelled: Boolean;
    ImportedSourceCount: Integer;
    ImportedPageCount: Integer;
    PreservedOutlineCount: Integer;
    RemovedDestinationCount: Integer;
    SourceGroupCount: Integer;
    PreservedNamedDestinationCount, RenamedNamedDestinationCount: Integer;
    RemovedNamedDestinationCount, RemappedPageLinkCount, RemovedPageLinkCount: Integer;
    ErrorMessage: string;
  end;

  // The caller's document is replaced only after the complete staged result
  // has been independently reopened and its outline destinations checked
  TPdfNavigationMergeHelper= class helper for TPdf
    function MergeFilesWithNavigation(const Sources: TPdfBatchMergeSources;
      const Options: TPdfNavigationMergeOptions;
      out Report: TPdfNavigationMergeReport): Boolean;
  end;

function MergePdfFilesWithNavigation(Destination: TPdf;
  const Sources: TPdfBatchMergeSources;
  const Options: TPdfNavigationMergeOptions;
  out Report: TPdfNavigationMergeReport): Boolean;

低レベルのストリーム処理

FPdfCompress は、ページインポートや疎な PDF リビジョンを自分で管理する呼び出し側に CapturePdfNavigation と WritePdfNavigation を公開します

TPdfNavigationNamedDestination.NameKey は raw PDF キーバイトです。ページ番号は絶対位置の 1 始まりで、0 は未解決の宛先を示します

TPdfNavigationPageLink.PageNumber は所属ページを示します。AnnotationIndex は元の全注釈内での 0 始まりの順序、LinkIndex はリンク注釈だけの 0 始まりの順序です

writer は LinkIndex でリンクを識別し、最終的な所属ページに注釈を複製して、指定された宛先ページと正確な宛先接尾辞を書きます。呼び出し側はインポートに必要な完全な対応表を渡してください

writer には別々のソース/出力ストリームと、暗号化も署名もない文書が必要です。同じストリームを指定した引数拒否ではソースを保持し、その他の失敗では別の出力ストリームを消去します

これらのストリーム関数はページのインポートや実行中の TPdf 文書の置換を行いません。ナビゲーション結合全体には上位のトランザクション関数を使ってください

function CapturePdfNavigation(Source: TStream; MaxNamedDestinations,
  MaxPageLinks, MaxDepth: Integer; out Names: TPdfNavigationNamedDestinations;
  out Links: TPdfNavigationPageLinks; out ErrorText: string): Boolean;

function WritePdfNavigation(Source, Output: TStream;
  const Names: TPdfNavigationNamedDestinations;
  const Links: TPdfNavigationPageLinks; ReplaceNamedDestinations: Boolean;
  out ErrorText: string): Boolean;