Individual Appearance Create an Individual Field Appearance

Introduction

Each form field has a so called appearance stream which should represent the visible appearance of the field value.

You can access this appearance stream to create an individual appearance by e.g. using an image, a page of another PDF document or by drawing the appearance directly through the canvas instance. The result can be flattened later.

If you want to use such forms as kind of templates while you fill in the field areas with individual content we suggest to use text or push button fields for this purpose.

Access the Current Appearance Canvas

A field appearance is represented by a form XObject which offers you a canvas instance to interact with it. You can simply receive the canvas instance of a form field this way: 

PHP
$field = $fields->get('fieldname');
$canvas = $field->getAppearanceCanvas();

This gives you direct access to a fields canvas and you can use all available methods documented here

Create a New Individual Appearance

It is also possible to create a form XObject by hand and pass this to the widget annotation of the form field:

PHP
// Get the field
$field = $fields->get('fieldname');
// Get the annotation
$annotation = $field->getAnnotation();

// Create a form XObject to which we are going to write the image
// This form XObject will be the resulting appearance of our form field
$xObject = SetaPDF_Core_XObject_Form::create(
    $document, [0, 0, $annotation->getWidth(), $annotation->getHeight()]
);

// Get the canvas for this XObject
$canvas = $xObject->getCanvas();
// ...draw the appearance

// Now add the appearance back to the annotation
$annotation->setAppearance($xObject);

Use an Image

Let's demonstrate this with a simple example: We want to fill in a form field with a company logo. It should be centered and use the full height or width of the form field. 

PHP
<?php
require_once('library/SetaPDF/Autoload.php');

// Setup a document instance
$writer = new SetaPDF_Core_Writer_Http('filled-with-an-image.pdf', true);
$document = SetaPDF_Core_Document::loadByFilename(
    'files/pdfs/Fact-Sheet-form.pdf', $writer
);

// Get a form filler instance
$formFiller = new SetaPDF_FormFiller($document);

// Get the form fields of the document
$fields = $formFiller->getFields();

// Now prepare an appearance for the Logo field
// First of all let's get the annotation of the form field
$annotation = $fields['Logo']->getAnnotation();
// Remember the width and height for further calculations
$width = $annotation->getWidth();
$height = $annotation->getHeight();

// Create a form xobject to which we are going to write the image.
// This form xobject will be the resulting appearance of our form field.
$xObject = SetaPDF_Core_XObject_Form::create($document, [0, 0, $width, $height]);
// Get the canvas for this xobject
$canvas = $xObject->getCanvas();

$image = SetaPDF_Core_Image::getByPath('files/pdfs/tektown/Logo.png')
    ->toXObject($document);

// Let's fit and center the image in the field area:
if ($image->getHeight($width) >= $height) {
    $image->draw(
        $canvas, $width / 2 - $image->getWidth($height) / 2, 0, null, $height
    );
} else {
    $image->draw(
        $canvas, 0, $height / 2 - $image->getHeight($width) / 2, $width
    );
}

// Now add the appearance to the annotation
$annotation->setAppearance($xObject);

// Flatten all appearances to the pages content stream
$fields->flatten();

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

Use a PDF Page

Same example but the company logo is taken from a PDF page: 

PHP
<?php
require_once('library/SetaPDF/Autoload.php');

// Setup a document instance
$writer = new SetaPDF_Core_Writer_Http('filled-with-a-pdf-page.pdf', true);
$document = SetaPDF_Core_Document::loadByFilename(
    'files/pdfs/Fact-Sheet-form.pdf', $writer
);

// Get a form filler instance
$formFiller = new SetaPDF_FormFiller($document);

// Get the form fields of the document
$fields = $formFiller->getFields();

// Now prepare an appearance for the Logo field
// First of all let's get the annotation of the form field
$annotation = $fields['Logo']->getAnnotation();
// Remember the width and height for further calculations
$width = $annotation->getWidth();
$height = $annotation->getHeight();

