Creare livelli di contenuto opzionale (OCG)
In breve
Sezione intitolata “In breve”Racchiudere i contenuti in gruppi denominati di contenuto opzionale (OCG), comunemente chiamati livelli. Il reader può attivare o disattivare ciascun livello nel relativo pannello Livelli e un livello risulta nascosto per impostazione predefinita. Questa ricetta segue examples/26-layers.php.
Un OCG è un dizionario ISO 32000-2 di gruppo di contenuto opzionale con Type /OCG. NextPDF racchiude i marcatori del livello tra BDC/EMC con il tag di contenuto marcato OC.
Installazione
Sezione intitolata “Installazione”composer require nextpdf/core:^3Non è necessaria alcuna estensione opzionale. L’API dei livelli è stabile dalla versione 1.0.0 e supporta la matrice di backport 8.1–8.4.
Panoramica concettuale
Sezione intitolata “Panoramica concettuale”startLayer($name, $visible) apre un OCG. Tutto ciò che viene disegnato fino al corrispondente endLayer() appartiene a quel gruppo. $name è l’etichetta mostrata dal reader nel relativo pannello Livelli. Lo standard ISO 32000-2 rende il Name dell’OCG una stringa obbligatoria destinata all’utente. Passando $visible: false, il gruppo viene registrato nello stato OFF della configurazione predefinita, così il reader lo nasconde finché l’utente non lo attiva.
La visibilità dipende dalla cooperazione del reader. Il criterio di visibilità predefinito per un dizionario di appartenenza è AnyOn: il livello è visibile se almeno uno dei gruppi referenziati è ON. Un livello nascosto lo è solo per convenzione del reader. Non viene rimosso né protetto e non costituisce né oscuramento né controllo di sicurezza. Per rimuovere contenuto, non disegnarlo.
Superficie dell’API
Sezione intitolata “Superficie dell’API”La superficie dell’API è generata automaticamente da PHPDoc. Questa ricetta utilizza due metodi:
startLayer(string $name, bool $visible = true): static— apre un OCG denominato;$visible: falselo nasconde per impostazione predefinita.endLayer(): static— chiude il livello aperto più di recente (bilanciato constartLayer()).
Esempio di codice — Avvio rapido
Sezione intitolata “Esempio di codice — Avvio rapido”<?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');Esempio di codice — Produzione
Sezione intitolata “Esempio di codice — Produzione”Questo è l’esempio completo, pronto per il harness. Rispetta NEXTPDF_COOKBOOK_OUTPUT e non introduce alcuna entropia propria.
<?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";Casi limite e insidie
Sezione intitolata “Casi limite e insidie”- Bilanciare ogni
startLayer()con unendLayer(). Un livello non chiuso lascia unBDCpendente senza il relativoEMC, rendendo malformata la struttura del documento. Abbinare ogni chiamata di apertura alla relativa chiamata di chiusura. - Un livello nascosto non viene rimosso.
visible: falsenasconde il contenuto solo per convenzione del reader. I marcatori e l’eventuale testo restano nel file e sono recuperabili. Questo non è un oscuramento. Per i dati sensibili, non disegnarli. - Il supporto del pannello dei livelli varia. L’attivazione e la disattivazione richiedono un reader che esponga il contenuto opzionale. Le pipeline di stampa e i visualizzatori minimali possono mostrare sempre, oppure nascondere sempre, i livelli disattivati per impostazione predefinita.
- Annidamento. I livelli annidati sono consentiti, ma la visibilità di ogni gruppo interno resta comunque indipendente. Non dare per scontato che un livello esterno OFF nasconda un gruppo interno ON, se non viene collegato un criterio di appartenenza.
Prestazioni
Sezione intitolata “Prestazioni”Ogni livello aggiunge un dizionario OCG e una coppia BDC/EMC attorno ai relativi marcatori. L’overhead risultante è trascurabile. Il costo cresce in proporzione al contenuto all’interno dei livelli, non al numero di livelli; quindi questa ricetta rimane ampiamente entro il budget di 2000 ms / 64 MB.
Note sulla sicurezza
Sezione intitolata “Note sulla sicurezza”La visibilità del contenuto opzionale dipende dalla cooperazione del reader; non è un controllo degli accessi. Nascondere un livello non cifra, non oscura e non rimuove il contenuto. Chiunque può riattivare il livello o estrarne i byte. Non utilizzare mai un livello nascosto per occultare testo riservato; omettere invece del tutto il contenuto. Questa ricetta non esegue alcun parsing dell’input né accessi alla rete.
Conformità
Sezione intitolata “Conformità”| Enunciato | Standard | Clausola | reference_id |
|---|---|---|---|
Un dizionario OCG ha Type /OCG. | ISO 32000-2 | §8.11.2 | |
Il Name dell’OCG è l’etichetta obbligatoria destinata all’utente. | ISO 32000-2 | §8.11.2 | |
Il contenuto opzionale è racchiuso tra BDC/EMC con il tag OC. | ISO 32000-2 | §8.11.3.2 | |
| I criteri OCMD sono AllOn/AnyOn/AnyOff/AllOff (predefinito AnyOn). | ISO 32000-2 | §8.11.4.3 |
Profilo di riproducibilità — strutturale. Il /ID del trailer e gli atomi della data variano a ogni salvataggio. L’harness rimuove tali atomi e confronta la struttura normalizzata con qpdf. Questa ricetta descrive come NextPDF produce tale struttura. Non dichiara una conformità generale a ISO 32000-2.
Contesto commerciale
Sezione intitolata “Contesto commerciale”Non applicabile. I gruppi di contenuto opzionale sono una funzionalità di Core, senza limitazioni Premium.