Pro エディション
Flow Layout — 詳細リファレンス
本ページは Pro Flow Layout モジュールの詳細リファレンスです。配置エンジン、要素モデル、改ページ戦略、それらの挙動コントラクト、そして障害モードを扱います。StreamingLayoutEngine は FlowElement 値のリストを順に走査します。各要素にゼロ始まりのページインデックスと LayoutRegion 内の位置を割り当てます。結果は不変な PlacedElement レコードから成る LayoutResult です。本モジュールは配置のみを計算し、レンダリングは行わず、I/O も実行しません。
提供とライセンス
「提供とライセンス」という見出しのセクションこの機能は NextPDF Pro(nextpdf/pro)に同梱され、Pro ティアのライセンスエンベロープで有効化されます。そのエンタイトルメントを持たないデプロイメントでは、この機能のクラスはロードされません。エディションを比較してライセンスを取得。
機能ごとのライセンスフラグは存在しません。これは Pro エディションの機能です。
パブリック API 面
「パブリック API 面」という見出しのセクションすべてのシンボルは NextPDF\Pro\FlowLayout 名前空間に存在します。すべての値オブジェクトは final かつ不変です。
| シンボル | パラメータ | 既定の挙動 | 戻り値 | スローまたは失敗条件 | 備考 |
|---|---|---|---|---|---|
StreamingLayoutEngine::__construct | LayoutRegion $region, PageBreakStrategy $strategy = PageBreakStrategy::Greedy | ページごとのコンテンツ領域を改ページ戦略に束縛 | StreamingLayoutEngine | — | 戦略の既定は Greedy。 |
StreamingLayoutEngine::layout | list<FlowElement> $elements | 単一の前方パス。戦略駆動の改ページを伴う逐次配置 | LayoutResult | 決してスローしない | 空リストは空ページ 1 枚を返す。 |
StreamingLayoutEngine::withStrategy | PageBreakStrategy $strategy | 同じ領域を持つ新しいエンジンを派生 | self | — | レシーバは変更されない。 |
StreamingLayoutEngine::withRegion | LayoutRegion $region | 同じ戦略を持つ新しいエンジンを派生 | self | — | レシーバは変更されない。 |
FlowElement::__construct | FlowElementType $type, string $content, float $widthPt = 0, float $heightPt = 0, float $marginTopPt = 0, float $marginBottomPt = 0, bool $keepWithNext = false | 不変な要素値オブジェクト | FlowElement | — | Table 要素の唯一の構築経路。 |
FlowElement::text | string $content, float $height | 呼び出し側が測定した高さを持つテキスト要素 | self(静的) | — | 幅 0 は配置時に領域幅へ解決。 |
FlowElement::image | string $path, float $width, float $height | 画像要素。content がパスを保持 | self(静的) | — | エンジンはファイルを開かない。 |
FlowElement::spacer | float $height | 空コンテンツの垂直方向の余白 | self(静的) | — | — |
FlowElement::pageBreak | — | 明示的な改ページマーカー | self(静的) | — | PlacedElement を発行しない。 |
FlowElement::totalHeight | — | 高さに上下マージンを加算 | float | — | すべての収まり判定はこの値を使用。 |
FlowElementType | 列挙ケース Text, Image, Table, Spacer, PageBreak | 文字列バック:text, image, table, spacer, page_break | — | — | — |
FlowElementType::isBreakable | — | Text と Table は true、その他は false を返す | bool | — | 分類のみ。以下のアトミック配置コントラクトを参照。 |
LayoutRegion::__construct | float $x, float $y, float $width, float $height | 左上原点のコンテンツボックス。ポイント単位 | LayoutRegion | — | 検証なし。値はそのまま採用。 |
LayoutRegion::contains | float $px, float $py | 境界を含む点包含判定 | bool | — | — |
LayoutRegion::remainingHeight | float $currentY | 領域の高さから消費済み垂直オフセットを減算 | float | — | カーソルがあふれるとゼロまたは負。 |
LayoutResult::__construct | list<PlacedElement> $placements, int $pageCount, float $totalHeightPt | 不変なレイアウト結果 | LayoutResult | — | — |
LayoutResult::placementsOnPage | int $pageIndex | ゼロ始まりのページインデックスで配置をフィルタ | list<PlacedElement> | — | 返されるリストは再インデックスされる。 |
LayoutResult::isEmpty | — | 要素が 1 つも配置されなかったとき true | bool | — | 空入力および改ページのみの入力で true。 |
PageBreakStrategy | 列挙ケース Greedy, AvoidOrphans, KeepTogether | 文字列バック:greedy, avoid_orphans, keep_together | — | — | — |
PageBreakStrategy::label | — | 人間可読の戦略ラベル | string | — | — |
PlacedElement::__construct | FlowElement $element, int $pageIndex, float $x, float $y, float $width, float $height | 不変な配置レコード | PlacedElement | — | 座標はポイント単位、左上原点。 |
public function layout(array $elements): LayoutResultpublic function withStrategy(PageBreakStrategy $strategy): selfpublic function withRegion(LayoutRegion $region): selfpublic static function text(string $content, float $height): selfpublic static function image(string $path, float $width, float $height): selfpublic static function spacer(float $height): selfpublic static function pageBreak(): self挙動コントラクト
「挙動コントラクト」という見出しのセクションStreamingLayoutEngine::layout() は入力リストに対して 1 回の前方パスを実行します。各要素について収まりを確認し、必要であれば改ページし、その後 PlacedElement を記録します。空の入力リストは、配置なし・ページ数 1・総高さ 0 の LayoutResult を返します。
配置ジオメトリは決定的です。
xは領域の左端です。yは現在のカーソル位置に要素の上マージンを加えた値です。widthは要素のwidthPtが正のときはその値、そうでなければ領域幅です。heightは要素のheightPtそのままです。
各配置の後、カーソルはマージンを含む totalHeight() だけ進みます。同じ量が LayoutResult::totalHeightPt に累積されます。
改ページ規則(評価順):
- 明示的な
PageBreak要素はページインデックスをインクリメントし、カーソルを領域の先頭にリセットします。配置は発行せず、総高さにも何も加えません。 - 要素の
totalHeight()が残り高さを超えるとき、エンジンは改ページします — ただしカーソルが既にページ先頭にある場合を除きます。 Greedyは追加条件を課しません。収まる要素は常に配置されます。AvoidOrphansは、配置後に残る空間が正でありながら要素自身の必要高さの半分を下回る場合、収まる要素の前で改ページします。基準単位は要素自身の高さで、固定の除数は 2 です。フォントメトリクスは関与しません。ページ先頭では決して改ページしません。KeepTogetherは、keepWithNextフラグが立ち、次の要素が存在し、カーソルがページ先頭になく、両要素の合計totalHeight()が残り空間を超える場合に、収まる要素の前で改ページします。最終要素のフラグは効果を持ちません。
アトミック配置:エンジンはすべての要素を 1 つの単位として配置します。要素のコンテンツをページ間で分割することは決してありません。FlowElementType::isBreakable() は、呼び出し側がより小さな要素へ事前分割してよい型を分類しますが、エンジン自身はそれを参照しません。
ステートレス性と決定性:エンジンは領域と戦略のみを保持します。layout() は呼び出し間で状態を共有せず、同一入力は同一結果を生みます。withStrategy() と withRegion() は新しいエンジンを返し、レシーバを決して変更しません。
エッジケースと障害モード
「エッジケースと障害モード」という見出しのセクション- 本モジュールのどのメソッドもスローしません。キャッチすべき例外階層は存在しません。
- コンストラクタは何も検証しません。負またはゼロの領域寸法、負の要素高さ、負のマージンは受理され、算術をそのまま通過します。
- 領域より高い要素であっても配置されます。ページ先頭ではそこに配置されてあふれ、それ以外の場所ではエンジンが先に改ページして新しいページであふれます。次の要素は常に改ページを誘発するため、あふれは 1 ページに限定されます。
- 先頭の
PageBreakは最初のコンテンツ要素をページインデックス 1 に配置し、ページ数は少なくとも 2 になります。 - 連続する
PageBreak要素はそれぞれページカウンタを進め、空白ページを生成します。末尾の 1 つはpageCountに最終の空ページを残します。 - keep-together は、ペアの両要素が 1 ページに同時に収まる場合にのみ機能します。合計高さがフルページを超えるペアはやはり分割されます。
- 非正の
widthPtは領域幅へ解決されます。置換判定は厳密にゼロより大です。 - カーソルがあふれると
remainingHeight()はゼロまたは負を返すことがあります。contains()は領域境界を内側として扱います。 - 範囲外のインデックスを渡した
placementsOnPage()は空リストを返します。 - 本モジュールは暗号操作を一切行わず、FIPS 固有の挙動も定義しません。
Flow Layout は NextPDF が定義する配置挙動を実装します。外部のレイアウトまたはタイポグラフィ標準を対象としないため、本ページは規範的な引用テーブルを持ちません。改ページ戦略は NextPDF のセマンティクスであり、CSS フラグメンテーションプロパティや XSL-FO の keep モデルの実装ではありません。すべての寸法はポイントで表され、Core ライタが消費する単位と一致します。
これらの記述は機能のみを説明します。NextPDF は適合認証を保有しておらず、いかなる認証の主張も行われず、暗示もされません。
開発上の注意
「開発上の注意」という見出しのセクション- コンテンツは上流で測定してください。エンジンは呼び出し側が供給する高さを消費し、フォントメトリクスを持たず、テキスト測定を行いません。
- 長いテキストやテーブルのコンテンツはレイアウト前に複数の要素へ事前分割してください。チャンカが分割してよい型を決めるには
isBreakable()を使用します。 - ページジオメトリごとに 1 つのエンジンを再利用してください。
withStrategy()とwithRegion()で変種を安価に派生できます。 - ページ単位でレンダリングする際は
placementsOnPage()で出力をページごとにグループ化してください。 - レイアウトは単一パスで、要素数に対して線形であり、ドキュメントツリーを保持しません。結果は決定的で、ゴールデンファイルテストに適します。
- HTML から PDF へのレンダリングには代わりに Core HTML パイプラインを使用してください。本モジュールは HTML や CSS のエンジンではありません。
本ページは外部から観測可能な挙動とサポートされるパブリック API 面のみを文書化します。内部の名前空間パス、ヘルパークラス、メカニズムテーブル、ランブックのファイル名、チケットプレフィックスは範囲外です。