default
[ class tree: default ] [ index: default ] [ all elements ]

Source for file fpdf.php

Documentation is available at fpdf.php

  1. <?php
  2. /*******************************************************************************
  3. * Software: FPDF                                                               *
  4. * Version:  1.53                                                               *
  5. * Date:     2004-12-31                                                         *
  6. * Author:   Olivier PLATHEY                                                    *
  7. * License:  Freeware                                                           *
  8. *                                                                              *
  9. * You may use and modify this software as you wish.                            *
  10. *******************************************************************************/
  11.  
  12. if(!class_exists('FPDF'))
  13. {
  14. define('FPDF_VERSION','1.53');
  15.  
  16. class FPDF
  17. {
  18. //Private properties
  19. var $page;               //current page number
  20. var $n;                  //current object number
  21. var $offsets;            //array of object offsets
  22. var $buffer;             //buffer holding in-memory PDF
  23. var $pages;              //array containing pages
  24. var $state;              //current document state
  25. var $compress;           //compression flag
  26. var $DefOrientation;     //default orientation
  27. var $CurOrientation;     //current orientation
  28. var $OrientationChanges//array indicating orientation changes
  29. var $k;                  //scale factor (number of points in user unit)
  30. var $fwPt,$fhPt;         //dimensions of page format in points
  31. var $fw,$fh;             //dimensions of page format in user unit
  32. var $wPt,$hPt;           //current dimensions of page in points
  33. var $w,$h;               //current dimensions of page in user unit
  34. var $lMargin;            //left margin
  35. var $tMargin;            //top margin
  36. var $rMargin;            //right margin
  37. var $bMargin;            //page break margin
  38. var $cMargin;            //cell margin
  39. var $x,$y;               //current position in user unit for cell positioning
  40. var $lasth;              //height of last cell printed
  41. var $LineWidth;          //line width in user unit
  42. var $CoreFonts;          //array of standard font names
  43. var $fonts;              //array of used fonts
  44. var $FontFiles;          //array of font files
  45. var $diffs;              //array of encoding differences
  46. var $images;             //array of used images
  47. var $PageLinks;          //array of links in pages
  48. var $links;              //array of internal links
  49. var $FontFamily;         //current font family
  50. var $FontStyle;          //current font style
  51. var $underline;          //underlining flag
  52. var $CurrentFont;        //current font info
  53. var $FontSizePt;         //current font size in points
  54. var $FontSize;           //current font size in user unit
  55. var $DrawColor;          //commands for drawing color
  56. var $FillColor;          //commands for filling color
  57. var $TextColor;          //commands for text color
  58. var $ColorFlag;          //indicates whether fill and text colors are different
  59. var $ws;                 //word spacing
  60. var $AutoPageBreak;      //automatic page breaking
  61. var $PageBreakTrigger;   //threshold used to trigger page breaks
  62. var $InFooter;           //flag set when processing footer
  63. var $ZoomMode;           //zoom display mode
  64. var $LayoutMode;         //layout display mode
  65. var $title;              //title
  66. var $subject;            //subject
  67. var $author;             //author
  68. var $keywords;           //keywords
  69. var $creator;            //creator
  70. var $AliasNbPages;       //alias for total number of pages
  71. var $PDFVersion;         //PDF version number
  72.  
  73. /*******************************************************************************
  74. *                                                                              *
  75. *                               Public methods                                 *
  76. *                                                                              *
  77. *******************************************************************************/
  78. function FPDF($orientation='P',$unit='mm',$format='A4')
  79. {
  80.     //Some checks
  81.     $this->_dochecks();
  82.     //Initialization of properties
  83.     $this->page=0;
  84.     $this->n=2;
  85.     $this->buffer='';
  86.     $this->pages=array();
  87.     $this->OrientationChanges=array();
  88.     $this->state=0;
  89.     $this->fonts=array();
  90.     $this->FontFiles=array();
  91.     $this->diffs=array();
  92.     $this->images=array();
  93.     $this->links=array();
  94.     $this->InFooter=false;
  95.     $this->lasth=0;
  96.     $this->FontFamily='';
  97.     $this->FontStyle='';
  98.     $this->FontSizePt=12;
  99.     $this->underline=false;
  100.     $this->DrawColor='0 G';
  101.     $this->FillColor='0 g';
  102.     $this->TextColor='0 g';
  103.     $this->ColorFlag=false;
  104.     $this->ws=0;
  105.     //Standard fonts
  106.     $this->CoreFonts=array('courier'=>'Courier','courierB'=>'Courier-Bold','courierI'=>'Courier-Oblique','courierBI'=>'Courier-BoldOblique',
  107.         'helvetica'=>'Helvetica','helveticaB'=>'Helvetica-Bold','helveticaI'=>'Helvetica-Oblique','helveticaBI'=>'Helvetica-BoldOblique',
  108.         'times'=>'Times-Roman','timesB'=>'Times-Bold','timesI'=>'Times-Italic','timesBI'=>'Times-BoldItalic',
  109.         'symbol'=>'Symbol','zapfdingbats'=>'ZapfDingbats');
  110.     //Scale factor
  111.     if($unit=='pt')
  112.         $this->k=1;
  113.     elseif($unit=='mm')
  114.         $this->k=72/25.4;
  115.     elseif($unit=='cm')
  116.         $this->k=72/2.54;
  117.     elseif($unit=='in')
  118.         $this->k=72;
  119.     else
  120.         $this->Error('Incorrect unit: '.$unit);
  121.     //Page format
  122.     if(is_string($format))
  123.     {
  124.         $format=strtolower($format);
  125.         if($format=='a3')
  126.             $format=array(841.89,1190.55);
  127.         elseif($format=='a4')
  128.             $format=array(595.28,841.89);
  129.         elseif($format=='a5')
  130.             $format=array(420.94,595.28);
  131.         elseif($format=='letter')
  132.             $format=array(612,792);
  133.         elseif($format=='legal')
  134.             $format=array(612,1008);
  135.         else
  136.             $this->Error('Unknown page format: '.$format);
  137.         $this->fwPt=$format[0];
  138.         $this->fhPt=$format[1];
  139.     }
  140.     else
  141.     {
  142.         $this->fwPt=$format[0]*$this->k;
  143.         $this->fhPt=$format[1]*$this->k;
  144.     }
  145.     $this->fw=$this->fwPt/$this->k;
  146.     $this->fh=$this->fhPt/$this->k;
  147.     //Page orientation
  148.     $orientation=strtolower($orientation);
  149.     if($orientation=='p' || $orientation=='portrait')
  150.     {
  151.         $this->DefOrientation='P';
  152.         $this->wPt=$this->fwPt;
  153.         $this->hPt=$this->fhPt;
  154.     }
  155.     elseif($orientation=='l' || $orientation=='landscape')
  156.     {
  157.         $this->DefOrientation='L';
  158.         $this->wPt=$this->fhPt;
  159.         $this->hPt=$this->fwPt;
  160.     }
  161.     else
  162.         $this->Error('Incorrect orientation: '.$orientation);
  163.     $this->CurOrientation=$this->DefOrientation;
  164.     $this->w=$this->wPt/$this->k;
  165.     $this->h=$this->hPt/$this->k;
  166.     //Page margins (1 cm)
  167.     $margin=28.35/$this->k;
  168.     $this->SetMargins($margin,$margin);
  169.     //Interior cell margin (1 mm)
  170.     $this->cMargin=$margin/10;
  171.     //Line width (0.2 mm)
  172.     $this->LineWidth=.567/$this->k;
  173.     //Automatic page break
  174.     $this->SetAutoPageBreak(true,2*$margin);
  175.     //Full width display mode
  176.     $this->SetDisplayMode('fullwidth');
  177.     //Enable compression
  178.     $this->SetCompression(true);
  179.     //Set default PDF version number
  180.     $this->PDFVersion='1.3';
  181. }
  182.  
  183. function SetMargins($left,$top,$right=-1)
  184. {
  185.     //Set left, top and right margins
  186.     $this->lMargin=$left;
  187.     $this->tMargin=$top;
  188.     if($right==-1)
  189.         $right=$left;
  190.     $this->rMargin=$right;
  191. }
  192.  
  193. function SetLeftMargin($margin)
  194. {
  195.     //Set left margin
  196.     $this->lMargin=$margin;
  197.     if($this->page>&& $this->x<$margin)
  198.         $this->x=$margin;
  199. }
  200.  
  201. function SetTopMargin($margin)
  202. {
  203.     //Set top margin
  204.     $this->tMargin=$margin;
  205. }
  206.  
  207. function SetRightMargin($margin)
  208. {
  209.     //Set right margin
  210.     $this->rMargin=$margin;
  211. }
  212.  
  213. function SetAutoPageBreak($auto,$margin=0)
  214. {
  215.     //Set auto page break mode and triggering margin
  216.     $this->AutoPageBreak=$auto;
  217.     $this->bMargin=$margin;
  218.     $this->PageBreakTrigger=$this->h-$margin;
  219. }
  220.  
  221. function SetDisplayMode($zoom,$layout='continuous')
  222. {
  223.     //Set display mode in viewer
  224.     if($zoom=='fullpage' || $zoom=='fullwidth' || $zoom=='real' || $zoom=='default' || !is_string($zoom))
  225.         $this->ZoomMode=$zoom;
  226.     else
  227.         $this->Error('Incorrect zoom display mode: '.$zoom);
  228.     if($layout=='single' || $layout=='continuous' || $layout=='two' || $layout=='default')
  229.         $this->LayoutMode=$layout;
  230.     else
  231.         $this->Error('Incorrect layout display mode: '.$layout);
  232. }
  233.  
  234. function SetCompression($compress)
  235. {
  236.     //Set page compression
  237.     if(function_exists('gzcompress'))
  238.         $this->compress=$compress;
  239.     else
  240.         $this->compress=false;
  241. }
  242.  
  243. function SetTitle($title)
  244. {
  245.     //Title of document
  246.     $this->title=$title;
  247. }
  248.  
  249. function SetSubject($subject)
  250. {
  251.     //Subject of document
  252.     $this->subject=$subject;
  253. }
  254.  
  255. function SetAuthor($author)
  256. {
  257.     //Author of document
  258.     $this->author=$author;
  259. }
  260.  
  261. function SetKeywords($keywords)
  262. {
  263.     //Keywords of document
  264.     $this->keywords=$keywords;
  265. }
  266.  
  267. function SetCreator($creator)
  268. {
  269.     //Creator of document
  270.     $this->creator=$creator;
  271. }
  272.  
  273. function AliasNbPages($alias='{nb}')
  274. {
  275.     //Define an alias for total number of pages
  276.     $this->AliasNbPages=$alias;
  277. }
  278.  
  279. function Error($msg)
  280. {
  281.     // MODIFIED PHPEXCEL
  282.  
  283.     // Error
  284.     throw new Exception('FPDF error: ' $msg);
  285. }
  286.  
  287. function Open()
  288. {
  289.     //Begin document
  290.     $this->state=1;
  291. }
  292.  
  293. function Close()
  294. {
  295.     //Terminate document
  296.     if($this->state==3)
  297.         return;
  298.     if($this->page==0)
  299.         $this->AddPage();
  300.     //Page footer
  301.     $this->InFooter=true;
  302.     $this->Footer();
  303.     $this->InFooter=false;
  304.     //Close page
  305.     $this->_endpage();
  306.     //Close document
  307.     $this->_enddoc();
  308. }
  309.  
  310. function AddPage($orientation='')
  311. {
  312.     //Start a new page
  313.     if($this->state==0)
  314.         $this->Open();
  315.     $family=$this->FontFamily;
  316.     $style=$this->FontStyle.($this->underline ? 'U' '');
  317.     $size=$this->FontSizePt;
  318.     $lw=$this->LineWidth;
  319.     $dc=$this->DrawColor;
  320.     $fc=$this->FillColor;
  321.     $tc=$this->TextColor;
  322.     $cf=$this->ColorFlag;
  323.     if($this->page>0)
  324.     {
  325.         //Page footer
  326.         $this->InFooter=true;
  327.         $this->Footer();
  328.         $this->InFooter=false;
  329.         //Close page
  330.         $this->_endpage();
  331.     }
  332.     //Start new page
  333.     $this->_beginpage($orientation);
  334.     //Set line cap style to square
  335.     $this->_out('2 J');
  336.     //Set line width
  337.     $this->LineWidth=$lw;
  338.     $this->_out(sprintf('%.2f w',$lw*$this->k));
  339.     //Set font
  340.     if($family)
  341.         $this->SetFont($family,$style,$size);
  342.     //Set colors
  343.     $this->DrawColor=$dc;
  344.     if($dc!='0 G')
  345.         $this->_out($dc);
  346.     $this->FillColor=$fc;
  347.     if($fc!='0 g')
  348.         $this->_out($fc);
  349.     $this->TextColor=$tc;
  350.     $this->ColorFlag=$cf;
  351.     //Page header
  352.     $this->Header();
  353.     //Restore line width
  354.     if($this->LineWidth!=$lw)
  355.     {
  356.         $this->LineWidth=$lw;
  357.         $this->_out(sprintf('%.2f w',$lw*$this->k));
  358.     }
  359.     //Restore font
  360.     if($family)
  361.         $this->SetFont($family,$style,$size);
  362.     //Restore colors
  363.     if($this->DrawColor!=$dc)
  364.     {
  365.         $this->DrawColor=$dc;
  366.         $this->_out($dc);
  367.     }
  368.     if($this->FillColor!=$fc)
  369.     {
  370.         $this->FillColor=$fc;
  371.         $this->_out($fc);
  372.     }
  373.     $this->TextColor=$tc;
  374.     $this->ColorFlag=$cf;
  375. }
  376.  
  377. function Header()
  378. {
  379.     //To be implemented in your own inherited class
  380. }
  381.  
  382. function Footer()
  383. {
  384.     //To be implemented in your own inherited class
  385. }
  386.  
  387. function PageNo()
  388. {
  389.     //Get current page number
  390.     return $this->page;
  391. }
  392.  
  393. function SetDrawColor($r,$g=-1,$b=-1)
  394. {
  395.     //Set color for all stroking operations
  396.     if(($r==&& $g==&& $b==0|| $g==-1)
  397.         $this->DrawColor=sprintf('%.3f G',$r/255);
  398.     else
  399.         $this->DrawColor=sprintf('%.3f %.3f %.3f RG',$r/255,$g/255,$b/255);
  400.     if($this->page>0)
  401.         $this->_out($this->DrawColor);
  402. }
  403.  
  404. function SetFillColor($r,$g=-1,$b=-1)
  405. {
  406.     //Set color for all filling operations
  407.     if(($r==&& $g==&& $b==0|| $g==-1)
  408.         $this->FillColor=sprintf('%.3f g',$r/255);
  409.     else
  410.         $this->FillColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255);
  411.     $this->ColorFlag=($this->FillColor!=$this->TextColor);
  412.     if($this->page>0)
  413.         $this->_out($this->FillColor);
  414. }
  415.  
  416. function SetTextColor($r,$g=-1,$b=-1)
  417. {
  418.     //Set color for text
  419.     if(($r==&& $g==&& $b==0|| $g==-1)
  420.         $this->TextColor=sprintf('%.3f g',$r/255);
  421.     else
  422.         $this->TextColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255);
  423.     $this->ColorFlag=($this->FillColor!=$this->TextColor);
  424. }
  425.  
  426. function GetStringWidth($s)
  427. {
  428.     //Get width of a string in the current font
  429.     $s=(string)$s;
  430.     $cw=&$this->CurrentFont['cw'];
  431.     $w=0;
  432.     $l=strlen($s);
  433.     for($i=0;$i<$l;++$i)
  434.         $w+=$cw[$s{$i}];
  435.     return $w*$this->FontSize/1000;
  436. }
  437.  
  438. function SetLineWidth($width)
  439. {
  440.     //Set line width
  441.     $this->LineWidth=$width;
  442.     if($this->page>0)
  443.         $this->_out(sprintf('%.2f w',$width*$this->k));
  444. }
  445.  
  446. function Line($x1,$y1,$x2,$y2)
  447. {
  448.     //Draw a line
  449.     $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));
  450. }
  451.  
  452. function Rect($x,$y,$w,$h,$style='')
  453. {
  454.     //Draw a rectangle
  455.     if($style=='F')
  456.         $op='f';
  457.     elseif($style=='FD' || $style=='DF')
  458.         $op='B';
  459.     else
  460.         $op='S';
  461.     $this->_out(sprintf('%.2f %.2f %.2f %.2f re %s',$x*$this->k,($this->h-$y)*$this->k,$w*$this->k,-$h*$this->k,$op));
  462. }
  463.  
  464. function AddFont($family,$style='',$file='')
  465. {
  466.     //Add a TrueType or Type1 font
  467.     $family=strtolower($family);
  468.     if($file=='')
  469.         $file=str_replace(' ','',$family).strtolower($style).'.php';
  470.     if($family=='arial')
  471.         $family='helvetica';
  472.     $style=strtoupper($style);
  473.     if($style=='IB')
  474.         $style='BI';
  475.     $fontkey=$family.$style;
  476.     if(isset($this->fonts[$fontkey]))
  477.         $this->Error('Font already added: '.$family.' '.$style);
  478.     include($this->_getfontpath().$file);
  479.     if(!isset($name))
  480.         $this->Error('Could not include font definition file');
  481.     $i=count($this->fonts)+1;
  482.     $this->fonts[$fontkey]=array('i'=>$i,'type'=>$type,'name'=>$name,'desc'=>$desc,'up'=>$up,'ut'=>$ut,'cw'=>$cw,'enc'=>$enc,'file'=>$file);
  483.     if($diff)
  484.     {
  485.         //Search existing encodings
  486.         $d=0;
  487.         $nb=count($this->diffs);
  488.         for($i=1;$i<=$nb;++$i)
  489.         {
  490.             if($this->diffs[$i]==$diff)
  491.             {
  492.                 $d=$i;
  493.                 break;
  494.             }
  495.         }
  496.         if($d==0)
  497.         {
  498.             $d=$nb+1;
  499.             $this->diffs[$d]=$diff;
  500.         }
  501.         $this->fonts[$fontkey]['diff']=$d;
  502.     }
  503.     if($file)
  504.     {
  505.         if($type=='TrueType')
  506.             $this->FontFiles[$file]=array('length1'=>$originalsize);
  507.         else
  508.             $this->FontFiles[$file]=array('length1'=>$size1,'length2'=>$size2);
  509.     }
  510. }
  511.  
  512. function SetFont($family,$style='',$size=0)
  513. {
  514.     //Select a font; size given in points
  515.     global $fpdf_charwidths;
  516.  
  517.     $family=strtolower($family);
  518.     if($family=='')
  519.         $family=$this->FontFamily;
  520.     if($family=='arial')
  521.         $family='helvetica';
  522.     elseif($family=='symbol' || $family=='zapfdingbats')
  523.         $style='';
  524.     $style=strtoupper($style);
  525.     if(strpos($style,'U')!==false)
  526.     {
  527.         $this->underline=true;
  528.         $style=str_replace('U','',$style);
  529.     }
  530.     else
  531.         $this->underline=false;
  532.     if($style=='IB')
  533.         $style='BI';
  534.     if($size==0)
  535.         $size=$this->FontSizePt;
  536.     //Test if font is already selected
  537.     if($this->FontFamily==$family && $this->FontStyle==$style && $this->FontSizePt==$size)
  538.         return;
  539.     //Test if used for the first time
  540.     $fontkey=$family.$style;
  541.     if(!isset($this->fonts[$fontkey]))
  542.     {
  543.         //Check if one of the standard fonts
  544.         if(isset($this->CoreFonts[$fontkey]))
  545.         {
  546.             if(!isset($fpdf_charwidths[$fontkey]))
  547.             {
  548.                 //Load metric file
  549.                 $file=$family;
  550.                 if($family=='times' || $family=='helvetica')
  551.                     $file.=strtolower($style);
  552.                 include($this->_getfontpath().$file.'.php');
  553.                 if(!isset($fpdf_charwidths[$fontkey]))
  554.                     $this->Error('Could not include font metric file');
  555.             }
  556.             $i=count($this->fonts)+1;
  557.             $this->fonts[$fontkey]=array('i'=>$i,'type'=>'core','name'=>$this->CoreFonts[$fontkey],'up'=>-100,'ut'=>50,'cw'=>$fpdf_charwidths[$fontkey]);
  558.         }
  559.         else
  560.             $this->Error('Undefined font: '.$family.' '.$style);
  561.     }
  562.     //Select it
  563.     $this->FontFamily=$family;
  564.     $this->FontStyle=$style;
  565.     $this->FontSizePt=$size;
  566.     $this->FontSize=$size/$this->k;
  567.     $this->CurrentFont=&$this->fonts[$fontkey];
  568.     if($this->page>0)
  569.         $this->_out(sprintf('BT /F%d %.2f Tf ET',$this->CurrentFont['i'],$this->FontSizePt));
  570. }
  571.  
  572. function SetFontSize($size)
  573. {
  574.     //Set font size in points
  575.     if($this->FontSizePt==$size)
  576.         return;
  577.     $this->FontSizePt=$size;
  578.     $this->FontSize=$size/$this->k;
  579.     if($this->page>0)
  580.         $this->_out(sprintf('BT /F%d %.2f Tf ET',$this->CurrentFont['i'],$this->FontSizePt));
  581. }
  582.  
  583. function AddLink()
  584. {
  585.     //Create a new internal link
  586.     $n=count($this->links)+1;
  587.     $this->links[$n]=array(0,0);
  588.     return $n;
  589. }
  590.  
  591. function SetLink($link,$y=0,$page=-1)
  592. {
  593.     //Set destination of internal link
  594.     if($y==-1)
  595.         $y=$this->y;
  596.     if($page==-1)
  597.         $page=$this->page;
  598.     $this->links[$link]=array($page,$y);
  599. }
  600.  
  601. function Link($x,$y,$w,$h,$link)
  602. {
  603.     //Put a link on the page
  604.     $this->PageLinks[$this->page][]=array($x*$this->k,$this->hPt-$y*$this->k,$w*$this->k,$h*$this->k,$link);
  605. }
  606.  
  607. function Text($x,$y,$txt)
  608. {
  609.     //Output a string
  610.     $s=sprintf('BT %.2f %.2f Td (%s) Tj ET',$x*$this->k,($this->h-$y)*$this->k,$this->_escape($txt));
  611.     if($this->underline && $txt!='')
  612.         $s.=' '.$this->_dounderline($x,$y,$txt);
  613.     if($this->ColorFlag)
  614.         $s='q '.$this->TextColor.' '.$s.' Q';
  615.     $this->_out($s);
  616. }
  617.  
  618. function AcceptPageBreak()
  619. {
  620.     //Accept automatic page break or not
  621.     return $this->AutoPageBreak;
  622. }
  623.  
  624. function Cell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='')
  625. {
  626.     //Output a cell
  627.     $k=$this->k;
  628.     if($this->y+$h>$this->PageBreakTrigger && !$this->InFooter && $this->AcceptPageBreak())
  629.     {
  630.         //Automatic page break
  631.         $x=$this->x;
  632.         $ws=$this->ws;
  633.         if($ws>0)
  634.         {
  635.             $this->ws=0;
  636.             $this->_out('0 Tw');
  637.         }
  638.         $this->AddPage($this->CurOrientation);
  639.         $this->x=$x;
  640.         if($ws>0)
  641.         {
  642.             $this->ws=$ws;
  643.             $this->_out(sprintf('%.3f Tw',$ws*$k));
  644.         }
  645.     }
  646.     if($w==0)
  647.         $w=$this->w-$this->rMargin-$this->x;
  648.     $s='';
  649.     if($fill==|| $border==1)
  650.     {
  651.         if($fill==1)
  652.             $op=($border==1'B' 'f';
  653.         else
  654.             $op='S';
  655.         $s=sprintf('%.2f %.2f %.2f %.2f re %s ',$this->x*$k,($this->h-$this->y)*$k,$w*$k,-$h*$k,$op);
  656.     }
  657.     if(is_string($border))
  658.     {
  659.         $x=$this->x;
  660.         $y=$this->y;
  661.         if(strpos($border,'L')!==false)
  662.             $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,$x*$k,($this->h-($y+$h))*$k);
  663.         if(strpos($border,'T')!==false)
  664.             $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-$y)*$k);
  665.         if(strpos($border,'R')!==false)
  666.             $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',($x+$w)*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
  667.         if(strpos($border,'B')!==false)
  668.             $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-($y+$h))*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
  669.     }
  670.     if($txt!=='')
  671.     {
  672.         if($align=='R')
  673.             $dx=$w-$this->cMargin-$this->GetStringWidth($txt);
  674.         elseif($align=='C')
  675.             $dx=($w-$this->GetStringWidth($txt))/2;
  676.         else
  677.             $dx=$this->cMargin;
  678.         if($this->ColorFlag)
  679.             $s.='q '.$this->TextColor.' ';
  680.         $txt2=str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$txt)));
  681.         $s.=sprintf('BT %.2f %.2f Td (%s) Tj ET',($this->x+$dx)*$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,$txt2);
  682.         if($this->underline)
  683.             $s.=' '.$this->_dounderline($this->x+$dx,$this->y+.5*$h+.3*$this->FontSize,$txt);
  684.         if($this->ColorFlag)
  685.             $s.=' Q';
  686.         if($link)
  687.             $this->Link($this->x+$dx,$this->y+.5*$h-.5*$this->FontSize,$this->GetStringWidth($txt),$this->FontSize,$link);
  688.     }
  689.     if($s)
  690.         $this->_out($s);
  691.     $this->lasth=$h;
  692.     if($ln>0)
  693.     {
  694.         //Go to next line
  695.         $this->y+=$h;
  696.         if($ln==1)
  697.             $this->x=$this->lMargin;
  698.     }
  699.     else
  700.         $this->x+=$w;
  701. }
  702.  
  703. function MultiCell($w,$h,$txt,$border=0,$align='J',$fill=0)
  704. {
  705.     //Output text with automatic or explicit line breaks
  706.     $cw=&$this->CurrentFont['cw'];
  707.     if($w==0)
  708.         $w=$this->w-$this->rMargin-$this->x;
  709.     $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
  710.     $s=str_replace("\r",'',$txt);
  711.     $nb=strlen($s);
  712.     if($nb>&& $s[$nb-1]=="\n")
  713.         --$nb;
  714.     $b=0;
  715.     if($border)
  716.     {
  717.         if($border==1)
  718.         {
  719.             $border='LTRB';
  720.             $b='LRT';
  721.             $b2='LR';
  722.         }
  723.         else
  724.         {
  725.             $b2='';
  726.             if(strpos($border,'L')!==false)
  727.                 $b2.='L';
  728.             if(strpos($border,'R')!==false)
  729.                 $b2.='R';
  730.             $b=(strpos($border,'T')!==false$b2.'T' $b2;
  731.         }
  732.     }
  733.     $sep=-1;
  734.     $i=0;
  735.     $j=0;
  736.     $l=0;
  737.     $ns=0;
  738.     $nl=1;
  739.     while($i<$nb)
  740.     {
  741.         //Get next character
  742.         $c=$s{$i};
  743.         if($c=="\n")
  744.         {
  745.             //Explicit line break
  746.             if($this->ws>0)
  747.             {
  748.                 $this->ws=0;
  749.                 $this->_out('0 Tw');
  750.             }
  751.             $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
  752.             ++$i;
  753.             $sep=-1;
  754.             $j=$i;
  755.             $l=0;
  756.             $ns=0;
  757.             ++$nl;
  758.             if($border && $nl==2)
  759.                 $b=$b2;
  760.             continue;
  761.         }
  762.         if($c==' ')
  763.         {
  764.             $sep=$i;
  765.             $ls=$l;
  766.             ++$ns;
  767.         }
  768.         $l+=$cw[$c];
  769.         if($l>$wmax)
  770.         {
  771.             //Automatic line break
  772.             if($sep==-1)
  773.             {
  774.                 if($i==$j)
  775.                     ++$i;
  776.                 if($this->ws>0)
  777.                 {
  778.                     $this->ws=0;
  779.                     $this->_out('0 Tw');
  780.                 }
  781.                 $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
  782.             }
  783.             else
  784.             {
  785.                 if($align=='J')
  786.                 {
  787.                     $this->ws=($ns>1($wmax-$ls)/1000*$this->FontSize/($ns-10;
  788.                     $this->_out(sprintf('%.3f Tw',$this->ws*$this->k));
  789.                 }
  790.                 $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill);
  791.                 $i=$sep+1;
  792.             }
  793.             $sep=-1;
  794.             $j=$i;
  795.             $l=0;
  796.             $ns=0;
  797.             ++$nl;
  798.             if($border && $nl==2)
  799.                 $b=$b2;
  800.         }
  801.         else
  802.             ++$i;
  803.     }
  804.     //Last chunk
  805.     if($this->ws>0)
  806.     {
  807.         $this->ws=0;
  808.         $this->_out('0 Tw');
  809.     }
  810.     if($border && strpos($border,'B')!==false)
  811.         $b.='B';
  812.  
  813.     // MODIFIED PHPEXCEL
  814.     $this->Cell($w,$h,substr($s,$j,$i-$j),$b,0,$align,$fill);
  815.     //$this->x=$this->lMargin;
  816. }
  817.  
  818. function Write($h,$txt,$link='')
  819. {
  820.     //Output text in flowing mode
  821.     $cw=&$this->CurrentFont['cw'];
  822.     $w=$this->w-$this->rMargin-$this->x;
  823.     $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
  824.     $s=str_replace("\r",'',$txt);
  825.     $nb=strlen($s);
  826.     $sep=-1;
  827.     $i=0;
  828.     $j=0;
  829.     $l=0;
  830.     $nl=1;
  831.     while($i<$nb)
  832.     {
  833.         //Get next character
  834.         $c=$s{$i};
  835.         if($c=="\n")
  836.         {
  837.             //Explicit line break
  838.             $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
  839.             ++$i;
  840.             $sep=-1;
  841.             $j=$i;
  842.             $l=0;
  843.             if($nl==1)
  844.             {
  845.                 $this->x=$this->lMargin;
  846.                 $w=$this->w-$this->rMargin-$this->x;
  847.                 $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
  848.             }
  849.             ++$nl;
  850.             continue;
  851.         }
  852.         if($c==' ')
  853.             $sep=$i;
  854.         $l+=$cw[$c];
  855.         if($l>$wmax)
  856.         {
  857.             //Automatic line break
  858.             if($sep==-1)
  859.             {
  860.                 if($this->x>$this->lMargin)
  861.                 {
  862.                     //Move to next line
  863.                     $this->x=$this->lMargin;
  864.                     $this->y+=$h;
  865.                     $w=$this->w-$this->rMargin-$this->x;
  866.                     $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
  867.                     ++$i;
  868.                     ++$nl;
  869.                     continue;
  870.                 }
  871.                 if($i==$j)
  872.                     ++$i;
  873.                 $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
  874.             }
  875.             else
  876.             {
  877.                 $this->Cell($w,$h,substr($s,$j,$sep-$j),0,2,'',0,$link);
  878.                 $i=$sep+1;
  879.             }
  880.             $sep=-1;
  881.             $j=$i;
  882.             $l=0;
  883.             if($nl==1)
  884.             {
  885.                 $this->x=$this->lMargin;
  886.                 $w=$this->w-$this->rMargin-$this->x;
  887.                 $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
  888.             }
  889.             ++$nl;
  890.         }
  891.         else
  892.             ++$i;
  893.     }
  894.     //Last chunk
  895.     if($i!=$j)
  896.         $this->Cell($l/1000*$this->FontSize,$h,substr($s,$j),0,0,'',0,$link);
  897. }
  898.  
  899. function Image($file,$x,$y,$w=0,$h=0,$type='',$link='',$tempFolder='')
  900. {
  901.     // MODIFIED PHPEXCEL
  902.     if ($tempFolder == ''{
  903.         $tempFolder sys_get_temp_dir();
  904.     }
  905.  
  906.     //Get image info
  907.     if($type=='')
  908.     {
  909.         $pos=strrpos($file,'.');
  910.         if(!$pos)
  911.             $this->Error('Image file has no extension and no type was specified: '.$file);
  912.         $type=substr($file,$pos+1);
  913.     }
  914.     $type=strtolower($type);
  915.  
  916.     //Determine type
  917.     $im null;
  918.     if($type=='jpg' || $type=='jpeg')
  919.         $im @imagecreatefromjpeg ($file);
  920.     elseif($type=='png')
  921.         $im @imagecreatefrompng ($file);
  922.     elseif($type=='gif')
  923.         $im @imagecreatefromgif ($file);
  924.  
  925.     //Create JPEG version
  926.     $tmpFile $tempFolder '/' basename($file);
  927.     if (@imagejpeg($im$tmpFile100=== true{
  928.         $type 'jpg';
  929.         $file $tmpFile;
  930.     }
  931.  
  932.     //Put an image on the page
  933.     if(!isset($this->images[$file]))
  934.     {
  935.         $mqr=get_magic_quotes_runtime();
  936.         set_magic_quotes_runtime(0);
  937.         if($type=='jpg' || $type=='jpeg')
  938.             $info=$this->_parsejpg($file);
  939.         elseif($type=='png')
  940.             $info=$this->_parsepng($file);
  941.         else
  942.         {
  943.             //Allow for additional formats
  944.             $mtd='_parse'.$type;
  945.             if(!method_exists($this,$mtd))
  946.                 $this->Error('Unsupported image type: '.$type);
  947.             $info=$this->$mtd($file);
  948.         }
  949.         set_magic_quotes_runtime($mqr);
  950.         $info['i']=count($this->images)+1;
  951.         $this->images[$file]=$info;
  952.     }
  953.     else
  954.         $info=$this->images[$file];
  955.     //Automatic width and height calculation if needed
  956.     if($w==&& $h==0)
  957.     {
  958.         //Put image at 72 dpi
  959.         $w=$info['w']/$this->k;
  960.         $h=$info['h']/$this->k;
  961.     }
  962.     if($w==0)
  963.         $w=$h*$info['w']/$info['h'];
  964.     if($h==0)
  965.         $h=$w*$info['h']/$info['w'];
  966.     $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']));
  967.     if($link)
  968.         $this->Link($x,$y,$w,$h,$link);
  969. }
  970.  
  971. function Ln($h='')
  972. {
  973.     //Line feed; default value is last cell height
  974.     $this->x=$this->lMargin;
  975.     if(is_string($h))
  976.         $this->y+=$this->lasth;
  977.     else
  978.         $this->y+=$h;
  979. }
  980.  
  981. function GetX()
  982. {
  983.     //Get x position
  984.     return $this->x;
  985. }
  986.  
  987. function SetX($x)
  988. {
  989.     //Set x position
  990.     if($x>=0)
  991.         $this->x=$x;
  992.     else
  993.         $this->x=$this->w+$x;
  994. }
  995.  
  996. function GetY()
  997. {
  998.     //Get y position
  999.     return $this->y;
  1000. }
  1001.  
  1002. function SetY($y)
  1003. {
  1004.     //Set y position and reset x
  1005.     $this->x=$this->lMargin;
  1006.     if($y>=0)
  1007.         $this->y=$y;
  1008.     else
  1009.         $this->y=$this->h+$y;
  1010. }
  1011.  
  1012. function SetXY($x,$y)
  1013. {
  1014.     //Set x and y positions
  1015.     $this->SetY($y);
  1016.     $this->SetX($x);
  1017. }
  1018.  
  1019. function Output($name='',$dest='')
  1020. {
  1021.     //Output PDF to some destination
  1022.     //Finish document if necessary
  1023.     if($this->state<3)
  1024.         $this->Close();
  1025.     //Normalize parameters
  1026.     if(is_bool($dest))
  1027.         $dest=$dest 'D' 'F';
  1028.     $dest=strtoupper($dest);
  1029.     if($dest=='')
  1030.     {
  1031.         if($name=='')
  1032.         {
  1033.             $name='doc.pdf';
  1034.             $dest='I';
  1035.         }
  1036.         else
  1037.             $dest='F';
  1038.     }
  1039.     switch($dest)
  1040.     {
  1041.         case 'I':
  1042.             //Send to standard output
  1043.             if(ob_get_contents())
  1044.                 $this->Error('Some data has already been output, can\'t send PDF file');
  1045.             if(php_sapi_name()!='cli')
  1046.             {
  1047.                 //We send to a browser
  1048.                 header('Content-Type: application/pdf');
  1049.                 if(headers_sent())
  1050.                     $this->Error('Some data has already been output to browser, can\'t send PDF file');
  1051.                 header('Content-Length: '.strlen($this->buffer));
  1052.                 header('Content-disposition: inline; filename="'.$name.'"');
  1053.             }
  1054.             echo $this->buffer;
  1055.             break;
  1056.         case 'D':
  1057.             //Download file
  1058.             if(ob_get_contents())
  1059.                 $this->Error('Some data has already been output, can\'t send PDF file');
  1060.             if(isset($_SERVER['HTTP_USER_AGENT']&& strpos($_SERVER['HTTP_USER_AGENT'],'MSIE'))
  1061.                 header('Content-Type: application/force-download');
  1062.             else
  1063.                 header('Content-Type: application/octet-stream');
  1064.             if(headers_sent())
  1065.                 $this->Error('Some data has already been output to browser, can\'t send PDF file');
  1066.             header('Content-Length: '.strlen($this->buffer));
  1067.             header('Content-disposition: attachment; filename="'.$name.'"');
  1068.             echo $this->buffer;
  1069.             break;
  1070.         case 'F':
  1071.             //Save to local file
  1072.             $f=fopen($name,'wb');
  1073.             if(!$f)
  1074.                 $this->Error('Unable to create output file: '.$name);
  1075.             fwrite($f,$this->buffer,strlen($this->buffer));
  1076.             fclose($f);
  1077.             break;
  1078.         case 'S':
  1079.             //Return as a string
  1080.             return $this->buffer;
  1081.         default:
  1082.             $this->Error('Incorrect output destination: '.$dest);
  1083.     }
  1084.     return '';
  1085. }
  1086.  
  1087. /*******************************************************************************
  1088. *                                                                              *
  1089. *                              Protected methods                               *
  1090. *                                                                              *
  1091. *******************************************************************************/
  1092. function _dochecks()
  1093. {
  1094.     //Check for locale-related bug
  1095.     if(1.1==1)
  1096.         $this->Error('Don\'t alter the locale before including class file');
  1097.     //Check for decimal separator
  1098.     if(sprintf('%.1f',1.0)!='1.0')
  1099.         setlocale(LC_NUMERIC,'C');
  1100. }
  1101.  
  1102. function _getfontpath()
  1103. {
  1104.     if(!defined('FPDF_FONTPATH'&& is_dir(dirname(__FILE__).'/font'))
  1105.         define('FPDF_FONTPATH',dirname(__FILE__).'/font/');
  1106.     return defined('FPDF_FONTPATH'FPDF_FONTPATH '';
  1107. }
  1108.  
  1109. function _putpages()
  1110. {
  1111.     $nb=$this->page;
  1112.     if(!empty($this->AliasNbPages))
  1113.     {
  1114.         //Replace number of pages
  1115.         for($n=1;$n<=$nb;++$n)
  1116.             $this->pages[$n]=str_replace($this->AliasNbPages,$nb,$this->pages[$n]);
  1117.     }
  1118.     if($this->DefOrientation=='P')
  1119.     {
  1120.         $wPt=$this->fwPt;
  1121.         $hPt=$this->fhPt;
  1122.     }
  1123.     else
  1124.     {
  1125.         $wPt=$this->fhPt;
  1126.         $hPt=$this->fwPt;
  1127.     }
  1128.     $filter=($this->compress'/Filter /FlateDecode ' '';
  1129.     for($n=1;$n<=$nb;++$n)
  1130.     {
  1131.         //Page
  1132.         $this->_newobj();
  1133.         $this->_out('<</Type /Page');
  1134.         $this->_out('/Parent 1 0 R');
  1135.         if(isset($this->OrientationChanges[$n]))
  1136.             $this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$hPt,$wPt));
  1137.         $this->_out('/Resources 2 0 R');
  1138.         if(isset($this->PageLinks[$n]))
  1139.         {
  1140.             //Links
  1141.             $annots='/Annots [';
  1142.             foreach($this->PageLinks[$nas $pl)
  1143.             {
  1144.                 $rect=sprintf('%.2f %.2f %.2f %.2f',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]);
  1145.                 $annots.='<</Type /Annot /Subtype /Link /Rect ['.$rect.'] /Border [0 0 0] ';
  1146.                 if(is_string($pl[4]))
  1147.                     $annots.='/A <</S /URI /URI '.$this->_textstring($pl[4]).'>>>>';
  1148.                 else
  1149.                 {
  1150.                     $l=$this->links[$pl[4]];
  1151.                     $h=isset($this->OrientationChanges[$l[0]]$wPt $hPt;
  1152.                     $annots.=sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]>>',1+2*$l[0],$h-$l[1]*$this->k);
  1153.                 }
  1154.             }
  1155.             $this->_out($annots.']');
  1156.         }
  1157.         $this->_out('/Contents '.($this->n+1).' 0 R>>');
  1158.         $this->_out('endobj');
  1159.         //Page content
  1160.         $p=($this->compressgzcompress($this->pages[$n]$this->pages[$n];
  1161.         $this->_newobj();
  1162.         $this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
  1163.         $this->_putstream($p);
  1164.         $this->_out('endobj');
  1165.     }
  1166.     //Pages root
  1167.     $this->offsets[1]=strlen($this->buffer);
  1168.     $this->_out('1 0 obj');
  1169.     $this->_out('<</Type /Pages');
  1170.     $kids='/Kids [';
  1171.     for($i=0;$i<$nb;++$i)
  1172.         $kids.=(3+2*$i).' 0 R ';
  1173.     $this->_out($kids.']');
  1174.     $this->_out('/Count '.$nb);
  1175.     $this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$wPt,$hPt));
  1176.     $this->_out('>>');
  1177.     $this->_out('endobj');
  1178. }
  1179.  
  1180. function _putfonts()
  1181. {
  1182.     $nf=$this->n;
  1183.     foreach($this->diffs as $diff)
  1184.     {
  1185.         //Encodings
  1186.         $this->_newobj();
  1187.         $this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.']>>');
  1188.         $this->_out('endobj');
  1189.     }
  1190.     $mqr=get_magic_quotes_runtime();
  1191.     foreach($this->FontFiles as $file=>$info)
  1192.     {
  1193.         //Font file embedding
  1194.         $this->_newobj();
  1195.         $this->FontFiles[$file]['n']=$this->n;
  1196.         $font='';
  1197.         $f=fopen($this->_getfontpath().$file,'rb',1);
  1198.         if(!$f)
  1199.             $this->Error('Font file not found');
  1200.         while(!feof($f))
  1201.             $font.=fread($f,8192);
  1202.         fclose($f);
  1203.         $compressed=(substr($file,-2)=='.z');
  1204.         if(!$compressed && isset($info['length2']))
  1205.         {
  1206.             $header=(ord($font{0})==128);
  1207.             if($header)
  1208.             {
  1209.                 //Strip first binary header
  1210.                 $font=substr($font,6);
  1211.             }
  1212.             if($header && ord($font{$info['length1']})==128)
  1213.             {
  1214.                 //Strip second binary header
  1215.                 $font=substr($font,0,$info['length1']).substr($font,$info['length1']+6);
  1216.             }
  1217.         }
  1218.         $this->_out('<</Length '.strlen($font));
  1219.         if($compressed)
  1220.             $this->_out('/Filter /FlateDecode');
  1221.         $this->_out('/Length1 '.$info['length1']);
  1222.         if(isset($info['length2']))
  1223.             $this->_out('/Length2 '.$info['length2'].' /Length3 0');
  1224.         $this->_out('>>');
  1225.         $this->_putstream($font);
  1226.         $this->_out('endobj');
  1227.     }
  1228.     foreach($this->fonts as $k=>$font)
  1229.     {
  1230.         //Font objects
  1231.         $this->fonts[$k]['n']=$this->n+1;
  1232.         $type=$font['type'];
  1233.         $name=$font['name'];
  1234.         if($type=='core')
  1235.         {
  1236.             //Standard font
  1237.             $this->_newobj();
  1238.             $this->_out('<</Type /Font');
  1239.             $this->_out('/BaseFont /'.$name);
  1240.             $this->_out('/Subtype /Type1');
  1241.             if($name!='Symbol' && $name!='ZapfDingbats')
  1242.                 $this->_out('/Encoding /WinAnsiEncoding');
  1243.             $this->_out('>>');
  1244.             $this->_out('endobj');
  1245.         }
  1246.         elseif($type=='Type1' || $type=='TrueType')
  1247.         {
  1248.             //Additional Type1 or TrueType font
  1249.             $this->_newobj();
  1250.             $this->_out('<</Type /Font');
  1251.             $this->_out('/BaseFont /'.$name);
  1252.             $this->_out('/Subtype /'.$type);
  1253.             $this->_out('/FirstChar 32 /LastChar 255');
  1254.             $this->_out('/Widths '.($this->n+1).' 0 R');
  1255.             $this->_out('/FontDescriptor '.($this->n+2).' 0 R');
  1256.             if($font['enc'])
  1257.             {
  1258.                 if(isset($font['diff']))
  1259.                     $this->_out('/Encoding '.($nf+$font['diff']).' 0 R');
  1260.                 else
  1261.                     $this->_out('/Encoding /WinAnsiEncoding');
  1262.             }
  1263.             $this->_out('>>');
  1264.             $this->_out('endobj');
  1265.             //Widths
  1266.             $this->_newobj();
  1267.             $cw=&$font['cw'];
  1268.             $s='[';
  1269.             for($i=32;$i<=255;++$i)
  1270.                 $s.=$cw[chr($i)].' ';
  1271.             $this->_out($s.']');
  1272.             $this->_out('endobj');
  1273.             //Descriptor
  1274.             $this->_newobj();
  1275.             $s='<</Type /FontDescriptor /FontName /'.$name;
  1276.             foreach($font['desc'as $k=>$v)
  1277.                 $s.=' /'.$k.' '.$v;
  1278.             $file=$font['file'];
  1279.             if($file)
  1280.                 $s.=' /FontFile'.($type=='Type1' '' '2').' '.$this->FontFiles[$file]['n'].' 0 R';
  1281.             $this->_out($s.'>>');
  1282.             $this->_out('endobj');
  1283.         }
  1284.         else
  1285.         {
  1286.             //Allow for additional types
  1287.             $mtd='_put'.strtolower($type);
  1288.             if(!method_exists($this,$mtd))
  1289.                 $this->Error('Unsupported font type: '.$type);
  1290.             $this->$mtd($font);
  1291.         }
  1292.     }
  1293. }
  1294.  
  1295. function _putimages()
  1296. {
  1297.     $filter=($this->compress'/Filter /FlateDecode ' '';
  1298.     reset($this->images);
  1299.     while(list($file,$info)=each($this->images))
  1300.     {
  1301.         $this->_newobj();
  1302.         $this->images[$file]['n']=$this->n;
  1303.         $this->_out('<</Type /XObject');
  1304.         $this->_out('/Subtype /Image');
  1305.         $this->_out('/Width '.$info['w']);
  1306.         $this->_out('/Height '.$info['h']);
  1307.         if($info['cs']=='Indexed')
  1308.             $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]');
  1309.         else
  1310.         {
  1311.             $this->_out('/ColorSpace /'.$info['cs']);
  1312.             if($info['cs']=='DeviceCMYK')
  1313.                 $this->_out('/Decode [1 0 1 0 1 0 1 0]');
  1314.         }
  1315.         $this->_out('/BitsPerComponent '.$info['bpc']);
  1316.         if(isset($info['f']))
  1317.             $this->_out('/Filter /'.$info['f']);
  1318.         if(isset($info['parms']))
  1319.             $this->_out($info['parms']);
  1320.         if(isset($info['trns']&& is_array($info['trns']))
  1321.         {
  1322.             $trns='';
  1323.             $infoTrnsCount count($info['trns']);
  1324.             for($i=0;$i<$infoTrnsCount;++$i)
  1325.                 $trns.=$info['trns'][$i].' '.$info['trns'][$i].' ';
  1326.             $this->_out('/Mask ['.$trns.']');
  1327.         }
  1328.         $this->_out('/Length '.strlen($info['data']).'>>');
  1329.         $this->_putstream($info['data']);
  1330.         unset($this->images[$file]['data']);
  1331.         $this->_out('endobj');
  1332.         //Palette
  1333.         if($info['cs']=='Indexed')
  1334.         {
  1335.             $this->_newobj();
  1336.             $pal=($this->compressgzcompress($info['pal']$info['pal'];
  1337.             $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
  1338.             $this->_putstream($pal);
  1339.             $this->_out('endobj');
  1340.         }
  1341.     }
  1342. }
  1343.  
  1344. function _putxobjectdict()
  1345. {
  1346.     foreach($this->images as $image)
  1347.         $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
  1348. }
  1349.  
  1350. function _putresourcedict()
  1351. {
  1352.     $this->_out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
  1353.     $this->_out('/Font <<');
  1354.     foreach($this->fonts as $font)
  1355.         $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
  1356.     $this->_out('>>');
  1357.     $this->_out('/XObject <<');
  1358.     $this->_putxobjectdict();
  1359.     $this->_out('>>');
  1360. }
  1361.  
  1362. function _putresources()
  1363. {
  1364.     $this->_putfonts();
  1365.     $this->_putimages();
  1366.     //Resource dictionary
  1367.     $this->offsets[2]=strlen($this->buffer);
  1368.     $this->_out('2 0 obj');
  1369.     $this->_out('<<');
  1370.     $this->_putresourcedict();
  1371.     $this->_out('>>');
  1372.     $this->_out('endobj');
  1373. }
  1374.  
  1375. function _putinfo()
  1376. {
  1377.     $this->_out('/Producer '.$this->_textstring('FPDF '.FPDF_VERSION));
  1378.     if(!empty($this->title))
  1379.         $this->_out('/Title '.$this->_textstring($this->title));
  1380.     if(!empty($this->subject))
  1381.         $this->_out('/Subject '.$this->_textstring($this->subject));
  1382.     if(!empty($this->author))
  1383.         $this->_out('/Author '.$this->_textstring($this->author));
  1384.     if(!empty($this->keywords))
  1385.         $this->_out('/Keywords '.$this->_textstring($this->keywords));
  1386.     if(!empty($this->creator))
  1387.         $this->_out('/Creator '.$this->_textstring($this->creator));
  1388.     $this->_out('/CreationDate '.$this->_textstring('D:'.date('YmdHis')));
  1389. }
  1390.  
  1391. function _putcatalog()
  1392. {
  1393.     $this->_out('/Type /Catalog');
  1394.     $this->_out('/Pages 1 0 R');
  1395.     if($this->ZoomMode=='fullpage')
  1396.         $this->_out('/OpenAction [3 0 R /Fit]');
  1397.     elseif($this->ZoomMode=='fullwidth')
  1398.         $this->_out('/OpenAction [3 0 R /FitH null]');
  1399.     elseif($this->ZoomMode=='real')
  1400.         $this->_out('/OpenAction [3 0 R /XYZ null null 1]');
  1401.     elseif(!is_string($this->ZoomMode))
  1402.         $this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode/100).']');
  1403.     if($this->LayoutMode=='single')
  1404.         $this->_out('/PageLayout /SinglePage');
  1405.     elseif($this->LayoutMode=='continuous')
  1406.         $this->_out('/PageLayout /OneColumn');
  1407.     elseif($this->LayoutMode=='two')
  1408.         $this->_out('/PageLayout /TwoColumnLeft');
  1409. }
  1410.  
  1411. function _putheader()
  1412. {
  1413.     $this->_out('%PDF-'.$this->PDFVersion);
  1414. }
  1415.  
  1416. function _puttrailer()
  1417. {
  1418.     $this->_out('/Size '.($this->n+1));
  1419.     $this->_out('/Root '.$this->n.' 0 R');
  1420.     $this->_out('/Info '.($this->n-1).' 0 R');
  1421. }
  1422.  
  1423. function _enddoc()
  1424. {
  1425.     $this->_putheader();
  1426.     $this->_putpages();
  1427.     $this->_putresources();
  1428.     //Info
  1429.     $this->_newobj();
  1430.     $this->_out('<<');
  1431.     $this->_putinfo();
  1432.     $this->_out('>>');
  1433.     $this->_out('endobj');
  1434.     //Catalog
  1435.     $this->_newobj();
  1436.     $this->_out('<<');
  1437.     $this->_putcatalog();
  1438.     $this->_out('>>');
  1439.     $this->_out('endobj');
  1440.     //Cross-ref
  1441.     $o=strlen($this->buffer);
  1442.     $this->_out('xref');
  1443.     $this->_out('0 '.($this->n+1));
  1444.     $this->_out('0000000000 65535 f ');
  1445.     for($i=1;$i<=$this->n;++$i)
  1446.         $this->_out(sprintf('%010d 00000 n ',$this->offsets[$i]));
  1447.     //Trailer
  1448.     $this->_out('trailer');
  1449.     $this->_out('<<');
  1450.     $this->_puttrailer();
  1451.     $this->_out('>>');
  1452.     $this->_out('startxref');
  1453.     $this->_out($o);
  1454.     $this->_out('%%EOF');
  1455.     $this->state=3;
  1456. }
  1457.  
  1458. function _beginpage($orientation)
  1459. {
  1460.     $this->page++;
  1461.     $this->pages[$this->page]='';
  1462.     $this->state=2;
  1463.     $this->x=$this->lMargin;
  1464.     $this->y=$this->tMargin;
  1465.     $this->FontFamily='';
  1466.     //Page orientation
  1467.     if(!$orientation)
  1468.         $orientation=$this->DefOrientation;
  1469.     else
  1470.     {
  1471.         $orientation=strtoupper($orientation{0});
  1472.         if($orientation!=$this->DefOrientation)
  1473.             $this->OrientationChanges[$this->page]=true;
  1474.     }
  1475.     if($orientation!=$this->CurOrientation)
  1476.     {
  1477.         //Change orientation
  1478.         if($orientation=='P')
  1479.         {
  1480.             $this->wPt=$this->fwPt;
  1481.             $this->hPt=$this->fhPt;
  1482.             $this->w=$this->fw;
  1483.             $this->h=$this->fh;
  1484.         }
  1485.         else
  1486.         {
  1487.             $this->wPt=$this->fhPt;
  1488.             $this->hPt=$this->fwPt;
  1489.             $this->w=$this->fh;
  1490.             $this->h=$this->fw;
  1491.         }
  1492.         $this->PageBreakTrigger=$this->h-$this->bMargin;
  1493.         $this->CurOrientation=$orientation;
  1494.     }
  1495. }
  1496.  
  1497. function _endpage()
  1498. {
  1499.     //End of page contents
  1500.     $this->state=1;
  1501. }
  1502.  
  1503. function _newobj()
  1504. {
  1505.     //Begin a new object
  1506.     $this->n++;
  1507.     $this->offsets[$this->n]=strlen($this->buffer);
  1508.     $this->_out($this->n.' 0 obj');
  1509. }
  1510.  
  1511. function _dounderline($x,$y,$txt)
  1512. {
  1513.     //Underline text
  1514.     $up=$this->CurrentFont['up'];
  1515.     $ut=$this->CurrentFont['ut'];
  1516.     $w=$this->GetStringWidth($txt)+$this->ws*substr_count($txt,' ');
  1517.     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);
  1518. }
  1519.  
  1520. function _parsejpg($file)
  1521. {
  1522.     //Extract info from a JPEG file
  1523.     $a=GetImageSize($file);
  1524.     if(!$a)
  1525.         $this->Error('Missing or incorrect image file: '.$file);
  1526.     if($a[2]!=2)
  1527.         $this->Error('Not a JPEG file: '.$file);
  1528.     if(!isset($a['channels']|| $a['channels']==3)
  1529.         $colspace='DeviceRGB';
  1530.     elseif($a['channels']==4)
  1531.         $colspace='DeviceCMYK';
  1532.     else
  1533.         $colspace='DeviceGray';
  1534.     $bpc=isset($a['bits']$a['bits'8;
  1535.     //Read whole file
  1536.     $f=fopen($file,'rb');
  1537.     $data='';
  1538.     while(!feof($f))
  1539.         $data.=fread($f,4096);
  1540.     fclose($f);
  1541.     return array('w'=>$a[0],'h'=>$a[1],'cs'=>$colspace,'bpc'=>$bpc,'f'=>'DCTDecode','data'=>$data);
  1542. }
  1543.  
  1544. function _parsepng($file)
  1545. {
  1546.     //Extract info from a PNG file
  1547.     $f=fopen($file,'rb');
  1548.     if(!$f)
  1549.         $this->Error('Can\'t open image file: '.$file);
  1550.     //Check signature
  1551.     if(fread($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10))
  1552.         $this->Error('Not a PNG file: '.$file);
  1553.     //Read header chunk
  1554.     fread($f,4);
  1555.     if(fread($f,4)!='IHDR')
  1556.         $this->Error('Incorrect PNG file: '.$file);
  1557.     $w=$this->_freadint($f);
  1558.     $h=$this->_freadint($f);
  1559.     $bpc=ord(fread($f,1));
  1560.     if($bpc>8)
  1561.         $this->Error('16-bit depth not supported: '.$file);
  1562.     $ct=ord(fread($f,1));
  1563.     if($ct==0)
  1564.         $colspace='DeviceGray';
  1565.     elseif($ct==2)
  1566.         $colspace='DeviceRGB';
  1567.     elseif($ct==3)
  1568.         $colspace='Indexed';
  1569.     else
  1570.         $this->Error('Alpha channel not supported: '.$file);
  1571.     if(ord(fread($f,1))!=0)
  1572.         $this->Error('Unknown compression method: '.$file);
  1573.     if(ord(fread($f,1))!=0)
  1574.         $this->Error('Unknown filter method: '.$file);
  1575.     if(ord(fread($f,1))!=0)
  1576.         $this->Error('Interlacing not supported: '.$file);
  1577.     fread($f,4);
  1578.     $parms='/DecodeParms <</Predictor 15 /Colors '.($ct==1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
  1579.     //Scan chunks looking for palette, transparency and image data
  1580.     $pal='';
  1581.     $trns='';
  1582.     $data='';
  1583.     do
  1584.     {
  1585.         $n=$this->_freadint($f);
  1586.         $type=fread($f,4);
  1587.         if($type=='PLTE')
  1588.         {
  1589.             //Read palette
  1590.             $pal=fread($f,$n);
  1591.             fread($f,4);
  1592.         }
  1593.         elseif($type=='tRNS')
  1594.         {
  1595.             //Read transparency info
  1596.             $t=fread($f,$n);
  1597.             if($ct==0)
  1598.                 $trns=array(ord(substr($t,1,1)));
  1599.             elseif($ct==2)
  1600.                 $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
  1601.             else
  1602.             {
  1603.                 $pos=strpos($t,chr(0));
  1604.                 if($pos!==false)
  1605.                     $trns=array($pos);
  1606.             }
  1607.             fread($f,4);
  1608.         }
  1609.         elseif($type=='IDAT')
  1610.         {
  1611.             //Read image data block
  1612.             $data.=fread($f,$n);
  1613.             fread($f,4);
  1614.         }
  1615.         elseif($type=='IEND')
  1616.             break;
  1617.         else
  1618.             fread($f,$n+4);
  1619.     }
  1620.     while($n);
  1621.     if($colspace=='Indexed' && empty($pal))
  1622.         $this->Error('Missing palette in '.$file);
  1623.     fclose($f);
  1624.     return array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$data);
  1625. }
  1626.  
  1627. function _freadint($f)
  1628. {
  1629.     //Read a 4-byte integer from file
  1630.     $a=unpack('Ni',fread($f,4));
  1631.     return $a['i'];
  1632. }
  1633.  
  1634. function _textstring($s)
  1635. {
  1636.     //Format a text string
  1637.     return '('.$this->_escape($s).')';
  1638. }
  1639.  
  1640. function _escape($s)
  1641. {
  1642.     //Add \ before \, ( and )
  1643.     return str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$s)));
  1644. }
  1645.  
  1646. function _putstream($s)
  1647. {
  1648.     $this->_out('stream');
  1649.     $this->_out($s);
  1650.     $this->_out('endstream');
  1651. }
  1652.  
  1653. function _out($s)
  1654. {
  1655.     //Add a line to the document
  1656.     if($this->state==2)
  1657.         $this->pages[$this->page].=$s."\n";
  1658.     else
  1659.         $this->buffer.=$s."\n";
  1660. }
  1661. //End of class
  1662. }
  1663.  
  1664. //Handle special IE contype request
  1665. if(isset($_SERVER['HTTP_USER_AGENT']&& $_SERVER['HTTP_USER_AGENT']=='contype')
  1666. {
  1667.     //header('Content-Type: application/pdf');
  1668.     //exit;
  1669. }
  1670.  
  1671. }

Documentation generated on Mon, 05 Jan 2009 20:37:22 +0100 by phpDocumentor 1.4.1