Qual: update fpdi libraries:

FPDF_TPL v1.1.4
FPDI v1.3.2
FPDI_Protection v1.0.3
This commit is contained in:
Regis Houssin 2010-03-03 09:13:45 +00:00
parent 3605390156
commit 925ead825c
14 changed files with 2829 additions and 2590 deletions

View File

@ -14,10 +14,10 @@ ArtiChow 1.07 Public Domain Yes Graphics
Php-barcode 0.3pl1 GPL 2.0 Yes Bar code generation Php-barcode 0.3pl1 GPL 2.0 Yes Bar code generation
EFC/XFSS 1.0.1 LGPL 3.0 Yes Enhanced File Crypt/Extended File Stealth System EFC/XFSS 1.0.1 LGPL 3.0 Yes Enhanced File Crypt/Extended File Stealth System
FCKEditor 2.6.4 LGPL 2.1 or Mozilla PL 1.0 Yes Editor WYSIWYG FCKEditor 2.6.4 LGPL 2.1 or Mozilla PL 1.0 Yes Editor WYSIWYG
FPDF 1.53 Public domain Yes PDF generation (original code is modified) FPDF 1.6 Public domain Yes PDF generation (original code is modified)
FPDF_TPL 1.1.2 Apache Software License 2.0 No GPL3 only PDF templates management FPDF_TPL 1.1.4 Apache Software License 2.0 No GPL3 only PDF templates management
FPDI 1.2.1 Apache Software License 2.0 No GPL3 only PDF templates management FPDI 1.3.2 Apache Software License 2.0 No GPL3 only PDF templates management
FPDI_Protection 1.0.2 Apache Software License 2.0 No GPL3 only PDF encryption (8 files) FPDI_Protection 1.0.3 Apache Software License 2.0 No GPL3 only PDF encryption (8 files)
GeoIP x.x Yes GeoIP Maxmind conversion GeoIP x.x Yes GeoIP Maxmind conversion
iWebkit 4.6.2 LGPL 3.0 Yes Iphone templates framework iWebkit 4.6.2 LGPL 3.0 Yes Iphone templates framework
JCrop 0.9.8 MIT Licence Yes JS library to crop images JCrop 0.9.8 MIT Licence Yes JS library to crop images

View File

@ -1,95 +0,0 @@
<?php
//
// FPDI - Version 1.2.1
//
// Copyright 2004-2008 Setasign - Jan Slabon
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
if (!defined("ORD_z"))
define("ORD_z",ord('z'));
if (!defined("ORD_exclmark"))
define("ORD_exclmark", ord('!'));
if (!defined("ORD_u"))
define("ORD_u", ord("u"));
if (!defined("ORD_tilde"))
define("ORD_tilde", ord('~'));
class ASCII85Decode {
function ASCII85Decode(&$fpdi) {
$this->fpdi =& $fpdi;
}
function decode($in) {
$out = "";
$state = 0;
$chn = null;
$l = strlen($in);
for ($k = 0; $k < $l; ++$k) {
$ch = ord($in[$k]) & 0xff;
if ($ch == ORD_tilde) {
break;
}
if (preg_match("/^\s$/",chr($ch))) {
continue;
}
if ($ch == ORD_z && $state == 0) {
$out .= chr(0).chr(0).chr(0).chr(0);
continue;
}
if ($ch < ORD_exclmark || $ch > ORD_u) {
$this->fpdi->error("Illegal character in ASCII85Decode.");
}
$chn[$state++] = $ch - ORD_exclmark;
if ($state == 5) {
$state = 0;
$r = 0;
for ($j = 0; $j < 5; ++$j)
$r = $r * 85 + $chn[$j];
$out .= chr($r >> 24);
$out .= chr($r >> 16);
$out .= chr($r >> 8);
$out .= chr($r);
}
}
$r = 0;
if ($state == 1)
$this->fpdi->error("Illegal length in ASCII85Decode.");
if ($state == 2) {
$r = $chn[0] * 85 * 85 * 85 * 85 + ($chn[1]+1) * 85 * 85 * 85;
$out .= chr($r >> 24);
}
else if ($state == 3) {
$r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + ($chn[2]+1) * 85 * 85;
$out .= chr($r >> 24);
$out .= chr($r >> 16);
}
else if ($state == 4) {
$r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + $chn[2] * 85 * 85 + ($chn[3]+1) * 85 ;
$out .= chr($r >> 24);
$out .= chr($r >> 16);
$out .= chr($r >> 8);
}
return $out;
}
}

View File

@ -1,147 +0,0 @@
<?php
//
// FPDI - Version 1.2.1
//
// Copyright 2004-2008 Setasign - Jan Slabon
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
class LZWDecode {
var $sTable = array();
var $data = null;
var $tIdx;
var $bitsToGet = 9;
var $bytePointer;
var $bitPointer;
var $nextData = 0;
var $nextBits = 0;
var $andTable = array(511, 1023, 2047, 4095);
function LZWDecode(&$fpdi) {
$this->fpdi =& $fpdi;
}
/**
* Method to decode LZW compressed data.
*
* @param string data The compressed data.
*/
function decode($data) {
if($data[0] == 0x00 && $data[1] == 0x01) {
$this->fpdi->error("LZW flavour not supported.");
}
$this->initsTable();
$this->data = $data;
// Initialize pointers
$this->bytePointer = 0;
$this->bitPointer = 0;
$this->nextData = 0;
$this->nextBits = 0;
$oldCode = 0;
$string = "";
$uncompData = "";
while (($code = $this->getNextCode()) != 257) {
if ($code == 256) {
$this->initsTable();
$code = $this->getNextCode();
if ($code == 257) {
break;
}
$uncompData .= $this->sTable[$code];
$oldCode = $code;
} else {
if ($code < $this->tIdx) {
$string = $this->sTable[$code];
$uncompData .= $string;
$this->addStringToTable($this->sTable[$oldCode], $string[0]);
$oldCode = $code;
} else {
$string = $this->sTable[$oldCode];
$string = $string.$string[0];
$uncompData .= $string;
$this->addStringToTable($string);
$oldCode = $code;
}
}
}
return $uncompData;
}
/**
* Initialize the string table.
*/
function initsTable() {
$this->sTable = array();
for ($i = 0; $i < 256; $i++)
$this->sTable[$i] = chr($i);
$this->tIdx = 258;
$this->bitsToGet = 9;
}
/**
* Add a new string to the string table.
*/
function addStringToTable ($oldString, $newString="") {
$string = $oldString.$newString;
// Add this new String to the table
$this->sTable[$this->tIdx++] = $string;
if ($this->tIdx == 511) {
$this->bitsToGet = 10;
} else if ($this->tIdx == 1023) {
$this->bitsToGet = 11;
} else if ($this->tIdx == 2047) {
$this->bitsToGet = 12;
}
}
// Returns the next 9, 10, 11 or 12 bits
function getNextCode() {
if ($this->bytePointer == strlen($this->data))
return 257;
$this->nextData = ($this->nextData << 8) | (ord($this->data[$this->bytePointer++]) & 0xff);
$this->nextBits += 8;
if ($this->nextBits < $this->bitsToGet) {
$this->nextData = ($this->nextData << 8) | (ord($this->data[$this->bytePointer++]) & 0xff);
$this->nextBits += 8;
}
$code = ($this->nextData >> ($this->nextBits - $this->bitsToGet)) & $this->andTable[$this->bitsToGet-9];
$this->nextBits -= $this->bitsToGet;
return $code;
}
}

View File

@ -0,0 +1,104 @@
<?php
//
// FPDI - Version 1.3.2
//
// Copyright 2004-2010 Setasign - Jan Slabon
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
if (!defined('ORD_z'))
define('ORD_z',ord('z'));
if (!defined('ORD_exclmark'))
define('ORD_exclmark', ord('!'));
if (!defined('ORD_u'))
define('ORD_u', ord('u'));
if (!defined('ORD_tilde'))
define('ORD_tilde', ord('~'));
$__tmp = version_compare(phpversion(), "5") == -1 ? array('FilterASCII85') : array('FilterASCII85', false);
if (!call_user_func_array('class_exists', $__tmp)) {
class FilterASCII85 {
function error($msg) {
die($msg);
}
function decode($in) {
$out = '';
$state = 0;
$chn = null;
$l = strlen($in);
for ($k = 0; $k < $l; ++$k) {
$ch = ord($in[$k]) & 0xff;
if ($ch == ORD_tilde) {
break;
}
if (preg_match('/^\s$/',chr($ch))) {
continue;
}
if ($ch == ORD_z && $state == 0) {
$out .= chr(0).chr(0).chr(0).chr(0);
continue;
}
if ($ch < ORD_exclmark || $ch > ORD_u) {
return $this->error('Illegal character in ASCII85Decode.');
}
$chn[$state++] = $ch - ORD_exclmark;
if ($state == 5) {
$state = 0;
$r = 0;
for ($j = 0; $j < 5; ++$j)
$r = $r * 85 + $chn[$j];
$out .= chr($r >> 24);
$out .= chr($r >> 16);
$out .= chr($r >> 8);
$out .= chr($r);
}
}
$r = 0;
if ($state == 1)
return $this->error('Illegal length in ASCII85Decode.');
if ($state == 2) {
$r = $chn[0] * 85 * 85 * 85 * 85 + ($chn[1]+1) * 85 * 85 * 85;
$out .= chr($r >> 24);
}
else if ($state == 3) {
$r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + ($chn[2]+1) * 85 * 85;
$out .= chr($r >> 24);
$out .= chr($r >> 16);
}
else if ($state == 4) {
$r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + $chn[2] * 85 * 85 + ($chn[3]+1) * 85 ;
$out .= chr($r >> 24);
$out .= chr($r >> 16);
$out .= chr($r >> 8);
}
return $out;
}
function encode($in) {
return $this->error("ASCII85 encoding not implemented.");
}
}
}
unset($__tmp);

