Pop PDF
Import

Modifying Imported Pages

A page that came from importFromFile() or merge() is a regular Page object — addText(), addImage() and every other addPage()-style method work on it exactly as they do on a page built from scratch. The examples below stamp a three-page report.pdf, whatever produced it.

Adding Content to an Imported Page#

Import the file, register a font on the imported Document, and add text to one of its pages the same way you would on any other:

PHP
use Pop\Pdf\Pdf;
use Pop\Pdf\Document\Page\Text;
use Pop\Pdf\Document\Font;

$document = Pdf::importFromFile(__DIR__ . '/report.pdf');
$document->addFont(Font::HELVETICA);
$document->getPage(2)->addText(new Text('Reviewed', size: 18), 'Helvetica', x: 400, y: 700);

Pdf::writeToFile($document, filename: __DIR__ . '/stamped.pdf');

That is the stamping pattern in full: import, add, write. Nothing distinguishes the imported pages from one you called addPage() on yourself — a watermark, a page number, a "DRAFT" mark or a signature line all follow the same three steps, and none of them touch report.pdf itself, since importing reads a file rather than opening it for editing in place. addImage() follows the identical pattern for a logo or a signature graphic rather than text:

PHP
use Pop\Pdf\Pdf;
use Pop\Pdf\Document\Page\Image;

$document = Pdf::importFromFile(__DIR__ . '/report.pdf');
$document->getPage(1)->addImage(Image::createImageFromFile(__DIR__ . '/signature.jpg'), x: 72, y: 400);

Pdf::writeToFile($document, filename: __DIR__ . '/stamped-image.pdf');

The imported text on page 1 reads back exactly as before — an image placed over an imported page sits alongside its original content the same way added text does, on its own separate layer rather than replacing anything underneath it.

Working With a Specific Page#

getPage($p) takes a 1-based page number, the same call a document you built yourself uses. Imported with no $pages filter, page numbers match the source file's own numbering exactly, so getPage(2) on the Document above is the same page that was page 2 in report.pdf:

PHP
use Pop\Pdf\Pdf;

$document = Pdf::importFromFile(__DIR__ . '/report.pdf');
$page = $document->getPage(2);

$page->hasImportedPageObject(); // true

hasImportedPageObject() on a Page answers whether that particular page came from an import at all, and getImportedPageObject() hands back the underlying PdfObject\PageObject the reader attached during parsing — Page::importPageObject() is the method that puts it there, called by importFromFile() and merge() themselves rather than by a page author. That object still knows the page's own dimensions from the source file:

PHP
use Pop\Pdf\Pdf;

$document = Pdf::importFromFile(__DIR__ . '/report.pdf');
$imported = $document->getPage(2)->getImportedPageObject();

$imported->getWidth() . 'x' . $imported->getHeight(); // '612x792' for a US Letter source

A page built with new Page(...) and never imported answers hasImportedPageObject() with false and getImportedPageObject() with null, and the check is what tells apart the imported pages from a freshly authored one sitting in the same document:

PHP
use Pop\Pdf\Pdf;
use Pop\Pdf\Document\Page;

$document = Pdf::importFromFile(__DIR__ . '/report.pdf');
$document->addPage(new Page(Page::LETTER));

foreach ($document->getPages() as $i => $page) {
    echo ($i + 1) . ': ' . ($page->hasImportedPageObject() ? 'imported' : 'native') . "\n";
}

That prints imported for pages 1 through 3 — report.pdf's own three pages — and native for page 4, the blank one addPage() added above.

Asking for a page number the document doesn't have raises Pop\Pdf\Exception, the same as it does on any other Document:

PHP
use Pop\Pdf\Pdf;

$document = Pdf::importFromFile(__DIR__ . '/report.pdf');

try {
    $document->getPage(4);
} catch (\Pop\Pdf\Exception $exception) {
    echo $exception->getMessage();
    // Error: That page (4) does not exist.
}

Importing with a $pages filter changes what "page 2" refers to, since the result renumbers from 1 — Selecting Pages covers that in full; the numbering here assumes every source page came across.

Replacing a Page's Content#

clearContent() clears what has been added to a page natively — text, images, paths, annotations and form fields called through addText(), addImage() and the rest — while leaving whatever the page carries from an import untouched. Stamping a page and then clearing it removes the stamp and keeps the original content underneath:

PHP
use Pop\Pdf\Pdf;
use Pop\Pdf\Document\Page\Text;
use Pop\Pdf\Document\Font;

$document = Pdf::importFromFile(__DIR__ . '/report.pdf');
$document->addFont(Font::HELVETICA);
$document->getPage(2)->addText(new Text('Reviewed', size: 18), 'Helvetica', x: 400, y: 700);
$document->getPage(2)->clearContent();

Pdf::writeToFile($document, filename: __DIR__ . '/stamped-cleared.pdf');
Pdf::extractTextFromFile(__DIR__ . '/stamped-cleared.pdf');

That reads back the source's own three pages unchanged — "Reviewed" is gone, but page 2's original text is exactly where it was before the stamp was ever added. clearContent() reaches the page's own $images, $text, $textStreams, $annotations, $paths and $fields, and an imported page's original content lives outside all six, carried on the imported page object importPageObject() attached rather than in any of the arrays addText() and its siblings fill. Calling clearContent() on a page with nothing natively added yet is a safe no-op — there is nothing in those six arrays to clear either way.

Because the source content isn't reachable through clearContent(), replacing it outright rather than adding to it means deleting the imported page and adding a fresh one in its place — deletePage() and addPage(), covered on Creating Documents — rather than importing and clearing.

Fonts on Imported Pages#

Registering a font on an imported or merged document works exactly as it does on one built from scratch, whether or not the source document used fonts of its own. A source's fonts never cross into the result's own registry, so getAvailableFonts() comes back empty on an import, and on a merge given no starter document — there is no name already sitting there to collide with:

PHP
use Pop\Pdf\Pdf;
use Pop\Pdf\Document\Page\Text;
use Pop\Pdf\Document\Font;

$document = Pdf::importFromFile(__DIR__ . '/report.pdf');
$document->addFont(Font::TIMES_BOLD);

$document->getPage(1)->addText(new Text('Signed', size: 16), 'Times-Bold', x: 400, y: 650);
Pdf::writeToFile($document, filename: __DIR__ . '/stamped-font.pdf');

The same holds after a merge() combining sources that used different fonts internally — the merged document's own getAvailableFonts() still comes back empty until something calls addFont() on it, and a font added afterward is available to new text on any of the merged pages, whichever source they came from:

PHP
use Pop\Pdf\Document\Page\Text;
use Pop\Pdf\Document\Font;
use Pop\Pdf\Pdf;

$merged = Pdf::merge([__DIR__ . '/cover.pdf', __DIR__ . '/report.pdf']);
$merged->getAvailableFonts(); // []

$merged->addFont(Font::TIMES_BOLD);
$merged->getPage(4)->addText(new Text('Reviewed', size: 14), 'Times-Bold', x: 400, y: 650);

See Also#

  • Importing — reading a file or byte stream in as a Document, and page selection
  • Merging — combining several files into one document before modifying it
  • Adding Text — the full addText() API this page's samples build on
  • Fonts — registering and checking fonts on any document, imported or not