콘텐츠로 이동

선택적 콘텐츠 레이어(OCG) 만들기

콘텐츠를 흔히 레이어라고 부르는 이름 있는 선택적 콘텐츠 그룹(OCG)으로 감쌉니다. 리더는 레이어 패널에서 각 레이어를 토글할 수 있으며, 한 레이어는 기본적으로 숨겨 둡니다. 이 레시피는 examples/26-layers.php를 따릅니다.

OCG는 Type /OCG를 갖는 ISO 32000-2 선택적 콘텐츠 그룹 딕셔너리입니다. NextPDF는 레이어 표시를 BDC/EMC 사이에 OC 마크된 콘텐츠 태그와 함께 둘러쌉니다.

Terminal window
composer require nextpdf/core:^3

선택적 확장 기능은 필요하지 않습니다. 레이어 API는 1.0.0 이후 안정적이며 8.1–8.4 백포트 매트릭스에서 실행됩니다.

startLayer($name, $visible)는 OCG를 엽니다. 대응하는 endLayer()까지 그려진 모든 항목은 해당 그룹에 속합니다. $name은 리더가 레이어 패널에 표시하는 레이블입니다. ISO 32000-2는 OCG Name을 필수 사용자 대상 문자열로 규정합니다. $visible: false를 전달하면 그룹이 기본 구성의 OFF 상태로 등록되므로, 사용자가 켜기 전까지 리더가 이를 숨깁니다.

가시성은 리더 협조 방식입니다. 멤버십 딕셔너리의 기본 가시성 정책은 AnyOn이며, 이는 참조된 그룹 중 하나라도 ON이면 레이어가 표시된다는 뜻입니다. 숨겨진 레이어는 리더 관례에 의해서만 숨겨집니다. 제거되거나 보호되는 것이 아니며, 삭제(redaction)도 보안 제어도 아닙니다. 콘텐츠를 제거하려면 해당 콘텐츠를 그리지 마십시오.

API 표면은 PHPDoc에서 자동 생성됩니다. 이 레시피는 다음 두 메서드를 사용합니다.

  • startLayer(string $name, bool $visible = true): static — 이름 있는 OCG를 엽니다. $visible: false는 이를 기본 숨김 상태로 만듭니다.
  • endLayer(): static — 가장 최근에 연 레이어를 닫습니다(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');

다음은 하니스에서 바로 사용할 수 있는 완전한 예제입니다. NEXTPDF_COOKBOOK_OUTPUT을 따르며 자체적으로 어떤 엔트로피도 고정하지 않습니다.

<?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";
  • 모든 startLayer()endLayer()로 짝을 맞추십시오. 닫히지 않은 레이어는 EMC 없이 매달린 BDC를 남기며, 이로 인해 문서 구조가 잘못된 형식이 됩니다. 각 여는 호출을 그에 대응하는 닫는 호출과 짝지으십시오.
  • 숨겨진 레이어는 제거되지 않습니다. visible: false는 리더 관례에 의해서만 콘텐츠를 숨깁니다. 표시와 모든 텍스트는 여전히 파일 안에 있으며 복구할 수 있습니다. 이는 삭제(redaction)가 아닙니다. 민감한 데이터는 그리지 마십시오.
  • 레이어 패널 지원은 다양합니다. 토글하려면 선택적 콘텐츠를 노출하는 리더가 필요합니다. 인쇄 파이프라인과 최소 기능 뷰어는 기본 꺼짐 레이어를 항상 표시하거나 항상 숨길 수 있습니다.
  • 중첩. 중첩된 레이어는 허용되지만, 각 내부 그룹의 가시성은 여전히 독립적입니다. 멤버십 정책을 연결하지 않는 한, 외부가 OFF인 레이어가 내부가 ON인 그룹을 숨긴다고 가정하지 마십시오.

각 레이어는 OCG 딕셔너리 하나와 해당 표시를 감싸는 BDC/EMC 쌍을 추가합니다. 이 오버헤드는 무시할 수 있는 수준입니다. 비용은 레이어 개수가 아니라 레이어 내부 콘텐츠에 따라 증가하므로, 2000 ms / 64 MB 예산 내에 충분히 들어옵니다.

선택적 콘텐츠 가시성은 리더 협조 방식이며, 접근 제어가 아닙니다. 레이어를 숨긴다고 해서 해당 콘텐츠가 암호화되거나 삭제(redaction)되거나 제거되지는 않습니다. 누구나 레이어를 다시 활성화하거나 바이트를 추출할 수 있습니다. 기밀 텍스트를 숨기기 위해 숨겨진 레이어를 사용하지 마십시오. 대신 콘텐츠를 완전히 생략하십시오. 이 레시피는 입력 파싱이나 네트워크 접근을 수행하지 않습니다.

진술사양조항reference_id 참조 ID
OCG 딕셔너리는 Type /OCG를 갖습니다.ISO 32000-2§8.11.2
OCG Name은 필수 사용자 대상 레이블입니다.ISO 32000-2§8.11.2
선택적 콘텐츠는 BDC/EMC 사이에 OC 태그와 함께 둘러싸입니다.ISO 32000-2§8.11.3.2
OCMD 정책은 AllOn/AnyOn/AnyOff/AllOff입니다(기본값 AnyOn).ISO 32000-2§8.11.4.3

재현성 프로필 — 구조적. 트레일러 /ID와 날짜 원자는 저장할 때마다 달라집니다. 하니스는 해당 원자를 제거하고 qpdf로 정규화된 구조를 비교합니다. 이 레시피는 NextPDF가 그 구조를 어떻게 생성하는지 설명합니다. 이는 일반적인 ISO 32000-2 적합성을 주장하지 않습니다.

해당 없음. 선택적 콘텐츠 그룹은 Core 기능이며, Premium 게이트가 없습니다.