addRoot(new SignatureField(new PartialFieldName(new TextString('Demonstration')), value: new IndirectReference($pending))); $form = new AcroForm($fields, entries: new Entry(new NameType('SigFlags'), new IntegerType(3))); $resources = new ResourceDictionary(new Font(new DictionaryType(new Entry(new NameType('F1'), new IndirectReference(new Type1Font(StandardFont::Helvetica)))))); $content = new StreamObject(new ContentStreams( new BeginTextObject(), new SetTextFontAndSize(new NameType('F1'), new NumericType(18)), new MoveTextPosition(new NumericType(48), new NumericType(740)), new ShowText(new LiteralString('Un document signe objet par objet')), new SetTextFontAndSize(new NameType('F1'), new NumericType(11)), new MoveTextPosition(new NumericType(0), new NumericType(-48)), new ShowText(new LiteralString('ByteRange couvre le fichier, sauf la reservation Contents.')), new MoveTextPosition(new NumericType(0), new NumericType(-24)), new ShowText(new LiteralString('Certificat et cle publics de test : aucune confiance attribuee.')), new EndTextObject(), )); $page = new PageObject(new Rectangle(new NumericType(0), new NumericType(0), new NumericType(595), new NumericType(842)), $resources, $content); $catalog = new DocumentCatalog((new PageTreeNode())->addKid($page), new Entry(new NameType('AcroForm'), new IndirectReference($form))); $file = new FileStructure(new FileHeader(), new FileBody($catalog)); // 3. prepare() fixes ByteRange before CMS; sign() fills only Contents // within its reservation. xref offsets and document length stay fixed. $prepared = (new SignatureWriter())->prepare($file, $pending); $signed = $prepared->sign($backend); $path = $argv[1] ?? __DIR__ . '/signed-document.pdf'; $signed->writeTo($path); echo 'PDF written to ' . $path . PHP_EOL;