PageRenderTime 141ms CodeModel.GetById 18ms RepoModel.GetById 3ms app.codeStats 1ms

/administrator/components/com_virtuemart/classes/pdf/html2fpdf.php

https://bitbucket.org/dgough/annamaria-daneswood-25102012
PHP | 2926 lines | 2458 code | 94 blank | 374 comment | 553 complexity | b143a1b1e84efd8712ce08255eb401c1 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' );
  3. /**
  4. * @version $Id: html2fpdf.php 1095 2007-12-19 20:19:16Z soeren_nb $
  5. * @package VirtueMart
  6. * @subpackage HMTL2PDF
  7. * @author Renato Coelho
  8. * @copyright Copyright (C) 2004-2007 soeren - All rights reserved.
  9. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
  10. * VirtueMart is free software. This version may have been modified pursuant
  11. * to the GNU General Public License, and as distributed it includes or
  12. * is derivative of works licensed under the GNU General Public License or
  13. * other free or open source software licenses.
  14. * See /administrator/components/com_virtuemart/COPYRIGHT.php for copyright notices and details.
  15. *
  16. * http://virtuemart.net
  17. */
  18. /*
  19. *** General-use version
  20. DEBUG HINT:
  21. - Inside function printbuffer make $fill=1
  22. - Inside function Cell make:
  23. if($fill==1 or $border==1)
  24. {
  25. // if ($fill==1) $op=($border==1) ? 'B' : 'f';
  26. // else $op='S';
  27. $op='S';
  28. - Following these 2 steps you will be able to see the cell's boundaries
  29. WARNING: When adding a new tag support, also add its name inside the function DisableTags()'s very long string
  30. ODDITIES (?):
  31. . It seems like saved['border'] and saved['bgcolor'] are useless inside the FlowingBlock...
  32. These 2 attributes do the same thing?!?:
  33. . $this->currentfont - mine
  34. . $this->CurrentFont - fpdf's
  35. TODO (in the future...):
  36. - Make font-family, font-size, lineheight customizable
  37. - Increase number of HTML/CSS tags/properties, Image/Font Types, recognized/supported
  38. - allow BMP support? (tried with http://phpthumb.sourceforge.net/ but failed)
  39. - Improve CSS support
  40. - support image side-by-side or one-below-another or both?
  41. - Improve code clarity even more (modularize and get better var names like on textbuffer array's indexes for example)
  42. //////////////////////////////////////////////////////////////////////////////
  43. //////////////DO NOT MODIFY THE CONTENTS OF THIS BOX//////////////////////////
  44. //////////////////////////////////////////////////////////////////////////////
  45. // //
  46. // HTML2FPDF is a php script to read a HTML text and generate a PDF file. //
  47. // Copyright (C) 2004-2005 Renato Coelho //
  48. // This script may be distributed as long as the following files are kept //
  49. // together: //
  50. // //
  51. // fpdf.php, html2fpdf.php, gif.php,htmltoolkit.php,license.txt,credits.txt //
  52. // //
  53. //////////////////////////////////////////////////////////////////////////////
  54. Misc. Observations:
  55. - CSS + align = bug! (?)
  56. OBS1: para textos de mais de 1 p�gina, talvez tenha que juntar varios $texto_artigo
  57. antes de mandar gerar o PDF, para que o PDF gerado seja completo.
  58. OBS2: there are 2 types of spaces 32 and 160 (ascii values)
  59. OBS3: //! is a special comment to be used with source2doc.php, a script I created
  60. in order to generate the doc on the site html2fpdf.sf.net
  61. OBS4: var $LineWidth; // line width in user unit - use this to make css thin/medium/thick work
  62. OBS5: Images and Textareas: when they are inserted you can only type below them (==display:block)
  63. OBS6: Optimized to 'A4' paper (default font: Arial , normal , size 11 )
  64. OBS7: Regexp + Perl ([preg]accepts non-greedy quantifiers while PHP[ereg] does not)
  65. Perl: '/regexp/x' where x == option ( x = i:ignore case , x = s: DOT gets \n as well)
  66. ========================END OF INITIAL COMMENTS=================================
  67. */
  68. define('HTML2FPDF_VERSION','3.0(beta)');
  69. if (!defined('RELATIVE_PATH')) define('RELATIVE_PATH','');
  70. if (!defined('FPDF_FONTPATH')) define('FPDF_FONTPATH','font/');
  71. require_once(RELATIVE_PATH.'fpdf.php');
  72. require_once(RELATIVE_PATH.'htmltoolkit.php');
  73. class HTML2FPDF extends FPDF
  74. {
  75. //internal attributes
  76. var $HREF; //! string
  77. var $pgwidth; //! float
  78. var $fontlist; //! array
  79. var $issetfont; //! bool
  80. var $issetcolor; //! bool
  81. var $titulo; //! string
  82. var $oldx; //! float
  83. var $oldy; //! float
  84. var $B; //! int
  85. var $U; //! int
  86. var $I; //! int
  87. var $tablestart; //! bool
  88. var $tdbegin; //! bool
  89. var $table; //! array
  90. var $cell; //! array
  91. var $col; //! int
  92. var $row; //! int
  93. var $divbegin; //! bool
  94. var $divalign; //! char
  95. var $divwidth; //! float
  96. var $divheight; //! float
  97. var $divbgcolor; //! bool
  98. var $divcolor; //! bool
  99. var $divborder; //! int
  100. var $divrevert; //! bool
  101. var $listlvl; //! int
  102. var $listnum; //! int
  103. var $listtype; //! string
  104. //array(lvl,# of occurrences)
  105. var $listoccur; //! array
  106. //array(lvl,occurrence,type,maxnum)
  107. var $listlist; //! array
  108. //array(lvl,num,content,type)
  109. var $listitem; //! array
  110. var $buffer_on; //! bool
  111. var $pbegin; //! bool
  112. var $pjustfinished; //! bool
  113. var $blockjustfinished; //! bool
  114. var $SUP; //! bool
  115. var $SUB; //! bool
  116. var $toupper; //! bool
  117. var $tolower; //! bool
  118. var $dash_on; //! bool
  119. var $dotted_on; //! bool
  120. var $strike; //! bool
  121. var $CSS; //! array
  122. var $cssbegin; //! bool
  123. var $backupcss; //! array
  124. var $textbuffer; //! array
  125. var $currentstyle; //! string
  126. var $currentfont; //! string
  127. var $colorarray; //! array
  128. var $bgcolorarray; //! array
  129. var $internallink; //! array
  130. var $enabledtags; //! string
  131. var $lineheight; //! int
  132. var $basepath; //! string
  133. // array('COLOR','WIDTH','OLDWIDTH')
  134. var $outlineparam; //! array
  135. var $outline_on; //! bool
  136. var $specialcontent; //! string
  137. var $selectoption; //! array
  138. //options attributes
  139. var $usecss; //! bool
  140. var $usepre; //! bool
  141. var $usetableheader; //! bool
  142. var $shownoimg; //! bool
  143. function HTML2FPDF($orientation='P',$unit='mm',$format='A4')
  144. {
  145. //! @desc Constructor
  146. //! @return An object (a class instance)
  147. //Call parent constructor
  148. $this->FPDF($orientation,$unit,$format);
  149. //To make the function Footer() work properly
  150. $this->AliasNbPages();
  151. //Enable all tags as default
  152. $this->DisableTags();
  153. //Set default display preferences
  154. $this->DisplayPreferences('');
  155. //Initialization of the attributes
  156. $this->SetFont('Arial','',11); // Changeable?(not yet...)
  157. $this->lineheight = 5; // Related to FontSizePt == 11
  158. $this->pgwidth = $this->fw - $this->lMargin - $this->rMargin ;
  159. $this->SetFillColor(255);
  160. $this->HREF='';
  161. $this->titulo='';
  162. $this->oldx=-1;
  163. $this->oldy=-1;
  164. $this->B=0;
  165. $this->U=0;
  166. $this->I=0;
  167. $this->listlvl=0;
  168. $this->listnum=0;
  169. $this->listtype='';
  170. $this->listoccur=array();
  171. $this->listlist=array();
  172. $this->listitem=array();
  173. $this->tablestart=false;
  174. $this->tdbegin=false;
  175. $this->table=array();
  176. $this->cell=array();
  177. $this->col=-1;
  178. $this->row=-1;
  179. $this->divbegin=false;
  180. $this->divalign="L";
  181. $this->divwidth=0;
  182. $this->divheight=0;
  183. $this->divbgcolor=false;
  184. $this->divcolor=false;
  185. $this->divborder=0;
  186. $this->divrevert=false;
  187. $this->fontlist=array("arial","times","courier","helvetica","symbol","monospace","serif","sans");
  188. $this->issetfont=false;
  189. $this->issetcolor=false;
  190. $this->pbegin=false;
  191. $this->pjustfinished=false;
  192. $this->blockjustfinished = true; //in order to eliminate exceeding left-side spaces
  193. $this->toupper=false;
  194. $this->tolower=false;
  195. $this->dash_on=false;
  196. $this->dotted_on=false;
  197. $this->SUP=false;
  198. $this->SUB=false;
  199. $this->buffer_on=false;
  200. $this->strike=false;
  201. $this->currentfont='';
  202. $this->currentstyle='';
  203. $this->colorarray=array();
  204. $this->bgcolorarray=array();
  205. $this->cssbegin=false;
  206. $this->textbuffer=array();
  207. $this->CSS=array();
  208. $this->backupcss=array();
  209. $this->internallink=array();
  210. $this->basepath = "";
  211. $this->outlineparam = array();
  212. $this->outline_on = false;
  213. $this->specialcontent = '';
  214. $this->selectoption = array();
  215. $this->shownoimg=false;
  216. $this->usetableheader=false;
  217. $this->usecss=true;
  218. $this->usepre=true;
  219. }
  220. function setBasePath($str)
  221. {
  222. //! @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.
  223. //! @return void
  224. $this->basepath = dirname($str) . "/";
  225. $this->basepath = str_replace("\\","/",$this->basepath); //If on Windows
  226. }
  227. function ShowNOIMG_GIF($opt=true)
  228. {
  229. //! @desc Enable/Disable Displaying the no_img.gif when an image is not found. No-Parameter: Enable
  230. //! @return void
  231. $this->shownoimg=$opt;
  232. }
  233. function UseCSS($opt=true)
  234. {
  235. //! @desc Enable/Disable CSS recognition. No-Parameter: Enable
  236. //! @return void
  237. $this->usecss=$opt;
  238. }
  239. function UseTableHeader($opt=true)
  240. {
  241. //! @desc Enable/Disable Table Header to appear every new page. No-Parameter: Enable
  242. //! @return void
  243. $this->usetableheader=$opt;
  244. }
  245. function UsePRE($opt=true)
  246. {
  247. //! @desc Enable/Disable pre tag recognition. No-Parameter: Enable
  248. //! @return void
  249. $this->usepre=$opt;
  250. }
  251. //Page header
  252. function Header($content='')
  253. {
  254. //! @return void
  255. //! @desc The header is printed in every page.
  256. if($this->usetableheader and $content != '')
  257. {
  258. $y = $this->y;
  259. foreach($content as $tableheader)
  260. {
  261. $this->y = $y;
  262. //Set some cell values
  263. $x = $tableheader['x'];
  264. $w = $tableheader['w'];
  265. $h = $tableheader['h'];
  266. $va = $tableheader['va'];
  267. $mih = $tableheader['mih'];
  268. $fill = $tableheader['bgcolor'];
  269. $border = $tableheader['border'];
  270. $align = $tableheader['a'];
  271. //Align
  272. $this->divalign=$align;
  273. $this->x = $x;
  274. //Vertical align
  275. if (!isset($va) || $va=='M') $this->y += ($h-$mih)/2;
  276. elseif (isset($va) && $va=='B') $this->y += $h-$mih;
  277. if ($fill)
  278. {
  279. $color = ConvertColor($fill);
  280. $this->SetFillColor($color['R'],$color['G'],$color['B']);
  281. $this->Rect($x, $y, $w, $h, 'F');
  282. }
  283. //Border
  284. if (isset($border) and $border != 'all') $this->_tableRect($x, $y, $w, $h, $border);
  285. elseif (isset($border) && $border == 'all') $this->Rect($x, $y, $w, $h);
  286. //Print cell content
  287. $this->divwidth = $w-2;
  288. $this->divheight = 1.1*$this->lineheight;
  289. $textbuffer = $tableheader['textbuffer'];
  290. if (!empty($textbuffer)) $this->printbuffer($textbuffer,false,true/*inside a table*/);
  291. $textbuffer = array();
  292. }
  293. $this->y = $y + $h; //Update y coordinate
  294. }//end of 'if usetableheader ...'
  295. }
  296. //Page footer
  297. function Footer()
  298. {
  299. //! @return void
  300. //! @desc The footer is printed in every page!
  301. //Position at 1.0 cm from bottom
  302. $this->SetY(-10);
  303. //Copyright //especial para esta vers�o
  304. $this->SetFont('Arial','B',9);
  305. $this->SetTextColor(0);
  306. //Arial italic 9
  307. $this->SetFont('Arial','I',9);
  308. //Page number
  309. $this->Cell(0,10,$this->PageNo().'/{nb}',0,0,'C');
  310. //Return Font to normal
  311. $this->SetFont('Arial','',11);
  312. }
  313. ///////////////////
  314. /// HTML parser ///
  315. ///////////////////
  316. function WriteHTML($html)
  317. {
  318. //! @desc HTML parser
  319. //! @return void
  320. /* $e == content */
  321. $this->ReadMetaTags($html);
  322. $html = AdjustHTML($html,$this->usepre); //Try to make HTML look more like XHTML
  323. if ($this->usecss) $html = $this->ReadCSS($html);
  324. //Add new supported tags in the DisableTags function
  325. $html=str_replace('<?','< ',$html); //Fix '<?XML' bug from HTML code generated by MS Word
  326. $html=strip_tags($html,$this->enabledtags); //remove all unsupported tags, but the ones inside the 'enabledtags' string
  327. //Explode the string in order to parse the HTML code
  328. $a=preg_split('/<(.*?)>/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
  329. foreach($a as $i => $e)
  330. {
  331. if($i%2==0)
  332. {
  333. //TEXT
  334. //Adjust lineheight
  335. // $this->lineheight = (5*$this->FontSizePt)/11; //should be inside printbuffer?
  336. //Adjust text, if needed
  337. if (strpos($e,"&") !== false) //HTML-ENTITIES decoding
  338. {
  339. if (strpos($e,"#") !== false) $e = value_entity_decode($e); // Decode value entities
  340. //Avoid crashing the script on PHP 4.0
  341. $version = phpversion();
  342. $version = str_replace('.','',$version);
  343. if ($version >= 430) $e = html_entity_decode($e,ENT_QUOTES,'cp1252'); // changes &nbsp; and the like by their respective char
  344. else $e = lesser_entity_decode($e);
  345. }
  346. $e = str_replace(chr(160),chr(32),$e); //unify ascii code of spaces (in order to recognize all of them correctly)
  347. if (strlen($e) == 0) continue;
  348. if ($this->divrevert) $e = strrev($e);
  349. if ($this->toupper) $e = strtoupper($e);
  350. if ($this->tolower) $e = strtolower($e);
  351. //Start of 'if/elseif's
  352. if($this->titulo) $this->SetTitle($e);
  353. elseif($this->specialcontent)
  354. {
  355. if ($this->specialcontent == "type=select" and $this->selectoption['ACTIVE'] == true) //SELECT tag (form element)
  356. {
  357. $stringwidth = $this->GetStringWidth($e);
  358. if (!isset($this->selectoption['MAXWIDTH']) or $stringwidth > $this->selectoption['MAXWIDTH']) $this->selectoption['MAXWIDTH'] = $stringwidth;
  359. if (!isset($this->selectoption['SELECTED']) or $this->selectoption['SELECTED'] == '') $this->selectoption['SELECTED'] = $e;
  360. }
  361. else $this->textbuffer[] = array("���"/*identifier*/.$this->specialcontent."���".$e);
  362. }
  363. elseif($this->tablestart)
  364. {
  365. if($this->tdbegin)
  366. {
  367. $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);
  368. $this->cell[$this->row][$this->col]['text'][] = $e;
  369. $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth($e);
  370. }
  371. //Ignore content between <table>,<tr> and a <td> tag (this content is usually only a bunch of spaces)
  372. }
  373. 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
  374. else
  375. {
  376. if ($this->blockjustfinished) $e = ltrim($e);
  377. if ($e != '')
  378. {
  379. $this->Write($this->lineheight,$e); //Write text directly in the PDF
  380. if ($this->pjustfinished) $this->pjustfinished = false;
  381. }
  382. }
  383. }
  384. else
  385. {
  386. //Tag
  387. if($e{0}=='/') $this->CloseTag(strtoupper(substr($e,1)));
  388. else
  389. {
  390. $regexp = '|=\'(.*?)\'|s'; // eliminate single quotes, if any
  391. $e = preg_replace($regexp,"=\"\$1\"",$e);
  392. $regexp = '| (\\w+?)=([^\\s>"]+)|si'; // changes anykey=anyvalue to anykey="anyvalue" (only do this when this happens inside tags)
  393. $e = preg_replace($regexp," \$1=\"\$2\"",$e);
  394. //Fix path values, if needed
  395. if ((stristr($e,"href=") !== false) or (stristr($e,"src=") !== false) )
  396. {
  397. $regexp = '/ (href|src)="(.*?)"/i';
  398. preg_match($regexp,$e,$auxiliararray);
  399. $path = $auxiliararray[2];
  400. $path = str_replace("\\","/",$path); //If on Windows
  401. //Get link info and obtain its absolute path
  402. $regexp = '|^./|';
  403. $path = preg_replace($regexp,'',$path);
  404. if($path{0} != '#') //It is not an Internal Link
  405. {
  406. if (strpos($path,"../") !== false ) //It is a Relative Link
  407. {
  408. $backtrackamount = substr_count($path,"../");
  409. $maxbacktrack = substr_count($this->basepath,"/") - 1;
  410. $filepath = str_replace("../",'',$path);
  411. $path = $this->basepath;
  412. //If it is an invalid relative link, then make it go to directory root
  413. if ($backtrackamount > $maxbacktrack) $backtrackamount = $maxbacktrack;
  414. //Backtrack some directories
  415. for( $i = 0 ; $i < $backtrackamount + 1 ; $i++ ) $path = substr( $path, 0 , strrpos($path,"/") );
  416. $path = $path . "/" . $filepath; //Make it an absolute path
  417. }
  418. elseif( strpos($path,":/") === false) //It is a Local Link
  419. {
  420. $path = $this->basepath . $path;
  421. }
  422. //Do nothing if it is an Absolute Link
  423. }
  424. $regexp = '/ (href|src)="(.*?)"/i';
  425. $e = preg_replace($regexp,' \\1="'.$path.'"',$e);
  426. }//END of Fix path values
  427. //Extract attributes
  428. $contents=array();
  429. preg_match_all('/\\S*=["\'][^"\']*["\']/',$e,$contents);
  430. preg_match('/\\S+/',$e,$a2);
  431. $tag=strtoupper($a2[0]);
  432. $attr=array();
  433. if (!empty($contents))
  434. {
  435. foreach($contents[0] as $v)
  436. {
  437. if(ereg('^([^=]*)=["\']?([^"\']*)["\']?$',$v,$a3))
  438. {
  439. $attr[strtoupper($a3[1])]=$a3[2];
  440. }
  441. }
  442. }
  443. $this->OpenTag($tag,$attr);
  444. }
  445. }
  446. }//end of foreach($a as $i=>$e)
  447. //Create Internal Links, if needed
  448. if (!empty($this->internallink) )
  449. {
  450. foreach($this->internallink as $k=>$v)
  451. {
  452. if (strpos($k,"#") !== false ) continue; //ignore
  453. $ypos = $v['Y'];
  454. $pagenum = $v['PAGE'];
  455. $sharp = "#";
  456. while (array_key_exists($sharp.$k,$this->internallink))
  457. {
  458. $internallink = $this->internallink[$sharp.$k];
  459. $this->SetLink($internallink,$ypos,$pagenum);
  460. $sharp .= "#";
  461. }
  462. }
  463. }
  464. }
  465. function OpenTag($tag,$attr)
  466. {
  467. //! @return void
  468. // What this gets: < $tag $attr['WIDTH']="90px" > does not get content here </closeTag here>
  469. $align = array('left'=>'L','center'=>'C','right'=>'R','top'=>'T','middle'=>'M','bottom'=>'B','justify'=>'J');
  470. $this->blockjustfinished=false;
  471. //Opening tag
  472. switch($tag){
  473. case 'PAGE_BREAK': //custom-tag
  474. case 'NEWPAGE': //custom-tag
  475. $this->blockjustfinished = true;
  476. $this->AddPage();
  477. break;
  478. case 'OUTLINE': //custom-tag (CSS2 property - browsers don't support it yet - Jan2005)
  479. //Usage: (default: width=normal color=white)
  480. //<outline width="(thin|medium|thick)" color="(usualcolorformat)" >Text</outline>
  481. //Mix this tag with the <font color="(usualcolorformat)"> tag to get mixed colors on outlined text!
  482. $this->buffer_on = true;
  483. if (isset($attr['COLOR'])) $this->outlineparam['COLOR'] = ConvertColor($attr['COLOR']);
  484. else $this->outlineparam['COLOR'] = array('R'=>255,'G'=>255,'B'=>255); //white
  485. $this->outlineparam['OLDWIDTH'] = $this->LineWidth;
  486. if (isset($attr['WIDTH']))
  487. {
  488. switch(strtoupper($attr['WIDTH']))
  489. {
  490. case 'THIN': $this->outlineparam['WIDTH'] = 0.75*$this->LineWidth; break;
  491. case 'MEDIUM': $this->outlineparam['WIDTH'] = $this->LineWidth; break;
  492. case 'THICK': $this->outlineparam['WIDTH'] = 1.75*$this->LineWidth; break;
  493. }
  494. }
  495. else $this->outlineparam['WIDTH'] = $this->LineWidth; //width == oldwidth
  496. break;
  497. case 'BDO':
  498. if (isset($attr['DIR']) and (strtoupper($attr['DIR']) == 'RTL' )) $this->divrevert = true;
  499. break;
  500. case 'S':
  501. case 'STRIKE':
  502. case 'DEL':
  503. $this->strike=true;
  504. break;
  505. case 'SUB':
  506. $this->SUB=true;
  507. break;
  508. case 'SUP':
  509. $this->SUP=true;
  510. break;
  511. case 'CENTER':
  512. $this->buffer_on = true;
  513. if ($this->tdbegin) $this->cell[$this->row][$this->col]['a'] = $align['center'];
  514. else
  515. {
  516. $this->divalign = $align['center'];
  517. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  518. }
  519. break;
  520. case 'ADDRESS':
  521. $this->buffer_on = true;
  522. $this->SetStyle('I',true);
  523. if (!$this->tdbegin and $this->x != $this->lMargin) $this->Ln($this->lineheight);
  524. break;
  525. case 'TABLE': // TABLE-BEGIN
  526. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  527. $this->tablestart = true;
  528. $this->table['nc'] = $this->table['nr'] = 0;
  529. if (isset($attr['REPEAT_HEADER']) and $attr['REPEAT_HEADER'] == true) $this->UseTableHeader(true);
  530. if (isset($attr['WIDTH'])) $this->table['w'] = ConvertSize($attr['WIDTH'],$this->pgwidth);
  531. if (isset($attr['HEIGHT'])) $this->table['h'] = ConvertSize($attr['HEIGHT'],$this->pgwidth);
  532. if (isset($attr['ALIGN'])) $this->table['a'] = $align[strtolower($attr['ALIGN'])];
  533. if (isset($attr['BORDER'])) $this->table['border'] = $attr['BORDER'];
  534. if (isset($attr['BGCOLOR'])) $this->table['bgcolor'][-1] = $attr['BGCOLOR'];
  535. break;
  536. case 'TR':
  537. $this->row++;
  538. $this->table['nr']++;
  539. $this->col = -1;
  540. if (isset($attr['BGCOLOR']))$this->table['bgcolor'][$this->row] = $attr['BGCOLOR'];
  541. break;
  542. case 'TH':
  543. $this->SetStyle('B',true);
  544. if (!isset($attr['ALIGN'])) $attr['ALIGN'] = "center";
  545. case 'TD':
  546. $this->tdbegin = true;
  547. $this->col++;
  548. while (isset($this->cell[$this->row][$this->col])) $this->col++;
  549. //Update number column
  550. if ($this->table['nc'] < $this->col+1) $this->table['nc'] = $this->col+1;
  551. $this->cell[$this->row][$this->col] = array();
  552. $this->cell[$this->row][$this->col]['text'] = array();
  553. $this->cell[$this->row][$this->col]['s'] = 3;
  554. if (isset($attr['WIDTH'])) $this->cell[$this->row][$this->col]['w'] = ConvertSize($attr['WIDTH'],$this->pgwidth);
  555. if (isset($attr['HEIGHT'])) $this->cell[$this->row][$this->col]['h'] = ConvertSize($attr['HEIGHT'],$this->pgwidth);
  556. if (isset($attr['ALIGN'])) $this->cell[$this->row][$this->col]['a'] = $align[strtolower($attr['ALIGN'])];
  557. if (isset($attr['VALIGN'])) $this->cell[$this->row][$this->col]['va'] = $align[strtolower($attr['VALIGN'])];
  558. if (isset($attr['BORDER'])) $this->cell[$this->row][$this->col]['border'] = $attr['BORDER'];
  559. if (isset($attr['BGCOLOR'])) $this->cell[$this->row][$this->col]['bgcolor'] = $attr['BGCOLOR'];
  560. $cs = $rs = 1;
  561. if (isset($attr['COLSPAN']) && $attr['COLSPAN']>1) $cs = $this->cell[$this->row][$this->col]['colspan'] = $attr['COLSPAN'];
  562. if (isset($attr['ROWSPAN']) && $attr['ROWSPAN']>1) $rs = $this->cell[$this->row][$this->col]['rowspan'] = $attr['ROWSPAN'];
  563. //Chiem dung vi tri de danh cho cell span (�mais hein?)
  564. for ($k=$this->row ; $k < $this->row+$rs ;$k++)
  565. for($l=$this->col; $l < $this->col+$cs ;$l++)
  566. {
  567. if ($k-$this->row || $l-$this->col) $this->cell[$k][$l] = 0;
  568. }
  569. if (isset($attr['NOWRAP'])) $this->cell[$this->row][$this->col]['nowrap']= 1;
  570. break;
  571. case 'OL':
  572. if ( !isset($attr['TYPE']) or $attr['TYPE'] == '' ) $this->listtype = '1'; //OL default == '1'
  573. else $this->listtype = $attr['TYPE']; // ol and ul types are mixed here
  574. case 'UL':
  575. if ( (!isset($attr['TYPE']) or $attr['TYPE'] == '') and $tag=='UL')
  576. {
  577. //Insert UL defaults
  578. if ($this->listlvl == 0) $this->listtype = 'disc';
  579. elseif ($this->listlvl == 1) $this->listtype = 'circle';
  580. else $this->listtype = 'square';
  581. }
  582. elseif (isset($attr['TYPE']) and $tag=='UL') $this->listtype = $attr['TYPE'];
  583. $this->buffer_on = false;
  584. if ($this->listlvl == 0)
  585. {
  586. //First of all, skip a line
  587. if (!$this->pjustfinished)
  588. {
  589. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  590. $this->Ln($this->lineheight);
  591. }
  592. $this->oldx = $this->x;
  593. $this->listlvl++; // first depth level
  594. $this->listnum = 0; // reset
  595. $this->listoccur[$this->listlvl] = 1;
  596. $this->listlist[$this->listlvl][1] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
  597. }
  598. else
  599. {
  600. if (!empty($this->textbuffer))
  601. {
  602. $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
  603. $this->listnum++;
  604. }
  605. $this->textbuffer = array();
  606. $occur = $this->listoccur[$this->listlvl];
  607. $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
  608. $this->listlvl++;
  609. $this->listnum = 0; // reset
  610. if ($this->listoccur[$this->listlvl] == 0) $this->listoccur[$this->listlvl] = 1;
  611. else $this->listoccur[$this->listlvl]++;
  612. $occur = $this->listoccur[$this->listlvl];
  613. $this->listlist[$this->listlvl][$occur] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
  614. }
  615. break;
  616. case 'LI':
  617. //Observation: </LI> is ignored
  618. if ($this->listlvl == 0) //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
  619. {
  620. //First of all, skip a line
  621. if (!$this->pjustfinished and $this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
  622. $this->oldx = $this->x;
  623. $this->listlvl++; // first depth level
  624. $this->listnum = 0; // reset
  625. $this->listoccur[$this->listlvl] = 1;
  626. $this->listlist[$this->listlvl][1] = array('TYPE'=>'disc','MAXNUM'=>$this->listnum);
  627. }
  628. if ($this->listnum == 0)
  629. {
  630. $this->buffer_on = true; //activate list 'bufferization'
  631. $this->listnum++;
  632. $this->textbuffer = array();
  633. }
  634. else
  635. {
  636. $this->buffer_on = true; //activate list 'bufferization'
  637. if (!empty($this->textbuffer))
  638. {
  639. $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
  640. $this->listnum++;
  641. }
  642. $this->textbuffer = array();
  643. }
  644. break;
  645. case 'H1': // 2 * fontsize
  646. case 'H2': // 1.5 * fontsize
  647. case 'H3': // 1.17 * fontsize
  648. case 'H4': // 1 * fontsize
  649. case 'H5': // 0.83 * fontsize
  650. case 'H6': // 0.67 * fontsize
  651. //Values obtained from: http://www.w3.org/TR/REC-CSS2/sample.html
  652. if(isset($attr['ALIGN'])) $this->divalign = $align[strtolower($attr['ALIGN'])];
  653. $this->buffer_on = true;
  654. if ($this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
  655. elseif (!$this->pjustfinished) $this->Ln($this->lineheight);
  656. $this->SetStyle('B',true);
  657. switch($tag)
  658. {
  659. case 'H1':
  660. $this->SetFontSize(2*$this->FontSizePt);
  661. $this->lineheight *= 2;
  662. break;
  663. case 'H2':
  664. $this->SetFontSize(1.5*$this->FontSizePt);
  665. $this->lineheight *= 1.5;
  666. break;
  667. case 'H3':
  668. $this->SetFontSize(1.17*$this->FontSizePt);
  669. $this->lineheight *= 1.17;
  670. break;
  671. case 'H4':
  672. $this->SetFontSize($this->FontSizePt);
  673. break;
  674. case 'H5':
  675. $this->SetFontSize(0.83*$this->FontSizePt);
  676. $this->lineheight *= 0.83;
  677. break;
  678. case 'H6':
  679. $this->SetFontSize(0.67*$this->FontSizePt);
  680. $this->lineheight *= 0.67;
  681. break;
  682. }
  683. break;
  684. case 'HR': //Default values: width=100% align=center color=gray
  685. //Skip a line, if needed
  686. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  687. $this->Ln(0.2*$this->lineheight);
  688. $hrwidth = $this->pgwidth;
  689. $hralign = 'C';
  690. $hrcolor = array('R'=>200,'G'=>200,'B'=>200);
  691. if($attr['WIDTH'] != '') $hrwidth = ConvertSize($attr['WIDTH'],$this->pgwidth);
  692. if($attr['ALIGN'] != '') $hralign = $align[strtolower($attr['ALIGN'])];
  693. if($attr['COLOR'] != '') $hrcolor = ConvertColor($attr['COLOR']);
  694. $this->SetDrawColor($hrcolor['R'],$hrcolor['G'],$hrcolor['B']);
  695. $x = $this->x;
  696. $y = $this->y;
  697. switch($hralign)
  698. {
  699. case 'L':
  700. case 'J':
  701. break;
  702. case 'C':
  703. $empty = $this->pgwidth - $hrwidth;
  704. $empty /= 2;
  705. $x += $empty;
  706. break;
  707. case 'R':
  708. $empty = $this->pgwidth - $hrwidth;
  709. $x += $empty;
  710. break;
  711. }
  712. $oldlinewidth = $this->LineWidth;
  713. $this->SetLineWidth(0.3);
  714. $this->Line($x,$y,$x+$hrwidth,$y);
  715. $this->SetLineWidth($oldlinewidth);
  716. $this->Ln(0.2*$this->lineheight);
  717. $this->SetDrawColor(0);
  718. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  719. break;
  720. case 'INS':
  721. $this->SetStyle('U',true);
  722. break;
  723. case 'SMALL':
  724. $newsize = $this->FontSizePt - 1;
  725. $this->SetFontSize($newsize);
  726. break;
  727. case 'BIG':
  728. $newsize = $this->FontSizePt + 1;
  729. $this->SetFontSize($newsize);
  730. case 'STRONG':
  731. $this->SetStyle('B',true);
  732. break;
  733. case 'CITE':
  734. case 'EM':
  735. $this->SetStyle('I',true);
  736. break;
  737. case 'TITLE':
  738. $this->titulo = true;
  739. break;
  740. case 'B':
  741. case 'I':
  742. case 'U':
  743. if( isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
  744. {
  745. $this->cssbegin=true;
  746. if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
  747. elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
  748. //Read Inline CSS
  749. if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
  750. //Look for name in the $this->CSS array
  751. $this->backupcss = $properties;
  752. if (!empty($properties)) $this->setCSS($properties); //name found in the CSS array!
  753. }
  754. $this->SetStyle($tag,true);
  755. break;
  756. case 'A':
  757. if (isset($attr['NAME']) and $attr['NAME'] != '') $this->textbuffer[] = array('','','',array(),'',false,false,$attr['NAME']); //an internal link (adds a space for recognition)
  758. if (isset($attr['HREF'])) $this->HREF=$attr['HREF'];
  759. break;
  760. case 'DIV':
  761. //in case of malformed HTML code. Example:(...)</div><li>Content</li><div>DIV1</div>(...)
  762. if ($this->listlvl > 0) // We are closing (omitted) OL/UL tag(s)
  763. {
  764. $this->buffer_on = false;
  765. if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
  766. $this->textbuffer = array();
  767. $this->listlvl--;
  768. $this->printlistbuffer();
  769. $this->pjustfinished = true; //act as if a paragraph just ended
  770. }
  771. $this->divbegin=true;
  772. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  773. if( isset($attr['ALIGN']) and $attr['ALIGN'] != '' ) $this->divalign = $align[strtolower($attr['ALIGN'])];
  774. if( isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
  775. {
  776. $this->cssbegin=true;
  777. if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
  778. elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
  779. //Read Inline CSS
  780. if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
  781. //Look for name in the $this->CSS array
  782. if (!empty($properties)) $this->setCSS($properties); //name found in the CSS array!
  783. }
  784. break;
  785. case 'IMG':
  786. if(!empty($this->textbuffer) and !$this->tablestart)
  787. {
  788. //Output previously buffered content and output image below
  789. //Set some default values
  790. $olddivwidth = $this->divwidth;
  791. $olddivheight = $this->divheight;
  792. if ( $this->divwidth == 0) $this->divwidth = $this->pgwidth - $x + $this->lMargin;
  793. if ( $this->divheight == 0) $this->divheight = $this->lineheight;
  794. //Print content
  795. $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
  796. $this->textbuffer=array();
  797. //Reset values
  798. $this->divwidth = $olddivwidth;
  799. $this->divheight = $olddivheight;
  800. $this->textbuffer=array();
  801. $this->Ln($this->lineheight);
  802. }
  803. if(isset($attr['SRC']))
  804. {
  805. $srcpath = $attr['SRC'];
  806. if(!isset($attr['WIDTH'])) $attr['WIDTH'] = 0;
  807. else $attr['WIDTH'] = ConvertSize($attr['WIDTH'],$this->pgwidth);//$attr['WIDTH'] /= 4;
  808. if(!isset($attr['HEIGHT'])) $attr['HEIGHT'] = 0;
  809. else $attr['HEIGHT'] = ConvertSize($attr['HEIGHT'],$this->pgwidth);//$attr['HEIGHT'] /= 4;
  810. if ($this->tdbegin)
  811. {
  812. $bak_x = $this->x;
  813. $bak_y = $this->y;
  814. //Check whether image exists locally or on the URL
  815. $f_exists = @fopen($srcpath,"rb");
  816. if (!$f_exists) //Show 'image not found' icon instead
  817. {
  818. if(!$this->shownoimg) break;
  819. $srcpath = str_replace("\\","/",dirname(__FILE__)) . "/";
  820. $srcpath .= 'no_img.gif';
  821. }
  822. $sizesarray = $this->Image($srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'],'','',false);
  823. $this->y = $bak_y;
  824. $this->x = $bak_x;
  825. }
  826. elseif($this->pbegin or $this->divbegin)
  827. {
  828. //In order to support <div align='center'><img ...></div>
  829. $ypos = 0;
  830. $bak_x = $this->x;
  831. $bak_y = $this->y;
  832. //Check whether image exists locally or on the URL
  833. $f_exists = @fopen($srcpath,"rb");
  834. if (!$f_exists) //Show 'image not found' icon instead
  835. {
  836. if(!$this->shownoimg) break;
  837. $srcpath = str_replace("\\","/",dirname(__FILE__)) . "/";
  838. $srcpath .= 'no_img.gif';
  839. }
  840. $sizesarray = $this->Image($srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'],'','',false);
  841. $this->y = $bak_y;
  842. $this->x = $bak_x;
  843. $xpos = '';
  844. switch($this->divalign)
  845. {
  846. case "C":
  847. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  848. $empty = ($this->pgwidth - $sizesarray['WIDTH'])/2;
  849. $xpos = 'xpos='.$empty.',';
  850. break;
  851. case "R":
  852. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  853. $empty = ($this->pgwidth - $sizesarray['WIDTH']);
  854. $xpos = 'xpos='.$empty.',';
  855. break;
  856. default: break;
  857. }
  858. $numberoflines = (integer)ceil($sizesarray['HEIGHT']/$this->lineheight) ;
  859. $ypos = $numberoflines * $this->lineheight;
  860. $this->textbuffer[] = array("���"/*identifier*/."type=image,ypos=$ypos,{$xpos}width=".$sizesarray['WIDTH'].",height=".$sizesarray['HEIGHT']."���".$sizesarray['OUTPUT']);
  861. 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--;}
  862. }
  863. else
  864. {
  865. $imgborder = 0;
  866. if (isset($attr['BORDER'])) $imgborder = ConvertSize($attr['BORDER'],$this->pgwidth);
  867. //Check whether image exists locally or on the URL
  868. $f_exists = @fopen($srcpath,"rb");
  869. if (!$f_exists) //Show 'image not found' icon instead
  870. {
  871. $srcpath = str_replace("\\","/",dirname(__FILE__)) . "/";
  872. $srcpath .= 'no_img.gif';
  873. }
  874. $sizesarray = $this->Image($srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'],'',$this->HREF); //Output Image
  875. $ini_x = $sizesarray['X'];
  876. $ini_y = $sizesarray['Y'];
  877. if ($imgborder)
  878. {
  879. $oldlinewidth = $this->LineWidth;
  880. $this->SetLineWidth($imgborder);
  881. $this->Rect($ini_x,$ini_y,$sizesarray['WIDTH'],$sizesarray['HEIGHT']);
  882. $this->SetLineWidth($oldlinewidth);
  883. }
  884. }
  885. if ($sizesarray['X'] < $this->x) $this->x = $this->lMargin;
  886. if ($this->tablestart)
  887. {
  888. $this->cell[$this->row][$this->col]['textbuffer'][] = array("���"/*identifier*/."type=image,width=".$sizesarray['WIDTH'].",height=".$sizesarray['HEIGHT']."���".$sizesarray['OUTPUT']);
  889. $this->cell[$this->row][$this->col]['s'] += $sizesarray['WIDTH'] + 1;// +1 == margin
  890. $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later
  891. if (!isset($this->cell[$this->row][$this->col]['w'])) $this->cell[$this->row][$this->col]['w'] = $sizesarray['WIDTH'] + 3;
  892. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $sizesarray['HEIGHT'] + 3;
  893. }
  894. }
  895. break;
  896. case 'BLOCKQUOTE':
  897. case 'BR':
  898. if($this->tablestart)
  899. {
  900. $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);
  901. $this->cell[$this->row][$this->col]['text'][] = "\n";
  902. 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
  903. 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
  904. $this->cell[$this->row][$this->col]['s'] = 0;// reset
  905. }
  906. 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);
  907. else {$this->Ln($this->lineheight);$this->blockjustfinished = true;}
  908. break;
  909. case 'P':
  910. //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
  911. if ($this->listlvl > 0) // We are closing (omitted) OL/UL tag(s)
  912. {
  913. $this->buffer_on = false;
  914. if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
  915. $this->textbuffer = array();
  916. $this->listlvl--;
  917. $this->printlistbuffer();
  918. $this->pjustfinished = true; //act as if a paragraph just ended
  919. }
  920. if ($this->tablestart)
  921. {
  922. $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);
  923. $this->cell[$this->row][$this->col]['text'][] = "\n";
  924. break;
  925. }
  926. $this->pbegin=true;
  927. if ($this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
  928. elseif (!$this->pjustfinished) $this->Ln($this->lineheight);
  929. //Save x,y coords in case we need to print borders...
  930. $this->oldx = $this->x;
  931. $this->oldy = $this->y;
  932. if(isset($attr['ALIGN'])) $this->divalign = $align[strtolower($attr['ALIGN'])];
  933. if(isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
  934. {
  935. $this->cssbegin=true;
  936. if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
  937. elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
  938. //Read Inline CSS
  939. if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
  940. //Look for name in the $this->CSS array
  941. $this->backupcss = $properties;
  942. if (!empty($properties)) $this->setCSS($properties); //name(id/class/style) found in the CSS array!
  943. }
  944. break;
  945. case 'SPAN':
  946. $this->buffer_on = true;
  947. //Save x,y coords in case we need to print borders...
  948. $this->oldx = $this->x;
  949. $this->oldy = $this->y;
  950. if( isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
  951. {
  952. $this->cssbegin=true;
  953. if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
  954. elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
  955. //Read Inline CSS
  956. if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
  957. //Look for name in the $this->CSS array
  958. $this->backupcss = $properties;
  959. if (!empty($properties)) $this->setCSS($properties); //name found in the CSS array!
  960. }
  961. break;
  962. case 'PRE':
  963. if($this->tablestart)
  964. {
  965. $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);
  966. $this->cell[$this->row][$this->col]['text'][] = "\n";
  967. }
  968. 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);
  969. else
  970. {
  971. if ($this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
  972. elseif (!$this->pjustfinished) $this->Ln($this->lineheight);
  973. $this->buffer_on = true;
  974. //Save x,y coords in case we need to print borders...
  975. $this->oldx = $this->x;
  976. $this->oldy = $this->y;
  977. if(isset($attr['ALIGN'])) $this->divalign = $align[strtolower($attr['ALIGN'])];
  978. if(isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
  979. {
  980. $this->cssbegin=true;
  981. if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
  982. elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
  983. //Read Inline CSS
  984. if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
  985. //Look for name in the $this->CSS array
  986. $this->backupcss = $properties;
  987. if (!empty($properties)) $this->setCSS($properties); //name(id/class/style) found in the CSS array!
  988. }
  989. }
  990. case 'TT':
  991. case 'KBD':
  992. case 'SAMP':
  993. case 'CODE':
  994. $this->SetFont('courier');
  995. $this->currentfont='courier';
  996. break;
  997. case 'TEXTAREA':
  998. $this->buffer_on = true;
  999. $colsize = 20; //HTML default value
  1000. $rowsize = 2; //HTML default value
  1001. if (isset($attr['COLS'])) $colsize = $attr['COLS'];
  1002. if (isset($attr['ROWS'])) $rowsize = $attr['ROWS'];
  1003. if (!$this->tablestart)
  1004. {
  1005. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  1006. $this->col = $colsize;
  1007. $this->row = $rowsize;
  1008. }
  1009. else //it is inside a table
  1010. {
  1011. $this->specialcontent = "type=textarea,lines=$rowsize,width=".((2.2*$colsize) + 3); //Activate form info in order to paint FORM elements within table
  1012. $this->cell[$this->row][$this->col]['s'] += (2.2*$colsize) + 6;// +6 == margin
  1013. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = 1.1*$this->lineheight*$rowsize + 2.5;
  1014. }
  1015. break;
  1016. case 'SELECT':
  1017. $this->specialcontent = "type=select"; //Activate form info in order to paint FORM elements within table
  1018. break;
  1019. case 'OPTION':
  1020. $this->selectoption['ACTIVE'] = true;
  1021. if (empty($this->selectoption))
  1022. {
  1023. $this->selectoption['MAXWIDTH'] = '';
  1024. $this->selectoption['SELECTED'] = '';
  1025. }
  1026. if (isset($attr['SELECTED'])) $this->selectoption['SELECTED'] = '';
  1027. break;
  1028. case 'FORM':
  1029. if($this->tablestart)
  1030. {
  1031. $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);
  1032. $this->cell[$this->row][$this->col]['text'][] = "\n";
  1033. }
  1034. elseif ($this->x != $this->lMargin) $this->Ln($this->lineheight); //Skip a line, if needed
  1035. break;
  1036. case 'INPUT':
  1037. if (!isset($attr['TYPE'])) $attr['TYPE'] == ''; //in order to allow default 'TEXT' form (in case of malformed HTML code)
  1038. if (!$this->tablestart)
  1039. {
  1040. switch(strtoupper($attr['TYPE'])){
  1041. case 'CHECKBOX': //Draw Checkbox
  1042. $checked = false;
  1043. if (isset($attr['CHECKED'])) $checked = true;
  1044. $this->SetFillColor(235,235,235);
  1045. $this->x += 3;
  1046. $this->Rect($this->x,$this->y+1,3,3,'DF');
  1047. if ($checked)
  1048. {
  1049. $this->Line($this->x,$this->y+1,$this->x+3,$this->y+1+3);
  1050. $this->Line($this->x,$this->y+1+3,$this->x+3,$this->y+1);
  1051. }
  1052. $this->SetFillColor(255);
  1053. $this->x += 3.5;
  1054. break;
  1055. case 'RADIO': //Draw Radio button
  1056. $checked = false;
  1057. if (isset($attr['CHECKED'])) $checked = true;
  1058. $this->x += 4;
  1059. $this->Circle($this->x,$this->y+2.2,1,'D');
  1060. $this->_out('0.000 g');
  1061. if ($checked) $this->Circle($this->x,$this->y+2.2,0.4,'DF');
  1062. $this->Write(5,$texto,$this->x);
  1063. $this->x += 2;
  1064. break;
  1065. case 'BUTTON': // Draw a button
  1066. case 'SUBMIT':
  1067. case 'RESET':
  1068. $texto='';
  1069. if (isset($attr['VALUE'])) $texto = $attr['VALUE'];
  1070. $nihil = 2.5;
  1071. $this->x += 2;
  1072. $this->SetFillColor(190,190,190);
  1073. $this->Rect($this->x,$this->y,$this->GetStringWidth($texto)+2*$nihil,4.5,'DF'); // 4.5 in order to avoid overlapping
  1074. $this->x += $nihil;
  1075. $this->Write(5,$texto,$this->x);
  1076. $this->x += $nihil;
  1077. $this->SetFillColor(255);
  1078. break;
  1079. case 'PASSWORD':
  1080. if (isset($attr['VALUE']))
  1081. {
  1082. $num_stars = strlen($attr['VALUE']);
  1083. $attr['VALUE'] = str_repeat('*',$num_stars);
  1084. }
  1085. case 'TEXT': //Draw TextField
  1086. default: //default == TEXT
  1087. $texto='';
  1088. if (isset($attr['VALUE'])) $texto = $attr['VALUE'];
  1089. $tamanho = 20;
  1090. if (isset($attr['SIZE']) and ctype_digit($attr['SIZE']) ) $tamanho = $attr['SIZE'];
  1091. $this->SetFillColor(235,235,235);
  1092. $this->x += 2;
  1093. $this->Rect($this->x,$this->y,2*$tamanho,4.5,'DF');// 4.5 in order to avoid overlapping
  1094. if ($texto != '')
  1095. {
  1096. $this->x += 1;
  1097. $this->Write(5,$texto,$this->x);
  1098. $this->x -= $this->GetStringWidth($texto);
  1099. }
  1100. $this->SetFillColor(255);
  1101. $this->x += 2*$tamanho;
  1102. break;
  1103. }
  1104. }
  1105. else //we are inside a table
  1106. {
  1107. $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later
  1108. $type = '';
  1109. $text = '';
  1110. $height = 0;
  1111. $width = 0;
  1112. switch(strtoupper($attr['TYPE'])){
  1113. case 'CHECKBOX': //Draw Checkbox
  1114. $checked = false;
  1115. if (isset($attr['CHECKED'])) $checked = true;
  1116. $text = $checked;
  1117. $type = 'CHECKBOX';
  1118. $width = 4;
  1119. $this->cell[$this->row][$this->col]['textbuffer'][] = array("���"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."���".$text);
  1120. $this->cell[$this->row][$this->col]['s'] += $width;
  1121. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight;
  1122. break;
  1123. case 'RADIO': //Draw Radio button
  1124. $checked = false;
  1125. if (isset($attr['CHECKED'])) $checked = true;
  1126. $text = $checked;
  1127. $type = 'RADIO';
  1128. $width = 3;
  1129. $this->cell[$this->row][$this->col]['textbuffer'][] = array("���"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."���".$text);
  1130. $this->cell[$this->row][$this->col]['s'] += $width;
  1131. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight;
  1132. break;
  1133. case 'BUTTON': $type = 'BUTTON'; // Draw a button
  1134. case 'SUBMIT': if ($type == '') $type = 'SUBMIT';
  1135. case 'RESET': if ($type == '') $type = 'RESET';
  1136. $texto='';
  1137. if (isset($attr['VALUE'])) $texto = " " . $attr['VALUE'] . " ";
  1138. $text = $texto;
  1139. $width = $this->GetStringWidth($texto)+3;
  1140. $this->cell[$this->row][$this->col]['textbuffer'][] = array("���"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."���".$text);
  1141. $this->cell[$this->row][$this->col]['s'] += $width;
  1142. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2;
  1143. break;
  1144. case 'PASSWORD':
  1145. if (isset($attr['VALUE']))
  1146. {
  1147. $num_stars = strlen($attr['VALUE']);
  1148. $attr['VALUE'] = str_repeat('*',$num_stars);
  1149. }
  1150. $type = 'PASSWORD';
  1151. case 'TEXT': //Draw TextField
  1152. default: //default == TEXT
  1153. $texto='';
  1154. if (isset($attr['VALUE'])) $texto = $attr['VALUE'];
  1155. $tamanho = 20;
  1156. if (isset($attr['SIZE']) and ctype_digit($attr['SIZE']) ) $tamanho = $attr['SIZE'];
  1157. $text = $texto;
  1158. $width = 2*$tamanho;
  1159. if ($type == '') $type = 'TEXT';
  1160. $this->cell[$this->row][$this->col]['textbuffer'][] = array("���"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."���".$text);
  1161. $this->cell[$this->row][$this->col]['s'] += $width;
  1162. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2;
  1163. break;
  1164. }
  1165. }
  1166. break;
  1167. case 'FONT':
  1168. //Font size is ignored for now
  1169. if (isset($attr['COLOR']) and $attr['COLOR']!='')
  1170. {
  1171. $cor = ConvertColor($attr['COLOR']);
  1172. //If something goes wrong switch color to black
  1173. $cor['R'] = (isset($cor['R'])?$cor['R']:0);
  1174. $cor['G'] = (isset($cor['G'])?$cor['G']:0);
  1175. $cor['B'] = (isset($cor['B'])?$cor['B']:0);
  1176. $this->colorarray = $cor;
  1177. $this->SetTextColor($cor['R'],$cor['G'],$cor['B']);
  1178. $this->issetcolor = true;
  1179. }
  1180. if (isset($attr['FACE']) and in_array(strtolower($attr['FACE']), $this->fontlist))
  1181. {
  1182. $this->SetFont(strtolower($attr['FACE']));
  1183. $this->issetfont=true;
  1184. }
  1185. //'If' disabled in this version due lack of testing (you may enable it if you want)
  1186. // if (isset($attr['FACE']) and in_array(strtolower($attr['FACE']), $this->fontlist) and isset($attr['SIZE']) and $attr['SIZE']!='') {
  1187. // $this->SetFont(strtolower($attr['FACE']),'',$attr['SIZE']);
  1188. // $this->issetfont=true;
  1189. // }
  1190. break;
  1191. }//end of switch
  1192. $this->pjustfinished=false;
  1193. }
  1194. function CloseTag($tag)
  1195. {
  1196. //! @return void
  1197. //Closing tag
  1198. if($tag=='OPTION') $this->selectoption['ACTIVE'] = false;
  1199. if($tag=='BDO') $this->divrevert = false;
  1200. if($tag=='INS') $tag='U';
  1201. if($tag=='STRONG') $tag='B';
  1202. if($tag=='EM' or $tag=='CITE') $tag='I';
  1203. if($tag=='OUTLINE')
  1204. {
  1205. if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
  1206. {
  1207. //Deactivate $this->outlineparam for its info is already stored inside $this->textbuffer
  1208. //if (isset($this->outlineparam['OLDWIDTH'])) $this->SetTextOutline($this->outlineparam['OLDWIDTH']);
  1209. $this->SetTextOutline(false);
  1210. $this->outlineparam=array();
  1211. //Save x,y coords ???
  1212. $x = $this->x;
  1213. $y = $this->y;
  1214. //Set some default values
  1215. $this->divwidth = $this->pgwidth - $x + $this->lMargin;
  1216. //Print content
  1217. $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
  1218. $this->textbuffer=array();
  1219. //Reset values
  1220. $this->Reset();
  1221. $this->buffer_on=false;
  1222. }
  1223. $this->SetTextOutline(false);
  1224. $this->outlineparam=array();
  1225. }
  1226. if($tag=='A')
  1227. {
  1228. if(!$this->pbegin and !$this->divbegin and !$this->tablestart and !$this->buffer_on)
  1229. {
  1230. //Deactivate $this->HREF for its info is already stored inside $this->textbuffer
  1231. $this->HREF='';
  1232. //Save x,y coords ???
  1233. $x = $this->x;
  1234. $y = $this->y;
  1235. //Set some default values
  1236. $this->divwidth = $this->pgwidth - $x + $this->lMargin;
  1237. //Print content
  1238. $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
  1239. $this->textbuffer=array();
  1240. //Reset values
  1241. $this->Reset();
  1242. }
  1243. $this->HREF='';
  1244. }
  1245. if($tag=='TH') $this->SetStyle('B',false);
  1246. if($tag=='TH' or $tag=='TD') $this->tdbegin = false;
  1247. if($tag=='SPAN')
  1248. {
  1249. if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
  1250. {
  1251. if($this->cssbegin)
  1252. {
  1253. //Check if we have borders to print
  1254. if ($this->cssbegin and ($this->divborder or $this->dash_on or $this->dotted_on or $this->divbgcolor))
  1255. {
  1256. $texto='';
  1257. foreach($this->textbuffer as $vetor) $texto.=$vetor[0];
  1258. $tempx = $this->x;
  1259. if($this->divbgcolor) $this->Cell($this->GetStringWidth($texto),$this->lineheight,'',$this->divborder,'','L',$this->divbgcolor);
  1260. if ($this->dash_on) $this->Rect($this->oldx,$this->oldy,$this->GetStringWidth($texto),$this->lineheight);
  1261. if ($this->dotted_on) $this->DottedRect($this->x - $this->GetStringWidth($texto),$this->y,$this->GetStringWidth($texto),$this->lineheight);
  1262. $this->x = $tempx;
  1263. $this->x -= 1; //adjust alignment
  1264. }
  1265. $this->cssbegin=false;
  1266. $this->backupcss=array();
  1267. }
  1268. //Save x,y coords ???
  1269. $x = $this->x;
  1270. $y = $this->y;
  1271. //Set some default values
  1272. $this->divwidth = $this->pgwidth - $x + $this->lMargin;
  1273. //Print content
  1274. $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
  1275. $this->textbuffer=array();
  1276. //Reset values
  1277. $this->Reset();
  1278. }
  1279. $this->buffer_on=false;
  1280. }
  1281. if($tag=='P' or $tag=='DIV') //CSS in BLOCK mode
  1282. {
  1283. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  1284. if(!$this->tablestart)
  1285. {
  1286. if ($this->divwidth == 0) $this->divwidth = $this->pgwidth;
  1287. if ($tag=='P')
  1288. {
  1289. $this->pbegin=false;
  1290. $this->pjustfinished=true;
  1291. }
  1292. else $this->divbegin=false;
  1293. $content='';
  1294. foreach($this->textbuffer as $aux) $content .= $aux[0];
  1295. $numlines = $this->WordWrap($content,$this->divwidth);
  1296. if ($this->divheight == 0) $this->divheight = $numlines * 5;
  1297. //Print content
  1298. $this->printbuffer($this->textbuffer);
  1299. $this->textbuffer=array();
  1300. if ($tag=='P') $this->Ln($this->lineheight);
  1301. }//end of 'if (!this->tablestart)'
  1302. //Reset values
  1303. $this->Reset();
  1304. $this->cssbegin=false;
  1305. $this->backupcss=array();
  1306. }
  1307. if($tag=='TABLE') { // TABLE-END
  1308. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  1309. $this->table['cells'] = $this->cell;
  1310. $this->table['wc'] = array_pad(array(),$this->table['nc'],array('miw'=>0,'maw'=>0));
  1311. $this->table['hr'] = array_pad(array(),$this->table['nr'],0);
  1312. $this->_tableColumnWidth($this->table);
  1313. $this->_tableWidth($this->table);
  1314. $this->_tableHeight($this->table);
  1315. //Output table on PDF
  1316. $this->_tableWrite($this->table);
  1317. //Reset values
  1318. $this->tablestart=false; //bool
  1319. $this->table=array(); //array
  1320. $this->cell=array(); //array
  1321. $this->col=-1; //int
  1322. $this->row=-1; //int
  1323. $this->Reset();
  1324. $this->Ln(0.5*$this->lineheight);
  1325. }
  1326. if(($tag=='UL') or ($tag=='OL')) {
  1327. if ($this->buffer_on == false) $this->listnum--;//Adjust minor BUG (this happens when there are two </OL> together)
  1328. if ($this->listlvl == 1) // We are closing the last OL/UL tag
  1329. {
  1330. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  1331. $this->buffer_on = false;
  1332. if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
  1333. $this->textbuffer = array();
  1334. $this->listlvl--;
  1335. $this->printlistbuffer();
  1336. }
  1337. else // returning one level
  1338. {
  1339. if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
  1340. $this->textbuffer = array();
  1341. $occur = $this->listoccur[$this->listlvl];
  1342. $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
  1343. $this->listlvl--;
  1344. $occur = $this->listoccur[$this->listlvl];
  1345. $this->listnum = $this->listlist[$this->listlvl][$occur]['MAXNUM']; // recover previous level's number
  1346. $this->listtype = $this->listlist[$this->listlvl][$occur]['TYPE']; // recover previous level's type
  1347. $this->buffer_on = false;
  1348. }
  1349. }
  1350. if($tag=='H1' or $tag=='H2' or $tag=='H3' or $tag=='H4' or $tag=='H5' or $tag=='H6')
  1351. {
  1352. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  1353. if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
  1354. {
  1355. //These 2 codelines are useless?
  1356. $texto='';
  1357. foreach($this->textbuffer as $vetor) $texto.=$vetor[0];
  1358. //Save x,y coords ???
  1359. $x = $this->x;
  1360. $y = $this->y;
  1361. //Set some default values
  1362. $this->divwidth = $this->pgwidth;
  1363. //Print content
  1364. $this->printbuffer($this->textbuffer);
  1365. $this->textbuffer=array();
  1366. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  1367. //Reset values
  1368. $this->Reset();
  1369. }
  1370. $this->buffer_on=false;
  1371. $this->lineheight = 5;
  1372. $this->Ln($this->lineheight);
  1373. $this->SetFontSize(11);
  1374. $this->SetStyle('B',false);
  1375. }
  1376. if($tag=='TITLE') {$this->titulo=false; $this->blockjustfinished = true;}
  1377. if($tag=='FORM') $this->Ln($this->lineheight);
  1378. if($tag=='PRE')
  1379. {
  1380. if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
  1381. {
  1382. if ($this->divwidth == 0) $this->divwidth = $this->pgwidth;
  1383. $content='';
  1384. foreach($this->textbuffer as $aux) $content .= $aux[0];
  1385. $numlines = $this->WordWrap($content,$this->divwidth);
  1386. if ($this->divheight == 0) $this->divheight = $numlines * 5;
  1387. //Print content
  1388. $this->textbuffer[0][0] = ltrim($this->textbuffer[0][0]); //Remove exceeding left-side space
  1389. $this->printbuffer($this->textbuffer);
  1390. $this->textbuffer=array();
  1391. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  1392. //Reset values
  1393. $this->Reset();
  1394. $this->Ln(1.1*$this->lineheight);
  1395. }
  1396. if($this->tablestart)
  1397. {
  1398. $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);
  1399. $this->cell[$this->row][$this->col]['text'][] = "\n";
  1400. }
  1401. 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);
  1402. $this->cssbegin=false;
  1403. $this->backupcss=array();
  1404. $this->buffer_on = false;
  1405. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  1406. $this->pjustfinished = true; //behaves the same way
  1407. }
  1408. if($tag=='CODE' or $tag=='PRE' or $tag=='TT' or $tag=='KBD' or $tag=='SAMP')
  1409. {
  1410. $this->currentfont='';
  1411. $this->SetFont('arial');
  1412. }
  1413. if($tag=='B' or $tag=='I' or $tag=='U')
  1414. {
  1415. $this->SetStyle($tag,false);
  1416. if ($this->cssbegin and !$this->divbegin and !$this->pbegin and !$this->buffer_on)
  1417. {
  1418. //Reset values
  1419. $this->Reset();
  1420. $this->cssbegin=false;
  1421. $this->backupcss=array();
  1422. }
  1423. }
  1424. if($tag=='TEXTAREA')
  1425. {
  1426. if (!$this->tablestart) //not inside a table
  1427. {
  1428. //Draw arrows too?
  1429. $texto = '';
  1430. foreach($this->textbuffer as $v) $texto .= $v[0];
  1431. $this->SetFillColor(235,235,235);
  1432. $this->SetFont('courier');
  1433. $this->x +=3;
  1434. $linesneeded = $this->WordWrap($texto,($this->col*2.2)+3);
  1435. if ( $linesneeded > $this->row ) //Too many words inside textarea
  1436. {
  1437. $textoaux = explode("\n",$texto);
  1438. $texto = '';
  1439. for($i=0;$i < $this->row;$i++)
  1440. {
  1441. if ($i == $this->row-1) $texto .= $textoaux[$i];
  1442. else $texto .= $textoaux[$i] . "\n";
  1443. }
  1444. //Inform the user that some text has been truncated
  1445. $texto{strlen($texto)-1} = ".";
  1446. $texto{strlen($texto)-2} = ".";
  1447. $texto{strlen($texto)-3} = ".";
  1448. }
  1449. $backup_y = $this->y;
  1450. $this->Rect($this->x,$this->y,(2.2*$this->col)+6,5*$this->row,'DF');
  1451. if ($texto != '') $this->MultiCell((2.2*$this->col)+6,$this->lineheight,$texto);
  1452. $this->y = $backup_y + $this->row*$this->lineheight;
  1453. $this->SetFont('arial');
  1454. }
  1455. else //inside a table
  1456. {
  1457. $this->cell[$this->row][$this->col]['textbuffer'][] = $this->textbuffer[0];
  1458. $this->cell[$this->row][$this->col]['text'][] = $this->textbuffer[0];
  1459. $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later
  1460. $this->specialcontent = '';
  1461. }
  1462. $this->SetFillColor(255);
  1463. $this->textbuffer=array();
  1464. $this->buffer_on = false;
  1465. }
  1466. if($tag=='SELECT')
  1467. {
  1468. $texto = '';
  1469. $tamanho = 0;
  1470. if (isset($this->selectoption['MAXWIDTH'])) $tamanho = $this->selectoption['MAXWIDTH'];
  1471. if ($this->tablestart)
  1472. {
  1473. $texto = "���".$this->specialcontent."���".$this->selectoption['SELECTED'];
  1474. $aux = explode("���",$texto);
  1475. $texto = $aux[2];
  1476. $texto = "���".$aux[1].",width=$tamanho,height=".($this->lineheight + 2)."���".$texto;
  1477. $this->cell[$this->row][$this->col]['s'] += $tamanho + 7; // margin + arrow box
  1478. $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later
  1479. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2;
  1480. $this->cell[$this->row][$this->col]['textbuffer'][] = array($texto);
  1481. $this->cell[$this->row][$this->col]['text'][] = '';
  1482. }
  1483. else //not inside a table
  1484. {
  1485. $texto = $this->selectoption['SELECTED'];
  1486. $this->SetFillColor(235,235,235);
  1487. $this->x += 2;
  1488. $this->Rect($this->x,$this->y,$tamanho+2,5,'DF');//+2 margin
  1489. $this->x += 1;
  1490. if ($texto != '') $this->Write(5,$texto,$this->x);
  1491. $this->x += $tamanho - $this->GetStringWidth($texto) + 2;
  1492. $this->SetFillColor(190,190,190);
  1493. $this->Rect($this->x-1,$this->y,5,5,'DF'); //Arrow Box
  1494. $this->SetFont('zapfdingbats');
  1495. $this->Write(5,chr(116),$this->x); //Down arrow
  1496. $this->SetFont('arial');
  1497. $this->SetFillColor(255);
  1498. $this->x += 1;
  1499. }
  1500. $this->selectoption = array();
  1501. $this->specialcontent = '';
  1502. $this->textbuffer = array();
  1503. }
  1504. if($tag=='SUB' or $tag=='SUP') //subscript or superscript
  1505. {
  1506. if(!$this->pbegin and !$this->divbegin and !$this->tablestart and !$this->buffer_on and !$this->strike)
  1507. {
  1508. //Deactivate $this->SUB/SUP for its info is already stored inside $this->textbuffer
  1509. $this->SUB=false;
  1510. $this->SUP=false;
  1511. //Save x,y coords ???
  1512. $x = $this->x;
  1513. $y = $this->y;
  1514. //Set some default values
  1515. $this->divwidth = $this->pgwidth - $x + $this->lMargin;
  1516. //Print content
  1517. $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
  1518. $this->textbuffer=array();
  1519. //Reset values
  1520. $this->Reset();
  1521. }
  1522. $this->SUB=false;
  1523. $this->SUP=false;
  1524. }
  1525. if($tag=='S' or $tag=='STRIKE' or $tag=='DEL')
  1526. {
  1527. if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
  1528. {
  1529. //Deactivate $this->strike for its info is already stored inside $this->textbuffer
  1530. $this->strike=false;
  1531. //Save x,y coords ???
  1532. $x = $this->x;
  1533. $y = $this->y;
  1534. //Set some default values
  1535. $this->divwidth = $this->pgwidth - $x + $this->lMargin;
  1536. //Print content
  1537. $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
  1538. $this->textbuffer=array();
  1539. //Reset values
  1540. $this->Reset();
  1541. }
  1542. $this->strike=false;
  1543. }
  1544. if($tag=='ADDRESS' or $tag=='CENTER') // <ADDRESS> or <CENTER> tag
  1545. {
  1546. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  1547. if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
  1548. {
  1549. //Save x,y coords ???
  1550. $x = $this->x;
  1551. $y = $this->y;
  1552. //Set some default values
  1553. $this->divwidth = $this->pgwidth - $x + $this->lMargin;
  1554. //Print content
  1555. $this->printbuffer($this->textbuffer);
  1556. $this->textbuffer=array();
  1557. //Reset values
  1558. $this->Reset();
  1559. }
  1560. $this->buffer_on=false;
  1561. if ($tag == 'ADDRESS') $this->SetStyle('I',false);
  1562. }
  1563. if($tag=='BIG')
  1564. {
  1565. $newsize = $this->FontSizePt - 1;
  1566. $this->SetFontSize($newsize);
  1567. $this->SetStyle('B',false);
  1568. }
  1569. if($tag=='SMALL')
  1570. {
  1571. $newsize = $this->FontSizePt + 1;
  1572. $this->SetFontSize($newsize);
  1573. }
  1574. if($tag=='FONT')
  1575. {
  1576. if ($this->issetcolor == true)
  1577. {
  1578. $this->colorarray = array();
  1579. $this->SetTextColor(0);
  1580. $this->issetcolor = false;
  1581. }
  1582. if ($this->issetfont)
  1583. {
  1584. $this->SetFont('arial');
  1585. $this->issetfont=false;
  1586. }
  1587. if ($this->cssbegin)
  1588. {
  1589. //Get some attributes back!
  1590. $this->setCSS($this->backupcss);
  1591. }
  1592. }
  1593. }
  1594. function printlistbuffer()
  1595. {
  1596. //! @return void
  1597. //! @desc Prints all list-related buffered info
  1598. //Save x coordinate
  1599. $x = $this->oldx;
  1600. foreach($this->listitem as $item)
  1601. {
  1602. //Set default width & height values
  1603. $this->divwidth = $this->pgwidth;
  1604. $this->divheight = $this->lineheight;
  1605. //Get list's buffered data
  1606. $lvl = $item[0];
  1607. $num = $item[1];
  1608. $this->textbuffer = $item[2];
  1609. $occur = $item[3];
  1610. $type = $this->listlist[$lvl][$occur]['TYPE'];
  1611. $maxnum = $this->listlist[$lvl][$occur]['MAXNUM'];
  1612. switch($type) //Format type
  1613. {
  1614. case 'A':
  1615. $num = dec2alpha($num,true);
  1616. $maxnum = dec2alpha($maxnum,true);
  1617. $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
  1618. break;
  1619. case 'a':
  1620. $num = dec2alpha($num,false);
  1621. $maxnum = dec2alpha($maxnum,false);
  1622. $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
  1623. break;
  1624. case 'I':
  1625. $num = dec2roman($num,true);
  1626. $maxnum = dec2roman($maxnum,true);
  1627. $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
  1628. break;
  1629. case 'i':
  1630. $num = dec2roman($num,false);
  1631. $maxnum = dec2roman($maxnum,false);
  1632. $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
  1633. break;
  1634. case '1':
  1635. $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
  1636. break;
  1637. case 'disc':
  1638. $type = chr(149);
  1639. break;
  1640. case 'square':
  1641. $type = chr(110); //black square on Zapfdingbats font
  1642. break;
  1643. case 'circle':
  1644. $type = chr(186);
  1645. break;
  1646. default: break;
  1647. }
  1648. $this->x = (5*$lvl) + $x; //Indent list
  1649. //Get bullet width including margins
  1650. $oldsize = $this->FontSize * $this->k;
  1651. if ($type == chr(110)) $this->SetFont('zapfdingbats','',5);
  1652. $type .= ' ';
  1653. $blt_width = $this->GetStringWidth($type)+$this->cMargin*2;
  1654. //Output bullet
  1655. $this->Cell($blt_width,5,$type,'','','L');
  1656. $this->SetFont('arial','',$oldsize);
  1657. $this->divwidth = $this->divwidth + $this->lMargin - $this->x;
  1658. //Print content
  1659. $this->printbuffer($this->textbuffer);
  1660. $this->textbuffer=array();
  1661. }
  1662. //Reset all used values
  1663. $this->listoccur = array();
  1664. $this->listitem = array();
  1665. $this->listlist = array();
  1666. $this->listlvl = 0;
  1667. $this->listnum = 0;
  1668. $this->listtype = '';
  1669. $this->textbuffer = array();
  1670. $this->divwidth = 0;
  1671. $this->divheight = 0;
  1672. $this->oldx = -1;
  1673. //At last, but not least, skip a line
  1674. $this->Ln($this->lineheight);
  1675. }
  1676. function printbuffer($arrayaux,$outofblock=false,$is_table=false)
  1677. {
  1678. //! @return headache
  1679. //! @desc Prepares buffered text to be printed with FlowingBlock()
  1680. //Save some previous parameters
  1681. $save = array();
  1682. $save['strike'] = $this->strike;
  1683. $save['SUP'] = $this->SUP;
  1684. $save['SUB'] = $this->SUB;
  1685. $save['DOTTED'] = $this->dotted_on;
  1686. $save['DASHED'] = $this->dash_on;
  1687. $this->SetDash(); //restore to no dash
  1688. $this->dash_on = false;
  1689. $this->dotted_on = false;
  1690. $bak_y = $this->y;
  1691. $bak_x = $this->x;
  1692. $align = $this->divalign;
  1693. $oldpage = $this->page;
  1694. //Overall object size == $old_height
  1695. //Line height == $this->divheight
  1696. $old_height = $this->divheight;
  1697. if ($is_table)
  1698. {
  1699. $this->divheight = 1.1*$this->lineheight;
  1700. $fill = 0;
  1701. }
  1702. else
  1703. {
  1704. $this->divheight = $this->lineheight;
  1705. if ($this->FillColor == '1.000 g') $fill = 0; //avoid useless background painting (1.000 g == white background color)
  1706. else $fill = 1;
  1707. }
  1708. $this->newFlowingBlock( $this->divwidth,$this->divheight,$this->divborder,$align,$fill,$is_table);
  1709. $array_size = count($arrayaux);
  1710. for($i=0;$i < $array_size; $i++)
  1711. {
  1712. $vetor = $arrayaux[$i];
  1713. if ($i == 0 and $vetor[0] != "\n") $vetor[0] = ltrim($vetor[0]);
  1714. if (empty($vetor[0]) and empty($vetor[7])) continue; //Ignore empty text and not carrying an internal link
  1715. //Activating buffer properties
  1716. if(isset($vetor[10]) and !empty($vetor[10])) //Background color
  1717. {
  1718. $cor = $vetor[10];
  1719. $this->SetFillColor($cor['R'],$cor['G'],$cor['B']);
  1720. $this->divbgcolor = true;
  1721. }
  1722. if(isset($vetor[9]) and !empty($vetor[9])) // Outline parameters
  1723. {
  1724. $cor = $vetor[9]['COLOR'];
  1725. $outlinewidth = $vetor[9]['WIDTH'];
  1726. $this->SetTextOutline($outlinewidth,$cor['R'],$cor['G'],$cor['B']);
  1727. $this->outline_on = true;
  1728. }
  1729. if(isset($vetor[8]) and $vetor[8] === true) // strike-through the text
  1730. {
  1731. $this->strike = true;
  1732. }
  1733. if(isset($vetor[7]) and $vetor[7] != '') // internal link: <a name="anyvalue">
  1734. {
  1735. $this->internallink[$vetor[7]] = array("Y"=>$this->y,"PAGE"=>$this->page );
  1736. $this->Bookmark($vetor[7]." (pg. $this->page)",0,$this->y);
  1737. if (empty($vetor[0])) continue; //Ignore empty text
  1738. }
  1739. if(isset($vetor[6]) and $vetor[6] === true) // Subscript
  1740. {
  1741. $this->SUB = true;
  1742. $this->SetFontSize(6);
  1743. }
  1744. if(isset($vetor[5]) and $vetor[5] === true) // Superscript
  1745. {
  1746. $this->SUP = true;
  1747. $this->SetFontSize(6);
  1748. }
  1749. if(isset($vetor[4]) and $vetor[4] != '') $this->SetFont($vetor[4]); // Font Family
  1750. if (!empty($vetor[3])) //Font Color
  1751. {
  1752. $cor = $vetor[3];
  1753. $this->SetTextColor($cor['R'],$cor['G'],$cor['B']);
  1754. }
  1755. if(isset($vetor[2]) and $vetor[2] != '') //Bold,Italic,Underline styles
  1756. {
  1757. if (strpos($vetor[2],"B") !== false) $this->SetStyle('B',true);
  1758. if (strpos($vetor[2],"I") !== false) $this->SetStyle('I',true);
  1759. if (strpos($vetor[2],"U") !== false) $this->SetStyle('U',true);
  1760. }
  1761. if(isset($vetor[1]) and $vetor[1] != '') //LINK
  1762. {
  1763. if (strpos($vetor[1],".") === false) //assuming every external link has a dot indicating extension (e.g: .html .txt .zip www.somewhere.com etc.)
  1764. {
  1765. //Repeated reference to same anchor?
  1766. while(array_key_exists($vetor[1],$this->internallink)) $vetor[1]="#".$vetor[1];
  1767. $this->internallink[$vetor[1]] = $this->AddLink();
  1768. $vetor[1] = $this->internallink[$vetor[1]];
  1769. }
  1770. $this->HREF = $vetor[1];
  1771. $this->SetTextColor(0,0,255);
  1772. $this->SetStyle('U',true);
  1773. }
  1774. //Print-out special content
  1775. if (isset($vetor[0]) and $vetor[0]{0} == '�' and $vetor[0]{1} == '�' and $vetor[0]{2} == '�') //identifier has been identified!
  1776. {
  1777. $content = explode("���",$vetor[0]);
  1778. $texto = $content[2];
  1779. $content = explode(",",$content[1]);
  1780. foreach($content as $value)
  1781. {
  1782. $value = explode("=",$value);
  1783. $specialcontent[$value[0]] = $value[1];
  1784. }
  1785. if ($this->flowingBlockAttr[ 'contentWidth' ] > 0) // Print out previously accumulated content
  1786. {
  1787. $width_used = $this->flowingBlockAttr[ 'contentWidth' ] / $this->k;
  1788. //Restart Flowing Block
  1789. $this->finishFlowingBlock($outofblock);
  1790. $this->x = $bak_x + ($width_used % $this->divwidth) + 0.5;// 0.5 == margin
  1791. $this->y -= ($this->lineheight + 0.5);
  1792. $extrawidth = 0; //only to be used in case $specialcontent['width'] does not contain all used width (e.g. Select Box)
  1793. if ($specialcontent['type'] == 'select') $extrawidth = 7; //arrow box + margin
  1794. if(($this->x - $bak_x) + $specialcontent['width'] + $extrawidth > $this->divwidth )
  1795. {
  1796. $this->x = $bak_x;
  1797. $this->y += $this->lineheight - 1;
  1798. }
  1799. $this->newFlowingBlock( $this->divwidth,$this->divheight,$this->divborder,$align,$fill,$is_table );
  1800. }
  1801. switch(strtoupper($specialcontent['type']))
  1802. {
  1803. case 'IMAGE':
  1804. //xpos and ypos used in order to support: <div align='center'><img ...></div>
  1805. $xpos = 0;
  1806. $ypos = 0;
  1807. if (isset($specialcontent['ypos']) and $specialcontent['ypos'] != '') $ypos = (float)$specialcontent['ypos'];
  1808. if (isset($specialcontent['xpos']) and $specialcontent['xpos'] != '') $xpos = (float)$specialcontent['xpos'];
  1809. $width_used = (($this->x - $bak_x) + $specialcontent['width'])*$this->k; //in order to adjust x coordinate later
  1810. //Is this the best way of fixing x,y coordinates?
  1811. $fix_x = ($this->x+2) * $this->k + ($xpos*$this->k); //+2 margin
  1812. $fix_y = ($this->h - (($this->y+2) + $specialcontent['height'])) * $this->k;//+2 margin
  1813. $imgtemp = explode(" ",$texto);
  1814. $imgtemp[5]=$fix_x; // x
  1815. $imgtemp[6]=$fix_y; // y
  1816. $texto = implode(" ",$imgtemp);
  1817. $this->_out($texto);
  1818. //Readjust x coordinate in order to allow text to be placed after this form element
  1819. $this->x = $bak_x;
  1820. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  1821. $spacenum = (integer)ceil(($width_used / $spacesize));
  1822. //Consider the space used so far in this line as a bunch of spaces
  1823. if ($ypos != 0) $this->Ln($ypos);
  1824. else $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
  1825. break;
  1826. case 'INPUT':
  1827. switch($specialcontent['subtype'])
  1828. {
  1829. case 'PASSWORD':
  1830. case 'TEXT': //Draw TextField
  1831. $width_used = (($this->x - $bak_x) + $specialcontent['width'])*$this->k; //in order to adjust x coordinate later
  1832. $this->SetFillColor(235,235,235);
  1833. $this->x += 1;
  1834. $this->y += 1;
  1835. $this->Rect($this->x,$this->y,$specialcontent['width'],4.5,'DF');// 4.5 in order to avoid overlapping
  1836. if ($texto != '')
  1837. {
  1838. $this->x += 1;
  1839. $this->Write(5,$texto,$this->x);
  1840. $this->x -= $this->GetStringWidth($texto);
  1841. }
  1842. $this->SetFillColor(255);
  1843. $this->y -= 1;
  1844. //Readjust x coordinate in order to allow text to be placed after this form element
  1845. $this->x = $bak_x;
  1846. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  1847. $spacenum = (integer)ceil(($width_used / $spacesize));
  1848. //Consider the space used so far in this line as a bunch of spaces
  1849. $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
  1850. break;
  1851. case 'CHECKBOX': //Draw Checkbox
  1852. $width_used = (($this->x - $bak_x) + $specialcontent['width'])*$this->k; //in order to adjust x coordinate later
  1853. $checked = $texto;
  1854. $this->SetFillColor(235,235,235);
  1855. $this->y += 1;
  1856. $this->x += 1;
  1857. $this->Rect($this->x,$this->y,3,3,'DF');
  1858. if ($checked)
  1859. {
  1860. $this->Line($this->x,$this->y,$this->x+3,$this->y+3);
  1861. $this->Line($this->x,$this->y+3,$this->x+3,$this->y);
  1862. }
  1863. $this->SetFillColor(255);
  1864. $this->y -= 1;
  1865. //Readjust x coordinate in order to allow text to be placed after this form element
  1866. $this->x = $bak_x;
  1867. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  1868. $spacenum = (integer)ceil(($width_used / $spacesize));
  1869. //Consider the space used so far in this line as a bunch of spaces
  1870. $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
  1871. break;
  1872. case 'RADIO': //Draw Radio button
  1873. $width_used = (($this->x - $bak_x) + $specialcontent['width']+0.5)*$this->k; //in order to adjust x coordinate later
  1874. $checked = $texto;
  1875. $this->x += 2;
  1876. $this->y += 1.5;
  1877. $this->Circle($this->x,$this->y+1.2,1,'D');
  1878. $this->_out('0.000 g');
  1879. if ($checked) $this->Circle($this->x,$this->y+1.2,0.4,'DF');
  1880. $this->y -= 1.5;
  1881. //Readjust x coordinate in order to allow text to be placed after this form element
  1882. $this->x = $bak_x;
  1883. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  1884. $spacenum = (integer)ceil(($width_used / $spacesize));
  1885. //Consider the space used so far in this line as a bunch of spaces
  1886. $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
  1887. break;
  1888. case 'BUTTON': // Draw a button
  1889. case 'SUBMIT':
  1890. case 'RESET':
  1891. $nihil = ($specialcontent['width']-$this->GetStringWidth($texto))/2;
  1892. $this->x += 1.5;
  1893. $this->y += 1;
  1894. $this->SetFillColor(190,190,190);
  1895. $this->Rect($this->x,$this->y,$specialcontent['width'],4.5,'DF'); // 4.5 in order to avoid overlapping
  1896. $this->x += $nihil;
  1897. $this->Write(5,$texto,$this->x);
  1898. $this->x += $nihil;
  1899. $this->SetFillColor(255);
  1900. $this->y -= 1;
  1901. break;
  1902. default: break;
  1903. }
  1904. break;
  1905. case 'SELECT':
  1906. $width_used = (($this->x - $bak_x) + $specialcontent['width'] + 8)*$this->k; //in order to adjust x coordinate later
  1907. $this->SetFillColor(235,235,235); //light gray
  1908. $this->x += 1.5;
  1909. $this->y += 1;
  1910. $this->Rect($this->x,$this->y,$specialcontent['width']+2,$this->lineheight,'DF'); // +2 == margin
  1911. $this->x += 1;
  1912. if ($texto != '') $this->Write($this->lineheight,$texto,$this->x); //the combobox content
  1913. $this->x += $specialcontent['width'] - $this->GetStringWidth($texto) + 2;
  1914. $this->SetFillColor(190,190,190); //dark gray
  1915. $this->Rect($this->x-1,$this->y,5,5,'DF'); //Arrow Box
  1916. $this->SetFont('zapfdingbats');
  1917. $this->Write($this->lineheight,chr(116),$this->x); //Down arrow
  1918. $this->SetFont('arial');
  1919. $this->SetFillColor(255);
  1920. //Readjust x coordinate in order to allow text to be placed after this form element
  1921. $this->x = $bak_x;
  1922. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  1923. $spacenum = (integer)ceil(($width_used / $spacesize));
  1924. //Consider the space used so far in this line as a bunch of spaces
  1925. $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
  1926. break;
  1927. case 'TEXTAREA':
  1928. //Setup TextArea properties
  1929. $this->SetFillColor(235,235,235);
  1930. $this->SetFont('courier');
  1931. $this->currentfont='courier';
  1932. $ta_lines = $specialcontent['lines'];
  1933. $ta_height = 1.1*$this->lineheight*$ta_lines;
  1934. $ta_width = $specialcontent['width'];
  1935. //Adjust x,y coordinates
  1936. $this->x += 1.5;
  1937. $this->y += 1.5;
  1938. $linesneeded = $this->WordWrap($texto,$ta_width);
  1939. if ( $linesneeded > $ta_lines ) //Too many words inside textarea
  1940. {
  1941. $textoaux = explode("\n",$texto);
  1942. $texto = '';
  1943. for($i=0;$i<$ta_lines;$i++)
  1944. {
  1945. if ($i == $ta_lines-1) $texto .= $textoaux[$i];
  1946. else $texto .= $textoaux[$i] . "\n";
  1947. }
  1948. //Inform the user that some text has been truncated
  1949. $texto{strlen($texto)-1} = ".";
  1950. $texto{strlen($texto)-2} = ".";
  1951. $texto{strlen($texto)-3} = ".";
  1952. }
  1953. $backup_y = $this->y;
  1954. $backup_x = $this->x;
  1955. $this->Rect($this->x,$this->y,$ta_width+3,$ta_height,'DF');
  1956. if ($texto != '') $this->MultiCell($ta_width+3,$this->lineheight,$texto);
  1957. $this->y = $backup_y - 1.5;
  1958. $this->x = $backup_x + $ta_width + 2.5;
  1959. $this->SetFillColor(255);
  1960. $this->SetFont('arial');
  1961. $this->currentfont='';
  1962. break;
  1963. default: break;
  1964. }
  1965. }
  1966. else //THE text
  1967. {
  1968. if ($vetor[0] == "\n") //We are reading a <BR> now turned into newline ("\n")
  1969. {
  1970. //Restart Flowing Block
  1971. $this->finishFlowingBlock($outofblock);
  1972. if($outofblock) $this->Ln($this->lineheight);
  1973. $this->x = $bak_x;
  1974. $this->newFlowingBlock( $this->divwidth,$this->divheight,$this->divborder,$align,$fill,$is_table );
  1975. }
  1976. else $this->WriteFlowingBlock( $vetor[0] , $outofblock );
  1977. }
  1978. //Check if it is the last element. If so then finish printing the block
  1979. if ($i == ($array_size-1)) $this->finishFlowingBlock($outofblock);
  1980. //Now we must deactivate what we have used
  1981. if( (isset($vetor[1]) and $vetor[1] != '') or $this->HREF != '')
  1982. {
  1983. $this->SetTextColor(0);
  1984. $this->SetStyle('U',false);
  1985. $this->HREF = '';
  1986. }
  1987. if(isset($vetor[2]) and $vetor[2] != '')
  1988. {
  1989. $this->SetStyle('B',false);
  1990. $this->SetStyle('I',false);
  1991. $this->SetStyle('U',false);
  1992. }
  1993. if(isset($vetor[3]) and $vetor[3] != '')
  1994. {
  1995. unset($cor);
  1996. $this->SetTextColor(0);
  1997. }
  1998. if(isset($vetor[4]) and $vetor[4] != '') $this->SetFont('arial');
  1999. if(isset($vetor[5]) and $vetor[5] === true)
  2000. {
  2001. $this->SUP = false;
  2002. $this->SetFontSize(11);
  2003. }
  2004. if(isset($vetor[6]) and $vetor[6] === true)
  2005. {
  2006. $this->SUB = false;
  2007. $this->SetFontSize(11);
  2008. }
  2009. //vetor7-internal links
  2010. if(isset($vetor[8]) and $vetor[8] === true) // strike-through the text
  2011. {
  2012. $this->strike = false;
  2013. }
  2014. if(isset($vetor[9]) and !empty($vetor[9])) // Outline parameters
  2015. {
  2016. $this->SetTextOutline(false);
  2017. $this->outline_on = false;
  2018. }
  2019. if(isset($vetor[10]) and !empty($vetor[10])) //Background color
  2020. {
  2021. $this->SetFillColor(255);
  2022. $this->divbgcolor = false;
  2023. }
  2024. }//end of for(i=0;i<arraysize;i++)
  2025. //Restore some previously set parameters
  2026. $this->strike = $save['strike'];
  2027. $this->SUP = $save['SUP'];
  2028. $this->SUB = $save['SUB'];
  2029. $this->dotted_on = $save['DOTTED'];
  2030. $this->dash_on = $save['DASHED'];
  2031. if ($this->dash_on) $this->SetDash(2,2);
  2032. //Check whether we have borders to paint or not
  2033. //(only works 100% if whole content spans only 1 page)
  2034. if ($this->cssbegin and ($this->divborder or $this->dash_on or $this->dotted_on or $this->divbgcolor))
  2035. {
  2036. if ($oldpage != $this->page)
  2037. {
  2038. //Only border on last page is painted (known bug)
  2039. $x = $this->lMargin;
  2040. $y = $this->tMargin;
  2041. $old_height = $this->y - $y;
  2042. }
  2043. else
  2044. {
  2045. if ($this->oldx < 0) $x = $this->x;
  2046. else $x = $this->oldx;
  2047. if ($this->oldy < 0) $y = $this->y - $old_height;
  2048. else $y = $this->oldy;
  2049. }
  2050. if ($this->divborder) $this->Rect($x,$y,$this->divwidth,$old_height);
  2051. if ($this->dash_on) $this->Rect($x,$y,$this->divwidth,$old_height);
  2052. if ($this->dotted_on) $this->DottedRect($x,$y,$this->divwidth,$old_height);
  2053. $this->x = $bak_x;
  2054. }
  2055. }
  2056. function Reset()
  2057. {
  2058. //! @return void
  2059. //! @desc Resets several class attributes
  2060. // if ( $this->issetcolor !== true )
  2061. // {
  2062. $this->SetTextColor(0);
  2063. $this->SetDrawColor(0);
  2064. $this->SetFillColor(255);
  2065. $this->colorarray = array();
  2066. $this->bgcolorarray = array();
  2067. $this->issetcolor = false;
  2068. // }
  2069. $this->HREF = '';
  2070. $this->SetTextOutline(false);
  2071. //$this->strike = false;
  2072. $this->SetFontSize(11);
  2073. $this->SetStyle('B',false);
  2074. $this->SetStyle('I',false);
  2075. $this->SetStyle('U',false);
  2076. $this->SetFont('arial');
  2077. $this->divwidth = 0;
  2078. $this->divheight = 0;
  2079. $this->divalign = "L";
  2080. $this->divrevert = false;
  2081. $this->divborder = 0;
  2082. $this->divbgcolor = false;
  2083. $this->toupper = false;
  2084. $this->tolower = false;
  2085. $this->SetDash(); //restore to no dash
  2086. $this->dash_on = false;
  2087. $this->dotted_on = false;
  2088. $this->oldx = -1;
  2089. $this->oldy = -1;
  2090. }
  2091. function ReadMetaTags($html)
  2092. {
  2093. //! @return void
  2094. //! @desc Pass meta tag info to PDF file properties
  2095. $regexp = '/ (\\w+?)=([^\\s>"]+)/si'; // changes anykey=anyvalue to anykey="anyvalue" (only do this when this happens inside tags)
  2096. $html = preg_replace($regexp," \$1=\"\$2\"",$html);
  2097. $regexp = '/<meta .*?(name|content)="(.*?)" .*?(name|content)="(.*?)".*?>/si';
  2098. preg_match_all($regexp,$html,$aux);
  2099. $firstattr = $aux[1];
  2100. $secondattr = $aux[3];
  2101. for( $i = 0 ; $i < count($aux[0]) ; $i++)
  2102. {
  2103. $name = ( strtoupper($firstattr[$i]) == "NAME" )? strtoupper($aux[2][$i]) : strtoupper($aux[4][$i]);
  2104. $content = ( strtoupper($firstattr[$i]) == "CONTENT" )? $aux[2][$i] : $aux[4][$i];
  2105. switch($name)
  2106. {
  2107. case "KEYWORDS": $this->SetKeywords($content); break;
  2108. case "AUTHOR": $this->SetAuthor($content); break;
  2109. case "DESCRIPTION": $this->SetSubject($content); break;
  2110. }
  2111. }
  2112. //Comercial do Aplicativo usado (no caso um script):
  2113. $this->SetCreator("HTML2FPDF >> http://html2fpdf.sf.net");
  2114. }
  2115. //////////////////
  2116. /// CSS parser ///
  2117. //////////////////
  2118. function ReadCSS($html)
  2119. {
  2120. //! @desc CSS parser
  2121. //! @return string
  2122. /*
  2123. * This version ONLY supports: .class {...} / #id { .... }
  2124. * It does NOT support: body{...} / a#hover { ... } / p.right { ... } / other mixed names
  2125. * This function must read the CSS code (internal or external) and order its value inside $this->CSS.
  2126. */
  2127. $match = 0; // no match for instance
  2128. $regexp = ''; // This helps debugging: showing what is the REAL string being processed
  2129. //CSS inside external files
  2130. $regexp = '/<link rel="stylesheet".*?href="(.+?)"\\s*?\/?>/si';
  2131. $match = preg_match_all($regexp,$html,$CSSext);
  2132. $ind = 0;
  2133. while($match){
  2134. //Fix path value
  2135. $path = $CSSext[1][$ind];
  2136. $path = str_replace("\\","/",$path); //If on Windows
  2137. //Get link info and obtain its absolute path
  2138. $regexp = '|^./|';
  2139. $path = preg_replace($regexp,'',$path);
  2140. if (strpos($path,"../") !== false ) //It is a Relative Link
  2141. {
  2142. $backtrackamount = substr_count($path,"../");
  2143. $maxbacktrack = substr_count($this->basepath,"/") - 1;
  2144. $filepath = str_replace("../",'',$path);
  2145. $path = $this->basepath;
  2146. //If it is an invalid relative link, then make it go to directory root
  2147. if ($backtrackamount > $maxbacktrack) $backtrackamount = $maxbacktrack;
  2148. //Backtrack some directories
  2149. for( $i = 0 ; $i < $backtrackamount + 1 ; $i++ ) $path = substr( $path, 0 , strrpos($path,"/") );
  2150. $path = $path . "/" . $filepath; //Make it an absolute path
  2151. }
  2152. elseif( strpos($path,":/") === false) //It is a Local Link
  2153. {
  2154. $path = $this->basepath . $path;
  2155. }
  2156. //Do nothing if it is an Absolute Link
  2157. //END of fix path value
  2158. $CSSextblock = file_get_contents($path);
  2159. //Get class/id name and its characteristics from $CSSblock[1]
  2160. $regexp = '/[.# ]([^.]+?)\\s*?\{(.+?)\}/s'; // '/s' PCRE_DOTALL including \n
  2161. preg_match_all( $regexp, $CSSextblock, $extstyle);
  2162. //Make CSS[Name-of-the-class] = array(key => value)
  2163. $regexp = '/\\s*?(\\S+?):(.+?);/si';
  2164. for($i=0; $i < count($extstyle[1]) ; $i++)
  2165. {
  2166. preg_match_all( $regexp, $extstyle[2][$i], $extstyleinfo);
  2167. $extproperties = $extstyleinfo[1];
  2168. $extvalues = $extstyleinfo[2];
  2169. for($j = 0; $j < count($extproperties) ; $j++)
  2170. {
  2171. //Array-properties and Array-values must have the SAME SIZE!
  2172. $extclassproperties[strtoupper($extproperties[$j])] = trim($extvalues[$j]);
  2173. }
  2174. $this->CSS[$extstyle[1][$i]] = $extclassproperties;
  2175. $extproperties = array();
  2176. $extvalues = array();
  2177. $extclassproperties = array();
  2178. }
  2179. $match--;
  2180. $ind++;
  2181. } //end of match
  2182. $match = 0; // reset value, if needed
  2183. //CSS internal
  2184. //Get content between tags and order it, using regexp
  2185. $regexp = '/<style.*?>(.*?)<\/style>/si'; // it can be <style> or <style type="txt/css">
  2186. $match = preg_match($regexp,$html,$CSSblock);
  2187. if ($match) {
  2188. //Get class/id name and its characteristics from $CSSblock[1]
  2189. $regexp = '/[.#]([^.]+?)\\s*?\{(.+?)\}/s'; // '/s' PCRE_DOTALL including \n
  2190. preg_match_all( $regexp, $CSSblock[1], $style);
  2191. //Make CSS[Name-of-the-class] = array(key => value)
  2192. $regexp = '/\\s*?(\\S+?):(.+?);/si';
  2193. for($i=0; $i < count($style[1]) ; $i++)
  2194. {
  2195. preg_match_all( $regexp, $style[2][$i], $styleinfo);
  2196. $properties = $styleinfo[1];
  2197. $values = $styleinfo[2];
  2198. for($j = 0; $j < count($properties) ; $j++)
  2199. {
  2200. //Array-properties and Array-values must have the SAME SIZE!
  2201. $classproperties[strtoupper($properties[$j])] = trim($values[$j]);
  2202. }
  2203. $this->CSS[$style[1][$i]] = $classproperties;
  2204. $properties = array();
  2205. $values = array();
  2206. $classproperties = array();
  2207. }
  2208. } // end of match
  2209. //Remove CSS (tags and content), if any
  2210. $regexp = '/<style.*?>(.*?)<\/style>/si'; // it can be <style> or <style type="txt/css">
  2211. $html = preg_replace($regexp,'',$html);
  2212. return $html;
  2213. }
  2214. function readInlineCSS($html)
  2215. {
  2216. //! @return array
  2217. //! @desc Reads inline CSS and returns an array of properties
  2218. //Fix incomplete CSS code
  2219. $size = strlen($html)-1;
  2220. if ($html{$size} != ';') $html .= ';';
  2221. //Make CSS[Name-of-the-class] = array(key => value)
  2222. $regexp = '|\\s*?(\\S+?):(.+?);|i';
  2223. preg_match_all( $regexp, $html, $styleinfo);
  2224. $properties = $styleinfo[1];
  2225. $values = $styleinfo[2];
  2226. //Array-properties and Array-values must have the SAME SIZE!
  2227. $classproperties = array();
  2228. for($i = 0; $i < count($properties) ; $i++) $classproperties[strtoupper($properties[$i])] = trim($values[$i]);
  2229. return $classproperties;
  2230. }
  2231. function setCSS($arrayaux)
  2232. {
  2233. //! @return void
  2234. //! @desc Change some class attributes according to CSS properties
  2235. if (!is_array($arrayaux)) return; //Removes PHP Warning
  2236. foreach($arrayaux as $k => $v)
  2237. {
  2238. switch($k){
  2239. case 'WIDTH':
  2240. $this->divwidth = ConvertSize($v,$this->pgwidth);
  2241. break;
  2242. case 'HEIGHT':
  2243. $this->divheight = ConvertSize($v,$this->pgwidth);
  2244. break;
  2245. case 'BORDER': // width style color (width not supported correctly - it is always considered as normal)
  2246. $prop = explode(' ',$v);
  2247. if ( count($prop) != 3 ) break; // Not supported: borders not fully declared
  2248. //style: dashed dotted none (anything else => solid )
  2249. if (strnatcasecmp($prop[1],"dashed") == 0) //found "dashed"! (ignores case)
  2250. {
  2251. $this->dash_on = true;
  2252. $this->SetDash(2,2); //2mm on, 2mm off
  2253. }
  2254. elseif (strnatcasecmp($prop[1],"dotted") == 0) //found "dotted"! (ignores case)
  2255. {
  2256. $this->dotted_on = true;
  2257. }
  2258. elseif (strnatcasecmp($prop[1],"none") == 0) $this->divborder = 0;
  2259. else $this->divborder = 1;
  2260. //color
  2261. $coul = ConvertColor($prop[2]);
  2262. $this->SetDrawColor($coul['R'],$coul['G'],$coul['B']);
  2263. $this->issetcolor=true;
  2264. break;
  2265. case 'FONT-FAMILY': // one of the $this->fontlist fonts
  2266. //If it is a font list, get all font types
  2267. $aux_fontlist = explode(",",$v);
  2268. $fontarraysize = count($aux_fontlist);
  2269. for($i=0;$i<$fontarraysize;$i++)
  2270. {
  2271. $fonttype = $aux_fontlist[$i];
  2272. $fonttype = trim($fonttype);
  2273. //If font is found, set it, and exit loop
  2274. if ( in_array(strtolower($fonttype), $this->fontlist) ) {$this->SetFont(strtolower($fonttype));break;}
  2275. //If font = "courier new" for example, try simply looking for "courier"
  2276. $fonttype = explode(" ",$fonttype);
  2277. $fonttype = $fonttype[0];
  2278. if ( in_array(strtolower($fonttype), $this->fontlist) ) {$this->SetFont(strtolower($fonttype));break;}
  2279. }
  2280. break;
  2281. case 'FONT-SIZE': //Does not support: smaller, larger
  2282. if(is_numeric($v{0}))
  2283. {
  2284. $mmsize = ConvertSize($v,$this->pgwidth);
  2285. $this->SetFontSize( $mmsize*(72/25.4) ); //Get size in points (pt)
  2286. }
  2287. else{
  2288. $v = strtoupper($v);
  2289. switch($v)
  2290. {
  2291. //Values obtained from http://www.w3schools.com/html/html_reference.asp
  2292. case 'XX-SMALL': $this->SetFontSize( (0.7)* 11);
  2293. break;
  2294. case 'X-SMALL': $this->SetFontSize( (0.77) * 11);
  2295. break;
  2296. case 'SMALL': $this->SetFontSize( (0.86)* 11);
  2297. break;
  2298. case 'MEDIUM': $this->SetFontSize(11);
  2299. break;
  2300. case 'LARGE': $this->SetFontSize( (1.2)*11);
  2301. break;
  2302. case 'X-LARGE': $this->SetFontSize( (1.5)*11);
  2303. break;
  2304. case 'XX-LARGE': $this->SetFontSize( 2*11);
  2305. break;
  2306. }
  2307. }
  2308. break;
  2309. case 'FONT-STYLE': // italic normal oblique
  2310. switch (strtoupper($v))
  2311. {
  2312. case 'ITALIC':
  2313. case 'OBLIQUE':
  2314. $this->SetStyle('I',true);
  2315. break;
  2316. case 'NORMAL': break;
  2317. }
  2318. break;
  2319. case 'FONT-WEIGHT': // normal bold //Does not support: bolder, lighter, 100..900(step value=100)
  2320. switch (strtoupper($v))
  2321. {
  2322. case 'BOLD':
  2323. $this->SetStyle('B',true);
  2324. break;
  2325. case 'NORMAL': break;
  2326. }
  2327. break;
  2328. case 'TEXT-DECORATION': // none underline //Does not support: overline, blink
  2329. switch (strtoupper($v))
  2330. {
  2331. case 'LINE-THROUGH':
  2332. $this->strike = true;
  2333. break;
  2334. case 'UNDERLINE':
  2335. $this->SetStyle('U',true);
  2336. break;
  2337. case 'NONE': break;
  2338. }
  2339. case 'TEXT-TRANSFORM': // none uppercase lowercase //Does not support: capitalize
  2340. switch (strtoupper($v)) //Not working 100%
  2341. {
  2342. case 'UPPERCASE':
  2343. $this->toupper=true;
  2344. break;
  2345. case 'LOWERCASE':
  2346. $this->tolower=true;
  2347. break;
  2348. case 'NONE': break;
  2349. }
  2350. case 'TEXT-ALIGN': //left right center justify
  2351. switch (strtoupper($v))
  2352. {
  2353. case 'LEFT':
  2354. $this->divalign="L";
  2355. break;
  2356. case 'CENTER':
  2357. $this->divalign="C";
  2358. break;
  2359. case 'RIGHT':
  2360. $this->divalign="R";
  2361. break;
  2362. case 'JUSTIFY':
  2363. $this->divalign="J";
  2364. break;
  2365. }
  2366. break;
  2367. case 'DIRECTION': //ltr(default) rtl
  2368. if (strtolower($v) == 'rtl') $this->divrevert = true;
  2369. break;
  2370. case 'BACKGROUND': // bgcolor only
  2371. $cor = ConvertColor($v);
  2372. $this->bgcolorarray = $cor;
  2373. $this->SetFillColor($cor['R'],$cor['G'],$cor['B']);
  2374. $this->divbgcolor = true;
  2375. break;
  2376. case 'COLOR': // font color
  2377. $cor = ConvertColor($v);
  2378. $this->colorarray = $cor;
  2379. $this->SetTextColor($cor['R'],$cor['G'],$cor['B']);
  2380. $this->issetcolor=true;
  2381. break;
  2382. }//end of switch($k)
  2383. }//end of foreach
  2384. }
  2385. function SetStyle($tag,$enable)
  2386. {
  2387. //! @return void
  2388. //! @desc Enables/Disables B,I,U styles
  2389. //Modify style and select corresponding font
  2390. $this->$tag+=($enable ? 1 : -1);
  2391. $style='';
  2392. //Fix some SetStyle misuse
  2393. if ($this->$tag < 0) $this->$tag = 0;
  2394. if ($this->$tag > 1) $this->$tag = 1;
  2395. foreach(array('B','I','U') as $s)
  2396. if($this->$s>0)
  2397. $style.=$s;
  2398. $this->currentstyle=$style;
  2399. $this->SetFont('',$style);
  2400. }
  2401. function DisableTags($str='')
  2402. {
  2403. //! @return void
  2404. //! @desc Disable some tags using ',' as separator. Enable all tags calling this function without parameters.
  2405. if ($str == '') //enable all tags
  2406. {
  2407. //Insert new supported tags in the long string below.
  2408. $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>";
  2409. }
  2410. else
  2411. {
  2412. $str = explode(",",$str);
  2413. foreach($str as $v) $this->enabledtags = str_replace(trim($v),'',$this->enabledtags);
  2414. }
  2415. }
  2416. ////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
  2417. //Thanks to vietcom (vncommando at yahoo dot com)
  2418. /* Modified by Renato Coelho
  2419. in order to print tables that span more than 1 page and to allow
  2420. bold,italic and the likes inside table cells (and alignment now works with styles!)
  2421. */
  2422. //table Array of (w, h, bc, nr, wc, hr, cells)
  2423. //w Width of table
  2424. //h Height of table
  2425. //nc Number column
  2426. //nr Number row
  2427. //hr List of height of each row
  2428. //wc List of width of each column
  2429. //cells List of cells of each rows, cells[i][j] is a cell in the table
  2430. function _tableColumnWidth(&$table){
  2431. //! @return void
  2432. $cs = &$table['cells'];
  2433. $mw = $this->getStringWidth('W');
  2434. $nc = $table['nc'];
  2435. $nr = $table['nr'];
  2436. $listspan = array();
  2437. //Xac dinh do rong cua cac cell va cac cot tuong ung
  2438. for($j = 0 ; $j < $nc ; $j++ ) //columns
  2439. {
  2440. $wc = &$table['wc'][$j];
  2441. for($i = 0 ; $i < $nr ; $i++ ) //rows
  2442. {
  2443. if (isset($cs[$i][$j]) && $cs[$i][$j])
  2444. {
  2445. $c = &$cs[$i][$j];
  2446. $miw = $mw;
  2447. if (isset($c['maxs']) and $c['maxs'] != '') $c['s'] = $c['maxs'];
  2448. $c['maw'] = $c['s'];
  2449. if (isset($c['nowrap'])) $miw = $c['maw'];
  2450. if (isset($c['w']))
  2451. {
  2452. if ($miw<$c['w']) $c['miw'] = $c['w'];
  2453. if ($miw>$c['w']) $c['miw'] = $c['w'] = $miw;
  2454. if (!isset($wc['w'])) $wc['w'] = 1;
  2455. }
  2456. else $c['miw'] = $miw;
  2457. if ($c['maw'] < $c['miw']) $c['maw'] = $c['miw'];
  2458. if (!isset($c['colspan']))
  2459. {
  2460. if ($wc['miw'] < $c['miw']) $wc['miw'] = $c['miw'];
  2461. if ($wc['maw'] < $c['maw']) $wc['maw'] = $c['maw'];
  2462. }
  2463. else $listspan[] = array($i,$j);
  2464. //Check if minimum width of the whole column is big enough for a huge word to fit
  2465. $auxtext = implode("",$c['text']);
  2466. $minwidth = $this->WordWrap($auxtext,$wc['miw']-2);// -2 == margin
  2467. if ($minwidth < 0 and (-$minwidth) > $wc['miw']) $wc['miw'] = (-$minwidth) +2; //increase minimum width
  2468. if ($wc['miw'] > $wc['maw']) $wc['maw'] = $wc['miw']; //update maximum width, if needed
  2469. }
  2470. }//rows
  2471. }//columns
  2472. //Xac dinh su anh huong cua cac cell colspan len cac cot va nguoc lai
  2473. $wc = &$table['wc'];
  2474. foreach ($listspan as $span)
  2475. {
  2476. list($i,$j) = $span;
  2477. $c = &$cs[$i][$j];
  2478. $lc = $j + $c['colspan'];
  2479. if ($lc > $nc) $lc = $nc;
  2480. $wis = $wisa = 0;
  2481. $was = $wasa = 0;
  2482. $list = array();
  2483. for($k=$j;$k<$lc;$k++)
  2484. {
  2485. $wis += $wc[$k]['miw'];
  2486. $was += $wc[$k]['maw'];
  2487. if (!isset($c['w']))
  2488. {
  2489. $list[] = $k;
  2490. $wisa += $wc[$k]['miw'];
  2491. $wasa += $wc[$k]['maw'];
  2492. }
  2493. }
  2494. if ($c['miw'] > $wis)
  2495. {
  2496. if (!$wis)
  2497. {//Cac cot chua co kich thuoc => chia deu
  2498. for($k=$j;$k<$lc;$k++) $wc[$k]['miw'] = $c['miw']/$c['colspan'];
  2499. }
  2500. elseif(!count($list))
  2501. {//Khong co cot nao co kich thuoc auto => chia deu phan du cho tat ca
  2502. $wi = $c['miw'] - $wis;
  2503. for($k=$j;$k<$lc;$k++) $wc[$k]['miw'] += ($wc[$k]['miw']/$wis)*$wi;
  2504. }
  2505. else
  2506. {//Co mot so cot co kich thuoc auto => chia deu phan du cho cac cot auto
  2507. $wi = $c['miw'] - $wis;
  2508. foreach ($list as $k) $wc[$k]['miw'] += ($wc[$k]['miw']/$wisa)*$wi;
  2509. }
  2510. }
  2511. if ($c['maw'] > $was)
  2512. {
  2513. if (!$wis)
  2514. {//Cac cot chua co kich thuoc => chia deu
  2515. for($k=$j;$k<$lc;$k++) $wc[$k]['maw'] = $c['maw']/$c['colspan'];
  2516. }
  2517. elseif (!count($list))
  2518. {
  2519. //Khong co cot nao co kich thuoc auto => chia deu phan du cho tat ca
  2520. $wi = $c['maw'] - $was;
  2521. for($k=$j;$k<$lc;$k++) $wc[$k]['maw'] += ($wc[$k]['maw']/$was)*$wi;
  2522. }
  2523. else
  2524. {//Co mot so cot co kich thuoc auto => chia deu phan du cho cac cot auto
  2525. $wi = $c['maw'] - $was;
  2526. foreach ($list as $k) $wc[$k]['maw'] += ($wc[$k]['maw']/$wasa)*$wi;
  2527. }
  2528. }
  2529. }
  2530. }
  2531. function _tableWidth(&$table){
  2532. //! @return void
  2533. //! @desc Calculates the Table Width
  2534. // @desc Xac dinh chieu rong cua table
  2535. $widthcols = &$table['wc'];
  2536. $numcols = $table['nc'];
  2537. $tablewidth = 0;
  2538. for ( $i = 0 ; $i < $numcols ; $i++ )
  2539. {
  2540. $tablewidth += isset($widthcols[$i]['w']) ? $widthcols[$i]['miw'] : $widthcols[$i]['maw'];
  2541. }
  2542. if ($tablewidth > $this->pgwidth) $table['w'] = $this->pgwidth;
  2543. if (isset($table['w']))
  2544. {
  2545. $wis = $wisa = 0;
  2546. $list = array();
  2547. for( $i = 0 ; $i < $numcols ; $i++ )
  2548. {
  2549. $wis += $widthcols[$i]['miw'];
  2550. if (!isset($widthcols[$i]['w'])){ $list[] = $i;$wisa += $widthcols[$i]['miw'];}
  2551. }
  2552. if ($table['w'] > $wis)
  2553. {
  2554. if (!count($list))
  2555. {//Khong co cot nao co kich thuoc auto => chia deu phan du cho tat ca
  2556. //http://www.ksvn.com/anhviet_new.htm - translating comments...
  2557. //bent shrink essence move size measure automatic => divide against give as a whole
  2558. //$wi = $table['w'] - $wis;
  2559. $wi = ($table['w'] - $wis)/$numcols;
  2560. for($k=0;$k<$numcols;$k++)
  2561. //$widthcols[$k]['miw'] += ($widthcols[$k]['miw']/$wis)*$wi;
  2562. $widthcols[$k]['miw'] += $wi;
  2563. }
  2564. else
  2565. {//Co mot so cot co kich thuoc auto => chia deu phan du cho cac cot auto
  2566. //$wi = $table['w'] - $wis;
  2567. $wi = ($table['w'] - $wis)/count($list);
  2568. foreach ($list as $k)
  2569. //$widthcols[$k]['miw'] += ($widthcols[$k]['miw']/$wisa)*$wi;
  2570. $widthcols[$k]['miw'] += $wi;
  2571. }
  2572. }
  2573. for ($i=0;$i<$numcols;$i++)
  2574. {
  2575. $tablewidth = $widthcols[$i]['miw'];
  2576. unset($widthcols[$i]);
  2577. $widthcols[$i] = $tablewidth;
  2578. }
  2579. }
  2580. else //table has no width defined
  2581. {
  2582. $table['w'] = $tablewidth;
  2583. for ( $i = 0 ; $i < $numcols ; $i++)
  2584. {
  2585. $tablewidth = isset($widthcols[$i]['w']) ? $widthcols[$i]['miw'] : $widthcols[$i]['maw'];
  2586. unset($widthcols[$i]);
  2587. $widthcols[$i] = $tablewidth;
  2588. }
  2589. }
  2590. }
  2591. function _tableHeight(&$table){
  2592. //! @return void
  2593. //! @desc Calculates the Table Height
  2594. $cells = &$table['cells'];
  2595. $numcols = $table['nc'];
  2596. $numrows = $table['nr'];
  2597. $listspan = array();
  2598. for( $i = 0 ; $i < $numrows ; $i++ )//rows
  2599. {
  2600. $heightrow = &$table['hr'][$i];
  2601. for( $j = 0 ; $j < $numcols ; $j++ ) //columns
  2602. {
  2603. if (isset($cells[$i][$j]) && $cells[$i][$j])
  2604. {
  2605. $c = &$cells[$i][$j];
  2606. list($x,$cw) = $this->_tableGetWidth($table, $i,$j);
  2607. //Check whether width is enough for this cells' text
  2608. $auxtext = implode("",$c['text']);
  2609. $auxtext2 = $auxtext; //in case we have text with styles
  2610. $nostyles_size = $this->GetStringWidth($auxtext) + 3; // +3 == margin
  2611. $linesneeded = $this->WordWrap($auxtext,$cw-2);// -2 == margin
  2612. if ($c['s'] > $nostyles_size and !isset($c['form'])) //Text with styles
  2613. {
  2614. $auxtext = $auxtext2; //recover original characteristics (original /n placements)
  2615. $diffsize = $c['s'] - $nostyles_size; //with bold et al. char width gets a bit bigger than plain char
  2616. if ($linesneeded == 0) $linesneeded = 1; //to avoid division by zero
  2617. $diffsize /= $linesneeded;
  2618. $linesneeded = $this->WordWrap($auxtext,$cw-2-$diffsize);//diffsize used to wrap text correctly
  2619. }
  2620. if (isset($c['form']))
  2621. {
  2622. $linesneeded = ceil(($c['s']-3)/($cw-2)); //Text + form in a cell
  2623. //Presuming the use of styles
  2624. if ( ($this->GetStringWidth($auxtext) + 3) > ($cw-2) ) $linesneeded++;
  2625. }
  2626. $ch = $linesneeded * 1.1 * $this->lineheight;
  2627. //If height is bigger than page height...
  2628. if ($ch > ($this->fh - $this->bMargin - $this->tMargin)) $ch = ($this->fh - $this->bMargin - $this->tMargin);
  2629. //If height is defined and it is bigger than calculated $ch then update values
  2630. if (isset($c['h']) && $c['h'] > $ch)
  2631. {
  2632. $c['mih'] = $ch; //in order to keep valign working
  2633. $ch = $c['h'];
  2634. }
  2635. else $c['mih'] = $ch;
  2636. if (isset($c['rowspan'])) $listspan[] = array($i,$j);
  2637. elseif ($heightrow < $ch) $heightrow = $ch;
  2638. if (isset($c['form'])) $c['mih'] = $ch;
  2639. }
  2640. }//end of columns
  2641. }//end of rows
  2642. $heightrow = &$table['hr'];
  2643. foreach ($listspan as $span)
  2644. {
  2645. list($i,$j) = $span;
  2646. $c = &$cells[$i][$j];
  2647. $lr = $i + $c['rowspan'];
  2648. if ($lr > $numrows) $lr = $numrows;
  2649. $hs = $hsa = 0;
  2650. $list = array();
  2651. for($k=$i;$k<$lr;$k++)
  2652. {
  2653. $hs += $heightrow[$k];
  2654. if (!isset($c['h']))
  2655. {
  2656. $list[] = $k;
  2657. $hsa += $heightrow[$k];
  2658. }
  2659. }
  2660. if ($c['mih'] > $hs)
  2661. {
  2662. if (!$hs)
  2663. {//Cac dong chua co kich thuoc => chia deu
  2664. for($k=$i;$k<$lr;$k++) $heightrow[$k] = $c['mih']/$c['rowspan'];
  2665. }
  2666. elseif (!count($list))
  2667. {//Khong co dong nao co kich thuoc auto => chia deu phan du cho tat ca
  2668. $hi = $c['mih'] - $hs;
  2669. for($k=$i;$k<$lr;$k++) $heightrow[$k] += ($heightrow[$k]/$hs)*$hi;
  2670. }
  2671. else
  2672. {//Co mot so dong co kich thuoc auto => chia deu phan du cho cac dong auto
  2673. $hi = $c['mih'] - $hsa;
  2674. foreach ($list as $k) $heightrow[$k] += ($heightrow[$k]/$hsa)*$hi;
  2675. }
  2676. }
  2677. }
  2678. }
  2679. function _tableGetWidth(&$table, $i,$j){
  2680. //! @return array(x,w)
  2681. // @desc Xac dinh toa do va do rong cua mot cell
  2682. $cell = &$table['cells'][$i][$j];
  2683. if ($cell)
  2684. {
  2685. if (isset($cell['x0'])) return array($cell['x0'], $cell['w0']);
  2686. $x = 0;
  2687. $widthcols = &$table['wc'];
  2688. for( $k = 0 ; $k < $j ; $k++ ) $x += $widthcols[$k];
  2689. $w = $widthcols[$j];
  2690. if (isset($cell['colspan']))
  2691. {
  2692. for ( $k = $j+$cell['colspan']-1 ; $k > $j ; $k-- ) $w += $widthcols[$k];
  2693. }
  2694. $cell['x0'] = $x;
  2695. $cell['w0'] = $w;
  2696. return array($x, $w);
  2697. }
  2698. return array(0,0);
  2699. }
  2700. function _tableGetHeight(&$table, $i,$j){
  2701. //! @return array(y,h)
  2702. $cell = &$table['cells'][$i][$j];
  2703. if ($cell){
  2704. if (isset($cell['y0'])) return array($cell['y0'], $cell['h0']);
  2705. $y = 0;
  2706. $heightrow = &$table['hr'];
  2707. for ($k=0;$k<$i;$k++) $y += $heightrow[$k];
  2708. $h = $heightrow[$i];
  2709. if (isset($cell['rowspan'])){
  2710. for ($k=$i+$cell['rowspan']-1;$k>$i;$k--)
  2711. $h += $heightrow[$k];
  2712. }
  2713. $cell['y0'] = $y;
  2714. $cell['h0'] = $h;
  2715. return array($y, $h);
  2716. }
  2717. return array(0,0);
  2718. }
  2719. function _tableRect($x, $y, $w, $h, $type=1){
  2720. //! @return void
  2721. if ($type==1) $this->Rect($x, $y, $w, $h);
  2722. elseif (strlen($type)==4){
  2723. $x2 = $x + $w; $y2 = $y + $h;
  2724. if (intval($type{0})) $this->Line($x , $y , $x2, $y );
  2725. if (intval($type{1})) $this->Line($x2, $y , $x2, $y2);
  2726. if (intval($type{2})) $this->Line($x , $y2, $x2, $y2);
  2727. if (intval($type{3})) $this->Line($x , $y , $x , $y2);
  2728. }
  2729. }
  2730. function _tableWrite(&$table){
  2731. //! @desc Main table function
  2732. //! @return void
  2733. $cells = &$table['cells'];
  2734. $numcols = $table['nc'];
  2735. $numrows = $table['nr'];
  2736. $x0 = $this->x;
  2737. $y0 = $this->y;
  2738. $right = $this->pgwidth - $this->rMargin;
  2739. if (isset($table['a']) and ($table['w'] != $this->pgwidth))
  2740. {
  2741. if ($table['a']=='C') $x0 += (($right-$x0) - $table['w'])/2;
  2742. elseif ($table['a']=='R') $x0 = $right - $table['w'];
  2743. }
  2744. $returny = 0;
  2745. $tableheader = array();
  2746. //Draw Table Contents and Borders
  2747. for( $i = 0 ; $i < $numrows ; $i++ ) //Rows
  2748. {
  2749. $skippage = false;
  2750. for( $j = 0 ; $j < $numcols ; $j++ ) //Columns
  2751. {
  2752. if (isset($cells[$i][$j]) && $cells[$i][$j])
  2753. {
  2754. $cell = &$cells[$i][$j];
  2755. list($x,$w) = $this->_tableGetWidth($table, $i, $j);
  2756. list($y,$h) = $this->_tableGetHeight($table, $i, $j);
  2757. $x += $x0;
  2758. $y += $y0;
  2759. $y -= $returny;
  2760. if ((($y + $h) > ($this->fh - $this->bMargin)) && ($y0 >0 || $x0 > 0))
  2761. {
  2762. if (!$skippage)
  2763. {
  2764. $y -= $y0;
  2765. $returny += $y;
  2766. $this->AddPage();
  2767. if ($this->usetableheader) $this->Header($tableheader);
  2768. if ($this->usetableheader) $y0 = $this->y;
  2769. else $y0 = $this->tMargin;
  2770. $y = $y0;
  2771. }
  2772. $skippage = true;
  2773. }
  2774. //Align
  2775. $this->x = $x; $this->y = $y;
  2776. $align = isset($cell['a'])? $cell['a'] : 'L';
  2777. //Vertical align
  2778. if (!isset($cell['va']) || $cell['va']=='M') $this->y += ($h-$cell['mih'])/2;
  2779. elseif (isset($cell['va']) && $cell['va']=='B') $this->y += $h-$cell['mih'];
  2780. //Fill
  2781. $fill = isset($cell['bgcolor']) ? $cell['bgcolor']
  2782. : (isset($table['bgcolor'][$i]) ? $table['bgcolor'][$i]
  2783. : (isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0));
  2784. if ($fill)
  2785. {
  2786. $color = ConvertColor($fill);
  2787. $this->SetFillColor($color['R'],$color['G'],$color['B']);
  2788. $this->Rect($x, $y, $w, $h, 'F');
  2789. }
  2790. //Border
  2791. if (isset($cell['border'])) $this->_tableRect($x, $y, $w, $h, $cell['border']);
  2792. elseif (isset($table['border']) && $table['border']) $this->Rect($x, $y, $w, $h);
  2793. $this->divalign=$align;
  2794. $this->divwidth=$w-2;
  2795. //Get info of first row == table header
  2796. if ($this->usetableheader and $i == 0 )
  2797. {
  2798. $tableheader[$j]['x'] = $x;
  2799. $tableheader[$j]['y'] = $y;
  2800. $tableheader[$j]['h'] = $h;
  2801. $tableheader[$j]['w'] = $w;
  2802. $tableheader[$j]['text'] = $cell['text'];
  2803. $tableheader[$j]['textbuffer'] = $cell['textbuffer'];
  2804. $tableheader[$j]['a'] = isset($cell['a'])? $cell['a'] : 'L';
  2805. $tableheader[$j]['va'] = $cell['va'];
  2806. $tableheader[$j]['mih'] = $cell['mih'];
  2807. $tableheader[$j]['bgcolor'] = $fill;
  2808. if ($table['border']) $tableheader[$j]['border'] = 'all';
  2809. elseif (isset($cell['border'])) $tableheader[$j]['border'] = $cell['border'];
  2810. }
  2811. if (!empty($cell['textbuffer'])) $this->printbuffer($cell['textbuffer'],false,true/*inside a table*/);
  2812. //Reset values
  2813. $this->Reset();
  2814. }//end of (if isset(cells)...)
  2815. }// end of columns
  2816. if ($i == $numrows-1) $this->y = $y + $h; //last row jump (update this->y position)
  2817. }// end of rows
  2818. }//END OF FUNCTION _tableWrite()
  2819. /////////////////////////END OF TABLE CODE//////////////////////////////////
  2820. }//end of Class
  2821. /*
  2822. ---- JUNK(?)/OLD CODE: ------
  2823. // <? <- this fixes HIGHLIGHT PSPAD bug ...
  2824. */
  2825. ?>