Przejdź do głównej zawartości

Tworzenie warstw opcjonalnej zawartości (OCG)

Ujmij zawartość w nazwane grupy opcjonalnej zawartości (OCG), często nazywane warstwami. Czytnik PDF może przełączać poszczególne warstwy w panelu warstw, a jedna z nich jest domyślnie ukryta. Ten przepis opiera się na examples/26-layers.php.

OCG to zgodny z ISO 32000-2 słownik grupy opcjonalnej zawartości, który zawiera Type /OCG. NextPDF otacza znaczniki warstwy parą BDC/EMC i używa znacznika oznaczonej zawartości OC.

Okno terminala
composer require nextpdf/core:^3

Nie jest potrzebne żadne opcjonalne rozszerzenie. API warstw jest stabilne od wersji 1.0.0 i działa w macierzy backportu 8.1–8.4.

startLayer($name, $visible) otwiera OCG. Wszystko, co narysujesz aż do odpowiadającego mu endLayer(), należy do tej grupy. $name to etykieta wyświetlana przez czytnik PDF w panelu warstw. ISO 32000-2 wymaga w OCG elementu Name, czyli ciągu widocznego dla użytkownika. Przekazanie $visible: false rejestruje grupę ze stanem OFF w konfiguracji domyślnej, więc czytnik ukrywa ją do czasu włączenia przez użytkownika.

Widoczność zależy od współpracy czytnika. W słowniku przynależności do opcjonalnej zawartości (OCMD) domyślną zasadą widoczności jest AnyOn. Warstwa jest widoczna, jeśli włączona jest którakolwiek z przywoływanych grup. Ukryta warstwa pozostaje ukryta wyłącznie zgodnie z konwencją czytnika. Nie jest usuwana ani chroniona i nie pełni roli redakcji ani mechanizmu zabezpieczającego. Aby usunąć zawartość, po prostu jej nie rysuj.

Powierzchnia API jest generowana automatycznie z PHPDoc. Ten przepis korzysta z dwóch metod:

  • startLayer(string $name, bool $visible = true): static — otwiera nazwaną OCG; $visible: false ustawia ją jako domyślnie ukrytą.
  • endLayer(): static — zamyka ostatnio otwartą warstwę (zrównoważoną z 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');

Użyj tego kompletnego przykładu, gotowego do uruchomienia w środowisku testowym. Uwzględnia NEXTPDF_COOKBOOK_OUTPUT i nie wprowadza własnej entropii.

<?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";
  • Każde wywołanie startLayer() zrównoważ wywołaniem endLayer(). Niezamknięta warstwa pozostawia zawieszone BDC bez EMC i powoduje nieprawidłową strukturę dokumentu. Każde wywołanie otwierające sparuj z odpowiadającym mu wywołaniem zamykającym.
  • Ukryta warstwa nie jest usuwana. visible: false ukrywa zawartość wyłącznie zgodnie z konwencją czytnika. Znaczniki i cały tekst pozostają w pliku i można je odzyskać. To nie jest redakcja. W przypadku danych wrażliwych po prostu ich nie rysuj.
  • Obsługa panelu warstw bywa różna. Przełączanie wymaga czytnika, który udostępnia opcjonalną zawartość. Potoki drukowania i minimalistyczne przeglądarki mogą zawsze pokazywać albo zawsze ukrywać warstwy domyślnie wyłączone.
  • Zagnieżdżanie. Zagnieżdżone warstwy są dozwolone, ale widoczność każdej grupy wewnętrznej pozostaje niezależna. Nie zakładaj, że wyłączona warstwa zewnętrzna ukryje włączoną grupę wewnętrzną, jeśli nie skonfigurujesz zasady przynależności.

Każda warstwa dodaje jeden słownik OCG oraz parę BDC/EMC wokół swoich znaczników. Narzut jest pomijalny. Koszt skaluje się z zawartością wewnątrz warstw, a nie z ich liczbą, więc z dużym zapasem mieści się w budżecie 2000 ms / 64 MB.

Widoczność opcjonalnej zawartości zależy od współpracy czytnika, a nie od kontroli dostępu. Ukrycie warstwy nie szyfruje jej zawartości, nie redaguje jej ani nie usuwa. Każdy może ponownie włączyć warstwę lub wyodrębnić jej bajty. Nigdy nie używaj ukrytej warstwy do ukrywania poufnego tekstu; zamiast tego całkowicie pomiń tę zawartość. Ten przepis nie przetwarza żadnych danych wejściowych ani nie wykonuje żadnych żądań sieciowych.

StwierdzenieSpecyfikacjaKlauzulareference_id
Słownik OCG zawiera Type /OCG.ISO 32000-2§8.11.2
Element Name w OCG jest wymaganą etykietą widoczną dla użytkownika.ISO 32000-2§8.11.2
Opcjonalna zawartość jest umieszczona między BDC/EMC ze znacznikiem OC.ISO 32000-2§8.11.3.2
Zasady OCMD to AllOn/AnyOn/AnyOff/AllOff (domyślnie AnyOn).ISO 32000-2§8.11.4.3

Profil odtwarzalności — strukturalny. Element /ID w trailerze oraz atomy daty zmieniają się przy każdym zapisie. Środowisko testowe usuwa te atomy i porównuje strukturę znormalizowaną przez qpdf. Ten przepis opisuje, jak NextPDF tworzy tę strukturę. Nie potwierdza ogólnej zgodności z ISO 32000-2.

Nie dotyczy. Grupy opcjonalnej zawartości to funkcja Core bez bramki Premium.