diff --git a/htdocs/includes/fpdf/fpdfi/decoders/ASCII85Decode.php b/htdocs/includes/fpdf/fpdfi/decoders/ASCII85Decode.php index 6bf53fb1b24..1f9492c143e 100644 --- a/htdocs/includes/fpdf/fpdfi/decoders/ASCII85Decode.php +++ b/htdocs/includes/fpdf/fpdfi/decoders/ASCII85Decode.php @@ -1,8 +1,8 @@ \ No newline at end of file +} \ No newline at end of file diff --git a/htdocs/includes/fpdf/fpdfi/decoders/LZWDecode.php b/htdocs/includes/fpdf/fpdfi/decoders/LZWDecode.php index 75d19e02617..59d1b487f8b 100644 --- a/htdocs/includes/fpdf/fpdfi/decoders/LZWDecode.php +++ b/htdocs/includes/fpdf/fpdfi/decoders/LZWDecode.php @@ -1,8 +1,8 @@ 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; } -} - - - -?> \ No newline at end of file +} \ No newline at end of file diff --git a/htdocs/includes/fpdf/fpdfi/fpdf_tpl.php b/htdocs/includes/fpdf/fpdfi/fpdf_tpl.php index ee9722c3298..50ae3c1f0c3 100644 --- a/htdocs/includes/fpdf/fpdfi/fpdf_tpl.php +++ b/htdocs/includes/fpdf/fpdfi/fpdf_tpl.php @@ -1,8 +1,8 @@ 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('<_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); + } } } - -?> \ No newline at end of file diff --git a/htdocs/includes/fpdf/fpdfi/fpdi.php b/htdocs/includes/fpdf/fpdfi/fpdi.php index 01eb1c031fe..6bec82a8759 100644 --- a/htdocs/includes/fpdf/fpdfi/fpdi.php +++ b/htdocs/includes/fpdf/fpdfi/fpdi.php @@ -1,8 +1,8 @@ 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('<_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 {} -} -?> \ No newline at end of file +} \ No newline at end of file diff --git a/htdocs/includes/fpdf/fpdfi/fpdi2tcpdf_bridge.php b/htdocs/includes/fpdf/fpdfi/fpdi2tcpdf_bridge.php new file mode 100644 index 00000000000..72cee145512 --- /dev/null +++ b/htdocs/includes/fpdf/fpdfi/fpdi2tcpdf_bridge.php @@ -0,0 +1,134 @@ +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)); + } +} \ No newline at end of file diff --git a/htdocs/includes/fpdf/fpdfi/fpdi_pdf_parser.php b/htdocs/includes/fpdf/fpdfi/fpdi_pdf_parser.php index 484e1080356..45bad2c3295 100644 --- a/htdocs/includes/fpdf/fpdfi/fpdi_pdf_parser.php +++ b/htdocs/includes/fpdf/fpdfi/fpdi_pdf_parser.php @@ -1,8 +1,8 @@ _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); } -} - -?> \ No newline at end of file +} \ No newline at end of file diff --git a/htdocs/includes/fpdf/fpdfi/pdf_context.php b/htdocs/includes/fpdf/fpdfi/pdf_context.php index 6cf4bdcc2b6..ce0b0e0c2c2 100644 --- a/htdocs/includes/fpdf/fpdfi/pdf_context.php +++ b/htdocs/includes/fpdf/fpdfi/pdf_context.php @@ -1,8 +1,8 @@ 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; } } -} -?> \ No newline at end of file +} \ No newline at end of file diff --git a/htdocs/includes/fpdf/fpdfi/pdf_parser.php b/htdocs/includes/fpdf/fpdfi/pdf_parser.php index 3832a0c7cd8..6d9be39778e 100644 --- a/htdocs/includes/fpdf/fpdfi/pdf_parser.php +++ b/htdocs/includes/fpdf/fpdfi/pdf_parser.php @@ -1,8 +1,8 @@ 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 { } -} - -?> \ No newline at end of file +} \ No newline at end of file diff --git a/htdocs/includes/fpdf/fpdfi/wrapper_functions.php b/htdocs/includes/fpdf/fpdfi/wrapper_functions.php index 25706ca610a..61eae2747e3 100644 --- a/htdocs/includes/fpdf/fpdfi/wrapper_functions.php +++ b/htdocs/includes/fpdf/fpdfi/wrapper_functions.php @@ -1,8 +1,8 @@ \ No newline at end of file +} \ No newline at end of file