Update FPDFI to support FPDF 1.6 and fix bug in FPDFI

This commit is contained in:
Laurent Destailleur 2009-01-21 17:20:36 +00:00
parent 21343804b8
commit f53f3989c1
9 changed files with 574 additions and 378 deletions

View File

@ -1,8 +1,8 @@
<?php
//
// FPDI - Version 1.2
// FPDI - Version 1.2.1
//
// Copyright 2004-2007 Setasign - Jan Slabon
// 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.
@ -92,6 +92,4 @@ class ASCII85Decode {
return $out;
}
}
?>
}

View File

@ -1,8 +1,8 @@
<?php
//
// FPDI - Version 1.2
// FPDI - Version 1.2.1
//
// Copyright 2004-2007 Setasign - Jan Slabon
// 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.
@ -38,7 +38,7 @@ class LZWDecode {
*
* @param string data The compressed data.
*/
function decode(&$data) {
function decode($data) {
if($data[0] == 0x00 && $data[1] == 0x01) {
$this->fpdi->error("LZW flavour not supported.");
@ -46,7 +46,7 @@ class LZWDecode {
$this->initsTable();
$this->data =& $data;
$this->data = $data;
// Initialize pointers
$this->bytePointer = 0;
@ -144,8 +144,4 @@ class LZWDecode {
return $code;
}
}
?>
}

View File

@ -1,8 +1,8 @@
<?php
//
// FPDF_TPL - Version 1.1.1
// FPDF_TPL - Version 1.1.2
//
// Copyright 2004-2007 Setasign - Jan Slabon
// 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.
@ -17,7 +17,10 @@
// limitations under the License.
//
// DOLCHANGE
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 {
/**
@ -31,13 +34,13 @@ class FPDF_TPL extends FPDF {
* @var int
*/
var $tpl = 0;
/**
* "In Template"-Flag
* @var boolean
*/
var $_intpl = false;
/**
* Nameprefix of Templates used in Resources-Dictonary
* @var string A String defining the Prefix used as Template-Object-Names. Have to beginn with an /
@ -49,18 +52,7 @@ class FPDF_TPL extends FPDF {
* @var array
*/
var $_res = array();
/**
* Constructor
* See FPDF-Documentation
* @param string $orientation
* @param string $unit
* @param mixed $format
*/
function fpdf_tpl($orientation='P',$unit='mm',$format='A4') {
parent::fpdf($orientation,$unit,$format);
}
/**
* Start a Template
*
@ -79,7 +71,7 @@ class FPDF_TPL extends FPDF {
* @param int $h The height given in user-unit
* @return int The ID of new created Template
*/
function beginTemplate($x=null,$y=null,$w=null,$h=null) {
function beginTemplate($x=null, $y=null, $w=null, $h=null) {
if ($this->page <= 0)
$this->error("You have to add a page to fpdf first!");
@ -113,18 +105,18 @@ class FPDF_TPL extends FPDF {
);
$this->SetAutoPageBreak(false);
// Define own high and width to calculate possitions correct
$this->h = $h;
$this->w = $w;
$this->_intpl = true;
$this->SetXY($x+$this->lMargin,$y+$this->tMargin);
$this->SetXY($x+$this->lMargin, $y+$this->tMargin);
$this->SetRightMargin($this->w-$w+$this->rMargin);
return $this->tpl;
}
/**
* End Template
*
@ -134,7 +126,7 @@ class FPDF_TPL extends FPDF {
*/
function endTemplate() {
if ($this->_intpl) {
$this->_intpl = false;
$this->_intpl = false;
$tpl =& $this->tpls[$this->tpl];
$this->SetXY($tpl['o_x'], $tpl['o_y']);
$this->tMargin = $tpl['o_tMargin'];
@ -143,13 +135,13 @@ class FPDF_TPL extends FPDF {
$this->h = $tpl['o_h'];
$this->w = $tpl['o_w'];
$this->SetAutoPageBreak($tpl['o_AutoPageBreak'], $tpl['o_bMargin']);
return $this->tpl;
} else {
return false;
}
}
/**
* Use a Template in current Page or other Template
*
@ -173,31 +165,31 @@ class FPDF_TPL extends FPDF {
if (!isset($this->tpls[$tplidx]))
$this->error("Template does not exist!");
if ($this->_intpl) {
$this->_res['tpl'][$this->tpl]['tpls'][$tplidx] =& $this->tpls[$tplidx];
}
$tpl =& $this->tpls[$tplidx];
$x = $tpl['x'];
$y = $tpl['y'];
$w = $tpl['w'];
$h = $tpl['h'];
if ($_x == null)
$_x = $x;
if ($_y == null)
$_y = $y;
$wh = $this->getTemplateSize($tplidx,$_w,$_h);
$wh = $this->getTemplateSize($tplidx, $_w, $_h);
$_w = $wh['w'];
$_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
$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
$this->_out($this->tplprefix.$tplidx." Do Q");
return array("w" => $_w, "h" => $_h);
}
/**
* Get The calculated Size of a Template
*
@ -215,85 +207,89 @@ class FPDF_TPL extends FPDF {
$tpl =& $this->tpls[$tplidx];
$w = $tpl['w'];
$h = $tpl['h'];
if ($_w == 0 and $_h == 0) {
$_w = $w;
$_h = $h;
}
if($_w==0)
$_w=$_h*$w/$h;
$_w = $_h*$w/$h;
if($_h==0)
$_h=$_w*$h/$w;
$_h = $_w*$h/$w;
return array("w" => $_w, "h" => $_h);
}
/**
* See FPDF-Documentation ;-)
*/
function SetFont($family,$style='',$size=0) {
function SetFont($family, $style='', $size=0) {
/**
* force the resetting of font changes in a template
*/
if ($this->_intpl)
$this->FontFamily = '';
parent::SetFont($family, $style, $size);
$fontkey = $this->FontFamily.$this->FontStyle;
if ($this->_intpl) {
$this->_res['tpl'][$this->tpl]['fonts'][$fontkey] =& $this->fonts[$fontkey];
} else {
$this->_res['page'][$this->page]['fonts'][$fontkey] =& $this->fonts[$fontkey];
}
}
/**
* See FPDF-Documentation ;-)
* See FPDF/TCPDF-Documentation ;-)
*/
function Image($file,$x,$y,$w=0,$h=0,$type='',$link='') {
parent::Image($file,$x,$y,$w,$h,$type,$link);
function Image($file, $x, $y, $w=0, $h=0, $type='', $link='', $align='', $resize=false, $dpi=300) {
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.');
}
parent::Image($file, $x, $y, $w, $h, $type, $link, $align, $resize, $dpi);
if ($this->_intpl) {
$this->_res['tpl'][$this->tpl]['images'][$file] =& $this->images[$file];
} else {
$this->_res['page'][$this->page]['images'][$file] =& $this->images[$file];
}
}
/**
* See FPDF-Documentation ;-)
*
* AddPage is not available when you're "in" a template.
*/
function AddPage($orientation='') {
function AddPage($orientation='', $format='') {
if ($this->_intpl)
$this->Error('Adding pages in templates isn\'t possible!');
parent::AddPage($orientation);
parent::AddPage($orientation, $format);
}
/**
* Preserve adding Links in Templates ...won't work
*/
function Link($x,$y,$w,$h,$link) {
function Link($x, $y, $w, $h, $link) {
if ($this->_intpl)
$this->Error('Using links in templates aren\'t possible!');
parent::Link($x,$y,$w,$h,$link);
parent::Link($x, $y, $w, $h, $link);
}
function AddLink() {
if ($this->_intpl)
$this->Error('Adding links in templates aren\'t possible!');
return parent::AddLink();
}
function SetLink($link,$y=0,$page=-1) {
function SetLink($link, $y=0, $page=-1) {
if ($this->_intpl)
$this->Error('Setting links in templates aren\'t possible!');
parent::SetLink($link,$y,$page);
parent::SetLink($link, $y, $page);
}
/**
* Private Method that writes the form xobjects
*/
@ -308,7 +304,7 @@ class FPDF_TPL extends FPDF {
$this->_out('<<'.$filter.'/Type /XObject');
$this->_out('/Subtype /Form');
$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]',$tpl['x']*$this->k, ($tpl['h']-$tpl['y'])*$this->k, $tpl['w']*$this->k, ($tpl['h']-$tpl['y']-$tpl['h'])*$this->k));
$this->_out('/Resources ');
$this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
@ -318,7 +314,7 @@ class FPDF_TPL extends FPDF {
$this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
$this->_out('>>');
}
if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) ||
if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) ||
isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls']))
{
$this->_out('/XObject <<');
@ -333,32 +329,59 @@ class FPDF_TPL extends FPDF {
$this->_out('>>');
}
$this->_out('>>');
$this->_out('/Length '.strlen($p).' >>');
$this->_putstream($p);
$this->_out('endobj');
}
}
/**
* Private Method
*/
function _putresources() {
$this->_putfonts();
$this->_putimages();
$this->_putformxobjects();
//Resource dictionary
$this->offsets[2]=strlen($this->buffer);
$this->_out('2 0 obj');
$this->_out('<<');
$this->_putresourcedict();
$this->_out('>>');
$this->_out('endobj');
if (!is_subclass_of($this, 'TCPDF')) {
$this->_putfonts();
$this->_putimages();
$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() {
parent::_putxobjectdict();
if (count($this->tpls)) {
foreach($this->tpls as $tplidx => $tpl) {
$this->_out($this->tplprefix.$tplidx.' '.$tpl['n'].' 0 R');
@ -370,16 +393,10 @@ class FPDF_TPL extends FPDF {
* Private Method
*/
function _out($s) {
//Add a line to the document
if ($this->state==2) {
if (!$this->_intpl)
$this->pages[$this->page].=$s."\n";
else
$this->tpls[$this->tpl]['buffer'] .= $s."\n";
} else {
$this->buffer.=$s."\n";
}
if ($this->state==2 && $this->_intpl) {
$this->tpls[$this->tpl]['buffer'] .= $s."\n";
} else {
parent::_out($s);
}
}
}
?>

View File

@ -1,8 +1,8 @@
<?php
//
// FPDI - Version 1.2
// FPDI - Version 1.2.1
//
// Copyright 2004-2007 Setasign - Jan Slabon
// 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.
@ -17,9 +17,12 @@
// limitations under the License.
//
define('FPDI_VERSION','1.2');
define('FPDI_VERSION','1.2.1');
ini_set('auto_detect_line_endings',1); // Strongly required!
// Check for TCPDF and remap TCPDF to FPDF
if (class_exists('TCPDF')) {
require_once('fpdi2tcpdf_bridge.php');
}
require_once("fpdf_tpl.php");
require_once("fpdi_pdf_parser.php");
@ -37,25 +40,19 @@ class FPDI extends FPDF_TPL {
* @var array
*/
var $parsers;
/**
* Current parser
* @var object
*/
var $current_parser;
/**
* Highest version of imported PDF
* @var double
*/
var $importVersion = 1.3;
/**
* object stack
* @var array
*/
var $_obj_stack;
/**
* done object stack
* @var array
@ -67,21 +64,16 @@ class FPDI extends FPDF_TPL {
* @var integer
*/
var $_current_obj_id;
/**
* The name of the last imported page box
* @var string
*/
var $lastUsedPageBox;
/**
* Constructor
* See FPDF-Manual
*/
function FPDI($orientation='P',$unit='mm',$format='A4') {
parent::FPDF_TPL($orientation,$unit,$format);
}
var $_importedPages = array();
/**
* Set a source-file
*
@ -95,10 +87,10 @@ class FPDI extends FPDF_TPL {
if (!isset($this->parsers[$fn]))
$this->parsers[$fn] =& new fpdi_pdf_parser($fn,$this);
$this->current_parser =& $this->parsers[$fn];
return $this->parsers[$fn]->getPageCount();
}
/**
* Import a page
*
@ -109,9 +101,14 @@ class FPDI extends FPDF_TPL {
if ($this->_intpl) {
return $this->error("Please import the desired pages before creating a new template.");
}
$fn =& $this->current_filename;
// check if page already imported
$pageKey = $fn.((int)$pageno).$boxName;
if (isset($this->_importedPages[$pageKey]))
return $this->_importedPages[$pageKey];
$parser =& $this->parsers[$fn];
$parser->setPageno($pageno);
@ -121,11 +118,11 @@ class FPDI extends FPDF_TPL {
$tpl['parser'] =& $parser;
$tpl['resources'] = $parser->getPageResources();
$tpl['buffer'] = $parser->getContent();
if (!in_array($boxName, $parser->availableBoxes))
return $this->Error(sprintf("Unknown box: %s", $boxName));
$pageboxes = $parser->getPageBoxes($pageno);
/**
* MediaBox
* CropBox: Default -> MediaBox
@ -137,65 +134,67 @@ class FPDI extends FPDF_TPL {
$boxName = "/CropBox";
if (!isset($pageboxes[$boxName]) && $boxName == "/CropBox")
$boxName = "/MediaBox";
if (!isset($pageboxes[$boxName]))
return false;
$this->lastUsedPageBox = $boxName;
$box = $pageboxes[$boxName];
$tpl['box'] = $box;
// To build an array that can be used by PDF_TPL::useTemplate()
$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()
$tpl['x'] = 0;
$tpl['y'] = 0;
$page =& $parser->pages[$parser->pageno];
// fix for rotated pages
$rotation = $parser->getPageRotation($pageno);
if (isset($rotation[1]) && ($angle = $rotation[1] % 360) != 0) {
$steps = $angle / 90;
$_w = $tpl['w'];
$_h = $tpl['h'];
$tpl['w'] = $steps % 2 == 0 ? $_w : $_h;
$tpl['h'] = $steps % 2 == 0 ? $_h : $_w;
if ($steps % 2 != 0) {
$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*=-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']);
$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;
return $this->tpl;
}
function getLastUsedPageBox() {
return $this->lastUsedPageBox;
}
function useTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0) {
$this->_out('q 0 J 1 w 0 j 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);
$this->_out('Q');
return $s;
}
/**
* Private method, that rebuilds all needed objects of source files
*/
@ -203,18 +202,18 @@ class FPDI extends FPDF_TPL {
if (is_array($this->parsers) && count($this->parsers) > 0) {
foreach($this->parsers AS $filename => $p) {
$this->current_parser =& $this->parsers[$filename];
if (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])) {
$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]);
if ($nObj[0] == PDF_TYPE_STREAM) {
$this->pdf_write_value ($nObj);
} else {
$this->pdf_write_value ($nObj[1]);
}
$this->_out('endobj');
$this->_obj_stack[$filename][$n] = null; // free memory
unset($this->_obj_stack[$filename][$n]);
@ -224,31 +223,53 @@ class FPDI extends FPDF_TPL {
}
}
}
/**
* Sets the PDF Version to the highest of imported documents
*/
function setVersion() {
$this->PDFVersion = max($this->importVersion, $this->PDFVersion);
}
/**
* Put resources
*/
function _putresources() {
$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');
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
*/
@ -258,26 +279,28 @@ class FPDI extends FPDF_TPL {
foreach($this->tpls AS $tplidx => $tpl) {
$p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer'];
$this->_newobj();
$cN = $this->n; // TCPDF/Protection: rem current "n"
$this->tpls[$tplidx]['n'] = $this->n;
$this->_out('<<'.$filter.'/Type /XObject');
$this->_out('/Subtype /Form');
$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,
($tpl['h'] + (isset($tpl['box']['y'])?$tpl['box']['y']:0) - $tpl['y'])*$this->k,
($tpl['w'] + (isset($tpl['box']['x'])?$tpl['box']['x']:0))*$this->k,
($tpl['h'] + (isset($tpl['box']['y'])?$tpl['box']['y']:0) - $tpl['y']-$tpl['h'])*$this->k)
);
if (isset($tpl['box']))
$this->_out(sprintf('/Matrix [1 0 0 1 %.5f %.5f]',-$tpl['box']['x']*$this->k, -$tpl['box']['y']*$this->k));
$this->_out(sprintf('/Matrix [1 0 0 1 %.5F %.5F]',-$tpl['box']['x']*$this->k, -$tpl['box']['y']*$this->k));
$this->_out('/Resources ');
if (isset($tpl['resources'])) {
$this->current_parser =& $tpl['parser'];
$this->pdf_write_value($tpl['resources']);
$this->pdf_write_value($tpl['resources']); // "n" will be changed
} else {
$this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
if (isset($this->_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) {
@ -286,7 +309,7 @@ class FPDI extends FPDF_TPL {
$this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
$this->_out('>>');
}
if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) ||
if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) ||
isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls']))
{
$this->_out('/XObject <<');
@ -303,9 +326,12 @@ class FPDI extends FPDF_TPL {
$this->_out('>>');
}
$this->_out('/Length '.strlen($p).' >>');
$nN = $this->n; // TCPDF: rem new "n"
$this->n = $cN; // TCPDF: reset to current "n"
$this->_out('/Length '.strlen($p).' >>');
$this->_putstream($p);
$this->_out('endobj');
$this->n = $nN; // TCPDF: reset to new "n"
}
}
@ -323,7 +349,6 @@ class FPDI extends FPDF_TPL {
$this->_out($obj_id.' 0 obj');
$this->_current_obj_id = $obj_id; // for later use with encryption
}
}
/**
@ -334,11 +359,15 @@ class FPDI extends FPDF_TPL {
*/
function pdf_write_value(&$value)
{
if (is_subclass_of($this, 'TCPDF')) {
parent::pdf_write_value($value);
}
switch ($value[0]) {
case PDF_TYPE_NUMERIC :
case PDF_TYPE_TOKEN :
case PDF_TYPE_REAL :
// A numeric value or a token.
// Simply output them
$this->_out($value[1]." ", false);
@ -380,11 +409,11 @@ class FPDI extends FPDF_TPL {
if (!isset($this->_don_obj_stack[$cpfn][$value[1]])) {
$this->_newobj(false,true);
$this->_obj_stack[$cpfn][$value[1]] = array($this->n, $value);
$this->_don_obj_stack[$cpfn][$value[1]] = array($this->n, $value);
$this->_don_obj_stack[$cpfn][$value[1]] = array($this->n, $value); // Value is maybee obsolete!!!
}
$objid = $this->_don_obj_stack[$cpfn][$value[1]][0];
$this->_out("{$objid} 0 R"); //{$value[2]}
$this->_out("{$objid} 0 R");
break;
case PDF_TYPE_STRING :
@ -405,10 +434,14 @@ class FPDI extends FPDF_TPL {
$this->_out("endstream");
break;
case PDF_TYPE_HEX :
$this->_out("<".$value[1].">");
break;
case PDF_TYPE_BOOLEAN :
$this->_out($value[1] ? 'true ' : 'false ', false);
break;
case PDF_TYPE_NULL :
// The null object.
@ -416,21 +449,28 @@ class FPDI extends FPDF_TPL {
break;
}
}
/**
* Private Method
* Modified so not each call will add a newline to the output.
*/
function _out($s,$ln=true) {
//Add a line to the document
if ($this->state==2) {
if (!$this->_intpl)
$this->pages[$this->page] .= $s.($ln == true ? "\n" : '');
else
$this->tpls[$this->tpl]['buffer'] .= $s.($ln == true ? "\n" : '');
} else {
$this->buffer.=$s.($ln == true ? "\n" : '');
}
function _out($s, $ln=true) {
//Add a line to the document
if ($this->state==2) {
if (!$this->_intpl) {
if (is_subclass_of($this, 'TCPDF') && isset($this->footerlen[$this->page]) AND ($this->footerlen[$this->page] > 0)) {
// puts data before page footer
$page = substr($this->pages[$this->page], 0, -$this->footerlen[$this->page]);
$footer = substr($this->pages[$this->page], -$this->footerlen[$this->page]);
$this->pages[$this->page] = $page." ".$s."\n".$footer;
} else {
$this->pages[$this->page] .= $s.($ln == true ? "\n" : '');
}
} else
$this->tpls[$this->tpl]['buffer'] .= $s.($ln == true ? "\n" : '');
} else {
$this->buffer.=$s.($ln == true ? "\n" : '');
}
}
/**
@ -441,7 +481,7 @@ class FPDI extends FPDF_TPL {
parent::_enddoc();
$this->_closeParsers();
}
/**
* close all files opened by parsers
*/
@ -457,10 +497,4 @@ class FPDI extends FPDF_TPL {
return false;
}
}
// for PHP5
if (!class_exists('fpdi')) {
class fpdi extends FPDI {}
}
?>
}

View File

@ -0,0 +1,134 @@
<?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.
//
/**
* This class is used as a bridge between TCPDF and FPDI
* and will create the possibility to use both FPDF and TCPDF
* via one FPDI version.
*
* We'll simply remap TCPDF to FPDF again.
*
* It'll be loaded and extended by FPDF_TPL.
*/
class FPDF extends TCPDF {
/**
* Missing in TCPDF
*
* @var string
*/
var $padding;
function __get($name) {
switch ($name) {
case 'PDFVersion':
return $this->PDFVersion;
case 'k':
return $this->k;
case 'lastUsedPageBox':
return $this->lastUsedPageBox;
default:
// Error handling
$this->Error('Cannot access protected property '.get_class($this).':$'.$name.' / Undefined property: '.get_class($this).'::$'.$name);
}
}
function __set($name, $value) {
switch ($name) {
case 'PDFVersion':
$this->PDFVersion = $value;
break;
default:
// Error handling
$this->Error('Cannot access protected property '.get_class($this).':$'.$name.' / Undefined property: '.get_class($this).'::$'.$name);
}
}
/**
* Encryption of imported data by FPDI
*
* @param array $value
*/
function pdf_write_value(&$value) {
switch ($value[0]) {
case PDF_TYPE_STRING :
if ($this->encrypted) {
$value[1] = $this->_unescape($value[1]);
$value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]);
$value[1] = $this->_escape($value[1]);
}
break;
case PDF_TYPE_STREAM :
if ($this->encrypted) {
$value[2][1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[2][1]);
}
break;
case PDF_TYPE_HEX :
if ($this->encrypted) {
$value[1] = $this->hex2str($value[1]);
$value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]);
// remake hexstring of encrypted string
$value[1] = $this->str2hex($value[1]);
}
break;
}
}
/**
* Unescapes a PDF string
*
* @param string $s
* @return string
*/
function _unescape($s) {
return strtr($s, array(
'\\\\' => "\\",
'\)' => ')',
'\(' => '(',
'\\f' => chr(0x0C),
'\\b' => chr(0x08),
'\\t' => chr(0x09),
'\\r' => chr(0x0D),
'\\n' => chr(0x0A),
));
}
/**
* Hexadecimal to string
*
* @param string $hex
* @return string
*/
function hex2str($hex) {
return pack("H*", str_replace(array("\r", "\n", " "), "", $hex));
}
/**
* String to hexadecimal
*
* @param string $str
* @return string
*/
function str2hex($str) {
return current(unpack("H*", $str));
}
}

View File

@ -1,8 +1,8 @@
<?php
//
// FPDI - Version 1.2
// FPDI - Version 1.2.1
//
// Copyright 2004-2007 Setasign - Jan Slabon
// 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.
@ -311,6 +311,12 @@ class fpdi_pdf_parser extends pdf_parser {
return $boxes;
}
/**
* Get the page rotation by pageno
*
* @param integer $pageno
* @return array
*/
function getPageRotation($pageno) {
return $this->_getPageRotation($this->pages[$pageno-1]);
}
@ -368,12 +374,7 @@ class fpdi_pdf_parser extends pdf_parser {
*/
function getPDFVersion() {
parent::getPDFVersion();
if (isset($this->fpdi->importVersion) && $this->pdfVersion > $this->fpdi->importVersion) {
$this->fpdi->importVersion = $this->pdfVersion;
}
$this->fpdi->PDFVersion = max($this->fpdi->PDFVersion, $this->pdfVersion);
}
}
?>
}

View File

@ -1,8 +1,8 @@
<?php
//
// FPDI - Version 1.2
// FPDI - Version 1.2.1
//
// Copyright 2004-2007 Setasign - Jan Slabon
// 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.
@ -43,8 +43,10 @@ class pdf_context {
}
$this->buffer = $l > 0 ? fread($this->file, $l) : '';
$this->offset = 0;
$this->length = strlen($this->buffer);
if ($this->length < $l)
$this->increase_length($l - $this->length);
$this->offset = 0;
$this->stack = array();
}
@ -68,11 +70,13 @@ class pdf_context {
if (feof($this->file)) {
return false;
} else {
$this->buffer .= fread($this->file, $l);
$this->length = strlen($this->buffer);
$totalLength = $this->length + $l;
do {
$this->buffer .= fread($this->file, $totalLength-$this->length);
} while ((($this->length = strlen($this->buffer)) != $totalLength) && !feof($this->file));
return true;
}
}
}
?>
}

View File

@ -1,8 +1,8 @@
<?php
//
// FPDI - Version 1.2
// FPDI - Version 1.2.1
//
// Copyright 2004-2007 Setasign - Jan Slabon
// 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.
@ -39,7 +39,11 @@ if (!defined ('PDF_TYPE_OBJECT'))
define ('PDF_TYPE_OBJECT', 9);
if (!defined ('PDF_TYPE_STREAM'))
define ('PDF_TYPE_STREAM', 10);
if (!defined ('PDF_TYPE_BOOLEAN'))
define ('PDF_TYPE_BOOLEAN', 11);
if (!defined ('PDF_TYPE_REAL'))
define ('PDF_TYPE_REAL', 12);
require_once("pdf_context.php");
require_once("wrapper_functions.php");
@ -75,6 +79,11 @@ class pdf_parser {
*/
var $root;
/**
* PDF version of the loaded document
* @var string
*/
var $pdfVersion;
/**
* Constructor
@ -158,15 +167,22 @@ class pdf_parser {
function getPDFVersion() {
fseek($this->f, 0);
preg_match("/\d\.\d/",fread($this->f,16),$m);
$this->pdfVersion = $m[0];
if (isset($m[0]))
$this->pdfVersion = $m[0];
return $this->pdfVersion;
}
/**
* Find the xref-Table
*/
function pdf_find_xref() {
fseek ($this->f, -min(filesize($this->filename),1500), SEEK_END);
$data = fread($this->f, 1500);
$toRead = 1500;
$stat = fseek ($this->f, -$toRead, SEEK_END);
if ($stat === -1) {
fseek ($this->f, 0);
}
$data = fread($this->f, $toRead);
$pos = strlen($data) - strpos(strrev($data), strrev('startxref'));
$data = substr($data, $pos);
@ -183,106 +199,108 @@ class pdf_parser {
*
* @param array $result Array of xref-table
* @param integer $offset of xref-table
* @param integer $start start-position in xref-table
* @param integer $end end-position in xref-table
*/
function pdf_read_xref(&$result, $offset, $start = null, $end = null) {
if (is_null ($start) || is_null ($end)) {
fseek($this->f, $o_pos = $offset);
$data = trim(fgets($this->f,1024));
if (strlen($data) == 0)
$data = trim(fgets($this->f,1024));
if ($data !== 'xref') {
fseek($this->f, $o_pos);
$data = trim(_fgets($this->f, true));
if ($data !== 'xref') {
if (preg_match('/(.*xref)(.*)/m', $data, $m)) { // xref 0 128 - in one line
fseek($this->f, $o_pos+strlen($m[1]));
} elseif (preg_match('/(x|r|e|f)+/', $data, $m)) { // correct invalid xref-pointer
$tmpOffset = $offset-4+strlen($m[0]);
$this->pdf_read_xref($result, $tmpOffset, $start, $end);
return;
} else {
$this->error("Unable to find xref table - Maybe a Problem with 'auto_detect_line_endings'");
}
}
}
$o_pos = ftell($this->f);
$data = explode(' ', trim(fgets($this->f,1024)));
if (count($data) != 2) {
fseek($this->f, $o_pos);
$data = explode(' ', trim(_fgets($this->f, true)));
if (count($data) != 2) {
if (count($data) > 2) { // no lineending
$n_pos = $o_pos+strlen($data[0])+strlen($data[1])+2;
fseek($this->f, $n_pos);
} else {
$this->error("Unexpected header in xref table");
}
}
}
$start = $data[0];
$end = $start + $data[1];
}
if (!isset($result['xref_location'])) {
$result['xref_location'] = $offset;
}
if (!isset($result['max_object']) || $end > $result['max_object']) {
$result['max_object'] = $end;
}
for (; $start < $end; $start++) {
$data = ltrim(fread($this->f, 20)); // Spezifications says: 20 bytes including newlines
$offset = substr($data, 0, 10);
$generation = substr($data, 11, 5);
if (!isset ($result['xref'][$start][(int) $generation])) {
$result['xref'][$start][(int) $generation] = (int) $offset;
}
}
$o_pos = ftell($this->f);
$data = fgets($this->f,1024);
if (strlen(trim($data)) == 0)
$data = fgets($this->f, 1024);
if (preg_match("/trailer/",$data)) {
if (preg_match("/(.*trailer[ \n\r]*)/",$data,$m)) {
fseek($this->f, $o_pos+strlen($m[1]));
}
$c =& new pdf_context($this->f);
$trailer = $this->pdf_read_value($c);
if (isset($trailer[1]['/Prev'])) {
$this->pdf_read_xref($result, $trailer[1]['/Prev'][1]);
$result['trailer'][1] = array_merge($result['trailer'][1], $trailer[1]);
} else {
$result['trailer'] = $trailer;
}
} else {
$data = explode(' ', trim($data));
function pdf_read_xref(&$result, $offset) {
fseek($this->f, $o_pos = $offset-20); // set some bytes backwards to fetch errorious docs
if (count($data) != 2) {
fseek($this->f, $o_pos);
$data = explode(' ', trim (_fgets ($this->f, true)));
if (count($data) != 2) {
$this->error("Unexpected data in xref table");
}
}
$this->pdf_read_xref($result, null, (int) $data[0], (int) $data[0] + (int) $data[1]);
$data = fread($this->f, 100);
$xrefPos = strpos($data, 'xref');
if ($xrefPos === false) {
$this->error('Unable to find xref table.');
}
if (!isset($result['xref_location'])) {
$result['xref_location'] = $o_pos+$xrefPos;
$result['max_object'] = 0;
}
$cylces = -1;
$bytesPerCycle = 100;
fseek($this->f, $o_pos = $o_pos+$xrefPos+4); // set the handle directly after the "xref"-keyword
$data = fread($this->f, $bytesPerCycle);
while (($trailerPos = strpos($data, 'trailer', max($bytesPerCycle*$cylces++, 0))) === false && !feof($this->f)) {
$data .= fread($this->f, $bytesPerCycle);
}
if ($trailerPos === false) {
$this->error('Trailer keyword not found after xref table');
}
$data = substr($data, 0, $trailerPos);
// get Line-Ending
preg_match_all("/(\r\n|\n|\r)/", substr($data, 0, 100), $m); // check the first 100 bytes for linebreaks
$differentLineEndings = count(array_unique($m[0]));
if ($differentLineEndings > 1) {
$lines = preg_split("/(\r\n|\n|\r)/", $data, -1, PREG_SPLIT_NO_EMPTY);
} else {
$lines = explode($m[0][1], $data);
}
$data = $differentLineEndings = $m = null;
unset($data, $differentLineEndings, $m);
$linesCount = count($lines);
$start = 1;
for ($i = 0; $i < $linesCount; $i++) {
$line = trim($lines[$i]);
if ($line) {
$pieces = explode(" ", $line);
$c = count($pieces);
switch($c) {
case 2:
$start = (int)$pieces[0];
$end = $start+(int)$pieces[1];
if ($end > $result['max_object'])
$result['max_object'] = $end;
break;
case 3:
if (!isset($result['xref'][$start]))
$result['xref'][$start] = array();
if (!array_key_exists($gen = (int) $pieces[1], $result['xref'][$start])) {
$result['xref'][$start][$gen] = $pieces[2] == 'n' ? (int) $pieces[0] : null;
}
$start++;
break;
default:
$this->error('Unexpected data in xref table');
}
}
}
$lines = $pieces = $line = $start = $end = $gen = null;
unset($lines, $pieces, $line, $start, $end, $gen);
fseek($this->f, $o_pos+$trailerPos+7);
$c =& new pdf_context($this->f);
$trailer = $this->pdf_read_value($c);
$c = null;
unset($c);
if (!isset($result['trailer'])) {
$result['trailer'] = $trailer;
}
if (isset($trailer[1]['/Prev'])) {
$this->pdf_read_xref($result, $trailer[1]['/Prev'][1]);
}
$trailer = null;
unset($trailer);
return true;
}
/**
* Reads an Value
*
@ -322,7 +340,7 @@ class pdf_parser {
}
$result = substr ($c->buffer, $c->offset, $match - $c->offset);
$c->offset = $match+1;
$c->offset = $match + 1;
return array (PDF_TYPE_HEX, $result);
}
@ -371,45 +389,30 @@ class pdf_parser {
case '(' :
// This is a string
$pos = $c->offset;
while(1) {
// Start by finding the next closed
// parenthesis
$match = strpos ($c->buffer, ')', $pos);
// If you can't find it, try
// reading more data from the stream
if ($match === false) {
if (!$c->increase_length()) {
return false;
} else {
continue;
$pos = $c->offset;
$openBrackets = 1;
do {
for (; $openBrackets != 0 && $pos < $c->length; $pos++) {
switch (ord($c->buffer[$pos])) {
case 0x28: // '('
$openBrackets++;
break;
case 0x29: // ')'
$openBrackets--;
break;
case 0x5C: // backslash
$pos++;
}
}
// Make sure that there is no backslash
// before the parenthesis. If there is,
// move on. Otherwise, return the string.
$esc = preg_match('/([\\\\]+)$/', $tmpresult = substr($c->buffer, $c->offset, $match - $c->offset), $m);
if ($esc === 0 || strlen($m[1]) % 2 == 0) {
$result = $tmpresult;
$c->offset = $match + 1;
return array (PDF_TYPE_STRING, $result);
} else {
$pos = $match + 1;
if ($pos > $c->offset + $c->length) {
$c->increase_length();
}
}
}
}
} while($openBrackets != 0 && $c->increase_length());
$result = substr($c->buffer, $c->offset, $pos - $c->offset - 1);
$c->offset = $pos;
return array (PDF_TYPE_STRING, $result);
case "stream":
$o_pos = ftell($c->file)-strlen($c->buffer);
$o_offset = $c->offset;
@ -440,6 +443,30 @@ class pdf_parser {
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 :
if (is_numeric ($token)) {
// A numeric token. Make sure that
@ -469,7 +496,12 @@ class pdf_parser {
array_push ($c->stack, $tok2);
}
return array (PDF_TYPE_NUMERIC, $token);
if ($token === (string)((int)$token))
return array (PDF_TYPE_NUMERIC, (int)$token);
else
return array (PDF_TYPE_REAL, (float)$token);
} else if ($token == 'true' || $token == 'false') {
return array (PDF_TYPE_BOOLEAN, $token == 'true');
} else {
// Just a token. Return it.
@ -655,6 +687,4 @@ class pdf_parser {
}
}
?>
}

View File

@ -1,8 +1,8 @@
<?php
//
// FPDI - Version 1.2
// FPDI - Version 1.2.1
//
// Copyright 2004-2007 Setasign - Jan Slabon
// 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.
@ -67,22 +67,4 @@ function _strcspn($str1, $str2, $start=null, $length=null) {
} else {
return strcspn($str1, $str2, $start, $length);
}
}
/**
* ensure that fgets works correct if php-version < 4.3
*/
function _fgets (&$h, $force=false) {
$startpos = ftell($h);
$s = fgets($h, 1024);
if ((PHP_VER_LOWER43 == 1 || $force) && preg_match("/^([^\r\n]*[\r\n]{1,2})(.)/",trim($s), $ns)) {
$s = $ns[1];
fseek($h,$startpos+strlen($s));
}
return $s;
}
?>
}