Crie camadas de conteúdo opcional (OCG)
Visão geral
Seção intitulada “Visão geral”Envolva o conteúdo em grupos de conteúdo opcional (OCGs) nomeados, frequentemente chamados de camadas. Um leitor de PDF pode alternar cada camada no painel de camadas, e você pode deixar uma camada oculta por padrão. Esta receita segue examples/26-layers.php.
Um OCG é um dicionário de grupo de conteúdo opcional definido pelo ISO 32000-2 com Type /OCG. O NextPDF delimita o conteúdo em camadas entre BDC/EMC e usa a tag de conteúdo marcado OC.
Instalação
Seção intitulada “Instalação”composer require nextpdf/core:^3Você não precisa de nenhuma extensão opcional. A API de camadas é estável desde a 1.0.0 e roda na matriz de backport 8.1–8.4.
Visão conceitual
Seção intitulada “Visão conceitual”startLayer($name, $visible) abre um OCG. Tudo o que você desenhar até chamar o endLayer() correspondente pertence a esse grupo. $name é o rótulo que o leitor de PDF exibe no painel de camadas. O ISO 32000-2 exige o Name do OCG, a string exibida para quem lê o PDF. Passar $visible: false registra o grupo no estado OFF da configuração padrão; assim, o leitor o oculta até que você o ative.
A visibilidade depende da cooperação do leitor. Para um dicionário de associação de conteúdo opcional (OCMD), a política de visibilidade padrão é AnyOn. A camada fica visível se qualquer grupo referenciado estiver ON. Uma camada oculta permanece oculta apenas por convenção do leitor. Ela não é removida nem protegida, e não funciona como redação nem como controle de segurança. Para remover conteúdo, não o desenhe.
Superfície da API
Seção intitulada “Superfície da API”O PHPDoc gera automaticamente a superfície da API. Esta receita usa dois métodos:
startLayer(string $name, bool $visible = true): static— abre um OCG nomeado;$visible: falsedeixa a camada oculta por padrão.endLayer(): static— fecha a camada aberta mais recentemente (balanceada comstartLayer()).
Exemplo de código — Início rápido
Seção intitulada “Exemplo de código — Início rápido”<?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');Exemplo de código — Produção
Seção intitulada “Exemplo de código — Produção”Use este exemplo completo, pronto para a estrutura de testes (harness). Ele respeita NEXTPDF_COOKBOOK_OUTPUT e não adiciona entropia própria.
<?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";Casos extremos e pegadinhas
Seção intitulada “Casos extremos e pegadinhas”- Balanceie cada
startLayer()com umendLayer(). Uma camada não fechada deixa umBDCpendente, semEMCcorrespondente, e torna a estrutura do documento malformada. Emparelhe cada chamada de abertura com a respectiva chamada de fechamento. - Uma camada oculta não é removida.
visible: falseoculta o conteúdo apenas por convenção do leitor. As marcas e qualquer texto permanecem no arquivo e são recuperáveis. Isso não é um recurso de redação. Para dados sensíveis, não os desenhe. - O suporte ao painel de camadas varia. Alternar exige um leitor que exponha o conteúdo opcional. Pipelines de impressão e visualizadores mínimos podem mostrar sempre, ou ocultar sempre, camadas desativadas por padrão.
- Aninhamento. Camadas aninhadas são permitidas, mas a visibilidade de cada grupo interno permanece independente. Não presuma que uma camada externa em OFF oculta um grupo interno em ON, a menos que você configure uma política de associação.
Desempenho
Seção intitulada “Desempenho”Cada camada adiciona um dicionário OCG e um par BDC/EMC ao redor das respectivas marcações. O custo adicional é mínimo. O custo escala com o conteúdo dentro das camadas, não com o número de camadas; por isso, permanece bem dentro do orçamento de 2000 ms / 64 MB.
Notas de segurança
Seção intitulada “Notas de segurança”A visibilidade do conteúdo opcional depende da cooperação do leitor, não é um controle de acesso. Ocultar uma camada não criptografa, não redige nem remove o conteúdo dela. Qualquer pessoa pode reativar a camada ou extrair os bytes. Nunca use uma camada oculta para esconder texto confidencial; em vez disso, omita o conteúdo por completo. Esta receita não processa nenhuma entrada nem faz requisições de rede.
Conformidade
Seção intitulada “Conformidade”| Declaração | Especificação | Cláusula | reference_id |
|---|---|---|---|
Um dicionário OCG tem Type /OCG. | ISO 32000-2 | §8.11.2 | |
O Name do OCG é o rótulo obrigatório exibido para quem lê o PDF. | ISO 32000-2 | §8.11.2 | |
O conteúdo opcional é delimitado entre BDC/EMC com a tag OC. | ISO 32000-2 | §8.11.3.2 | |
| As políticas de OCMD são AllOn/AnyOn/AnyOff/AllOff (padrão AnyOn). | ISO 32000-2 | §8.11.4.3 |
Perfil de reprodutibilidade — estrutural. O /ID do trailer e os átomos de data mudam a cada salvamento. A estrutura de testes (harness) remove esses átomos e compara a estrutura normalizada pelo qpdf. Esta receita descreve como o NextPDF produz essa estrutura. Ela não afirma conformidade geral com o ISO 32000-2.
Contexto comercial
Seção intitulada “Contexto comercial”Não se aplica. Os grupos de conteúdo opcional são um recurso do Core, sem restrição do Premium.