コンテンツにスキップ

レイアウト: ヘッダー、フッター、段組み、小冊子、ページマネージャー

Layout モジュールには、Document ファサードが処理を委譲するページ装飾エンジンが含まれます。ヘッダーとフッターのレンダリング、段組みレイアウト、中綴じ小冊子の面付け、構造的なページ操作を担います。これは小規模で安定したモジュールであり、6 つのクラスはすべて@since 1.0.0です。

Terminal window
composer require nextpdf/core:^3

Layoutsrc/Layout/、6 つのクラス、@since 1.0.0)は、HasLayout トレイトの基盤となるエンジン層です。アプリケーションコードはDocument のファサードメソッドを呼び出し、トレイトが各呼び出しをこれらのエンジンのいずれかに振り分けます。このモジュールはマニフェストでstandard リスク、internal 安定性としてマークされており、依存先はCore のみです。クラスを直接構築せず、ファサードを通じてアクセスします。

HeaderFooter は、繰り返し表示されるヘッダーとフッターをレンダリングします。各バンドのタイトル、説明、ロゴ、フォント、マージン、色の状態を保持します。PDF コンテンツストリームのオペレーターはrenderHeader()renderFooter() が生成します。デフォルトのフッターは、右揃えの"page / total" 文字列を出力します。setHeaderCallback()setFooterCallback() は、デフォルトのレイアウトを呼び出し元が指定したクロージャーに置き換えます。getHeaderContentHeight() は、ヘッダーが消費する垂直方向のスペースを返し、ページ本文がその下から開始できるようにします。ドキュメントがタグ付き PDF モードの場合、ヘッダーのコンテンツは構造ツリーの外側に位置するため、自動ヘッダーは上流のHasPages で抑制されます。

ColumnLayout は段組みのフローを管理します。setEqualColumns(int $count, float $totalWidth, float $gap = 5) は、利用可能な幅を等しい段に分割します。setColumnsArray() は、明示的なColumnDefinition の位置と幅を受け取ります。カーソルはselectColumn() で段を選択するか、nextColumn() で次の段へ進めます。getCurrentColumnX()/getCurrentColumnWidth() は、アクティブな段のジオメトリを返します。不正な段数、負のギャップ、または計算された段幅が正でない場合は、PageLayoutException が発生します。

BookletLayout は、中綴じ(センターフォールド)製本のためにページを並べ替えます。reorderPages() は、ページリストを 4 の倍数にパディングし(1 枚の小冊子用紙には 4 つのページスロットがあります)、折ってステープルで綴じた用紙が順番に読めるよう、ページを外側から内側へ面付けします。getMarginAdjustments() は、指定された位置について、各辺の内側(背)と外側(端)のマージンを返します。getSheetCount() は、指定されたページ数に必要な両面用紙の枚数を返します。並べ替えはコンテンツの配置のみを変更します。基盤となる PDF のページシーケンスは線形のまま保たれ、ドキュメント内のページの順序を定義するページツリーと整合します(ISO 32000-2§7.7)。

PageManager は、コンテンツのレンダリングとは別に、構造的なページ操作を提供します。movePage()copyPage()deletePage() は、PageData 配列を参照渡しで操作します。ページ領域(addPageRegion()isInRegion()getRegionOffset())は、書き込み禁止ゾーンを定義します。ページグループ(startPageGroup()getGroupPageNo())は、セクションごとのページ番号付けをサポートします。PageRegionColumnDefinition は、これらのエンジンが使用する 2 つの値キャリアです。Writer モジュールは、結果として得られたページを、Kids エントリがページツリーノードの直接の子への間接参照の配列となるページツリーへシリアライズします(ISO 32000-2§7.7.3.2)。

シンボル種別安定性導入バージョン
HeaderFooter::setHeaderData(string, string, string, float): selfメソッドstable1.0.0
HeaderFooter::setHeaderFont(string, float): self/setHeaderMargin(float): selfメソッドstable1.0.0
HeaderFooter::setFooterFont(string, float): self/setFooterMargin(float): selfメソッドstable1.0.0
HeaderFooter::setHeaderCallback(Closure): self/setFooterCallback(Closure): selfメソッドstable1.0.0
HeaderFooter::getHeaderContentHeight(): floatメソッドstable1.0.0
HeaderFooter::renderHeader(float, float, float, float, int, int): stringメソッドstable1.0.0
HeaderFooter::renderFooter(float, float, float, float, int, int, string): stringメソッドstable1.0.0
ColumnLayout::setEqualColumns(int, float, float): selfメソッドstable1.0.0
ColumnLayout::setColumnsArray(array): self/resetColumns(): selfメソッドstable1.0.0
ColumnLayout::selectColumn(int): self/nextColumn(): boolメソッドstable1.0.0
ColumnLayout::getCurrentColumnX(float): float/getCurrentColumnWidth(float): floatメソッドstable1.0.0
BookletLayout::setBooklet(bool, float, float): voidメソッドstable1.0.0
BookletLayout::reorderPages(array): arrayメソッドstable1.0.0
BookletLayout::getMarginAdjustments(int): array{left: float, right: float}メソッドstable1.0.0
BookletLayout::getSheetCount(int): intメソッドstable1.0.0
PageManager::movePage(int, int, array): void/copyPage(int, array): void/deletePage(int, array): voidメソッドstable1.0.0
PageManager::addPageRegion(float, float, float, float): void/isInRegion(float, float): boolメソッドstable1.0.0
PageManager::getRegionOffset(float, float, float, float): floatメソッドstable1.0.0
PageManager::startPageGroup(): void/getGroupPageNo(int): intメソッドstable1.0.0
PageRegion/ColumnDefinition値キャリアstable1.0.0
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Header and Footer');
$doc->setHeaderData(
title: 'NextPDF Example',
description: 'Header and Footer Demonstration',
);
$doc->setHeaderFont('helvetica', 10);
$doc->setHeaderMargin(5);
$doc->setFooterFont('helvetica', 8);
$doc->setFooterMargin(10);
$doc->addPage();
$doc->setFont('helvetica', 'B', 16);
$doc->cell(0, 12, 'Document with Header and Footer', newLine: true);
$doc->save(__DIR__ . '/output/13-header-footer.pdf');

