Ir al contenido

Crear capas de contenido opcional (OCG)

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.

Ventana de terminal
composer require nextpdf/core:^3

No 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.

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.

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: false lo deja oculto de forma predeterminada.
  • endLayer(): static — cierra la capa abierta más recientemente (equilibrada con 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');

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";
  • Equilibrar cada startLayer() con un endLayer(). Una capa sin cerrar deja un BDC colgante sin su EMC, lo que malforma la estructura del documento. Emparejar cada llamada de apertura con su llamada de cierre.
  • Una capa oculta no se elimina. visible: false oculta 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.

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.

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.

DeclaraciónEspecificaciónCláusulareference_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.

No aplica. Los grupos de contenido opcional son una capacidad del núcleo, sin restricción Premium.