PageRenderTime 72ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/gforge/plugins/wiki/www/lib/fpdf.php

https://github.com/neymanna/fusionforge
PHP | 1561 lines | 1305 code | 85 blank | 171 comment | 206 complexity | 876f2f8bc0ccc8970c9abe3d23af654b MD5 | raw file
Possible License(s): GPL-2.0, MPL-2.0-no-copyleft-exception

Large files files are truncated, but you can click here to view the full file

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

Large files files are truncated, but you can click here to view the full file