オプショナルコンテンツレイヤー(OCG)の作成
コンテンツを、一般にレイヤーと呼ばれる名前付きのオプショナルコンテンツグループ(OCG)で囲みます。リーダーのレイヤーパネルで各レイヤーを切り替えられ、1 つのレイヤーは既定で非表示になります。このレシピは examples/26-layers.php に従います。
OCG は、Type /OCG を持つ ISO 32000-2 のオプショナルコンテンツグループ辞書です。NextPDF は、レイヤー化されたマークに OC マークコンテンツタグを付け、BDC/EMC の間に囲みます。
インストール
「インストール」という見出しのセクションcomposer require nextpdf/core:^3追加の拡張機能は必要ありません。レイヤー API は 1.0.0 以降で安定しており、8.1–8.4 のバックポートマトリックスで動作します。
概念の概要
「概念の概要」という見出しのセクションstartLayer($name, $visible) は OCG を開きます。対応する endLayer() が呼ばれるまでに描画された内容はすべて、そのグループに属します。$name は、リーダーがレイヤーパネルに表示するラベルです。ISO 32000-2 では、OCG の Name は必須のユーザー向け文字列とされています。$visible: false を渡すと、グループが既定の構成で OFF 状態として登録されるため、ユーザーがオンにするまでリーダーではそのグループが非表示になります。
表示・非表示はリーダーの協調動作に依存します。メンバーシップ辞書の既定の表示ポリシーは AnyOn であり、参照されているグループのいずれかが ON であればレイヤーが表示されることを意味します。非表示のレイヤーは、リーダー側の慣習に従って非表示になるだけです。削除も保護もされておらず、墨消し(redaction)でもセキュリティ制御でもありません。コンテンツを削除するには、それを描画しないでください。
API サーフェス
「API サーフェス」という見出しのセクションAPI サーフェスは PHPDoc から自動生成されます。このレシピでは、次の 2 つのメソッドを使用します。
startLayer(string $name, bool $visible = true): static— 名前付きの OCG を開きます。$visible: falseを指定すると、既定で非表示になります。endLayer(): static— 最後に開いたレイヤーを閉じます(startLayer()と対応させます)。
コードサンプル — クイックスタート
「コードサンプル — クイックスタート」という見出しのセクション<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->addPage();
$doc->startLayer('Content', visible: true);$doc->setFont('helvetica', '', 12);$doc->cell(0, 8, 'Always-visible body content.', newLine: true);$doc->endLayer();
$doc->startLayer('Debug Grid', visible: false); // hidden until toggled$doc->setDrawColor(200, 200, 200);for ($x = 0.0; $x <= 210.0; $x += 10.0) { $doc->line($x, 0, $x, 297);}$doc->endLayer();
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/layers.pdf');コードサンプル — 本番
「コードサンプル — 本番」という見出しのセクションこれは、ハーネスでそのまま使用できる完全な例です。NEXTPDF_COOKBOOK_OUTPUT に従い、それ自体はエントロピーを固定しません。
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Contracts\Alignment;use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Layer Examples (OCG)');$doc->addPage();
// Layer 1 — background, visible by default.$doc->startLayer('Background', visible: true);$doc->setFillColor(230, 240, 250);$doc->rect(10, 10, 190, 277, 'F');$doc->endLayer();
// Layer 2 — watermark, visible by default; can be toggled off.$doc->startLayer('Watermark', visible: true);$doc->setFont('helvetica', 'B', 54);$doc->setTextColor(200, 200, 200);$doc->startTransform();$doc->rotate(45, 105, 148);$doc->setXY(30, 135);$doc->cell(150, 20, 'DRAFT', align: Alignment::Center);$doc->stopTransform();$doc->endLayer();
// Layer 3 — main content, visible by default.$doc->startLayer('Content', visible: true);$doc->setTextColor(0);$doc->setFont('helvetica', 'B', 20);$doc->setXY(10, 15);$doc->cell(0, 14, 'Layer Examples (OCG)', newLine: true);$doc->ln(4);$doc->setFont('helvetica', '', 11);$doc->multiCell(0, 7, 'This document contains four optional content groups. ' . "Toggle them in your reader's Layers panel.");$doc->endLayer();
// Layer 4 — debug grid, hidden by default.$doc->startLayer('Debug Grid', visible: false);$doc->setDrawColor(180, 180, 180);$doc->setLineWidth(0.15);for ($x = 0.0; $x <= 210.0; $x += 10.0) { $doc->line($x, 0, $x, 297);}for ($y = 0.0; $y <= 297.0; $y += 10.0) { $doc->line(0, $y, 210, $y);}$doc->endLayer();
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/layers.pdf';$doc->save($out);
echo "Created layers.pdf\n";エッジケースと注意点
「エッジケースと注意点」という見出しのセクション- すべての
startLayer()をendLayer()と対応させてください。 閉じられていないレイヤーは、対応するEMCのない宙ぶらりんのBDCを残し、ドキュメント構造が不正な形式になります。各オープン呼び出しは、対応するクローズ呼び出しと対にしてください。 - 非表示のレイヤーは削除されません。
visible: falseは、リーダー側の慣習に従ってコンテンツを非表示にするだけです。マークやテキストは依然としてファイル内にあり、復元可能です。これは墨消し(redaction)ではありません。機密データは描画しないでください。 - レイヤーパネルのサポートはまちまちです。 切り替えには、オプショナルコンテンツを表示できるリーダーが必要です。印刷パイプラインや最小限のビューアーでは、既定でオフのレイヤーを常に表示するか、常に非表示にすることがあります。
- ネスト。 レイヤーのネストは許可されますが、内側の各グループの表示・非表示は依然として独立しています。メンバーシップポリシーを設定しない限り、外側のレイヤーが OFF なら内側の ON グループも非表示になる、とは想定しないでください。
パフォーマンス
「パフォーマンス」という見出しのセクション各レイヤーは、1 つの OCG 辞書と、そのマークを囲む BDC/EMC のペアを追加します。そのオーバーヘッドはごくわずかです。コストはレイヤーの数ではなくレイヤー内のコンテンツに応じて増減するため、2000 ms / 64 MB のバジェット内に十分収まります。
セキュリティに関する注意
「セキュリティに関する注意」という見出しのセクションオプショナルコンテンツの表示・非表示は、リーダーの協調動作によるものであり、アクセス制御ではありません。 レイヤーを非表示にしても、そのコンテンツは暗号化も、墨消しも、削除もされません。誰でもレイヤーを再び有効にしたり、バイト列を抽出したりできます。機密テキストを隠す目的で非表示レイヤーを使用しないでください。代わりに、そのコンテンツを完全に省略してください。このレシピは、入力の解析もネットワークアクセスも行いません。
| 記述 | 仕様 | 箇条 | リファレンス ID |
|---|---|---|---|
Type /OCG を持つ OCG 辞書 | ISO 32000-2 | §8.11.2 | |
OCG の Name は必須のユーザー向けラベル | ISO 32000-2 | §8.11.2 | |
OC タグ付きで BDC/EMC の間に囲まれるオプショナルコンテンツ | ISO 32000-2 | §8.11.3.2 | |
| OCMD のポリシーは AllOn/AnyOn/AnyOff/AllOff(既定は AnyOn) | ISO 32000-2 | §8.11.4.3 |
再現性プロファイル — 構造的。 トレーラーの /ID と日付アトムは、保存のたびに変化します。ハーネスはこれらのアトムを除去し、qpdf で正規化された構造を比較します。このレシピは、NextPDF がその構造をどのように生成するかを説明します。ISO 32000-2 全般への準拠を主張するものではありません。
商用コンテキスト
「商用コンテキスト」という見出しのセクション該当しません。オプショナルコンテンツグループは Core の機能であり、Premium のゲートはありません。