withDeterministic(new DeterministicSettings( $timestamp, \str_repeat('c', 32), )); $doc = Document::createStandalone($config); $doc->setTitle('Barcode Integration Sample Sheet'); $doc->setPrintFooter(false); $doc->enableTaggedPdf(lang: 'en'); $doc->addPage(); $qrOptions = new QrCodeOptions(ecLevel: 'M'); $layout = BarcodeSheetLayout::integration(); $title = $layout['title']; $doc->setFont($layout['fontFamily'], $title['fontStyle'], $title['fontSize']); $doc->setXY($title['x'], $title['y']); $doc->cell(0, $title['height'], $title['text'], newLine: true); $symbolOrigins = []; foreach ($layout['rows'] as $row) { foreach ($row['cells'] as $cell) { $symbolOrigins[$cell['id']] = ['x' => $cell['symbolX'], 'y' => $row['symbolY']]; $doc->setFont($layout['fontFamily'], '', $layout['fontSize']); foreach ($cell['lines'] as $line => $captionLine) { $doc->setXY($cell['captionX'], $row['captionY'] + $line * $layout['lineHeight']); $doc->cell($layout['cellWidth'], $layout['lineHeight'], $captionLine); } } } $symbolSize = $layout['symbolSize']; $doc->write2DBarcodeWithOptions( 'NEXTPDF-TAGGED-FIGURE', Barcode2DType::QRCode, symbolOptions: $qrOptions, appearance: new BarcodeAppearance( altText: 'QR Code for the integration sheet tagged Figure demonstration.', actualTextFromPayload: true, ), x: $symbolOrigins['tagged-qr-figure']['x'], y: $symbolOrigins['tagged-qr-figure']['y'], w: $symbolSize, h: $symbolSize, ); $doc->write2DBarcodeWithOptions( 'NEXTPDF-AUTO-ALT', Barcode2DType::QRCode, symbolOptions: $qrOptions, appearance: new BarcodeAppearance(), x: $symbolOrigins['auto-alt-qr-figure']['x'], y: $symbolOrigins['auto-alt-qr-figure']['y'], w: $symbolSize, h: $symbolSize, ); $doc->write2DBarcodeWithOptions( 'https://nextpdf.dev/barcode/integration', Barcode2DType::QRCode, symbolOptions: $qrOptions, appearance: new BarcodeAppearance(linkify: true), x: $symbolOrigins['linkified-https-qr']['x'], y: $symbolOrigins['linkified-https-qr']['y'], w: $symbolSize, h: $symbolSize, ); $doc->write2DBarcodeWithOptions( 'NEXTPDF-LAYOUT-MARKER', Barcode2DType::QRCode, symbolOptions: $qrOptions, appearance: new BarcodeAppearance(role: BarcodeSemanticRole::Artifact), x: $symbolOrigins['artifact-qr']['x'], y: $symbolOrigins['artifact-qr']['y'], w: $symbolSize, h: $symbolSize, ); $doc->write2DBarcodeWithOptions( 'NEXTPDF-NPBC-DIGEST', Barcode2DType::QRCode, symbolOptions: $qrOptions, appearance: new BarcodeAppearance( altText: 'QR Code used for the Digest-mode npbc metadata demonstration.', ), x: $symbolOrigins['npbc-digest-qr']['x'], y: $symbolOrigins['npbc-digest-qr']['y'], w: $symbolSize, h: $symbolSize, ); $provenanceLedger = new BarcodePlacementLedger(); foreach ($doc->barcodePlacements() as $placement) { if ($placement->rawRequest === null || $placement->canonicalPayload === null) { throw new RuntimeException('Every demonstrated barcode must carry ledger payload contracts.'); } $provenanceLedger->record( pageIndex: $placement->pageIndex, type: $placement->type, payload: $placement->payload, contentDigest: $placement->contentDigest, bounds: $placement->bounds, componentBounds: $placement->componentBounds, rawRequest: $placement->rawRequest, canonicalPayload: $placement->canonicalPayload, symbologyIdentifier: $placement->symbologyIdentifier, ctm: $placement->ctm, optionsSnapshot: $placement->optionsSnapshot, preparedPlacement: $placement, ); } $provenanceExport = new BarcodeProvenanceExporter()->export( $provenanceLedger, BarcodeProvenanceMode::Digest, ); $provenanceBlock = new XmpBarcodeProvenanceEmitter()->render($provenanceExport); $xmpPacket = new XmpMetadataBuilder( title: 'Barcode Integration Sample Sheet', author: '', creatorTool: 'NextPDF', producer: 'NextPDF', createDate: $timestamp, modifyDate: $timestamp, metadataDate: $timestamp, documentId: XmpMetadataBuilder::formatIdentifier(\str_repeat('d', 32)), instanceId: XmpMetadataBuilder::formatIdentifier(\str_repeat('e', 32)), barcodeProvenanceBlock: $provenanceBlock, )->build(); $parsedProvenance = new BarcodeProvenanceImporter()->importXmpPacket( $xmpPacket, documentPageCount: $doc->getNumPages(), ); if ( $parsedProvenance->mode !== BarcodeProvenanceMode::Digest || \count($parsedProvenance->records) !== \count($doc->barcodePlacements()) ) { throw new RuntimeException('The generated Digest-mode npbc XMP packet did not round-trip.'); } $pdfPath = \getenv('NEXTPDF_SAMPLE_OUTPUT') ?: __DIR__ . '/../output/48-barcode-integration.pdf'; $xmpPath = __DIR__ . '/../output/48-barcode-integration.xmp'; $doc->save($pdfPath); if (\file_put_contents($xmpPath, $xmpPacket) === false) { throw new RuntimeException('Unable to write the npbc XMP companion packet.'); } echo "Created: {$pdfPath}\n"; echo "Created: {$xmpPath}\n";