Named destinations

Add-On Named destinations

Informations

Author:Jan Slabon
License: FPDF

Description

This extension allows to use and define named destinations in a PDF document.

If the $link parameter of SetLink() is prefixed with a "#", it will be registered as a named destination.

If a $link parameter of Link(), Cell(), Write(), ... is prefixed with a "#", it will be treated as a named destination target.

Source

<?php
require_once('fpdf.php');

class PDF_NamedDestinations extends FPDF
{
    protected $namedDestinations = array();
    protected $n_namedDestinations;

    function __construct($orientation='P', $unit='mm', $size='A4')
    {
        if(!defined('FPDF::VERSION'))
            $this->Error('Unsupported FPDF version');
        parent::__construct($orientation, $unit, $size);
    }

    function SetLink($link, $y = 0, $page = -1)
    {
        if (strpos($link, '#') !== 0) {
            parent::SetLink($link);
        } else {
            // Set destination of internal link
            if ($y == -1)
                $y = $this->y;
            if ($page == -1)
                $page = $this->page;
            $this->namedDestinations[substr($link, 1)] = array($page, $y);
        }
    }

    function _putnamedDestinations()
    {
        if ($this->DefOrientation == 'P') {
            $hPt = $this->DefPageSize[1] * $this->k;
        } else {
            $hPt = $this->DefPageSize[0] * $this->k;
        }
        
        $names = array();
        foreach ($this->namedDestinations as $name => $namedDestinations) {
            $h = isset($this->PageInfo[$namedDestinations[0]]['size']) ? $this->PageInfo[$namedDestinations[0]]['size'][1] : $hPt;
            $this->_newobj();
            $this->_put(sprintf('[%d 0 R /XYZ 0 %.2F null]', $this->PageInfo[$namedDestinations[0]]['n'], $h - $namedDestinations[1] * $this->k));
            $this->_put('endobj');

            $names[$name] = $this->n;
        }
        ksort($names, SORT_STRING);

        $this->_newobj();
        $this->n_namedDestinations = $this->n;
        $this->_put('<<');
        $s = array();
        foreach ($names as $name => $n)
            $s[] = $this->_textstring((string)$name) . ' ' . $n . ' 0 R';
        $this->_put('/Names [' . implode(' ', $s) . ']');
        $this->_put('>>');
        $this->_put('endobj');
    }

    function _putresources()
    {
        parent::_putresources();
        if(!empty($this->namedDestinations))
            $this->_putnamedDestinations();
    }

    function _putcatalog()
    {
        parent::_putcatalog();
        if(!empty($this->namedDestinations))
            $this->_put('/Names <</Dests '.$this->n_namedDestinations.' 0 R>>');
    }

    protected function _putlinks($n)
    {
        foreach($this->PageLinks[$n] as $pl)
        {
            $this->_newobj();
            $rect = sprintf('%.2F %.2F %.2F %.2F', $pl[0], $pl[1], $pl[0]+$pl[2], $pl[1]-$pl[3]);
            $s = '<</Type /Annot /Subtype /Link /Rect ['.$rect.'] /Border [0 0 0] ';
            if(is_string($pl[4])) {
                if (strpos($pl[4], '#') === 0) {
                    $s .= '/A <</S /GoTo /D ' . $this->_textstring(substr($pl[4], 1)) . '>>>>';
                } else {
                    $s .= '/A <</S /URI /URI ' . $this->_textstring($pl[4]) . '>>>>';
                }
            } else {
                $l = $this->links[$pl[4]];
                if(isset($this->PageInfo[$l[0]]['size']))
                    $h = $this->PageInfo[$l[0]]['size'][1];
                else
                    $h = ($this->DefOrientation=='P') ? $this->DefPageSize[1]*$this->k : $this->DefPageSize[0]*$this->k;
                $s .= sprintf('/Dest [%d 0 R /XYZ 0 %.2F null]>>', $this->PageInfo[$l[0]]['n'], $h-$l[1]*$this->k);
            }
            $this->_put($s);
            $this->_put('endobj');
        }
    }
}

Example

<?php
require_once('named_destinations.php');

$pdf = new PDF_NamedDestinations();

$pdf->AddPage();
$pdf->SetFont('Arial', '', 14);
$pdf->SetLink('#page-1');
$pdf->Write(10, 'Link to page 2', '#page-2');

$pdf->AddPage();
$pdf->SetLink('#page-2');
$pdf->Write(10, 'Link to page 1', '#page-1');

$pdf->Output();
?>
View the result here.

Download

ZIP | TGZ
An Error Occurred:Internal Server Error

Oops! An Error Occurred

The server returned a "500Internal Server Error".

Something is broken. Please let us know what you were doing when this error occurred. We will fix it as soon as possible. Sorry for any inconvenience caused.