5.9.204 (2013-01-23)

- The method Bookmark() was extended to include named destinations, URLs, internal links or embedded files (see example n. 15).
- automatic path calculation on configuration file was fixed.
- Error() method was extended to throw new Exception if PHP > 5.
This commit is contained in:
Nicola Asuni 2013-01-30 17:13:12 +00:00
parent f7d525858a
commit a3bcc0957f
8 changed files with 161 additions and 48 deletions

View File

@ -1,3 +1,8 @@
5.9.204 (2013-01-23)
- The method Bookmark() was extended to include named destinations, URLs, internal links or embedded files (see example n. 15).
- automatic path calculation on configuration file was fixed.
- Error() method was extended to throw new Exception if PHP > 5.
5.9.203 (2013-01-22)
- Horizontal position of radiobuttons and checkboxes was adjusted.

View File

@ -8,8 +8,8 @@ http://sourceforge.net/donate/index.php?group_id=128076
------------------------------------------------------------
Name: TCPDF
Version: 5.9.203
Release date: 2013-01-22
Version: 5.9.204
Release date: 2013-01-30
Author: Nicola Asuni
Copyright (c) 2002-2013:

View File

@ -1,6 +1,6 @@
{
"name": "tecnick.com/tcpdf",
"version": "5.9.203",
"version": "5.9.204",
"homepage": "http://www.tcpdf.org/",
"type": "library",
"description": "TCPDF is a PHP class for generating PDF documents.",

View File

@ -2,7 +2,7 @@
//============================================================+
// File name : tcpdf_config.php
// Begin : 2004-06-11
// Last Update : 2011-04-15
// Last Update : 2013-01-28
//
// Description : Configuration file for TCPDF.
// Author : Nicola Asuni - Tecnick.com LTD - Manor Coach House, Church Hill, Aldershot, Hants, GU12 4RQ, UK - www.tecnick.com - info@tecnick.com
@ -52,6 +52,9 @@ if (!defined('K_TCPDF_EXTERNAL_CONFIG')) {
}
}
// be sure that the end slash is present
$_SERVER['DOCUMENT_ROOT'] = str_replace('//', '/', $_SERVER['DOCUMENT_ROOT'].'/');
// Automatic calculation for the following K_PATH_MAIN constant
$k_path_main = str_replace( '\\', '/', realpath(substr(dirname(__FILE__), 0, 0-strlen('config'))));
if (substr($k_path_main, -1) != '/') {

View File

@ -2,7 +2,7 @@
//============================================================+
// File name : tcpdf_config.php
// Begin : 2004-06-11
// Last Update : 2011-04-15
// Last Update : 2013-01-28
//
// Description : Alternative configuration file for TCPDF.
// Author : Nicola Asuni - Tecnick.com LTD - Manor Coach House, Church Hill, Aldershot, Hants, GU12 4RQ, UK - www.tecnick.com - info@tecnick.com
@ -48,6 +48,9 @@ if ((!isset($_SERVER['DOCUMENT_ROOT'])) OR (empty($_SERVER['DOCUMENT_ROOT']))) {
}
}
// be sure that the end slash is present
$_SERVER['DOCUMENT_ROOT'] = str_replace('//', '/', $_SERVER['DOCUMENT_ROOT'].'/');
// Automatic calculation for the following K_PATH_MAIN constant
$k_path_main = str_replace( '\\', '/', realpath(substr(dirname(__FILE__), 0, 0-strlen('config'))));
if (substr($k_path_main, -1) != '/') {
@ -214,7 +217,7 @@ define ('PDF_IMAGE_SCALE_RATIO', 1.25);
define('HEAD_MAGNIFICATION', 1.1);
/**
* height of cell respect font height
* height of cell repect font height
*/
define('K_CELL_HEIGHT_RATIO', 1.25);

BIN
examples/example_012.pdf Normal file

Binary file not shown.

View File

@ -2,7 +2,7 @@
//============================================================+
// File name : example_015.php
// Begin : 2008-03-04
// Last Update : 2011-04-15
// Last Update : 2013-01-28
//
// Description : Example 015 for TCPDF class
// Bookmarks (Table of Content)
@ -108,7 +108,8 @@ $pdf->Cell(0, 10, 'Paragraph 1.3', 0, 1, 'L');
$pdf->AddPage();
// add a named destination so you can open this document at this page using the link: "example_015.pdf#chapter2"
$pdf->setDestination('chapter2', 0, '');
$pdf->Bookmark('Chapter 2', 0, 0, '', 'BI', array(128,0,0));
// add a bookmark that points to a named destination
$pdf->Bookmark('Chapter 2', 0, 0, '', 'BI', array(128,0,0), -1, '#chapter2');
$pdf->Cell(0, 10, 'Chapter 2', 0, 1, 'L');
$pdf->SetFont('times', 'I', 14);
$pdf->Write(0, 'Once saved, you can open this document at this page using the link: "example_015.pdf#chapter2".');
@ -125,6 +126,31 @@ $pdf->SetFont('times', 'B', 20);
$pdf->Bookmark('Chapter 4', 0, 0, '', 'B', array(0,64,128));
$pdf->Cell(0, 10, 'Chapter 4', 0, 1, 'L');
$pdf->AddPage();
$pdf->Bookmark('Chapter 5', 0, 0, '', 'B', array(0,128,0));
$pdf->Cell(0, 10, 'Chapter 5', 0, 1, 'L');
$txt = 'Example of File Attachment.
Double click on the icon to open the attached file.';
$pdf->SetFont('helvetica', '', 10);
$pdf->Write(0, $txt, '', 0, 'L', true, 0, false, false, 0);
// attach an external file TXT file
$pdf->Annotation(20, 50, 5, 5, 'TXT file', array('Subtype'=>'FileAttachment', 'Name' => 'PushPin', 'FS' => '../cache/utf8test.txt'));
// attach an external file
$pdf->Annotation(50, 50, 5, 5, 'PDF file', array('Subtype'=>'FileAttachment', 'Name' => 'PushPin', 'FS' => 'example_012.pdf'));
// add a bookmark that points to an embedded file
// NOTE: prefix the file name with the * character for generic file and with % character for PDF file
$pdf->Bookmark('TXT file', 0, 0, '', 'B', array(128,0,255), -1, '*utf8test.txt');
// add a bookmark that points to an embedded file
// NOTE: prefix the file name with the * character for generic file and with % character for PDF file
$pdf->Bookmark('PDF file', 0, 0, '', 'B', array(128,0,255), -1, '%example_012.pdf');
// add a bookmark that points to an external URL
$pdf->Bookmark('External URL', 0, 0, '', 'B', array(0,0,255), -1, 'http://www.tcpdf.org');
// ---------------------------------------------------------
//Close and output PDF document

156
tcpdf.php
View File

@ -1,9 +1,9 @@
<?php
//============================================================+
// File name : tcpdf.php
// Version : 5.9.203
// Version : 5.9.204
// Begin : 2002-08-03
// Last Update : 2013-01-22
// Last Update : 2013-01-30
// Author : Nicola Asuni - Tecnick.com LTD - Manor Coach House, Church Hill, Aldershot, Hants, GU12 4RQ, UK - www.tecnick.com - info@tecnick.com
// License : http://www.tecnick.com/pagefiles/tcpdf/LICENSE.TXT GNU-LGPLv3
// -------------------------------------------------------------------
@ -139,7 +139,7 @@
* Tools to encode your unicode fonts are on fonts/utils directory.</p>
* @package com.tecnick.tcpdf
* @author Nicola Asuni
* @version 5.9.203
* @version 5.9.204
*/
// Main configuration file. Define the K_TCPDF_EXTERNAL_CONFIG constant to skip this file.
@ -151,7 +151,7 @@ require_once(dirname(__FILE__).'/config/tcpdf_config.php');
* TCPDF project (http://www.tcpdf.org) has been originally derived in 2002 from the Public Domain FPDF class by Olivier Plathey (http://www.fpdf.org), but now is almost entirely rewritten.<br>
* @package com.tecnick.tcpdf
* @brief PHP class for generating PDF documents without requiring external extensions.
* @version 5.9.203
* @version 5.9.204
* @author Nicola Asuni - info@tecnick.com
*/
class TCPDF {
@ -162,7 +162,7 @@ class TCPDF {
* Current TCPDF version.
* @private
*/
private $tcpdf_version = '5.9.203';
private $tcpdf_version = '5.9.204';
// Protected properties
@ -1706,6 +1706,13 @@ class TCPDF {
*/
protected $n_dests;
/**
* Embedded Files Names
* @protected
* @since 5.9.204 (2013-01-23)
*/
protected $efnames = array();
/**
* Directory used for the last SVG image.
* @protected
@ -3835,8 +3842,13 @@ class TCPDF {
public function Error($msg) {
// unset all class variables
$this->_destroy(true);
$phpmainver = PHP_VERSION;
// exit program and print error
die('<strong>TCPDF ERROR: </strong>'.$msg);
if (intval($phpmainver[0]) < 5) {
die('<strong>TCPDF ERROR: </strong>'.$msg);
} else {
throw new Exception('TCPDF ERROR: '.$msg);
}
}
/**
@ -5670,6 +5682,18 @@ class TCPDF {
$this->Annotation($x, $y, $w, $h, $link, array('Subtype'=>'Link'), $spaces);
}
/**
* Check if the URL exist.
* @param $ur (string) URL to check.
* @return Boolean true if the URl exist, false otherwise.
* @public
* @since 5.9.204 (2013-01-28)
*/
public function isValidURL($url) {
$headers = @get_headers($url);
return (strpos($headers[0], '200') !== false);
}
/**
* Puts a markup annotation on a rectangular area of the page.
* !!!!THE ANNOTATION SUPPORT IS NOT YET FULLY IMPLEMENTED !!!!
@ -5747,12 +5771,12 @@ class TCPDF {
if (!isset($this->PageAnnots[$page])) {
$this->PageAnnots[$page] = array();
}
++$this->n;
$this->PageAnnots[$page][] = array('n' => $this->n, 'x' => $x, 'y' => $y, 'w' => $w, 'h' => $h, 'txt' => $text, 'opt' => $opt, 'numspaces' => $spaces);
$this->PageAnnots[$page][] = array('n' => ++$this->n, 'x' => $x, 'y' => $y, 'w' => $w, 'h' => $h, 'txt' => $text, 'opt' => $opt, 'numspaces' => $spaces);
if (!$this->pdfa_mode) {
if ((($opt['Subtype'] == 'FileAttachment') OR ($opt['Subtype'] == 'Sound')) AND (!$this->empty_string($opt['FS'])) AND file_exists($opt['FS']) AND (!isset($this->embeddedfiles[basename($opt['FS'])]))) {
++$this->n;
$this->embeddedfiles[basename($opt['FS'])] = array('n' => $this->n, 'file' => $opt['FS']);
if ((($opt['Subtype'] == 'FileAttachment') OR ($opt['Subtype'] == 'Sound')) AND (!$this->empty_string($opt['FS']))
AND (file_exists($opt['FS']) OR $this->isValidURL($opt['FS']))
AND (!isset($this->embeddedfiles[basename($opt['FS'])]))) {
$this->embeddedfiles[basename($opt['FS'])] = array('f' => ++$this->n, 'n' => ++$this->n, 'file' => $opt['FS']);
}
}
// Add widgets annotation's icons
@ -5780,15 +5804,24 @@ class TCPDF {
}
reset($this->embeddedfiles);
foreach ($this->embeddedfiles as $filename => $filedata) {
// update name tree
$this->efnames[$filename] = $filedata['f'].' 0 R';
// embedded file specification object
$out = $this->_getobj($filedata['f'])."\n";
$out .= '<</Type /Filespec /F '.$this->_datastring($filename, $filedata['f']).' /EF <</F '.$filedata['n'].' 0 R>> >>';
$out .= "\n".'endobj';
$this->_out($out);
// embedded file object
$data = file_get_contents($filedata['file']);
$filter = '';
$rawsize = strlen($data);
if ($this->compress) {
$data = gzcompress($data);
$filter = ' /Filter /FlateDecode';
}
$stream = $this->_getrawstream($data, $filedata['n']);
$out = $this->_getobj($filedata['n'])."\n";
$out .= '<< /Type /EmbeddedFile'.$filter.' /Length '.strlen($stream).' >>';
$out .= '<< /Type /EmbeddedFile'.$filter.' /Length '.strlen($stream).' /Params <</Size '.$rawsize.'>> >>';
$out .= ' stream'."\n".$stream."\n".'endstream';
$out .= "\n".'endobj';
$this->_out($out);
@ -9834,17 +9867,24 @@ class TCPDF {
if ($pl['txt'][0] == '#') {
// internal destination
$annots .= ' /Dest /'.$this->encodeNameObject(substr($pl['txt'], 1));
} elseif ($pl['txt'][0] == '%') {
// embedded PDF file
$filename = basename(substr($pl['txt'], 1));
$annots .= ' /A << /S /GoToE /D [0 /Fit] /NewWindow true /T << /R /C /P '.($n - 1).' /A '.$this->embeddedfiles[$filename]['a'].' >> >>';
} elseif ($pl['txt'][0] == '*') {
// embedded generic file
$filename = basename(substr($pl['txt'], 1));
$jsa = 'var D=event.target.doc;var MyData=D.dataObjects;for (var i in MyData) if (MyData[i].path=="'.$filename.'") D.exportDataObject( { cName : MyData[i].name, nLaunch : 2});';
$annots .= ' /A << /S /JavaScript /JS '.$this->_textstring($jsa, $annot_obj_id).'>>';
} else {
// external URI link
$annots .= ' /A <</S /URI /URI '.$this->_datastring($this->unhtmlentities($pl['txt']), $annot_obj_id).'>>';
}
} else {
// internal link
if (isset($this->links[$pl['txt']])) {
$l = $this->links[$pl['txt']];
if (isset($this->page_obj_id[($l[0])])) {
$annots .= sprintf(' /Dest [%u 0 R /XYZ 0 %F null]', $this->page_obj_id[($l[0])], ($this->pagedim[$l[0]]['h'] - ($l[1] * $this->k)));
}
} elseif (isset($this->links[$pl['txt']])) {
// internal link ID
$l = $this->links[$pl['txt']];
if (isset($this->page_obj_id[($l[0])])) {
$annots .= sprintf(' /Dest [%u 0 R /XYZ 0 %F null]', $this->page_obj_id[($l[0])], ($this->pagedim[$l[0]]['h'] - ($l[1] * $this->k)));
}
}
$hmodes = array('N', 'I', 'O', 'P');
@ -9941,14 +9981,16 @@ class TCPDF {
break;
}
$filename = basename($pl['opt']['fs']);
if (isset($this->embeddedfiles[$filename]['n'])) {
$annots .= ' /FS <</Type /Filespec /F '.$this->_datastring($filename, $annot_obj_id).' /EF <</F '.$this->embeddedfiles[$filename]['n'].' 0 R>> >>';
if (isset($this->embeddedfiles[$filename]['f'])) {
$annots .= ' /FS '.$this->embeddedfiles[$filename]['f'].' 0 R';
$iconsapp = array('Graph', 'Paperclip', 'PushPin', 'Tag');
if (isset($pl['opt']['name']) AND in_array($pl['opt']['name'], $iconsapp)) {
$annots .= ' /Name /'.$pl['opt']['name'];
} else {
$annots .= ' /Name /PushPin';
}
// index (zero-based) of the annotation in the Annots array of this page
$this->embeddedfiles[$filename]['a'] = $key;
}
break;
}
@ -9957,10 +9999,10 @@ class TCPDF {
break;
}
$filename = basename($pl['opt']['fs']);
if (isset($this->embeddedfiles[$filename]['n'])) {
if (isset($this->embeddedfiles[$filename]['f'])) {
// ... TO BE COMPLETED ...
// /R /C /B /E /CO /CP
$annots .= ' /Sound <</Type /Filespec /F '.$this->_datastring($filename, $annot_obj_id).' /EF <</F '.$this->embeddedfiles[$filename]['n'].' 0 R>> >>';
$annots .= ' /Sound '.$this->embeddedfiles[$filename]['f'].' 0 R';
$iconsapp = array('Speaker', 'Mic');
if (isset($pl['opt']['name']) AND in_array($pl['opt']['name'], $iconsapp)) {
$annots .= ' /Name /'.$pl['opt']['name'];
@ -12689,10 +12731,10 @@ class TCPDF {
$this->_putxobjects();
$this->_putresourcedict();
$this->_putdests();
$this->_putbookmarks();
$this->_putEmbeddedFiles();
$this->_putannotsobjs();
$this->_putjavascript();
$this->_putbookmarks();
$this->_putencryption();
}
@ -12924,12 +12966,19 @@ class TCPDF {
$out .= ' /Pages 1 0 R';
//$out .= ' /PageLabels ' //...;
$out .= ' /Names <<';
if ((!$this->pdfa_mode) AND ((!empty($this->javascript)) OR (!empty($this->js_objects)))) {
$out .= ' /JavaScript '.($this->n_js).' 0 R';
if ((!$this->pdfa_mode) AND !empty($this->n_js)) {
$out .= ' /JavaScript '.$this->n_js;
}
if (!empty($this->efnames)) {
$out .= ' /EmbeddedFiles <</Names [';
foreach ($this->efnames AS $fn => $fref) {
$out .= ' '.$this->_datastring($fn).' '.$fref;
}
$out .= ' ]>>';
}
$out .= ' >>';
if (!empty($this->dests)) {
$out .= ' /Dests '.$this->n_dests.' 0 R';
$out .= ' /Dests '.($this->n_dests).' 0 R';
}
$out .= $this->_putviewerpreferences();
if (isset($this->LayoutMode) AND (!$this->empty_string($this->LayoutMode))) {
@ -16880,10 +16929,12 @@ class TCPDF {
* @param $page (int) Target page number (leave empty for current page).
* @param $style (string) Font style: B = Bold, I = Italic, BI = Bold + Italic.
* @param $color (array) RGB color array (values from 0 to 255).
* @param $x (float) X position in user units of the bookmark on the selected page (default = -1 = current position;).
* @param $link (mixed) URL, or numerical link ID, or named destination (# character followed by the destination name), or embedded file (* character followed by the file name).
* @public
*/
public function setBookmark($txt, $level=0, $y=-1, $page='', $style='', $color=array(0,0,0)) {
$this->Bookmark($txt, $level, $y, $page, $style, $color);
public function setBookmark($txt, $level=0, $y=-1, $page='', $style='', $color=array(0,0,0), $x=-1, $link='') {
$this->Bookmark($txt, $level, $y, $page, $style, $color, $x, $link);
}
/**
@ -16895,11 +16946,11 @@ class TCPDF {
* @param $style (string) Font style: B = Bold, I = Italic, BI = Bold + Italic.
* @param $color (array) RGB color array (values from 0 to 255).
* @param $x (float) X position in user units of the bookmark on the selected page (default = -1 = current position;).
* @param $link (mixed) URL, or numerical link ID, or named destination (# character followed by the destination name), or embedded file (* character followed by the file name).
* @public
* @author Olivier Plathey, Nicola Asuni
* @since 2.1.002 (2008-02-12)
*/
public function Bookmark($txt, $level=0, $y=-1, $page='', $style='', $color=array(0,0,0), $x=-1) {
public function Bookmark($txt, $level=0, $y=-1, $page='', $style='', $color=array(0,0,0), $x=-1, $link='') {
if ($level < 0) {
$level = 0;
}
@ -16932,7 +16983,7 @@ class TCPDF {
return;
}
}
$this->outlines[] = array('t' => $txt, 'l' => $level, 'x' => $x, 'y' => $y, 'p' => $page, 's' => strtoupper($style), 'c' => $color);
$this->outlines[] = array('t' => $txt, 'l' => $level, 'x' => $x, 'y' => $y, 'p' => $page, 's' => strtoupper($style), 'c' => $color, 'u' => $link);
}
/**
@ -17014,7 +17065,34 @@ class TCPDF {
if (isset($o['last'])) {
$out .= ' /Last '.($n + $o['last']).' 0 R';
}
if (isset($this->page_obj_id[($o['p'])])) {
if (isset($o['u']) AND !empty($o['u'])) {
// link
if (is_string($o['u'])) {
if ($o['u'][0] == '#') {
// internal destination
$out .= ' /Dest /'.$this->encodeNameObject(substr($o['u'], 1));
} elseif ($o['u'][0] == '%') {
// embedded PDF file
$filename = basename(substr($o['u'], 1));
$out .= ' /A <</S /GoToE /D [0 /Fit] /NewWindow true /T << /R /C /P '.($o['p'] - 1).' /A '.$this->embeddedfiles[$filename]['a'].' >> >>';
} elseif ($o['u'][0] == '*') {
// embedded generic file
$filename = basename(substr($o['u'], 1));
$jsa = 'var D=event.target.doc;var MyData=D.dataObjects;for (var i in MyData) if (MyData[i].path=="'.$filename.'") D.exportDataObject( { cName : MyData[i].name, nLaunch : 2});';
$out .= ' /A <</S /JavaScript /JS '.$this->_textstring($jsa, $oid).'>>';
} else {
// external URI link
$out .= ' /A <</S /URI /URI '.$this->_datastring($this->unhtmlentities($o['u']), $oid).'>>';
}
} elseif (isset($this->links[$o['u']])) {
// internal link ID
$l = $this->links[$o['u']];
if (isset($this->page_obj_id[($l[0])])) {
$out .= sprintf(' /Dest [%u 0 R /XYZ 0 %F null]', $this->page_obj_id[($l[0])], ($this->pagedim[$l[0]]['h'] - ($l[1] * $this->k)));
}
}
} elseif (isset($this->page_obj_id[($o['p'])])) {
// link to a page
$out .= ' '.sprintf('/Dest [%u 0 R /XYZ %F %F null]', $this->page_obj_id[($o['p'])], ($o['x'] * $this->k), ($this->pagedim[$o['p']]['h'] - ($o['y'] * $this->k)));
}
// set font style
@ -17100,21 +17178,19 @@ class TCPDF {
$jsb = "getField('tcpdfdocsaved').value='saved';";
$this->javascript = $jsa."\n".$this->javascript."\n".$jsb;
}
$this->n_js = $this->_newobj();
$out = ' << /Names [';
// name tree for javascript
$this->n_js = '<< /Names [';
if (!empty($this->javascript)) {
$out .= ' (EmbeddedJS) '.($this->n + 1).' 0 R';
$this->n_js .= ' (EmbeddedJS) '.($this->n + 1).' 0 R';
}
if (!empty($this->js_objects)) {
foreach ($this->js_objects as $key => $val) {
if ($val['onload']) {
$out .= ' (JS'.$key.') '.$key.' 0 R';
$this->n_js .= ' (JS'.$key.') '.$key.' 0 R';
}
}
}
$out .= ' ] >>';
$out .= "\n".'endobj';
$this->_out($out);
$this->n_js .= ' ] >>';
// default Javascript object
if (!empty($this->javascript)) {
$obj_id = $this->_newobj();