FPDF

The WooCommerce PDF & Print FPDF class.

Defined (1)

The class is defined in the following location(s).

/pdf/fpdf.php  
  1. class FPDF 
  2.  
  3.  
  4. var $page; //current page number 
  5.  
  6. var $n; //current object number 
  7.  
  8. var $offsets; //array of object offsets 
  9.  
  10. var $buffer; //buffer holding in-memory PDF 
  11.  
  12. var $pages; //array containing pages 
  13.  
  14. var $state; //current document state 
  15.  
  16. var $compress; //compression flag 
  17.  
  18. var $k; //scale factor (number of points in user unit) 
  19.  
  20. var $DefOrientation; //default orientation 
  21.  
  22. var $CurOrientation; //current orientation 
  23.  
  24. var $PageFormats; //available page formats 
  25.  
  26. var $DefPageFormat; //default page format 
  27.  
  28. var $CurPageFormat; //current page format 
  29.  
  30. var $PageSizes; //array storing non-default page sizes 
  31.  
  32. var $wPt, $hPt; //dimensions of current page in points 
  33.  
  34. var $w, $h; //dimensions of current page in user unit 
  35.  
  36. var $lMargin; //left margin 
  37.  
  38. var $tMargin; //top margin 
  39.  
  40. var $rMargin; //right margin 
  41.  
  42. var $bMargin; //page break margin 
  43.  
  44. var $cMargin; //cell margin 
  45.  
  46. var $x, $y; //current position in user unit 
  47.  
  48. var $lasth; //height of last printed cell 
  49.  
  50. var $LineWidth; //line width in user unit 
  51.  
  52. var $CoreFonts; //array of standard font names 
  53.  
  54. var $fonts; //array of used fonts 
  55.  
  56. var $FontFiles; //array of font files 
  57.  
  58. var $diffs; //array of encoding differences 
  59.  
  60. var $FontFamily; //current font family 
  61.  
  62. var $FontStyle; //current font style 
  63.  
  64. var $underline; //underlining flag 
  65.  
  66. var $CurrentFont; //current font info 
  67.  
  68. var $FontSizePt; //current font size in points 
  69.  
  70. var $FontSize; //current font size in user unit 
  71.  
  72. var $DrawColor; //commands for drawing color 
  73.  
  74. var $FillColor; //commands for filling color 
  75.  
  76. var $TextColor; //commands for text color 
  77.  
  78. var $ColorFlag; //indicates whether fill and text colors are different 
  79.  
  80. var $ws; //word spacing 
  81.  
  82. var $images; //array of used images 
  83.  
  84. var $PageLinks; //array of links in pages 
  85.  
  86. var $links; //array of internal links 
  87.  
  88. var $AutoPageBreak; //automatic page breaking 
  89.  
  90. var $PageBreakTrigger; //threshold used to trigger page breaks 
  91.  
  92. var $InHeader; //flag set when processing header 
  93.  
  94. var $InFooter; //flag set when processing footer 
  95.  
  96. var $ZoomMode; //zoom display mode 
  97.  
  98. var $LayoutMode; //layout display mode 
  99.  
  100. var $title; //title 
  101.  
  102. var $subject; //subject 
  103.  
  104. var $author; //author 
  105.  
  106. var $keywords; //keywords 
  107.  
  108. var $creator; //creator 
  109.  
  110. var $AliasNbPages; //alias for total number of pages 
  111.  
  112. var $PDFVersion; //PDF version number 
  113.  
  114.  
  115.  
  116. /******************************************************************************* 
  117.   
  118. * * 
  119.   
  120. * Public methods * 
  121.   
  122. * * 
  123.   
  124. *******************************************************************************/ 
  125.  
  126. function FPDF($orientation='P', $unit='mm', $format='A4') 
  127.  
  128.  
  129. //Some checks 
  130.  
  131. $this->_dochecks(); 
  132.  
  133. //Initialization of properties 
  134.  
  135. $this->page=0; 
  136.  
  137. $this->n=2; 
  138.  
  139. $this->buffer=''; 
  140.  
  141. $this->pages=array(); 
  142.  
  143. $this->PageSizes=array(); 
  144.  
  145. $this->state=0; 
  146.  
  147. $this->fonts=array(); 
  148.  
  149. $this->FontFiles=array(); 
  150.  
  151. $this->diffs=array(); 
  152.  
  153. $this->images=array(); 
  154.  
  155. $this->links=array(); 
  156.  
  157. $this->InHeader=false; 
  158.  
  159. $this->InFooter=false; 
  160.  
  161. $this->lasth=0; 
  162.  
  163. $this->FontFamily=''; 
  164.  
  165. $this->FontStyle=''; 
  166.  
  167. $this->FontSizePt=12; 
  168.  
  169. $this->underline=false; 
  170.  
  171. $this->DrawColor='0 G'; 
  172.  
  173. $this->FillColor='0 g'; 
  174.  
  175. $this->TextColor='0 g'; 
  176.  
  177. $this->ColorFlag=false; 
  178.  
  179. $this->ws=0; 
  180.  
  181. //Standard fonts 
  182.  
  183. $this->CoreFonts=array('courier'=>'Courier',  
  184.  
  185. 'courierB'=>'Courier-Bold',  
  186.  
  187. 'courierI'=>'Courier-Oblique',  
  188.  
  189. 'courierBI'=>'Courier-BoldOblique',  
  190.  
  191. 'helvetica'=>'Helvetica',  
  192.  
  193. 'helveticaB'=>'Helvetica-Bold',  
  194.  
  195. 'helveticaI'=>'Helvetica-Oblique',  
  196.  
  197. 'helveticaBI'=>'Helvetica-BoldOblique',  
  198.  
  199. 'times'=>'Times-Roman',  
  200.  
  201. 'timesB'=>'Times-Bold',  
  202.  
  203. 'timesI'=>'Times-Italic',  
  204.  
  205. 'timesBI'=>'Times-BoldItalic',  
  206.  
  207. 'symbol'=>'Symbol',  
  208.  
  209. 'zapfdingbats'=>'ZapfDingbats'); 
  210.  
  211. //Scale factor 
  212.  
  213. if($unit=='pt') 
  214.  
  215. $this->k=1; 
  216.  
  217. elseif($unit=='mm') 
  218.  
  219. $this->k=72/25.4; 
  220.  
  221. elseif($unit=='cm') 
  222.  
  223. $this->k=72/2.54; 
  224.  
  225. elseif($unit=='in') 
  226.  
  227. $this->k=72; 
  228.  
  229. else 
  230.  
  231. $this->Error('Incorrect unit: '.$unit); 
  232.  
  233. //Page format 
  234.  
  235. $this->PageFormats=array('a3'=>array(841.89, 1190.55), 'a4'=>array(595.28, 841.89), 'a5'=>array(420.94, 595.28),  
  236.  
  237. 'letter'=>array(612, 792), 'legal'=>array(612, 1008)); 
  238.  
  239. if(is_string($format)) 
  240.  
  241. $format=$this->_getpageformat($format); 
  242.  
  243. $this->DefPageFormat=$format; 
  244.  
  245. $this->CurPageFormat=$format; 
  246.  
  247. //Page orientation 
  248.  
  249. $orientation=strtolower($orientation); 
  250.  
  251. if($orientation=='p' || $orientation=='portrait') 
  252.  
  253.  
  254. $this->DefOrientation='P'; 
  255.  
  256. $this->w=$this->DefPageFormat[0]; 
  257.  
  258. $this->h=$this->DefPageFormat[1]; 
  259.  
  260.  
  261. elseif($orientation=='l' || $orientation=='landscape') 
  262.  
  263.  
  264. $this->DefOrientation='L'; 
  265.  
  266. $this->w=$this->DefPageFormat[1]; 
  267.  
  268. $this->h=$this->DefPageFormat[0]; 
  269.  
  270.  
  271. else 
  272.  
  273. $this->Error('Incorrect orientation: '.$orientation); 
  274.  
  275. $this->CurOrientation=$this->DefOrientation; 
  276.  
  277. $this->wPt=$this->w*$this->k; 
  278.  
  279. $this->hPt=$this->h*$this->k; 
  280.  
  281. //Page margins (1 cm) 
  282.  
  283. $margin=28.35/$this->k; 
  284.  
  285. $this->SetMargins($margin, $margin); 
  286.  
  287. //Interior cell margin (1 mm) 
  288.  
  289. $this->cMargin=$margin/10; 
  290.  
  291. //Line width (0.2 mm) 
  292.  
  293. $this->LineWidth=.567/$this->k; 
  294.  
  295. //Automatic page break 
  296.  
  297. $this->SetAutoPageBreak(true, 2*$margin); 
  298.  
  299. //Full width display mode 
  300.  
  301. $this->SetDisplayMode('fullwidth'); 
  302.  
  303. //Enable compression 
  304.  
  305. $this->SetCompression(true); 
  306.  
  307. //Set default PDF version number 
  308.  
  309. $this->PDFVersion='1.3'; 
  310.  
  311.  
  312.  
  313.  
  314. function SetMargins($left, $top, $right=null) 
  315.  
  316.  
  317. //Set left, top and right margins 
  318.  
  319. $this->lMargin=$left; 
  320.  
  321. $this->tMargin=$top; 
  322.  
  323. if($right===null) 
  324.  
  325. $right=$left; 
  326.  
  327. $this->rMargin=$right; 
  328.  
  329.  
  330.  
  331.  
  332. function SetLeftMargin($margin) 
  333.  
  334.  
  335. //Set left margin 
  336.  
  337. $this->lMargin=$margin; 
  338.  
  339. if($this->page>0 && $this->x<$margin) 
  340.  
  341. $this->x=$margin; 
  342.  
  343.  
  344.  
  345.  
  346. function SetTopMargin($margin) 
  347.  
  348.  
  349. //Set top margin 
  350.  
  351. $this->tMargin=$margin; 
  352.  
  353.  
  354.  
  355.  
  356. function SetRightMargin($margin) 
  357.  
  358.  
  359. //Set right margin 
  360.  
  361. $this->rMargin=$margin; 
  362.  
  363.  
  364.  
  365.  
  366. function SetAutoPageBreak($auto, $margin=0) 
  367.  
  368.  
  369. //Set auto page break mode and triggering margin 
  370.  
  371. $this->AutoPageBreak=$auto; 
  372.  
  373. $this->bMargin=$margin; 
  374.  
  375. $this->PageBreakTrigger=$this->h-$margin; 
  376.  
  377.  
  378.  
  379.  
  380. function SetDisplayMode($zoom, $layout='continuous') 
  381.  
  382.  
  383. //Set display mode in viewer 
  384.  
  385. if($zoom=='fullpage' || $zoom=='fullwidth' || $zoom=='real' || $zoom=='default' || !is_string($zoom)) 
  386.  
  387. $this->ZoomMode=$zoom; 
  388.  
  389. else 
  390.  
  391. $this->Error('Incorrect zoom display mode: '.$zoom); 
  392.  
  393. if($layout=='single' || $layout=='continuous' || $layout=='two' || $layout=='default') 
  394.  
  395. $this->LayoutMode=$layout; 
  396.  
  397. else 
  398.  
  399. $this->Error('Incorrect layout display mode: '.$layout); 
  400.  
  401.  
  402.  
  403.  
  404. function SetCompression($compress) 
  405.  
  406.  
  407. //Set page compression 
  408.  
  409. if(function_exists('gzcompress')) 
  410.  
  411. $this->compress=$compress; 
  412.  
  413. else 
  414.  
  415. $this->compress=false; 
  416.  
  417.  
  418.  
  419.  
  420. function SetTitle($title, $isUTF8=false) 
  421.  
  422.  
  423. //Title of document 
  424.  
  425. if($isUTF8) 
  426.  
  427. $title=$this->_UTF8toUTF16($title); 
  428.  
  429. $this->title=$title; 
  430.  
  431.  
  432.  
  433.  
  434. function SetSubject($subject, $isUTF8=false) 
  435.  
  436.  
  437. //Subject of document 
  438.  
  439. if($isUTF8) 
  440.  
  441. $subject=$this->_UTF8toUTF16($subject); 
  442.  
  443. $this->subject=$subject; 
  444.  
  445.  
  446.  
  447.  
  448. function SetAuthor($author, $isUTF8=false) 
  449.  
  450.  
  451. //Author of document 
  452.  
  453. if($isUTF8) 
  454.  
  455. $author=$this->_UTF8toUTF16($author); 
  456.  
  457. $this->author=$author; 
  458.  
  459.  
  460.  
  461.  
  462. function SetKeywords($keywords, $isUTF8=false) 
  463.  
  464.  
  465. //Keywords of document 
  466.  
  467. if($isUTF8) 
  468.  
  469. $keywords=$this->_UTF8toUTF16($keywords); 
  470.  
  471. $this->keywords=$keywords; 
  472.  
  473.  
  474.  
  475.  
  476. function SetCreator($creator, $isUTF8=false) 
  477.  
  478.  
  479. //Creator of document 
  480.  
  481. if($isUTF8) 
  482.  
  483. $creator=$this->_UTF8toUTF16($creator); 
  484.  
  485. $this->creator=$creator; 
  486.  
  487.  
  488.  
  489.  
  490. function AliasNbPages($alias='{nb}') 
  491.  
  492.  
  493. //Define an alias for total number of pages 
  494.  
  495. $this->AliasNbPages=$alias; 
  496.  
  497.  
  498.  
  499.  
  500. function Error($msg) 
  501.  
  502.  
  503. //Fatal error 
  504.  
  505. die('<b>FPDF error:</b> '.$msg); 
  506.  
  507.  
  508.  
  509.  
  510. function Open() 
  511.  
  512.  
  513. //Begin document 
  514.  
  515. $this->state=1; 
  516.  
  517.  
  518.  
  519.  
  520. function Close() 
  521.  
  522.  
  523. //Terminate document 
  524.  
  525. if($this->state==3) 
  526.  
  527. return; 
  528.  
  529. if($this->page==0) 
  530.  
  531. $this->AddPage(); 
  532.  
  533. //Page footer 
  534.  
  535. $this->InFooter=true; 
  536.  
  537. $this->Footer(); 
  538.  
  539. $this->InFooter=false; 
  540.  
  541. //Close page 
  542.  
  543. $this->_endpage(); 
  544.  
  545. //Close document 
  546.  
  547. $this->_enddoc(); 
  548.  
  549.  
  550.  
  551.  
  552. function AddPage($orientation='', $format='') 
  553.  
  554.  
  555. //Start a new page 
  556.  
  557. if($this->state==0) 
  558.  
  559. $this->Open(); 
  560.  
  561. $family=$this->FontFamily; 
  562.  
  563. $style=$this->FontStyle.($this->underline ? 'U' : ''); 
  564.  
  565. $size=$this->FontSizePt; 
  566.  
  567. $lw=$this->LineWidth; 
  568.  
  569. $dc=$this->DrawColor; 
  570.  
  571. $fc=$this->FillColor; 
  572.  
  573. $tc=$this->TextColor; 
  574.  
  575. $cf=$this->ColorFlag; 
  576.  
  577. if($this->page>0) 
  578.  
  579.  
  580. //Page footer 
  581.  
  582. $this->InFooter=true; 
  583.  
  584. $this->Footer(); 
  585.  
  586. $this->InFooter=false; 
  587.  
  588. //Close page 
  589.  
  590. $this->_endpage(); 
  591.  
  592.  
  593. //Start new page 
  594.  
  595. $this->_beginpage($orientation, $format); 
  596.  
  597. //Set line cap style to square 
  598.  
  599. $this->_out('2 J'); 
  600.  
  601. //Set line width 
  602.  
  603. $this->LineWidth=$lw; 
  604.  
  605. $this->_out(sprintf('%.2F w', $lw*$this->k)); 
  606.  
  607. //Set font 
  608.  
  609. if($family) 
  610.  
  611. $this->SetFont($family, $style, $size); 
  612.  
  613. //Set colors 
  614.  
  615. $this->DrawColor=$dc; 
  616.  
  617. if($dc!='0 G') 
  618.  
  619. $this->_out($dc); 
  620.  
  621. $this->FillColor=$fc; 
  622.  
  623. if($fc!='0 g') 
  624.  
  625. $this->_out($fc); 
  626.  
  627. $this->TextColor=$tc; 
  628.  
  629. $this->ColorFlag=$cf; 
  630.  
  631. //Page header 
  632.  
  633. $this->InHeader=true; 
  634.  
  635. $this->Header(); 
  636.  
  637. $this->InHeader=false; 
  638.  
  639. //Restore line width 
  640.  
  641. if($this->LineWidth!=$lw) 
  642.  
  643.  
  644. $this->LineWidth=$lw; 
  645.  
  646. $this->_out(sprintf('%.2F w', $lw*$this->k)); 
  647.  
  648.  
  649. //Restore font 
  650.  
  651. if($family) 
  652.  
  653. $this->SetFont($family, $style, $size); 
  654.  
  655. //Restore colors 
  656.  
  657. if($this->DrawColor!=$dc) 
  658.  
  659.  
  660. $this->DrawColor=$dc; 
  661.  
  662. $this->_out($dc); 
  663.  
  664.  
  665. if($this->FillColor!=$fc) 
  666.  
  667.  
  668. $this->FillColor=$fc; 
  669.  
  670. $this->_out($fc); 
  671.  
  672.  
  673. $this->TextColor=$tc; 
  674.  
  675. $this->ColorFlag=$cf; 
  676.  
  677.  
  678.  
  679.  
  680. function Header() 
  681.  
  682.  
  683. //To be implemented in your own inherited class 
  684.  
  685.  
  686.  
  687.  
  688. function Footer() 
  689.  
  690.  
  691. //To be implemented in your own inherited class 
  692.  
  693.  
  694.  
  695.  
  696. function PageNo() 
  697.  
  698.  
  699. //Get current page number 
  700.  
  701. return $this->page; 
  702.  
  703.  
  704.  
  705.  
  706. function SetDrawColor($r, $g=null, $b=null) 
  707.  
  708.  
  709. //Set color for all stroking operations 
  710.  
  711. if(($r==0 && $g==0 && $b==0) || $g===null) 
  712.  
  713. $this->DrawColor=sprintf('%.3F G', $r/255); 
  714.  
  715. else 
  716.  
  717. $this->DrawColor=sprintf('%.3F %.3F %.3F RG', $r/255, $g/255, $b/255); 
  718.  
  719. if($this->page>0) 
  720.  
  721. $this->_out($this->DrawColor); 
  722.  
  723.  
  724.  
  725.  
  726. function SetFillColor($r, $g=null, $b=null) 
  727.  
  728.  
  729. //Set color for all filling operations 
  730.  
  731. if(($r==0 && $g==0 && $b==0) || $g===null) 
  732.  
  733. $this->FillColor=sprintf('%.3F g', $r/255); 
  734.  
  735. else 
  736.  
  737. $this->FillColor=sprintf('%.3F %.3F %.3F rg', $r/255, $g/255, $b/255); 
  738.  
  739. $this->ColorFlag=($this->FillColor!=$this->TextColor); 
  740.  
  741. if($this->page>0) 
  742.  
  743. $this->_out($this->FillColor); 
  744.  
  745.  
  746.  
  747.  
  748. function SetTextColor($r, $g=null, $b=null) 
  749.  
  750.  
  751. //Set color for text 
  752.  
  753. if(($r==0 && $g==0 && $b==0) || $g===null) 
  754.  
  755. $this->TextColor=sprintf('%.3F g', $r/255); 
  756.  
  757. else 
  758.  
  759. $this->TextColor=sprintf('%.3F %.3F %.3F rg', $r/255, $g/255, $b/255); 
  760.  
  761. $this->ColorFlag=($this->FillColor!=$this->TextColor); 
  762.  
  763.  
  764.  
  765.  
  766. function GetStringWidth($s) 
  767.  
  768.  
  769. //Get width of a string in the current font 
  770.  
  771. $s=(string)$s; 
  772.  
  773. $cw=&$this->CurrentFont['cw']; 
  774.  
  775. $w=0; 
  776.  
  777. $l=strlen($s); 
  778.  
  779. for($i=0;$i<$l;$i++) 
  780.  
  781. $w+=$cw[$s[$i]]; 
  782.  
  783. return $w*$this->FontSize/1000; 
  784.  
  785.  
  786.  
  787.  
  788. function SetLineWidth($width) 
  789.  
  790.  
  791. //Set line width 
  792.  
  793. $this->LineWidth=$width; 
  794.  
  795. if($this->page>0) 
  796.  
  797. $this->_out(sprintf('%.2F w', $width*$this->k)); 
  798.  
  799.  
  800.  
  801.  
  802. function Line($x1, $y1, $x2, $y2) 
  803.  
  804.  
  805. //Draw a line 
  806.  
  807. $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)); 
  808.  
  809.  
  810.  
  811.  
  812. function Rect($x, $y, $w, $h, $style='') 
  813.  
  814.  
  815. //Draw a rectangle 
  816.  
  817. if($style=='F') 
  818.  
  819. $op='f'; 
  820.  
  821. elseif($style=='FD' || $style=='DF') 
  822.  
  823. $op='B'; 
  824.  
  825. else 
  826.  
  827. $op='S'; 
  828.  
  829. $this->_out(sprintf('%.2F %.2F %.2F %.2F re %s', $x*$this->k, ($this->h-$y)*$this->k, $w*$this->k, -$h*$this->k, $op)); 
  830.  
  831.  
  832.  
  833.  
  834. function AddFont($family, $style='', $file='') 
  835.  
  836.  
  837. //Add a TrueType or Type1 font 
  838.  
  839. $family=strtolower($family); 
  840.  
  841. if($file=='') 
  842.  
  843. $file=str_replace(' ', '', $family).strtolower($style).'.php'; 
  844.  
  845. if($family=='arial') 
  846.  
  847. $family='helvetica'; 
  848.  
  849. $style=strtoupper($style); 
  850.  
  851. if($style=='IB') 
  852.  
  853. $style='BI'; 
  854.  
  855. $fontkey=$family.$style; 
  856.  
  857. if(isset($this->fonts[$fontkey])) 
  858.  
  859. return; 
  860.  
  861. include($this->_getfontpath().$file); 
  862.  
  863. if(!isset($name)) 
  864.  
  865. $this->Error('Could not include font definition file'); 
  866.  
  867. $i=count($this->fonts)+1; 
  868.  
  869. $this->fonts[$fontkey]=array('i'=>$i, 'type'=>$type, 'name'=>$name, 'desc'=>$desc, 'up'=>$up, 'ut'=>$ut, 'cw'=>$cw, 'enc'=>$enc, 'file'=>$file); 
  870.  
  871. if($diff) 
  872.  
  873.  
  874. //Search existing encodings 
  875.  
  876. $d=0; 
  877.  
  878. $nb=count($this->diffs); 
  879.  
  880. for($i=1;$i<=$nb;$i++) 
  881.  
  882.  
  883. if($this->diffs[$i]==$diff) 
  884.  
  885.  
  886. $d=$i; 
  887.  
  888. break; 
  889.  
  890.  
  891.  
  892. if($d==0) 
  893.  
  894.  
  895. $d=$nb+1; 
  896.  
  897. $this->diffs[$d]=$diff; 
  898.  
  899.  
  900. $this->fonts[$fontkey]['diff']=$d; 
  901.  
  902.  
  903. if($file) 
  904.  
  905.  
  906. if($type=='TrueType') 
  907.  
  908. $this->FontFiles[$file]=array('length1'=>$originalsize); 
  909.  
  910. else 
  911.  
  912. $this->FontFiles[$file]=array('length1'=>$size1, 'length2'=>$size2); 
  913.  
  914.  
  915.  
  916.  
  917.  
  918. function SetFont($family, $style='', $size=0) 
  919.  
  920.  
  921. //Select a font; size given in points 
  922.  
  923. global $fpdf_charwidths; 
  924.  
  925.  
  926.  
  927. $family=strtolower($family); 
  928.  
  929. if($family=='') 
  930.  
  931. $family=$this->FontFamily; 
  932.  
  933. if($family=='arial') 
  934.  
  935. $family='helvetica'; 
  936.  
  937. elseif($family=='symbol' || $family=='zapfdingbats') 
  938.  
  939. $style=''; 
  940.  
  941. $style=strtoupper($style); 
  942.  
  943. if(strpos($style, 'U')!==false) 
  944.  
  945.  
  946. $this->underline=true; 
  947.  
  948. $style=str_replace('U', '', $style); 
  949.  
  950.  
  951. else 
  952.  
  953. $this->underline=false; 
  954.  
  955. if($style=='IB') 
  956.  
  957. $style='BI'; 
  958.  
  959. if($size==0) 
  960.  
  961. $size=$this->FontSizePt; 
  962.  
  963. //Test if font is already selected 
  964.  
  965. if($this->FontFamily==$family && $this->FontStyle==$style && $this->FontSizePt==$size) 
  966.  
  967. return; 
  968.  
  969. //Test if used for the first time 
  970.  
  971. $fontkey=$family.$style; 
  972.  
  973. if(!isset($this->fonts[$fontkey])) 
  974.  
  975.  
  976. //Check if one of the standard fonts 
  977.  
  978. if(isset($this->CoreFonts[$fontkey])) 
  979.  
  980.  
  981. if(!isset($fpdf_charwidths[$fontkey])) 
  982.  
  983.  
  984. //Load metric file 
  985.  
  986. $file=$family; 
  987.  
  988. if($family=='times' || $family=='helvetica') 
  989.  
  990. $file.=strtolower($style); 
  991.  
  992. include($this->_getfontpath().$file.'.php'); 
  993.  
  994. if(!isset($fpdf_charwidths[$fontkey])) 
  995.  
  996. $this->Error('Could not include font metric file'); 
  997.  
  998.  
  999. $i=count($this->fonts)+1; 
  1000.  
  1001. $name=$this->CoreFonts[$fontkey]; 
  1002.  
  1003. $cw=$fpdf_charwidths[$fontkey]; 
  1004.  
  1005. $this->fonts[$fontkey]=array('i'=>$i, 'type'=>'core', 'name'=>$name, 'up'=>-100, 'ut'=>50, 'cw'=>$cw); 
  1006.  
  1007.  
  1008. else 
  1009.  
  1010. $this->Error('Undefined font: '.$family.' '.$style); 
  1011.  
  1012.  
  1013. //Select it 
  1014.  
  1015. $this->FontFamily=$family; 
  1016.  
  1017. $this->FontStyle=$style; 
  1018.  
  1019. $this->FontSizePt=$size; 
  1020.  
  1021. $this->FontSize=$size/$this->k; 
  1022.  
  1023. $this->CurrentFont=&$this->fonts[$fontkey]; 
  1024.  
  1025. if($this->page>0) 
  1026.  
  1027. $this->_out(sprintf('BT /F%d %.2F Tf ET', $this->CurrentFont['i'], $this->FontSizePt)); 
  1028.  
  1029.  
  1030.  
  1031.  
  1032. function SetFontSize($size) 
  1033.  
  1034.  
  1035. //Set font size in points 
  1036.  
  1037. if($this->FontSizePt==$size) 
  1038.  
  1039. return; 
  1040.  
  1041. $this->FontSizePt=$size; 
  1042.  
  1043. $this->FontSize=$size/$this->k; 
  1044.  
  1045. if($this->page>0) 
  1046.  
  1047. $this->_out(sprintf('BT /F%d %.2F Tf ET', $this->CurrentFont['i'], $this->FontSizePt)); 
  1048.  
  1049.  
  1050.  
  1051.  
  1052. function AddLink() 
  1053.  
  1054.  
  1055. //Create a new internal link 
  1056.  
  1057. $n=count($this->links)+1; 
  1058.  
  1059. $this->links[$n]=array(0, 0); 
  1060.  
  1061. return $n; 
  1062.  
  1063.  
  1064.  
  1065.  
  1066. function SetLink($link, $y=0, $page=-1) 
  1067.  
  1068.  
  1069. //Set destination of internal link 
  1070.  
  1071. if($y==-1) 
  1072.  
  1073. $y=$this->y; 
  1074.  
  1075. if($page==-1) 
  1076.  
  1077. $page=$this->page; 
  1078.  
  1079. $this->links[$link]=array($page, $y); 
  1080.  
  1081.  
  1082.  
  1083.  
  1084. function Link($x, $y, $w, $h, $link) 
  1085.  
  1086.  
  1087. //Put a link on the page 
  1088.  
  1089. $this->PageLinks[$this->page][]=array($x*$this->k, $this->hPt-$y*$this->k, $w*$this->k, $h*$this->k, $link); 
  1090.  
  1091.  
  1092.  
  1093.  
  1094. function Text($x, $y, $txt) 
  1095.  
  1096.  
  1097. //Output a string 
  1098.  
  1099. $s=sprintf('BT %.2F %.2F Td (%s) Tj ET', $x*$this->k, ($this->h-$y)*$this->k, $this->_escape($txt)); 
  1100.  
  1101. if($this->underline && $txt!='') 
  1102.  
  1103. $s.=' '.$this->_dounderline($x, $y, $txt); 
  1104.  
  1105. if($this->ColorFlag) 
  1106.  
  1107. $s='q '.$this->TextColor.' '.$s.' Q'; 
  1108.  
  1109. $this->_out($s); 
  1110.  
  1111.  
  1112.  
  1113.  
  1114. function AcceptPageBreak() 
  1115.  
  1116.  
  1117. //Accept automatic page break or not 
  1118.  
  1119. return $this->AutoPageBreak; 
  1120.  
  1121.  
  1122.  
  1123.  
  1124. function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='') 
  1125.  
  1126.  
  1127. //Output a cell 
  1128.  
  1129. $k=$this->k; 
  1130.  
  1131. if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak()) 
  1132.  
  1133.  
  1134. //Automatic page break 
  1135.  
  1136. $x=$this->x; 
  1137.  
  1138. $ws=$this->ws; 
  1139.  
  1140. if($ws>0) 
  1141.  
  1142.  
  1143. $this->ws=0; 
  1144.  
  1145. $this->_out('0 Tw'); 
  1146.  
  1147.  
  1148. $this->AddPage($this->CurOrientation, $this->CurPageFormat); 
  1149.  
  1150. $this->x=$x; 
  1151.  
  1152. if($ws>0) 
  1153.  
  1154.  
  1155. $this->ws=$ws; 
  1156.  
  1157. $this->_out(sprintf('%.3F Tw', $ws*$k)); 
  1158.  
  1159.  
  1160.  
  1161. if($w==0) 
  1162.  
  1163. $w=$this->w-$this->rMargin-$this->x; 
  1164.  
  1165. $s=''; 
  1166.  
  1167. if($fill || $border==1) 
  1168.  
  1169.  
  1170. if($fill) 
  1171.  
  1172. $op=($border==1) ? 'B' : 'f'; 
  1173.  
  1174. else 
  1175.  
  1176. $op='S'; 
  1177.  
  1178. $s=sprintf('%.2F %.2F %.2F %.2F re %s ', $this->x*$k, ($this->h-$this->y)*$k, $w*$k, -$h*$k, $op); 
  1179.  
  1180.  
  1181. if(is_string($border)) 
  1182.  
  1183.  
  1184. $x=$this->x; 
  1185.  
  1186. $y=$this->y; 
  1187.  
  1188. if(strpos($border, 'L')!==false) 
  1189.  
  1190. $s.=sprintf('%.2F %.2F m %.2F %.2F l S ', $x*$k, ($this->h-$y)*$k, $x*$k, ($this->h-($y+$h))*$k); 
  1191.  
  1192. if(strpos($border, 'T')!==false) 
  1193.  
  1194. $s.=sprintf('%.2F %.2F m %.2F %.2F l S ', $x*$k, ($this->h-$y)*$k, ($x+$w)*$k, ($this->h-$y)*$k); 
  1195.  
  1196. if(strpos($border, 'R')!==false) 
  1197.  
  1198. $s.=sprintf('%.2F %.2F m %.2F %.2F l S ', ($x+$w)*$k, ($this->h-$y)*$k, ($x+$w)*$k, ($this->h-($y+$h))*$k); 
  1199.  
  1200. if(strpos($border, 'B')!==false) 
  1201.  
  1202. $s.=sprintf('%.2F %.2F m %.2F %.2F l S ', $x*$k, ($this->h-($y+$h))*$k, ($x+$w)*$k, ($this->h-($y+$h))*$k); 
  1203.  
  1204.  
  1205. if($txt!=='') 
  1206.  
  1207.  
  1208. if($align=='R') 
  1209.  
  1210. $dx=$w-$this->cMargin-$this->GetStringWidth($txt); 
  1211.  
  1212. elseif($align=='C') 
  1213.  
  1214. $dx=($w-$this->GetStringWidth($txt))/2; 
  1215.  
  1216. else 
  1217.  
  1218. $dx=$this->cMargin; 
  1219.  
  1220. if($this->ColorFlag) 
  1221.  
  1222. $s.='q '.$this->TextColor.' '; 
  1223.  
  1224. $txt2=str_replace(')', '\\)', str_replace('(', '\\(', str_replace('\\', '\\\\', $txt))); 
  1225.  
  1226. $s.=sprintf('BT %.2F %.2F Td (%s) Tj ET', ($this->x+$dx)*$k, ($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k, $txt2); 
  1227.  
  1228. if($this->underline) 
  1229.  
  1230. $s.=' '.$this->_dounderline($this->x+$dx, $this->y+.5*$h+.3*$this->FontSize, $txt); 
  1231.  
  1232. if($this->ColorFlag) 
  1233.  
  1234. $s.=' Q'; 
  1235.  
  1236. if($link) 
  1237.  
  1238. $this->Link($this->x+$dx, $this->y+.5*$h-.5*$this->FontSize, $this->GetStringWidth($txt), $this->FontSize, $link); 
  1239.  
  1240.  
  1241. if($s) 
  1242.  
  1243. $this->_out($s); 
  1244.  
  1245. $this->lasth=$h; 
  1246.  
  1247. if($ln>0) 
  1248.  
  1249.  
  1250. //Go to next line 
  1251.  
  1252. $this->y+=$h; 
  1253.  
  1254. if($ln==1) 
  1255.  
  1256. $this->x=$this->lMargin; 
  1257.  
  1258.  
  1259. else 
  1260.  
  1261. $this->x+=$w; 
  1262.  
  1263.  
  1264.  
  1265.  
  1266. function MultiCell($w, $h, $txt, $border=0, $align='J', $fill=false) 
  1267.  
  1268.  
  1269. //Output text with automatic or explicit line breaks 
  1270.  
  1271. $cw=&$this->CurrentFont['cw']; 
  1272.  
  1273. if($w==0) 
  1274.  
  1275. $w=$this->w-$this->rMargin-$this->x; 
  1276.  
  1277. $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; 
  1278.  
  1279. $s=str_replace("\r", '', $txt); 
  1280.  
  1281. $nb=strlen($s); 
  1282.  
  1283. if($nb>0 && $s[$nb-1]=="\n") 
  1284.  
  1285. $nb--; 
  1286.  
  1287. $b=0; 
  1288.  
  1289. if($border) 
  1290.  
  1291.  
  1292. if($border==1) 
  1293.  
  1294.  
  1295. $border='LTRB'; 
  1296.  
  1297. $b='LRT'; 
  1298.  
  1299. $b2='LR'; 
  1300.  
  1301.  
  1302. else 
  1303.  
  1304.  
  1305. $b2=''; 
  1306.  
  1307. if(strpos($border, 'L')!==false) 
  1308.  
  1309. $b2.='L'; 
  1310.  
  1311. if(strpos($border, 'R')!==false) 
  1312.  
  1313. $b2.='R'; 
  1314.  
  1315. $b=(strpos($border, 'T')!==false) ? $b2.'T' : $b2; 
  1316.  
  1317.  
  1318.  
  1319. $sep=-1; 
  1320.  
  1321. $i=0; 
  1322.  
  1323. $j=0; 
  1324.  
  1325. $l=0; 
  1326.  
  1327. $ns=0; 
  1328.  
  1329. $nl=1; 
  1330.  
  1331. while($i<$nb) 
  1332.  
  1333.  
  1334. //Get next character 
  1335.  
  1336. $c=$s[$i]; 
  1337.  
  1338. if($c=="\n") 
  1339.  
  1340.  
  1341. //Explicit line break 
  1342.  
  1343. if($this->ws>0) 
  1344.  
  1345.  
  1346. $this->ws=0; 
  1347.  
  1348. $this->_out('0 Tw'); 
  1349.  
  1350.  
  1351. $this->Cell($w, $h, substr($s, $j, $i-$j), $b, 2, $align, $fill); 
  1352.  
  1353. $i++; 
  1354.  
  1355. $sep=-1; 
  1356.  
  1357. $j=$i; 
  1358.  
  1359. $l=0; 
  1360.  
  1361. $ns=0; 
  1362.  
  1363. $nl++; 
  1364.  
  1365. if($border && $nl==2) 
  1366.  
  1367. $b=$b2; 
  1368.  
  1369. continue; 
  1370.  
  1371.  
  1372. if($c==' ') 
  1373.  
  1374.  
  1375. $sep=$i; 
  1376.  
  1377. $ls=$l; 
  1378.  
  1379. $ns++; 
  1380.  
  1381.  
  1382. $l+=$cw[$c]; 
  1383.  
  1384. if($l>$wmax) 
  1385.  
  1386.  
  1387. //Automatic line break 
  1388.  
  1389. if($sep==-1) 
  1390.  
  1391.  
  1392. if($i==$j) 
  1393.  
  1394. $i++; 
  1395.  
  1396. if($this->ws>0) 
  1397.  
  1398.  
  1399. $this->ws=0; 
  1400.  
  1401. $this->_out('0 Tw'); 
  1402.  
  1403.  
  1404. $this->Cell($w, $h, substr($s, $j, $i-$j), $b, 2, $align, $fill); 
  1405.  
  1406.  
  1407. else 
  1408.  
  1409.  
  1410. if($align=='J') 
  1411.  
  1412.  
  1413. $this->ws=($ns>1) ? ($wmax-$ls)/1000*$this->FontSize/($ns-1) : 0; 
  1414.  
  1415. $this->_out(sprintf('%.3F Tw', $this->ws*$this->k)); 
  1416.  
  1417.  
  1418. $this->Cell($w, $h, substr($s, $j, $sep-$j), $b, 2, $align, $fill); 
  1419.  
  1420. $i=$sep+1; 
  1421.  
  1422.  
  1423. $sep=-1; 
  1424.  
  1425. $j=$i; 
  1426.  
  1427. $l=0; 
  1428.  
  1429. $ns=0; 
  1430.  
  1431. $nl++; 
  1432.  
  1433. if($border && $nl==2) 
  1434.  
  1435. $b=$b2; 
  1436.  
  1437.  
  1438. else 
  1439.  
  1440. $i++; 
  1441.  
  1442.  
  1443. //Last chunk 
  1444.  
  1445. if($this->ws>0) 
  1446.  
  1447.  
  1448. $this->ws=0; 
  1449.  
  1450. $this->_out('0 Tw'); 
  1451.  
  1452.  
  1453. if($border && strpos($border, 'B')!==false) 
  1454.  
  1455. $b.='B'; 
  1456.  
  1457. $this->Cell($w, $h, substr($s, $j, $i-$j), $b, 2, $align, $fill); 
  1458.  
  1459. $this->x=$this->lMargin; 
  1460.  
  1461.  
  1462.  
  1463.  
  1464. function Write($h, $txt, $link='') 
  1465.  
  1466.  
  1467. //Output text in flowing mode 
  1468.  
  1469. $cw=&$this->CurrentFont['cw']; 
  1470.  
  1471. $w=$this->w-$this->rMargin-$this->x; 
  1472.  
  1473. $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; 
  1474.  
  1475. $s=str_replace("\r", '', $txt); 
  1476.  
  1477. $nb=strlen($s); 
  1478.  
  1479. $sep=-1; 
  1480.  
  1481. $i=0; 
  1482.  
  1483. $j=0; 
  1484.  
  1485. $l=0; 
  1486.  
  1487. $nl=1; 
  1488.  
  1489. while($i<$nb) 
  1490.  
  1491.  
  1492. //Get next character 
  1493.  
  1494. $c=$s[$i]; 
  1495.  
  1496. if($c=="\n") 
  1497.  
  1498.  
  1499. //Explicit line break 
  1500.  
  1501. $this->Cell($w, $h, substr($s, $j, $i-$j), 0, 2, '', 0, $link); 
  1502.  
  1503. $i++; 
  1504.  
  1505. $sep=-1; 
  1506.  
  1507. $j=$i; 
  1508.  
  1509. $l=0; 
  1510.  
  1511. if($nl==1) 
  1512.  
  1513.  
  1514. $this->x=$this->lMargin; 
  1515.  
  1516. $w=$this->w-$this->rMargin-$this->x; 
  1517.  
  1518. $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; 
  1519.  
  1520.  
  1521. $nl++; 
  1522.  
  1523. continue; 
  1524.  
  1525.  
  1526. if($c==' ') 
  1527.  
  1528. $sep=$i; 
  1529.  
  1530. $l+=$cw[$c]; 
  1531.  
  1532. if($l>$wmax) 
  1533.  
  1534.  
  1535. //Automatic line break 
  1536.  
  1537. if($sep==-1) 
  1538.  
  1539.  
  1540. if($this->x>$this->lMargin) 
  1541.  
  1542.  
  1543. //Move to next line 
  1544.  
  1545. $this->x=$this->lMargin; 
  1546.  
  1547. $this->y+=$h; 
  1548.  
  1549. $w=$this->w-$this->rMargin-$this->x; 
  1550.  
  1551. $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; 
  1552.  
  1553. $i++; 
  1554.  
  1555. $nl++; 
  1556.  
  1557. continue; 
  1558.  
  1559.  
  1560. if($i==$j) 
  1561.  
  1562. $i++; 
  1563.  
  1564. $this->Cell($w, $h, substr($s, $j, $i-$j), 0, 2, '', 0, $link); 
  1565.  
  1566.  
  1567. else 
  1568.  
  1569.  
  1570. $this->Cell($w, $h, substr($s, $j, $sep-$j), 0, 2, '', 0, $link); 
  1571.  
  1572. $i=$sep+1; 
  1573.  
  1574.  
  1575. $sep=-1; 
  1576.  
  1577. $j=$i; 
  1578.  
  1579. $l=0; 
  1580.  
  1581. if($nl==1) 
  1582.  
  1583.  
  1584. $this->x=$this->lMargin; 
  1585.  
  1586. $w=$this->w-$this->rMargin-$this->x; 
  1587.  
  1588. $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; 
  1589.  
  1590.  
  1591. $nl++; 
  1592.  
  1593.  
  1594. else 
  1595.  
  1596. $i++; 
  1597.  
  1598.  
  1599. //Last chunk 
  1600.  
  1601. if($i!=$j) 
  1602.  
  1603. $this->Cell($l/1000*$this->FontSize, $h, substr($s, $j), 0, 0, '', 0, $link); 
  1604.  
  1605.  
  1606.  
  1607.  
  1608. function Ln($h=null) 
  1609.  
  1610.  
  1611. //Line feed; default value is last cell height 
  1612.  
  1613. $this->x=$this->lMargin; 
  1614.  
  1615. if($h===null) 
  1616.  
  1617. $this->y+=$this->lasth; 
  1618.  
  1619. else 
  1620.  
  1621. $this->y+=$h; 
  1622.  
  1623.  
  1624.  
  1625.  
  1626. function Image($file, $x=null, $y=null, $w=0, $h=0, $type='', $link='') 
  1627.  
  1628.  
  1629. //Put an image on the page 
  1630.  
  1631. if(!isset($this->images[$file])) 
  1632.  
  1633.  
  1634. //First use of this image, get info 
  1635.  
  1636. if($type=='') 
  1637.  
  1638.  
  1639. $pos=strrpos($file, '.'); 
  1640.  
  1641. if(!$pos) 
  1642.  
  1643. $this->Error('Image file has no extension and no type was specified: '.$file); 
  1644.  
  1645. $type=substr($file, $pos+1); 
  1646.  
  1647.  
  1648. $type=strtolower($type); 
  1649.  
  1650. if($type=='jpeg') 
  1651.  
  1652. $type='jpg'; 
  1653.  
  1654. $mtd='_parse'.$type; 
  1655.  
  1656. if(!method_exists($this, $mtd)) 
  1657.  
  1658. $this->Error('Unsupported image type: '.$type); 
  1659.  
  1660. $info=$this->$mtd($file); 
  1661.  
  1662. $info['i']=count($this->images)+1; 
  1663.  
  1664. $this->images[$file]=$info; 
  1665.  
  1666.  
  1667. else 
  1668.  
  1669. $info=$this->images[$file]; 
  1670.  
  1671. //Automatic width and height calculation if needed 
  1672.  
  1673. if($w==0 && $h==0) 
  1674.  
  1675.  
  1676. //Put image at 72 dpi 
  1677.  
  1678. $w=$info['w']/$this->k; 
  1679.  
  1680. $h=$info['h']/$this->k; 
  1681.  
  1682.  
  1683. elseif($w==0) 
  1684.  
  1685. $w=$h*$info['w']/$info['h']; 
  1686.  
  1687. elseif($h==0) 
  1688.  
  1689. $h=$w*$info['h']/$info['w']; 
  1690.  
  1691. //Flowing mode 
  1692.  
  1693. if($y===null) 
  1694.  
  1695.  
  1696. if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak()) 
  1697.  
  1698.  
  1699. //Automatic page break 
  1700.  
  1701. $x2=$this->x; 
  1702.  
  1703. $this->AddPage($this->CurOrientation, $this->CurPageFormat); 
  1704.  
  1705. $this->x=$x2; 
  1706.  
  1707.  
  1708. $y=$this->y; 
  1709.  
  1710. $this->y+=$h; 
  1711.  
  1712.  
  1713. if($x===null) 
  1714.  
  1715. $x=$this->x; 
  1716.  
  1717. $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'])); 
  1718.  
  1719. if($link) 
  1720.  
  1721. $this->Link($x, $y, $w, $h, $link); 
  1722.  
  1723.  
  1724.  
  1725.  
  1726. function GetX() 
  1727.  
  1728.  
  1729. //Get x position 
  1730.  
  1731. return $this->x; 
  1732.  
  1733.  
  1734.  
  1735.  
  1736. function SetX($x) 
  1737.  
  1738.  
  1739. //Set x position 
  1740.  
  1741. if($x>=0) 
  1742.  
  1743. $this->x=$x; 
  1744.  
  1745. else 
  1746.  
  1747. $this->x=$this->w+$x; 
  1748.  
  1749.  
  1750.  
  1751.  
  1752. function GetY() 
  1753.  
  1754.  
  1755. //Get y position 
  1756.  
  1757. return $this->y; 
  1758.  
  1759.  
  1760.  
  1761.  
  1762. function SetY($y) 
  1763.  
  1764.  
  1765. //Set y position and reset x 
  1766.  
  1767. $this->x=$this->lMargin; 
  1768.  
  1769. if($y>=0) 
  1770.  
  1771. $this->y=$y; 
  1772.  
  1773. else 
  1774.  
  1775. $this->y=$this->h+$y; 
  1776.  
  1777.  
  1778.  
  1779.  
  1780. function SetXY($x, $y) 
  1781.  
  1782.  
  1783. //Set x and y positions 
  1784.  
  1785. $this->SetY($y); 
  1786.  
  1787. $this->SetX($x); 
  1788.  
  1789.  
  1790.  
  1791.  
  1792. function Output($name='', $dest='') 
  1793.  
  1794.  
  1795. ob_clean(); 
  1796. //Output PDF to some destination 
  1797.  
  1798. if($this->state<3) 
  1799.  
  1800. $this->Close(); 
  1801.  
  1802. $dest=strtoupper($dest); 
  1803.  
  1804. if($dest=='') 
  1805.  
  1806.  
  1807. if($name=='') 
  1808.  
  1809.  
  1810. $name='doc.pdf'; 
  1811.  
  1812. $dest='I'; 
  1813.  
  1814.  
  1815. else 
  1816.  
  1817. $dest='F'; 
  1818.  
  1819.  
  1820. switch($dest) 
  1821.  
  1822.  
  1823. case 'I': 
  1824.  
  1825. //Send to standard output 
  1826.  
  1827. if(ob_get_length()) 
  1828.  
  1829. $this->Error('Some data has already been output, can\'t send PDF file'); 
  1830.  
  1831. if(php_sapi_name()!='cli') 
  1832.  
  1833.  
  1834. //We send to a browser 
  1835.  
  1836. header('Content-Type: application/pdf'); 
  1837.  
  1838. if(headers_sent()) 
  1839.  
  1840. $this->Error('Some data has already been output, can\'t send PDF file'); 
  1841.  
  1842. header('Content-Length: '.strlen($this->buffer)); 
  1843.  
  1844. header('Content-Disposition: inline; filename="'.$name.'"'); 
  1845.  
  1846. header('Cache-Control: private, max-age=0, must-revalidate'); 
  1847.  
  1848. header('Pragma: public'); 
  1849.  
  1850. ini_set('zlib.output_compression', '0'); 
  1851.  
  1852.  
  1853. echo $this->buffer; 
  1854.  
  1855. break; 
  1856.  
  1857. case 'D': 
  1858.  
  1859. //Download file 
  1860.  
  1861. if(ob_get_length()) 
  1862.  
  1863. $this->Error('Some data has already been output, can\'t send PDF file'); 
  1864.  
  1865. header('Content-Type: application/x-download'); 
  1866.  
  1867. if(headers_sent()) 
  1868.  
  1869. $this->Error('Some data has already been output, can\'t send PDF file'); 
  1870.  
  1871. header('Content-Length: '.strlen($this->buffer)); 
  1872.  
  1873. header('Content-Disposition: attachment; filename="'.$name.'"'); 
  1874.  
  1875. header('Cache-Control: private, max-age=0, must-revalidate'); 
  1876.  
  1877. header('Pragma: public'); 
  1878.  
  1879. ini_set('zlib.output_compression', '0'); 
  1880.  
  1881. echo $this->buffer; 
  1882.  
  1883. break; 
  1884.  
  1885. case 'F': 
  1886.  
  1887. //Save to local file 
  1888.  
  1889. $f=fopen($name, 'wb'); 
  1890.  
  1891. if(!$f) 
  1892.  
  1893. $this->Error('Unable to create output file: '.$name); 
  1894.  
  1895. fwrite($f, $this->buffer, strlen($this->buffer)); 
  1896.  
  1897. fclose($f); 
  1898.  
  1899. break; 
  1900.  
  1901. case 'S': 
  1902.  
  1903. //Return as a string 
  1904.  
  1905. return $this->buffer; 
  1906.  
  1907. default: 
  1908.  
  1909. $this->Error('Incorrect output destination: '.$dest); 
  1910.  
  1911.  
  1912. return ''; 
  1913.  
  1914.  
  1915.  
  1916.  
  1917. /******************************************************************************* 
  1918.   
  1919. * * 
  1920.   
  1921. * Protected methods * 
  1922.   
  1923. * * 
  1924.   
  1925. *******************************************************************************/ 
  1926.  
  1927. function _dochecks() 
  1928.  
  1929.  
  1930. //Check availability of %F 
  1931.  
  1932. if(sprintf('%.1F', 1.0)!='1.0') 
  1933.  
  1934. $this->Error('This version of PHP is not supported'); 
  1935.  
  1936. //Check mbstring overloading 
  1937.  
  1938. if(ini_get('mbstring.func_overload') & 2) 
  1939.  
  1940. $this->Error('mbstring overloading must be disabled'); 
  1941.  
  1942. //Disable runtime magic quotes 
  1943.  
  1944. if(get_magic_quotes_runtime()) 
  1945.  
  1946. @set_magic_quotes_runtime(0); 
  1947.  
  1948.  
  1949.  
  1950.  
  1951. function _getpageformat($format) 
  1952.  
  1953.  
  1954. $format=strtolower($format); 
  1955.  
  1956. if(!isset($this->PageFormats[$format])) 
  1957.  
  1958. $this->Error('Unknown page format: '.$format); 
  1959.  
  1960. $a=$this->PageFormats[$format]; 
  1961.  
  1962. return array($a[0]/$this->k, $a[1]/$this->k); 
  1963.  
  1964.  
  1965.  
  1966.  
  1967. function _getfontpath() 
  1968.  
  1969.  
  1970. if(!defined('FPDF_FONTPATH') && is_dir(dirname(__FILE__).'/font')) 
  1971.  
  1972. define('FPDF_FONTPATH', dirname(__FILE__).'/font/'); 
  1973.  
  1974. return defined('FPDF_FONTPATH') ? FPDF_FONTPATH : ''; 
  1975.  
  1976.  
  1977.  
  1978.  
  1979. function _beginpage($orientation, $format) 
  1980.  
  1981.  
  1982. $this->page++; 
  1983.  
  1984. $this->pages[$this->page]=''; 
  1985.  
  1986. $this->state=2; 
  1987.  
  1988. $this->x=$this->lMargin; 
  1989.  
  1990. $this->y=$this->tMargin; 
  1991.  
  1992. $this->FontFamily=''; 
  1993.  
  1994. //Check page size 
  1995.  
  1996. if($orientation=='') 
  1997.  
  1998. $orientation=$this->DefOrientation; 
  1999.  
  2000. else 
  2001.  
  2002. $orientation=strtoupper($orientation[0]); 
  2003.  
  2004. if($format=='') 
  2005.  
  2006. $format=$this->DefPageFormat; 
  2007.  
  2008. else 
  2009.  
  2010.  
  2011. if(is_string($format)) 
  2012.  
  2013. $format=$this->_getpageformat($format); 
  2014.  
  2015.  
  2016. if($orientation!=$this->CurOrientation || $format[0]!=$this->CurPageFormat[0] || $format[1]!=$this->CurPageFormat[1]) 
  2017.  
  2018.  
  2019. //New size 
  2020.  
  2021. if($orientation=='P') 
  2022.  
  2023.  
  2024. $this->w=$format[0]; 
  2025.  
  2026. $this->h=$format[1]; 
  2027.  
  2028.  
  2029. else 
  2030.  
  2031.  
  2032. $this->w=$format[1]; 
  2033.  
  2034. $this->h=$format[0]; 
  2035.  
  2036.  
  2037. $this->wPt=$this->w*$this->k; 
  2038.  
  2039. $this->hPt=$this->h*$this->k; 
  2040.  
  2041. $this->PageBreakTrigger=$this->h-$this->bMargin; 
  2042.  
  2043. $this->CurOrientation=$orientation; 
  2044.  
  2045. $this->CurPageFormat=$format; 
  2046.  
  2047.  
  2048. if($orientation!=$this->DefOrientation || $format[0]!=$this->DefPageFormat[0] || $format[1]!=$this->DefPageFormat[1]) 
  2049.  
  2050. $this->PageSizes[$this->page]=array($this->wPt, $this->hPt); 
  2051.  
  2052.  
  2053.  
  2054.  
  2055. function _endpage() 
  2056.  
  2057.  
  2058. $this->state=1; 
  2059.  
  2060.  
  2061.  
  2062.  
  2063. function _escape($s) 
  2064.  
  2065.  
  2066. //Escape special characters in strings 
  2067.  
  2068. $s=str_replace('\\', '\\\\', $s); 
  2069.  
  2070. $s=str_replace('(', '\\(', $s); 
  2071.  
  2072. $s=str_replace(')', '\\)', $s); 
  2073.  
  2074. $s=str_replace("\r", '\\r', $s); 
  2075.  
  2076. return $s; 
  2077.  
  2078.  
  2079.  
  2080.  
  2081. function _textstring($s) 
  2082.  
  2083.  
  2084. //Format a text string 
  2085.  
  2086. return '('.$this->_escape($s).')'; 
  2087.  
  2088.  
  2089.  
  2090.  
  2091. function _UTF8toUTF16($s) 
  2092.  
  2093.  
  2094. //Convert UTF-8 to UTF-16BE with BOM 
  2095.  
  2096. $res="\xFE\xFF"; 
  2097.  
  2098. $nb=strlen($s); 
  2099.  
  2100. $i=0; 
  2101.  
  2102. while($i<$nb) 
  2103.  
  2104.  
  2105. $c1=ord($s[$i++]); 
  2106.  
  2107. if($c1>=224) 
  2108.  
  2109.  
  2110. //3-byte character 
  2111.  
  2112. $c2=ord($s[$i++]); 
  2113.  
  2114. $c3=ord($s[$i++]); 
  2115.  
  2116. $res.=chr((($c1 & 0x0F)<<4) + (($c2 & 0x3C)>>2)); 
  2117.  
  2118. $res.=chr((($c2 & 0x03)<<6) + ($c3 & 0x3F)); 
  2119.  
  2120.  
  2121. elseif($c1>=192) 
  2122.  
  2123.  
  2124. //2-byte character 
  2125.  
  2126. $c2=ord($s[$i++]); 
  2127.  
  2128. $res.=chr(($c1 & 0x1C)>>2); 
  2129.  
  2130. $res.=chr((($c1 & 0x03)<<6) + ($c2 & 0x3F)); 
  2131.  
  2132.  
  2133. else 
  2134.  
  2135.  
  2136. //Single-byte character 
  2137.  
  2138. $res.="\0".chr($c1); 
  2139.  
  2140.  
  2141.  
  2142. return $res; 
  2143.  
  2144.  
  2145.  
  2146.  
  2147. function _dounderline($x, $y, $txt) 
  2148.  
  2149.  
  2150. //Underline text 
  2151.  
  2152. $up=$this->CurrentFont['up']; 
  2153.  
  2154. $ut=$this->CurrentFont['ut']; 
  2155.  
  2156. $w=$this->GetStringWidth($txt)+$this->ws*substr_count($txt, ' '); 
  2157.  
  2158. 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); 
  2159.  
  2160.  
  2161.  
  2162.  
  2163. function _parsejpg($file) 
  2164.  
  2165.  
  2166. //Extract info from a JPEG file 
  2167.  
  2168. $a=getimagesize($file); 
  2169.  
  2170. if(!$a) { 
  2171. $makeitlocal = trim(get_option( 'siteurl' ), '/') . '/'; 
  2172. $file = str_replace($makeitlocal, '', $file); 
  2173. $a = getimagesize($file); 
  2174. if( !$a && strpos($file, 'http') !== FALSE ) { 
  2175. $this->Error('[Error] '.$file.' Missing or Please turn on "allow_url_fopen" on your server to allow insert images in PDF Document, more info here: http://stackoverflow.com/questions/3694240/add-allow-url-fopen-to-my-php-ini-using-htaccess'); 
  2176. if(!$a) { 
  2177. $a = getimagesize( './'. $file ); 
  2178.  
  2179. if(!$a) $a = array ( 0 => 18, 1 => 13, 2 => 2, 3 => 'width="18" height="13"', 'bits' => 8, 'channels' => 3, 'mime' => 'image/jpeg' ) ; 
  2180.  
  2181.  
  2182.  
  2183. if(!$a)  
  2184.  
  2185. $this->Error('Missing or incorrect image file: '.$file); 
  2186.  
  2187. if($a[2]!=2) 
  2188.  
  2189. $this->Error('Not a JPEG file: '.$file); 
  2190.  
  2191. if(!isset($a['channels']) || $a['channels']==3) 
  2192.  
  2193. $colspace='DeviceRGB'; 
  2194.  
  2195. elseif($a['channels']==4) 
  2196.  
  2197. $colspace='DeviceCMYK'; 
  2198.  
  2199. else 
  2200.  
  2201. $colspace='DeviceGray'; 
  2202.  
  2203. $bpc=isset($a['bits']) ? $a['bits'] : 8; 
  2204.  
  2205. //Read whole file 
  2206.  
  2207. $f=fopen($file, 'rb'); 
  2208.  
  2209. $data=''; 
  2210.  
  2211. while(!feof($f)) 
  2212.  
  2213. $data.=fread($f, 8192); 
  2214.  
  2215. fclose($f); 
  2216.  
  2217. return array('w'=>$a[0], 'h'=>$a[1], 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'DCTDecode', 'data'=>$data); 
  2218.  
  2219.  
  2220.  
  2221.  
  2222. function _parsepng($file) 
  2223.  
  2224. //Extract info from a PNG file 
  2225.  
  2226. $f=fopen($file, 'rb'); 
  2227.  
  2228. if(!$f) { 
  2229. $makeitlocal = trim(get_option( 'siteurl' ), '/') . '/'; 
  2230. $file = str_replace($makeitlocal, '', $file); 
  2231. $f=fopen($file, 'rb'); 
  2232. if( !$f && strpos($file, 'http') !== FALSE ) { 
  2233. $this->Error('[Error] '.$file.' Missing or Please turn on "allow_url_fopen" on your server to allow insert images in PDF Document, more info here: http://stackoverflow.com/questions/3694240/add-allow-url-fopen-to-my-php-ini-using-htaccess'); 
  2234. if(!$f) { 
  2235. $f=fopen( './'.$file, 'rb'); 
  2236.  
  2237. if(!$f) 
  2238.  
  2239. $this->Error('Can\'t open image file: '.$file); 
  2240.  
  2241. //Check signature 
  2242.  
  2243. if($this->_readstream($f, 8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) 
  2244.  
  2245. $this->Error('Not a PNG file: '.$file); 
  2246.  
  2247. //Read header chunk 
  2248.  
  2249. $this->_readstream($f, 4); 
  2250.  
  2251. if($this->_readstream($f, 4)!='IHDR') 
  2252.  
  2253. $this->Error('Incorrect PNG file: '.$file); 
  2254.  
  2255. $w=$this->_readint($f); 
  2256.  
  2257. $h=$this->_readint($f); 
  2258.  
  2259. $bpc=ord($this->_readstream($f, 1)); 
  2260.  
  2261. if($bpc>8) 
  2262.  
  2263. $this->Error('16-bit depth not supported: '.$file); 
  2264.  
  2265. $ct=ord($this->_readstream($f, 1)); 
  2266.  
  2267. if($ct==0) 
  2268.  
  2269. $colspace='DeviceGray'; 
  2270.  
  2271. elseif($ct==2) 
  2272.  
  2273. $colspace='DeviceRGB'; 
  2274.  
  2275. elseif($ct==3) 
  2276.  
  2277. $colspace='Indexed'; 
  2278.  
  2279. else 
  2280.  
  2281. $this->Error('Alpha channel not supported: '.$file); 
  2282.  
  2283. if(ord($this->_readstream($f, 1))!=0) 
  2284.  
  2285. $this->Error('Unknown compression method: '.$file); 
  2286.  
  2287. if(ord($this->_readstream($f, 1))!=0) 
  2288.  
  2289. $this->Error('Unknown filter method: '.$file); 
  2290.  
  2291. if(ord($this->_readstream($f, 1))!=0) 
  2292.  
  2293. $this->Error('Interlacing not supported: '.$file); 
  2294.  
  2295. $this->_readstream($f, 4); 
  2296.  
  2297. $parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>'; 
  2298.  
  2299. //Scan chunks looking for palette, transparency and image data 
  2300.  
  2301. $pal=''; 
  2302.  
  2303. $trns=''; 
  2304.  
  2305. $data=''; 
  2306.  
  2307. do 
  2308.  
  2309.  
  2310. $n=$this->_readint($f); 
  2311.  
  2312. $type=$this->_readstream($f, 4); 
  2313.  
  2314. if($type=='PLTE') 
  2315.  
  2316.  
  2317. //Read palette 
  2318.  
  2319. $pal=$this->_readstream($f, $n); 
  2320.  
  2321. $this->_readstream($f, 4); 
  2322.  
  2323.  
  2324. elseif($type=='tRNS') 
  2325.  
  2326.  
  2327. //Read transparency info 
  2328.  
  2329. $t=$this->_readstream($f, $n); 
  2330.  
  2331. if($ct==0) 
  2332.  
  2333. $trns=array(ord(substr($t, 1, 1))); 
  2334.  
  2335. elseif($ct==2) 
  2336.  
  2337. $trns=array(ord(substr($t, 1, 1)), ord(substr($t, 3, 1)), ord(substr($t, 5, 1))); 
  2338.  
  2339. else 
  2340.  
  2341.  
  2342. $pos=strpos($t, chr(0)); 
  2343.  
  2344. if($pos!==false) 
  2345.  
  2346. $trns=array($pos); 
  2347.  
  2348.  
  2349. $this->_readstream($f, 4); 
  2350.  
  2351.  
  2352. elseif($type=='IDAT') 
  2353.  
  2354.  
  2355. //Read image data block 
  2356.  
  2357. $data.=$this->_readstream($f, $n); 
  2358.  
  2359. $this->_readstream($f, 4); 
  2360.  
  2361.  
  2362. elseif($type=='IEND') 
  2363.  
  2364. break; 
  2365.  
  2366. else 
  2367.  
  2368. $this->_readstream($f, $n+4); 
  2369.  
  2370.  
  2371. while($n); 
  2372.  
  2373. if($colspace=='Indexed' && empty($pal)) 
  2374.  
  2375. $this->Error('Missing palette in '.$file); 
  2376.  
  2377. fclose($f); 
  2378.  
  2379. return array('w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'FlateDecode', 'parms'=>$parms, 'pal'=>$pal, 'trns'=>$trns, 'data'=>$data); 
  2380.  
  2381.  
  2382.  
  2383.  
  2384. function _readstream($f, $n) 
  2385.  
  2386.  
  2387. //Read n bytes from stream 
  2388.  
  2389. $res=''; 
  2390.  
  2391. while($n>0 && !feof($f)) 
  2392.  
  2393.  
  2394. $s=fread($f, $n); 
  2395.  
  2396. if($s===false) 
  2397.  
  2398. $this->Error('Error while reading stream'); 
  2399.  
  2400. $n-=strlen($s); 
  2401.  
  2402. $res.=$s; 
  2403.  
  2404.  
  2405. //if($n>0) //$this->Error('Unexpected end of stream'); 
  2406.  
  2407. return $res; 
  2408.  
  2409.  
  2410.  
  2411.  
  2412. function _readint($f) 
  2413.  
  2414.  
  2415. //Read a 4-byte integer from stream 
  2416.  
  2417. $a=unpack('Ni', $this->_readstream($f, 4)); 
  2418.  
  2419. return $a['i']; 
  2420.  
  2421.  
  2422.  
  2423.  
  2424. function _parsegif($file) 
  2425.  
  2426.  
  2427. //Extract info from a GIF file (via PNG conversion) 
  2428.  
  2429. if(!function_exists('imagepng')) 
  2430.  
  2431. $this->Error('GD extension is required for GIF support'); 
  2432.  
  2433. if(!function_exists('imagecreatefromgif')) 
  2434.  
  2435. $this->Error('GD has no GIF read support'); 
  2436.  
  2437. $im=imagecreatefromgif($file); 
  2438.  
  2439. if(!$im) { 
  2440. $makeitlocal = trim(get_option( 'siteurl' ), '/') . '/'; 
  2441. $file = str_replace($makeitlocal, '', $file); 
  2442. $im = imagecreatefromgif($file); 
  2443. if( !$im && strpos($file, 'http') !== FALSE ) { 
  2444. $this->Error('[Error] '.$file.' Missing or Please turn on "allow_url_fopen" on your server to allow insert images in PDF Document, more info here: http://stackoverflow.com/questions/3694240/add-allow-url-fopen-to-my-php-ini-using-htaccess'); 
  2445. $im = imagecreatefromgif( './' . $file); 
  2446.  
  2447.  
  2448. if(!$im) 
  2449.  
  2450. $this->Error('Missing or incorrect image file: '.$file); 
  2451.  
  2452. imageinterlace($im, 0); 
  2453.  
  2454. $tmp=tempnam('.', 'gif'); 
  2455.  
  2456. if(!$tmp) 
  2457.  
  2458. $this->Error('Unable to create a temporary file'); 
  2459.  
  2460. if(!imagepng($im, $tmp)) 
  2461.  
  2462. $this->Error('Error while saving to temporary file'); 
  2463.  
  2464. imagedestroy($im); 
  2465.  
  2466. $info=$this->_parsepng($tmp); 
  2467.  
  2468. unlink($tmp); 
  2469.  
  2470. return $info; 
  2471.  
  2472.  
  2473.  
  2474.  
  2475. function _newobj() 
  2476.  
  2477.  
  2478. //Begin a new object 
  2479.  
  2480. $this->n++; 
  2481.  
  2482. $this->offsets[$this->n]=strlen($this->buffer); 
  2483.  
  2484. $this->_out($this->n.' 0 obj'); 
  2485.  
  2486.  
  2487.  
  2488.  
  2489. function _putstream($s) 
  2490.  
  2491.  
  2492. $this->_out('stream'); 
  2493.  
  2494. $this->_out($s); 
  2495.  
  2496. $this->_out('endstream'); 
  2497.  
  2498.  
  2499.  
  2500.  
  2501. function _out($s) 
  2502.  
  2503.  
  2504. //Add a line to the document 
  2505.  
  2506. if($this->state==2) 
  2507.  
  2508. $this->pages[$this->page].=$s."\n"; 
  2509.  
  2510. else 
  2511.  
  2512. $this->buffer.=$s."\n"; 
  2513.  
  2514.  
  2515.  
  2516.  
  2517. function _putpages() 
  2518.  
  2519.  
  2520. $nb=$this->page; 
  2521.  
  2522. if(!empty($this->AliasNbPages)) 
  2523.  
  2524.  
  2525. //Replace number of pages 
  2526.  
  2527. for($n=1;$n<=$nb;$n++) 
  2528.  
  2529. $this->pages[$n]=str_replace($this->AliasNbPages, $nb, $this->pages[$n]); 
  2530.  
  2531.  
  2532. if($this->DefOrientation=='P') 
  2533.  
  2534.  
  2535. $wPt=$this->DefPageFormat[0]*$this->k; 
  2536.  
  2537. $hPt=$this->DefPageFormat[1]*$this->k; 
  2538.  
  2539.  
  2540. else 
  2541.  
  2542.  
  2543. $wPt=$this->DefPageFormat[1]*$this->k; 
  2544.  
  2545. $hPt=$this->DefPageFormat[0]*$this->k; 
  2546.  
  2547.  
  2548. $filter=($this->compress) ? '/Filter /FlateDecode ' : ''; 
  2549.  
  2550. for($n=1;$n<=$nb;$n++) 
  2551.  
  2552.  
  2553. //Page 
  2554.  
  2555. $this->_newobj(); 
  2556.  
  2557. $this->_out('<</Type /Page'); 
  2558.  
  2559. $this->_out('/Parent 1 0 R'); 
  2560.  
  2561. if(isset($this->PageSizes[$n])) 
  2562.  
  2563. $this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]', $this->PageSizes[$n][0], $this->PageSizes[$n][1])); 
  2564.  
  2565. $this->_out('/Resources 2 0 R'); 
  2566.  
  2567. if(isset($this->PageLinks[$n])) 
  2568.  
  2569.  
  2570. //Links 
  2571.  
  2572. $annots='/Annots ['; 
  2573.  
  2574. foreach($this->PageLinks[$n] as $pl) 
  2575.  
  2576.  
  2577. $rect=sprintf('%.2F %.2F %.2F %.2F', $pl[0], $pl[1], $pl[0]+$pl[2], $pl[1]-$pl[3]); 
  2578.  
  2579. $annots.='<</Type /Annot /Subtype /Link /Rect ['.$rect.'] /Border [0 0 0] '; 
  2580.  
  2581. if(is_string($pl[4])) 
  2582.  
  2583. $annots.='/A <</S /URI /URI '.$this->_textstring($pl[4]).'>>>>'; 
  2584.  
  2585. else 
  2586.  
  2587.  
  2588. $l=$this->links[$pl[4]]; 
  2589.  
  2590. $h=isset($this->PageSizes[$l[0]]) ? $this->PageSizes[$l[0]][1] : $hPt; 
  2591.  
  2592. $annots.=sprintf('/Dest [%d 0 R /XYZ 0 %.2F null]>>', 1+2*$l[0], $h-$l[1]*$this->k); 
  2593.  
  2594.  
  2595.  
  2596. $this->_out($annots.']'); 
  2597.  
  2598.  
  2599. $this->_out('/Contents '.($this->n+1).' 0 R>>'); 
  2600.  
  2601. $this->_out('endobj'); 
  2602.  
  2603. //Page content 
  2604.  
  2605. $p=($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n]; 
  2606.  
  2607. $this->_newobj(); 
  2608.  
  2609. $this->_out('<<'.$filter.'/Length '.strlen($p).'>>'); 
  2610.  
  2611. $this->_putstream($p); 
  2612.  
  2613. $this->_out('endobj'); 
  2614.  
  2615.  
  2616. //Pages root 
  2617.  
  2618. $this->offsets[1]=strlen($this->buffer); 
  2619.  
  2620. $this->_out('1 0 obj'); 
  2621.  
  2622. $this->_out('<</Type /Pages'); 
  2623.  
  2624. $kids='/Kids ['; 
  2625.  
  2626. for($i=0;$i<$nb;$i++) 
  2627.  
  2628. $kids.=(3+2*$i).' 0 R '; 
  2629.  
  2630. $this->_out($kids.']'); 
  2631.  
  2632. $this->_out('/Count '.$nb); 
  2633.  
  2634. $this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]', $wPt, $hPt)); 
  2635.  
  2636. $this->_out('>>'); 
  2637.  
  2638. $this->_out('endobj'); 
  2639.  
  2640.  
  2641.  
  2642.  
  2643. function _putfonts() 
  2644.  
  2645.  
  2646. $nf=$this->n; 
  2647.  
  2648. foreach($this->diffs as $diff) 
  2649.  
  2650.  
  2651. //Encodings 
  2652.  
  2653. $this->_newobj(); 
  2654.  
  2655. $this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.']>>'); 
  2656.  
  2657. $this->_out('endobj'); 
  2658.  
  2659.  
  2660. foreach($this->FontFiles as $file=>$info) 
  2661.  
  2662.  
  2663. //Font file embedding 
  2664.  
  2665. $this->_newobj(); 
  2666.  
  2667. $this->FontFiles[$file]['n']=$this->n; 
  2668.  
  2669. $font=''; 
  2670.  
  2671. $f=fopen($this->_getfontpath().$file, 'rb', 1); 
  2672.  
  2673. if(!$f) 
  2674.  
  2675. $this->Error('Font file not found'); 
  2676.  
  2677. while(!feof($f)) 
  2678.  
  2679. $font.=fread($f, 8192); 
  2680.  
  2681. fclose($f); 
  2682.  
  2683. $compressed=(substr($file, -2)=='.z'); 
  2684.  
  2685. if(!$compressed && isset($info['length2'])) 
  2686.  
  2687.  
  2688. $header=(ord($font[0])==128); 
  2689.  
  2690. if($header) 
  2691.  
  2692.  
  2693. //Strip first binary header 
  2694.  
  2695. $font=substr($font, 6); 
  2696.  
  2697.  
  2698. if($header && ord($font[$info['length1']])==128) 
  2699.  
  2700.  
  2701. //Strip second binary header 
  2702.  
  2703. $font=substr($font, 0, $info['length1']).substr($font, $info['length1']+6); 
  2704.  
  2705.  
  2706.  
  2707. $this->_out('<</Length '.strlen($font)); 
  2708.  
  2709. if($compressed) 
  2710.  
  2711. $this->_out('/Filter /FlateDecode'); 
  2712.  
  2713. $this->_out('/Length1 '.$info['length1']); 
  2714.  
  2715. if(isset($info['length2'])) 
  2716.  
  2717. $this->_out('/Length2 '.$info['length2'].' /Length3 0'); 
  2718.  
  2719. $this->_out('>>'); 
  2720.  
  2721. $this->_putstream($font); 
  2722.  
  2723. $this->_out('endobj'); 
  2724.  
  2725.  
  2726. foreach($this->fonts as $k=>$font) 
  2727.  
  2728.  
  2729. //Font objects 
  2730.  
  2731. $this->fonts[$k]['n']=$this->n+1; 
  2732.  
  2733. $type=$font['type']; 
  2734.  
  2735. $name=$font['name']; 
  2736.  
  2737. if($type=='core') 
  2738.  
  2739.  
  2740. //Standard font 
  2741.  
  2742. $this->_newobj(); 
  2743.  
  2744. $this->_out('<</Type /Font'); 
  2745.  
  2746. $this->_out('/BaseFont /'.$name); 
  2747.  
  2748. $this->_out('/Subtype /Type1'); 
  2749.  
  2750. if($name!='Symbol' && $name!='ZapfDingbats') 
  2751.  
  2752. $this->_out('/Encoding /WinAnsiEncoding'); 
  2753.  
  2754. $this->_out('>>'); 
  2755.  
  2756. $this->_out('endobj'); 
  2757.  
  2758.  
  2759. elseif($type=='Type1' || $type=='TrueType') 
  2760.  
  2761.  
  2762. //Additional Type1 or TrueType font 
  2763.  
  2764. $this->_newobj(); 
  2765.  
  2766. $this->_out('<</Type /Font'); 
  2767.  
  2768. $this->_out('/BaseFont /'.$name); 
  2769.  
  2770. $this->_out('/Subtype /'.$type); 
  2771.  
  2772. $this->_out('/FirstChar 32 /LastChar 255'); 
  2773.  
  2774. $this->_out('/Widths '.($this->n+1).' 0 R'); 
  2775.  
  2776. $this->_out('/FontDescriptor '.($this->n+2).' 0 R'); 
  2777.  
  2778. if($font['enc']) 
  2779.  
  2780.  
  2781. if(isset($font['diff'])) 
  2782.  
  2783. $this->_out('/Encoding '.($nf+$font['diff']).' 0 R'); 
  2784.  
  2785. else 
  2786.  
  2787. $this->_out('/Encoding /WinAnsiEncoding'); 
  2788.  
  2789.  
  2790. $this->_out('>>'); 
  2791.  
  2792. $this->_out('endobj'); 
  2793.  
  2794. //Widths 
  2795.  
  2796. $this->_newobj(); 
  2797.  
  2798. $cw=&$font['cw']; 
  2799.  
  2800. $s='['; 
  2801.  
  2802. for($i=32;$i<=255;$i++) 
  2803.  
  2804. $s.=$cw[chr($i)].' '; 
  2805.  
  2806. $this->_out($s.']'); 
  2807.  
  2808. $this->_out('endobj'); 
  2809.  
  2810. //Descriptor 
  2811.  
  2812. $this->_newobj(); 
  2813.  
  2814. $s='<</Type /FontDescriptor /FontName /'.$name; 
  2815.  
  2816. foreach($font['desc'] as $k=>$v) 
  2817.  
  2818. $s.=' /'.$k.' '.$v; 
  2819.  
  2820. $file=$font['file']; 
  2821.  
  2822. if($file) 
  2823.  
  2824. $s.=' /FontFile'.($type=='Type1' ? '' : '2').' '.$this->FontFiles[$file]['n'].' 0 R'; 
  2825.  
  2826. $this->_out($s.'>>'); 
  2827.  
  2828. $this->_out('endobj'); 
  2829.  
  2830.  
  2831. else 
  2832.  
  2833.  
  2834. //Allow for additional types 
  2835.  
  2836. $mtd='_put'.strtolower($type); 
  2837.  
  2838. if(!method_exists($this, $mtd)) 
  2839.  
  2840. $this->Error('Unsupported font type: '.$type); 
  2841.  
  2842. $this->$mtd($font); 
  2843.  
  2844.  
  2845.  
  2846.  
  2847.  
  2848.  
  2849. function _putimages() 
  2850.  
  2851.  
  2852. $filter=($this->compress) ? '/Filter /FlateDecode ' : ''; 
  2853.  
  2854. reset($this->images); 
  2855.  
  2856. while(list($file, $info)=each($this->images)) 
  2857.  
  2858.  
  2859. $this->_newobj(); 
  2860.  
  2861. $this->images[$file]['n']=$this->n; 
  2862.  
  2863. $this->_out('<</Type /XObject'); 
  2864.  
  2865. $this->_out('/Subtype /Image'); 
  2866.  
  2867. $this->_out('/Width '.$info['w']); 
  2868.  
  2869. $this->_out('/Height '.$info['h']); 
  2870.  
  2871. if($info['cs']=='Indexed') 
  2872.  
  2873. $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]'); 
  2874.  
  2875. else 
  2876.  
  2877.  
  2878. $this->_out('/ColorSpace /'.$info['cs']); 
  2879.  
  2880. if($info['cs']=='DeviceCMYK') 
  2881.  
  2882. $this->_out('/Decode [1 0 1 0 1 0 1 0]'); 
  2883.  
  2884.  
  2885. $this->_out('/BitsPerComponent '.$info['bpc']); 
  2886.  
  2887. if(isset($info['f'])) 
  2888.  
  2889. $this->_out('/Filter /'.$info['f']); 
  2890.  
  2891. if(isset($info['parms'])) 
  2892.  
  2893. $this->_out($info['parms']); 
  2894.  
  2895. if(isset($info['trns']) && is_array($info['trns'])) 
  2896.  
  2897.  
  2898. $trns=''; 
  2899.  
  2900. for($i=0;$i<count($info['trns']);$i++) 
  2901.  
  2902. $trns.=$info['trns'][$i].' '.$info['trns'][$i].' '; 
  2903.  
  2904. $this->_out('/Mask ['.$trns.']'); 
  2905.  
  2906.  
  2907. $this->_out('/Length '.strlen($info['data']).'>>'); 
  2908.  
  2909. $this->_putstream($info['data']); 
  2910.  
  2911. unset($this->images[$file]['data']); 
  2912.  
  2913. $this->_out('endobj'); 
  2914.  
  2915. //Palette 
  2916.  
  2917. if($info['cs']=='Indexed') 
  2918.  
  2919.  
  2920. $this->_newobj(); 
  2921.  
  2922. $pal=($this->compress) ? gzcompress($info['pal']) : $info['pal']; 
  2923.  
  2924. $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>'); 
  2925.  
  2926. $this->_putstream($pal); 
  2927.  
  2928. $this->_out('endobj'); 
  2929.  
  2930.  
  2931.  
  2932.  
  2933.  
  2934.  
  2935. function _putxobjectdict() 
  2936.  
  2937.  
  2938. foreach($this->images as $image) 
  2939.  
  2940. $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R'); 
  2941.  
  2942.  
  2943.  
  2944.  
  2945. function _putresourcedict() 
  2946.  
  2947.  
  2948. $this->_out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); 
  2949.  
  2950. $this->_out('/Font <<'); 
  2951.  
  2952. foreach($this->fonts as $font) 
  2953.  
  2954. $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R'); 
  2955.  
  2956. $this->_out('>>'); 
  2957.  
  2958. $this->_out('/XObject <<'); 
  2959.  
  2960. $this->_putxobjectdict(); 
  2961.  
  2962. $this->_out('>>'); 
  2963.  
  2964.  
  2965.  
  2966.  
  2967. function _putresources() 
  2968.  
  2969.  
  2970. $this->_putfonts(); 
  2971.  
  2972. $this->_putimages(); 
  2973.  
  2974. //Resource dictionary 
  2975.  
  2976. $this->offsets[2]=strlen($this->buffer); 
  2977.  
  2978. $this->_out('2 0 obj'); 
  2979.  
  2980. $this->_out('<<'); 
  2981.  
  2982. $this->_putresourcedict(); 
  2983.  
  2984. $this->_out('>>'); 
  2985.  
  2986. $this->_out('endobj'); 
  2987.  
  2988.  
  2989.  
  2990.  
  2991. function _putinfo() 
  2992.  
  2993.  
  2994. $this->_out('/Producer '.$this->_textstring('FPDF '.FPDF_VERSION)); 
  2995.  
  2996. if(!empty($this->title)) 
  2997.  
  2998. $this->_out('/Title '.$this->_textstring($this->title)); 
  2999.  
  3000. if(!empty($this->subject)) 
  3001.  
  3002. $this->_out('/Subject '.$this->_textstring($this->subject)); 
  3003.  
  3004. if(!empty($this->author)) 
  3005.  
  3006. $this->_out('/Author '.$this->_textstring($this->author)); 
  3007.  
  3008. if(!empty($this->keywords)) 
  3009.  
  3010. $this->_out('/Keywords '.$this->_textstring($this->keywords)); 
  3011.  
  3012. if(!empty($this->creator)) 
  3013.  
  3014. $this->_out('/Creator '.$this->_textstring($this->creator)); 
  3015.  
  3016. $this->_out('/CreationDate '.$this->_textstring('D:'.@date('YmdHis'))); 
  3017.  
  3018.  
  3019.  
  3020.  
  3021. function _putcatalog() 
  3022.  
  3023.  
  3024. $this->_out('/Type /Catalog'); 
  3025.  
  3026. $this->_out('/Pages 1 0 R'); 
  3027.  
  3028. if($this->ZoomMode=='fullpage') 
  3029.  
  3030. $this->_out('/OpenAction [3 0 R /Fit]'); 
  3031.  
  3032. elseif($this->ZoomMode=='fullwidth') 
  3033.  
  3034. $this->_out('/OpenAction [3 0 R /FitH null]'); 
  3035.  
  3036. elseif($this->ZoomMode=='real') 
  3037.  
  3038. $this->_out('/OpenAction [3 0 R /XYZ null null 1]'); 
  3039.  
  3040. elseif(!is_string($this->ZoomMode)) 
  3041.  
  3042. $this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode/100).']'); 
  3043.  
  3044. if($this->LayoutMode=='single') 
  3045.  
  3046. $this->_out('/PageLayout /SinglePage'); 
  3047.  
  3048. elseif($this->LayoutMode=='continuous') 
  3049.  
  3050. $this->_out('/PageLayout /OneColumn'); 
  3051.  
  3052. elseif($this->LayoutMode=='two') 
  3053.  
  3054. $this->_out('/PageLayout /TwoColumnLeft'); 
  3055.  
  3056.  
  3057.  
  3058.  
  3059. function _putheader() 
  3060.  
  3061.  
  3062. $this->_out('%PDF-'.$this->PDFVersion); 
  3063.  
  3064.  
  3065.  
  3066.  
  3067. function _puttrailer() 
  3068.  
  3069.  
  3070. $this->_out('/Size '.($this->n+1)); 
  3071.  
  3072. $this->_out('/Root '.$this->n.' 0 R'); 
  3073.  
  3074. $this->_out('/Info '.($this->n-1).' 0 R'); 
  3075.  
  3076.  
  3077.  
  3078.  
  3079. function _enddoc() 
  3080.  
  3081.  
  3082. $this->_putheader(); 
  3083.  
  3084. $this->_putpages(); 
  3085.  
  3086. $this->_putresources(); 
  3087.  
  3088. //Info 
  3089.  
  3090. $this->_newobj(); 
  3091.  
  3092. $this->_out('<<'); 
  3093.  
  3094. $this->_putinfo(); 
  3095.  
  3096. $this->_out('>>'); 
  3097.  
  3098. $this->_out('endobj'); 
  3099.  
  3100. //Catalog 
  3101.  
  3102. $this->_newobj(); 
  3103.  
  3104. $this->_out('<<'); 
  3105.  
  3106. $this->_putcatalog(); 
  3107.  
  3108. $this->_out('>>'); 
  3109.  
  3110. $this->_out('endobj'); 
  3111.  
  3112. //Cross-ref 
  3113.  
  3114. $o=strlen($this->buffer); 
  3115.  
  3116. $this->_out('xref'); 
  3117.  
  3118. $this->_out('0 '.($this->n+1)); 
  3119.  
  3120. $this->_out('0000000000 65535 f '); 
  3121.  
  3122. for($i=1;$i<=$this->n;$i++) 
  3123.  
  3124. $this->_out(sprintf('%010d 00000 n ', $this->offsets[$i])); 
  3125.  
  3126. //Trailer 
  3127.  
  3128. $this->_out('trailer'); 
  3129.  
  3130. $this->_out('<<'); 
  3131.  
  3132. $this->_puttrailer(); 
  3133.  
  3134. $this->_out('>>'); 
  3135.  
  3136. $this->_out('startxref'); 
  3137.  
  3138. $this->_out($o); 
  3139.  
  3140. $this->_out('%%EOF'); 
  3141.  
  3142. $this->state=3; 
  3143.  
  3144.  
  3145. //End of class 
  3146.