PageRenderTime 67ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/sites/all/modules/table_export/formats/export_pdf/pdf/html2fpdf.php

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