From 44b6ec5b942adf0618d291d09497806b5847e953 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Monta=C3=B1ana=20G=C3=B3mez?= Date: Fri, 14 Feb 2014 18:44:09 +0100 Subject: [PATCH] =?UTF-8?q?-Actualizado=20FPdf.php=20a=20versi=C3=B3n=201.?= =?UTF-8?q?7=20-Incluido=20FPDF=5FMerge=20para=20hacer=20inventario=20tota?= =?UTF-8?q?l=20(todav=C3=ADa=20no=20funciona=20bien)=20-A=C3=B1adido=20.DS?= =?UTF-8?q?=5FStore=20y=20tmp/*=20a=20.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + Fpdf.php | 2014 +++++++++++++++++++---------------- InformeInventario.php | 16 +- font/courier.php | 9 +- font/courierb.php | 8 + font/courierbi.php | 8 + font/courieri.php | 8 + font/helvetica.php | 6 +- font/helveticab.php | 6 +- font/helveticabi.php | 6 +- font/helveticai.php | 6 +- font/makefont/makefont.php | 79 +- font/symbol.php | 6 +- font/times.php | 6 +- font/timesb.php | 6 +- font/timesbi.php | 6 +- font/timesi.php | 6 +- font/zapfdingbats.php | 6 +- fpdf.css | 21 + fpdf_merge.php | 795 ++++++++++++++ pdf.php | 13 - timerbar.js | 0 tmp/inventarioArticulo.xml | 21 - tmp/inventarioUbicacion.xml | 23 - 24 files changed, 2033 insertions(+), 1044 deletions(-) create mode 100644 font/courierb.php create mode 100644 font/courierbi.php create mode 100644 font/courieri.php create mode 100755 fpdf.css create mode 100644 fpdf_merge.php delete mode 100644 pdf.php mode change 100644 => 100755 timerbar.js delete mode 100644 tmp/inventarioArticulo.xml delete mode 100644 tmp/inventarioUbicacion.xml diff --git a/.gitignore b/.gitignore index 1ffd740..4e4a072 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ nbproject +tmp/* +.DS_Store diff --git a/Fpdf.php b/Fpdf.php index 7bb02a9..0dd1cb6 100644 --- a/Fpdf.php +++ b/Fpdf.php @@ -1,780 +1,756 @@ _dochecks(); - //Initialization of properties - $this->page=0; - $this->n=2; - $this->buffer=''; - $this->pages=array(); - $this->OrientationChanges=array(); - $this->state=0; - $this->fonts=array(); - $this->FontFiles=array(); - $this->diffs=array(); - $this->images=array(); - $this->links=array(); - $this->InFooter=false; - $this->lasth=0; - $this->FontFamily=''; - $this->FontStyle=''; - $this->FontSizePt=12; - $this->underline=false; - $this->DrawColor='0 G'; - $this->FillColor='0 g'; - $this->TextColor='0 g'; - $this->ColorFlag=false; - $this->ws=0; - //Standard fonts - $this->CoreFonts=array('courier'=>'Courier','courierB'=>'Courier-Bold','courierI'=>'Courier-Oblique','courierBI'=>'Courier-BoldOblique', - 'helvetica'=>'Helvetica','helveticaB'=>'Helvetica-Bold','helveticaI'=>'Helvetica-Oblique','helveticaBI'=>'Helvetica-BoldOblique', - 'times'=>'Times-Roman','timesB'=>'Times-Bold','timesI'=>'Times-Italic','timesBI'=>'Times-BoldItalic', - 'symbol'=>'Symbol','zapfdingbats'=>'ZapfDingbats'); - //Scale factor + // Initialization of properties + $this->page = 0; + $this->n = 2; + $this->buffer = ''; + $this->pages = array(); + $this->PageSizes = array(); + $this->state = 0; + $this->fonts = array(); + $this->FontFiles = array(); + $this->diffs = array(); + $this->images = array(); + $this->links = array(); + $this->InHeader = false; + $this->InFooter = false; + $this->lasth = 0; + $this->FontFamily = ''; + $this->FontStyle = ''; + $this->FontSizePt = 12; + $this->underline = false; + $this->DrawColor = '0 G'; + $this->FillColor = '0 g'; + $this->TextColor = '0 g'; + $this->ColorFlag = false; + $this->ws = 0; + // Font path + if(defined('FPDF_FONTPATH')) + { + $this->fontpath = FPDF_FONTPATH; + if(substr($this->fontpath,-1)!='/' && substr($this->fontpath,-1)!='\\') + $this->fontpath .= '/'; + } + elseif(is_dir(dirname(__FILE__).'/font')) + $this->fontpath = dirname(__FILE__).'/font/'; + else + $this->fontpath = ''; + // Core fonts + $this->CoreFonts = array('courier', 'helvetica', 'times', 'symbol', 'zapfdingbats'); + // Scale factor if($unit=='pt') - $this->k=1; + $this->k = 1; elseif($unit=='mm') - $this->k=72/25.4; + $this->k = 72/25.4; elseif($unit=='cm') - $this->k=72/2.54; + $this->k = 72/2.54; elseif($unit=='in') - $this->k=72; + $this->k = 72; else $this->Error('Incorrect unit: '.$unit); - //Page format - if(is_string($format)) - { - $format=strtolower($format); - if($format=='a3') - $format=array(841.89,1190.55); - elseif($format=='a4') - $format=array(595.28,841.89); - elseif($format=='a5') - $format=array(420.94,595.28); - elseif($format=='letter') - $format=array(612,792); - elseif($format=='legal') - $format=array(612,1008); - else - $this->Error('Unknown page format: '.$format); - $this->fwPt=$format[0]; - $this->fhPt=$format[1]; - } - else - { - $this->fwPt=$format[0]*$this->k; - $this->fhPt=$format[1]*$this->k; - } - $this->fw=$this->fwPt/$this->k; - $this->fh=$this->fhPt/$this->k; - //Page orientation - $orientation=strtolower($orientation); + // Page sizes + $this->StdPageSizes = array('a3'=>array(841.89,1190.55), 'a4'=>array(595.28,841.89), 'a5'=>array(420.94,595.28), + 'letter'=>array(612,792), 'legal'=>array(612,1008)); + $size = $this->_getpagesize($size); + $this->DefPageSize = $size; + $this->CurPageSize = $size; + // Page orientation + $orientation = strtolower($orientation); if($orientation=='p' || $orientation=='portrait') { - $this->DefOrientation='P'; - $this->wPt=$this->fwPt; - $this->hPt=$this->fhPt; + $this->DefOrientation = 'P'; + $this->w = $size[0]; + $this->h = $size[1]; } elseif($orientation=='l' || $orientation=='landscape') { - $this->DefOrientation='L'; - $this->wPt=$this->fhPt; - $this->hPt=$this->fwPt; + $this->DefOrientation = 'L'; + $this->w = $size[1]; + $this->h = $size[0]; } else $this->Error('Incorrect orientation: '.$orientation); - $this->CurOrientation=$this->DefOrientation; - $this->w=$this->wPt/$this->k; - $this->h=$this->hPt/$this->k; - //Page margins (1 cm) - $margin=25.35/$this->k; + $this->CurOrientation = $this->DefOrientation; + $this->wPt = $this->w*$this->k; + $this->hPt = $this->h*$this->k; + // Page margins (1 cm) + $margin = 28.35/$this->k; $this->SetMargins($margin,$margin); - //Interior cell margin (1 mm) - $this->cMargin=$margin/10; - //Line width (0.2 mm) - $this->LineWidth=.567/$this->k; - //Automatic page break + // Interior cell margin (1 mm) + $this->cMargin = $margin/10; + // Line width (0.2 mm) + $this->LineWidth = .567/$this->k; + // Automatic page break $this->SetAutoPageBreak(true,2*$margin); - //Full width display mode - $this->SetDisplayMode('fullwidth'); - //Enable compression + // Default display mode + $this->SetDisplayMode('default'); + // Enable compression $this->SetCompression(true); - //Set default PDF version number - $this->PDFVersion='1.3'; + // Set default PDF version number + $this->PDFVersion = '1.3'; } -function SetMargins($left,$top,$right=-1) +function SetMargins($left, $top, $right=null) { - //Set left, top and right margins - $this->lMargin=$left; - $this->tMargin=$top; - if($right==-1) - $right=$left; - $this->rMargin=$right; + // Set left, top and right margins + $this->lMargin = $left; + $this->tMargin = $top; + if($right===null) + $right = $left; + $this->rMargin = $right; } function SetLeftMargin($margin) { - //Set left margin - $this->lMargin=$margin; + // Set left margin + $this->lMargin = $margin; if($this->page>0 && $this->x<$margin) - $this->x=$margin; + $this->x = $margin; } function SetTopMargin($margin) { - //Set top margin - $this->tMargin=$margin; + // Set top margin + $this->tMargin = $margin; } function SetRightMargin($margin) { - //Set right margin - $this->rMargin=$margin; + // Set right margin + $this->rMargin = $margin; } -function SetAutoPageBreak($auto,$margin=0) +function SetAutoPageBreak($auto, $margin=0) { - //Set auto page break mode and triggering margin - $this->AutoPageBreak=$auto; - $this->bMargin=$margin; - $this->PageBreakTrigger=$this->h-$margin; + // Set auto page break mode and triggering margin + $this->AutoPageBreak = $auto; + $this->bMargin = $margin; + $this->PageBreakTrigger = $this->h-$margin; } -function SetDisplayMode($zoom,$layout='continuous') +function SetDisplayMode($zoom, $layout='default') { - //Set display mode in viewer + // Set display mode in viewer if($zoom=='fullpage' || $zoom=='fullwidth' || $zoom=='real' || $zoom=='default' || !is_string($zoom)) - $this->ZoomMode=$zoom; + $this->ZoomMode = $zoom; else $this->Error('Incorrect zoom display mode: '.$zoom); if($layout=='single' || $layout=='continuous' || $layout=='two' || $layout=='default') - $this->LayoutMode=$layout; + $this->LayoutMode = $layout; else $this->Error('Incorrect layout display mode: '.$layout); } function SetCompression($compress) { - //Set page compression + // Set page compression if(function_exists('gzcompress')) - $this->compress=$compress; + $this->compress = $compress; else - $this->compress=false; + $this->compress = false; } -function SetTitle($title) +function SetTitle($title, $isUTF8=false) { - //Title of document - $this->title=$title; + // Title of document + if($isUTF8) + $title = $this->_UTF8toUTF16($title); + $this->title = $title; } -function SetSubject($subject) +function SetSubject($subject, $isUTF8=false) { - //Subject of document - $this->subject=$subject; + // Subject of document + if($isUTF8) + $subject = $this->_UTF8toUTF16($subject); + $this->subject = $subject; } -function SetAuthor($author) +function SetAuthor($author, $isUTF8=false) { - //Author of document - $this->author=$author; + // Author of document + if($isUTF8) + $author = $this->_UTF8toUTF16($author); + $this->author = $author; } -function SetKeywords($keywords) +function SetKeywords($keywords, $isUTF8=false) { - //Keywords of document - $this->keywords=$keywords; + // Keywords of document + if($isUTF8) + $keywords = $this->_UTF8toUTF16($keywords); + $this->keywords = $keywords; } -function SetCreator($creator) +function SetCreator($creator, $isUTF8=false) { - //Creator of document - $this->creator=$creator; + // Creator of document + if($isUTF8) + $creator = $this->_UTF8toUTF16($creator); + $this->creator = $creator; } function AliasNbPages($alias='{nb}') { - //Define an alias for total number of pages - $this->AliasNbPages=$alias; + // Define an alias for total number of pages + $this->AliasNbPages = $alias; } function Error($msg) { - //Fatal error - die('FPDF error: '.$msg); + // Fatal error + die('FPDF error: '.$msg); } function Open() { - //Begin document - $this->state=1; + // Begin document + $this->state = 1; } function Close() { - //Terminate document + // Terminate document if($this->state==3) return; if($this->page==0) $this->AddPage(); - //Page footer - $this->InFooter=true; + // Page footer + $this->InFooter = true; $this->Footer(); - $this->InFooter=false; - //Close page + $this->InFooter = false; + // Close page $this->_endpage(); - //Close document + // Close document $this->_enddoc(); } -function AddPage($orientation='') +function AddPage($orientation='', $size='') { - //Start a new page + // Start a new page if($this->state==0) $this->Open(); - $family=$this->FontFamily; - $style=$this->FontStyle.($this->underline ? 'U' : ''); - $size=$this->FontSizePt; - $lw=$this->LineWidth; - $dc=$this->DrawColor; - $fc=$this->FillColor; - $tc=$this->TextColor; - $cf=$this->ColorFlag; + $family = $this->FontFamily; + $style = $this->FontStyle.($this->underline ? 'U' : ''); + $fontsize = $this->FontSizePt; + $lw = $this->LineWidth; + $dc = $this->DrawColor; + $fc = $this->FillColor; + $tc = $this->TextColor; + $cf = $this->ColorFlag; if($this->page>0) { - //Page footer - $this->InFooter=true; + // Page footer + $this->InFooter = true; $this->Footer(); - $this->InFooter=false; - //Close page + $this->InFooter = false; + // Close page $this->_endpage(); } - //Start new page - $this->_beginpage($orientation); - //Set line cap style to square + // Start new page + $this->_beginpage($orientation,$size); + // Set line cap style to square $this->_out('2 J'); - //Set line width - $this->LineWidth=$lw; - $this->_out(sprintf('%.2f w',$lw*$this->k)); - //Set font + // Set line width + $this->LineWidth = $lw; + $this->_out(sprintf('%.2F w',$lw*$this->k)); + // Set font if($family) - $this->SetFont($family,$style,$size); - //Set colors - $this->DrawColor=$dc; + $this->SetFont($family,$style,$fontsize); + // Set colors + $this->DrawColor = $dc; if($dc!='0 G') $this->_out($dc); - $this->FillColor=$fc; + $this->FillColor = $fc; if($fc!='0 g') $this->_out($fc); - $this->TextColor=$tc; - $this->ColorFlag=$cf; - //Page header + $this->TextColor = $tc; + $this->ColorFlag = $cf; + // Page header + $this->InHeader = true; $this->Header(); - //Restore line width + $this->InHeader = false; + // Restore line width if($this->LineWidth!=$lw) { - $this->LineWidth=$lw; - $this->_out(sprintf('%.2f w',$lw*$this->k)); + $this->LineWidth = $lw; + $this->_out(sprintf('%.2F w',$lw*$this->k)); } - //Restore font + // Restore font if($family) - $this->SetFont($family,$style,$size); - //Restore colors + $this->SetFont($family,$style,$fontsize); + // Restore colors if($this->DrawColor!=$dc) { - $this->DrawColor=$dc; + $this->DrawColor = $dc; $this->_out($dc); } if($this->FillColor!=$fc) { - $this->FillColor=$fc; + $this->FillColor = $fc; $this->_out($fc); } - $this->TextColor=$tc; - $this->ColorFlag=$cf; + $this->TextColor = $tc; + $this->ColorFlag = $cf; } function Header() { - //To be implemented in your own inherited class + // To be implemented in your own inherited class } function Footer() { - //To be implemented in your own inherited class + // To be implemented in your own inherited class } function PageNo() { - //Get current page number + // Get current page number return $this->page; } -function SetDrawColor($r,$g=-1,$b=-1) +function SetDrawColor($r, $g=null, $b=null) { - //Set color for all stroking operations - if(($r==0 && $g==0 && $b==0) || $g==-1) - $this->DrawColor=sprintf('%.3f G',$r/255); + // Set color for all stroking operations + if(($r==0 && $g==0 && $b==0) || $g===null) + $this->DrawColor = sprintf('%.3F G',$r/255); else - $this->DrawColor=sprintf('%.3f %.3f %.3f RG',$r/255,$g/255,$b/255); + $this->DrawColor = sprintf('%.3F %.3F %.3F RG',$r/255,$g/255,$b/255); if($this->page>0) $this->_out($this->DrawColor); } -function SetFillColor($r,$g=-1,$b=-1) +function SetFillColor($r, $g=null, $b=null) { - //Set color for all filling operations - if(($r==0 && $g==0 && $b==0) || $g==-1) - $this->FillColor=sprintf('%.3f g',$r/255); + // Set color for all filling operations + if(($r==0 && $g==0 && $b==0) || $g===null) + $this->FillColor = sprintf('%.3F g',$r/255); else - $this->FillColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255); - $this->ColorFlag=($this->FillColor!=$this->TextColor); + $this->FillColor = sprintf('%.3F %.3F %.3F rg',$r/255,$g/255,$b/255); + $this->ColorFlag = ($this->FillColor!=$this->TextColor); if($this->page>0) $this->_out($this->FillColor); } -function SetTextColor($r,$g=-1,$b=-1) +function SetTextColor($r, $g=null, $b=null) { - //Set color for text - if(($r==0 && $g==0 && $b==0) || $g==-1) - $this->TextColor=sprintf('%.3f g',$r/255); + // Set color for text + if(($r==0 && $g==0 && $b==0) || $g===null) + $this->TextColor = sprintf('%.3F g',$r/255); else - $this->TextColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255); - $this->ColorFlag=($this->FillColor!=$this->TextColor); + $this->TextColor = sprintf('%.3F %.3F %.3F rg',$r/255,$g/255,$b/255); + $this->ColorFlag = ($this->FillColor!=$this->TextColor); } function GetStringWidth($s) { - //Get width of a string in the current font - $s=(string)$s; - $cw=&$this->CurrentFont['cw']; - $w=0; - $l=strlen($s); + // Get width of a string in the current font + $s = (string)$s; + $cw = &$this->CurrentFont['cw']; + $w = 0; + $l = strlen($s); for($i=0;$i<$l;$i++) - $w+=$cw[$s{$i}]; + $w += $cw[$s[$i]]; return $w*$this->FontSize/1000; } function SetLineWidth($width) { - //Set line width - $this->LineWidth=$width; + // Set line width + $this->LineWidth = $width; if($this->page>0) - $this->_out(sprintf('%.2f w',$width*$this->k)); + $this->_out(sprintf('%.2F w',$width*$this->k)); } -function Line($x1,$y1,$x2,$y2) +function Line($x1, $y1, $x2, $y2) { - //Draw a line - $this->_out(sprintf('%.2f %.2f m %.2f %.2f l S',$x1*$this->k,($this->h-$y1)*$this->k,$x2*$this->k,($this->h-$y2)*$this->k)); + // Draw a line + $this->_out(sprintf('%.2F %.2F m %.2F %.2F l S',$x1*$this->k,($this->h-$y1)*$this->k,$x2*$this->k,($this->h-$y2)*$this->k)); } -function Rect($x,$y,$w,$h,$style='') +function Rect($x, $y, $w, $h, $style='') { - //Draw a rectangle + // Draw a rectangle if($style=='F') - $op='f'; + $op = 'f'; elseif($style=='FD' || $style=='DF') - $op='B'; + $op = 'B'; else - $op='S'; - $this->_out(sprintf('%.2f %.2f %.2f %.2f re %s',$x*$this->k,($this->h-$y)*$this->k,$w*$this->k,-$h*$this->k,$op)); + $op = 'S'; + $this->_out(sprintf('%.2F %.2F %.2F %.2F re %s',$x*$this->k,($this->h-$y)*$this->k,$w*$this->k,-$h*$this->k,$op)); } -function AddFont($family,$style='',$file='') +function AddFont($family, $style='', $file='') { - //Add a TrueType or Type1 font - $family=strtolower($family); + // Add a TrueType, OpenType or Type1 font + $family = strtolower($family); if($file=='') - $file=str_replace(' ','',$family).strtolower($style).'.php'; - if($family=='arial') - $family='helvetica'; - $style=strtoupper($style); + $file = str_replace(' ','',$family).strtolower($style).'.php'; + $style = strtoupper($style); if($style=='IB') - $style='BI'; - $fontkey=$family.$style; + $style = 'BI'; + $fontkey = $family.$style; if(isset($this->fonts[$fontkey])) - $this->Error('Font already added: '.$family.' '.$style); - include($this->_getfontpath().$file); - if(!isset($name)) - $this->Error('Could not include font definition file'); - $i=count($this->fonts)+1; - $this->fonts[$fontkey]=array('i'=>$i,'type'=>$type,'name'=>$name,'desc'=>$desc,'up'=>$up,'ut'=>$ut,'cw'=>$cw,'enc'=>$enc,'file'=>$file); - if($diff) + return; + $info = $this->_loadfont($file); + $info['i'] = count($this->fonts)+1; + if(!empty($info['diff'])) { - //Search existing encodings - $d=0; - $nb=count($this->diffs); - for($i=1;$i<=$nb;$i++) + // Search existing encodings + $n = array_search($info['diff'],$this->diffs); + if(!$n) { - if($this->diffs[$i]==$diff) - { - $d=$i; - break; - } + $n = count($this->diffs)+1; + $this->diffs[$n] = $info['diff']; } - if($d==0) - { - $d=$nb+1; - $this->diffs[$d]=$diff; - } - $this->fonts[$fontkey]['diff']=$d; + $info['diffn'] = $n; } - if($file) + if(!empty($info['file'])) { - if($type=='TrueType') - $this->FontFiles[$file]=array('length1'=>$originalsize); + // Embedded font + if($info['type']=='TrueType') + $this->FontFiles[$info['file']] = array('length1'=>$info['originalsize']); else - $this->FontFiles[$file]=array('length1'=>$size1,'length2'=>$size2); + $this->FontFiles[$info['file']] = array('length1'=>$info['size1'], 'length2'=>$info['size2']); } + $this->fonts[$fontkey] = $info; } -function SetFont($family,$style='',$size=0) +function SetFont($family, $style='', $size=0) { - //Select a font; size given in points - global $fpdf_charwidths; - - $family=strtolower($family); + // Select a font; size given in points if($family=='') - $family=$this->FontFamily; - if($family=='arial') - $family='helvetica'; - elseif($family=='symbol' || $family=='zapfdingbats') - $style=''; - $style=strtoupper($style); + $family = $this->FontFamily; + else + $family = strtolower($family); + $style = strtoupper($style); if(strpos($style,'U')!==false) { - $this->underline=true; - $style=str_replace('U','',$style); + $this->underline = true; + $style = str_replace('U','',$style); } else - $this->underline=false; + $this->underline = false; if($style=='IB') - $style='BI'; + $style = 'BI'; if($size==0) - $size=$this->FontSizePt; - //Test if font is already selected + $size = $this->FontSizePt; + // Test if font is already selected if($this->FontFamily==$family && $this->FontStyle==$style && $this->FontSizePt==$size) return; - //Test if used for the first time - $fontkey=$family.$style; + // Test if font is already loaded + $fontkey = $family.$style; if(!isset($this->fonts[$fontkey])) { - //Check if one of the standard fonts - if(isset($this->CoreFonts[$fontkey])) + // Test if one of the core fonts + if($family=='arial') + $family = 'helvetica'; + if(in_array($family,$this->CoreFonts)) { - if(!isset($fpdf_charwidths[$fontkey])) - { - //Load metric file - $file=$family; - if($family=='times' || $family=='helvetica') - $file.=strtolower($style); - include($this->_getfontpath().$file.'.php'); - if(!isset($fpdf_charwidths[$fontkey])) - $this->Error('Could not include font metric file'); - } - $i=count($this->fonts)+1; - $this->fonts[$fontkey]=array('i'=>$i,'type'=>'core','name'=>$this->CoreFonts[$fontkey],'up'=>-100,'ut'=>50,'cw'=>$fpdf_charwidths[$fontkey]); + if($family=='symbol' || $family=='zapfdingbats') + $style = ''; + $fontkey = $family.$style; + if(!isset($this->fonts[$fontkey])) + $this->AddFont($family,$style); } else $this->Error('Undefined font: '.$family.' '.$style); } - //Select it - $this->FontFamily=$family; - $this->FontStyle=$style; - $this->FontSizePt=$size; - $this->FontSize=$size/$this->k; - $this->CurrentFont=&$this->fonts[$fontkey]; + // Select it + $this->FontFamily = $family; + $this->FontStyle = $style; + $this->FontSizePt = $size; + $this->FontSize = $size/$this->k; + $this->CurrentFont = &$this->fonts[$fontkey]; if($this->page>0) - $this->_out(sprintf('BT /F%d %.2f Tf ET',$this->CurrentFont['i'],$this->FontSizePt)); + $this->_out(sprintf('BT /F%d %.2F Tf ET',$this->CurrentFont['i'],$this->FontSizePt)); } function SetFontSize($size) { - //Set font size in points + // Set font size in points if($this->FontSizePt==$size) return; - $this->FontSizePt=$size; - $this->FontSize=$size/$this->k; + $this->FontSizePt = $size; + $this->FontSize = $size/$this->k; if($this->page>0) - $this->_out(sprintf('BT /F%d %.2f Tf ET',$this->CurrentFont['i'],$this->FontSizePt)); + $this->_out(sprintf('BT /F%d %.2F Tf ET',$this->CurrentFont['i'],$this->FontSizePt)); } function AddLink() { - //Create a new internal link - $n=count($this->links)+1; - $this->links[$n]=array(0,0); + // Create a new internal link + $n = count($this->links)+1; + $this->links[$n] = array(0, 0); return $n; } -function SetLink($link,$y=0,$page=-1) +function SetLink($link, $y=0, $page=-1) { - //Set destination of internal link + // Set destination of internal link if($y==-1) - $y=$this->y; + $y = $this->y; if($page==-1) - $page=$this->page; - $this->links[$link]=array($page,$y); + $page = $this->page; + $this->links[$link] = array($page, $y); } -function Link($x,$y,$w,$h,$link) +function Link($x, $y, $w, $h, $link) { - //Put a link on the page - $this->PageLinks[$this->page][]=array($x*$this->k,$this->hPt-$y*$this->k,$w*$this->k,$h*$this->k,$link); + // Put a link on the page + $this->PageLinks[$this->page][] = array($x*$this->k, $this->hPt-$y*$this->k, $w*$this->k, $h*$this->k, $link); } -function Text($x,$y,$txt) +function Text($x, $y, $txt) { - //Output a string - $s=sprintf('BT %.2f %.2f Td (%s) Tj ET',$x*$this->k,($this->h-$y)*$this->k,$this->_escape($txt)); + // Output a string + $s = sprintf('BT %.2F %.2F Td (%s) Tj ET',$x*$this->k,($this->h-$y)*$this->k,$this->_escape($txt)); if($this->underline && $txt!='') - $s.=' '.$this->_dounderline($x,$y,$txt); + $s .= ' '.$this->_dounderline($x,$y,$txt); if($this->ColorFlag) - $s='q '.$this->TextColor.' '.$s.' Q'; + $s = 'q '.$this->TextColor.' '.$s.' Q'; $this->_out($s); } function AcceptPageBreak() { - //Accept automatic page break or not + // Accept automatic page break or not return $this->AutoPageBreak; } -function Cell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='') +function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='') { - //Output a cell - $k=$this->k; - if($this->y+$h>$this->PageBreakTrigger && !$this->InFooter && $this->AcceptPageBreak()) + // Output a cell + $k = $this->k; + if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak()) { - //Automatic page break - $x=$this->x; - $ws=$this->ws; + // Automatic page break + $x = $this->x; + $ws = $this->ws; if($ws>0) { - $this->ws=0; + $this->ws = 0; $this->_out('0 Tw'); } - $this->AddPage($this->CurOrientation); - $this->x=$x; + $this->AddPage($this->CurOrientation,$this->CurPageSize); + $this->x = $x; if($ws>0) { - $this->ws=$ws; - $this->_out(sprintf('%.3f Tw',$ws*$k)); + $this->ws = $ws; + $this->_out(sprintf('%.3F Tw',$ws*$k)); } } if($w==0) - $w=$this->w-$this->rMargin-$this->x; - $s=''; - if($fill==1 || $border==1) + $w = $this->w-$this->rMargin-$this->x; + $s = ''; + if($fill || $border==1) { - if($fill==1) - $op=($border==1) ? 'B' : 'f'; + if($fill) + $op = ($border==1) ? 'B' : 'f'; else - $op='S'; - $s=sprintf('%.2f %.2f %.2f %.2f re %s ',$this->x*$k,($this->h-$this->y)*$k,$w*$k,-$h*$k,$op); + $op = 'S'; + $s = sprintf('%.2F %.2F %.2F %.2F re %s ',$this->x*$k,($this->h-$this->y)*$k,$w*$k,-$h*$k,$op); } if(is_string($border)) { - $x=$this->x; - $y=$this->y; + $x = $this->x; + $y = $this->y; if(strpos($border,'L')!==false) - $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,$x*$k,($this->h-($y+$h))*$k); + $s .= sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-$y)*$k,$x*$k,($this->h-($y+$h))*$k); if(strpos($border,'T')!==false) - $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-$y)*$k); + $s .= sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-$y)*$k); if(strpos($border,'R')!==false) - $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',($x+$w)*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-($y+$h))*$k); + $s .= sprintf('%.2F %.2F m %.2F %.2F l S ',($x+$w)*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-($y+$h))*$k); if(strpos($border,'B')!==false) - $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-($y+$h))*$k,($x+$w)*$k,($this->h-($y+$h))*$k); + $s .= sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-($y+$h))*$k,($x+$w)*$k,($this->h-($y+$h))*$k); } if($txt!=='') { if($align=='R') - $dx=$w-$this->cMargin-$this->GetStringWidth($txt); + $dx = $w-$this->cMargin-$this->GetStringWidth($txt); elseif($align=='C') - $dx=($w-$this->GetStringWidth($txt))/2; + $dx = ($w-$this->GetStringWidth($txt))/2; else - $dx=$this->cMargin; + $dx = $this->cMargin; if($this->ColorFlag) - $s.='q '.$this->TextColor.' '; - $txt2=str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$txt))); - $s.=sprintf('BT %.2f %.2f Td (%s) Tj ET',($this->x+$dx)*$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,$txt2); + $s .= 'q '.$this->TextColor.' '; + $txt2 = str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$txt))); + $s .= sprintf('BT %.2F %.2F Td (%s) Tj ET',($this->x+$dx)*$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,$txt2); if($this->underline) - $s.=' '.$this->_dounderline($this->x+$dx,$this->y+.5*$h+.3*$this->FontSize,$txt); + $s .= ' '.$this->_dounderline($this->x+$dx,$this->y+.5*$h+.3*$this->FontSize,$txt); if($this->ColorFlag) - $s.=' Q'; + $s .= ' Q'; if($link) $this->Link($this->x+$dx,$this->y+.5*$h-.5*$this->FontSize,$this->GetStringWidth($txt),$this->FontSize,$link); } if($s) $this->_out($s); - $this->lasth=$h; + $this->lasth = $h; if($ln>0) { - //Go to next line - $this->y+=$h; + // Go to next line + $this->y += $h; if($ln==1) - $this->x=$this->lMargin; + $this->x = $this->lMargin; } else - $this->x+=$w; + $this->x += $w; } -function MultiCell($w,$h,$txt,$border=0,$align='J',$fill=0) +function MultiCell($w, $h, $txt, $border=0, $align='J', $fill=false) { - //Output text with automatic or explicit line breaks - $cw=&$this->CurrentFont['cw']; + // Output text with automatic or explicit line breaks + $cw = &$this->CurrentFont['cw']; if($w==0) - $w=$this->w-$this->rMargin-$this->x; - $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; - $s=str_replace("\r",'',$txt); - $nb=strlen($s); + $w = $this->w-$this->rMargin-$this->x; + $wmax = ($w-2*$this->cMargin)*1000/$this->FontSize; + $s = str_replace("\r",'',$txt); + $nb = strlen($s); if($nb>0 && $s[$nb-1]=="\n") $nb--; - $b=0; + $b = 0; if($border) { if($border==1) { - $border='LTRB'; - $b='LRT'; - $b2='LR'; + $border = 'LTRB'; + $b = 'LRT'; + $b2 = 'LR'; } else { - $b2=''; + $b2 = ''; if(strpos($border,'L')!==false) - $b2.='L'; + $b2 .= 'L'; if(strpos($border,'R')!==false) - $b2.='R'; - $b=(strpos($border,'T')!==false) ? $b2.'T' : $b2; + $b2 .= 'R'; + $b = (strpos($border,'T')!==false) ? $b2.'T' : $b2; } } - $sep=-1; - $i=0; - $j=0; - $l=0; - $ns=0; - $nl=1; + $sep = -1; + $i = 0; + $j = 0; + $l = 0; + $ns = 0; + $nl = 1; while($i<$nb) { - //Get next character - $c=$s{$i}; + // Get next character + $c = $s[$i]; if($c=="\n") { - //Explicit line break + // Explicit line break if($this->ws>0) { - $this->ws=0; + $this->ws = 0; $this->_out('0 Tw'); } $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill); $i++; - $sep=-1; - $j=$i; - $l=0; - $ns=0; + $sep = -1; + $j = $i; + $l = 0; + $ns = 0; $nl++; if($border && $nl==2) - $b=$b2; + $b = $b2; continue; } if($c==' ') { - $sep=$i; - $ls=$l; + $sep = $i; + $ls = $l; $ns++; } - $l+=$cw[$c]; + $l += $cw[$c]; if($l>$wmax) { - //Automatic line break + // Automatic line break if($sep==-1) { if($i==$j) $i++; if($this->ws>0) { - $this->ws=0; + $this->ws = 0; $this->_out('0 Tw'); } $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill); @@ -783,84 +759,84 @@ function MultiCell($w,$h,$txt,$border=0,$align='J',$fill=0) { if($align=='J') { - $this->ws=($ns>1) ? ($wmax-$ls)/1000*$this->FontSize/($ns-1) : 0; - $this->_out(sprintf('%.3f Tw',$this->ws*$this->k)); + $this->ws = ($ns>1) ? ($wmax-$ls)/1000*$this->FontSize/($ns-1) : 0; + $this->_out(sprintf('%.3F Tw',$this->ws*$this->k)); } $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill); - $i=$sep+1; + $i = $sep+1; } - $sep=-1; - $j=$i; - $l=0; - $ns=0; + $sep = -1; + $j = $i; + $l = 0; + $ns = 0; $nl++; if($border && $nl==2) - $b=$b2; + $b = $b2; } else $i++; } - //Last chunk + // Last chunk if($this->ws>0) { - $this->ws=0; + $this->ws = 0; $this->_out('0 Tw'); } if($border && strpos($border,'B')!==false) - $b.='B'; + $b .= 'B'; $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill); - $this->x=$this->lMargin; + $this->x = $this->lMargin; } -function Write($h,$txt,$link='') +function Write($h, $txt, $link='') { - //Output text in flowing mode - $cw=&$this->CurrentFont['cw']; - $w=$this->w-$this->rMargin-$this->x; - $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; - $s=str_replace("\r",'',$txt); - $nb=strlen($s); - $sep=-1; - $i=0; - $j=0; - $l=0; - $nl=1; + // Output text in flowing mode + $cw = &$this->CurrentFont['cw']; + $w = $this->w-$this->rMargin-$this->x; + $wmax = ($w-2*$this->cMargin)*1000/$this->FontSize; + $s = str_replace("\r",'',$txt); + $nb = strlen($s); + $sep = -1; + $i = 0; + $j = 0; + $l = 0; + $nl = 1; while($i<$nb) { - //Get next character - $c=$s{$i}; + // Get next character + $c = $s[$i]; if($c=="\n") { - //Explicit line break + // Explicit line break $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link); $i++; - $sep=-1; - $j=$i; - $l=0; + $sep = -1; + $j = $i; + $l = 0; if($nl==1) { - $this->x=$this->lMargin; - $w=$this->w-$this->rMargin-$this->x; - $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; + $this->x = $this->lMargin; + $w = $this->w-$this->rMargin-$this->x; + $wmax = ($w-2*$this->cMargin)*1000/$this->FontSize; } $nl++; continue; } if($c==' ') - $sep=$i; - $l+=$cw[$c]; + $sep = $i; + $l += $cw[$c]; if($l>$wmax) { - //Automatic line break + // Automatic line break if($sep==-1) { if($this->x>$this->lMargin) { - //Move to next line - $this->x=$this->lMargin; - $this->y+=$h; - $w=$this->w-$this->rMargin-$this->x; - $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; + // Move to next line + $this->x = $this->lMargin; + $this->y += $h; + $w = $this->w-$this->rMargin-$this->x; + $wmax = ($w-2*$this->cMargin)*1000/$this->FontSize; $i++; $nl++; continue; @@ -872,186 +848,188 @@ function Write($h,$txt,$link='') else { $this->Cell($w,$h,substr($s,$j,$sep-$j),0,2,'',0,$link); - $i=$sep+1; + $i = $sep+1; } - $sep=-1; - $j=$i; - $l=0; + $sep = -1; + $j = $i; + $l = 0; if($nl==1) { - $this->x=$this->lMargin; - $w=$this->w-$this->rMargin-$this->x; - $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; + $this->x = $this->lMargin; + $w = $this->w-$this->rMargin-$this->x; + $wmax = ($w-2*$this->cMargin)*1000/$this->FontSize; } $nl++; } else $i++; } - //Last chunk + // Last chunk if($i!=$j) $this->Cell($l/1000*$this->FontSize,$h,substr($s,$j),0,0,'',0,$link); } -function Image($file,$x,$y,$w=0,$h=0,$type='',$link='') +function Ln($h=null) { - //Put an image on the page + // Line feed; default value is last cell height + $this->x = $this->lMargin; + if($h===null) + $this->y += $this->lasth; + else + $this->y += $h; +} + +function Image($file, $x=null, $y=null, $w=0, $h=0, $type='', $link='') +{ + // Put an image on the page if(!isset($this->images[$file])) { - //First use of image, get info + // First use of this image, get info if($type=='') { - $pos=strrpos($file,'.'); + $pos = strrpos($file,'.'); if(!$pos) $this->Error('Image file has no extension and no type was specified: '.$file); - $type=substr($file,$pos+1); + $type = substr($file,$pos+1); } - $type=strtolower($type); - $mqr=get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); - if($type=='jpg' || $type=='jpeg') - $info=$this->_parsejpg($file); - elseif($type=='png') - $info=$this->_parsepng($file); - else - { - //Allow for additional formats - $mtd='_parse'.$type; - if(!method_exists($this,$mtd)) - $this->Error('Unsupported image type: '.$type); - $info=$this->$mtd($file); - } - set_magic_quotes_runtime($mqr); - $info['i']=count($this->images)+1; - $this->images[$file]=$info; + $type = strtolower($type); + if($type=='jpeg') + $type = 'jpg'; + $mtd = '_parse'.$type; + if(!method_exists($this,$mtd)) + $this->Error('Unsupported image type: '.$type); + $info = $this->$mtd($file); + $info['i'] = count($this->images)+1; + $this->images[$file] = $info; } else - $info=$this->images[$file]; - //Automatic width and height calculation if needed + $info = $this->images[$file]; + + // Automatic width and height calculation if needed if($w==0 && $h==0) { - //Put image at 72 dpi - $w=$info['w']/$this->k; - $h=$info['h']/$this->k; + // Put image at 96 dpi + $w = -96; + $h = -96; } + if($w<0) + $w = -$info['w']*72/$w/$this->k; + if($h<0) + $h = -$info['h']*72/$h/$this->k; if($w==0) - $w=$h*$info['w']/$info['h']; + $w = $h*$info['w']/$info['h']; if($h==0) - $h=$w*$info['h']/$info['w']; - $this->_out(sprintf('q %.2f 0 0 %.2f %.2f %.2f cm /I%d Do Q',$w*$this->k,$h*$this->k,$x*$this->k,($this->h-($y+$h))*$this->k,$info['i'])); + $h = $w*$info['h']/$info['w']; + + // Flowing mode + if($y===null) + { + if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak()) + { + // Automatic page break + $x2 = $this->x; + $this->AddPage($this->CurOrientation,$this->CurPageSize); + $this->x = $x2; + } + $y = $this->y; + $this->y += $h; + } + + if($x===null) + $x = $this->x; + $this->_out(sprintf('q %.2F 0 0 %.2F %.2F %.2F cm /I%d Do Q',$w*$this->k,$h*$this->k,$x*$this->k,($this->h-($y+$h))*$this->k,$info['i'])); if($link) $this->Link($x,$y,$w,$h,$link); } -function Ln($h='') -{ - //Line feed; default value is last cell height - $this->x=$this->lMargin; - if(is_string($h)) - $this->y+=$this->lasth; - else - $this->y+=$h; -} - function GetX() { - //Get x position + // Get x position return $this->x; } function SetX($x) { - //Set x position + // Set x position if($x>=0) - $this->x=$x; + $this->x = $x; else - $this->x=$this->w+$x; + $this->x = $this->w+$x; } function GetY() { - //Get y position + // Get y position return $this->y; } function SetY($y) { - //Set y position and reset x - $this->x=$this->lMargin; + // Set y position and reset x + $this->x = $this->lMargin; if($y>=0) - $this->y=$y; + $this->y = $y; else - $this->y=$this->h+$y; + $this->y = $this->h+$y; } -function SetXY($x,$y) +function SetXY($x, $y) { - //Set x and y positions + // Set x and y positions $this->SetY($y); $this->SetX($x); } -function Output($name='',$dest='') +function Output($name='', $dest='') { - //Output PDF to some destination - //Finish document if necessary + // Output PDF to some destination if($this->state<3) $this->Close(); - //Normalize parameters - if(is_bool($dest)) - $dest=$dest ? 'D' : 'F'; - $dest=strtoupper($dest); + $dest = strtoupper($dest); if($dest=='') { if($name=='') { - $name='doc.pdf'; - $dest='I'; + $name = 'doc.pdf'; + $dest = 'I'; } else - $dest='F'; + $dest = 'F'; } switch($dest) { case 'I': - //Send to standard output - if(ob_get_contents()) - $this->Error('Some data has already been output, can\'t send PDF file'); - if(php_sapi_name()!='cli') + // Send to standard output + $this->_checkoutput(); + if(PHP_SAPI!='cli') { - //We send to a browser + // We send to a browser header('Content-Type: application/pdf'); - if(headers_sent()) - $this->Error('Some data has already been output to browser, can\'t send PDF file'); - header('Content-Length: '.strlen($this->buffer)); - header('Content-disposition: inline; filename="'.$name.'"'); + header('Content-Disposition: inline; filename="'.$name.'"'); + header('Cache-Control: private, max-age=0, must-revalidate'); + header('Pragma: public'); } echo $this->buffer; break; case 'D': - //Download file - if(ob_get_contents()) - $this->Error('Some data has already been output, can\'t send PDF file'); - if(isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'],'MSIE')) - header('Content-Type: application/force-download'); - else - header('Content-Type: application/octet-stream'); - if(headers_sent()) - $this->Error('Some data has already been output to browser, can\'t send PDF file'); - header('Content-Length: '.strlen($this->buffer)); - header('Content-disposition: attachment; filename="'.$name.'"'); + // Download file + $this->_checkoutput(); + header('Content-Type: application/x-download'); + header('Content-Disposition: attachment; filename="'.$name.'"'); + header('Cache-Control: private, max-age=0, must-revalidate'); + header('Pragma: public'); echo $this->buffer; break; case 'F': - //Save to local file - $f=fopen($name,'wb'); + // Save to local file + $f = fopen($name,'wb'); if(!$f) $this->Error('Unable to create output file: '.$name); fwrite($f,$this->buffer,strlen($this->buffer)); fclose($f); break; case 'S': - //Return as a string + // Return as a string return $this->buffer; default: $this->Error('Incorrect output destination: '.$dest); @@ -1066,131 +1044,505 @@ function Output($name='',$dest='') *******************************************************************************/ function _dochecks() { - //Check for locale-related bug - if(1.1==1) - $this->Error('Don\'t alter the locale before including class file'); - //Check for decimal separator - if(sprintf('%.1f',1.0)!='1.0') - setlocale(LC_NUMERIC,'C'); + // Check availability of %F + if(sprintf('%.1F',1.0)!='1.0') + $this->Error('This version of PHP is not supported'); + // Check mbstring overloading + if(ini_get('mbstring.func_overload') & 2) + $this->Error('mbstring overloading must be disabled'); + // Ensure runtime magic quotes are disabled + if(get_magic_quotes_runtime()) + @set_magic_quotes_runtime(0); } -function _getfontpath() +function _checkoutput() { - if(!defined('FPDF_FONTPATH') && is_dir(dirname(__FILE__).'/font')) - define('FPDF_FONTPATH',dirname(__FILE__).'/font/'); - return defined('FPDF_FONTPATH') ? FPDF_FONTPATH : ''; + if(PHP_SAPI!='cli') + { + if(headers_sent($file,$line)) + $this->Error("Some data has already been output, can't send PDF file (output started at $file:$line)"); + } + if(ob_get_length()) + { + // The output buffer is not empty + if(preg_match('/^(\xEF\xBB\xBF)?\s*$/',ob_get_contents())) + { + // It contains only a UTF-8 BOM and/or whitespace, let's clean it + ob_clean(); + } + else + $this->Error("Some data has already been output, can't send PDF file"); + } +} + +function _getpagesize($size) +{ + if(is_string($size)) + { + $size = strtolower($size); + if(!isset($this->StdPageSizes[$size])) + $this->Error('Unknown page size: '.$size); + $a = $this->StdPageSizes[$size]; + return array($a[0]/$this->k, $a[1]/$this->k); + } + else + { + if($size[0]>$size[1]) + return array($size[1], $size[0]); + else + return $size; + } +} + +function _beginpage($orientation, $size) +{ + $this->page++; + $this->pages[$this->page] = ''; + $this->state = 2; + $this->x = $this->lMargin; + $this->y = $this->tMargin; + $this->FontFamily = ''; + // Check page size and orientation + if($orientation=='') + $orientation = $this->DefOrientation; + else + $orientation = strtoupper($orientation[0]); + if($size=='') + $size = $this->DefPageSize; + else + $size = $this->_getpagesize($size); + if($orientation!=$this->CurOrientation || $size[0]!=$this->CurPageSize[0] || $size[1]!=$this->CurPageSize[1]) + { + // New size or orientation + if($orientation=='P') + { + $this->w = $size[0]; + $this->h = $size[1]; + } + else + { + $this->w = $size[1]; + $this->h = $size[0]; + } + $this->wPt = $this->w*$this->k; + $this->hPt = $this->h*$this->k; + $this->PageBreakTrigger = $this->h-$this->bMargin; + $this->CurOrientation = $orientation; + $this->CurPageSize = $size; + } + if($orientation!=$this->DefOrientation || $size[0]!=$this->DefPageSize[0] || $size[1]!=$this->DefPageSize[1]) + $this->PageSizes[$this->page] = array($this->wPt, $this->hPt); +} + +function _endpage() +{ + $this->state = 1; +} + +function _loadfont($font) +{ + // Load a font definition file from the font directory + include($this->fontpath.$font); + $a = get_defined_vars(); + if(!isset($a['name'])) + $this->Error('Could not include font definition file'); + return $a; +} + +function _escape($s) +{ + // Escape special characters in strings + $s = str_replace('\\','\\\\',$s); + $s = str_replace('(','\\(',$s); + $s = str_replace(')','\\)',$s); + $s = str_replace("\r",'\\r',$s); + return $s; +} + +function _textstring($s) +{ + // Format a text string + return '('.$this->_escape($s).')'; +} + +function _UTF8toUTF16($s) +{ + // Convert UTF-8 to UTF-16BE with BOM + $res = "\xFE\xFF"; + $nb = strlen($s); + $i = 0; + while($i<$nb) + { + $c1 = ord($s[$i++]); + if($c1>=224) + { + // 3-byte character + $c2 = ord($s[$i++]); + $c3 = ord($s[$i++]); + $res .= chr((($c1 & 0x0F)<<4) + (($c2 & 0x3C)>>2)); + $res .= chr((($c2 & 0x03)<<6) + ($c3 & 0x3F)); + } + elseif($c1>=192) + { + // 2-byte character + $c2 = ord($s[$i++]); + $res .= chr(($c1 & 0x1C)>>2); + $res .= chr((($c1 & 0x03)<<6) + ($c2 & 0x3F)); + } + else + { + // Single-byte character + $res .= "\0".chr($c1); + } + } + return $res; +} + +function _dounderline($x, $y, $txt) +{ + // Underline text + $up = $this->CurrentFont['up']; + $ut = $this->CurrentFont['ut']; + $w = $this->GetStringWidth($txt)+$this->ws*substr_count($txt,' '); + return sprintf('%.2F %.2F %.2F %.2F re f',$x*$this->k,($this->h-($y-$up/1000*$this->FontSize))*$this->k,$w*$this->k,-$ut/1000*$this->FontSizePt); +} + +function _parsejpg($file) +{ + // Extract info from a JPEG file + $a = getimagesize($file); + if(!$a) + $this->Error('Missing or incorrect image file: '.$file); + if($a[2]!=2) + $this->Error('Not a JPEG file: '.$file); + if(!isset($a['channels']) || $a['channels']==3) + $colspace = 'DeviceRGB'; + elseif($a['channels']==4) + $colspace = 'DeviceCMYK'; + else + $colspace = 'DeviceGray'; + $bpc = isset($a['bits']) ? $a['bits'] : 8; + $data = file_get_contents($file); + return array('w'=>$a[0], 'h'=>$a[1], 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'DCTDecode', 'data'=>$data); +} + +function _parsepng($file) +{ + // Extract info from a PNG file + $f = fopen($file,'rb'); + if(!$f) + $this->Error('Can\'t open image file: '.$file); + $info = $this->_parsepngstream($f,$file); + fclose($f); + return $info; +} + +function _parsepngstream($f, $file) +{ + // Check signature + if($this->_readstream($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) + $this->Error('Not a PNG file: '.$file); + + // Read header chunk + $this->_readstream($f,4); + if($this->_readstream($f,4)!='IHDR') + $this->Error('Incorrect PNG file: '.$file); + $w = $this->_readint($f); + $h = $this->_readint($f); + $bpc = ord($this->_readstream($f,1)); + if($bpc>8) + $this->Error('16-bit depth not supported: '.$file); + $ct = ord($this->_readstream($f,1)); + if($ct==0 || $ct==4) + $colspace = 'DeviceGray'; + elseif($ct==2 || $ct==6) + $colspace = 'DeviceRGB'; + elseif($ct==3) + $colspace = 'Indexed'; + else + $this->Error('Unknown color type: '.$file); + if(ord($this->_readstream($f,1))!=0) + $this->Error('Unknown compression method: '.$file); + if(ord($this->_readstream($f,1))!=0) + $this->Error('Unknown filter method: '.$file); + if(ord($this->_readstream($f,1))!=0) + $this->Error('Interlacing not supported: '.$file); + $this->_readstream($f,4); + $dp = '/Predictor 15 /Colors '.($colspace=='DeviceRGB' ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w; + + // Scan chunks looking for palette, transparency and image data + $pal = ''; + $trns = ''; + $data = ''; + do + { + $n = $this->_readint($f); + $type = $this->_readstream($f,4); + if($type=='PLTE') + { + // Read palette + $pal = $this->_readstream($f,$n); + $this->_readstream($f,4); + } + elseif($type=='tRNS') + { + // Read transparency info + $t = $this->_readstream($f,$n); + if($ct==0) + $trns = array(ord(substr($t,1,1))); + elseif($ct==2) + $trns = array(ord(substr($t,1,1)), ord(substr($t,3,1)), ord(substr($t,5,1))); + else + { + $pos = strpos($t,chr(0)); + if($pos!==false) + $trns = array($pos); + } + $this->_readstream($f,4); + } + elseif($type=='IDAT') + { + // Read image data block + $data .= $this->_readstream($f,$n); + $this->_readstream($f,4); + } + elseif($type=='IEND') + break; + else + $this->_readstream($f,$n+4); + } + while($n); + + if($colspace=='Indexed' && empty($pal)) + $this->Error('Missing palette in '.$file); + $info = array('w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'FlateDecode', 'dp'=>$dp, 'pal'=>$pal, 'trns'=>$trns); + if($ct>=4) + { + // Extract alpha channel + if(!function_exists('gzuncompress')) + $this->Error('Zlib not available, can\'t handle alpha channel: '.$file); + $data = gzuncompress($data); + $color = ''; + $alpha = ''; + if($ct==4) + { + // Gray image + $len = 2*$w; + for($i=0;$i<$h;$i++) + { + $pos = (1+$len)*$i; + $color .= $data[$pos]; + $alpha .= $data[$pos]; + $line = substr($data,$pos+1,$len); + $color .= preg_replace('/(.)./s','$1',$line); + $alpha .= preg_replace('/.(.)/s','$1',$line); + } + } + else + { + // RGB image + $len = 4*$w; + for($i=0;$i<$h;$i++) + { + $pos = (1+$len)*$i; + $color .= $data[$pos]; + $alpha .= $data[$pos]; + $line = substr($data,$pos+1,$len); + $color .= preg_replace('/(.{3})./s','$1',$line); + $alpha .= preg_replace('/.{3}(.)/s','$1',$line); + } + } + unset($data); + $data = gzcompress($color); + $info['smask'] = gzcompress($alpha); + if($this->PDFVersion<'1.4') + $this->PDFVersion = '1.4'; + } + $info['data'] = $data; + return $info; +} + +function _readstream($f, $n) +{ + // Read n bytes from stream + $res = ''; + while($n>0 && !feof($f)) + { + $s = fread($f,$n); + if($s===false) + $this->Error('Error while reading stream'); + $n -= strlen($s); + $res .= $s; + } + if($n>0) + $this->Error('Unexpected end of stream'); + return $res; +} + +function _readint($f) +{ + // Read a 4-byte integer from stream + $a = unpack('Ni',$this->_readstream($f,4)); + return $a['i']; +} + +function _parsegif($file) +{ + // Extract info from a GIF file (via PNG conversion) + if(!function_exists('imagepng')) + $this->Error('GD extension is required for GIF support'); + if(!function_exists('imagecreatefromgif')) + $this->Error('GD has no GIF read support'); + $im = imagecreatefromgif($file); + if(!$im) + $this->Error('Missing or incorrect image file: '.$file); + imageinterlace($im,0); + $f = @fopen('php://temp','rb+'); + if($f) + { + // Perform conversion in memory + ob_start(); + imagepng($im); + $data = ob_get_clean(); + imagedestroy($im); + fwrite($f,$data); + rewind($f); + $info = $this->_parsepngstream($f,$file); + fclose($f); + } + else + { + // Use temporary file + $tmp = tempnam('.','gif'); + if(!$tmp) + $this->Error('Unable to create a temporary file'); + if(!imagepng($im,$tmp)) + $this->Error('Error while saving to temporary file'); + imagedestroy($im); + $info = $this->_parsepng($tmp); + unlink($tmp); + } + return $info; +} + +function _newobj() +{ + // Begin a new object + $this->n++; + $this->offsets[$this->n] = strlen($this->buffer); + $this->_out($this->n.' 0 obj'); +} + +function _putstream($s) +{ + $this->_out('stream'); + $this->_out($s); + $this->_out('endstream'); +} + +function _out($s) +{ + // Add a line to the document + if($this->state==2) + $this->pages[$this->page] .= $s."\n"; + else + $this->buffer .= $s."\n"; } function _putpages() { - $nb=$this->page; + $nb = $this->page; if(!empty($this->AliasNbPages)) { - //Replace number of pages + // Replace number of pages for($n=1;$n<=$nb;$n++) - $this->pages[$n]=str_replace($this->AliasNbPages,$nb,$this->pages[$n]); + $this->pages[$n] = str_replace($this->AliasNbPages,$nb,$this->pages[$n]); } if($this->DefOrientation=='P') { - $wPt=$this->fwPt; - $hPt=$this->fhPt; + $wPt = $this->DefPageSize[0]*$this->k; + $hPt = $this->DefPageSize[1]*$this->k; } else { - $wPt=$this->fhPt; - $hPt=$this->fwPt; + $wPt = $this->DefPageSize[1]*$this->k; + $hPt = $this->DefPageSize[0]*$this->k; } - $filter=($this->compress) ? '/Filter /FlateDecode ' : ''; + $filter = ($this->compress) ? '/Filter /FlateDecode ' : ''; for($n=1;$n<=$nb;$n++) { - //Page + // Page $this->_newobj(); $this->_out('<_out('/Parent 1 0 R'); - if(isset($this->OrientationChanges[$n])) - $this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$hPt,$wPt)); + if(isset($this->PageSizes[$n])) + $this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]',$this->PageSizes[$n][0],$this->PageSizes[$n][1])); $this->_out('/Resources 2 0 R'); if(isset($this->PageLinks[$n])) { - //Links - $annots='/Annots ['; + // Links + $annots = '/Annots ['; foreach($this->PageLinks[$n] as $pl) { - $rect=sprintf('%.2f %.2f %.2f %.2f',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]); - $annots.='<_textstring($pl[4]).'>>>>'; + $annots .= '/A <_textstring($pl[4]).'>>>>'; else { - $l=$this->links[$pl[4]]; - $h=isset($this->OrientationChanges[$l[0]]) ? $wPt : $hPt; - $annots.=sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]>>',1+2*$l[0],$h-$l[1]*$this->k); + $l = $this->links[$pl[4]]; + $h = isset($this->PageSizes[$l[0]]) ? $this->PageSizes[$l[0]][1] : $hPt; + $annots .= sprintf('/Dest [%d 0 R /XYZ 0 %.2F null]>>',1+2*$l[0],$h-$l[1]*$this->k); } } $this->_out($annots.']'); } + if($this->PDFVersion>'1.3') + $this->_out('/Group <>'); $this->_out('/Contents '.($this->n+1).' 0 R>>'); $this->_out('endobj'); - //Page content - $p=($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n]; + // Page content + $p = ($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n]; $this->_newobj(); $this->_out('<<'.$filter.'/Length '.strlen($p).'>>'); $this->_putstream($p); $this->_out('endobj'); } - //Pages root - $this->offsets[1]=strlen($this->buffer); + // Pages root + $this->offsets[1] = strlen($this->buffer); $this->_out('1 0 obj'); $this->_out('<_out($kids.']'); $this->_out('/Count '.$nb); - $this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$wPt,$hPt)); + $this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]',$wPt,$hPt)); $this->_out('>>'); $this->_out('endobj'); } function _putfonts() { - $nf=$this->n; + $nf = $this->n; foreach($this->diffs as $diff) { - //Encodings + // Encodings $this->_newobj(); $this->_out('<>'); $this->_out('endobj'); } - $mqr=get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); foreach($this->FontFiles as $file=>$info) { - //Font file embedding + // Font file embedding $this->_newobj(); - $this->FontFiles[$file]['n']=$this->n; - $font=''; - $f=fopen($this->_getfontpath().$file,'rb',1); - if(!$f) - $this->Error('Font file not found'); - while(!feof($f)) - $font.=fread($f,8192); - fclose($f); - $compressed=(substr($file,-2)=='.z'); + $this->FontFiles[$file]['n'] = $this->n; + $font = file_get_contents($this->fontpath.$file,true); + if(!$font) + $this->Error('Font file not found: '.$file); + $compressed = (substr($file,-2)=='.z'); if(!$compressed && isset($info['length2'])) - { - $header=(ord($font{0})==128); - if($header) - { - //Strip first binary header - $font=substr($font,6); - } - if($header && ord($font{$info['length1']})==128) - { - //Strip second binary header - $font=substr($font,0,$info['length1']).substr($font,$info['length1']+6); - } - } + $font = substr($font,6,$info['length1']).substr($font,6+$info['length1']+6,$info['length2']); $this->_out('<_out('/Filter /FlateDecode'); @@ -1201,16 +1553,15 @@ function _putfonts() $this->_putstream($font); $this->_out('endobj'); } - set_magic_quotes_runtime($mqr); foreach($this->fonts as $k=>$font) { - //Font objects - $this->fonts[$k]['n']=$this->n+1; - $type=$font['type']; - $name=$font['name']; - if($type=='core') + // Font objects + $this->fonts[$k]['n'] = $this->n+1; + $type = $font['type']; + $name = $font['name']; + if($type=='Core') { - //Standard font + // Core font $this->_newobj(); $this->_out('<_out('/BaseFont /'.$name); @@ -1222,7 +1573,7 @@ function _putfonts() } elseif($type=='Type1' || $type=='TrueType') { - //Additional Type1 or TrueType font + // Additional Type1 or TrueType/OpenType font $this->_newobj(); $this->_out('<_out('/BaseFont /'.$name); @@ -1230,38 +1581,34 @@ function _putfonts() $this->_out('/FirstChar 32 /LastChar 255'); $this->_out('/Widths '.($this->n+1).' 0 R'); $this->_out('/FontDescriptor '.($this->n+2).' 0 R'); - if($font['enc']) - { - if(isset($font['diff'])) - $this->_out('/Encoding '.($nf+$font['diff']).' 0 R'); - else - $this->_out('/Encoding /WinAnsiEncoding'); - } + if(isset($font['diffn'])) + $this->_out('/Encoding '.($nf+$font['diffn']).' 0 R'); + else + $this->_out('/Encoding /WinAnsiEncoding'); $this->_out('>>'); $this->_out('endobj'); - //Widths + // Widths $this->_newobj(); - $cw=&$font['cw']; - $s='['; + $cw = &$font['cw']; + $s = '['; for($i=32;$i<=255;$i++) - $s.=$cw[chr($i)].' '; + $s .= $cw[chr($i)].' '; $this->_out($s.']'); $this->_out('endobj'); - //Descriptor + // Descriptor $this->_newobj(); - $s='<$v) - $s.=' /'.$k.' '.$v; - $file=$font['file']; - if($file) - $s.=' /FontFile'.($type=='Type1' ? '' : '2').' '.$this->FontFiles[$file]['n'].' 0 R'; + $s .= ' /'.$k.' '.$v; + if(!empty($font['file'])) + $s .= ' /FontFile'.($type=='Type1' ? '' : '2').' '.$this->FontFiles[$font['file']]['n'].' 0 R'; $this->_out($s.'>>'); $this->_out('endobj'); } else { - //Allow for additional types - $mtd='_put'.strtolower($type); + // Allow for additional types + $mtd = '_put'.strtolower($type); if(!method_exists($this,$mtd)) $this->Error('Unsupported font type: '.$type); $this->$mtd($font); @@ -1271,49 +1618,63 @@ function _putfonts() function _putimages() { - $filter=($this->compress) ? '/Filter /FlateDecode ' : ''; - reset($this->images); - while(list($file,$info)=each($this->images)) + foreach(array_keys($this->images) as $file) { - $this->_newobj(); - $this->images[$file]['n']=$this->n; - $this->_out('<_out('/Subtype /Image'); - $this->_out('/Width '.$info['w']); - $this->_out('/Height '.$info['h']); - if($info['cs']=='Indexed') - $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]'); - else - { - $this->_out('/ColorSpace /'.$info['cs']); - if($info['cs']=='DeviceCMYK') - $this->_out('/Decode [1 0 1 0 1 0 1 0]'); - } - $this->_out('/BitsPerComponent '.$info['bpc']); - if(isset($info['f'])) - $this->_out('/Filter /'.$info['f']); - if(isset($info['parms'])) - $this->_out($info['parms']); - if(isset($info['trns']) && is_array($info['trns'])) - { - $trns=''; - for($i=0;$i_out('/Mask ['.$trns.']'); - } - $this->_out('/Length '.strlen($info['data']).'>>'); - $this->_putstream($info['data']); + $this->_putimage($this->images[$file]); unset($this->images[$file]['data']); + unset($this->images[$file]['smask']); + } +} + +function _putimage(&$info) +{ + $this->_newobj(); + $info['n'] = $this->n; + $this->_out('<_out('/Subtype /Image'); + $this->_out('/Width '.$info['w']); + $this->_out('/Height '.$info['h']); + if($info['cs']=='Indexed') + $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]'); + else + { + $this->_out('/ColorSpace /'.$info['cs']); + if($info['cs']=='DeviceCMYK') + $this->_out('/Decode [1 0 1 0 1 0 1 0]'); + } + $this->_out('/BitsPerComponent '.$info['bpc']); + if(isset($info['f'])) + $this->_out('/Filter /'.$info['f']); + if(isset($info['dp'])) + $this->_out('/DecodeParms <<'.$info['dp'].'>>'); + if(isset($info['trns']) && is_array($info['trns'])) + { + $trns = ''; + for($i=0;$i_out('/Mask ['.$trns.']'); + } + if(isset($info['smask'])) + $this->_out('/SMask '.($this->n+1).' 0 R'); + $this->_out('/Length '.strlen($info['data']).'>>'); + $this->_putstream($info['data']); + $this->_out('endobj'); + // Soft mask + if(isset($info['smask'])) + { + $dp = '/Predictor 15 /Colors 1 /BitsPerComponent 8 /Columns '.$info['w']; + $smask = array('w'=>$info['w'], 'h'=>$info['h'], 'cs'=>'DeviceGray', 'bpc'=>8, 'f'=>$info['f'], 'dp'=>$dp, 'data'=>$info['smask']); + $this->_putimage($smask); + } + // Palette + if($info['cs']=='Indexed') + { + $filter = ($this->compress) ? '/Filter /FlateDecode ' : ''; + $pal = ($this->compress) ? gzcompress($info['pal']) : $info['pal']; + $this->_newobj(); + $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>'); + $this->_putstream($pal); $this->_out('endobj'); - //Palette - if($info['cs']=='Indexed') - { - $this->_newobj(); - $pal=($this->compress) ? gzcompress($info['pal']) : $info['pal']; - $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>'); - $this->_putstream($pal); - $this->_out('endobj'); - } } } @@ -1339,8 +1700,8 @@ function _putresources() { $this->_putfonts(); $this->_putimages(); - //Resource dictionary - $this->offsets[2]=strlen($this->buffer); + // Resource dictionary + $this->offsets[2] = strlen($this->buffer); $this->_out('2 0 obj'); $this->_out('<<'); $this->_putresourcedict(); @@ -1361,7 +1722,7 @@ function _putinfo() $this->_out('/Keywords '.$this->_textstring($this->keywords)); if(!empty($this->creator)) $this->_out('/Creator '.$this->_textstring($this->creator)); - $this->_out('/CreationDate '.$this->_textstring('D:'.date('YmdHis'))); + $this->_out('/CreationDate '.$this->_textstring('D:'.@date('YmdHis'))); } function _putcatalog() @@ -1375,7 +1736,7 @@ function _putcatalog() elseif($this->ZoomMode=='real') $this->_out('/OpenAction [3 0 R /XYZ null null 1]'); elseif(!is_string($this->ZoomMode)) - $this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode/100).']'); + $this->_out('/OpenAction [3 0 R /XYZ null null '.sprintf('%.2F',$this->ZoomMode/100).']'); if($this->LayoutMode=='single') $this->_out('/PageLayout /SinglePage'); elseif($this->LayoutMode=='continuous') @@ -1401,26 +1762,26 @@ function _enddoc() $this->_putheader(); $this->_putpages(); $this->_putresources(); - //Info + // Info $this->_newobj(); $this->_out('<<'); $this->_putinfo(); $this->_out('>>'); $this->_out('endobj'); - //Catalog + // Catalog $this->_newobj(); $this->_out('<<'); $this->_putcatalog(); $this->_out('>>'); $this->_out('endobj'); - //Cross-ref - $o=strlen($this->buffer); + // Cross-ref + $o = strlen($this->buffer); $this->_out('xref'); $this->_out('0 '.($this->n+1)); $this->_out('0000000000 65535 f '); for($i=1;$i<=$this->n;$i++) $this->_out(sprintf('%010d 00000 n ',$this->offsets[$i])); - //Trailer + // Trailer $this->_out('trailer'); $this->_out('<<'); $this->_puttrailer(); @@ -1428,221 +1789,16 @@ function _enddoc() $this->_out('startxref'); $this->_out($o); $this->_out('%%EOF'); - $this->state=3; + $this->state = 3; +} +// End of class } -function _beginpage($orientation) -{ - $this->page++; - $this->pages[$this->page]=''; - $this->state=2; - $this->x=$this->lMargin; - $this->y=$this->tMargin; - $this->FontFamily=''; - //Page orientation - if(!$orientation) - $orientation=$this->DefOrientation; - else - { - $orientation=strtoupper($orientation{0}); - if($orientation!=$this->DefOrientation) - $this->OrientationChanges[$this->page]=true; - } - if($orientation!=$this->CurOrientation) - { - //Change orientation - if($orientation=='P') - { - $this->wPt=$this->fwPt; - $this->hPt=$this->fhPt; - $this->w=$this->fw; - $this->h=$this->fh; - } - else - { - $this->wPt=$this->fhPt; - $this->hPt=$this->fwPt; - $this->w=$this->fh; - $this->h=$this->fw; - } - $this->PageBreakTrigger=$this->h-$this->bMargin; - $this->CurOrientation=$orientation; - } -} - -function _endpage() -{ - //End of page contents - $this->state=1; -} - -function _newobj() -{ - //Begin a new object - $this->n++; - $this->offsets[$this->n]=strlen($this->buffer); - $this->_out($this->n.' 0 obj'); -} - -function _dounderline($x,$y,$txt) -{ - //Underline text - $up=$this->CurrentFont['up']; - $ut=$this->CurrentFont['ut']; - $w=$this->GetStringWidth($txt)+$this->ws*substr_count($txt,' '); - return sprintf('%.2f %.2f %.2f %.2f re f',$x*$this->k,($this->h-($y-$up/1000*$this->FontSize))*$this->k,$w*$this->k,-$ut/1000*$this->FontSizePt); -} - -function _parsejpg($file) -{ - //Extract info from a JPEG file - $a=GetImageSize($file); - if(!$a) - $this->Error('Missing or incorrect image file: '.$file); - if($a[2]!=2) - $this->Error('Not a JPEG file: '.$file); - if(!isset($a['channels']) || $a['channels']==3) - $colspace='DeviceRGB'; - elseif($a['channels']==4) - $colspace='DeviceCMYK'; - else - $colspace='DeviceGray'; - $bpc=isset($a['bits']) ? $a['bits'] : 8; - //Read whole file - $f=fopen($file,'rb'); - $data=''; - while(!feof($f)) - $data.=fread($f,4096); - fclose($f); - return array('w'=>$a[0],'h'=>$a[1],'cs'=>$colspace,'bpc'=>$bpc,'f'=>'DCTDecode','data'=>$data); -} - -function _parsepng($file) -{ - //Extract info from a PNG file - $f=fopen($file,'rb'); - if(!$f) - $this->Error('Can\'t open image file: '.$file); - //Check signature - if(fread($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) - $this->Error('Not a PNG file: '.$file); - //Read header chunk - fread($f,4); - if(fread($f,4)!='IHDR') - $this->Error('Incorrect PNG file: '.$file); - $w=$this->_freadint($f); - $h=$this->_freadint($f); - $bpc=ord(fread($f,1)); - if($bpc>8) - $this->Error('16-bit depth not supported: '.$file); - $ct=ord(fread($f,1)); - if($ct==0) - $colspace='DeviceGray'; - elseif($ct==2) - $colspace='DeviceRGB'; - elseif($ct==3) - $colspace='Indexed'; - else - $this->Error('Alpha channel not supported: '.$file); - if(ord(fread($f,1))!=0) - $this->Error('Unknown compression method: '.$file); - if(ord(fread($f,1))!=0) - $this->Error('Unknown filter method: '.$file); - if(ord(fread($f,1))!=0) - $this->Error('Interlacing not supported: '.$file); - fread($f,4); - $parms='/DecodeParms <>'; - //Scan chunks looking for palette, transparency and image data - $pal=''; - $trns=''; - $data=''; - do - { - $n=$this->_freadint($f); - $type=fread($f,4); - if($type=='PLTE') - { - //Read palette - $pal=fread($f,$n); - fread($f,4); - } - elseif($type=='tRNS') - { - //Read transparency info - $t=fread($f,$n); - if($ct==0) - $trns=array(ord(substr($t,1,1))); - elseif($ct==2) - $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1))); - else - { - $pos=strpos($t,chr(0)); - if($pos!==false) - $trns=array($pos); - } - fread($f,4); - } - elseif($type=='IDAT') - { - //Read image data block - $data.=fread($f,$n); - fread($f,4); - } - elseif($type=='IEND') - break; - else - fread($f,$n+4); - } - while($n); - if($colspace=='Indexed' && empty($pal)) - $this->Error('Missing palette in '.$file); - fclose($f); - return array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$data); -} - -function _freadint($f) -{ - //Read a 4-byte integer from file - $a=unpack('Ni',fread($f,4)); - return $a['i']; -} - -function _textstring($s) -{ - //Format a text string - return '('.$this->_escape($s).')'; -} - -function _escape($s) -{ - //Add \ before \, ( and ) - return str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$s))); -} - -function _putstream($s) -{ - $this->_out('stream'); - $this->_out($s); - $this->_out('endstream'); -} - -function _out($s) -{ - //Add a line to the document - if($this->state==2) - $this->pages[$this->page].=$s."\n"; - else - $this->buffer.=$s."\n"; -} -//End of class -} - -//Handle special IE contype request +// Handle special IE contype request if(isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT']=='contype') { header('Content-Type: application/pdf'); exit; } -} ?> diff --git a/InformeInventario.php b/InformeInventario.php index 0636e43..3e98277 100644 --- a/InformeInventario.php +++ b/InformeInventario.php @@ -133,19 +133,23 @@ class InformeInventario { if (!$resultado) { return $this->bdd->mensajeError($comando); } - $salidaTotal = ''; + //Utiliza un nuevo manejador de base de datos para poder hacer una consulta en los informes + $bdatos = new Sql(SERVIDOR, USUARIO, CLAVE, BASEDATOS); + $mezcla = new FPDF_Merge(); + $i = 0; while ($fila = $this->bdd->procesaResultado()) { //$fila=$this->bdd->procesaResultado(); $plantilla = file_get_contents($fichero) or die('Fallo en la apertura de la plantilla ' . $fichero); $plantilla = str_replace("{id}", $fila['id'], $plantilla); $plantilla = str_replace("{Descripcion}", utf8_encode($fila['Descripcion']), $plantilla); file_put_contents($salida, $plantilla) or die('Fallo en la escritura de la plantilla ' . $salida); - $informe = new InformePDF($this->bdd, $salida, true); - $salidaTotal.=$informe->getContenido(); + $informe = new InformePDF($bdatos, $salida, true); + $nombre = "tmp/sal" . $i++ . ".pdf"; + $informe->guardaArchivo($nombre); + $mezcla->add($nombre); } - file_put_contents("tmp/prueba.pdf", $salidaTotal); - $informe->enviaCabecera(); - echo $salidaTotal; + $nombre = "tmp/total.pdf"; + $mezcla->output($nombre); } } diff --git a/font/courier.php b/font/courier.php index 913f9a4..213bf35 100644 --- a/font/courier.php +++ b/font/courier.php @@ -1,7 +1,8 @@ diff --git a/font/courierb.php b/font/courierb.php new file mode 100644 index 0000000..3fc69a5 --- /dev/null +++ b/font/courierb.php @@ -0,0 +1,8 @@ + diff --git a/font/courierbi.php b/font/courierbi.php new file mode 100644 index 0000000..a49f2ae --- /dev/null +++ b/font/courierbi.php @@ -0,0 +1,8 @@ + diff --git a/font/courieri.php b/font/courieri.php new file mode 100644 index 0000000..9c1c2cf --- /dev/null +++ b/font/courieri.php @@ -0,0 +1,8 @@ + diff --git a/font/helvetica.php b/font/helvetica.php index ca94cdf..7e20c3a 100644 --- a/font/helvetica.php +++ b/font/helvetica.php @@ -1,5 +1,9 @@ 278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278, chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>278,'"'=>355,'#'=>556,'$'=>556,'%'=>889,'&'=>667,'\''=>191,'('=>333,')'=>333,'*'=>389,'+'=>584, ','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>278,';'=>278,'<'=>584,'='=>584,'>'=>584,'?'=>556,'@'=>1015,'A'=>667, diff --git a/font/helveticab.php b/font/helveticab.php index 276cfa8..452e0ac 100644 --- a/font/helveticab.php +++ b/font/helveticab.php @@ -1,5 +1,9 @@ 278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278, chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>333,'"'=>474,'#'=>556,'$'=>556,'%'=>889,'&'=>722,'\''=>238,'('=>333,')'=>333,'*'=>389,'+'=>584, ','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>333,';'=>333,'<'=>584,'='=>584,'>'=>584,'?'=>611,'@'=>975,'A'=>722, diff --git a/font/helveticabi.php b/font/helveticabi.php index 8d21774..ea5c56f 100644 --- a/font/helveticabi.php +++ b/font/helveticabi.php @@ -1,5 +1,9 @@ 278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278, chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>333,'"'=>474,'#'=>556,'$'=>556,'%'=>889,'&'=>722,'\''=>238,'('=>333,')'=>333,'*'=>389,'+'=>584, ','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>333,';'=>333,'<'=>584,'='=>584,'>'=>584,'?'=>611,'@'=>975,'A'=>722, diff --git a/font/helveticai.php b/font/helveticai.php index 88bf437..e3c638a 100644 --- a/font/helveticai.php +++ b/font/helveticai.php @@ -1,5 +1,9 @@ 278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278, chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>278,'"'=>355,'#'=>556,'$'=>556,'%'=>889,'&'=>667,'\''=>191,'('=>333,')'=>333,'*'=>389,'+'=>584, ','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>278,';'=>278,'<'=>584,'='=>584,'>'=>584,'?'=>556,'@'=>1015,'A'=>667, diff --git a/font/makefont/makefont.php b/font/makefont/makefont.php index 178e9e2..7e7ed56 100644 --- a/font/makefont/makefont.php +++ b/font/makefont/makefont.php @@ -1,8 +1,10 @@ Error: encoding not found: '.$enc); + die('Error: encoding not found: '.$enc); $cc2gn=array(); foreach($a as $l) { - if($l{0}=='!') + if($l[0]=='!') { $e=preg_split('/[ \\t]+/',rtrim($l)); $cc=hexdec(substr($e[0],1)); @@ -31,7 +33,7 @@ function ReadMap($enc) return $cc2gn; } -function ReadAFM($file,&$map) +function ReadAFM($file, &$map) { //Read a font metric file $a=file($file); @@ -114,14 +116,14 @@ function ReadAFM($file,&$map) { if(!isset($widths['.notdef'])) $widths['.notdef']=600; - if(!isset($widths['Delta']) and isset($widths['increment'])) + if(!isset($widths['Delta']) && isset($widths['increment'])) $widths['Delta']=$widths['increment']; //Order widths according to map for($i=0;$i<=255;$i++) { if(!isset($widths[$map[$i]])) { - echo 'Warning: character '.$map[$i].' is missing
'; + echo 'Warning: character '.$map[$i].' is missing
'; $widths[$i]=$widths['.notdef']; } else @@ -132,7 +134,7 @@ function ReadAFM($file,&$map) return $fm; } -function MakeFontDescriptor($fm,$symbolic) +function MakeFontDescriptor($fm, $symbolic) { //Ascent $asc=(isset($fm['Ascender']) ? $fm['Ascender'] : 1000); @@ -150,20 +152,20 @@ function MakeFontDescriptor($fm,$symbolic) $fd.=",'CapHeight'=>".$ch; //Flags $flags=0; - if(isset($fm['IsFixedPitch']) and $fm['IsFixedPitch']) + if(isset($fm['IsFixedPitch']) && $fm['IsFixedPitch']) $flags+=1<<0; if($symbolic) $flags+=1<<2; if(!$symbolic) $flags+=1<<5; - if(isset($fm['ItalicAngle']) and $fm['ItalicAngle']!=0) + if(isset($fm['ItalicAngle']) && $fm['ItalicAngle']!=0) $flags+=1<<6; $fd.=",'Flags'=>".$flags; //FontBBox if(isset($fm['FontBBox'])) $fbb=$fm['FontBBox']; else - $fbb=array(0,$des-100,1000,$asc+100); + $fbb=array(0,$desc-100,1000,$asc+100); $fd.=",'FontBBox'=>'[".$fbb[0].' '.$fbb[1].' '.$fbb[2].' '.$fbb[3]."]'"; //ItalicAngle $ia=(isset($fm['ItalicAngle']) ? $fm['ItalicAngle'] : 0); @@ -171,7 +173,7 @@ function MakeFontDescriptor($fm,$symbolic) //StemV if(isset($fm['StdVW'])) $stemv=$fm['StdVW']; - elseif(isset($fm['Weight']) and eregi('(bold|black)',$fm['Weight'])) + elseif(isset($fm['Weight']) && preg_match('/bold|black/i',$fm['Weight'])) $stemv=120; else $stemv=70; @@ -194,7 +196,7 @@ function MakeWidthArray($fm) $s.="'\\''"; elseif(chr($i)=="\\") $s.="'\\\\'"; - elseif($i>=32 and $i<=126) + elseif($i>=32 && $i<=126) $s.="'".chr($i)."'"; else $s.="chr($i)"; @@ -227,7 +229,7 @@ function MakeFontEncoding($map) return rtrim($s); } -function SaveToFile($file,$s,$mode='t') +function SaveToFile($file, $s, $mode) { $f=fopen($file,'w'.$mode); if(!$f) @@ -253,7 +255,7 @@ function CheckTTF($file) //Check if font license allows embedding $f=fopen($file,'rb'); if(!$f) - die('Error: Can\'t open '.$file); + die('Error: Can\'t open '.$file); //Extract number of tables fseek($f,4,SEEK_CUR); $nb=ReadShort($f); @@ -284,21 +286,22 @@ function CheckTTF($file) $pp=($fsType & 0x04)!=0; $e=($fsType & 0x08)!=0; fclose($f); - if($rl and !$pp and !$e) - echo 'Warning: font license does not allow embedding'; + if($rl && !$pp && !$e) + echo 'Warning: font license does not allow embedding'; } /******************************************************************************* -* $fontfile : chemin du fichier TTF (ou chaîne vide si pas d'incorporation) * -* $afmfile : chemin du fichier AFM * -* $enc : encodage (ou chaîne vide si la police est symbolique) * -* $patch : patch optionnel pour l'encodage * -* $type : type de la police si $fontfile est vide * +* fontfile: path to TTF file (or empty string if not to be embedded) * +* afmfile: path to AFM file * +* enc: font encoding (or empty string for symbolic fonts) * +* patch: optional patch for encoding * +* type: font type if fontfile is empty * *******************************************************************************/ -function MakeFont($fontfile,$afmfile,$enc='cp1252',$patch=array(),$type='TrueType') +function MakeFont($fontfile, $afmfile, $enc='cp1252', $patch=array(), $type='TrueType') { //Generate a font definition file - set_magic_quotes_runtime(0); + if(get_magic_quotes_runtime()) + @set_magic_quotes_runtime(0); ini_set('auto_detect_line_endings','1'); if($enc) { @@ -309,7 +312,7 @@ function MakeFont($fontfile,$afmfile,$enc='cp1252',$patch=array(),$type='TrueTyp else $map=array(); if(!file_exists($afmfile)) - die('Error: AFM file not found: '.$afmfile); + die('Error: AFM file not found: '.$afmfile); $fm=ReadAFM($afmfile,$map); if($enc) $diff=MakeFontEncoding($map); @@ -325,12 +328,12 @@ function MakeFont($fontfile,$afmfile,$enc='cp1252',$patch=array(),$type='TrueTyp elseif($ext=='pfb') $type='Type1'; else - die('Error: unrecognized font file extension: '.$ext); + die('Error: unrecognized font file extension: '.$ext); } else { - if($type!='TrueType' and $type!='Type1') - die('Error: incorrect font type: '.$type); + if($type!='TrueType' && $type!='Type1') + die('Error: incorrect font type: '.$type); } //Start generation $s='Error: font file not found: '.$fontfile); + die('Error: font file not found: '.$fontfile); if($type=='TrueType') CheckTTF($fontfile); $f=fopen($fontfile,'rb'); if(!$f) - die('Error: Can\'t open '.$fontfile); + die('Error: Can\'t open '.$fontfile); $file=fread($f,filesize($fontfile)); fclose($f); if($type=='Type1') { //Find first two sections and discard third one - $header=(ord($file{0})==128); + $header=(ord($file[0])==128); if($header) { //Strip first binary header @@ -371,16 +374,16 @@ function MakeFont($fontfile,$afmfile,$enc='cp1252',$patch=array(),$type='TrueTyp } $pos=strpos($file,'eexec'); if(!$pos) - die('Error: font file does not seem to be valid Type1'); + die('Error: font file does not seem to be valid Type1'); $size1=$pos+6; - if($header and ord($file{$size1})==128) + if($header && ord($file[$size1])==128) { //Strip second binary header $file=substr($file,0,$size1).substr($file,$size1+6); } $pos=strpos($file,'00000000'); if(!$pos) - die('Error: font file does not seem to be valid Type1'); + die('Error: font file does not seem to be valid Type1'); $size2=$pos-$size1; $file=substr($file,0,$size1+$size2); } @@ -389,12 +392,12 @@ function MakeFont($fontfile,$afmfile,$enc='cp1252',$patch=array(),$type='TrueTyp $cmp=$basename.'.z'; SaveToFile($cmp,gzcompress($file),'b'); $s.='$file=\''.$cmp."';\n"; - echo 'Font file compressed ('.$cmp.')
'; + echo 'Font file compressed ('.$cmp.')
'; } else { $s.='$file=\''.basename($fontfile)."';\n"; - echo 'Notice: font file could not be compressed (zlib extension not available)
'; + echo 'Notice: font file could not be compressed (zlib extension not available)
'; } if($type=='Type1') { @@ -410,7 +413,7 @@ function MakeFont($fontfile,$afmfile,$enc='cp1252',$patch=array(),$type='TrueTyp $s.='$file='."'';\n"; } $s.="?>\n"; - SaveToFile($basename.'.php',$s); - echo 'Font definition file generated ('.$basename.'.php'.')
'; + SaveToFile($basename.'.php',$s,'t'); + echo 'Font definition file generated ('.$basename.'.php'.')
'; } ?> diff --git a/font/symbol.php b/font/symbol.php index 43b50e4..b980b07 100644 --- a/font/symbol.php +++ b/font/symbol.php @@ -1,5 +1,9 @@ 250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250, chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>713,'#'=>500,'$'=>549,'%'=>833,'&'=>778,'\''=>439,'('=>333,')'=>333,'*'=>500,'+'=>549, ','=>250,'-'=>549,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>278,';'=>278,'<'=>549,'='=>549,'>'=>549,'?'=>444,'@'=>549,'A'=>722, diff --git a/font/times.php b/font/times.php index 837c706..d3ea808 100644 --- a/font/times.php +++ b/font/times.php @@ -1,5 +1,9 @@ 250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250, chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>408,'#'=>500,'$'=>500,'%'=>833,'&'=>778,'\''=>180,'('=>333,')'=>333,'*'=>500,'+'=>564, ','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>278,';'=>278,'<'=>564,'='=>564,'>'=>564,'?'=>444,'@'=>921,'A'=>722, diff --git a/font/timesb.php b/font/timesb.php index 09cff86..1c198f0 100644 --- a/font/timesb.php +++ b/font/timesb.php @@ -1,5 +1,9 @@ 250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250, chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>555,'#'=>500,'$'=>500,'%'=>1000,'&'=>833,'\''=>278,'('=>333,')'=>333,'*'=>500,'+'=>570, ','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>333,';'=>333,'<'=>570,'='=>570,'>'=>570,'?'=>500,'@'=>930,'A'=>722, diff --git a/font/timesbi.php b/font/timesbi.php index b4e38d7..a6034b2 100644 --- a/font/timesbi.php +++ b/font/timesbi.php @@ -1,5 +1,9 @@ 250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250, chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>389,'"'=>555,'#'=>500,'$'=>500,'%'=>833,'&'=>778,'\''=>278,'('=>333,')'=>333,'*'=>500,'+'=>570, ','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>333,';'=>333,'<'=>570,'='=>570,'>'=>570,'?'=>500,'@'=>832,'A'=>667, diff --git a/font/timesi.php b/font/timesi.php index 0ba2b77..bd9e0d9 100644 --- a/font/timesi.php +++ b/font/timesi.php @@ -1,5 +1,9 @@ 250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250, chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>420,'#'=>500,'$'=>500,'%'=>833,'&'=>778,'\''=>214,'('=>333,')'=>333,'*'=>500,'+'=>675, ','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>333,';'=>333,'<'=>675,'='=>675,'>'=>675,'?'=>500,'@'=>920,'A'=>611, diff --git a/font/zapfdingbats.php b/font/zapfdingbats.php index 1f926a8..afef4d3 100644 --- a/font/zapfdingbats.php +++ b/font/zapfdingbats.php @@ -1,5 +1,9 @@ 0,chr(1)=>0,chr(2)=>0,chr(3)=>0,chr(4)=>0,chr(5)=>0,chr(6)=>0,chr(7)=>0,chr(8)=>0,chr(9)=>0,chr(10)=>0,chr(11)=>0,chr(12)=>0,chr(13)=>0,chr(14)=>0,chr(15)=>0,chr(16)=>0,chr(17)=>0,chr(18)=>0,chr(19)=>0,chr(20)=>0,chr(21)=>0, chr(22)=>0,chr(23)=>0,chr(24)=>0,chr(25)=>0,chr(26)=>0,chr(27)=>0,chr(28)=>0,chr(29)=>0,chr(30)=>0,chr(31)=>0,' '=>278,'!'=>974,'"'=>961,'#'=>974,'$'=>980,'%'=>719,'&'=>789,'\''=>790,'('=>791,')'=>690,'*'=>960,'+'=>939, ','=>549,'-'=>855,'.'=>911,'/'=>933,'0'=>911,'1'=>945,'2'=>974,'3'=>755,'4'=>846,'5'=>762,'6'=>761,'7'=>571,'8'=>677,'9'=>763,':'=>760,';'=>759,'<'=>754,'='=>494,'>'=>552,'?'=>537,'@'=>577,'A'=>692, diff --git a/fpdf.css b/fpdf.css new file mode 100755 index 0000000..dd2c540 --- /dev/null +++ b/fpdf.css @@ -0,0 +1,21 @@ +body {font-family:"Times New Roman",serif} +h1 {font:bold 135% Arial,sans-serif; color:#4000A0; margin-bottom:0.9em} +h2 {font:bold 95% Arial,sans-serif; color:#900000; margin-top:1.5em; margin-bottom:1em} +dl.param dt {text-decoration:underline} +dl.param dd {margin-top:1em; margin-bottom:1em} +dl.param ul {margin-top:1em; margin-bottom:1em} +tt, code, kbd {font-family:"Courier New",Courier,monospace; font-size:82%} +div.source {margin-top:1.4em; margin-bottom:1.3em} +div.source pre {display:table; border:1px solid #24246A; width:100%; margin:0em; font-family:inherit; font-size:100%} +div.source code {display:block; border:1px solid #C5C5EC; background-color:#F0F5FF; padding:6px; color:#000000} +div.doc-source {margin-top:1.4em; margin-bottom:1.3em} +div.doc-source pre {display:table; width:100%; margin:0em; font-family:inherit; font-size:100%} +div.doc-source code {display:block; background-color:#E0E0E0; padding:4px} +.kw {color:#000080; font-weight:bold} +.str {color:#CC0000} +.cmt {color:#008000} +p.demo {text-align:center; margin-top:-0.9em} +a.demo {text-decoration:none; font-weight:bold; color:#0000CC} +a.demo:link {text-decoration:none; font-weight:bold; color:#0000CC} +a.demo:hover {text-decoration:none; font-weight:bold; color:#0000FF} +a.demo:active {text-decoration:none; font-weight:bold; color:#0000FF} diff --git a/fpdf_merge.php b/fpdf_merge.php new file mode 100644 index 0000000..9228a25 --- /dev/null +++ b/fpdf_merge.php @@ -0,0 +1,795 @@ + + * @copyright (C) Digitick 2011 + * @license GNU Lesser General Public License v3.0 + * + * Why this tool ? + * + * All the library tested (fpdi, ...) produce too heavy pdf + * because, these are not optimized. + * This library parses the pages, get the objects included (font, images) + * generate a hash to store only once these objects or reuse previous stored ones. + * + * + * Notes + * + * - links are not supported in this version + * - all pages are included (because this was what we needed) but update it + * to create an add(array pages) should be easy + * + * + * I tried to optimize a lot this tool using X-Debug, let me know if you do best :) + * If you get trouble or want to comment, feel free to send me an email. + * + * Use + * + * $merge = new FPDF_Merge(); + * $merge->add('/tmp/pdf-1.pdf'); + * $merge->add('/tmp/pdf-2.pdf'); + * $merge->output('/tmp/pdf-merge.pdf'); // or $merge->output(); to open it directly in the browser + * + * */ +class FPDF_Merge { + + const TYPE_NULL = 0, + TYPE_TOKEN = 1, + TYPE_REFERENCE = 2, + TYPE_REFERENCE_F = 3, + TYPE_NUMERIC = 4, + TYPE_HEX = 5, + TYPE_BOOL = 6, + TYPE_STRING = 7, + TYPE_ARRAY = 8, + TYPE_DICTIONARY = 9, + TYPE_STREAM = 10; + + private $buffer, $compress, $fonts, $objects, $pages, $ref, $n, $xref; + + /* * ************************************************ + /* CONSTRUCTOR + /************************************************* */ + + public function __construct() { + $this->buffer = ''; + $this->fonts = array(); + $this->objects = array(); + $this->pages = array(); + $this->ref = array(); + $this->xref = array(); + $this->n = 0; + $this->compress = function_exists('gzcompress'); + } + + /* * ************************************************ + /* PRIVATE + /************************************************* */ + + private function error($msg) { + throw new Exception($msg); + die; + } + + //================================================ + // FONCTIONS D'IMPORT + //================================================ + + private function parse($buffer, &$len, &$off) { + if ($len === $off) { + return null; + } + + if (!preg_match('`\s*(.)`', $buffer, $m, PREG_OFFSET_CAPTURE, $off)) + return null; + $off = $m[1][1]; + + switch ($buffer[$off]) { + case '<': + if ($buffer[$off + 1] === '<') { + // dictionnary + $v = array(); + $off+=2; + while (1) { + $key = $this->parse($buffer, $len, $off); + if ($key === null) + break; + if ($key[0] !== self::TYPE_TOKEN) + break; + $value = $this->parse($buffer, $len, $off); + $v[$key[1]] = $value; + } + $off+=2; + return array(self::TYPE_DICTIONARY, $v); + } else { + // hex + $p = strpos($buffer, '>', $off); + if ($p !== false) { + $v = substr($buffer, $off + 1, $p - $off - 1); + $off = $p + 1; + return array(self::TYPE_HEX, $v); + } + } + break; + case '(': + // string + $p = $off; + while (1) { + $p++; + if ($p === $len) + break; + if (($buffer[$p] === ')') && ($buffer[$p - 1] !== '\\')) + break; + } + if ($p < $len) { + $v = substr($buffer, $off + 1, $p - $off - 1); + $off = $p + 1; + return array(self::TYPE_STRING, $v); + } + break; + case '[': + $v = array(); + $off++; // jump the [ + while (1) { + $value = $this->parse($buffer, $len, $off); + if ($value === null) + break; + $v[] = $value; + } + $off++; // jump the ] + return array(self::TYPE_ARRAY, $v); + break; + case '>': // dictionnary : end + case ']': // array : end + return null; + break; + case '%': // comments : jump + $p = strpos($buffer, "\n", $off); + if ($p !== false) { + $off = $p + 1; + return $this->parse($buffer, $len, $off); + } + + break; + default: + if (preg_match('`^\s*([0-9]+) 0 R`', substr($buffer, $off, 32), $m)) { + $off += strlen($m[0]); + return array(self::TYPE_REFERENCE, $m[1]); + } else { + $p = strcspn($buffer, " %[]<>()\r\n\t/", $off + 1); + $v = substr($buffer, $off, $p + 1); + $off += $p + 1; + if (is_numeric($v)) { + $type = self::TYPE_NUMERIC; + } else if (($v === 'true') || ($v === 'false')) { + $type = self::TYPE_BOOL; + } else if ($v === 'null') { + $type = self::TYPE_NULL; + } else { + $type = self::TYPE_TOKEN; + } + return array($type, $v); + } + break; + } + return null; + } + + private function getObject($f, $xref, $index, $includeSubObject = false) { + + $type = self::TYPE_TOKEN; + + if (!isset($xref[$index])) { + $this->error('reference d\'object inconnue'); + } + + fseek($f, $xref[$index]); + + $data = ''; + $len = 0; + $offset = 0; + $expLen = 1024; + do { + $prev = $len; + $data .= fread($f, $expLen); + $len = strlen($data); + $p = strpos($data, "endobj", $offset); + if ($p !== false) { + if ($data[$p - 1] !== "\n") { + $offset = $p + 6; + $p = false; + } else { + if ($len < $p + 8) { + $data .= fread($f, 1); + $len = strlen($data); + } + if ($data[$p + 6] !== "\n") { + $offset = $p + 6; // not the endobj markup, maybe a string content + $p = false; + } + } + } + $expLen *= 2; + } while (($p === false) && ($prev !== $len)); + + if ($p === false) { + $this->error('object [' . $index . '] non trouve'); + } + + $p--; + $data = substr($data, 0, $p); + + if (!preg_match('`^([0-9]+ 0 obj)`', $data, $m, PREG_OFFSET_CAPTURE)) { + $this->error('object [' . $index . '] invalide'); + } + + $p = $m[0][1] + strlen($m[1][0]) + 1; + $data = substr($data, $p); + + if (substr($data, 0, 2) === '<<') { + $type = self::TYPE_DICTIONARY; + $off = 0; + $len = strlen($data); + $dictionary = $this->parse($data, $len, $off); + $off++; + $data = substr($data, $off); + if ($data === false) { + $data = ''; + } else if (substr($data, 0, 7) === "stream\n") { + $data = substr($data, 7, strlen($data) - 17); + $type = self::TYPE_STREAM; + } + if ($includeSubObject) { + $dictionary = $this->_resolveValues($f, $xref, $dictionary); + } + } else { + $dictionary = null; + } + return array($type, $dictionary, $data); + } + + private function _resolveValues($f, $xref, $item) { + switch ($item[0]) { + case self::TYPE_REFERENCE: + $object = $this->getObject($f, $xref, $item[1], true); + if ($object[0] === self::TYPE_TOKEN) { + return array(self::TYPE_TOKEN, $object[2]); + } + $ref = $this->storeObject($object); + return array(self::TYPE_REFERENCE_F, $this->_getObjectType($object), $ref); + break; + case self::TYPE_ARRAY: + case self::TYPE_DICTIONARY: + $r = array(); + foreach ($item[1] as $key => $val) { + if (($val[0] == self::TYPE_REFERENCE) || + ($val[0] == self::TYPE_ARRAY) || + ($val[0] == self::TYPE_DICTIONARY)) { + $r[$key] = $this->_resolveValues($f, $xref, $val); + } else { + $r[$key] = $val; + } + } + return array($item[0], $r); + break; + default: + return $item; + } + } + + private function getResources($f, $xref, $page) { + if ($page[0] !== self::TYPE_DICTIONARY) { + $this->error('getResources necessite un dictionaire'); + } + if (isset($page[1]['/Resources'])) { + if ($page[1]['/Resources'][0] === self::TYPE_REFERENCE) { + return $this->getObject($f, $xref, $page[1]['/Resources'][1]); + } else { + return array($page[1]['/Resources'][1]); + } + } else if (isset($page[1]['/Parent'])) { + return $this->getResources($f, $xref, $page[1]['/Parent']); + } + return null; + } + + private function getContent($f, $xref, $page) { + if ($page[0] !== self::TYPE_DICTIONARY) { + $this->error('getContent necessite un dictionaire'); + } + $stream = ''; + if (isset($page[1]['/Contents'])) { + $stream = $this->_getContent($f, $xref, $page[1]['/Contents']); + } + return $stream; + } + + private function _getContent($f, $xref, $content) { + $stream = ''; + if ($content[0] === self::TYPE_REFERENCE) { + $stream .= $this->getStream($f, $xref, $this->getObject($f, $xref, $content[1])); + } else if ($content[0] === self::TYPE_ARRAY) { + foreach ($content[1] as $sub) { + $stream .= $this->_getContent($f, $xref, $sub); + } + } else { + $stream .= $this->getStream($f, $xref, $item); + } + return $stream; + } + + private function getCompression($f, $xref, $item) { + if ($item[0] === self::TYPE_TOKEN) { + return array($item[1]); + } else if ($item[0] === self::TYPE_ARRAY) { + $r = array(); + foreach ($item[1] as $sub) { + $r = array_merge($r, $this->getCompression($f, $xref, $sub)); + } + return $r; + } else if ($item[0] === self::TYPE_REFERENCE) { + return $this->getCompression($f, $xref, $this->getObject($f, $xref, $item[1])); + } + return array(); + } + + private function getStream($f, $xref, $item) { + $methods = isset($item[1][1]['/Filter']) ? $this->getCompression($f, $xref, $item[1][1]['/Filter']) : array(); + + $raw = $item[2]; + foreach ($methods as $method) { + switch ($method) { + case '/FlateDecode': + if (function_exists('gzuncompress')) { + $raw = !empty($raw) ? @gzuncompress($raw) : ''; + } else { + $this->error('gzuncompress necessaire pour decompresser ce stream'); + } + if ($raw === false) { + $this->error('erreur de decompression du stream'); + } + break; + default: + $this->error($method . ' necessaire pour decompresser ce stream'); + } + } + return $raw; + } + + private function storeObject($item, $type = false) { + $md5 = md5(serialize($item)); + if ($type === '/Font') { + $array = & $this->fonts; + $prefix = '/F'; + } else { + $array = & $this->objects; + $prefix = '/Obj'; + } + if (!isset($array[$md5])) { + $index = count($array) + 1; + $array[$md5] = array( + 'name' => $prefix . $index, + 'item' => $item, + 'type' => $type, + 'index' => $index + ); + } else if ($type) { + $array[$md5]['type'] = $type; + } + return $array[$md5][$type ? 'name' : 'index']; + } + + //================================================ + // FONCTIONS D'IMPRESSION + //================================================ + + private function _out($raw) { + $this->buffer .= $raw . "\n"; + } + + private function _strval($value) { + $value+=0; + if ($value) { + return strval($value); + } + return '0'; + } + + private function _toStream($item) { + switch ($item[0]) { + case self::TYPE_NULL : return 'null'; + case self::TYPE_TOKEN : return $item[1]; + case self::TYPE_REFERENCE : return $this->_strval($item[1]) . ' 0 R'; + case self::TYPE_REFERENCE_F : + if (!isset($this->ref[$item[1]][$item[2]])) { + $this->error('reference vers un object non sauve'); + } + return $this->_strval($this->ref[$item[1]][$item[2]]) . ' 0 R'; + + case self::TYPE_NUMERIC : return $this->_strval($item[1]); + case self::TYPE_HEX : return '<' . strval($item[1]) . '>'; + case self::TYPE_BOOL : return $item[1] ? 'true' : 'false'; + case self::TYPE_STRING : return '(' . str_replace(array('\\', '(', ')'), array('\\\\', '\\(', '\\)'), strval($item[1])) . ')'; + case self::TYPE_ARRAY : + $r = array(); + foreach ($item[1] as $val) { + $r[] = $this->_toStream($val); + } + return '[' . implode(' ', $r) . ']'; + case self::TYPE_DICTIONARY : + $r = array(); + foreach ($item[1] as $key => $val) { + $val = $this->_toStream($val); + $r[] = $key . ' ' . $val; + } + return '<<' . implode("\n", $r) . '>>'; + break; + } + return ''; + } + + private function _newobj($n = null) { + if (($n === null) || ($n === true)) { + $this->n++; + $id = $this->n; + } else { + $id = $n; + } + if ($n !== true) { + $this->xref[$id] = strlen($this->buffer); + $this->_out($id . ' 0 obj'); + } + return $id; + } + + private function _addObj($dico = null, $buf = null) { + $ref = $this->_newobj(); + $buf = empty($buf) && ($buf !== 0) && ($buf !== '0') ? null : $buf; + if (is_array($dico)) { + if ($buf !== null) { + if ($this->compress && !isset($dico['/Filter'])) { + $buf = gzcompress($buf); + $dico['/Filter'] = array(self::TYPE_TOKEN, '/FlateDecode'); + } + $dico['/Length'] = array(self::TYPE_NUMERIC, strlen($buf)); + } + $this->_out($this->_toStream(array(self::TYPE_DICTIONARY, $dico))); + } + if ($buf !== null) { + $this->_out('stream'); + $this->_out($buf); + $this->_out('endstream'); + } + $this->_out('endobj'); + return $ref; + } + + private function _getObjectType($object) { + return isset($object['type']) && !empty($object['type']) ? $object['type'] : 'default'; + } + + private function _putObject($object) { + $type = $this->_getObjectType($object); + if (!isset($this->ref[$type])) { + $this->ref[$type] = array(); + } + $this->ref[$type][$object['index']] = $this->_addObj($object['item'][1][1], $object['item'][2]); + } + + private function _putObjects() { + foreach ($this->objects as $object) { + if ($object['type']) + continue; + $this->_putObject($object); + } + foreach ($this->objects as $object) { + if (!$object['type']) + continue; + $this->_putObject($object); + } + foreach ($this->fonts as $object) { + $this->_putObject($object); + } + } + + private function _putResources() { + $dico = array( + '/ProcSet' => array( + self::TYPE_ARRAY, + array( + array(self::TYPE_TOKEN, '/PDF'), + array(self::TYPE_TOKEN, '/Text'), + array(self::TYPE_TOKEN, '/ImageB'), + array(self::TYPE_TOKEN, '/ImageC'), + array(self::TYPE_TOKEN, '/ImageI') + ) + ) + ); + + $xObjects = array(); + foreach ($this->objects as $index => $object) { + if ($object['type'] === false) { + continue; + } + $value = array( + self::TYPE_TOKEN, + $this->_toStream(array(self::TYPE_REFERENCE, $this->ref[$object['type']][$object['index']])) + ); + if ($object['type'] === '/XObject') { + $xObjects[$object['name']] = $value; + } + } + if (!empty($xObjects)) { + $dico['/XObject'] = array(self::TYPE_DICTIONARY, $xObjects); + } + + $fonts = array(); + foreach ($this->fonts as $index => $object) { + $value = array( + self::TYPE_TOKEN, + $this->_toStream(array(self::TYPE_REFERENCE, $this->ref['/Font'][$object['index']])) + ); + $fonts[$object['name']] = $value; + } + if (!empty($fonts)) { + $dico['/Font'] = array(self::TYPE_DICTIONARY, $fonts); + } + return $this->_addObj($dico); + } + + /* * ************************************************ + /* PUBLIC + /************************************************* */ + + public function add($filename) { + $f = @fopen($filename, 'rb'); + if (!$f) { + $this->error('impossible d\'ouvrir le fichier'); + } + fseek($f, 0, SEEK_END); + $fileLength = ftell($f); + + // Localisation de xref + //------------------------------------------------- + + fseek($f, -128, SEEK_END); + $data = fread($f, 128); + if ($data === false) { + return $this->error('erreur de lecture dans le fichier'); + } + $p = strripos($data, 'startxref'); + if ($p === false) { + return $this->error('startxref absent'); + } + $startxref = substr($data, $p + 10, strlen($data) - $p - 17); + $posStartxref = $fileLength - 128 + $p; + + // extraction de xref + trailer + //------------------------------------------------- + + fseek($f, $startxref); + $data = fread($f, $posStartxref - $startxref); + + // extraction du trailer + //------------------------------------------------- + $p = stripos($data, 'trailer'); + if ($p === false) { + return $this->error('trailer absent'); + } + $dataTrailer = substr($data, $p + 8); + $len = strlen($dataTrailer); + $off = 0; + $trailer = $this->parse($dataTrailer, $len, $off); + + // extraction du xref + //------------------------------------------------- + + $data = explode("\n", trim(substr($data, 0, $p))); + array_shift($data); // "xref" + + $cnt = 0; + $xref = array(); + + foreach ($data as $line) { + if (!$cnt) { + if (preg_match('`^([0-9]+) ([0-9]+)$`', $line, $m)) { + $index = intval($m[1]) - 1; + $cnt = intval($m[2]); + } else { + $this->error('erreur dans xref'); + } + } else { + $index++; + $cnt--; + if (preg_match('`^([0-9]{10}) [0-9]{5} ([n|f])`', $line, $m)) { + if ($m[2] === 'f') { + continue; + } + $xref[$index] = $m[1]; + } else { + $this->error('erreur dans xref : ' . $line); + } + } + } + + // Lecture des pages + //------------------------------------------------- + + $root = $this->getObject($f, $xref, $trailer[1]['/Root'][1]); + $root = $root[1][1]; + + $pages = $this->getObject($f, $xref, $root['/Pages'][1]); + $pages = $pages[1][1]; + + foreach ($pages['/Kids'][1] as $kid) { + $kid = $this->getObject($f, $xref, $kid[1]); + $kid = $kid[1]; + + $resources = $this->getResources($f, $xref, $kid); + $resources = $resources[1][1]; + + $content = $this->getContent($f, $xref, $kid); + + // traitement des fonts + //------------------------------------------------- + $newFonts = array(); + if (isset($resources['/Font']) && !empty($resources['/Font'])) { + if (preg_match_all("`(/F[0-9]+)\s+-?[0-9\.]+\s+Tf`", $content, $matches, PREG_OFFSET_CAPTURE)) { + $newContent = ''; + $offset = 0; + $cnt = count($matches[0]); + for ($i = 0; $i < $cnt; $i++) { + $position = $matches[0][$i][1]; + $name = $matches[1][$i][0]; + if (!isset($newFonts[$name])) { + $object = $this->getObject($f, $xref, $resources['/Font'][1][$name][1], true); + $newFonts[$name] = $this->storeObject($object, '/Font'); + } + if ($newFonts[$name] !== $name) { + $newContent .= substr($content, $offset, $position - $offset); + $newContent .= $newFonts[$name]; + $offset = $position + strlen($name); + } + } + $content = $newContent . substr($content, $offset); + } + } + + // traitement des XObjets + //------------------------------------------------- + $newXObjects = array(); + if (isset($resources['/XObject']) && !empty($resources['/XObject'])) { + if (preg_match_all("`(/[^%\[\]<>\(\)\r\n\t/]+) Do`", $content, $matches, PREG_OFFSET_CAPTURE)) { + $newContent = ''; + $offset = 0; + foreach ($matches[1] as $m) { + $name = $m[0]; + $position = $m[1]; + if (!isset($newXObjects[$name])) { + $object = $this->getObject($f, $xref, $resources['/XObject'][1][$name][1], true); + $newXObjects[$name] = $this->storeObject($object, '/XObject'); + } + if ($newXObjects[$name] !== $name) { + $newContent .= substr($content, $offset, $position - $offset); + $newContent .= $newXObjects[$name]; + $offset = $position + strlen($name); + } + } + $content = $newContent . substr($content, $offset); + } + } + + $mediaBox = isset($kid[1]['/MediaBox']) ? $kid[1]['/MediaBox'] : (isset($pages['/MediaBox']) ? $pages['/MediaBox'] : null); + + if ($mediaBox[0] !== self::TYPE_ARRAY) { + $this->error('MediaBox non definie'); + } + + + $this->pages[] = array( + 'content' => $content, + '/XObject' => array_values($newXObjects), + '/Font' => array_values($newFonts), + '/MediaBox' => $mediaBox + ); + } + fclose($f); + } + + public function output($filename = null) { + $this->_out('%PDF-1.6'); + + $this->_putObjects(); + + $rsRef = $this->_putResources(); + + $ptRef = $this->_newobj(true); + + $kids = array(); + + // Ajout des pages + $n = count($this->pages); + for ($i = 0; $i < $n; $i++) { + $ctRef = $this->_addObj(array(), $this->pages[$i]['content']); + $dico = array( + '/Type' => array(self::TYPE_TOKEN, '/Page'), + '/Parent' => array(self::TYPE_REFERENCE, $ptRef), + '/MediaBox' => $this->pages[$i]['/MediaBox'], + '/Resources' => array(self::TYPE_REFERENCE, $rsRef), + '/Contents' => array(self::TYPE_REFERENCE, $ctRef), + ); + $kids[] = array(self::TYPE_REFERENCE, $this->_addObj($dico)); + } + + // Ajout du page tree + $ptDico = array( + self::TYPE_DICTIONARY, + array( + '/Type' => array(self::TYPE_TOKEN, '/Pages'), + '/Kids' => array(self::TYPE_ARRAY, $kids), + '/Count' => array(self::TYPE_NUMERIC, count($kids)) + ) + ); + + $this->_newobj($ptRef); + $this->_out($this->_toStream($ptDico)); + $this->_out('endobj'); + + // Ajout du catalogue + $ctDico = array( + self::TYPE_DICTIONARY, + array( + '/Type' => array(self::TYPE_TOKEN, '/Calalog'), + '/Pages' => array(self::TYPE_REFERENCE, $ptRef) + ) + ); + $ctRef = $this->_newobj(); + $this->_out($this->_toStream($ctDico)); + $this->_out('endobj'); + + // Ajout du xref + $xrefOffset = strlen($this->buffer); + $count = count($this->xref); + $this->_out('xref'); + $this->_out('0 ' . ($count + 1)); + $this->_out('0000000000 65535 f '); + for ($i = 0; $i < $count; $i++) { + $this->_out(sprintf('%010d 00000 n ', $this->xref[$i + 1])); + } + + // Ajout du trailer + $dico = array( + '/Size' => array(self::TYPE_NUMERIC, 1 + count($this->xref)), + '/Root' => array(self::TYPE_REFERENCE, $ctRef) + ); + $this->_out('trailer'); + $this->_out($this->_toStream(array(self::TYPE_DICTIONARY, $dico))); + + + // Ajout du startxref + $this->_out('startxref'); + $this->_out($xrefOffset); + $this->_out('%%EOF'); + + if ($filename === null) { + header('Content-Type: application/pdf'); + header('Content-Length: ' . strlen($this->buffer)); + header('Cache-Control: private, max-age=0, must-revalidate'); + header('Pragma: public'); + ini_set('zlib.output_compression', '0'); + + echo $this->buffer; + die; + } else { + file_put_contents($filename, $this->buffer); + } + } + +} + +?> \ No newline at end of file diff --git a/pdf.php b/pdf.php deleted file mode 100644 index c465aca..0000000 --- a/pdf.php +++ /dev/null @@ -1,13 +0,0 @@ -Open(); -$pdf->AddPage(); -$pdf->SetFont('Arial','B',16); -$pdf->Cell(40,10,utf8_decode('¡Hola, Mundo!'),1,1); -$pdf->Cell(60,10,utf8_decode('Conserjería'),1,1); -$pdf->Cell(80,10,'Conserjería',1,1); -$pdf->Close(); -$pdf->Output(); -?> \ No newline at end of file diff --git a/timerbar.js b/timerbar.js old mode 100644 new mode 100755 diff --git a/tmp/inventarioArticulo.xml b/tmp/inventarioArticulo.xml deleted file mode 100644 index 3cc8a39..0000000 --- a/tmp/inventarioArticulo.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - select A.id as id,U.Descripcion as ubicacion,E.fechaCompra as fechaCompra, - E.numSerie as numserie,E.Cantidad as cantidad - from Elementos E, Articulos A, Ubicaciones U where A.id=E.id_Articulo and U.id=E.id_Ubicacion - and A.id='700' order by U.Descripcion,numserie; - - - - M. E. C. - Dotación Inicial - - - - - - - - diff --git a/tmp/inventarioUbicacion.xml b/tmp/inventarioUbicacion.xml deleted file mode 100644 index e856064..0000000 --- a/tmp/inventarioUbicacion.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - select A.id as id,A.Marca as marca,A.Modelo as modelo,E.fechaCompra as fechaCompra, - E.numSerie as numserie,A.Descripcion as descripcion,E.Cantidad as cantidad - from Elementos E, Articulos A, Ubicaciones U where A.id=E.id_Articulo and U.id=E.id_Ubicacion - and U.id='144' order by A.descripcion; - - - - Inventario de Ubicación - - - - - - - - - - \ No newline at end of file