PageRenderTime 40ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/webcore/ext/pdf/webcore.pdf.php

#
PHP | 2552 lines | 2307 code | 128 blank | 117 comment | 501 complexity | 0f2431773e64bb248890c925c715e39e MD5 | raw file
  1. <?php
  2. require_once "webcore.pdf.base.php";
  3. /**
  4. * Class to write a PDF using a HTML
  5. *
  6. * @package WebCore
  7. * @subpackage Pdf
  8. * @author original work Renato A.C. webcore implementation Geo Perez
  9. */
  10. class PdfWriter extends PdfGenerator
  11. {
  12. protected $pgwidth;
  13. protected $fontlist;
  14. protected $issetcolor;
  15. protected $titulo;
  16. protected $oldx;
  17. protected $oldy;
  18. protected $B;
  19. protected $U;
  20. protected $I;
  21. protected $tablestart;
  22. protected $tdbegin;
  23. protected $table;
  24. protected $cell;
  25. protected $col;
  26. protected $row;
  27. protected $divSettings;
  28. protected $listlvl;
  29. protected $listnum;
  30. protected $listtype;
  31. protected $listoccur;
  32. protected $listlist;
  33. protected $listitem;
  34. protected $buffer_on;
  35. protected $pbegin;
  36. protected $pjustfinished;
  37. protected $blockjustfinished;
  38. protected $SUP;
  39. protected $SUB;
  40. protected $toupper;
  41. protected $tolower;
  42. protected $dash_on;
  43. protected $dotted_on;
  44. protected $strike;
  45. protected $CSS;
  46. protected $cssbegin;
  47. protected $backupcss;
  48. protected $textbuffer;
  49. protected $currentstyle;
  50. protected $currentfont;
  51. protected $colorarray;
  52. protected $bgcolorarray;
  53. protected $enabledtags;
  54. protected $lineheight;
  55. protected $basepath;
  56. protected $outlineparam;
  57. protected $outline_on;
  58. protected $specialcontent;
  59. protected $selectoption;
  60. public function __construct($orientation='P', $unit='mm', $format='letter')
  61. {
  62. parent::__construct($orientation, $unit, $format);
  63. $this->AliasNbPages();
  64. $this->enabledtags = "<option><outline><span><newpage><page_break><s><strike><del><ins><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>";
  65. $this->setFont('Arial', '', 11);
  66. $this->lineheight = 5;
  67. $this->pgwidth = $this->fw - $this->lMargin - $this->rMargin ;
  68. $this->setFillColor(255);
  69. $this->titulo='';
  70. $this->oldx=-1;
  71. $this->oldy=-1;
  72. $this->B=0;
  73. $this->U=0;
  74. $this->I=0;
  75. $this->listlvl=0;
  76. $this->listnum=0;
  77. $this->listtype='';
  78. $this->listoccur=array();
  79. $this->listlist=array();
  80. $this->listitem=array();
  81. $this->tablestart=false;
  82. $this->tdbegin=false;
  83. $this->table=array();
  84. $this->cell=array();
  85. $this->col=-1;
  86. $this->row=-1;
  87. $divSettings = array ("divbegin" => false,
  88. "divalign" => "L",
  89. "divwidth" => 0,
  90. "divheight" => 0,
  91. "divbgcolor" => false,
  92. "divcolor" => false,
  93. "divborder" => 0);
  94. $this->divSettings = new KeyedCollectionWrapper($divSettings, false);
  95. $this->fontlist=array("arial","times","courier","helvetica","symbol","monospace","serif","sans");
  96. $this->issetcolor=false;
  97. $this->pbegin=false;
  98. $this->pjustfinished=false;
  99. $this->blockjustfinished = true;
  100. $this->toupper=false;
  101. $this->tolower=false;
  102. $this->dash_on=false;
  103. $this->dotted_on=false;
  104. $this->SUP=false;
  105. $this->SUB=false;
  106. $this->buffer_on=false;
  107. $this->strike=false;
  108. $this->currentfont='';
  109. $this->currentstyle='';
  110. $this->colorarray=array();
  111. $this->bgcolorarray=array();
  112. $this->cssbegin=false;
  113. $this->textbuffer=array();
  114. $this->CSS=array();
  115. $this->backupcss=array();
  116. $this->basepath = "";
  117. $this->outlineparam = array();
  118. $this->outline_on = false;
  119. $this->specialcontent = '';
  120. $this->selectoption = array();
  121. }
  122. public function setBasePath($str)
  123. {
  124. $this->basepath = dirname($str) . "/";
  125. $this->basepath = str_replace("\\","/",$this->basepath); //If on Windows
  126. }
  127. public function header($content='')
  128. {
  129. if ($content == '')
  130. return;
  131. $y = $this->y;
  132. foreach($content as $tableheader)
  133. {
  134. $this->y = $y;
  135. $x = $tableheader['x'];
  136. $w = $tableheader['w'];
  137. $h = $tableheader['h'];
  138. $va = $tableheader['va'];
  139. $mih = $tableheader['mih'];
  140. $border = $tableheader['border'];
  141. $align = $tableheader['a'];
  142. $this->divalign=$align;
  143. $this->x = $x;
  144. if (!isset($va) || $va=='M')
  145. $this->y += ($h-$mih)/2;
  146. elseif (isset($va) && $va=='B')
  147. $this->y += $h-$mih;
  148. if (isset($border) and $border != 'all')
  149. $this->_tableRect($x, $y, $w, $h, $border);
  150. elseif (isset($border) && $border == 'all')
  151. $this->Rect($x, $y, $w, $h);
  152. $value = $w-2;
  153. $this->divSettings->setValue("divwidth", $value);
  154. $this->divheight = 1.1*$this->lineheight;
  155. $textbuffer = $tableheader['textbuffer'];
  156. if (!empty($textbuffer))
  157. $this->printbuffer($textbuffer,false,true/*inside a table*/);
  158. $textbuffer = array();
  159. }
  160. $this->y = $y + $h;
  161. }
  162. public function footer()
  163. {
  164. $this->setY(-10);
  165. $this->setFont('Arial', 'B', 9);
  166. $this->setTextColor(0);
  167. $this->setFont('Arial','I',9);
  168. $this->Cell(0,10,$this->PageNo().'/{nb}', 0, 0, 'C');
  169. $this->setFont('Arial','',11);
  170. }
  171. public function writeHTML($html)
  172. {
  173. if($this->page==0) $this->addPage();
  174. $html = $this->adjustHtml($html);
  175. $html = $this->readCss($html);
  176. $html = str_replace('<?','< ',$html);
  177. $html = strip_tags($html,$this->enabledtags);
  178. $a = preg_split('/<(.*?)>/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
  179. foreach($a as $i => $e)
  180. {
  181. if($i%2==0)
  182. {
  183. if (strpos($e,"&") !== false)
  184. {
  185. if (strpos($e,"#") !== false)
  186. $e = $this->value_entity_decode($e);
  187. $e = html_entity_decode($e,ENT_QUOTES,'cp1252');
  188. }
  189. $e = str_replace(chr(160),chr(32),$e);
  190. if (strlen($e) == 0)
  191. continue;
  192. if ($this->toupper) $e = strtoupper($e);
  193. if ($this->tolower) $e = strtolower($e);
  194. if($this->titulo)
  195. $this->setTitle($e);
  196. elseif($this->specialcontent)
  197. {
  198. if ($this->specialcontent == "type=select" and $this->selectoption['ACTIVE'] == true)
  199. {
  200. $stringwidth = $this->GetStringWidth($e);
  201. if (!isset($this->selectoption['MAXWIDTH']) or $stringwidth > $this->selectoption['MAXWIDTH'])
  202. $this->selectoption['MAXWIDTH'] = $stringwidth;
  203. if (!isset($this->selectoption['SELECTED']) or $this->selectoption['SELECTED'] == '')
  204. $this->selectoption['SELECTED'] = $e;
  205. }
  206. else
  207. $this->textbuffer[] = array("»¤¬"/*identifier*/.$this->specialcontent."»¤¬".$e);
  208. }
  209. elseif($this->tablestart)
  210. {
  211. if($this->tdbegin)
  212. {
  213. $this->cell[$this->row][$this->col]['textbuffer'][] = array($e,'',$this->currentstyle,
  214. $this->colorarray,$this->currentfont,
  215. $this->SUP,$this->SUB,'',$this->strike,
  216. $this->outlineparam,$this->bgcolorarray);
  217. $this->cell[$this->row][$this->col]['text'][] = $e;
  218. $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth($e);
  219. }
  220. }
  221. elseif($this->pbegin or $this->divSettings->getValue("divbegin") or $this->SUP or $this->SUB or $this->strike or $this->buffer_on)
  222. {
  223. $this->textbuffer[] = array($e, '',$this->currentstyle,$this->colorarray,$this->currentfont,
  224. $this->SUP,$this->SUB,'',$this->strike,$this->outlineparam,
  225. $this->bgcolorarray);
  226. }
  227. else
  228. {
  229. if ($this->blockjustfinished) $e = ltrim($e);
  230. if ($e != '')
  231. {
  232. $this->Write($this->lineheight,$e);
  233. if ($this->pjustfinished) $this->pjustfinished = false;
  234. }
  235. }
  236. }
  237. else
  238. {
  239. if ($e{0} == '/')
  240. {
  241. $this->CloseTag(strtoupper(substr($e,1)));
  242. }
  243. else
  244. {
  245. $e = preg_replace('|=\'(.*?)\'|s', "=\"\$1\"", $e);
  246. $e = preg_replace('| (\\w+?)=([^\\s>"]+)|si', " \$1=\"\$2\"", $e);
  247. if ((stristr($e,"href=") !== false) or (stristr($e,"src=") !== false) )
  248. {
  249. $regexp = '/ (href|src)="(.*?)"/i';
  250. preg_match($regexp,$e,$auxiliararray);
  251. $path = $auxiliararray[2];
  252. $path = str_replace("\\","/",$path); //If on Windows
  253. $regexp = '|^./|';
  254. $path = preg_replace($regexp,'',$path);
  255. if($path{0} != '#') //It is not an Internal Link
  256. {
  257. if (strpos($path,"../") !== false ) //It is a Relative Link
  258. {
  259. $backtrackamount = substr_count($path,"../");
  260. $maxbacktrack = substr_count($this->basepath,"/") - 1;
  261. $filepath = str_replace("../",'',$path);
  262. $path = $this->basepath;
  263. //If it is an invalid relative link, then make it go to directory root
  264. if ($backtrackamount > $maxbacktrack) $backtrackamount = $maxbacktrack;
  265. //Backtrack some directories
  266. for( $i = 0 ; $i < $backtrackamount + 1 ; $i++ ) $path = substr( $path, 0 , strrpos($path,"/") );
  267. $path = $path . "/" . $filepath; //Make it an absolute path
  268. }
  269. elseif( strpos($path,":/") === false) //It is a Local Link
  270. {
  271. $path = $this->basepath . $path;
  272. }
  273. }
  274. $e = preg_replace('/ (href|src)="(.*?)"/i',' \\1="'.$path.'"',$e);
  275. }
  276. $contents=array();
  277. preg_match_all('/\\S*=["\'][^"\']*["\']/',$e,$contents);
  278. preg_match('/\\S+/',$e,$a2);
  279. $tag=strtoupper($a2[0]);
  280. $attr=array();
  281. if (!empty($contents))
  282. {
  283. foreach($contents[0] as $v)
  284. {
  285. if(ereg('^([^=]*)=["\']?([^"\']*)["\']?$',$v,$a3))
  286. $attr[strtoupper($a3[1])]=$a3[2];
  287. }
  288. }
  289. $this->openTag($tag,$attr);
  290. }
  291. }
  292. }
  293. }
  294. private function openTag($tag,$attr)
  295. {
  296. $align = array('left'=>'L','center'=>'C','right'=>'R','top'=>'T','middle'=>'M','bottom'=>'B','justify'=>'J');
  297. $this->blockjustfinished=false;
  298. switch($tag)
  299. {
  300. case 'PAGE_BREAK':
  301. case 'NEWPAGE':
  302. $this->blockjustfinished = true;
  303. $this->addPage();
  304. break;
  305. case 'S':
  306. case 'STRIKE':
  307. case 'DEL':
  308. $this->strike=true;
  309. break;
  310. case 'SUB':
  311. $this->SUB=true;
  312. break;
  313. case 'SUP':
  314. $this->SUP=true;
  315. break;
  316. case 'TABLE':
  317. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  318. $this->tablestart = true;
  319. $this->table['nc'] = $this->table['nr'] = 0;
  320. if (isset($attr['WIDTH'])) $this->table['w'] = $this->convertSize($attr['WIDTH'],$this->pgwidth);
  321. if (isset($attr['HEIGHT'])) $this->table['h'] = $this->convertSize($attr['HEIGHT'],$this->pgwidth);
  322. if (isset($attr['ALIGN'])) $this->table['a'] = $align[strtolower($attr['ALIGN'])];
  323. if (isset($attr['BORDER'])) $this->table['border'] = $attr['BORDER'];
  324. break;
  325. case 'TR':
  326. $this->row++;
  327. $this->table['nr']++;
  328. $this->col = -1;
  329. break;
  330. case 'TH':
  331. $this->setStyle('B',true);
  332. if (!isset($attr['ALIGN'])) $attr['ALIGN'] = "center";
  333. case 'TD':
  334. $this->tdbegin = true;
  335. $this->col++;
  336. while (isset($this->cell[$this->row][$this->col]))
  337. $this->col++;
  338. if ($this->table['nc'] < $this->col+1)
  339. $this->table['nc'] = $this->col+1;
  340. $this->cell[$this->row][$this->col] = array();
  341. $this->cell[$this->row][$this->col]['text'] = array();
  342. $this->cell[$this->row][$this->col]['s'] = 3;
  343. if (isset($attr['WIDTH'])) $this->cell[$this->row][$this->col]['w'] = $this->convertSize($attr['WIDTH'],$this->pgwidth);
  344. if (isset($attr['HEIGHT'])) $this->cell[$this->row][$this->col]['h'] = $this->convertSize($attr['HEIGHT'],$this->pgwidth);
  345. if (isset($attr['ALIGN'])) $this->cell[$this->row][$this->col]['a'] = $align[strtolower($attr['ALIGN'])];
  346. if (isset($attr['VALIGN'])) $this->cell[$this->row][$this->col]['va'] = $align[strtolower($attr['VALIGN'])];
  347. if (isset($attr['BORDER'])) $this->cell[$this->row][$this->col]['border'] = $attr['BORDER'];
  348. $cs = $rs = 1;
  349. if (isset($attr['COLSPAN']) && $attr['COLSPAN']>1) $cs = $this->cell[$this->row][$this->col]['colspan'] = $attr['COLSPAN'];
  350. if (isset($attr['ROWSPAN']) && $attr['ROWSPAN']>1) $rs = $this->cell[$this->row][$this->col]['rowspan'] = $attr['ROWSPAN'];
  351. for ($k=$this->row ; $k < $this->row+$rs ;$k++)
  352. {
  353. for($l=$this->col; $l < $this->col+$cs ;$l++)
  354. {
  355. if ($k-$this->row || $l-$this->col)
  356. $this->cell[$k][$l] = 0;
  357. }
  358. }
  359. if (isset($attr['NOWRAP'])) $this->cell[$this->row][$this->col]['nowrap']= 1;
  360. break;
  361. case 'OL':
  362. if (!isset($attr['TYPE']) or $attr['TYPE'] == '')
  363. $this->listtype = '1';
  364. else
  365. $this->listtype = $attr['TYPE'];
  366. case 'UL':
  367. if ((!isset($attr['TYPE']) or $attr['TYPE'] == '') and $tag=='UL')
  368. {
  369. //Insert UL defaults
  370. if ($this->listlvl == 0) $this->listtype = 'disc';
  371. elseif ($this->listlvl == 1) $this->listtype = 'circle';
  372. else $this->listtype = 'square';
  373. }
  374. elseif (isset($attr['TYPE']) and $tag=='UL') $this->listtype = $attr['TYPE'];
  375. $this->buffer_on = false;
  376. if ($this->listlvl == 0)
  377. {
  378. if (!$this->pjustfinished)
  379. {
  380. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  381. $this->Ln($this->lineheight);
  382. }
  383. $this->oldx = $this->x;
  384. $this->listlvl++; // first depth level
  385. $this->listnum = 0; // reset
  386. $this->listoccur[$this->listlvl] = 1;
  387. $this->listlist[$this->listlvl][1] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
  388. }
  389. else
  390. {
  391. if (!empty($this->textbuffer))
  392. {
  393. $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
  394. $this->listnum++;
  395. }
  396. $this->textbuffer = array();
  397. $occur = $this->listoccur[$this->listlvl];
  398. $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
  399. $this->listlvl++;
  400. $this->listnum = 0; // reset
  401. if ($this->listoccur[$this->listlvl] == 0) $this->listoccur[$this->listlvl] = 1;
  402. else $this->listoccur[$this->listlvl]++;
  403. $occur = $this->listoccur[$this->listlvl];
  404. $this->listlist[$this->listlvl][$occur] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
  405. }
  406. break;
  407. case 'LI':
  408. if ($this->listlvl == 0)
  409. {
  410. if (!$this->pjustfinished and $this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
  411. $this->oldx = $this->x;
  412. $this->listlvl++; // first depth level
  413. $this->listnum = 0; // reset
  414. $this->listoccur[$this->listlvl] = 1;
  415. $this->listlist[$this->listlvl][1] = array('TYPE'=>'disc','MAXNUM'=>$this->listnum);
  416. }
  417. if ($this->listnum == 0)
  418. {
  419. $this->buffer_on = true; //activate list 'bufferization'
  420. $this->listnum++;
  421. $this->textbuffer = array();
  422. }
  423. else
  424. {
  425. $this->buffer_on = true; //activate list 'bufferization'
  426. if (!empty($this->textbuffer))
  427. {
  428. $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
  429. $this->listnum++;
  430. }
  431. $this->textbuffer = array();
  432. }
  433. break;
  434. case 'H1': // 2 * fontsize
  435. case 'H2': // 1.5 * fontsize
  436. case 'H3': // 1.17 * fontsize
  437. case 'H4': // 1 * fontsize
  438. case 'H5': // 0.83 * fontsize
  439. case 'H6': // 0.67 * fontsize
  440. $this->buffer_on = true;
  441. if ($this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
  442. elseif (!$this->pjustfinished) $this->Ln($this->lineheight);
  443. $this->setStyle('B',true);
  444. switch($tag)
  445. {
  446. case 'H1':
  447. $this->setFontSize(2*$this->FontSizePt);
  448. $this->lineheight *= 2;
  449. break;
  450. case 'H2':
  451. $this->setFontSize(1.5*$this->FontSizePt);
  452. $this->lineheight *= 1.5;
  453. break;
  454. case 'H3':
  455. $this->setFontSize(1.17*$this->FontSizePt);
  456. $this->lineheight *= 1.17;
  457. break;
  458. case 'H4':
  459. $this->setFontSize($this->FontSizePt);
  460. break;
  461. case 'H5':
  462. $this->setFontSize(0.83*$this->FontSizePt);
  463. $this->lineheight *= 0.83;
  464. break;
  465. case 'H6':
  466. $this->setFontSize(0.67*$this->FontSizePt);
  467. $this->lineheight *= 0.67;
  468. break;
  469. }
  470. break;
  471. case 'HR':
  472. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  473. $this->Ln(0.2*$this->lineheight);
  474. $hrwidth = $this->pgwidth;
  475. $this->setDrawColor(200, 200, 200);
  476. $x = $this->x;
  477. $y = $this->y;
  478. $empty = $this->pgwidth - $hrwidth;
  479. $empty /= 2;
  480. $x += $empty;
  481. $oldlinewidth = $this->LineWidth;
  482. $this->setLineWidth(0.3);
  483. $this->Line($x,$y,$x+$hrwidth,$y);
  484. $this->setLineWidth($oldlinewidth);
  485. $this->Ln(0.2*$this->lineheight);
  486. $this->setDrawColor(0);
  487. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  488. break;
  489. case 'INS':
  490. $this->setStyle('U',true);
  491. break;
  492. case 'TITLE':
  493. $this->titulo = true;
  494. break;
  495. case 'B':
  496. case 'I':
  497. case 'U':
  498. if( isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
  499. {
  500. $this->cssbegin=true;
  501. if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
  502. elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
  503. //Read Inline CSS
  504. if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
  505. //Look for name in the $this->CSS array
  506. $this->backupcss = $properties;
  507. if (!empty($properties)) $this->setCSS($properties); //name found in the CSS array!
  508. }
  509. $this->setStyle($tag,true);
  510. break;
  511. case 'A':
  512. if (isset($attr['NAME']) and $attr['NAME'] != '')
  513. $this->textbuffer[] = array('','','',array(),'',false,false,$attr['NAME']); //an internal link (adds a space for recognition)
  514. break;
  515. case 'DIV':
  516. if ($this->listlvl > 0) // We are closing (omitted) OL/UL tag(s)
  517. {
  518. $this->buffer_on = false;
  519. if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
  520. $this->textbuffer = array();
  521. $this->listlvl--;
  522. $this->printlistbuffer();
  523. $this->pjustfinished = true; //act as if a paragraph just ended
  524. }
  525. $this->divSettings->setValue("divbegin", true);
  526. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  527. if( isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
  528. {
  529. $this->cssbegin=true;
  530. if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
  531. elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
  532. //Read Inline CSS
  533. if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
  534. //Look for name in the $this->CSS array
  535. if (!empty($properties)) $this->setCSS($properties); //name found in the CSS array!
  536. }
  537. break;
  538. case 'IMG':
  539. if(!empty($this->textbuffer) and !$this->tablestart)
  540. {
  541. $olddivwidth = $this->divSettings->getValue("divwidth");
  542. $olddivheight = $this->divSettings->getValue("divheight");
  543. if ( $olddivwidth == 0) $this->divwidth = $this->pgwidth - $x + $this->lMargin;
  544. if ( $olddivheight == 0) $this->divheight = $this->lineheight;
  545. //Print content
  546. $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
  547. $this->textbuffer=array();
  548. $this->divSettings->setValue("divwidth", $olddivwidth);
  549. $this->divSettings->setValue("divheight", $olddivheight);
  550. $this->textbuffer=array();
  551. $this->Ln($this->lineheight);
  552. }
  553. if(isset($attr['SRC']))
  554. {
  555. $srcpath = $attr['SRC'];
  556. if(!isset($attr['WIDTH'])) $attr['WIDTH'] = 0;
  557. else $attr['WIDTH'] = $this->convertSize($attr['WIDTH'],$this->pgwidth);//$attr['WIDTH'] /= 4;
  558. if(!isset($attr['HEIGHT'])) $attr['HEIGHT'] = 0;
  559. else $attr['HEIGHT'] = $this->convertSize($attr['HEIGHT'],$this->pgwidth);//$attr['HEIGHT'] /= 4;
  560. if ($this->tdbegin)
  561. {
  562. $bak_x = $this->x;
  563. $bak_y = $this->y;
  564. $f_exists = @fopen($srcpath,"rb");
  565. if (!$f_exists)
  566. break;
  567. $sizesarray = $this->Image($srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'],'','',false);
  568. $this->y = $bak_y;
  569. $this->x = $bak_x;
  570. }
  571. elseif($this->pbegin or $this->divSettings->getValue("divbegin"))
  572. {
  573. $ypos = 0;
  574. $bak_x = $this->x;
  575. $bak_y = $this->y;
  576. $f_exists = @fopen($srcpath,"rb");
  577. if (!$f_exists)
  578. break;
  579. $sizesarray = $this->Image($srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'],'','',false);
  580. $this->y = $bak_y;
  581. $this->x = $bak_x;
  582. $xpos = '';
  583. switch($this->divalign)
  584. {
  585. case "C":
  586. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  587. $empty = ($this->pgwidth - $sizesarray['WIDTH'])/2;
  588. $xpos = 'xpos='.$empty.',';
  589. break;
  590. case "R":
  591. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  592. $empty = ($this->pgwidth - $sizesarray['WIDTH']);
  593. $xpos = 'xpos='.$empty.',';
  594. break;
  595. default: break;
  596. }
  597. $numberoflines = (integer)ceil($sizesarray['HEIGHT']/$this->lineheight) ;
  598. $ypos = $numberoflines * $this->lineheight;
  599. $this->textbuffer[] = array("»¤¬"/*identifier*/."type=image,ypos=$ypos,{$xpos}width=".$sizesarray['WIDTH'].",height=".$sizesarray['HEIGHT']."»¤¬".$sizesarray['OUTPUT']);
  600. while($numberoflines)
  601. {
  602. $this->textbuffer[] = array("\n", '' ,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);$numberoflines--;
  603. }
  604. }
  605. else
  606. {
  607. $imgborder = 0;
  608. if (isset($attr['BORDER'])) $imgborder = $this->convertSize($attr['BORDER'],$this->pgwidth);
  609. $f_exists = @fopen($srcpath,"rb");
  610. if (!$f_exists) //Show 'image not found' icon instead
  611. {
  612. $srcpath = str_replace("\\","/",dirname(__FILE__)) . "/";
  613. $srcpath .= 'no_img.gif';
  614. }
  615. $sizesarray = $this->Image($srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'],'', ''); //Output Image
  616. $ini_x = $sizesarray['X'];
  617. $ini_y = $sizesarray['Y'];
  618. if ($imgborder)
  619. {
  620. $oldlinewidth = $this->LineWidth;
  621. $this->setLineWidth($imgborder);
  622. $this->Rect($ini_x,$ini_y,$sizesarray['WIDTH'],$sizesarray['HEIGHT']);
  623. $this->setLineWidth($oldlinewidth);
  624. }
  625. }
  626. if ($sizesarray['X'] < $this->x) $this->x = $this->lMargin;
  627. if ($this->tablestart)
  628. {
  629. $this->cell[$this->row][$this->col]['textbuffer'][] = array("»¤¬"/*identifier*/."type=image,width=".$sizesarray['WIDTH'].",height=".$sizesarray['HEIGHT']."»¤¬".$sizesarray['OUTPUT']);
  630. $this->cell[$this->row][$this->col]['s'] += $sizesarray['WIDTH'] + 1;// +1 == margin
  631. $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later
  632. if (!isset($this->cell[$this->row][$this->col]['w'])) $this->cell[$this->row][$this->col]['w'] = $sizesarray['WIDTH'] + 3;
  633. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $sizesarray['HEIGHT'] + 3;
  634. }
  635. }
  636. break;
  637. case 'BLOCKQUOTE':
  638. case 'BR':
  639. if($this->tablestart)
  640. {
  641. $this->cell[$this->row][$this->col]['textbuffer'][] = array("\n", '',$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
  642. $this->cell[$this->row][$this->col]['text'][] = "\n";
  643. 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
  644. 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
  645. $this->cell[$this->row][$this->col]['s'] = 0;// reset
  646. }
  647. elseif($this->divSettings->getValue("divbegin") or $this->pbegin or $this->buffer_on) $this->textbuffer[] = array("\n", '',$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
  648. else {$this->Ln($this->lineheight);$this->blockjustfinished = true;}
  649. break;
  650. case 'P':
  651. //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
  652. if ($this->listlvl > 0) // We are closing (omitted) OL/UL tag(s)
  653. {
  654. $this->buffer_on = false;
  655. if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
  656. $this->textbuffer = array();
  657. $this->listlvl--;
  658. $this->printlistbuffer();
  659. $this->pjustfinished = true; //act as if a paragraph just ended
  660. }
  661. if ($this->tablestart)
  662. {
  663. $this->cell[$this->row][$this->col]['textbuffer'][] = array($e, '',$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
  664. $this->cell[$this->row][$this->col]['text'][] = "\n";
  665. break;
  666. }
  667. $this->pbegin=true;
  668. if ($this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
  669. elseif (!$this->pjustfinished) $this->Ln($this->lineheight);
  670. //Save x,y coords in case we need to print borders...
  671. $this->oldx = $this->x;
  672. $this->oldy = $this->y;
  673. if(isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
  674. {
  675. $this->cssbegin=true;
  676. if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
  677. elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
  678. //Read Inline CSS
  679. if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
  680. $this->backupcss = $properties;
  681. if (!empty($properties)) $this->setCSS($properties); //name(id/class/style) found in the CSS array!
  682. }
  683. break;
  684. case 'SPAN':
  685. $this->buffer_on = true;
  686. //Save x,y coords in case we need to print borders...
  687. $this->oldx = $this->x;
  688. $this->oldy = $this->y;
  689. if( isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
  690. {
  691. $this->cssbegin=true;
  692. if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
  693. elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
  694. //Read Inline CSS
  695. if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
  696. //Look for name in the $this->CSS array
  697. $this->backupcss = $properties;
  698. if (!empty($properties)) $this->setCSS($properties); //name found in the CSS array!
  699. }
  700. break;
  701. case 'PRE':
  702. if($this->tablestart)
  703. {
  704. $this->cell[$this->row][$this->col]['textbuffer'][] = array("\n", '',$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
  705. $this->cell[$this->row][$this->col]['text'][] = "\n";
  706. }
  707. elseif($this->divSettings->getValue("divbegin") or $this->pbegin or $this->buffer_on) $this->textbuffer[] = array("\n", '',$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
  708. else
  709. {
  710. if ($this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
  711. elseif (!$this->pjustfinished) $this->Ln($this->lineheight);
  712. $this->buffer_on = true;
  713. $this->oldx = $this->x;
  714. $this->oldy = $this->y;
  715. if(isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
  716. {
  717. $this->cssbegin=true;
  718. if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
  719. elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
  720. //Read Inline CSS
  721. if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
  722. //Look for name in the $this->CSS array
  723. $this->backupcss = $properties;
  724. if (!empty($properties)) $this->setCSS($properties); //name(id/class/style) found in the CSS array!
  725. }
  726. }
  727. case 'CODE':
  728. $this->setFont('courier');
  729. $this->currentfont='courier';
  730. break;
  731. case 'TEXTAREA':
  732. $this->buffer_on = true;
  733. $colsize = 20; //HTML default value
  734. $rowsize = 2; //HTML default value
  735. if (isset($attr['COLS'])) $colsize = $attr['COLS'];
  736. if (isset($attr['ROWS'])) $rowsize = $attr['ROWS'];
  737. if (!$this->tablestart)
  738. {
  739. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  740. $this->col = $colsize;
  741. $this->row = $rowsize;
  742. }
  743. else //it is inside a table
  744. {
  745. $this->specialcontent = "type=textarea,lines=$rowsize,width=".((2.2*$colsize) + 3); //Activate form info in order to paint FORM elements within table
  746. $this->cell[$this->row][$this->col]['s'] += (2.2*$colsize) + 6;// +6 == margin
  747. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = 1.1*$this->lineheight*$rowsize + 2.5;
  748. }
  749. break;
  750. case 'SELECT':
  751. $this->specialcontent = "type=select"; //Activate form info in order to paint FORM elements within table
  752. break;
  753. case 'OPTION':
  754. $this->selectoption['ACTIVE'] = true;
  755. if (empty($this->selectoption))
  756. {
  757. $this->selectoption['MAXWIDTH'] = '';
  758. $this->selectoption['SELECTED'] = '';
  759. }
  760. if (isset($attr['SELECTED'])) $this->selectoption['SELECTED'] = '';
  761. break;
  762. case 'FORM':
  763. if($this->tablestart)
  764. {
  765. $this->cell[$this->row][$this->col]['textbuffer'][] = array($e, '',$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
  766. $this->cell[$this->row][$this->col]['text'][] = "\n";
  767. }
  768. elseif ($this->x != $this->lMargin) $this->Ln($this->lineheight); //Skip a line, if needed
  769. break;
  770. case 'INPUT':
  771. if (!isset($attr['TYPE'])) $attr['TYPE'] == ''; //in order to allow default 'TEXT' form (in case of malformed HTML code)
  772. if (!$this->tablestart)
  773. {
  774. switch(strtoupper($attr['TYPE'])){
  775. case 'CHECKBOX': //Draw Checkbox
  776. $checked = false;
  777. if (isset($attr['CHECKED'])) $checked = true;
  778. $this->setFillColor(235,235,235);
  779. $this->x += 3;
  780. $this->Rect($this->x,$this->y+1,3,3,'DF');
  781. if ($checked)
  782. {
  783. $this->Line($this->x,$this->y+1,$this->x+3,$this->y+1+3);
  784. $this->Line($this->x,$this->y+1+3,$this->x+3,$this->y+1);
  785. }
  786. $this->setFillColor(255);
  787. $this->x += 3.5;
  788. break;
  789. case 'RADIO': //Draw Radio button
  790. $checked = false;
  791. if (isset($attr['CHECKED'])) $checked = true;
  792. $this->x += 4;
  793. $this->Circle($this->x,$this->y+2.2,1,'D');
  794. $this->_out('0.000 g');
  795. if ($checked) $this->Circle($this->x,$this->y+2.2,0.4,'DF');
  796. $this->Write(5,$texto,$this->x);
  797. $this->x += 2;
  798. break;
  799. case 'BUTTON':
  800. case 'SUBMIT':
  801. case 'RESET':
  802. $texto='';
  803. if (isset($attr['VALUE'])) $texto = $attr['VALUE'];
  804. $nihil = 2.5;
  805. $this->x += 2;
  806. $this->setFillColor(190,190,190);
  807. $this->Rect($this->x,$this->y,$this->GetStringWidth($texto)+2*$nihil,4.5,'DF'); // 4.5 in order to avoid overlapping
  808. $this->x += $nihil;
  809. $this->Write(5,$texto,$this->x);
  810. $this->x += $nihil;
  811. $this->setFillColor(255);
  812. break;
  813. case 'PASSWORD':
  814. if (isset($attr['VALUE']))
  815. {
  816. $num_stars = strlen($attr['VALUE']);
  817. $attr['VALUE'] = str_repeat('*',$num_stars);
  818. }
  819. case 'TEXT': //Draw TextField
  820. default: //default == TEXT
  821. $texto='';
  822. if (isset($attr['VALUE'])) $texto = $attr['VALUE'];
  823. $tamanho = 20;
  824. if (isset($attr['SIZE']) and ctype_digit($attr['SIZE']) ) $tamanho = $attr['SIZE'];
  825. $this->setFillColor(235,235,235);
  826. $this->x += 2;
  827. $this->Rect($this->x,$this->y,2*$tamanho,4.5,'DF');// 4.5 in order to avoid overlapping
  828. if ($texto != '')
  829. {
  830. $this->x += 1;
  831. $this->Write(5,$texto,$this->x);
  832. $this->x -= $this->GetStringWidth($texto);
  833. }
  834. $this->setFillColor(255);
  835. $this->x += 2*$tamanho;
  836. break;
  837. }
  838. }
  839. else //we are inside a table
  840. {
  841. $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later
  842. $type = '';
  843. $text = '';
  844. $height = 0;
  845. $width = 0;
  846. switch(strtoupper($attr['TYPE'])){
  847. case 'CHECKBOX': //Draw Checkbox
  848. $checked = false;
  849. if (isset($attr['CHECKED'])) $checked = true;
  850. $text = $checked;
  851. $type = 'CHECKBOX';
  852. $width = 4;
  853. $this->cell[$this->row][$this->col]['textbuffer'][] = array("»¤¬"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."»¤¬".$text);
  854. $this->cell[$this->row][$this->col]['s'] += $width;
  855. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight;
  856. break;
  857. case 'RADIO': //Draw Radio button
  858. $checked = false;
  859. if (isset($attr['CHECKED'])) $checked = true;
  860. $text = $checked;
  861. $type = 'RADIO';
  862. $width = 3;
  863. $this->cell[$this->row][$this->col]['textbuffer'][] = array("»¤¬"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."»¤¬".$text);
  864. $this->cell[$this->row][$this->col]['s'] += $width;
  865. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight;
  866. break;
  867. case 'BUTTON': $type = 'BUTTON'; // Draw a button
  868. case 'SUBMIT': if ($type == '') $type = 'SUBMIT';
  869. case 'RESET': if ($type == '') $type = 'RESET';
  870. $texto='';
  871. if (isset($attr['VALUE'])) $texto = " " . $attr['VALUE'] . " ";
  872. $text = $texto;
  873. $width = $this->GetStringWidth($texto)+3;
  874. $this->cell[$this->row][$this->col]['textbuffer'][] = array("»¤¬"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."»¤¬".$text);
  875. $this->cell[$this->row][$this->col]['s'] += $width;
  876. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2;
  877. break;
  878. case 'PASSWORD':
  879. if (isset($attr['VALUE']))
  880. {
  881. $num_stars = strlen($attr['VALUE']);
  882. $attr['VALUE'] = str_repeat('*',$num_stars);
  883. }
  884. $type = 'PASSWORD';
  885. case 'TEXT': //Draw TextField
  886. default: //default == TEXT
  887. $texto='';
  888. if (isset($attr['VALUE'])) $texto = $attr['VALUE'];
  889. $tamanho = 20;
  890. if (isset($attr['SIZE']) and ctype_digit($attr['SIZE']) ) $tamanho = $attr['SIZE'];
  891. $text = $texto;
  892. $width = 2*$tamanho;
  893. if ($type == '') $type = 'TEXT';
  894. $this->cell[$this->row][$this->col]['textbuffer'][] = array("»¤¬"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."»¤¬".$text);
  895. $this->cell[$this->row][$this->col]['s'] += $width;
  896. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2;
  897. break;
  898. }
  899. }
  900. break;
  901. }
  902. $this->pjustfinished=false;
  903. }
  904. function CloseTag($tag)
  905. {
  906. if($tag=='OPTION') $this->selectoption['ACTIVE'] = false;
  907. if($tag=='INS') $tag='U';
  908. if($tag=='STRONG') $tag='B';
  909. if($tag=='EM' or $tag=='CITE') $tag='I';
  910. if($tag=='OUTLINE')
  911. {
  912. if(!$this->pbegin and !$this->divSettings->getValue("divbegin") and !$this->tablestart)
  913. {
  914. $this->setTextOutline(false);
  915. $this->outlineparam=array();
  916. //Save x,y coords ???
  917. $x = $this->x;
  918. $y = $this->y;
  919. //Set some default values
  920. $this->divSettings->setValue("divwidth", $this->pgwidth - $x + $this->lMargin);
  921. //Print content
  922. $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
  923. $this->textbuffer=array();
  924. //Reset values
  925. $this->Reset();
  926. $this->buffer_on=false;
  927. }
  928. $this->setTextOutline(false);
  929. $this->outlineparam=array();
  930. }
  931. if($tag=='A')
  932. {
  933. if(!$this->pbegin and !$this->divSettings->getValue("divbegin") and !$this->tablestart and !$this->buffer_on)
  934. {
  935. //Save x,y coords ???
  936. $x = $this->x;
  937. $y = $this->y;
  938. //Set some default values
  939. $this->divSettings->setValue("divwidth", $this->pgwidth - $x + $this->lMargin);
  940. //Print content
  941. $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
  942. $this->textbuffer=array();
  943. //Reset values
  944. $this->Reset();
  945. }
  946. }
  947. if($tag=='TH') $this->setStyle('B',false);
  948. if($tag=='TH' or $tag=='TD') $this->tdbegin = false;
  949. if($tag=='SPAN')
  950. {
  951. if(!$this->pbegin and !$this->divSettings->getValue("divbegin") and !$this->tablestart)
  952. {
  953. if($this->cssbegin)
  954. {
  955. //Check if we have borders to print
  956. if ($this->cssbegin and ($this->divborder or $this->dash_on or $this->dotted_on or $this->divbgcolor))
  957. {
  958. $texto='';
  959. foreach($this->textbuffer as $vetor) $texto.=$vetor[0];
  960. $tempx = $this->x;
  961. if($this->divbgcolor) $this->Cell($this->GetStringWidth($texto),$this->lineheight,'',$this->divborder,'','L',$this->divbgcolor);
  962. if ($this->dash_on) $this->Rect($this->oldx,$this->oldy,$this->GetStringWidth($texto),$this->lineheight);
  963. if ($this->dotted_on) $this->DottedRect($this->x - $this->GetStringWidth($texto),$this->y,$this->GetStringWidth($texto),$this->lineheight);
  964. $this->x = $tempx;
  965. $this->x -= 1; //adjust alignment
  966. }
  967. $this->cssbegin=false;
  968. $this->backupcss=array();
  969. }
  970. //Save x,y coords ???
  971. $x = $this->x;
  972. $y = $this->y;
  973. //Set some default values
  974. $this->divSettings->setValue("divwidth", $this->pgwidth - $x + $this->lMargin);
  975. //Print content
  976. $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
  977. $this->textbuffer=array();
  978. //Reset values
  979. $this->Reset();
  980. }
  981. $this->buffer_on=false;
  982. }
  983. if($tag=='P' or $tag=='DIV') //CSS in BLOCK mode
  984. {
  985. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  986. if(!$this->tablestart)
  987. {
  988. if ($this->divSettings->getValue("divwidth") == 0) $this->divSettings->setValue("divwidth", $this->pgwidth);
  989. if ($tag=='P')
  990. {
  991. $this->pbegin=false;
  992. $this->pjustfinished=true;
  993. }
  994. else $this->divSettings->setValue("divbegin", false);
  995. $content='';
  996. foreach($this->textbuffer as $aux) $content .= $aux[0];
  997. $numlines = $this->WordWrap($content, $this->divSettings->getValue("divwidth"));
  998. if ($this->divheight == 0) $this->divheight = $numlines * 5;
  999. //Print content
  1000. $this->printbuffer($this->textbuffer);
  1001. $this->textbuffer=array();
  1002. if ($tag=='P') $this->Ln($this->lineheight);
  1003. }//end of 'if (!this->tablestart)'
  1004. //Reset values
  1005. $this->Reset();
  1006. $this->cssbegin=false;
  1007. $this->backupcss=array();
  1008. }
  1009. if($tag=='TABLE') { // TABLE-END
  1010. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  1011. $this->table['cells'] = $this->cell;
  1012. $this->table['wc'] = array_pad(array(),$this->table['nc'],array('miw'=>0,'maw'=>0));
  1013. $this->table['hr'] = array_pad(array(),$this->table['nr'],0);
  1014. $this->_tableColumnWidth($this->table);
  1015. $this->_tableWidth($this->table);
  1016. $this->_tableHeight($this->table);
  1017. $this->_tableWrite($this->table);
  1018. //Reset values
  1019. $this->tablestart=false; //bool
  1020. $this->table=array(); //array
  1021. $this->cell=array(); //array
  1022. $this->col=-1; //int
  1023. $this->row=-1; //int
  1024. $this->Reset();
  1025. $this->Ln(0.5*$this->lineheight);
  1026. }
  1027. if(($tag=='UL') or ($tag=='OL')) {
  1028. if ($this->buffer_on == false) $this->listnum--;
  1029. if ($this->listlvl == 1) // We are closing the last OL/UL tag
  1030. {
  1031. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  1032. $this->buffer_on = false;
  1033. if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
  1034. $this->textbuffer = array();
  1035. $this->listlvl--;
  1036. $this->printlistbuffer();
  1037. }
  1038. else // returning one level
  1039. {
  1040. if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
  1041. $this->textbuffer = array();
  1042. $occur = $this->listoccur[$this->listlvl];
  1043. $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
  1044. $this->listlvl--;
  1045. $occur = $this->listoccur[$this->listlvl];
  1046. $this->listnum = $this->listlist[$this->listlvl][$occur]['MAXNUM']; // recover previous level's number
  1047. $this->listtype = $this->listlist[$this->listlvl][$occur]['TYPE']; // recover previous level's type
  1048. $this->buffer_on = false;
  1049. }
  1050. }
  1051. if($tag=='H1' or $tag=='H2' or $tag=='H3' or $tag=='H4' or $tag=='H5' or $tag=='H6')
  1052. {
  1053. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  1054. if(!$this->pbegin and !$this->divSettings->getValue("divbegin") and !$this->tablestart)
  1055. {
  1056. //These 2 codelines are useless?
  1057. $texto='';
  1058. foreach($this->textbuffer as $vetor) $texto.=$vetor[0];
  1059. //Save x,y coords ???
  1060. $x = $this->x;
  1061. $y = $this->y;
  1062. //Set some default values
  1063. $this->divSettings->setValue("divwidth", $this->pgwidth);
  1064. //Print content
  1065. $this->printbuffer($this->textbuffer);
  1066. $this->textbuffer=array();
  1067. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  1068. //Reset values
  1069. $this->Reset();
  1070. }
  1071. $this->buffer_on=false;
  1072. $this->lineheight = 5;
  1073. $this->Ln($this->lineheight);
  1074. $this->setFontSize(11);
  1075. $this->setStyle('B',false);
  1076. }
  1077. if($tag=='TITLE') {$this->titulo=false; $this->blockjustfinished = true;}
  1078. if($tag=='FORM') $this->Ln($this->lineheight);
  1079. if($tag=='PRE')
  1080. {
  1081. if(!$this->pbegin and !$this->divSettings->getValue("divbegin") and !$this->tablestart)
  1082. {
  1083. if ($this->divSettings->getValue("divwidth") == 0) $this->divwidth = $this->pgwidth;
  1084. $content='';
  1085. foreach($this->textbuffer as $aux) $content .= $aux[0];
  1086. $numlines = $this->WordWrap($content, $this->divSettings->getValue("divwidth"));
  1087. if ($this->divheight == 0) $this->divheight = $numlines * 5;
  1088. //Print content
  1089. $this->textbuffer[0][0] = ltrim($this->textbuffer[0][0]); //Remove exceeding left-side space
  1090. $this->printbuffer($this->textbuffer);
  1091. $this->textbuffer=array();
  1092. if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
  1093. //Reset values
  1094. $this->Reset();
  1095. $this->Ln(1.1*$this->lineheight);
  1096. }
  1097. if($this->tablestart)
  1098. {
  1099. $this->cell[$this->row][$this->col]['textbuffer'][] = array("\n", '',$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
  1100. $this->cell[$this->row][$this->col]['text'][] = "\n";
  1101. }
  1102. if($this->divSettings->getValue("divbegin") or $this->pbegin or $this->buffer_on) $this->textbuffer[] = array("\n", '',$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
  1103. $this->cssbegin=false;
  1104. $this->backupcss=array();
  1105. $this->buffer_on = false;
  1106. $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
  1107. $this->pjustfinished = true; //behaves the same way
  1108. }
  1109. if($tag=='CODE' or $tag=='PRE')
  1110. {
  1111. $this->currentfont='';
  1112. $this->setFont('arial');
  1113. }
  1114. if($tag=='B' or $tag=='I' or $tag=='U')
  1115. {
  1116. $this->setStyle($tag,false);
  1117. if ($this->cssbegin and !$this->divSettings->getValue("divbegin") and !$this->pbegin and !$this->buffer_on)
  1118. {
  1119. //Reset values
  1120. $this->Reset();
  1121. $this->cssbegin=false;
  1122. $this->backupcss=array();
  1123. }
  1124. }
  1125. if($tag=='TEXTAREA')
  1126. {
  1127. if (!$this->tablestart) //not inside a table
  1128. {
  1129. //Draw arrows too?
  1130. $texto = '';
  1131. foreach($this->textbuffer as $v) $texto .= $v[0];
  1132. $this->setFillColor(235,235,235);
  1133. $this->setFont('courier');
  1134. $this->x +=3;
  1135. $linesneeded = $this->WordWrap($texto,($this->col*2.2)+3);
  1136. if ( $linesneeded > $this->row ) //Too many words inside textarea
  1137. {
  1138. $textoaux = explode("\n",$texto);
  1139. $texto = '';
  1140. for($i=0;$i < $this->row;$i++)
  1141. {
  1142. if ($i == $this->row-1) $texto .= $textoaux[$i];
  1143. else $texto .= $textoaux[$i] . "\n";
  1144. }
  1145. //Inform the user that some text has been truncated
  1146. $texto{strlen($texto)-1} = ".";
  1147. $texto{strlen($texto)-2} = ".";
  1148. $texto{strlen($texto)-3} = ".";
  1149. }
  1150. $backup_y = $this->y;
  1151. $this->Rect($this->x,$this->y,(2.2*$this->col)+6,5*$this->row,'DF');
  1152. if ($texto != '') $this->MultiCell((2.2*$this->col)+6,$this->lineheight,$texto);
  1153. $this->y = $backup_y + $this->row*$this->lineheight;
  1154. $this->setFont('arial');
  1155. }
  1156. else //inside a table
  1157. {
  1158. $this->cell[$this->row][$this->col]['textbuffer'][] = $this->textbuffer[0];
  1159. $this->cell[$this->row][$this->col]['text'][] = $this->textbuffer[0];
  1160. $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later
  1161. $this->specialcontent = '';
  1162. }
  1163. $this->setFillColor(255);
  1164. $this->textbuffer=array();
  1165. $this->buffer_on = false;
  1166. }
  1167. if($tag=='SELECT')
  1168. {
  1169. $texto = '';
  1170. $tamanho = 0;
  1171. if (isset($this->selectoption['MAXWIDTH'])) $tamanho = $this->selectoption['MAXWIDTH'];
  1172. if ($this->tablestart)
  1173. {
  1174. $texto = "»¤¬".$this->specialcontent."»¤¬".$this->selectoption['SELECTED'];
  1175. $aux = explode("»¤¬",$texto);
  1176. $texto = $aux[2];
  1177. $texto = "»¤¬".$aux[1].",width=$tamanho,height=".($this->lineheight + 2)."»¤¬".$texto;
  1178. $this->cell[$this->row][$this->col]['s'] += $tamanho + 7; // margin + arrow box
  1179. $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later
  1180. if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2;
  1181. $this->cell[$this->row][$this->col]['textbuffer'][] = array($texto);
  1182. $this->cell[$this->row][$this->col]['text'][] = '';
  1183. }
  1184. else //not inside a table
  1185. {
  1186. $texto = $this->selectoption['SELECTED'];
  1187. $this->setFillColor(235,235,235);
  1188. $this->x += 2;
  1189. $this->Rect($this->x,$this->y,$tamanho+2,5,'DF');//+2 margin
  1190. $this->x += 1;
  1191. if ($texto != '') $this->Write(5,$texto,$this->x);
  1192. $this->x += $tamanho - $this->GetStringWidth($texto) + 2;
  1193. $this->setFillColor(190,190,190);
  1194. $this->Rect($this->x-1,$this->y,5,5,'DF'); //Arrow Box
  1195. $this->setFont('zapfdingbats');
  1196. $this->Write(5,chr(116),$this->x); //Down arrow
  1197. $this->setFont('arial');
  1198. $this->setFillColor(255);
  1199. $this->x += 1;
  1200. }
  1201. $this->selectoption = array();
  1202. $this->specialcontent = '';
  1203. $this->textbuffer = array();
  1204. }
  1205. if($tag=='SUB' or $tag=='SUP') //subscript or superscript
  1206. {
  1207. if(!$this->pbegin and !$this->divSettings->getValue("divbegin") and !$this->tablestart and !$this->buffer_on and !$this->strike)
  1208. {
  1209. $this->SUB=false;
  1210. $this->SUP=false;
  1211. $x = $this->x;
  1212. $y = $this->y;
  1213. $this->divSettings->setValue("divwidth", $this->pgwidth - $x + $this->lMargin);
  1214. //Print content
  1215. $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
  1216. $this->textbuffer=array();
  1217. //Reset values
  1218. $this->Reset();
  1219. }
  1220. $this->SUB=false;
  1221. $this->SUP=false;
  1222. }
  1223. if($tag=='S' or $tag=='STRIKE' or $tag=='DEL')
  1224. {
  1225. if(!$this->pbegin and !$this->divSettings->getValue("divbegin") and !$this->tablestart)
  1226. {
  1227. //Deactivate $this->strike for its info is already stored inside $this->textbuffer
  1228. $this->strike=false;
  1229. //Save x,y coords ???
  1230. $x = $this->x;
  1231. $y = $this->y;
  1232. //Set some default values
  1233. $this->divSettings->setValue("divwidth", $this->pgwidth - $x + $this->lMargin);
  1234. //Print content
  1235. $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
  1236. $this->textbuffer=array();
  1237. //Reset values
  1238. $this->Reset();
  1239. }
  1240. $this->strike=false;
  1241. }
  1242. }
  1243. function printlistbuffer()
  1244. {
  1245. //Save x coordinate
  1246. $x = $this->oldx;
  1247. foreach($this->listitem as $item)
  1248. {
  1249. //Set default width & height values
  1250. $this->divSettings->setValue("divwidth", $this->pgwidth);
  1251. $this->divheight = $this->lineheight;
  1252. //Get list's buffered data
  1253. $lvl = $item[0];
  1254. $num = $item[1];
  1255. $this->textbuffer = $item[2];
  1256. $occur = $item[3];
  1257. $type = $this->listlist[$lvl][$occur]['TYPE'];
  1258. $maxnum = $this->listlist[$lvl][$occur]['MAXNUM'];
  1259. switch($type) //Format type
  1260. {
  1261. case 'A':
  1262. $num = dec2alpha($num,true);
  1263. $maxnum = dec2alpha($maxnum,true);
  1264. $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
  1265. break;
  1266. case 'a':
  1267. $num = dec2alpha($num,false);
  1268. $maxnum = dec2alpha($maxnum,false);
  1269. $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
  1270. break;
  1271. case 'I':
  1272. $num = StringHelper::convertDecimalToRoman($num,true);
  1273. $maxnum = StringHelper::convertDecimalToRoman($maxnum,true);
  1274. $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
  1275. break;
  1276. case 'i':
  1277. $num = StringHelper::convertDecimalToRoman($num,false);
  1278. $maxnum = StringHelper::convertDecimalToRoman($maxnum,false);
  1279. $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
  1280. break;
  1281. case '1':
  1282. $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
  1283. break;
  1284. case 'disc':
  1285. $type = chr(149);
  1286. break;
  1287. case 'square':
  1288. $type = chr(110); //black square on Zapfdingbats font
  1289. break;
  1290. case 'circle':
  1291. $type = chr(186);
  1292. break;
  1293. default: break;
  1294. }
  1295. $this->x = (5*$lvl) + $x; //Indent list
  1296. //Get bullet width including margins
  1297. $oldsize = $this->FontSize * $this->k;
  1298. if ($type == chr(110)) $this->setFont('zapfdingbats','',5);
  1299. $type .= ' ';
  1300. $blt_width = $this->GetStringWidth($type)+$this->cMargin*2;
  1301. //Output bullet
  1302. $this->Cell($blt_width,5,$type,'','','L');
  1303. $this->setFont('arial','',$oldsize);
  1304. $this->divSettings->setValue("divwidth", $this->divSettings->getValue("divwidth") + $this->lMargin - $this->x);
  1305. //Print content
  1306. $this->printbuffer($this->textbuffer);
  1307. $this->textbuffer=array();
  1308. }
  1309. //Reset all used values
  1310. $this->listoccur = array();
  1311. $this->listitem = array();
  1312. $this->listlist = array();
  1313. $this->listlvl = 0;
  1314. $this->listnum = 0;
  1315. $this->listtype = '';
  1316. $this->textbuffer = array();
  1317. $this->divSettings->setValue("divwidth", 0);
  1318. $this->divheight = 0;
  1319. $this->oldx = -1;
  1320. //At last, but not least, skip a line
  1321. $this->Ln($this->lineheight);
  1322. }
  1323. function printbuffer($arrayaux,$outofblock=false,$is_table=false)
  1324. {
  1325. //Save some previous parameters
  1326. $save = array();
  1327. $save['strike'] = $this->strike;
  1328. $save['SUP'] = $this->SUP;
  1329. $save['SUB'] = $this->SUB;
  1330. $save['DOTTED'] = $this->dotted_on;
  1331. $save['DASHED'] = $this->dash_on;
  1332. $this->setDash(); //restore to no dash
  1333. $this->dash_on = false;
  1334. $this->dotted_on = false;
  1335. $bak_y = $this->y;
  1336. $bak_x = $this->x;
  1337. $align = $this->divalign;
  1338. $oldpage = $this->page;
  1339. $old_height = $this->divheight;
  1340. if ($is_table)
  1341. {
  1342. $this->divheight = 1.1*$this->lineheight;
  1343. $fill = 0;
  1344. }
  1345. else
  1346. {
  1347. $this->divheight = $this->lineheight;
  1348. if ($this->FillColor == '1.000 g') $fill = 0;
  1349. else $fill = 1;
  1350. }
  1351. $this->newFlowingBlock( $this->divSettings->getValue("divwidth"), $this->divheight,$this->divborder,$align,$fill,$is_table);
  1352. $array_size = count($arrayaux);
  1353. for($i=0;$i < $array_size; $i++)
  1354. {
  1355. $vetor = $arrayaux[$i];
  1356. if ($i == 0 and $vetor[0] != "\n") $vetor[0] = ltrim($vetor[0]);
  1357. if (empty($vetor[0]) and empty($vetor[7])) continue; //Ignore empty text and not carrying an internal link
  1358. //Activating buffer properties
  1359. if(isset($vetor[10]) and !empty($vetor[10])) //Background color
  1360. {
  1361. $cor = $vetor[10];
  1362. $this->setFillColor($cor['R'],$cor['G'],$cor['B']);
  1363. $this->divbgcolor = true;
  1364. }
  1365. if(isset($vetor[9]) and !empty($vetor[9])) // Outline parameters
  1366. {
  1367. $cor = $vetor[9]['COLOR'];
  1368. $outlinewidth = $vetor[9]['WIDTH'];
  1369. $this->setTextOutline($outlinewidth,$cor['R'],$cor['G'],$cor['B']);
  1370. $this->outline_on = true;
  1371. }
  1372. if(isset($vetor[8]) and $vetor[8] === true) // strike-through the text
  1373. {
  1374. $this->strike = true;
  1375. }
  1376. if(isset($vetor[6]) and $vetor[6] === true) // Subscript
  1377. {
  1378. $this->SUB = true;
  1379. $this->setFontSize(6);
  1380. }
  1381. if(isset($vetor[5]) and $vetor[5] === true) // Superscript
  1382. {
  1383. $this->SUP = true;
  1384. $this->setFontSize(6);
  1385. }
  1386. if(isset($vetor[4]) and $vetor[4] != '') $this->setFont($vetor[4]); // Font Family
  1387. if (!empty($vetor[3])) //Font Color
  1388. {
  1389. $cor = $vetor[3];
  1390. $this->setTextColor($cor['R'],$cor['G'],$cor['B']);
  1391. }
  1392. if(isset($vetor[2]) and $vetor[2] != '') //Bold,Italic,Underline styles
  1393. {
  1394. if (strpos($vetor[2],"B") !== false) $this->setStyle('B',true);
  1395. if (strpos($vetor[2],"I") !== false) $this->setStyle('I',true);
  1396. if (strpos($vetor[2],"U") !== false) $this->setStyle('U',true);
  1397. }
  1398. if (isset($vetor[0]) and $vetor[0]{0} == '»' and $vetor[0]{1} == '¤' and $vetor[0]{2} == '¬') //identifier has been identified!
  1399. {
  1400. $content = explode("»¤¬",$vetor[0]);
  1401. $texto = $content[2];
  1402. $content = explode(",",$content[1]);
  1403. foreach($content as $value)
  1404. {
  1405. $value = explode("=",$value);
  1406. $specialcontent[$value[0]] = $value[1];
  1407. }
  1408. if ($this->flowingBlockAttr[ 'contentWidth' ] > 0) // Print out previously accumulated content
  1409. {
  1410. $width_used = $this->flowingBlockAttr[ 'contentWidth' ] / $this->k;
  1411. //Restart Flowing Block
  1412. $this->finishFlowingBlock($outofblock);
  1413. $this->x = $bak_x + ($width_used % $this->divSettings->getValue("divwidth")) + 0.5;// 0.5 == margin
  1414. $this->y -= ($this->lineheight + 0.5);
  1415. $extrawidth = 0; //only to be used in case $specialcontent['width'] does not contain all used width (e.g. Select Box)
  1416. if ($specialcontent['type'] == 'select') $extrawidth = 7; //arrow box + margin
  1417. if(($this->x - $bak_x) + $specialcontent['width'] + $extrawidth > $this->divSettings->getValue("divwidth") )
  1418. {
  1419. $this->x = $bak_x;
  1420. $this->y += $this->lineheight - 1;
  1421. }
  1422. $this->newFlowingBlock( $this->divSettings->getValue("divwidth") ,$this->divheight,$this->divborder,$align,$fill,$is_table );
  1423. }
  1424. switch(strtoupper($specialcontent['type']))
  1425. {
  1426. case 'IMAGE':
  1427. //xpos and ypos used in order to support: <div align='center'><img ...></div>
  1428. $xpos = 0;
  1429. $ypos = 0;
  1430. if (isset($specialcontent['ypos']) and $specialcontent['ypos'] != '') $ypos = (float)$specialcontent['ypos'];
  1431. if (isset($specialcontent['xpos']) and $specialcontent['xpos'] != '') $xpos = (float)$specialcontent['xpos'];
  1432. $width_used = (($this->x - $bak_x) + $specialcontent['width'])*$this->k; //in order to adjust x coordinate later
  1433. //Is this the best way of fixing x,y coordinates?
  1434. $fix_x = ($this->x+2) * $this->k + ($xpos*$this->k); //+2 margin
  1435. $fix_y = ($this->h - (($this->y+2) + $specialcontent['height'])) * $this->k;//+2 margin
  1436. $imgtemp = explode(" ",$texto);
  1437. $imgtemp[5]=$fix_x; // x
  1438. $imgtemp[6]=$fix_y; // y
  1439. $texto = implode(" ",$imgtemp);
  1440. $this->_out($texto);
  1441. //Readjust x coordinate in order to allow text to be placed after this form element
  1442. $this->x = $bak_x;
  1443. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  1444. $spacenum = (integer)ceil(($width_used / $spacesize));
  1445. //Consider the space used so far in this line as a bunch of spaces
  1446. if ($ypos != 0) $this->Ln($ypos);
  1447. else $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
  1448. break;
  1449. case 'INPUT':
  1450. switch($specialcontent['subtype'])
  1451. {
  1452. case 'PASSWORD':
  1453. case 'TEXT': //Draw TextField
  1454. $width_used = (($this->x - $bak_x) + $specialcontent['width'])*$this->k; //in order to adjust x coordinate later
  1455. $this->setFillColor(235,235,235);
  1456. $this->x += 1;
  1457. $this->y += 1;
  1458. $this->Rect($this->x,$this->y,$specialcontent['width'],4.5,'DF');// 4.5 in order to avoid overlapping
  1459. if ($texto != '')
  1460. {
  1461. $this->x += 1;
  1462. $this->Write(5,$texto,$this->x);
  1463. $this->x -= $this->GetStringWidth($texto);
  1464. }
  1465. $this->setFillColor(255);
  1466. $this->y -= 1;
  1467. //Readjust x coordinate in order to allow text to be placed after this form element
  1468. $this->x = $bak_x;
  1469. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  1470. $spacenum = (integer)ceil(($width_used / $spacesize));
  1471. //Consider the space used so far in this line as a bunch of spaces
  1472. $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
  1473. break;
  1474. case 'CHECKBOX': //Draw Checkbox
  1475. $width_used = (($this->x - $bak_x) + $specialcontent['width'])*$this->k; //in order to adjust x coordinate later
  1476. $checked = $texto;
  1477. $this->setFillColor(235,235,235);
  1478. $this->y += 1;
  1479. $this->x += 1;
  1480. $this->Rect($this->x,$this->y,3,3,'DF');
  1481. if ($checked)
  1482. {
  1483. $this->Line($this->x,$this->y,$this->x+3,$this->y+3);
  1484. $this->Line($this->x,$this->y+3,$this->x+3,$this->y);
  1485. }
  1486. $this->setFillColor(255);
  1487. $this->y -= 1;
  1488. //Readjust x coordinate in order to allow text to be placed after this form element
  1489. $this->x = $bak_x;
  1490. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  1491. $spacenum = (integer)ceil(($width_used / $spacesize));
  1492. //Consider the space used so far in this line as a bunch of spaces
  1493. $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
  1494. break;
  1495. case 'RADIO': //Draw Radio button
  1496. $width_used = (($this->x - $bak_x) + $specialcontent['width']+0.5)*$this->k; //in order to adjust x coordinate later
  1497. $checked = $texto;
  1498. $this->x += 2;
  1499. $this->y += 1.5;
  1500. $this->Circle($this->x,$this->y+1.2,1,'D');
  1501. $this->_out('0.000 g');
  1502. if ($checked) $this->Circle($this->x,$this->y+1.2,0.4,'DF');
  1503. $this->y -= 1.5;
  1504. //Readjust x coordinate in order to allow text to be placed after this form element
  1505. $this->x = $bak_x;
  1506. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  1507. $spacenum = (integer)ceil(($width_used / $spacesize));
  1508. //Consider the space used so far in this line as a bunch of spaces
  1509. $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
  1510. break;
  1511. case 'BUTTON': // Draw a button
  1512. case 'SUBMIT':
  1513. case 'RESET':
  1514. $nihil = ($specialcontent['width']-$this->GetStringWidth($texto))/2;
  1515. $this->x += 1.5;
  1516. $this->y += 1;
  1517. $this->setFillColor(190,190,190);
  1518. $this->Rect($this->x,$this->y,$specialcontent['width'],4.5,'DF'); // 4.5 in order to avoid overlapping
  1519. $this->x += $nihil;
  1520. $this->Write(5,$texto,$this->x);
  1521. $this->x += $nihil;
  1522. $this->setFillColor(255);
  1523. $this->y -= 1;
  1524. break;
  1525. default: break;
  1526. }
  1527. break;
  1528. case 'SELECT':
  1529. $width_used = (($this->x - $bak_x) + $specialcontent['width'] + 8)*$this->k; //in order to adjust x coordinate later
  1530. $this->setFillColor(235,235,235); //light gray
  1531. $this->x += 1.5;
  1532. $this->y += 1;
  1533. $this->Rect($this->x,$this->y,$specialcontent['width']+2,$this->lineheight,'DF'); // +2 == margin
  1534. $this->x += 1;
  1535. if ($texto != '') $this->Write($this->lineheight,$texto,$this->x); //the combobox content
  1536. $this->x += $specialcontent['width'] - $this->GetStringWidth($texto) + 2;
  1537. $this->setFillColor(190,190,190); //dark gray
  1538. $this->Rect($this->x-1,$this->y,5,5,'DF'); //Arrow Box
  1539. $this->setFont('zapfdingbats');
  1540. $this->Write($this->lineheight,chr(116),$this->x); //Down arrow
  1541. $this->setFont('arial');
  1542. $this->setFillColor(255);
  1543. //Readjust x coordinate in order to allow text to be placed after this form element
  1544. $this->x = $bak_x;
  1545. $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
  1546. $spacenum = (integer)ceil(($width_used / $spacesize));
  1547. //Consider the space used so far in this line as a bunch of spaces
  1548. $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
  1549. break;
  1550. case 'TEXTAREA':
  1551. //Setup TextArea properties
  1552. $this->setFillColor(235,235,235);
  1553. $this->setFont('courier');
  1554. $this->currentfont='courier';
  1555. $ta_lines = $specialcontent['lines'];
  1556. $ta_height = 1.1*$this->lineheight*$ta_lines;
  1557. $ta_width = $specialcontent['width'];
  1558. //Adjust x,y coordinates
  1559. $this->x += 1.5;
  1560. $this->y += 1.5;
  1561. $linesneeded = $this->WordWrap($texto,$ta_width);
  1562. if ( $linesneeded > $ta_lines ) //Too many words inside textarea
  1563. {
  1564. $textoaux = explode("\n",$texto);
  1565. $texto = '';
  1566. for($i=0;$i<$ta_lines;$i++)
  1567. {
  1568. if ($i == $ta_lines-1) $texto .= $textoaux[$i];
  1569. else $texto .= $textoaux[$i] . "\n";
  1570. }
  1571. //Inform the user that some text has been truncated
  1572. $texto{strlen($texto)-1} = ".";
  1573. $texto{strlen($texto)-2} = ".";
  1574. $texto{strlen($texto)-3} = ".";
  1575. }
  1576. $backup_y = $this->y;
  1577. $backup_x = $this->x;
  1578. $this->Rect($this->x,$this->y,$ta_width+3,$ta_height,'DF');
  1579. if ($texto != '') $this->MultiCell($ta_width+3,$this->lineheight,$texto);
  1580. $this->y = $backup_y - 1.5;
  1581. $this->x = $backup_x + $ta_width + 2.5;
  1582. $this->setFillColor(255);
  1583. $this->setFont('arial');
  1584. $this->currentfont='';
  1585. break;
  1586. default: break;
  1587. }
  1588. }
  1589. else //THE text
  1590. {
  1591. if ($vetor[0] == "\n") //We are reading a <BR> now turned into newline ("\n")
  1592. {
  1593. //Restart Flowing Block
  1594. $this->finishFlowingBlock($outofblock);
  1595. if($outofblock) $this->Ln($this->lineheight);
  1596. $this->x = $bak_x;
  1597. $this->newFlowingBlock( $this->divSettings->getValue("divwidth"), $this->divheight,$this->divborder,$align,$fill,$is_table );
  1598. }
  1599. else $this->WriteFlowingBlock( $vetor[0] , $outofblock );
  1600. }
  1601. //Check if it is the last element. If so then finish printing the block
  1602. if ($i == ($array_size-1)) $this->finishFlowingBlock($outofblock);
  1603. if(isset($vetor[1]) and $vetor[1] != '')
  1604. {
  1605. $this->setTextColor(0);
  1606. $this->setStyle('U',false);
  1607. }
  1608. if(isset($vetor[2]) and $vetor[2] != '')
  1609. {
  1610. $this->setStyle('B',false);
  1611. $this->setStyle('I',false);
  1612. $this->setStyle('U',false);
  1613. }
  1614. if(isset($vetor[3]) and $vetor[3] != '')
  1615. {
  1616. unset($cor);
  1617. $this->setTextColor(0);
  1618. }
  1619. if(isset($vetor[4]) and $vetor[4] != '') $this->setFont('arial');
  1620. if(isset($vetor[5]) and $vetor[5] === true)
  1621. {
  1622. $this->SUP = false;
  1623. $this->setFontSize(11);
  1624. }
  1625. if(isset($vetor[6]) and $vetor[6] === true)
  1626. {
  1627. $this->SUB = false;
  1628. $this->setFontSize(11);
  1629. }
  1630. if(isset($vetor[8]) and $vetor[8] === true) // strike-through the text
  1631. {
  1632. $this->strike = false;
  1633. }
  1634. if(isset($vetor[9]) and !empty($vetor[9])) // Outline parameters
  1635. {
  1636. $this->setTextOutline(false);
  1637. $this->outline_on = false;
  1638. }
  1639. if(isset($vetor[10]) and !empty($vetor[10])) //Background color
  1640. {
  1641. $this->setFillColor(255);
  1642. $this->divbgcolor = false;
  1643. }
  1644. }//end of for(i=0;i<arraysize;i++)
  1645. //Restore some previously set parameters
  1646. $this->strike = $save['strike'];
  1647. $this->SUP = $save['SUP'];
  1648. $this->SUB = $save['SUB'];
  1649. $this->dotted_on = $save['DOTTED'];
  1650. $this->dash_on = $save['DASHED'];
  1651. if ($this->dash_on) $this->setDash(2,2);
  1652. //Check whether we have borders to paint or not
  1653. //(only works 100% if whole content spans only 1 page)
  1654. if ($this->cssbegin and ($this->divborder or $this->dash_on or $this->dotted_on or $this->divbgcolor))
  1655. {
  1656. if ($oldpage != $this->page)
  1657. {
  1658. //Only border on last page is painted (known bug)
  1659. $x = $this->lMargin;
  1660. $y = $this->tMargin;
  1661. $old_height = $this->y - $y;
  1662. }
  1663. else
  1664. {
  1665. if ($this->oldx < 0) $x = $this->x;
  1666. else $x = $this->oldx;
  1667. if ($this->oldy < 0) $y = $this->y - $old_height;
  1668. else $y = $this->oldy;
  1669. }
  1670. if ($this->divborder) $this->Rect($x,$y, $this->divSettings->getValue("divwidth"), $old_height);
  1671. if ($this->dash_on) $this->Rect($x,$y, $this->divSettings->getValue("divwidth"), $old_height);
  1672. if ($this->dotted_on) $this->DottedRect($x,$y, $this->divSettings->getValue("divwidth"), $old_height);
  1673. $this->x = $bak_x;
  1674. }
  1675. }
  1676. private function Reset()
  1677. {
  1678. $this->setTextColor(0);
  1679. $this->setDrawColor(0);
  1680. $this->setFillColor(255);
  1681. $this->colorarray = array();
  1682. $this->bgcolorarray = array();
  1683. $this->issetcolor = false;
  1684. $this->setTextOutline(false);
  1685. $this->setFontSize(11);
  1686. $this->setStyle('B',false);
  1687. $this->setStyle('I',false);
  1688. $this->setStyle('U',false);
  1689. $this->setFont('arial');
  1690. $val = 0;
  1691. $this->divSettings->setValue("divwidth", $val);
  1692. $this->divheight = 0;
  1693. $this->divalign = "L";
  1694. $this->divborder = 0;
  1695. $this->divbgcolor = false;
  1696. $this->toupper = false;
  1697. $this->tolower = false;
  1698. $this->setDash(); //restore to no dash
  1699. $this->dash_on = false;
  1700. $this->dotted_on = false;
  1701. $this->oldx = -1;
  1702. $this->oldy = -1;
  1703. }
  1704. private function readCss($html)
  1705. {
  1706. $match = 0; // no match for instance
  1707. $match = preg_match_all('/<link rel="stylesheet".*?href="(.+?)"\\s*?\/?>/si', $html, $CSSext);
  1708. $ind = 0;
  1709. while($match){
  1710. //Fix path value
  1711. $path = $CSSext[1][$ind];
  1712. $path = str_replace("\\","/",$path); //If on Windows
  1713. $path = preg_replace('|^./|', '', $path);
  1714. if (strpos($path,"../") !== false ) //It is a Relative Link
  1715. {
  1716. $backtrackamount = substr_count($path,"../");
  1717. $maxbacktrack = substr_count($this->basepath,"/") - 1;
  1718. $filepath = str_replace("../",'',$path);
  1719. $path = $this->basepath;
  1720. //If it is an invalid relative link, then make it go to directory root
  1721. if ($backtrackamount > $maxbacktrack) $backtrackamount = $maxbacktrack;
  1722. //Backtrack some directories
  1723. for( $i = 0 ; $i < $backtrackamount + 1 ; $i++ ) $path = substr( $path, 0 , strrpos($path,"/") );
  1724. $path = $path . "/" . $filepath; //Make it an absolute path
  1725. }
  1726. elseif( strpos($path,":/") === false) //It is a Local Link
  1727. {
  1728. $path = $this->basepath . $path;
  1729. }
  1730. $CSSextblock = file_get_contents($path);
  1731. preg_match_all('/[.# ]([^.]+?)\\s*?\{(.+?)\}/s', $CSSextblock, $extstyle);
  1732. for($i=0; $i < count($extstyle[1]) ; $i++)
  1733. {
  1734. preg_match_all('/\\s*?(\\S+?):(.+?);/si', $extstyle[2][$i], $extstyleinfo);
  1735. $extproperties = $extstyleinfo[1];
  1736. $extvalues = $extstyleinfo[2];
  1737. for($j = 0; $j < count($extproperties) ; $j++)
  1738. {
  1739. //Array-properties and Array-values must have the SAME SIZE!
  1740. $extclassproperties[strtoupper($extproperties[$j])] = trim($extvalues[$j]);
  1741. }
  1742. $this->CSS[$extstyle[1][$i]] = $extclassproperties;
  1743. $extproperties = array();
  1744. $extvalues = array();
  1745. $extclassproperties = array();
  1746. }
  1747. $match--;
  1748. $ind++;
  1749. } //end of match
  1750. $match = 0;
  1751. $match = preg_match('/<style.*?>(.*?)<\/style>/si', $html, $CSSblock);
  1752. if ($match) {
  1753. //Get class/id name and its characteristics from $CSSblock[1]
  1754. $regexp = '/[.#]([^.]+?)\\s*?\{(.+?)\}/s'; // '/s' PCRE_DOTALL including \n
  1755. preg_match_all( $regexp, $CSSblock[1], $style);
  1756. //Make CSS[Name-of-the-class] = array(key => value)
  1757. $regexp = '/\\s*?(\\S+?):(.+?);/si';
  1758. for($i=0; $i < count($style[1]) ; $i++)
  1759. {
  1760. preg_match_all( $regexp, $style[2][$i], $styleinfo);
  1761. $properties = $styleinfo[1];
  1762. $values = $styleinfo[2];
  1763. for($j = 0; $j < count($properties) ; $j++)
  1764. {
  1765. //Array-properties and Array-values must have the SAME SIZE!
  1766. $classproperties[strtoupper($properties[$j])] = trim($values[$j]);
  1767. }
  1768. $this->CSS[$style[1][$i]] = $classproperties;
  1769. $properties = array();
  1770. $values = array();
  1771. $classproperties = array();
  1772. }
  1773. }
  1774. $html = preg_replace('/<style.*?>(.*?)<\/style>/si', '', $html);
  1775. return $html;
  1776. }
  1777. private function readInlineCSS($html)
  1778. {
  1779. $size = strlen($html)-1;
  1780. if ($html{$size} != ';') $html .= ';';
  1781. //Make CSS[Name-of-the-class] = array(key => value)
  1782. $regexp = '|\\s*?(\\S+?):(.+?);|i';
  1783. preg_match_all($regexp, $html, $styleinfo);
  1784. $properties = $styleinfo[1];
  1785. $values = $styleinfo[2];
  1786. //Array-properties and Array-values must have the SAME SIZE!
  1787. $classproperties = array();
  1788. for($i = 0; $i < count($properties) ; $i++) $classproperties[strtoupper($properties[$i])] = trim($values[$i]);
  1789. return $classproperties;
  1790. }
  1791. public function setCSS($arrayaux)
  1792. {
  1793. if (!is_array($arrayaux)) return;
  1794. foreach($arrayaux as $k => $v)
  1795. {
  1796. switch($k)
  1797. {
  1798. case 'WIDTH':
  1799. $this->divSettings->setValue("divwidth", $this->convertSize($v,$this->pgwidth));
  1800. break;
  1801. case 'HEIGHT':
  1802. $this->divheight = $this->convertSize($v,$this->pgwidth);
  1803. break;
  1804. case 'BORDER': // width style color (width not supported correctly - it is always considered as normal)
  1805. $prop = explode(' ',$v);
  1806. if (count($prop) != 3) break; // Not supported: borders not fully declared
  1807. if (strnatcasecmp($prop[1],"dashed") == 0) //found "dashed"! (ignores case)
  1808. {
  1809. $this->dash_on = true;
  1810. $this->setDash(2,2); //2mm on, 2mm off
  1811. }
  1812. elseif (strnatcasecmp($prop[1],"dotted") == 0) //found "dotted"! (ignores case)
  1813. {
  1814. $this->dotted_on = true;
  1815. }
  1816. elseif (strnatcasecmp($prop[1],"none") == 0) $this->divborder = 0;
  1817. else $this->divborder = 1;
  1818. //color
  1819. $coul = $this->convertColor($prop[2]);
  1820. $this->setDrawColor($coul['R'],$coul['G'],$coul['B']);
  1821. $this->issetcolor=true;
  1822. break;
  1823. case 'FONT-FAMILY': // one of the $this->fontlist fonts
  1824. //If it is a font list, get all font types
  1825. $aux_fontlist = explode(",",$v);
  1826. $fontarraysize = count($aux_fontlist);
  1827. for($i=0;$i<$fontarraysize;$i++)
  1828. {
  1829. $fonttype = $aux_fontlist[$i];
  1830. $fonttype = trim($fonttype);
  1831. //If font is found, set it, and exit loop
  1832. if ( in_array(strtolower($fonttype), $this->fontlist) ) {$this->setFont(strtolower($fonttype));break;}
  1833. //If font = "courier new" for example, try simply looking for "courier"
  1834. $fonttype = explode(" ",$fonttype);
  1835. $fonttype = $fonttype[0];
  1836. if ( in_array(strtolower($fonttype), $this->fontlist) ) {$this->setFont(strtolower($fonttype));break;}
  1837. }
  1838. break;
  1839. case 'FONT-SIZE': //Does not support: smaller, larger
  1840. $mmsize = $this->convertSize($v,$this->pgwidth);
  1841. $this->setFontSize( $mmsize*(72/25.4) ); //Get size in points (pt)
  1842. break;
  1843. case 'FONT-STYLE': // italic normal oblique
  1844. switch (strtoupper($v))
  1845. {
  1846. case 'ITALIC':
  1847. case 'OBLIQUE':
  1848. $this->setStyle('I',true);
  1849. break;
  1850. case 'NORMAL': break;
  1851. }
  1852. break;
  1853. case 'FONT-WEIGHT': // normal bold //Does not support: bolder, lighter, 100..900(step value=100)
  1854. if (strtoupper($v) == 'BOLD') $this->setStyle('B',true);
  1855. break;
  1856. case 'TEXT-DECORATION': // none underline //Does not support: overline, blink
  1857. switch (strtoupper($v))
  1858. {
  1859. case 'LINE-THROUGH':
  1860. $this->strike = true;
  1861. break;
  1862. case 'UNDERLINE':
  1863. $this->setStyle('U',true);
  1864. break;
  1865. case 'NONE': break;
  1866. }
  1867. case 'TEXT-TRANSFORM': // none uppercase lowercase //Does not support: capitalize
  1868. switch (strtoupper($v)) //Not working 100%
  1869. {
  1870. case 'UPPERCASE':
  1871. $this->toupper=true;
  1872. break;
  1873. case 'LOWERCASE':
  1874. $this->tolower=true;
  1875. break;
  1876. case 'NONE': break;
  1877. }
  1878. case 'TEXT-ALIGN': //left right center justify
  1879. switch (strtoupper($v))
  1880. {
  1881. case 'LEFT':
  1882. $this->divalign="L";
  1883. break;
  1884. case 'CENTER':
  1885. $this->divalign="C";
  1886. break;
  1887. case 'RIGHT':
  1888. $this->divalign="R";
  1889. break;
  1890. case 'JUSTIFY':
  1891. $this->divalign="J";
  1892. break;
  1893. }
  1894. break;
  1895. case 'BACKGROUND': // bgcolor only
  1896. $cor = $this->convertColor($v);
  1897. $this->bgcolorarray = $cor;
  1898. $this->setFillColor($cor['R'],$cor['G'],$cor['B']);
  1899. $this->divbgcolor = true;
  1900. break;
  1901. case 'COLOR': // font color
  1902. $cor = $this->convertColor($v);
  1903. $this->colorarray = $cor;
  1904. $this->setTextColor($cor['R'],$cor['G'],$cor['B']);
  1905. $this->issetcolor=true;
  1906. break;
  1907. }
  1908. }
  1909. }
  1910. public function SetStyle($tag,$enable)
  1911. {
  1912. $this->$tag+=($enable ? 1 : -1);
  1913. $style='';
  1914. //Fix some SetStyle misuse
  1915. if ($this->$tag < 0) $this->$tag = 0;
  1916. if ($this->$tag > 1) $this->$tag = 1;
  1917. foreach(array('B','I','U') as $s)
  1918. if($this->$s>0) $style.=$s;
  1919. $this->currentstyle=$style;
  1920. $this->setFont('',$style);
  1921. }
  1922. function _tableColumnWidth(&$table)
  1923. {
  1924. $cs = &$table['cells'];
  1925. $mw = $this->getStringWidth('W');
  1926. $nc = $table['nc'];
  1927. $nr = $table['nr'];
  1928. $listspan = array();
  1929. //Xac dinh do rong cua cac cell va cac cot tuong ung
  1930. for($j = 0 ; $j < $nc ; $j++ ) //columns
  1931. {
  1932. $wc = &$table['wc'][$j];
  1933. for($i = 0 ; $i < $nr ; $i++ ) //rows
  1934. {
  1935. if (isset($cs[$i][$j]) && $cs[$i][$j])
  1936. {
  1937. $c = &$cs[$i][$j];
  1938. $miw = $mw;
  1939. if (isset($c['maxs']) and $c['maxs'] != '') $c['s'] = $c['maxs'];
  1940. $c['maw'] = $c['s'];
  1941. if (isset($c['nowrap'])) $miw = $c['maw'];
  1942. if (isset($c['w']))
  1943. {
  1944. if ($miw<$c['w']) $c['miw'] = $c['w'];
  1945. if ($miw>$c['w']) $c['miw'] = $c['w'] = $miw;
  1946. if (!isset($wc['w'])) $wc['w'] = 1;
  1947. }
  1948. else $c['miw'] = $miw;
  1949. if ($c['maw'] < $c['miw']) $c['maw'] = $c['miw'];
  1950. if (!isset($c['colspan']))
  1951. {
  1952. if ($wc['miw'] < $c['miw']) $wc['miw'] = $c['miw'];
  1953. if ($wc['maw'] < $c['maw']) $wc['maw'] = $c['maw'];
  1954. }
  1955. else $listspan[] = array($i,$j);
  1956. //Check if minimum width of the whole column is big enough for a huge word to fit
  1957. $auxtext = implode("",$c['text']);
  1958. $minwidth = $this->WordWrap($auxtext,$wc['miw']-2);// -2 == margin
  1959. if ($minwidth < 0 and (-$minwidth) > $wc['miw']) $wc['miw'] = (-$minwidth) +2; //increase minimum width
  1960. if ($wc['miw'] > $wc['maw']) $wc['maw'] = $wc['miw']; //update maximum width, if needed
  1961. }
  1962. }//rows
  1963. }//columns
  1964. //Xac dinh su anh huong cua cac cell colspan len cac cot va nguoc lai
  1965. $wc = &$table['wc'];
  1966. foreach ($listspan as $span)
  1967. {
  1968. list($i,$j) = $span;
  1969. $c = &$cs[$i][$j];
  1970. $lc = $j + $c['colspan'];
  1971. if ($lc > $nc) $lc = $nc;
  1972. $wis = $wisa = 0;
  1973. $was = $wasa = 0;
  1974. $list = array();
  1975. for($k=$j;$k<$lc;$k++)
  1976. {
  1977. $wis += $wc[$k]['miw'];
  1978. $was += $wc[$k]['maw'];
  1979. if (!isset($c['w']))
  1980. {
  1981. $list[] = $k;
  1982. $wisa += $wc[$k]['miw'];
  1983. $wasa += $wc[$k]['maw'];
  1984. }
  1985. }
  1986. if ($c['miw'] > $wis)
  1987. {
  1988. if (!$wis)
  1989. {
  1990. for($k=$j;$k<$lc;$k++) $wc[$k]['miw'] = $c['miw']/$c['colspan'];
  1991. }
  1992. elseif(!count($list))
  1993. {
  1994. $wi = $c['miw'] - $wis;
  1995. for($k=$j;$k<$lc;$k++) $wc[$k]['miw'] += ($wc[$k]['miw']/$wis)*$wi;
  1996. }
  1997. else
  1998. {
  1999. $wi = $c['miw'] - $wis;
  2000. foreach ($list as $k) $wc[$k]['miw'] += ($wc[$k]['miw']/$wisa)*$wi;
  2001. }
  2002. }
  2003. if ($c['maw'] > $was)
  2004. {
  2005. if (!$wis)
  2006. {
  2007. for($k=$j;$k<$lc;$k++) $wc[$k]['maw'] = $c['maw']/$c['colspan'];
  2008. }
  2009. elseif (!count($list))
  2010. {
  2011. $wi = $c['maw'] - $was;
  2012. for($k=$j;$k<$lc;$k++) $wc[$k]['maw'] += ($wc[$k]['maw']/$was)*$wi;
  2013. }
  2014. else
  2015. {
  2016. $wi = $c['maw'] - $was;
  2017. foreach ($list as $k) $wc[$k]['maw'] += ($wc[$k]['maw']/$wasa)*$wi;
  2018. }
  2019. }
  2020. }
  2021. }
  2022. function _tableWidth(&$table)
  2023. {
  2024. $widthcols = &$table['wc'];
  2025. $numcols = $table['nc'];
  2026. $tablewidth = 0;
  2027. for ( $i = 0 ; $i < $numcols ; $i++ )
  2028. {
  2029. $tablewidth += isset($widthcols[$i]['w']) ? $widthcols[$i]['miw'] : $widthcols[$i]['maw'];
  2030. }
  2031. if ($tablewidth > $this->pgwidth) $table['w'] = $this->pgwidth;
  2032. if (isset($table['w']))
  2033. {
  2034. $wis = $wisa = 0;
  2035. $list = array();
  2036. for( $i = 0 ; $i < $numcols ; $i++ )
  2037. {
  2038. $wis += $widthcols[$i]['miw'];
  2039. if (!isset($widthcols[$i]['w'])){ $list[] = $i;$wisa += $widthcols[$i]['miw'];}
  2040. }
  2041. if ($table['w'] > $wis)
  2042. {
  2043. if (!count($list))
  2044. {
  2045. $wi = ($table['w'] - $wis)/$numcols;
  2046. for($k=0;$k<$numcols;$k++)
  2047. $widthcols[$k]['miw'] += $wi;
  2048. }
  2049. else
  2050. {
  2051. $wi = ($table['w'] - $wis)/count($list);
  2052. foreach ($list as $k)
  2053. $widthcols[$k]['miw'] += $wi;
  2054. }
  2055. }
  2056. for ($i=0;$i<$numcols;$i++)
  2057. {
  2058. $tablewidth = $widthcols[$i]['miw'];
  2059. unset($widthcols[$i]);
  2060. $widthcols[$i] = $tablewidth;
  2061. }
  2062. }
  2063. else //table has no width defined
  2064. {
  2065. $table['w'] = $tablewidth;
  2066. for ( $i = 0 ; $i < $numcols ; $i++)
  2067. {
  2068. $tablewidth = isset($widthcols[$i]['w']) ? $widthcols[$i]['miw'] : $widthcols[$i]['maw'];
  2069. unset($widthcols[$i]);
  2070. $widthcols[$i] = $tablewidth;
  2071. }
  2072. }
  2073. }
  2074. private function _tableHeight(&$table)
  2075. {
  2076. $cells = &$table['cells'];
  2077. $numcols = $table['nc'];
  2078. $numrows = $table['nr'];
  2079. $listspan = array();
  2080. for( $i = 0 ; $i < $numrows ; $i++ )//rows
  2081. {
  2082. $heightrow = &$table['hr'][$i];
  2083. for( $j = 0 ; $j < $numcols ; $j++ ) //columns
  2084. {
  2085. if (isset($cells[$i][$j]) && $cells[$i][$j])
  2086. {
  2087. $c = &$cells[$i][$j];
  2088. list($x,$cw) = $this->_tableGetWidth($table, $i,$j);
  2089. $auxtext = implode("",$c['text']);
  2090. $auxtext2 = $auxtext; //in case we have text with styles
  2091. $nostyles_size = $this->GetStringWidth($auxtext) + 3; // +3 == margin
  2092. $linesneeded = $this->WordWrap($auxtext,$cw-2);// -2 == margin
  2093. if ($c['s'] > $nostyles_size and !isset($c['form'])) //Text with styles
  2094. {
  2095. $auxtext = $auxtext2; //recover original characteristics (original /n placements)
  2096. $diffsize = $c['s'] - $nostyles_size; //with bold et al. char width gets a bit bigger than plain char
  2097. if ($linesneeded == 0) $linesneeded = 1; //to avoid division by zero
  2098. $diffsize /= $linesneeded;
  2099. $linesneeded = $this->WordWrap($auxtext,$cw-2-$diffsize);//diffsize used to wrap text correctly
  2100. }
  2101. if (isset($c['form']))
  2102. {
  2103. $linesneeded = ceil(($c['s']-3)/($cw-2)); //Text + form in a cell
  2104. //Presuming the use of styles
  2105. if ( ($this->GetStringWidth($auxtext) + 3) > ($cw-2) ) $linesneeded++;
  2106. }
  2107. $ch = $linesneeded * 1.1 * $this->lineheight;
  2108. if ($ch > ($this->fh - $this->bMargin - $this->tMargin)) $ch = ($this->fh - $this->bMargin - $this->tMargin);
  2109. //If height is defined and it is bigger than calculated $ch then update values
  2110. if (isset($c['h']) && $c['h'] > $ch)
  2111. {
  2112. $c['mih'] = $ch; //in order to keep valign working
  2113. $ch = $c['h'];
  2114. }
  2115. else $c['mih'] = $ch;
  2116. if (isset($c['rowspan'])) $listspan[] = array($i,$j);
  2117. elseif ($heightrow < $ch) $heightrow = $ch;
  2118. if (isset($c['form'])) $c['mih'] = $ch;
  2119. }
  2120. }//end of columns
  2121. }//end of rows
  2122. $heightrow = &$table['hr'];
  2123. foreach ($listspan as $span)
  2124. {
  2125. list($i,$j) = $span;
  2126. $c = &$cells[$i][$j];
  2127. $lr = $i + $c['rowspan'];
  2128. if ($lr > $numrows) $lr = $numrows;
  2129. $hs = $hsa = 0;
  2130. $list = array();
  2131. for($k=$i;$k<$lr;$k++)
  2132. {
  2133. $hs += $heightrow[$k];
  2134. if (!isset($c['h']))
  2135. {
  2136. $list[] = $k;
  2137. $hsa += $heightrow[$k];
  2138. }
  2139. }
  2140. if ($c['mih'] > $hs)
  2141. {
  2142. if (!$hs)
  2143. {
  2144. for($k=$i;$k<$lr;$k++) $heightrow[$k] = $c['mih']/$c['rowspan'];
  2145. }
  2146. elseif (!count($list))
  2147. {
  2148. $hi = $c['mih'] - $hs;
  2149. for($k=$i;$k<$lr;$k++) $heightrow[$k] += ($heightrow[$k]/$hs)*$hi;
  2150. }
  2151. else
  2152. {
  2153. $hi = $c['mih'] - $hsa;
  2154. foreach ($list as $k) $heightrow[$k] += ($heightrow[$k]/$hsa)*$hi;
  2155. }
  2156. }
  2157. }
  2158. }
  2159. private function _tableGetWidth(&$table, $i,$j)
  2160. {
  2161. $cell = &$table['cells'][$i][$j];
  2162. if ($cell)
  2163. {
  2164. if (isset($cell['x0'])) return array($cell['x0'], $cell['w0']);
  2165. $x = 0;
  2166. $widthcols = &$table['wc'];
  2167. for( $k = 0 ; $k < $j ; $k++ ) $x += $widthcols[$k];
  2168. $w = $widthcols[$j];
  2169. if (isset($cell['colspan']))
  2170. {
  2171. for ( $k = $j+$cell['colspan']-1 ; $k > $j ; $k-- ) $w += $widthcols[$k];
  2172. }
  2173. $cell['x0'] = $x;
  2174. $cell['w0'] = $w;
  2175. return array($x, $w);
  2176. }
  2177. return array(0,0);
  2178. }
  2179. private function _tableGetHeight(&$table, $i,$j)
  2180. {
  2181. $cell = &$table['cells'][$i][$j];
  2182. if ($cell){
  2183. if (isset($cell['y0'])) return array($cell['y0'], $cell['h0']);
  2184. $y = 0;
  2185. $heightrow = &$table['hr'];
  2186. for ($k=0;$k<$i;$k++) $y += $heightrow[$k];
  2187. $h = $heightrow[$i];
  2188. if (isset($cell['rowspan'])){
  2189. for ($k=$i+$cell['rowspan']-1;$k>$i;$k--)
  2190. $h += $heightrow[$k];
  2191. }
  2192. $cell['y0'] = $y;
  2193. $cell['h0'] = $h;
  2194. return array($y, $h);
  2195. }
  2196. return array(0,0);
  2197. }
  2198. private function _tableRect($x, $y, $w, $h, $type=1)
  2199. {
  2200. if ($type==1) $this->Rect($x, $y, $w, $h);
  2201. elseif (strlen($type)==4){
  2202. $x2 = $x + $w; $y2 = $y + $h;
  2203. if (intval($type{0})) $this->Line($x , $y , $x2, $y );
  2204. if (intval($type{1})) $this->Line($x2, $y , $x2, $y2);
  2205. if (intval($type{2})) $this->Line($x , $y2, $x2, $y2);
  2206. if (intval($type{3})) $this->Line($x , $y , $x , $y2);
  2207. }
  2208. }
  2209. private function _tableWrite(&$table)
  2210. {
  2211. $cells = &$table['cells'];
  2212. $numcols = $table['nc'];
  2213. $numrows = $table['nr'];
  2214. $x0 = $this->x;
  2215. $y0 = $this->y;
  2216. $right = $this->pgwidth - $this->rMargin;
  2217. if (isset($table['a']) and ($table['w'] != $this->pgwidth))
  2218. {
  2219. if ($table['a']=='C') $x0 += (($right-$x0) - $table['w'])/2;
  2220. elseif ($table['a']=='R') $x0 = $right - $table['w'];
  2221. }
  2222. $returny = 0;
  2223. $tableheader = array();
  2224. //Draw Table Contents and Borders
  2225. for( $i = 0 ; $i < $numrows ; $i++ ) //Rows
  2226. {
  2227. $skippage = false;
  2228. for( $j = 0 ; $j < $numcols ; $j++ ) //Columns
  2229. {
  2230. if (isset($cells[$i][$j]) && $cells[$i][$j])
  2231. {
  2232. $cell = &$cells[$i][$j];
  2233. list($x,$w) = $this->_tableGetWidth($table, $i, $j);
  2234. list($y,$h) = $this->_tableGetHeight($table, $i, $j);
  2235. $x += $x0;
  2236. $y += $y0;
  2237. $y -= $returny;
  2238. if ((($y + $h) > ($this->fh - $this->bMargin)) && ($y0 >0 || $x0 > 0))
  2239. {
  2240. if (!$skippage)
  2241. {
  2242. $y -= $y0;
  2243. $returny += $y;
  2244. $this->addPage();
  2245. $this->header($tableheader);
  2246. $y0 = $this->y;
  2247. $y = $y0;
  2248. }
  2249. $skippage = true;
  2250. }
  2251. //Align
  2252. $this->x = $x; $this->y = $y;
  2253. $align = isset($cell['a'])? $cell['a'] : 'L';
  2254. //Vertical align
  2255. if (!isset($cell['va']) || $cell['va']=='M') $this->y += ($h-$cell['mih'])/2;
  2256. elseif (isset($cell['va']) && $cell['va']=='B') $this->y += $h-$cell['mih'];
  2257. //Fill
  2258. $fill = isset($cell['bgcolor']) ? $cell['bgcolor']
  2259. : (isset($table['bgcolor'][$i]) ? $table['bgcolor'][$i]
  2260. : (isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0));
  2261. if ($fill)
  2262. {
  2263. $color = $this->convertColor($fill);
  2264. $this->setFillColor($color['R'],$color['G'],$color['B']);
  2265. $this->Rect($x, $y, $w, $h, 'F');
  2266. }
  2267. //Border
  2268. if (isset($cell['border'])) $this->_tableRect($x, $y, $w, $h, $cell['border']);
  2269. elseif (isset($table['border']) && $table['border']) $this->Rect($x, $y, $w, $h);
  2270. $this->divalign=$align;
  2271. $wHalf = $w-2;
  2272. $this->divSettings->setValue("divwidth", $wHalf);
  2273. //Get info of first row == table header
  2274. if ($i == 0 )
  2275. {
  2276. $tableheader[$j]['x'] = $x;
  2277. $tableheader[$j]['y'] = $y;
  2278. $tableheader[$j]['h'] = $h;
  2279. $tableheader[$j]['w'] = $w;
  2280. $tableheader[$j]['text'] = $cell['text'];
  2281. $tableheader[$j]['textbuffer'] = $cell['textbuffer'];
  2282. $tableheader[$j]['a'] = isset($cell['a'])? $cell['a'] : 'L';
  2283. if (isset($cell['va'])) $tableheader[$j]['va'] = $cell['va'];
  2284. $tableheader[$j]['mih'] = $cell['mih'];
  2285. $tableheader[$j]['bgcolor'] = $fill;
  2286. if (isset($cell['border'])) $tableheader[$j]['border'] = $cell['border'];
  2287. }
  2288. if (!empty($cell['textbuffer'])) $this->printbuffer($cell['textbuffer'],false,true/*inside a table*/);
  2289. //Reset values
  2290. $this->Reset();
  2291. }//end of (if isset(cells)...)
  2292. }// end of columns
  2293. if ($i == $numrows-1)
  2294. $this->y = $y + $h;
  2295. }
  2296. }
  2297. private function convertColor($color="#000000")
  2298. {
  2299. $common_colors = array('antiquewhite'=>'#FAEBD7','aquamarine'=>'#7FFFD4','beige'=>'#F5F5DC','black'=>'#000000','blue'=>'#0000FF','brown'=>'#A52A2A','cadetblue'=>'#5F9EA0','chocolate'=>'#D2691E','cornflowerblue'=>'#6495ED','crimson'=>'#DC143C','darkblue'=>'#00008B','darkgoldenrod'=>'#B8860B','darkgreen'=>'#006400','darkmagenta'=>'#8B008B','darkorange'=>'#FF8C00','darkred'=>'#8B0000','darkseagreen'=>'#8FBC8F','darkslategray'=>'#2F4F4F','darkviolet'=>'#9400D3','deepskyblue'=>'#00BFFF','dodgerblue'=>'#1E90FF','firebrick'=>'#B22222','forestgreen'=>'#228B22','gainsboro'=>'#DCDCDC','gold'=>'#FFD700','gray'=>'#808080','green'=>'#008000','greenyellow'=>'#ADFF2F','hotpink'=>'#FF69B4','indigo'=>'#4B0082','khaki'=>'#F0E68C','lavenderblush'=>'#FFF0F5','lemonchiffon'=>'#FFFACD','lightcoral'=>'#F08080','lightgoldenrodyellow'=>'#FAFAD2','lightgreen'=>'#90EE90','lightsalmon'=>'#FFA07A','lightskyblue'=>'#87CEFA','lightslategray'=>'#778899','lightyellow'=>'#FFFFE0','limegreen'=>'#32CD32','magenta'=>'#FF00FF','mediumaquamarine'=>'#66CDAA','mediumorchid'=>'#BA55D3','mediumseagreen'=>'#3CB371','mediumspringgreen'=>'#00FA9A','mediumvioletred'=>'#C71585','mintcream'=>'#F5FFFA','moccasin'=>'#FFE4B5','navy'=>'#000080','olive'=>'#808000','orange'=>'#FFA500','orchid'=>'#DA70D6','palegreen'=>'#98FB98','palevioletred'=>'#D87093','peachpuff'=>'#FFDAB9','pink'=>'#FFC0CB','powderblue'=>'#B0E0E6','red'=>'#FF0000','royalblue'=>'#4169E1','salmon'=>'#FA8072','seagreen'=>'#2E8B57','sienna'=>'#A0522D','skyblue'=>'#87CEEB','slategray'=>'#708090','springgreen'=>'#00FF7F','tan'=>'#D2B48C','thistle'=>'#D8BFD8','turquoise'=>'#40E0D0','violetred'=>'#D02090','white'=>'#FFFFFF','yellow'=>'#FFFF00');
  2300. if (($color{0} != '#') and (strstr($color,'(') === false ))
  2301. $color = $common_colors[strtolower($color)];
  2302. if ($color{0} == '#') //case of #nnnnnn or #nnn
  2303. {
  2304. $cor = strtoupper($color);
  2305. if (strlen($cor) == 4) // Turn #RGB into #RRGGBB
  2306. {
  2307. $cor = "#" . $cor{1} . $cor{1} . $cor{2} . $cor{2} . $cor{3} . $cor{3};
  2308. }
  2309. $R = substr($cor, 1, 2);
  2310. $vermelho = hexdec($R);
  2311. $V = substr($cor, 3, 2);
  2312. $verde = hexdec($V);
  2313. $B = substr($cor, 5, 2);
  2314. $azul = hexdec($B);
  2315. $color = array();
  2316. $color['R']=$vermelho;
  2317. $color['G']=$verde;
  2318. $color['B']=$azul;
  2319. }
  2320. else //case of RGB(r,g,b)
  2321. {
  2322. $color = str_ireplace("rgb(",'',$color);
  2323. $color = str_replace(")",'',$color);
  2324. $cores = explode(",", $color);
  2325. $color = array();
  2326. $color['R']=$cores[0];
  2327. $color['G']=$cores[1];
  2328. $color['B']=$cores[2];
  2329. }
  2330. if (empty($color)) return array('R'=>255,'G'=>255,'B'=>255);
  2331. return $color;
  2332. }
  2333. private function convertSize($size=5, $maxsize=0)
  2334. {
  2335. if (stristr($size,'px') ) $size *= 0.2645; //pixels
  2336. elseif ( stristr($size,'cm') ) $size *= 10; //centimeters
  2337. elseif ( stristr($size,'mm') ) $size += 0; //millimeters
  2338. elseif ( stristr($size,'in') ) $size *= 25.4; //inches
  2339. elseif ( stristr($size,'pc') ) $size *= 38.1/9; //PostScript picas
  2340. elseif ( stristr($size,'pt') ) $size *= 25.4/72; //72dpi
  2341. elseif ( stristr($size,'%') )
  2342. {
  2343. $size += 0; //make "90%" become simply "90"
  2344. $size *= $maxsize/100;
  2345. }
  2346. else $size *= 0.2645; //nothing == px
  2347. return $size;
  2348. }
  2349. private function value_entity_decode($html)
  2350. {
  2351. preg_match_all('|&#(.*?);|',$html,$temparray);
  2352. foreach($temparray[1] as $val) $html = str_replace("&#".$val.";",chr($val),$html);
  2353. return $html;
  2354. }
  2355. private function adjustHtml($html)
  2356. {
  2357. $regexp = '|<script.*?</script>|si';
  2358. $html = preg_replace($regexp,'',$html);
  2359. $html = str_replace("\r\n","\n",$html); //replace carriagereturn-linefeed-combo by a simple linefeed
  2360. $html = str_replace("\f",'',$html); //replace formfeed by nothing
  2361. $html = str_replace("\r",'',$html); //replace carriage return by nothing
  2362. // Preserve '\n's in content between the tags <pre> and </pre>
  2363. $regexp = '#<pre(.*?)>(.+?)</pre>#si';
  2364. $thereispre = preg_match_all($regexp,$html,$temp);
  2365. // Preserve '\n's in content between the tags <textarea> and </textarea>
  2366. $regexp2 = '#<textarea(.*?)>(.+?)</textarea>#si';
  2367. $thereistextarea = preg_match_all($regexp2,$html,$temp2);
  2368. $html = str_replace("\n",' ',$html); //replace linefeed by spaces
  2369. $html = str_replace("\t",' ',$html); //replace tabs by spaces
  2370. $regexp3 = '#\s{2,}#s'; // turn 2+ consecutive spaces into one
  2371. $html = preg_replace($regexp3,' ',$html);
  2372. $iterator = 0;
  2373. while($thereispre) //Recover <pre attributes>content</pre>
  2374. {
  2375. $temp[2][$iterator] = str_replace("\n","<br>",$temp[2][$iterator]);
  2376. $html = preg_replace($regexp,'<erp'.$temp[1][$iterator].'>'.$temp[2][$iterator].'</erp>',$html,1);
  2377. $thereispre--;
  2378. $iterator++;
  2379. }
  2380. $iterator = 0;
  2381. while($thereistextarea) //Recover <textarea attributes>content</textarea>
  2382. {
  2383. $temp2[2][$iterator] = str_replace(" ","&nbsp;",$temp2[2][$iterator]);
  2384. $html = preg_replace($regexp2,'<aeratxet'.$temp2[1][$iterator].'>'.trim($temp2[2][$iterator]).'</aeratxet>',$html,1);
  2385. $thereistextarea--;
  2386. $iterator++;
  2387. }
  2388. //Restore original tag names
  2389. $html = str_replace("<erp","<pre",$html);
  2390. $html = str_replace("</erp>","</pre>",$html);
  2391. $html = str_replace("<aeratxet","<textarea",$html);
  2392. $html = str_replace("</aeratxet>","</textarea>",$html);
  2393. $regexp = '/(<br[ \/]?[\/]?>)+?<\/div>/si'; //<?//fix PSPAD highlight bug
  2394. $html = preg_replace($regexp,'</div>',$html);
  2395. return $html;
  2396. }
  2397. private function dec2alpha($valor,$toupper="true")
  2398. {
  2399. if (($valor < 1) || ($valor > 18278)) return "?"; //supports 'only' up to 18278
  2400. $c1 = $c2 = $c3 = '';
  2401. if ($valor > 702) // 3 letters (up to 18278)
  2402. {
  2403. $c1 = 65 + floor(($valor-703)/676);
  2404. $c2 = 65 + floor((($valor-703)%676)/26);
  2405. $c3 = 65 + floor((($valor-703)%676)%26);
  2406. }
  2407. elseif ($valor > 26) // 2 letters (up to 702)
  2408. {
  2409. $c1 = (64 + (int)(($valor-1) / 26));
  2410. $c2 = (64 + (int)($valor % 26));
  2411. if ($c2 == 64) $c2 += 26;
  2412. }
  2413. else // 1 letter (up to 26)
  2414. {
  2415. $c1 = (64 + $valor);
  2416. }
  2417. $alpha = chr($c1);
  2418. if ($c2 != '') $alpha .= chr($c2);
  2419. if ($c3 != '') $alpha .= chr($c3);
  2420. if (!$toupper) $alpha = strtolower($alpha);
  2421. return $alpha;
  2422. }
  2423. }
  2424. ?>