fpdf.php

gehe zur Dokumentation dieser Datei
00001 <?php
00002 /*******************************************************************************
00003  * FPDF                                                                         *
00004  *                                                                              *
00005  * Version: 1.6                                                                 *
00006  * Date:    2008-08-03                                                          *
00007  * Author:  Olivier PLATHEY                                                     *
00008  *******************************************************************************/
00009 
00010 define('FPDF_VERSION','1.6');
00011 
00012 class FPDF
00013 {
00014      var $page;               //current page numberstrem
00015      var $n;                  //current object number
00016      var $offsets;            //array of object offsets
00017      var $buffer;             //buffer holding in-memory PDF
00018      var $pages;              //array containing pages
00019      var $state;              //current document state
00020      var $compress;           //compression flag
00021      var $k;                  //scale factor (number of points in user unit)
00022      var $DefOrientation;     //default orientation
00023      var $CurOrientation;     //current orientation
00024      var $PageFormats;        //available page formats
00025      var $DefPageFormat;      //default page format
00026      var $CurPageFormat;      //current page format
00027      var $PageSizes;          //array storing non-default page sizes
00028      var $wPt,$hPt;           //dimensions of current page in points
00029      var $w,$h;               //dimensions of current page in user unit
00030      var $lMargin;            //left margin
00031      var $tMargin;            //top margin
00032      var $rMargin;            //right margin
00033      var $bMargin;            //page break margin
00034      var $cMargin;            //cell margin
00035      var $x,$y;               //current position in user unit
00036      var $lasth;              //height of last printed cell
00037      var $LineWidth;          //line width in user unit
00038      var $CoreFonts;          //array of standard font names
00039      var $fonts;              //array of used fonts
00040      var $FontFiles;          //array of font files
00041      var $diffs;              //array of encoding differences
00042      var $FontFamily;         //current font family
00043      var $FontStyle;          //current font style
00044      var $underline;          //underlining flag
00045      var $CurrentFont;        //current font info
00046      var $FontSizePt;         //current font size in points
00047      var $FontSize;           //current font size in user unit
00048      var $DrawColor;          //commands for drawing color
00049      var $FillColor;          //commands for filling color
00050      var $TextColor;          //commands for text color
00051      var $ColorFlag;          //indicates whether fill and text colors are different
00052      var $ws;                 //word spacing
00053      var $images;             //array of used images
00054      var $PageLinks;          //array of links in pages
00055      var $links;              //array of internal links
00056      var $AutoPageBreak;      //automatic page breaking
00057      var $PageBreakTrigger;   //threshold used to trigger page breaks
00058      var $InHeader;           //flag set when processing header
00059      var $InFooter;           //flag set when processing footer
00060      var $ZoomMode;           //zoom display mode
00061      var $LayoutMode;         //layout display mode
00062      var $title;              //title
00063      var $subject;            //subject
00064      var $author;             //author
00065      var $keywords;           //keywords
00066      var $creator;            //creator
00067      var $AliasNbPages;       //alias for total number of pages
00068      var $PDFVersion;         //PDF version number
00069 
00070      /*******************************************************************************
00071       *                                                                              *
00072       *                               Public methods                                 *
00073       *                                                                              *
00074       *******************************************************************************/
00075      function FPDF($orientation='P', $unit='mm', $format='A4')
00076      {
00077           //Some checks
00078           $this->_dochecks();
00079           //Initialization of properties
00080           $this->page=0;
00081           $this->n=2;
00082           $this->buffer='';
00083           $this->pages=array();
00084           $this->PageSizes=array();
00085           $this->state=0;
00086           $this->fonts=array();
00087           $this->FontFiles=array();
00088           $this->diffs=array();
00089           $this->images=array();
00090           $this->links=array();
00091           $this->InHeader=false;
00092           $this->InFooter=false;
00093           $this->lasth=0;
00094           $this->FontFamily='';
00095           $this->FontStyle='';
00096           $this->FontSizePt=12;
00097           $this->underline=false;
00098           $this->DrawColor='0 G';
00099           $this->FillColor='0 g';
00100           $this->TextColor='0 g';
00101           $this->ColorFlag=false;
00102           $this->ws=0;
00103           //Standard fonts
00104           $this->CoreFonts=array('courier'=>'Courier', 'courierB'=>'Courier-Bold', 'courierI'=>'Courier-Oblique', 'courierBI'=>'Courier-BoldOblique',
00105           'helvetica'=>'Helvetica', 'helveticaB'=>'Helvetica-Bold', 'helveticaI'=>'Helvetica-Oblique', 'helveticaBI'=>'Helvetica-BoldOblique',
00106           'times'=>'Times-Roman', 'timesB'=>'Times-Bold', 'timesI'=>'Times-Italic', 'timesBI'=>'Times-BoldItalic',
00107           'symbol'=>'Symbol', 'zapfdingbats'=>'ZapfDingbats');
00108           //Scale factor
00109           if($unit=='pt')
00110           $this->k=1;
00111           elseif($unit=='mm')
00112           $this->k=72/25.4;
00113           elseif($unit=='cm')
00114           $this->k=72/2.54;
00115           elseif($unit=='in')
00116           $this->k=72;
00117           else
00118           $this->Error('Incorrect unit: '.$unit);
00119           //Page format
00120           $this->PageFormats=array('a3'=>array(841.89,1190.55), 'a4'=>array(595.28,841.89), 'a5'=>array(420.94,595.28),
00121           'letter'=>array(612,792), 'legal'=>array(612,1008));
00122           if(is_string($format))
00123           $format=$this->_getpageformat($format);
00124           $this->DefPageFormat=$format;
00125           $this->CurPageFormat=$format;
00126           //Page orientation
00127           $orientation=strtolower($orientation);
00128           if($orientation=='p' || $orientation=='portrait')
00129           {
00130                $this->DefOrientation='P';
00131                $this->w=$this->DefPageFormat[0];
00132                $this->h=$this->DefPageFormat[1];
00133           }
00134           elseif($orientation=='l' || $orientation=='landscape')
00135           {
00136                $this->DefOrientation='L';
00137                $this->w=$this->DefPageFormat[1];
00138                $this->h=$this->DefPageFormat[0];
00139           }
00140           else
00141           $this->Error('Incorrect orientation: '.$orientation);
00142           $this->CurOrientation=$this->DefOrientation;
00143           $this->wPt=$this->w*$this->k;
00144           $this->hPt=$this->h*$this->k;
00145           //Page margins (1 cm)
00146           $margin=28.35/$this->k;
00147           $this->SetMargins($margin,$margin);
00148           //Interior cell margin (1 mm)
00149           $this->cMargin=$margin/10;
00150           //Line width (0.2 mm)
00151           $this->LineWidth=.567/$this->k;
00152           //Automatic page break
00153           $this->SetAutoPageBreak(true,2*$margin);
00154           //Full width display mode
00155           $this->SetDisplayMode('fullwidth');
00156           //Enable compression
00157           $this->SetCompression(true);
00158           //Set default PDF version number
00159           $this->PDFVersion='1.3';
00160      }
00161 
00162      function SetMargins($left, $top, $right=null)
00163      {
00164           //Set left, top and right margins
00165           $this->lMargin=$left;
00166           $this->tMargin=$top;
00167           if($right===null)
00168           $right=$left;
00169           $this->rMargin=$right;
00170      }
00171 
00172      function SetLeftMargin($margin)
00173      {
00174           //Set left margin
00175           $this->lMargin=$margin;
00176           if($this->page>0 && $this->x<$margin)
00177           $this->x=$margin;
00178      }
00179 
00180      function SetTopMargin($margin)
00181      {
00182           //Set top margin
00183           $this->tMargin=$margin;
00184      }
00185 
00186      function SetRightMargin($margin)
00187      {
00188           //Set right margin
00189           $this->rMargin=$margin;
00190      }
00191 
00192      function SetAutoPageBreak($auto, $margin=0)
00193      {
00194           //Set auto page break mode and triggering margin
00195           $this->AutoPageBreak=$auto;
00196           $this->bMargin=$margin;
00197           $this->PageBreakTrigger=$this->h-$margin;
00198      }
00199 
00200      function SetDisplayMode($zoom, $layout='continuous')
00201      {
00202           //Set display mode in viewer
00203           if($zoom=='fullpage' || $zoom=='fullwidth' || $zoom=='real' || $zoom=='default' || !is_string($zoom))
00204           $this->ZoomMode=$zoom;
00205           else
00206           $this->Error('Incorrect zoom display mode: '.$zoom);
00207           if($layout=='single' || $layout=='continuous' || $layout=='two' || $layout=='default')
00208           $this->LayoutMode=$layout;
00209           else
00210           $this->Error('Incorrect layout display mode: '.$layout);
00211      }
00212 
00213      function SetCompression($compress)
00214      {
00215           //Set page compression
00216           if(function_exists('gzcompress'))
00217           $this->compress=$compress;
00218           else
00219           $this->compress=false;
00220      }
00221 
00222      function SetTitle($title, $isUTF8=false)
00223      {
00224           //Title of document
00225           if($isUTF8)
00226           $title=$this->_UTF8toUTF16($title);
00227           $this->title=$title;
00228      }
00229 
00230      function SetSubject($subject, $isUTF8=false)
00231      {
00232           //Subject of document
00233           if($isUTF8)
00234           $subject=$this->_UTF8toUTF16($subject);
00235           $this->subject=$subject;
00236      }
00237 
00238      function SetAuthor($author, $isUTF8=false)
00239      {
00240           //Author of document
00241           if($isUTF8)
00242           $author=$this->_UTF8toUTF16($author);
00243           $this->author=$author;
00244      }
00245 
00246      function SetKeywords($keywords, $isUTF8=false)
00247      {
00248           //Keywords of document
00249           if($isUTF8)
00250           $keywords=$this->_UTF8toUTF16($keywords);
00251           $this->keywords=$keywords;
00252      }
00253 
00254      function SetCreator($creator, $isUTF8=false)
00255      {
00256           //Creator of document
00257           if($isUTF8)
00258           $creator=$this->_UTF8toUTF16($creator);
00259           $this->creator=$creator;
00260      }
00261 
00262      function AliasNbPages($alias='{nb}')
00263      {
00264           //Define an alias for total number of pages
00265           $this->AliasNbPages=$alias;
00266      }
00267 
00268      function Error($msg)
00269      {
00270           //Fatal error
00271           die('<b>FPDF error:</b> '.$msg);
00272      }
00273 
00274      function Open()
00275      {
00276           //Begin document
00277           $this->state=1;
00278      }
00279 
00280      function Close()
00281      {
00282           //Terminate document
00283           if($this->state==3)
00284           return;
00285           if($this->page==0)
00286           $this->AddPage();
00287           //Page footer
00288           $this->InFooter=true;
00289           $this->Footer();
00290           $this->InFooter=false;
00291           //Close page
00292           $this->_endpage();
00293           //Close document
00294           $this->_enddoc();
00295      }
00296 
00297      function AddPage($orientation='', $format='')
00298      {
00299           //Start a new page
00300           if($this->state==0)
00301           $this->Open();
00302           $family=$this->FontFamily;
00303           $style=$this->FontStyle.($this->underline ? 'U' : '');
00304           $size=$this->FontSizePt;
00305           $lw=$this->LineWidth;
00306           $dc=$this->DrawColor;
00307           $fc=$this->FillColor;
00308           $tc=$this->TextColor;
00309           $cf=$this->ColorFlag;
00310           if($this->page>0)
00311           {
00312                //Page footer
00313                $this->InFooter=true;
00314                $this->Footer();
00315                $this->InFooter=false;
00316                //Close page
00317                $this->_endpage();
00318           }
00319           //Start new page
00320           $this->_beginpage($orientation,$format);
00321           //Set line cap style to square
00322           $this->_out('2 J');
00323           //Set line width
00324           $this->LineWidth=$lw;
00325           $this->_out(sprintf('%.2F w',$lw*$this->k));
00326           //Set font
00327           if($family)
00328           $this->SetFont($family,$style,$size);
00329           //Set colors
00330           $this->DrawColor=$dc;
00331           if($dc!='0 G')
00332           $this->_out($dc);
00333           $this->FillColor=$fc;
00334           if($fc!='0 g')
00335           $this->_out($fc);
00336           $this->TextColor=$tc;
00337           $this->ColorFlag=$cf;
00338           //Page header
00339           $this->InHeader=true;
00340           $this->Header();
00341           $this->InHeader=false;
00342           //Restore line width
00343           if($this->LineWidth!=$lw)
00344           {
00345                $this->LineWidth=$lw;
00346                $this->_out(sprintf('%.2F w',$lw*$this->k));
00347           }
00348           //Restore font
00349           if($family)
00350           $this->SetFont($family,$style,$size);
00351           //Restore colors
00352           if($this->DrawColor!=$dc)
00353           {
00354                $this->DrawColor=$dc;
00355                $this->_out($dc);
00356           }
00357           if($this->FillColor!=$fc)
00358           {
00359                $this->FillColor=$fc;
00360                $this->_out($fc);
00361           }
00362           $this->TextColor=$tc;
00363           $this->ColorFlag=$cf;
00364      }
00365 
00366      function Header()
00367      {
00368           //To be implemented in your own inherited class
00369      }
00370 
00371      function Footer()
00372      {
00373           //To be implemented in your own inherited class
00374      }
00375 
00376      function PageNo()
00377      {
00378           //Get current page number
00379           return $this->page;
00380      }
00381 
00382      function SetDrawColor($r, $g=null, $b=null)
00383      {
00384           //Set color for all stroking operations
00385           if(($r==0 && $g==0 && $b==0) || $g===null)
00386           $this->DrawColor=sprintf('%.3F G',$r/255);
00387           else
00388           $this->DrawColor=sprintf('%.3F %.3F %.3F RG',$r/255,$g/255,$b/255);
00389           if($this->page>0)
00390           $this->_out($this->DrawColor);
00391      }
00392 
00393      function SetFillColor($r, $g=null, $b=null)
00394      {
00395           //Set color for all filling operations
00396           if(($r==0 && $g==0 && $b==0) || $g===null)
00397           $this->FillColor=sprintf('%.3F g',$r/255);
00398           else
00399           $this->FillColor=sprintf('%.3F %.3F %.3F rg',$r/255,$g/255,$b/255);
00400           $this->ColorFlag=($this->FillColor!=$this->TextColor);
00401           if($this->page>0)
00402           $this->_out($this->FillColor);
00403      }
00404 
00405      function SetTextColor($r, $g=null, $b=null)
00406      {
00407           //Set color for text
00408           if(($r==0 && $g==0 && $b==0) || $g===null)
00409           $this->TextColor=sprintf('%.3F g',$r/255);
00410           else
00411           $this->TextColor=sprintf('%.3F %.3F %.3F rg',$r/255,$g/255,$b/255);
00412           $this->ColorFlag=($this->FillColor!=$this->TextColor);
00413      }
00414 
00415      function GetStringWidth($s)
00416      {
00417           //Get width of a string in the current font
00418           $s=(string)$s;
00419           $cw=&$this->CurrentFont['cw'];
00420           $w=0;
00421           $l=strlen($s);
00422           for($i=0;$i<$l;$i++)
00423           $w+=$cw[$s[$i]];
00424           return $w*$this->FontSize/1000;
00425      }
00426 
00427      function SetLineWidth($width)
00428      {
00429           //Set line width
00430           $this->LineWidth=$width;
00431           if($this->page>0)
00432           $this->_out(sprintf('%.2F w',$width*$this->k));
00433      }
00434 
00435      function Line($x1, $y1, $x2, $y2)
00436      {
00437           //Draw a line
00438           $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));
00439      }
00440 
00441      function Rect($x, $y, $w, $h, $style='')
00442      {
00443           //Draw a rectangle
00444           if($style=='F')
00445           $op='f';
00446           elseif($style=='FD' || $style=='DF')
00447           $op='B';
00448           else
00449           $op='S';
00450           $this->_out(sprintf('%.2F %.2F %.2F %.2F re %s',$x*$this->k,($this->h-$y)*$this->k,$w*$this->k,-$h*$this->k,$op));
00451      }
00452 
00453      function AddFont($family, $style='', $file='')
00454      {
00455           //Add a TrueType or Type1 font
00456           $family=strtolower($family);
00457           if($file=='')
00458           $file=str_replace(' ','',$family).strtolower($style).'.php';
00459           if($family=='arial')
00460           $family='helvetica';
00461           $style=strtoupper($style);
00462           if($style=='IB')
00463           $style='BI';
00464           $fontkey=$family.$style;
00465           if(isset($this->fonts[$fontkey]))
00466           return;
00467           include($this->_getfontpath().$file);
00468           if(!isset($name))
00469           $this->Error('Could not include font definition file');
00470           $i=count($this->fonts)+1;
00471           $this->fonts[$fontkey]=array('i'=>$i, 'type'=>$type, 'name'=>$name, 'desc'=>$desc, 'up'=>$up, 'ut'=>$ut, 'cw'=>$cw, 'enc'=>$enc, 'file'=>$file);
00472           if($diff)
00473           {
00474                //Search existing encodings
00475                $d=0;
00476                $nb=count($this->diffs);
00477                for($i=1;$i<=$nb;$i++)
00478                {
00479                     if($this->diffs[$i]==$diff)
00480                     {
00481                          $d=$i;
00482                          break;
00483                     }
00484                }
00485                if($d==0)
00486                {
00487                     $d=$nb+1;
00488                     $this->diffs[$d]=$diff;
00489                }
00490                $this->fonts[$fontkey]['diff']=$d;
00491           }
00492           if($file)
00493           {
00494                if($type=='TrueType')
00495                $this->FontFiles[$file]=array('length1'=>$originalsize);
00496                else
00497                $this->FontFiles[$file]=array('length1'=>$size1, 'length2'=>$size2);
00498           }
00499      }
00500 
00501      function SetFont($family, $style='', $size=0)
00502      {
00503           //Select a font; size given in points
00504           global $fpdf_charwidths;
00505 
00506           $family=strtolower($family);
00507           if($family=='')
00508           $family=$this->FontFamily;
00509           if($family=='arial')
00510           $family='helvetica';
00511           elseif($family=='symbol' || $family=='zapfdingbats')
00512           $style='';
00513           $style=strtoupper($style);
00514           if(strpos($style,'U')!==false)
00515           {
00516                $this->underline=true;
00517                $style=str_replace('U','',$style);
00518           }
00519           else
00520           $this->underline=false;
00521           if($style=='IB')
00522           $style='BI';
00523           if($size==0)
00524           $size=$this->FontSizePt;
00525           //Test if font is already selected
00526           if($this->FontFamily==$family && $this->FontStyle==$style && $this->FontSizePt==$size)
00527           return;
00528           //Test if used for the first time
00529           $fontkey=$family.$style;
00530           if(!isset($this->fonts[$fontkey]))
00531           {
00532                //Check if one of the standard fonts
00533                if(isset($this->CoreFonts[$fontkey]))
00534                {
00535                     if(!isset($fpdf_charwidths[$fontkey]))
00536                     {
00537                          //Load metric file
00538                          $file=$family;
00539                          if($family=='times' || $family=='helvetica')
00540                          $file.=strtolower($style);
00541                          include($this->_getfontpath().$file.'.php');
00542                          if(!isset($fpdf_charwidths[$fontkey]))
00543                          $this->Error('Could not include font metric file');
00544                     }
00545                     $i=count($this->fonts)+1;
00546                     $name=$this->CoreFonts[$fontkey];
00547                     $cw=$fpdf_charwidths[$fontkey];
00548                     $this->fonts[$fontkey]=array('i'=>$i, 'type'=>'core', 'name'=>$name, 'up'=>-100, 'ut'=>50, 'cw'=>$cw);
00549                }
00550                else
00551                $this->Error('Undefined font: '.$family.' '.$style);
00552           }
00553           //Select it
00554           $this->FontFamily=$family;
00555           $this->FontStyle=$style;
00556           $this->FontSizePt=$size;
00557           $this->FontSize=$size/$this->k;
00558           $this->CurrentFont=&$this->fonts[$fontkey];
00559           if($this->page>0)
00560           $this->_out(sprintf('BT /F%d %.2F Tf ET',$this->CurrentFont['i'],$this->FontSizePt));
00561      }
00562 
00563      function SetFontSize($size)
00564      {
00565           //Set font size in points
00566           if($this->FontSizePt==$size)
00567           return;
00568           $this->FontSizePt=$size;
00569           $this->FontSize=$size/$this->k;
00570           if($this->page>0)
00571           $this->_out(sprintf('BT /F%d %.2F Tf ET',$this->CurrentFont['i'],$this->FontSizePt));
00572      }
00573 
00574      function AddLink()
00575      {
00576           //Create a new internal link
00577           $n=count($this->links)+1;
00578           $this->links[$n]=array(0, 0);
00579           return $n;
00580      }
00581 
00582      function SetLink($link, $y=0, $page=-1)
00583      {
00584           //Set destination of internal link
00585           if($y==-1)
00586           $y=$this->y;
00587           if($page==-1)
00588           $page=$this->page;
00589           $this->links[$link]=array($page, $y);
00590      }
00591 
00592      function Link($x, $y, $w, $h, $link)
00593      {
00594           //Put a link on the page
00595           $this->PageLinks[$this->page][]=array($x*$this->k, $this->hPt-$y*$this->k, $w*$this->k, $h*$this->k, $link);
00596      }
00597 
00598      function Text($x, $y, $txt)
00599      {
00600           //Output a string
00601           $s=sprintf('BT %.2F %.2F Td (%s) Tj ET',$x*$this->k,($this->h-$y)*$this->k,$this->_escape($txt));
00602           if($this->underline && $txt!='')
00603           $s.=' '.$this->_dounderline($x,$y,$txt);
00604           if($this->ColorFlag)
00605           $s='q '.$this->TextColor.' '.$s.' Q';
00606           $this->_out($s);
00607      }
00608 
00609      function AcceptPageBreak()
00610      {
00611           //Accept automatic page break or not
00612           return $this->AutoPageBreak;
00613      }
00614 
00615      function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='')
00616      {
00617           //Output a cell
00618           $k=$this->k;
00619           if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak())
00620           {
00621                //Automatic page break
00622                $x=$this->x;
00623                $ws=$this->ws;
00624                if($ws>0)
00625                {
00626                     $this->ws=0;
00627                     $this->_out('0 Tw');
00628                }
00629                $this->AddPage($this->CurOrientation,$this->CurPageFormat);
00630                $this->x=$x;
00631                if($ws>0)
00632                {
00633                     $this->ws=$ws;
00634                     $this->_out(sprintf('%.3F Tw',$ws*$k));
00635                }
00636           }
00637           if($w==0)
00638           $w=$this->w-$this->rMargin-$this->x;
00639           $s='';
00640           if($fill || $border==1)
00641           {
00642                if($fill)
00643                $op=($border==1) ? 'B' : 'f';
00644                else
00645                $op='S';
00646                $s=sprintf('%.2F %.2F %.2F %.2F re %s ',$this->x*$k,($this->h-$this->y)*$k,$w*$k,-$h*$k,$op);
00647           }
00648           if(is_string($border))
00649           {
00650                $x=$this->x;
00651                $y=$this->y;
00652                if(strpos($border,'L')!==false)
00653                $s.=sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-$y)*$k,$x*$k,($this->h-($y+$h))*$k);
00654                if(strpos($border,'T')!==false)
00655                $s.=sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-$y)*$k);
00656                if(strpos($border,'R')!==false)
00657                $s.=sprintf('%.2F %.2F m %.2F %.2F l S ',($x+$w)*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
00658                if(strpos($border,'B')!==false)
00659                $s.=sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-($y+$h))*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
00660           }
00661           if($txt!=='')
00662           {
00663                if($align=='R')
00664                $dx=$w-$this->cMargin-$this->GetStringWidth($txt);
00665                elseif($align=='C')
00666                $dx=($w-$this->GetStringWidth($txt))/2;
00667                else
00668                $dx=$this->cMargin;
00669                if($this->ColorFlag)
00670                $s.='q '.$this->TextColor.' ';
00671                $txt2=str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$txt)));
00672                $s.=sprintf('BT %.2F %.2F Td (%s) Tj ET',($this->x+$dx)*$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,$txt2);
00673                if($this->underline)
00674                $s.=' '.$this->_dounderline($this->x+$dx,$this->y+.5*$h+.3*$this->FontSize,$txt);
00675                if($this->ColorFlag)
00676                $s.=' Q';
00677                if($link)
00678                $this->Link($this->x+$dx,$this->y+.5*$h-.5*$this->FontSize,$this->GetStringWidth($txt),$this->FontSize,$link);
00679           }
00680           if($s)
00681           $this->_out($s);
00682           $this->lasth=$h;
00683           if($ln>0)
00684           {
00685                //Go to next line
00686                $this->y+=$h;
00687                if($ln==1)
00688                $this->x=$this->lMargin;
00689           }
00690           else
00691           $this->x+=$w;
00692      }
00693 
00694      function MultiCell($w, $h, $txt, $border=0, $align='J', $fill=false)
00695      {
00696           //Output text with automatic or explicit line breaks
00697           $cw=&$this->CurrentFont['cw'];
00698           if($w==0)
00699           $w=$this->w-$this->rMargin-$this->x;
00700           $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
00701           $s=str_replace("\r",'',$txt);
00702           $nb=strlen($s);
00703           if($nb>0 && $s[$nb-1]=="\n")
00704           $nb--;
00705           $b=0;
00706           if($border)
00707           {
00708                if($border==1)
00709                {
00710                     $border='LTRB';
00711                     $b='LRT';
00712                     $b2='LR';
00713                }
00714                else
00715                {
00716                     $b2='';
00717                     if(strpos($border,'L')!==false)
00718                     $b2.='L';
00719                     if(strpos($border,'R')!==false)
00720                     $b2.='R';
00721                     $b=(strpos($border,'T')!==false) ? $b2.'T' : $b2;
00722                }
00723           }
00724           $sep=-1;
00725           $i=0;
00726           $j=0;
00727           $l=0;
00728           $ns=0;
00729           $nl=1;
00730           while($i<$nb)
00731           {
00732                //Get next character
00733                $c=$s[$i];
00734                if($c=="\n")
00735                {
00736                     //Explicit line break
00737                     if($this->ws>0)
00738                     {
00739                          $this->ws=0;
00740                          $this->_out('0 Tw');
00741                     }
00742                     $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
00743                     $i++;
00744                     $sep=-1;
00745                     $j=$i;
00746                     $l=0;
00747                     $ns=0;
00748                     $nl++;
00749                     if($border && $nl==2)
00750                     $b=$b2;
00751                     continue;
00752                }
00753                if($c==' ')
00754                {
00755                     $sep=$i;
00756                     $ls=$l;
00757                     $ns++;
00758                }
00759                $l+=$cw[$c];
00760                if($l>$wmax)
00761                {
00762                     //Automatic line break
00763                     if($sep==-1)
00764                     {
00765                          if($i==$j)
00766                          $i++;
00767                          if($this->ws>0)
00768                          {
00769                               $this->ws=0;
00770                               $this->_out('0 Tw');
00771                          }
00772                          $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
00773                     }
00774                     else
00775                     {
00776                          if($align=='J')
00777                          {
00778                               $this->ws=($ns>1) ? ($wmax-$ls)/1000*$this->FontSize/($ns-1) : 0;
00779                               $this->_out(sprintf('%.3F Tw',$this->ws*$this->k));
00780                          }
00781                          $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill);
00782                          $i=$sep+1;
00783                     }
00784                     $sep=-1;
00785                     $j=$i;
00786                     $l=0;
00787                     $ns=0;
00788                     $nl++;
00789                     if($border && $nl==2)
00790                     $b=$b2;
00791                }
00792                else
00793                $i++;
00794           }
00795           //Last chunk
00796           if($this->ws>0)
00797           {
00798                $this->ws=0;
00799                $this->_out('0 Tw');
00800           }
00801           if($border && strpos($border,'B')!==false)
00802           $b.='B';
00803           $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
00804           $this->x=$this->lMargin;
00805      }
00806 
00807      function Write($h, $txt, $link='')
00808      {
00809           //Output text in flowing mode
00810           $cw=&$this->CurrentFont['cw'];
00811           $w=$this->w-$this->rMargin-$this->x;
00812           $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
00813           $s=str_replace("\r",'',$txt);
00814           $nb=strlen($s);
00815           $sep=-1;
00816           $i=0;
00817           $j=0;
00818           $l=0;
00819           $nl=1;
00820           while($i<$nb)
00821           {
00822                //Get next character
00823                $c=$s[$i];
00824                if($c=="\n")
00825                {
00826                     //Explicit line break
00827                     $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
00828                     $i++;
00829                     $sep=-1;
00830                     $j=$i;
00831                     $l=0;
00832                     if($nl==1)
00833                     {
00834                          $this->x=$this->lMargin;
00835                          $w=$this->w-$this->rMargin-$this->x;
00836                          $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
00837                     }
00838                     $nl++;
00839                     continue;
00840                }
00841                if($c==' ')
00842                $sep=$i;
00843                $l+=$cw[$c];
00844                if($l>$wmax)
00845                {
00846                     //Automatic line break
00847                     if($sep==-1)
00848                     {
00849                          if($this->x>$this->lMargin)
00850                          {
00851                               //Move to next line
00852                               $this->x=$this->lMargin;
00853                               $this->y+=$h;
00854                               $w=$this->w-$this->rMargin-$this->x;
00855                               $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
00856                               $i++;
00857                               $nl++;
00858                               continue;
00859                          }
00860                          if($i==$j)
00861                          $i++;
00862                          $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
00863                     }
00864                     else
00865                     {
00866                          $this->Cell($w,$h,substr($s,$j,$sep-$j),0,2,'',0,$link);
00867                          $i=$sep+1;
00868                     }
00869                     $sep=-1;
00870                     $j=$i;
00871                     $l=0;
00872                     if($nl==1)
00873                     {
00874                          $this->x=$this->lMargin;
00875                          $w=$this->w-$this->rMargin-$this->x;
00876                          $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
00877                     }
00878                     $nl++;
00879                }
00880                else
00881                $i++;
00882           }
00883           //Last chunk
00884           if($i!=$j)
00885           $this->Cell($l/1000*$this->FontSize,$h,substr($s,$j),0,0,'',0,$link);
00886      }
00887 
00888      function Ln($h=null)
00889      {
00890           //Line feed; default value is last cell height
00891           $this->x=$this->lMargin;
00892           if($h===null)
00893           $this->y+=$this->lasth;
00894           else
00895           $this->y+=$h;
00896      }
00897 
00898      function Image($file, $x=null, $y=null, $w=0, $h=0, $type='', $link='')
00899      {
00900           //Put an image on the page
00901           if(!isset($this->images[$file]))
00902           {
00903                //First use of this image, get info
00904                if($type=='')
00905                {
00906                     $pos=strrpos($file,'.');
00907                     if(!$pos)
00908                     $this->Error('Image file has no extension and no type was specified: '.$file);
00909                     $type=substr($file,$pos+1);
00910                }
00911                $type=strtolower($type);
00912                if($type=='jpeg')
00913                $type='jpg';
00914                $mtd='_parse'.$type;
00915                if(!method_exists($this,$mtd))
00916                $this->Error('Unsupported image type: '.$type);
00917                $info=$this->$mtd($file);
00918                $info['i']=count($this->images)+1;
00919                $this->images[$file]=$info;
00920           }
00921           else
00922           $info=$this->images[$file];
00923           //Automatic width and height calculation if needed
00924           if($w==0 && $h==0)
00925           {
00926                //Put image at 72 dpi
00927                $w=$info['w']/$this->k;
00928                $h=$info['h']/$this->k;
00929           }
00930           elseif($w==0)
00931           $w=$h*$info['w']/$info['h'];
00932           elseif($h==0)
00933           $h=$w*$info['h']/$info['w'];
00934           //Flowing mode
00935           if($y===null)
00936           {
00937                if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak())
00938                {
00939                     //Automatic page break
00940                     $x2=$this->x;
00941                     $this->AddPage($this->CurOrientation,$this->CurPageFormat);
00942                     $this->x=$x2;
00943                }
00944                $y=$this->y;
00945                $this->y+=$h;
00946           }
00947           if($x===null)
00948           $x=$this->x;
00949           $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']));
00950           if($link)
00951           $this->Link($x,$y,$w,$h,$link);
00952      }
00953 
00954      function GetX()
00955      {
00956           //Get x position
00957           return $this->x;
00958      }
00959 
00960      function SetX($x)
00961      {
00962           //Set x position
00963           if($x>=0)
00964           $this->x=$x;
00965           else
00966           $this->x=$this->w+$x;
00967      }
00968 
00969      function GetY()
00970      {
00971           //Get y position
00972           return $this->y;
00973      }
00974 
00975      function SetY($y)
00976      {
00977           //Set y position and reset x
00978           $this->x=$this->lMargin;
00979           if($y>=0)
00980           $this->y=$y;
00981           else
00982           $this->y=$this->h+$y;
00983      }
00984 
00985      function SetXY($x, $y)
00986      {
00987           //Set x and y positions
00988           $this->SetY($y);
00989           $this->SetX($x);
00990      }
00991 
00992      function Output($name='', $dest='')
00993      {
00994           //Output PDF to some destination
00995           if($this->state<3)
00996           $this->Close();
00997           $dest=strtoupper($dest);
00998           if($dest=='')
00999           {
01000                if($name=='')
01001                {
01002                     $name='doc.pdf';
01003                     $dest='I';
01004                }
01005                else
01006                $dest='F';
01007           }
01008           switch($dest)
01009           {
01010                case 'I':
01011                     //Send to standard output
01012                     if(ob_get_length())
01013                     $this->Error('Some data has already been output, can\'t send PDF file');
01014                     if(php_sapi_name()!='cli')
01015                     {
01016                          //We send to a browser
01017                          header('Content-Type: application/pdf');
01018                          if(headers_sent())
01019                          $this->Error('Some data has already been output, can\'t send PDF file');
01020                          header('Content-Length: '.strlen($this->buffer));
01021                          header('Content-Disposition: inline; filename="'.$name.'"');
01022                          header('Cache-Control: private, max-age=0, must-revalidate');
01023                          header('Pragma: public');
01024                          ini_set('zlib.output_compression','0');
01025                     }
01026                     echo $this->buffer;
01027                     break;
01028                case 'D':
01029                     //Download file
01030                     if(ob_get_length())
01031                     $this->Error('Some data has already been output, can\'t send PDF file');
01032                     header('Content-Type: application/x-download');
01033                     if(headers_sent())
01034                     $this->Error('Some data has already been output, can\'t send PDF file');
01035                     header('Content-Length: '.strlen($this->buffer));
01036                     header('Content-Disposition: attachment; filename="'.$name.'"');
01037                     header('Cache-Control: private, max-age=0, must-revalidate');
01038                     header('Pragma: public');
01039                     ini_set('zlib.output_compression','0');
01040                     echo $this->buffer;
01041                     break;
01042                case 'F':
01043                     //Save to local file
01044                     $f=fopen($name,'wb');
01045                     if(!$f)
01046                     $this->Error('Unable to create output file: '.$name);
01047                     fwrite($f,$this->buffer,strlen($this->buffer));
01048                     fclose($f);
01049                     break;
01050                case 'S':
01051                     //Return as a string
01052                     return $this->buffer;
01053                default:
01054                     $this->Error('Incorrect output destination: '.$dest);
01055           }
01056           return '';
01057      }
01058 
01059      /*******************************************************************************
01060       *                                                                              *
01061       *                              Protected methods                               *
01062       *                                                                              *
01063       *******************************************************************************/
01064      function _dochecks()
01065      {
01066           //Check availability of %F
01067           if(sprintf('%.1F',1.0)!='1.0')
01068           $this->Error('This version of PHP is not supported');
01069           //Check mbstring overloading
01070           if(ini_get('mbstring.func_overload') & 2)
01071           $this->Error('mbstring overloading must be disabled');
01072           //Disable runtime magic quotes
01073           if(get_magic_quotes_runtime())
01074           @set_magic_quotes_runtime(0);
01075      }
01076 
01077      function _getpageformat($format)
01078      {
01079           $format=strtolower($format);
01080           if(!isset($this->PageFormats[$format]))
01081           $this->Error('Unknown page format: '.$format);
01082           $a=$this->PageFormats[$format];
01083           return array($a[0]/$this->k, $a[1]/$this->k);
01084      }
01085 
01086      function _getfontpath()
01087      {
01088           if(!defined('FPDF_FONTPATH') && is_dir(dirname(__FILE__).'/font'))
01089           define('FPDF_FONTPATH',dirname(__FILE__).'/font/');
01090           return defined('FPDF_FONTPATH') ? FPDF_FONTPATH : '';
01091      }
01092 
01093      function _beginpage($orientation, $format)
01094      {
01095           $this->page++;
01096           $this->pages[$this->page]='';
01097           $this->state=2;
01098           $this->x=$this->lMargin;
01099           $this->y=$this->tMargin;
01100           $this->FontFamily='';
01101           //Check page size
01102           if($orientation=='')
01103           $orientation=$this->DefOrientation;
01104           else
01105           $orientation=strtoupper($orientation[0]);
01106           if($format=='')
01107           $format=$this->DefPageFormat;
01108           else
01109           {
01110                if(is_string($format))
01111                $format=$this->_getpageformat($format);
01112           }
01113           if($orientation!=$this->CurOrientation || $format[0]!=$this->CurPageFormat[0] || $format[1]!=$this->CurPageFormat[1])
01114           {
01115                //New size
01116                if($orientation=='P')
01117                {
01118                     $this->w=$format[0];
01119                     $this->h=$format[1];
01120                }
01121                else
01122                {
01123                     $this->w=$format[1];
01124                     $this->h=$format[0];
01125                }
01126                $this->wPt=$this->w*$this->k;
01127                $this->hPt=$this->h*$this->k;
01128                $this->PageBreakTrigger=$this->h-$this->bMargin;
01129                $this->CurOrientation=$orientation;
01130                $this->CurPageFormat=$format;
01131           }
01132           if($orientation!=$this->DefOrientation || $format[0]!=$this->DefPageFormat[0] || $format[1]!=$this->DefPageFormat[1])
01133           $this->PageSizes[$this->page]=array($this->wPt, $this->hPt);
01134      }
01135 
01136      function _endpage()
01137      {
01138           $this->state=1;
01139      }
01140 
01141      function _escape($s)
01142      {
01143           //Escape special characters in strings
01144           $s=str_replace('\\','\\\\',$s);
01145           $s=str_replace('(','\\(',$s);
01146           $s=str_replace(')','\\)',$s);
01147           $s=str_replace("\r",'\\r',$s);
01148           return $s;
01149      }
01150 
01151      function _textstring($s)
01152      {
01153           //Format a text string
01154           return '('.$this->_escape($s).')';
01155      }
01156 
01157      function _UTF8toUTF16($s)
01158      {
01159           //Convert UTF-8 to UTF-16BE with BOM
01160           $res="\xFE\xFF";
01161           $nb=strlen($s);
01162           $i=0;
01163           while($i<$nb)
01164           {
01165                $c1=ord($s[$i++]);
01166                if($c1>=224)
01167                {
01168                     //3-byte character
01169                     $c2=ord($s[$i++]);
01170                     $c3=ord($s[$i++]);
01171                     $res.=chr((($c1 & 0x0F)<<4) + (($c2 & 0x3C)>>2));
01172                     $res.=chr((($c2 & 0x03)<<6) + ($c3 & 0x3F));
01173                }
01174                elseif($c1>=192)
01175                {
01176                     //2-byte character
01177                     $c2=ord($s[$i++]);
01178                     $res.=chr(($c1 & 0x1C)>>2);
01179                     $res.=chr((($c1 & 0x03)<<6) + ($c2 & 0x3F));
01180                }
01181                else
01182                {
01183                     //Single-byte character
01184                     $res.="\0".chr($c1);
01185                }
01186           }
01187           return $res;
01188      }
01189 
01190      function _dounderline($x, $y, $txt)
01191      {
01192           //Underline text
01193           $up=$this->CurrentFont['up'];
01194           $ut=$this->CurrentFont['ut'];
01195           $w=$this->GetStringWidth($txt)+$this->ws*substr_count($txt,' ');
01196           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);
01197      }
01198 
01199      function _parsejpg($file)
01200      {
01201           //Extract info from a JPEG file
01202           $a=GetImageSize($file);
01203           if(!$a)
01204           $this->Error('Missing or incorrect image file: '.$file);
01205           if($a[2]!=2)
01206           $this->Error('Not a JPEG file: '.$file);
01207           if(!isset($a['channels']) || $a['channels']==3)
01208           $colspace='DeviceRGB';
01209           elseif($a['channels']==4)
01210           $colspace='DeviceCMYK';
01211           else
01212           $colspace='DeviceGray';
01213           $bpc=isset($a['bits']) ? $a['bits'] : 8;
01214           //Read whole file
01215           $f=fopen($file,'rb');
01216           $data='';
01217           while(!feof($f))
01218           $data.=fread($f,8192);
01219           fclose($f);
01220           return array('w'=>$a[0], 'h'=>$a[1], 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'DCTDecode', 'data'=>$data);
01221      }
01222 
01223      function _parsepng($file)
01224      {
01225           //Extract info from a PNG file
01226           $f=fopen($file,'rb');
01227           if(!$f)
01228           $this->Error('Can\'t open image file: '.$file);
01229           //Check signature
01230           if($this->_readstream($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10))
01231           $this->Error('Not a PNG file: '.$file);
01232           //Read header chunk
01233           $this->_readstream($f,4);
01234           if($this->_readstream($f,4)!='IHDR')
01235           $this->Error('Incorrect PNG file: '.$file);
01236           $w=$this->_readint($f);
01237           $h=$this->_readint($f);
01238           $bpc=ord($this->_readstream($f,1));
01239           if($bpc>8)
01240           $this->Error('16-bit depth not supported: '.$file);
01241           $ct=ord($this->_readstream($f,1));
01242           if($ct==0)
01243           $colspace='DeviceGray';
01244           elseif($ct==2)
01245           $colspace='DeviceRGB';
01246           elseif($ct==3)
01247           $colspace='Indexed';
01248           else
01249           $this->Error('Alpha channel not supported: '.$file);
01250           if(ord($this->_readstream($f,1))!=0)
01251           $this->Error('Unknown compression method: '.$file);
01252           if(ord($this->_readstream($f,1))!=0)
01253           $this->Error('Unknown filter method: '.$file);
01254           if(ord($this->_readstream($f,1))!=0)
01255           $this->Error('Interlacing not supported: '.$file);
01256           $this->_readstream($f,4);
01257           $parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
01258           //Scan chunks looking for palette, transparency and image data
01259           $pal='';
01260           $trns='';
01261           $data='';
01262           do
01263           {
01264                $n=$this->_readint($f);
01265                $type=$this->_readstream($f,4);
01266                if($type=='PLTE')
01267                {
01268                     //Read palette
01269                     $pal=$this->_readstream($f,$n);
01270                     $this->_readstream($f,4);
01271                }
01272                elseif($type=='tRNS')
01273                {
01274                     //Read transparency info
01275                     $t=$this->_readstream($f,$n);
01276                     if($ct==0)
01277                     $trns=array(ord(substr($t,1,1)));
01278                     elseif($ct==2)
01279                     $trns=array(ord(substr($t,1,1)), ord(substr($t,3,1)), ord(substr($t,5,1)));
01280                     else
01281                     {
01282                          $pos=strpos($t,chr(0));
01283                          if($pos!==false)
01284                          $trns=array($pos);
01285                     }
01286                     $this->_readstream($f,4);
01287                }
01288                elseif($type=='IDAT')
01289                {
01290                     //Read image data block
01291                     $data.=$this->_readstream($f,$n);
01292                     $this->_readstream($f,4);
01293                }
01294                elseif($type=='IEND')
01295                break;
01296                else
01297                $this->_readstream($f,$n+4);
01298           }
01299           while($n);
01300           if($colspace=='Indexed' && empty($pal))
01301           $this->Error('Missing palette in '.$file);
01302           fclose($f);
01303           return array('w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'FlateDecode', 'parms'=>$parms, 'pal'=>$pal, 'trns'=>$trns, 'data'=>$data);
01304      }
01305 
01306      function _readstream($f, $n)
01307      {
01308           //Read n bytes from stream
01309           $res='';
01310           while($n>0 && !feof($f))
01311           {
01312                $s=fread($f,$n);
01313                if($s===false)
01314                $this->Error('Error while reading stream');
01315                $n-=strlen($s);
01316                $res.=$s;
01317           }
01318           if($n>0)
01319           $this->Error('Unexpected end of stream');
01320           return $res;
01321      }
01322 
01323      function _readint($f)
01324      {
01325           //Read a 4-byte integer from stream
01326           $a=unpack('Ni',$this->_readstream($f,4));
01327           return $a['i'];
01328      }
01329 
01330      function _parsegif($file)
01331      {
01332           //Extract info from a GIF file (via PNG conversion)
01333           if(!function_exists('imagepng'))
01334           $this->Error('GD extension is required for GIF support');
01335           if(!function_exists('imagecreatefromgif'))
01336           $this->Error('GD has no GIF read support');
01337           $im=imagecreatefromgif($file);
01338           if(!$im)
01339           $this->Error('Missing or incorrect image file: '.$file);
01340           imageinterlace($im,0);
01341           $tmp=tempnam('.','gif');
01342           if(!$tmp)
01343           $this->Error('Unable to create a temporary file');
01344           if(!imagepng($im,$tmp))
01345           $this->Error('Error while saving to temporary file');
01346           imagedestroy($im);
01347           $info=$this->_parsepng($tmp);
01348           unlink($tmp);
01349           return $info;
01350      }
01351 
01352      function _newobj()
01353      {
01354           //Begin a new object
01355           $this->n++;
01356           $this->offsets[$this->n]=strlen($this->buffer);
01357           $this->_out($this->n.' 0 obj');
01358      }
01359 
01360      function _putstream($s)
01361      {
01362           $this->_out('stream');
01363           $this->_out($s);
01364           $this->_out('endstream');
01365      }
01366 
01367      function _out($s)
01368      {
01369           //Add a line to the document
01370           if($this->state==2)
01371           $this->pages[$this->page].=$s."\n";
01372           else
01373           $this->buffer.=$s."\n";
01374      }
01375 
01376      function _putpages()
01377      {
01378           $nb=$this->page;
01379           if(!empty($this->AliasNbPages))
01380           {
01381                //Replace number of pages
01382                for($n=1;$n<=$nb;$n++)
01383                $this->pages[$n]=str_replace($this->AliasNbPages,$nb,$this->pages[$n]);
01384           }
01385           if($this->DefOrientation=='P')
01386           {
01387                $wPt=$this->DefPageFormat[0]*$this->k;
01388                $hPt=$this->DefPageFormat[1]*$this->k;
01389           }
01390           else
01391           {
01392                $wPt=$this->DefPageFormat[1]*$this->k;
01393                $hPt=$this->DefPageFormat[0]*$this->k;
01394           }
01395           $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
01396           for($n=1;$n<=$nb;$n++)
01397           {
01398                //Page
01399                $this->_newobj();
01400                $this->_out('<</Type /Page');
01401                $this->_out('/Parent 1 0 R');
01402                if(isset($this->PageSizes[$n]))
01403                $this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]',$this->PageSizes[$n][0],$this->PageSizes[$n][1]));
01404                $this->_out('/Resources 2 0 R');
01405                if(isset($this->PageLinks[$n]))
01406                {
01407                     //Links
01408                     $annots='/Annots [';
01409                     foreach($this->PageLinks[$n] as $pl)
01410                     {
01411                          $rect=sprintf('%.2F %.2F %.2F %.2F',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]);
01412                          $annots.='<</Type /Annot /Subtype /Link /Rect ['.$rect.'] /Border [0 0 0] ';
01413                          if(is_string($pl[4]))
01414                          $annots.='/A <</S /URI /URI '.$this->_textstring($pl[4]).'>>>>';
01415                          else
01416                          {
01417                               $l=$this->links[$pl[4]];
01418                               $h=isset($this->PageSizes[$l[0]]) ? $this->PageSizes[$l[0]][1] : $hPt;
01419                               $annots.=sprintf('/Dest [%d 0 R /XYZ 0 %.2F null]>>',1+2*$l[0],$h-$l[1]*$this->k);
01420                          }
01421                     }
01422                     $this->_out($annots.']');
01423                }
01424                $this->_out('/Contents '.($this->n+1).' 0 R>>');
01425                $this->_out('endobj');
01426                //Page content
01427                $p=($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n];
01428                $this->_newobj();
01429                $this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
01430                $this->_putstream($p);
01431                $this->_out('endobj');
01432           }
01433           //Pages root
01434           $this->offsets[1]=strlen($this->buffer);
01435           $this->_out('1 0 obj');
01436           $this->_out('<</Type /Pages');
01437           $kids='/Kids [';
01438           for($i=0;$i<$nb;$i++)
01439           $kids.=(3+2*$i).' 0 R ';
01440           $this->_out($kids.']');
01441           $this->_out('/Count '.$nb);
01442           $this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]',$wPt,$hPt));
01443           $this->_out('>>');
01444           $this->_out('endobj');
01445      }
01446 
01447      function _putfonts()
01448      {
01449           $nf=$this->n;
01450           foreach($this->diffs as $diff)
01451           {
01452                //Encodings
01453                $this->_newobj();
01454                $this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.']>>');
01455                $this->_out('endobj');
01456           }
01457           foreach($this->FontFiles as $file=>$info)
01458           {
01459                //Font file embedding
01460                $this->_newobj();
01461                $this->FontFiles[$file]['n']=$this->n;
01462                $font='';
01463                $f=fopen($this->_getfontpath().$file,'rb',1);
01464                if(!$f)
01465                $this->Error('Font file not found');
01466                while(!feof($f))
01467                $font.=fread($f,8192);
01468                fclose($f);
01469                $compressed=(substr($file,-2)=='.z');
01470                if(!$compressed && isset($info['length2']))
01471                {
01472                     $header=(ord($font[0])==128);
01473                     if($header)
01474                     {
01475                          //Strip first binary header
01476                          $font=substr($font,6);
01477                     }
01478                     if($header && ord($font[$info['length1']])==128)
01479                     {
01480                          //Strip second binary header
01481                          $font=substr($font,0,$info['length1']).substr($font,$info['length1']+6);
01482                     }
01483                }
01484                $this->_out('<</Length '.strlen($font));
01485                if($compressed)
01486                $this->_out('/Filter /FlateDecode');
01487                $this->_out('/Length1 '.$info['length1']);
01488                if(isset($info['length2']))
01489                $this->_out('/Length2 '.$info['length2'].' /Length3 0');
01490                $this->_out('>>');
01491                $this->_putstream($font);
01492                $this->_out('endobj');
01493           }
01494           foreach($this->fonts as $k=>$font)
01495           {
01496                //Font objects
01497                $this->fonts[$k]['n']=$this->n+1;
01498                $type=$font['type'];
01499                $name=$font['name'];
01500                if($type=='core')
01501                {
01502                     //Standard font
01503                     $this->_newobj();
01504                     $this->_out('<</Type /Font');
01505                     $this->_out('/BaseFont /'.$name);
01506                     $this->_out('/Subtype /Type1');
01507                     if($name!='Symbol' && $name!='ZapfDingbats')
01508                     $this->_out('/Encoding /WinAnsiEncoding');
01509                     $this->_out('>>');
01510                     $this->_out('endobj');
01511                }
01512                elseif($type=='Type1' || $type=='TrueType')
01513                {
01514                     //Additional Type1 or TrueType font
01515                     $this->_newobj();
01516                     $this->_out('<</Type /Font');
01517                     $this->_out('/BaseFont /'.$name);
01518                     $this->_out('/Subtype /'.$type);
01519                     $this->_out('/FirstChar 32 /LastChar 255');
01520                     $this->_out('/Widths '.($this->n+1).' 0 R');
01521                     $this->_out('/FontDescriptor '.($this->n+2).' 0 R');
01522                     if($font['enc'])
01523                     {
01524                          if(isset($font['diff']))
01525                          $this->_out('/Encoding '.($nf+$font['diff']).' 0 R');
01526                          else
01527                          $this->_out('/Encoding /WinAnsiEncoding');
01528                     }
01529                     $this->_out('>>');
01530                     $this->_out('endobj');
01531                     //Widths
01532                     $this->_newobj();
01533                     $cw=&$font['cw'];
01534                     $s='[';
01535                     for($i=32;$i<=255;$i++)
01536                     $s.=$cw[chr($i)].' ';
01537                     $this->_out($s.']');
01538                     $this->_out('endobj');
01539                     //Descriptor
01540                     $this->_newobj();
01541                     $s='<</Type /FontDescriptor /FontName /'.$name;
01542                     foreach($font['desc'] as $k=>$v)
01543                     $s.=' /'.$k.' '.$v;
01544                     $file=$font['file'];
01545                     if($file)
01546                     $s.=' /FontFile'.($type=='Type1' ? '' : '2').' '.$this->FontFiles[$file]['n'].' 0 R';
01547                     $this->_out($s.'>>');
01548                     $this->_out('endobj');
01549                }
01550                else
01551                {
01552                     //Allow for additional types
01553                     $mtd='_put'.strtolower($type);
01554                     if(!method_exists($this,$mtd))
01555                     $this->Error('Unsupported font type: '.$type);
01556                     $this->$mtd($font);
01557                }
01558           }
01559      }
01560 
01561      function _putimages()
01562      {
01563           $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
01564           reset($this->images);
01565           while(list($file,$info)=each($this->images))
01566           {
01567                $this->_newobj();
01568                $this->images[$file]['n']=$this->n;
01569                $this->_out('<</Type /XObject');
01570                $this->_out('/Subtype /Image');
01571                $this->_out('/Width '.$info['w']);
01572                $this->_out('/Height '.$info['h']);
01573                if($info['cs']=='Indexed')
01574                $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]');
01575                else
01576                {
01577                     $this->_out('/ColorSpace /'.$info['cs']);
01578                     if($info['cs']=='DeviceCMYK')
01579                     $this->_out('/Decode [1 0 1 0 1 0 1 0]');
01580                }
01581                $this->_out('/BitsPerComponent '.$info['bpc']);
01582                if(isset($info['f']))
01583                $this->_out('/Filter /'.$info['f']);
01584                if(isset($info['parms']))
01585                $this->_out($info['parms']);
01586                if(isset($info['trns']) && is_array($info['trns']))
01587                {
01588                     $trns='';
01589                     for($i=0;$i<count($info['trns']);$i++)
01590                     $trns.=$info['trns'][$i].' '.$info['trns'][$i].' ';
01591                     $this->_out('/Mask ['.$trns.']');
01592                }
01593                $this->_out('/Length '.strlen($info['data']).'>>');
01594                $this->_putstream($info['data']);
01595                unset($this->images[$file]['data']);
01596                $this->_out('endobj');
01597                //Palette
01598                if($info['cs']=='Indexed')
01599                {
01600                     $this->_newobj();
01601                     $pal=($this->compress) ? gzcompress($info['pal']) : $info['pal'];
01602                     $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
01603                     $this->_putstream($pal);
01604                     $this->_out('endobj');
01605                }
01606           }
01607      }
01608 
01609      function _putxobjectdict()
01610      {
01611           foreach($this->images as $image)
01612           $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
01613      }
01614 
01615      function _putresourcedict()
01616      {
01617           $this->_out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
01618           $this->_out('/Font <<');
01619           foreach($this->fonts as $font)
01620           $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
01621           $this->_out('>>');
01622           $this->_out('/XObject <<');
01623           $this->_putxobjectdict();
01624           $this->_out('>>');
01625      }
01626 
01627      function _putresources()
01628      {
01629           $this->_putfonts();
01630           $this->_putimages();
01631           //Resource dictionary
01632           $this->offsets[2]=strlen($this->buffer);
01633           $this->_out('2 0 obj');
01634           $this->_out('<<');
01635           $this->_putresourcedict();
01636           $this->_out('>>');
01637           $this->_out('endobj');
01638      }
01639 
01640      function _putinfo()
01641      {
01642           $this->_out('/Producer '.$this->_textstring('FPDF '.FPDF_VERSION));
01643           if(!empty($this->title))
01644           $this->_out('/Title '.$this->_textstring($this->title));
01645           if(!empty($this->subject))
01646           $this->_out('/Subject '.$this->_textstring($this->subject));
01647           if(!empty($this->author))
01648           $this->_out('/Author '.$this->_textstring($this->author));
01649           if(!empty($this->keywords))
01650           $this->_out('/Keywords '.$this->_textstring($this->keywords));
01651           if(!empty($this->creator))
01652           $this->_out('/Creator '.$this->_textstring($this->creator));
01653           $this->_out('/CreationDate '.$this->_textstring('D:'.@date('YmdHis')));
01654      }
01655 
01656      function _putcatalog()
01657      {
01658           $this->_out('/Type /Catalog');
01659           $this->_out('/Pages 1 0 R');
01660           if($this->ZoomMode=='fullpage')
01661           $this->_out('/OpenAction [3 0 R /Fit]');
01662           elseif($this->ZoomMode=='fullwidth')
01663           $this->_out('/OpenAction [3 0 R /FitH null]');
01664           elseif($this->ZoomMode=='real')
01665           $this->_out('/OpenAction [3 0 R /XYZ null null 1]');
01666           elseif(!is_string($this->ZoomMode))
01667           $this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode/100).']');
01668           if($this->LayoutMode=='single')
01669           $this->_out('/PageLayout /SinglePage');
01670           elseif($this->LayoutMode=='continuous')
01671           $this->_out('/PageLayout /OneColumn');
01672           elseif($this->LayoutMode=='two')
01673           $this->_out('/PageLayout /TwoColumnLeft');
01674      }
01675 
01676      function _putheader()
01677      {
01678           $this->_out('%PDF-'.$this->PDFVersion);
01679      }
01680 
01681      function _puttrailer()
01682      {
01683           $this->_out('/Size '.($this->n+1));
01684           $this->_out('/Root '.$this->n.' 0 R');
01685           $this->_out('/Info '.($this->n-1).' 0 R');
01686      }
01687 
01688      function _enddoc()
01689      {
01690           $this->_putheader();
01691           $this->_putpages();
01692           $this->_putresources();
01693           //Info
01694           $this->_newobj();
01695           $this->_out('<<');
01696           $this->_putinfo();
01697           $this->_out('>>');
01698           $this->_out('endobj');
01699           //Catalog
01700           $this->_newobj();
01701           $this->_out('<<');
01702           $this->_putcatalog();
01703           $this->_out('>>');
01704           $this->_out('endobj');
01705           //Cross-ref
01706           $o=strlen($this->buffer);
01707           $this->_out('xref');
01708           $this->_out('0 '.($this->n+1));
01709           $this->_out('0000000000 65535 f ');
01710           for($i=1;$i<=$this->n;$i++)
01711           $this->_out(sprintf('%010d 00000 n ',$this->offsets[$i]));
01712           //Trailer
01713           $this->_out('trailer');
01714           $this->_out('<<');
01715           $this->_puttrailer();
01716           $this->_out('>>');
01717           $this->_out('startxref');
01718           $this->_out($o);
01719           $this->_out('%%EOF');
01720           $this->state=3;
01721      }
01722      //End of class
01723 }
01724 
01725 ?>

Erzeugt am Thu May 14 00:55:49 2009 für OpenRat von  doxygen 1.5.8