コンテンツにスキップ

オプショナルコンテンツレイヤー(OCG)の作成

コンテンツを、一般にレイヤーと呼ばれる名前付きのオプショナルコンテンツグループ(OCG)で囲みます。リーダーのレイヤーパネルで各レイヤーを切り替えられ、1 つのレイヤーは既定で非表示になります。このレシピは examples/26-layers.php に従います。

OCG は、Type /OCG を持つ ISO 32000-2 のオプショナルコンテンツグループ辞書です。NextPDF は、レイヤー化されたマークに OC マークコンテンツタグを付け、BDC/EMC の間に囲みます。

Terminal window
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 サーフェスは 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 のゲートはありません。