View File

@ -0,0 +1,33 @@
<?php
//
// FPDI - Version 1.3.2
//
// Copyright 2004-2010 Setasign - Jan Slabon
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
require_once('FilterASCII85.php');
class FilterASCII85_FPDI extends FilterASCII85 {
var $fpdi;
function FPDI_FilterASCII85(&$fpdi) {
$this->fpdi =& $fpdi;
}
function error($msg) {
$this->fpdi->error($msg);
}
}

View File

@ -0,0 +1,160 @@
<?php
//
// FPDI - Version 1.3.2
//
// Copyright 2004-2010 Setasign - Jan Slabon
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
$__tmp = version_compare(phpversion(), "5") == -1 ? array('FilterLZW') : array('FilterLZW', false);
if (!call_user_func_array('class_exists', $__tmp)) {
class FilterLZW {
var $sTable = array();
var $data = null;
var $dataLength = 0;
var $tIdx;
var $bitsToGet = 9;
var $bytePointer;
var $bitPointer;
var $nextData = 0;
var $nextBits = 0;
var $andTable = array(511, 1023, 2047, 4095);
function error($msg) {
die($msg);
}
/**
* Method to decode LZW compressed data.
*
* @param string data The compressed data.
*/
function decode($data) {
if($data[0] == 0x00 && $data[1] == 0x01) {
$this->error('LZW flavour not supported.');
}
$this->initsTable();
$this->data = $data;
$this->dataLength = strlen($data);
// Initialize pointers
$this->bytePointer = 0;
$this->bitPointer = 0;
$this->nextData = 0;
$this->nextBits = 0;
$oldCode = 0;
$string = '';
$uncompData = '';
while (($code = $this->getNextCode()) != 257) {
if ($code == 256) {
$this->initsTable();
$code = $this->getNextCode();
if ($code == 257) {
break;
}
$uncompData .= $this->sTable[$code];
$oldCode = $code;
} else {
if ($code < $this->tIdx) {
$string = $this->sTable[$code];
$uncompData .= $string;
$this->addStringToTable($this->sTable[$oldCode], $string[0]);
$oldCode = $code;
} else {
$string = $this->sTable[$oldCode];
$string = $string.$string[0];
$uncompData .= $string;
$this->addStringToTable($string);
$oldCode = $code;
}
}
}
return $uncompData;
}
/**
* Initialize the string table.
*/
function initsTable() {
$this->sTable = array();
for ($i = 0; $i < 256; $i++)
$this->sTable[$i] = chr($i);
$this->tIdx = 258;
$this->bitsToGet = 9;
}
/**
* Add a new string to the string table.
*/
function addStringToTable ($oldString, $newString='') {
$string = $oldString.$newString;
// Add this new String to the table
$this->sTable[$this->tIdx++] = $string;
if ($this->tIdx == 511) {
$this->bitsToGet = 10;
} else if ($this->tIdx == 1023) {
$this->bitsToGet = 11;
} else if ($this->tIdx == 2047) {
$this->bitsToGet = 12;
}
}
// Returns the next 9, 10, 11 or 12 bits
function getNextCode() {
if ($this->bytePointer == $this->dataLength) {
return 257;
}
$this->nextData = ($this->nextData << 8) | (ord($this->data[$this->bytePointer++]) & 0xff);
$this->nextBits += 8;
if ($this->nextBits < $this->bitsToGet) {
$this->nextData = ($this->nextData << 8) | (ord($this->data[$this->bytePointer++]) & 0xff);
$this->nextBits += 8;
}
$code = ($this->nextData >> ($this->nextBits - $this->bitsToGet)) & $this->andTable[$this->bitsToGet-9];
$this->nextBits -= $this->bitsToGet;
return $code;
}
function encode($in) {
$this->error("LZW encoding not implemented.");
}
}
}
unset($__tmp);

View File

@ -0,0 +1,33 @@
<?php
//
// FPDI - Version 1.3.2
//
// Copyright 2004-2010 Setasign - Jan Slabon
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
require_once('FilterLZW.php');
class FilterLZW_FPDI extends FilterLZW {
var $fpdi;
function FilterLZW_FPDI(&$fpdi) {
$this->fpdi =& $fpdi;
}
function error($msg) {
$this->fpdi->error($msg);
}
}

View File

