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 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 _putpage($n)
    {
        $this->_newobj();
        $this->_put('<</Type /Page');
        $this->_put('/Parent 1 0 R');
        if(isset($this->PageInfo[$n]['size']))
            $this->_put(sprintf('/MediaBox [0 0 %.2F %.2F]', $this->PageInfo[$n]['size'][0], $this->PageInfo[$n]['size'][1]));
        if(isset($this->PageInfo[$n]['rotation']))
            $this->_put('/Rotate '.$this->PageInfo[$n]['rotation']);
        $this->_put('/Resources 2 0 R');
        if(!empty($this->PageLinks[$n]))
        {
            $s = '/Annots [';
            foreach($this->PageLinks[$n] as $pl)
                $s .= $pl[5].' 0 R ';
            $s .= ']';
            $this->_put($s);
        }
        if($this->WithAlpha)
            $this->_put('/Group <</Type /Group /S /Transparency /CS /DeviceRGB>>');
        $this->_put('/Contents '.($this->n+1).' 0 R>>');
        $this->_put('endobj');
        // Page content
        if(!empty($this->AliasNbPages))
            $this->pages[$n] = str_replace($this->AliasNbPages, $this->page, $this->pages[$n]);
        $this->_putstreamobject($this->pages[$n]);
        // Annotations
        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
Es ist ein Fehler aufgetreten

Es ist ein Fehler aufgetreten

Was ist das Problem?

Bei der Ausführung des Skriptes ist ein Fehler aufgetreten. Irgendetwas funktioniert nicht richtig.

Wie kann ich das Problem lösen?

Öffnen Sie die aktuelle Log-Datei im Ordner var/logs bzw. app/logs und suchen Sie die zugehörige Fehlermeldung (normalerweise die letzte).

Weitere Informationen

Die Skriptausführung wurde gestoppt, weil irgendetwas nicht korrekt funktioniert. Die eigentliche Fehlermeldung wird aus Sicherheitsgründen hinter dieser Meldung verborgen und findet sich in der aktuellen Log-Datei (siehe oben). Wenn Sie die Fehlermeldung nicht verstehen oder nicht wissen, wie das Problem zu beheben ist, durchsuchen Sie die Contao-FAQs oder besuchen Sie die Contao-Supportseite.