// Create a form xobject to which we are going to write the image.
// This form xobject will be the resulting appearance of our form field.
$xObject = SetaPDF_Core_XObject_Form::create($document, [0, 0, $width, $height]);
// Get the canvas for this xobject
$canvas = $xObject->getCanvas();

// Let's use an existing PDF page as the logo appearance
$logoDoc = SetaPDF_Core_Document::loadByFilename('files/pdfs/tektown/Logo.pdf');
$image = $logoDoc->getCatalog()->getPages()->getPage(1)
    ->toXObject($document, SetaPDF_Core_PageBoundaries::ART_BOX);

// Let's fit and center the image in the field area:
if ($image->getHeight($width) >= $height) {
    $image->draw(
        $canvas, $width / 2 - $image->getWidth($height) / 2, 0, null, $height
    );
} else {
    $image->draw(
        $canvas, 0, $height / 2 - $image->getHeight($width) / 2, $width
    );
}

// Now add the appearance to the annotation
$annotation->setAppearance($xObject);

// Flatten all appearances to the pages content stream
$fields->flatten();

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

Use The Canvas

The above examples already made use of the canvas object but it is not limited to draw images or pages of existing PDF documents. Let's try to build a logo by using the canvas directly: 

PHP
<?php
require_once('library/SetaPDF/Autoload.php');

// Setup a document instance
$writer = new SetaPDF_Core_Writer_Http('filled-with-a-pdf-page.pdf', true);
$document = SetaPDF_Core_Document::loadByFilename(
    'files/pdfs/Fact-Sheet-form.pdf', $writer
);

// Get a form filler instance
$formFiller = new SetaPDF_FormFiller($document);

// Get the form fields of the document
$fields = $formFiller->getFields();

// Now prepare an appearance for the Logo field
// First of all let's get the annotation of the form field
$annotation = $fields['Logo']->getAnnotation();
// Remember the width and height for further calculations
$width = $annotation->getWidth();
$height = $annotation->getHeight();

// Create a form xobject to which we are going to write the image.
// This form xobject will be the resulting appearance of our form field.
$xObject = SetaPDF_Core_XObject_Form::create($document, [0, 0, $width, $height]);
// Get the canvas for this xobject
$canvas = $xObject->getCanvas();

// Define a font, size and calculate the text width
$font = SetaPDF_Core_Font_Standard_Helvetica::create($document);
$fontSize = 36;
$textWidth = $font->getGlyphsWidth('tektown', 'UTF-8') * $fontSize / 1000;

// Draw the text
$canvas->text()
    ->begin()
    ->setFont($font, $fontSize)
    ->moveToNextLine(($width - $textWidth) / 2, 15) // center
    ->showText($font->getCharsByCharCodes('tek'))
    ->setNonStrokingColor('#3a65af')
    ->showText($font->getCharsByCharCodes('town'))
    ->end();

// Draw the left small tower
$canvas->setNonStrokingColor('#3a65af')
    ->path()
    ->rect(35, 15, 10, 25)
    ->fill();

// Draw the right tower
$canvas->setNonStrokingColor('#3a65af')
    ->path()
    ->rect(55, 15, 15, 30)
    ->fill();

// We need windows
$canvas->setNonStrokingColor('#FFFFFF')
    ->path()
    ->rect(57.5, 35, 3.5, 5.5)
    ->rect(64, 35, 3.5, 5.5)
    ->fill();

// Draw the front house
$canvas
    ->setNonStrokingColor('#3a65af')
    ->setStrokingColor('#FFFFFF')
    ->path()
    ->setLineWidth(1.5)
    ->moveTo(40, 10)
    ->lineTo(60, 10)
    ->lineTo(60, 25)
    ->lineTo(50, 30)
    ->lineTo(40, 25)
    ->closeFillAndStroke();

// Now add the appearance to the annotation
$annotation->setAppearance($xObject);

// Flatten all appearances to the pages content stream
$fields->flatten();

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