ソース: examples/13-header-footer.php。ヘッダーはaddPage() ごとにレンダリングされ、フッターはページがフラッシュされるときにレンダリングされます。

フッターコールバックがページ番号テキストを管理し、段組みエンジンが 2 段の本文を制御します。どちらのエンジンにもファサードを通じてアクセスします。

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Two-Column Report');
$doc->setFooterCallback(static function (Document $d): void {
$d->setFont('helvetica', '', 8);
$d->text(180.0, 285.0, 'Page ' . ($d->getPage() + 1));
});
$doc->addPage();
$doc->setEqualColumns(2, gap: 8);
$doc->selectColumn(0);
$doc->setFont('helvetica', '', 10);
$doc->multiCell(0, 6, 'Left column flows here.');
$doc->selectColumn(1);
$doc->multiCell(0, 6, 'Right column flows here.');
$doc->save(__DIR__ . '/output/two-column-report.pdf');

ソース: 以下のパターンに基づきます: examples/13-header-footer.php

  • setEqualColumns() は、1 未満の段数、負のギャップ、または計算された段幅が正でないレイアウトを拒否します。これらのいずれの場合も、劣化したレイアウトを返すのではなくPageLayoutException を発生させます。
  • selectColumn() は範囲外のインデックスを無視して現在の段を維持し、不正なインデックスで例外をスローすることはありません。nextColumn() は、すでに最後の段にある場合にfalse を返します。
  • BookletLayout::reorderPages() は、最後のページの寸法を複製した空白ページで 4 の倍数にパディングします。空のページリストは空の配列を返します。並べ替えは配置のみに影響します。movePage() のインデックスは引き続き論理的な順序を参照します。
  • PageManager::movePage()copyPage()deletePage() は、範囲外のインデックスに対して何も行わずに静かに終了します。これらはisset() で検証し、配列を変更せずに戻ります。ページの欠落が呼び出し元のエラーとなる場合は、インデックスを自分で検証してください。
  • getHeaderContentHeight() は、ヘッダーが無効である場合、またはタイトルと説明のいずれも持たない場合に0.0 を返します。その場合、ページ本文は上マージンから開始します。
  • タグ付き PDF モードでは、自動ヘッダーは上流で抑制されます。アクセシブルなドキュメントのために、構造を意識したレイアウトを構築してください。

ヘッダーとフッターのレンダリングは、O(装飾コンテンツ) でアクティブなページバッファーにオペレーターを追加します。コストは、書き込まれるタイトル、説明、区切り線に比例し、ドキュメントのサイズには比例しません。段組みの計算は、呼び出しごとに O(1) です。BookletLayout::reorderPages() はページ数に対して O(n) であり、1 回限りのパディングパスを伴います。面付けのループは、パディングされた各スロットを 1 回ずつ処理します。PageManager の領域テストは、ポイントごとに O(領域数) です。ページ操作は O(n) の配列スプライスです。これらのエンジンはいずれもドキュメント全体にわたるページ単位の状態を保持しないため、長いドキュメントでのメモリ増加には寄与しません。主要なメモリコストは蓄積されたコンテンツストリームであり、ストリーミングとメモリの概念 で説明しています。HTML パイプラインのレイテンシーとメモリバジェットのゲートはPERFORMANCE-BUDGETS に記載されています。これは HTML レンダリングパスを対象としており、これらのレイアウトエンジンを直接ゲートするものではありません。performance_budget の 1500 ms / 64 MB は、クイックスタートのキャンバスのエンベロープであり、呼び出しごとの契約ではありません。

これらのエンジンは、呼び出し元が指定する文字列とロゴパスを使用します。ロゴパスは画像エンジンを経由し、画像エンジンは埋め込み前にファイルを検証します。renderHeader()renderFooter() は、タイトル、説明、ページ番号のテキストがコンテンツストリームに到達する前に、一元化された PDF 文字列エスケーパーを通じてエスケープします。これにより、呼び出し元のテキストがリテラル文字列の文法から逸脱することはありません。ヘッダーまたはフッターのコールバックは、ドキュメントの他の部分と同じ信頼レベルで呼び出し元のコードを実行します。そのコードが読み取る外部データは、それに応じて扱ってください。PageManager のページ操作は、既存のPageData への参照を移動するものであり、信頼できないバイト列を解析することはありません。

主張規格箇条エビデンス
小冊子出力のためのページ並べ替えは配置のみを変更します。ページツリーは引き続き、ドキュメント内のページの線形順序を定義します。ISO 32000-2§7.7
シリアライズされたページツリーノードのKids エントリは、そのノードの直接の子への間接参照の配列です。ISO 32000-2§7.7.3.2

箇条は言い換えられ、用語集に固定されています。規範的なテキストは複製されていません。