PageRenderTime 96ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/public_html/vendors/fpdf/fpdf.php

https://bitbucket.org/southsidehealth/southsidehealth
PHP | 5514 lines | 4574 code | 262 blank | 678 comment | 971 complexity | 1420121e2fbd2dc188ac02bb56960791 MD5 | raw file
Possible License(s): Apache-2.0, GPL-3.0, LGPL-2.1

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(modified) *
  5. * Date: 2003-12-30 *
  6. * Author: Olivier PLATHEY *
  7. * License: Freeware *
  8. * *
  9. * You may use, modify and redistribute this software as you wish. *
  10. *******************************************************************************/
  11. // Modified by Renato A.C. [html2fpdf.sf.net]
  12. // (look for 'EDITEI' in the code)
  13. if(!class_exists('FPDF'))
  14. {
  15. define('FPDF_VERSION','1.52');
  16. class FPDF
  17. {
  18. //Private properties
  19. var $DisplayPreferences=''; //EDITEI - added
  20. var $outlines=array(); //EDITEI - added
  21. var $OutlineRoot; //EDITEI - added
  22. var $flowingBlockAttr; //EDITEI - added
  23. var $page; //current page number
  24. var $n; //current object number
  25. var $offsets; //array of object offsets
  26. var $buffer; //buffer holding in-memory PDF
  27. var $pages; //array containing pages
  28. var $state; //current document state
  29. var $compress; //compression flag
  30. var $DefOrientation; //default orientation
  31. var $CurOrientation; //current orientation
  32. var $OrientationChanges; //array indicating orientation changes
  33. var $k; //scale factor (number of points in user unit)
  34. var $fwPt,$fhPt; //dimensions of page format in points
  35. var $fw,$fh; //dimensions of page format in user unit
  36. var $wPt,$hPt; //current dimensions of page in points
  37. var $w,$h; //current dimensions of page in user unit
  38. var $lMargin; //left margin
  39. var $tMargin; //top margin
  40. var $rMargin; //right margin
  41. var $bMargin; //page break margin
  42. var $cMargin; //cell margin
  43. var $x,$y; //current position in user unit for cell positioning
  44. var $lasth; //height of last cell printed
  45. var $LineWidth; //line width in user unit
  46. var $CoreFonts; //array of standard font names
  47. var $fonts; //array of used fonts
  48. var $FontFiles; //array of font files
  49. var $diffs; //array of encoding differences
  50. var $images; //array of used images
  51. var $PageLinks; //array of links in pages
  52. var $links; //array of internal links
  53. var $FontFamily; //current font family
  54. var $FontStyle; //current font style
  55. var $underline; //underlining flag
  56. var $CurrentFont; //current font info
  57. var $FontSizePt; //current font size in points
  58. var $FontSize; //current font size in user unit
  59. var $DrawColor; //commands for drawing color
  60. var $FillColor; //commands for filling color
  61. var $TextColor; //commands for text color
  62. var $ColorFlag; //indicates whether fill and text colors are different
  63. var $ws; //word spacing
  64. var $AutoPageBreak; //automatic page breaking
  65. var $PageBreakTrigger; //threshold used to trigger page breaks
  66. var $InFooter; //flag set when processing footer
  67. var $ZoomMode; //zoom display mode
  68. var $LayoutMode; //layout display mode
  69. var $title; //title
  70. var $subject; //subject
  71. var $author; //author
  72. var $keywords; //keywords
  73. var $creator; //creator
  74. var $AliasNbPages; //alias for total number of pages
  75. /*******************************************************************************
  76. * *
  77. * Public methods *
  78. * *
  79. *******************************************************************************/
  80. function FPDF($w=null,$orientation='P',$unit='mm',$format='A4')
  81. {
  82. //Some checks
  83. $this->_dochecks();
  84. //Initialization of properties
  85. $this->page=0;
  86. $this->n=2;
  87. $this->buffer='';
  88. $this->pages=array();
  89. $this->OrientationChanges=array();
  90. $this->state=0;
  91. $this->fonts=array();
  92. $this->FontFiles=array();
  93. $this->diffs=array();
  94. $this->images=array();
  95. $this->links=array();
  96. $this->InFooter=false;
  97. $this->lasth=0;
  98. $this->FontFamily='';
  99. $this->FontStyle='';
  100. $this->FontSizePt=12;
  101. $this->underline=false;
  102. $this->DrawColor='0 G';
  103. $this->FillColor='0 g';
  104. $this->TextColor='0 g';
  105. $this->ColorFlag=false;
  106. $this->ws=0;
  107. //Standard fonts
  108. $this->CoreFonts=array('courier'=>'Courier','courierB'=>'Courier-Bold','courierI'=>'Courier-Oblique','courierBI'=>'Courier-BoldOblique',
  109. 'helvetica'=>'Helvetica','helveticaB'=>'Helvetica-Bold','helveticaI'=>'Helvetica-Oblique','helveticaBI'=>'Helvetica-BoldOblique',
  110. 'times'=>'Times-Roman','timesB'=>'Times-Bold','timesI'=>'Times-Italic','timesBI'=>'Times-BoldItalic',
  111. 'symbol'=>'Symbol','zapfdingbats'=>'ZapfDingbats');
  112. //Scale factor
  113. if($unit=='pt') $this->k=1;
  114. elseif($unit=='mm') $this->k=72/25.4;
  115. elseif($unit=='cm') $this->k=72/2.54;
  116. elseif($unit=='in') $this->k=72;
  117. else $this->Error('Incorrect unit: '.$unit);
  118. //Page format
  119. if(is_string($format))
  120. {
  121. $format=strtolower($format);
  122. if($format=='a3') $format=array(841.89,1190.55);
  123. elseif($format=='a4') $format=array(595.28,841.89);
  124. elseif($format=='a5') $format=array(420.94,595.28);
  125. elseif($format=='letter') $format=array(612,792);
  126. elseif($format=='legal') $format=array(612,1008);
  127. else $this->Error('Unknown page format: '.$format);
  128. $this->fwPt=$format[0];
  129. $this->fhPt=$format[1];
  130. }
  131. else
  132. {
  133. $this->fwPt=$format[0]*$this->k;
  134. $this->fhPt=$format[1]*$this->k;
  135. }
  136. $this->fw=$this->fwPt/$this->k;
  137. $this->fh=$this->fhPt/$this->k;
  138. //Page orientation
  139. $orientation=strtolower($orientation);
  140. if($orientation=='p' or $orientation=='portrait')
  141. {
  142. $this->DefOrientation='P';
  143. $this->wPt=$this->fwPt;
  144. $this->hPt=$this->fhPt;
  145. }
  146. elseif($orientation=='l' or $orientation=='landscape')
  147. {
  148. $this->DefOrientation='L';
  149. $this->wPt=$this->fhPt;
  150. $this->hPt=$this->fwPt;
  151. }
  152. else $this->Error('Incorrect orientation: '.$orientation);
  153. $this->CurOrientation=$this->DefOrientation;
  154. $this->w=$this->wPt/$this->k;
  155. $this->h=$this->hPt/$this->k;
  156. //Page margins (1 cm)
  157. $margin=28.35/$this->k;
  158. $this->SetMargins($margin,$margin);
  159. //Interior cell margin (1 mm)
  160. $this->cMargin=$margin/10;
  161. //Line width (0.2 mm)
  162. $this->LineWidth=.567/$this->k;
  163. //Automatic page break
  164. $this->SetAutoPageBreak(true,2*$margin);
  165. //Full width display mode
  166. $this->SetDisplayMode('fullwidth');
  167. //Compression
  168. $this->SetCompression(true);
  169. }
  170. function SetMargins($left,$top,$right=-1)
  171. {
  172. //Set left, top and right margins
  173. $this->lMargin=$left;
  174. $this->tMargin=$top;
  175. if($right==-1) $right=$left;
  176. $this->rMargin=$right;
  177. }
  178. function SetLeftMargin($margin)
  179. {
  180. //Set left margin
  181. $this->lMargin=$margin;
  182. if($this->page>0 and $this->x<$margin) $this->x=$margin;
  183. }
  184. function SetTopMargin($margin)
  185. {
  186. //Set top margin
  187. $this->tMargin=$margin;
  188. }
  189. function SetRightMargin($margin)
  190. {
  191. //Set right margin
  192. $this->rMargin=$margin;
  193. }
  194. function SetAutoPageBreak($auto,$margin=0)
  195. {
  196. //Set auto page break mode and triggering margin
  197. $this->AutoPageBreak=$auto;
  198. $this->bMargin=$margin;
  199. //debug($margin);
  200. // debug($this->h);
  201. $this->PageBreakTrigger=$this->h-$margin;
  202. }
  203. function SetDisplayMode($zoom,$layout='continuous')
  204. {
  205. //Set display mode in viewer
  206. if($zoom=='fullpage' or $zoom=='fullwidth' or $zoom=='real' or $zoom=='default' or !is_string($zoom))
  207. $this->ZoomMode=$zoom;
  208. else
  209. $this->Error('Incorrect zoom display mode: '.$zoom);
  210. if($layout=='single' or $layout=='continuous' or $layout=='two' or $layout=='default')
  211. $this->LayoutMode=$layout;
  212. else
  213. $this->Error('Incorrect layout display mode: '.$layout);
  214. }
  215. function SetCompression($compress)
  216. {
  217. //Set page compression
  218. if(function_exists('gzcompress')) $this->compress=$compress;
  219. else $this->compress=false;
  220. }
  221. function SetTitle($title)
  222. {
  223. //Title of document
  224. $this->title=$title;
  225. }
  226. function SetSubject($subject)
  227. {
  228. //Subject of document
  229. $this->subject=$subject;
  230. }
  231. function SetAuthor($author)
  232. {
  233. //Author of document
  234. $this->author=$author;
  235. }
  236. function SetKeywords($keywords)
  237. {
  238. //Keywords of document
  239. $this->keywords=$keywords;
  240. }
  241. function SetCreator($creator)
  242. {
  243. //Creator of document
  244. $this->creator=$creator;
  245. }
  246. function AliasNbPages($alias='{nb}')
  247. {
  248. //Define an alias for total number of pages
  249. $this->AliasNbPages=$alias;
  250. }
  251. function Error($msg)
  252. {
  253. //Fatal error
  254. die('<B>FPDF error: </B>'.$msg);
  255. }
  256. function Open()
  257. {
  258. //Begin document
  259. if($this->state==0) $this->_begindoc();
  260. }
  261. function Close()
  262. {
  263. //Terminate document
  264. if($this->state==3) return;
  265. if($this->page==0) $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. {
  277. //Start a new page
  278. if($this->state==0) $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. {
  289. //Page footer
  290. $this->InFooter=true;
  291. $this->Footer();
  292. $this->InFooter=false;
  293. //Close page
  294. $this->_endpage();
  295. }
  296. //Start new page
  297. $this->_beginpage($orientation);
  298. //Set line cap style to square
  299. $this->_out('2 J');
  300. //Set line width
  301. $this->LineWidth=$lw;
  302. $this->_out(sprintf('%.2f w',$lw*$this->k));
  303. //Set font
  304. if($family) $this->SetFont($family,$style,$size);
  305. //Set colors
  306. $this->DrawColor=$dc;
  307. if($dc!='0 G') $this->_out($dc);
  308. $this->FillColor=$fc;
  309. if($fc!='0 g') $this->_out($fc);
  310. $this->TextColor=$tc;
  311. $this->ColorFlag=$cf;
  312. //Page header
  313. $this->Header();
  314. //Restore line width
  315. if($this->LineWidth!=$lw)
  316. {
  317. $this->LineWidth=$lw;
  318. $this->_out(sprintf('%.2f w',$lw*$this->k));
  319. }
  320. //Restore font
  321. if($family) $this->SetFont($family,$style,$size);
  322. //Restore colors
  323. if($this->DrawColor!=$dc)
  324. {
  325. $this->DrawColor=$dc;
  326. $this->_out($dc);
  327. }
  328. if($this->FillColor!=$fc)
  329. {
  330. $this->FillColor=$fc;
  331. $this->_out($fc);
  332. }
  333. $this->TextColor=$tc;
  334. $this->ColorFlag=$cf;
  335. }
  336. function Header()
  337. {
  338. //To be implemented in your own inherited class
  339. }
  340. function Footer()
  341. {
  342. //To be implemented in your own inherited class
  343. }
  344. function PageNo()
  345. {
  346. //Get current page number
  347. return $this->page;
  348. }
  349. function SetDrawColor($r,$g=-1,$b=-1)
  350. {
  351. //Set color for all stroking operations
  352. if(($r==0 and $g==0 and $b==0) or $g==-1) $this->DrawColor=sprintf('%.3f G',$r/255);
  353. else $this->DrawColor=sprintf('%.3f %.3f %.3f RG',$r/255,$g/255,$b/255);
  354. if($this->page>0) $this->_out($this->DrawColor);
  355. }
  356. function SetFillColor($r,$g=-1,$b=-1)
  357. {
  358. //Set color for all filling operations
  359. if(($r==0 and $g==0 and $b==0) or $g==-1) $this->FillColor=sprintf('%.3f g',$r/255);
  360. else$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) $this->_out($this->FillColor);
  363. }
  364. function SetTextColor($r,$g=-1,$b=-1)
  365. {
  366. //Set color for text
  367. if(($r==0 and $g==0 and $b==0) or $g==-1) $this->TextColor=sprintf('%.3f g',$r/255);
  368. else $this->TextColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255);
  369. $this->ColorFlag = ($this->FillColor != $this->TextColor);
  370. }
  371. function GetStringWidth($s)
  372. {
  373. //Get width of a string in the current font
  374. $s=(string)$s;
  375. $cw=&$this->CurrentFont['cw'];
  376. $w=0;
  377. $l=strlen($s);
  378. for($i=0;$i<$l;$i++) $w+=$cw[$s{$i}];
  379. return $w*$this->FontSize/1000;
  380. }
  381. function SetLineWidth($width)
  382. {
  383. //Set line width
  384. $this->LineWidth=$width;
  385. if($this->page>0) $this->_out(sprintf('%.2f w',$width*$this->k));
  386. }
  387. function Line($x1,$y1,$x2,$y2)
  388. {
  389. //Draw a line
  390. $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));
  391. }
  392. function Rect($x,$y,$w,$h,$style='')
  393. {
  394. //Draw a rectangle
  395. if($style=='F') $op='f';
  396. elseif($style=='FD' or $style=='DF') $op='B';
  397. else $op='S';
  398. $this->_out(sprintf('%.2f %.2f %.2f %.2f re %s',$x*$this->k,($this->h-$y)*$this->k,$w*$this->k,-$h*$this->k,$op));
  399. }
  400. function AddFont($family,$style='',$file='')
  401. {
  402. //Add a TrueType or Type1 font
  403. $family=strtolower($family);
  404. if($family=='arial') $family='helvetica';
  405. $style=strtoupper($style);
  406. if($style=='IB') $style='BI';
  407. if(isset($this->fonts[$family.$style])) $this->Error('Font already added: '.$family.' '.$style);
  408. if($file=='') $file=str_replace(' ','',$family).strtolower($style).'.php';
  409. if(defined('FPDF_FONTPATH')) $file=FPDF_FONTPATH.$file;
  410. //debug($file);
  411. include($file);
  412. if(!isset($name)) $this->Error('Could not include font definition file');
  413. $i=count($this->fonts)+1;
  414. $this->fonts[$family.$style]=array('i'=>$i,'type'=>$type,'name'=>$name,'desc'=>$desc,'up'=>$up,'ut'=>$ut,'cw'=>$cw,'enc'=>$enc,'file'=>$file);
  415. if($diff)
  416. {
  417. //Search existing encodings
  418. $d=0;
  419. $nb=count($this->diffs);
  420. for($i=1;$i<=$nb;$i++)
  421. if($this->diffs[$i]==$diff)
  422. {
  423. $d=$i;
  424. break;
  425. }
  426. if($d==0)
  427. {
  428. $d=$nb+1;
  429. $this->diffs[$d]=$diff;
  430. }
  431. $this->fonts[$family.$style]['diff']=$d;
  432. }
  433. if($file)
  434. {
  435. if($type=='TrueType') $this->FontFiles[$file]=array('length1'=>$originalsize);
  436. else $this->FontFiles[$file]=array('length1'=>$size1,'length2'=>$size2);
  437. }
  438. }
  439. function SetFont($family,$style='',$size=0)
  440. {
  441. //Select a font; size given in points
  442. global $fpdf_charwidths;
  443. $family=strtolower($family);
  444. if($family=='') $family=$this->FontFamily;
  445. //EDITEI - now understands: monospace,serif,sans [serif]
  446. if($family=='monospace') $family='courier';
  447. if($family=='serif') $family='times';
  448. if($family=='sans') $family='arial';
  449. if($family=='arial') $family='helvetica';
  450. elseif($family=='symbol' or $family=='zapfdingbats') $style='';
  451. $style=strtoupper($style);
  452. if(is_int(strpos($style,'U')))
  453. {
  454. $this->underline=true;
  455. $style=str_replace('U','',$style);
  456. }
  457. else $this->underline=false;
  458. if ($style=='IB') $style='BI';
  459. if ($size==0) $size=$this->FontSizePt;
  460. //Test if font is already selected
  461. if($this->FontFamily==$family and $this->FontStyle==$style and $this->FontSizePt==$size) return;
  462. //Test if used for the first time
  463. $fontkey=$family.$style;
  464. if(!isset($this->fonts[$fontkey]))
  465. {
  466. //Check if one of the standard fonts
  467. if(isset($this->CoreFonts[$fontkey]))
  468. {
  469. if(!isset($fpdf_charwidths[$fontkey]))
  470. {
  471. //Load metric file
  472. $file=$family;
  473. if($family=='times' or $family=='helvetica') $file.=strtolower($style);
  474. $file.='.php';
  475. if(defined('FPDF_FONTPATH')) $file=FPDF_FONTPATH.$file;
  476. include($file);
  477. if(!isset($fpdf_charwidths[$fontkey])) $this->Error('Could not include font metric file');
  478. }
  479. $i=count($this->fonts)+1;
  480. $this->fonts[$fontkey]=array('i'=>$i,'type'=>'core','name'=>$this->CoreFonts[$fontkey],'up'=>-100,'ut'=>50,'cw'=>$fpdf_charwidths[$fontkey]);
  481. }
  482. else $this->Error('Undefined font: '.$family.' '.$style);
  483. }
  484. //Select it
  485. $this->FontFamily=$family;
  486. $this->FontStyle=$style;
  487. $this->FontSizePt=$size;
  488. $this->FontSize=$size/$this->k;
  489. $this->CurrentFont=&$this->fonts[$fontkey];
  490. if($this->page>0)
  491. $this->_out(sprintf('BT /F%d %.2f Tf ET',$this->CurrentFont['i'],$this->FontSizePt));
  492. }
  493. function SetFontSize($size)
  494. {
  495. //Set font size in points
  496. if($this->FontSizePt==$size) return;
  497. $this->FontSizePt=$size;
  498. $this->FontSize=$size/$this->k;
  499. if($this->page>0)
  500. $this->_out(sprintf('BT /F%d %.2f Tf ET',$this->CurrentFont['i'],$this->FontSizePt));
  501. }
  502. function AddLink()
  503. {
  504. //Create a new internal link
  505. $n=count($this->links)+1;
  506. $this->links[$n]=array(0,0);
  507. return $n;
  508. }
  509. function SetLink($link,$y=0,$page=-1)
  510. {
  511. //Set destination of internal link
  512. if($y==-1) $y=$this->y;
  513. if($page==-1) $page=$this->page;
  514. $this->links[$link]=array($page,$y);
  515. }
  516. function Link($x,$y,$w,$h,$link)
  517. {
  518. //Put a link on the page
  519. $this->PageLinks[$this->page][]=array($x*$this->k,$this->hPt-$y*$this->k,$w*$this->k,$h*$this->k,$link);
  520. }
  521. function Text($x,$y,$txt)
  522. {
  523. //Output a string
  524. $s=sprintf('BT %.2f %.2f Td (%s) Tj ET',$x*$this->k,($this->h-$y)*$this->k,$this->_escape($txt));
  525. if($this->underline and $txt!='') $s.=' '.$this->_dounderline($x,$y,$txt);
  526. if($this->ColorFlag) $s='q '.$this->TextColor.' '.$s.' Q';
  527. $this->_out($s);
  528. }
  529. function AcceptPageBreak()
  530. {
  531. //Accept automatic page break or not
  532. return $this->AutoPageBreak;
  533. }
  534. function Cell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='',$currentx=0) //EDITEI
  535. {
  536. //Output a cell
  537. //debug($this->y+$h);
  538. //debug($this->PageBreakTrigger);
  539. $k=$this->k;
  540. if($this->y+$h>$this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak())
  541. {
  542. //Automatic page break
  543. $x=$this->x;//Current X position
  544. $ws=$this->ws;//Word Spacing
  545. if($ws>0)
  546. {
  547. $this->ws=0;
  548. $this->_out('0 Tw');
  549. }
  550. $this->AddPage($this->CurOrientation);
  551. $this->x=$x;
  552. if($ws>0)
  553. {
  554. $this->ws=$ws;
  555. $this->_out(sprintf('%.3f Tw',$ws*$k));
  556. }
  557. }
  558. if($w==0) $w = $this->w-$this->rMargin-$this->x;
  559. $s='';
  560. if($fill==1 or $border==1)
  561. {
  562. if ($fill==1) $op=($border==1) ? 'B' : 'f';
  563. else $op='S';
  564. //$op='S';//DEBUG
  565. $s=sprintf('%.2f %.2f %.2f %.2f re %s ',$this->x*$k,($this->h-$this->y)*$k,$w*$k,-$h*$k,$op);
  566. }
  567. if(is_string($border))
  568. {
  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. {
  582. if($align=='R') $dx=$w-$this->cMargin-$this->GetStringWidth($txt);
  583. elseif($align=='C') $dx=($w-$this->GetStringWidth($txt))/2;
  584. elseif($align=='L' or $align=='J') $dx=$this->cMargin;
  585. else $dx = 0;
  586. if($this->ColorFlag) $s.='q '.$this->TextColor.' ';
  587. $txt2=str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$txt)));
  588. //Check whether we are going to outline text or not
  589. if($this->outline_on)
  590. {
  591. $s.=' '.sprintf('%.2f w',$this->LineWidth*$this->k).' ';
  592. $s.=" $this->DrawColor ";
  593. $s.=" 2 Tr ";
  594. }
  595. //Superscript and Subscript Y coordinate adjustment
  596. $adjusty = 0;
  597. if($this->SUB) $adjusty = 1;
  598. if($this->SUP) $adjusty = -1;
  599. //End of coordinate adjustment
  600. $s.=sprintf('BT %.2f %.2f Td (%s) Tj ET',($this->x+$dx)*$k,($this->h-(($this->y+$adjusty)+.5*$h+.3*$this->FontSize))*$k,$txt2); //EDITEI
  601. if($this->underline)
  602. $s.=' '.$this->_dounderline($this->x+$dx,$this->y+.5*$h+.3*$this->FontSize+$adjusty,$txt2);
  603. //Superscript and Subscript Y coordinate adjustment (now for striked-through texts)
  604. $adjusty = 1.6;
  605. if($this->SUB) $adjusty = 3.05;
  606. if($this->SUP) $adjusty = 1.1;
  607. //End of coordinate adjustment
  608. if($this->strike) //EDITEI
  609. $s.=' '.$this->_dounderline($this->x+$dx,$this->y+$adjusty,$txt);
  610. if($this->ColorFlag) $s.=' Q';
  611. if($link!='') $this->Link($this->x+$dx,$this->y+.5*$h-.5*$this->FontSize,$this->GetStringWidth($txt),$this->FontSize,$link);
  612. }
  613. if($s) $this->_out($s);
  614. $this->lasth=$h;
  615. if( strpos($txt,"\n") !== false) $ln=1; //EDITEI - cell now recognizes \n! << comes from <BR> tag
  616. if($ln>0)
  617. {
  618. //Go to next line
  619. $this->y += $h;
  620. if($ln==1) //EDITEI
  621. {
  622. //Move to next line
  623. if ($currentx != 0) $this->x=$currentx;
  624. else $this->x=$this->lMargin;
  625. }
  626. }
  627. else $this->x+=$w;
  628. }
  629. //EDITEI
  630. function MultiCell($w,$h,$txt,$border=0,$align='J',$fill=0,$link='')
  631. {
  632. //Output text with automatic or explicit line breaks
  633. $cw=&$this->CurrentFont['cw'];
  634. if($w==0) $w=$this->w-$this->rMargin-$this->x;
  635. $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
  636. $s=str_replace("\r",'',$txt);
  637. $nb=strlen($s);
  638. if($nb>0 and $s[$nb-1]=="\n") $nb--;
  639. $b=0;
  640. if($border)
  641. {
  642. if($border==1)
  643. {
  644. $border='LTRB';
  645. $b='LRT';
  646. $b2='LR';
  647. }
  648. else
  649. {
  650. $b2='';
  651. if(is_int(strpos($border,'L'))) $b2.='L';
  652. if(is_int(strpos($border,'R'))) $b2.='R';
  653. $b=is_int(strpos($border,'T')) ? $b2.'T' : $b2;
  654. }
  655. }
  656. $sep=-1;
  657. $i=0;
  658. $j=0;
  659. $l=0;
  660. $ns=0;
  661. $nl=1;
  662. while($i<$nb)
  663. {
  664. //Get next character
  665. $c=$s{$i};
  666. if($c=="\n")
  667. {
  668. //Explicit line break
  669. if($this->ws>0)
  670. {
  671. $this->ws=0;
  672. $this->_out('0 Tw');
  673. }
  674. $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link);
  675. $i++;
  676. $sep=-1;
  677. $j=$i;
  678. $l=0;
  679. $ns=0;
  680. $nl++;
  681. if($border and $nl==2) $b=$b2;
  682. continue;
  683. }
  684. if($c==' ')
  685. {
  686. $sep=$i;
  687. $ls=$l;
  688. $ns++;
  689. }
  690. $l+=$cw[$c];
  691. if($l>$wmax)
  692. {
  693. //Automatic line break
  694. if($sep==-1)
  695. {
  696. if($i==$j) $i++;
  697. if($this->ws>0)
  698. {
  699. $this->ws=0;
  700. $this->_out('0 Tw');
  701. }
  702. $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link);
  703. }
  704. else
  705. {
  706. if($align=='J')
  707. {
  708. $this->ws=($ns>1) ? ($wmax-$ls)/1000*$this->FontSize/($ns-1) : 0;
  709. $this->_out(sprintf('%.3f Tw',$this->ws*$this->k));
  710. }
  711. $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill,$link);
  712. $i=$sep+1;
  713. }
  714. $sep=-1;
  715. $j=$i;
  716. $l=0;
  717. $ns=0;
  718. $nl++;
  719. if($border and $nl==2) $b=$b2;
  720. }
  721. else $i++;
  722. }
  723. //Last chunk
  724. if($this->ws>0)
  725. {
  726. $this->ws=0;
  727. $this->_out('0 Tw');
  728. }
  729. if($border and is_int(strpos($border,'B'))) $b.='B';
  730. $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill,$link);
  731. $this->x=$this->lMargin;
  732. }
  733. function Write($h,$txt,$currentx=0,$link='') //EDITEI
  734. {
  735. //Output text in flowing mode
  736. $cw=&$this->CurrentFont['cw'];
  737. $w=$this->w-$this->rMargin-$this->x;
  738. $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
  739. $s=str_replace("\r",'',$txt);
  740. $nb=strlen($s);
  741. $sep=-1;
  742. $i=0;
  743. $j=0;
  744. $l=0;
  745. $nl=1;
  746. while($i<$nb)
  747. {
  748. //Get next character
  749. $c=$s{$i};
  750. if($c=="\n")
  751. {
  752. //Explicit line break
  753. $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
  754. $i++;
  755. $sep=-1;
  756. $j=$i;
  757. $l=0;
  758. if($nl==1)
  759. {
  760. if ($currentx != 0) $this->x=$currentx;//EDITEI
  761. else $this->x=$this->lMargin;
  762. $w=$this->w-$this->rMargin-$this->x;
  763. $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
  764. }
  765. $nl++;
  766. continue;
  767. }
  768. if($c == ' ') $sep=$i;
  769. $l += $cw[$c];
  770. if($l > $wmax)
  771. {
  772. //Automatic line break
  773. if($sep==-1)
  774. {
  775. if($this->x > $this->lMargin)
  776. {
  777. //Move to next line
  778. if ($currentx != 0) $this->x=$currentx;//EDITEI
  779. else $this->x=$this->lMargin;
  780. $this->y+=$h;
  781. $w=$this->w-$this->rMargin-$this->x;
  782. $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
  783. $i++;
  784. $nl++;
  785. continue;
  786. }
  787. if($i==$j) $i++;
  788. $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
  789. }
  790. else
  791. {
  792. $this->Cell($w,$h,substr($s,$j,$sep-$j),0,2,'',0,$link);
  793. $i=$sep+1;
  794. }
  795. $sep=-1;
  796. $j=$i;
  797. $l=0;
  798. if($nl==1)
  799. {
  800. if ($currentx != 0) $this->x=$currentx;//EDITEI
  801. else $this->x=$this->lMargin;
  802. $w=$this->w-$this->rMargin-$this->x;
  803. $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
  804. }
  805. $nl++;
  806. }
  807. else $i++;
  808. }
  809. //Last chunk
  810. if($i!=$j) $this->Cell($l/1000*$this->FontSize,$h,substr($s,$j),0,0,'',0,$link);
  811. }
  812. //-------------------------FLOWING BLOCK------------------------------------//
  813. //EDITEI some things (added/changed) //
  814. //The following functions were originally written by Damon Kohler //
  815. //--------------------------------------------------------------------------//
  816. function saveFont()
  817. {
  818. $saved = array();
  819. $saved[ 'family' ] = $this->FontFamily;
  820. $saved[ 'style' ] = $this->FontStyle;
  821. $saved[ 'sizePt' ] = $this->FontSizePt;
  822. $saved[ 'size' ] = $this->FontSize;
  823. $saved[ 'curr' ] =& $this->CurrentFont;
  824. $saved[ 'color' ] = $this->TextColor; //EDITEI
  825. $saved[ 'bgcolor' ] = $this->FillColor; //EDITEI
  826. $saved[ 'HREF' ] = $this->HREF; //EDITEI
  827. $saved[ 'underline' ] = $this->underline; //EDITEI
  828. $saved[ 'strike' ] = $this->strike; //EDITEI
  829. $saved[ 'SUP' ] = $this->SUP; //EDITEI
  830. $saved[ 'SUB' ] = $this->SUB; //EDITEI
  831. $saved[ 'linewidth' ] = $this->LineWidth; //EDITEI
  832. $saved[ 'drawcolor' ] = $this->DrawColor; //EDITEI
  833. $saved[ 'is_outline' ] = $this->outline_on; //EDITEI
  834. return $saved;
  835. }
  836. function restoreFont( $saved )
  837. {
  838. $this->FontFamily = $saved[ 'family' ];
  839. $this->FontStyle = $saved[ 'style' ];
  840. $this->FontSizePt = $saved[ 'sizePt' ];
  841. $this->FontSize = $saved[ 'size' ];
  842. $this->CurrentFont =& $saved[ 'curr' ];
  843. $this->TextColor = $saved[ 'color' ]; //EDITEI
  844. $this->FillColor = $saved[ 'bgcolor' ]; //EDITEI
  845. $this->ColorFlag = ($this->FillColor != $this->TextColor); //Restore ColorFlag as well
  846. $this->HREF = $saved[ 'HREF' ]; //EDITEI
  847. $this->underline = $saved[ 'underline' ]; //EDITEI
  848. $this->strike = $saved[ 'strike' ]; //EDITEI
  849. $this->SUP = $saved[ 'SUP' ]; //EDITEI
  850. $this->SUB = $saved[ 'SUB' ]; //EDITEI
  851. $this->LineWidth = $saved[ 'linewidth' ]; //EDITEI
  852. $this->DrawColor = $saved[ 'drawcolor' ]; //EDITEI
  853. $this->outline_on = $saved[ 'is_outline' ]; //EDITEI
  854. if( $this->page > 0)
  855. $this->_out( sprintf( 'BT /F%d %.2f Tf ET', $this->CurrentFont[ 'i' ], $this->FontSizePt ) );
  856. }
  857. function newFlowingBlock( $w, $h, $b = 0, $a = 'J', $f = 0 , $is_table = false )
  858. {
  859. // cell width in points
  860. if ($is_table) $this->flowingBlockAttr[ 'width' ] = ($w * $this->k);
  861. else $this->flowingBlockAttr[ 'width' ] = ($w * $this->k) - (2*$this->cMargin*$this->k);
  862. // line height in user units
  863. $this->flowingBlockAttr[ 'is_table' ] = $is_table;
  864. $this->flowingBlockAttr[ 'height' ] = $h;
  865. $this->flowingBlockAttr[ 'lineCount' ] = 0;
  866. $this->flowingBlockAttr[ 'border' ] = $b;
  867. $this->flowingBlockAttr[ 'align' ] = $a;
  868. $this->flowingBlockAttr[ 'fill' ] = $f;
  869. $this->flowingBlockAttr[ 'font' ] = array();
  870. $this->flowingBlockAttr[ 'content' ] = array();
  871. $this->flowingBlockAttr[ 'contentWidth' ] = 0;
  872. }
  873. function finishFlowingBlock($outofblock=false)
  874. {
  875. if (!$outofblock) $currentx = $this->x; //EDITEI - in order to make the Cell method work better
  876. //prints out the last chunk
  877. $is_table = $this->flowingBlockAttr[ 'is_table' ];
  878. $maxWidth =& $this->flowingBlockAttr[ 'width' ];
  879. $lineHeight =& $this->flowingBlockAttr[ 'height' ];
  880. $border =& $this->flowingBlockAttr[ 'border' ];
  881. $align =& $this->flowingBlockAttr[ 'align' ];
  882. $fill =& $this->flowingBlockAttr[ 'fill' ];
  883. $content =& $this->flowingBlockAttr[ 'content' ];
  884. $font =& $this->flowingBlockAttr[ 'font' ];
  885. $contentWidth =& $this->flowingBlockAttr[ 'contentWidth' ];
  886. $lineCount =& $this->flowingBlockAttr[ 'lineCount' ];
  887. // set normal spacing
  888. $this->_out( sprintf( '%.3f Tw', 0 ) );
  889. $this->ws = 0;
  890. // the amount of space taken up so far in user units
  891. $usedWidth = 0;
  892. // Print out each chunk
  893. //EDITEI - Print content according to alignment
  894. $empty = $maxWidth - $contentWidth;
  895. $empty /= $this->k;
  896. $b = ''; //do not use borders
  897. $arraysize = count($content);
  898. $margins = (2*$this->cMargin);
  899. if ($outofblock)
  900. {
  901. $align = 'C';
  902. $empty = 0;
  903. $margins = $this->cMargin;
  904. }
  905. switch($align)
  906. {
  907. case 'R':
  908. foreach ( $content as $k => $chunk )
  909. {
  910. $this->restoreFont( $font[ $k ] );
  911. $stringWidth = $this->GetStringWidth( $chunk ) + ( $this->ws * substr_count( $chunk, ' ' ) / $this->k );
  912. // determine which borders should be used
  913. $b = '';
  914. if ( $lineCount == 1 && is_int( strpos( $border, 'T' ) ) ) $b .= 'T';
  915. if ( $k == count( $content ) - 1 && is_int( strpos( $border, 'R' ) ) ) $b .= 'R';
  916. if ($k == $arraysize-1 and !$outofblock) $skipln = 1;
  917. else $skipln = 0;
  918. if ($arraysize == 1) $this->Cell( $stringWidth + $margins + $empty, $lineHeight, $chunk, $b, $skipln, $align, $fill, $this->HREF , $currentx ); //mono-style line
  919. elseif ($k == 0) $this->Cell( $stringWidth + ($margins/2) + $empty, $lineHeight, $chunk, $b, 0, 'R', $fill, $this->HREF );//first part
  920. elseif ($k == $arraysize-1 ) $this->Cell( $stringWidth + ($margins/2), $lineHeight, $chunk, $b, $skipln, '', $fill, $this->HREF, $currentx );//last part
  921. else $this->Cell( $stringWidth , $lineHeight, $chunk, $b, 0, '', $fill, $this->HREF );//middle part
  922. }
  923. break;
  924. case 'L':
  925. case 'J':
  926. foreach ( $content as $k => $chunk )
  927. {
  928. $this->restoreFont( $font[ $k ] );
  929. $stringWidth = $this->GetStringWidth( $chunk ) + ( $this->ws * substr_count( $chunk, ' ' ) / $this->k );
  930. // determine which borders should be used
  931. $b = '';
  932. if ( $lineCount == 1 && is_int( strpos( $border, 'T' ) ) ) $b .= 'T';
  933. if ( $k == 0 && is_int( strpos( $border, 'L' ) ) ) $b .= 'L';
  934. if ($k == $arraysize-1 and !$outofblock) $skipln = 1;
  935. else $skipln = 0;
  936. if (!$is_table and !$outofblock and !$fill and $align=='L' and $k == 0) {$align='';$margins=0;} //Remove margins in this special (though often) case
  937. if ($arraysize == 1) $this->Cell( $stringWidth + $margins + $empty, $lineHeight, $chunk, $b, $skipln, $align, $fill, $this->HREF , $currentx ); //mono-style line
  938. elseif ($k == 0) $this->Cell( $stringWidth + ($margins/2), $lineHeight, $chunk, $b, $skipln, $align, $fill, $this->HREF );//first part
  939. elseif ($k == $arraysize-1 ) $this->Cell( $stringWidth + ($margins/2) + $empty, $lineHeight, $chunk, $b, $skipln, '', $fill, $this->HREF, $currentx );//last part
  940. else $this->Cell( $stringWidth , $lineHeight, $chunk, $b, $skipln, '', $fill, $this->HREF );//middle part
  941. }
  942. break;
  943. case 'C':
  944. foreach ( $content as $k => $chunk )
  945. {
  946. $this->restoreFont( $font[ $k ] );
  947. $stringWidth = $this->GetStringWidth( $chunk ) + ( $this->ws * substr_count( $chunk, ' ' ) / $this->k );
  948. // determine which borders should be used
  949. $b = '';
  950. if ( $lineCount == 1 && is_int( strpos( $border, 'T' ) ) ) $b .= 'T';
  951. if ($k == $arraysize-1 and !$outofblock) $skipln = 1;
  952. else $skipln = 0;
  953. if ($arraysize == 1) $this->Cell( $stringWidth + $margins + $empty, $lineHeight, $chunk, $b, $skipln, $align, $fill, $this->HREF , $currentx ); //mono-style line
  954. elseif ($k == 0) $this->Cell( $stringWidth + ($margins/2) + ($empty/2), $lineHeight, $chunk, $b, 0, 'R', $fill, $this->HREF );//first part
  955. elseif ($k == $arraysize-1 ) $this->Cell( $stringWidth + ($margins/2) + ($empty/2), $lineHeight, $chunk, $b, $skipln, 'L', $fill, $this->HREF, $currentx );//last part
  956. else $this->Cell( $stringWidth , $lineHeight, $chunk, $b, 0, '', $fill, $this->HREF );//middle part
  957. }
  958. break;
  959. default: break;
  960. }
  961. }
  962. function WriteFlowingBlock( $s , $outofblock = false )
  963. {
  964. if (!$outofblock) $currentx = $this->x; //EDITEI - in order to make the Cell method work better
  965. $is_table = $this->flowingBlockAttr[ 'is_table' ];
  966. // width of all the content so far in points
  967. $contentWidth =& $this->flowingBlockAttr[ 'contentWidth' ];
  968. // cell width in points
  969. $maxWidth =& $this->flowingBlockAttr[ 'width' ];
  970. $lineCount =& $this->flowingBlockAttr[ 'lineCount' ];
  971. // line height in user units
  972. $lineHeight =& $this->flowingBlockAttr[ 'height' ];
  973. $border =& $this->flowingBlockAttr[ 'border' ];
  974. $align =& $this->flowingBlockAttr[ 'align' ];
  975. $fill =& $this->flowingBlockAttr[ 'fill' ];
  976. $content =& $this->flowingBlockAttr[ 'content' ];
  977. $font =& $this->flowingBlockAttr[ 'font' ];
  978. $font[] = $this->saveFont();
  979. $content[] = '';
  980. $currContent =& $content[ count( $content ) - 1 ];
  981. // where the line should be cutoff if it is to be justified
  982. $cutoffWidth = $contentWidth;
  983. // for every character in the string
  984. for ( $i = 0; $i < strlen( $s ); $i++ )
  985. {
  986. // extract the current character
  987. $c = $s{$i};
  988. // get the width of the character in points
  989. $cw = $this->CurrentFont[ 'cw' ][ $c ] * ( $this->FontSizePt / 1000 );
  990. if ( $c == ' ' )
  991. {
  992. $currContent .= ' ';
  993. $cutoffWidth = $contentWidth;
  994. $contentWidth += $cw;
  995. continue;
  996. }
  997. // try adding another char
  998. if ( $contentWidth + $cw > $maxWidth )
  999. {
  1000. // it won't fit, output what we already have
  1001. $lineCount++;
  1002. //Readjust MaxSize in order to use the whole page width
  1003. if ($outofblock and ($lineCount == 1) ) $maxWidth = $this->pgwidth * $this->k;
  1004. // contains any content that didn't make it into this print
  1005. $savedContent = '';
  1006. $savedFont = array();
  1007. // first, cut off and save any partial words at the end of the string
  1008. $words = explode( ' ', $currContent );
  1009. // if it looks like we didn't finish any words for this chunk
  1010. if ( count( $words ) == 1 )
  1011. {
  1012. // save and crop off the content currently on the stack
  1013. $savedContent = array_pop( $content );
  1014. $savedFont = array_pop( $font );
  1015. // trim any trailing spaces off the last bit of content
  1016. $currContent =& $content[ count( $content ) - 1 ];
  1017. $currContent = rtrim( $currContent );
  1018. }
  1019. else // otherwise, we need to find which bit to cut off
  1020. {
  1021. $lastContent = '';
  1022. for ( $w = 0; $w < count( $words ) - 1; $w++) $lastContent .= "{$words[ $w ]} ";
  1023. $savedContent = $words[ count( $words ) - 1 ];
  1024. $savedFont = $this->saveFont();
  1025. // replace the current content with the cropped version
  1026. $currContent = rtrim( $lastContent );
  1027. }
  1028. // update $contentWidth and $cutoffWidth since they changed with cropping
  1029. $contentWidth = 0;
  1030. foreach ( $content as $k => $chunk )
  1031. {
  1032. $this->restoreFont( $font[ $k ] );
  1033. $contentWidth += $this->GetStringWidth( $chunk ) * $this->k;
  1034. }
  1035. $cutoffWidth = $contentWidth;
  1036. // if it's justified, we need to find the char spacing
  1037. if( $align == 'J' )
  1038. {
  1039. // count how many spaces there are in the entire content string
  1040. $numSpaces = 0;
  1041. foreach ( $content as $chunk ) $numSpaces += substr_count( $chunk, ' ' );
  1042. // if there's more than one space, find word spacing in points
  1043. if ( $numSpaces > 0 ) $this->ws = ( $maxWidth - $cutoffWidth ) / $numSpaces;
  1044. else $this->ws = 0;
  1045. $this->_out( sprintf( '%.3f Tw', $this->ws ) );
  1046. }
  1047. // otherwise, we want normal spacing
  1048. else $this->_out( sprintf( '%.3f Tw', 0 ) );
  1049. //EDITEI - Print content according to alignment
  1050. if (!isset($numSpaces)) $numSpaces = 0;
  1051. $contentWidth -= ($this->ws*$numSpaces);
  1052. $empty = $maxWidth - $contentWidth - 2*($this->ws*$numSpaces);
  1053. $empty /= $this->k;
  1054. $b = ''; //do not use borders
  1055. /*'If' below used in order to fix "first-line of other page with justify on" bug*/
  1056. if($this->y+$this->divheight>$this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak())
  1057. {
  1058. $bak_x=$this->x;//Current X position
  1059. $ws=$this->ws;//Word Spacing
  1060. if($ws>0)
  1061. {
  1062. $this->ws=0;
  1063. $this->_out('0 Tw');
  1064. }
  1065. debug('calling add Page');
  1066. $this->AddPage($this->CurOrientation);
  1067. $this->x=$bak_x;
  1068. if($ws>0)
  1069. {
  1070. $this->ws=$ws;
  1071. $this->_out(sprintf('%.3f Tw',$ws));
  1072. }
  1073. }
  1074. $arraysize = count($content);
  1075. $margins = (2*$this->cMargin);
  1076. if ($outofblock)
  1077. {
  1078. $align = 'C';
  1079. $empty = 0;
  1080. $margins = $this->cMargin;
  1081. }
  1082. switch($align)
  1083. {
  1084. case 'R':
  1085. foreach ( $content as $k => $chunk )
  1086. {
  1087. $this->restoreFont( $font[ $k ] );
  1088. $stringWidth = $this->GetStringWidth( $chunk ) + (

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