diff --git a/scripts/ESignaturePlaceholder/ESignaturePlaceholderTrait.php b/scripts/ESignaturePlaceholder/ESignaturePlaceholderTrait.php new file mode 100644 index 0000000..27ad8f0 --- /dev/null +++ b/scripts/ESignaturePlaceholder/ESignaturePlaceholderTrait.php @@ -0,0 +1,86 @@ +PageLinks[$this->page][] = compact('name', 'x', 'y', 'w', 'h'); + + if (! isset($this->SigFields[$this->page])) { + $this->SigFields[$this->page] = true; + $this->PageLinks[$this->page][] = []; // just to reserve the oid on _putpages + } + } + + protected function _putlinks($n) + { + $this->_putsigfields($n); + parent::_putlinks($n); + } + + protected function _putsigfields($n) + { + $pageLinks = $this->PageLinks[$n]; + $this->PageLinks[$n] = []; + $this->SigFields[$n] = []; + foreach ($pageLinks as $pl) + { + if (isset($pl['name'])) // it's a sig placeholder + $this->SigFields[$n][] = $pl; + elseif (isset($pl[0])) // it's a page link + $this->PageLinks[$n][] = $pl; + } + + if (empty($this->SigFields[$n])) + return; + + $fieldRefs = []; + $page = $this->PageInfo[$n]['n'] . ' 0 R'; + + foreach ($this->SigFields[$n] as $i => $f) { + $this->_newobj(); + $fieldRefs[] = $this->n . ' 0 R'; + $name = $f['name'] ?: 'Sign_' . $n. '_' . $i; + $rect = sprintf( + '%.2F %.2F %.2F %.2F', + $f['x'] * $this->k, + ($this->h - $f['y'] - $f['h']) * $this->k, + ($f['x'] + $f['w']) * $this->k, + ($this->h - $f['y']) * $this->k + ); + $this->_put("<>"); + $this->_put('endobj'); + } + + $this->_newobj(); + $this->acroformObjId = $this->n; + $this->_put('<>'); + $this->_put('endobj'); + } + + function _putcatalog() + { + parent::_putcatalog(); + $this->_putesignatureplaceholdercatalog(); + } + + protected function _putesignatureplaceholdercatalog() { + if ($this->acroformObjId) + $this->_put('/AcroForm ' . $this->acroformObjId . ' 0 R'); + } +} diff --git a/scripts/ESignaturePlaceholder/README.md b/scripts/ESignaturePlaceholder/README.md new file mode 100644 index 0000000..e99963b --- /dev/null +++ b/scripts/ESignaturePlaceholder/README.md @@ -0,0 +1,51 @@ +# ESignaturePlaceholderTrait +![GitHub license](https://img.shields.io/badge/license-FPDF-green) +[![Author](https://img.shields.io/badge/author-ErikN-blue)](https://github.com/erikn69) + +This trait handles e-Signature Placeholders + +## Usage +The method to add empty placeholder for e-signature: + +```php +/** + * Add a e-signature placeholder + * + * @param float $x Abscissa of upper-left corner + * @param float $y Ordinate of upper-left corner + * @param float $w Width + * @param float $h Height + * @param string $name Name of pdf object + */ +function AddSignatureField(float $x, float $y, float $w, float $h, string $name = '');; +``` + +## Example + +```php +declare(strict_types=1); + +require dirname(dirname(__DIR__)) . '/fpdf/fpdf.php'; +require __DIR__ . '/ESignaturePlaceholderTrait.php'; + +use FPDF\Scripts\ESignaturePlaceholder\ESignaturePlaceholderTrait; + +$pdf = new class extends FPDF { + use ESignaturePlaceholderTrait; +}; + +$pdf->AddPage(); +$pdf->SetFont('Arial', '', 12); +$pdf->Text(20, 10, 'First Sign Here:'); +// add placeholder with name `SignPlaceholder1` on page 1 +$pdf->AddSignatureField(20, 15, 120, 40, 'SignPlaceholder1'); + +$pdf->AddPage(); +$pdf->SetFont('Arial', '', 12); +$pdf->Text(20, 10, 'Second Sign Here:'); +// add placeholder with default name on page 2 +$pdf->AddSignatureField(20, 15, 120, 40); + +$pdf->Output('F', __DIR__ . '/example.pdf'); +``` +[Result](ex.pdf) diff --git a/scripts/ESignaturePlaceholder/ex.pdf b/scripts/ESignaturePlaceholder/ex.pdf new file mode 100644 index 0000000..70c5586 Binary files /dev/null and b/scripts/ESignaturePlaceholder/ex.pdf differ diff --git a/scripts/ESignaturePlaceholder/ex.php b/scripts/ESignaturePlaceholder/ex.php new file mode 100644 index 0000000..85ea054 --- /dev/null +++ b/scripts/ESignaturePlaceholder/ex.php @@ -0,0 +1,23 @@ +AddPage(); + $pdf->SetFont('Arial', '', 12); + $pdf->Text(20, 10, 'First Sign Here:'); + // add placeholder with name `SignPlaceholder1` on page 1 + $pdf->AddSignatureField(20, 15, 120, 40, 'SignPlaceholder1'); + + $pdf->AddPage(); + $pdf->SetFont('Arial', '', 12); + $pdf->Text(20, 10, 'Second Sign Here:'); + // add placeholder with default name on page 2 + $pdf->AddSignatureField(20, 15, 120, 40); diff --git a/scripts/README.md b/scripts/README.md index 3df84f5..88a8e98 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -20,3 +20,4 @@ $pdf = new class extends FPDF { 95. [Attachments](Attachments) by **Olivier** (2012-04-29) - [QRcode](QRcode) by **Laurent MINGUET** (2010-04-29) +- [ESignaturePlaceholder](ESignaturePlaceholder) by **Erik N.** (2025-12-06) diff --git a/src/FawnoFPDF.php b/src/FawnoFPDF.php index d3f2c29..e8e097b 100644 --- a/src/FawnoFPDF.php +++ b/src/FawnoFPDF.php @@ -9,6 +9,7 @@ use Fawno\FPDF\Traits\BasicFunctionsTrait; use Fawno\FPDF\Traits\EAN13Trait; use Fawno\FPDF\Traits\FontsTrait; + use FPDF\Scripts\ESignaturePlaceholder\ESignaturePlaceholderTrait; use FPDF\Scripts\Attachments\AttachmentsTrait; use FPDF\Scripts\PDFBookmark\PDFBookmarkTrait; use FPDF\Scripts\PDFCircularText\PDFCircularTextTrait; @@ -29,6 +30,9 @@ class FawnoFPDF extends PDFWrapper { AttachmentsTrait::_putresources as Attachments_putresources; AttachmentsTrait::_putcatalog as Attachments_putcatalog; } + use ESignaturePlaceholderTrait{ + ESignaturePlaceholderTrait::_putcatalog as ESignaturePlaceholder_putcatalog; + } use PDFBookmarkTrait { PDFBookmarkTrait::_putresources as PDFBookmark_putresources; PDFBookmarkTrait::_putcatalog as PDFBookmark_putcatalog; @@ -59,5 +63,6 @@ protected function _putcatalog() parent::_putcatalog(); $this->_putbookmarkscatalog(); $this->_putfilescatalog(); + $this->_putesignatureplaceholdercatalog(); } } diff --git a/tests/Scripts/ESignaturePlaceholderTraitTest.php b/tests/Scripts/ESignaturePlaceholderTraitTest.php new file mode 100644 index 0000000..1aabf7a --- /dev/null +++ b/tests/Scripts/ESignaturePlaceholderTraitTest.php @@ -0,0 +1,22 @@ +AddSignatureField(20, 15, 120, 40); + + $this->assertFileCanBeCreated($pdf); + + $this->assertPdfIsOk($pdf); + } + } diff --git a/tests/examples/example.pdf b/tests/examples/example.pdf index 8c4f475..2eaf5e1 100644 Binary files a/tests/examples/example.pdf and b/tests/examples/example.pdf differ diff --git a/tests/examples/exampleESignaturePlaceholderTraitTest.pdf b/tests/examples/exampleESignaturePlaceholderTraitTest.pdf new file mode 100644 index 0000000..ca001b6 Binary files /dev/null and b/tests/examples/exampleESignaturePlaceholderTraitTest.pdf differ diff --git a/tests/test.php b/tests/test.php index 4fec0f3..51e4f98 100644 --- a/tests/test.php +++ b/tests/test.php @@ -38,6 +38,14 @@ $pdf->Bookmark('Paragraph 3', false, 1, -1); $pdf->Cell(0, 6, 'Paragraph 3'); + // ESignaturePlaceholderTrait + // Page 3 + $pdf->AddPage(); + $pdf->AddSignatureField(20, 15, 120, 40); + // Page 4 + $pdf->AddPage(); + $pdf->AddSignatureField(20, 15, 120, 40); + //EAN13Trait $pdf->AddPage(); $pdf->Bookmark('EAN13 Barcode', false);