PageRenderTime 56ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 2ms

/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
  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 ) + ( $this->ws * substr_count( $chunk, ' ' ) / $this->k );
  1089. // determine which borders should be used
  1090. $b = '';
  1091. if ( $lineCount == 1 && is_int( strpos( $border, 'T' ) ) ) $b .= 'T';
  1092. if ( $k == count( $content ) - 1 && is_int( strpos( $border, 'R' ) ) ) $b .= 'R';
  1093. if ($arraysize == 1) $this->Cell( $stringWidth + $margins + $empty, $lineHeight, $chunk, $b, 1, $align, $fill, $this->HREF , $currentx ); //mono-style line
  1094. elseif ($k == 0) $this->Cell( $stringWidth + ($margins/2) + $empty, $lineHeight, $chunk, $b, 0, 'R', $fill, $this->HREF );//first part
  1095. elseif ($k == $arraysize-1 ) $this->Cell( $stringWidth + ($margins/2), $lineHeight, $chunk, $b, 1, '', $fill, $this->HREF, $currentx );//last part
  1096. else $this->Cell( $stringWidth , $lineHeight, $chunk, $b, 0, '', $fill, $this->HREF );//middle part
  1097. }
  1098. break;
  1099. case 'L':
  1100. case 'J':
  1101. foreach ( $content as $k => $chunk )
  1102. {
  1103. $this->restoreFont( $font[ $k ] );
  1104. $stringWidth = $this->GetStringWidth( $chunk ) + ( $this->ws * substr_count( $chunk, ' ' ) / $this->k );
  1105. // determine which borders should be used
  1106. $b = '';
  1107. if ( $lineCount == 1 && is_int( strpos( $border, 'T' ) ) ) $b .= 'T';
  1108. if ( $k == 0 && is_int( strpos( $border, 'L' ) ) ) $b .= 'L';
  1109. if (!$is_table and !$outofblock and !$fill and $align=='L' and $k == 0)
  1110. {
  1111. //Remove margins in this special (though often) case
  1112. $align='';
  1113. $margins=0;
  1114. }
  1115. if ($arraysize == 1) $this->Cell( $stringWidth + $margins + $empty, $lineHeight, $chunk, $b, 1, $align, $fill, $this->HREF , $currentx ); //mono-style line
  1116. elseif ($k == 0) $this->Cell( $stringWidth + ($margins/2), $lineHeight, $chunk, $b, 0, $align, $fill, $this->HREF );//first part
  1117. elseif ($k == $arraysize-1 ) $this->Cell( $stringWidth + ($margins/2) + $empty, $lineHeight, $chunk, $b, 1, '', $fill, $this->HREF, $currentx );//last part
  1118. else $this->Cell( $stringWidth , $lineHeight, $chunk, $b, 0, '', $fill, $this->HREF );//middle part
  1119. if (!$is_table and !$outofblock and !$fill and $align=='' and $k == 0)
  1120. {
  1121. $align = 'L';
  1122. $margins = (2*$this->cMargin);
  1123. }
  1124. }
  1125. break;
  1126. case 'C':
  1127. foreach ( $content as $k => $chunk )
  1128. {
  1129. $this->restoreFont( $font[ $k ] );
  1130. $stringWidth = $this->GetStringWidth( $chunk ) + ( $this->ws * substr_count( $chunk, ' ' ) / $this->k );
  1131. // determine which borders should be used
  1132. $b = '';
  1133. if ( $lineCount == 1 && is_int( strpos( $border, 'T' ) ) ) $b .= 'T';
  1134. if ($arraysize == 1) $this->Cell( $stringWidth + $margins + $empty, $lineHeight, $chunk, $b, 1, $align, $fill, $this->HREF , $currentx ); //mono-style line
  1135. elseif ($k == 0) $this->Cell( $stringWidth + ($margins/2) + ($empty/2), $lineHeight, $chunk, $b, 0, 'R', $fill, $this->HREF );//first part
  1136. elseif ($k == $arraysize-1 ) $this->Cell( $stringWidth + ($margins/2) + ($empty/2), $lineHeight, $chunk, $b, 1, 'L', $fill, $this->HREF, $currentx );//last part
  1137. else $this->Cell( $stringWidth , $lineHeight, $chunk, $b, 0, '', $fill, $this->HREF );//middle part
  1138. }
  1139. break;
  1140. default: break;
  1141. }
  1142. // move on to the next line, reset variables, tack on saved content and current char
  1143. $this->restoreFont( $savedFont );
  1144. $font = array( $savedFont );
  1145. $content = array( $savedContent . $s{ $i } );
  1146. $currContent =& $content[ 0 ];
  1147. $contentWidth = $this->GetStringWidth( $currContent ) * $this->k;
  1148. $cutoffWidth = $contentWidth;
  1149. }
  1150. // another character will fit, so add it on
  1151. else
  1152. {
  1153. $contentWidth += $cw;
  1154. $currContent .= $s{ $i };
  1155. }
  1156. }
  1157. }
  1158. //----------------------END OF FLOWING BLOCK------------------------------------//
  1159. //EDITEI
  1160. //Thanks to Ron Korving for the WordWrap() function
  1161. function WordWrap(&$text, $maxwidth)
  1162. {
  1163. $biggestword=0;//EDITEI
  1164. $toonarrow=false;//EDITEI
  1165. $text = trim($text);
  1166. if ($text==='') return 0;
  1167. $space = $this->GetStringWidth(' ');
  1168. $lines = explode("\n", $text);
  1169. $text = '';
  1170. $count = 0;
  1171. foreach ($lines as $line)
  1172. {
  1173. $words = preg_split('/ +/', $line);
  1174. $width = 0;
  1175. foreach ($words as $word)
  1176. {
  1177. $wordwidth = $this->GetStringWidth($word);
  1178. //EDITEI
  1179. //Warn user that maxwidth is insufficient
  1180. if ($wordwidth > $maxwidth)
  1181. {
  1182. if ($wordwidth > $biggestword) $biggestword = $wordwidth;
  1183. $toonarrow=true;//EDITEI
  1184. }
  1185. if ($width + $wordwidth <= $maxwidth)
  1186. {
  1187. $width += $wordwidth + $space;
  1188. $text .= $word.' ';
  1189. }
  1190. else
  1191. {
  1192. $width = $wordwidth + $space;
  1193. $text = rtrim($text)."\n".$word.' ';
  1194. $count++;
  1195. }
  1196. }
  1197. $text = rtrim($text)."\n";
  1198. $count++;
  1199. }
  1200. $text = rtrim($text);
  1201. //Return -(wordsize) if word is bigger than maxwidth
  1202. if ($toonarrow) return -$biggestword;
  1203. else return $count;
  1204. }
  1205. //EDITEI
  1206. //Thanks to Seb(captainseb@wanadoo.fr) for the _SetTextRendering() and SetTextOutline() functions
  1207. /**
  1208. * Set Text Rendering Mode
  1209. * @param int $mode Set the rendering mode.<ul><li>0 : Fill text (default)</li><li>1 : Stroke</li><li>2 : Fill & stroke</li></ul>
  1210. * @see SetTextOutline()
  1211. */
  1212. //This function is not being currently used
  1213. function _SetTextRendering($mode) {
  1214. if (!(($mode == 0) || ($mode == 1) || ($mode == 2)))
  1215. $this->Error("Text rendering mode should be 0, 1 or 2 (value : $mode)");
  1216. $this->_out($mode.' Tr');
  1217. }
  1218. /**
  1219. * Set Text Ouline On/Off
  1220. * @param mixed $width If set to false the text rending mode is set to fill, else it's the width of the outline
  1221. * @param int $r If g et b are given, red component; if not, indicates the gray level. Value between 0 and 255
  1222. * @param int $g Green component (between 0 and 255)
  1223. * @param int $b Blue component (between 0 and 255)
  1224. * @see _SetTextRendering()
  1225. */
  1226. function SetTextOutline($width, $r=0, $g=-1, $b=-1) //EDITEI
  1227. {
  1228. if ($width == false) //Now resets all values
  1229. {
  1230. $this->outline_on = false;
  1231. $this->SetLineWidth(0.2);
  1232. $this->SetDrawColor(0);
  1233. $this->_setTextRendering(0);
  1234. $this->_out('0 Tr');
  1235. }
  1236. else
  1237. {
  1238. $this->SetLineWidth($width);
  1239. $this->SetDrawColor($r, $g , $b);
  1240. $this->_out('2 Tr'); //Fixed
  1241. }
  1242. }
  1243. //function Circle() thanks to Olivier PLATHEY
  1244. //EDITEI
  1245. function Circle($x,$y,$r,$style='')
  1246. {
  1247. $this->Ellipse($x,$y,$r,$r,$style);
  1248. }
  1249. //function Ellipse() thanks to Olivier PLATHEY
  1250. //EDITEI
  1251. function Ellipse($x,$y,$rx,$ry,$style='D')
  1252. {
  1253. if($style=='F') $op='f';
  1254. elseif($style=='FD' or $style=='DF') $op='B';
  1255. else $op='S';
  1256. $lx=4/3*(M_SQRT2-1)*$rx;
  1257. $ly=4/3*(M_SQRT2-1)*$ry;
  1258. $k=$this->k;
  1259. $h=$this->h;
  1260. $this->_out(sprintf('%.2f %.2f m %.2f %.2f %.2f %.2f %.2f %.2f c',
  1261. ($x+$rx)*$k,($h-$y)*$k,
  1262. ($x+$rx)*$k,($h-($y-$ly))*$k,
  1263. ($x+$lx)*$k,($h-($y-$ry))*$k,
  1264. $x*$k,($h-($y-$ry))*$k));
  1265. $this->_out(sprintf('%.2f %.2f %.2f %.2f %.2f %.2f c',
  1266. ($x-$lx)*$k,($h-($y-$ry))*$k,
  1267. ($x-$rx)*$k,($h-($y-$ly))*$k,
  1268. ($x-$rx)*$k,($h-$y)*$k));
  1269. $this->_out(sprintf('%.2f %.2f %.2f %.2f %.2f %.2f c',
  1270. ($x-$rx)*$k,($h-($y+$ly))*$k,
  1271. ($x-$lx)*$k,($h-($y+$ry))*$k,
  1272. $x*$k,($h-($y+$ry))*$k));
  1273. $this->_out(sprintf('%.2f %.2f %.2f %.2f %.2f %.2f c %s',
  1274. ($x+$lx)*$k,($h-($y+$ry))*$k,
  1275. ($x+$rx)*$k,($h-($y+$ly))*$k,
  1276. ($x+$rx)*$k,($h-$y)*$k,
  1277. $op));
  1278. }
  1279. function Image($file,$x,$y,$w=0,$h=0,$type='',$link='',$paint=true)
  1280. {
  1281. //Put an image on the page
  1282. if(!isset($this->images[$file]))
  1283. {
  1284. //First use of image, get info
  1285. if($type=='')
  1286. {
  1287. $pos=strrpos($file,'.');
  1288. if(!$pos) $this->Error('Image file has no extension and no type was specified: '.$file);
  1289. $type=substr($file,$pos+1);
  1290. }
  1291. $type=strtolower($type);
  1292. $mqr=get_magic_quotes_runtime();
  1293. set_magic_quotes_runtime(0);
  1294. if($type=='jpg' or $type=='jpeg') $info=$this->_parsejpg($file);
  1295. elseif($type=='png') $info=$this->_parsepng($file);
  1296. elseif($type=='gif') $info=$this->_parsegif($file); //EDITEI - GIF format included
  1297. else
  1298. {
  1299. //Allow for additional formats
  1300. $mtd='_parse'.$type;
  1301. if(!method_exists($this,$mtd)) $this->Error('Unsupported image type: '.$type);
  1302. $info=$this->$mtd($file);
  1303. }
  1304. set_magic_quotes_runtime($mqr);
  1305. $info['i']=count($this->images)+1;
  1306. $this->images[$file]=$info;
  1307. }
  1308. else $info=$this->images[$file];
  1309. //Automatic width and height calculation if needed
  1310. if($w==0 and $h==0)
  1311. {
  1312. //Put image at 72 dpi
  1313. $w=$info['w']/$this->k;
  1314. $h=$info['h']/$this->k;
  1315. }
  1316. if($w==0) $w=$h*$info['w']/$info['h'];
  1317. if($h==0) $h=$w*$info['h']/$info['w'];
  1318. $changedpage = false; //EDITEI
  1319. //Avoid drawing out of the paper(exceeding width limits). //EDITEI
  1320. if ( ($x + $w) > $this->fw )
  1321. {
  1322. $x = $this->lMargin;
  1323. $y += 5;
  1324. }
  1325. //Avoid drawing out of the page. //EDITEI
  1326. if ( ($y + $h) > $this->fh )
  1327. {
  1328. $this->AddPage();
  1329. $y = $tMargin + 10; // +10 to avoid drawing too close to border of page
  1330. $changedpage = true;
  1331. }
  1332. $outstring = 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']);
  1333. if($paint) //EDITEI
  1334. {
  1335. $this->_out($outstring);
  1336. if($link) $this->Link($x,$y,$w,$h,$link);
  1337. }
  1338. //Avoid writing text on top of the image. //EDITEI
  1339. if ($changedpage) $this->y = $y + $h;
  1340. else $this->y = $y + $h;
  1341. //Return width-height array //EDITEI
  1342. $sizesarray['WIDTH'] = $w;
  1343. $sizesarray['HEIGHT'] = $h;
  1344. $sizesarray['X'] = $x; //Position before painting image
  1345. $sizesarray['Y'] = $y; //Position before painting image
  1346. $sizesarray['OUTPUT'] = $outstring;
  1347. return $sizesarray;
  1348. }
  1349. //EDITEI - Done after reading a little about PDF reference guide
  1350. function DottedRect($x=100,$y=150,$w=50,$h=50)
  1351. {
  1352. $x *= $this->k ;
  1353. $y = ($this->h-$y)*$this->k;
  1354. $w *= $this->k ;
  1355. $h *= $this->k ;// - h?
  1356. $herex = $x;
  1357. $herey = $y;
  1358. //Make fillcolor == drawcolor
  1359. $bak_fill = $this->FillColor;
  1360. $this->FillColor = $this->DrawColor;
  1361. $this->FillColor = str_replace('RG','rg',$this->FillColor);
  1362. $this->_out($this->FillColor);
  1363. while ($herex < ($x + $w)) //draw from upper left to upper right
  1364. {
  1365. $this->DrawDot($herex,$herey);
  1366. $herex += (3*$this->k);
  1367. }
  1368. $herex = $x + $w;
  1369. while ($herey > ($y - $h)) //draw from upper right to lower right
  1370. {
  1371. $this->DrawDot($herex,$herey);
  1372. $herey -= (3*$this->k);
  1373. }
  1374. $herey = $y - $h;
  1375. while ($herex > $x) //draw from lower right to lower left
  1376. {
  1377. $this->DrawDot($herex,$herey);
  1378. $herex -= (3*$this->k);
  1379. }
  1380. $herex = $x;
  1381. while ($herey < $y) //draw from lower left to upper left
  1382. {
  1383. $this->DrawDot($herex,$herey);
  1384. $herey += (3*$this->k);
  1385. }
  1386. $herey = $y;
  1387. $this->FillColor = $bak_fill;
  1388. $this->_out($this->FillColor); //return fillcolor back to normal
  1389. }
  1390. //EDITEI - Done after reading a little about PDF reference guide
  1391. function DrawDot($x,$y) //center x y
  1392. {
  1393. $op = 'B'; // draw Filled Dots
  1394. //F == fill //S == stroke //B == stroke and fill
  1395. $r = 0.5 * $this->k; //raio
  1396. //Start Point
  1397. $x1 = $x - $r;
  1398. $y1 = $y;
  1399. //End Point
  1400. $x2 = $x + $r;
  1401. $y2 = $y;
  1402. //Auxiliar Point
  1403. $x3 = $x;
  1404. $y3 = $y + (2*$r);// 2*raio to make a round (not oval) shape
  1405. //Round join and cap
  1406. $s="\n".'1 J'."\n";
  1407. $s.='1 j'."\n";
  1408. //Upper circle
  1409. $s.=sprintf('%.3f %.3f m'."\n",$x1,$y1); //x y start drawing
  1410. $s.=sprintf('%.3f %.3f %.3f %.3f %.3f %.3f c'."\n",$x1,$y1,$x3,$y3,$x2,$y2);//Bezier curve
  1411. //Lower circle
  1412. $y3 = $y - (2*$r);
  1413. $s.=sprintf("\n".'%.3f %.3f m'."\n",$x1,$y1); //x y start drawing
  1414. $s.=sprintf('%.3f %.3f %.3f %.3f %.3f %.3f c'."\n",$x1,$y1,$x3,$y3,$x2,$y2);
  1415. $s.=$op."\n"; //stroke and fill
  1416. //Draw in PDF file
  1417. $this->_out($s);
  1418. }
  1419. function SetDash($black=false,$white=false)
  1420. {
  1421. if($black and $white) $s=sprintf('[%.3f %.3f] 0 d',$black*$this->k,$white*$this->k);
  1422. else $s='[] 0 d';
  1423. $this->_out($s);
  1424. }
  1425. function Bookmark($txt,$level=0,$y=0)
  1426. {
  1427. if($y == -1) $y = $this->GetY();
  1428. $this->outlines[]=array('t'=>$txt,'l'=>$level,'y'=>$y,'p'=>$this->PageNo());
  1429. }
  1430. function DisplayPreferences($preferences)
  1431. {
  1432. $this->DisplayPreferences .= $preferences;
  1433. }
  1434. function _putbookmarks()
  1435. {
  1436. $nb=count($this->outlines);
  1437. if($nb==0) return;
  1438. $lru=array();
  1439. $level=0;
  1440. foreach($this->outlines as $i=>$o)
  1441. {
  1442. if($o['l']>0)
  1443. {
  1444. $parent=$lru[$o['l']-1];
  1445. //Set parent and last pointers
  1446. $this->outlines[$i]['parent']=$parent;
  1447. $this->outlines[$parent]['last']=$i;
  1448. if($o['l']>$level)
  1449. {
  1450. //Level increasing: set first pointer
  1451. $this->outlines[$parent]['first']=$i;
  1452. }
  1453. }
  1454. else
  1455. $this->outlines[$i]['parent']=$nb;
  1456. if($o['l']<=$level and $i>0)
  1457. {
  1458. //Set prev and next pointers
  1459. $prev=$lru[$o['l']];
  1460. $this->outlines[$prev]['next']=$i;
  1461. $this->outlines[$i]['prev']=$prev;
  1462. }
  1463. $lru[$o['l']]=$i;
  1464. $level=$o['l'];
  1465. }
  1466. //Outline items
  1467. $n=$this->n+1;
  1468. foreach($this->outlines as $i=>$o)
  1469. {
  1470. $this->_newobj();
  1471. $this->_out('<</Title '.$this->_textstring($o['t']));
  1472. $this->_out('/Parent '.($n+$o['parent']).' 0 R');
  1473. if(isset($o['prev']))
  1474. $this->_out('/Prev '.($n+$o['prev']).' 0 R');
  1475. if(isset($o['next']))
  1476. $this->_out('/Next '.($n+$o['next']).' 0 R');
  1477. if(isset($o['first']))
  1478. $this->_out('/First '.($n+$o['first']).' 0 R');
  1479. if(isset($o['last']))
  1480. $this->_out('/Last '.($n+$o['last']).' 0 R');
  1481. $this->_out(sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]',1+2*$o['p'],($this->h-$o['y'])*$this->k));
  1482. $this->_out('/Count 0>>');
  1483. $this->_out('endobj');
  1484. }
  1485. //Outline root
  1486. $this->_newobj();
  1487. $this->OutlineRoot=$this->n;
  1488. $this->_out('<</Type /Outlines /First '.$n.' 0 R');
  1489. $this->_out('/Last '.($n+$lru[0]).' 0 R>>');
  1490. $this->_out('endobj');
  1491. }
  1492. function Ln($h='')
  1493. {
  1494. //Line feed; default value is last cell height
  1495. $this->x=$this->lMargin;
  1496. if(is_string($h)) $this->y+=$this->lasth;
  1497. else $this->y+=$h;
  1498. }
  1499. function GetX()
  1500. {
  1501. //Get x position
  1502. return $this->x;
  1503. }
  1504. function SetX($x)
  1505. {
  1506. //Set x position
  1507. if($x >= 0) $this->x=$x;
  1508. else $this->x = $this->w + $x;
  1509. }
  1510. function GetY()
  1511. {
  1512. //Get y position
  1513. return $this->y;
  1514. }
  1515. function SetY($y)
  1516. {
  1517. //Set y position and reset x
  1518. $this->x=$this->lMargin;
  1519. if($y>=0)
  1520. $this->y=$y;
  1521. else
  1522. $this->y=$this->h+$y;
  1523. }
  1524. function SetXY($x,$y)
  1525. {
  1526. //Set x and y positions
  1527. $this->SetY($y);
  1528. $this->SetX($x);
  1529. }
  1530. function Output($name='',$dest='')
  1531. {
  1532. //Output PDF to some destination
  1533. global $HTTP_SERVER_VARS;
  1534. //Finish document if necessary
  1535. if($this->state < 3) $this->Close();
  1536. //Normalize parameters
  1537. if(is_bool($dest)) $dest=$dest ? 'D' : 'F';
  1538. $dest=strtoupper($dest);
  1539. if($dest=='')
  1540. {
  1541. if($name=='')
  1542. {
  1543. $name='doc.pdf';
  1544. $dest='I';
  1545. }
  1546. else
  1547. $dest='F';
  1548. }
  1549. switch($dest)
  1550. {
  1551. case 'I':
  1552. //Send to standard output
  1553. if(isset($HTTP_SERVER_VARS['SERVER_NAME']))
  1554. {
  1555. //We send to a browser
  1556. Header('Content-Type: application/pdf');
  1557. if(headers_sent())
  1558. $this->Error('Some data has already been output to browser, can\'t send PDF file');
  1559. Header('Content-Length: '.strlen($this->buffer));
  1560. Header('Content-disposition: inline; filename='.$name);
  1561. }
  1562. echo $this->buffer;
  1563. break;
  1564. case 'D':
  1565. //Download file
  1566. if(isset($HTTP_SERVER_VARS['HTTP_USER_AGENT']) and strpos($HTTP_SERVER_VARS['HTTP_USER_AGENT'],'MSIE'))
  1567. Header('Content-Type: application/force-download');
  1568. else
  1569. Header('Content-Type: application/octet-stream');
  1570. if(headers_sent())
  1571. $this->Error('Some data has already been output to browser, can\'t send PDF file');
  1572. Header('Content-Length: '.strlen($this->buffer));
  1573. Header('Content-disposition: attachment; filename='.$name);
  1574. echo $this->buffer;
  1575. break;
  1576. case 'F':
  1577. //Save to local file
  1578. $f=fopen($name,'wb');
  1579. if(!$f) $this->Error('Unable to create output file: '.$name);
  1580. fwrite($f,$this->buffer,strlen($this->buffer));
  1581. fclose($f);
  1582. break;
  1583. case 'S':
  1584. //Return as a string
  1585. return $this->buffer;
  1586. default:
  1587. $this->Error('Incorrect output destination: '.$dest);
  1588. }
  1589. return '';
  1590. }
  1591. /*******************************************************************************
  1592. * *
  1593. * Protected methods *
  1594. * *
  1595. *******************************************************************************/
  1596. function _dochecks()
  1597. {
  1598. //Check for locale-related bug
  1599. if(1.1==1)
  1600. $this->Error('Don\'t alter the locale before including class file');
  1601. //Check for decimal separator
  1602. if(sprintf('%.1f',1.0)!='1.0')
  1603. setlocale(LC_NUMERIC,'C');
  1604. }
  1605. function _begindoc()
  1606. {
  1607. //Start document
  1608. $this->state=1;
  1609. $this->_out('%PDF-1.3');
  1610. }
  1611. function _putpages()
  1612. {
  1613. $nb=$this->page;
  1614. if(!empty($this->AliasNbPages))
  1615. {
  1616. //Replace number of pages
  1617. for($n=1;$n<=$nb;$n++)
  1618. $this->pages[$n]=str_replace($this->AliasNbPages,$nb,$this->pages[$n]);
  1619. }
  1620. if($this->DefOrientation=='P')
  1621. {
  1622. $wPt=$this->fwPt;
  1623. $hPt=$this->fhPt;
  1624. }
  1625. else
  1626. {
  1627. $wPt=$this->fhPt;
  1628. $hPt=$this->fwPt;
  1629. }
  1630. $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
  1631. for($n=1;$n<=$nb;$n++)
  1632. {
  1633. //Page
  1634. $this->_newobj();
  1635. $this->_out('<</Type /Page');
  1636. $this->_out('/Parent 1 0 R');
  1637. if(isset($this->OrientationChanges[$n]))
  1638. $this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$hPt,$wPt));
  1639. $this->_out('/Resources 2 0 R');
  1640. if(isset($this->PageLinks[$n]))
  1641. {
  1642. //Links
  1643. $annots='/Annots [';
  1644. foreach($this->PageLinks[$n] as $pl)
  1645. {
  1646. $rect=sprintf('%.2f %.2f %.2f %.2f',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]);
  1647. $annots.='<</Type /Annot /Subtype /Link /Rect ['.$rect.'] /Border [0 0 0] ';
  1648. if(is_string($pl[4]))
  1649. $annots.='/A <</S /URI /URI '.$this->_textstring($pl[4]).'>>>>';
  1650. else
  1651. {
  1652. $l=$this->links[$pl[4]];
  1653. $h=isset($this->OrientationChanges[$l[0]]) ? $wPt : $hPt;
  1654. $annots.=sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]>>',1+2*$l[0],$h-$l[1]*$this->k);
  1655. }
  1656. }
  1657. $this->_out($annots.']');
  1658. }
  1659. $this->_out('/Contents '.($this->n+1).' 0 R>>');
  1660. $this->_out('endobj');
  1661. //Page content
  1662. $p=($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n];
  1663. $this->_newobj();
  1664. $this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
  1665. $this->_putstream($p);
  1666. $this->_out('endobj');
  1667. }
  1668. //Pages root
  1669. $this->offsets[1]=strlen($this->buffer);
  1670. $this->_out('1 0 obj');
  1671. $this->_out('<</Type /Pages');
  1672. $kids='/Kids [';
  1673. for($i=0;$i<$nb;$i++)
  1674. $kids.=(3+2*$i).' 0 R ';
  1675. $this->_out($kids.']');
  1676. $this->_out('/Count '.$nb);
  1677. $this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$wPt,$hPt));
  1678. $this->_out('>>');
  1679. $this->_out('endobj');
  1680. }
  1681. function _putfonts()
  1682. {
  1683. $nf=$this->n;
  1684. foreach($this->diffs as $diff)
  1685. {
  1686. //Encodings
  1687. $this->_newobj();
  1688. $this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.']>>');
  1689. $this->_out('endobj');
  1690. }
  1691. $mqr=get_magic_quotes_runtime();
  1692. set_magic_quotes_runtime(0);
  1693. foreach($this->FontFiles as $file=>$info)
  1694. {
  1695. //Font file embedding
  1696. $this->_newobj();
  1697. $this->FontFiles[$file]['n']=$this->n;
  1698. if(defined('FPDF_FONTPATH'))
  1699. $file=FPDF_FONTPATH.$file;
  1700. $size=filesize($file);
  1701. if(!$size)
  1702. $this->Error('Font file not found');
  1703. $this->_out('<</Length '.$size);
  1704. if(substr($file,-2)=='.z')
  1705. $this->_out('/Filter /FlateDecode');
  1706. $this->_out('/Length1 '.$info['length1']);
  1707. if(isset($info['length2']))
  1708. $this->_out('/Length2 '.$info['length2'].' /Length3 0');
  1709. $this->_out('>>');
  1710. $f=fopen($file,'rb');
  1711. $this->_putstream(fread($f,$size));
  1712. fclose($f);
  1713. $this->_out('endobj');
  1714. }
  1715. set_magic_quotes_runtime($mqr);
  1716. foreach($this->fonts as $k=>$font)
  1717. {
  1718. //Font objects
  1719. $this->fonts[$k]['n']=$this->n+1;
  1720. $type=$font['type'];
  1721. $name=$font['name'];
  1722. if($type=='core')
  1723. {
  1724. //Standard font
  1725. $this->_newobj();
  1726. $this->_out('<</Type /Font');
  1727. $this->_out('/BaseFont /'.$name);
  1728. $this->_out('/Subtype /Type1');
  1729. if($name!='Symbol' and $name!='ZapfDingbats')
  1730. $this->_out('/Encoding /WinAnsiEncoding');
  1731. $this->_out('>>');
  1732. $this->_out('endobj');
  1733. }
  1734. elseif($type=='Type1' or $type=='TrueType')
  1735. {
  1736. //Additional Type1 or TrueType font
  1737. $this->_newobj();
  1738. $this->_out('<</Type /Font');
  1739. $this->_out('/BaseFont /'.$name);
  1740. $this->_out('/Subtype /'.$type);
  1741. $this->_out('/FirstChar 32 /LastChar 255');
  1742. $this->_out('/Widths '.($this->n+1).' 0 R');
  1743. $this->_out('/FontDescriptor '.($this->n+2).' 0 R');
  1744. if($font['enc'])
  1745. {
  1746. if(isset($font['diff']))
  1747. $this->_out('/Encoding '.($nf+$font['diff']).' 0 R');
  1748. else
  1749. $this->_out('/Encoding /WinAnsiEncoding');
  1750. }
  1751. $this->_out('>>');
  1752. $this->_out('endobj');
  1753. //Widths
  1754. $this->_newobj();
  1755. $cw=&$font['cw'];
  1756. $s='[';
  1757. for($i=32;$i<=255;$i++)
  1758. $s.=$cw[chr($i)].' ';
  1759. $this->_out($s.']');
  1760. $this->_out('endobj');
  1761. //Descriptor
  1762. $this->_newobj();
  1763. $s='<</Type /FontDescriptor /FontName /'.$name;
  1764. foreach($font['desc'] as $k=>$v)
  1765. $s.=' /'.$k.' '.$v;
  1766. $file=$font['file'];
  1767. if($file)
  1768. $s.=' /FontFile'.($type=='Type1' ? '' : '2').' '.$this->FontFiles[$file]['n'].' 0 R';
  1769. $this->_out($s.'>>');
  1770. $this->_out('endobj');
  1771. }
  1772. else
  1773. {
  1774. //Allow for additional types
  1775. $mtd='_put'.strtolower($type);
  1776. if(!method_exists($this,$mtd))
  1777. $this->Error('Unsupported font type: '.$type);
  1778. $this->$mtd($font);
  1779. }
  1780. }
  1781. }
  1782. function _putimages()
  1783. {
  1784. $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
  1785. reset($this->images);
  1786. while(list($file,$info)=each($this->images))
  1787. {
  1788. $this->_newobj();
  1789. $this->images[$file]['n']=$this->n;
  1790. $this->_out('<</Type /XObject');
  1791. $this->_out('/Subtype /Image');
  1792. $this->_out('/Width '.$info['w']);
  1793. $this->_out('/Height '.$info['h']);
  1794. if($info['cs']=='Indexed')
  1795. $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]');
  1796. else
  1797. {
  1798. $this->_out('/ColorSpace /'.$info['cs']);
  1799. if($info['cs']=='DeviceCMYK')
  1800. $this->_out('/Decode [1 0 1 0 1 0 1 0]');
  1801. }
  1802. $this->_out('/BitsPerComponent '.$info['bpc']);
  1803. $this->_out('/Filter /'.$info['f']);
  1804. if(isset($info['parms']))
  1805. $this->_out($info['parms']);
  1806. if(isset($info['trns']) and is_array($info['trns']))
  1807. {
  1808. $trns='';
  1809. for($i=0;$i<count($info['trns']);$i++)
  1810. $trns.=$info['trns'][$i].' '.$info['trns'][$i].' ';
  1811. $this->_out('/Mask ['.$trns.']');
  1812. }
  1813. $this->_out('/Length '.strlen($info['data']).'>>');
  1814. $this->_putstream($info['data']);
  1815. unset($this->images[$file]['data']);
  1816. $this->_out('endobj');
  1817. //Palette
  1818. if($info['cs']=='Indexed')
  1819. {
  1820. $this->_newobj();
  1821. $pal=($this->compress) ? gzcompress($info['pal']) : $info['pal'];
  1822. $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
  1823. $this->_putstream($pal);
  1824. $this->_out('endobj');
  1825. }
  1826. }
  1827. }
  1828. function _putresources()
  1829. {
  1830. $this->_putfonts();
  1831. $this->_putimages();
  1832. //Resource dictionary
  1833. $this->offsets[2]=strlen($this->buffer);
  1834. $this->_out('2 0 obj');
  1835. $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
  1836. $this->_out('/Font <<');
  1837. foreach($this->fonts as $font)
  1838. $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
  1839. $this->_out('>>');
  1840. if(count($this->images))
  1841. {
  1842. $this->_out('/XObject <<');
  1843. foreach($this->images as $image)
  1844. $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
  1845. $this->_out('>>');
  1846. }
  1847. $this->_out('>>');
  1848. $this->_out('endobj');
  1849. $this->_putbookmarks(); //EDITEI
  1850. }
  1851. function _putinfo()
  1852. {
  1853. $this->_out('/Producer '.$this->_textstring('FPDF '.FPDF_VERSION));
  1854. if(!empty($this->title))
  1855. $this->_out('/Title '.$this->_textstring($this->title));
  1856. if(!empty($this->subject))
  1857. $this->_out('/Subject '.$this->_textstring($this->subject));
  1858. if(!empty($this->author))
  1859. $this->_out('/Author '.$this->_textstring($this->author));
  1860. if(!empty($this->keywords))
  1861. $this->_out('/Keywords '.$this->_textstring($this->keywords));
  1862. if(!empty($this->creator))
  1863. $this->_out('/Creator '.$this->_textstring($this->creator));
  1864. $this->_out('/CreationDate '.$this->_textstring('D:'.date('YmdHis')));
  1865. }
  1866. function _putcatalog()
  1867. {
  1868. $this->_out('/Type /Catalog');
  1869. $this->_out('/Pages 1 0 R');
  1870. if($this->ZoomMode=='fullpage') $this->_out('/OpenAction [3 0 R /Fit]');
  1871. elseif($this->ZoomMode=='fullwidth') $this->_out('/OpenAction [3 0 R /FitH null]');
  1872. elseif($this->ZoomMode=='real') $this->_out('/OpenAction [3 0 R /XYZ null null 1]');
  1873. elseif(!is_string($this->ZoomMode)) $this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode/100).']');
  1874. if($this->LayoutMode=='single') $this->_out('/PageLayout /SinglePage');
  1875. elseif($this->LayoutMode=='continuous') $this->_out('/PageLayout /OneColumn');
  1876. elseif($this->LayoutMode=='two') $this->_out('/PageLayout /TwoColumnLeft');
  1877. //EDITEI - added lines below
  1878. if(count($this->outlines)>0)
  1879. {
  1880. $this->_out('/Outlines '.$this->OutlineRoot.' 0 R');
  1881. $this->_out('/PageMode /UseOutlines');
  1882. }
  1883. if(is_int(strpos($this->DisplayPreferences,'FullScreen'))) $this->_out('/PageMode /FullScreen');
  1884. if($this->DisplayPreferences)
  1885. {
  1886. $this->_out('/ViewerPreferences<<');
  1887. if(is_int(strpos($this->DisplayPreferences,'HideMenubar'))) $this->_out('/HideMenubar true');
  1888. if(is_int(strpos($this->DisplayPreferences,'HideToolbar'))) $this->_out('/HideToolbar true');
  1889. if(is_int(strpos($this->DisplayPreferences,'HideWindowUI'))) $this->_out('/HideWindowUI true');
  1890. if(is_int(strpos($this->DisplayPreferences,'DisplayDocTitle'))) $this->_out('/DisplayDocTitle true');
  1891. if(is_int(strpos($this->DisplayPreferences,'CenterWindow'))) $this->_out('/CenterWindow true');
  1892. if(is_int(strpos($this->DisplayPreferences,'FitWindow'))) $this->_out('/FitWindow true');
  1893. $this->_out('>>');
  1894. }
  1895. }
  1896. function _puttrailer()
  1897. {
  1898. $this->_out('/Size '.($this->n+1));
  1899. $this->_out('/Root '.$this->n.' 0 R');
  1900. $this->_out('/Info '.($this->n-1).' 0 R');
  1901. }
  1902. function _enddoc()
  1903. {
  1904. $this->_putpages();
  1905. $this->_putresources();
  1906. //Info
  1907. $this->_newobj();
  1908. $this->_out('<<');
  1909. $this->_putinfo();
  1910. $this->_out('>>');
  1911. $this->_out('endobj');
  1912. //Catalog
  1913. $this->_newobj();
  1914. $this->_out('<<');
  1915. $this->_putcatalog();
  1916. $this->_out('>>');
  1917. $this->_out('endobj');
  1918. //Cross-ref
  1919. $o=strlen($this->buffer);
  1920. $this->_out('xref');
  1921. $this->_out('0 '.($this->n+1));
  1922. $this->_out('0000000000 65535 f ');
  1923. for($i=1; $i <= $this->n ; $i++)
  1924. $this->_out(sprintf('%010d 00000 n ',$this->offsets[$i]));
  1925. //Trailer
  1926. $this->_out('trailer');
  1927. $this->_out('<<');
  1928. $this->_puttrailer();
  1929. $this->_out('>>');
  1930. $this->_out('startxref');
  1931. $this->_out($o);
  1932. $this->_out('%%EOF');
  1933. $this->state=3;
  1934. }
  1935. function _beginpage($orientation)
  1936. {
  1937. $this->page++;
  1938. $this->pages[$this->page]='';
  1939. $this->state=2;
  1940. $this->x=$this->lMargin;
  1941. $this->y=$this->tMargin;
  1942. $this->FontFamily='';
  1943. //Page orientation
  1944. if(!$orientation)
  1945. $orientation=$this->DefOrientation;
  1946. else
  1947. {
  1948. $orientation=strtoupper($orientation{0});
  1949. if($orientation!=$this->DefOrientation)
  1950. $this->OrientationChanges[$this->page]=true;
  1951. }
  1952. if($orientation!=$this->CurOrientation)
  1953. {
  1954. //Change orientation
  1955. if($orientation=='P')
  1956. {
  1957. $this->wPt=$this->fwPt;
  1958. $this->hPt=$this->fhPt;
  1959. $this->w=$this->fw;
  1960. $this->h=$this->fh;
  1961. }
  1962. else
  1963. {
  1964. $this->wPt=$this->fhPt;
  1965. $this->hPt=$this->fwPt;
  1966. $this->w=$this->fh;
  1967. $this->h=$this->fw;
  1968. }
  1969. $this->PageBreakTrigger=$this->h-$this->bMargin;
  1970. $this->CurOrientation=$orientation;
  1971. }
  1972. }
  1973. function _endpage()
  1974. {
  1975. //End of page contents
  1976. $this->state=1;
  1977. }
  1978. function _newobj()
  1979. {
  1980. //Begin a new object
  1981. $this->n++;
  1982. $this->offsets[$this->n]=strlen($this->buffer);
  1983. $this->_out($this->n.' 0 obj');
  1984. }
  1985. function _dounderline($x,$y,$txt)
  1986. {
  1987. //Underline text
  1988. $up=$this->CurrentFont['up'];
  1989. $ut=$this->CurrentFont['ut'];
  1990. $w=$this->GetStringWidth($txt)+$this->ws*substr_count($txt,' ');
  1991. 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);
  1992. }
  1993. function _parsejpg($file)
  1994. {
  1995. //Extract info from a JPEG file
  1996. $a=GetImageSize($file);
  1997. if(!$a)
  1998. $this->Error('Missing or incorrect image file: '.$file);
  1999. if($a[2]!=2)
  2000. $this->Error('Not a JPEG file: '.$file);
  2001. if(!isset($a['channels']) or $a['channels']==3)
  2002. $colspace='DeviceRGB';
  2003. elseif($a['channels']==4)
  2004. $colspace='DeviceCMYK';
  2005. else
  2006. $colspace='DeviceGray';
  2007. $bpc=isset($a['bits']) ? $a['bits'] : 8;
  2008. //Read whole file
  2009. $f=fopen($file,'rb');
  2010. $data='';
  2011. while(!feof($f))
  2012. $data.=fread($f,4096);
  2013. fclose($f);
  2014. return array('w'=>$a[0],'h'=>$a[1],'cs'=>$colspace,'bpc'=>$bpc,'f'=>'DCTDecode','data'=>$data);
  2015. }
  2016. function _parsepng($file)
  2017. {
  2018. //Extract info from a PNG file
  2019. $f=fopen($file,'rb');
  2020. //Extract info from a PNG file
  2021. if(!$f) $this->Error('Can\'t open image file: '.$file);
  2022. //Check signature
  2023. if(fread($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10))
  2024. $this->Error('Not a PNG file: '.$file);
  2025. //Read header chunk
  2026. fread($f,4);
  2027. if(fread($f,4)!='IHDR') $this->Error('Incorrect PNG file: '.$file);
  2028. $w=$this->_freadint($f);
  2029. $h=$this->_freadint($f);
  2030. $bpc=ord(fread($f,1));
  2031. if($bpc>8) $this->Error('16-bit depth not supported: '.$file);
  2032. $ct=ord(fread($f,1));
  2033. if($ct==0) $colspace='DeviceGray';
  2034. elseif($ct==2) $colspace='DeviceRGB';
  2035. elseif($ct==3) $colspace='Indexed';
  2036. else $this->Error('Alpha channel not supported: '.$file);
  2037. if(ord(fread($f,1))!=0) $this->Error('Unknown compression method: '.$file);
  2038. if(ord(fread($f,1))!=0) $this->Error('Unknown filter method: '.$file);
  2039. if(ord(fread($f,1))!=0) $this->Error('Interlacing not supported: '.$file);
  2040. fread($f,4);
  2041. $parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
  2042. //Scan chunks looking for palette, transparency and image data
  2043. $pal='';
  2044. $trns='';
  2045. $data='';
  2046. do
  2047. {
  2048. $n=$this->_freadint($f);
  2049. $type=fread($f,4);
  2050. if($type=='PLTE')
  2051. {
  2052. //Read palette
  2053. $pal=fread($f,$n);
  2054. fread($f,4);
  2055. }
  2056. elseif($type=='tRNS')
  2057. {
  2058. //Read transparency info
  2059. $t=fread($f,$n);
  2060. if($ct==0) $trns=array(ord(substr($t,1,1)));
  2061. elseif($ct==2) $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
  2062. else
  2063. {
  2064. $pos=strpos($t,chr(0));
  2065. if(is_int($pos)) $trns=array($pos);
  2066. }
  2067. fread($f,4);
  2068. }
  2069. elseif($type=='IDAT')
  2070. {
  2071. //Read image data block
  2072. $data.=fread($f,$n);
  2073. fread($f,4);
  2074. }
  2075. elseif($type=='IEND') break;
  2076. else fread($f,$n+4);
  2077. }
  2078. while($n);
  2079. if($colspace=='Indexed' and empty($pal)) $this->Error('Missing palette in '.$file);
  2080. fclose($f);
  2081. return array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$data);
  2082. }
  2083. function _parsegif($file) //EDITEI - GIF support is now included
  2084. {
  2085. //Function by J�r�me Fenal
  2086. require_once(RELATIVE_PATH.'gif.php'); //GIF class in pure PHP from Yamasoft (http://www.yamasoft.com/php-gif.zip)
  2087. $h=0;
  2088. $w=0;
  2089. $gif=new CGIF();
  2090. if (!$gif->loadFile($file, 0))
  2091. $this->Error("GIF parser: unable to open file $file");
  2092. if($gif->m_img->m_gih->m_bLocalClr) {
  2093. $nColors = $gif->m_img->m_gih->m_nTableSize;
  2094. $pal = $gif->m_img->m_gih->m_colorTable->toString();
  2095. if($bgColor != -1) {
  2096. $bgColor = $this->m_img->m_gih->m_colorTable->colorIndex($bgColor);
  2097. }
  2098. $colspace='Indexed';
  2099. } elseif($gif->m_gfh->m_bGlobalClr) {
  2100. $nColors = $gif->m_gfh->m_nTableSize;
  2101. $pal = $gif->m_gfh->m_colorTable->toString();
  2102. if((isset($bgColor)) and $bgColor != -1) {
  2103. $bgColor = $gif->m_gfh->m_colorTable->colorIndex($bgColor);
  2104. }
  2105. $colspace='Indexed';
  2106. } else {
  2107. $nColors = 0;
  2108. $bgColor = -1;
  2109. $colspace='DeviceGray';
  2110. $pal='';
  2111. }
  2112. $trns='';
  2113. if($gif->m_img->m_bTrans && ($nColors > 0)) {
  2114. $trns=array($gif->m_img->m_nTrans);
  2115. }
  2116. $data=$gif->m_img->m_data;
  2117. $w=$gif->m_gfh->m_nWidth;
  2118. $h=$gif->m_gfh->m_nHeight;
  2119. if($colspace=='Indexed' and empty($pal))
  2120. $this->Error('Missing palette in '.$file);
  2121. if ($this->compress) {
  2122. $data=gzcompress($data);
  2123. return array( 'w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>8, 'f'=>'FlateDecode', 'pal'=>$pal, 'trns'=>$trns, 'data'=>$data);
  2124. } else {
  2125. return array( 'w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>8, 'pal'=>$pal, 'trns'=>$trns, 'data'=>$data);
  2126. }
  2127. }
  2128. function _freadint($f)
  2129. {
  2130. //Read a 4-byte integer from file
  2131. $i=ord(fread($f,1))<<24;
  2132. $i+=ord(fread($f,1))<<16;
  2133. $i+=ord(fread($f,1))<<8;
  2134. $i+=ord(fread($f,1));
  2135. return $i;
  2136. }
  2137. function _textstring($s)
  2138. {
  2139. //Format a text string
  2140. return '('.$this->_escape($s).')';
  2141. }
  2142. function _escape($s)
  2143. {
  2144. //Add \ before \, ( and )
  2145. return str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$s)));
  2146. }
  2147. function _putstream($s)
  2148. {
  2149. $this->_out('stream');
  2150. $this->_out($s);
  2151. $this->_out('endstream');
  2152. }
  2153. function _out($s)
  2154. {
  2155. //Add a line to the document
  2156. if($this->state==2) $this->pages[$this->page] .= $s."\n";
  2157. else $this->buffer .= $s."\n";
  2158. }
  2159. }//End of class
  2160. //Handle special IE contype request
  2161. if(isset($HTTP_SERVER_VARS['HTTP_USER_AGENT']) and $HTTP_SERVER_VARS['HTTP_USER_AGENT']=='contype')
  2162. {
  2163. Header('Content-Type: application/pdf');
  2164. exit;
  2165. }
  2166. } //end of 'if(!class_exists('FPDF'))''
  2167. ?>
  2168. <?php
  2169. /*
  2170. This script is supposed to be used together with the HTML2FPDF.php class
  2171. Copyright (C) 2004-2005 Renato Coelho
  2172. */
  2173. function ConvertColor($color="#000000"){
  2174. //returns an associative array (keys: R,G,B) from html code (e.g. #3FE5AA)
  2175. //W3C approved color array (disabled)
  2176. //static $common_colors = array('black'=>'#000000','silver'=>'#C0C0C0','gray'=>'#808080', 'white'=>'#FFFFFF','maroon'=>'#800000','red'=>'#FF0000','purple'=>'#800080','fuchsia'=>'#FF00FF','green'=>'#008000','lime'=>'#00FF00','olive'=>'#808000','yellow'=>'#FFFF00','navy'=>'#000080', 'blue'=>'#0000FF','teal'=>'#008080','aqua'=>'#00FFFF');
  2177. //All color names array
  2178. static $common_colors = array('antiquewhite'=>'#FAEBD7','aquamarine'=>'#7FFFD4','beige'=>'#F5F5DC','black'=>'#000000','blue'=>'#0000FF','brown'=>'#A52A2A','cadetblue'=>'#5F9EA0','chocolate'=>'#D2691E','cornflowerblue'=>'#6495ED','crimson'=>'#DC143C','darkblue'=>'#00008B','darkgoldenrod'=>'#B8860B','darkgreen'=>'#006400','darkmagenta'=>'#8B008B','darkorange'=>'#FF8C00','darkred'=>'#8B0000','darkseagreen'=>'#8FBC8F','darkslategray'=>'#2F4F4F','darkviolet'=>'#9400D3','deepskyblue'=>'#00BFFF','dodgerblue'=>'#1E90FF','firebrick'=>'#B22222','forestgreen'=>'#228B22','gainsboro'=>'#DCDCDC','gold'=>'#FFD700','gray'=>'#808080','green'=>'#008000','greenyellow'=>'#ADFF2F','hotpink'=>'#FF69B4','indigo'=>'#4B0082','khaki'=>'#F0E68C','lavenderblush'=>'#FFF0F5','lemonchiffon'=>'#FFFACD','lightcoral'=>'#F08080','lightgoldenrodyellow'=>'#FAFAD2','lightgreen'=>'#90EE90','lightsalmon'=>'#FFA07A','lightskyblue'=>'#87CEFA','lightslategray'=>'#778899','lightyellow'=>'#FFFFE0','limegreen'=>'#32CD32','magenta'=>'#FF00FF','mediumaquamarine'=>'#66CDAA','mediumorchid'=>'#BA55D3','mediumseagreen'=>'#3CB371','mediumspringgreen'=>'#00FA9A','mediumvioletred'=>'#C71585','mintcream'=>'#F5FFFA','moccasin'=>'#FFE4B5','navy'=>'#000080','olive'=>'#808000','orange'=>'#FFA500','orchid'=>'#DA70D6','palegreen'=>'#98FB98','palevioletred'=>'#D87093','peachpuff'=>'#FFDAB9','pink'=>'#FFC0CB','powderblue'=>'#B0E0E6','red'=>'#FF0000','royalblue'=>'#4169E1','salmon'=>'#FA8072','seagreen'=>'#2E8B57','sienna'=>'#A0522D','skyblue'=>'#87CEEB','slategray'=>'#708090','springgreen'=>'#00FF7F','tan'=>'#D2B48C','thistle'=>'#D8BFD8','turquoise'=>'#40E0D0','violetred'=>'#D02090','white'=>'#FFFFFF','yellow'=>'#FFFF00');
  2179. //http://www.w3schools.com/css/css_colornames.asp
  2180. if ( ($color{0} != '#') and ( strstr($color,'(') === false ) ) $color = $common_colors[strtolower($color)];
  2181. if ($color{0} == '#') //case of #nnnnnn or #nnn
  2182. {
  2183. $cor = strtoupper($color);
  2184. if (strlen($cor) == 4) // Turn #RGB into #RRGGBB
  2185. {
  2186. $cor = "#" . $cor{1} . $cor{1} . $cor{2} . $cor{2} . $cor{3} . $cor{3};
  2187. }
  2188. $R = substr($cor, 1, 2);
  2189. $vermelho = hexdec($R);
  2190. $V = substr($cor, 3, 2);
  2191. $verde = hexdec($V);
  2192. $B = substr($cor, 5, 2);
  2193. $azul = hexdec($B);
  2194. $color = array();
  2195. $color['R']=$vermelho;
  2196. $color['G']=$verde;
  2197. $color['B']=$azul;
  2198. }
  2199. else //case of RGB(r,g,b)
  2200. {
  2201. $color = str_replace("rgb(",'',$color); //remove �rgb(�
  2202. $color = str_replace("RGB(",'',$color); //remove �RGB(� -- PHP < 5 does not have str_ireplace
  2203. $color = str_replace(")",'',$color); //remove �)�
  2204. $cores = explode(",", $color);
  2205. $color = array();
  2206. $color['R']=$cores[0];
  2207. $color['G']=$cores[1];
  2208. $color['B']=$cores[2];
  2209. }
  2210. if (empty($color)) return array('R'=>255,'G'=>255,'B'=>255);
  2211. else return $color; // array['R']['G']['B']
  2212. }
  2213. function ConvertSize($size=5,$maxsize=0){
  2214. // Depends of maxsize value to make % work properly. Usually maxsize == pagewidth
  2215. //Identify size (remember: we are using 'mm' units here)
  2216. if ( stristr($size,'px') ) $size *= 0.2645; //pixels
  2217. elseif ( stristr($size,'cm') ) $size *= 10; //centimeters
  2218. elseif ( stristr($size,'mm') ) $size += 0; //millimeters
  2219. elseif ( stristr($size,'in') ) $size *= 25.4; //inches
  2220. elseif ( stristr($size,'pc') ) $size *= 38.1/9; //PostScript picas
  2221. elseif ( stristr($size,'pt') ) $size *= 25.4/72; //72dpi
  2222. elseif ( stristr($size,'%') )
  2223. {
  2224. $size += 0; //make "90%" become simply "90"
  2225. $size *= $maxsize/100;
  2226. }
  2227. else $size *= 0.2645; //nothing == px
  2228. return $size;
  2229. }
  2230. function value_entity_decode($html)
  2231. {
  2232. //replace each value entity by its respective char
  2233. preg_match_all('|&#(.*?);|',$html,$temparray);
  2234. foreach($temparray[1] as $val) $html = str_replace("&#".$val.";",chr($val),$html);
  2235. return $html;
  2236. }
  2237. function lesser_entity_decode($html)
  2238. {
  2239. //supports the most used entity codes
  2240. $html = str_replace("&nbsp;"," ",$html);
  2241. $html = str_replace("&amp;","&",$html);
  2242. $html = str_replace("&lt;","<",$html);
  2243. $html = str_replace("&gt;",">",$html);
  2244. $html = str_replace("&laquo;","�",$html);
  2245. $html = str_replace("&raquo;","�",$html);
  2246. $html = str_replace("&para;","�",$html);
  2247. $html = str_replace("&euro;","�",$html);
  2248. $html = str_replace("&trade;","�",$html);
  2249. $html = str_replace("&copy;","�",$html);
  2250. $html = str_replace("&reg;","�",$html);
  2251. $html = str_replace("&plusmn;","�",$html);
  2252. $html = str_replace("&tilde;","~",$html);
  2253. $html = str_replace("&circ;","^",$html);
  2254. $html = str_replace("&quot;",'"',$html);
  2255. $html = str_replace("&permil;","�",$html);
  2256. $html = str_replace("&Dagger;","�",$html);
  2257. $html = str_replace("&dagger;","�",$html);
  2258. return $html;
  2259. }
  2260. function AdjustHTML($html,$usepre=true)
  2261. {
  2262. //Try to make the html text more manageable (turning it into XHTML)
  2263. //Remove javascript code from HTML (should not appear in the PDF file)
  2264. $regexp = '|<script.*?</script>|si';
  2265. $html = preg_replace($regexp,'',$html);
  2266. $html = str_replace("\r\n","\n",$html); //replace carriagereturn-linefeed-combo by a simple linefeed
  2267. $html = str_replace("\f",'',$html); //replace formfeed by nothing
  2268. $html = str_replace("\r",'',$html); //replace carriage return by nothing
  2269. if ($usepre) //used to keep \n on content inside <pre> and inside <textarea>
  2270. {
  2271. // Preserve '\n's in content between the tags <pre> and </pre>
  2272. $regexp = '#<pre(.*?)>(.+?)</pre>#si';
  2273. $thereispre = preg_match_all($regexp,$html,$temp);
  2274. // Preserve '\n's in content between the tags <textarea> and </textarea>
  2275. $regexp2 = '#<textarea(.*?)>(.+?)</textarea>#si';
  2276. $thereistextarea = preg_match_all($regexp2,$html,$temp2);
  2277. $html = str_replace("\n",' ',$html); //replace linefeed by spaces
  2278. $html = str_replace("\t",' ',$html); //replace tabs by spaces
  2279. $regexp3 = '#\s{2,}#s'; // turn 2+ consecutive spaces into one
  2280. $html = preg_replace($regexp3,' ',$html);
  2281. $iterator = 0;
  2282. while($thereispre) //Recover <pre attributes>content</pre>
  2283. {
  2284. $temp[2][$iterator] = str_replace("\n","<br>",$temp[2][$iterator]);
  2285. $html = preg_replace($regexp,'<erp'.$temp[1][$iterator].'>'.$temp[2][$iterator].'</erp>',$html,1);
  2286. $thereispre--;
  2287. $iterator++;
  2288. }
  2289. $iterator = 0;
  2290. while($thereistextarea) //Recover <textarea attributes>content</textarea>
  2291. {
  2292. $temp2[2][$iterator] = str_replace(" ","&nbsp;",$temp2[2][$iterator]);
  2293. $html = preg_replace($regexp2,'<aeratxet'.$temp2[1][$iterator].'>'.trim($temp2[2][$iterator]).'</aeratxet>',$html,1);
  2294. $thereistextarea--;
  2295. $iterator++;
  2296. }
  2297. //Restore original tag names
  2298. $html = str_replace("<erp","<pre",$html);
  2299. $html = str_replace("</erp>","</pre>",$html);
  2300. $html = str_replace("<aeratxet","<textarea",$html);
  2301. $html = str_replace("</aeratxet>","</textarea>",$html);
  2302. // (the code above might slowdown overall performance?)
  2303. } //end of if($usepre)
  2304. else
  2305. {
  2306. $html = str_replace("\n",' ',$html); //replace linefeed by spaces
  2307. $html = str_replace("\t",' ',$html); //replace tabs by spaces
  2308. $regexp = '/\\s{2,}/s'; // turn 2+ consecutive spaces into one
  2309. $html = preg_replace($regexp,' ',$html);
  2310. }
  2311. // remove redundant <br>'s before </div>, avoiding huge leaps between text blocks
  2312. // such things appear on computer-generated HTML code
  2313. $regexp = '/(<br[ \/]?[\/]?>)+?<\/div>/si'; //<?//fix PSPAD highlight bug
  2314. $html = preg_replace($regexp,'</div>',$html);
  2315. //pr($html);
  2316. return $html;
  2317. }
  2318. function dec2alpha($valor,$toupper="true"){
  2319. // returns a string from A-Z to AA-ZZ to AAA-ZZZ
  2320. // OBS: A = 65 ASCII TABLE VALUE
  2321. if (($valor < 1) || ($valor > 18278)) return "?"; //supports 'only' up to 18278
  2322. $c1 = $c2 = $c3 = '';
  2323. if ($valor > 702) // 3 letters (up to 18278)
  2324. {
  2325. $c1 = 65 + floor(($valor-703)/676);
  2326. $c2 = 65 + floor((($valor-703)%676)/26);
  2327. $c3 = 65 + floor((($valor-703)%676)%26);
  2328. }
  2329. elseif ($valor > 26) // 2 letters (up to 702)
  2330. {
  2331. $c1 = (64 + (int)(($valor-1) / 26));
  2332. $c2 = (64 + (int)($valor % 26));
  2333. if ($c2 == 64) $c2 += 26;
  2334. }
  2335. else // 1 letter (up to 26)
  2336. {
  2337. $c1 = (64 + $valor);
  2338. }
  2339. $alpha = chr($c1);
  2340. if ($c2 != '') $alpha .= chr($c2);
  2341. if ($c3 != '') $alpha .= chr($c3);
  2342. if (!$toupper) $alpha = strtolower($alpha);
  2343. return $alpha;
  2344. }
  2345. function dec2roman($valor,$toupper=true){
  2346. //returns a string as a roman numeral
  2347. if (($valor >= 5000) || ($valor < 1)) return "?"; //supports 'only' up to 4999
  2348. $aux = (int)($valor/1000);
  2349. if ($aux!==0)
  2350. {
  2351. $valor %= 1000;
  2352. while($aux!==0)
  2353. {
  2354. $r1 .= "M";
  2355. $aux--;
  2356. }
  2357. }
  2358. $aux = (int)($valor/100);
  2359. if ($aux!==0)
  2360. {
  2361. $valor %= 100;
  2362. switch($aux){
  2363. case 3: $r2="C";
  2364. case 2: $r2.="C";
  2365. case 1: $r2.="C"; break;
  2366. case 9: $r2="CM"; break;
  2367. case 8: $r2="C";
  2368. case 7: $r2.="C";
  2369. case 6: $r2.="C";
  2370. case 5: $r2="D".$r2; break;
  2371. case 4: $r2="CD"; break;
  2372. default: break;
  2373. }
  2374. }
  2375. $aux = (int)($valor/10);
  2376. if ($aux!==0)
  2377. {
  2378. $valor %= 10;
  2379. switch($aux){
  2380. case 3: $r3="X";
  2381. case 2: $r3.="X";
  2382. case 1: $r3.="X"; break;
  2383. case 9: $r3="XC"; break;
  2384. case 8: $r3="X";
  2385. case 7: $r3.="X";
  2386. case 6: $r3.="X";
  2387. case 5: $r3="L".$r3; break;
  2388. case 4: $r3="XL"; break;
  2389. default: break;
  2390. }
  2391. }
  2392. switch($valor){
  2393. case 3: $r4="I";
  2394. case 2: $r4.="I";
  2395. case 1: $r4.="I"; break;
  2396. case 9: $r4="IX"; break;
  2397. case 8: $r4="I";
  2398. case 7: $r4.="I";
  2399. case 6: $r4.="I";
  2400. case 5: $r4="V".$r4; break;
  2401. case 4: $r4="IV"; break;
  2402. default: break;
  2403. }
  2404. $roman = $r1.$r2.$r3.$r4;
  2405. if (!$toupper) $roman = strtolower($roman);
  2406. return $roman;
  2407. }
  2408. ?>
  2409. <?php
  2410. /*
  2411. *** General-use version
  2412. DEBUG HINT:
  2413. - Inside function printbuffer make $fill=1
  2414. - Inside function Cell make:
  2415. if($fill==1 or $border==1)
  2416. {
  2417. // if ($fill==1) $op=($border==1) ? 'B' : 'f';
  2418. // else $op='S';
  2419. $op='S';
  2420. - Following these 2 steps you will be able to see the cell's boundaries
  2421. WARNING: When adding a new tag support, also add its name inside the function DisableTags()'s very long string
  2422. ODDITIES (?):
  2423. . It seems like saved['border'] and saved['bgcolor'] are useless inside the FlowingBlock...
  2424. These 2 attributes do the same thing?!?:
  2425. . $this->currentfont - mine
  2426. . $this->CurrentFont - fpdf's
  2427. TODO (in the future...):
  2428. - Make font-family, font-size, lineheight customizable
  2429. - Increase number of HTML/CSS tags/properties, Image/Font Types, recognized/supported
  2430. - allow BMP support? (tried with http://phpthumb.sourceforge.net/ but failed)
  2431. - Improve CSS support
  2432. - support image side-by-side or one-below-another or both?
  2433. - Improve code clarity even more (modularize and get better var names like on textbuffer array's indexes for example)
  2434. //////////////////////////////////////////////////////////////////////////////
  2435. //////////////DO NOT MODIFY THE CONTENTS OF THIS BOX//////////////////////////
  2436. //////////////////////////////////////////////////////////////////////////////
  2437. // //
  2438. // HTML2FPDF is a php script to read a HTML text and generate a PDF file. //
  2439. // Copyright (C) 2004-2005 Renato Coelho //
  2440. // This script may be distributed as long as the following files are kept //
  2441. // together: //
  2442. // //
  2443. // fpdf.php, html2fpdf.php, gif.php,htmltoolkit.php,license.txt,credits.txt //
  2444. // //
  2445. //////////////////////////////////////////////////////////////////////////////
  2446. Misc. Observations:
  2447. - CSS + align = bug! (?)
  2448. OBS1: para textos de mais de 1 p�gina, talvez tenha que juntar varios $texto_artigo
  2449. antes de mandar gerar o PDF, para que o PDF gerado seja completo.
  2450. OBS2: there are 2 types of spaces 32 and 160 (ascii values)
  2451. OBS3: //! is a special comment to be used with source2doc.php, a script I created
  2452. in order to generate the doc on the site html2fpdf.sf.net
  2453. OBS4: var $LineWidth; // line width in user unit - use this to make css thin/medium/thick work
  2454. OBS5: Images and Textareas: when they are inserted you can only type below them (==display:block)
  2455. OBS6: Optimized to 'A4' paper (default font: Arial , normal , size 11 )
  2456. OBS7: Regexp + Perl ([preg]accepts non-greedy quantifiers while PHP[ereg] does not)
  2457. Perl: '/regexp/x' where x == option ( x = i:ignore case , x = s: DOT gets \n as well)
  2458. ========================END OF INITIAL COMMENTS=================================
  2459. */
  2460. if (!defined('PARAGRAPH_STRING')) define('PARAGRAPH_STRING', '~~~');
  2461. define('HTML2FPDF_VERSION','3.0(beta)');
  2462. //if (!defined('RELATIVE_PATH')) define('RELATIVE_PATH','');
  2463. if (!defined('FPDF_FONTPATH')) define('FPDF_FONTPATH','font/');
  2464. //require_once(RELATIVE_PATH.'htmltoolkit.php');
  2465. class HTML2FPDF extends FPDF
  2466. {
  2467. //internal attributes
  2468. var $HREF; //! string
  2469. var $pgwidth; //! float
  2470. var $fontlist; //! array
  2471. var $issetfont; //! bool
  2472. var $issetcolor; //! bool
  2473. var $titulo; //! string
  2474. var $oldx; //! float
  2475. var $oldy; //! float
  2476. var $B; //! int
  2477. var $U; //! int
  2478. var $I; //! int
  2479. var $tablestart; //! bool
  2480. var $tdbegin; //! bool
  2481. var $table; //! array
  2482. var $cell; //! array
  2483. var $col; //! int
  2484. var $row; //! int
  2485. var $divbegin; //! bool
  2486. var $divalign; //! char
  2487. var $divwidth; //! float
  2488. var $divheight; //! float
  2489. var $divbgcolor; //! bool
  2490. var $divcolor; //! bool
  2491. var $divborder; //! int
  2492. var $divrevert; //! bool
  2493. var $listlvl; //! int
  2494. var $listnum; //! int
  2495. var $listtype; //! string
  2496. //array(lvl,# of occurrences)
  2497. var $listoccur; //! array
  2498. //array(lvl,occurrence,type,maxnum)
  2499. var $listlist; //! array
  2500. //array(lvl,num,content,type)
  2501. var $listitem; //! array
  2502. var $buffer_on; //! bool
  2503. var $pbegin; //! bool
  2504. var $pjustfinished; //! bool
  2505. var $blockjustfinished; //! bool
  2506. var $SUP; //! bool
  2507. var $SUB; //! bool
  2508. var $toupper; //! bool
  2509. var $tolower; //! bool
  2510. var $dash_on; //! bool
  2511. var $dotted_on; //! bool
  2512. var $strike; //! bool
  2513. var $CSS; //! array
  2514. var $cssbegin; //! bool
  2515. var $backupcss; //! array
  2516. var $textbuffer; //! array
  2517. var $currentstyle; //! string
  2518. var $currentfont; //! string
  2519. var $colorarray; //! array
  2520. var $bgcolorarray; //! array
  2521. var $internallink; //! array
  2522. var $enabledtags; //! string
  2523. var $lineheight; //! int
  2524. var $basepath; //! string
  2525. // array('COLOR','WIDTH','OLDWIDTH')
  2526. var $outlineparam; //! array
  2527. var $outline_on; //! bool
  2528. var $specialcontent; //! string
  2529. var $selectoption; //! array
  2530. //options attributes
  2531. var $usecss; //! bool
  2532. var $usepre; //! bool
  2533. var $usetableheader; //! bool
  2534. var $shownoimg; //! bool
  2535. function HTML2FPDF($w=null,$orientation='P',$unit='mm',$format='A4')
  2536. {
  2537. //! @desc Constructor
  2538. //! @return An object (a class instance)
  2539. //Call parent constructor
  2540. $this->FPDF($w,$orientation,$unit,$format);
  2541. //To make the function Footer() work properly
  2542. $this->AliasNbPages();
  2543. //Enable all tags as default
  2544. $this->DisableTags();
  2545. //Set default display preferences
  2546. $this->DisplayPreferences('');
  2547. //Initialization of the attributes
  2548. $this->SetFont('Arial','',11); // Changeable?(not yet...)
  2549. $this->lineheight = 5; // Related to FontSizePt == 11
  2550. $this->pgwidth = $this->fw - $this->lMargin - $this->rMargin ;
  2551. $this->SetFillColor(255);
  2552. $this->HREF='';
  2553. $this->titulo='';
  2554. $this->oldx=-1;
  2555. $this->oldy=-1;
  2556. $this->B=0;
  2557. $this->U=0;
  2558. $this->I=0;
  2559. $this->listlvl=0;
  2560. $this->listnum=0;
  2561. $this->listtype='';
  2562. $this->listoccur=array();
  2563. $this->listlist=array();
  2564. $this->listitem=array();
  2565. $this->tablestart=false;
  2566. $this->tdbegin=false;
  2567. $this->table=array('nc' => 0,'nr'=>0);
  2568. $this->cell=array();
  2569. $this->col=-1;
  2570. $this->row=-1;
  2571. $this->divbegin=false;
  2572. $this->divalign="L";
  2573. $this->divwidth=0;
  2574. $this->divheight=0;
  2575. $this->divbgcolor=false;
  2576. $this->divcolor=false;
  2577. $this->divborder=0;
  2578. $this->divrevert=false;
  2579. $this->fontlist=array("arial","times","courier","helvetica","symbol","monospace","serif","sans");
  2580. $this->issetfont=false;
  2581. $this->issetcolor=false;
  2582. $this->pbegin=false;
  2583. $this->pjustfinished=false;
  2584. $this->blockjustfinished = true; //in order to eliminate exceeding left-side spaces
  2585. $this->toupper=false;
  2586. $this->tolower=false;
  2587. $this->dash_on=false;
  2588. $this->dotted_on=false;
  2589. $this->SUP=false;
  2590. $this->SUB=false;
  2591. $this->buffer_on=false;
  2592. $this->strike=false;
  2593. $this->currentfont='';
  2594. $this->currentstyle='';
  2595. $this->colorarray=array();
  2596. $this->bgcolorarray=array();
  2597. $this->cssbegin=false;
  2598. $this->textbuffer=array();
  2599. $this->CSS=array();
  2600. $this->backupcss=array();
  2601. $this->internallink=array();
  2602. $this->basepath = "";
  2603. $this->outlineparam = array();
  2604. $this->outline_on = false;
  2605. $this->specialcontent = '';
  2606. $this->selectoption = array();
  2607. $this->shownoimg=false;
  2608. $this->usetableheader=false;
  2609. $this->usecss=true;
  2610. $this->usepre=true;
  2611. }
  2612. function setBasePath($str)
  2613. {
  2614. //! @desc Inform the script where the html file is (full path - e.g. http://www.google.com/dir1/dir2/dir3/file.html ) in order to adjust HREF and SRC links. No-Parameter: The directory where this script is.
  2615. //! @return void
  2616. $this->basepath = dirname($str) . "/";
  2617. $this->basepath = str_replace("\\","/",$this->basepath); //If on Windows
  2618. }
  2619. function ShowNOIMG_GIF($opt=true)
  2620. {
  2621. //! @desc Enable/Disable Displaying the no_img.gif when an image is not found. No-Parameter: Enable
  2622. //! @return void
  2623. $this->shownoimg=$opt;
  2624. }
  2625. function UseCSS($opt=true)
  2626. {
  2627. //! @desc Enable/Disable CSS recognition. No-Parameter: Enable
  2628. //! @return void
  2629. $this->usecss=$opt;
  2630. }
  2631. function UseTableHeader($opt=true)
  2632. {
  2633. //! @desc Enable/Disable Table Header to appear every new page. No-Parameter: Enable
  2634. //! @return void
  2635. $this->usetableheader=$opt;
  2636. }
  2637. function UsePRE($opt=true)
  2638. {
  2639. //! @desc Enable/Disable pre tag recognition. No-Parameter: Enable
  2640. //! @return void
  2641. $this->usepre=$opt;
  2642. }
  2643. //Page header
  2644. function __tableHeader($content='')
  2645. {
  2646. // $this->Image(WWW_ROOT.DS.'img/site_logo/big/logouch.jpg',10,8,10);
  2647. //$this->Ln(2);
  2648. // debug($this->usetableheader);
  2649. //$this->y = $this->y + 10;
  2650. // $this->SetFont('Arial','B',15);
  2651. // //Move to the right
  2652. // $this->Cell(80);
  2653. // //Framed title
  2654. // $this->Cell(30,10,'Title',1,0,'C');
  2655. // //Line break
  2656. //$this->Ln(20);
  2657. //$h = 10;
  2658. //! @return void
  2659. //! @desc The header is printed in every page.
  2660. if($this->usetableheader and $content != '')
  2661. {
  2662. $y = $this->y;
  2663. foreach($content as $tableheader)
  2664. {
  2665. $this->y = $y;
  2666. //Set some cell values
  2667. $x = $tableheader['x'];
  2668. $w = $tableheader['w'];
  2669. $h = $tableheader['h'];
  2670. $va = $tableheader['va'];
  2671. $mih = $tableheader['mih'];
  2672. $fill = $tableheader['bgcolor'];
  2673. $border = $tableheader['border'];
  2674. $align = $tableheader['a'];
  2675. //Align
  2676. $this->divalign=$align;
  2677. $this->x = $x;
  2678. //Vertical align
  2679. if (!isset($va) || $va=='M') $this->y += ($h-$mih)/2;
  2680. elseif (isset($va) && $va=='B') $this->y += $h-$mih;
  2681. if ($fill)
  2682. {
  2683. // debug($fill);
  2684. $color = ConvertColor($fill);
  2685. $this->SetFillColor($color['R'],$color['G'],$color['B']);
  2686. $this->Rect($x, $y, $w, $h, 'F');
  2687. }
  2688. //Border
  2689. if (isset($border) and $border != 'all') $this->_tableRect($x, $y, $w, $h, $border);
  2690. elseif (isset($border) && $border == 'all') $this->Rect($x, $y, $w, $h);
  2691. //Print cell content
  2692. $this->divwidth = $w-2;
  2693. $this->divheight = 1.1*$this->lineheight;
  2694. $textbuffer = $tableheader['textbuffer'];
  2695. //debug($textbuffer);
  2696. if (!empty($textbuffer)) $this->printbuffer($textbuffer,false,true/*inside a table*/);
  2697. $textbuffer = array();
  2698. $this->y = $y + $h;
  2699. }
  2700. //Update y coordinate
  2701. }//end of 'if usetableheader ...'
  2702. // debug($this->y);
  2703. }
  2704. //Page footer
  2705. function Footer()
  2706. {
  2707. //! @return void
  2708. //! @desc The footer is printed in every page!
  2709. //Position at 1.0 cm from bottom
  2710. $this->SetY(-10);
  2711. //Copyright //especial para esta vers�o
  2712. $this->SetFont('Arial','B',9);
  2713. $this->SetTextColor(0);
  2714. //Arial italic 9
  2715. $this->SetFont('Arial','I',9);
  2716. //Page number
  2717. $this->Cell(0,10,$this->PageNo().'/{nb}',0,0,'C');
  2718. //Return Font to normal
  2719. $this->SetFont('Arial','',11);
  2720. }
  2721. ///////////////////
  2722. /// HTML parser ///
  2723. ///////////////////
  2724. function WriteHTML($html)
  2725. {
  2726. //! @desc HTML parser
  2727. //! @return void
  2728. /* $e == content */
  2729. $this->ReadMetaTags($html);
  2730. $html = AdjustHTML($html,$this->usepre); //Try to make HTML look more like XHTML
  2731. if ($this->usecss) $html = $this->ReadCSS($html);
  2732. //Add new supported tags in the DisableTags function
  2733. $html=str_replace('<?','< ',$html); //Fix '<?XML' bug from HTML code generated by MS Word
  2734. $html=strip_tags($html,$this->enabledtags); //remove all unsupported tags, but the ones inside the 'enabledtags' string
  2735. //Explode the string in order to parse the HTML code
  2736. $a=preg_split('/<(.*?)>/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
  2737. foreach($a as $i => $e)
  2738. {
  2739. if($i%2==0)
  2740. {
  2741. //TEXT
  2742. //Adjust lineheight
  2743. // $this->lineheight = (5*$this->FontSizePt)/11; //should be inside printbuffer?
  2744. //Adjust text, if needed
  2745. if (strpos($e,"&") !== false) //HTML-ENTITIES decoding
  2746. {
  2747. if (strpos($e,"#") !== false) $e = value_entity_decode($e); // Decode value entities
  2748. //Avoid crashing the script on PHP 4.0
  2749. $version = phpversion();
  2750. $version = str_replace('.','',$version);
  2751. if ($version >= 430) $e = html_entity_decode($e,ENT_QUOTES,'cp1252'); // changes &nbsp; and the like by their respective char
  2752. else $e = lesser_entity_decode($e);
  2753. }
  2754. $e = str_replace(chr(160),chr(32),$e); //unify ascii code of spaces (in order to recognize all of them correctly)
  2755. if (strlen($e) == 0) continue;
  2756. if ($this->divrevert) $e = strrev($e);
  2757. if ($this->toupper) $e = strtoupper($e);
  2758. if ($this->tolower) $e = strtolower($e);
  2759. //Start of 'if/elseif's
  2760. if($this->titulo) $this->SetTitle($e);
  2761. elseif($this->specialcontent)
  2762. {
  2763. if ($this->specialcontent == "type=select" and $this->selectoption['ACTIVE'] == true) //SELECT tag (form element)
  2764. {
  2765. $stringwidth = $this->GetStringWidth($e);
  2766. if (!isset($this->selectoption['MAXWIDTH']) or $stringwidth > $this->selectoption['MAXWIDTH']) $this->selectoption['MAXWIDTH'] = $stringwidth;
  2767. if (!isset($this->selectoption['SELECTED']) or $this->selectoption['SELECTED'] == '') $this->selectoption['SELECTED'] = $e;
  2768. }
  2769. else $this->textbuffer[] = array("���"/*identifier*/.$this->specialcontent."���".$e);
  2770. }
  2771. elseif($this->tablestart)
  2772. {
  2773. if($this->tdbegin)
  2774. {
  2775. $this->cell[$this->row][$this->col]['textbuffer'][] = array($e,$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
  2776. $this->cell[$this->row][$this->col]['text'][] = $e;
  2777. $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth($e);
  2778. }
  2779. //Ignore content between <table>,<tr> and a <td> tag (this content is usually only a bunch of spaces)
  2780. }
  2781. elseif($this->pbegin or $this->HREF or $this->divbegin or $this->SUP or $this->SUB or $this->strike or $this->buffer_on) $this->textbuffer[] = array($e,$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray); //Accumulate text on buffer
  2782. else
  2783. {
  2784. if ($this->blockjustfinished) $e = ltrim($e);
  2785. if ($e != '')
  2786. {
  2787. $this->Write($this->lineheight,$e); //Write text directly in the PDF
  2788. if ($this->pjustfinished) $this->pjustfinished = false;
  2789. }
  2790. }
  2791. }
  2792. else
  2793. {
  2794. //Tag
  2795. if($e{0}=='/') $this->CloseTag(strtoupper(substr($e,1)));
  2796. else
  2797. {
  2798. $regexp = '|=\'(.*?)\'|s'; // eliminate single quotes, if any
  2799. $e = preg_replace($regexp,"=\"\$1\"",$e);
  2800. $regexp = '| (\\w+?)=([^\\s>"]+)|si'; // changes anykey=anyvalue to anykey="anyvalue" (only do this when this happens inside tags)
  2801. $e = preg_replace($regexp," \$1=\"\$2\"",$e);
  2802. //Fix path values, if needed
  2803. if ((stristr($e,"href=") !== false) or (stristr($e,"src=") !== false) )
  2804. {
  2805. $regexp = '/ (href|src)="(.*?)"/i';
  2806. preg_match($regexp,$e,$auxiliararray);
  2807. $path = $auxiliararray[2];
  2808. $path = str_replace("\\","/",$path); //If on Windows
  2809. //Get link info and obtain its absolute path
  2810. $regexp = '|^./|';
  2811. $path = preg_replace($regexp,'',$path);
  2812. //debug($path);
  2813. if($path{0} != '#') //It is not an Internal Link
  2814. {
  2815. if (strpos($path,"../") !== false ) //It is a Relative Link
  2816. {
  2817. $backtrackamount = substr_count($path,"../");
  2818. $maxbacktrack = substr_count($this->basepath,"/") - 1;
  2819. $filepath = str_replace("../",'',$path);
  2820. $path = $this->basepath;
  2821. //If it is an invalid relative link, then make it go to directory root
  2822. if ($backtrackamount > $maxbacktrack) $backtrackamount = $maxbacktrack;
  2823. //Backtrack some directories
  2824. for( $i = 0 ; $i < $backtrackamount + 1 ; $i++ ) $path = substr( $path, 0 , strrpos($path,"/") );
  2825. $path = $path . "/" . $filepath; //Make it an absolute path
  2826. }
  2827. elseif( strpos($path,":/") === false) //It is a Local Link
  2828. {
  2829. $path = $this->basepath . $path;
  2830. }
  2831. //Do nothing if it is an Absolute Link
  2832. }
  2833. $regexp = '/ (href|src)="(.*?)"/i';
  2834. $e = preg_replace($regexp,' \\1="'.$path.'"',$e);
  2835. }//END of Fix path values
  2836. //Extract attributes
  2837. $contents=array();
  2838. preg_match_all('/\\S*=["\'][^"\']*["\']/',$e,$contents);
  2839. preg_match('/\\S+/',$e,$a2);
  2840. $tag=strtoupper($a2[0]);
  2841. $attr=array();
  2842. if (!empty($contents))
  2843. {
  2844. foreach($contents[0] as $v)
  2845. {
  2846. if(ereg('^([^=]*)=["\']?([^"\']*)["\']?$',$v,$a3))
  2847. {
  2848. $attr[strtoupper($a3[1])]=$a3[2];
  2849. }
  2850. }
  2851. }
  2852. $this->OpenTag($tag,$attr);
  2853. }
  2854. }
  2855. }//end of foreach($a as $i=>$e)
  2856. //Create Internal Links, if needed
  2857. if (!empty($this->internallink) )
  2858. {
  2859. foreach($this->internallink as $k=>$v)
  2860. {
  2861. if (strpos($k,"#") !== false ) continue; //ignore
  2862. $ypos = $v['Y'];
  2863. $pagenum = $v['PAGE'];
  2864. $sharp = "#";
  2865. while (array_key_exists($sharp.$k,$this->internallink))
  2866. {
  2867. $internallink = $this->internallink[$sharp.$k];
  2868. $this->SetLink($internallink,$ypos,$pagenum);
  2869. $sharp .= "#";
  2870. }
  2871. }
  2872. }
  2873. }
  2874. function OpenTag($tag,$attr)
  2875. {
  2876. //! @return void
  2877. // What this gets: < $tag $attr['WIDTH']="90px" > does not get content here </closeTag here>
  2878. $align = array('left'=>'L','center'=>'C','right'=>'R','top'=>'T','middle'=>'M','bottom'=>'B','justify'=>'J');
  2879. $this->blockjustfinished=false;
  2880. //Opening tag
  2881. switch($tag){
  2882. case 'PAGE_BREAK': //custom-tag
  2883. case 'NEWPAGE': //custom-tag
  2884. $this->blockjustfinished = true;
  2885. $this->AddPage();
  2886. break;
  2887. case 'OUTLINE': //custom-tag (CSS2 property - browsers don't support it yet - Jan2005)
  2888. //Usage: (default: width=normal color=white)
  2889. //<outline width="(thin|medium|thick)" color="(usualcolorformat)" >Text</outline>
  2890. //Mix this tag with the <font color="(usualcolorformat)"> tag to get mixed colors on outlined text!
  2891. $this->buffer_on = true;
  2892. if (isset($attr['COLOR'])) $this->outlineparam['COLOR'] = ConvertColor($attr['COLOR']);
  2893. else $this->outlineparam['COLOR'] = array('R'=>255,'G'=>255,'B'=>255); //white
  2894. $this->outlineparam['OLDWIDTH'] = $this->LineWidth;
  2895. if (isset($attr['WIDTH']))
  2896. {
  2897. switch(strtoupper($attr['WIDTH']))
  2898. {
  2899. case 'THIN': $this->outlineparam['WIDTH'] = 0.75*$this->LineWidth; break;
  2900. case 'MEDIUM': $this->outlineparam['WIDTH'] = $this->LineWidth; break;
  2901. case 'THICK': $this->outlineparam['WIDTH'] = 1.75*$this->LineWidth; break;
  2902. }
  2903. }
  2904. else $this->outlineparam['WIDTH'] = $this->LineWidth; //width == oldwidth
  2905. break;
  2906. case 'BDO':
  2907. if (isset($attr['DIR']) and (strtoupper($attr['DIR']) == 'RTL' )) $this->divrevert = true;
  2908. break;
  2909. case 'S':
  2910. case 'STRIKE':
  2911. case 'DEL':
  2912. $this->strike=true;
  2913. break;
  2914. case 'SUB':
  2915. $this->SUB=true;
  2916. break;
  2917. case 'SUP':
  2918. $this->SUP=true;
  2919. break;
  2920. case 'CENTER':
  2921. $this->buffer_on = true;
  2922. if ($this->tdbegin) $this->cell[$this->row][$this->col]['a'] = $align['center'];
  2923. else
  2924. {
  2925. $this->divalign = $align['center'];
  2926. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  2927. }
  2928. break;
  2929. case 'ADDRESS':
  2930. $this->buffer_on = true;
  2931. $this->SetStyle('I',true);
  2932. if (!$this->tdbegin and $this->x != $this->lMargin) $this->Ln($this->lineheight);
  2933. break;
  2934. case 'TABLE': // TABLE-BEGIN
  2935. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  2936. $this->tablestart = true;
  2937. $this->table['nc'] = $this->table['nr'] = 0;
  2938. if (isset($attr['REPEAT_HEADER']) and $attr['REPEAT_HEADER'] == true) $this->UseTableHeader(true);
  2939. if (isset($attr['WIDTH'])) $this->table['w'] = ConvertSize($attr['WIDTH'],$this->pgwidth);
  2940. if (isset($attr['HEIGHT'])) $this->table['h'] = ConvertSize($attr['HEIGHT'],$this->pgwidth);
  2941. if (isset($attr['ALIGN'])) $this->table['a'] = $align[strtolower($attr['ALIGN'])];
  2942. if (isset($attr['BORDER'])) $this->table['border'] = $attr['BORDER'];
  2943. if (isset($attr['BGCOLOR'])) $this->table['bgcolor'][-1] = $attr['BGCOLOR'];
  2944. break;
  2945. case 'TR':
  2946. $this->row++;
  2947. //debug($this->table);
  2948. $this->table['nr']++;
  2949. $this->col = -1;
  2950. if (isset($attr['BGCOLOR']))$this->table['bgcolor'][$this->row] = $attr['BGCOLOR'];
  2951. break;
  2952. case 'TH':
  2953. $this->SetStyle('B',true);
  2954. if (!isset($attr['ALIGN'])) $attr['ALIGN'] = "center";
  2955. case 'TD':
  2956. $this->tdbegin = true;
  2957. $this->col++;
  2958. while (isset($this->cell[$this->row][$this->col])) $this->col++;
  2959. //Update number column
  2960. if ($this->table['nc'] < $this->col+1) $this->table['nc'] = $this->col+1;
  2961. $this->cell[$this->row][$this->col] = array();
  2962. $this->cell[$this->row][$this->col]['text'] = array();
  2963. $this->cell[$this->row][$this->col]['s'] = 3;
  2964. if (isset($attr['WIDTH'])) $this->cell[$this->row][$this->col]['w'] = ConvertSize($attr['WIDTH'],$this->pgwidth);
  2965. if (isset($attr['HEIGHT'])) $this->cell[$this->row][$this->col]['h'] = ConvertSize($attr['HEIGHT'],$this->pgwidth);
  2966. if (isset($attr['ALIGN'])) $this->cell[$this->row][$this->col]['a'] = $align[strtolower($attr['ALIGN'])];
  2967. if (isset($attr['VALIGN'])) $this->cell[$this->row][$this->col]['va'] = $align[strtolower($attr['VALIGN'])];
  2968. if (isset($attr['BORDER'])) $this->cell[$this->row][$this->col]['border'] = $attr['BORDER'];
  2969. if (isset($attr['BGCOLOR'])) $this->cell[$this->row][$this->col]['bgcolor'] = $attr['BGCOLOR'];
  2970. $cs = $rs = 1;
  2971. if (isset($attr['COLSPAN']) && $attr['COLSPAN']>1) $cs = $this->cell[$this->row][$this->col]['colspan'] = $attr['COLSPAN'];
  2972. if (isset($attr['ROWSPAN']) && $attr['ROWSPAN']>1) $rs = $this->cell[$this->row][$this->col]['rowspan'] = $attr['ROWSPAN'];
  2973. //Chiem dung vi tri de danh cho cell span (�mais hein?)
  2974. for ($k=$this->row ; $k < $this->row+$rs ;$k++)
  2975. for($l=$this->col; $l < $this->col+$cs ;$l++)
  2976. {
  2977. if ($k-$this->row || $l-$this->col) $this->cell[$k][$l] = 0;
  2978. }
  2979. if (isset($attr['NOWRAP'])) $this->cell[$this->row][$this->col]['nowrap']= 1;
  2980. break;
  2981. case 'OL':
  2982. if ( !isset($attr['TYPE']) or $attr['TYPE'] == '' ) $this->listtype = '1'; //OL default == '1'
  2983. else $this->listtype = $attr['TYPE']; // ol and ul types are mixed here
  2984. case 'UL':
  2985. if ( (!isset($attr['TYPE']) or $attr['TYPE'] == '') and $tag=='UL')
  2986. {
  2987. //Insert UL defaults
  2988. if ($this->listlvl == 0) $this->listtype = 'disc';
  2989. elseif ($this->listlvl == 1) $this->listtype = 'circle';
  2990. else $this->listtype = 'square';
  2991. }
  2992. elseif (isset($attr['TYPE']) and $tag=='UL') $this->listtype = $attr['TYPE'];
  2993. $this->buffer_on = false;
  2994. if ($this->listlvl == 0)
  2995. {
  2996. //First of all, skip a line
  2997. if (!$this->pjustfinished)
  2998. {
  2999. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  3000. $this->Ln($this->lineheight);
  3001. }
  3002. $this->oldx = $this->x;
  3003. $this->listlvl++; // first depth level
  3004. $this->listnum = 0; // reset
  3005. $this->listoccur[$this->listlvl] = 1;
  3006. $this->listlist[$this->listlvl][1] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
  3007. }
  3008. else
  3009. {
  3010. if (!empty($this->textbuffer))
  3011. {
  3012. $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
  3013. $this->listnum++;
  3014. }
  3015. $this->textbuffer = array();
  3016. $occur = $this->listoccur[$this->listlvl];
  3017. $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
  3018. $this->listlvl++;
  3019. $this->listnum = 0; // reset
  3020. if ($this->listoccur[$this->listlvl] == 0) $this->listoccur[$this->listlvl] = 1;
  3021. else $this->listoccur[$this->listlvl]++;
  3022. $occur = $this->listoccur[$this->listlvl];
  3023. $this->listlist[$this->listlvl][$occur] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
  3024. }
  3025. break;
  3026. case 'LI':
  3027. //Observation: </LI> is ignored
  3028. if ($this->listlvl == 0) //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
  3029. {
  3030. //First of all, skip a line
  3031. if (!$this->pjustfinished and $this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
  3032. $this->oldx = $this->x;
  3033. $this->listlvl++; // first depth level
  3034. $this->listnum = 0; // reset
  3035. $this->listoccur[$this->listlvl] = 1;
  3036. $this->listlist[$this->listlvl][1] = array('TYPE'=>'disc','MAXNUM'=>$this->listnum);
  3037. }
  3038. if ($this->listnum == 0)
  3039. {
  3040. $this->buffer_on = true; //activate list 'bufferization'
  3041. $this->listnum++;
  3042. $this->textbuffer = array();
  3043. }
  3044. else
  3045. {
  3046. $this->buffer_on = true; //activate list 'bufferization'
  3047. if (!empty($this->textbuffer))
  3048. {
  3049. $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
  3050. $this->listnum++;
  3051. }
  3052. $this->textbuffer = array();
  3053. }
  3054. break;
  3055. case 'H1': // 2 * fontsize
  3056. case 'H2': // 1.5 * fontsize
  3057. case 'H3': // 1.17 * fontsize
  3058. case 'H4': // 1 * fontsize
  3059. case 'H5': // 0.83 * fontsize
  3060. case 'H6': // 0.67 * fontsize
  3061. //Values obtained from: http://www.w3.org/TR/REC-CSS2/sample.html
  3062. if(isset($attr['ALIGN'])) $this->divalign = $align[strtolower($attr['ALIGN'])];
  3063. $this->buffer_on = true;
  3064. if ($this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
  3065. elseif (!$this->pjustfinished) $this->Ln($this->lineheight);
  3066. $this->SetStyle('B',true);
  3067. switch($tag)
  3068. {
  3069. case 'H1':
  3070. $this->SetFontSize(2*$this->FontSizePt);
  3071. $this->lineheight *= 2;
  3072. break;
  3073. case 'H2':
  3074. $this->SetFontSize(1.5*$this->FontSizePt);
  3075. $this->lineheight *= 1.5;
  3076. break;
  3077. case 'H3':
  3078. $this->SetFontSize(1.17*$this->FontSizePt);
  3079. $this->lineheight *= 1.17;
  3080. break;
  3081. case 'H4':
  3082. $this->SetFontSize($this->FontSizePt);
  3083. break;
  3084. case 'H5':
  3085. $this->SetFontSize(0.83*$this->FontSizePt);
  3086. $this->lineheight *= 0.83;
  3087. break;
  3088. case 'H6':
  3089. $this->SetFontSize(0.67*$this->FontSizePt);
  3090. $this->lineheight *= 0.67;
  3091. break;
  3092. }
  3093. break;
  3094. case 'HR': //Default values: width=100% align=center color=gray
  3095. //Skip a line, if needed
  3096. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  3097. $this->Ln(0.2*$this->lineheight);
  3098. $hrwidth = $this->pgwidth;
  3099. $hralign = 'C';
  3100. $hrcolor = array('R'=>200,'G'=>200,'B'=>200);
  3101. if($attr['WIDTH'] != '') $hrwidth = ConvertSize($attr['WIDTH'],$this->pgwidth);
  3102. if($attr['ALIGN'] != '') $hralign = $align[strtolower($attr['ALIGN'])];
  3103. if($attr['COLOR'] != '') $hrcolor = ConvertColor($attr['COLOR']);
  3104. $this->SetDrawColor($hrcolor['R'],$hrcolor['G'],$hrcolor['B']);
  3105. $x = $this->x;
  3106. $y = $this->y;
  3107. switch($hralign)
  3108. {
  3109. case 'L':
  3110. case 'J':
  3111. break;
  3112. case 'C':
  3113. $empty = $this->pgwidth - $hrwidth;
  3114. $empty /= 2;
  3115. $x += $empty;
  3116. break;
  3117. case 'R':
  3118. $empty = $this->pgwidth - $hrwidth;
  3119. $x += $empty;
  3120. break;
  3121. }
  3122. $oldlinewidth = $this->LineWidth;
  3123. $this->SetLineWidth(0.3);
  3124. $this->Line($x,$y,$x+$hrwidth,$y);
  3125. $this->SetLineWidth($oldlinewidth);
  3126. $this->Ln(0.2*$this->lineheight);
  3127. $this->SetDrawColor(0);
  3128. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  3129. break;
  3130. case 'INS':
  3131. $this->SetStyle('U',true);
  3132. break;
  3133. case 'SMALL':
  3134. $newsize = $this->FontSizePt - 1;
  3135. $this->SetFontSize($newsize);
  3136. break;
  3137. case 'BIG':
  3138. $newsize = $this->FontSizePt + 1;
  3139. $this->SetFontSize($newsize);
  3140. case 'STRONG':
  3141. $this->SetStyle('B',true);
  3142. break;
  3143. case 'CITE':
  3144. case 'EM':
  3145. $this->SetStyle('I',true);
  3146. break;
  3147. case 'TITLE':
  3148. $this->titulo = true;
  3149. break;
  3150. case 'B':
  3151. case 'I':
  3152. case 'U':
  3153. if( isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
  3154. {
  3155. $this->cssbegin=true;
  3156. if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
  3157. elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
  3158. //Read Inline CSS
  3159. if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
  3160. //Look for name in the $this->CSS array
  3161. $this->backupcss = $properties;
  3162. if (!empty($properties)) $this->setCSS($properties); //name found in the CSS array!
  3163. }
  3164. $this->SetStyle($tag,true);
  3165. break;
  3166. case 'A':
  3167. if (isset($attr['NAME']) and $attr['NAME'] != '') $this->textbuffer[] = array('','','',array(),'',false,false,$attr['NAME']); //an internal link (adds a space for recognition)
  3168. if (isset($attr['HREF'])) $this->HREF=$attr['HREF'];
  3169. break;
  3170. case 'DIV':
  3171. //in case of malformed HTML code. Example:(...)</div><li>Content</li><div>DIV1</div>(...)
  3172. if ($this->listlvl > 0) // We are closing (omitted) OL/UL tag(s)
  3173. {
  3174. $this->buffer_on = false;
  3175. if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
  3176. $this->textbuffer = array();
  3177. $this->listlvl--;
  3178. $this->printlistbuffer();
  3179. $this->pjustfinished = true; //act as if a paragraph just ended
  3180. }
  3181. $this->divbegin=true;
  3182. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  3183. if( isset($attr['ALIGN']) and $attr['ALIGN'] != '' ) $this->divalign = $align[strtolower($attr['ALIGN'])];
  3184. if( isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
  3185. {
  3186. $this->cssbegin=true;
  3187. if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
  3188. elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
  3189. //Read Inline CSS
  3190. if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
  3191. //Look for name in the $this->CSS array
  3192. if (!empty($properties)) $this->setCSS($properties); //name found in the CSS array!
  3193. }
  3194. break;
  3195. case 'IMG':
  3196. if(!empty($this->textbuffer) and !$this->tablestart)
  3197. {
  3198. //Output previously buffered content and output image below
  3199. //Set some default values
  3200. $olddivwidth = $this->divwidth;
  3201. $olddivheight = $this->divheight;
  3202. if ( $this->divwidth == 0) $this->divwidth = $this->pgwidth - $x + $this->lMargin;
  3203. if ( $this->divheight == 0) $this->divheight = $this->lineheight;
  3204. //Print content
  3205. $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
  3206. $this->textbuffer=array();
  3207. //Reset values
  3208. $this->divwidth = $olddivwidth;
  3209. $this->divheight = $olddivheight;
  3210. $this->textbuffer=array();
  3211. $this->Ln($this->lineheight);
  3212. }
  3213. if(isset($attr['SRC']))
  3214. {
  3215. $srcpath = $attr['SRC'];
  3216. if(!isset($attr['WIDTH'])) $attr['WIDTH'] = 0;
  3217. else $attr['WIDTH'] = ConvertSize($attr['WIDTH'],$this->pgwidth);//$attr['WIDTH'] /= 4;
  3218. if(!isset($attr['HEIGHT'])) $attr['HEIGHT'] = 0;
  3219. else $attr['HEIGHT'] = ConvertSize($attr['HEIGHT'],$this->pgwidth);//$attr['HEIGHT'] /= 4;
  3220. if ($this->tdbegin)
  3221. {
  3222. $bak_x = $this->x;
  3223. $bak_y = $this->y;
  3224. //Check whether image exists locally or on the URL
  3225. $f_exists = @fopen($srcpath,"rb");
  3226. if (!$f_exists) //Show 'image not found' icon instead
  3227. {
  3228. if(!$this->shownoimg) break;
  3229. $srcpath = str_replace("\\","/",dirname(__FILE__)) . "/";
  3230. $srcpath .= 'no_img.gif';
  3231. }
  3232. $sizesarray = $this->Image($srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'],'','',false);
  3233. $this->y = $bak_y;
  3234. $this->x = $bak_x;
  3235. }
  3236. elseif($this->pbegin or $this->divbegin)
  3237. {
  3238. //In order to support <div align='center'><img ...></div>
  3239. $ypos = 0;
  3240. $bak_x = $this->x;
  3241. $bak_y = $this->y;
  3242. //Check whether image exists locally or on the URL
  3243. $f_exists = @fopen($srcpath,"rb");
  3244. if (!$f_exists) //Show 'image not found' icon instead
  3245. {
  3246. if(!$this->shownoimg) break;
  3247. $srcpath = str_replace("\\","/",dirname(__FILE__)) . "/";
  3248. $srcpath .= 'no_img.gif';
  3249. }
  3250. $sizesarray = $this->Image($srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'],'','',false);
  3251. $this->y = $bak_y;
  3252. $this->x = $bak_x;
  3253. $xpos = '';
  3254. switch($this->divalign)
  3255. {
  3256. case "C":
  3257. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  3258. $empty = ($this->pgwidth - $sizesarray['WIDTH'])/2;
  3259. $xpos = 'xpos='.$empty.',';
  3260. break;
  3261. case "R":
  3262. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  3263. $empty = ($this->pgwidth - $sizesarray['WIDTH']);
  3264. $xpos = 'xpos='.$empty.',';
  3265. break;
  3266. default: break;
  3267. }
  3268. $numberoflines = (integer)ceil($sizesarray['HEIGHT']/$this->lineheight) ;
  3269. $ypos = $numberoflines * $this->lineheight;
  3270. $this->textbuffer[] = array("���"/*identifier*/."type=image,ypos=$ypos,{$xpos}width=".$sizesarray['WIDTH'].",height=".$sizesarray['HEIGHT']."���".$sizesarray['OUTPUT']);
  3271. while($numberoflines) {$this->textbuffer[] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);$numberoflines--;}
  3272. }
  3273. else
  3274. {
  3275. $imgborder = 0;
  3276. if (isset($attr['BORDER'])) $imgborder = ConvertSize($attr['BORDER'],$this->pgwidth);
  3277. //Check whether image exists locally or on the URL
  3278. $f_exists = @fopen($srcpath,"rb");
  3279. if (!$f_exists) //Show 'image not found' icon instead
  3280. {
  3281. $srcpath = str_replace("\\","/",dirname(__FILE__)) . "/";
  3282. $srcpath .= 'no_img.gif';
  3283. }
  3284. $sizesarray = $this->Image($srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'],'',$this->HREF); //Output Image
  3285. $ini_x = $sizesarray['X'];
  3286. $ini_y = $sizesarray['Y'];
  3287. if ($imgborder)
  3288. {
  3289. $oldlinewidth = $this->LineWidth;
  3290. $this->SetLineWidth($imgborder);
  3291. $this->Rect($ini_x,$ini_y,$sizesarray['WIDTH'],$sizesarray['HEIGHT']);
  3292. $this->SetLineWidth($oldlinewidth);
  3293. }
  3294. }
  3295. if ($sizesarray['X'] < $this->x) $this->x = $this->lMargin;
  3296. if ($this->tablestart)
  3297. {
  3298. $this->cell[$this->row][$this->col]['textbuffer'][] = array("���"/*identifier*/."type=image,width=".$sizesarray['WIDTH'].",height=".$sizesarray['HEIGHT']."���".$sizesarray['OUTPUT']);
  3299. $this->cell[$this->row][$this->col]['s'] += $sizesarray['WIDTH'] + 1;// +1 == margin
  3300. $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later
  3301. if (!isset($this->cell[$this->row][$this->col]['w'])) $this->cell[$this->row][$this->col]['w'] = $sizesarray['WIDTH'] + 3;
  3302. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $sizesarray['HEIGHT'] + 3;
  3303. }
  3304. }
  3305. break;
  3306. case 'BLOCKQUOTE':
  3307. case 'BR':
  3308. if($this->tablestart)
  3309. {
  3310. $this->cell[$this->row][$this->col]['textbuffer'][] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
  3311. $this->cell[$this->row][$this->col]['text'][] = "\n";
  3312. if (!isset($this->cell[$this->row][$this->col]['maxs'])) $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'] +2; //+2 == margin
  3313. elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s']+2;//+2 == margin
  3314. $this->cell[$this->row][$this->col]['s'] = 0;// reset
  3315. }
  3316. elseif($this->divbegin or $this->pbegin or $this->buffer_on) $this->textbuffer[] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
  3317. else {$this->Ln($this->lineheight);$this->blockjustfinished = true;}
  3318. break;
  3319. case 'P':
  3320. //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
  3321. if ($this->listlvl > 0) // We are closing (omitted) OL/UL tag(s)
  3322. {
  3323. $this->buffer_on = false;
  3324. if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
  3325. $this->textbuffer = array();
  3326. $this->listlvl--;
  3327. $this->printlistbuffer();
  3328. $this->pjustfinished = true; //act as if a paragraph just ended
  3329. }
  3330. if ($this->tablestart)
  3331. {
  3332. //$this->cell[$this->row][$this->col]['textbuffer'][] = array($e,$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
  3333. //added the following line by Venkat
  3334. $e = null;
  3335. $this->cell[$this->row][$this->col]['textbuffer'][] = array($e,$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
  3336. $this->cell[$this->row][$this->col]['text'][] = "\n";
  3337. break;
  3338. }
  3339. $this->pbegin=true;
  3340. if ($this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
  3341. elseif (!$this->pjustfinished) $this->Ln($this->lineheight);
  3342. //Save x,y coords in case we need to print borders...
  3343. $this->oldx = $this->x;
  3344. $this->oldy = $this->y;
  3345. if(isset($attr['ALIGN'])) $this->divalign = $align[strtolower($attr['ALIGN'])];
  3346. if(isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
  3347. {
  3348. $this->cssbegin=true;
  3349. if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
  3350. elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
  3351. //Read Inline CSS
  3352. if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
  3353. //Look for name in the $this->CSS array
  3354. $this->backupcss = $properties;
  3355. if (!empty($properties)) $this->setCSS($properties); //name(id/class/style) found in the CSS array!
  3356. }
  3357. break;
  3358. case 'SPAN':
  3359. $this->buffer_on = true;
  3360. //Save x,y coords in case we need to print borders...
  3361. $this->oldx = $this->x;
  3362. $this->oldy = $this->y;
  3363. if( isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
  3364. {
  3365. $this->cssbegin=true;
  3366. if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
  3367. elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
  3368. //Read Inline CSS
  3369. if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
  3370. //Look for name in the $this->CSS array
  3371. $this->backupcss = $properties;
  3372. if (!empty($properties)) $this->setCSS($properties); //name found in the CSS array!
  3373. }
  3374. break;
  3375. case 'PRE':
  3376. if($this->tablestart)
  3377. {
  3378. $this->cell[$this->row][$this->col]['textbuffer'][] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
  3379. $this->cell[$this->row][$this->col]['text'][] = "\n";
  3380. }
  3381. elseif($this->divbegin or $this->pbegin or $this->buffer_on) $this->textbuffer[] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
  3382. else
  3383. {
  3384. if ($this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
  3385. elseif (!$this->pjustfinished) $this->Ln($this->lineheight);
  3386. $this->buffer_on = true;
  3387. //Save x,y coords in case we need to print borders...
  3388. $this->oldx = $this->x;
  3389. $this->oldy = $this->y;
  3390. if(isset($attr['ALIGN'])) $this->divalign = $align[strtolower($attr['ALIGN'])];
  3391. if(isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
  3392. {
  3393. $this->cssbegin=true;
  3394. if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
  3395. elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
  3396. //Read Inline CSS
  3397. if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
  3398. //Look for name in the $this->CSS array
  3399. $this->backupcss = $properties;
  3400. if (!empty($properties)) $this->setCSS($properties); //name(id/class/style) found in the CSS array!
  3401. }
  3402. }
  3403. case 'TT':
  3404. case 'KBD':
  3405. case 'SAMP':
  3406. case 'CODE':
  3407. $this->SetFont('courier');
  3408. $this->currentfont='courier';
  3409. break;
  3410. case 'TEXTAREA':
  3411. $this->buffer_on = true;
  3412. $colsize = 20; //HTML default value
  3413. $rowsize = 2; //HTML default value
  3414. if (isset($attr['COLS'])) $colsize = $attr['COLS'];
  3415. if (isset($attr['ROWS'])) $rowsize = $attr['ROWS'];
  3416. if (!$this->tablestart)
  3417. {
  3418. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  3419. $this->col = $colsize;
  3420. $this->row = $rowsize;
  3421. }
  3422. else //it is inside a table
  3423. {
  3424. $this->specialcontent = "type=textarea,lines=$rowsize,width=".((2.2*$colsize) + 3); //Activate form info in order to paint FORM elements within table
  3425. $this->cell[$this->row][$this->col]['s'] += (2.2*$colsize) + 6;// +6 == margin
  3426. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = 1.1*$this->lineheight*$rowsize + 2.5;
  3427. }
  3428. break;
  3429. case 'SELECT':
  3430. $this->specialcontent = "type=select"; //Activate form info in order to paint FORM elements within table
  3431. break;
  3432. case 'OPTION':
  3433. $this->selectoption['ACTIVE'] = true;
  3434. if (empty($this->selectoption))
  3435. {
  3436. $this->selectoption['MAXWIDTH'] = '';
  3437. $this->selectoption['SELECTED'] = '';
  3438. }
  3439. if (isset($attr['SELECTED'])) $this->selectoption['SELECTED'] = '';
  3440. break;
  3441. case 'FORM':
  3442. if($this->tablestart)
  3443. {
  3444. $this->cell[$this->row][$this->col]['textbuffer'][] = array($e,$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
  3445. $this->cell[$this->row][$this->col]['text'][] = "\n";
  3446. }
  3447. elseif ($this->x != $this->lMargin) $this->Ln($this->lineheight); //Skip a line, if needed
  3448. break;
  3449. case 'INPUT':
  3450. if (!isset($attr['TYPE'])) $attr['TYPE'] == ''; //in order to allow default 'TEXT' form (in case of malformed HTML code)
  3451. if (!$this->tablestart)
  3452. {
  3453. switch(strtoupper($attr['TYPE'])){
  3454. case 'CHECKBOX': //Draw Checkbox
  3455. $checked = false;
  3456. if (isset($attr['CHECKED'])) $checked = true;
  3457. $this->SetFillColor(235,235,235);
  3458. $this->x += 3;
  3459. $this->Rect($this->x,$this->y+1,3,3,'DF');
  3460. if ($checked)
  3461. {
  3462. $this->Line($this->x,$this->y+1,$this->x+3,$this->y+1+3);
  3463. $this->Line($this->x,$this->y+1+3,$this->x+3,$this->y+1);
  3464. }
  3465. $this->SetFillColor(255);
  3466. $this->x += 3.5;
  3467. break;
  3468. case 'RADIO': //Draw Radio button
  3469. $checked = false;
  3470. if (isset($attr['CHECKED'])) $checked = true;
  3471. $this->x += 4;
  3472. $this->Circle($this->x,$this->y+2.2,1,'D');
  3473. $this->_out('0.000 g');
  3474. if ($checked) $this->Circle($this->x,$this->y+2.2,0.4,'DF');
  3475. $this->Write(5,$texto,$this->x);
  3476. $this->x += 2;
  3477. break;
  3478. case 'BUTTON': // Draw a button
  3479. case 'SUBMIT':
  3480. case 'RESET':
  3481. $texto='';
  3482. if (isset($attr['VALUE'])) $texto = $attr['VALUE'];
  3483. $nihil = 2.5;
  3484. $this->x += 2;
  3485. $this->SetFillColor(190,190,190);
  3486. $this->Rect($this->x,$this->y,$this->GetStringWidth($texto)+2*$nihil,4.5,'DF'); // 4.5 in order to avoid overlapping
  3487. $this->x += $nihil;
  3488. $this->Write(5,$texto,$this->x);
  3489. $this->x += $nihil;
  3490. $this->SetFillColor(255);
  3491. break;
  3492. case 'PASSWORD':
  3493. if (isset($attr['VALUE']))
  3494. {
  3495. $num_stars = strlen($attr['VALUE']);
  3496. $attr['VALUE'] = str_repeat('*',$num_stars);
  3497. }
  3498. case 'TEXT': //Draw TextField
  3499. default: //default == TEXT
  3500. $texto='';
  3501. if (isset($attr['VALUE'])) $texto = $attr['VALUE'];
  3502. $tamanho = 20;
  3503. if (isset($attr['SIZE']) and ctype_digit($attr['SIZE']) ) $tamanho = $attr['SIZE'];
  3504. $this->SetFillColor(235,235,235);
  3505. $this->x += 2;
  3506. $this->Rect($this->x,$this->y,2*$tamanho,4.5,'DF');// 4.5 in order to avoid overlapping
  3507. if ($texto != '')
  3508. {
  3509. $this->x += 1;
  3510. $this->Write(5,$texto,$this->x);
  3511. $this->x -= $this->GetStringWidth($texto);
  3512. }
  3513. $this->SetFillColor(255);
  3514. $this->x += 2*$tamanho;
  3515. break;
  3516. }
  3517. }
  3518. else //we are inside a table
  3519. {
  3520. $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later
  3521. $type = '';
  3522. $text = '';
  3523. $height = 0;
  3524. $width = 0;
  3525. switch(strtoupper($attr['TYPE'])){
  3526. case 'CHECKBOX': //Draw Checkbox
  3527. $checked = false;
  3528. if (isset($attr['CHECKED'])) $checked = true;
  3529. $text = $checked;
  3530. $type = 'CHECKBOX';
  3531. $width = 4;
  3532. $this->cell[$this->row][$this->col]['textbuffer'][] = array("���"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."���".$text);
  3533. $this->cell[$this->row][$this->col]['s'] += $width;
  3534. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight;
  3535. break;
  3536. case 'RADIO': //Draw Radio button
  3537. $checked = false;
  3538. if (isset($attr['CHECKED'])) $checked = true;
  3539. $text = $checked;
  3540. $type = 'RADIO';
  3541. $width = 3;
  3542. $this->cell[$this->row][$this->col]['textbuffer'][] = array("���"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."���".$text);
  3543. $this->cell[$this->row][$this->col]['s'] += $width;
  3544. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight;
  3545. break;
  3546. case 'BUTTON': $type = 'BUTTON'; // Draw a button
  3547. case 'SUBMIT': if ($type == '') $type = 'SUBMIT';
  3548. case 'RESET': if ($type == '') $type = 'RESET';
  3549. $texto='';
  3550. if (isset($attr['VALUE'])) $texto = " " . $attr['VALUE'] . " ";
  3551. $text = $texto;
  3552. $width = $this->GetStringWidth($texto)+3;
  3553. $this->cell[$this->row][$this->col]['textbuffer'][] = array("���"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."���".$text);
  3554. $this->cell[$this->row][$this->col]['s'] += $width;
  3555. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2;
  3556. break;
  3557. case 'PASSWORD':
  3558. if (isset($attr['VALUE']))
  3559. {
  3560. $num_stars = strlen($attr['VALUE']);
  3561. $attr['VALUE'] = str_repeat('*',$num_stars);
  3562. }
  3563. $type = 'PASSWORD';
  3564. case 'TEXT': //Draw TextField
  3565. default: //default == TEXT
  3566. $texto='';
  3567. if (isset($attr['VALUE'])) $texto = $attr['VALUE'];
  3568. $tamanho = 20;
  3569. if (isset($attr['SIZE']) and ctype_digit($attr['SIZE']) ) $tamanho = $attr['SIZE'];
  3570. $text = $texto;
  3571. $width = 2*$tamanho;
  3572. if ($type == '') $type = 'TEXT';
  3573. $this->cell[$this->row][$this->col]['textbuffer'][] = array("���"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."���".$text);
  3574. $this->cell[$this->row][$this->col]['s'] += $width;
  3575. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2;
  3576. break;
  3577. }
  3578. }
  3579. break;
  3580. case 'FONT':
  3581. //Font size is ignored for now
  3582. if (isset($attr['COLOR']) and $attr['COLOR']!='')
  3583. {
  3584. $cor = ConvertColor($attr['COLOR']);
  3585. //If something goes wrong switch color to black
  3586. $cor['R'] = (isset($cor['R'])?$cor['R']:0);
  3587. $cor['G'] = (isset($cor['G'])?$cor['G']:0);
  3588. $cor['B'] = (isset($cor['B'])?$cor['B']:0);
  3589. $this->colorarray = $cor;
  3590. $this->SetTextColor($cor['R'],$cor['G'],$cor['B']);
  3591. $this->issetcolor = true;
  3592. }
  3593. if (isset($attr['FACE']) and in_array(strtolower($attr['FACE']), $this->fontlist))
  3594. {
  3595. $this->SetFont(strtolower($attr['FACE']));
  3596. $this->issetfont=true;
  3597. }
  3598. //'If' disabled in this version due lack of testing (you may enable it if you want)
  3599. // if (isset($attr['FACE']) and in_array(strtolower($attr['FACE']), $this->fontlist) and isset($attr['SIZE']) and $attr['SIZE']!='') {
  3600. // $this->SetFont(strtolower($attr['FACE']),'',$attr['SIZE']);
  3601. // $this->issetfont=true;
  3602. // }
  3603. break;
  3604. }//end of switch
  3605. $this->pjustfinished=false;
  3606. }
  3607. function CloseTag($tag)
  3608. {
  3609. //! @return void
  3610. //Closing tag
  3611. if($tag=='OPTION') $this->selectoption['ACTIVE'] = false;
  3612. if($tag=='BDO') $this->divrevert = false;
  3613. if($tag=='INS') $tag='U';
  3614. if($tag=='STRONG') $tag='B';
  3615. if($tag=='EM' or $tag=='CITE') $tag='I';
  3616. if($tag=='OUTLINE')
  3617. {
  3618. if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
  3619. {
  3620. //Deactivate $this->outlineparam for its info is already stored inside $this->textbuffer
  3621. //if (isset($this->outlineparam['OLDWIDTH'])) $this->SetTextOutline($this->outlineparam['OLDWIDTH']);
  3622. $this->SetTextOutline(false);
  3623. $this->outlineparam=array();
  3624. //Save x,y coords ???
  3625. $x = $this->x;
  3626. $y = $this->y;
  3627. //Set some default values
  3628. $this->divwidth = $this->pgwidth - $x + $this->lMargin;
  3629. //Print content
  3630. $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
  3631. $this->textbuffer=array();
  3632. //Reset values
  3633. $this->Reset();
  3634. $this->buffer_on=false;
  3635. }
  3636. $this->SetTextOutline(false);
  3637. $this->outlineparam=array();
  3638. }
  3639. if($tag=='A')
  3640. {
  3641. if(!$this->pbegin and !$this->divbegin and !$this->tablestart and !$this->buffer_on)
  3642. {
  3643. //Deactivate $this->HREF for its info is already stored inside $this->textbuffer
  3644. $this->HREF='';
  3645. //Save x,y coords ???
  3646. $x = $this->x;
  3647. $y = $this->y;
  3648. //Set some default values
  3649. $this->divwidth = $this->pgwidth - $x + $this->lMargin;
  3650. //Print content
  3651. $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
  3652. $this->textbuffer=array();
  3653. //Reset values
  3654. $this->Reset();
  3655. }
  3656. $this->HREF='';
  3657. }
  3658. if($tag=='TH') $this->SetStyle('B',false);
  3659. if($tag=='TH' or $tag=='TD') $this->tdbegin = false;
  3660. if($tag=='SPAN')
  3661. {
  3662. if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
  3663. {
  3664. if($this->cssbegin)
  3665. {
  3666. //Check if we have borders to print
  3667. if ($this->cssbegin and ($this->divborder or $this->dash_on or $this->dotted_on or $this->divbgcolor))
  3668. {
  3669. $texto='';
  3670. foreach($this->textbuffer as $vetor) $texto.=$vetor[0];
  3671. $tempx = $this->x;
  3672. if($this->divbgcolor) $this->Cell($this->GetStringWidth($texto),$this->lineheight,'',$this->divborder,'','L',$this->divbgcolor);
  3673. if ($this->dash_on) $this->Rect($this->oldx,$this->oldy,$this->GetStringWidth($texto),$this->lineheight);
  3674. if ($this->dotted_on) $this->DottedRect($this->x - $this->GetStringWidth($texto),$this->y,$this->GetStringWidth($texto),$this->lineheight);
  3675. $this->x = $tempx;
  3676. $this->x -= 1; //adjust alignment
  3677. }
  3678. $this->cssbegin=false;
  3679. $this->backupcss=array();
  3680. }
  3681. //Save x,y coords ???
  3682. $x = $this->x;
  3683. $y = $this->y;
  3684. //Set some default values
  3685. $this->divwidth = $this->pgwidth - $x + $this->lMargin;
  3686. //Print content
  3687. $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
  3688. $this->textbuffer=array();
  3689. //Reset values
  3690. $this->Reset();
  3691. }
  3692. $this->buffer_on=false;
  3693. }
  3694. if($tag=='P' or $tag=='DIV') //CSS in BLOCK mode
  3695. {
  3696. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  3697. if(!$this->tablestart)
  3698. {
  3699. if ($this->divwidth == 0) $this->divwidth = $this->pgwidth;
  3700. if ($tag=='P')
  3701. {
  3702. $this->pbegin=false;
  3703. $this->pjustfinished=true;
  3704. }
  3705. else $this->divbegin=false;
  3706. $content='';
  3707. foreach($this->textbuffer as $aux) $content .= $aux[0];
  3708. $numlines = $this->WordWrap($content,$this->divwidth);
  3709. if ($this->divheight == 0) $this->divheight = $numlines * 5;
  3710. //Print content
  3711. $this->printbuffer($this->textbuffer);
  3712. $this->textbuffer=array();
  3713. if ($tag=='P') $this->Ln($this->lineheight);
  3714. }//end of 'if (!this->tablestart)'
  3715. //Reset values
  3716. $this->Reset();
  3717. $this->cssbegin=false;
  3718. $this->backupcss=array();
  3719. }
  3720. if($tag=='TABLE') { // TABLE-END
  3721. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  3722. $this->table['cells'] = $this->cell;
  3723. $this->table['wc'] = array_pad(array(),$this->table['nc'],array('miw'=>0,'maw'=>0));
  3724. $this->table['hr'] = array_pad(array(),$this->table['nr'],0);
  3725. $this->_tableColumnWidth($this->table);
  3726. $this->_tableWidth($this->table);
  3727. $this->_tableHeight($this->table);
  3728. //Output table on PDF
  3729. // debug($this->table);
  3730. $this->_tableWrite($this->table);
  3731. //Reset values
  3732. $this->tablestart=false; //bool
  3733. $this->table=array(); //array
  3734. $this->cell=array(); //array
  3735. $this->col=-1; //int
  3736. $this->row=-1; //int
  3737. $this->Reset();
  3738. $this->Ln(0.5*$this->lineheight);
  3739. }
  3740. if(($tag=='UL') or ($tag=='OL')) {
  3741. if ($this->buffer_on == false) $this->listnum--;//Adjust minor BUG (this happens when there are two </OL> together)
  3742. if ($this->listlvl == 1) // We are closing the last OL/UL tag
  3743. {
  3744. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  3745. $this->buffer_on = false;
  3746. if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
  3747. $this->textbuffer = array();
  3748. $this->listlvl--;
  3749. $this->printlistbuffer();
  3750. }
  3751. else // returning one level
  3752. {
  3753. if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
  3754. $this->textbuffer = array();
  3755. $occur = $this->listoccur[$this->listlvl];
  3756. $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
  3757. $this->listlvl--;
  3758. $occur = $this->listoccur[$this->listlvl];
  3759. $this->listnum = $this->listlist[$this->listlvl][$occur]['MAXNUM']; // recover previous level's number
  3760. $this->listtype = $this->listlist[$this->listlvl][$occur]['TYPE']; // recover previous level's type
  3761. $this->buffer_on = false;
  3762. }
  3763. }
  3764. if($tag=='H1' or $tag=='H2' or $tag=='H3' or $tag=='H4' or $tag=='H5' or $tag=='H6')
  3765. {
  3766. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  3767. if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
  3768. {
  3769. //These 2 codelines are useless?
  3770. $texto='';
  3771. foreach($this->textbuffer as $vetor) $texto.=$vetor[0];
  3772. //Save x,y coords ???
  3773. $x = $this->x;
  3774. $y = $this->y;
  3775. //Set some default values
  3776. $this->divwidth = $this->pgwidth;
  3777. //Print content
  3778. $this->printbuffer($this->textbuffer);
  3779. $this->textbuffer=array();
  3780. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  3781. //Reset values
  3782. $this->Reset();
  3783. }
  3784. $this->buffer_on=false;
  3785. $this->lineheight = 5;
  3786. $this->Ln($this->lineheight);
  3787. $this->SetFontSize(11);
  3788. $this->SetStyle('B',false);
  3789. }
  3790. if($tag=='TITLE') {$this->titulo=false; $this->blockjustfinished = true;}
  3791. if($tag=='FORM') $this->Ln($this->lineheight);
  3792. if($tag=='PRE')
  3793. {
  3794. if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
  3795. {
  3796. if ($this->divwidth == 0) $this->divwidth = $this->pgwidth;
  3797. $content='';
  3798. foreach($this->textbuffer as $aux) $content .= $aux[0];
  3799. $numlines = $this->WordWrap($content,$this->divwidth);
  3800. if ($this->divheight == 0) $this->divheight = $numlines * 5;
  3801. //Print content
  3802. $this->textbuffer[0][0] = ltrim($this->textbuffer[0][0]); //Remove exceeding left-side space
  3803. $this->printbuffer($this->textbuffer);
  3804. $this->textbuffer=array();
  3805. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  3806. //Reset values
  3807. $this->Reset();
  3808. $this->Ln(1.1*$this->lineheight);
  3809. }
  3810. if($this->tablestart)
  3811. {
  3812. $this->cell[$this->row][$this->col]['textbuffer'][] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
  3813. $this->cell[$this->row][$this->col]['text'][] = "\n";
  3814. }
  3815. if($this->divbegin or $this->pbegin or $this->buffer_on) $this->textbuffer[] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
  3816. $this->cssbegin=false;
  3817. $this->backupcss=array();
  3818. $this->buffer_on = false;
  3819. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  3820. $this->pjustfinished = true; //behaves the same way
  3821. }
  3822. if($tag=='CODE' or $tag=='PRE' or $tag=='TT' or $tag=='KBD' or $tag=='SAMP')
  3823. {
  3824. $this->currentfont='';
  3825. $this->SetFont('arial');
  3826. }
  3827. if($tag=='B' or $tag=='I' or $tag=='U')
  3828. {
  3829. $this->SetStyle($tag,false);
  3830. if ($this->cssbegin and !$this->divbegin and !$this->pbegin and !$this->buffer_on)
  3831. {
  3832. //Reset values
  3833. $this->Reset();
  3834. $this->cssbegin=false;
  3835. $this->backupcss=array();
  3836. }
  3837. }
  3838. if($tag=='TEXTAREA')
  3839. {
  3840. if (!$this->tablestart) //not inside a table
  3841. {
  3842. //Draw arrows too?
  3843. $texto = '';
  3844. foreach($this->textbuffer as $v) $texto .= $v[0];
  3845. $this->SetFillColor(235,235,235);
  3846. $this->SetFont('courier');
  3847. $this->x +=3;
  3848. $linesneeded = $this->WordWrap($texto,($this->col*2.2)+3);
  3849. if ( $linesneeded > $this->row ) //Too many words inside textarea
  3850. {
  3851. $textoaux = explode("\n",$texto);
  3852. $texto = '';
  3853. for($i=0;$i < $this->row;$i++)
  3854. {
  3855. if ($i == $this->row-1) $texto .= $textoaux[$i];
  3856. else $texto .= $textoaux[$i] . "\n";
  3857. }
  3858. //Inform the user that some text has been truncated
  3859. $texto{strlen($texto)-1} = ".";
  3860. $texto{strlen($texto)-2} = ".";
  3861. $texto{strlen($texto)-3} = ".";
  3862. }
  3863. $backup_y = $this->y;
  3864. $this->Rect($this->x,$this->y,(2.2*$this->col)+6,5*$this->row,'DF');
  3865. if ($texto != '') $this->MultiCell((2.2*$this->col)+6,$this->lineheight,$texto);
  3866. $this->y = $backup_y + $this->row*$this->lineheight;
  3867. $this->SetFont('arial');
  3868. }
  3869. else //inside a table
  3870. {
  3871. $this->cell[$this->row][$this->col]['textbuffer'][] = $this->textbuffer[0];
  3872. $this->cell[$this->row][$this->col]['text'][] = $this->textbuffer[0];
  3873. $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later
  3874. $this->specialcontent = '';
  3875. }
  3876. $this->SetFillColor(255);
  3877. $this->textbuffer=array();
  3878. $this->buffer_on = false;
  3879. }
  3880. if($tag=='SELECT')
  3881. {
  3882. $texto = '';
  3883. $tamanho = 0;
  3884. if (isset($this->selectoption['MAXWIDTH'])) $tamanho = $this->selectoption['MAXWIDTH'];
  3885. if ($this->tablestart)
  3886. {
  3887. $texto = "���".$this->specialcontent."���".$this->selectoption['SELECTED'];
  3888. $aux = explode("���",$texto);
  3889. $texto = $aux[2];
  3890. $texto = "���".$aux[1].",width=$tamanho,height=".($this->lineheight + 2)."���".$texto;
  3891. $this->cell[$this->row][$this->col]['s'] += $tamanho + 7; // margin + arrow box
  3892. $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later
  3893. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2;
  3894. $this->cell[$this->row][$this->col]['textbuffer'][] = array($texto);
  3895. $this->cell[$this->row][$this->col]['text'][] = '';
  3896. }
  3897. else //not inside a table
  3898. {
  3899. $texto = $this->selectoption['SELECTED'];
  3900. $this->SetFillColor(235,235,235);
  3901. $this->x += 2;
  3902. $this->Rect($this->x,$this->y,$tamanho+2,5,'DF');//+2 margin
  3903. $this->x += 1;
  3904. if ($texto != '') $this->Write(5,$texto,$this->x);
  3905. $this->x += $tamanho - $this->GetStringWidth($texto) + 2;
  3906. $this->SetFillColor(190,190,190);
  3907. $this->Rect($this->x-1,$this->y,5,5,'DF'); //Arrow Box
  3908. $this->SetFont('zapfdingbats');
  3909. $this->Write(5,chr(116),$this->x); //Down arrow
  3910. $this->SetFont('arial');
  3911. $this->SetFillColor(255);
  3912. $this->x += 1;
  3913. }
  3914. $this->selectoption = array();
  3915. $this->specialcontent = '';
  3916. $this->textbuffer = array();
  3917. }
  3918. if($tag=='SUB' or $tag=='SUP') //subscript or superscript
  3919. {
  3920. if(!$this->pbegin and !$this->divbegin and !$this->tablestart and !$this->buffer_on and !$this->strike)
  3921. {
  3922. //Deactivate $this->SUB/SUP for its info is already stored inside $this->textbuffer
  3923. $this->SUB=false;
  3924. $this->SUP=false;
  3925. //Save x,y coords ???
  3926. $x = $this->x;
  3927. $y = $this->y;
  3928. //Set some default values
  3929. $this->divwidth = $this->pgwidth - $x + $this->lMargin;
  3930. //Print content
  3931. $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
  3932. $this->textbuffer=array();
  3933. //Reset values
  3934. $this->Reset();
  3935. }
  3936. $this->SUB=false;
  3937. $this->SUP=false;
  3938. }
  3939. if($tag=='S' or $tag=='STRIKE' or $tag=='DEL')
  3940. {
  3941. if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
  3942. {
  3943. //Deactivate $this->strike for its info is already stored inside $this->textbuffer
  3944. $this->strike=false;
  3945. //Save x,y coords ???
  3946. $x = $this->x;
  3947. $y = $this->y;
  3948. //Set some default values
  3949. $this->divwidth = $this->pgwidth - $x + $this->lMargin;
  3950. //Print content
  3951. $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
  3952. $this->textbuffer=array();
  3953. //Reset values
  3954. $this->Reset();
  3955. }
  3956. $this->strike=false;
  3957. }
  3958. if($tag=='ADDRESS' or $tag=='CENTER') // <ADDRESS> or <CENTER> tag
  3959. {
  3960. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  3961. if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
  3962. {
  3963. //Save x,y coords ???
  3964. $x = $this->x;
  3965. $y = $this->y;
  3966. //Set some default values
  3967. $this->divwidth = $this->pgwidth - $x + $this->lMargin;
  3968. //Print content
  3969. $this->printbuffer($this->textbuffer);
  3970. $this->textbuffer=array();
  3971. //Reset values
  3972. $this->Reset();
  3973. }
  3974. $this->buffer_on=false;
  3975. if ($tag == 'ADDRESS') $this->SetStyle('I',false);
  3976. }
  3977. if($tag=='BIG')
  3978. {
  3979. $newsize = $this->FontSizePt - 1;
  3980. $this->SetFontSize($newsize);
  3981. $this->SetStyle('B',false);
  3982. }
  3983. if($tag=='SMALL')
  3984. {
  3985. $newsize = $this->FontSizePt + 1;
  3986. $this->SetFontSize($newsize);
  3987. }
  3988. if($tag=='FONT')
  3989. {
  3990. if ($this->issetcolor == true)
  3991. {
  3992. $this->colorarray = array();
  3993. $this->SetTextColor(0);
  3994. $this->issetcolor = false;
  3995. }
  3996. if ($this->issetfont)
  3997. {
  3998. $this->SetFont('arial');
  3999. $this->issetfont=false;
  4000. }
  4001. if ($this->cssbegin)
  4002. {
  4003. //Get some attributes back!
  4004. $this->setCSS($this->backupcss);
  4005. }
  4006. }
  4007. }
  4008. function printlistbuffer()
  4009. {
  4010. //! @return void
  4011. //! @desc Prints all list-related buffered info
  4012. //Save x coordinate
  4013. $x = $this->oldx;
  4014. foreach($this->listitem as $item)
  4015. {
  4016. //Set default width & height values
  4017. $this->divwidth = $this->pgwidth;
  4018. $this->divheight = $this->lineheight;
  4019. //Get list's buffered data
  4020. $lvl = $item[0];
  4021. $num = $item[1];
  4022. $this->textbuffer = $item[2];
  4023. $occur = $item[3];
  4024. $type = $this->listlist[$lvl][$occur]['TYPE'];
  4025. $maxnum = $this->listlist[$lvl][$occur]['MAXNUM'];
  4026. switch($type) //Format type
  4027. {
  4028. case 'A':
  4029. $num = dec2alpha($num,true);
  4030. $maxnum = dec2alpha($maxnum,true);
  4031. $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
  4032. break;
  4033. case 'a':
  4034. $num = dec2alpha($num,false);
  4035. $maxnum = dec2alpha($maxnum,false);
  4036. $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
  4037. break;
  4038. case 'I':
  4039. $num = dec2roman($num,true);
  4040. $maxnum = dec2roman($maxnum,true);
  4041. $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
  4042. break;
  4043. case 'i':
  4044. $num = dec2roman($num,false);
  4045. $maxnum = dec2roman($maxnum,false);
  4046. $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
  4047. break;
  4048. case '1':
  4049. $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
  4050. break;
  4051. case 'disc':
  4052. $type = chr(149);
  4053. break;
  4054. case 'square':
  4055. $type = chr(110); //black square on Zapfdingbats font
  4056. break;
  4057. case 'circle':
  4058. $type = chr(186);
  4059. break;
  4060. default: break;
  4061. }
  4062. $this->x = (5*$lvl) + $x; //Indent list
  4063. //Get bullet width including margins
  4064. $oldsize = $this->FontSize * $this->k;
  4065. if ($type == chr(110)) $this->SetFont('zapfdingbats','',5);
  4066. $type .= ' ';
  4067. $blt_width = $this->GetStringWidth($type)+$this->cMargin*2;
  4068. //Output bullet
  4069. $this->Cell($blt_width,5,$type,'','','L');
  4070. $this->SetFont('arial','',$oldsize);
  4071. $this->divwidth = $this->divwidth + $this->lMargin - $this->x;
  4072. //Print content
  4073. $this->printbuffer($this->textbuffer);
  4074. $this->textbuffer=array();
  4075. }
  4076. //Reset all used values
  4077. $this->listoccur = array();
  4078. $this->listitem = array();
  4079. $this->listlist = array();
  4080. $this->listlvl = 0;
  4081. $this->listnum = 0;
  4082. $this->listtype = '';
  4083. $this->textbuffer = array();
  4084. $this->divwidth = 0;
  4085. $this->divheight = 0;
  4086. $this->oldx = -1;
  4087. //At last, but not least, skip a line
  4088. $this->Ln($this->lineheight);
  4089. }
  4090. function printbuffer($arrayaux,$outofblock=false,$is_table=false)
  4091. {
  4092. //! @return headache
  4093. //! @desc Prepares buffered text to be printed with FlowingBlock()
  4094. //Save some previous parameters
  4095. $save = array();
  4096. $save['strike'] = $this->strike;
  4097. $save['SUP'] = $this->SUP;
  4098. $save['SUB'] = $this->SUB;
  4099. $save['DOTTED'] = $this->dotted_on;
  4100. $save['DASHED'] = $this->dash_on;
  4101. $this->SetDash(); //restore to no dash
  4102. $this->dash_on = false;
  4103. $this->dotted_on = false;
  4104. $bak_y = $this->y;
  4105. $bak_x = $this->x;
  4106. $align = $this->divalign;
  4107. $oldpage = $this->page;
  4108. //Overall object size == $old_height
  4109. //Line height == $this->divheight
  4110. $old_height = $this->divheight;
  4111. if ($is_table)
  4112. {
  4113. $this->divheight = 1.1*$this->lineheight;
  4114. $fill = 0;
  4115. }
  4116. else
  4117. {
  4118. $this->divheight = $this->lineheight;
  4119. if ($this->FillColor == '1.000 g') $fill = 0; //avoid useless background painting (1.000 g == white background color)
  4120. else $fill = 1;
  4121. }
  4122. $this->newFlowingBlock( $this->divwidth,$this->divheight,$this->divborder,$align,$fill,$is_table);
  4123. $array_size = count($arrayaux);
  4124. for($i=0;$i < $array_size; $i++)
  4125. {
  4126. $vetor = $arrayaux[$i];
  4127. if ($i == 0 and $vetor[0] != "\n") $vetor[0] = ltrim($vetor[0]);
  4128. if (empty($vetor[0]) and empty($vetor[7])) continue; //Ignore empty text and not carrying an internal link
  4129. //Activating buffer properties
  4130. if(isset($vetor[10]) and !empty($vetor[10])) //Background color
  4131. {
  4132. $cor = $vetor[10];
  4133. $this->SetFillColor($cor['R'],$cor['G'],$cor['B']);
  4134. $this->divbgcolor = true;
  4135. }
  4136. if(isset($vetor[9]) and !empty($vetor[9])) // Outline parameters
  4137. {
  4138. $cor = $vetor[9]['COLOR'];
  4139. $outlinewidth = $vetor[9]['WIDTH'];
  4140. $this->SetTextOutline($outlinewidth,$cor['R'],$cor['G'],$cor['B']);
  4141. $this->outline_on = true;
  4142. }
  4143. if(isset($vetor[8]) and $vetor[8] === true) // strike-through the text
  4144. {
  4145. $this->strike = true;
  4146. }
  4147. if(isset($vetor[7]) and $vetor[7] != '') // internal link: <a name="anyvalue">
  4148. {
  4149. $this->internallink[$vetor[7]] = array("Y"=>$this->y,"PAGE"=>$this->page );
  4150. $this->Bookmark($vetor[7]." (pg. $this->page)",0,$this->y);
  4151. if (empty($vetor[0])) continue; //Ignore empty text
  4152. }
  4153. if(isset($vetor[6]) and $vetor[6] === true) // Subscript
  4154. {
  4155. $this->SUB = true;
  4156. $this->SetFontSize(6);
  4157. }
  4158. if(isset($vetor[5]) and $vetor[5] === true) // Superscript
  4159. {
  4160. $this->SUP = true;
  4161. $this->SetFontSize(6);
  4162. }
  4163. if(isset($vetor[4]) and $vetor[4] != '') $this->SetFont($vetor[4]); // Font Family
  4164. if (!empty($vetor[3])) //Font Color
  4165. {
  4166. $cor = $vetor[3];
  4167. $this->SetTextColor($cor['R'],$cor['G'],$cor['B']);
  4168. }
  4169. if(isset($vetor[2]) and $vetor[2] != '') //Bold,Italic,Underline styles
  4170. {
  4171. if (strpos($vetor[2],"B") !== false) $this->SetStyle('B',true);
  4172. if (strpos($vetor[2],"I") !== false) $this->SetStyle('I',true);
  4173. if (strpos($vetor[2],"U") !== false) $this->SetStyle('U',true);
  4174. }
  4175. if(isset($vetor[1]) and $vetor[1] != '') //LINK
  4176. {
  4177. if (strpos($vetor[1],".") === false) //assuming every external link has a dot indicating extension (e.g: .html .txt .zip www.somewhere.com etc.)
  4178. {
  4179. //Repeated reference to same anchor?
  4180. while(array_key_exists($vetor[1],$this->internallink)) $vetor[1]="#".$vetor[1];
  4181. $this->internallink[$vetor[1]] = $this->AddLink();
  4182. $vetor[1] = $this->internallink[$vetor[1]];
  4183. }
  4184. $this->HREF = $vetor[1];
  4185. $this->SetTextColor(0,0,255);
  4186. $this->SetStyle('U',true);
  4187. }
  4188. //Print-out special content
  4189. if (isset($vetor[0]) and $vetor[0]{0} == '�' and $vetor[0]{1} == '�' and $vetor[0]{2} == '�') //identifier has been identified!
  4190. {
  4191. $content = explode("���",$vetor[0]);
  4192. $texto = $content[2];
  4193. $content = explode(",",$content[1]);
  4194. foreach($content as $value)
  4195. {
  4196. $value = explode("=",$value);
  4197. $specialcontent[$value[0]] = $value[1];
  4198. }
  4199. if ($this->flowingBlockAttr[ 'contentWidth' ] > 0) // Print out previously accumulated content
  4200. {
  4201. $width_used = $this->flowingBlockAttr[ 'contentWidth' ] / $this->k;
  4202. //Restart Flowing Block
  4203. $this->finishFlowingBlock($outofblock);
  4204. $this->x = $bak_x + ($width_used % $this->divwidth) + 0.5;// 0.5 == margin
  4205. $this->y -= ($this->lineheight + 0.5);
  4206. $extrawidth = 0; //only to be used in case $specialcontent['width'] does not contain all used width (e.g. Select Box)
  4207. if ($specialcontent['type'] == 'select') $extrawidth = 7; //arrow box + margin
  4208. if(($this->x - $bak_x) + $specialcontent['width'] + $extrawidth > $this->divwidth )
  4209. {
  4210. $this->x = $bak_x;
  4211. $this->y += $this->lineheight - 1;
  4212. }
  4213. $this->newFlowingBlock( $this->divwidth,$this->divheight,$this->divborder,$align,$fill,$is_table );
  4214. }
  4215. switch(strtoupper($specialcontent['type']))
  4216. {
  4217. case 'IMAGE':
  4218. //xpos and ypos used in order to support: <div align='center'><img ...></div>
  4219. $xpos = 0;
  4220. $ypos = 0;
  4221. if (isset($specialcontent['ypos']) and $specialcontent['ypos'] != '') $ypos = (float)$specialcontent['ypos'];
  4222. if (isset($specialcontent['xpos']) and $specialcontent['xpos'] != '') $xpos = (float)$specialcontent['xpos'];
  4223. $width_used = (($this->x - $bak_x) + $specialcontent['width'])*$this->k; //in order to adjust x coordinate later
  4224. //Is this the best way of fixing x,y coordinates?
  4225. $fix_x = ($this->x+2) * $this->k + ($xpos*$this->k); //+2 margin
  4226. $fix_y = ($this->h - (($this->y+2) + $specialcontent['height'])) * $this->k;//+2 margin
  4227. $imgtemp = explode(" ",$texto);
  4228. $imgtemp[5]=$fix_x; // x
  4229. $imgtemp[6]=$fix_y; // y
  4230. $texto = implode(" ",$imgtemp);
  4231. $this->_out($texto);
  4232. //Readjust x coordinate in order to allow text to be placed after this form element
  4233. $this->x = $bak_x;
  4234. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  4235. $spacenum = (integer)ceil(($width_used / $spacesize));
  4236. //Consider the space used so far in this line as a bunch of spaces
  4237. if ($ypos != 0) $this->Ln($ypos);
  4238. else $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
  4239. break;
  4240. case 'INPUT':
  4241. switch($specialcontent['subtype'])
  4242. {
  4243. case 'PASSWORD':
  4244. case 'TEXT': //Draw TextField
  4245. $width_used = (($this->x - $bak_x) + $specialcontent['width'])*$this->k; //in order to adjust x coordinate later
  4246. $this->SetFillColor(235,235,235);
  4247. $this->x += 1;
  4248. $this->y += 1;
  4249. $this->Rect($this->x,$this->y,$specialcontent['width'],4.5,'DF');// 4.5 in order to avoid overlapping
  4250. if ($texto != '')
  4251. {
  4252. $this->x += 1;
  4253. $this->Write(5,$texto,$this->x);
  4254. $this->x -= $this->GetStringWidth($texto);
  4255. }
  4256. $this->SetFillColor(255);
  4257. $this->y -= 1;
  4258. //Readjust x coordinate in order to allow text to be placed after this form element
  4259. $this->x = $bak_x;
  4260. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  4261. $spacenum = (integer)ceil(($width_used / $spacesize));
  4262. //Consider the space used so far in this line as a bunch of spaces
  4263. $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
  4264. break;
  4265. case 'CHECKBOX': //Draw Checkbox
  4266. $width_used = (($this->x - $bak_x) + $specialcontent['width'])*$this->k; //in order to adjust x coordinate later
  4267. $checked = $texto;
  4268. $this->SetFillColor(235,235,235);
  4269. $this->y += 1;
  4270. $this->x += 1;
  4271. $this->Rect($this->x,$this->y,3,3,'DF');
  4272. if ($checked)
  4273. {
  4274. $this->Line($this->x,$this->y,$this->x+3,$this->y+3);
  4275. $this->Line($this->x,$this->y+3,$this->x+3,$this->y);
  4276. }
  4277. $this->SetFillColor(255);
  4278. $this->y -= 1;
  4279. //Readjust x coordinate in order to allow text to be placed after this form element
  4280. $this->x = $bak_x;
  4281. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  4282. $spacenum = (integer)ceil(($width_used / $spacesize));
  4283. //Consider the space used so far in this line as a bunch of spaces
  4284. $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
  4285. break;
  4286. case 'RADIO': //Draw Radio button
  4287. $width_used = (($this->x - $bak_x) + $specialcontent['width']+0.5)*$this->k; //in order to adjust x coordinate later
  4288. $checked = $texto;
  4289. $this->x += 2;
  4290. $this->y += 1.5;
  4291. $this->Circle($this->x,$this->y+1.2,1,'D');
  4292. $this->_out('0.000 g');
  4293. if ($checked) $this->Circle($this->x,$this->y+1.2,0.4,'DF');
  4294. $this->y -= 1.5;
  4295. //Readjust x coordinate in order to allow text to be placed after this form element
  4296. $this->x = $bak_x;
  4297. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  4298. $spacenum = (integer)ceil(($width_used / $spacesize));
  4299. //Consider the space used so far in this line as a bunch of spaces
  4300. $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
  4301. break;
  4302. case 'BUTTON': // Draw a button
  4303. case 'SUBMIT':
  4304. case 'RESET':
  4305. $nihil = ($specialcontent['width']-$this->GetStringWidth($texto))/2;
  4306. $this->x += 1.5;
  4307. $this->y += 1;
  4308. $this->SetFillColor(190,190,190);
  4309. $this->Rect($this->x,$this->y,$specialcontent['width'],4.5,'DF'); // 4.5 in order to avoid overlapping
  4310. $this->x += $nihil;
  4311. $this->Write(5,$texto,$this->x);
  4312. $this->x += $nihil;
  4313. $this->SetFillColor(255);
  4314. $this->y -= 1;
  4315. break;
  4316. default: break;
  4317. }
  4318. break;
  4319. case 'SELECT':
  4320. $width_used = (($this->x - $bak_x) + $specialcontent['width'] + 8)*$this->k; //in order to adjust x coordinate later
  4321. $this->SetFillColor(235,235,235); //light gray
  4322. $this->x += 1.5;
  4323. $this->y += 1;
  4324. $this->Rect($this->x,$this->y,$specialcontent['width']+2,$this->lineheight,'DF'); // +2 == margin
  4325. $this->x += 1;
  4326. if ($texto != '') $this->Write($this->lineheight,$texto,$this->x); //the combobox content
  4327. $this->x += $specialcontent['width'] - $this->GetStringWidth($texto) + 2;
  4328. $this->SetFillColor(190,190,190); //dark gray
  4329. $this->Rect($this->x-1,$this->y,5,5,'DF'); //Arrow Box
  4330. $this->SetFont('zapfdingbats');
  4331. $this->Write($this->lineheight,chr(116),$this->x); //Down arrow
  4332. $this->SetFont('arial');
  4333. $this->SetFillColor(255);
  4334. //Readjust x coordinate in order to allow text to be placed after this form element
  4335. $this->x = $bak_x;
  4336. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  4337. $spacenum = (integer)ceil(($width_used / $spacesize));
  4338. //Consider the space used so far in this line as a bunch of spaces
  4339. $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
  4340. break;
  4341. case 'TEXTAREA':
  4342. //Setup TextArea properties
  4343. $this->SetFillColor(235,235,235);
  4344. $this->SetFont('courier');
  4345. $this->currentfont='courier';
  4346. $ta_lines = $specialcontent['lines'];
  4347. $ta_height = 1.1*$this->lineheight*$ta_lines;
  4348. $ta_width = $specialcontent['width'];
  4349. //Adjust x,y coordinates
  4350. $this->x += 1.5;
  4351. $this->y += 1.5;
  4352. $linesneeded = $this->WordWrap($texto,$ta_width);
  4353. if ( $linesneeded > $ta_lines ) //Too many words inside textarea
  4354. {
  4355. $textoaux = explode("\n",$texto);
  4356. $texto = '';
  4357. for($i=0;$i<$ta_lines;$i++)
  4358. {
  4359. if ($i == $ta_lines-1) $texto .= $textoaux[$i];
  4360. else $texto .= $textoaux[$i] . "\n";
  4361. }
  4362. //Inform the user that some text has been truncated
  4363. $texto{strlen($texto)-1} = ".";
  4364. $texto{strlen($texto)-2} = ".";
  4365. $texto{strlen($texto)-3} = ".";
  4366. }
  4367. $backup_y = $this->y;
  4368. $backup_x = $this->x;
  4369. $this->Rect($this->x,$this->y,$ta_width+3,$ta_height,'DF');
  4370. if ($texto != '') $this->MultiCell($ta_width+3,$this->lineheight,$texto);
  4371. $this->y = $backup_y - 1.5;
  4372. $this->x = $backup_x + $ta_width + 2.5;
  4373. $this->SetFillColor(255);
  4374. $this->SetFont('arial');
  4375. $this->currentfont='';
  4376. break;
  4377. default: break;
  4378. }
  4379. }
  4380. else //THE text
  4381. {
  4382. if ($vetor[0] == "\n") //We are reading a <BR> now turned into newline ("\n")
  4383. {
  4384. //Restart Flowing Block
  4385. $this->finishFlowingBlock($outofblock);
  4386. if($outofblock) $this->Ln($this->lineheight);
  4387. $this->x = $bak_x;
  4388. $this->newFlowingBlock( $this->divwidth,$this->divheight,$this->divborder,$align,$fill,$is_table );
  4389. }
  4390. else {
  4391. $this->WriteFlowingBlock( $vetor[0] , $outofblock );
  4392. }
  4393. }
  4394. //Check if it is the last element. If so then finish printing the block
  4395. if ($i == ($array_size-1)) $this->finishFlowingBlock($outofblock);
  4396. //Now we must deactivate what we have used
  4397. if( (isset($vetor[1]) and $vetor[1] != '') or $this->HREF != '')
  4398. {
  4399. $this->SetTextColor(0);
  4400. $this->SetStyle('U',false);
  4401. $this->HREF = '';
  4402. }
  4403. if(isset($vetor[2]) and $vetor[2] != '')
  4404. {
  4405. $this->SetStyle('B',false);
  4406. $this->SetStyle('I',false);
  4407. $this->SetStyle('U',false);
  4408. }
  4409. if(isset($vetor[3]) and $vetor[3] != '')
  4410. {
  4411. unset($cor);
  4412. $this->SetTextColor(0);
  4413. }
  4414. if(isset($vetor[4]) and $vetor[4] != '') $this->SetFont('arial');
  4415. if(isset($vetor[5]) and $vetor[5] === true)
  4416. {
  4417. $this->SUP = false;
  4418. $this->SetFontSize(11);
  4419. }
  4420. if(isset($vetor[6]) and $vetor[6] === true)
  4421. {
  4422. $this->SUB = false;
  4423. $this->SetFontSize(11);
  4424. }
  4425. //vetor7-internal links
  4426. if(isset($vetor[8]) and $vetor[8] === true) // strike-through the text
  4427. {
  4428. $this->strike = false;
  4429. }
  4430. if(isset($vetor[9]) and !empty($vetor[9])) // Outline parameters
  4431. {
  4432. $this->SetTextOutline(false);
  4433. $this->outline_on = false;
  4434. }
  4435. if(isset($vetor[10]) and !empty($vetor[10])) //Background color
  4436. {
  4437. $this->SetFillColor(255);
  4438. $this->divbgcolor = false;
  4439. }
  4440. }//end of for(i=0;i<arraysize;i++)
  4441. //Restore some previously set parameters
  4442. $this->strike = $save['strike'];
  4443. $this->SUP = $save['SUP'];
  4444. $this->SUB = $save['SUB'];
  4445. $this->dotted_on = $save['DOTTED'];
  4446. $this->dash_on = $save['DASHED'];
  4447. if ($this->dash_on) $this->SetDash(2,2);
  4448. //Check whether we have borders to paint or not
  4449. //(only works 100% if whole content spans only 1 page)
  4450. if ($this->cssbegin and ($this->divborder or $this->dash_on or $this->dotted_on or $this->divbgcolor))
  4451. {
  4452. if ($oldpage != $this->page)
  4453. {
  4454. //Only border on last page is painted (known bug)
  4455. $x = $this->lMargin;
  4456. $y = $this->tMargin;
  4457. $old_height = $this->y - $y;
  4458. }
  4459. else
  4460. {
  4461. if ($this->oldx < 0) $x = $this->x;
  4462. else $x = $this->oldx;
  4463. if ($this->oldy < 0) $y = $this->y - $old_height;
  4464. else $y = $this->oldy;
  4465. }
  4466. if ($this->divborder) $this->Rect($x,$y,$this->divwidth,$old_height);
  4467. if ($this->dash_on) $this->Rect($x,$y,$this->divwidth,$old_height);
  4468. if ($this->dotted_on) $this->DottedRect($x,$y,$this->divwidth,$old_height);
  4469. $this->x = $bak_x;
  4470. }
  4471. }
  4472. function Reset()
  4473. {
  4474. //! @return void
  4475. //! @desc Resets several class attributes
  4476. // if ( $this->issetcolor !== true )
  4477. // {
  4478. $this->SetTextColor(0);
  4479. $this->SetDrawColor(0);
  4480. $this->SetFillColor(255);
  4481. $this->colorarray = array();
  4482. $this->bgcolorarray = array();
  4483. $this->issetcolor = false;
  4484. // }
  4485. $this->HREF = '';
  4486. $this->SetTextOutline(false);
  4487. //$this->strike = false;
  4488. $this->SetFontSize(11);
  4489. $this->SetStyle('B',false);
  4490. $this->SetStyle('I',false);
  4491. $this->SetStyle('U',false);
  4492. $this->SetFont('arial');
  4493. $this->divwidth = 0;
  4494. $this->divheight = 0;
  4495. $this->divalign = "L";
  4496. $this->divrevert = false;
  4497. $this->divborder = 0;
  4498. $this->divbgcolor = false;
  4499. $this->toupper = false;
  4500. $this->tolower = false;
  4501. $this->SetDash(); //restore to no dash
  4502. $this->dash_on = false;
  4503. $this->dotted_on = false;
  4504. $this->oldx = -1;
  4505. $this->oldy = -1;
  4506. }
  4507. function ReadMetaTags($html)
  4508. {
  4509. //! @return void
  4510. //! @desc Pass meta tag info to PDF file properties
  4511. $regexp = '/ (\\w+?)=([^\\s>"]+)/si'; // changes anykey=anyvalue to anykey="anyvalue" (only do this when this happens inside tags)
  4512. $html = preg_replace($regexp," \$1=\"\$2\"",$html);
  4513. $regexp = '/<meta .*?(name|content)="(.*?)" .*?(name|content)="(.*?)".*?>/si';
  4514. preg_match_all($regexp,$html,$aux);
  4515. $firstattr = $aux[1];
  4516. $secondattr = $aux[3];
  4517. for( $i = 0 ; $i < count($aux[0]) ; $i++)
  4518. {
  4519. $name = ( strtoupper($firstattr[$i]) == "NAME" )? strtoupper($aux[2][$i]) : strtoupper($aux[4][$i]);
  4520. $content = ( strtoupper($firstattr[$i]) == "CONTENT" )? $aux[2][$i] : $aux[4][$i];
  4521. switch($name)
  4522. {
  4523. case "KEYWORDS": $this->SetKeywords($content); break;
  4524. case "AUTHOR": $this->SetAuthor($content); break;
  4525. case "DESCRIPTION": $this->SetSubject($content); break;
  4526. }
  4527. }
  4528. //Comercial do Aplicativo usado (no caso um script):
  4529. $this->SetCreator("HTML2FPDF >> http://html2fpdf.sf.net");
  4530. }
  4531. //////////////////
  4532. /// CSS parser ///
  4533. //////////////////
  4534. function ReadCSS($html)
  4535. {
  4536. //! @desc CSS parser
  4537. //! @return string
  4538. /*
  4539. * This version ONLY supports: .class {...} / #id { .... }
  4540. * It does NOT support: body{...} / a#hover { ... } / p.right { ... } / other mixed names
  4541. * This function must read the CSS code (internal or external) and order its value inside $this->CSS.
  4542. */
  4543. $match = 0; // no match for instance
  4544. $regexp = ''; // This helps debugging: showing what is the REAL string being processed
  4545. //CSS inside external files
  4546. $regexp = '/<link rel="stylesheet".*?href="(.+?)"\\s*?\/?>/si';
  4547. $match = preg_match_all($regexp,$html,$CSSext);
  4548. $ind = 0;
  4549. while($match){
  4550. //Fix path value
  4551. $path = $CSSext[1][$ind];
  4552. $path = str_replace("\\","/",$path); //If on Windows
  4553. //Get link info and obtain its absolute path
  4554. $regexp = '|^./|';
  4555. $path = preg_replace($regexp,'',$path);
  4556. if (strpos($path,"../") !== false ) //It is a Relative Link
  4557. {
  4558. $backtrackamount = substr_count($path,"../");
  4559. $maxbacktrack = substr_count($this->basepath,"/") - 1;
  4560. $filepath = str_replace("../",'',$path);
  4561. $path = $this->basepath;
  4562. //If it is an invalid relative link, then make it go to directory root
  4563. if ($backtrackamount > $maxbacktrack) $backtrackamount = $maxbacktrack;
  4564. //Backtrack some directories
  4565. for( $i = 0 ; $i < $backtrackamount + 1 ; $i++ ) $path = substr( $path, 0 , strrpos($path,"/") );
  4566. $path = $path . "/" . $filepath; //Make it an absolute path
  4567. }
  4568. elseif( strpos($path,":/") === false) //It is a Local Link
  4569. {
  4570. $path = $this->basepath . $path;
  4571. }
  4572. //Do nothing if it is an Absolute Link
  4573. //END of fix path value
  4574. $CSSextblock = file_get_contents($path);
  4575. //Get class/id name and its characteristics from $CSSblock[1]
  4576. $regexp = '/[.# ]([^.]+?)\\s*?\{(.+?)\}/s'; // '/s' PCRE_DOTALL including \n
  4577. preg_match_all( $regexp, $CSSextblock, $extstyle);
  4578. //Make CSS[Name-of-the-class] = array(key => value)
  4579. $regexp = '/\\s*?(\\S+?):(.+?);/si';
  4580. for($i=0; $i < count($extstyle[1]) ; $i++)
  4581. {
  4582. preg_match_all( $regexp, $extstyle[2][$i], $extstyleinfo);
  4583. $extproperties = $extstyleinfo[1];
  4584. $extvalues = $extstyleinfo[2];
  4585. for($j = 0; $j < count($extproperties) ; $j++)
  4586. {
  4587. //Array-properties and Array-values must have the SAME SIZE!
  4588. $extclassproperties[strtoupper($extproperties[$j])] = trim($extvalues[$j]);
  4589. }
  4590. $this->CSS[$extstyle[1][$i]] = $extclassproperties;
  4591. $extproperties = array();
  4592. $extvalues = array();
  4593. $extclassproperties = array();
  4594. }
  4595. $match--;
  4596. $ind++;
  4597. } //end of match
  4598. $match = 0; // reset value, if needed
  4599. //CSS internal
  4600. //Get content between tags and order it, using regexp
  4601. $regexp = '/<style.*?>(.*?)<\/style>/si'; // it can be <style> or <style type="txt/css">
  4602. $match = preg_match($regexp,$html,$CSSblock);
  4603. if ($match) {
  4604. //Get class/id name and its characteristics from $CSSblock[1]
  4605. $regexp = '/[.#]([^.]+?)\\s*?\{(.+?)\}/s'; // '/s' PCRE_DOTALL including \n
  4606. preg_match_all( $regexp, $CSSblock[1], $style);
  4607. //Make CSS[Name-of-the-class] = array(key => value)
  4608. $regexp = '/\\s*?(\\S+?):(.+?);/si';
  4609. for($i=0; $i < count($style[1]) ; $i++)
  4610. {
  4611. preg_match_all( $regexp, $style[2][$i], $styleinfo);
  4612. $properties = $styleinfo[1];
  4613. $values = $styleinfo[2];
  4614. for($j = 0; $j < count($properties) ; $j++)
  4615. {
  4616. //Array-properties and Array-values must have the SAME SIZE!
  4617. $classproperties[strtoupper($properties[$j])] = trim($values[$j]);
  4618. }
  4619. $this->CSS[$style[1][$i]] = $classproperties;
  4620. $properties = array();
  4621. $values = array();
  4622. $classproperties = array();
  4623. }
  4624. } // end of match
  4625. //Remove CSS (tags and content), if any
  4626. $regexp = '/<style.*?>(.*?)<\/style>/si'; // it can be <style> or <style type="txt/css">
  4627. $html = preg_replace($regexp,'',$html);
  4628. return $html;
  4629. }
  4630. function readInlineCSS($html)
  4631. {
  4632. //! @return array
  4633. //! @desc Reads inline CSS and returns an array of properties
  4634. //Fix incomplete CSS code
  4635. $size = strlen($html)-1;
  4636. if ($html{$size} != ';') $html .= ';';
  4637. //Make CSS[Name-of-the-class] = array(key => value)
  4638. $regexp = '|\\s*?(\\S+?):(.+?);|i';
  4639. preg_match_all( $regexp, $html, $styleinfo);
  4640. $properties = $styleinfo[1];
  4641. $values = $styleinfo[2];
  4642. //Array-properties and Array-values must have the SAME SIZE!
  4643. $classproperties = array();
  4644. for($i = 0; $i < count($properties) ; $i++) $classproperties[strtoupper($properties[$i])] = trim($values[$i]);
  4645. return $classproperties;
  4646. }
  4647. function setCSS($arrayaux)
  4648. {
  4649. //! @return void
  4650. //! @desc Change some class attributes according to CSS properties
  4651. if (!is_array($arrayaux)) return; //Removes PHP Warning
  4652. foreach($arrayaux as $k => $v)
  4653. {
  4654. switch($k){
  4655. case 'WIDTH':
  4656. $this->divwidth = ConvertSize($v,$this->pgwidth);
  4657. break;
  4658. case 'HEIGHT':
  4659. $this->divheight = ConvertSize($v,$this->pgwidth);
  4660. break;
  4661. case 'BORDER': // width style color (width not supported correctly - it is always considered as normal)
  4662. $prop = explode(' ',$v);
  4663. if ( count($prop) != 3 ) break; // Not supported: borders not fully declared
  4664. //style: dashed dotted none (anything else => solid )
  4665. if (strnatcasecmp($prop[1],"dashed") == 0) //found "dashed"! (ignores case)
  4666. {
  4667. $this->dash_on = true;
  4668. $this->SetDash(2,2); //2mm on, 2mm off
  4669. }
  4670. elseif (strnatcasecmp($prop[1],"dotted") == 0) //found "dotted"! (ignores case)
  4671. {
  4672. $this->dotted_on = true;
  4673. }
  4674. elseif (strnatcasecmp($prop[1],"none") == 0) $this->divborder = 0;
  4675. else $this->divborder = 1;
  4676. //color
  4677. $coul = ConvertColor($prop[2]);
  4678. $this->SetDrawColor($coul['R'],$coul['G'],$coul['B']);
  4679. $this->issetcolor=true;
  4680. break;
  4681. case 'FONT-FAMILY': // one of the $this->fontlist fonts
  4682. //If it is a font list, get all font types
  4683. $aux_fontlist = explode(",",$v);
  4684. $fontarraysize = count($aux_fontlist);
  4685. for($i=0;$i<$fontarraysize;$i++)
  4686. {
  4687. $fonttype = $aux_fontlist[$i];
  4688. $fonttype = trim($fonttype);
  4689. //If font is found, set it, and exit loop
  4690. if ( in_array(strtolower($fonttype), $this->fontlist) ) {$this->SetFont(strtolower($fonttype));break;}
  4691. //If font = "courier new" for example, try simply looking for "courier"
  4692. $fonttype = explode(" ",$fonttype);
  4693. $fonttype = $fonttype[0];
  4694. if ( in_array(strtolower($fonttype), $this->fontlist) ) {$this->SetFont(strtolower($fonttype));break;}
  4695. }
  4696. break;
  4697. case 'FONT-SIZE': //Does not support: smaller, larger
  4698. if(is_numeric($v{0}))
  4699. {
  4700. $mmsize = ConvertSize($v,$this->pgwidth);
  4701. $this->SetFontSize( $mmsize*(72/25.4) ); //Get size in points (pt)
  4702. }
  4703. else{
  4704. $v = strtoupper($v);
  4705. switch($v)
  4706. {
  4707. //Values obtained from http://www.w3schools.com/html/html_reference.asp
  4708. case 'XX-SMALL': $this->SetFontSize( (0.7)* 11);
  4709. break;
  4710. case 'X-SMALL': $this->SetFontSize( (0.77) * 11);
  4711. break;
  4712. case 'SMALL': $this->SetFontSize( (0.86)* 11);
  4713. break;
  4714. case 'MEDIUM': $this->SetFontSize(11);
  4715. break;
  4716. case 'LARGE': $this->SetFontSize( (1.2)*11);
  4717. break;
  4718. case 'X-LARGE': $this->SetFontSize( (1.5)*11);
  4719. break;
  4720. case 'XX-LARGE': $this->SetFontSize( 2*11);
  4721. break;
  4722. }
  4723. }
  4724. break;
  4725. case 'FONT-STYLE': // italic normal oblique
  4726. switch (strtoupper($v))
  4727. {
  4728. case 'ITALIC':
  4729. case 'OBLIQUE':
  4730. $this->SetStyle('I',true);
  4731. break;
  4732. case 'NORMAL': break;
  4733. }
  4734. break;
  4735. case 'FONT-WEIGHT': // normal bold //Does not support: bolder, lighter, 100..900(step value=100)
  4736. switch (strtoupper($v))
  4737. {
  4738. case 'BOLD':
  4739. $this->SetStyle('B',true);
  4740. break;
  4741. case 'NORMAL': break;
  4742. }
  4743. break;
  4744. case 'TEXT-DECORATION': // none underline //Does not support: overline, blink
  4745. switch (strtoupper($v))
  4746. {
  4747. case 'LINE-THROUGH':
  4748. $this->strike = true;
  4749. break;
  4750. case 'UNDERLINE':
  4751. $this->SetStyle('U',true);
  4752. break;
  4753. case 'NONE': break;
  4754. }
  4755. case 'TEXT-TRANSFORM': // none uppercase lowercase //Does not support: capitalize
  4756. switch (strtoupper($v)) //Not working 100%
  4757. {
  4758. case 'UPPERCASE':
  4759. $this->toupper=true;
  4760. break;
  4761. case 'LOWERCASE':
  4762. $this->tolower=true;
  4763. break;
  4764. case 'NONE': break;
  4765. }
  4766. case 'TEXT-ALIGN': //left right center justify
  4767. switch (strtoupper($v))
  4768. {
  4769. case 'LEFT':
  4770. $this->divalign="L";
  4771. break;
  4772. case 'CENTER':
  4773. $this->divalign="C";
  4774. break;
  4775. case 'RIGHT':
  4776. $this->divalign="R";
  4777. break;
  4778. case 'JUSTIFY':
  4779. $this->divalign="J";
  4780. break;
  4781. }
  4782. break;
  4783. case 'DIRECTION': //ltr(default) rtl
  4784. if (strtolower($v) == 'rtl') $this->divrevert = true;
  4785. break;
  4786. case 'BACKGROUND': // bgcolor only
  4787. $cor = ConvertColor($v);
  4788. $this->bgcolorarray = $cor;
  4789. $this->SetFillColor($cor['R'],$cor['G'],$cor['B']);
  4790. $this->divbgcolor = true;
  4791. break;
  4792. case 'COLOR': // font color
  4793. $cor = ConvertColor($v);
  4794. $this->colorarray = $cor;
  4795. $this->SetTextColor($cor['R'],$cor['G'],$cor['B']);
  4796. $this->issetcolor=true;
  4797. break;
  4798. }//end of switch($k)
  4799. }//end of foreach
  4800. }
  4801. function SetStyle($tag,$enable)
  4802. {
  4803. //! @return void
  4804. //! @desc Enables/Disables B,I,U styles
  4805. //Modify style and select corresponding font
  4806. $this->$tag+=($enable ? 1 : -1);
  4807. $style='';
  4808. //Fix some SetStyle misuse
  4809. if ($this->$tag < 0) $this->$tag = 0;
  4810. if ($this->$tag > 1) $this->$tag = 1;
  4811. foreach(array('B','I','U') as $s)
  4812. if($this->$s>0)
  4813. $style.=$s;
  4814. $this->currentstyle=$style;
  4815. $this->SetFont('',$style);
  4816. }
  4817. function DisableTags($str='')
  4818. {
  4819. //! @return void
  4820. //! @desc Disable some tags using ',' as separator. Enable all tags calling this function without parameters.
  4821. if ($str == '') //enable all tags
  4822. {
  4823. //Insert new supported tags in the long string below.
  4824. $this->enabledtags = "<tt><kbd><samp><option><outline><span><newpage><page_break><s><strike><del><bdo><big><small><address><ins><cite><font><center><sup><sub><input><select><option><textarea><title><form><ol><ul><li><h1><h2><h3><h4><h5><h6><pre><b><u><i><a><img><p><br><strong><em><code><th><tr><blockquote><hr><td><tr><table><div>";
  4825. }
  4826. else
  4827. {
  4828. $str = explode(",",$str);
  4829. foreach($str as $v) $this->enabledtags = str_replace(trim($v),'',$this->enabledtags);
  4830. }
  4831. }
  4832. ////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
  4833. //Thanks to vietcom (vncommando at yahoo dot com)
  4834. /* Modified by Renato Coelho
  4835. in order to print tables that span more than 1 page and to allow
  4836. bold,italic and the likes inside table cells (and alignment now works with styles!)
  4837. */
  4838. //table Array of (w, h, bc, nr, wc, hr, cells)
  4839. //w Width of table
  4840. //h Height of table
  4841. //nc Number column
  4842. //nr Number row
  4843. //hr List of height of each row
  4844. //wc List of width of each column
  4845. //cells List of cells of each rows, cells[i][j] is a cell in the table
  4846. function _tableColumnWidth(&$table){
  4847. //! @return void
  4848. $cs = &$table['cells'];
  4849. $mw = $this->getStringWidth('W');
  4850. $nc = $table['nc'];
  4851. $nr = $table['nr'];
  4852. $listspan = array();
  4853. //Xac dinh do rong cua cac cell va cac cot tuong ung
  4854. for($j = 0 ; $j < $nc ; $j++ ) //columns
  4855. {
  4856. $wc = &$table['wc'][$j];
  4857. for($i = 0 ; $i < $nr ; $i++ ) //rows
  4858. {
  4859. if (isset($cs[$i][$j]) && $cs[$i][$j])
  4860. {
  4861. $c = &$cs[$i][$j];
  4862. $miw = $mw;
  4863. if (isset($c['maxs']) and $c['maxs'] != '') $c['s'] = $c['maxs'];
  4864. $c['maw'] = $c['s'];
  4865. if (isset($c['nowrap'])) $miw = $c['maw'];
  4866. if (isset($c['w']))
  4867. {
  4868. if ($miw<$c['w']) $c['miw'] = $c['w'];
  4869. if ($miw>$c['w']) $c['miw'] = $c['w'] = $miw;
  4870. if (!isset($wc['w'])) $wc['w'] = 1;
  4871. }
  4872. else $c['miw'] = $miw;
  4873. if ($c['maw'] < $c['miw']) $c['maw'] = $c['miw'];
  4874. if (!isset($c['colspan']))
  4875. {
  4876. if ($wc['miw'] < $c['miw']) $wc['miw'] = $c['miw'];
  4877. if ($wc['maw'] < $c['maw']) $wc['maw'] = $c['maw'];
  4878. }
  4879. else $listspan[] = array($i,$j);
  4880. //Check if minimum width of the whole column is big enough for a huge word to fit
  4881. $auxtext = implode("",$c['text']);
  4882. $minwidth = $this->WordWrap($auxtext,$wc['miw']-2);// -2 == margin
  4883. if ($minwidth < 0 and (-$minwidth) > $wc['miw']) $wc['miw'] = (-$minwidth) +2; //increase minimum width
  4884. if ($wc['miw'] > $wc['maw']) $wc['maw'] = $wc['miw']; //update maximum width, if needed
  4885. }
  4886. }//rows
  4887. }//columns
  4888. //Xac dinh su anh huong cua cac cell colspan len cac cot va nguoc lai
  4889. $wc = &$table['wc'];
  4890. foreach ($listspan as $span)
  4891. {
  4892. list($i,$j) = $span;
  4893. $c = &$cs[$i][$j];
  4894. $lc = $j + $c['colspan'];
  4895. if ($lc > $nc) $lc = $nc;
  4896. $wis = $wisa = 0;
  4897. $was = $wasa = 0;
  4898. $list = array();
  4899. for($k=$j;$k<$lc;$k++)
  4900. {
  4901. $wis += $wc[$k]['miw'];
  4902. $was += $wc[$k]['maw'];
  4903. if (!isset($c['w']))
  4904. {
  4905. $list[] = $k;
  4906. $wisa += $wc[$k]['miw'];
  4907. $wasa += $wc[$k]['maw'];
  4908. }
  4909. }
  4910. if ($c['miw'] > $wis)
  4911. {
  4912. if (!$wis)
  4913. {//Cac cot chua co kich thuoc => chia deu
  4914. for($k=$j;$k<$lc;$k++) $wc[$k]['miw'] = $c['miw']/$c['colspan'];
  4915. }
  4916. elseif(!count($list))
  4917. {//Khong co cot nao co kich thuoc auto => chia deu phan du cho tat ca
  4918. $wi = $c['miw'] - $wis;
  4919. for($k=$j;$k<$lc;$k++) $wc[$k]['miw'] += ($wc[$k]['miw']/$wis)*$wi;
  4920. }
  4921. else
  4922. {//Co mot so cot co kich thuoc auto => chia deu phan du cho cac cot auto
  4923. $wi = $c['miw'] - $wis;
  4924. foreach ($list as $k) $wc[$k]['miw'] += ($wc[$k]['miw']/$wisa)*$wi;
  4925. }
  4926. }
  4927. if ($c['maw'] > $was)
  4928. {
  4929. if (!$wis)
  4930. {//Cac cot chua co kich thuoc => chia deu
  4931. for($k=$j;$k<$lc;$k++) $wc[$k]['maw'] = $c['maw']/$c['colspan'];
  4932. }
  4933. elseif (!count($list))
  4934. {
  4935. //Khong co cot nao co kich thuoc auto => chia deu phan du cho tat ca
  4936. $wi = $c['maw'] - $was;
  4937. for($k=$j;$k<$lc;$k++) $wc[$k]['maw'] += ($wc[$k]['maw']/$was)*$wi;
  4938. }
  4939. else
  4940. {//Co mot so cot co kich thuoc auto => chia deu phan du cho cac cot auto
  4941. $wi = $c['maw'] - $was;
  4942. foreach ($list as $k) $wc[$k]['maw'] += ($wc[$k]['maw']/$wasa)*$wi;
  4943. }
  4944. }
  4945. }
  4946. }
  4947. function _tableWidth(&$table){
  4948. //! @return void
  4949. //! @desc Calculates the Table Width
  4950. // @desc Xac dinh chieu rong cua table
  4951. $widthcols = &$table['wc'];
  4952. $numcols = $table['nc'];
  4953. $tablewidth = 0;
  4954. for ( $i = 0 ; $i < $numcols ; $i++ )
  4955. {
  4956. $tablewidth += isset($widthcols[$i]['w']) ? $widthcols[$i]['miw'] : $widthcols[$i]['maw'];
  4957. }
  4958. if ($tablewidth > $this->pgwidth) $table['w'] = $this->pgwidth;
  4959. if (isset($table['w']))
  4960. {
  4961. $wis = $wisa = 0;
  4962. $list = array();
  4963. for( $i = 0 ; $i < $numcols ; $i++ )
  4964. {
  4965. $wis += $widthcols[$i]['miw'];
  4966. if (!isset($widthcols[$i]['w'])){ $list[] = $i;$wisa += $widthcols[$i]['miw'];}
  4967. }
  4968. if ($table['w'] > $wis)
  4969. {
  4970. if (!count($list))
  4971. {//Khong co cot nao co kich thuoc auto => chia deu phan du cho tat ca
  4972. //http://www.ksvn.com/anhviet_new.htm - translating comments...
  4973. //bent shrink essence move size measure automatic => divide against give as a whole
  4974. //$wi = $table['w'] - $wis;
  4975. $wi = ($table['w'] - $wis)/$numcols;
  4976. for($k=0;$k<$numcols;$k++)
  4977. //$widthcols[$k]['miw'] += ($widthcols[$k]['miw']/$wis)*$wi;
  4978. $widthcols[$k]['miw'] += $wi;
  4979. }
  4980. else
  4981. {//Co mot so cot co kich thuoc auto => chia deu phan du cho cac cot auto
  4982. //$wi = $table['w'] - $wis;
  4983. $wi = ($table['w'] - $wis)/count($list);
  4984. foreach ($list as $k)
  4985. //$widthcols[$k]['miw'] += ($widthcols[$k]['miw']/$wisa)*$wi;
  4986. $widthcols[$k]['miw'] += $wi;
  4987. }
  4988. }
  4989. for ($i=0;$i<$numcols;$i++)
  4990. {
  4991. $tablewidth = $widthcols[$i]['miw'];
  4992. unset($widthcols[$i]);
  4993. $widthcols[$i] = $tablewidth;
  4994. }
  4995. }
  4996. else //table has no width defined
  4997. {
  4998. $table['w'] = $tablewidth;
  4999. for ( $i = 0 ; $i < $numcols ; $i++)
  5000. {
  5001. $tablewidth = isset($widthcols[$i]['w']) ? $widthcols[$i]['miw'] : $widthcols[$i]['maw'];
  5002. unset($widthcols[$i]);
  5003. $widthcols[$i] = $tablewidth;
  5004. }
  5005. }
  5006. }
  5007. function _tableHeight(&$table){
  5008. //! @return void
  5009. //! @desc Calculates the Table Height
  5010. $cells = &$table['cells'];
  5011. $numcols = $table['nc'];
  5012. $numrows = $table['nr'];
  5013. $listspan = array();
  5014. for( $i = 0 ; $i < $numrows ; $i++ )//rows
  5015. {
  5016. $heightrow = &$table['hr'][$i];
  5017. for( $j = 0 ; $j < $numcols ; $j++ ) //columns
  5018. {
  5019. if (isset($cells[$i][$j]) && $cells[$i][$j])
  5020. {
  5021. $c = &$cells[$i][$j];
  5022. list($x,$cw) = $this->_tableGetWidth($table, $i,$j);
  5023. //Check whether width is enough for this cells' text
  5024. $auxtext = implode("",$c['text']);
  5025. $auxtext2 = $auxtext; //in case we have text with styles
  5026. $nostyles_size = $this->GetStringWidth($auxtext) + 3; // +3 == margin
  5027. $linesneeded = $this->WordWrap($auxtext,$cw-2);// -2 == margin
  5028. if ($c['s'] > $nostyles_size and !isset($c['form'])) //Text with styles
  5029. {
  5030. $auxtext = $auxtext2; //recover original characteristics (original /n placements)
  5031. $diffsize = $c['s'] - $nostyles_size; //with bold et al. char width gets a bit bigger than plain char
  5032. if ($linesneeded == 0) $linesneeded = 1; //to avoid division by zero
  5033. $diffsize /= $linesneeded;
  5034. $linesneeded = $this->WordWrap($auxtext,$cw-2-$diffsize);//diffsize used to wrap text correctly
  5035. }
  5036. if (isset($c['form']))
  5037. {
  5038. $linesneeded = ceil(($c['s']-3)/($cw-2)); //Text + form in a cell
  5039. //Presuming the use of styles
  5040. if ( ($this->GetStringWidth($auxtext) + 3) > ($cw-2) ) $linesneeded++;
  5041. }
  5042. $ch = $linesneeded * 1.1 * $this->lineheight;
  5043. //If height is bigger than page height...
  5044. if ($ch > ($this->fh - $this->bMargin - $this->tMargin)) $ch = ($this->fh - $this->bMargin - $this->tMargin);
  5045. //If height is defined and it is bigger than calculated $ch then update values
  5046. if (isset($c['h']) && $c['h'] > $ch)
  5047. {
  5048. $c['mih'] = $ch; //in order to keep valign working
  5049. $ch = $c['h'];
  5050. }
  5051. else $c['mih'] = $ch;
  5052. if (isset($c['rowspan'])) $listspan[] = array($i,$j);
  5053. elseif ($heightrow < $ch) $heightrow = $ch;
  5054. if (isset($c['form'])) $c['mih'] = $ch;
  5055. }
  5056. }//end of columns
  5057. }//end of rows
  5058. $heightrow = &$table['hr'];
  5059. foreach ($listspan as $span)
  5060. {
  5061. list($i,$j) = $span;
  5062. $c = &$cells[$i][$j];
  5063. $lr = $i + $c['rowspan'];
  5064. if ($lr > $numrows) $lr = $numrows;
  5065. $hs = $hsa = 0;
  5066. $list = array();
  5067. for($k=$i;$k<$lr;$k++)
  5068. {
  5069. $hs += $heightrow[$k];
  5070. if (!isset($c['h']))
  5071. {
  5072. $list[] = $k;
  5073. $hsa += $heightrow[$k];
  5074. }
  5075. }
  5076. if ($c['mih'] > $hs)
  5077. {
  5078. if (!$hs)
  5079. {//Cac dong chua co kich thuoc => chia deu
  5080. for($k=$i;$k<$lr;$k++) $heightrow[$k] = $c['mih']/$c['rowspan'];
  5081. }
  5082. elseif (!count($list))
  5083. {//Khong co dong nao co kich thuoc auto => chia deu phan du cho tat ca
  5084. $hi = $c['mih'] - $hs;
  5085. for($k=$i;$k<$lr;$k++) $heightrow[$k] += ($heightrow[$k]/$hs)*$hi;
  5086. }
  5087. else
  5088. {//Co mot so dong co kich thuoc auto => chia deu phan du cho cac dong auto
  5089. $hi = $c['mih'] - $hsa;
  5090. foreach ($list as $k) $heightrow[$k] += ($heightrow[$k]/$hsa)*$hi;
  5091. }
  5092. }
  5093. }
  5094. }
  5095. function _tableGetWidth(&$table, $i,$j){
  5096. //! @return array(x,w)
  5097. // @desc Xac dinh toa do va do rong cua mot cell
  5098. $cell = &$table['cells'][$i][$j];
  5099. if ($cell)
  5100. {
  5101. if (isset($cell['x0'])) return array($cell['x0'], $cell['w0']);
  5102. $x = 0;
  5103. $widthcols = &$table['wc'];
  5104. for( $k = 0 ; $k < $j ; $k++ ) $x += $widthcols[$k];
  5105. $w = $widthcols[$j];
  5106. if (isset($cell['colspan']))
  5107. {
  5108. for ( $k = $j+$cell['colspan']-1 ; $k > $j ; $k-- ) $w += $widthcols[$k];
  5109. }
  5110. $cell['x0'] = $x;
  5111. $cell['w0'] = $w;
  5112. return array($x, $w);
  5113. }
  5114. return array(0,0);
  5115. }
  5116. function _tableGetHeight(&$table, $i,$j){
  5117. //! @return array(y,h)
  5118. $cell = &$table['cells'][$i][$j];
  5119. if ($cell){
  5120. if (isset($cell['y0'])) return array($cell['y0'], $cell['h0']);
  5121. $y = 0;
  5122. $heightrow = &$table['hr'];
  5123. for ($k=0;$k<$i;$k++) $y += $heightrow[$k];
  5124. $h = $heightrow[$i];
  5125. if (isset($cell['rowspan'])){
  5126. for ($k=$i+$cell['rowspan']-1;$k>$i;$k--)
  5127. $h += $heightrow[$k];
  5128. }
  5129. $cell['y0'] = $y;
  5130. $cell['h0'] = $h;
  5131. return array($y, $h);
  5132. }
  5133. return array(0,0);
  5134. }
  5135. function _tableRect($x, $y, $w, $h, $type=1){
  5136. //! @return void
  5137. if ($type==1) $this->Rect($x, $y, $w, $h);
  5138. elseif (strlen($type)==4){
  5139. $x2 = $x + $w; $y2 = $y + $h;
  5140. if (intval($type{0})) $this->Line($x , $y , $x2, $y );
  5141. if (intval($type{1})) $this->Line($x2, $y , $x2, $y2);
  5142. if (intval($type{2})) $this->Line($x , $y2, $x2, $y2);
  5143. if (intval($type{3})) $this->Line($x , $y , $x , $y2);
  5144. }
  5145. }
  5146. function _tableWrite(&$table){
  5147. //! @desc Main table function
  5148. //! @return void
  5149. $cells = &$table['cells'];
  5150. $numcols = $table['nc'];
  5151. $numrows = $table['nr'];
  5152. $x0 = $this->x;
  5153. $y0 = $this->y;
  5154. //added by Venkat
  5155. $h = 0;
  5156. //added by Venkat
  5157. $y = 0;
  5158. $right = $this->pgwidth - $this->rMargin;
  5159. if (isset($table['a']) and ($table['w'] != $this->pgwidth))
  5160. {
  5161. if ($table['a']=='C') $x0 += (($right-$x0) - $table['w'])/2;
  5162. elseif ($table['a']=='R') $x0 = $right - $table['w'];
  5163. }
  5164. $returny = 0;
  5165. $tableheader = array();
  5166. //Draw Table Contents and Borders
  5167. for( $i = 0 ; $i < $numrows ; $i++ ) //Rows
  5168. {
  5169. $skippage = false;
  5170. for( $j = 0 ; $j < $numcols ; $j++ ) //Columns
  5171. {
  5172. if (isset($cells[$i][$j]) && $cells[$i][$j])
  5173. {
  5174. $cell = &$cells[$i][$j];
  5175. list($x,$w) = $this->_tableGetWidth($table, $i, $j);
  5176. list($y,$h) = $this->_tableGetHeight($table, $i, $j);
  5177. $x += $x0;
  5178. $y += $y0;
  5179. $y -= $returny;
  5180. if ((($y + $h) > ($this->fh - $this->bMargin)) && ($y0 >0 || $x0 > 0))
  5181. {
  5182. if (!$skippage)
  5183. {
  5184. $y -= $y0;
  5185. $returny += $y;
  5186. $this->AddPage();
  5187. if ($this->usetableheader) $this->__tableHeader($tableheader);
  5188. if ($this->usetableheader) $y0 = $this->y;
  5189. else $y0 = $this->tMargin;
  5190. $y = $y0;
  5191. }
  5192. $skippage = true;
  5193. }
  5194. //Align
  5195. $this->x = $x; $this->y = $y;
  5196. $align = isset($cell['a'])? $cell['a'] : 'L';
  5197. //Vertical align
  5198. if (!isset($cell['va']) || $cell['va']=='M') $this->y += ($h-$cell['mih'])/2;
  5199. elseif (isset($cell['va']) && $cell['va']=='B') $this->y += $h-$cell['mih'];
  5200. //Fill
  5201. $fill = isset($cell['bgcolor']) ? $cell['bgcolor']
  5202. : (isset($table['bgcolor'][$i]) ? $table['bgcolor'][$i]
  5203. : (isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0));
  5204. if ($fill)
  5205. {
  5206. $color = ConvertColor($fill);
  5207. $this->SetFillColor($color['R'],$color['G'],$color['B']);
  5208. $this->Rect($x, $y, $w, $h, 'F');
  5209. }
  5210. //Border
  5211. if (isset($cell['border'])) $this->_tableRect($x, $y, $w, $h, $cell['border']);
  5212. elseif (isset($table['border']) && $table['border']) $this->Rect($x, $y, $w, $h);
  5213. $this->divalign=$align;
  5214. $this->divwidth=$w-2;
  5215. //Get info of first row == table header
  5216. if ($this->usetableheader and $i == 0 )
  5217. {
  5218. $tableheader[$j]['x'] = $x;
  5219. $tableheader[$j]['y'] = $y;
  5220. $tableheader[$j]['h'] = $h;
  5221. $tableheader[$j]['w'] = $w;
  5222. $tableheader[$j]['text'] = $cell['text'];
  5223. $tableheader[$j]['textbuffer'] = $cell['textbuffer'];
  5224. $tableheader[$j]['a'] = isset($cell['a'])? $cell['a'] : 'L';
  5225. $tableheader[$j]['va'] = $cell['va'];
  5226. $tableheader[$j]['mih'] = $cell['mih'];
  5227. $tableheader[$j]['bgcolor'] = $fill;
  5228. if ($table['border']) $tableheader[$j]['border'] = 'all';
  5229. elseif (isset($cell['border'])) $tableheader[$j]['border'] = $cell['border'];
  5230. }
  5231. if (!empty($cell['textbuffer'])) $this->printbuffer($cell['textbuffer'],false,true/*inside a table*/);
  5232. //Reset values
  5233. $this->Reset();
  5234. }//end of (if isset(cells)...)
  5235. }// end of columns
  5236. if ($i == $numrows-1) $this->y = $y + $h; //last row jump (update this->y position)
  5237. }// end of rows
  5238. }//END OF FUNCTION _tableWrite()
  5239. /////////////////////////END OF TABLE CODE//////////////////////////////////
  5240. }//end of Class
  5241. /*
  5242. ---- JUNK(?)/OLD CODE: ------
  5243. // <? <- this fixes HIGHLIGHT PSPAD bug ...
  5244. */
  5245. ?>