Crear capas de contenido opcional (OCG)
De un vistazo
Sección titulada «De un vistazo»Envuelve el contenido en grupos de contenido opcional (OCG) con nombre, comúnmente denominados capas. El lector puede activar o desactivar cada capa desde su panel de capas, y una de ellas queda oculta de forma predeterminada. Esta recipe sigue examples/26-layers.php.
Un OCG es un diccionario de grupo de contenido opcional según ISO 32000-2, con Type /OCG. NextPDF encierra las marcas en capas entre BDC/EMC usando la etiqueta de contenido marcado OC.
Instalación
Sección titulada «Instalación»composer require nextpdf/core:^3No se requiere ninguna extensión opcional. La API de capas es estable desde la versión 1.0.0 y es compatible con la matriz de backport 8.1-8.4.
Resumen conceptual
Sección titulada «Resumen conceptual»startLayer($name, $visible) abre un OCG. Todo lo que se dibuje hasta la llamada correspondiente a endLayer() queda asociado a ese grupo. $name es la etiqueta que el lector muestra en su panel de capas. ISO 32000-2 exige que el Name del OCG sea una cadena obligatoria y visible para el usuario. Pasar $visible: false registra el grupo en el estado OFF de la configuración predeterminada, de modo que el lector lo oculte hasta que el usuario lo active.
La visibilidad depende de que el lector coopere. La política de visibilidad predeterminada para un diccionario de membresía es AnyOn, lo que significa que la capa es visible si cualquiera de los grupos referenciados está activado. Una capa oculta lo está solo por convención del lector. No se elimina ni queda protegida, y no es redacción ni control de seguridad. Para eliminar contenido, omitirlo por completo.
Superficie de la API
Sección titulada «Superficie de la API»La superficie de la API se genera automáticamente a partir del PHPDoc. Esta recipe utiliza estos dos métodos:
startLayer(string $name, bool $visible = true): static— abre un OCG con nombre;$visible: falselo deja oculto de forma predeterminada.endLayer(): static— cierra la capa abierta más recientemente (equilibrada constartLayer()).
Ejemplo de código — Inicio rápido
Sección titulada «Ejemplo de código — Inicio 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');Ejemplo de código — Producción
Sección titulada «Ejemplo de código — Producción»Este es el ejemplo completo, listo para el arnés. Respeta NEXTPDF_COOKBOOK_OUTPUT y no fija ninguna entropía propia.
<?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 límite y trampas
Sección titulada «Casos límite y trampas»- Equilibrar cada
startLayer()con unendLayer(). Una capa sin cerrar deja unBDCcolgante sin suEMC, lo que malforma la estructura del documento. Emparejar cada llamada de apertura con su llamada de cierre. - Una capa oculta no se elimina.
visible: falseoculta el contenido solo por convención del lector. Las marcas y cualquier texto permanecen en el archivo y pueden recuperarse. Esto no es redacción. Para datos sensibles, no dibujarlos. - La compatibilidad con el panel de capas varía. Para activar y desactivar capas, se necesita un lector que exponga el contenido opcional. Las canalizaciones de impresión y los visores mínimos pueden mostrar siempre las capas desactivadas de forma predeterminada, u ocultarlas siempre.
- Anidamiento. Se permiten capas anidadas, pero la visibilidad de cada grupo interno sigue siendo independiente. No debe suponerse que una capa externa desactivada oculta un grupo interno activado, a menos que se conecte una política de membresía.
Rendimiento
Sección titulada «Rendimiento»Cada capa añade un diccionario OCG y un par BDC/EMC alrededor de sus marcas. Esa sobrecarga es insignificante. El costo escala con el contenido dentro de las capas, no con el número de capas, por lo que se mantiene holgadamente dentro del presupuesto de 2000 ms / 64 MB.
Notas de seguridad
Sección titulada «Notas de seguridad»La visibilidad del contenido opcional depende de que el lector coopere; no es un control de acceso. Ocultar una capa no cifra, no redacta ni elimina su contenido. Cualquiera puede volver a habilitar la capa o extraer los bytes. Nunca debe usarse una capa oculta para ocultar texto confidencial; en su lugar, omitir el contenido por completo. Esta recipe no analiza entradas ni accede a la red.
Conformidad
Sección titulada «Conformidad»| Declaración | Especificación | Cláusula | reference_id |
|---|---|---|---|
Un diccionario OCG tiene Type /OCG. | ISO 32000-2 | §8.11.2 | |
El Name del OCG es la etiqueta obligatoria visible para el usuario. | ISO 32000-2 | §8.11.2 | |
El contenido opcional se encierra entre BDC/EMC con la etiqueta OC. | ISO 32000-2 | §8.11.3.2 | |
| Las políticas OCMD son AllOn/AnyOn/AnyOff/AllOff (AnyOn de forma predeterminada). | ISO 32000-2 | §8.11.4.3 |
Perfil de reproducibilidad — estructural. El /ID del tráiler y los átomos de fecha varían en cada guardado. El arnés elimina esos átomos y compara la estructura normalizada mediante qpdf. Esta recipe describe cómo NextPDF produce esa estructura. No afirma conformidad general con ISO 32000-2.
Contexto comercial
Sección titulada «Contexto comercial»No aplica. Los grupos de contenido opcional son una capacidad del núcleo, sin restricción Premium.