3 * HTML2PDF Library - main class
5 * HTML => PDF convertor
6 * distributed under the LGPL License
9 * @author Laurent MINGUET <webmaster@html2pdf.fr>
10 * @copyright 2016 Laurent MINGUET
12 require_once(dirname(__FILE__
).'/_class/tcpdfConfig.php');
17 * HTML2PDF_myPdf object, extends from TCPDF
24 * @var HTML2PDF_parsingCss
26 public $parsingCss = null;
30 * @var HTML2PDF_parsingHtml
32 public $parsingHtml = null;
34 protected $_langue = 'fr'; // locale of the messages
35 protected $_orientation = 'P'; // page orientation : Portrait ou Landscape
36 protected $_format = 'A4'; // page format : A4, A3, ...
37 protected $_encoding = ''; // charset encoding
38 protected $_unicode = true; // means that the input text is unicode (default = true)
40 protected $_testTdInOnepage = true; // test of TD that can not take more than one page
41 protected $_testIsImage = true; // test if the images exist or not
42 protected $_testIsDeprecated = false; // test the deprecated functions
44 protected $_parsePos = 0; // position in the parsing
45 protected $_tempPos = 0; // temporary position for complex table
46 protected $_page = 0; // current page number
48 protected $_subHtml = null; // sub html
49 protected $_subPart = false; // sub HTML2PDF
50 protected $_subHEADER = array(); // sub action to make the header
51 protected $_subFOOTER = array(); // sub action to make the footer
52 protected $_subSTATES = array(); // array to save some parameters
54 protected $_isSubPart = false; // flag : in a sub html2pdf
55 protected $_isInThead = false; // flag : in a thead
56 protected $_isInTfoot = false; // flag : in a tfoot
57 protected $_isInOverflow = false; // flag : in a overflow
58 protected $_isInFooter = false; // flag : in a footer
59 protected $_isInDraw = null; // flag : in a draw (svg)
60 protected $_isAfterFloat = false; // flag : is just after a float
61 protected $_isInForm = false; // flag : is in a float. false / action of the form
62 protected $_isInLink = ''; // flag : is in a link. empty / href of the link
63 protected $_isInParagraph = false; // flag : is in a paragraph
64 protected $_isForOneLine = false; // flag : in a specific sub html2pdf to have the height of the next line
66 protected $_maxX = 0; // maximum X of the current zone
67 protected $_maxY = 0; // maximum Y of the current zone
68 protected $_maxE = 0; // number of elements in the current zone
69 protected $_maxH = 0; // maximum height of the line in the current zone
70 protected $_maxSave = array(); // save the maximums of the current zone
71 protected $_currentH = 0; // height of the current line
73 protected $_defaultLeft = 0; // default marges of the page
74 protected $_defaultTop = 0;
75 protected $_defaultRight = 0;
76 protected $_defaultBottom = 0;
77 protected $_defaultFont = null; // default font to use, is the asked font does not exist
79 protected $_margeLeft = 0; // current marges of the page
80 protected $_margeTop = 0;
81 protected $_margeRight = 0;
82 protected $_margeBottom = 0;
83 protected $_marges = array(); // save the different marges of the current page
84 protected $_pageMarges = array(); // float marges of the current page
85 protected $_background = array(); // background informations
87 protected $_hideHeader = array(); // array : list of pages which the header gonna be hidden
88 protected $_firstPage = true; // flag : first page
89 protected $_defList = array(); // table to save the stats of the tags UL and OL
91 protected $_lstAnchor = array(); // list of the anchors
92 protected $_lstField = array(); // list of the fields
93 protected $_lstSelect = array(); // list of the options of the current select
94 protected $_previousCall = null; // last action called
96 protected $_debugActif = false; // flag : mode debug is active
97 protected $_debugOkUsage = false; // flag : the function memory_get_usage exist
98 protected $_debugOkPeak = false; // flag : the function memory_get_peak_usage exist
99 protected $_debugLevel = 0; // level in the debug
100 protected $_debugStartTime = 0; // debug start time
101 protected $_debugLastTime = 0; // debug stop time
103 static protected $_subobj = null; // object html2pdf prepared in order to accelerate the creation of sub html2pdf
104 static protected $_tables = array(); // static table to prepare the nested html tables
110 * @param string $orientation page orientation, same as TCPDF
111 * @param mixed $format The format used for pages, same as TCPDF
112 * @param $tring $langue Lang : fr, en, it...
113 * @param boolean $unicode TRUE means that the input text is unicode (default = true)
114 * @param String $encoding charset encoding; default is UTF-8
115 * @param array $marges Default margins (left, top, right, bottom)
116 * @param boolean $is_rtl True will set to use RTL(right to left) language.
117 * @return HTML2PDF $this
119 public function __construct($orientation = 'P', $format = 'A4', $langue='fr', $unicode=true, $encoding='UTF-8', $marges = array(5, 5, 5, 8), $is_rtl = false)
121 // init the page number
123 $this->_firstPage
= true;
125 // save the parameters
126 $this->_orientation
= $orientation;
127 $this->_format
= $format;
128 $this->_langue
= strtolower($langue);
129 $this->_unicode
= $unicode;
130 $this->_encoding
= $encoding;
133 HTML2PDF_locale
::load($this->_langue
);
135 // create the HTML2PDF_myPdf object
136 $this->pdf
= new HTML2PDF_myPdf($orientation, 'mm', $format, $unicode, $encoding);
138 // init the CSS parsing object
139 $this->parsingCss
= new HTML2PDF_parsingCss($this->pdf
);
140 $this->parsingCss
->fontSet();
141 $this->_defList
= array();
144 $this->setTestTdInOnePage(true);
145 $this->setTestIsImage(true);
146 $this->setTestIsDeprecated(true);
148 // init the default font
149 $this->setDefaultFont(null);
151 // init language direction setting
153 $this->pdf
->setRTL(true);
155 // init the HTML parsing object
156 $this->parsingHtml
= new HTML2PDF_parsingHtml($this->_encoding
);
157 $this->_subHtml
= null;
158 $this->_subPart
= false;
160 // init the marges of the page
161 if (!is_array($marges)) $marges = array($marges, $marges, $marges, $marges);
162 $this->_setDefaultMargins($marges[0], $marges[1], $marges[2], $marges[3]);
163 $this->_setMargins();
164 $this->_marges
= array();
166 // init the form's fields
167 $this->_lstField
= array();
178 public function __destruct()
184 * Gets the detailed version as array
188 public function getVersionAsArray()
198 * Gets the current version as string
202 public function getVersion()
204 $v = $this->getVersionAsArray();
205 return $v['major'].'.'.$v['minor'].'.'.$v['revision'];
209 * Clone to create a sub HTML2PDF from HTML2PDF::$_subobj
213 public function __clone()
215 $this->pdf
= clone $this->pdf
;
216 $this->parsingHtml
= clone $this->parsingHtml
;
217 $this->parsingCss
= clone $this->parsingCss
;
218 $this->parsingCss
->setPdfParent($this->pdf
);
222 * set the debug mode to On
225 * @return HTML2PDF $this
227 public function setModeDebug()
229 $time = microtime(true);
231 $this->_debugActif
= true;
232 $this->_debugOkUsage
= function_exists('memory_get_usage');
233 $this->_debugOkPeak
= function_exists('memory_get_peak_usage');
234 $this->_debugStartTime
= $time;
235 $this->_debugLastTime
= $time;
237 $this->_DEBUG_stepline('step', 'time', 'delta', 'memory', 'peak');
238 $this->_DEBUG_add('Init debug');
244 * Set the test of TD that can not take more than one page
247 * @param boolean $mode
248 * @return HTML2PDF $this
250 public function setTestTdInOnePage($mode = true)
252 $this->_testTdInOnepage
= $mode ?
true : false;
258 * Set the test if the images exist or not
261 * @param boolean $mode
262 * @return HTML2PDF $this
264 public function setTestIsImage($mode = true)
266 $this->_testIsImage
= $mode ?
true : false;
272 * Set the test on deprecated functions
275 * @param boolean $mode
276 * @return HTML2PDF $this
278 public function setTestIsDeprecated($mode = true)
280 $this->_testIsDeprecated
= $mode ?
true : false;
286 * Set the default font to use, if no font is specified, or if the asked font does not exist
289 * @param string $default name of the default font to use. If null : Arial if no font is specified, and error if the asked font does not exist
290 * @return HTML2PDF $this
292 public function setDefaultFont($default = null)
294 $this->_defaultFont
= $default;
295 $this->parsingCss
->setDefaultFont($default);
301 * add a font, see TCPDF function addFont
304 * @param string $family Font family. The name can be chosen arbitrarily. If it is a standard family name, it will override the corresponding font.
305 * @param string $style Font style. Possible values are (case insensitive):<ul><li>empty string: regular (default)</li><li>B: bold</li><li>I: italic</li><li>BI or IB: bold italic</li></ul>
306 * @param string $file The font definition file. By default, the name is built from the family and style, in lower case with no spaces.
307 * @return HTML2PDF $this
308 * @see TCPDF::addFont
310 public function addFont($family, $style='', $file='')
312 $this->pdf
->AddFont($family, $style, $file);
318 * display a automatic index, from the bookmarks
321 * @param string $titre index title
322 * @param int $sizeTitle font size of the index title, in mm
323 * @param int $sizeBookmark font size of the index, in mm
324 * @param boolean $bookmarkTitle add a bookmark for the index, at his beginning
325 * @param boolean $displayPage display the page numbers
326 * @param int $onPage if null : at the end of the document on a new page, else on the $onPage page
327 * @param string $fontName font name to use
330 public function createIndex($titre = 'Index', $sizeTitle = 20, $sizeBookmark = 15, $bookmarkTitle = true, $displayPage = true, $onPage = null, $fontName = 'helvetica')
332 $oldPage = $this->_INDEX_NewPage($onPage);
333 $this->pdf
->createIndex($this, $titre, $sizeTitle, $sizeBookmark, $bookmarkTitle, $displayPage, $onPage, $fontName);
334 if ($oldPage) $this->pdf
->setPage($oldPage);
338 * clean up the objects
342 protected function _cleanUp()
344 HTML2PDF
::$_subobj = null;
345 HTML2PDF
::$_tables = array();
349 * Send the document to a given destination: string, local file or browser.
351 * I : send the file inline to the browser (default). The plug-in is used if available. The name given by name is used when one selects the "Save as" option on the link generating the PDF.
352 * D : send to the browser and force a file download with the name given by name.
353 * F : save to a local server file with the name given by name.
354 * S : return the document as a string. name is ignored.
355 * FI: equivalent to F + I option
356 * FD: equivalent to F + D option
360 * @param string $name The name of the file when saved.
361 * @param string $dest Destination where to send the document.
362 * @return string content of the PDF, if $dest=S
363 * @throws HTML2PDF_exception
367 public function Output($name = '', $dest = false)
369 // close the pdf and clean up
373 if ($this->_debugActif
) {
374 $this->_DEBUG_add('Before output');
379 // complete parameters
380 if ($dest===false) $dest = 'I';
381 if ($dest===true) $dest = 'S';
382 if ($dest==='') $dest = 'I';
383 if ($name=='') $name='document.pdf';
385 // clean up the destination
386 $dest = strtoupper($dest);
387 if (!in_array($dest, array('I', 'D', 'F', 'S', 'FI','FD'))) $dest = 'I';
389 // the name must be a PDF name
390 if (strtolower(substr($name, -4))!='.pdf') {
391 throw new HTML2PDF_exception(0, 'The output document name "'.$name.'" is not a PDF name');
394 // call the output of TCPDF
395 return $this->pdf
->Output($name, $dest);
399 * convert HTML to PDF
402 * @param string $html
403 * @param boolean $debugVue enable the HTML debug vue
406 public function writeHTML($html, $debugVue = false)
408 // if it is a real html page, we have to convert it
409 if (preg_match('/<body/isU', $html))
410 $html = $this->getHtmlFromPage($html);
412 $html = str_replace('[[date_y]]', date('Y'), $html);
413 $html = str_replace('[[date_m]]', date('m'), $html);
414 $html = str_replace('[[date_d]]', date('d'), $html);
416 $html = str_replace('[[date_h]]', date('H'), $html);
417 $html = str_replace('[[date_i]]', date('i'), $html);
418 $html = str_replace('[[date_s]]', date('s'), $html);
420 // If we are in HTML debug vue : display the HTML
422 return $this->_vueHTML($html);
425 // convert HTMl to PDF
426 $this->parsingCss
->readStyle($html);
427 $this->parsingHtml
->setHTML($html);
428 $this->parsingHtml
->parse();
429 $this->_makeHTMLcode();
433 * convert the HTML of a real page, to a code adapted to HTML2PDF
436 * @param string $html HTML code of a real page
437 * @return string HTML adapted to HTML2PDF
439 public function getHtmlFromPage($html)
441 $html = str_replace('<BODY', '<body', $html);
442 $html = str_replace('</BODY', '</body', $html);
444 // extract the content
445 $res = explode('<body', $html);
446 if (count($res)<2) return $html;
447 $content = '<page'.$res[1];
448 $content = explode('</body', $content);
449 $content = $content[0].'</page>';
451 // extract the link tags
452 preg_match_all('/<link([^>]*)>/isU', $html, $match);
453 foreach ($match[0] as $src)
454 $content = $src.'</link>'.$content;
456 // extract the css style tags
457 preg_match_all('/<style[^>]*>(.*)<\/style[^>]*>/isU', $html, $match);
458 foreach ($match[0] as $src)
459 $content = $src.$content;
465 * init a sub HTML2PDF. do not use it directly. Only the method createSubHTML must use it
468 * @param string $format
469 * @param string $orientation
470 * @param array $marge
471 * @param integer $page
472 * @param array $defLIST
473 * @param integer $myLastPageGroup
474 * @param integer $myLastPageGroupNb
476 public function initSubHtml($format, $orientation, $marge, $page, $defLIST, $myLastPageGroup, $myLastPageGroupNb)
478 $this->_isSubPart
= true;
480 $this->parsingCss
->setOnlyLeft();
482 $this->_setNewPage($format, $orientation, null, null, ($myLastPageGroup!==null));
484 $this->_saveMargin(0, 0, $marge);
485 $this->_defList
= $defLIST;
487 $this->_page
= $page;
488 $this->pdf
->setMyLastPageGroup($myLastPageGroup);
489 $this->pdf
->setMyLastPageGroupNb($myLastPageGroupNb);
490 $this->pdf
->setXY(0, 0);
491 $this->parsingCss
->fontSet();
495 * display the content in HTML moden for debug
498 * @param string $content
500 protected function _vueHTML($content)
502 $content = preg_replace('/<page_header([^>]*)>/isU', '<hr>'.HTML2PDF_locale
::get('vue01').' : $1<hr><div$1>', $content);
503 $content = preg_replace('/<page_footer([^>]*)>/isU', '<hr>'.HTML2PDF_locale
::get('vue02').' : $1<hr><div$1>', $content);
504 $content = preg_replace('/<page([^>]*)>/isU', '<hr>'.HTML2PDF_locale
::get('vue03').' : $1<hr><div$1>', $content);
505 $content = preg_replace('/<\/page([^>]*)>/isU', '</div><hr>', $content);
506 $content = preg_replace('/<bookmark([^>]*)>/isU', '<hr>bookmark : $1<hr>', $content);
507 $content = preg_replace('/<\/bookmark([^>]*)>/isU', '', $content);
508 $content = preg_replace('/<barcode([^>]*)>/isU', '<hr>barcode : $1<hr>', $content);
509 $content = preg_replace('/<\/barcode([^>]*)>/isU', '', $content);
510 $content = preg_replace('/<qrcode([^>]*)>/isU', '<hr>qrcode : $1<hr>', $content);
511 $content = preg_replace('/<\/qrcode([^>]*)>/isU', '', $content);
513 echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
516 <title>'.HTML2PDF_locale
::get('vue04').' HTML</title>
517 <meta http-equiv="Content-Type" content="text/html; charset='.$this->_encoding
.'" >
519 <body style="padding: 10px; font-size: 10pt;font-family: Verdana;">
527 * set the default margins of the page
530 * @param int $left (mm, left margin)
531 * @param int $top (mm, top margin)
532 * @param int $right (mm, right margin, if null => left=right)
533 * @param int $bottom (mm, bottom margin, if null => bottom=8mm)
535 protected function _setDefaultMargins($left, $top, $right = null, $bottom = null)
537 if ($right===null) $right = $left;
538 if ($bottom===null) $bottom = 8;
540 $this->_defaultLeft
= $this->parsingCss
->ConvertToMM($left.'mm');
541 $this->_defaultTop
= $this->parsingCss
->ConvertToMM($top.'mm');
542 $this->_defaultRight
= $this->parsingCss
->ConvertToMM($right.'mm');
543 $this->_defaultBottom
= $this->parsingCss
->ConvertToMM($bottom.'mm');
550 * @param mixed $format
551 * @param string $orientation
552 * @param array $background background information
553 * @param integer $curr real position in the html parser (if break line in the write of a text)
554 * @param boolean $resetPageNumber
556 protected function _setNewPage($format = null, $orientation = '', $background = null, $curr = null, $resetPageNumber=false)
558 $this->_firstPage
= false;
560 $this->_format
= $format ?
$format : $this->_format
;
561 $this->_orientation
= $orientation ?
$orientation : $this->_orientation
;
562 $this->_background
= $background!==null ?
$background : $this->_background
;
568 $this->pdf
->SetMargins($this->_defaultLeft
, $this->_defaultTop
, $this->_defaultRight
);
570 if ($resetPageNumber) {
571 $this->pdf
->startPageGroup();
574 $this->pdf
->AddPage($this->_orientation
, $this->_format
);
576 if ($resetPageNumber) {
577 $this->pdf
->myStartPageGroup();
582 if (!$this->_subPart
&& !$this->_isSubPart
) {
583 if (is_array($this->_background
)) {
584 if (isset($this->_background
['color']) && $this->_background
['color']) {
585 $this->pdf
->setFillColorArray($this->_background
['color']);
586 $this->pdf
->Rect(0, 0, $this->pdf
->getW(), $this->pdf
->getH(), 'F');
589 if (isset($this->_background
['img']) && $this->_background
['img'])
590 $this->pdf
->Image($this->_background
['img'], $this->_background
['posX'], $this->_background
['posY'], $this->_background
['width']);
593 $this->_setPageHeader();
594 $this->_setPageFooter();
597 $this->_setMargins();
598 $this->pdf
->setY($this->_margeTop
);
600 $this->_setNewPositionForNewLine($curr);
605 * set the real margin, using the default margins and the page margins
609 protected function _setMargins()
611 // prepare the margins
612 $this->_margeLeft
= $this->_defaultLeft +
(isset($this->_background
['left']) ?
$this->_background
['left'] : 0);
613 $this->_margeRight
= $this->_defaultRight +
(isset($this->_background
['right']) ?
$this->_background
['right'] : 0);
614 $this->_margeTop
= $this->_defaultTop +
(isset($this->_background
['top']) ?
$this->_background
['top'] : 0);
615 $this->_margeBottom
= $this->_defaultBottom +
(isset($this->_background
['bottom']) ?
$this->_background
['bottom'] : 0);
617 // set the PDF margins
618 $this->pdf
->SetMargins($this->_margeLeft
, $this->_margeTop
, $this->_margeRight
);
619 $this->pdf
->SetAutoPageBreak(false, $this->_margeBottom
);
621 // set the float Margins
622 $this->_pageMarges
= array();
623 if ($this->_isInParagraph
!==false) {
624 $this->_pageMarges
[floor($this->_margeTop
*100)] = array($this->_isInParagraph
[0], $this->pdf
->getW()-$this->_isInParagraph
[1]);
626 $this->_pageMarges
[floor($this->_margeTop
*100)] = array($this->_margeLeft
, $this->pdf
->getW()-$this->_margeRight
);
634 * @param string $name step name
635 * @param boolean $level (true=up, false=down, null=nothing to do)
638 protected function _DEBUG_add($name, $level=null)
641 if ($level===true) $this->_debugLevel++
;
643 $name = str_repeat(' ', $this->_debugLevel
). $name.($level===true ?
' Begin' : ($level===false ?
' End' : ''));
644 $time = microtime(true);
645 $usage = ($this->_debugOkUsage ?
memory_get_usage() : 0);
646 $peak = ($this->_debugOkPeak ?
memory_get_peak_usage() : 0);
648 $this->_DEBUG_stepline(
650 number_format(($time - $this->_debugStartTime
)*1000, 1, '.', ' ').' ms',
651 number_format(($time - $this->_debugLastTime
)*1000, 1, '.', ' ').' ms',
652 number_format($usage/1024, 1, '.', ' ').' Ko',
653 number_format($peak/1024, 1, '.', ' ').' Ko'
656 $this->_debugLastTime
= $time;
659 if ($level===false) $this->_debugLevel
--;
665 * display a debug line
669 * @param string $name
670 * @param string $timeTotal
671 * @param string $timeStep
672 * @param string $memoryUsage
673 * @param string $memoryPeak
675 protected function _DEBUG_stepline($name, $timeTotal, $timeStep, $memoryUsage, $memoryPeak)
677 $txt = str_pad($name, 30, ' ', STR_PAD_RIGHT
).
678 str_pad($timeTotal, 12, ' ', STR_PAD_LEFT
).
679 str_pad($timeStep, 12, ' ', STR_PAD_LEFT
).
680 str_pad($memoryUsage, 15, ' ', STR_PAD_LEFT
).
681 str_pad($memoryPeak, 15, ' ', STR_PAD_LEFT
);
683 echo '<pre style="padding:0; margin:0">'.$txt.'</pre>';
687 * get the Min and Max X, for Y (use the float margins)
691 * @return array(float, float)
693 protected function _getMargins($y)
696 $x = array($this->pdf
->getlMargin(), $this->pdf
->getW()-$this->pdf
->getrMargin());
698 foreach ($this->_pageMarges
as $mY => $mX)
699 if ($mY<=$y) $x = $mX;
705 * Add margins, for a float
708 * @param string $float (left / right)
709 * @param float $xLeft
711 * @param float $xRight
712 * @param float $yBottom
714 protected function _addMargins($float, $xLeft, $yTop, $xRight, $yBottom)
716 // get the current float margins, for top and bottom
717 $oldTop = $this->_getMargins($yTop);
718 $oldBottom = $this->_getMargins($yBottom);
720 // update the top float margin
721 if ($float=='left' && $oldTop[0]<$xRight) $oldTop[0] = $xRight;
722 if ($float=='right' && $oldTop[1]>$xLeft) $oldTop[1] = $xLeft;
724 $yTop = floor($yTop*100);
725 $yBottom = floor($yBottom*100);
727 // erase all the float margins that are smaller than the new one
728 foreach ($this->_pageMarges
as $mY => $mX) {
729 if ($mY<$yTop) continue;
730 if ($mY>$yBottom) break;
731 if ($float=='left' && $this->_pageMarges
[$mY][0]<$xRight) unset($this->_pageMarges
[$mY]);
732 if ($float=='right' && $this->_pageMarges
[$mY][1]>$xLeft) unset($this->_pageMarges
[$mY]);
735 // save the new Top and Bottom margins
736 $this->_pageMarges
[$yTop] = $oldTop;
737 $this->_pageMarges
[$yBottom] = $oldBottom;
740 ksort($this->_pageMarges
);
742 // we are just after float
743 $this->_isAfterFloat
= true;
747 * Save old margins (push), and set new ones
750 * @param float $ml left margin
751 * @param float $mt top margin
752 * @param float $mr right margin
754 protected function _saveMargin($ml, $mt, $mr)
757 $this->_marges
[] = array('l' => $this->pdf
->getlMargin(), 't' => $this->pdf
->gettMargin(), 'r' => $this->pdf
->getrMargin(), 'page' => $this->_pageMarges
);
760 $this->pdf
->SetMargins($ml, $mt, $mr);
762 // prepare for float margins
763 $this->_pageMarges
= array();
764 $this->_pageMarges
[floor($mt*100)] = array($ml, $this->pdf
->getW()-$mr);
768 * load the last saved margins (pop)
772 protected function _loadMargin()
774 $old = array_pop($this->_marges
);
781 $ml = $this->_margeLeft
;
783 $mr = $this->_margeRight
;
784 $mP = array($mt => array($ml, $this->pdf
->getW()-$mr));
787 $this->pdf
->SetMargins($ml, $mt, $mr);
788 $this->_pageMarges
= $mP;
792 * save the current maxs (push)
796 protected function _saveMax()
798 $this->_maxSave
[] = array($this->_maxX
, $this->_maxY
, $this->_maxH
, $this->_maxE
);
802 * load the last saved current maxs (pop)
806 protected function _loadMax()
808 $old = array_pop($this->_maxSave
);
811 $this->_maxX
= $old[0];
812 $this->_maxY
= $old[1];
813 $this->_maxH
= $old[2];
814 $this->_maxE
= $old[3];
824 * draw the PDF header with the HTML in page_header
828 protected function _setPageHeader()
830 if (!count($this->_subHEADER
)) return false;
832 if (in_array($this->pdf
->getPage(), $this->_hideHeader
)) return false;
834 $oldParsePos = $this->_parsePos
;
835 $oldParseCode = $this->parsingHtml
->code
;
837 $this->_parsePos
= 0;
838 $this->parsingHtml
->code
= $this->_subHEADER
;
839 $this->_makeHTMLcode();
841 $this->_parsePos
= $oldParsePos;
842 $this->parsingHtml
->code
= $oldParseCode;
846 * draw the PDF footer with the HTML in page_footer
850 protected function _setPageFooter()
852 if (!count($this->_subFOOTER
)) return false;
854 $oldParsePos = $this->_parsePos
;
855 $oldParseCode = $this->parsingHtml
->code
;
857 $this->_parsePos
= 0;
858 $this->parsingHtml
->code
= $this->_subFOOTER
;
859 $this->_isInFooter
= true;
860 $this->_makeHTMLcode();
861 $this->_isInFooter
= false;
863 $this->_parsePos
= $oldParsePos;
864 $this->parsingHtml
->code
= $oldParseCode;
868 * new line, with a specific height
872 * @param integer $curr real current position in the text, if new line in the write of a text
874 protected function _setNewLine($h, $curr = null)
877 $this->_setNewPositionForNewLine($curr);
881 * calculate the start position of the next line, depending on the text-align
884 * @param integer $curr real current position in the text, if new line in the write of a text
886 protected function _setNewPositionForNewLine($curr = null)
888 // get the margins for the current line
889 list($lx, $rx) = $this->_getMargins($this->pdf
->getY());
890 $this->pdf
->setX($lx);
892 $this->_currentH
= 0;
894 // if subPart => return because align left
895 if ($this->_subPart ||
$this->_isSubPart ||
$this->_isForOneLine
) {
896 $this->pdf
->setWordSpacing(0);
900 // create the sub object
902 $this->_createSubHTML($sub);
903 $sub->_saveMargin(0, 0, $sub->pdf
->getW()-$wMax);
904 $sub->_isForOneLine
= true;
905 $sub->_parsePos
= $this->_parsePos
;
906 $sub->parsingHtml
->code
= $this->parsingHtml
->code
;
908 // if $curr => adapt the current position of the parsing
909 if ($curr!==null && $sub->parsingHtml
->code
[$this->_parsePos
]['name']=='write') {
910 $txt = $sub->parsingHtml
->code
[$this->_parsePos
]['param']['txt'];
911 $txt = str_replace('[[page_cu]]', $sub->pdf
->getMyNumPage($this->_page
), $txt);
912 $sub->parsingHtml
->code
[$this->_parsePos
]['param']['txt'] = substr($txt, $curr+
1);
916 // for each element of the parsing => load the action
918 for ($sub->_parsePos
; $sub->_parsePos
<count($sub->parsingHtml
->code
); $sub->_parsePos++
) {
919 $action = $sub->parsingHtml
->code
[$sub->_parsePos
];
920 $res = $sub->_executeAction($action);
924 $w = $sub->_maxX
; // max width
925 $h = $sub->_maxH
; // max height
926 $e = ($res===null ?
$sub->_maxE
: 0); // maxnumber of elemets on the line
928 // destroy the sub HTML
929 $this->_destroySubHTML($sub);
931 // adapt the start of the line, depending on the text-align
932 if ($this->parsingCss
->value
['text-align']=='center')
933 $this->pdf
->setX(($rx+
$this->pdf
->getX()-$w)*0.5-0.01);
934 else if ($this->parsingCss
->value
['text-align']=='right')
935 $this->pdf
->setX($rx-$w-0.01);
937 $this->pdf
->setX($lx);
939 // set the height of the line
940 $this->_currentH
= $h;
942 // if justify => set the word spacing
943 if ($this->parsingCss
->value
['text-align']=='justify' && $e>1) {
944 $this->pdf
->setWordSpacing(($wMax-$w)/($e-1));
946 $this->pdf
->setWordSpacing(0);
951 * prepare HTML2PDF::$_subobj (used for create the sub HTML2PDF objects
955 protected function _prepareSubObj()
959 // create the sub object
960 HTML2PDF
::$_subobj = new HTML2PDF(
966 array($this->_defaultLeft
,$this->_defaultTop
,$this->_defaultRight
,$this->_defaultBottom
)
970 HTML2PDF
::$_subobj->setTestTdInOnePage($this->_testTdInOnepage
);
971 HTML2PDF
::$_subobj->setTestIsImage($this->_testIsImage
);
972 HTML2PDF
::$_subobj->setTestIsDeprecated($this->_testIsDeprecated
);
973 HTML2PDF
::$_subobj->setDefaultFont($this->_defaultFont
);
974 HTML2PDF
::$_subobj->parsingCss
->css
= &$this->parsingCss
->css
;
975 HTML2PDF
::$_subobj->parsingCss
->cssKeys
= &$this->parsingCss
->cssKeys
;
977 // clone font from the original PDF
978 HTML2PDF
::$_subobj->pdf
->cloneFontFrom($this->pdf
);
980 // remove the link to the parent
981 HTML2PDF
::$_subobj->parsingCss
->setPdfParent($pdf);
985 * create a sub HTML2PDF, to calculate the multi-tables
988 * @param &HTML2PDF $subHtml sub HTML2PDF to create
989 * @param integer $cellmargin if in a TD : cellmargin of this td
991 protected function _createSubHTML(&$subHtml, $cellmargin=0)
993 // prepare the subObject, if never prepare before
994 if (HTML2PDF
::$_subobj===null) {
995 $this->_prepareSubObj();
998 // calculate the width to use
999 if ($this->parsingCss
->value
['width']) {
1000 $marge = $cellmargin*2;
1001 $marge+
= $this->parsingCss
->value
['padding']['l'] +
$this->parsingCss
->value
['padding']['r'];
1002 $marge+
= $this->parsingCss
->value
['border']['l']['width'] +
$this->parsingCss
->value
['border']['r']['width'];
1003 $marge = $this->pdf
->getW() - $this->parsingCss
->value
['width'] +
$marge;
1005 $marge = $this->_margeLeft+
$this->_margeRight
;
1008 // BUGFIX : we have to call the method, because of a bug in php 5.1.6
1009 HTML2PDF
::$_subobj->pdf
->getPage();
1011 // clone the sub oject
1012 $subHtml = clone HTML2PDF
::$_subobj;
1013 $subHtml->parsingCss
->table
= $this->parsingCss
->table
;
1014 $subHtml->parsingCss
->value
= $this->parsingCss
->value
;
1015 $subHtml->initSubHtml(
1017 $this->_orientation
,
1021 $this->pdf
->getMyLastPageGroup(),
1022 $this->pdf
->getMyLastPageGroupNb()
1027 * destroy a subHTML2PDF
1031 protected function _destroySubHTML(&$subHtml)
1038 * Convert an arabic number into a roman number
1041 * @param integer $nbArabic
1042 * @return string $nbRoman
1044 protected function _listeArab2Rom($nbArabic)
1046 $nbBaseTen = array('I','X','C','M');
1047 $nbBaseFive = array('V','L','D');
1050 if ($nbArabic<1) return $nbArabic;
1051 if ($nbArabic>3999) return $nbArabic;
1053 for ($i=3; $i>=0 ; $i--) {
1054 $digit=floor($nbArabic/pow(10, $i));
1056 $nbArabic=$nbArabic-$digit*pow(10, $i);
1058 for ($j=$digit; $j>=1; $j--) {
1059 $nbRoman=$nbRoman.$nbBaseTen[$i];
1061 } else if ($digit==9) {
1062 $nbRoman=$nbRoman.$nbBaseTen[$i].$nbBaseTen[$i+
1];
1063 } else if ($digit==4) {
1064 $nbRoman=$nbRoman.$nbBaseTen[$i].$nbBaseFive[$i];
1066 $nbRoman=$nbRoman.$nbBaseFive[$i];
1067 for ($j=$digit-5; $j>=1; $j--) {
1068 $nbRoman=$nbRoman.$nbBaseTen[$i];
1077 * add a LI to the current level
1081 protected function _listeAddLi()
1083 $this->_defList
[count($this->_defList
)-1]['nb']++
;
1087 * get the width to use for the column of the list
1090 * @return string $width
1092 protected function _listeGetWidth()
1098 * get the padding to use for the column of the list
1101 * @return string $padding
1103 protected function _listeGetPadding()
1109 * get the information of the li on the current level
1112 * @return array(fontName, small size, string)
1114 protected function _listeGetLi()
1116 $im = $this->_defList
[count($this->_defList
)-1]['img'];
1117 $st = $this->_defList
[count($this->_defList
)-1]['style'];
1118 $nb = $this->_defList
[count($this->_defList
)-1]['nb'];
1119 $up = (substr($st, 0, 6)=='upper-');
1121 if ($im) return array(false, false, $im);
1126 return array('helvetica', true, ' ');
1132 $str = chr(96+
$nb%26
).$str;
1133 $nb = floor($nb/26);
1135 $str = chr(96+
$nb).$str;
1137 return array('helvetica', false, ($up ?
strtoupper($str) : $str).'.');
1141 $str = $this->_listeArab2Rom($nb);
1143 return array('helvetica', false, ($up ?
strtoupper($str) : $str).'.');
1146 return array('helvetica', false, $nb.'.');
1149 return array('zapfdingbats', true, chr(110));
1152 return array('zapfdingbats', true, chr(109));
1156 return array('zapfdingbats', true, chr(108));
1161 * add a level to the list
1164 * @param string $type : ul, ol
1165 * @param string $style : lower-alpha, ...
1166 * @param string $img
1168 protected function _listeAddLevel($type = 'ul', $style = '', $img = null)
1170 // get the url of the image, if we want to use a image
1172 if (preg_match('/^url\(([^)]+)\)$/isU', trim($img), $match)) {
1181 // prepare the datas
1182 if (!in_array($type, array('ul', 'ol'))) $type = 'ul';
1183 if (!in_array($style, array('lower-alpha', 'upper-alpha', 'upper-roman', 'lower-roman', 'decimal', 'square', 'circle', 'disc', 'none'))) $style = '';
1186 if ($type=='ul') $style = 'disc';
1187 else $style = 'decimal';
1190 // add the new level
1191 $this->_defList
[count($this->_defList
)] = array('style' => $style, 'nb' => 0, 'img' => $img);
1195 * remove a level from the list
1199 protected function _listeDelLevel()
1201 if (count($this->_defList
)) {
1202 unset($this->_defList
[count($this->_defList
)-1]);
1203 $this->_defList
= array_values($this->_defList
);
1208 * execute the actions to convert the html
1212 protected function _makeHTMLcode()
1214 // foreach elements of the parsing
1215 for ($this->_parsePos
=0; $this->_parsePos
<count($this->parsingHtml
->code
); $this->_parsePos++
) {
1217 // get the action to do
1218 $action = $this->parsingHtml
->code
[$this->_parsePos
];
1220 // if it is a opening of table / ul / ol
1221 if (in_array($action['name'], array('table', 'ul', 'ol')) && !$action['close']) {
1223 // we will work as a sub HTML to calculate the size of the element
1224 $this->_subPart
= true;
1226 // get the name of the opening tag
1227 $tagOpen = $action['name'];
1229 // save the actual pos on the parsing
1230 $this->_tempPos
= $this->_parsePos
;
1232 // foreach elements, while we are in the opened tag
1233 while (isset($this->parsingHtml
->code
[$this->_tempPos
]) && !($this->parsingHtml
->code
[$this->_tempPos
]['name']==$tagOpen && $this->parsingHtml
->code
[$this->_tempPos
]['close'])) {
1235 $this->_executeAction($this->parsingHtml
->code
[$this->_tempPos
]);
1239 // execute the closure of the tag
1240 if (isset($this->parsingHtml
->code
[$this->_tempPos
])) {
1241 $this->_executeAction($this->parsingHtml
->code
[$this->_tempPos
]);
1244 // end of the sub part
1245 $this->_subPart
= false;
1248 // execute the action
1249 $this->_executeAction($action);
1254 * execute the action from the parsing
1257 * @param array $action
1259 * @throws HTML2PDF_exception
1261 protected function _executeAction($action)
1263 // name of the action
1264 $fnc = ($action['close'] ?
'_tag_close_' : '_tag_open_').strtoupper($action['name']);
1266 // parameters of the action
1267 $param = $action['param'];
1269 // if it is the first action of the first page, and if it is not an open tag of PAGE => create the new page
1270 if ($fnc!='_tag_open_PAGE' && $this->_firstPage
) {
1271 $this->_setNewPage();
1274 // the action must exist
1275 if (!is_callable(array(&$this, $fnc))) {
1276 throw new HTML2PDF_exception(1, strtoupper($action['name']), $this->parsingHtml
->getHtmlErrorCode($action['html_pos']));
1280 $res = $this->{$fnc}($param);
1282 // save the name of the action
1283 $this->_previousCall
= $fnc;
1285 // return the result
1290 * get the position of the element on the current line, depending on its height
1296 protected function _getElementY($h)
1298 if ($this->_subPart ||
$this->_isSubPart ||
!$this->_currentH ||
$this->_currentH
<$h)
1301 return ($this->_currentH
-$h)*0.8;
1308 * @param float $h current line height
1309 * @param integer $curr real current position in the text, if new line in the write of a text
1311 protected function _makeBreakLine($h, $curr = null)
1314 if (($this->pdf
->getY()+
$h<$this->pdf
->getH() - $this->pdf
->getbMargin()) ||
$this->_isInOverflow ||
$this->_isInFooter
)
1315 $this->_setNewLine($h, $curr);
1317 $this->_setNewPage(null, '', null, $curr);
1319 $this->_setNewPositionForNewLine($curr);
1330 * @param string $src
1331 * @param boolean $subLi if true=image of a list
1332 * @return boolean depending on "isForOneLine"
1333 * @throws HTML2PDF_exception
1335 protected function _drawImage($src, $subLi=false)
1337 // get the size of the image
1338 // WARNING : if URL, "allow_url_fopen" must turned to "on" in php.ini
1339 $infos=@getimagesize
($src);
1341 // if the image does not exist, or can not be loaded
1342 if (count($infos)<2) {
1343 // if the test is activ => exception
1344 if ($this->_testIsImage
) {
1345 throw new HTML2PDF_exception(6, $src);
1348 // else, display a gray rectangle
1350 $infos = array(16, 16);
1353 // convert the size of the image in the unit of the PDF
1354 $imageWidth = $infos[0]/$this->pdf
->getK();
1355 $imageHeight = $infos[1]/$this->pdf
->getK();
1357 // calculate the size from the css style
1358 if ($this->parsingCss
->value
['width'] && $this->parsingCss
->value
['height']) {
1359 $w = $this->parsingCss
->value
['width'];
1360 $h = $this->parsingCss
->value
['height'];
1361 } else if ($this->parsingCss
->value
['width']) {
1362 $w = $this->parsingCss
->value
['width'];
1363 $h = $imageHeight*$w/$imageWidth;
1364 } else if ($this->parsingCss
->value
['height']) {
1365 $h = $this->parsingCss
->value
['height'];
1366 $w = $imageWidth*$h/$imageHeight;
1369 $w = 72./96.*$imageWidth;
1370 $h = 72./96.*$imageHeight;
1373 // are we in a float
1374 $float = $this->parsingCss
->getFloat();
1376 // if we are in a float, but if something else if on the line => Break Line
1377 if ($float && $this->_maxH
) {
1378 // make the break line (false if we are in "_isForOneLine" mode)
1379 if (!$this->_tag_open_BR(array())) {
1384 // position of the image
1385 $x = $this->pdf
->getX();
1386 $y = $this->pdf
->getY();
1388 // if the image can not be put on the current line => new line
1389 if (!$float && ($x +
$w>$this->pdf
->getW() - $this->pdf
->getrMargin()) && $this->_maxH
) {
1390 if ($this->_isForOneLine
) {
1395 $hnl = max($this->_maxH
, $this->parsingCss
->getLineHeight());
1396 $this->_setNewLine($hnl);
1398 // get the new position
1399 $x = $this->pdf
->getX();
1400 $y = $this->pdf
->getY();
1403 // if the image can not be put on the current page
1404 if (($y +
$h>$this->pdf
->getH() - $this->pdf
->getbMargin()) && !$this->_isInOverflow
) {
1406 $this->_setNewPage();
1408 // get the new position
1409 $x = $this->pdf
->getX();
1410 $y = $this->pdf
->getY();
1413 // correction for display the image of a list
1414 $hT = 0.80*$this->parsingCss
->value
['font-size'];
1415 if ($subLi && $h<$hT) {
1419 // add the margin top
1420 $yc = $y-$this->parsingCss
->value
['margin']['t'];
1422 // get the width and the position of the parent
1423 $old = $this->parsingCss
->getOldValues();
1424 if ( $old['width']) {
1425 $parentWidth = $old['width'];
1428 $parentWidth = $this->pdf
->getW() - $this->pdf
->getlMargin() - $this->pdf
->getrMargin();
1429 $parentX = $this->pdf
->getlMargin();
1432 // if we are in a gloat => adapt the parent position and width
1434 list($lx, $rx) = $this->_getMargins($yc);
1436 $parentWidth = $rx-$lx;
1439 // calculate the position of the image, if align to the right
1440 if ($parentWidth>$w && $float!='left') {
1441 if ($float=='right' ||
$this->parsingCss
->value
['text-align']=='li_right') $x = $parentX +
$parentWidth - $w-$this->parsingCss
->value
['margin']['r']-$this->parsingCss
->value
['margin']['l'];
1444 // display the image
1445 if (!$this->_subPart
&& !$this->_isSubPart
) {
1447 $this->pdf
->Image($src, $x, $y, $w, $h, '', $this->_isInLink
);
1449 // rectangle if the image can not be loaded
1450 $this->pdf
->setFillColorArray(array(240, 220, 220));
1451 $this->pdf
->Rect($x, $y, $w, $h, 'F');
1455 // apply the margins
1456 $x-= $this->parsingCss
->value
['margin']['l'];
1457 $y-= $this->parsingCss
->value
['margin']['t'];
1458 $w+
= $this->parsingCss
->value
['margin']['l'] +
$this->parsingCss
->value
['margin']['r'];
1459 $h+
= $this->parsingCss
->value
['margin']['t'] +
$this->parsingCss
->value
['margin']['b'];
1461 if ($float=='left') {
1462 // save the current max
1463 $this->_maxX
= max($this->_maxX
, $x+
$w);
1464 $this->_maxY
= max($this->_maxY
, $y+
$h);
1466 // add the image to the margins
1467 $this->_addMargins($float, $x, $y, $x+
$w, $y+
$h);
1469 // get the new position
1470 list($lx, $rx) = $this->_getMargins($yc);
1471 $this->pdf
->setXY($lx, $yc);
1472 } else if ($float=='right') {
1473 // save the current max. We don't save the X because it is not the real max of the line
1474 $this->_maxY
= max($this->_maxY
, $y+
$h);
1476 // add the image to the margins
1477 $this->_addMargins($float, $x, $y, $x+
$w, $y+
$h);
1479 // get the new position
1480 list($lx, $rx) = $this->_getMargins($yc);
1481 $this->pdf
->setXY($lx, $yc);
1483 // set the new position at the end of the image
1484 $this->pdf
->setX($x+
$w);
1486 // save the current max
1487 $this->_maxX
= max($this->_maxX
, $x+
$w);
1488 $this->_maxY
= max($this->_maxY
, $y+
$h);
1489 $this->_maxH
= max($this->_maxH
, $h);
1503 * @param array $border
1504 * @param float $padding - internal margin of the rectangle => not used, but...
1505 * @param float $margin - external margin of the rectangle
1506 * @param array $background
1508 * @throws HTML2PDF_exception
1510 protected function _drawRectangle($x, $y, $w, $h, $border, $padding, $margin, $background)
1512 // if we are in a subpart or if height is null => return false
1513 if ($this->_subPart ||
$this->_isSubPart ||
$h===null) return false;
1521 // get the radius of the border
1522 $outTL = $border['radius']['tl'];
1523 $outTR = $border['radius']['tr'];
1524 $outBR = $border['radius']['br'];
1525 $outBL = $border['radius']['bl'];
1527 // prepare the out radius
1528 $outTL = ($outTL[0] && $outTL[1]) ?
$outTL : null;
1529 $outTR = ($outTR[0] && $outTR[1]) ?
$outTR : null;
1530 $outBR = ($outBR[0] && $outBR[1]) ?
$outBR : null;
1531 $outBL = ($outBL[0] && $outBL[1]) ?
$outBL : null;
1533 // prepare the in radius
1539 if (is_array($inTL)) {
1540 $inTL[0]-= $border['l']['width'];
1541 $inTL[1]-= $border['t']['width'];
1543 if (is_array($inTR)) {
1544 $inTR[0]-= $border['r']['width'];
1545 $inTR[1]-= $border['t']['width'];
1547 if (is_array($inBR)) {
1548 $inBR[0]-= $border['r']['width'];
1549 $inBR[1]-= $border['b']['width'];
1551 if (is_array($inBL)) {
1552 $inBL[0]-= $border['l']['width'];
1553 $inBL[1]-= $border['b']['width'];
1556 if ($inTL[0]<=0 ||
$inTL[1]<=0) $inTL = null;
1557 if ($inTR[0]<=0 ||
$inTR[1]<=0) $inTR = null;
1558 if ($inBR[0]<=0 ||
$inBR[1]<=0) $inBR = null;
1559 if ($inBL[0]<=0 ||
$inBL[1]<=0) $inBL = null;
1561 // prepare the background color
1563 if ($background['color']) {
1564 $this->pdf
->setFillColorArray($background['color']);
1568 // if we have a background to fill => fill it with a path (because of the radius)
1570 $this->pdf
->clippingPathStart($x, $y, $w, $h, $outTL, $outTR, $outBL, $outBR);
1571 $this->pdf
->Rect($x, $y, $w, $h, $pdfStyle);
1572 $this->pdf
->clippingPathStop();
1575 // prepare the background image
1576 if ($background['image']) {
1577 $iName = $background['image'];
1578 $iPosition = $background['position']!==null ?
$background['position'] : array(0, 0);
1579 $iRepeat = $background['repeat']!==null ?
$background['repeat'] : array(true, true);
1581 // size of the background without the borders
1587 if ($border['b']['width']) {
1588 $bH-= $border['b']['width'];
1590 if ($border['l']['width']) {
1591 $bW-= $border['l']['width'];
1592 $bX+
= $border['l']['width'];
1594 if ($border['t']['width']) {
1595 $bH-= $border['t']['width'];
1596 $bY+
= $border['t']['width'];
1598 if ($border['r']['width']) {
1599 $bW-= $border['r']['width'];
1602 // get the size of the image
1603 // WARNING : if URL, "allow_url_fopen" must turned to "on" in php.ini
1604 $imageInfos=@getimagesize
($iName);
1606 // if the image can not be loaded
1607 if (count($imageInfos)<2) {
1608 if ($this->_testIsImage
) {
1609 throw new HTML2PDF_exception(6, $iName);
1612 // convert the size of the image from pixel to the unit of the PDF
1613 $imageWidth = 72./96.*$imageInfos[0]/$this->pdf
->getK();
1614 $imageHeight = 72./96.*$imageInfos[1]/$this->pdf
->getK();
1616 // prepare the position of the backgroung
1617 if ($iRepeat[0]) $iPosition[0] = $bX;
1618 else if (preg_match('/^([-]?[0-9\.]+)%/isU', $iPosition[0], $match)) $iPosition[0] = $bX +
$match[1]*($bW-$imageWidth)/100;
1619 else $iPosition[0] = $bX+
$iPosition[0];
1621 if ($iRepeat[1]) $iPosition[1] = $bY;
1622 else if (preg_match('/^([-]?[0-9\.]+)%/isU', $iPosition[1], $match)) $iPosition[1] = $bY +
$match[1]*($bH-$imageHeight)/100;
1623 else $iPosition[1] = $bY+
$iPosition[1];
1626 $imageXmax = $bX+
$bW;
1628 $imageYmax = $bY+
$bH;
1630 if (!$iRepeat[0] && !$iRepeat[1]) {
1631 $imageXmin = $iPosition[0]; $imageXmax = $iPosition[0]+
$imageWidth;
1632 $imageYmin = $iPosition[1]; $imageYmax = $iPosition[1]+
$imageHeight;
1633 } else if ($iRepeat[0] && !$iRepeat[1]) {
1634 $imageYmin = $iPosition[1]; $imageYmax = $iPosition[1]+
$imageHeight;
1635 } else if (!$iRepeat[0] && $iRepeat[1]) {
1636 $imageXmin = $iPosition[0]; $imageXmax = $iPosition[0]+
$imageWidth;
1639 // build the path to display the image (because of radius)
1640 $this->pdf
->clippingPathStart($bX, $bY, $bW, $bH, $inTL, $inTR, $inBL, $inBR);
1643 for ($iY=$imageYmin; $iY<$imageYmax; $iY+
=$imageHeight) {
1644 for ($iX=$imageXmin; $iX<$imageXmax; $iX+
=$imageWidth) {
1649 if ($imageYmax-$iY<$imageHeight) {
1652 $cH = $imageYmax-$iY;
1654 if ($imageXmax-$iX<$imageWidth) {
1657 $cW = $imageXmax-$iX;
1660 $this->pdf
->Image($iName, $iX, $iY, $imageWidth, $imageHeight, '', '');
1665 $this->pdf
->clippingPathStop();
1669 // adding some loose (0.01mm)
1675 if ($border['l']['width']) $border['l']['width']+
= 2.*$loose;
1676 if ($border['t']['width']) $border['t']['width']+
= 2.*$loose;
1677 if ($border['r']['width']) $border['r']['width']+
= 2.*$loose;
1678 if ($border['b']['width']) $border['b']['width']+
= 2.*$loose;
1680 // prepare the test on borders
1681 $testBl = ($border['l']['width'] && $border['l']['color'][0]!==null);
1682 $testBt = ($border['t']['width'] && $border['t']['color'][0]!==null);
1683 $testBr = ($border['r']['width'] && $border['r']['color'][0]!==null);
1684 $testBb = ($border['b']['width'] && $border['b']['color'][0]!==null);
1686 // draw the radius bottom-left
1687 if (is_array($outBL) && ($testBb ||
$testBl)) {
1690 $courbe[] = $x+
$outBL[0]; $courbe[] = $y+
$h;
1691 $courbe[] = $x; $courbe[] = $y+
$h-$outBL[1];
1692 $courbe[] = $x+
$outBL[0]; $courbe[] = $y+
$h-$border['b']['width'];
1693 $courbe[] = $x+
$border['l']['width']; $courbe[] = $y+
$h-$outBL[1];
1694 $courbe[] = $x+
$outBL[0]; $courbe[] = $y+
$h-$outBL[1];
1697 $courbe[] = $x+
$outBL[0]; $courbe[] = $y+
$h;
1698 $courbe[] = $x; $courbe[] = $y+
$h-$outBL[1];
1699 $courbe[] = $x+
$border['l']['width']; $courbe[] = $y+
$h-$border['b']['width'];
1700 $courbe[] = $x+
$outBL[0]; $courbe[] = $y+
$h-$outBL[1];
1702 $this->_drawCurve($courbe, $border['l']['color']);
1705 // draw the radius left-top
1706 if (is_array($outTL) && ($testBt ||
$testBl)) {
1709 $courbe[] = $x; $courbe[] = $y+
$outTL[1];
1710 $courbe[] = $x+
$outTL[0]; $courbe[] = $y;
1711 $courbe[] = $x+
$border['l']['width']; $courbe[] = $y+
$outTL[1];
1712 $courbe[] = $x+
$outTL[0]; $courbe[] = $y+
$border['t']['width'];
1713 $courbe[] = $x+
$outTL[0]; $courbe[] = $y+
$outTL[1];
1716 $courbe[] = $x; $courbe[] = $y+
$outTL[1];
1717 $courbe[] = $x+
$outTL[0]; $courbe[] = $y;
1718 $courbe[] = $x+
$border['l']['width']; $courbe[] = $y+
$border['t']['width'];
1719 $courbe[] = $x+
$outTL[0]; $courbe[] = $y+
$outTL[1];
1721 $this->_drawCurve($courbe, $border['t']['color']);
1724 // draw the radius top-right
1725 if (is_array($outTR) && ($testBt ||
$testBr)) {
1728 $courbe[] = $x+
$w-$outTR[0]; $courbe[] = $y;
1729 $courbe[] = $x+
$w; $courbe[] = $y+
$outTR[1];
1730 $courbe[] = $x+
$w-$outTR[0]; $courbe[] = $y+
$border['t']['width'];
1731 $courbe[] = $x+
$w-$border['r']['width']; $courbe[] = $y+
$outTR[1];
1732 $courbe[] = $x+
$w-$outTR[0]; $courbe[] = $y+
$outTR[1];
1735 $courbe[] = $x+
$w-$outTR[0]; $courbe[] = $y;
1736 $courbe[] = $x+
$w; $courbe[] = $y+
$outTR[1];
1737 $courbe[] = $x+
$w-$border['r']['width']; $courbe[] = $y+
$border['t']['width'];
1738 $courbe[] = $x+
$w-$outTR[0]; $courbe[] = $y+
$outTR[1];
1740 $this->_drawCurve($courbe, $border['r']['color']);
1743 // draw the radius right-bottom
1744 if (is_array($outBR) && ($testBb ||
$testBr)) {
1747 $courbe[] = $x+
$w; $courbe[] = $y+
$h-$outBR[1];
1748 $courbe[] = $x+
$w-$outBR[0]; $courbe[] = $y+
$h;
1749 $courbe[] = $x+
$w-$border['r']['width']; $courbe[] = $y+
$h-$outBR[1];
1750 $courbe[] = $x+
$w-$outBR[0]; $courbe[] = $y+
$h-$border['b']['width'];
1751 $courbe[] = $x+
$w-$outBR[0]; $courbe[] = $y+
$h-$outBR[1];
1754 $courbe[] = $x+
$w; $courbe[] = $y+
$h-$outBR[1];
1755 $courbe[] = $x+
$w-$outBR[0]; $courbe[] = $y+
$h;
1756 $courbe[] = $x+
$w-$border['r']['width']; $courbe[] = $y+
$h-$border['b']['width'];
1757 $courbe[] = $x+
$w-$outBR[0]; $courbe[] = $y+
$h-$outBR[1];
1759 $this->_drawCurve($courbe, $border['b']['color']);
1762 // draw the left border
1765 $pt[] = $x; $pt[] = $y+
$h;
1766 $pt[] = $x; $pt[] = $y+
$h-$border['b']['width'];
1767 $pt[] = $x; $pt[] = $y+
$border['t']['width'];
1768 $pt[] = $x; $pt[] = $y;
1769 $pt[] = $x+
$border['l']['width']; $pt[] = $y+
$border['t']['width'];
1770 $pt[] = $x+
$border['l']['width']; $pt[] = $y+
$h-$border['b']['width'];
1773 if (is_array($outBL)) {
1775 $pt[3] -= $outBL[1] - $border['b']['width'];
1776 if ($inBL) $pt[11]-= $inBL[1];
1777 unset($pt[0]);unset($pt[1]);
1779 if (is_array($outTL)) {
1781 $pt[5] +
= $outTL[1]-$border['t']['width'];
1782 if ($inTL) $pt[9] +
= $inTL[1];
1783 unset($pt[6]);unset($pt[7]);
1786 $pt = array_values($pt);
1787 $this->_drawLine($pt, $border['l']['color'], $border['l']['type'], $border['l']['width'], $bord);
1790 // draw the top border
1793 $pt[] = $x; $pt[] = $y;
1794 $pt[] = $x+
$border['l']['width']; $pt[] = $y;
1795 $pt[] = $x+
$w-$border['r']['width']; $pt[] = $y;
1796 $pt[] = $x+
$w; $pt[] = $y;
1797 $pt[] = $x+
$w-$border['r']['width']; $pt[] = $y+
$border['t']['width'];
1798 $pt[] = $x+
$border['l']['width']; $pt[] = $y+
$border['t']['width'];
1801 if (is_array($outTL)) {
1803 $pt[2] +
= $outTL[0] - $border['l']['width'];
1804 if ($inTL) $pt[10]+
= $inTL[0];
1805 unset($pt[0]);unset($pt[1]);
1807 if (is_array($outTR)) {
1809 $pt[4] -= $outTR[0] - $border['r']['width'];
1810 if ($inTR) $pt[8] -= $inTR[0];
1811 unset($pt[6]);unset($pt[7]);
1814 $pt = array_values($pt);
1815 $this->_drawLine($pt, $border['t']['color'], $border['t']['type'], $border['t']['width'], $bord);
1818 // draw the right border
1821 $pt[] = $x+
$w; $pt[] = $y;
1822 $pt[] = $x+
$w; $pt[] = $y+
$border['t']['width'];
1823 $pt[] = $x+
$w; $pt[] = $y+
$h-$border['b']['width'];
1824 $pt[] = $x+
$w; $pt[] = $y+
$h;
1825 $pt[] = $x+
$w-$border['r']['width']; $pt[] = $y+
$h-$border['b']['width'];
1826 $pt[] = $x+
$w-$border['r']['width']; $pt[] = $y+
$border['t']['width'];
1829 if (is_array($outTR)) {
1831 $pt[3] +
= $outTR[1] - $border['t']['width'];
1832 if ($inTR) $pt[11]+
= $inTR[1];
1833 unset($pt[0]);unset($pt[1]);
1835 if (is_array($outBR)) {
1837 $pt[5] -= $outBR[1] - $border['b']['width'];
1838 if ($inBR) $pt[9] -= $inBR[1];
1839 unset($pt[6]);unset($pt[7]);
1842 $pt = array_values($pt);
1843 $this->_drawLine($pt, $border['r']['color'], $border['r']['type'], $border['r']['width'], $bord);
1846 // draw the bottom border
1849 $pt[] = $x+
$w; $pt[] = $y+
$h;
1850 $pt[] = $x+
$w-$border['r']['width']; $pt[] = $y+
$h;
1851 $pt[] = $x+
$border['l']['width']; $pt[] = $y+
$h;
1852 $pt[] = $x; $pt[] = $y+
$h;
1853 $pt[] = $x+
$border['l']['width']; $pt[] = $y+
$h-$border['b']['width'];
1854 $pt[] = $x+
$w-$border['r']['width']; $pt[] = $y+
$h-$border['b']['width'];
1857 if (is_array($outBL)) {
1859 $pt[4] +
= $outBL[0] - $border['l']['width'];
1860 if ($inBL) $pt[8] +
= $inBL[0];
1861 unset($pt[6]);unset($pt[7]);
1863 if (is_array($outBR)) {
1865 $pt[2] -= $outBR[0] - $border['r']['width'];
1866 if ($inBR) $pt[10]-= $inBR[0];
1867 unset($pt[0]);unset($pt[1]);
1871 $pt = array_values($pt);
1872 $this->_drawLine($pt, $border['b']['color'], $border['b']['type'], $border['b']['width'], $bord);
1875 if ($background['color']) {
1876 $this->pdf
->setFillColorArray($background['color']);
1883 * draw a curve (for border radius)
1887 * @param array $color
1889 protected function _drawCurve($pt, $color)
1891 $this->pdf
->setFillColorArray($color);
1894 $this->pdf
->drawCurve($pt[0], $pt[1], $pt[2], $pt[3], $pt[4], $pt[5], $pt[6], $pt[7], $pt[8], $pt[9]);
1896 $this->pdf
->drawCorner($pt[0], $pt[1], $pt[2], $pt[3], $pt[4], $pt[5], $pt[6], $pt[7]);
1900 * draw a line with a specific type, and specific start and end for radius
1904 * @param array $color
1905 * @param string $type (dashed, dotted, double, solid)
1906 * @param float $width
1907 * @param integer $radius (binary from 0 to 3 with 1=>start with a radius, 2=>end with a radius)
1909 protected function _drawLine($pt, $color, $type, $width, $radius=3)
1911 // set the fill color
1912 $this->pdf
->setFillColorArray($color);
1914 // if dashed or dotted
1915 if ($type=='dashed' ||
$type=='dotted') {
1917 // clean the end of the line, if radius
1919 $tmp = array(); $tmp[]=$pt[0]; $tmp[]=$pt[1]; $tmp[]=$pt[2]; $tmp[]=$pt[3]; $tmp[]=$pt[8]; $tmp[]=$pt[9];
1920 $this->pdf
->Polygon($tmp, 'F');
1922 $tmp = array(); $tmp[]=$pt[2]; $tmp[]=$pt[3]; $tmp[]=$pt[4]; $tmp[]=$pt[5]; $tmp[]=$pt[6]; $tmp[]=$pt[7]; $tmp[]=$pt[8]; $tmp[]=$pt[9];
1924 } else if ($radius==2) {
1925 $tmp = array(); $tmp[]=$pt[2]; $tmp[]=$pt[3]; $tmp[]=$pt[4]; $tmp[]=$pt[5]; $tmp[]=$pt[6]; $tmp[]=$pt[7];
1926 $this->pdf
->Polygon($tmp, 'F');
1928 $tmp = array(); $tmp[]=$pt[0]; $tmp[]=$pt[1]; $tmp[]=$pt[2]; $tmp[]=$pt[3]; $tmp[]=$pt[6]; $tmp[]=$pt[7]; $tmp[]=$pt[8]; $tmp[]=$pt[9];
1930 } else if ($radius==3) {
1931 $tmp = array(); $tmp[]=$pt[0]; $tmp[]=$pt[1]; $tmp[]=$pt[2]; $tmp[]=$pt[3]; $tmp[]=$pt[10]; $tmp[]=$pt[11];
1932 $this->pdf
->Polygon($tmp, 'F');
1934 $tmp = array(); $tmp[]=$pt[4]; $tmp[]=$pt[5]; $tmp[]=$pt[6]; $tmp[]=$pt[7]; $tmp[]=$pt[8]; $tmp[]=$pt[9];
1935 $this->pdf
->Polygon($tmp, 'F');
1937 $tmp = array(); $tmp[]=$pt[2]; $tmp[]=$pt[3]; $tmp[]=$pt[4]; $tmp[]=$pt[5]; $tmp[]=$pt[8]; $tmp[]=$pt[9]; $tmp[]=$pt[10]; $tmp[]=$pt[11];
1941 // horisontal or vertical line
1942 if ($pt[2]==$pt[0]) {
1943 $l = abs(($pt[3]-$pt[1])*0.5);
1946 $x1 = $pt[0]; $y1 = ($pt[3]+
$pt[1])*0.5;
1947 $x2 = $pt[6]; $y2 = ($pt[7]+
$pt[5])*0.5;
1949 $l = abs(($pt[2]-$pt[0])*0.5);
1952 $x1 = ($pt[2]+
$pt[0])*0.5; $y1 = $pt[1];
1953 $x2 = ($pt[6]+
$pt[4])*0.5; $y2 = $pt[7];
1956 // if dashed : 3x bigger than dotted
1957 if ($type=='dashed') {
1961 $mode = ($l/($px+
$py)<.5);
1963 // display the dotted/dashed line
1964 for ($i=0; $l-($px+
$py)*($i-0.5)>0; $i++
) {
1965 if (($i%2
)==$mode) {
1967 $lx1 = $px*($j); if ($lx1<-$l) $lx1 =-$l;
1968 $ly1 = $py*($j); if ($ly1<-$l) $ly1 =-$l;
1969 $lx2 = $px*($j+
1); if ($lx2>$l) $lx2 = $l;
1970 $ly2 = $py*($j+
1); if ($ly2>$l) $ly2 = $l;
1973 $tmp[] = $x1+
$lx1; $tmp[] = $y1+
$ly1;
1974 $tmp[] = $x1+
$lx2; $tmp[] = $y1+
$ly2;
1975 $tmp[] = $x2+
$lx2; $tmp[] = $y2+
$ly2;
1976 $tmp[] = $x2+
$lx1; $tmp[] = $y2+
$ly1;
1977 $this->pdf
->Polygon($tmp, 'F');
1981 $tmp[] = $x1-$lx1; $tmp[] = $y1-$ly1;
1982 $tmp[] = $x1-$lx2; $tmp[] = $y1-$ly2;
1983 $tmp[] = $x2-$lx2; $tmp[] = $y2-$ly2;
1984 $tmp[] = $x2-$lx1; $tmp[] = $y2-$ly1;
1985 $this->pdf
->Polygon($tmp, 'F');
1989 } else if ($type=='double') {
1991 // if double, 2 lines : 0=>1/3 and 2/3=>1
1995 if (count($pt)==12) {
1997 $pt1[0] = ($pt[0]-$pt[10])*0.33 +
$pt[10];
1998 $pt1[1] = ($pt[1]-$pt[11])*0.33 +
$pt[11];
1999 $pt1[2] = ($pt[2]-$pt[10])*0.33 +
$pt[10];
2000 $pt1[3] = ($pt[3]-$pt[11])*0.33 +
$pt[11];
2001 $pt1[4] = ($pt[4]-$pt[8])*0.33 +
$pt[8];
2002 $pt1[5] = ($pt[5]-$pt[9])*0.33 +
$pt[9];
2003 $pt1[6] = ($pt[6]-$pt[8])*0.33 +
$pt[8];
2004 $pt1[7] = ($pt[7]-$pt[9])*0.33 +
$pt[9];
2005 $pt2[10]= ($pt[10]-$pt[0])*0.33 +
$pt[0];
2006 $pt2[11]= ($pt[11]-$pt[1])*0.33 +
$pt[1];
2009 $pt2[2] = ($pt[2] -$pt[0])*0.33 +
$pt[0];
2010 $pt2[3] = ($pt[3] -$pt[1])*0.33 +
$pt[1];
2011 $pt2[4] = ($pt[4] -$pt[6])*0.33 +
$pt[6];
2012 $pt2[5] = ($pt[5] -$pt[7])*0.33 +
$pt[7];
2013 $pt2[8] = ($pt[8] -$pt[6])*0.33 +
$pt[6];
2014 $pt2[9] = ($pt[9] -$pt[7])*0.33 +
$pt[7];
2017 $pt1[0] = ($pt[0]-$pt[6])*0.33 +
$pt[6];
2018 $pt1[1] = ($pt[1]-$pt[7])*0.33 +
$pt[7];
2019 $pt1[2] = ($pt[2]-$pt[4])*0.33 +
$pt[4];
2020 $pt1[3] = ($pt[3]-$pt[5])*0.33 +
$pt[5];
2023 $pt2[6] = ($pt[6]-$pt[0])*0.33 +
$pt[0];
2024 $pt2[7] = ($pt[7]-$pt[1])*0.33 +
$pt[1];
2025 $pt2[4] = ($pt[4]-$pt[2])*0.33 +
$pt[2];
2026 $pt2[5] = ($pt[5]-$pt[3])*0.33 +
$pt[3];
2028 $this->pdf
->Polygon($pt1, 'F');
2029 $this->pdf
->Polygon($pt2, 'F');
2030 } else if ($type=='solid') {
2031 // solid line : draw directly the polygon
2032 $this->pdf
->Polygon($pt, 'F');
2037 * prepare a transform matrix, only for drawing a SVG graphic
2040 * @param string $transform
2041 * @return array $matrix
2043 protected function _prepareTransform($transform)
2045 // it can not be empty
2046 if (!$transform) return null;
2048 // sctions must be like scale(...)
2049 if (!preg_match_all('/([a-z]+)\(([^\)]*)\)/isU', $transform, $match)) return null;
2051 // prepare the list of the actions
2055 for ($k=0; $k<count($match[0]); $k++
) {
2057 // get the name of the action
2058 $name = strtolower($match[1][$k]);
2060 // get the parameters of the action
2061 $val = explode(',', trim($match[2][$k]));
2062 foreach ($val as $i => $j) {
2063 $val[$i] = trim($j);
2066 // prepare the matrix, depending on the action
2070 if (!isset($val[0])) $val[0] = 1.; else $val[0] = 1.*$val[0];
2071 if (!isset($val[1])) $val[1] = $val[0]; else $val[1] = 1.*$val[1];
2072 $actions[] = array($val[0],0,0,$val[1],0,0);
2076 if (!isset($val[0])) $val[0] = 0.; else $val[0] = $this->parsingCss
->ConvertToMM($val[0], $this->_isInDraw
['w']);
2077 if (!isset($val[1])) $val[1] = 0.; else $val[1] = $this->parsingCss
->ConvertToMM($val[1], $this->_isInDraw
['h']);
2078 $actions[] = array(1,0,0,1,$val[0],$val[1]);
2082 if (!isset($val[0])) $val[0] = 0.; else $val[0] = $val[0]*M_PI
/180.;
2083 if (!isset($val[1])) $val[1] = 0.; else $val[1] = $this->parsingCss
->ConvertToMM($val[1], $this->_isInDraw
['w']);
2084 if (!isset($val[2])) $val[2] = 0.; else $val[2] = $this->parsingCss
->ConvertToMM($val[2], $this->_isInDraw
['h']);
2085 if ($val[1] ||
$val[2]) $actions[] = array(1,0,0,1,-$val[1],-$val[2]);
2086 $actions[] = array(cos($val[0]),sin($val[0]),-sin($val[0]),cos($val[0]),0,0);
2087 if ($val[1] ||
$val[2]) $actions[] = array(1,0,0,1,$val[1],$val[2]);
2091 if (!isset($val[0])) $val[0] = 0.; else $val[0] = $val[0]*M_PI
/180.;
2092 $actions[] = array(1,0,tan($val[0]),1,0,0);
2096 if (!isset($val[0])) $val[0] = 0.; else $val[0] = $val[0]*M_PI
/180.;
2097 $actions[] = array(1,tan($val[0]),0,1,0,0);
2100 if (!isset($val[0])) $val[0] = 0.; else $val[0] = $val[0]*1.;
2101 if (!isset($val[1])) $val[1] = 0.; else $val[1] = $val[1]*1.;
2102 if (!isset($val[2])) $val[2] = 0.; else $val[2] = $val[2]*1.;
2103 if (!isset($val[3])) $val[3] = 0.; else $val[3] = $val[3]*1.;
2104 if (!isset($val[4])) $val[4] = 0.; else $val[4] = $this->parsingCss
->ConvertToMM($val[4], $this->_isInDraw
['w']);
2105 if (!isset($val[5])) $val[5] = 0.; else $val[5] = $this->parsingCss
->ConvertToMM($val[5], $this->_isInDraw
['h']);
2111 // if there are no actions => return
2112 if (!$actions) return null;
2114 // get the first matrix
2115 $m = $actions[0]; unset($actions[0]);
2117 // foreach matrix => multiply to the last matrix
2118 foreach ($actions as $n) {
2120 $m[0]*$n[0]+
$m[2]*$n[1],
2121 $m[1]*$n[0]+
$m[3]*$n[1],
2122 $m[0]*$n[2]+
$m[2]*$n[3],
2123 $m[1]*$n[2]+
$m[3]*$n[3],
2124 $m[0]*$n[4]+
$m[2]*$n[5]+
$m[4],
2125 $m[1]*$n[4]+
$m[3]*$n[5]+
$m[5]
2129 // return the matrix
2135 * @param &array $cases
2136 * @param &array $corr
2138 protected function _calculateTableCellSize(&$cases, &$corr)
2140 if (!isset($corr[0])) return true;
2142 // for each cell without colspan, we get the max width for each column
2144 for ($x=0; $x<count($corr[0]); $x++
) {
2146 for ($y=0; $y<count($corr); $y++
) {
2147 if (isset($corr[$y][$x]) && is_array($corr[$y][$x]) && $corr[$y][$x][2]==1) {
2148 $m = max($m, $cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['w']);
2154 // for each cell with colspan, we adapt the width of each column
2155 for ($x=0; $x<count($corr[0]); $x++
) {
2156 for ($y=0; $y<count($corr); $y++
) {
2157 if (isset($corr[$y][$x]) && is_array($corr[$y][$x]) && $corr[$y][$x][2]>1) {
2159 // sum the max width of each column in colspan
2160 $s = 0; for ($i=0; $i<$corr[$y][$x][2]; $i++
) $s+
= $sw[$x+
$i];
2162 // if the max width is < the width of the cell with colspan => we adapt the width of each max width
2163 if ($s>0 && $s<$cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['w']) {
2164 for ($i=0; $i<$corr[$y][$x][2]; $i++
) {
2165 $sw[$x+
$i] = $sw[$x+
$i]/$s*$cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['w'];
2172 // set the new width, for each cell
2173 for ($x=0; $x<count($corr[0]); $x++
) {
2174 for ($y=0; $y<count($corr); $y++
) {
2175 if (isset($corr[$y][$x]) && is_array($corr[$y][$x])) {
2177 if ($corr[$y][$x][2]==1) {
2178 $cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['w'] = $sw[$x];
2182 for ($i=0; $i<$corr[$y][$x][2]; $i++
) {
2185 $cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['w'] = $s;
2191 // for each cell without rowspan, we get the max height for each line
2193 for ($y=0; $y<count($corr); $y++
) {
2195 for ($x=0; $x<count($corr[0]); $x++
) {
2196 if (isset($corr[$y][$x]) && is_array($corr[$y][$x]) && $corr[$y][$x][3]==1) {
2197 $m = max($m, $cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['h']);
2203 // for each cell with rowspan, we adapt the height of each line
2204 for ($y=0; $y<count($corr); $y++
) {
2205 for ($x=0; $x<count($corr[0]); $x++
) {
2206 if (isset($corr[$y][$x]) && is_array($corr[$y][$x]) && $corr[$y][$x][3]>1) {
2208 // sum the max height of each line in rowspan
2210 for ($i=0; $i<$corr[$y][$x][3]; $i++
) {
2211 $s+
= isset($sh[$y+
$i]) ?
$sh[$y+
$i] : 0;
2214 // if the max height is < the height of the cell with rowspan => we adapt the height of each max height
2215 if ($s>0 && $s<$cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['h']) {
2216 for ($i=0; $i<$corr[$y][$x][3]; $i++
) {
2217 $sh[$y+
$i] = $sh[$y+
$i]/$s*$cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['h'];
2224 // set the new height, for each cell
2225 for ($y=0; $y<count($corr); $y++
) {
2226 for ($x=0; $x<count($corr[0]); $x++
) {
2227 if (isset($corr[$y][$x]) && is_array($corr[$y][$x])) {
2229 if ($corr[$y][$x][3]==1) {
2230 $cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['h'] = $sh[$y];
2234 for ($i=0; $i<$corr[$y][$x][3]; $i++
) {
2237 $cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['h'] = $s;
2239 for ($j=1; $j<$corr[$y][$x][3]; $j++
) {
2242 for (true; isset($corr[$ty][$tx]) && !is_array($corr[$ty][$tx]); $tx++
);
2243 if (isset($corr[$ty][$tx])) {
2244 $cases[$corr[$ty][$tx][1]][$corr[$ty][$tx][0]]['dw']+
= $cases[$corr[$y][$x][1]][$corr[$y][$x][0]]['w'];
2257 * @param array $param
2260 protected function _tag_open_PAGE($param)
2262 if ($this->_isForOneLine
) return false;
2263 if ($this->_debugActif
) $this->_DEBUG_add('PAGE '.($this->_page+
1), true);
2265 $newPageSet= (!isset($param['pageset']) ||
$param['pageset']!='old');
2267 $resetPageNumber = (isset($param['pagegroup']) && $param['pagegroup']=='new');
2269 if (array_key_exists('hideheader', $param) && $param['hideheader']!='false' && !empty($param['hideheader'])) {
2270 $this->_hideHeader
= (array) array_merge($this->_hideHeader
, split(',', $param['hideheader']));
2275 // if new page set asked
2277 $this->_subHEADER
= array();
2278 $this->_subFOOTER
= array();
2282 if (isset($param['orientation'])) {
2283 $param['orientation'] = strtolower($param['orientation']);
2284 if ($param['orientation']=='p') $orientation = 'P';
2285 if ($param['orientation']=='portrait') $orientation = 'P';
2287 if ($param['orientation']=='l') $orientation = 'L';
2288 if ($param['orientation']=='paysage') $orientation = 'L';
2289 if ($param['orientation']=='landscape') $orientation = 'L';
2294 if (isset($param['format'])) {
2295 $format = strtolower($param['format']);
2296 if (preg_match('/^([0-9]+)x([0-9]+)$/isU', $format, $match)) {
2297 $format = array(intval($match[1]), intval($match[2]));
2302 $background = array();
2303 if (isset($param['backimg'])) {
2304 $background['img'] = isset($param['backimg']) ?
$param['backimg'] : ''; // src of the image
2305 $background['posX'] = isset($param['backimgx']) ?
$param['backimgx'] : 'center'; // horizontale position of the image
2306 $background['posY'] = isset($param['backimgy']) ?
$param['backimgy'] : 'middle'; // vertical position of the image
2307 $background['width'] = isset($param['backimgw']) ?
$param['backimgw'] : '100%'; // width of the image (100% = page width)
2309 // convert the src of the image, if parameters
2310 $background['img'] = str_replace('&', '&', $background['img']);
2312 // convert the positions
2313 if ($background['posX']=='left') $background['posX'] = '0%';
2314 if ($background['posX']=='center') $background['posX'] = '50%';
2315 if ($background['posX']=='right') $background['posX'] = '100%';
2316 if ($background['posY']=='top') $background['posY'] = '0%';
2317 if ($background['posY']=='middle') $background['posY'] = '50%';
2318 if ($background['posY']=='bottom') $background['posY'] = '100%';
2320 if ($background['img']) {
2321 // get the size of the image
2322 // WARNING : if URL, "allow_url_fopen" must turned to "on" in php.ini
2323 $infos=@getimagesize
($background['img']);
2324 if (count($infos)>1) {
2325 $imageWidth = $this->parsingCss
->ConvertToMM($background['width'], $this->pdf
->getW());
2326 $imageHeight = $imageWidth*$infos[1]/$infos[0];
2328 $background['width'] = $imageWidth;
2329 $background['posX'] = $this->parsingCss
->ConvertToMM($background['posX'], $this->pdf
->getW() - $imageWidth);
2330 $background['posY'] = $this->parsingCss
->ConvertToMM($background['posY'], $this->pdf
->getH() - $imageHeight);
2332 $background = array();
2335 $background = array();
2339 // margins of the page
2340 $background['top'] = isset($param['backtop']) ?
$param['backtop'] : '0';
2341 $background['bottom'] = isset($param['backbottom']) ?
$param['backbottom'] : '0';
2342 $background['left'] = isset($param['backleft']) ?
$param['backleft'] : '0';
2343 $background['right'] = isset($param['backright']) ?
$param['backright'] : '0';
2346 if (preg_match('/^([0-9]*)$/isU', $background['top'])) $background['top'] .= 'mm';
2347 if (preg_match('/^([0-9]*)$/isU', $background['bottom'])) $background['bottom'] .= 'mm';
2348 if (preg_match('/^([0-9]*)$/isU', $background['left'])) $background['left'] .= 'mm';
2349 if (preg_match('/^([0-9]*)$/isU', $background['right'])) $background['right'] .= 'mm';
2352 $background['top'] = $this->parsingCss
->ConvertToMM($background['top'], $this->pdf
->getH());
2353 $background['bottom'] = $this->parsingCss
->ConvertToMM($background['bottom'], $this->pdf
->getH());
2354 $background['left'] = $this->parsingCss
->ConvertToMM($background['left'], $this->pdf
->getW());
2355 $background['right'] = $this->parsingCss
->ConvertToMM($background['right'], $this->pdf
->getW());
2357 // get the background color
2359 $background['color'] = isset($param['backcolor']) ?
$this->parsingCss
->convertToColor($param['backcolor'], $res) : null;
2360 if (!$res) $background['color'] = null;
2362 $this->parsingCss
->save();
2363 $this->parsingCss
->analyse('PAGE', $param);
2364 $this->parsingCss
->setPosition();
2365 $this->parsingCss
->fontSet();
2368 $this->_setNewPage($format, $orientation, $background, null, $resetPageNumber);
2371 if (isset($param['footer'])) {
2372 $lst = explode(';', $param['footer']);
2373 foreach ($lst as $key => $val) $lst[$key] = trim(strtolower($val));
2374 $page = in_array('page', $lst);
2375 $date = in_array('date', $lst);
2376 $hour = in_array('heure', $lst);
2377 $form = in_array('form', $lst);
2384 $this->pdf
->SetMyFooter($page, $date, $hour, $form);
2385 // else => we use the last page set used
2387 $this->parsingCss
->save();
2388 $this->parsingCss
->analyse('PAGE', $param);
2389 $this->parsingCss
->setPosition();
2390 $this->parsingCss
->fontSet();
2392 $this->_setNewPage(null, null, null, null, $resetPageNumber);
2402 * @param array $param
2405 protected function _tag_close_PAGE($param)
2407 if ($this->_isForOneLine
) return false;
2411 $this->parsingCss
->load();
2412 $this->parsingCss
->fontSet();
2414 if ($this->_debugActif
) $this->_DEBUG_add('PAGE '.$this->_page
, false);
2423 * @param array $param
2426 protected function _tag_open_PAGE_HEADER($param)
2428 if ($this->_isForOneLine
) return false;
2430 $this->_subHEADER
= array();
2431 for ($this->_parsePos
; $this->_parsePos
<count($this->parsingHtml
->code
); $this->_parsePos++
) {
2432 $action = $this->parsingHtml
->code
[$this->_parsePos
];
2433 if ($action['name']=='page_header') $action['name']='page_header_sub';
2434 $this->_subHEADER
[] = $action;
2435 if (strtolower($action['name'])=='page_header_sub' && $action['close']) break;
2438 $this->_setPageHeader();
2447 * @param array $param
2450 protected function _tag_open_PAGE_FOOTER($param)
2452 if ($this->_isForOneLine
) return false;
2454 $this->_subFOOTER
= array();
2455 for ($this->_parsePos
; $this->_parsePos
<count($this->parsingHtml
->code
); $this->_parsePos++
) {
2456 $action = $this->parsingHtml
->code
[$this->_parsePos
];
2457 if ($action['name']=='page_footer') $action['name']='page_footer_sub';
2458 $this->_subFOOTER
[] = $action;
2459 if (strtolower($action['name'])=='page_footer_sub' && $action['close']) break;
2462 $this->_setPageFooter();
2468 * It is not a real tag. Does not use it directly
2470 * @param array $param
2473 protected function _tag_open_PAGE_HEADER_SUB($param)
2475 if ($this->_isForOneLine
) return false;
2477 // save the current stat
2478 $this->_subSTATES
= array();
2479 $this->_subSTATES
['x'] = $this->pdf
->getX();
2480 $this->_subSTATES
['y'] = $this->pdf
->getY();
2481 $this->_subSTATES
['s'] = $this->parsingCss
->value
;
2482 $this->_subSTATES
['t'] = $this->parsingCss
->table
;
2483 $this->_subSTATES
['ml'] = $this->_margeLeft
;
2484 $this->_subSTATES
['mr'] = $this->_margeRight
;
2485 $this->_subSTATES
['mt'] = $this->_margeTop
;
2486 $this->_subSTATES
['mb'] = $this->_margeBottom
;
2487 $this->_subSTATES
['mp'] = $this->_pageMarges
;
2489 // new stat for the header
2490 $this->_pageMarges
= array();
2491 $this->_margeLeft
= $this->_defaultLeft
;
2492 $this->_margeRight
= $this->_defaultRight
;
2493 $this->_margeTop
= $this->_defaultTop
;
2494 $this->_margeBottom
= $this->_defaultBottom
;
2495 $this->pdf
->SetMargins($this->_margeLeft
, $this->_margeTop
, $this->_margeRight
);
2496 $this->pdf
->SetAutoPageBreak(false, $this->_margeBottom
);
2497 $this->pdf
->setXY($this->_defaultLeft
, $this->_defaultTop
);
2499 $this->parsingCss
->initStyle();
2500 $this->parsingCss
->resetStyle();
2501 $this->parsingCss
->value
['width'] = $this->pdf
->getW() - $this->_defaultLeft
- $this->_defaultRight
;
2502 $this->parsingCss
->table
= array();
2504 $this->parsingCss
->save();
2505 $this->parsingCss
->analyse('page_header_sub', $param);
2506 $this->parsingCss
->setPosition();
2507 $this->parsingCss
->fontSet();
2508 $this->_setNewPositionForNewLine();
2513 * It is not a real tag. Does not use it directly
2515 * @param array $param
2518 protected function _tag_close_PAGE_HEADER_SUB($param)
2520 if ($this->_isForOneLine
) return false;
2522 $this->parsingCss
->load();
2525 $this->parsingCss
->value
= $this->_subSTATES
['s'];
2526 $this->parsingCss
->table
= $this->_subSTATES
['t'];
2527 $this->_pageMarges
= $this->_subSTATES
['mp'];
2528 $this->_margeLeft
= $this->_subSTATES
['ml'];
2529 $this->_margeRight
= $this->_subSTATES
['mr'];
2530 $this->_margeTop
= $this->_subSTATES
['mt'];
2531 $this->_margeBottom
= $this->_subSTATES
['mb'];
2532 $this->pdf
->SetMargins($this->_margeLeft
, $this->_margeTop
, $this->_margeRight
);
2533 $this->pdf
->setbMargin($this->_margeBottom
);
2534 $this->pdf
->SetAutoPageBreak(false, $this->_margeBottom
);
2535 $this->pdf
->setXY($this->_subSTATES
['x'], $this->_subSTATES
['y']);
2537 $this->parsingCss
->fontSet();
2544 * It is not a real tag. Does not use it directly
2546 * @param array $param
2549 protected function _tag_open_PAGE_FOOTER_SUB($param)
2551 if ($this->_isForOneLine
) return false;
2553 // save the current stat
2554 $this->_subSTATES
= array();
2555 $this->_subSTATES
['x'] = $this->pdf
->getX();
2556 $this->_subSTATES
['y'] = $this->pdf
->getY();
2557 $this->_subSTATES
['s'] = $this->parsingCss
->value
;
2558 $this->_subSTATES
['t'] = $this->parsingCss
->table
;
2559 $this->_subSTATES
['ml'] = $this->_margeLeft
;
2560 $this->_subSTATES
['mr'] = $this->_margeRight
;
2561 $this->_subSTATES
['mt'] = $this->_margeTop
;
2562 $this->_subSTATES
['mb'] = $this->_margeBottom
;
2563 $this->_subSTATES
['mp'] = $this->_pageMarges
;
2565 // new stat for the footer
2566 $this->_pageMarges
= array();
2567 $this->_margeLeft
= $this->_defaultLeft
;
2568 $this->_margeRight
= $this->_defaultRight
;
2569 $this->_margeTop
= $this->_defaultTop
;
2570 $this->_margeBottom
= $this->_defaultBottom
;
2571 $this->pdf
->SetMargins($this->_margeLeft
, $this->_margeTop
, $this->_margeRight
);
2572 $this->pdf
->SetAutoPageBreak(false, $this->_margeBottom
);
2573 $this->pdf
->setXY($this->_defaultLeft
, $this->_defaultTop
);
2575 $this->parsingCss
->initStyle();
2576 $this->parsingCss
->resetStyle();
2577 $this->parsingCss
->value
['width'] = $this->pdf
->getW() - $this->_defaultLeft
- $this->_defaultRight
;
2578 $this->parsingCss
->table
= array();
2580 // we create a sub HTML2PFDF, and we execute on it the content of the footer, to get the height of it
2582 $this->_createSubHTML($sub);
2583 $sub->parsingHtml
->code
= $this->parsingHtml
->getLevel($this->_parsePos
);
2584 $sub->_makeHTMLcode();
2585 $this->pdf
->setY($this->pdf
->getH() - $sub->_maxY
- $this->_defaultBottom
- 0.01);
2586 $this->_destroySubHTML($sub);
2588 $this->parsingCss
->save();
2589 $this->parsingCss
->analyse('page_footer_sub', $param);
2590 $this->parsingCss
->setPosition();
2591 $this->parsingCss
->fontSet();
2592 $this->_setNewPositionForNewLine();
2598 * It is not a real tag. Do not use it directly
2600 * @param array $param
2603 protected function _tag_close_PAGE_FOOTER_SUB($param)
2605 if ($this->_isForOneLine
) return false;
2607 $this->parsingCss
->load();
2609 $this->parsingCss
->value
= $this->_subSTATES
['s'];
2610 $this->parsingCss
->table
= $this->_subSTATES
['t'];
2611 $this->_pageMarges
= $this->_subSTATES
['mp'];
2612 $this->_margeLeft
= $this->_subSTATES
['ml'];
2613 $this->_margeRight
= $this->_subSTATES
['mr'];
2614 $this->_margeTop
= $this->_subSTATES
['mt'];
2615 $this->_margeBottom
= $this->_subSTATES
['mb'];
2616 $this->pdf
->SetMargins($this->_margeLeft
, $this->_margeTop
, $this->_margeRight
);
2617 $this->pdf
->SetAutoPageBreak(false, $this->_margeBottom
);
2618 $this->pdf
->setXY($this->_subSTATES
['x'], $this->_subSTATES
['y']);
2620 $this->parsingCss
->fontSet();
2630 * @param array $param
2633 protected function _tag_open_NOBREAK($param)
2635 if ($this->_isForOneLine
) return false;
2639 // create a sub HTML2PDF to execute the content of the tag, to get the dimensions
2641 $this->_createSubHTML($sub);
2642 $sub->parsingHtml
->code
= $this->parsingHtml
->getLevel($this->_parsePos
);
2643 $sub->_makeHTMLcode();
2644 $y = $this->pdf
->getY();
2646 // if the content does not fit on the page => new page
2648 $sub->_maxY
< ($this->pdf
->getH() - $this->pdf
->gettMargin()-$this->pdf
->getbMargin()) &&
2649 $y +
$sub->_maxY
>=($this->pdf
->getH() - $this->pdf
->getbMargin())
2651 $this->_setNewPage();
2654 // destroy the sub HTML2PDF
2655 $this->_destroySubHTML($sub);
2665 * @param array $param
2668 protected function _tag_close_NOBREAK($param)
2670 if ($this->_isForOneLine
) return false;
2681 * @param array $param
2682 * @param string $other name of tag that used the div tag
2685 protected function _tag_open_DIV($param, $other = 'div')
2687 if ($this->_isForOneLine
) return false;
2688 if ($this->_debugActif
) $this->_DEBUG_add(strtoupper($other), true);
2690 $this->parsingCss
->save();
2691 $this->parsingCss
->analyse($other, $param);
2692 $this->parsingCss
->fontSet();
2694 // for fieldset and legend
2695 if (in_array($other, array('fieldset', 'legend'))) {
2696 if (isset($param['moveTop'])) $this->parsingCss
->value
['margin']['t'] +
= $param['moveTop'];
2697 if (isset($param['moveLeft'])) $this->parsingCss
->value
['margin']['l'] +
= $param['moveLeft'];
2698 if (isset($param['moveDown'])) $this->parsingCss
->value
['margin']['b'] +
= $param['moveDown'];
2701 $alignObject = null;
2702 if ($this->parsingCss
->value
['margin-auto']) $alignObject = 'center';
2705 $marge['l'] = $this->parsingCss
->value
['border']['l']['width'] +
$this->parsingCss
->value
['padding']['l']+
0.03;
2706 $marge['r'] = $this->parsingCss
->value
['border']['r']['width'] +
$this->parsingCss
->value
['padding']['r']+
0.03;
2707 $marge['t'] = $this->parsingCss
->value
['border']['t']['width'] +
$this->parsingCss
->value
['padding']['t']+
0.03;
2708 $marge['b'] = $this->parsingCss
->value
['border']['b']['width'] +
$this->parsingCss
->value
['padding']['b']+
0.03;
2710 // extract the content of the div
2711 $level = $this->parsingHtml
->getLevel($this->_parsePos
);
2713 // create a sub HTML2PDF to get the dimensions of the content of the div
2715 if (count($level)) {
2717 $this->_createSubHTML($sub);
2718 $sub->parsingHtml
->code
= $level;
2719 $sub->_makeHTMLcode();
2722 $this->_destroySubHTML($sub);
2727 $w+
= $marge['l']+
$marge['r']+
0.001;
2728 $h+
= $marge['t']+
$marge['b']+
0.001;
2730 if ($this->parsingCss
->value
['overflow']=='hidden') {
2731 $overW = max($w, $this->parsingCss
->value
['width']);
2732 $overH = max($h, $this->parsingCss
->value
['height']);
2734 $this->parsingCss
->value
['old_maxX'] = $this->_maxX
;
2735 $this->parsingCss
->value
['old_maxY'] = $this->_maxY
;
2736 $this->parsingCss
->value
['old_maxH'] = $this->_maxH
;
2737 $this->parsingCss
->value
['old_overflow'] = $this->_isInOverflow
;
2738 $this->_isInOverflow
= true;
2743 $this->parsingCss
->value
['width'] = max($w, $this->parsingCss
->value
['width']);
2744 $this->parsingCss
->value
['height'] = max($h, $this->parsingCss
->value
['height']);
2747 switch($this->parsingCss
->value
['rotate'])
2750 $tmp = $overH; $overH = $overW; $overW = $tmp;
2751 $tmp = $hReel; $hReel = $wReel; $wReel = $tmp;
2753 $w = $this->parsingCss
->value
['height'];
2754 $h = $this->parsingCss
->value
['width'];
2760 $w = $this->parsingCss
->value
['width'];
2761 $h = $this->parsingCss
->value
['height'];
2767 $tmp = $overH; $overH = $overW; $overW = $tmp;
2768 $tmp = $hReel; $hReel = $wReel; $wReel = $tmp;
2770 $w = $this->parsingCss
->value
['height'];
2771 $h = $this->parsingCss
->value
['width'];
2777 $w = $this->parsingCss
->value
['width'];
2778 $h = $this->parsingCss
->value
['height'];
2784 if (!$this->parsingCss
->value
['position']) {
2786 $w < ($this->pdf
->getW() - $this->pdf
->getlMargin()-$this->pdf
->getrMargin()) &&
2787 $this->pdf
->getX() +
$w>=($this->pdf
->getW() - $this->pdf
->getrMargin())
2789 $this->_tag_open_BR(array());
2792 ($h < ($this->pdf
->getH() - $this->pdf
->gettMargin()-$this->pdf
->getbMargin())) &&
2793 ($this->pdf
->getY() +
$h>=($this->pdf
->getH() - $this->pdf
->getbMargin())) &&
2794 !$this->_isInOverflow
2796 $this->_setNewPage();
2798 $old = $this->parsingCss
->getOldValues();
2799 $parentWidth = $old['width'] ?
$old['width'] : $this->pdf
->getW() - $this->pdf
->getlMargin() - $this->pdf
->getrMargin();
2801 if ($parentWidth>$w) {
2802 if ($alignObject=='center') $this->pdf
->setX($this->pdf
->getX() +
($parentWidth-$w)*0.5);
2803 else if ($alignObject=='right') $this->pdf
->setX($this->pdf
->getX() +
$parentWidth-$w);
2806 $this->parsingCss
->setPosition();
2808 $old = $this->parsingCss
->getOldValues();
2809 $parentWidth = $old['width'] ?
$old['width'] : $this->pdf
->getW() - $this->pdf
->getlMargin() - $this->pdf
->getrMargin();
2811 if ($parentWidth>$w) {
2812 if ($alignObject=='center') $this->pdf
->setX($this->pdf
->getX() +
($parentWidth-$w)*0.5);
2813 else if ($alignObject=='right') $this->pdf
->setX($this->pdf
->getX() +
$parentWidth-$w);
2816 $this->parsingCss
->setPosition();
2824 if ($this->parsingCss
->value
['rotate']) {
2825 $this->pdf
->startTransform();
2826 $this->pdf
->setRotation($this->parsingCss
->value
['rotate']);
2827 $this->pdf
->setTranslate($tX, $tY);
2830 $this->_drawRectangle(
2831 $this->parsingCss
->value
['x'],
2832 $this->parsingCss
->value
['y'],
2833 $this->parsingCss
->value
['width'],
2834 $this->parsingCss
->value
['height'],
2835 $this->parsingCss
->value
['border'],
2836 $this->parsingCss
->value
['padding'],
2838 $this->parsingCss
->value
['background']
2842 $marge['l'] = $this->parsingCss
->value
['border']['l']['width'] +
$this->parsingCss
->value
['padding']['l']+
0.03;
2843 $marge['r'] = $this->parsingCss
->value
['border']['r']['width'] +
$this->parsingCss
->value
['padding']['r']+
0.03;
2844 $marge['t'] = $this->parsingCss
->value
['border']['t']['width'] +
$this->parsingCss
->value
['padding']['t']+
0.03;
2845 $marge['b'] = $this->parsingCss
->value
['border']['b']['width'] +
$this->parsingCss
->value
['padding']['b']+
0.03;
2847 $this->parsingCss
->value
['width'] -= $marge['l']+
$marge['r'];
2848 $this->parsingCss
->value
['height']-= $marge['t']+
$marge['b'];
2852 if (!$this->_subPart
&& !$this->_isSubPart
) {
2853 switch($this->parsingCss
->value
['text-align'])
2856 $xCorr = ($this->parsingCss
->value
['width']-$wReel);
2859 $xCorr = ($this->parsingCss
->value
['width']-$wReel)*0.5;
2862 if ($xCorr>0) $xCorr=0;
2863 switch($this->parsingCss
->value
['vertical-align'])
2866 $yCorr = ($this->parsingCss
->value
['height']-$hReel);
2869 $yCorr = ($this->parsingCss
->value
['height']-$hReel)*0.5;
2875 $overW-= $marge['l']+
$marge['r'];
2876 $overH-= $marge['t']+
$marge['b'];
2877 $this->pdf
->clippingPathStart(
2878 $this->parsingCss
->value
['x']+
$marge['l'],
2879 $this->parsingCss
->value
['y']+
$marge['t'],
2880 $this->parsingCss
->value
['width'],
2881 $this->parsingCss
->value
['height']
2884 $this->parsingCss
->value
['x']+
= $xCorr;
2886 // marges from the dimension of the content
2887 $mL = $this->parsingCss
->value
['x']+
$marge['l'];
2888 $mR = $this->pdf
->getW() - $mL - $overW;
2890 // marges from the dimension of the div
2891 $mL = $this->parsingCss
->value
['x']+
$marge['l'];
2892 $mR = $this->pdf
->getW() - $mL - $this->parsingCss
->value
['width'];
2895 $x = $this->parsingCss
->value
['x']+
$marge['l'];
2896 $y = $this->parsingCss
->value
['y']+
$marge['t']+
$yCorr;
2897 $this->_saveMargin($mL, 0, $mR);
2898 $this->pdf
->setXY($x, $y);
2900 $this->_setNewPositionForNewLine();
2909 * @param array $param
2912 protected function _tag_open_BLOCKQUOTE($param)
2914 return $this->_tag_open_DIV($param, 'blockquote');
2921 * @param array $param
2924 protected function _tag_open_LEGEND($param)
2926 return $this->_tag_open_DIV($param, 'legend');
2933 * @author Pavel Kochman
2934 * @param array $param
2937 protected function _tag_open_FIELDSET($param)
2940 $this->parsingCss
->save();
2941 $this->parsingCss
->analyse('fieldset', $param);
2943 // get height of LEGEND element and make fieldset corrections
2944 for ($tempPos = $this->_parsePos +
1; $tempPos<count($this->parsingHtml
->code
); $tempPos++
) {
2945 $action = $this->parsingHtml
->code
[$tempPos];
2946 if ($action['name'] == 'fieldset') break;
2947 if ($action['name'] == 'legend' && !$action['close']) {
2948 $legendOpenPos = $tempPos;
2951 $this->_createSubHTML($sub);
2952 $sub->parsingHtml
->code
= $this->parsingHtml
->getLevel($tempPos - 1);
2955 for ($sub->_parsePos
= 0; $sub->_parsePos
<count($sub->parsingHtml
->code
); $sub->_parsePos++
) {
2956 $action = $sub->parsingHtml
->code
[$sub->_parsePos
];
2957 $sub->_executeAction($action);
2959 if ($action['name'] == 'legend' && $action['close'])
2963 $legendH = $sub->_maxY
;
2964 $this->_destroySubHTML($sub);
2966 $move = $this->parsingCss
->value
['padding']['t'] +
$this->parsingCss
->value
['border']['t']['width'] +
0.03;
2968 $param['moveTop'] = $legendH / 2;
2970 $this->parsingHtml
->code
[$legendOpenPos]['param']['moveTop'] = - ($legendH / 2 +
$move);
2971 $this->parsingHtml
->code
[$legendOpenPos]['param']['moveLeft'] = 2 - $this->parsingCss
->value
['border']['l']['width'] - $this->parsingCss
->value
['padding']['l'];
2972 $this->parsingHtml
->code
[$legendOpenPos]['param']['moveDown'] = $move;
2976 $this->parsingCss
->load();
2978 return $this->_tag_open_DIV($param, 'fieldset');
2985 * @param array $param
2986 * @param string $other name of tag that used the div tag
2989 protected function _tag_close_DIV($param, $other='div')
2991 if ($this->_isForOneLine
) return false;
2993 if ($this->parsingCss
->value
['overflow']=='hidden') {
2994 $this->_maxX
= $this->parsingCss
->value
['old_maxX'];
2995 $this->_maxY
= $this->parsingCss
->value
['old_maxY'];
2996 $this->_maxH
= $this->parsingCss
->value
['old_maxH'];
2997 $this->_isInOverflow
= $this->parsingCss
->value
['old_overflow'];
2998 $this->pdf
->clippingPathStop();
3001 if ($this->parsingCss
->value
['rotate'])
3002 $this->pdf
->stopTransform();
3005 $marge['l'] = $this->parsingCss
->value
['border']['l']['width'] +
$this->parsingCss
->value
['padding']['l']+
0.03;
3006 $marge['r'] = $this->parsingCss
->value
['border']['r']['width'] +
$this->parsingCss
->value
['padding']['r']+
0.03;
3007 $marge['t'] = $this->parsingCss
->value
['border']['t']['width'] +
$this->parsingCss
->value
['padding']['t']+
0.03;
3008 $marge['b'] = $this->parsingCss
->value
['border']['b']['width'] +
$this->parsingCss
->value
['padding']['b']+
0.03;
3010 $x = $this->parsingCss
->value
['x'];
3011 $y = $this->parsingCss
->value
['y'];
3012 $w = $this->parsingCss
->value
['width']+
$marge['l']+
$marge['r']+
$this->parsingCss
->value
['margin']['r'];
3013 $h = $this->parsingCss
->value
['height']+
$marge['t']+
$marge['b']+
$this->parsingCss
->value
['margin']['b'];
3015 switch($this->parsingCss
->value
['rotate'])
3018 $t = $w; $w = $h; $h = $t;
3022 $t = $w; $w = $h; $h = $t;
3030 if ($this->parsingCss
->value
['position']!='absolute') {
3031 $this->pdf
->setXY($x+
$w, $y);
3033 $this->_maxX
= max($this->_maxX
, $x+
$w);
3034 $this->_maxY
= max($this->_maxY
, $y+
$h);
3035 $this->_maxH
= max($this->_maxH
, $h);
3037 $this->pdf
->setXY($this->parsingCss
->value
['xc'], $this->parsingCss
->value
['yc']);
3042 $block = ($this->parsingCss
->value
['display']!='inline' && $this->parsingCss
->value
['position']!='absolute');
3044 $this->parsingCss
->load();
3045 $this->parsingCss
->fontSet();
3046 $this->_loadMargin();
3048 if ($block) $this->_tag_open_BR(array());
3049 if ($this->_debugActif
) $this->_DEBUG_add(strtoupper($other), false);
3058 * @param array $param
3061 protected function _tag_close_BLOCKQUOTE($param)
3063 return $this->_tag_close_DIV($param, 'blockquote');
3070 * @param array $param
3073 protected function _tag_close_FIELDSET($param)
3075 return $this->_tag_close_DIV($param, 'fieldset');
3082 * @param array $param
3085 protected function _tag_close_LEGEND($param)
3087 return $this->_tag_close_DIV($param, 'legend');
3094 * @param array $param
3097 protected function _tag_open_BARCODE($param)
3099 // for compatibility with old versions < 3.29
3100 $lstBarcode = array();
3101 $lstBarcode['UPC_A'] = 'UPCA';
3102 $lstBarcode['CODE39'] = 'C39';
3104 if (!isset($param['type'])) $param['type'] = 'C39';
3105 if (!isset($param['value'])) $param['value'] = 0;
3106 if (!isset($param['label'])) $param['label'] = 'label';
3107 if (!isset($param['style']['color'])) $param['style']['color'] = '#000000';
3109 if ($this->_testIsDeprecated
&& (isset($param['bar_h']) ||
isset($param['bar_w'])))
3110 throw new HTML2PDF_exception(9, array('BARCODE', 'bar_h, bar_w'));
3112 $param['type'] = strtoupper($param['type']);
3113 if (isset($lstBarcode[$param['type']])) $param['type'] = $lstBarcode[$param['type']];
3115 $this->parsingCss
->save();
3116 $this->parsingCss
->analyse('barcode', $param);
3117 $this->parsingCss
->setPosition();
3118 $this->parsingCss
->fontSet();
3120 $x = $this->pdf
->getX();
3121 $y = $this->pdf
->getY();
3122 $w = $this->parsingCss
->value
['width']; if (!$w) $w = $this->parsingCss
->ConvertToMM('50mm');
3123 $h = $this->parsingCss
->value
['height']; if (!$h) $h = $this->parsingCss
->ConvertToMM('10mm');
3124 $txt = ($param['label']!=='none' ?
$this->parsingCss
->value
['font-size'] : false);
3125 $c = $this->parsingCss
->value
['color'];
3126 $infos = $this->pdf
->myBarcode($param['value'], $param['type'], $x, $y, $w, $h, $txt, $c);
3128 $this->_maxX
= max($this->_maxX
, $x+
$infos[0]);
3129 $this->_maxY
= max($this->_maxY
, $y+
$infos[1]);
3130 $this->_maxH
= max($this->_maxH
, $infos[1]);
3133 $this->pdf
->setXY($x+
$infos[0], $y);
3135 $this->parsingCss
->load();
3136 $this->parsingCss
->fontSet();
3145 * @param array $param
3148 protected function _tag_close_BARCODE($param)
3150 // there is nothing to do here
3159 * @param array $param
3162 protected function _tag_open_QRCODE($param)
3164 if ($this->_testIsDeprecated
&& (isset($param['size']) ||
isset($param['noborder'])))
3165 throw new HTML2PDF_exception(9, array('QRCODE', 'size, noborder'));
3167 if ($this->_debugActif
) $this->_DEBUG_add('QRCODE');
3169 if (!isset($param['value'])) $param['value'] = '';
3170 if (!isset($param['ec'])) $param['ec'] = 'H';
3171 if (!isset($param['style']['color'])) $param['style']['color'] = '#000000';
3172 if (!isset($param['style']['background-color'])) $param['style']['background-color'] = '#FFFFFF';
3173 if (isset($param['style']['border'])) {
3174 $borders = $param['style']['border']!='none';
3175 unset($param['style']['border']);
3180 if ($param['value']==='') return true;
3181 if (!in_array($param['ec'], array('L', 'M', 'Q', 'H'))) $param['ec'] = 'H';
3183 $this->parsingCss
->save();
3184 $this->parsingCss
->analyse('qrcode', $param);
3185 $this->parsingCss
->setPosition();
3186 $this->parsingCss
->fontSet();
3188 $x = $this->pdf
->getX();
3189 $y = $this->pdf
->getY();
3190 $w = $this->parsingCss
->value
['width'];
3191 $h = $this->parsingCss
->value
['height'];
3192 $size = max($w, $h); if (!$size) $size = $this->parsingCss
->ConvertToMM('50mm');
3195 'fgcolor' => $this->parsingCss
->value
['color'],
3196 'bgcolor' => $this->parsingCss
->value
['background']['color'],
3200 $style['border'] = true;
3201 $style['padding'] = 'auto';
3203 $style['border'] = false;
3204 $style['padding'] = 0;
3207 if (!$this->_subPart
&& !$this->_isSubPart
) {
3208 $this->pdf
->write2DBarcode($param['value'], 'QRCODE,'.$param['ec'], $x, $y, $size, $size, $style);
3211 $this->_maxX
= max($this->_maxX
, $x+
$size);
3212 $this->_maxY
= max($this->_maxY
, $y+
$size);
3213 $this->_maxH
= max($this->_maxH
, $size);
3216 $this->pdf
->setX($x+
$size);
3218 $this->parsingCss
->load();
3219 $this->parsingCss
->fontSet();
3228 * @param array $param
3231 protected function _tag_close_QRCODE($param)
3233 // there is nothing to do here
3242 * @param array $param
3245 protected function _tag_open_BOOKMARK($param)
3247 $titre = isset($param['title']) ?
trim($param['title']) : '';
3248 $level = isset($param['level']) ?
floor($param['level']) : 0;
3250 if ($level<0) $level = 0;
3251 if ($titre) $this->pdf
->Bookmark($titre, $level, -1);
3260 * @param array $param
3263 protected function _tag_close_BOOKMARK($param)
3265 // there is nothing to do here
3271 * this is not a real TAG, it is just to write texts
3273 * @param array $param
3276 protected function _tag_open_WRITE($param)
3278 $fill = ($this->parsingCss
->value
['background']['color']!==null && $this->parsingCss
->value
['background']['image']===null);
3279 if (in_array($this->parsingCss
->value
['id_tag'], array('fieldset', 'legend', 'div', 'table', 'tr', 'td', 'th'))) {
3283 // get the text to write
3284 $txt = $param['txt'];
3286 if ($this->_isAfterFloat
) {
3288 $this->_isAfterFloat
= false;
3291 $txt = str_replace('[[page_nb]]', $this->pdf
->getMyAliasNbPages(), $txt);
3292 $txt = str_replace('[[page_cu]]', $this->pdf
->getMyNumPage($this->_page
), $txt);
3294 if ($this->parsingCss
->value
['text-transform']!='none') {
3295 if ($this->parsingCss
->value
['text-transform']=='capitalize')
3296 $txt = mb_convert_case($txt, MB_CASE_TITLE
, $this->_encoding
);
3297 else if ($this->parsingCss
->value
['text-transform']=='uppercase')
3298 $txt = mb_convert_case($txt, MB_CASE_UPPER
, $this->_encoding
);
3299 else if ($this->parsingCss
->value
['text-transform']=='lowercase')
3300 $txt = mb_convert_case($txt, MB_CASE_LOWER
, $this->_encoding
);
3304 $h = 1.08*$this->parsingCss
->value
['font-size'];
3305 $dh = $h*$this->parsingCss
->value
['mini-decal'];
3306 $lh = $this->parsingCss
->getLineHeight();
3308 // identify the align
3310 if ($this->parsingCss
->value
['text-align']=='li_right') {
3311 $w = $this->parsingCss
->value
['width'];
3315 // calculate the width of each words, and of all the sentence
3317 $words = explode(' ', $txt);
3318 foreach ($words as $k => $word) {
3319 $words[$k] = array($word, $this->pdf
->GetStringWidth($word));
3322 $space = $this->pdf
->GetStringWidth(' ');
3323 $w+
= $space*(count($words)-1);
3325 // position in the text
3328 // the bigger width of the text, after automatic break line
3331 // position of the text
3332 $x = $this->pdf
->getX();
3333 $y = $this->pdf
->getY();
3334 $dy = $this->_getElementY($lh);
3337 list($left, $right) = $this->_getMargins($y);
3339 // number of lines after automatic break line
3342 // while we have words, and the text does not fit on the line => we cut the sentence
3343 while ($x+
$w>$right && $x<$right+
$space && count($words)) {
3344 // adding words 1 by 1 to fit on the line
3346 $old = array('', 0);
3349 while (($x+
$str[1])<$right) {
3353 array_shift($words);
3356 if (!count($words)) break;
3357 $str[0].= ' '.$words[0][0];
3358 $str[1]+
= $space+
$words[0][1];
3362 // if nothing fits on the line, and if the first word does not fit on the line => the word is too long, we put it
3363 if ($i==0 && (($left+
$words[0][1])>=$right)) {
3365 array_shift($words);
3369 $currPos+
= ($currPos ?
1 : 0)+
strlen($str[0]);
3371 // write the extract sentence that fit on the page
3372 $wc = ($align=='L' ?
$str[1] : $this->parsingCss
->value
['width']);
3373 if ($right - $left<$wc) $wc = $right - $left;
3375 if (strlen($str[0])) {
3376 $this->pdf
->setXY($this->pdf
->getX(), $y+
$dh+
$dy);
3377 $this->pdf
->Cell($wc, $h, $str[0], 0, 0, $align, $fill, $this->_isInLink
);
3378 $this->pdf
->setXY($this->pdf
->getX(), $y);
3380 $this->_maxH
= max($this->_maxH
, $lh);
3383 $maxX = max($maxX, $this->pdf
->getX());
3385 // new position and new width for the "while"
3387 $y = $this->pdf
->getY();
3388 $x = $this->pdf
->getX();
3389 $dy = $this->_getElementY($lh);
3391 // if we have again words to write
3392 if (count($words)) {
3393 // remove the space at the end
3394 if ($add) $w-= $space;
3396 // if we don't add any word, and if the first word is empty => useless space to skip
3397 if (!$add && $words[0][0]==='') {
3398 array_shift($words);
3401 // if it is just to calculate for one line => adding the number of words
3402 if ($this->_isForOneLine
) {
3404 $this->_maxX
= max($this->_maxX
, $maxX);
3408 // automatic line break
3409 $this->_tag_open_BR(array('style' => ''), $currPos);
3412 $y = $this->pdf
->getY();
3413 $x = $this->pdf
->getX();
3414 $dy = $this->_getElementY($lh);
3416 // if the next line does not fit on the page => new page
3417 if ($y +
$h>=$this->pdf
->getH() - $this->pdf
->getbMargin()) {
3418 if (!$this->_isInOverflow
&& !$this->_isInFooter
) {
3419 $this->_setNewPage(null, '', null, $currPos);
3420 $y = $this->pdf
->getY();
3421 $x = $this->pdf
->getX();
3422 $dy = $this->_getElementY($lh);
3426 // if more than 10000 line => error
3429 $txt = ''; foreach ($words as $k => $word) $txt.= ($k ?
' ' : '').$word[0];
3430 throw new HTML2PDF_exception(2, array($txt, $right-$left, $w));
3433 // new margins for the new line
3434 list($left, $right) = $this->_getMargins($y);
3438 // if we have words after automatic cut, it is because they fit on the line => we write the text
3439 if (count($words)) {
3440 $txt = ''; foreach ($words as $k => $word) $txt.= ($k ?
' ' : '').$word[0];
3441 $w+
= $this->pdf
->getWordSpacing()*(count($words));
3442 $this->pdf
->setXY($this->pdf
->getX(), $y+
$dh+
$dy);
3443 $this->pdf
->Cell(($align=='L' ?
$w : $this->parsingCss
->value
['width']), $h, $txt, 0, 0, $align, $fill, $this->_isInLink
);
3444 $this->pdf
->setXY($this->pdf
->getX(), $y);
3445 $this->_maxH
= max($this->_maxH
, $lh);
3446 $this->_maxE+
= count($words);
3449 $maxX = max($maxX, $this->pdf
->getX());
3450 $maxY = $this->pdf
->getY()+
$h;
3452 $this->_maxX
= max($this->_maxX
, $maxX);
3453 $this->_maxY
= max($this->_maxY
, $maxY);
3462 * @param array $param
3463 * @param integer $curr real position in the html parseur (if break line in the write of a text)
3466 protected function _tag_open_BR($param, $curr = null)
3468 if ($this->_isForOneLine
) return false;
3470 $h = max($this->_maxH
, $this->parsingCss
->getLineHeight());
3472 if ($this->_maxH
==0) $this->_maxY
= max($this->_maxY
, $this->pdf
->getY()+
$h);
3474 $this->_makeBreakLine($h, $curr);
3486 * @param array $param
3489 protected function _tag_open_HR($param)
3491 if ($this->_isForOneLine
) return false;
3492 $oldAlign = $this->parsingCss
->value
['text-align'];
3493 $this->parsingCss
->value
['text-align'] = 'left';
3495 if ($this->_maxH
) $this->_tag_open_BR($param);
3497 $fontSize = $this->parsingCss
->value
['font-size'];
3498 $this->parsingCss
->value
['font-size']=$fontSize*0.5;
3499 $this->_tag_open_BR($param);
3500 $this->parsingCss
->value
['font-size']=$fontSize;
3502 $param['style']['width'] = '100%';
3504 $this->parsingCss
->save();
3505 $this->parsingCss
->value
['height']=$this->parsingCss
->ConvertToMM('1mm');
3507 $this->parsingCss
->analyse('hr', $param);
3508 $this->parsingCss
->setPosition();
3509 $this->parsingCss
->fontSet();
3511 $h = $this->parsingCss
->value
['height'];
3512 if ($h) $h-= $this->parsingCss
->value
['border']['t']['width']+
$this->parsingCss
->value
['border']['b']['width'];
3513 if ($h<=0) $h = $this->parsingCss
->value
['border']['t']['width']+
$this->parsingCss
->value
['border']['b']['width'];
3515 $this->_drawRectangle($this->pdf
->getX(), $this->pdf
->getY(), $this->parsingCss
->value
['width'], $h, $this->parsingCss
->value
['border'], 0, 0, $this->parsingCss
->value
['background']);
3518 $this->parsingCss
->load();
3519 $this->parsingCss
->fontSet();
3521 $this->parsingCss
->value
['font-size'] = 0;
3522 $this->_tag_open_BR($param);
3524 $this->parsingCss
->value
['font-size']=$fontSize*0.5; $this->_tag_open_BR($param);
3525 $this->parsingCss
->value
['font-size']=$fontSize;
3527 $this->parsingCss
->value
['text-align'] = $oldAlign;
3528 $this->_setNewPositionForNewLine();
3537 * @param array $param
3538 * @param string $other
3541 protected function _tag_open_B($param, $other = 'b')
3543 $this->parsingCss
->save();
3544 $this->parsingCss
->value
['font-bold'] = true;
3545 $this->parsingCss
->analyse($other, $param);
3546 $this->parsingCss
->setPosition();
3547 $this->parsingCss
->fontSet();
3556 * @param array $param
3559 protected function _tag_open_STRONG($param)
3561 return $this->_tag_open_B($param, 'strong');
3568 * @param array $param
3571 protected function _tag_close_B($param)
3573 $this->parsingCss
->load();
3574 $this->parsingCss
->fontSet();
3583 * @param array $param
3586 protected function _tag_close_STRONG($param)
3588 return $this->_tag_close_B($param);
3595 * @param array $param
3596 * @param string $other
3599 protected function _tag_open_I($param, $other = 'i')
3601 $this->parsingCss
->save();
3602 $this->parsingCss
->value
['font-italic'] = true;
3603 $this->parsingCss
->analyse($other, $param);
3604 $this->parsingCss
->setPosition();
3605 $this->parsingCss
->fontSet();
3614 * @param array $param
3617 protected function _tag_open_ADDRESS($param)
3619 return $this->_tag_open_I($param, 'address');
3626 * @param array $param
3629 protected function _tag_open_CITE($param)
3631 return $this->_tag_open_I($param, 'cite');
3638 * @param array $param
3641 protected function _tag_open_EM($param)
3643 return $this->_tag_open_I($param, 'em');
3650 * @param array $param
3653 protected function _tag_open_SAMP($param)
3655 return $this->_tag_open_I($param, 'samp');
3662 * @param array $param
3665 protected function _tag_close_I($param)
3667 $this->parsingCss
->load();
3668 $this->parsingCss
->fontSet();
3677 * @param array $param
3680 protected function _tag_close_ADDRESS($param)
3682 return $this->_tag_close_I($param);
3689 * @param array $param
3692 protected function _tag_close_CITE($param)
3694 return $this->_tag_close_I($param);
3701 * @param array $param
3704 protected function _tag_close_EM($param)
3706 return $this->_tag_close_I($param);
3713 * @param array $param
3716 protected function _tag_close_SAMP($param)
3718 return $this->_tag_close_I($param);
3725 * @param array $param
3726 * @param string $other
3729 protected function _tag_open_S($param, $other = 's')
3731 $this->parsingCss
->save();
3732 $this->parsingCss
->value
['font-linethrough'] = true;
3733 $this->parsingCss
->analyse($other, $param);
3734 $this->parsingCss
->setPosition();
3735 $this->parsingCss
->fontSet();
3744 * @param array $param
3747 protected function _tag_open_DEL($param)
3749 return $this->_tag_open_S($param, 'del');
3756 * @param array $param
3759 protected function _tag_close_S($param)
3761 $this->parsingCss
->load();
3762 $this->parsingCss
->fontSet();
3771 * @param array $param
3774 protected function _tag_close_DEL($param)
3776 return $this->_tag_close_S($param);
3783 * @param array $param
3784 * @param string $other
3787 protected function _tag_open_U($param, $other='u')
3789 $this->parsingCss
->save();
3790 $this->parsingCss
->value
['font-underline'] = true;
3791 $this->parsingCss
->analyse($other, $param);
3792 $this->parsingCss
->setPosition();
3793 $this->parsingCss
->fontSet();
3802 * @param array $param
3805 protected function _tag_open_INS($param)
3807 return $this->_tag_open_U($param, 'ins');
3814 * @param array $param
3817 protected function _tag_close_U($param)
3819 $this->parsingCss
->load();
3820 $this->parsingCss
->fontSet();
3829 * @param array $param
3832 protected function _tag_close_INS($param)
3834 return $this->_tag_close_U($param);
3841 * @param array $param
3844 protected function _tag_open_A($param)
3846 $this->_isInLink
= str_replace('&', '&', isset($param['href']) ?
$param['href'] : '');
3848 if (isset($param['name'])) {
3849 $name = $param['name'];
3850 if (!isset($this->_lstAnchor
[$name])) $this->_lstAnchor
[$name] = array($this->pdf
->AddLink(), false);
3852 if (!$this->_lstAnchor
[$name][1]) {
3853 $this->_lstAnchor
[$name][1] = true;
3854 $this->pdf
->SetLink($this->_lstAnchor
[$name][0], -1, -1);
3858 if (preg_match('/^#([^#]+)$/isU', $this->_isInLink
, $match)) {
3860 if (!isset($this->_lstAnchor
[$name])) $this->_lstAnchor
[$name] = array($this->pdf
->AddLink(), false);
3862 $this->_isInLink
= $this->_lstAnchor
[$name][0];
3865 $this->parsingCss
->save();
3866 $this->parsingCss
->value
['font-underline'] = true;
3867 $this->parsingCss
->value
['color'] = array(20, 20, 250);
3868 $this->parsingCss
->analyse('a', $param);
3869 $this->parsingCss
->setPosition();
3870 $this->parsingCss
->fontSet();
3879 * @param array $param
3882 protected function _tag_close_A($param)
3884 $this->_isInLink
= '';
3885 $this->parsingCss
->load();
3886 $this->parsingCss
->fontSet();
3895 * @param array $param
3896 * @param string $other
3899 protected function _tag_open_H1($param, $other = 'h1')
3901 if ($this->_isForOneLine
) return false;
3903 if ($this->_maxH
) $this->_tag_open_BR(array());
3904 $this->parsingCss
->save();
3905 $this->parsingCss
->value
['font-bold'] = true;
3907 $size = array('h1' => '28px', 'h2' => '24px', 'h3' => '20px', 'h4' => '16px', 'h5' => '12px', 'h6' => '9px');
3908 $this->parsingCss
->value
['margin']['l'] = 0;
3909 $this->parsingCss
->value
['margin']['r'] = 0;
3910 $this->parsingCss
->value
['margin']['t'] = $this->parsingCss
->ConvertToMM('16px');
3911 $this->parsingCss
->value
['margin']['b'] = $this->parsingCss
->ConvertToMM('16px');
3912 $this->parsingCss
->value
['font-size'] = $this->parsingCss
->ConvertToMM($size[$other]);
3914 $this->parsingCss
->analyse($other, $param);
3915 $this->parsingCss
->setPosition();
3916 $this->parsingCss
->fontSet();
3917 $this->_setNewPositionForNewLine();
3926 * @param array $param
3929 protected function _tag_open_H2($param)
3931 return $this->_tag_open_H1($param, 'h2');
3938 * @param array $param
3941 protected function _tag_open_H3($param)
3943 return $this->_tag_open_H1($param, 'h3');
3950 * @param array $param
3953 protected function _tag_open_H4($param)
3955 return $this->_tag_open_H1($param, 'h4');
3962 * @param array $param
3965 protected function _tag_open_H5($param)
3967 return $this->_tag_open_H1($param, 'h5');
3974 * @param array $param
3977 protected function _tag_open_H6($param)
3979 return $this->_tag_open_H1($param, 'h6');
3986 * @param array $param
3989 protected function _tag_close_H1($param)
3991 if ($this->_isForOneLine
) return false;
3993 $this->_maxH+
= $this->parsingCss
->value
['margin']['b'];
3994 $h = max($this->_maxH
, $this->parsingCss
->getLineHeight());
3996 $this->parsingCss
->load();
3997 $this->parsingCss
->fontSet();
3999 $this->_makeBreakLine($h);
4002 $this->_maxY
= max($this->_maxY
, $this->pdf
->getY());
4011 * @param array $param
4014 protected function _tag_close_H2($param)
4016 return $this->_tag_close_H1($param);
4023 * @param array $param
4026 protected function _tag_close_H3($param)
4028 return $this->_tag_close_H1($param);
4035 * @param array $param
4038 protected function _tag_close_H4($param)
4040 return $this->_tag_close_H1($param);
4047 * @param array $param
4050 protected function _tag_close_H5($param)
4052 return $this->_tag_close_H1($param);
4059 * @param array $param
4062 protected function _tag_close_H6($param)
4064 return $this->_tag_close_H1($param);
4071 * @param array $param
4072 * @param string $other
4075 protected function _tag_open_SPAN($param, $other = 'span')
4077 $this->parsingCss
->save();
4078 $this->parsingCss
->analyse($other, $param);
4079 $this->parsingCss
->setPosition();
4080 $this->parsingCss
->fontSet();
4089 * @param array $param
4092 protected function _tag_open_FONT($param)
4094 return $this->_tag_open_SPAN($param, 'font');
4101 * @param array $param
4104 protected function _tag_open_LABEL($param)
4106 return $this->_tag_open_SPAN($param, 'label');
4113 * @param array $param
4116 protected function _tag_close_SPAN($param)
4118 $this->parsingCss
->restorePosition();
4119 $this->parsingCss
->load();
4120 $this->parsingCss
->fontSet();
4129 * @param array $param
4132 protected function _tag_close_FONT($param)
4134 return $this->_tag_close_SPAN($param);
4141 * @param array $param
4144 protected function _tag_close_LABEL($param)
4146 return $this->_tag_close_SPAN($param);
4153 * @param array $param
4156 protected function _tag_open_P($param)
4158 if ($this->_isForOneLine
) return false;
4160 if (!in_array($this->_previousCall
, array('_tag_close_P', '_tag_close_UL'))) {
4161 if ($this->_maxH
) $this->_tag_open_BR(array());
4164 $this->parsingCss
->save();
4165 $this->parsingCss
->analyse('p', $param);
4166 $this->parsingCss
->setPosition();
4167 $this->parsingCss
->fontSet();
4169 // cancel the effects of the setPosition
4170 $this->pdf
->setXY($this->pdf
->getX()-$this->parsingCss
->value
['margin']['l'], $this->pdf
->getY()-$this->parsingCss
->value
['margin']['t']);
4172 list($mL, $mR) = $this->_getMargins($this->pdf
->getY());
4173 $mR = $this->pdf
->getW()-$mR;
4174 $mL+
= $this->parsingCss
->value
['margin']['l']+
$this->parsingCss
->value
['padding']['l'];
4175 $mR+
= $this->parsingCss
->value
['margin']['r']+
$this->parsingCss
->value
['padding']['r'];
4176 $this->_saveMargin($mL, 0, $mR);
4178 if ($this->parsingCss
->value
['text-indent']>0) {
4179 $y = $this->pdf
->getY()+
$this->parsingCss
->value
['margin']['t']+
$this->parsingCss
->value
['padding']['t'];
4180 $this->_pageMarges
[floor($y*100)] = array($mL+
$this->parsingCss
->value
['text-indent'], $this->pdf
->getW()-$mR);
4181 $y+
= $this->parsingCss
->getLineHeight()*0.1;
4182 $this->_pageMarges
[floor($y*100)] = array($mL, $this->pdf
->getW()-$mR);
4184 $this->_makeBreakLine($this->parsingCss
->value
['margin']['t']+
$this->parsingCss
->value
['padding']['t']);
4185 $this->_isInParagraph
= array($mL, $mR);
4193 * @param array $param
4196 protected function _tag_close_P($param)
4198 if ($this->_isForOneLine
) return false;
4200 if ($this->_maxH
) $this->_tag_open_BR(array());
4201 $this->_isInParagraph
= false;
4202 $this->_loadMargin();
4203 $h = $this->parsingCss
->value
['margin']['b']+
$this->parsingCss
->value
['padding']['b'];
4205 $this->parsingCss
->load();
4206 $this->parsingCss
->fontSet();
4207 $this->_makeBreakLine($h);
4216 * @param array $param
4217 * @param string $other
4220 protected function _tag_open_PRE($param, $other = 'pre')
4222 if ($other=='pre' && $this->_maxH
) $this->_tag_open_BR(array());
4224 $this->parsingCss
->save();
4225 $this->parsingCss
->value
['font-family'] = 'courier';
4226 $this->parsingCss
->analyse($other, $param);
4227 $this->parsingCss
->setPosition();
4228 $this->parsingCss
->fontSet();
4230 if ($other=='pre') return $this->_tag_open_DIV($param, $other);
4239 * @param array $param
4242 protected function _tag_open_CODE($param)
4244 return $this->_tag_open_PRE($param, 'code');
4251 * @param array $param
4252 * @param string $other
4255 protected function _tag_close_PRE($param, $other = 'pre')
4257 if ($other=='pre') {
4258 if ($this->_isForOneLine
) return false;
4260 $this->_tag_close_DIV($param, $other);
4261 $this->_tag_open_BR(array());
4263 $this->parsingCss
->load();
4264 $this->parsingCss
->fontSet();
4273 * @param array $param
4276 protected function _tag_close_CODE($param)
4278 return $this->_tag_close_PRE($param, 'code');
4285 * @param array $param
4288 protected function _tag_open_BIG($param)
4290 $this->parsingCss
->save();
4291 $this->parsingCss
->value
['mini-decal']-= $this->parsingCss
->value
['mini-size']*0.12;
4292 $this->parsingCss
->value
['mini-size'] *= 1.2;
4293 $this->parsingCss
->analyse('big', $param);
4294 $this->parsingCss
->setPosition();
4295 $this->parsingCss
->fontSet();
4303 * @param array $param
4306 protected function _tag_close_BIG($param)
4308 $this->parsingCss
->load();
4309 $this->parsingCss
->fontSet();
4318 * @param array $param
4321 protected function _tag_open_SMALL($param)
4323 $this->parsingCss
->save();
4324 $this->parsingCss
->value
['mini-decal']+
= $this->parsingCss
->value
['mini-size']*0.05;
4325 $this->parsingCss
->value
['mini-size'] *= 0.82;
4326 $this->parsingCss
->analyse('small', $param);
4327 $this->parsingCss
->setPosition();
4328 $this->parsingCss
->fontSet();
4336 * @param array $param
4339 protected function _tag_close_SMALL($param)
4341 $this->parsingCss
->load();
4342 $this->parsingCss
->fontSet();
4351 * @param array $param
4354 protected function _tag_open_SUP($param)
4356 $this->parsingCss
->save();
4357 $this->parsingCss
->value
['mini-decal']-= $this->parsingCss
->value
['mini-size']*0.15;
4358 $this->parsingCss
->value
['mini-size'] *= 0.75;
4359 $this->parsingCss
->analyse('sup', $param);
4360 $this->parsingCss
->setPosition();
4361 $this->parsingCss
->fontSet();
4370 * @param array $param
4373 protected function _tag_close_SUP($param)
4375 $this->parsingCss
->load();
4376 $this->parsingCss
->fontSet();
4385 * @param array $param
4388 protected function _tag_open_SUB($param)
4390 $this->parsingCss
->save();
4391 $this->parsingCss
->value
['mini-decal']+
= $this->parsingCss
->value
['mini-size']*0.15;
4392 $this->parsingCss
->value
['mini-size'] *= 0.75;
4393 $this->parsingCss
->analyse('sub', $param);
4394 $this->parsingCss
->setPosition();
4395 $this->parsingCss
->fontSet();
4403 * @param array $param
4406 protected function _tag_close_SUB($param)
4408 $this->parsingCss
->load();
4409 $this->parsingCss
->fontSet();
4418 * @param array $param
4419 * @param string $other
4422 protected function _tag_open_UL($param, $other = 'ul')
4424 if ($this->_isForOneLine
) return false;
4426 if (!in_array($this->_previousCall
, array('_tag_close_P', '_tag_close_UL'))) {
4427 if ($this->_maxH
) $this->_tag_open_BR(array());
4428 if (!count($this->_defList
)) $this->_tag_open_BR(array());
4431 if (!isset($param['style']['width'])) $param['allwidth'] = true;
4432 $param['cellspacing'] = 0;
4434 // a list is like a table
4435 $this->_tag_open_TABLE($param, $other);
4437 // add a level of list
4438 $this->_listeAddLevel($other, $this->parsingCss
->value
['list-style-type'], $this->parsingCss
->value
['list-style-image']);
4447 * @param array $param
4450 protected function _tag_open_OL($param)
4452 return $this->_tag_open_UL($param, 'ol');
4459 * @param array $param
4462 protected function _tag_close_UL($param)
4464 if ($this->_isForOneLine
) return false;
4466 $this->_tag_close_TABLE($param);
4468 $this->_listeDelLevel();
4470 if (!$this->_subPart
) {
4471 if (!count($this->_defList
)) $this->_tag_open_BR(array());
4481 * @param array $param
4484 protected function _tag_close_OL($param)
4486 return $this->_tag_close_UL($param);
4493 * @param array $param
4496 protected function _tag_open_LI($param)
4498 if ($this->_isForOneLine
) return false;
4500 $this->_listeAddLi();
4502 if (!isset($param['style']['width'])) $param['style']['width'] = '100%';
4504 $paramPUCE = $param;
4506 $inf = $this->_listeGetLi();
4508 $paramPUCE['style']['font-family'] = $inf[0];
4509 $paramPUCE['style']['text-align'] = 'li_right';
4510 $paramPUCE['style']['vertical-align'] = 'top';
4511 $paramPUCE['style']['width'] = $this->_listeGetWidth();
4512 $paramPUCE['style']['padding-right'] = $this->_listeGetPadding();
4513 $paramPUCE['txt'] = $inf[2];
4515 $paramPUCE['style']['text-align'] = 'li_right';
4516 $paramPUCE['style']['vertical-align'] = 'top';
4517 $paramPUCE['style']['width'] = $this->_listeGetWidth();
4518 $paramPUCE['style']['padding-right'] = $this->_listeGetPadding();
4519 $paramPUCE['src'] = $inf[2];
4520 $paramPUCE['sub_li'] = true;
4523 $this->_tag_open_TR($param, 'li');
4525 $this->parsingCss
->save();
4529 $this->parsingCss
->value
['mini-decal']+
= $this->parsingCss
->value
['mini-size']*0.045;
4530 $this->parsingCss
->value
['mini-size'] *= 0.75;
4533 // if we are in a sub html => prepare. Else : display
4534 if ($this->_subPart
) {
4536 $tmpPos = $this->_tempPos
;
4537 $tmpLst1 = $this->parsingHtml
->code
[$tmpPos+
1];
4538 $tmpLst2 = $this->parsingHtml
->code
[$tmpPos+
2];
4539 $this->parsingHtml
->code
[$tmpPos+
1] = array();
4540 $this->parsingHtml
->code
[$tmpPos+
1]['name'] = (isset($paramPUCE['src'])) ?
'img' : 'write';
4541 $this->parsingHtml
->code
[$tmpPos+
1]['param'] = $paramPUCE; unset($this->parsingHtml
->code
[$tmpPos+
1]['param']['style']['width']);
4542 $this->parsingHtml
->code
[$tmpPos+
1]['close'] = 0;
4543 $this->parsingHtml
->code
[$tmpPos+
2] = array();
4544 $this->parsingHtml
->code
[$tmpPos+
2]['name'] = 'li';
4545 $this->parsingHtml
->code
[$tmpPos+
2]['param'] = $paramPUCE;
4546 $this->parsingHtml
->code
[$tmpPos+
2]['close'] = 1;
4547 $this->_tag_open_TD($paramPUCE, 'li_sub');
4548 $this->_tag_close_TD($param);
4549 $this->_tempPos
= $tmpPos;
4550 $this->parsingHtml
->code
[$tmpPos+
1] = $tmpLst1;
4551 $this->parsingHtml
->code
[$tmpPos+
2] = $tmpLst2;
4554 $this->_tag_open_TD($paramPUCE, 'li_sub');
4555 unset($paramPUCE['style']['width']);
4556 if (isset($paramPUCE['src'])) $this->_tag_open_IMG($paramPUCE);
4557 else $this->_tag_open_WRITE($paramPUCE);
4558 $this->_tag_close_TD($paramPUCE);
4560 $this->parsingCss
->load();
4563 // TD for the content
4564 $this->_tag_open_TD($param, 'li');
4573 * @param array $param
4576 protected function _tag_close_LI($param)
4578 if ($this->_isForOneLine
) return false;
4580 $this->_tag_close_TD($param);
4582 $this->_tag_close_TR($param);
4591 * @param array $param
4594 protected function _tag_open_TBODY($param)
4596 if ($this->_isForOneLine
) return false;
4598 $this->parsingCss
->save();
4599 $this->parsingCss
->analyse('tbody', $param);
4600 $this->parsingCss
->setPosition();
4601 $this->parsingCss
->fontSet();
4610 * @param array $param
4613 protected function _tag_close_TBODY($param)
4615 if ($this->_isForOneLine
) return false;
4617 $this->parsingCss
->load();
4618 $this->parsingCss
->fontSet();
4627 * @param array $param
4630 protected function _tag_open_THEAD($param)
4632 if ($this->_isForOneLine
) return false;
4634 $this->parsingCss
->save();
4635 $this->parsingCss
->analyse('thead', $param);
4636 $this->parsingCss
->setPosition();
4637 $this->parsingCss
->fontSet();
4639 // if we are in a sub part, save the number of the first TR in the thead
4640 if ($this->_subPart
) {
4641 HTML2PDF
::$_tables[$param['num']]['thead']['tr'][0] = HTML2PDF
::$_tables[$param['num']]['tr_curr'];
4642 HTML2PDF
::$_tables[$param['num']]['thead']['code'] = array();
4643 for ($pos=$this->_tempPos
; $pos<count($this->parsingHtml
->code
); $pos++
) {
4644 $action = $this->parsingHtml
->code
[$pos];
4645 if (strtolower($action['name'])=='thead') $action['name'] = 'thead_sub';
4646 HTML2PDF
::$_tables[$param['num']]['thead']['code'][] = $action;
4647 if (strtolower($action['name'])=='thead_sub' && $action['close']) break;
4650 $level = $this->parsingHtml
->getLevel($this->_parsePos
);
4651 $this->_parsePos+
= count($level);
4652 HTML2PDF
::$_tables[$param['num']]['tr_curr']+
= count(HTML2PDF
::$_tables[$param['num']]['thead']['tr']);
4662 * @param array $param
4665 protected function _tag_close_THEAD($param)
4667 if ($this->_isForOneLine
) return false;
4669 $this->parsingCss
->load();
4670 $this->parsingCss
->fontSet();
4672 // if we are in a sub HTM, construct the list of the TR in the thead
4673 if ($this->_subPart
) {
4674 $min = HTML2PDF
::$_tables[$param['num']]['thead']['tr'][0];
4675 $max = HTML2PDF
::$_tables[$param['num']]['tr_curr']-1;
4676 HTML2PDF
::$_tables[$param['num']]['thead']['tr'] = range($min, $max);
4686 * @param array $param
4689 protected function _tag_open_TFOOT($param)
4691 if ($this->_isForOneLine
) return false;
4693 $this->parsingCss
->save();
4694 $this->parsingCss
->analyse('tfoot', $param);
4695 $this->parsingCss
->setPosition();
4696 $this->parsingCss
->fontSet();
4698 // if we are in a sub part, save the number of the first TR in the tfoot
4699 if ($this->_subPart
) {
4700 HTML2PDF
::$_tables[$param['num']]['tfoot']['tr'][0] = HTML2PDF
::$_tables[$param['num']]['tr_curr'];
4701 HTML2PDF
::$_tables[$param['num']]['tfoot']['code'] = array();
4702 for ($pos=$this->_tempPos
; $pos<count($this->parsingHtml
->code
); $pos++
) {
4703 $action = $this->parsingHtml
->code
[$pos];
4704 if (strtolower($action['name'])=='tfoot') $action['name'] = 'tfoot_sub';
4705 HTML2PDF
::$_tables[$param['num']]['tfoot']['code'][] = $action;
4706 if (strtolower($action['name'])=='tfoot_sub' && $action['close']) break;
4709 $level = $this->parsingHtml
->getLevel($this->_parsePos
);
4710 $this->_parsePos+
= count($level);
4711 HTML2PDF
::$_tables[$param['num']]['tr_curr']+
= count(HTML2PDF
::$_tables[$param['num']]['tfoot']['tr']);
4721 * @param array $param
4724 protected function _tag_close_TFOOT($param)
4726 if ($this->_isForOneLine
) return false;
4728 $this->parsingCss
->load();
4729 $this->parsingCss
->fontSet();
4731 // if we are in a sub HTM, construct the list of the TR in the tfoot
4732 if ($this->_subPart
) {
4733 $min = HTML2PDF
::$_tables[$param['num']]['tfoot']['tr'][0];
4734 $max = HTML2PDF
::$_tables[$param['num']]['tr_curr']-1;
4735 HTML2PDF
::$_tables[$param['num']]['tfoot']['tr'] = range($min, $max);
4742 * It is not a real TAG, do not use it !
4744 * @param array $param
4747 protected function _tag_open_THEAD_SUB($param)
4749 if ($this->_isForOneLine
) return false;
4751 $this->parsingCss
->save();
4752 $this->parsingCss
->analyse('thead', $param);
4753 $this->parsingCss
->setPosition();
4754 $this->parsingCss
->fontSet();
4760 * It is not a real TAG, do not use it !
4762 * @param array $param
4765 protected function _tag_close_THEAD_SUB($param)
4767 if ($this->_isForOneLine
) return false;
4769 $this->parsingCss
->load();
4770 $this->parsingCss
->fontSet();
4776 * It is not a real TAG, do not use it !
4778 * @param array $param
4781 protected function _tag_open_TFOOT_SUB($param)
4783 if ($this->_isForOneLine
) return false;
4785 $this->parsingCss
->save();
4786 $this->parsingCss
->analyse('tfoot', $param);
4787 $this->parsingCss
->setPosition();
4788 $this->parsingCss
->fontSet();
4794 * It is not a real TAG, do not use it !
4796 * @param array $param
4799 protected function _tag_close_TFOOT_SUB($param)
4801 if ($this->_isForOneLine
) return false;
4803 $this->parsingCss
->load();
4804 $this->parsingCss
->fontSet();
4813 * @param array $param
4816 protected function _tag_open_FORM($param)
4818 $this->parsingCss
->save();
4819 $this->parsingCss
->analyse('form', $param);
4820 $this->parsingCss
->setPosition();
4821 $this->parsingCss
->fontSet();
4823 $this->pdf
->setFormDefaultProp(
4826 'borderStyle'=>'solid',
4827 'fillColor'=>array(220, 220, 255),
4828 'strokeColor'=>array(128, 128, 200)
4832 $this->_isInForm
= isset($param['action']) ?
$param['action'] : '';
4841 * @param array $param
4844 protected function _tag_close_FORM($param)
4846 $this->_isInForm
= false;
4847 $this->parsingCss
->load();
4848 $this->parsingCss
->fontSet();
4857 * @param array $param
4860 protected function _tag_open_TABLE($param, $other = 'table')
4863 if ($this->_isForOneLine
) return false;
4864 $this->_tag_open_BR(array());
4867 if ($this->_isForOneLine
) {
4868 $this->_maxX
= $this->pdf
->getW() - $this->pdf
->getlMargin() - $this->pdf
->getrMargin();
4874 $alignObject = isset($param['align']) ?
strtolower($param['align']) : 'left';
4875 if (isset($param['align'])) unset($param['align']);
4876 if (!in_array($alignObject, array('left', 'center', 'right'))) $alignObject = 'left';
4878 $this->parsingCss
->save();
4879 $this->parsingCss
->analyse($other, $param);
4880 $this->parsingCss
->setPosition();
4881 $this->parsingCss
->fontSet();
4883 if ($this->parsingCss
->value
['margin-auto']) $alignObject = 'center';
4887 if ($other=='table') {
4888 $collapse = isset($this->parsingCss
->value
['border']['collapse']) ?
$this->parsingCss
->value
['border']['collapse'] : false;
4891 // if collapse => no borders for the table, only for TD
4893 $param['style']['border'] = 'none';
4894 $param['cellspacing'] = 0;
4895 $none = $this->parsingCss
->readBorder('none');
4896 $this->parsingCss
->value
['border']['t'] = $none;
4897 $this->parsingCss
->value
['border']['r'] = $none;
4898 $this->parsingCss
->value
['border']['b'] = $none;
4899 $this->parsingCss
->value
['border']['l'] = $none;
4902 // if we are in a SUB html => prepare the properties of the table
4903 if ($this->_subPart
) {
4904 if ($this->_debugActif
) $this->_DEBUG_add('Table n'.$param['num'], true);
4905 HTML2PDF
::$_tables[$param['num']] = array();
4906 HTML2PDF
::$_tables[$param['num']]['border'] = isset($param['border']) ?
$this->parsingCss
->readBorder($param['border']) : null;
4907 HTML2PDF
::$_tables[$param['num']]['cellpadding'] = $this->parsingCss
->ConvertToMM(isset($param['cellpadding']) ?
$param['cellpadding'] : '1px');
4908 HTML2PDF
::$_tables[$param['num']]['cellspacing'] = $this->parsingCss
->ConvertToMM(isset($param['cellspacing']) ?
$param['cellspacing'] : '2px');
4909 HTML2PDF
::$_tables[$param['num']]['cases'] = array(); // properties of each TR/TD
4910 HTML2PDF
::$_tables[$param['num']]['corr'] = array(); // link between TR/TD and colspan/rowspan
4911 HTML2PDF
::$_tables[$param['num']]['corr_x'] = 0; // position in 'cases'
4912 HTML2PDF
::$_tables[$param['num']]['corr_y'] = 0; // position in 'cases'
4913 HTML2PDF
::$_tables[$param['num']]['td_curr'] = 0; // current column
4914 HTML2PDF
::$_tables[$param['num']]['tr_curr'] = 0; // current row
4915 HTML2PDF
::$_tables[$param['num']]['curr_x'] = $this->pdf
->getX();
4916 HTML2PDF
::$_tables[$param['num']]['curr_y'] = $this->pdf
->getY();
4917 HTML2PDF
::$_tables[$param['num']]['width'] = 0; // global width
4918 HTML2PDF
::$_tables[$param['num']]['height'] = 0; // global height
4919 HTML2PDF
::$_tables[$param['num']]['align'] = $alignObject;
4920 HTML2PDF
::$_tables[$param['num']]['marge'] = array();
4921 HTML2PDF
::$_tables[$param['num']]['marge']['t'] = $this->parsingCss
->value
['padding']['t']+
$this->parsingCss
->value
['border']['t']['width']+HTML2PDF
::$_tables[$param['num']]['cellspacing']*0.5;
4922 HTML2PDF
::$_tables[$param['num']]['marge']['r'] = $this->parsingCss
->value
['padding']['r']+
$this->parsingCss
->value
['border']['r']['width']+HTML2PDF
::$_tables[$param['num']]['cellspacing']*0.5;
4923 HTML2PDF
::$_tables[$param['num']]['marge']['b'] = $this->parsingCss
->value
['padding']['b']+
$this->parsingCss
->value
['border']['b']['width']+HTML2PDF
::$_tables[$param['num']]['cellspacing']*0.5;
4924 HTML2PDF
::$_tables[$param['num']]['marge']['l'] = $this->parsingCss
->value
['padding']['l']+
$this->parsingCss
->value
['border']['l']['width']+HTML2PDF
::$_tables[$param['num']]['cellspacing']*0.5;
4925 HTML2PDF
::$_tables[$param['num']]['page'] = 0; // number of pages
4926 HTML2PDF
::$_tables[$param['num']]['new_page'] = true; // flag : new page for the current TR
4927 HTML2PDF
::$_tables[$param['num']]['style_value'] = null; // CSS style of the table
4928 HTML2PDF
::$_tables[$param['num']]['thead'] = array(); // properties on the thead
4929 HTML2PDF
::$_tables[$param['num']]['tfoot'] = array(); // properties on the tfoot
4930 HTML2PDF
::$_tables[$param['num']]['thead']['tr'] = array(); // list of the TRs in the thead
4931 HTML2PDF
::$_tables[$param['num']]['tfoot']['tr'] = array(); // list of the TRs in the tfoot
4932 HTML2PDF
::$_tables[$param['num']]['thead']['height'] = 0; // thead height
4933 HTML2PDF
::$_tables[$param['num']]['tfoot']['height'] = 0; // tfoot height
4934 HTML2PDF
::$_tables[$param['num']]['thead']['code'] = array(); // HTML content of the thead
4935 HTML2PDF
::$_tables[$param['num']]['tfoot']['code'] = array(); // HTML content of the tfoot
4936 HTML2PDF
::$_tables[$param['num']]['cols'] = array(); // properties of the COLs
4938 $this->_saveMargin($this->pdf
->getlMargin(), $this->pdf
->gettMargin(), $this->pdf
->getrMargin());
4940 $this->parsingCss
->value
['width']-= HTML2PDF
::$_tables[$param['num']]['marge']['l'] + HTML2PDF
::$_tables[$param['num']]['marge']['r'];
4942 // we start from the first page and the first page of the table
4943 HTML2PDF
::$_tables[$param['num']]['page'] = 0;
4944 HTML2PDF
::$_tables[$param['num']]['td_curr'] = 0;
4945 HTML2PDF
::$_tables[$param['num']]['tr_curr'] = 0;
4946 HTML2PDF
::$_tables[$param['num']]['td_x'] = HTML2PDF
::$_tables[$param['num']]['marge']['l']+HTML2PDF
::$_tables[$param['num']]['curr_x'];
4947 HTML2PDF
::$_tables[$param['num']]['td_y'] = HTML2PDF
::$_tables[$param['num']]['marge']['t']+HTML2PDF
::$_tables[$param['num']]['curr_y'];
4949 // draw the borders/background of the first page/part of the table
4950 $this->_drawRectangle(
4951 HTML2PDF
::$_tables[$param['num']]['curr_x'],
4952 HTML2PDF
::$_tables[$param['num']]['curr_y'],
4953 HTML2PDF
::$_tables[$param['num']]['width'],
4954 isset(HTML2PDF
::$_tables[$param['num']]['height'][0]) ? HTML2PDF
::$_tables[$param['num']]['height'][0] : null,
4955 $this->parsingCss
->value
['border'],
4956 $this->parsingCss
->value
['padding'],
4958 $this->parsingCss
->value
['background']
4961 HTML2PDF
::$_tables[$param['num']]['style_value'] = $this->parsingCss
->value
;
4971 * @param array $param
4974 protected function _tag_close_TABLE($param)
4976 if ($this->_isForOneLine
) return false;
4980 // if we are in a sub HTML
4981 if ($this->_subPart
) {
4982 // calculate the size of each case
4983 $this->_calculateTableCellSize(HTML2PDF
::$_tables[$param['num']]['cases'], HTML2PDF
::$_tables[$param['num']]['corr']);
4985 // calculate the height of the thead and the tfoot
4986 $lst = array('thead', 'tfoot');
4987 foreach ($lst as $mode) {
4988 HTML2PDF
::$_tables[$param['num']][$mode]['height'] = 0;
4989 foreach (HTML2PDF
::$_tables[$param['num']][$mode]['tr'] as $tr) {
4990 // hauteur de la ligne tr
4992 for ($i=0; $i<count(HTML2PDF
::$_tables[$param['num']]['cases'][$tr]); $i++
)
4993 if (HTML2PDF
::$_tables[$param['num']]['cases'][$tr][$i]['rowspan']==1)
4994 $h = max($h, HTML2PDF
::$_tables[$param['num']]['cases'][$tr][$i]['h']);
4995 HTML2PDF
::$_tables[$param['num']][$mode]['height']+
= $h;
4999 // calculate the width of the table
5000 HTML2PDF
::$_tables[$param['num']]['width'] = HTML2PDF
::$_tables[$param['num']]['marge']['l'] + HTML2PDF
::$_tables[$param['num']]['marge']['r'];
5001 if (isset(HTML2PDF
::$_tables[$param['num']]['cases'][0])) {
5002 foreach (HTML2PDF
::$_tables[$param['num']]['cases'][0] as $case) {
5003 HTML2PDF
::$_tables[$param['num']]['width']+
= $case['w'];
5007 // X position of the table
5008 $old = $this->parsingCss
->getOldValues();
5009 $parentWidth = $old['width'] ?
$old['width'] : $this->pdf
->getW() - $this->pdf
->getlMargin() - $this->pdf
->getrMargin();
5010 $x = HTML2PDF
::$_tables[$param['num']]['curr_x'];
5011 $w = HTML2PDF
::$_tables[$param['num']]['width'];
5012 if ($parentWidth>$w) {
5013 if (HTML2PDF
::$_tables[$param['num']]['align']=='center')
5014 $x = $x +
($parentWidth-$w)*0.5;
5015 else if (HTML2PDF
::$_tables[$param['num']]['align']=='right')
5016 $x = $x +
$parentWidth-$w;
5018 HTML2PDF
::$_tables[$param['num']]['curr_x'] = $x;
5021 // calculate the height of the table
5022 HTML2PDF
::$_tables[$param['num']]['height'] = array();
5024 // minimum of the height because of margins, and of the thead and tfoot height
5025 $h0 = HTML2PDF
::$_tables[$param['num']]['marge']['t'] + HTML2PDF
::$_tables[$param['num']]['marge']['b'];
5026 $h0+
= HTML2PDF
::$_tables[$param['num']]['thead']['height'] + HTML2PDF
::$_tables[$param['num']]['tfoot']['height'];
5028 // max height of the page
5029 $max = $this->pdf
->getH() - $this->pdf
->getbMargin();
5031 // current position on the page
5032 $y = HTML2PDF
::$_tables[$param['num']]['curr_y'];
5035 // we get the height of each line
5036 for ($k=0; $k<count(HTML2PDF
::$_tables[$param['num']]['cases']); $k++
) {
5038 // if it is a TR of the thead or of the tfoot => skip
5039 if (in_array($k, HTML2PDF
::$_tables[$param['num']]['thead']['tr'])) continue;
5040 if (in_array($k, HTML2PDF
::$_tables[$param['num']]['tfoot']['tr'])) continue;
5042 // height of the line
5045 for ($i=0; $i<count(HTML2PDF
::$_tables[$param['num']]['cases'][$k]); $i++
) {
5046 $h = max($h, HTML2PDF
::$_tables[$param['num']]['cases'][$k][$i]['h']);
5048 if (HTML2PDF
::$_tables[$param['num']]['cases'][$k][$i]['rowspan']==1)
5049 $th = max($th, HTML2PDF
::$_tables[$param['num']]['cases'][$k][$i]['h']);
5052 // if the row does not fit on the page => new page
5053 if ($y+
$h+
$height>$max) {
5054 if ($height==$h0) $height = null;
5055 HTML2PDF
::$_tables[$param['num']]['height'][] = $height;
5057 $y = $this->_margeTop
;
5062 // if ther is a height at the end, add it
5063 if ($height!=$h0 ||
$k==0) HTML2PDF
::$_tables[$param['num']]['height'][] = $height;
5065 // if we have tfoor, draw it
5066 if (count(HTML2PDF
::$_tables[$param['num']]['tfoot']['code'])) {
5067 $tmpTR = HTML2PDF
::$_tables[$param['num']]['tr_curr'];
5068 $tmpTD = HTML2PDF
::$_tables[$param['num']]['td_curr'];
5069 $oldParsePos = $this->_parsePos
;
5070 $oldParseCode = $this->parsingHtml
->code
;
5072 HTML2PDF
::$_tables[$param['num']]['tr_curr'] = HTML2PDF
::$_tables[$param['num']]['tfoot']['tr'][0];
5073 HTML2PDF
::$_tables[$param['num']]['td_curr'] = 0;
5074 $this->_parsePos
= 0;
5075 $this->parsingHtml
->code
= HTML2PDF
::$_tables[$param['num']]['tfoot']['code'];
5076 $this->_isInTfoot
= true;
5077 $this->_makeHTMLcode();
5078 $this->_isInTfoot
= false;
5080 $this->_parsePos
= $oldParsePos;
5081 $this->parsingHtml
->code
= $oldParseCode;
5082 HTML2PDF
::$_tables[$param['num']]['tr_curr'] = $tmpTR;
5083 HTML2PDF
::$_tables[$param['num']]['td_curr'] = $tmpTD;
5086 // get the positions of the end of the table
5087 $x = HTML2PDF
::$_tables[$param['num']]['curr_x'] + HTML2PDF
::$_tables[$param['num']]['width'];
5088 if (count(HTML2PDF
::$_tables[$param['num']]['height'])>1)
5089 $y = $this->_margeTop+HTML2PDF
::$_tables[$param['num']]['height'][count(HTML2PDF
::$_tables[$param['num']]['height'])-1];
5090 else if (count(HTML2PDF
::$_tables[$param['num']]['height'])==1)
5091 $y = HTML2PDF
::$_tables[$param['num']]['curr_y']+HTML2PDF
::$_tables[$param['num']]['height'][count(HTML2PDF
::$_tables[$param['num']]['height'])-1];
5093 $y = HTML2PDF
::$_tables[$param['num']]['curr_y'];
5095 $this->_maxX
= max($this->_maxX
, $x);
5096 $this->_maxY
= max($this->_maxY
, $y);
5098 $this->pdf
->setXY($this->pdf
->getlMargin(), $y);
5100 $this->_loadMargin();
5102 if ($this->_debugActif
) $this->_DEBUG_add('Table '.$param['num'], false);
5105 $this->parsingCss
->load();
5106 $this->parsingCss
->fontSet();
5116 * @param array $param
5119 protected function _tag_open_COL($param)
5121 $span = isset($param['span']) ?
$param['span'] : 1;
5122 for ($k=0; $k<$span; $k++
)
5123 HTML2PDF
::$_tables[$param['num']]['cols'][] = $param;
5130 * @param array $param
5133 protected function _tag_close_COL($param)
5135 // there is nothing to do here
5144 * @param array $param
5147 protected function _tag_open_TR($param, $other = 'tr')
5149 if ($this->_isForOneLine
) return false;
5153 $this->parsingCss
->save();
5154 $this->parsingCss
->analyse($other, $param);
5155 $this->parsingCss
->setPosition();
5156 $this->parsingCss
->fontSet();
5158 // position in the table
5159 HTML2PDF
::$_tables[$param['num']]['tr_curr']++
;
5160 HTML2PDF
::$_tables[$param['num']]['td_curr']= 0;
5162 // if we are not in a sub html
5163 if (!$this->_subPart
) {
5167 for ($ii=0; $ii<count(HTML2PDF
::$_tables[$param['num']]['cases'][HTML2PDF
::$_tables[$param['num']]['tr_curr']-1]); $ii++
) {
5168 $ty = max($ty, HTML2PDF
::$_tables[$param['num']]['cases'][HTML2PDF
::$_tables[$param['num']]['tr_curr']-1][$ii]['h']);
5171 // height of the tfoot
5172 $hfoot = HTML2PDF
::$_tables[$param['num']]['tfoot']['height'];
5174 // if the line does not fit on the page => new page
5175 if (!$this->_isInTfoot
&& HTML2PDF
::$_tables[$param['num']]['td_y'] + HTML2PDF
::$_tables[$param['num']]['marge']['b'] +
$ty +
$hfoot> $this->pdf
->getH() - $this->pdf
->getbMargin()) {
5177 // fi ther is a tfoot => draw it
5178 if (count(HTML2PDF
::$_tables[$param['num']]['tfoot']['code'])) {
5179 $tmpTR = HTML2PDF
::$_tables[$param['num']]['tr_curr'];
5180 $tmpTD = HTML2PDF
::$_tables[$param['num']]['td_curr'];
5181 $oldParsePos = $this->_parsePos
;
5182 $oldParseCode = $this->parsingHtml
->code
;
5184 HTML2PDF
::$_tables[$param['num']]['tr_curr'] = HTML2PDF
::$_tables[$param['num']]['tfoot']['tr'][0];
5185 HTML2PDF
::$_tables[$param['num']]['td_curr'] = 0;
5186 $this->_parsePos
= 0;
5187 $this->parsingHtml
->code
= HTML2PDF
::$_tables[$param['num']]['tfoot']['code'];
5188 $this->_isInTfoot
= true;
5189 $this->_makeHTMLcode();
5190 $this->_isInTfoot
= false;
5192 $this->_parsePos
= $oldParsePos;
5193 $this->parsingHtml
->code
= $oldParseCode;
5194 HTML2PDF
::$_tables[$param['num']]['tr_curr'] = $tmpTR;
5195 HTML2PDF
::$_tables[$param['num']]['td_curr'] = $tmpTD;
5199 HTML2PDF
::$_tables[$param['num']]['new_page'] = true;
5200 $this->_setNewPage();
5203 HTML2PDF
::$_tables[$param['num']]['page']++
;
5204 HTML2PDF
::$_tables[$param['num']]['curr_y'] = $this->pdf
->getY();
5205 HTML2PDF
::$_tables[$param['num']]['td_y'] = HTML2PDF
::$_tables[$param['num']]['curr_y']+HTML2PDF
::$_tables[$param['num']]['marge']['t'];
5207 // if we have the height of the tbale on the page => draw borders and background
5208 if (isset(HTML2PDF
::$_tables[$param['num']]['height'][HTML2PDF
::$_tables[$param['num']]['page']])) {
5209 $old = $this->parsingCss
->value
;
5210 $this->parsingCss
->value
= HTML2PDF
::$_tables[$param['num']]['style_value'];
5212 $this->_drawRectangle(
5213 HTML2PDF
::$_tables[$param['num']]['curr_x'],
5214 HTML2PDF
::$_tables[$param['num']]['curr_y'],
5215 HTML2PDF
::$_tables[$param['num']]['width'],
5216 HTML2PDF
::$_tables[$param['num']]['height'][HTML2PDF
::$_tables[$param['num']]['page']],
5217 $this->parsingCss
->value
['border'],
5218 $this->parsingCss
->value
['padding'],
5219 HTML2PDF
::$_tables[$param['num']]['cellspacing']*0.5,
5220 $this->parsingCss
->value
['background']
5223 $this->parsingCss
->value
= $old;
5227 // if we are in a new page, and if we have a thead => draw it
5228 if (HTML2PDF
::$_tables[$param['num']]['new_page'] && count(HTML2PDF
::$_tables[$param['num']]['thead']['code'])) {
5229 HTML2PDF
::$_tables[$param['num']]['new_page'] = false;
5230 $tmpTR = HTML2PDF
::$_tables[$param['num']]['tr_curr'];
5231 $tmpTD = HTML2PDF
::$_tables[$param['num']]['td_curr'];
5232 $oldParsePos = $this->_parsePos
;
5233 $oldParseCode = $this->parsingHtml
->code
;
5235 HTML2PDF
::$_tables[$param['num']]['tr_curr'] = HTML2PDF
::$_tables[$param['num']]['thead']['tr'][0];
5236 HTML2PDF
::$_tables[$param['num']]['td_curr'] = 0;
5237 $this->_parsePos
= 0;
5238 $this->parsingHtml
->code
= HTML2PDF
::$_tables[$param['num']]['thead']['code'];
5239 $this->_isInThead
= true;
5240 $this->_makeHTMLcode();
5241 $this->_isInThead
= false;
5243 $this->_parsePos
= $oldParsePos;
5244 $this->parsingHtml
->code
= $oldParseCode;
5245 HTML2PDF
::$_tables[$param['num']]['tr_curr'] = $tmpTR;
5246 HTML2PDF
::$_tables[$param['num']]['td_curr'] = $tmpTD;
5247 HTML2PDF
::$_tables[$param['num']]['new_page'] = true;
5249 // else (in a sub HTML)
5252 HTML2PDF
::$_tables[$param['num']]['cases'][HTML2PDF
::$_tables[$param['num']]['tr_curr']-1] = array();
5253 if (!isset(HTML2PDF
::$_tables[$param['num']]['corr'][HTML2PDF
::$_tables[$param['num']]['corr_y']]))
5254 HTML2PDF
::$_tables[$param['num']]['corr'][HTML2PDF
::$_tables[$param['num']]['corr_y']] = array();
5256 HTML2PDF
::$_tables[$param['num']]['corr_x']=0;
5257 while(isset(HTML2PDF
::$_tables[$param['num']]['corr'][HTML2PDF
::$_tables[$param['num']]['corr_y']][HTML2PDF
::$_tables[$param['num']]['corr_x']]))
5258 HTML2PDF
::$_tables[$param['num']]['corr_x']++
;
5268 * @param array $param
5271 protected function _tag_close_TR($param)
5273 if ($this->_isForOneLine
) return false;
5277 $this->parsingCss
->load();
5278 $this->parsingCss
->fontSet();
5280 // if we are not in a sub HTML
5281 if (!$this->_subPart
) {
5283 // Y of the current line
5285 for ($ii=0; $ii<count(HTML2PDF
::$_tables[$param['num']]['cases'][HTML2PDF
::$_tables[$param['num']]['tr_curr']-1]); $ii++
) {
5286 if (HTML2PDF
::$_tables[$param['num']]['cases'][HTML2PDF
::$_tables[$param['num']]['tr_curr']-1][$ii]['rowspan']==1) {
5287 $ty = HTML2PDF
::$_tables[$param['num']]['cases'][HTML2PDF
::$_tables[$param['num']]['tr_curr']-1][$ii]['h'];
5292 HTML2PDF
::$_tables[$param['num']]['td_x'] = HTML2PDF
::$_tables[$param['num']]['curr_x']+HTML2PDF
::$_tables[$param['num']]['marge']['l'];
5293 HTML2PDF
::$_tables[$param['num']]['td_y']+
= $ty;
5294 HTML2PDF
::$_tables[$param['num']]['new_page'] = false;
5296 HTML2PDF
::$_tables[$param['num']]['corr_y']++
;
5306 * @param array $param
5307 * @param string $other
5310 * @throws HTML2PDF_exception
5312 protected function _tag_open_TD($param, $other = 'td')
5314 if ($this->_isForOneLine
) return false;
5318 $param['cellpadding'] = HTML2PDF
::$_tables[$param['num']]['cellpadding'].'mm';
5319 $param['cellspacing'] = HTML2PDF
::$_tables[$param['num']]['cellspacing'].'mm';
5321 // specific style for LI
5326 if ($other=='li_sub') {
5327 $param['style']['border'] = 'none';
5328 $param['style']['background-color'] = 'transparent';
5329 $param['style']['background-image'] = 'none';
5330 $param['style']['background-position'] = '';
5331 $param['style']['background-repeat'] = '';
5336 // get the properties of the TD
5337 $x = HTML2PDF
::$_tables[$param['num']]['td_curr'];
5338 $y = HTML2PDF
::$_tables[$param['num']]['tr_curr']-1;
5339 $colspan = isset($param['colspan']) ?
$param['colspan'] : 1;
5340 $rowspan = isset($param['rowspan']) ?
$param['rowspan'] : 1;
5342 // flag for collapse table
5345 // specific treatment for TD and TH
5346 if (in_array($other, array('td', 'th'))) {
5348 $numCol = isset(HTML2PDF
::$_tables[$param['num']]['cases'][$y][$x]['Xr']) ? HTML2PDF
::$_tables[$param['num']]['cases'][$y][$x]['Xr'] : HTML2PDF
::$_tables[$param['num']]['corr_x'];
5350 // we get the properties of the COL tag, if exist
5351 if (isset(HTML2PDF
::$_tables[$param['num']]['cols'][$numCol])) {
5353 $colParam = HTML2PDF
::$_tables[$param['num']]['cols'][$numCol];
5355 // for colspans => we get all the needed widths
5356 $colParam['style']['width'] = array();
5357 for ($k=0; $k<$colspan; $k++
) {
5358 if (isset(HTML2PDF
::$_tables[$param['num']]['cols'][$numCol+
$k]['style']['width'])) {
5359 $colParam['style']['width'][] = HTML2PDF
::$_tables[$param['num']]['cols'][$numCol+
$k]['style']['width'];
5363 // calculate the total width of the column
5365 $last = $this->parsingCss
->getLastWidth();
5366 if (count($colParam['style']['width'])) {
5367 $total = $colParam['style']['width'][0]; unset($colParam['style']['width'][0]);
5368 foreach ($colParam['style']['width'] as $width) {
5369 if (substr($total, -1)=='%' && substr($width, -1)=='%')
5370 $total = (str_replace('%', '', $total)+
str_replace('%', '', $width)).'%';
5372 $total = ($this->parsingCss
->ConvertToMM($total, $last) +
$this->parsingCss
->ConvertToMM($width, $last)).'mm';
5376 // get the final width
5378 $colParam['style']['width'] = $total;
5380 unset($colParam['style']['width']);
5384 // merge the styles of the COL and the TD
5385 $param['style'] = array_merge($colParam['style'], $param['style']);
5387 // merge the class of the COL and the TD
5388 if (isset($colParam['class'])) {
5389 $param['class'] = $colParam['class'].(isset($param['class']) ?
' '.$param['class'] : '');
5393 $collapse = isset($this->parsingCss
->value
['border']['collapse']) ?
$this->parsingCss
->value
['border']['collapse'] : false;
5396 $this->parsingCss
->save();
5398 // legacy for TD and TH
5400 if (in_array($other, array('td', 'th'))) {
5403 $old = $this->parsingCss
->getLastValue('background');
5404 if ($old && ($old['color'] ||
$old['image']))
5405 $legacy['background'] = $old;
5407 if (HTML2PDF
::$_tables[$param['num']]['border']) {
5408 $legacy['border'] = array();
5409 $legacy['border']['l'] = HTML2PDF
::$_tables[$param['num']]['border'];
5410 $legacy['border']['t'] = HTML2PDF
::$_tables[$param['num']]['border'];
5411 $legacy['border']['r'] = HTML2PDF
::$_tables[$param['num']]['border'];
5412 $legacy['border']['b'] = HTML2PDF
::$_tables[$param['num']]['border'];
5415 $return = $this->parsingCss
->analyse($other, $param, $legacy);
5418 $this->parsingCss
->value
['width']-= $this->parsingCss
->ConvertToMM($this->_listeGetWidth());
5419 $this->parsingCss
->value
['width']-= $this->parsingCss
->ConvertToMM($this->_listeGetPadding());
5421 $this->parsingCss
->setPosition();
5422 $this->parsingCss
->fontSet();
5424 // if table collapse => modify the borders
5426 if (!$this->_subPart
) {
5428 (HTML2PDF
::$_tables[$param['num']]['tr_curr']>1 && !HTML2PDF
::$_tables[$param['num']]['new_page']) ||
5429 (!$this->_isInThead
&& count(HTML2PDF
::$_tables[$param['num']]['thead']['code']))
5431 $this->parsingCss
->value
['border']['t'] = $this->parsingCss
->readBorder('none');
5435 if (HTML2PDF
::$_tables[$param['num']]['td_curr']>0) {
5436 if (!$return) $this->parsingCss
->value
['width']+
= $this->parsingCss
->value
['border']['l']['width'];
5437 $this->parsingCss
->value
['border']['l'] = $this->parsingCss
->readBorder('none');
5441 // margins of the table
5443 $marge['t'] = $this->parsingCss
->value
['padding']['t']+
0.5*HTML2PDF
::$_tables[$param['num']]['cellspacing']+
$this->parsingCss
->value
['border']['t']['width'];
5444 $marge['r'] = $this->parsingCss
->value
['padding']['r']+
0.5*HTML2PDF
::$_tables[$param['num']]['cellspacing']+
$this->parsingCss
->value
['border']['r']['width'];
5445 $marge['b'] = $this->parsingCss
->value
['padding']['b']+
0.5*HTML2PDF
::$_tables[$param['num']]['cellspacing']+
$this->parsingCss
->value
['border']['b']['width'];
5446 $marge['l'] = $this->parsingCss
->value
['padding']['l']+
0.5*HTML2PDF
::$_tables[$param['num']]['cellspacing']+
$this->parsingCss
->value
['border']['l']['width'];
5448 // if we are in a sub HTML
5449 if ($this->_subPart
) {
5450 // new position in the table
5451 HTML2PDF
::$_tables[$param['num']]['td_curr']++
;
5452 HTML2PDF
::$_tables[$param['num']]['cases'][$y][$x] = array();
5453 HTML2PDF
::$_tables[$param['num']]['cases'][$y][$x]['w'] = 0;
5454 HTML2PDF
::$_tables[$param['num']]['cases'][$y][$x]['h'] = 0;
5455 HTML2PDF
::$_tables[$param['num']]['cases'][$y][$x]['dw'] = 0;
5456 HTML2PDF
::$_tables[$param['num']]['cases'][$y][$x]['colspan'] = $colspan;
5457 HTML2PDF
::$_tables[$param['num']]['cases'][$y][$x]['rowspan'] = $rowspan;
5458 HTML2PDF
::$_tables[$param['num']]['cases'][$y][$x]['Xr'] = HTML2PDF
::$_tables[$param['num']]['corr_x'];
5459 HTML2PDF
::$_tables[$param['num']]['cases'][$y][$x]['Yr'] = HTML2PDF
::$_tables[$param['num']]['corr_y'];
5461 // prepare the mapping for rowspan and colspan
5462 for ($j=0; $j<$rowspan; $j++
) {
5463 for ($i=0; $i<$colspan; $i++
) {
5464 HTML2PDF
::$_tables[$param['num']]['corr']
5465 [HTML2PDF
::$_tables[$param['num']]['corr_y']+
$j]
5466 [HTML2PDF
::$_tables[$param['num']]['corr_x']+
$i] = ($i+
$j>0) ?
'' : array($x,$y,$colspan,$rowspan);
5469 HTML2PDF
::$_tables[$param['num']]['corr_x']+
= $colspan;
5470 while (isset(HTML2PDF
::$_tables[$param['num']]['corr'][HTML2PDF
::$_tables[$param['num']]['corr_y']][HTML2PDF
::$_tables[$param['num']]['corr_x']])) {
5471 HTML2PDF
::$_tables[$param['num']]['corr_x']++
;
5474 // extract the content of the TD, and calculate his size
5475 $level = $this->parsingHtml
->getLevel($this->_tempPos
);
5476 $this->_createSubHTML($this->_subHtml
);
5477 $this->_subHtml
->parsingHtml
->code
= $level;
5478 $this->_subHtml
->_makeHTMLcode();
5479 $this->_tempPos+
= count($level);
5481 // new position in the table
5482 HTML2PDF
::$_tables[$param['num']]['td_curr']++
;
5483 HTML2PDF
::$_tables[$param['num']]['td_x']+
= HTML2PDF
::$_tables[$param['num']]['cases'][$y][$x]['dw'];
5485 // borders and background of the TD
5486 $this->_drawRectangle(
5487 HTML2PDF
::$_tables[$param['num']]['td_x'],
5488 HTML2PDF
::$_tables[$param['num']]['td_y'],
5489 HTML2PDF
::$_tables[$param['num']]['cases'][$y][$x]['w'],
5490 HTML2PDF
::$_tables[$param['num']]['cases'][$y][$x]['h'],
5491 $this->parsingCss
->value
['border'],
5492 $this->parsingCss
->value
['padding'],
5493 HTML2PDF
::$_tables[$param['num']]['cellspacing']*0.5,
5494 $this->parsingCss
->value
['background']
5497 $this->parsingCss
->value
['width'] = HTML2PDF
::$_tables[$param['num']]['cases'][$y][$x]['w'] - $marge['l'] - $marge['r'];
5499 // marges = size of the TD
5500 $mL = HTML2PDF
::$_tables[$param['num']]['td_x']+
$marge['l'];
5501 $mR = $this->pdf
->getW() - $mL - $this->parsingCss
->value
['width'];
5502 $this->_saveMargin($mL, 0, $mR);
5504 // position of the content, from vertical-align
5505 $hCorr = HTML2PDF
::$_tables[$param['num']]['cases'][$y][$x]['h'];
5506 $hReel = HTML2PDF
::$_tables[$param['num']]['cases'][$y][$x]['real_h'];
5507 switch($this->parsingCss
->value
['vertical-align'])
5510 $yCorr = $hCorr-$hReel;
5514 $yCorr = ($hCorr-$hReel)*0.5;
5523 // position of the content
5524 $x = HTML2PDF
::$_tables[$param['num']]['td_x']+
$marge['l'];
5525 $y = HTML2PDF
::$_tables[$param['num']]['td_y']+
$marge['t']+
$yCorr;
5526 $this->pdf
->setXY($x, $y);
5527 $this->_setNewPositionForNewLine();
5537 * @param array $param
5540 protected function _tag_close_TD($param)
5542 if ($this->_isForOneLine
) return false;
5548 $marge['t'] = $this->parsingCss
->value
['padding']['t']+
0.5*HTML2PDF
::$_tables[$param['num']]['cellspacing']+
$this->parsingCss
->value
['border']['t']['width'];
5549 $marge['r'] = $this->parsingCss
->value
['padding']['r']+
0.5*HTML2PDF
::$_tables[$param['num']]['cellspacing']+
$this->parsingCss
->value
['border']['r']['width'];
5550 $marge['b'] = $this->parsingCss
->value
['padding']['b']+
0.5*HTML2PDF
::$_tables[$param['num']]['cellspacing']+
$this->parsingCss
->value
['border']['b']['width'];
5551 $marge['l'] = $this->parsingCss
->value
['padding']['l']+
0.5*HTML2PDF
::$_tables[$param['num']]['cellspacing']+
$this->parsingCss
->value
['border']['l']['width'];
5552 $marge['t']+
= 0.001;
5553 $marge['r']+
= 0.001;
5554 $marge['b']+
= 0.001;
5555 $marge['l']+
= 0.001;
5557 // if we are in a sub HTML
5558 if ($this->_subPart
) {
5560 // it msut take only one page
5561 if ($this->_testTdInOnepage
&& $this->_subHtml
->pdf
->getPage()>1) {
5562 throw new HTML2PDF_exception(7);
5565 // size of the content of the TD
5566 $w0 = $this->_subHtml
->_maxX +
$marge['l'] +
$marge['r'];
5567 $h0 = $this->_subHtml
->_maxY +
$marge['t'] +
$marge['b'];
5569 // size from the CSS style
5570 $w2 = $this->parsingCss
->value
['width'] +
$marge['l'] +
$marge['r'];
5571 $h2 = $this->parsingCss
->value
['height'] +
$marge['t'] +
$marge['b'];
5573 // final size of the TD
5574 HTML2PDF
::$_tables[$param['num']]['cases'][HTML2PDF
::$_tables[$param['num']]['tr_curr']-1][HTML2PDF
::$_tables[$param['num']]['td_curr']-1]['w'] = max(array($w0, $w2));
5575 HTML2PDF
::$_tables[$param['num']]['cases'][HTML2PDF
::$_tables[$param['num']]['tr_curr']-1][HTML2PDF
::$_tables[$param['num']]['td_curr']-1]['h'] = max(array($h0, $h2));
5577 // real position of the content
5578 HTML2PDF
::$_tables[$param['num']]['cases'][HTML2PDF
::$_tables[$param['num']]['tr_curr']-1][HTML2PDF
::$_tables[$param['num']]['td_curr']-1]['real_w'] = $w0;
5579 HTML2PDF
::$_tables[$param['num']]['cases'][HTML2PDF
::$_tables[$param['num']]['tr_curr']-1][HTML2PDF
::$_tables[$param['num']]['td_curr']-1]['real_h'] = $h0;
5581 // destroy the sub HTML
5582 $this->_destroySubHTML($this->_subHtml
);
5584 $this->_loadMargin();
5586 HTML2PDF
::$_tables[$param['num']]['td_x']+
= HTML2PDF
::$_tables[$param['num']]['cases'][HTML2PDF
::$_tables[$param['num']]['tr_curr']-1][HTML2PDF
::$_tables[$param['num']]['td_curr']-1]['w'];
5589 $this->parsingCss
->load();
5590 $this->parsingCss
->fontSet();
5600 * @param array $param
5603 protected function _tag_open_TH($param)
5605 if ($this->_isForOneLine
) return false;
5607 $this->parsingCss
->save();
5608 $this->parsingCss
->value
['font-bold'] = true;
5610 $this->_tag_open_TD($param, 'th');
5619 * @param array $param
5622 protected function _tag_close_TH($param)
5624 if ($this->_isForOneLine
) return false;
5626 $this->_tag_close_TD($param);
5628 $this->parsingCss
->load();
5637 * @param array $param
5640 protected function _tag_open_IMG($param)
5642 $src = str_replace('&', '&', $param['src']);
5644 $this->parsingCss
->save();
5645 $this->parsingCss
->value
['width'] = 0;
5646 $this->parsingCss
->value
['height'] = 0;
5647 $this->parsingCss
->value
['border'] = array('type' => 'none', 'width' => 0, 'color' => array(0, 0, 0));
5648 $this->parsingCss
->value
['background'] = array('color' => null, 'image' => null, 'position' => null, 'repeat' => null);
5649 $this->parsingCss
->analyse('img', $param);
5650 $this->parsingCss
->setPosition();
5651 $this->parsingCss
->fontSet();
5653 $res = $this->_drawImage($src, isset($param['sub_li']));
5654 if (!$res) return $res;
5656 $this->parsingCss
->load();
5657 $this->parsingCss
->fontSet();
5667 * @param array $param
5670 protected function _tag_open_SELECT($param)
5672 if (!isset($param['name'])) {
5673 $param['name'] = 'champs_pdf_'.(count($this->_lstField
)+
1);
5676 $param['name'] = strtolower($param['name']);
5678 if (isset($this->_lstField
[$param['name']])) {
5679 $this->_lstField
[$param['name']]++
;
5681 $this->_lstField
[$param['name']] = 1;
5684 $this->parsingCss
->save();
5685 $this->parsingCss
->analyse('select', $param);
5686 $this->parsingCss
->setPosition();
5687 $this->parsingCss
->fontSet();
5689 $this->_lstSelect
= array();
5690 $this->_lstSelect
['name'] = $param['name'];
5691 $this->_lstSelect
['multi'] = isset($param['multiple']) ?
true : false;
5692 $this->_lstSelect
['size'] = isset($param['size']) ?
$param['size'] : 1;
5693 $this->_lstSelect
['options'] = array();
5695 if ($this->_lstSelect
['multi'] && $this->_lstSelect
['size']<3) $this->_lstSelect
['size'] = 3;
5704 * @param array $param
5707 protected function _tag_open_OPTION($param)
5709 // get the content of the option : it is the text of the option
5710 $level = $this->parsingHtml
->getLevel($this->_parsePos
);
5711 $this->_parsePos+
= count($level);
5712 $value = isset($param['value']) ?
$param['value'] : 'aut_tag_open_opt_'.(count($this->_lstSelect
)+
1);
5714 $this->_lstSelect
['options'][$value] = isset($level[0]['param']['txt']) ?
$level[0]['param']['txt'] : '';
5723 * @param array $param
5726 protected function _tag_close_OPTION($param)
5728 // nothing to do here
5737 * @param array $param
5740 protected function _tag_close_SELECT()
5742 // position of the select
5743 $x = $this->pdf
->getX();
5744 $y = $this->pdf
->getY();
5745 $f = 1.08*$this->parsingCss
->value
['font-size'];
5748 $w = $this->parsingCss
->value
['width']; if (!$w) $w = 50;
5750 // height (automatic)
5751 $h = ($f*1.07*$this->_lstSelect
['size'] +
1);
5753 $prop = $this->parsingCss
->getFormStyle();
5756 if ($this->_lstSelect
['multi']) {
5757 $prop['multipleSelection'] = 'true';
5761 // single or multi select
5762 if ($this->_lstSelect
['size']>1) {
5763 $this->pdf
->ListBox($this->_lstSelect
['name'], $w, $h, $this->_lstSelect
['options'], $prop);
5765 $this->pdf
->ComboBox($this->_lstSelect
['name'], $w, $h, $this->_lstSelect
['options'], $prop);
5768 $this->_maxX
= max($this->_maxX
, $x+
$w);
5769 $this->_maxY
= max($this->_maxY
, $y+
$h);
5770 $this->_maxH
= max($this->_maxH
, $h);
5772 $this->pdf
->setX($x+
$w);
5774 $this->parsingCss
->load();
5775 $this->parsingCss
->fontSet();
5777 $this->_lstSelect
= array();
5786 * @param array $param
5789 protected function _tag_open_TEXTAREA($param)
5791 if (!isset($param['name'])) {
5792 $param['name'] = 'champs_pdf_'.(count($this->_lstField
)+
1);
5795 $param['name'] = strtolower($param['name']);
5797 if (isset($this->_lstField
[$param['name']])) {
5798 $this->_lstField
[$param['name']]++
;
5800 $this->_lstField
[$param['name']] = 1;
5803 $this->parsingCss
->save();
5804 $this->parsingCss
->analyse('textarea', $param);
5805 $this->parsingCss
->setPosition();
5806 $this->parsingCss
->fontSet();
5808 $x = $this->pdf
->getX();
5809 $y = $this->pdf
->getY();
5810 $fx = 0.65*$this->parsingCss
->value
['font-size'];
5811 $fy = 1.08*$this->parsingCss
->value
['font-size'];
5813 // extract the content the textarea : value
5814 $level = $this->parsingHtml
->getLevel($this->_parsePos
);
5815 $this->_parsePos+
= count($level);
5817 // automatic size, from cols and rows properties
5818 $w = $fx*(isset($param['cols']) ?
$param['cols'] : 22)+
1;
5819 $h = $fy*1.07*(isset($param['rows']) ?
$param['rows'] : 3)+
3;
5821 $prop = $this->parsingCss
->getFormStyle();
5823 $prop['multiline'] = true;
5824 $prop['value'] = isset($level[0]['param']['txt']) ?
$level[0]['param']['txt'] : '';
5826 $this->pdf
->TextField($param['name'], $w, $h, $prop, array(), $x, $y);
5828 $this->_maxX
= max($this->_maxX
, $x+
$w);
5829 $this->_maxY
= max($this->_maxY
, $y+
$h);
5830 $this->_maxH
= max($this->_maxH
, $h);
5832 $this->pdf
->setX($x+
$w);
5841 * @param array $param
5844 protected function _tag_close_TEXTAREA()
5846 $this->parsingCss
->load();
5847 $this->parsingCss
->fontSet();
5856 * @param array $param
5859 protected function _tag_open_INPUT($param)
5861 if (!isset($param['name'])) $param['name'] = 'champs_pdf_'.(count($this->_lstField
)+
1);
5862 if (!isset($param['value'])) $param['value'] = '';
5863 if (!isset($param['type'])) $param['type'] = 'text';
5865 $param['name'] = strtolower($param['name']);
5866 $param['type'] = strtolower($param['type']);
5868 // the type must be valid
5869 if (!in_array($param['type'], array('text', 'checkbox', 'radio', 'hidden', 'submit', 'reset', 'button'))) {
5870 $param['type'] = 'text';
5873 if (isset($this->_lstField
[$param['name']])) {
5874 $this->_lstField
[$param['name']]++
;
5876 $this->_lstField
[$param['name']] = 1;
5879 $this->parsingCss
->save();
5880 $this->parsingCss
->analyse('input', $param);
5881 $this->parsingCss
->setPosition();
5882 $this->parsingCss
->fontSet();
5884 $name = $param['name'];
5886 $x = $this->pdf
->getX();
5887 $y = $this->pdf
->getY();
5888 $f = 1.08*$this->parsingCss
->value
['font-size'];
5890 $prop = $this->parsingCss
->getFormStyle();
5892 switch($param['type'])
5897 if ($h<$f) $y+
= ($f-$h)*0.5;
5898 $checked = (isset($param['checked']) && $param['checked']=='checked');
5899 $this->pdf
->CheckBox($name, $w, $checked, $prop, array(), ($param['value'] ?
$param['value'] : 'Yes'), $x, $y);
5905 if ($h<$f) $y+
= ($f-$h)*0.5;
5906 $checked = (isset($param['checked']) && $param['checked']=='checked');
5907 $this->pdf
->RadioButton($name, $w, $prop, array(), ($param['value'] ?
$param['value'] : 'On'), $checked, $x, $y);
5913 $prop['value'] = $param['value'];
5914 $this->pdf
->TextField($name, $w, $h, $prop, array(), $x, $y);
5918 $w = $this->parsingCss
->value
['width']; if (!$w) $w = 40;
5920 $prop['value'] = $param['value'];
5921 $this->pdf
->TextField($name, $w, $h, $prop, array(), $x, $y);
5925 $w = $this->parsingCss
->value
['width']; if (!$w) $w = 40;
5926 $h = $this->parsingCss
->value
['height']; if (!$h) $h = $f*1.3;
5927 $action = array('S'=>'SubmitForm', 'F'=>$this->_isInForm
, 'Flags'=>array('ExportFormat'));
5928 $this->pdf
->Button($name, $w, $h, $param['value'], $action, $prop, array(), $x, $y);
5932 $w = $this->parsingCss
->value
['width']; if (!$w) $w = 40;
5933 $h = $this->parsingCss
->value
['height']; if (!$h) $h = $f*1.3;
5934 $action = array('S'=>'ResetForm');
5935 $this->pdf
->Button($name, $w, $h, $param['value'], $action, $prop, array(), $x, $y);
5939 $w = $this->parsingCss
->value
['width']; if (!$w) $w = 40;
5940 $h = $this->parsingCss
->value
['height']; if (!$h) $h = $f*1.3;
5941 $action = isset($param['onclick']) ?
$param['onclick'] : '';
5942 $this->pdf
->Button($name, $w, $h, $param['value'], $action, $prop, array(), $x, $y);
5951 $this->_maxX
= max($this->_maxX
, $x+
$w);
5952 $this->_maxY
= max($this->_maxY
, $y+
$h);
5953 $this->_maxH
= max($this->_maxH
, $h);
5955 $this->pdf
->setX($x+
$w);
5957 $this->parsingCss
->load();
5958 $this->parsingCss
->fontSet();
5967 * @param array $param
5970 protected function _tag_open_DRAW($param)
5972 if ($this->_isForOneLine
) return false;
5973 if ($this->_debugActif
) $this->_DEBUG_add('DRAW', true);
5975 $this->parsingCss
->save();
5976 $this->parsingCss
->analyse('draw', $param);
5977 $this->parsingCss
->fontSet();
5979 $alignObject = null;
5980 if ($this->parsingCss
->value
['margin-auto']) $alignObject = 'center';
5982 $overW = $this->parsingCss
->value
['width'];
5983 $overH = $this->parsingCss
->value
['height'];
5984 $this->parsingCss
->value
['old_maxX'] = $this->_maxX
;
5985 $this->parsingCss
->value
['old_maxY'] = $this->_maxY
;
5986 $this->parsingCss
->value
['old_maxH'] = $this->_maxH
;
5988 $w = $this->parsingCss
->value
['width'];
5989 $h = $this->parsingCss
->value
['height'];
5991 if (!$this->parsingCss
->value
['position']) {
5993 $w < ($this->pdf
->getW() - $this->pdf
->getlMargin()-$this->pdf
->getrMargin()) &&
5994 $this->pdf
->getX() +
$w>=($this->pdf
->getW() - $this->pdf
->getrMargin())
5996 $this->_tag_open_BR(array());
5999 ($h < ($this->pdf
->getH() - $this->pdf
->gettMargin()-$this->pdf
->getbMargin())) &&
6000 ($this->pdf
->getY() +
$h>=($this->pdf
->getH() - $this->pdf
->getbMargin())) &&
6001 !$this->_isInOverflow
6003 $this->_setNewPage();
6005 $old = $this->parsingCss
->getOldValues();
6006 $parentWidth = $old['width'] ?
$old['width'] : $this->pdf
->getW() - $this->pdf
->getlMargin() - $this->pdf
->getrMargin();
6008 if ($parentWidth>$w) {
6009 if ($alignObject=='center') $this->pdf
->setX($this->pdf
->getX() +
($parentWidth-$w)*0.5);
6010 else if ($alignObject=='right') $this->pdf
->setX($this->pdf
->getX() +
$parentWidth-$w);
6013 $this->parsingCss
->setPosition();
6015 $old = $this->parsingCss
->getOldValues();
6016 $parentWidth = $old['width'] ?
$old['width'] : $this->pdf
->getW() - $this->pdf
->getlMargin() - $this->pdf
->getrMargin();
6018 if ($parentWidth>$w) {
6019 if ($alignObject=='center') $this->pdf
->setX($this->pdf
->getX() +
($parentWidth-$w)*0.5);
6020 else if ($alignObject=='right') $this->pdf
->setX($this->pdf
->getX() +
$parentWidth-$w);
6023 $this->parsingCss
->setPosition();
6031 $this->_drawRectangle(
6032 $this->parsingCss
->value
['x'],
6033 $this->parsingCss
->value
['y'],
6034 $this->parsingCss
->value
['width'],
6035 $this->parsingCss
->value
['height'],
6036 $this->parsingCss
->value
['border'],
6037 $this->parsingCss
->value
['padding'],
6039 $this->parsingCss
->value
['background']
6043 $marge['l'] = $this->parsingCss
->value
['border']['l']['width'];
6044 $marge['r'] = $this->parsingCss
->value
['border']['r']['width'];
6045 $marge['t'] = $this->parsingCss
->value
['border']['t']['width'];
6046 $marge['b'] = $this->parsingCss
->value
['border']['b']['width'];
6048 $this->parsingCss
->value
['width'] -= $marge['l']+
$marge['r'];
6049 $this->parsingCss
->value
['height']-= $marge['t']+
$marge['b'];
6051 $overW-= $marge['l']+
$marge['r'];
6052 $overH-= $marge['t']+
$marge['b'];
6054 // clipping to draw only in the size opf the DRAW tag
6055 $this->pdf
->clippingPathStart(
6056 $this->parsingCss
->value
['x']+
$marge['l'],
6057 $this->parsingCss
->value
['y']+
$marge['t'],
6058 $this->parsingCss
->value
['width'],
6059 $this->parsingCss
->value
['height']
6062 // left and right of the DRAW tag
6063 $mL = $this->parsingCss
->value
['x']+
$marge['l'];
6064 $mR = $this->pdf
->getW() - $mL - $overW;
6066 // position of the DRAW tag
6067 $x = $this->parsingCss
->value
['x']+
$marge['l'];
6068 $y = $this->parsingCss
->value
['y']+
$marge['t'];
6070 // prepare the drawing area
6071 $this->_saveMargin($mL, 0, $mR);
6072 $this->pdf
->setXY($x, $y);
6074 // we are in a draw tag
6075 $this->_isInDraw
= array(
6082 // init the translate matrix : (0,0) => ($x, $y)
6083 $this->pdf
->doTransform(array(1,0,0,1,$x,$y));
6084 $this->pdf
->SetAlpha(1.);
6092 * @param array $param
6095 protected function _tag_close_DRAW($param)
6097 if ($this->_isForOneLine
) return false;
6099 $this->pdf
->SetAlpha(1.);
6100 $this->pdf
->undoTransform();
6101 $this->pdf
->clippingPathStop();
6103 $this->_maxX
= $this->parsingCss
->value
['old_maxX'];
6104 $this->_maxY
= $this->parsingCss
->value
['old_maxY'];
6105 $this->_maxH
= $this->parsingCss
->value
['old_maxH'];
6108 $marge['l'] = $this->parsingCss
->value
['border']['l']['width'];
6109 $marge['r'] = $this->parsingCss
->value
['border']['r']['width'];
6110 $marge['t'] = $this->parsingCss
->value
['border']['t']['width'];
6111 $marge['b'] = $this->parsingCss
->value
['border']['b']['width'];
6113 $x = $this->parsingCss
->value
['x'];
6114 $y = $this->parsingCss
->value
['y'];
6115 $w = $this->parsingCss
->value
['width']+
$marge['l']+
$marge['r'];
6116 $h = $this->parsingCss
->value
['height']+
$marge['t']+
$marge['b'];
6118 if ($this->parsingCss
->value
['position']!='absolute') {
6119 $this->pdf
->setXY($x+
$w, $y);
6121 $this->_maxX
= max($this->_maxX
, $x+
$w);
6122 $this->_maxY
= max($this->_maxY
, $y+
$h);
6123 $this->_maxH
= max($this->_maxH
, $h);
6127 $this->pdf
->setXY($this->parsingCss
->value
['xc'], $this->parsingCss
->value
['yc']);
6132 $block = ($this->parsingCss
->value
['display']!='inline' && $this->parsingCss
->value
['position']!='absolute');
6134 $this->parsingCss
->load();
6135 $this->parsingCss
->fontSet();
6136 $this->_loadMargin();
6138 if ($block) $this->_tag_open_BR(array());
6139 if ($this->_debugActif
) $this->_DEBUG_add('DRAW', false);
6141 $this->_isInDraw
= null;
6150 * @param array $param
6153 protected function _tag_open_LINE($param)
6155 if (!$this->_isInDraw
) throw new HTML2PDF_exception(8, 'LINE');
6157 $this->pdf
->doTransform(isset($param['transform']) ?
$this->_prepareTransform($param['transform']) : null);
6158 $this->parsingCss
->save();
6159 $styles = $this->parsingCss
->getSvgStyle('path', $param);
6160 $styles['fill'] = null;
6161 $style = $this->pdf
->svgSetStyle($styles);
6163 $x1 = isset($param['x1']) ?
$this->parsingCss
->ConvertToMM($param['x1'], $this->_isInDraw
['w']) : 0.;
6164 $y1 = isset($param['y1']) ?
$this->parsingCss
->ConvertToMM($param['y1'], $this->_isInDraw
['h']) : 0.;
6165 $x2 = isset($param['x2']) ?
$this->parsingCss
->ConvertToMM($param['x2'], $this->_isInDraw
['w']) : 0.;
6166 $y2 = isset($param['y2']) ?
$this->parsingCss
->ConvertToMM($param['y2'], $this->_isInDraw
['h']) : 0.;
6167 $this->pdf
->svgLine($x1, $y1, $x2, $y2);
6169 $this->pdf
->undoTransform();
6170 $this->parsingCss
->load();
6177 * @param array $param
6180 protected function _tag_open_RECT($param)
6182 if (!$this->_isInDraw
) throw new HTML2PDF_exception(8, 'RECT');
6184 $this->pdf
->doTransform(isset($param['transform']) ?
$this->_prepareTransform($param['transform']) : null);
6185 $this->parsingCss
->save();
6186 $styles = $this->parsingCss
->getSvgStyle('path', $param);
6187 $style = $this->pdf
->svgSetStyle($styles);
6189 $x = isset($param['x']) ?
$this->parsingCss
->ConvertToMM($param['x'], $this->_isInDraw
['w']) : 0.;
6190 $y = isset($param['y']) ?
$this->parsingCss
->ConvertToMM($param['y'], $this->_isInDraw
['h']) : 0.;
6191 $w = isset($param['w']) ?
$this->parsingCss
->ConvertToMM($param['w'], $this->_isInDraw
['w']) : 0.;
6192 $h = isset($param['h']) ?
$this->parsingCss
->ConvertToMM($param['h'], $this->_isInDraw
['h']) : 0.;
6194 $this->pdf
->svgRect($x, $y, $w, $h, $style);
6196 $this->pdf
->undoTransform();
6197 $this->parsingCss
->load();
6204 * @param array $param
6207 protected function _tag_open_CIRCLE($param)
6209 if (!$this->_isInDraw
) throw new HTML2PDF_exception(8, 'CIRCLE');
6211 $this->pdf
->doTransform(isset($param['transform']) ?
$this->_prepareTransform($param['transform']) : null);
6212 $this->parsingCss
->save();
6213 $styles = $this->parsingCss
->getSvgStyle('path', $param);
6214 $style = $this->pdf
->svgSetStyle($styles);
6216 $cx = isset($param['cx']) ?
$this->parsingCss
->ConvertToMM($param['cx'], $this->_isInDraw
['w']) : 0.;
6217 $cy = isset($param['cy']) ?
$this->parsingCss
->ConvertToMM($param['cy'], $this->_isInDraw
['h']) : 0.;
6218 $r = isset($param['r']) ?
$this->parsingCss
->ConvertToMM($param['r'], $this->_isInDraw
['w']) : 0.;
6219 $this->pdf
->svgEllipse($cx, $cy, $r, $r, $style);
6221 $this->pdf
->undoTransform();
6222 $this->parsingCss
->load();
6229 * @param array $param
6232 protected function _tag_open_ELLIPSE($param)
6234 if (!$this->_isInDraw
) throw new HTML2PDF_exception(8, 'ELLIPSE');
6236 $this->pdf
->doTransform(isset($param['transform']) ?
$this->_prepareTransform($param['transform']) : null);
6237 $this->parsingCss
->save();
6238 $styles = $this->parsingCss
->getSvgStyle('path', $param);
6239 $style = $this->pdf
->svgSetStyle($styles);
6241 $cx = isset($param['cx']) ?
$this->parsingCss
->ConvertToMM($param['cx'], $this->_isInDraw
['w']) : 0.;
6242 $cy = isset($param['cy']) ?
$this->parsingCss
->ConvertToMM($param['cy'], $this->_isInDraw
['h']) : 0.;
6243 $rx = isset($param['ry']) ?
$this->parsingCss
->ConvertToMM($param['rx'], $this->_isInDraw
['w']) : 0.;
6244 $ry = isset($param['rx']) ?
$this->parsingCss
->ConvertToMM($param['ry'], $this->_isInDraw
['h']) : 0.;
6245 $this->pdf
->svgEllipse($cx, $cy, $rx, $ry, $style);
6247 $this->pdf
->undoTransform();
6248 $this->parsingCss
->load();
6256 * @param array $param
6259 protected function _tag_open_POLYLINE($param)
6261 if (!$this->_isInDraw
) throw new HTML2PDF_exception(8, 'POLYGON');
6263 $this->pdf
->doTransform(isset($param['transform']) ?
$this->_prepareTransform($param['transform']) : null);
6264 $this->parsingCss
->save();
6265 $styles = $this->parsingCss
->getSvgStyle('path', $param);
6266 $style = $this->pdf
->svgSetStyle($styles);
6268 $path = isset($param['points']) ?
$param['points'] : null;
6270 $path = str_replace(',', ' ', $path);
6271 $path = preg_replace('/[\s]+/', ' ', trim($path));
6274 $path = explode(' ', $path);
6275 foreach ($path as $k => $v) {
6276 $path[$k] = trim($v);
6277 if ($path[$k]==='') unset($path[$k]);
6279 $path = array_values($path);
6282 for ($k=0; $k<count($path); $k+
=2) {
6285 $this->parsingCss
->ConvertToMM($path[$k+
0], $this->_isInDraw
['w']),
6286 $this->parsingCss
->ConvertToMM($path[$k+
1], $this->_isInDraw
['h'])
6291 $this->pdf
->svgPolygone($actions, $style);
6294 $this->pdf
->undoTransform();
6295 $this->parsingCss
->load();
6302 * @param array $param
6305 protected function _tag_open_POLYGON($param)
6307 if (!$this->_isInDraw
) throw new HTML2PDF_exception(8, 'POLYGON');
6309 $this->pdf
->doTransform(isset($param['transform']) ?
$this->_prepareTransform($param['transform']) : null);
6310 $this->parsingCss
->save();
6311 $styles = $this->parsingCss
->getSvgStyle('path', $param);
6312 $style = $this->pdf
->svgSetStyle($styles);
6314 $path = (isset($param['points']) ?
$param['points'] : null);
6316 $path = str_replace(',', ' ', $path);
6317 $path = preg_replace('/[\s]+/', ' ', trim($path));
6320 $path = explode(' ', $path);
6321 foreach ($path as $k => $v) {
6322 $path[$k] = trim($v);
6323 if ($path[$k]==='') unset($path[$k]);
6325 $path = array_values($path);
6328 for ($k=0; $k<count($path); $k+
=2) {
6331 $this->parsingCss
->ConvertToMM($path[$k+
0], $this->_isInDraw
['w']),
6332 $this->parsingCss
->ConvertToMM($path[$k+
1], $this->_isInDraw
['h'])
6335 $actions[] = array('z');
6338 $this->pdf
->svgPolygone($actions, $style);
6341 $this->pdf
->undoTransform();
6342 $this->parsingCss
->load();
6349 * @param array $param
6352 protected function _tag_open_PATH($param)
6354 if (!$this->_isInDraw
) throw new HTML2PDF_exception(8, 'PATH');
6356 $this->pdf
->doTransform(isset($param['transform']) ?
$this->_prepareTransform($param['transform']) : null);
6357 $this->parsingCss
->save();
6358 $styles = $this->parsingCss
->getSvgStyle('path', $param);
6359 $style = $this->pdf
->svgSetStyle($styles);
6361 $path = isset($param['d']) ?
$param['d'] : null;
6365 $path = str_replace(',', ' ', $path);
6366 $path = preg_replace('/([a-zA-Z])([0-9\.\-])/', '$1 $2', $path);
6367 $path = preg_replace('/([0-9\.])([a-zA-Z])/', '$1 $2', $path);
6368 $path = preg_replace('/[\s]+/', ' ', trim($path));
6369 $path = preg_replace('/ ([a-z]{2})/', '$1', $path);
6371 $path = explode(' ', $path);
6372 foreach ($path as $k => $v) {
6373 $path[$k] = trim($v);
6374 if ($path[$k]==='') unset($path[$k]);
6376 $path = array_values($path);
6378 // read each actions in the path
6381 $lastAction = null; // last action found
6382 for ($k=0; $k<count($path);true) {
6384 // for this actions, we can not have multi coordonate
6385 if (in_array($lastAction, array('z', 'Z'))) {
6389 // read the new action (forcing if no action before)
6390 if (preg_match('/^[a-z]+$/i', $path[$k]) ||
$lastAction===null) {
6391 $lastAction = $path[$k];
6397 $action[] = $lastAction;
6402 $action[] = $this->parsingCss
->ConvertToMM($path[$k+
0], $this->_isInDraw
['w']); // x1
6403 $action[] = $this->parsingCss
->ConvertToMM($path[$k+
1], $this->_isInDraw
['h']); // y1
6404 $action[] = $this->parsingCss
->ConvertToMM($path[$k+
2], $this->_isInDraw
['w']); // x2
6405 $action[] = $this->parsingCss
->ConvertToMM($path[$k+
3], $this->_isInDraw
['h']); // y2
6406 $action[] = $this->parsingCss
->ConvertToMM($path[$k+
4], $this->_isInDraw
['w']); // x
6407 $action[] = $this->parsingCss
->ConvertToMM($path[$k+
5], $this->_isInDraw
['h']); // y
6415 $action[] = $this->parsingCss
->ConvertToMM($path[$k+
0], $this->_isInDraw
['w']); // x2
6416 $action[] = $this->parsingCss
->ConvertToMM($path[$k+
1], $this->_isInDraw
['h']); // y2
6417 $action[] = $this->parsingCss
->ConvertToMM($path[$k+
2], $this->_isInDraw
['w']); // x
6418 $action[] = $this->parsingCss
->ConvertToMM($path[$k+
3], $this->_isInDraw
['h']); // y
6424 $action[] = $this->parsingCss
->ConvertToMM($path[$k+
0], $this->_isInDraw
['w']); // rx
6425 $action[] = $this->parsingCss
->ConvertToMM($path[$k+
1], $this->_isInDraw
['h']); // ry
6426 $action[] = 1.*$path[$k+
2]; // angle de deviation de l'axe X
6427 $action[] = ($path[$k+
3]=='1') ?
1 : 0; // large-arc-flag
6428 $action[] = ($path[$k+
4]=='1') ?
1 : 0; // sweep-flag
6429 $action[] = $this->parsingCss
->ConvertToMM($path[$k+
5], $this->_isInDraw
['w']); // x
6430 $action[] = $this->parsingCss
->ConvertToMM($path[$k+
6], $this->_isInDraw
['h']); // y
6440 $action[] = $this->parsingCss
->ConvertToMM($path[$k+
0], $this->_isInDraw
['w']); // x
6441 $action[] = $this->parsingCss
->ConvertToMM($path[$k+
1], $this->_isInDraw
['h']); // y
6447 $action[] = $this->parsingCss
->ConvertToMM($path[$k+
0], $this->_isInDraw
['w']); // x
6453 $action[] = $this->parsingCss
->ConvertToMM($path[$k+
0], $this->_isInDraw
['h']); // y
6463 $actions[] = $action;
6467 $this->pdf
->svgPolygone($actions, $style);
6470 $this->pdf
->undoTransform();
6471 $this->parsingCss
->load();
6478 * @param array $param
6481 protected function _tag_open_G($param)
6483 if (!$this->_isInDraw
) throw new HTML2PDF_exception(8, 'G');
6485 $this->pdf
->doTransform(isset($param['transform']) ?
$this->_prepareTransform($param['transform']) : null);
6486 $this->parsingCss
->save();
6487 $styles = $this->parsingCss
->getSvgStyle('path', $param);
6488 $style = $this->pdf
->svgSetStyle($styles);
6495 * @param array $param
6498 protected function _tag_close_G($param)
6500 $this->pdf
->undoTransform();
6501 $this->parsingCss
->load();
6505 * tag : END_LAST_PAGE
6508 * @param array $param
6511 protected function _tag_open_END_LAST_PAGE($param)
6513 $height = $this->parsingCss
->ConvertToMM(
6514 $param['end_height'],
6515 $this->pdf
->getH() - $this->pdf
->gettMargin()-$this->pdf
->getbMargin()
6518 if ($height < ($this->pdf
->getH() - $this->pdf
->gettMargin()-$this->pdf
->getbMargin())
6519 && $this->pdf
->getY() +
$height>=($this->pdf
->getH() - $this->pdf
->getbMargin())
6521 $this->_setNewPage();
6524 $this->parsingCss
->save();
6525 $this->parsingCss
->analyse('end_last_page', $param);
6526 $this->parsingCss
->setPosition();
6527 $this->parsingCss
->fontSet();
6529 $this->pdf
->setY($this->pdf
->getH() - $this->pdf
->getbMargin() - $height);
6533 * tag : END_LAST_PAGE
6536 * @param array $param
6539 protected function _tag_close_END_LAST_PAGE($param)
6541 $this->parsingCss
->load();
6542 $this->parsingCss
->fontSet();
6546 * new page for the automatic Index, do not use this method. Only HTML2PDF_myPdf could use it !!!!
6549 * @return integer $oldPage
6551 public function _INDEX_NewPage(&$page)
6554 $oldPage = $this->pdf
->getPage();
6555 $this->pdf
->setPage($page);
6556 $this->pdf
->setXY($this->_margeLeft
, $this->_margeTop
);
6561 $this->_setNewPage();