Créer des calques de contenu optionnel (OCG)
Regroupe le contenu dans des groupes de contenu optionnel nommés (OCG), couramment appelés calques. Le lecteur peut activer ou désactiver chaque calque depuis le panneau des calques, et un calque est masqué par défaut. Cette recette suit examples/26-layers.php.
Un OCG correspond à un dictionnaire de groupe de contenu optionnel ISO 32000-2 avec Type /OCG. NextPDF encadre le contenu marqué du calque entre BDC/EMC avec la balise de contenu marqué OC.
Installation
Section intitulée « Installation »composer require nextpdf/core:^3Aucune extension optionnelle n’est nécessaire. L’API des calques est stable depuis la version 1.0.0 et compatible avec la matrice de rétroportage 8.1–8.4.
Vue d’ensemble conceptuelle
Section intitulée « Vue d’ensemble conceptuelle »startLayer($name, $visible) ouvre un OCG. Tout ce qui est dessiné jusqu’à l’appel endLayer() correspondant appartient à ce groupe. $name est le libellé que le lecteur affiche dans son panneau des calques. ISO 32000-2 fait du Name de l’OCG une chaîne obligatoire et visible par l’utilisateur. Passer $visible: false enregistre le groupe à l’état OFF dans la configuration par défaut, de sorte que le lecteur le masque jusqu’à ce que l’utilisateur l’active.
La visibilité dépend de la coopération du lecteur. La politique de visibilité par défaut d’un dictionnaire d’appartenance est AnyOn, ce qui signifie que le calque est visible si au moins un groupe référencé est ON. Un calque masqué l’est uniquement par convention du lecteur. Il n’est ni supprimé ni protégé, et ce n’est ni une expurgation ni un contrôle de sécurité. Pour retirer du contenu, ne le dessine pas.
Surface d’API
Section intitulée « Surface d’API »La surface d’API est générée automatiquement à partir du PHPDoc. Cette recette utilise ces deux méthodes :
startLayer(string $name, bool $visible = true): static— ouvre un OCG nommé ;$visible: falsele rend masqué par défaut.endLayer(): static— ferme le dernier calque ouvert (à équilibrer avecstartLayer()).
Exemple de code — Démarrage rapide
Section intitulée « Exemple de code — Démarrage rapide »<?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');Exemple de code — Production
Section intitulée « Exemple de code — Production »Voici l’exemple complet, prêt à être exécuté par le harness. Il respecte NEXTPDF_COOKBOOK_OUTPUT et ne fige aucune entropie propre.
<?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";Cas limites et pièges
Section intitulée « Cas limites et pièges »- Équilibre chaque
startLayer()avec unendLayer(). Un calque non fermé laisse unBDCsansEMCcorrespondant, ce qui rend la structure du document mal formée. Associe chaque appel d’ouverture à son appel de fermeture. - Un calque masqué n’est pas supprimé.
visible: falsemasque le contenu uniquement par convention du lecteur. Les marques, ainsi que tout texte, restent dans le fichier et sont récupérables. Ce n’est pas une expurgation. Pour les données sensibles, ne les dessine pas. - La prise en charge du panneau des calques varie. Le basculement nécessite un lecteur qui expose le contenu optionnel. Les pipelines d’impression et les lecteurs minimalistes peuvent afficher systématiquement, ou masquer systématiquement, les calques désactivés par défaut.
- Imbrication. Les calques imbriqués sont autorisés, mais la visibilité de chaque groupe interne reste indépendante. Ne suppose pas qu’un calque externe désactivé masque un groupe interne activé, sauf si tu configures une politique d’appartenance à cet effet.
Performance
Section intitulée « Performance »Chaque calque ajoute un dictionnaire OCG ainsi qu’une paire BDC/EMC autour de ses marques. Cette surcharge est négligeable. Le coût croît avec le contenu à l’intérieur des calques, et non avec le nombre de calques ; il reste donc bien en deçà du budget de 2000 ms / 64 Mo.
Notes de sécurité
Section intitulée « Notes de sécurité »La visibilité du contenu optionnel dépend de la coopération du lecteur ; ce n’est pas un contrôle d’accès. Masquer un calque ne chiffre pas, n’expurge pas et ne supprime pas son contenu. N’importe qui peut réactiver le calque ou extraire les octets. N’utilise jamais un calque masqué pour dissimuler du texte confidentiel ; omets entièrement le contenu à la place. Cette recette n’effectue aucune analyse d’entrée et n’établit aucun accès réseau.
Conformité
Section intitulée « Conformité »| Déclaration | Spécification | Article | reference_id |
|---|---|---|---|
Un dictionnaire OCG possède Type /OCG. | ISO 32000-2 | §8.11.2 | |
Le Name de l’OCG est l’étiquette obligatoire visible par l’utilisateur. | ISO 32000-2 | §8.11.2 | |
Le contenu optionnel est encadré entre BDC/EMC avec la balise OC. | ISO 32000-2 | §8.11.3.2 | |
| Les politiques OCMD sont AllOn/AnyOn/AnyOff/AllOff (AnyOn par défaut). | ISO 32000-2 | §8.11.4.3 |
Profil de reproductibilité — structurel. Le /ID du trailer et les atomes de date varient à chaque enregistrement. Le harness retire ces atomes et compare la structure normalisée par qpdf. Cette recette décrit comment NextPDF produit cette structure. Elle n’affirme pas de conformité générale à ISO 32000-2.
Contexte commercial
Section intitulée « Contexte commercial »Sans objet. Les groupes de contenu optionnel sont une fonctionnalité du cœur et ne sont soumis à aucun verrou Premium.