PageRenderTime 73ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/common/libraries/plugin/html2pdf/html2pdf.class.php

https://bitbucket.org/chamilo/chamilo/
PHP | 2115 lines | 1344 code | 309 blank | 462 comment | 188 complexity | ca913e667e1afd5ef9c8573b8103cda4 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, LGPL-3.0, GPL-3.0, MIT

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

  1. <?php
  2. /**
  3. * Logiciel : HTML2PDF
  4. *
  5. * Convertisseur HTML => PDF, utilise TCPDF
  6. * Distribu? sous la licence LGPL.
  7. *
  8. * @author Laurent MINGUET <webmaster@html2pdf.fr>
  9. * @version 4.00
  10. */
  11. if (!defined('__CLASS_HTML2PDF__'))
  12. {
  13. define('__CLASS_HTML2PDF__', '4.00');
  14. require_once(dirname(__FILE__).'/_mypdf/mypdf.class.php'); // classe mypdf
  15. require_once(dirname(__FILE__).'/parsingHTML.class.php'); // classe de parsing HTML
  16. require_once(dirname(__FILE__).'/styleHTML.class.php'); // classe de gestion des styles
  17. class HTML2PDF
  18. {
  19. public $pdf = null; // objet PDF
  20. public $style = null; // objet de style
  21. public $parsing = null; // objet de parsing
  22. protected $langue = 'fr'; // langue des messages
  23. protected $sens = 'P'; // sens d'affichage Portrait ou Landscape
  24. protected $format = 'A4'; // format de la page : A4, A3, ...
  25. protected $encoding = ''; // charset encoding
  26. protected $unicode = true; // means that the input text is unicode (default = true)
  27. protected $background = array(); // informations sur le background
  28. protected $testTDin1page = true; // activer le test de TD ne devant pas depasser une page
  29. protected $testIsImage = true; // test si les images existes ou non
  30. protected $isSubPart = false; // indique que le convertisseur courant est un sous html
  31. protected $parse_pos = 0; // position du parsing
  32. protected $temp_pos = 0; // position temporaire pour multi tableau
  33. protected $page = 0; // numero de la page courante
  34. protected $sub_html = null; // sous html
  35. protected $sub_part = false; // indicateur de sous html
  36. protected $maxX = 0; // zone maxi X
  37. protected $maxY = 0; // zone maxi Y
  38. protected $maxE = 0; // nomre d'elements dans la zone
  39. protected $maxH = 0; // plus grande hauteur dans la ligne, pour saut de ligne ? corriger
  40. protected $maxSave = array(); // tableau de sauvegarde des maximaux
  41. protected $currentH = 0; // hauteur de la ligne courante
  42. protected $firstPage = true; // premier page
  43. protected $defaultLeft = 0; // marges par default de la page
  44. protected $defaultTop = 0;
  45. protected $defaultRight = 0;
  46. protected $defaultBottom = 0;
  47. protected $margeLeft = 0; //marges r?elles de la page
  48. protected $margeTop = 0;
  49. protected $margeRight = 0;
  50. protected $margeBottom = 0;
  51. protected $marges = array(); // tableau de sauvegarde des differents etats des marges de la page courante
  52. protected $inLink = ''; // indique si on est ? l'interieur d'un lien
  53. protected $lstAncre = array(); // liste des ancres d?tect?es ou cr??es
  54. protected $subHEADER = array(); // tableau des sous commandes pour faire l'HEADER
  55. protected $subFOOTER = array(); // tableau des sous commandes pour faire le FOOTER
  56. protected $subSTATES = array(); // tableau de sauvegarde de certains param?tres
  57. protected $defLIST = array(); // tableau de sauvegarde de l'etat des UL et OL
  58. protected $lstChamps = array(); // liste des champs
  59. protected $lstSelect = array(); // options du select en cours
  60. protected $previousCall = null; // dernier appel
  61. protected $pageMarges = array(); // marges sp?cifiques dues aux floats
  62. protected $isInThead = false; // indique si on est dans un thead
  63. protected $isInTfoot = false; // indique si on est dans un tfoot
  64. protected $isInOverflow = false; // indique si on est dans une div overflow
  65. protected $isInFooter = false; // indique si on est dans un footer ou non
  66. protected $isInDraw = null; // indique si on est en mode dessin
  67. protected $isAfterFloat = false; // indique si on est apres un float
  68. protected $forOneLine = false; // indique si on est dans un sous HTML ne servant qu'a calculer la taille de la prochaine ligne
  69. protected $isInForm = false; // indique si on est dans un formulaire. Contient dans ce cas l? l'action de celui-ci
  70. protected $DEBUG_actif = false; // indique si on est en mode debug
  71. protected $DEBUG_ok_usage = false; // indique l'existance de la fonction memory_get_usage
  72. protected $DEBUG_ok_peak = false; // indique l'existance de la fonction memory_get_peak_usage
  73. protected $DEBUG_level = 0; // niveau du debug
  74. protected $DEBUG_start_time = 0; //
  75. protected $DEBUG_last_time = 0; //
  76. protected $defaultFont = null; // fonte par d?faut si la fonte demand?e n'existe pas
  77. static protected $SUBOBJ = null; // sous objet HTML2PDF pr?par? en cas de besoin
  78. static protected $TABLES = array(); // tableau global necessaire ? la gestion des tables imbriqu?es
  79. static protected $TEXTES = array(); // tableau comprennant le fichier de langue
  80. /**
  81. * Constructeur
  82. *
  83. * @param string sens portrait ou landscape
  84. * @param string format A4, A5, ...
  85. * @param string langue : fr, en, it...
  86. * @param boolean $unicode TRUE means that the input text is unicode (default = true)
  87. * @param String $encoding charset encoding; default is UTF-8
  88. * @param array marges par defaut, dans l'ordre (left, top, right, bottom)
  89. * @return null
  90. */
  91. public function __construct($sens = 'P', $format = 'A4', $langue='fr', $unicode=true, $encoding='UTF-8', $marges = array(5, 5, 5, 8))
  92. {
  93. // sauvegarde des param?tres
  94. $this->page = 0;
  95. $this->sens = $sens;
  96. $this->format = $format;
  97. $this->unicode = $unicode;
  98. $this->encoding = $encoding;
  99. $this->firstPage = true;
  100. $this->langue = strtolower($langue);
  101. // chargement du fichier de langue
  102. HTML2PDF::textLOAD($this->langue);
  103. // cr?ation de l' objet PDF
  104. $this->pdf = new MyPDF($sens, 'mm', $format, $unicode, $encoding);
  105. // initialisation des styles
  106. $this->style = new styleHTML($this->pdf);
  107. $this->style->FontSet();
  108. $this->defLIST = array();
  109. // initialisations diverses
  110. $this->setTestTdInOnePage(true);
  111. $this->setTestIsImage(true);
  112. $this->setDefaultFont(null);
  113. // initialisation du parsing
  114. $this->parsing = new parsingHTML($this->encoding);
  115. $this->sub_html = null;
  116. $this->sub_part = false;
  117. // initialisation des marges
  118. if (!is_array($marges)) $marges = array($marges, $marges, $marges, $marges);
  119. $this->setDefaultMargins($marges[0], $marges[1], $marges[2], $marges[3]);
  120. $this->setMargins();
  121. $this->marges = array();
  122. // initialisation des champs de formulaire
  123. $this->lstChamps = array();
  124. }
  125. /**
  126. * Destructeur
  127. *
  128. * @return null
  129. */
  130. public function __destruct()
  131. {
  132. }
  133. /**
  134. * activer le debug mode
  135. *
  136. * @return null
  137. */
  138. public function setModeDebug()
  139. {
  140. list($usec, $sec) = explode(' ', microtime());
  141. $this->DEBUG_actif = true;
  142. $this->DEBUG_ok_usage = function_exists('memory_get_usage');
  143. $this->DEBUG_ok_peak = function_exists('memory_get_peak_usage');
  144. $this->DEBUG_start_time = (float)$sec + (float)$usec;
  145. $this->DEBUG_last_time = (float)$sec + (float)$usec;
  146. $this->DEBUG_stepline('step', 'time', 'delta', 'memory', 'peak');
  147. $this->DEBUG_add('Init debug');
  148. }
  149. /**
  150. * rajouter une ligne de debug
  151. *
  152. * @param string nom de l'etape
  153. * @param boolean true=monter d'un niveau, false=descendre d'un niveau, null : ne rien faire
  154. * @return null
  155. */
  156. protected function DEBUG_add($nom, $level=null)
  157. {
  158. list($usec, $sec) = explode(' ', microtime());
  159. if ($level===true) $this->DEBUG_level++;
  160. $nom = str_repeat(' ',$this->DEBUG_level). $nom.($level===true ? ' Begin' : ($level===false ? ' End' : ''));
  161. $time = (float)$sec + (float)$usec;
  162. $usage = ($this->DEBUG_ok_usage ? memory_get_usage() : 0);
  163. $peak = ($this->DEBUG_ok_peak ? memory_get_peak_usage() : 0);
  164. $this->DEBUG_stepline(
  165. $nom,
  166. number_format(($time - $this->DEBUG_start_time)*1000, 1, '.', ' ').' ms',
  167. number_format(($time - $this->DEBUG_last_time)*1000, 1, '.', ' ').' ms',
  168. number_format($usage/1024, 1, '.', ' ').' Ko',
  169. number_format($peak/1024, 1, '.', ' ').' Ko');
  170. $this->DEBUG_last_time = $time;
  171. if ($level===false) $this->DEBUG_level--;
  172. return true;
  173. }
  174. /**
  175. * affiche une ligne de debug
  176. *
  177. * @param string nom de l'etape
  178. * @param string valeur 1
  179. * @param string valeur 2
  180. * @param string valeur 3
  181. * @param string valeur 4
  182. * @return null
  183. */
  184. protected function DEBUG_stepline($nom, $val1, $val2, $val3, $val4)
  185. {
  186. $txt = str_pad($nom, 30, ' ', STR_PAD_RIGHT).
  187. str_pad($val1, 12, ' ', STR_PAD_LEFT).
  188. str_pad($val2, 12, ' ', STR_PAD_LEFT).
  189. str_pad($val3, 15, ' ', STR_PAD_LEFT).
  190. str_pad($val4, 15, ' ', STR_PAD_LEFT);
  191. echo '<pre style="padding:0; margin:0">'.$txt.'</pre>';
  192. }
  193. /**
  194. * activer ou desactiver le test de TD ne devant pas depasser une page
  195. *
  196. * @param boolean nouvel etat
  197. * @return boolean ancien etat
  198. */
  199. public function setTestTdInOnePage($mode = true)
  200. {
  201. $old = $this->testTDin1page;
  202. $this->testTDin1page = $mode ? true : false;
  203. return $old;
  204. }
  205. /**
  206. * activer ou desactiver le test sur la pr?sence des images
  207. *
  208. * @param boolean nouvel etat
  209. * @return boolean ancien etat
  210. */
  211. public function setTestIsImage($mode = true)
  212. {
  213. $old = $this->testIsImage;
  214. $this->testIsImage = $mode ? true : false;
  215. return $old;
  216. }
  217. /**
  218. * d?finit la fonte par d?faut si aucun fonte n'est sp?cifi?e, ou si la fonte demand?e n'existe pas
  219. *
  220. * @param string nom de la fonte par defaut. si null : Arial pour fonte non sp?cifi?e, et erreur pour fonte non existante
  221. * @return string nom de l'ancienne fonte par defaut
  222. */
  223. public function setDefaultFont($default = null)
  224. {
  225. $old = $this->defaultFont;
  226. $this->defaultFont = $default;
  227. $this->style->setDefaultFont($default);
  228. return $old;
  229. }
  230. /**
  231. * d?finir les marges par d?fault
  232. *
  233. * @param int en mm, marge left
  234. * @param int en mm, marge top
  235. * @param int en mm, marge right. si null, left=right
  236. * @param int en mm, marge bottom. si null, bottom=8
  237. * @return null
  238. */
  239. protected function setDefaultMargins($left, $top, $right = null, $bottom = null)
  240. {
  241. if ($right===null) $right = $left;
  242. if ($bottom===null) $bottom = 8;
  243. $this->defaultLeft = $this->style->ConvertToMM($left.'mm');
  244. $this->defaultTop = $this->style->ConvertToMM($top.'mm');
  245. $this->defaultRight = $this->style->ConvertToMM($right.'mm');
  246. $this->defaultBottom = $this->style->ConvertToMM($bottom.'mm');
  247. }
  248. /**
  249. * d?finir les marges r?elles, fonctions de la balise page
  250. *
  251. * @return null
  252. */
  253. protected function setMargins()
  254. {
  255. $this->margeLeft = $this->defaultLeft + (isset($this->background['left']) ? $this->background['left'] : 0);
  256. $this->margeRight = $this->defaultRight + (isset($this->background['right']) ? $this->background['right'] : 0);
  257. $this->margeTop = $this->defaultTop + (isset($this->background['top']) ? $this->background['top'] : 0);
  258. $this->margeBottom = $this->defaultBottom + (isset($this->background['bottom']) ? $this->background['bottom'] : 0);
  259. $this->pdf->SetMargins($this->margeLeft, $this->margeTop, $this->margeRight);
  260. $this->pdf->setcMargin(0);
  261. $this->pdf->SetAutoPageBreak(false, $this->margeBottom);
  262. $this->pageMarges = array();
  263. $this->pageMarges[floor($this->margeTop*100)] = array($this->margeLeft, $this->pdf->getW()-$this->margeRight);
  264. }
  265. /**
  266. * recuperer les positions x minimales et maximales en fonction d'une hauteur
  267. *
  268. * @param float y
  269. * @return array(float, float)
  270. */
  271. protected function getMargins($y)
  272. {
  273. $y = floor($y*100);
  274. $x = array($this->pdf->getlMargin(), $this->pdf->getW()-$this->pdf->getrMargin());
  275. foreach($this->pageMarges as $m_y => $m_x)
  276. if ($m_y<=$y) $x = $m_x;
  277. return $x;
  278. }
  279. /**
  280. * ajouter une marge suite a un float
  281. *
  282. * @param string left ou right
  283. * @param float x1
  284. * @param float y1
  285. * @param float x2
  286. * @param float y2
  287. * @return null
  288. */
  289. protected function addMargins($float, $x1, $y1, $x2, $y2)
  290. {
  291. $old1 = $this->getMargins($y1);
  292. $old2 = $this->getMargins($y2);
  293. if ($float=='left') $old1[0] = $x2;
  294. if ($float=='right') $old1[1] = $x1;
  295. $y1 = floor($y1*100);
  296. $y2 = floor($y2*100);
  297. foreach($this->pageMarges as $m_y => $m_x)
  298. {
  299. if ($m_y<$y1) continue;
  300. if ($m_y>$y2) break;
  301. if ($float=='left' && $this->pageMarges[$m_y][0]<$x2) unset($this->pageMarges[$m_y]);
  302. if ($float=='right' && $this->pageMarges[$m_y][1]>$x1) unset($this->pageMarges[$m_y]);
  303. }
  304. $this->pageMarges[$y1] = $old1;
  305. $this->pageMarges[$y2] = $old2;
  306. ksort($this->pageMarges);
  307. $this->isAfterFloat = true;
  308. }
  309. /**
  310. * d?finir des nouvelles marges et sauvegarder les anciennes
  311. *
  312. * @param float marge left
  313. * @param float marge top
  314. * @param float marge right
  315. * @return null
  316. */
  317. protected function saveMargin($ml, $mt, $mr)
  318. {
  319. $this->marges[] = array('l' => $this->pdf->getlMargin(), 't' => $this->pdf->gettMargin(), 'r' => $this->pdf->getrMargin(), 'page' => $this->pageMarges);
  320. $this->pdf->SetMargins($ml, $mt, $mr);
  321. $this->pageMarges = array();
  322. $this->pageMarges[floor($mt*100)] = array($ml, $this->pdf->getW()-$mr);
  323. }
  324. /**
  325. * r?cuperer les derni?res marches sauv?es
  326. *
  327. * @return null
  328. */
  329. protected function loadMargin()
  330. {
  331. $old = array_pop($this->marges);
  332. if ($old)
  333. {
  334. $ml = $old['l'];
  335. $mt = $old['t'];
  336. $mr = $old['r'];
  337. $mP = $old['page'];
  338. }
  339. else
  340. {
  341. $ml = $this->margeLeft;
  342. $mt = 0;
  343. $mr = $this->margeRight;
  344. $mP = array($mt => array($ml, $this->pdf->getW()-$mr));
  345. }
  346. $this->pdf->SetMargins($ml, $mt, $mr);
  347. $this->pageMarges = $mP;
  348. }
  349. /**
  350. * permet d'ajouter une fonte.
  351. *
  352. * @param string nom de la fonte
  353. * @param string style de la fonte
  354. * @param string fichier de la fonte
  355. * @return null
  356. */
  357. public function addFont($family, $style='', $file='')
  358. {
  359. $this->pdf->AddFont($family, $style, $file);
  360. }
  361. /**
  362. * sauvegarder l'?tat actuelle des maximums
  363. *
  364. * @return null
  365. */
  366. protected function saveMax()
  367. {
  368. $this->maxSave[] = array($this->maxX, $this->maxY, $this->maxH, $this->maxE);
  369. }
  370. /**
  371. * charger le dernier ?tat sauv? des maximums
  372. *
  373. * @return null
  374. */
  375. protected function loadMax()
  376. {
  377. $old = array_pop($this->maxSave);
  378. if ($old)
  379. {
  380. $this->maxX = $old[0];
  381. $this->maxY = $old[1];
  382. $this->maxH = $old[2];
  383. $this->maxE = $old[3];
  384. }
  385. else
  386. {
  387. $this->maxX = 0;
  388. $this->maxY = 0;
  389. $this->maxH = 0;
  390. $this->maxE = 0;
  391. }
  392. }
  393. /**
  394. * afficher l'header contenu dans page_header
  395. *
  396. * @return null
  397. */
  398. protected function setPageHeader()
  399. {
  400. if (!count($this->subHEADER)) return false;
  401. $OLD_parse_pos = $this->parse_pos;
  402. $OLD_parse_code = $this->parsing->code;
  403. $this->parse_pos = 0;
  404. $this->parsing->code = $this->subHEADER;
  405. $this->makeHTMLcode();
  406. $this->parse_pos = $OLD_parse_pos;
  407. $this->parsing->code = $OLD_parse_code;
  408. }
  409. /**
  410. * afficher le footer contenu dans page_footer
  411. *
  412. * @return null
  413. */
  414. protected function setPageFooter()
  415. {
  416. if (!count($this->subFOOTER)) return false;
  417. $OLD_parse_pos = $this->parse_pos;
  418. $OLD_parse_code = $this->parsing->code;
  419. $this->parse_pos = 0;
  420. $this->parsing->code = $this->subFOOTER;
  421. $this->isInFooter = true;
  422. $this->makeHTMLcode();
  423. $this->isInFooter = false;
  424. $this->parse_pos = $OLD_parse_pos;
  425. $this->parsing->code = $OLD_parse_code;
  426. }
  427. /**
  428. * saut de ligne avec une hauteur sp?cifique
  429. *
  430. * @param float hauteur de la ligne
  431. * @param integer position reelle courante si saut de ligne pendant l'ecriture d'un texte
  432. * @return null
  433. */
  434. protected function setNewLine($h, $curr = null)
  435. {
  436. $this->pdf->Ln($h);
  437. $this->setNewPositionForNewLine($curr);
  438. }
  439. /**
  440. * cr?ation d'une nouvelle page avec le format et l'orientation sp?cifies
  441. *
  442. * @param mixed format de la page : A5, A4, array(width, height)
  443. * @param string sens P=portrait ou L=landscape
  444. * @param array tableau des propri?t?s du fond de la page
  445. * @param integer position reelle courante si saut de ligne pendant l'ecriture d'un texte
  446. * @return null
  447. */
  448. public function setNewPage($format = null, $orientation = '', $background = null, $curr = null)
  449. {
  450. $this->firstPage = false;
  451. $this->format = $format ? $format : $this->format;
  452. $this->sens = $orientation ? $orientation : $this->sens;
  453. $this->background = $background!==null ? $background : $this->background;
  454. $this->maxY = 0;
  455. $this->maxX = 0;
  456. $this->maxH = 0;
  457. $this->pdf->SetMargins($this->defaultLeft, $this->defaultTop, $this->defaultRight);
  458. $this->pdf->AddPage($this->sens, $this->format);
  459. $this->page++;
  460. if (!$this->sub_part && !$this->isSubPart)
  461. {
  462. if (is_array($this->background))
  463. {
  464. if (isset($this->background['color']) && $this->background['color'])
  465. {
  466. $this->pdf->setFillColorArray($this->background['color']);
  467. $this->pdf->Rect(0, 0, $this->pdf->getW(), $this->pdf->getH(), 'F');
  468. }
  469. if (isset($this->background['img']) && $this->background['img'])
  470. $this->pdf->Image($this->background['img'], $this->background['posX'], $this->background['posY'], $this->background['width']);
  471. }
  472. $this->setPageHeader();
  473. $this->setPageFooter();
  474. }
  475. $this->setMargins();
  476. $this->pdf->setY($this->margeTop);
  477. $this->setNewPositionForNewLine($curr);
  478. $this->maxH = 0;
  479. }
  480. /**
  481. * calcul de la position de debut de la prochaine ligne en fonction de l'alignement voulu
  482. *
  483. * @param integer position reelle courante si saut de ligne pendant l'ecriture d'un texte
  484. * @return null
  485. */
  486. protected function setNewPositionForNewLine($curr = null)
  487. {
  488. list($lx, $rx) = $this->getMargins($this->pdf->getY());
  489. $this->pdf->setX($lx);
  490. $wMax = $rx-$lx;
  491. $this->currentH = 0;
  492. if ($this->sub_part || $this->isSubPart || $this->forOneLine)
  493. {
  494. // $this->pdf->setWordSpacing(0);
  495. return null;
  496. }
  497. /*
  498. if (
  499. $this->style->value['text-align']!='right' &&
  500. $this->style->value['text-align']!='center' &&
  501. $this->style->value['text-align']!='justify'
  502. )
  503. {
  504. // $this->pdf->setWordSpacing(0);
  505. return null;
  506. }
  507. */
  508. $sub = null;
  509. $this->createSubHTML($sub);
  510. $sub->saveMargin(0, 0, $sub->pdf->getW()-$wMax);
  511. $sub->forOneLine = true;
  512. $sub->parse_pos = $this->parse_pos;
  513. $sub->parsing->code = $this->parsing->code;
  514. if ($curr!==null && $sub->parsing->code[$this->parse_pos]['name']=='write')
  515. {
  516. $txt = $sub->parsing->code[$this->parse_pos]['param']['txt'];
  517. $txt = str_replace('[[page_cu]]', $sub->page, $txt);
  518. $sub->parsing->code[$this->parse_pos]['param']['txt'] = substr($txt, $curr);
  519. }
  520. else
  521. $sub->parse_pos++;
  522. // pour chaque element identifi? par le parsing
  523. $res = null;
  524. for($sub->parse_pos; $sub->parse_pos<count($sub->parsing->code); $sub->parse_pos++)
  525. {
  526. $todo = $sub->parsing->code[$sub->parse_pos];
  527. $res = $sub->loadAction($todo);
  528. if (!$res) break;
  529. }
  530. $w = $sub->maxX; // largeur maximale
  531. $h = $sub->maxH; // hauteur maximale
  532. $e = ($res===null ? $sub->maxE : 0); // nombre d'?l?ments maximal
  533. $this->destroySubHTML($sub);
  534. if ($this->style->value['text-align']=='center')
  535. $this->pdf->setX(($rx+$this->pdf->getX()-$w)*0.5-0.01);
  536. elseif ($this->style->value['text-align']=='right')
  537. $this->pdf->setX($rx-$w-0.01);
  538. else
  539. $this->pdf->setX($lx);
  540. $this->currentH = $h;
  541. /*
  542. if ($this->style->value['text-align']=='justify' && $e>1)
  543. $this->pdf->setWordSpacing(($wMax-$w)/($e-1));
  544. else
  545. $this->pdf->setWordSpacing(0);
  546. */
  547. }
  548. /**
  549. * r?cup?ration du PDF
  550. *
  551. * @param string nom du fichier PDF
  552. * @param boolean destination
  553. * @return string contenu ?ventuel du pdf
  554. *
  555. *
  556. * Destination o? envoyer le document. Le param?tre peut prendre les valeurs suivantes :
  557. * true : equivalent ? I
  558. * false : equivalent ? S
  559. * I : envoyer en inline au navigateur. Le plug-in est utilis? s'il est install?. Le nom indiqu? dans name est utilis? lorsque l'on s?lectionne "Enregistrer sous" sur le lien g?n?rant le PDF.
  560. * D : envoyer au navigateur en for?ant le t?l?chargement, avec le nom indiqu? dans name.
  561. * F : sauver dans un fichier local, avec le nom indiqu? dans name (peut inclure un r?pertoire).
  562. * S : renvoyer le document sous forme de cha?ne. name est ignor?.
  563. */
  564. public function Output($name = '', $dest = false)
  565. {
  566. // nettoyage
  567. HTML2PDF::$TABLES = array();
  568. if ($this->DEBUG_actif)
  569. {
  570. $this->DEBUG_add('Before output');
  571. $this->pdf->Close();
  572. exit;
  573. }
  574. // interpretation des param?tres
  575. if ($dest===false) $dest = 'I';
  576. if ($dest===true) $dest = 'S';
  577. if ($dest==='') $dest = 'I';
  578. if ($name=='') $name='document.pdf';
  579. // verification de la destination
  580. $dest = strtoupper($dest);
  581. if (!in_array($dest, array('I', 'D', 'F', 'S'))) $dest = 'I';
  582. // verification du nom
  583. if (strtolower(substr($name, -4))!='.pdf')
  584. {
  585. echo 'ERROR : The output document name "'.$name.'" is not a PDF name';
  586. exit;
  587. }
  588. return $this->pdf->Output($name, $dest);
  589. }
  590. /**
  591. * preparation de HTML2PDF::$SUBOBJ utilis? pour la cr?ation des sous HTML2PDF
  592. *
  593. * @return null
  594. */
  595. protected function prepareSubObj()
  596. {
  597. $pdf = null;
  598. HTML2PDF::$SUBOBJ = new HTML2PDF(
  599. $this->sens,
  600. $this->format,
  601. $this->langue,
  602. $this->unicode,
  603. $this->encoding,
  604. array($this->defaultLeft,$this->defaultTop,$this->defaultRight,$this->defaultBottom)
  605. );
  606. // initialisation
  607. HTML2PDF::$SUBOBJ->setIsSubPart();
  608. HTML2PDF::$SUBOBJ->setTestTdInOnePage($this->testTDin1page);
  609. HTML2PDF::$SUBOBJ->setTestIsImage($this->testIsImage);
  610. HTML2PDF::$SUBOBJ->setDefaultFont($this->defaultFont);
  611. HTML2PDF::$SUBOBJ->style->css = &$this->style->css;
  612. HTML2PDF::$SUBOBJ->style->css_keys = &$this->style->css_keys;
  613. HTML2PDF::$SUBOBJ->pdf->cloneFontFrom($this->pdf);
  614. HTML2PDF::$SUBOBJ->style->setPdfParent($pdf);
  615. }
  616. /**
  617. * fonction de clonage pour la creation d'un sous HTML2PDF ? partir de HTML2PDF::$SUBOBJ
  618. *
  619. * @return null
  620. */
  621. public function __clone()
  622. {
  623. $this->pdf = clone $this->pdf;
  624. $this->parsing = clone $this->parsing;
  625. $this->style = clone $this->style;
  626. $this->style->setPdfParent($this->pdf);
  627. }
  628. /**
  629. * cr?ation d'un sous HTML2PDF pour la gestion des tableaux imbriqu?s
  630. *
  631. * @param HTML2PDF futur sous HTML2PDF pass? en r?f?rence pour cr?ation
  632. * @param integer marge eventuelle de l'objet si simulation d'un TD
  633. * @return null
  634. */
  635. protected function createSubHTML(&$sub_html, $cellmargin=0)
  636. {
  637. if (!HTML2PDF::$SUBOBJ) $this->prepareSubObj();
  638. // calcul de la largueur
  639. if ($this->style->value['width'])
  640. {
  641. $marge = $cellmargin*2;
  642. $marge+= $this->style->value['padding']['l'] + $this->style->value['padding']['r'];
  643. $marge+= $this->style->value['border']['l']['width'] + $this->style->value['border']['r']['width'];
  644. $marge = $this->pdf->getW() - $this->style->value['width'] + $marge;
  645. }
  646. else
  647. $marge = $this->margeLeft+$this->margeRight;
  648. //clonage
  649. $sub_html = clone HTML2PDF::$SUBOBJ;
  650. $sub_html->style->table = $this->style->table;
  651. $sub_html->style->value = $this->style->value;
  652. $sub_html->style->setOnlyLeft();
  653. $sub_html->setNewPage($this->format, $this->sens);
  654. $sub_html->initSubHtml($marge, $this->page, $this->defLIST);
  655. }
  656. /**
  657. * initialise le sous HTML2PDF. Ne pas utiliser directement. seul la fonction createSubHTML doit l'utiliser
  658. *
  659. * @return null
  660. */
  661. public function initSubHtml($marge, $page, $defLIST)
  662. {
  663. $this->saveMargin(0, 0, $marge);
  664. $this->defLIST = $defLIST;
  665. $this->page = $page;
  666. $this->pdf->setXY(0, 0);
  667. $this->style->FontSet();
  668. }
  669. public function setIsSubPart()
  670. {
  671. $this->isSubPart = true;
  672. }
  673. /**
  674. * destruction d'un sous HTML2PDF pour la gestion des tableaux imbriqu?s
  675. *
  676. * @return null
  677. */
  678. protected function destroySubHTML(&$sub_html)
  679. {
  680. unset($sub_html);
  681. $sub_html = null;
  682. }
  683. /**
  684. * Convertir un nombre arabe en nombre romain
  685. *
  686. * @param integer nombre ? convertir
  687. * @return string nombre converti
  688. */
  689. protected function listeArab2Rom($nb_ar)
  690. {
  691. $nb_b10 = array('I','X','C','M');
  692. $nb_b5 = array('V','L','D');
  693. $nb_ro = '';
  694. if ($nb_ar<1) return $nb_ar;
  695. if ($nb_ar>3999) return $nb_ar;
  696. for($i=3; $i>=0 ; $i--)
  697. {
  698. $chiffre=floor($nb_ar/pow(10,$i));
  699. if($chiffre>=1)
  700. {
  701. $nb_ar=$nb_ar-$chiffre*pow(10,$i);
  702. if($chiffre<=3)
  703. {
  704. for($j=$chiffre; $j>=1; $j--)
  705. {
  706. $nb_ro=$nb_ro.$nb_b10[$i];
  707. }
  708. }
  709. else if($chiffre==9)
  710. {
  711. $nb_ro=$nb_ro.$nb_b10[$i].$nb_b10[$i+1];
  712. }
  713. elseif($chiffre==4)
  714. {
  715. $nb_ro=$nb_ro.$nb_b10[$i].$nb_b5[$i];
  716. }
  717. else
  718. {
  719. $nb_ro=$nb_ro.$nb_b5[$i];
  720. for($j=$chiffre-5; $j>=1; $j--)
  721. {
  722. $nb_ro=$nb_ro.$nb_b10[$i];
  723. }
  724. }
  725. }
  726. }
  727. return $nb_ro;
  728. }
  729. /**
  730. * Ajouter un LI au niveau actuel
  731. *
  732. * @return null
  733. */
  734. protected function listeAddLi()
  735. {
  736. $this->defLIST[count($this->defLIST)-1]['nb']++;
  737. }
  738. protected function listeGetWidth() { return '7mm'; }
  739. protected function listeGetPadding() { return '1mm'; }
  740. /**
  741. * Recuperer le LI du niveau actuel
  742. *
  743. * @return string chaine ? afficher
  744. */
  745. protected function listeGetLi()
  746. {
  747. $im = $this->defLIST[count($this->defLIST)-1]['img'];
  748. $st = $this->defLIST[count($this->defLIST)-1]['style'];
  749. $nb = $this->defLIST[count($this->defLIST)-1]['nb'];
  750. $up = (substr($st, 0, 6)=='upper-');
  751. if ($im) return array(false, false, $im);
  752. switch($st)
  753. {
  754. case 'none':
  755. return array('helvetica', true, ' ');
  756. case 'upper-alpha':
  757. case 'lower-alpha':
  758. $str = '';
  759. while($nb>26)
  760. {
  761. $str = chr(96+$nb%26).$str;
  762. $nb = floor($nb/26);
  763. }
  764. $str = chr(96+$nb).$str;
  765. return array('helvetica', false, ($up ? strtoupper($str) : $str).'.');
  766. case 'upper-roman':
  767. case 'lower-roman':
  768. $str = $this->listeArab2Rom($nb);
  769. return array('helvetica', false, ($up ? strtoupper($str) : $str).'.');
  770. case 'decimal':
  771. return array('helvetica', false, $nb.'.');
  772. case 'square':
  773. return array('zapfdingbats', true, chr(110));
  774. case 'circle':
  775. return array('zapfdingbats', true, chr(109));
  776. case 'disc':
  777. default:
  778. return array('zapfdingbats', true, chr(108));
  779. }
  780. }
  781. /**
  782. * Ajouter un niveau de liste
  783. *
  784. * @param string type de liste : ul, ol
  785. * @param string style de la liste
  786. * @return null
  787. */
  788. protected function listeAddLevel($type = 'ul', $style = '', $img = null)
  789. {
  790. if ($img)
  791. {
  792. if (preg_match('/^url\(([^)]+)\)$/isU', trim($img), $match))
  793. $img = $match[1];
  794. else
  795. $img = null;
  796. }
  797. else
  798. $img = null;
  799. if (!in_array($type, array('ul', 'ol'))) $type = 'ul';
  800. if (!in_array($style, array('lower-alpha', 'upper-alpha', 'upper-roman', 'lower-roman', 'decimal', 'square', 'circle', 'disc', 'none'))) $style = '';
  801. if (!$style)
  802. {
  803. if ($type=='ul') $style = 'disc';
  804. else $style = 'decimal';
  805. }
  806. $this->defLIST[count($this->defLIST)] = array('style' => $style, 'nb' => 0, 'img' => $img);
  807. }
  808. /**
  809. * Supprimer un niveau de liste
  810. *
  811. * @return null
  812. */
  813. protected function listeDelLevel()
  814. {
  815. if (count($this->defLIST))
  816. {
  817. unset($this->defLIST[count($this->defLIST)-1]);
  818. $this->defLIST = array_values($this->defLIST);
  819. }
  820. }
  821. /**
  822. * traitement d'un code HTML fait pour HTML2PDF
  823. *
  824. * @param string code HTML ? convertir
  825. * @param boolean afficher en pdf (false) ou en html adapt? (true)
  826. * @return null
  827. */
  828. public function writeHTML($html, $vue = false)
  829. {
  830. // si c'est une vrai page HTML, une conversion s'impose
  831. if (preg_match('/<body/isU', $html))
  832. $html = $this->getHtmlFromPage($html);
  833. $html = str_replace('[[page_nb]]', '{nb}', $html);
  834. $html = str_replace('[[date_y]]', date('Y'), $html);
  835. $html = str_replace('[[date_m]]', date('m'), $html);
  836. $html = str_replace('[[date_d]]', date('d'), $html);
  837. $html = str_replace('[[date_h]]', date('H'), $html);
  838. $html = str_replace('[[date_i]]', date('i'), $html);
  839. $html = str_replace('[[date_s]]', date('s'), $html);
  840. // si on veut voir le r?sultat en HTML => on appelle la fonction
  841. if ($vue) $this->vueHTML($html);
  842. // sinon, traitement pour conversion en PDF :
  843. // parsing
  844. $this->sub_pdf = false;
  845. $this->style->readStyle($html);
  846. $this->parsing->setHTML($html);
  847. $this->parsing->parse();
  848. $this->makeHTMLcode();
  849. }
  850. /**
  851. * traitement du code d'une vrai page HTML pour l'adapter ? HTML2PDF
  852. *
  853. * @param string code HTML ? adapter
  854. * @return string code HTML adapt?
  855. */
  856. public function getHtmlFromPage($html)
  857. {
  858. $html = str_replace('<BODY', '<body', $html);
  859. $html = str_replace('</BODY', '</body', $html);
  860. // extraction du contenu
  861. $res = explode('<body', $html);
  862. if (count($res)<2) return $html;
  863. $content = '<page'.$res[1];
  864. $content = explode('</body', $content);
  865. $content = $content[0].'</page>';
  866. // extraction des balises link
  867. preg_match_all('/<link([^>]*)>/isU', $html, $match);
  868. foreach($match[0] as $src)
  869. $content = $src.'</link>'.$content;
  870. // extraction des balises style
  871. preg_match_all('/<style[^>]*>(.*)<\/style[^>]*>/isU', $html, $match);
  872. foreach($match[0] as $src)
  873. $content = $src.$content;
  874. return $content;
  875. }
  876. /**
  877. * execute les diff?rentes actions du code HTML
  878. *
  879. * @return null
  880. */
  881. protected function makeHTMLcode()
  882. {
  883. // pour chaque element identifi? par le parsing
  884. for($this->parse_pos=0; $this->parse_pos<count($this->parsing->code); $this->parse_pos++)
  885. {
  886. // r?cup?ration de l'?l?ment
  887. $todo = $this->parsing->code[$this->parse_pos];
  888. // si c'est une ouverture de tableau
  889. if (in_array($todo['name'], array('table', 'ul', 'ol')) && !$todo['close'])
  890. {
  891. // on va cr?er un sous HTML, et on va travailler sur une position temporaire
  892. $tag_open = $todo['name'];
  893. $this->sub_part = true;
  894. $this->temp_pos = $this->parse_pos;
  895. // pour tous les ?l?ments jusqu'? la fermeture de la table afin de pr?parer les dimensions
  896. while(isset($this->parsing->code[$this->temp_pos]) && !($this->parsing->code[$this->temp_pos]['name']==$tag_open && $this->parsing->code[$this->temp_pos]['close']))
  897. {
  898. $this->loadAction($this->parsing->code[$this->temp_pos]);
  899. $this->temp_pos++;
  900. }
  901. if (isset($this->parsing->code[$this->temp_pos])) $this->loadAction($this->parsing->code[$this->temp_pos]);
  902. $this->sub_part = false;
  903. }
  904. // chargement de l'action correspondant ? l'?l?ment
  905. $this->loadAction($todo);
  906. }
  907. }
  908. /**
  909. * affichage en mode HTML du contenu
  910. *
  911. * @param string contenu
  912. * @return null
  913. */
  914. protected function vueHTML($content)
  915. {
  916. $content = preg_replace('/<page_header([^>]*)>/isU', '<hr>'.HTML2PDF::textGET('vue01').' : $1<hr><div$1>', $content);
  917. $content = preg_replace('/<page_footer([^>]*)>/isU', '<hr>'.HTML2PDF::textGET('vue02').' : $1<hr><div$1>', $content);
  918. $content = preg_replace('/<page([^>]*)>/isU', '<hr>'.HTML2PDF::textGET('vue03').' : $1<hr><div$1>', $content);
  919. $content = preg_replace('/<\/page([^>]*)>/isU', '</div><hr>', $content);
  920. $content = preg_replace('/<bookmark([^>]*)>/isU', '<hr>bookmark : $1<hr>', $content);
  921. $content = preg_replace('/<\/bookmark([^>]*)>/isU', '', $content);
  922. $content = preg_replace('/<barcode([^>]*)>/isU', '<hr>barcode : $1<hr>', $content);
  923. $content = preg_replace('/<\/barcode([^>]*)>/isU', '', $content);
  924. $content = preg_replace('/<qrcode([^>]*)>/isU', '<hr>qrcode : $1<hr>', $content);
  925. $content = preg_replace('/<\/qrcode([^>]*)>/isU', '', $content);
  926. echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  927. <html>
  928. <head>
  929. <title>'.HTML2PDF::textGET('vue04').' HTML</title>
  930. <meta http-equiv="Content-Type" content="text/html; charset='.$this->encoding.'" >
  931. </head>
  932. <body style="padding: 10px; font-size: 10pt;font-family: Verdana;">
  933. '.$content.'
  934. </body>
  935. </html>';
  936. exit;
  937. }
  938. /**
  939. * chargement de l'action correspondante ? un element de parsing
  940. *
  941. * @param array ?l?ment de parsing
  942. * @return null
  943. */
  944. protected function loadAction($row)
  945. {
  946. // nom de l'action
  947. $fnc = ($row['close'] ? 'c_' : 'o_').strtoupper($row['name']);
  948. // parametres de l'action
  949. $param = $row['param'];
  950. // si aucune page n'est cr??, on la cr??
  951. if ($fnc!='o_PAGE' && $this->firstPage)
  952. {
  953. $this->setNewPage();
  954. }
  955. // lancement de l'action
  956. if (is_callable(array(&$this, $fnc)))
  957. {
  958. $res = $this->{$fnc}($param);
  959. $this->previousCall = $fnc;
  960. return $res;
  961. }
  962. else
  963. {
  964. HTML2PDF::makeError(1, __FILE__, __LINE__, strtoupper($row['name']), $this->parsing->getHtmlErrorCode($row['html_pos']));
  965. return false;
  966. }
  967. }
  968. /**
  969. * balise : PAGE
  970. * mode : OUVERTURE
  971. *
  972. * @param array param?tres de l'?l?ment de parsing
  973. * @return null
  974. */
  975. protected function o_PAGE($param)
  976. {
  977. if ($this->forOneLine) return false;
  978. if ($this->DEBUG_actif) $this->DEBUG_add('PAGE n?'.($this->page+1), true);
  979. $newPageSet= (!isset($param['pageset']) || $param['pageset']!='old');
  980. $this->maxH = 0;
  981. if ($newPageSet)
  982. {
  983. $this->subHEADER = array();
  984. $this->subFOOTER = array();
  985. // identification de l'orientation demand?e
  986. $orientation = '';
  987. if (isset($param['orientation']))
  988. {
  989. $param['orientation'] = strtolower($param['orientation']);
  990. if ($param['orientation']=='p') $orientation = 'P';
  991. if ($param['orientation']=='portrait') $orientation = 'P';
  992. if ($param['orientation']=='l') $orientation = 'L';
  993. if ($param['orientation']=='paysage') $orientation = 'L';
  994. if ($param['orientation']=='landscape') $orientation = 'L';
  995. }
  996. // identification de l'orientation demand?e
  997. $format = null;
  998. if (isset($param['format']))
  999. {
  1000. $format = strtolower($param['format']);
  1001. if (preg_match('/^([0-9]+)x([0-9]+)$/isU', $format, $match))
  1002. {
  1003. $format = array(intval($match[1]), intval($match[2]));
  1004. }
  1005. }
  1006. // identification des propri?t?s du background
  1007. $background = array();
  1008. if (isset($param['backimg']))
  1009. {
  1010. $background['img'] = isset($param['backimg']) ? $param['backimg'] : ''; // nom de l'image
  1011. $background['posX'] = isset($param['backimgx']) ? $param['backimgx'] : 'center'; // position horizontale de l'image
  1012. $background['posY'] = isset($param['backimgy']) ? $param['backimgy'] : 'middle'; // position verticale de l'image
  1013. $background['width'] = isset($param['backimgw']) ? $param['backimgw'] : '100%'; // taille de l'image (100% = largueur de la feuille)
  1014. // conversion du nom de l'image, en cas de param?tres en _GET
  1015. $background['img'] = str_replace('&amp;', '&', $background['img']);
  1016. // conversion des positions
  1017. if ($background['posX']=='left') $background['posX'] = '0%';
  1018. if ($background['posX']=='center') $background['posX'] = '50%';
  1019. if ($background['posX']=='right') $background['posX'] = '100%';
  1020. if ($background['posY']=='top') $background['posY'] = '0%';
  1021. if ($background['posY']=='middle') $background['posY'] = '50%';
  1022. if ($background['posY']=='bottom') $background['posY'] = '100%';
  1023. // si il y a une image de pr?cis?
  1024. if ($background['img'])
  1025. {
  1026. // est-ce que c'est une image ?
  1027. $infos=@GetImageSize($background['img']);
  1028. if (count($infos)>1)
  1029. {
  1030. // taille de l'image, en fonction de la taille sp?cifi?e.
  1031. $Wi = $this->style->ConvertToMM($background['width'], $this->pdf->getW());
  1032. $Hi = $Wi*$infos[1]/$infos[0];
  1033. // r?cup?ration des dimensions et positions de l'image
  1034. $background['width'] = $Wi;
  1035. $background['posX'] = $this->style->ConvertToMM($background['posX'], $this->pdf->getW() - $Wi);
  1036. $background['posY'] = $this->style->ConvertToMM($background['posY'], $this->pdf->getH() - $Hi);
  1037. }
  1038. else
  1039. $background = array();
  1040. }
  1041. else
  1042. $background = array();
  1043. }
  1044. // marges TOP et BOTTOM pour le texte.
  1045. $background['top'] = isset($param['backtop']) ? $param['backtop'] : '0';
  1046. $background['bottom'] = isset($param['backbottom']) ? $param['backbottom'] : '0';
  1047. $background['left'] = isset($param['backleft']) ? $param['backleft'] : '0';
  1048. $background['right'] = isset($param['backright']) ? $param['backright'] : '0';
  1049. if (preg_match('/^([0-9]*)$/isU', $background['top'])) $background['top'] .= 'mm';
  1050. if (preg_match('/^([0-9]*)$/isU', $background['bottom'])) $background['bottom'] .= 'mm';
  1051. if (preg_match('/^([0-9]*)$/isU', $background['left'])) $background['left'] .= 'mm';
  1052. if (preg_match('/^([0-9]*)$/isU', $background['right'])) $background['right'] .= 'mm';
  1053. $background['top'] = $this->style->ConvertToMM($background['top'], $this->pdf->getH());
  1054. $background['bottom'] = $this->style->ConvertToMM($background['bottom'], $this->pdf->getH());
  1055. $background['left'] = $this->style->ConvertToMM($background['left'], $this->pdf->getW());
  1056. $background['right'] = $this->style->ConvertToMM($background['right'], $this->pdf->getW());
  1057. $res = false;
  1058. $background['color'] = isset($param['backcolor']) ? $this->style->ConvertToColor($param['backcolor'], $res) : null;
  1059. if (!$res) $background['color'] = null;
  1060. $this->style->save();
  1061. $this->style->analyse('PAGE', $param);
  1062. $this->style->setPosition();
  1063. $this->style->FontSet();
  1064. // nouvelle page
  1065. $this->setNewPage($format, $orientation, $background);
  1066. // footer automatique
  1067. if (isset($param['footer']))
  1068. {
  1069. $lst = explode(';', $param['footer']);
  1070. foreach($lst as $key => $val) $lst[$key] = trim(strtolower($val));
  1071. $page = in_array('page', $lst);
  1072. $date = in_array('date', $lst);
  1073. $heure = in_array('heure', $lst);
  1074. $form = in_array('form', $lst);
  1075. }
  1076. else
  1077. {
  1078. $page = null;
  1079. $date = null;
  1080. $heure = null;
  1081. $form = null;
  1082. }
  1083. $this->pdf->SetMyFooter($page, $date, $heure, $form);
  1084. }
  1085. else
  1086. {
  1087. $this->style->save();
  1088. $this->style->analyse('PAGE', $param);
  1089. $this->style->setPosition();
  1090. $this->style->FontSet();
  1091. $this->setNewPage();
  1092. }
  1093. return true;
  1094. }
  1095. /**
  1096. * balise : PAGE
  1097. * mode : FERMETURE
  1098. *
  1099. * @param array param?tres de l'?l?ment de parsing
  1100. * @return null
  1101. */
  1102. protected function c_PAGE($param)
  1103. {
  1104. if ($this->forOneLine) return false;
  1105. $this->maxH = 0;
  1106. $this->style->load();
  1107. $this->style->FontSet();
  1108. if ($this->DEBUG_actif) $this->DEBUG_add('PAGE n?'.$this->page, false);
  1109. return true;
  1110. }
  1111. protected function o_PAGE_HEADER($param)
  1112. {
  1113. if ($this->forOneLine) return false;
  1114. $this->subHEADER = array();
  1115. for($this->parse_pos; $this->parse_pos<count($this->parsing->code); $this->parse_pos++)
  1116. {
  1117. $todo = $this->parsing->code[$this->parse_pos];
  1118. if ($todo['name']=='page_header') $todo['name']='page_header_sub';
  1119. $this->subHEADER[] = $todo;
  1120. if (strtolower($todo['name'])=='page_header_sub' && $todo['close']) break;
  1121. }
  1122. $this->setPageHeader();
  1123. return true;
  1124. }
  1125. protected function o_PAGE_FOOTER($param)
  1126. {
  1127. if ($this->forOneLine) return false;
  1128. $this->subFOOTER = array();
  1129. for($this->parse_pos; $this->parse_pos<count($this->parsing->code); $this->parse_pos++)
  1130. {
  1131. $todo = $this->parsing->code[$this->parse_pos];
  1132. if ($todo['name']=='page_footer') $todo['name']='page_footer_sub';
  1133. $this->subFOOTER[] = $todo;
  1134. if (strtolower($todo['name'])=='page_footer_sub' && $todo['close']) break;
  1135. }
  1136. $this->setPageFooter();
  1137. return true;
  1138. }
  1139. protected function o_PAGE_HEADER_SUB($param)
  1140. {
  1141. if ($this->forOneLine) return false;
  1142. // sauvegarde de l'?tat
  1143. $this->subSTATES = array();
  1144. $this->subSTATES['x'] = $this->pdf->getX();
  1145. $this->subSTATES['y'] = $this->pdf->getY();
  1146. $this->subSTATES['s'] = $this->style->value;
  1147. $this->subSTATES['t'] = $this->style->table;
  1148. $this->subSTATES['ml'] = $this->margeLeft;
  1149. $this->subSTATES['mr'] = $this->margeRight;
  1150. $this->subSTATES['mt'] = $this->margeTop;
  1151. $this->subSTATES['mb'] = $this->margeBottom;
  1152. $this->subSTATES['mp'] = $this->pageMarges;
  1153. // nouvel etat pour le footer
  1154. $this->pageMarges = array();
  1155. $this->margeLeft = $this->defaultLeft;
  1156. $this->margeRight = $this->defaultRight;
  1157. $this->margeTop = $this->defaultTop;
  1158. $this->margeBottom = $this->defaultBottom;
  1159. $this->pdf->SetMargins($this->margeLeft, $this->margeTop, $this->margeRight);
  1160. $this->pdf->SetAutoPageBreak(false, $this->margeBottom);
  1161. $this->pdf->setXY($this->defaultLeft, $this->defaultTop);
  1162. $this->style->initStyle();
  1163. $this->style->resetStyle();
  1164. $this->style->value['width'] = $this->pdf->getW() - $this->defaultLeft - $this->defaultRight;
  1165. $this->style->table = array();
  1166. $this->style->save();
  1167. $this->style->analyse('page_header_sub', $param);
  1168. $this->style->setPosition();
  1169. $this->style->FontSet();
  1170. $this->setNewPositionForNewLine();
  1171. return true;
  1172. }
  1173. protected function c_PAGE_HEADER_SUB($param)
  1174. {
  1175. if ($this->forOneLine) return false;
  1176. $this->style->load();
  1177. // retablissement de l'etat
  1178. $this->style->value = $this->subSTATES['s'];
  1179. $this->style->table = $this->subSTATES['t'];
  1180. $this->pageMarges = $this->subSTATES['mp'];
  1181. $this->margeLeft = $this->subSTATES['ml'];
  1182. $this->margeRight = $this->subSTATES['mr'];
  1183. $this->margeTop = $this->subSTATES['mt'];
  1184. $this->margeBottom = $this->subSTATES['mb'];
  1185. $this->pdf->SetMargins($this->margeLeft, $this->margeTop, $this->margeRight);
  1186. $this->pdf->setbMargin($this->margeBottom);
  1187. $this->pdf->SetAutoPageBreak(false, $this->margeBottom);
  1188. $this->pdf->setXY($this->subSTATES['x'], $this->subSTATES['y']);
  1189. $this->style->FontSet();
  1190. $this->maxH = 0;
  1191. return true;
  1192. }
  1193. protected function o_PAGE_FOOTER_SUB($param)
  1194. {
  1195. if ($this->forOneLine) return false;
  1196. $this->subSTATES = array();
  1197. $this->subSTATES['x'] = $this->pdf->getX();
  1198. $this->subSTATES['y'] = $this->pdf->getY();
  1199. $this->subSTATES['s'] = $this->style->value;
  1200. $this->subSTATES['t'] = $this->style->table;
  1201. $this->subSTATES['ml'] = $this->margeLeft;
  1202. $this->subSTATES['mr'] = $this->margeRight;
  1203. $this->subSTATES['mt'] = $this->margeTop;
  1204. $this->subSTATES['mb'] = $this->margeBottom;
  1205. $this->subSTATES['mp'] = $this->pageMarges;
  1206. // nouvel etat pour le footer
  1207. $this->pageMarges = array();
  1208. $this->margeLeft = $this->defaultLeft;
  1209. $this->margeRight = $this->defaultRight;
  1210. $this->margeTop = $this->defaultTop;
  1211. $this->margeBottom = $this->defaultBottom;
  1212. $this->pdf->SetMargins($this->margeLeft, $this->margeTop, $this->margeRight);
  1213. $this->pdf->SetAutoPageBreak(false, $this->margeBottom);
  1214. $this->pdf->setXY($this->defaultLeft, $this->defaultTop);
  1215. $this->style->initStyle();
  1216. $this->style->resetStyle();
  1217. $this->style->value['width'] = $this->pdf->getW() - $this->defaultLeft - $this->defaultRight;
  1218. $this->style->table = array();
  1219. // on en cr?? un sous HTML que l'on transforme en PDF
  1220. // pour r?cup?rer la hauteur
  1221. // on extrait tout ce qui est contenu dans le FOOTER
  1222. $sub = null;
  1223. $this->CreateSubHTML($sub);
  1224. $sub->parsing->code = $this->parsing->getLevel($this->parse_pos);
  1225. $sub->MakeHTMLcode();
  1226. $this->pdf->setY($this->pdf->getH() - $sub->maxY - $this->defaultBottom - 0.01);
  1227. $this->destroySubHTML($sub);
  1228. $this->style->save();
  1229. $this->style->analyse('page_footer_sub', $param);
  1230. $this->style->setPosition();
  1231. $this->style->FontSet();
  1232. $this->setNewPositionForNewLine();
  1233. return true;
  1234. }
  1235. protected function c_PAGE_FOOTER_SUB($param)
  1236. {
  1237. if ($this->forOneLine) return false;
  1238. $this->style->load();
  1239. $this->style->value = $this->subSTATES['s'];
  1240. $this->style->table = $this->subSTATES['t'];
  1241. $this->pageMarges = $this->subSTATES['mp'];
  1242. $this->margeLeft = $this->subSTATES['ml'];
  1243. $this->margeRight = $this->subSTATES['mr'];
  1244. $this->margeTop = $this->subSTATES['mt'];
  1245. $this->margeBottom = $this->subSTATES['mb'];
  1246. $this->pdf->SetMargins($this->margeLeft, $this->margeTop, $this->margeRight);
  1247. $this->pdf->SetAutoPageBreak(false, $this->margeBottom);
  1248. $this->pdf->setXY($this->subSTATES['x'], $this->subSTATES['y']);
  1249. $this->style->FontSet();
  1250. $this->maxH = 0;
  1251. return true;
  1252. }
  1253. /**
  1254. * balise : NOBREAK
  1255. * mode : OUVERTURE
  1256. *
  1257. * @param array param?tres de l'?l?ment de parsing
  1258. * @return null
  1259. */
  1260. protected function o_NOBREAK($param)
  1261. {
  1262. if ($this->forOneLine) return false;
  1263. $this->maxH = 0;
  1264. // on en cr?? un sous HTML que l'on transforme en PDF
  1265. // pour analyse les dimensions
  1266. // et voir si ca rentre
  1267. $sub = null;
  1268. $this->CreateSubHTML($sub);
  1269. $sub->parsing->code = $this->parsing->getLevel($this->parse_pos);
  1270. $sub->MakeHTMLcode();
  1271. $y = $this->pdf->getY();
  1272. if (
  1273. $sub->maxY < ($this->pdf->getH() - $this->pdf->gettMargin()-$this->pdf->getbMargin()) &&
  1274. $y + $sub->maxY>=($this->pdf->getH() - $this->pdf->getbMargin())
  1275. )
  1276. $this->setNewPage();
  1277. $this->destroySubHTML($sub);
  1278. return true;
  1279. }
  1280. /**
  1281. * balise : NOBREAK
  1282. * mode : FERMETURE
  1283. *
  1284. * @param array param?tres de l'?l?ment de parsing
  1285. * @return null
  1286. */
  1287. protected function c_NOBREAK($param)
  1288. {
  1289. if ($this->forOneLine) return false;
  1290. $this->maxH = 0;
  1291. return true;
  1292. }
  1293. /**
  1294. * balise : DIV
  1295. * mode : OUVERTURE
  1296. *
  1297. * @param array param?tres de l'?l?ment de parsing
  1298. * @return null
  1299. */
  1300. protected function o_DIV($param, $other = 'div')
  1301. {
  1302. if ($this->forOneLine) return false;
  1303. if ($this->DEBUG_actif) $this->DEBUG_add('DIV', true);
  1304. $this->style->save();
  1305. $this->style->analyse($other, $param);
  1306. $this->style->FontSet();
  1307. $align_object = null;
  1308. if ($this->style->value['margin-auto']) $align_object = 'center';
  1309. $marge = array();
  1310. $marge['l'] = $this->style->value['border']['l']['width'] + $this->style->value['padding']['l']+0.03;
  1311. $marge['r'] = $this->style->value['border']['r']['width'] + $this->style->value['padding']['r']+0.03;
  1312. $marge['t'] = $this->style->value['border']['t']['width'] + $this->style->value['padding']['t']+0.03;
  1313. $marge['b'] = $this->style->value['border']['b']['width'] + $this->style->value['padding']['b']+0.03;
  1314. // on extrait tout ce qui est contenu dans la DIV
  1315. $level = $this->parsing->getLevel($this->parse_pos);
  1316. // on en cr?? un sous HTML que l'on transforme en PDF
  1317. // pour analyse les dimensions
  1318. $w = 0; $h = 0;
  1319. if (count($level))
  1320. {
  1321. $sub = null;
  1322. $this->CreateSubHTML($sub);
  1323. $sub->parsing->code = $level;
  1324. $sub->MakeHTMLcode();
  1325. $w = $sub->maxX;
  1326. $h = $sub->maxY;
  1327. $this->destroySubHTML($sub);
  1328. }
  1329. $w_reel = $w;
  1330. $h_reel = $h;
  1331. // if (($w==0 && $this->style->value['width']==0) || ($w>$this->style->value['width']) || $this->style->value['position']=='absolute')
  1332. $w+= $marge['l']+$marge['r']+0.001;
  1333. $h+= $marge['t']+$marge['b']+0.001;
  1334. if ($this->style->value['overflow']=='hidden')
  1335. {
  1336. $over_w = max($w, $this->style->value['width']);
  1337. $over_h = max($h, $this->style->value['height']);
  1338. $overflow = true;
  1339. $this->style->value['old_maxX'] = $this->maxX;
  1340. $this->style->value['old_maxY'] = $this->maxY;
  1341. $this->style->value['old_maxH'] = $this->maxH;
  1342. $this->style->value['old_overflow'] = $this->isInOverflow;
  1343. $this->isInOverflow = true;
  1344. }
  1345. else
  1346. {
  1347. $over_w = null;
  1348. $over_h = null;
  1349. $overflow = false;
  1350. $this->style->value['width'] = max($w, $this->style->value['width']);
  1351. $this->style->value['height'] = max($h, $this->style->value['height']);
  1352. }
  1353. switch($this->style->value['rotate'])
  1354. {
  1355. case 90:
  1356. $tmp = $over_h; $over_h = $over_w; $over_w = $tmp;
  1357. $tmp = $h_reel; $h_reel = $w_reel; $w_reel = $tmp;
  1358. unset($tmp);
  1359. $w = $this->style->value['height'];
  1360. $h = $this->style->value['width'];
  1361. $t_x =-$h;
  1362. $t_y = 0;
  1363. break;
  1364. case 180:
  1365. $w = $this->style->value['width'];
  1366. $h = $this->style->value['height'];
  1367. $t_x = -$w;
  1368. $t_y = -$h;
  1369. break;
  1370. case 270:
  1371. $tmp = $over_h; $over_h = $over_w; $over_w = $tmp;
  1372. $tmp = $h_reel; $h_reel = $w_reel; $w_reel = $tmp;
  1373. unset($t

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