SetaPDF Demos

There seems to be a problem loading the components. Please check your PHP error logs for details!

Common issues could be that you missed to install the trial license or that you are using a trial version on an unsupported PHP version.

Add a Free Text Annotation to a Signed PDF

A complete example of how to add a free text annotation to a digital signed PDF document.

In this demo we also create the appearance of the free text annotation and calculate the correct coordinates based on the rotation and boundary box values of the page.

Furthermore, we add some normally optional values to the annotation dictionary which are required by Acrobat if the document is e.g. digital signed afterward.

PHP
<?php

use \SetaPDF_Core_Document_Page_Annotation_FreeText as FreeTextAnnotation;

// load and register the autoload function
require_once '../../../../../bootstrap.php';

// let's define some properties first
$x = 10;
$yTop = 10; // we take the upper left as the origin

$borderWidth = 1;

$borderColor = '#FF0000';
$fillColor = '#00FF00';
$textColor = '#0000FF';

$text = "Received: " . date('Y-m-d H:i:s');
$align = SetaPDF_Core_Text::ALIGN_LEFT;

// create a document instance by loading an existing PDF
$writer = new \SetaPDF_Core_Writer_Http('signed+free-text-annotation.pdf', true);
$document = \SetaPDF_Core_Document::loadByFilename(
    $assetsDirectory . '/pdfs/tektown/Laboratory-Report-signed.pdf',
    $writer
);

// we will need a font instance
$font = SetaPDF_Core_Font_Standard_Helvetica::create($document);
$fontSize = 12;

// now we create a text block first to know the final size:
$box = new SetaPDF_Core_Text_Block($font, $fontSize);
$box->setTextColor($textColor);
$box->setBorderWidth($borderWidth);
$box->setBorderColor($borderColor);
$box->setBackgroundColor($fillColor);
$box->setAlign($align);
$box->setText($text);
$box->setPadding(2);

$width = $box->getWidth();
$height = $box->getHeight();

// now draw the text block onto a canvas (we add the $borderWidth to show the complete border)
$appearance = SetaPDF_Core_XObject_Form::create($document, [0, 0, $width + $borderWidth, $height + $borderWidth]);
$box->draw($appearance->getCanvas(), $borderWidth / 2, $borderWidth / 2);

// now we need a page and calculate the correct coordinates for our annotation
$page = $document->getCatalog()->getPages()->getPage(1);
// we need its rotation
$rotation = $page->getRotation();
// ...and page boundary box
$box = $page->getBoundary();

// with this information we create a graphic state
$pageGs = new \SetaPDF_Core_Canvas_GraphicState();
switch ($rotation) {
    case 90:
        $pageGs->translate($box->getWidth(), 0);
        break;
    case 180:
        $pageGs->translate($box->getWidth(), $box->getHeight());
        break;
    case 270:
        $pageGs->translate(0, $box->getHeight());
        break;
}

$pageGs->rotate($box->llx, $box->lly, $rotation);
$pageGs->translate($box->llx, $box->lly);

// ...and a helper function to translate coordinates into vectors by using the page graphic state
$f = static function($x, $y) use ($pageGs) {
    $v = new \SetaPDF_Core_Geometry_Vector($x, $y);
    return $v->multiply($pageGs->getCurrentTransformationMatrix());
};

// calculate the ordinate
$y = $page->getHeight() - $height - $yTop;

$ll = $f($x, $y);
$ur = $f($x + $width + $borderWidth, $y + $height + $borderWidth);

// now we create the annotation object:
$annotation = new FreeTextAnnotation(
    [$ll->getX(), $ll->getY(), $ur->getX(), $ur->getY()],
    'Helv',
    $fontSize,
    $borderColor
);
$annotation->getBorderStyle()->setWidth($borderWidth);
$annotation->setColor($fillColor);
$annotation->setTextLabel("John Dow"); // Used as Author in a Reader application
$annotation->setContents($text);
$annotation->setName(uniqid('', true));
$annotation->setModificationDate(new DateTime());
$annotation->setAppearance($appearance);

// now we need to add some things regarding "variable text" that are required by e.g. Acrobat (if you want to add
// e.g. a digital signature directly after adding a free-text annotation)
$dict = $annotation->getDictionary();
$dict->offsetSet(
    'DS',
    new SetaPDF_Core_Type_String('font: Helvetica, sans-serif ' . sprintf('%.2F', $fontSize) . 'pt;color: ' . $textColor)
);
switch ($align) {
    case SetaPDF_Core_Text::ALIGN_CENTER:
        $align = 'center';
        break;
    case SetaPDF_Core_Text::ALIGN_RIGHT:
        $align = 'right';
        break;
    case SetaPDF_Core_Text::ALIGN_JUSTIFY:
        $align = 'justify';
        break;
    default:
        $align = 'left';
}

$dict->offsetSet('RC', new SetaPDF_Core_Type_String(
    '<?xml version="1.0"?><body xmlns="http://www.w3.org/1999/xhtml" xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/" ' .
    'xfa:APIVersion="Acrobat:11.0.23" xfa:spec="2.0.2"  style="font-size:' . $fontSize . 'pt;text-align:' . $align .
    ';color:' . $textColor . ';font-weight:normal;font-style:normal;font-family:Helvetica,sans-serif;font-stretch:normal">' .
    '<p dir="ltr"><span style="font-family:Helvetica">' . htmlentities($annotation->getContents(), ENT_XML1) . '</span></p></body>'
));

// lastly add the annotation to the page
$page->getAnnotations()->add($annotation);

$document->save()->finish();