@ -1,8 +1,8 @@
<?php <?php
// //
// FPDF_TPL - Version 1.1.2 // FPDF_TPL - Version 1.1.4
// //
// Copyright 2004-2008 Setasign - Jan Slabon // Copyright 2004-2010 Setasign - Jan Slabon
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -19,8 +19,6 @@
// DOLCHANGE // DOLCHANGE
require_once(FPDF_PATH."fpdf.php"); require_once(FPDF_PATH."fpdf.php");
//require_once('E:/Mes Developpements/dolibarr/htdocs/includes/fpdf/fpdf/fpdf.php');
//require_once('C:/temp/16/fpdf.php');
class FPDF_TPL extends FPDF { class FPDF_TPL extends FPDF {
/** /**
@ -53,6 +51,13 @@ class FPDF_TPL extends FPDF {
*/ */
var $_res = array(); var $_res = array();
/**
* Last used Template data
*
* @var array
*/
var $lastUsedTemplateData = array();
/** /**
* Start a Template * Start a Template
* *
@ -171,21 +176,37 @@ class FPDF_TPL extends FPDF {
} }
$tpl =& $this->tpls[$tplidx]; $tpl =& $this->tpls[$tplidx];
$x = $tpl['x'];
$y = $tpl['y'];
$w = $tpl['w']; $w = $tpl['w'];
$h = $tpl['h']; $h = $tpl['h'];
if ($_x == null) if ($_x == null)
$_x = $x; $_x = 0;
if ($_y == null) if ($_y == null)
$_y = $y; $_y = 0;
$_x += $tpl['x'];
$_y += $tpl['y'];
$wh = $this->getTemplateSize($tplidx, $_w, $_h); $wh = $this->getTemplateSize($tplidx, $_w, $_h);
$_w = $wh['w']; $_w = $wh['w'];
$_h = $wh['h']; $_h = $wh['h'];
$this->_out(sprintf("q %.4F 0 0 %.4F %.2F %.2F cm", ($_w/$w), ($_h/$h), $_x*$this->k, ($this->h-($_y+$_h))*$this->k)); // Translate $tData = array(
$this->_out($this->tplprefix.$tplidx." Do Q"); 'x' => $this->x,
'y' => $this->y,
'w' => $_w,
'h' => $_h,
'scaleX' => ($_w/$w),
'scaleY' => ($_h/$h),
'tx' => $_x,
'ty' => ($this->h-$_y-$_h),
'lty' => ($this->h-$_y-$_h) - ($this->h-$h) * ($_h/$h)
);
$this->_out(sprintf("q %.4F 0 0 %.4F %.4F %.4F cm", $tData['scaleX'], $tData['scaleY'], $tData['tx']*$this->k, $tData['ty']*$this->k)); // Translate
$this->_out(sprintf('%s%d Do Q', $this->tplprefix, $tplidx));
$this->lastUsedTemplateData = $tData;
return array("w" => $_w, "h" => $_h); return array("w" => $_w, "h" => $_h);
} }
@ -222,16 +243,19 @@ class FPDF_TPL extends FPDF {
} }
/** /**
* See FPDF-Documentation ;-) * See FPDF/TCPDF-Documentation ;-)
*/ */
function SetFont($family, $style='', $size=0) { function SetFont($family, $style='', $size=0, $fontfile='') {
if (!is_subclass_of($this, 'TCPDF') && func_num_args() > 3) {
$this->Error('More than 3 arguments for the SetFont method are only available in TCPDF.');
}
/** /**
* force the resetting of font changes in a template * force the resetting of font changes in a template
*/ */
if ($this->_intpl) if ($this->_intpl)
$this->FontFamily = ''; $this->FontFamily = '';
parent::SetFont($family, $style, $size); parent::SetFont($family, $style, $size, $fontfile);
$fontkey = $this->FontFamily.$this->FontStyle; $fontkey = $this->FontFamily.$this->FontStyle;
@ -245,12 +269,12 @@ class FPDF_TPL extends FPDF {
/** /**
* See FPDF/TCPDF-Documentation ;-) * See FPDF/TCPDF-Documentation ;-)
*/ */
function Image($file, $x, $y, $w=0, $h=0, $type='', $link='', $align='', $resize=false, $dpi=300) { function Image($file, $x, $y, $w=0, $h=0, $type='', $link='', $align='', $resize=false, $dpi=300, $palign='', $ismask=false, $imgmask=false, $border=0, $fitbox = false, $hidden = false) {
if (!is_subclass_of($this, 'TCPDF') && func_num_args() > 7) { if (!is_subclass_of($this, 'TCPDF') && func_num_args() > 7) {
$this->Error('More than 7 arguments for the Image method are only available in TCPDF.'); $this->Error('More than 7 arguments for the Image method are only available in TCPDF.');
} }
parent::Image($file, $x, $y, $w, $h, $type, $link, $align, $resize, $dpi); parent::Image($file, $x, $y, $w, $h, $type, $link, $align, $resize, $dpi, $palign, $ismask, $imgmask, $border, $fitbox, $hidden);
if ($this->_intpl) { if ($this->_intpl) {
$this->_res['tpl'][$this->tpl]['images'][$file] =& $this->images[$file]; $this->_res['tpl'][$this->tpl]['images'][$file] =& $this->images[$file];
} else { } else {
@ -272,10 +296,14 @@ class FPDF_TPL extends FPDF {
/** /**
* Preserve adding Links in Templates ...won't work * Preserve adding Links in Templates ...won't work
*/ */
function Link($x, $y, $w, $h, $link) { function Link($x, $y, $w, $h, $link, $spaces=0) {
if (!is_subclass_of($this, 'TCPDF') && func_num_args() > 5) {
$this->Error('More than 5 arguments for the Image method are only available in TCPDF.');
}
if ($this->_intpl) if ($this->_intpl)
$this->Error('Using links in templates aren\'t possible!'); $this->Error('Using links in templates aren\'t possible!');
parent::Link($x, $y, $w, $h, $link); parent::Link($x, $y, $w, $h, $link, $spaces);
} }
function AddLink() { function AddLink() {
@ -304,7 +332,23 @@ class FPDF_TPL extends FPDF {
$this->_out('<<'.$filter.'/Type /XObject'); $this->_out('<<'.$filter.'/Type /XObject');
$this->_out('/Subtype /Form'); $this->_out('/Subtype /Form');
$this->_out('/FormType 1'); $this->_out('/FormType 1');
$this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]',$tpl['x']*$this->k, ($tpl['h']-$tpl['y'])*$this->k, $tpl['w']*$this->k, ($tpl['h']-$tpl['y']-$tpl['h'])*$this->k)); $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]',
// llx
$tpl['x']*$this->k,
// lly
-$tpl['y']*$this->k,
// urx
($tpl['w']+$tpl['x'])*$this->k,
// ury
($tpl['h']-$tpl['y'])*$this->k
));
if ($tpl['x'] != 0 || $tpl['y'] != 0) {
$this->_out(sprintf('/Matrix [1 0 0 1 %.5F %.5F]',
-$tpl['x']*$this->k*2, $tpl['y']*$this->k*2
));
}
$this->_out('/Resources '); $this->_out('/Resources ');
$this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
@ -337,46 +381,12 @@ class FPDF_TPL extends FPDF {
} }
/** /**
* Private Method * Overwritten to add _putformxobjects() after _putimages()
*
*/ */
function _putresources() { function _putimages() {
if (!is_subclass_of($this, 'TCPDF')) { parent::_putimages();
$this->_putfonts();
$this->_putimages();
$this->_putformxobjects(); $this->_putformxobjects();
//Resource dictionary
$this->offsets[2]=strlen($this->buffer);
$this->_out('2 0 obj');
$this->_out('<<');
$this->_putresourcedict();
$this->_out('>>');
$this->_out('endobj');
} else {
$this->_putextgstates();
$this->_putocg();
$this->_putfonts();
$this->_putimages();
$this->_putshaders();
$this->_putformxobjects();
//Resource dictionary
$this->offsets[2]=strlen($this->buffer);
$this->_out('2 0 obj');
$this->_out('<<');
$this->_putresourcedict();
$this->_out('>>');
$this->_out('endobj');
$this->_putjavascript();
$this->_putbookmarks();
// encryption
if ($this->encrypted) {
$this->_newobj();
$this->enc_obj_id = $this->n;
$this->_out('<<');
$this->_putencryption();
$this->_out('>>');
$this->_out('endobj');
}
}
} }
function _putxobjectdict() { function _putxobjectdict() {
@ -384,7 +394,7 @@ class FPDF_TPL extends FPDF {
if (count($this->tpls)) { if (count($this->tpls)) {
foreach($this->tpls as $tplidx => $tpl) { foreach($this->tpls as $tplidx => $tpl) {
$this->_out($this->tplprefix.$tplidx.' '.$tpl['n'].' 0 R'); $this->_out(sprintf('%s%d %d 0 R', $this->tplprefix, $tplidx, $tpl['n']));
} }
} }
} }

View File

@ -1,8 +1,8 @@
<?php <?php
// //
// FPDI - Version 1.2.1 // FPDI - Version 1.3.2
// //
// Copyright 2004-2008 Setasign - Jan Slabon // Copyright 2004-2010 Setasign - Jan Slabon
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -17,15 +17,17 @@
// limitations under the License. // limitations under the License.
// //
define('FPDI_VERSION','1.2.1'); define('FPDI_VERSION','1.3.2');
// Check for TCPDF and remap TCPDF to FPDF // Check for TCPDF and remap TCPDF to FPDF
if (class_exists('TCPDF')) { $__tmp = version_compare(phpversion(), "5") == -1 ? array('TCPDF') : array('TCPDF', false);
if (call_user_func_array('class_exists', $__tmp)) {
require_once('fpdi2tcpdf_bridge.php'); require_once('fpdi2tcpdf_bridge.php');
} }
unset($__tmp);
require_once("fpdf_tpl.php"); require_once('fpdf_tpl.php');
require_once("fpdi_pdf_parser.php"); require_once('fpdi_pdf_parser.php');
class FPDI extends FPDF_TPL { class FPDI extends FPDF_TPL {
@ -99,7 +101,7 @@ class FPDI extends FPDF_TPL {
*/ */
function importPage($pageno, $boxName='/CropBox') { function importPage($pageno, $boxName='/CropBox') {
if ($this->_intpl) { if ($this->_intpl) {
return $this->error("Please import the desired pages before creating a new template."); return $this->error('Please import the desired pages before creating a new template.');
} }
$fn =& $this->current_filename; $fn =& $this->current_filename;
@ -112,15 +114,8 @@ class FPDI extends FPDF_TPL {
$parser =& $this->parsers[$fn]; $parser =& $this->parsers[$fn];
$parser->setPageno($pageno); $parser->setPageno($pageno);
$this->tpl++;
$this->tpls[$this->tpl] = array();
$tpl =& $this->tpls[$this->tpl];
$tpl['parser'] =& $parser;
$tpl['resources'] = $parser->getPageResources();
$tpl['buffer'] = $parser->getContent();
if (!in_array($boxName, $parser->availableBoxes)) if (!in_array($boxName, $parser->availableBoxes))
return $this->Error(sprintf("Unknown box: %s", $boxName)); return $this->Error(sprintf('Unknown box: %s', $boxName));
$pageboxes = $parser->getPageBoxes($pageno); $pageboxes = $parser->getPageBoxes($pageno);
/** /**
@ -130,28 +125,35 @@ class FPDI extends FPDF_TPL {
* TrimBox: Default -> CropBox * TrimBox: Default -> CropBox
* ArtBox: Default -> CropBox * ArtBox: Default -> CropBox
*/ */
if (!isset($pageboxes[$boxName]) && ($boxName == "/BleedBox" || $boxName == "/TrimBox" || $boxName == "/ArtBox")) if (!isset($pageboxes[$boxName]) && ($boxName == '/BleedBox' || $boxName == '/TrimBox' || $boxName == '/ArtBox'))
$boxName = "/CropBox"; $boxName = '/CropBox';
if (!isset($pageboxes[$boxName]) && $boxName == "/CropBox") if (!isset($pageboxes[$boxName]) && $boxName == '/CropBox')
$boxName = "/MediaBox"; $boxName = '/MediaBox';
if (!isset($pageboxes[$boxName])) if (!isset($pageboxes[$boxName]))
return false; return false;
$this->lastUsedPageBox = $boxName; $this->lastUsedPageBox = $boxName;
$box = $pageboxes[$boxName]; $box = $pageboxes[$boxName];
$this->tpl++;
$this->tpls[$this->tpl] = array();
$tpl =& $this->tpls[$this->tpl];
$tpl['parser'] =& $parser;
$tpl['resources'] = $parser->getPageResources();
$tpl['buffer'] = $parser->getContent();
$tpl['box'] = $box; $tpl['box'] = $box;
// To build an array that can be used by PDF_TPL::useTemplate() // To build an array that can be used by PDF_TPL::useTemplate()
$this->tpls[$this->tpl] = array_merge($this->tpls[$this->tpl], $box); $this->tpls[$this->tpl] = array_merge($this->tpls[$this->tpl], $box);
// An imported page will start at 0,0 everytime. Translation will be set in _putformxobjects() // An imported page will start at 0,0 everytime. Translation will be set in _putformxobjects()
$tpl['x'] = 0; $tpl['x'] = 0;
$tpl['y'] = 0; $tpl['y'] = 0;
$page =& $parser->pages[$parser->pageno]; // handle rotated pages
// fix for rotated pages
$rotation = $parser->getPageRotation($pageno); $rotation = $parser->getPageRotation($pageno);
$tpl['_rotationAngle'] = 0;
if (isset($rotation[1]) && ($angle = $rotation[1] % 360) != 0) { if (isset($rotation[1]) && ($angle = $rotation[1] % 360) != 0) {
$steps = $angle / 90; $steps = $angle / 90;
@ -160,23 +162,7 @@ class FPDI extends FPDF_TPL {
$tpl['w'] = $steps % 2 == 0 ? $_w : $_h; $tpl['w'] = $steps % 2 == 0 ? $_w : $_h;
$tpl['h'] = $steps % 2 == 0 ? $_h : $_w; $tpl['h'] = $steps % 2 == 0 ? $_h : $_w;
if ($steps % 2 != 0) { $tpl['_rotationAngle'] = $angle*-1;
$x = $y = ($steps == 1 || $steps == -3) ? $tpl['h'] : $tpl['w'];
} else {
$x = $tpl['w'];
$y = $tpl['h'];
}
$cx=($x/2+$tpl['box']['x'])*$this->k;
$cy=($y/2+$tpl['box']['y'])*$this->k;
$angle*=-1;
$angle*=M_PI/180;
$c=cos($angle);
$s=sin($angle);
$tpl['buffer'] = sprintf('q %.5F %.5F %.5F %.5F %.2F %.2F cm 1 0 0 1 %.2F %.2F cm %s Q',$c,$s,-$s,$c,$cx,$cy,-$cx,-$cy, $tpl['buffer']);
} }
$this->_importedPages[$pageKey] = $this->tpl; $this->_importedPages[$pageKey] = $this->tpl;
@ -188,7 +174,21 @@ class FPDI extends FPDF_TPL {
return $this->lastUsedPageBox; return $this->lastUsedPageBox;
} }
function useTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0) { function useTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0, $adjustPageSize=false) {
if ($adjustPageSize == true && is_null($_x) && is_null($_y)) {
$size = $this->getTemplateSize($tplidx, $_w, $_h);
$format = array($size['w'], $size['h']);
if ($format[0]!=$this->CurPageFormat[0] || $format[1]!=$this->CurPageFormat[1]) {
$this->w=$format[0];
$this->h=$format[1];
$this->wPt=$this->w*$this->k;
$this->hPt=$this->h*$this->k;
$this->PageBreakTrigger=$this->h-$this->bMargin;
$this->CurPageFormat=$format;
$this->PageSizes[$this->page]=array($this->wPt, $this->hPt);
}
}
$this->_out('q 0 J 1 w 0 j 0 G 0 g'); // reset standard values $this->_out('q 0 J 1 w 0 j 0 G 0 g'); // reset standard values
$s = parent::useTemplate($tplidx, $_x, $_y, $_w, $_h); $s = parent::useTemplate($tplidx, $_x, $_y, $_w, $_h);
$this->_out('Q'); $this->_out('Q');
@ -203,7 +203,7 @@ class FPDI extends FPDF_TPL {
foreach($this->parsers AS $filename => $p) { foreach($this->parsers AS $filename => $p) {
$this->current_parser =& $this->parsers[$filename]; $this->current_parser =& $this->parsers[$filename];
if (isset($this->_obj_stack[$filename]) && is_array($this->_obj_stack[$filename])) { if (isset($this->_obj_stack[$filename]) && is_array($this->_obj_stack[$filename])) {
while($n = key($this->_obj_stack[$filename])) { while(($n = key($this->_obj_stack[$filename])) !== null) {
$nObj = $this->current_parser->pdf_resolve_object($this->current_parser->c,$this->_obj_stack[$filename][$n][1]); $nObj = $this->current_parser->pdf_resolve_object($this->current_parser->c,$this->_obj_stack[$filename][$n][1]);
$this->_newobj($this->_obj_stack[$filename][$n][0]); $this->_newobj($this->_obj_stack[$filename][$n][0]);
@ -224,51 +224,6 @@ class FPDI extends FPDF_TPL {
} }
} }
/**
* Put resources
*/
function _putresources() {
if (!is_subclass_of($this, 'TCPDF')) {
$this->_putfonts();
$this->_putimages();
$this->_putformxobjects();
$this->_putimportedobjects();
//Resource dictionary
$this->offsets[2]=strlen($this->buffer);
$this->_out('2 0 obj');
$this->_out('<<');
$this->_putresourcedict();
$this->_out('>>');
$this->_out('endobj');
} else { // TCPDF - Part
$this->_putextgstates();
$this->_putocg();
$this->_putfonts();
$this->_putimages();
$this->_putshaders();
$this->_putformxobjects();
$this->_putimportedobjects();
//Resource dictionary
$this->offsets[2]=strlen($this->buffer);
$this->_out('2 0 obj');
$this->_out('<<');
$this->_putresourcedict();
$this->_out('>>');
$this->_out('endobj');
$this->_putjavascript();
$this->_putbookmarks();
// encryption
if ($this->encrypted) {
$this->_newobj();
$this->enc_obj_id = $this->n;
$this->_out('<<');
$this->_putencryption();
$this->_out('>>');
$this->_out('endobj');
}
}
}
/** /**
* Private Method that writes the form xobjects * Private Method that writes the form xobjects
@ -287,14 +242,54 @@ class FPDI extends FPDF_TPL {
$this->_out('/FormType 1'); $this->_out('/FormType 1');
$this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]', $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]',
($tpl['x'] + (isset($tpl['box']['x'])?$tpl['box']['x']:0))*$this->k, (isset($tpl['box']['llx']) ? $tpl['box']['llx'] : $tpl['x'])*$this->k,
($tpl['h'] + (isset($tpl['box']['y'])?$tpl['box']['y']:0) - $tpl['y'])*$this->k, (isset($tpl['box']['lly']) ? $tpl['box']['lly'] : -$tpl['y'])*$this->k,
($tpl['w'] + (isset($tpl['box']['x'])?$tpl['box']['x']:0))*$this->k, (isset($tpl['box']['urx']) ? $tpl['box']['urx'] : $tpl['w'] + $tpl['x'])*$this->k,
($tpl['h'] + (isset($tpl['box']['y'])?$tpl['box']['y']:0) - $tpl['y']-$tpl['h'])*$this->k) (isset($tpl['box']['ury']) ? $tpl['box']['ury'] : $tpl['h']-$tpl['y'])*$this->k
); ));
if (isset($tpl['box'])) $c = 1;
$this->_out(sprintf('/Matrix [1 0 0 1 %.5F %.5F]',-$tpl['box']['x']*$this->k, -$tpl['box']['y']*$this->k)); $s = 0;
$tx = 0;
$ty = 0;
if (isset($tpl['box'])) {
$tx = -$tpl['box']['llx'];
$ty = -$tpl['box']['lly'];
if ($tpl['_rotationAngle'] <> 0) {
$angle = $tpl['_rotationAngle'] * M_PI/180;
$c=cos($angle);
$s=sin($angle);
switch($tpl['_rotationAngle']) {
case -90:
$tx = -$tpl['box']['lly'];
$ty = $tpl['box']['urx'];
break;
case -180:
$tx = $tpl['box']['urx'];
$ty = $tpl['box']['ury'];
break;
case -270:
$tx = $tpl['box']['ury'];
$ty = -$tpl['box']['llx'];
break;
}
}
} else if ($tpl['x'] != 0 || $tpl['y'] != 0) {
$tx = -$tpl['x']*2;
$ty = $tpl['y']*2;
}
$tx *= $this->k;
$ty *= $this->k;
if ($c != 1 || $s != 0 || $tx != 0 || $ty != 0) {
$this->_out(sprintf('/Matrix [%.5F %.5F %.5F %.5F %.5F %.5F]',
$c, $s, -$s, $c, $tx, $ty
));
}
$this->_out('/Resources '); $this->_out('/Resources ');
@ -333,6 +328,8 @@ class FPDI extends FPDF_TPL {
$this->_out('endobj'); $this->_out('endobj');
$this->n = $nN; // TCPDF: reset to new "n" $this->n = $nN; // TCPDF: reset to new "n"
} }
$this->_putimportedobjects();
} }
/** /**
@ -345,10 +342,11 @@ class FPDI extends FPDF_TPL {
//Begin a new object //Begin a new object
if (!$onlynewobj) { if (!$onlynewobj) {
$this->offsets[$obj_id] = strlen($this->buffer); $this->offsets[$obj_id] = is_subclass_of($this, 'TCPDF') ? $this->bufferlen : strlen($this->buffer);
$this->_out($obj_id.' 0 obj'); $this->_out($obj_id.' 0 obj');
$this->_current_obj_id = $obj_id; // for later use with encryption $this->_current_obj_id = $obj_id; // for later use with encryption
} }
return $obj_id;
} }
/** /**
@ -365,12 +363,16 @@ class FPDI extends FPDF_TPL {
switch ($value[0]) { switch ($value[0]) {
case PDF_TYPE_NUMERIC :
case PDF_TYPE_TOKEN : case PDF_TYPE_TOKEN :
$this->_straightOut($value[1] . ' ');
break;
case PDF_TYPE_NUMERIC :
case PDF_TYPE_REAL : case PDF_TYPE_REAL :
// A numeric value or a token. if (is_float($value[1]) && $value[1] != 0) {
// Simply output them $this->_straightOut(rtrim(rtrim(sprintf('%F', $value[1]), '0'), '.') .' ');
$this->_out($value[1]." ", false); } else {
$this->_straightOut($value[1] . ' ');
}
break; break;
case PDF_TYPE_ARRAY : case PDF_TYPE_ARRAY :
@ -378,27 +380,27 @@ class FPDI extends FPDF_TPL {
// An array. Output the proper // An array. Output the proper
// structure and move on. // structure and move on.
$this->_out("[",false); $this->_straightOut('[');
for ($i = 0; $i < count($value[1]); $i++) { for ($i = 0; $i < count($value[1]); $i++) {
$this->pdf_write_value($value[1][$i]); $this->pdf_write_value($value[1][$i]);
} }
$this->_out("]"); $this->_out(']');
break; break;
case PDF_TYPE_DICTIONARY : case PDF_TYPE_DICTIONARY :
// A dictionary. // A dictionary.
$this->_out("<<",false); $this->_straightOut('<<');
reset ($value[1]); reset ($value[1]);
while (list($k, $v) = each($value[1])) { while (list($k, $v) = each($value[1])) {
$this->_out($k . " ",false); $this->_straightOut($k . ' ');
$this->pdf_write_value($v); $this->pdf_write_value($v);
} }
$this->_out(">>"); $this->_straightOut('>>');
break; break;
case PDF_TYPE_OBJREF : case PDF_TYPE_OBJREF :
@ -406,6 +408,7 @@ class FPDI extends FPDF_TPL {
// An indirect object reference // An indirect object reference
// Fill the object stack if needed // Fill the object stack if needed
$cpfn =& $this->current_parser->filename; $cpfn =& $this->current_parser->filename;
if (!isset($this->_don_obj_stack[$cpfn][$value[1]])) { if (!isset($this->_don_obj_stack[$cpfn][$value[1]])) {
$this->_newobj(false,true); $this->_newobj(false,true);
$this->_obj_stack[$cpfn][$value[1]] = array($this->n, $value); $this->_obj_stack[$cpfn][$value[1]] = array($this->n, $value);
@ -413,13 +416,13 @@ class FPDI extends FPDF_TPL {
} }
$objid = $this->_don_obj_stack[$cpfn][$value[1]][0]; $objid = $this->_don_obj_stack[$cpfn][$value[1]][0];
$this->_out("{$objid} 0 R"); $this->_out($objid.' 0 R');
break; break;
case PDF_TYPE_STRING : case PDF_TYPE_STRING :
// A string. // A string.
$this->_out('('.$value[1].')'); $this->_straightOut('('.$value[1].')');
break; break;
@ -429,23 +432,22 @@ class FPDI extends FPDF_TPL {
// stream dictionary, then the // stream dictionary, then the
// stream data itself. // stream data itself.
$this->pdf_write_value($value[1]); $this->pdf_write_value($value[1]);
$this->_out("stream"); $this->_out('stream');
$this->_out($value[2][1]); $this->_out($value[2][1]);
$this->_out("endstream"); $this->_out('endstream');
break; break;
case PDF_TYPE_HEX : case PDF_TYPE_HEX :
$this->_straightOut('<'.$value[1].'>');
$this->_out("<".$value[1].">");
break; break;
case PDF_TYPE_BOOLEAN : case PDF_TYPE_BOOLEAN :
$this->_out($value[1] ? 'true ' : 'false ', false); $this->_straightOut($value[1] ? 'true ' : 'false ');
break; break;
case PDF_TYPE_NULL : case PDF_TYPE_NULL :
// The null object. // The null object.
$this->_out("null"); $this->_straightOut('null ');
break; break;
} }
} }
@ -454,22 +456,25 @@ class FPDI extends FPDF_TPL {
/** /**
* Modified so not each call will add a newline to the output. * Modified so not each call will add a newline to the output.
*/ */
function _out($s, $ln=true) { function _straightOut($s) {
//Add a line to the document if (!is_subclass_of($this, 'TCPDF')) {
if($this->state==2)
$this->pages[$this->page] .= $s;
else
$this->buffer .= $s;
} else {
if ($this->state == 2) { if ($this->state == 2) {
if (!$this->_intpl) { if (isset($this->footerlen[$this->page]) AND ($this->footerlen[$this->page] > 0)) {
if (is_subclass_of($this, 'TCPDF') && isset($this->footerlen[$this->page]) AND ($this->footerlen[$this->page] > 0)) {
// puts data before page footer // puts data before page footer
$page = substr($this->pages[$this->page], 0, -$this->footerlen[$this->page]); $page = substr($this->getPageBuffer($this->page), 0, -$this->footerlen[$this->page]);
$footer = substr($this->pages[$this->page], -$this->footerlen[$this->page]); $footer = substr($this->getPageBuffer($this->page), -$this->footerlen[$this->page]);
$this->pages[$this->page] = $page." ".$s."\n".$footer; $this->setPageBuffer($this->page, $page.' '.$s."\n".$footer);
} else { } else {
$this->pages[$this->page] .= $s.($ln == true ? "\n" : ''); $this->setPageBuffer($this->page, $s, true);
} }
} else
$this->tpls[$this->tpl]['buffer'] .= $s.($ln == true ? "\n" : '');
} else { } else {
$this->buffer.=$s.($ln == true ? "\n" : ''); $this->setBuffer($s);
}
} }
} }
@ -496,5 +501,4 @@ class FPDI extends FPDF_TPL {
} }
return false; return false;
} }
} }

View File

@ -1,8 +1,8 @@
<?php <?php
// //
// FPDI - Version 1.2.1 // FPDI - Version 1.3.2
// //
// Copyright 2004-2008 Setasign - Jan Slabon // Copyright 2004-2010 Setasign - Jan Slabon
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -28,21 +28,12 @@
*/ */
class FPDF extends TCPDF { class FPDF extends TCPDF {
/**
* Missing in TCPDF
*
* @var string
*/
var $padding;
function __get($name) { function __get($name) {
switch ($name) { switch ($name) {
case 'PDFVersion': case 'PDFVersion':
return $this->PDFVersion; return $this->PDFVersion;
case 'k': case 'k':
return $this->k; return $this->k;
case 'lastUsedPageBox':
return $this->lastUsedPageBox;
default: default:
// Error handling // Error handling
$this->Error('Cannot access protected property '.get_class($this).':$'.$name.' / Undefined property: '.get_class($this).'::$'.$name); $this->Error('Cannot access protected property '.get_class($this).':$'.$name.' / Undefined property: '.get_class($this).'::$'.$name);
@ -100,16 +91,62 @@ class FPDF extends TCPDF {
* @return string * @return string
*/ */
function _unescape($s) { function _unescape($s) {
return strtr($s, array( $out = '';
'\\\\' => "\\", for ($count = 0, $n = strlen($s); $count < $n; $count++) {
'\)' => ')', if ($s[$count] != '\\' || $count == $n-1) {
'\(' => '(', $out .= $s[$count];
'\\f' => chr(0x0C), } else {
'\\b' => chr(0x08), switch ($s[++$count]) {
'\\t' => chr(0x09), case ')':
'\\r' => chr(0x0D), case '(':
'\\n' => chr(0x0A), case '\\':
)); $out .= $s[$count];
break;
case 'f':
$out .= chr(0x0C);
break;
case 'b':
$out .= chr(0x08);
break;
case 't':
$out .= chr(0x09);
break;
case 'r':
$out .= chr(0x0D);
break;
case 'n':
$out .= chr(0x0A);
break;
case "\r":
if ($count != $n-1 && $s[$count+1] == "\n")
$count++;
break;
case "\n":
break;
default:
// Octal-Values
if (ord($s[$count]) >= ord('0') &&
ord($s[$count]) <= ord('9')) {
$oct = ''. $s[$count];
if (ord($s[$count+1]) >= ord('0') &&
ord($s[$count+1]) <= ord('9')) {
$oct .= $s[++$count];
if (ord($s[$count+1]) >= ord('0') &&
ord($s[$count+1]) <= ord('9')) {
$oct .= $s[++$count];
}
}
$out .= chr(octdec($oct));
} else {
$out .= $s[$count];
}
}
}
}
return $out;
} }
/** /**
@ -119,7 +156,7 @@ class FPDF extends TCPDF {
* @return string * @return string
*/ */
function hex2str($hex) { function hex2str($hex) {
return pack("H*", str_replace(array("\r", "\n", " "), "", $hex)); return pack('H*', str_replace(array("\r", "\n", ' '), '', $hex));
} }
/** /**
@ -129,6 +166,6 @@ class FPDF extends TCPDF {
* @return string * @return string
*/ */
function str2hex($str) { function str2hex($str) {
return current(unpack("H*", $str)); return current(unpack('H*', $str));
} }
} }

View File

@ -1,8 +1,8 @@
<?php <?php
// //
// FPDI - Version 1.2.1 // FPDI - Version 1.3.2
// //
// Copyright 2004-2008 Setasign - Jan Slabon // Copyright 2004-2010 Setasign - Jan Slabon
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -17,7 +17,7 @@
// limitations under the License. // limitations under the License.
// //
require_once("pdf_parser.php"); require_once('pdf_parser.php');
class fpdi_pdf_parser extends pdf_parser { class fpdi_pdf_parser extends pdf_parser {
@ -58,7 +58,7 @@ class fpdi_pdf_parser extends pdf_parser {
* *
* @var array * @var array
*/ */
var $availableBoxes = array("/MediaBox","/CropBox","/BleedBox","/TrimBox","/ArtBox"); var $availableBoxes = array('/MediaBox', '/CropBox', '/BleedBox', '/TrimBox', '/ArtBox');
/** /**
* Constructor * Constructor
@ -68,7 +68,6 @@ class fpdi_pdf_parser extends pdf_parser {
*/ */
function fpdi_pdf_parser($filename, &$fpdi) { function fpdi_pdf_parser($filename, &$fpdi) {
$this->fpdi =& $fpdi; $this->fpdi =& $fpdi;
$this->filename = $filename;
parent::pdf_parser($filename); parent::pdf_parser($filename);
@ -110,7 +109,7 @@ class fpdi_pdf_parser extends pdf_parser {
$pageno = ((int) $pageno) - 1; $pageno = ((int) $pageno) - 1;
if ($pageno < 0 || $pageno >= $this->getPageCount()) { if ($pageno < 0 || $pageno >= $this->getPageCount()) {
$this->fpdi->error("Pagenumber is wrong!"); $this->fpdi->error('Pagenumber is wrong!');
} }
$this->pageno = $pageno; $this->pageno = $pageno;
@ -163,7 +162,7 @@ class fpdi_pdf_parser extends pdf_parser {
* @return string * @return string
*/ */
function getContent() { function getContent() {
$buffer = ""; $buffer = '';
if (isset($this->pages[$this->pageno][1][1]['/Contents'])) { if (isset($this->pages[$this->pageno][1][1]['/Contents'])) {
$contents = $this->_getPageContent($this->pages[$this->pageno][1][1]['/Contents']); $contents = $this->_getPageContent($this->pages[$this->pageno][1][1]['/Contents']);
@ -225,31 +224,31 @@ class fpdi_pdf_parser extends pdf_parser {
foreach ($filters AS $_filter) { foreach ($filters AS $_filter) {
switch ($_filter[1]) { switch ($_filter[1]) {
case "/FlateDecode": case '/FlateDecode':
if (function_exists('gzuncompress')) { if (function_exists('gzuncompress')) {
$stream = (strlen($stream) > 0) ? @gzuncompress($stream) : ''; $stream = (strlen($stream) > 0) ? @gzuncompress($stream) : '';
} else { } else {
$this->fpdi->error(sprintf("To handle %s filter, please compile php with zlib support.",$_filter[1])); $this->error(sprintf('To handle %s filter, please compile php with zlib support.',$_filter[1]));
} }
if ($stream === false) { if ($stream === false) {
$this->fpdi->error("Error while decompressing stream."); $this->error('Error while decompressing stream.');
} }
break; break;
case '/LZWDecode':
include_once('filters/FilterLZW_FPDI.php');
$decoder = new FilterLZW_FPDI($this->fpdi);
$stream = $decoder->decode($stream);
break;
case '/ASCII85Decode':
include_once('filters/FilterASCII85_FPDI.php');
$decoder = new FilterASCII85_FPDI($this->fpdi);
$stream = $decoder->decode($stream);
break;
case null: case null:
$stream = $stream; $stream = $stream;
break; break;
default: default:
if (preg_match("/^\/[a-z85]*$/i", $_filter[1], $filterName) && @include_once('decoders'.$_filter[1].'.php')) { $this->error(sprintf('Unsupported Filter: %s',$_filter[1]));
$filterName = substr($_filter[1],1);
if (class_exists($filterName)) {
$decoder = new $filterName($this->fpdi);
$stream = $decoder->decode(trim($stream));
} else {
$this->fpdi->error(sprintf("Unsupported Filter: %s",$_filter[1]));
}
} else {
$this->fpdi->error(sprintf("Unsupported Filter: %s",$_filter[1]));
}
} }
} }
@ -278,10 +277,15 @@ class fpdi_pdf_parser extends pdf_parser {
if (!is_null($box) && $box[0] == PDF_TYPE_ARRAY) { if (!is_null($box) && $box[0] == PDF_TYPE_ARRAY) {
$b =& $box[1]; $b =& $box[1];
return array("x" => $b[0][1]/$this->fpdi->k, return array('x' => $b[0][1]/$this->fpdi->k,
"y" => $b[1][1]/$this->fpdi->k, 'y' => $b[1][1]/$this->fpdi->k,
"w" => abs($b[0][1]-$b[2][1])/$this->fpdi->k, 'w' => abs($b[0][1]-$b[2][1])/$this->fpdi->k,
"h" => abs($b[1][1]-$b[3][1])/$this->fpdi->k); 'h' => abs($b[1][1]-$b[3][1])/$this->fpdi->k,
'llx' => min($b[0][1], $b[2][1])/$this->fpdi->k,
'lly' => min($b[1][1], $b[3][1])/$this->fpdi->k,
'urx' => max($b[0][1], $b[2][1])/$this->fpdi->k,
'ury' => max($b[1][1], $b[3][1])/$this->fpdi->k,
);
} else if (!isset ($page[1][1]['/Parent'])) { } else if (!isset ($page[1][1]['/Parent'])) {
return false; return false;
} else { } else {
@ -349,11 +353,18 @@ class fpdi_pdf_parser extends pdf_parser {
*/ */
function read_pages (&$c, &$pages, &$result) { function read_pages (&$c, &$pages, &$result) {
// Get the kids dictionary // Get the kids dictionary
$kids = $this->pdf_resolve_object ($c, $pages[1][1]['/Kids']); $_kids = $this->pdf_resolve_object ($c, $pages[1][1]['/Kids']);
if (!is_array($kids)) if (!is_array($_kids))
$this->fpdi->Error("Cannot find /Kids in current /Page-Dictionary"); $this->error('Cannot find /Kids in current /Page-Dictionary');
foreach ($kids[1] as $v) {
if ($_kids[1][0] == PDF_TYPE_ARRAY) {
$kids = $_kids[1][1];
} else {
$kids = $_kids[1];
}
foreach ($kids as $v) {
$pg = $this->pdf_resolve_object ($c, $v); $pg = $this->pdf_resolve_object ($c, $v);
if ($pg[1][1]['/Type'][1] === '/Pages') { if ($pg[1][1]['/Type'][1] === '/Pages') {
// If one of the kids is an embedded // If one of the kids is an embedded

View File

@ -1,8 +1,8 @@
<?php <?php
/**************************************************************************** /****************************************************************************
* Software: FPDI_Protection * * Software: FPDI_Protection *
* Version: 1.0.2 * * Version: 1.0.3 *
* Date: 2006/11/20 * * Date: 2009/03/06 *
* Author: Klemen VODOPIVEC, Jan Slabon * * Author: Klemen VODOPIVEC, Jan Slabon *
* License: Freeware * * License: Freeware *
* * * *
@ -17,19 +17,21 @@
* * * *
****************************************************************************/ ****************************************************************************/
require_once("fpdi.php"); require_once('fpdi.php');
class FPDI_Protection extends FPDI { class FPDI_Protection extends FPDI {
var $encrypted; //whether document is protected var $encrypted = false; //whether document is protected
var $Uvalue; //U entry in pdf document var $Uvalue; //U entry in pdf document
var $Ovalue; //O entry in pdf document var $Ovalue; //O entry in pdf document
var $Pvalue; //P entry in pdf document var $Pvalue; //P entry in pdf document
var $enc_obj_id; //encryption object id var $enc_obj_id; //encryption object id
var $last_rc4_key; //last RC4 key encrypted (cached for optimisation) var $last_rc4_key = ''; //last RC4 key encrypted (cached for optimisation)
var $last_rc4_key_c; //last RC4 computed key var $last_rc4_key_c; //last RC4 computed key
var $padding = ''; var $padding = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
// DOL_CHANGE
/*
function FPDI_Protection($orientation='P',$unit='mm',$format='A4') function FPDI_Protection($orientation='P',$unit='mm',$format='A4')
{ {
parent::FPDI($orientation,$unit,$format); parent::FPDI($orientation,$unit,$format);
@ -40,6 +42,7 @@ class FPDI_Protection extends FPDI {
$this->padding = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08". $this->padding = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08".
"\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A"; "\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
} }
*/
/** /**
* Function to set permissions as well as user and owner passwords * Function to set permissions as well as user and owner passwords
@ -52,8 +55,7 @@ class FPDI_Protection extends FPDI {
* - If an owner password is set, document can be opened in privilege mode with no * - If an owner password is set, document can be opened in privilege mode with no
* restriction if that password is entered * restriction if that password is entered
*/ */
function SetProtection($permissions=array(),$user_pass='',$owner_pass=null) function SetProtection($permissions=array(), $user_pass='', $owner_pass=null) {
{
$options = array('print' => 4, 'modify' => 8, 'copy' => 16, 'annot-forms' => 32 ); $options = array('print' => 4, 'modify' => 8, 'copy' => 16, 'annot-forms' => 32 );
$protection = 192; $protection = 192;
foreach($permissions as $permission){ foreach($permissions as $permission){
@ -62,14 +64,13 @@ class FPDI_Protection extends FPDI {
$protection += $options[$permission]; $protection += $options[$permission];
} }
if ($owner_pass === null) if ($owner_pass === null)
$owner_pass = uniqid(mt_rand()); $owner_pass = uniqid(rand());
$this->encrypted = true; $this->encrypted = true;
$this->_generateencryptionkey($user_pass, $owner_pass, $protection); $this->_generateencryptionkey($user_pass, $owner_pass, $protection);
} }
function _putstream($s) function _putstream($s) {
{
if ($this->encrypted) { if ($this->encrypted) {
$s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s); $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
} }
@ -77,8 +78,7 @@ class FPDI_Protection extends FPDI {
} }
function _textstring($s) function _textstring($s) {
{
if ($this->encrypted) { if ($this->encrypted) {
$s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s); $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
} }
@ -89,8 +89,7 @@ class FPDI_Protection extends FPDI {
/** /**
* Compute key depending on object number where the encrypted data is stored * Compute key depending on object number where the encrypted data is stored
*/ */
function _objectkey($n) function _objectkey($n) {
{
return substr($this->_md5_16($this->encryption_key.pack('VXxx', $n)), 0, 10); return substr($this->_md5_16($this->encryption_key.pack('VXxx', $n)), 0, 10);
} }
@ -98,15 +97,13 @@ class FPDI_Protection extends FPDI {
/** /**
* Escape special characters * Escape special characters
*/ */
function _escape($s) function _escape($s) {
{
return str_replace( return str_replace(
array('\\',')','(',"\r"), array('\\',')','(',"\r", "\n", "\t"),
array('\\\\','\\)','\\(','\\r'),$s); array('\\\\','\\)','\\(','\\r', '\\n', '\\t'),$s);
} }
function _putresources() function _putresources() {
{
parent::_putresources(); parent::_putresources();
if ($this->encrypted) { if ($this->encrypted) {
$this->_newobj(); $this->_newobj();
@ -117,8 +114,7 @@ class FPDI_Protection extends FPDI {
} }
} }
function _putencryption() function _putencryption() {
{
$this->_out('/Filter /Standard'); $this->_out('/Filter /Standard');
$this->_out('/V 1'); $this->_out('/V 1');
$this->_out('/R 2'); $this->_out('/R 2');
@ -128,13 +124,11 @@ class FPDI_Protection extends FPDI {
} }
function _puttrailer() function _puttrailer() {
{
parent::_puttrailer(); parent::_puttrailer();
if ($this->encrypted) { if ($this->encrypted) {
$this->_out('/Encrypt '.$this->enc_obj_id.' 0 R'); $this->_out('/Encrypt '.$this->enc_obj_id.' 0 R');
$id = isset($this->fileidentifier) ? $this->fileidentifier : ''; $this->_out('/ID [()()]');
$this->_out('/ID [<'.$id.'><'.$id.'>]');
} }
} }
@ -142,8 +136,7 @@ class FPDI_Protection extends FPDI {
/** /**
* RC4 is the standard encryption algorithm used in PDF format * RC4 is the standard encryption algorithm used in PDF format
*/ */
function _RC4($key, $text) function _RC4($key, $text) {
{
if ($this->last_rc4_key != $key) { if ($this->last_rc4_key != $key) {
$k = str_repeat($key, 256/strlen($key)+1); $k = str_repeat($key, 256/strlen($key)+1);
$rc4 = range(0,255); $rc4 = range(0,255);
@ -181,16 +174,14 @@ class FPDI_Protection extends FPDI {
/** /**
* Get MD5 as binary string * Get MD5 as binary string
*/ */
function _md5_16($string) function _md5_16($string) {
{
return pack('H*',md5($string)); return pack('H*',md5($string));
} }
/** /**
* Compute O value * Compute O value
*/ */
function _Ovalue($user_pass, $owner_pass) function _Ovalue($user_pass, $owner_pass) {
{
$tmp = $this->_md5_16($owner_pass); $tmp = $this->_md5_16($owner_pass);
$owner_RC4_key = substr($tmp,0,5); $owner_RC4_key = substr($tmp,0,5);
return $this->_RC4($owner_RC4_key, $user_pass); return $this->_RC4($owner_RC4_key, $user_pass);
@ -200,8 +191,7 @@ class FPDI_Protection extends FPDI {
/** /**
* Compute U value * Compute U value
*/ */
function _Uvalue() function _Uvalue() {
{
return $this->_RC4($this->encryption_key, $this->padding); return $this->_RC4($this->encryption_key, $this->padding);
} }
@ -209,8 +199,7 @@ class FPDI_Protection extends FPDI {
/** /**
* Compute encryption key * Compute encryption key
*/ */
function _generateencryptionkey($user_pass, $owner_pass, $protection) function _generateencryptionkey($user_pass, $owner_pass, $protection) {
{
// Pad passwords // Pad passwords
$user_pass = substr($user_pass.$this->padding,0,32); $user_pass = substr($user_pass.$this->padding,0,32);
$owner_pass = substr($owner_pass.$this->padding,0,32); $owner_pass = substr($owner_pass.$this->padding,0,32);
@ -230,6 +219,7 @@ class FPDI_Protection extends FPDI {
switch ($value[0]) { switch ($value[0]) {
case PDF_TYPE_STRING : case PDF_TYPE_STRING :
if ($this->encrypted) { if ($this->encrypted) {
$value[1] = $this->_unescape($value[1]);
$value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]); $value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]);
$value[1] = $this->_escape($value[1]); $value[1] = $this->_escape($value[1]);
} }
@ -258,12 +248,72 @@ class FPDI_Protection extends FPDI {
function hex2str($hex) { function hex2str($hex) {
return pack("H*", str_replace(array("\r","\n"," "),"", $hex)); return pack('H*', str_replace(array("\r","\n",' '),'', $hex));
} }
function str2hex($str) { function str2hex($str) {
return current(unpack("H*",$str)); return current(unpack('H*',$str));
}
/**
* Deescape special characters
*/
function _unescape($s) {
$out = '';
for ($count = 0, $n = strlen($s); $count < $n; $count++) {
if ($s[$count] != '\\' || $count == $n-1) {
$out .= $s[$count];
} else {
switch ($s[++$count]) {
case ')':
case '(':
case '\\':
$out .= $s[$count];
break;
case 'f':
$out .= chr(0x0C);
break;
case 'b':
$out .= chr(0x08);
break;
case 't':
$out .= chr(0x09);
break;
case 'r':
$out .= chr(0x0D);
break;
case 'n':
$out .= chr(0x0A);
break;
case "\r":
if ($count != $n-1 && $s[$count+1] == "\n")
$count++;
break;
case "\n":
break;
default:
// Octal-Values
if (ord($s[$count]) >= ord('0') &&
ord($s[$count]) <= ord('9')) {
$oct = ''. $s[$count];
if (ord($s[$count+1]) >= ord('0') &&
ord($s[$count+1]) <= ord('9')) {
$oct .= $s[++$count];
if (ord($s[$count+1]) >= ord('0') &&
ord($s[$count+1]) <= ord('9')) {
$oct .= $s[++$count];
} }
} }
?> $out .= chr(octdec($oct));
} else {
$out .= $s[$count];
}
}
}
}
return $out;
}
}

View File

@ -1,8 +1,8 @@
<?php <?php
// //
// FPDI - Version 1.2.1 // FPDI - Version 1.3.2
// //
// Copyright 2004-2008 Setasign - Jan Slabon // Copyright 2004-2010 Setasign - Jan Slabon
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -17,8 +17,18 @@
// limitations under the License. // limitations under the License.
// //
$__tmp = version_compare(phpversion(), "5") == -1 ? array('pdf_context') : array('pdf_context', false);
if (!call_user_func_array('class_exists', $__tmp)) {
class pdf_context { class pdf_context {
/**
* Modi
*
* @var integer 0 = file | 1 = string
*/
var $_mode = 0;
var $file; var $file;
var $buffer; var $buffer;
var $offset; var $offset;
@ -28,8 +38,10 @@ class pdf_context {
// Constructor // Constructor
function pdf_context($f) { function pdf_context(&$f) {
$this->file = $f; $this->file =& $f;
if (is_string($this->file))
$this->_mode = 1;
$this->reset(); $this->reset();
} }
@ -38,6 +50,7 @@ class pdf_context {
// and reset the buffered data // and reset the buffered data
function reset($pos = null, $l = 100) { function reset($pos = null, $l = 100) {
if ($this->_mode == 0) {
if (!is_null ($pos)) { if (!is_null ($pos)) {
fseek ($this->file, $pos); fseek ($this->file, $pos);
} }
@ -46,6 +59,10 @@ class pdf_context {
$this->length = strlen($this->buffer); $this->length = strlen($this->buffer);
if ($this->length < $l) if ($this->length < $l)
$this->increase_length($l - $this->length); $this->increase_length($l - $this->length);
} else {
$this->buffer = $this->file;
$this->length = strlen($this->buffer);
}
$this->offset = 0; $this->offset = 0;
$this->stack = array(); $this->stack = array();
} }
@ -67,16 +84,20 @@ class pdf_context {
// Forcefully read more data into the buffer // Forcefully read more data into the buffer
function increase_length($l=100) { function increase_length($l=100) {
if (feof($this->file)) { if ($this->_mode == 0 && feof($this->file)) {
return false; return false;
} else { } else if ($this->_mode == 0) {
$totalLength = $this->length + $l; $totalLength = $this->length + $l;
do { do {
$this->buffer .= fread($this->file, $totalLength-$this->length); $this->buffer .= fread($this->file, $totalLength-$this->length);
} while ((($this->length = strlen($this->buffer)) != $totalLength) && !feof($this->file)); } while ((($this->length = strlen($this->buffer)) != $totalLength) && !feof($this->file));
return true; return true;
} else {
return false;
}
}
} }
} }
} unset($__tmp);

View File

@ -1,8 +1,8 @@
<?php <?php
// //
// FPDI - Version 1.2.1 // FPDI - Version 1.3.2
// //
// Copyright 2004-2008 Setasign - Jan Slabon // Copyright 2004-2010 Setasign - Jan Slabon
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -44,8 +44,10 @@ if (!defined ('PDF_TYPE_BOOLEAN'))
if (!defined ('PDF_TYPE_REAL')) if (!defined ('PDF_TYPE_REAL'))
define ('PDF_TYPE_REAL', 12); define ('PDF_TYPE_REAL', 12);
require_once("pdf_context.php"); require_once('pdf_context.php');
require_once("wrapper_functions.php");
$__tmp = version_compare(phpversion(), "5") == -1 ? array('pdf_parser') : array('pdf_parser', false);
if (!call_user_func_array('class_exists', $__tmp)) {
class pdf_parser { class pdf_parser {
@ -93,15 +95,17 @@ class pdf_parser {
function pdf_parser($filename) { function pdf_parser($filename) {
$this->filename = $filename; $this->filename = $filename;
$this->f = @fopen($this->filename, "rb"); $this->f = @fopen($this->filename, 'rb');
if (!$this->f) if (!$this->f)
$this->error(sprintf("Cannot open %s !", $filename)); $this->error(sprintf('Cannot open %s !', $filename));
$this->getPDFVersion(); $this->getPDFVersion();
$this->c = new pdf_context($this->f); $this->c = new pdf_context($this->f);
// Read xref-Data // Read xref-Data
$this->xref = array();
$this->pdf_read_xref($this->xref, $this->pdf_find_xref()); $this->pdf_read_xref($this->xref, $this->pdf_find_xref());
// Check for Encryption // Check for Encryption
@ -115,7 +119,7 @@ class pdf_parser {
* Close the opened file * Close the opened file
*/ */
function closeFile() { function closeFile() {
if (isset($this->f)) { if (isset($this->f) && is_resource($this->f)) {
fclose($this->f); fclose($this->f);
unset($this->f); unset($this->f);
} }
@ -127,7 +131,7 @@ class pdf_parser {
* @param string $msg Error-Message * @param string $msg Error-Message
*/ */
function error($msg) { function error($msg) {
die("<b>PDF-Parser Error:</b> ".$msg); die('<b>PDF-Parser Error:</b> '.$msg);
} }
/** /**
@ -135,7 +139,7 @@ class pdf_parser {
*/ */
function getEncryption() { function getEncryption() {
if (isset($this->xref['trailer'][1]['/Encrypt'])) { if (isset($this->xref['trailer'][1]['/Encrypt'])) {
$this->error("File is encrypted!"); $this->error('File is encrypted!');
} }
} }
@ -146,8 +150,9 @@ class pdf_parser {
*/ */
function pdf_find_root() { function pdf_find_root() {
if ($this->xref['trailer'][1]['/Root'][0] != PDF_TYPE_OBJREF) { if ($this->xref['trailer'][1]['/Root'][0] != PDF_TYPE_OBJREF) {
$this->error("Wrong Type of Root-Element! Must be an indirect reference"); $this->error('Wrong Type of Root-Element! Must be an indirect reference');
} }
return $this->xref['trailer'][1]['/Root']; return $this->xref['trailer'][1]['/Root'];
} }
@ -166,7 +171,7 @@ class pdf_parser {
*/ */
function getPDFVersion() { function getPDFVersion() {
fseek($this->f, 0); fseek($this->f, 0);
preg_match("/\d\.\d/",fread($this->f,16),$m); preg_match('/\d\.\d/',fread($this->f,16),$m);
if (isset($m[0])) if (isset($m[0]))
$this->pdfVersion = $m[0]; $this->pdfVersion = $m[0];
return $this->pdfVersion; return $this->pdfVersion;
@ -188,7 +193,7 @@ class pdf_parser {
$data = substr($data, $pos); $data = substr($data, $pos);
if (!preg_match('/\s*(\d+).*$/s', $data, $matches)) { if (!preg_match('/\s*(\d+).*$/s', $data, $matches)) {
$this->error("Unable to find pointer to xref table"); $this->error('Unable to find pointer to xref table');
} }
return (int) $matches[1]; return (int) $matches[1];
@ -201,15 +206,24 @@ class pdf_parser {
* @param integer $offset of xref-table * @param integer $offset of xref-table
*/ */
function pdf_read_xref(&$result, $offset) { function pdf_read_xref(&$result, $offset) {
fseek($this->f, $o_pos = $offset-20); // set some bytes backwards to fetch errorious docs fseek($this->f, $o_pos = $offset-20); // set some bytes backwards to fetch errorious docs
$data = fread($this->f, 100); $data = fread($this->f, 100);
$xrefPos = strpos($data, 'xref'); $xrefPos = strrpos($data, 'xref');
if ($xrefPos === false) { if ($xrefPos === false) {
fseek($this->f, $offset);
$c = new pdf_context($this->f);
$xrefStreamObjDec = $this->pdf_read_value($c);
if (is_array($xrefStreamObjDec) && isset($xrefStreamObjDec[0]) && $xrefStreamObjDec[0] == PDF_TYPE_OBJDEC) {
$this->error(sprintf('This document (%s) probably uses a compression technique which is not supported by the free parser shipped with FPDI.', $this->filename));
} else {
$this->error('Unable to find xref table.'); $this->error('Unable to find xref table.');
} }
}
if (!isset($result['xref_location'])) { if (!isset($result['xref_location'])) {
$result['xref_location'] = $o_pos+$xrefPos; $result['xref_location'] = $o_pos+$xrefPos;
@ -252,7 +266,7 @@ class pdf_parser {
for ($i = 0; $i < $linesCount; $i++) { for ($i = 0; $i < $linesCount; $i++) {
$line = trim($lines[$i]); $line = trim($lines[$i]);
if ($line) { if ($line) {
$pieces = explode(" ", $line); $pieces = explode(' ', $line);
$c = count($pieces); $c = count($pieces);
switch($c) { switch($c) {
case 2: case 2:
@ -361,6 +375,13 @@ class pdf_parser {
if (($value = $this->pdf_read_value($c)) === false) { if (($value = $this->pdf_read_value($c)) === false) {
return false; return false;
} }
// Catch missing value
if ($value[0] == PDF_TYPE_TOKEN && $value[1] == '>>') {
$result[$key] = array(PDF_TYPE_NULL);
break;
}
$result[$key] = $value; $result[$key] = $value;
} }
@ -412,8 +433,7 @@ class pdf_parser {
return array (PDF_TYPE_STRING, $result); return array (PDF_TYPE_STRING, $result);
case 'stream':
case "stream":
$o_pos = ftell($c->file)-strlen($c->buffer); $o_pos = ftell($c->file)-strlen($c->buffer);
$o_offset = $c->offset; $o_offset = $c->offset;
@ -443,30 +463,6 @@ class pdf_parser {
return array(PDF_TYPE_STREAM, $v); return array(PDF_TYPE_STREAM, $v);
case '%':
// this is a comment - just jump over it
$pos = $c->offset;
while(1) {
// PHP 4.3.3 required
#$match = preg_match("/(\r\n|\r|\n)/", $c->buffer, $m, PREG_OFFSET_CAPTURE, $pos);
// alternative
$match = preg_match("/(\r\n|\r|\n)/", substr($c->buffer, $pos), $m);
if ($match === false) {
if (!$c->increase_length()) {
return false;
} else {
continue;
}
}
// PHP 4.3.3 required
#$c->offset = $m[0][1]+strlen($m[0][0]);
// alternative
$c->offset = strpos($c->buffer, $m[0], $pos)+strlen($m[0]);
return $this->pdf_read_value($c);
}
default : default :
if (is_numeric ($token)) { if (is_numeric ($token)) {
// A numeric token. Make sure that // A numeric token. Make sure that
@ -502,12 +498,12 @@ class pdf_parser {
return array (PDF_TYPE_REAL, (float)$token); return array (PDF_TYPE_REAL, (float)$token);
} else if ($token == 'true' || $token == 'false') { } else if ($token == 'true' || $token == 'false') {
return array (PDF_TYPE_BOOLEAN, $token == 'true'); return array (PDF_TYPE_BOOLEAN, $token == 'true');
} else if ($token == 'null') {
return array (PDF_TYPE_NULL);
} else { } else {
// Just a token. Return it. // Just a token. Return it.
return array (PDF_TYPE_TOKEN, $token); return array (PDF_TYPE_TOKEN, $token);
} }
} }
} }
@ -521,7 +517,8 @@ class pdf_parser {
function pdf_resolve_object(&$c, $obj_spec, $encapsulate = true) { function pdf_resolve_object(&$c, $obj_spec, $encapsulate = true) {
// Exit if we get invalid data // Exit if we get invalid data
if (!is_array($obj_spec)) { if (!is_array($obj_spec)) {
return false; $ret = false;
return $ret;
} }
if ($obj_spec[0] == PDF_TYPE_OBJREF) { if ($obj_spec[0] == PDF_TYPE_OBJREF) {
@ -542,7 +539,7 @@ class pdf_parser {
$c->reset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]]); $c->reset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]]);
$header = $this->pdf_read_value($c,null,true); $header = $this->pdf_read_value($c);
if ($header[0] != PDF_TYPE_OBJDEC || $header[1] != $obj_spec[1] || $header[2] != $obj_spec[2]) { if ($header[0] != PDF_TYPE_OBJDEC || $header[1] != $obj_spec[1] || $header[2] != $obj_spec[2]) {
$this->error("Unable to find object ({$obj_spec[1]}, {$obj_spec[2]}) at expected location"); $this->error("Unable to find object ({$obj_spec[1]}, {$obj_spec[2]}) at expected location");
@ -551,6 +548,7 @@ class pdf_parser {
// If we're being asked to store all the information // If we're being asked to store all the information
// about the object, we add the object ID and generation // about the object, we add the object ID and generation
// number for later use // number for later use
$result = array();
$this->actual_obj =& $result; $this->actual_obj =& $result;
if ($encapsulate) { if ($encapsulate) {
$result = array ( $result = array (
@ -558,8 +556,6 @@ class pdf_parser {
'obj' => $obj_spec[1], 'obj' => $obj_spec[1],
'gen' => $obj_spec[2] 'gen' => $obj_spec[2]
); );
} else {
$result = array();
} }
// Now simply read the object data until // Now simply read the object data until
@ -615,7 +611,7 @@ class pdf_parser {
if (!$c->ensure_content()) { if (!$c->ensure_content()) {
return false; return false;
} }
$c->offset += _strspn($c->buffer, " \n\r\t", $c->offset); $c->offset += strspn($c->buffer, " \n\r\t", $c->offset);
} while ($c->offset >= $c->length - 1); } while ($c->offset >= $c->length - 1);
// Get the first character in the stream // Get the first character in the stream
@ -651,6 +647,26 @@ class pdf_parser {
return $char; return $char;
} }
case '%':
// This is a comment - jump over it!
$pos = $c->offset;
while(1) {
$match = preg_match("/(\r\n|\r|\n)/", $c->buffer, $m, PREG_OFFSET_CAPTURE, $pos);
if ($match === 0) {
if (!$c->increase_length()) {
return false;
} else {
continue;
}
}
$c->offset = $m[0][1]+strlen($m[0][0]);
return $this->pdf_read_token($c);
}
default: default:
// This is "another" type of token (probably // This is "another" type of token (probably
@ -665,7 +681,8 @@ class pdf_parser {
// Determine the length of the token // Determine the length of the token
$pos = _strcspn($c->buffer, " []<>()\r\n\t/", $c->offset); $pos = strcspn($c->buffer, " %[]<>()\r\n\t/", $c->offset);
if ($c->offset + $pos <= $c->length - 1) { if ($c->offset + $pos <= $c->length - 1) {
break; break;
} else { } else {
@ -685,6 +702,7 @@ class pdf_parser {
return $result; return $result;
} }
} }
} }
}
unset($__tmp);